Merge "Import translations. DO NOT MERGE"
diff --git a/Android.mk b/Android.mk
index 642d8b9..a5746e4 100644
--- a/Android.mk
+++ b/Android.mk
@@ -232,6 +232,7 @@
 	core/java/android/view/IWindowId.aidl \
 	core/java/android/view/IWindowManager.aidl \
 	core/java/android/view/IWindowSession.aidl \
+	core/java/android/view/IWindowSessionCallback.aidl \
 	core/java/android/speech/IRecognitionListener.aidl \
 	core/java/android/speech/IRecognitionService.aidl \
 	core/java/android/speech/tts/ITextToSpeechCallback.aidl \
@@ -717,7 +718,7 @@
 LOCAL_DROIDDOC_OPTIONS:=\
 		$(framework_docs_LOCAL_DROIDDOC_OPTIONS) \
 		-stubs $(TARGET_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/android_private_stubs_current_intermediates/src \
-        -showAnnotation android.annotation.PrivateApi \
+        -showAnnotation android.annotation.SystemApi \
 		-nodocs
 
 LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=build/tools/droiddoc/templates-sdk
diff --git a/api/current.txt b/api/current.txt
index 8a5f1df..004d91d 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -266,7 +266,7 @@
     field public static final int actionModeSplitBackground = 16843677; // 0x101039d
     field public static final int actionModeStyle = 16843668; // 0x1010394
     field public static final int actionOverflowButtonStyle = 16843510; // 0x10102f6
-    field public static final int actionOverflowMenuStyle = 16843848; // 0x1010448
+    field public static final int actionOverflowMenuStyle = 16843847; // 0x1010447
     field public static final int actionProviderClass = 16843657; // 0x1010389
     field public static final int actionViewClass = 16843516; // 0x10102fc
     field public static final int activatedBackgroundIndicator = 16843517; // 0x10102fd
@@ -312,7 +312,7 @@
     field public static final int autoCompleteTextViewStyle = 16842859; // 0x101006b
     field public static final int autoLink = 16842928; // 0x10100b0
     field public static final int autoMirrored = 16843754; // 0x10103ea
-    field public static final int autoRemoveFromRecents = 16843850; // 0x101044a
+    field public static final int autoRemoveFromRecents = 16843849; // 0x1010449
     field public static final int autoStart = 16843445; // 0x10102b5
     field public static final deprecated int autoText = 16843114; // 0x101016a
     field public static final int autoUrlDetect = 16843404; // 0x101028c
@@ -385,7 +385,7 @@
     field public static final int codes = 16843330; // 0x1010242
     field public static final int collapseColumns = 16843083; // 0x101014b
     field public static final int color = 16843173; // 0x10101a5
-    field public static final int colorAccent = 16843833; // 0x1010439
+    field public static final int colorAccent = 16843832; // 0x1010438
     field public static final int colorActivatedHighlight = 16843664; // 0x1010390
     field public static final int colorBackground = 16842801; // 0x1010031
     field public static final int colorBackgroundCacheHint = 16843435; // 0x10102ab
@@ -399,9 +399,8 @@
     field public static final int colorLongPressedHighlight = 16843662; // 0x101038e
     field public static final int colorMultiSelectHighlight = 16843665; // 0x1010391
     field public static final int colorPressedHighlight = 16843661; // 0x101038d
-    field public static final int colorPrimary = 16843831; // 0x1010437
-    field public static final int colorPrimaryDark = 16843832; // 0x1010438
-    field public static final int colorPrimaryLight = 16843830; // 0x1010436
+    field public static final int colorPrimary = 16843830; // 0x1010436
+    field public static final int colorPrimaryDark = 16843831; // 0x1010437
     field public static final int columnCount = 16843639; // 0x1010377
     field public static final int columnDelay = 16843215; // 0x10101cf
     field public static final int columnOrderPreserved = 16843640; // 0x1010378
@@ -416,10 +415,10 @@
     field public static final int content = 16843355; // 0x101025b
     field public static final int contentAuthority = 16843408; // 0x1010290
     field public static final int contentDescription = 16843379; // 0x1010273
-    field public static final int contentInsetEnd = 16843863; // 0x1010457
-    field public static final int contentInsetLeft = 16843864; // 0x1010458
-    field public static final int contentInsetRight = 16843865; // 0x1010459
-    field public static final int contentInsetStart = 16843862; // 0x1010456
+    field public static final int contentInsetEnd = 16843862; // 0x1010456
+    field public static final int contentInsetLeft = 16843863; // 0x1010457
+    field public static final int contentInsetRight = 16843864; // 0x1010458
+    field public static final int contentInsetStart = 16843861; // 0x1010455
     field public static final int controlX1 = 16843798; // 0x1010416
     field public static final int controlX2 = 16843800; // 0x1010418
     field public static final int controlY1 = 16843799; // 0x1010417
@@ -464,7 +463,7 @@
     field public static final int dividerHorizontal = 16843564; // 0x101032c
     field public static final int dividerPadding = 16843562; // 0x101032a
     field public static final int dividerVertical = 16843530; // 0x101030a
-    field public static final int documentLaunchMode = 16843849; // 0x1010449
+    field public static final int documentLaunchMode = 16843848; // 0x1010448
     field public static final int drawSelectorOnTop = 16843004; // 0x10100fc
     field public static final int drawable = 16843161; // 0x1010199
     field public static final int drawableBottom = 16843118; // 0x101016e
@@ -493,7 +492,8 @@
     field public static final int editTextStyle = 16842862; // 0x101006e
     field public static final deprecated int editable = 16843115; // 0x101016b
     field public static final int editorExtras = 16843300; // 0x1010224
-    field public static final int elevation = 16843844; // 0x1010444
+    field public static final int elegantTextHeight = 16843871; // 0x101045f
+    field public static final int elevation = 16843843; // 0x1010443
     field public static final int ellipsize = 16842923; // 0x10100ab
     field public static final int ems = 16843096; // 0x1010158
     field public static final int enabled = 16842766; // 0x101000e
@@ -503,10 +503,10 @@
     field public static final int entries = 16842930; // 0x10100b2
     field public static final int entryValues = 16843256; // 0x10101f8
     field public static final int eventsInterceptionEnabled = 16843389; // 0x101027d
-    field public static final int excludeClass = 16843846; // 0x1010446
+    field public static final int excludeClass = 16843845; // 0x1010445
     field public static final int excludeFromRecents = 16842775; // 0x1010017
-    field public static final int excludeId = 16843845; // 0x1010445
-    field public static final int excludeViewName = 16843857; // 0x1010451
+    field public static final int excludeId = 16843844; // 0x1010444
+    field public static final int excludeViewName = 16843856; // 0x1010450
     field public static final int exitFadeDuration = 16843533; // 0x101030d
     field public static final int expandableListPreferredChildIndicatorLeft = 16842834; // 0x1010052
     field public static final int expandableListPreferredChildIndicatorRight = 16842835; // 0x1010053
@@ -568,7 +568,7 @@
     field public static final int freezesText = 16843116; // 0x101016c
     field public static final int fromAlpha = 16843210; // 0x10101ca
     field public static final int fromDegrees = 16843187; // 0x10101b3
-    field public static final int fromId = 16843853; // 0x101044d
+    field public static final int fromId = 16843852; // 0x101044c
     field public static final int fromScene = 16843741; // 0x10103dd
     field public static final int fromXDelta = 16843206; // 0x10101c6
     field public static final int fromXScale = 16843202; // 0x10101c2
@@ -601,7 +601,7 @@
     field public static final int headerBackground = 16843055; // 0x101012f
     field public static final int headerDividersEnabled = 16843310; // 0x101022e
     field public static final int height = 16843093; // 0x1010155
-    field public static final int hideOnContentScroll = 16843847; // 0x1010447
+    field public static final int hideOnContentScroll = 16843846; // 0x1010446
     field public static final int hint = 16843088; // 0x1010150
     field public static final int homeAsUpIndicator = 16843531; // 0x101030b
     field public static final int homeLayout = 16843549; // 0x101031d
@@ -748,7 +748,7 @@
     field public static final int layout_centerVertical = 16843153; // 0x1010191
     field public static final int layout_column = 16843084; // 0x101014c
     field public static final int layout_columnSpan = 16843645; // 0x101037d
-    field public static final int layout_columnWeight = 16843868; // 0x101045c
+    field public static final int layout_columnWeight = 16843867; // 0x101045b
     field public static final int layout_gravity = 16842931; // 0x10100b3
     field public static final int layout_height = 16842997; // 0x10100f5
     field public static final int layout_margin = 16842998; // 0x10100f6
@@ -760,7 +760,7 @@
     field public static final int layout_marginTop = 16843000; // 0x10100f8
     field public static final int layout_row = 16843643; // 0x101037b
     field public static final int layout_rowSpan = 16843644; // 0x101037c
-    field public static final int layout_rowWeight = 16843867; // 0x101045b
+    field public static final int layout_rowWeight = 16843866; // 0x101045a
     field public static final int layout_scale = 16843155; // 0x1010193
     field public static final int layout_span = 16843085; // 0x101014d
     field public static final int layout_toEndOf = 16843704; // 0x10103b8
@@ -799,7 +799,7 @@
     field public static final int manageSpaceActivity = 16842756; // 0x1010004
     field public static final int mapViewStyle = 16842890; // 0x101008a
     field public static final int marqueeRepeatLimit = 16843293; // 0x101021d
-    field public static final int matchOrder = 16843858; // 0x1010452
+    field public static final int matchOrder = 16843857; // 0x1010451
     field public static final int max = 16843062; // 0x1010136
     field public static final int maxDate = 16843584; // 0x1010340
     field public static final int maxEms = 16843095; // 0x1010157
@@ -832,10 +832,10 @@
     field public static final int moreIcon = 16843061; // 0x1010135
     field public static final int multiprocess = 16842771; // 0x1010013
     field public static final int name = 16842755; // 0x1010003
-    field public static final int navigationBarColor = 16843861; // 0x1010455
+    field public static final int navigationBarColor = 16843860; // 0x1010454
     field public static final int navigationMode = 16843471; // 0x10102cf
     field public static final int negativeButtonText = 16843254; // 0x10101f6
-    field public static final int nestedScrollingEnabled = 16843834; // 0x101043a
+    field public static final int nestedScrollingEnabled = 16843833; // 0x1010439
     field public static final int nextFocusDown = 16842980; // 0x10100e4
     field public static final int nextFocusForward = 16843580; // 0x101033c
     field public static final int nextFocusLeft = 16842977; // 0x10100e1
@@ -866,7 +866,7 @@
     field public static final int paddingBottom = 16842969; // 0x10100d9
     field public static final int paddingEnd = 16843700; // 0x10103b4
     field public static final int paddingLeft = 16842966; // 0x10100d6
-    field public static final int paddingMode = 16843866; // 0x101045a
+    field public static final int paddingMode = 16843865; // 0x1010459
     field public static final int paddingRight = 16842968; // 0x10100d8
     field public static final int paddingStart = 16843699; // 0x10103b3
     field public static final int paddingTop = 16842967; // 0x10100d7
@@ -962,7 +962,7 @@
     field public static final int restoreAnyVersion = 16843450; // 0x10102ba
     field public static final deprecated int restoreNeedsApplication = 16843421; // 0x101029d
     field public static final int restrictedAccountType = 16843733; // 0x10103d5
-    field public static final int reversible = 16843854; // 0x101044e
+    field public static final int reversible = 16843853; // 0x101044d
     field public static final int right = 16843183; // 0x10101af
     field public static final int ringtonePreferenceStyle = 16842899; // 0x1010093
     field public static final int ringtoneType = 16843257; // 0x10101f9
@@ -1016,10 +1016,10 @@
     field public static final int selectAllOnFocus = 16843102; // 0x101015e
     field public static final int selectable = 16843238; // 0x10101e6
     field public static final int selectableItemBackground = 16843534; // 0x101030e
-    field public static final int selectableItemBackgroundBorderless = 16843871; // 0x101045f
+    field public static final int selectableItemBackgroundBorderless = 16843870; // 0x101045e
     field public static final int selectedDateVerticalBar = 16843591; // 0x1010347
     field public static final int selectedWeekBackgroundColor = 16843586; // 0x1010342
-    field public static final int sessionService = 16843841; // 0x1010441
+    field public static final int sessionService = 16843840; // 0x1010440
     field public static final int settingsActivity = 16843301; // 0x1010225
     field public static final int setupActivity = 16843766; // 0x10103f6
     field public static final int shadowColor = 16843105; // 0x1010161
@@ -1053,19 +1053,19 @@
     field public static final int spinnerStyle = 16842881; // 0x1010081
     field public static final int spinnersShown = 16843595; // 0x101034b
     field public static final int splitMotionEvents = 16843503; // 0x10102ef
-    field public static final int splitTrack = 16843855; // 0x101044f
+    field public static final int splitTrack = 16843854; // 0x101044e
     field public static final int src = 16843033; // 0x1010119
     field public static final int ssp = 16843747; // 0x10103e3
     field public static final int sspPattern = 16843749; // 0x10103e5
     field public static final int sspPrefix = 16843748; // 0x10103e4
     field public static final int stackFromBottom = 16843005; // 0x10100fd
-    field public static final int stackViewStyle = 16843842; // 0x1010442
+    field public static final int stackViewStyle = 16843841; // 0x1010441
     field public static final int starStyle = 16842882; // 0x1010082
     field public static final int startColor = 16843165; // 0x101019d
     field public static final int startDelay = 16843746; // 0x10103e2
     field public static final int startOffset = 16843198; // 0x10101be
     field public static final deprecated int startYear = 16843132; // 0x101017c
-    field public static final int stateListAnimator = 16843851; // 0x101044b
+    field public static final int stateListAnimator = 16843850; // 0x101044a
     field public static final int stateNotNeeded = 16842774; // 0x1010016
     field public static final int state_above_anchor = 16842922; // 0x10100aa
     field public static final int state_accelerated = 16843547; // 0x101031b
@@ -1090,7 +1090,7 @@
     field public static final int state_single = 16842915; // 0x10100a3
     field public static final int state_window_focused = 16842909; // 0x101009d
     field public static final int staticWallpaperPreview = 16843569; // 0x1010331
-    field public static final int statusBarColor = 16843860; // 0x1010454
+    field public static final int statusBarColor = 16843859; // 0x1010453
     field public static final int stepSize = 16843078; // 0x1010146
     field public static final int stopWithTask = 16843626; // 0x101036a
     field public static final int streamType = 16843273; // 0x1010209
@@ -1119,7 +1119,7 @@
     field public static final int switchMinWidth = 16843632; // 0x1010370
     field public static final int switchPadding = 16843633; // 0x1010371
     field public static final int switchPreferenceStyle = 16843629; // 0x101036d
-    field public static final int switchStyle = 16843843; // 0x1010443
+    field public static final int switchStyle = 16843842; // 0x1010442
     field public static final int switchTextAppearance = 16843630; // 0x101036e
     field public static final int switchTextOff = 16843628; // 0x101036c
     field public static final int switchTextOn = 16843627; // 0x101036b
@@ -1135,7 +1135,7 @@
     field public static final int targetId = 16843740; // 0x10103dc
     field public static final int targetPackage = 16842785; // 0x1010021
     field public static final int targetSdkVersion = 16843376; // 0x1010270
-    field public static final int targetViewName = 16843856; // 0x1010450
+    field public static final int targetViewName = 16843855; // 0x101044f
     field public static final int taskAffinity = 16842770; // 0x1010012
     field public static final int taskCloseEnterAnimation = 16842942; // 0x10100be
     field public static final int taskCloseExitAnimation = 16842943; // 0x10100bf
@@ -1225,7 +1225,7 @@
     field public static final int titleTextStyle = 16843512; // 0x10102f8
     field public static final int toAlpha = 16843211; // 0x10101cb
     field public static final int toDegrees = 16843188; // 0x10101b4
-    field public static final int toId = 16843852; // 0x101044c
+    field public static final int toId = 16843851; // 0x101044b
     field public static final int toScene = 16843742; // 0x10103de
     field public static final int toXDelta = 16843207; // 0x10101c7
     field public static final int toXScale = 16843203; // 0x10101c3
@@ -1244,8 +1244,8 @@
     field public static final int transition = 16843743; // 0x10103df
     field public static final int transitionGroup = 16843803; // 0x101041b
     field public static final int transitionOrdering = 16843744; // 0x10103e0
-    field public static final int translateX = 16843869; // 0x101045d
-    field public static final int translateY = 16843870; // 0x101045e
+    field public static final int translateX = 16843868; // 0x101045c
+    field public static final int translateY = 16843869; // 0x101045d
     field public static final int translationX = 16843554; // 0x1010322
     field public static final int translationY = 16843555; // 0x1010323
     field public static final int translationZ = 16843796; // 0x1010414
@@ -1307,8 +1307,8 @@
     field public static final int windowActionBar = 16843469; // 0x10102cd
     field public static final int windowActionBarOverlay = 16843492; // 0x10102e4
     field public static final int windowActionModeOverlay = 16843485; // 0x10102dd
-    field public static final int windowAllowEnterTransitionOverlap = 16843840; // 0x1010440
-    field public static final int windowAllowExitTransitionOverlap = 16843839; // 0x101043f
+    field public static final int windowAllowEnterTransitionOverlap = 16843839; // 0x101043f
+    field public static final int windowAllowExitTransitionOverlap = 16843838; // 0x101043e
     field public static final int windowAnimationStyle = 16842926; // 0x10100ae
     field public static final int windowBackground = 16842836; // 0x1010054
     field public static final int windowCloseOnTouchOutside = 16843611; // 0x101035b
@@ -1316,12 +1316,12 @@
     field public static final int windowContentTransitionManager = 16843795; // 0x1010413
     field public static final int windowContentTransitions = 16843794; // 0x1010412
     field public static final int windowDisablePreview = 16843298; // 0x1010222
-    field public static final int windowDrawsSystemBarBackgrounds = 16843859; // 0x1010453
+    field public static final int windowDrawsSystemBarBackgrounds = 16843858; // 0x1010452
     field public static final int windowEnableSplitTouch = 16843543; // 0x1010317
     field public static final int windowEnterAnimation = 16842932; // 0x10100b4
-    field public static final int windowEnterTransition = 16843835; // 0x101043b
+    field public static final int windowEnterTransition = 16843834; // 0x101043a
     field public static final int windowExitAnimation = 16842933; // 0x10100b5
-    field public static final int windowExitTransition = 16843836; // 0x101043c
+    field public static final int windowExitTransition = 16843835; // 0x101043b
     field public static final int windowFrame = 16842837; // 0x1010055
     field public static final int windowFullscreen = 16843277; // 0x101020d
     field public static final int windowHideAnimation = 16842935; // 0x10100b7
@@ -1332,8 +1332,8 @@
     field public static final int windowNoDisplay = 16843294; // 0x101021e
     field public static final int windowNoTitle = 16842838; // 0x1010056
     field public static final int windowOverscan = 16843727; // 0x10103cf
-    field public static final int windowSharedElementEnterTransition = 16843837; // 0x101043d
-    field public static final int windowSharedElementExitTransition = 16843838; // 0x101043e
+    field public static final int windowSharedElementEnterTransition = 16843836; // 0x101043c
+    field public static final int windowSharedElementExitTransition = 16843837; // 0x101043d
     field public static final int windowShowAnimation = 16842934; // 0x10100b6
     field public static final int windowShowWallpaper = 16843410; // 0x1010292
     field public static final int windowSoftInputMode = 16843307; // 0x101022b
@@ -1865,54 +1865,54 @@
     field public static final int TextAppearance_Inverse = 16973887; // 0x103003f
     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 = 16974348; // 0x103020c
+    field public static final int TextAppearance_Material_Body1 = 16974546; // 0x10302d2
+    field public static final int TextAppearance_Material_Body2 = 16974545; // 0x10302d1
+    field public static final int TextAppearance_Material_Button = 16974549; // 0x10302d5
+    field public static final int TextAppearance_Material_Caption = 16974547; // 0x10302d3
+    field public static final int TextAppearance_Material_DialogWindowTitle = 16974349; // 0x103020d
+    field public static final int TextAppearance_Material_Display1 = 16974541; // 0x10302cd
+    field public static final int TextAppearance_Material_Display2 = 16974540; // 0x10302cc
+    field public static final int TextAppearance_Material_Display3 = 16974539; // 0x10302cb
+    field public static final int TextAppearance_Material_Display4 = 16974538; // 0x10302ca
+    field public static final int TextAppearance_Material_Headline = 16974542; // 0x10302ce
+    field public static final int TextAppearance_Material_Inverse = 16974350; // 0x103020e
+    field public static final int TextAppearance_Material_Large = 16974351; // 0x103020f
+    field public static final int TextAppearance_Material_Large_Inverse = 16974352; // 0x1030210
+    field public static final int TextAppearance_Material_Medium = 16974353; // 0x1030211
+    field public static final int TextAppearance_Material_Medium_Inverse = 16974354; // 0x1030212
+    field public static final int TextAppearance_Material_Menu = 16974548; // 0x10302d4
+    field public static final int TextAppearance_Material_SearchResult_Subtitle = 16974355; // 0x1030213
+    field public static final int TextAppearance_Material_SearchResult_Title = 16974356; // 0x1030214
+    field public static final int TextAppearance_Material_Small = 16974357; // 0x1030215
+    field public static final int TextAppearance_Material_Small_Inverse = 16974358; // 0x1030216
+    field public static final int TextAppearance_Material_Subhead = 16974544; // 0x10302d0
+    field public static final int TextAppearance_Material_Title = 16974543; // 0x10302cf
+    field public static final int TextAppearance_Material_Widget = 16974360; // 0x1030218
+    field public static final int TextAppearance_Material_Widget_ActionBar_Menu = 16974361; // 0x1030219
+    field public static final int TextAppearance_Material_Widget_ActionBar_Subtitle = 16974362; // 0x103021a
+    field public static final int TextAppearance_Material_Widget_ActionBar_Subtitle_Inverse = 16974363; // 0x103021b
+    field public static final int TextAppearance_Material_Widget_ActionBar_Title = 16974364; // 0x103021c
+    field public static final int TextAppearance_Material_Widget_ActionBar_Title_Inverse = 16974365; // 0x103021d
+    field public static final int TextAppearance_Material_Widget_ActionMode_Subtitle = 16974366; // 0x103021e
+    field public static final int TextAppearance_Material_Widget_ActionMode_Subtitle_Inverse = 16974367; // 0x103021f
+    field public static final int TextAppearance_Material_Widget_ActionMode_Title = 16974368; // 0x1030220
+    field public static final int TextAppearance_Material_Widget_ActionMode_Title_Inverse = 16974369; // 0x1030221
+    field public static final int TextAppearance_Material_Widget_Button = 16974370; // 0x1030222
+    field public static final int TextAppearance_Material_Widget_DropDownHint = 16974371; // 0x1030223
+    field public static final int TextAppearance_Material_Widget_DropDownItem = 16974372; // 0x1030224
+    field public static final int TextAppearance_Material_Widget_EditText = 16974373; // 0x1030225
+    field public static final int TextAppearance_Material_Widget_IconMenu_Item = 16974374; // 0x1030226
+    field public static final int TextAppearance_Material_Widget_PopupMenu = 16974375; // 0x1030227
+    field public static final int TextAppearance_Material_Widget_PopupMenu_Large = 16974376; // 0x1030228
+    field public static final int TextAppearance_Material_Widget_PopupMenu_Small = 16974377; // 0x1030229
+    field public static final int TextAppearance_Material_Widget_TabWidget = 16974378; // 0x103022a
+    field public static final int TextAppearance_Material_Widget_TextView = 16974379; // 0x103022b
+    field public static final int TextAppearance_Material_Widget_TextView_PopupMenu = 16974380; // 0x103022c
+    field public static final int TextAppearance_Material_Widget_TextView_SpinnerItem = 16974381; // 0x103022d
+    field public static final int TextAppearance_Material_WindowTitle = 16974359; // 0x1030217
     field public static final int TextAppearance_Medium = 16973892; // 0x1030044
     field public static final int TextAppearance_Medium_Inverse = 16973893; // 0x1030045
-    field public static final int TextAppearance_Quantum = 16974348; // 0x103020c
-    field public static final int TextAppearance_Quantum_Body1 = 16974545; // 0x10302d1
-    field public static final int TextAppearance_Quantum_Body2 = 16974544; // 0x10302d0
-    field public static final int TextAppearance_Quantum_Button = 16974548; // 0x10302d4
-    field public static final int TextAppearance_Quantum_Caption = 16974546; // 0x10302d2
-    field public static final int TextAppearance_Quantum_DialogWindowTitle = 16974349; // 0x103020d
-    field public static final int TextAppearance_Quantum_Display1 = 16974540; // 0x10302cc
-    field public static final int TextAppearance_Quantum_Display2 = 16974539; // 0x10302cb
-    field public static final int TextAppearance_Quantum_Display3 = 16974538; // 0x10302ca
-    field public static final int TextAppearance_Quantum_Display4 = 16974537; // 0x10302c9
-    field public static final int TextAppearance_Quantum_Headline = 16974541; // 0x10302cd
-    field public static final int TextAppearance_Quantum_Inverse = 16974350; // 0x103020e
-    field public static final int TextAppearance_Quantum_Large = 16974351; // 0x103020f
-    field public static final int TextAppearance_Quantum_Large_Inverse = 16974352; // 0x1030210
-    field public static final int TextAppearance_Quantum_Medium = 16974353; // 0x1030211
-    field public static final int TextAppearance_Quantum_Medium_Inverse = 16974354; // 0x1030212
-    field public static final int TextAppearance_Quantum_Menu = 16974547; // 0x10302d3
-    field public static final int TextAppearance_Quantum_SearchResult_Subtitle = 16974355; // 0x1030213
-    field public static final int TextAppearance_Quantum_SearchResult_Title = 16974356; // 0x1030214
-    field public static final int TextAppearance_Quantum_Small = 16974357; // 0x1030215
-    field public static final int TextAppearance_Quantum_Small_Inverse = 16974358; // 0x1030216
-    field public static final int TextAppearance_Quantum_Subhead = 16974543; // 0x10302cf
-    field public static final int TextAppearance_Quantum_Title = 16974542; // 0x10302ce
-    field public static final int TextAppearance_Quantum_Widget = 16974360; // 0x1030218
-    field public static final int TextAppearance_Quantum_Widget_ActionBar_Menu = 16974361; // 0x1030219
-    field public static final int TextAppearance_Quantum_Widget_ActionBar_Subtitle = 16974362; // 0x103021a
-    field public static final int TextAppearance_Quantum_Widget_ActionBar_Subtitle_Inverse = 16974363; // 0x103021b
-    field public static final int TextAppearance_Quantum_Widget_ActionBar_Title = 16974364; // 0x103021c
-    field public static final int TextAppearance_Quantum_Widget_ActionBar_Title_Inverse = 16974365; // 0x103021d
-    field public static final int TextAppearance_Quantum_Widget_ActionMode_Subtitle = 16974366; // 0x103021e
-    field public static final int TextAppearance_Quantum_Widget_ActionMode_Subtitle_Inverse = 16974367; // 0x103021f
-    field public static final int TextAppearance_Quantum_Widget_ActionMode_Title = 16974368; // 0x1030220
-    field public static final int TextAppearance_Quantum_Widget_ActionMode_Title_Inverse = 16974369; // 0x1030221
-    field public static final int TextAppearance_Quantum_Widget_Button = 16974370; // 0x1030222
-    field public static final int TextAppearance_Quantum_Widget_DropDownHint = 16974371; // 0x1030223
-    field public static final int TextAppearance_Quantum_Widget_DropDownItem = 16974372; // 0x1030224
-    field public static final int TextAppearance_Quantum_Widget_EditText = 16974373; // 0x1030225
-    field public static final int TextAppearance_Quantum_Widget_IconMenu_Item = 16974374; // 0x1030226
-    field public static final int TextAppearance_Quantum_Widget_PopupMenu = 16974375; // 0x1030227
-    field public static final int TextAppearance_Quantum_Widget_PopupMenu_Large = 16974376; // 0x1030228
-    field public static final int TextAppearance_Quantum_Widget_PopupMenu_Small = 16974377; // 0x1030229
-    field public static final int TextAppearance_Quantum_Widget_TabWidget = 16974378; // 0x103022a
-    field public static final int TextAppearance_Quantum_Widget_TextView = 16974379; // 0x103022b
-    field public static final int TextAppearance_Quantum_Widget_TextView_PopupMenu = 16974380; // 0x103022c
-    field public static final int TextAppearance_Quantum_Widget_TextView_SpinnerItem = 16974381; // 0x103022d
-    field public static final int TextAppearance_Quantum_WindowTitle = 16974359; // 0x1030217
     field public static final int TextAppearance_Small = 16973894; // 0x1030046
     field public static final int TextAppearance_Small_Inverse = 16973895; // 0x1030047
     field public static final int TextAppearance_StatusBar_EventContent = 16973927; // 0x1030067
@@ -1937,10 +1937,11 @@
     field public static final int TextAppearance_WindowTitle = 16973907; // 0x1030053
     field public static final int Theme = 16973829; // 0x1030005
     field public static final int ThemeOverlay = 16974412; // 0x103024c
-    field public static final int ThemeOverlay_Quantum = 16974413; // 0x103024d
-    field public static final int ThemeOverlay_Quantum_ActionBarWidget = 16974416; // 0x1030250
-    field public static final int ThemeOverlay_Quantum_Dark = 16974415; // 0x103024f
-    field public static final int ThemeOverlay_Quantum_Light = 16974414; // 0x103024e
+    field public static final int ThemeOverlay_Material = 16974413; // 0x103024d
+    field public static final int ThemeOverlay_Material_ActionBar = 16974414; // 0x103024e
+    field public static final int ThemeOverlay_Material_Dark = 16974416; // 0x1030250
+    field public static final int ThemeOverlay_Material_Dark_ActionBar = 16974417; // 0x1030251
+    field public static final int ThemeOverlay_Material_Light = 16974415; // 0x103024f
     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
@@ -2007,41 +2008,41 @@
     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 = 16974382; // 0x103022e
+    field public static final int Theme_Material_Dialog = 16974383; // 0x103022f
+    field public static final int Theme_Material_DialogWhenLarge = 16974387; // 0x1030233
+    field public static final int Theme_Material_DialogWhenLarge_NoActionBar = 16974388; // 0x1030234
+    field public static final int Theme_Material_Dialog_MinWidth = 16974384; // 0x1030230
+    field public static final int Theme_Material_Dialog_NoActionBar = 16974385; // 0x1030231
+    field public static final int Theme_Material_Dialog_NoActionBar_MinWidth = 16974386; // 0x1030232
+    field public static final int Theme_Material_InputMethod = 16974389; // 0x1030235
+    field public static final int Theme_Material_Light = 16974398; // 0x103023e
+    field public static final int Theme_Material_Light_DarkActionBar = 16974399; // 0x103023f
+    field public static final int Theme_Material_Light_Dialog = 16974400; // 0x1030240
+    field public static final int Theme_Material_Light_DialogWhenLarge = 16974404; // 0x1030244
+    field public static final int Theme_Material_Light_DialogWhenLarge_NoActionBar = 16974405; // 0x1030245
+    field public static final int Theme_Material_Light_Dialog_MinWidth = 16974401; // 0x1030241
+    field public static final int Theme_Material_Light_Dialog_NoActionBar = 16974402; // 0x1030242
+    field public static final int Theme_Material_Light_Dialog_NoActionBar_MinWidth = 16974403; // 0x1030243
+    field public static final int Theme_Material_Light_NoActionBar = 16974406; // 0x1030246
+    field public static final int Theme_Material_Light_NoActionBar_Fullscreen = 16974407; // 0x1030247
+    field public static final int Theme_Material_Light_NoActionBar_Overscan = 16974408; // 0x1030248
+    field public static final int Theme_Material_Light_NoActionBar_TranslucentDecor = 16974409; // 0x1030249
+    field public static final int Theme_Material_Light_Panel = 16974410; // 0x103024a
+    field public static final int Theme_Material_Light_Voice = 16974411; // 0x103024b
+    field public static final int Theme_Material_NoActionBar = 16974390; // 0x1030236
+    field public static final int Theme_Material_NoActionBar_Fullscreen = 16974391; // 0x1030237
+    field public static final int Theme_Material_NoActionBar_Overscan = 16974392; // 0x1030238
+    field public static final int Theme_Material_NoActionBar_TranslucentDecor = 16974393; // 0x1030239
+    field public static final int Theme_Material_Panel = 16974394; // 0x103023a
+    field public static final int Theme_Material_Voice = 16974395; // 0x103023b
+    field public static final int Theme_Material_Wallpaper = 16974396; // 0x103023c
+    field public static final int Theme_Material_Wallpaper_NoTitleBar = 16974397; // 0x103023d
     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
     field public static final int Theme_NoTitleBar_OverlayActionModes = 16973930; // 0x103006a
     field public static final int Theme_Panel = 16973913; // 0x1030059
-    field public static final int Theme_Quantum = 16974382; // 0x103022e
-    field public static final int Theme_Quantum_Dialog = 16974383; // 0x103022f
-    field public static final int Theme_Quantum_DialogWhenLarge = 16974387; // 0x1030233
-    field public static final int Theme_Quantum_DialogWhenLarge_NoActionBar = 16974388; // 0x1030234
-    field public static final int Theme_Quantum_Dialog_MinWidth = 16974384; // 0x1030230
-    field public static final int Theme_Quantum_Dialog_NoActionBar = 16974385; // 0x1030231
-    field public static final int Theme_Quantum_Dialog_NoActionBar_MinWidth = 16974386; // 0x1030232
-    field public static final int Theme_Quantum_InputMethod = 16974389; // 0x1030235
-    field public static final int Theme_Quantum_Light = 16974398; // 0x103023e
-    field public static final int Theme_Quantum_Light_DarkActionBar = 16974399; // 0x103023f
-    field public static final int Theme_Quantum_Light_Dialog = 16974400; // 0x1030240
-    field public static final int Theme_Quantum_Light_DialogWhenLarge = 16974404; // 0x1030244
-    field public static final int Theme_Quantum_Light_DialogWhenLarge_NoActionBar = 16974405; // 0x1030245
-    field public static final int Theme_Quantum_Light_Dialog_MinWidth = 16974401; // 0x1030241
-    field public static final int Theme_Quantum_Light_Dialog_NoActionBar = 16974402; // 0x1030242
-    field public static final int Theme_Quantum_Light_Dialog_NoActionBar_MinWidth = 16974403; // 0x1030243
-    field public static final int Theme_Quantum_Light_NoActionBar = 16974406; // 0x1030246
-    field public static final int Theme_Quantum_Light_NoActionBar_Fullscreen = 16974407; // 0x1030247
-    field public static final int Theme_Quantum_Light_NoActionBar_Overscan = 16974408; // 0x1030248
-    field public static final int Theme_Quantum_Light_NoActionBar_TranslucentDecor = 16974409; // 0x1030249
-    field public static final int Theme_Quantum_Light_Panel = 16974410; // 0x103024a
-    field public static final int Theme_Quantum_Light_Voice = 16974411; // 0x103024b
-    field public static final int Theme_Quantum_NoActionBar = 16974390; // 0x1030236
-    field public static final int Theme_Quantum_NoActionBar_Fullscreen = 16974391; // 0x1030237
-    field public static final int Theme_Quantum_NoActionBar_Overscan = 16974392; // 0x1030238
-    field public static final int Theme_Quantum_NoActionBar_TranslucentDecor = 16974393; // 0x1030239
-    field public static final int Theme_Quantum_Panel = 16974394; // 0x103023a
-    field public static final int Theme_Quantum_Voice = 16974395; // 0x103023b
-    field public static final int Theme_Quantum_Wallpaper = 16974396; // 0x103023c
-    field public static final int Theme_Quantum_Wallpaper_NoTitleBar = 16974397; // 0x103023d
     field public static final int Theme_Translucent = 16973839; // 0x103000f
     field public static final int Theme_Translucent_NoTitleBar = 16973840; // 0x1030010
     field public static final int Theme_Translucent_NoTitleBar_Fullscreen = 16973841; // 0x1030011
@@ -2321,6 +2322,126 @@
     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 = 16974418; // 0x1030252
+    field public static final int Widget_Material_ActionBar = 16974419; // 0x1030253
+    field public static final int Widget_Material_ActionBar_Solid = 16974420; // 0x1030254
+    field public static final int Widget_Material_ActionBar_TabBar = 16974421; // 0x1030255
+    field public static final int Widget_Material_ActionBar_TabText = 16974422; // 0x1030256
+    field public static final int Widget_Material_ActionBar_TabView = 16974423; // 0x1030257
+    field public static final int Widget_Material_ActionButton = 16974424; // 0x1030258
+    field public static final int Widget_Material_ActionButton_CloseMode = 16974425; // 0x1030259
+    field public static final int Widget_Material_ActionButton_Overflow = 16974426; // 0x103025a
+    field public static final int Widget_Material_ActionMode = 16974427; // 0x103025b
+    field public static final int Widget_Material_AutoCompleteTextView = 16974428; // 0x103025c
+    field public static final int Widget_Material_Button = 16974429; // 0x103025d
+    field public static final int Widget_Material_ButtonBar = 16974435; // 0x1030263
+    field public static final int Widget_Material_ButtonBar_AlertDialog = 16974436; // 0x1030264
+    field public static final int Widget_Material_Button_Borderless = 16974430; // 0x103025e
+    field public static final int Widget_Material_Button_Borderless_Small = 16974431; // 0x103025f
+    field public static final int Widget_Material_Button_Inset = 16974432; // 0x1030260
+    field public static final int Widget_Material_Button_Small = 16974433; // 0x1030261
+    field public static final int Widget_Material_Button_Toggle = 16974434; // 0x1030262
+    field public static final int Widget_Material_CalendarView = 16974437; // 0x1030265
+    field public static final int Widget_Material_CheckedTextView = 16974438; // 0x1030266
+    field public static final int Widget_Material_CompoundButton_CheckBox = 16974439; // 0x1030267
+    field public static final int Widget_Material_CompoundButton_RadioButton = 16974440; // 0x1030268
+    field public static final int Widget_Material_CompoundButton_Star = 16974441; // 0x1030269
+    field public static final int Widget_Material_DatePicker = 16974442; // 0x103026a
+    field public static final int Widget_Material_DropDownItem = 16974443; // 0x103026b
+    field public static final int Widget_Material_DropDownItem_Spinner = 16974444; // 0x103026c
+    field public static final int Widget_Material_EditText = 16974445; // 0x103026d
+    field public static final int Widget_Material_ExpandableListView = 16974446; // 0x103026e
+    field public static final int Widget_Material_FastScroll = 16974447; // 0x103026f
+    field public static final int Widget_Material_GridView = 16974448; // 0x1030270
+    field public static final int Widget_Material_HorizontalScrollView = 16974449; // 0x1030271
+    field public static final int Widget_Material_ImageButton = 16974450; // 0x1030272
+    field public static final int Widget_Material_Light = 16974477; // 0x103028d
+    field public static final int Widget_Material_Light_ActionBar = 16974478; // 0x103028e
+    field public static final int Widget_Material_Light_ActionBar_Solid = 16974479; // 0x103028f
+    field public static final int Widget_Material_Light_ActionBar_TabBar = 16974480; // 0x1030290
+    field public static final int Widget_Material_Light_ActionBar_TabText = 16974481; // 0x1030291
+    field public static final int Widget_Material_Light_ActionBar_TabView = 16974482; // 0x1030292
+    field public static final int Widget_Material_Light_ActionButton = 16974483; // 0x1030293
+    field public static final int Widget_Material_Light_ActionButton_CloseMode = 16974484; // 0x1030294
+    field public static final int Widget_Material_Light_ActionButton_Overflow = 16974485; // 0x1030295
+    field public static final int Widget_Material_Light_ActionMode = 16974486; // 0x1030296
+    field public static final int Widget_Material_Light_AutoCompleteTextView = 16974487; // 0x1030297
+    field public static final int Widget_Material_Light_Button = 16974488; // 0x1030298
+    field public static final int Widget_Material_Light_ButtonBar = 16974494; // 0x103029e
+    field public static final int Widget_Material_Light_ButtonBar_AlertDialog = 16974495; // 0x103029f
+    field public static final int Widget_Material_Light_Button_Borderless = 16974489; // 0x1030299
+    field public static final int Widget_Material_Light_Button_Borderless_Small = 16974490; // 0x103029a
+    field public static final int Widget_Material_Light_Button_Inset = 16974491; // 0x103029b
+    field public static final int Widget_Material_Light_Button_Small = 16974492; // 0x103029c
+    field public static final int Widget_Material_Light_Button_Toggle = 16974493; // 0x103029d
+    field public static final int Widget_Material_Light_CalendarView = 16974496; // 0x10302a0
+    field public static final int Widget_Material_Light_CheckedTextView = 16974497; // 0x10302a1
+    field public static final int Widget_Material_Light_CompoundButton_CheckBox = 16974498; // 0x10302a2
+    field public static final int Widget_Material_Light_CompoundButton_RadioButton = 16974499; // 0x10302a3
+    field public static final int Widget_Material_Light_CompoundButton_Star = 16974500; // 0x10302a4
+    field public static final int Widget_Material_Light_DropDownItem = 16974501; // 0x10302a5
+    field public static final int Widget_Material_Light_DropDownItem_Spinner = 16974502; // 0x10302a6
+    field public static final int Widget_Material_Light_EditText = 16974503; // 0x10302a7
+    field public static final int Widget_Material_Light_ExpandableListView = 16974504; // 0x10302a8
+    field public static final int Widget_Material_Light_FastScroll = 16974505; // 0x10302a9
+    field public static final int Widget_Material_Light_GridView = 16974506; // 0x10302aa
+    field public static final int Widget_Material_Light_HorizontalScrollView = 16974507; // 0x10302ab
+    field public static final int Widget_Material_Light_ImageButton = 16974508; // 0x10302ac
+    field public static final int Widget_Material_Light_ListPopupWindow = 16974509; // 0x10302ad
+    field public static final int Widget_Material_Light_ListView = 16974510; // 0x10302ae
+    field public static final int Widget_Material_Light_ListView_DropDown = 16974511; // 0x10302af
+    field public static final int Widget_Material_Light_MediaRouteButton = 16974512; // 0x10302b0
+    field public static final int Widget_Material_Light_PopupMenu = 16974513; // 0x10302b1
+    field public static final int Widget_Material_Light_PopupMenu_Overflow = 16974514; // 0x10302b2
+    field public static final int Widget_Material_Light_PopupWindow = 16974515; // 0x10302b3
+    field public static final int Widget_Material_Light_ProgressBar = 16974516; // 0x10302b4
+    field public static final int Widget_Material_Light_ProgressBar_Horizontal = 16974517; // 0x10302b5
+    field public static final int Widget_Material_Light_ProgressBar_Inverse = 16974518; // 0x10302b6
+    field public static final int Widget_Material_Light_ProgressBar_Large = 16974519; // 0x10302b7
+    field public static final int Widget_Material_Light_ProgressBar_Large_Inverse = 16974520; // 0x10302b8
+    field public static final int Widget_Material_Light_ProgressBar_Small = 16974521; // 0x10302b9
+    field public static final int Widget_Material_Light_ProgressBar_Small_Inverse = 16974522; // 0x10302ba
+    field public static final int Widget_Material_Light_ProgressBar_Small_Title = 16974523; // 0x10302bb
+    field public static final int Widget_Material_Light_RatingBar = 16974524; // 0x10302bc
+    field public static final int Widget_Material_Light_RatingBar_Indicator = 16974525; // 0x10302bd
+    field public static final int Widget_Material_Light_RatingBar_Small = 16974526; // 0x10302be
+    field public static final int Widget_Material_Light_ScrollView = 16974527; // 0x10302bf
+    field public static final int Widget_Material_Light_SeekBar = 16974528; // 0x10302c0
+    field public static final int Widget_Material_Light_SegmentedButton = 16974529; // 0x10302c1
+    field public static final int Widget_Material_Light_Spinner = 16974531; // 0x10302c3
+    field public static final int Widget_Material_Light_StackView = 16974530; // 0x10302c2
+    field public static final int Widget_Material_Light_Tab = 16974532; // 0x10302c4
+    field public static final int Widget_Material_Light_TabWidget = 16974533; // 0x10302c5
+    field public static final int Widget_Material_Light_TextView = 16974534; // 0x10302c6
+    field public static final int Widget_Material_Light_TextView_SpinnerItem = 16974535; // 0x10302c7
+    field public static final int Widget_Material_Light_WebTextView = 16974536; // 0x10302c8
+    field public static final int Widget_Material_Light_WebView = 16974537; // 0x10302c9
+    field public static final int Widget_Material_ListPopupWindow = 16974451; // 0x1030273
+    field public static final int Widget_Material_ListView = 16974452; // 0x1030274
+    field public static final int Widget_Material_ListView_DropDown = 16974453; // 0x1030275
+    field public static final int Widget_Material_MediaRouteButton = 16974454; // 0x1030276
+    field public static final int Widget_Material_PopupMenu = 16974455; // 0x1030277
+    field public static final int Widget_Material_PopupMenu_Overflow = 16974456; // 0x1030278
+    field public static final int Widget_Material_PopupWindow = 16974457; // 0x1030279
+    field public static final int Widget_Material_ProgressBar = 16974458; // 0x103027a
+    field public static final int Widget_Material_ProgressBar_Horizontal = 16974459; // 0x103027b
+    field public static final int Widget_Material_ProgressBar_Large = 16974460; // 0x103027c
+    field public static final int Widget_Material_ProgressBar_Small = 16974461; // 0x103027d
+    field public static final int Widget_Material_ProgressBar_Small_Title = 16974462; // 0x103027e
+    field public static final int Widget_Material_RatingBar = 16974463; // 0x103027f
+    field public static final int Widget_Material_RatingBar_Indicator = 16974464; // 0x1030280
+    field public static final int Widget_Material_RatingBar_Small = 16974465; // 0x1030281
+    field public static final int Widget_Material_ScrollView = 16974466; // 0x1030282
+    field public static final int Widget_Material_SeekBar = 16974467; // 0x1030283
+    field public static final int Widget_Material_SegmentedButton = 16974468; // 0x1030284
+    field public static final int Widget_Material_Spinner = 16974470; // 0x1030286
+    field public static final int Widget_Material_StackView = 16974469; // 0x1030285
+    field public static final int Widget_Material_Tab = 16974471; // 0x1030287
+    field public static final int Widget_Material_TabWidget = 16974472; // 0x1030288
+    field public static final int Widget_Material_TextView = 16974473; // 0x1030289
+    field public static final int Widget_Material_TextView_SpinnerItem = 16974474; // 0x103028a
+    field public static final int Widget_Material_WebTextView = 16974475; // 0x103028b
+    field public static final int Widget_Material_WebView = 16974476; // 0x103028c
     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
@@ -2330,126 +2451,6 @@
     field public static final int Widget_ProgressBar_Large_Inverse = 16973916; // 0x103005c
     field public static final int Widget_ProgressBar_Small = 16973854; // 0x103001e
     field public static final int Widget_ProgressBar_Small_Inverse = 16973917; // 0x103005d
-    field public static final int Widget_Quantum = 16974417; // 0x1030251
-    field public static final int Widget_Quantum_ActionBar = 16974418; // 0x1030252
-    field public static final int Widget_Quantum_ActionBar_Solid = 16974419; // 0x1030253
-    field public static final int Widget_Quantum_ActionBar_TabBar = 16974420; // 0x1030254
-    field public static final int Widget_Quantum_ActionBar_TabText = 16974421; // 0x1030255
-    field public static final int Widget_Quantum_ActionBar_TabView = 16974422; // 0x1030256
-    field public static final int Widget_Quantum_ActionButton = 16974423; // 0x1030257
-    field public static final int Widget_Quantum_ActionButton_CloseMode = 16974424; // 0x1030258
-    field public static final int Widget_Quantum_ActionButton_Overflow = 16974425; // 0x1030259
-    field public static final int Widget_Quantum_ActionMode = 16974426; // 0x103025a
-    field public static final int Widget_Quantum_AutoCompleteTextView = 16974427; // 0x103025b
-    field public static final int Widget_Quantum_Button = 16974428; // 0x103025c
-    field public static final int Widget_Quantum_ButtonBar = 16974434; // 0x1030262
-    field public static final int Widget_Quantum_ButtonBar_AlertDialog = 16974435; // 0x1030263
-    field public static final int Widget_Quantum_Button_Borderless = 16974429; // 0x103025d
-    field public static final int Widget_Quantum_Button_Borderless_Small = 16974430; // 0x103025e
-    field public static final int Widget_Quantum_Button_Inset = 16974431; // 0x103025f
-    field public static final int Widget_Quantum_Button_Small = 16974432; // 0x1030260
-    field public static final int Widget_Quantum_Button_Toggle = 16974433; // 0x1030261
-    field public static final int Widget_Quantum_CalendarView = 16974436; // 0x1030264
-    field public static final int Widget_Quantum_CheckedTextView = 16974437; // 0x1030265
-    field public static final int Widget_Quantum_CompoundButton_CheckBox = 16974438; // 0x1030266
-    field public static final int Widget_Quantum_CompoundButton_RadioButton = 16974439; // 0x1030267
-    field public static final int Widget_Quantum_CompoundButton_Star = 16974440; // 0x1030268
-    field public static final int Widget_Quantum_DatePicker = 16974441; // 0x1030269
-    field public static final int Widget_Quantum_DropDownItem = 16974442; // 0x103026a
-    field public static final int Widget_Quantum_DropDownItem_Spinner = 16974443; // 0x103026b
-    field public static final int Widget_Quantum_EditText = 16974444; // 0x103026c
-    field public static final int Widget_Quantum_ExpandableListView = 16974445; // 0x103026d
-    field public static final int Widget_Quantum_FastScroll = 16974446; // 0x103026e
-    field public static final int Widget_Quantum_GridView = 16974447; // 0x103026f
-    field public static final int Widget_Quantum_HorizontalScrollView = 16974448; // 0x1030270
-    field public static final int Widget_Quantum_ImageButton = 16974449; // 0x1030271
-    field public static final int Widget_Quantum_Light = 16974476; // 0x103028c
-    field public static final int Widget_Quantum_Light_ActionBar = 16974477; // 0x103028d
-    field public static final int Widget_Quantum_Light_ActionBar_Solid = 16974478; // 0x103028e
-    field public static final int Widget_Quantum_Light_ActionBar_TabBar = 16974479; // 0x103028f
-    field public static final int Widget_Quantum_Light_ActionBar_TabText = 16974480; // 0x1030290
-    field public static final int Widget_Quantum_Light_ActionBar_TabView = 16974481; // 0x1030291
-    field public static final int Widget_Quantum_Light_ActionButton = 16974482; // 0x1030292
-    field public static final int Widget_Quantum_Light_ActionButton_CloseMode = 16974483; // 0x1030293
-    field public static final int Widget_Quantum_Light_ActionButton_Overflow = 16974484; // 0x1030294
-    field public static final int Widget_Quantum_Light_ActionMode = 16974485; // 0x1030295
-    field public static final int Widget_Quantum_Light_AutoCompleteTextView = 16974486; // 0x1030296
-    field public static final int Widget_Quantum_Light_Button = 16974487; // 0x1030297
-    field public static final int Widget_Quantum_Light_ButtonBar = 16974493; // 0x103029d
-    field public static final int Widget_Quantum_Light_ButtonBar_AlertDialog = 16974494; // 0x103029e
-    field public static final int Widget_Quantum_Light_Button_Borderless = 16974488; // 0x1030298
-    field public static final int Widget_Quantum_Light_Button_Borderless_Small = 16974489; // 0x1030299
-    field public static final int Widget_Quantum_Light_Button_Inset = 16974490; // 0x103029a
-    field public static final int Widget_Quantum_Light_Button_Small = 16974491; // 0x103029b
-    field public static final int Widget_Quantum_Light_Button_Toggle = 16974492; // 0x103029c
-    field public static final int Widget_Quantum_Light_CalendarView = 16974495; // 0x103029f
-    field public static final int Widget_Quantum_Light_CheckedTextView = 16974496; // 0x10302a0
-    field public static final int Widget_Quantum_Light_CompoundButton_CheckBox = 16974497; // 0x10302a1
-    field public static final int Widget_Quantum_Light_CompoundButton_RadioButton = 16974498; // 0x10302a2
-    field public static final int Widget_Quantum_Light_CompoundButton_Star = 16974499; // 0x10302a3
-    field public static final int Widget_Quantum_Light_DropDownItem = 16974500; // 0x10302a4
-    field public static final int Widget_Quantum_Light_DropDownItem_Spinner = 16974501; // 0x10302a5
-    field public static final int Widget_Quantum_Light_EditText = 16974502; // 0x10302a6
-    field public static final int Widget_Quantum_Light_ExpandableListView = 16974503; // 0x10302a7
-    field public static final int Widget_Quantum_Light_FastScroll = 16974504; // 0x10302a8
-    field public static final int Widget_Quantum_Light_GridView = 16974505; // 0x10302a9
-    field public static final int Widget_Quantum_Light_HorizontalScrollView = 16974506; // 0x10302aa
-    field public static final int Widget_Quantum_Light_ImageButton = 16974507; // 0x10302ab
-    field public static final int Widget_Quantum_Light_ListPopupWindow = 16974508; // 0x10302ac
-    field public static final int Widget_Quantum_Light_ListView = 16974509; // 0x10302ad
-    field public static final int Widget_Quantum_Light_ListView_DropDown = 16974510; // 0x10302ae
-    field public static final int Widget_Quantum_Light_MediaRouteButton = 16974511; // 0x10302af
-    field public static final int Widget_Quantum_Light_PopupMenu = 16974512; // 0x10302b0
-    field public static final int Widget_Quantum_Light_PopupMenu_Overflow = 16974513; // 0x10302b1
-    field public static final int Widget_Quantum_Light_PopupWindow = 16974514; // 0x10302b2
-    field public static final int Widget_Quantum_Light_ProgressBar = 16974515; // 0x10302b3
-    field public static final int Widget_Quantum_Light_ProgressBar_Horizontal = 16974516; // 0x10302b4
-    field public static final int Widget_Quantum_Light_ProgressBar_Inverse = 16974517; // 0x10302b5
-    field public static final int Widget_Quantum_Light_ProgressBar_Large = 16974518; // 0x10302b6
-    field public static final int Widget_Quantum_Light_ProgressBar_Large_Inverse = 16974519; // 0x10302b7
-    field public static final int Widget_Quantum_Light_ProgressBar_Small = 16974520; // 0x10302b8
-    field public static final int Widget_Quantum_Light_ProgressBar_Small_Inverse = 16974521; // 0x10302b9
-    field public static final int Widget_Quantum_Light_ProgressBar_Small_Title = 16974522; // 0x10302ba
-    field public static final int Widget_Quantum_Light_RatingBar = 16974523; // 0x10302bb
-    field public static final int Widget_Quantum_Light_RatingBar_Indicator = 16974524; // 0x10302bc
-    field public static final int Widget_Quantum_Light_RatingBar_Small = 16974525; // 0x10302bd
-    field public static final int Widget_Quantum_Light_ScrollView = 16974526; // 0x10302be
-    field public static final int Widget_Quantum_Light_SeekBar = 16974527; // 0x10302bf
-    field public static final int Widget_Quantum_Light_SegmentedButton = 16974528; // 0x10302c0
-    field public static final int Widget_Quantum_Light_Spinner = 16974530; // 0x10302c2
-    field public static final int Widget_Quantum_Light_StackView = 16974529; // 0x10302c1
-    field public static final int Widget_Quantum_Light_Tab = 16974531; // 0x10302c3
-    field public static final int Widget_Quantum_Light_TabWidget = 16974532; // 0x10302c4
-    field public static final int Widget_Quantum_Light_TextView = 16974533; // 0x10302c5
-    field public static final int Widget_Quantum_Light_TextView_SpinnerItem = 16974534; // 0x10302c6
-    field public static final int Widget_Quantum_Light_WebTextView = 16974535; // 0x10302c7
-    field public static final int Widget_Quantum_Light_WebView = 16974536; // 0x10302c8
-    field public static final int Widget_Quantum_ListPopupWindow = 16974450; // 0x1030272
-    field public static final int Widget_Quantum_ListView = 16974451; // 0x1030273
-    field public static final int Widget_Quantum_ListView_DropDown = 16974452; // 0x1030274
-    field public static final int Widget_Quantum_MediaRouteButton = 16974453; // 0x1030275
-    field public static final int Widget_Quantum_PopupMenu = 16974454; // 0x1030276
-    field public static final int Widget_Quantum_PopupMenu_Overflow = 16974455; // 0x1030277
-    field public static final int Widget_Quantum_PopupWindow = 16974456; // 0x1030278
-    field public static final int Widget_Quantum_ProgressBar = 16974457; // 0x1030279
-    field public static final int Widget_Quantum_ProgressBar_Horizontal = 16974458; // 0x103027a
-    field public static final int Widget_Quantum_ProgressBar_Large = 16974459; // 0x103027b
-    field public static final int Widget_Quantum_ProgressBar_Small = 16974460; // 0x103027c
-    field public static final int Widget_Quantum_ProgressBar_Small_Title = 16974461; // 0x103027d
-    field public static final int Widget_Quantum_RatingBar = 16974462; // 0x103027e
-    field public static final int Widget_Quantum_RatingBar_Indicator = 16974463; // 0x103027f
-    field public static final int Widget_Quantum_RatingBar_Small = 16974464; // 0x1030280
-    field public static final int Widget_Quantum_ScrollView = 16974465; // 0x1030281
-    field public static final int Widget_Quantum_SeekBar = 16974466; // 0x1030282
-    field public static final int Widget_Quantum_SegmentedButton = 16974467; // 0x1030283
-    field public static final int Widget_Quantum_Spinner = 16974469; // 0x1030285
-    field public static final int Widget_Quantum_StackView = 16974468; // 0x1030284
-    field public static final int Widget_Quantum_Tab = 16974470; // 0x1030286
-    field public static final int Widget_Quantum_TabWidget = 16974471; // 0x1030287
-    field public static final int Widget_Quantum_TextView = 16974472; // 0x1030288
-    field public static final int Widget_Quantum_TextView_SpinnerItem = 16974473; // 0x1030289
-    field public static final int Widget_Quantum_WebTextView = 16974474; // 0x103028a
-    field public static final int Widget_Quantum_WebView = 16974475; // 0x103028b
     field public static final int Widget_RatingBar = 16973857; // 0x1030021
     field public static final int Widget_ScrollView = 16973869; // 0x103002d
     field public static final int Widget_SeekBar = 16973856; // 0x1030020
@@ -5228,12 +5229,14 @@
     method public void setPasswordMinimumUpperCase(android.content.ComponentName, int);
     method public void setPasswordQuality(android.content.ComponentName, int);
     method public void setProfileEnabled(android.content.ComponentName);
+    method public void setRecommendedGlobalProxy(android.content.ComponentName, android.net.ProxyInfo);
     method public void setRestrictionsProvider(android.content.ComponentName, android.content.ComponentName);
     method public void setSecureSetting(android.content.ComponentName, java.lang.String, java.lang.String);
     method public int setStorageEncryption(android.content.ComponentName, boolean);
     method public void wipeData(int);
     field public static final java.lang.String ACTION_ADD_DEVICE_ADMIN = "android.app.action.ADD_DEVICE_ADMIN";
     field public static final java.lang.String ACTION_PROVISION_MANAGED_PROFILE = "android.app.action.ACTION_PROVISION_MANAGED_PROFILE";
+    field public static final java.lang.String ACTION_SEND_PROVISIONING_VALUES = "android.app.action.ACTION_SEND_PROVISIONING_VALUES";
     field public static final java.lang.String ACTION_SET_NEW_PASSWORD = "android.app.action.SET_NEW_PASSWORD";
     field public static final java.lang.String ACTION_START_ENCRYPTION = "android.app.action.START_ENCRYPTION";
     field public static final int ENCRYPTION_STATUS_ACTIVATING = 2; // 0x2
@@ -5244,6 +5247,7 @@
     field public static final java.lang.String EXTRA_DEVICE_ADMIN = "android.app.extra.DEVICE_ADMIN";
     field public static final java.lang.String EXTRA_PROVISIONING_DEFAULT_MANAGED_PROFILE_NAME = "defaultManagedProfileName";
     field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME = "deviceAdminPackageName";
+    field public static final java.lang.String EXTRA_PROVISIONING_EMAIL_ADDRESS = "android.app.extra.ManagedProfileEmailAddress";
     field public static final java.lang.String EXTRA_PROVISIONING_TOKEN = "android.app.extra.token";
     field public static int FLAG_MANAGED_CAN_ACCESS_PARENT;
     field public static int FLAG_PARENT_CAN_ACCESS_MANAGED;
@@ -5368,7 +5372,7 @@
   public class Task implements android.os.Parcelable {
     method public int describeContents();
     method public int getBackoffPolicy();
-    method public android.os.Bundle getExtras();
+    method public android.os.PersistableBundle getExtras();
     method public int getId();
     method public long getInitialBackoffMillis();
     method public long getIntervalMillis();
@@ -5392,7 +5396,7 @@
     ctor public Task.Builder(int, android.content.ComponentName);
     method public android.app.task.Task build();
     method public android.app.task.Task.Builder setBackoffCriteria(long, int);
-    method public android.app.task.Task.Builder setExtras(android.os.Bundle);
+    method public android.app.task.Task.Builder setExtras(android.os.PersistableBundle);
     method public android.app.task.Task.Builder setMinimumLatency(long);
     method public android.app.task.Task.Builder setOverrideDeadline(long);
     method public android.app.task.Task.Builder setPeriodic(long);
@@ -5419,7 +5423,7 @@
 
   public class TaskParams implements android.os.Parcelable {
     method public int describeContents();
-    method public android.os.Bundle getExtras();
+    method public android.os.PersistableBundle getExtras();
     method public int getTaskId();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator CREATOR;
@@ -6757,7 +6761,6 @@
     method public final android.os.Bundle call(android.net.Uri, java.lang.String, java.lang.String, android.os.Bundle);
     method public deprecated void cancelSync(android.net.Uri);
     method public static void cancelSync(android.accounts.Account, java.lang.String);
-    method public static void cancelSync(android.content.ComponentName);
     method public static void cancelSync(android.content.SyncRequest);
     method public final android.net.Uri canonicalize(android.net.Uri);
     method public final int delete(android.net.Uri, java.lang.String, java.lang.String[]);
@@ -6767,18 +6770,14 @@
     method public static boolean getMasterSyncAutomatically();
     method public java.util.List<android.content.UriPermission> getOutgoingPersistedUriPermissions();
     method public static java.util.List<android.content.PeriodicSync> getPeriodicSyncs(android.accounts.Account, java.lang.String);
-    method public static java.util.List<android.content.PeriodicSync> getPeriodicSyncs(android.content.ComponentName);
     method public java.util.List<android.content.UriPermission> getPersistedUriPermissions();
     method public java.lang.String[] getStreamTypes(android.net.Uri, java.lang.String);
     method public static android.content.SyncAdapterType[] getSyncAdapterTypes();
     method public static boolean getSyncAutomatically(android.accounts.Account, java.lang.String);
     method public final java.lang.String getType(android.net.Uri);
     method public final android.net.Uri insert(android.net.Uri, android.content.ContentValues);
-    method public static boolean isServiceActive(android.content.ComponentName);
     method public static boolean isSyncActive(android.accounts.Account, java.lang.String);
-    method public static boolean isSyncActive(android.content.ComponentName);
     method public static boolean isSyncPending(android.accounts.Account, java.lang.String);
-    method public static boolean isSyncPending(android.content.ComponentName);
     method public void notifyChange(android.net.Uri, android.database.ContentObserver);
     method public void notifyChange(android.net.Uri, android.database.ContentObserver, boolean);
     method public final android.content.res.AssetFileDescriptor openAssetFileDescriptor(android.net.Uri, java.lang.String) throws java.io.FileNotFoundException;
@@ -6800,7 +6799,6 @@
     method public static void requestSync(android.content.SyncRequest);
     method public static void setIsSyncable(android.accounts.Account, java.lang.String, int);
     method public static void setMasterSyncAutomatically(boolean);
-    method public static void setServiceActive(android.content.ComponentName, boolean);
     method public static void setSyncAutomatically(android.accounts.Account, java.lang.String, boolean);
     method public deprecated void startSync(android.net.Uri, android.os.Bundle);
     method public void takePersistableUriPermission(android.net.Uri, int);
@@ -7769,9 +7767,7 @@
     field public final android.accounts.Account account;
     field public final java.lang.String authority;
     field public final android.os.Bundle extras;
-    field public final boolean isService;
     field public final long period;
-    field public final android.content.ComponentName service;
   }
 
   public class ReceiverCallNotAllowedException extends android.util.AndroidRuntimeException {
@@ -7916,7 +7912,6 @@
     method public void writeToParcel(android.os.Parcel, int);
     field public final android.accounts.Account account;
     field public final java.lang.String authority;
-    field public final android.content.ComponentName service;
     field public final long startTime;
   }
 
@@ -7939,8 +7934,6 @@
     method public android.content.SyncRequest.Builder setNoRetry(boolean);
     method public android.content.SyncRequest.Builder setPriority(int);
     method public android.content.SyncRequest.Builder setSyncAdapter(android.accounts.Account, java.lang.String);
-    method public android.content.SyncRequest.Builder setSyncAdapter(android.content.ComponentName);
-    method public android.content.SyncRequest.Builder setTransferSize(long, long);
     method public android.content.SyncRequest.Builder syncOnce();
     method public android.content.SyncRequest.Builder syncPeriodic(long, long);
   }
@@ -7968,13 +7961,6 @@
     field public boolean tooManyRetries;
   }
 
-  public abstract class SyncService extends android.app.Service {
-    ctor public SyncService();
-    method public android.os.IBinder onBind(android.content.Intent);
-    method public abstract void onPerformSync(android.os.Bundle, android.content.SyncResult);
-    method protected boolean parallelSyncsEnabled();
-  }
-
   public class SyncStats implements android.os.Parcelable {
     ctor public SyncStats();
     ctor public SyncStats(android.os.Parcel);
@@ -8421,7 +8407,7 @@
     field public static final java.lang.String FEATURE_LOCATION = "android.hardware.location";
     field public static final java.lang.String FEATURE_LOCATION_GPS = "android.hardware.location.gps";
     field public static final java.lang.String FEATURE_LOCATION_NETWORK = "android.hardware.location.network";
-    field public static final java.lang.String FEATURE_MANAGEDPROFILES = "android.software.managedprofiles";
+    field public static final java.lang.String FEATURE_MANAGED_PROFILES = "android.software.managed_profiles";
     field public static final java.lang.String FEATURE_MICROPHONE = "android.hardware.microphone";
     field public static final java.lang.String FEATURE_NFC = "android.hardware.nfc";
     field public static final java.lang.String FEATURE_NFC_HOST_CARD_EMULATION = "android.hardware.nfc.hce";
@@ -10127,13 +10113,13 @@
     field public android.graphics.Bitmap inBitmap;
     field public int inDensity;
     field public boolean inDither;
-    field public boolean inInputShareable;
+    field public deprecated boolean inInputShareable;
     field public boolean inJustDecodeBounds;
     field public boolean inMutable;
     field public boolean inPreferQualityOverSpeed;
     field public android.graphics.Bitmap.Config inPreferredConfig;
     field public boolean inPremultiplied;
-    field public boolean inPurgeable;
+    field public deprecated boolean inPurgeable;
     field public int inSampleSize;
     field public boolean inScaled;
     field public int inScreenDensity;
@@ -12203,12 +12189,12 @@
 
   public static abstract class CameraCaptureSession.CaptureListener {
     ctor public CameraCaptureSession.CaptureListener();
-    method public void onCaptureCompleted(android.hardware.camera2.CameraDevice, android.hardware.camera2.CaptureRequest, android.hardware.camera2.TotalCaptureResult);
-    method public void onCaptureFailed(android.hardware.camera2.CameraDevice, android.hardware.camera2.CaptureRequest, android.hardware.camera2.CaptureFailure);
-    method public void onCaptureProgressed(android.hardware.camera2.CameraDevice, android.hardware.camera2.CaptureRequest, android.hardware.camera2.CaptureResult);
-    method public void onCaptureSequenceAborted(android.hardware.camera2.CameraDevice, int);
-    method public void onCaptureSequenceCompleted(android.hardware.camera2.CameraDevice, int, long);
-    method public void onCaptureStarted(android.hardware.camera2.CameraDevice, android.hardware.camera2.CaptureRequest, long);
+    method public void onCaptureCompleted(android.hardware.camera2.CameraCaptureSession, android.hardware.camera2.CaptureRequest, android.hardware.camera2.TotalCaptureResult);
+    method public void onCaptureFailed(android.hardware.camera2.CameraCaptureSession, android.hardware.camera2.CaptureRequest, android.hardware.camera2.CaptureFailure);
+    method public void onCaptureProgressed(android.hardware.camera2.CameraCaptureSession, android.hardware.camera2.CaptureRequest, android.hardware.camera2.CaptureResult);
+    method public void onCaptureSequenceAborted(android.hardware.camera2.CameraCaptureSession, int);
+    method public void onCaptureSequenceCompleted(android.hardware.camera2.CameraCaptureSession, int, long);
+    method public void onCaptureStarted(android.hardware.camera2.CameraCaptureSession, android.hardware.camera2.CaptureRequest, long);
   }
 
   public static abstract class CameraCaptureSession.StateListener {
@@ -12252,7 +12238,6 @@
     field public static final android.hardware.camera2.CameraCharacteristics.Key LENS_INFO_MINIMUM_FOCUS_DISTANCE;
     field public static final android.hardware.camera2.CameraCharacteristics.Key NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES;
     field public static final android.hardware.camera2.CameraCharacteristics.Key REQUEST_AVAILABLE_CAPABILITIES;
-    field public static final android.hardware.camera2.CameraCharacteristics.Key REQUEST_MAX_NUM_INPUT_STREAMS;
     field public static final android.hardware.camera2.CameraCharacteristics.Key REQUEST_MAX_NUM_OUTPUT_PROC;
     field public static final android.hardware.camera2.CameraCharacteristics.Key REQUEST_MAX_NUM_OUTPUT_PROC_STALLING;
     field public static final android.hardware.camera2.CameraCharacteristics.Key REQUEST_MAX_NUM_OUTPUT_RAW;
@@ -12295,7 +12280,7 @@
     method public final int hashCode();
   }
 
-  public abstract interface CameraDevice implements java.lang.AutoCloseable {
+  public abstract class CameraDevice implements java.lang.AutoCloseable {
     method public abstract deprecated int capture(android.hardware.camera2.CaptureRequest, android.hardware.camera2.CameraDevice.CaptureListener, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
     method public abstract deprecated int captureBurst(java.util.List<android.hardware.camera2.CaptureRequest>, android.hardware.camera2.CameraDevice.CaptureListener, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
     method public abstract void close();
@@ -12477,7 +12462,6 @@
     field public static final int REQUEST_AVAILABLE_CAPABILITIES_DNG = 5; // 0x5
     field public static final int REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING = 3; // 0x3
     field public static final int REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR = 2; // 0x2
-    field public static final int REQUEST_AVAILABLE_CAPABILITIES_ZSL = 4; // 0x4
     field public static final int SCALER_CROPPING_TYPE_CENTER_ONLY = 0; // 0x0
     field public static final int SCALER_CROPPING_TYPE_FREEFORM = 1; // 0x1
     field public static final int SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_BGGR = 3; // 0x3
@@ -12688,14 +12672,7 @@
   public final class DngCreator implements java.lang.AutoCloseable {
     ctor public DngCreator(android.hardware.camera2.CameraCharacteristics, android.hardware.camera2.CaptureResult);
     method public void close();
-    method public android.hardware.camera2.DngCreator setDescription(java.lang.String);
-    method public android.hardware.camera2.DngCreator setLocation(android.location.Location);
-    method public android.hardware.camera2.DngCreator setOrientation(int);
-    method public android.hardware.camera2.DngCreator setThumbnail(android.graphics.Bitmap);
-    method public android.hardware.camera2.DngCreator setThumbnail(android.media.Image);
-    method public void writeByteBuffer(java.io.OutputStream, android.util.Size, java.nio.ByteBuffer, long) throws java.io.IOException;
     method public void writeImage(java.io.OutputStream, android.media.Image) throws java.io.IOException;
-    method public void writeInputStream(java.io.OutputStream, android.util.Size, java.io.InputStream, long) throws java.io.IOException;
   }
 
   public final class TotalCaptureResult extends android.hardware.camera2.CaptureResult {
@@ -12783,6 +12760,7 @@
   }
 
   public final class TonemapCurve {
+    ctor public TonemapCurve(float[], float[], float[]);
     method public void copyColorCurve(int, float[], int);
     method public android.graphics.PointF getPoint(int, int);
     method public int getPointCount(int);
@@ -13801,11 +13779,12 @@
     method public void stop();
   }
 
-  public final class AudioAttributes {
+  public final class AudioAttributes implements android.os.Parcelable {
+    method public int describeContents();
     method public int getContentType();
     method public int getFlags();
-    method public java.util.Set<java.lang.String> getTags();
     method public int getUsage();
+    method public void writeToParcel(android.os.Parcel, int);
     field public static final int CONTENT_TYPE_MOVIE = 3; // 0x3
     field public static final int CONTENT_TYPE_MUSIC = 2; // 0x2
     field public static final int CONTENT_TYPE_SONIFICATION = 4; // 0x4
@@ -13832,7 +13811,6 @@
   public static class AudioAttributes.Builder {
     ctor public AudioAttributes.Builder();
     ctor public AudioAttributes.Builder(android.media.AudioAttributes);
-    method public android.media.AudioAttributes.Builder addTag(java.lang.String);
     method public android.media.AudioAttributes build();
     method public android.media.AudioAttributes.Builder setContentType(int);
     method public android.media.AudioAttributes.Builder setFlags(int);
@@ -15975,6 +15953,8 @@
 package android.media.tv {
 
   public final class TvContract {
+    method public static final android.net.Uri buildChannelLogoUri(long);
+    method public static final android.net.Uri buildChannelLogoUri(android.net.Uri);
     method public static final android.net.Uri buildChannelUri(long);
     method public static final android.net.Uri buildChannelsUriForInput(android.content.ComponentName);
     method public static final android.net.Uri buildChannelsUriForInput(android.content.ComponentName, boolean);
@@ -16032,6 +16012,10 @@
     field public static final int TYPE_T_DMB = 393216; // 0x60000
   }
 
+  public static final class TvContract.Channels.Logo {
+    field public static final java.lang.String CONTENT_DIRECTORY = "logo";
+  }
+
   public static final class TvContract.Programs implements android.media.tv.TvContract.BaseTvColumns {
     field public static final java.lang.String COLUMN_AUDIO_LANGUAGE = "audio_language";
     field public static final java.lang.String COLUMN_BROADCAST_GENRE = "broadcast_genre";
@@ -16040,8 +16024,10 @@
     field public static final java.lang.String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis";
     field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
     field public static final java.lang.String COLUMN_LONG_DESCRIPTION = "long_description";
+    field public static final java.lang.String COLUMN_POSTER_ART_URI = "poster_art_uri";
     field public static final java.lang.String COLUMN_SHORT_DESCRIPTION = "short_description";
     field public static final java.lang.String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis";
+    field public static final java.lang.String COLUMN_THUMBNAIL_URI = "thumbnail_uri";
     field public static final java.lang.String COLUMN_TITLE = "title";
     field public static final java.lang.String COLUMN_VERSION_NUMBER = "version_number";
     field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/program";
@@ -16067,35 +16053,18 @@
 
   public final class TvInputInfo implements android.os.Parcelable {
     method public int describeContents();
-    method public android.content.ComponentName getComponent();
     method public java.lang.String getId();
     method public android.content.Intent getIntentForSettingsActivity();
     method public android.content.Intent getIntentForSetupActivity();
-    method public java.lang.String getPackageName();
-    method public java.lang.String getServiceName();
+    method public android.content.pm.ServiceInfo getServiceInfo();
     method public java.lang.CharSequence loadLabel(android.content.pm.PackageManager);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final java.lang.String EXTRA_SERVICE_NAME = "serviceName";
   }
 
   public final class TvInputManager {
-    method public void createSession(java.lang.String, android.media.tv.TvInputManager.SessionCallback, android.os.Handler);
     method public boolean getAvailability(java.lang.String);
     method public java.util.List<android.media.tv.TvInputInfo> getTvInputList();
-    method public void registerListener(java.lang.String, android.media.tv.TvInputManager.TvInputListener, android.os.Handler);
-    method public void unregisterListener(java.lang.String, android.media.tv.TvInputManager.TvInputListener);
-  }
-
-  public static final class TvInputManager.Session {
-    method public void release();
-    method public void setVolume(float);
-    method public void tune(android.net.Uri);
-  }
-
-  public static abstract class TvInputManager.SessionCallback {
-    ctor public TvInputManager.SessionCallback();
-    method public void onSessionCreated(android.media.tv.TvInputManager.Session);
-    method public void onSessionReleased(android.media.tv.TvInputManager.Session);
   }
 
   public static abstract class TvInputManager.TvInputListener {
@@ -16106,14 +16075,13 @@
   public abstract class TvInputService extends android.app.Service {
     ctor public TvInputService();
     method public final android.os.IBinder onBind(android.content.Intent);
-    method public abstract android.media.tv.TvInputService.TvInputSessionImpl onCreateSession();
-    method public final void setAvailable(boolean);
+    method public abstract android.media.tv.TvInputService.Session onCreateSession();
     field public static final java.lang.String SERVICE_INTERFACE = "android.media.tv.TvInputService";
     field public static final java.lang.String SERVICE_META_DATA = "android.media.tv.input";
   }
 
-  public abstract class TvInputService.TvInputSessionImpl implements android.view.KeyEvent.Callback {
-    ctor public TvInputService.TvInputSessionImpl();
+  public abstract class TvInputService.Session implements android.view.KeyEvent.Callback {
+    ctor public TvInputService.Session();
     method public android.view.View onCreateOverlayView();
     method public boolean onGenericMotionEvent(android.view.MotionEvent);
     method public boolean onKeyDown(int, android.view.KeyEvent);
@@ -16121,8 +16089,8 @@
     method public boolean onKeyMultiple(int, int, android.view.KeyEvent);
     method public boolean onKeyUp(int, android.view.KeyEvent);
     method public abstract void onRelease();
+    method public abstract void onSetStreamVolume(float);
     method public abstract boolean onSetSurface(android.view.Surface);
-    method public abstract void onSetVolume(float);
     method public boolean onTouchEvent(android.view.MotionEvent);
     method public boolean onTrackballEvent(android.view.MotionEvent);
     method public abstract boolean onTune(android.net.Uri);
@@ -16133,17 +16101,26 @@
     ctor public TvView(android.content.Context);
     ctor public TvView(android.content.Context, android.util.AttributeSet);
     ctor public TvView(android.content.Context, android.util.AttributeSet, int);
-    method public void bindTvInput(java.lang.String, android.media.tv.TvInputManager.SessionCallback);
     method public boolean dispatchUnhandledInputEvent(android.view.InputEvent);
     method public boolean onUnhandledInputEvent(android.view.InputEvent);
+    method public void reset();
     method public void setOnUnhandledInputEventListener(android.media.tv.TvView.OnUnhandledInputEventListener);
-    method public void unbindTvInput();
+    method public void setStreamVolume(float);
+    method public void setTvInputListener(android.media.tv.TvView.TvInputListener);
+    method public void tune(java.lang.String, android.net.Uri);
+    field public static final int ERROR_BUSY = 0; // 0x0
+    field public static final int ERROR_TV_INPUT_DISCONNECTED = 1; // 0x1
   }
 
   public static abstract interface TvView.OnUnhandledInputEventListener {
     method public abstract boolean onUnhandledInputEvent(android.view.InputEvent);
   }
 
+  public static abstract class TvView.TvInputListener {
+    ctor public TvView.TvInputListener();
+    method public void onError(java.lang.String, int);
+  }
+
 }
 
 package android.mtp {
@@ -21497,12 +21474,14 @@
   public final class PowerManager {
     method public void goToSleep(long);
     method public boolean isInteractive();
+    method public boolean isPowerSaveMode();
     method public deprecated boolean isScreenOn();
     method public android.os.PowerManager.WakeLock newWakeLock(int, java.lang.String);
     method public void reboot(java.lang.String);
     method public void userActivity(long, boolean);
     method public void wakeUp(long);
     field public static final int ACQUIRE_CAUSES_WAKEUP = 268435456; // 0x10000000
+    field public static final java.lang.String ACTION_POWER_SAVE_MODE_CHANGED = "android.os.action.POWER_SAVE_MODE_CHANGED";
     field public static final deprecated int FULL_WAKE_LOCK = 26; // 0x1a
     field public static final int ON_AFTER_RELEASE = 536870912; // 0x20000000
     field public static final int PARTIAL_WAKE_LOCK = 1; // 0x1
@@ -22522,6 +22501,7 @@
     method protected void onDisconnected();
     method protected abstract void onPrintJobQueued(android.printservice.PrintJob);
     method protected abstract void onRequestCancelPrintJob(android.printservice.PrintJob);
+    field public static final java.lang.String EXTRA_PRINTER_INFO = "android.intent.extra.print.PRINTER_INFO";
     field public static final java.lang.String EXTRA_PRINT_JOB_INFO = "android.intent.extra.print.PRINT_JOB_INFO";
     field public static final java.lang.String SERVICE_INTERFACE = "android.printservice.PrintService";
     field public static final java.lang.String SERVICE_META_DATA = "android.printservice";
@@ -23036,16 +23016,6 @@
     field public static final deprecated android.net.Uri DELETED_CONTENT_URI;
     field public static final deprecated java.lang.String GROUP_ANDROID_STARRED = "Starred in Android";
     field public static final deprecated java.lang.String GROUP_MY_CONTACTS = "Contacts";
-    field public static final java.lang.String NON_SYNCABLE_ACCOUNT = "non_syncable";
-    field public static final java.lang.String NON_SYNCABLE_ACCOUNT_TYPE = "android.local";
-    field public static final java.lang.String _SYNC_ACCOUNT = "_sync_account";
-    field public static final java.lang.String _SYNC_ACCOUNT_TYPE = "_sync_account_type";
-    field public static final java.lang.String _SYNC_DIRTY = "_sync_dirty";
-    field public static final java.lang.String _SYNC_ID = "_sync_id";
-    field public static final java.lang.String _SYNC_LOCAL_ID = "_sync_local_id";
-    field public static final java.lang.String _SYNC_MARK = "_sync_mark";
-    field public static final java.lang.String _SYNC_TIME = "_sync_time";
-    field public static final java.lang.String _SYNC_VERSION = "_sync_version";
   }
 
   public static abstract deprecated interface Contacts.GroupsColumns {
@@ -23147,19 +23117,9 @@
     field public static final deprecated android.net.Uri CONTENT_URI;
     field public static final deprecated java.lang.String DEFAULT_SORT_ORDER = "name ASC";
     field public static final deprecated android.net.Uri DELETED_CONTENT_URI;
-    field public static final java.lang.String NON_SYNCABLE_ACCOUNT = "non_syncable";
-    field public static final java.lang.String NON_SYNCABLE_ACCOUNT_TYPE = "android.local";
     field public static final deprecated java.lang.String PRIMARY_EMAIL_ID = "primary_email";
     field public static final deprecated java.lang.String PRIMARY_ORGANIZATION_ID = "primary_organization";
     field public static final deprecated java.lang.String PRIMARY_PHONE_ID = "primary_phone";
-    field public static final java.lang.String _SYNC_ACCOUNT = "_sync_account";
-    field public static final java.lang.String _SYNC_ACCOUNT_TYPE = "_sync_account_type";
-    field public static final java.lang.String _SYNC_DIRTY = "_sync_dirty";
-    field public static final java.lang.String _SYNC_ID = "_sync_id";
-    field public static final java.lang.String _SYNC_LOCAL_ID = "_sync_local_id";
-    field public static final java.lang.String _SYNC_MARK = "_sync_mark";
-    field public static final java.lang.String _SYNC_TIME = "_sync_time";
-    field public static final java.lang.String _SYNC_VERSION = "_sync_version";
   }
 
   public static final deprecated class Contacts.People.ContactMethods implements android.provider.BaseColumns android.provider.Contacts.ContactMethodsColumns android.provider.Contacts.PeopleColumns {
@@ -23222,16 +23182,6 @@
     field public static final deprecated java.lang.String CONTENT_DIRECTORY = "photo";
     field public static final deprecated android.net.Uri CONTENT_URI;
     field public static final deprecated java.lang.String DEFAULT_SORT_ORDER = "person ASC";
-    field public static final java.lang.String NON_SYNCABLE_ACCOUNT = "non_syncable";
-    field public static final java.lang.String NON_SYNCABLE_ACCOUNT_TYPE = "android.local";
-    field public static final java.lang.String _SYNC_ACCOUNT = "_sync_account";
-    field public static final java.lang.String _SYNC_ACCOUNT_TYPE = "_sync_account_type";
-    field public static final java.lang.String _SYNC_DIRTY = "_sync_dirty";
-    field public static final java.lang.String _SYNC_ID = "_sync_id";
-    field public static final java.lang.String _SYNC_LOCAL_ID = "_sync_local_id";
-    field public static final java.lang.String _SYNC_MARK = "_sync_mark";
-    field public static final java.lang.String _SYNC_TIME = "_sync_time";
-    field public static final java.lang.String _SYNC_VERSION = "_sync_version";
   }
 
   public static abstract deprecated interface Contacts.PhotosColumns {
@@ -23559,7 +23509,6 @@
   protected static abstract interface ContactsContract.ContactOptionsColumns {
     field public static final java.lang.String CUSTOM_RINGTONE = "custom_ringtone";
     field public static final java.lang.String LAST_TIME_CONTACTED = "last_time_contacted";
-    field public static final java.lang.String PINNED = "pinned";
     field public static final java.lang.String SEND_TO_VOICEMAIL = "send_to_voicemail";
     field public static final java.lang.String STARRED = "starred";
     field public static final java.lang.String TIMES_CONTACTED = "times_contacted";
@@ -23837,15 +23786,6 @@
     field public static final int UNDEFINED = 0; // 0x0
   }
 
-  public static final class ContactsContract.PinnedPositions {
-    ctor public ContactsContract.PinnedPositions();
-    field public static final int DEMOTED = -1; // 0xffffffff
-    field public static final java.lang.String STAR_WHEN_PINNING = "star_when_pinning";
-    field public static final java.lang.String UNDEMOTE = "undemote";
-    field public static final int UNPINNED = 2147483647; // 0x7fffffff
-    field public static final android.net.Uri UPDATE_URI;
-  }
-
   public static final class ContactsContract.Preferences {
     ctor public ContactsContract.Preferences();
     field public static final java.lang.String DISPLAY_ORDER = "android.contacts.DISPLAY_ORDER";
@@ -24328,7 +24268,6 @@
   }
 
   public static final class MediaStore.Audio.Radio {
-    ctor public MediaStore.Audio.Radio();
     field public static final java.lang.String ENTRY_CONTENT_TYPE = "vnd.android.cursor.item/radio";
   }
 
@@ -25711,7 +25650,7 @@
     method public void contextDump();
     method public static android.renderscript.RenderScript create(android.content.Context);
     method public static android.renderscript.RenderScript create(android.content.Context, android.renderscript.RenderScript.ContextType);
-    method public static android.renderscript.RenderScript create(android.content.Context, android.renderscript.RenderScript.ContextType, long);
+    method public static android.renderscript.RenderScript create(android.content.Context, android.renderscript.RenderScript.ContextType, int);
     method public void destroy();
     method public void finish();
     method public final android.content.Context getApplicationContext();
@@ -25721,9 +25660,9 @@
     method public void setErrorHandler(android.renderscript.RenderScript.RSErrorHandler);
     method public void setMessageHandler(android.renderscript.RenderScript.RSMessageHandler);
     method public void setPriority(android.renderscript.RenderScript.Priority);
-    field public static final long CREATE_FLAG_LOW_LATENCY = 2L; // 0x2L
-    field public static final long CREATE_FLAG_LOW_POWER = 4L; // 0x4L
-    field public static final long CREATE_FLAG_NONE = 0L; // 0x0L
+    field public static final int CREATE_FLAG_LOW_LATENCY = 2; // 0x2
+    field public static final int CREATE_FLAG_LOW_POWER = 4; // 0x4
+    field public static final int CREATE_FLAG_NONE = 0; // 0x0
   }
 
   public static final class RenderScript.ContextType extends java.lang.Enum {
@@ -27653,6 +27592,8 @@
     method protected void onAdapterAttached(android.telecomm.CallServiceAdapter);
     method public abstract void onAudioStateChanged(java.lang.String, android.telecomm.CallAudioState);
     method public final android.os.IBinder onBind(android.content.Intent);
+    method public void onPostDialContinue(java.lang.String, boolean);
+    method public void onPostDialWait(android.telecomm.Connection, java.lang.String);
     method public abstract void playDtmfTone(java.lang.String, char);
     method public abstract void reject(java.lang.String);
     method public abstract void setIncomingCallId(java.lang.String, android.os.Bundle);
@@ -27661,9 +27602,10 @@
   }
 
   public final class CallServiceAdapter {
-    method public void handleFailedOutgoingCall(java.lang.String, java.lang.String);
+    method public void handleFailedOutgoingCall(android.telecomm.ConnectionRequest, int, java.lang.String);
     method public void handleSuccessfulOutgoingCall(java.lang.String);
     method public void notifyIncomingCall(android.telecomm.CallInfo);
+    method public void onPostDialWait(java.lang.String, java.lang.String);
     method public void setActive(java.lang.String);
     method public void setDialing(java.lang.String);
     method public void setDisconnected(java.lang.String, int, java.lang.String);
@@ -27741,6 +27683,7 @@
     method protected void onDisconnect();
     method protected void onHold();
     method protected void onPlayDtmfTone(char);
+    method protected void onPostDialContinue(boolean);
     method protected void onReject();
     method protected void onSetAudioState(android.telecomm.CallAudioState);
     method protected void onSetSignal(android.os.Bundle);
@@ -27788,10 +27731,15 @@
     field public static final int RINGING = 1; // 0x1
   }
 
-  public final class ConnectionRequest {
+  public final class ConnectionRequest implements android.os.Parcelable {
     ctor public ConnectionRequest(android.net.Uri, android.os.Bundle);
+    ctor public ConnectionRequest(java.lang.String, android.net.Uri, android.os.Bundle);
+    method public int describeContents();
+    method public java.lang.String getCallId();
     method public android.os.Bundle getExtras();
     method public android.net.Uri getHandle();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
   }
 
   public abstract class ConnectionService extends android.telecomm.CallService {
@@ -27806,6 +27754,8 @@
     method public void onCreateConnections(android.telecomm.ConnectionRequest, android.telecomm.Response<android.telecomm.ConnectionRequest, android.telecomm.Connection>);
     method public void onCreateIncomingConnection(android.telecomm.ConnectionRequest, android.telecomm.Response<android.telecomm.ConnectionRequest, android.telecomm.Connection>);
     method public void onFindSubscriptions(android.net.Uri, android.telecomm.Response<android.net.Uri, android.telecomm.Subscription>);
+    method public final void onPostDialContinue(java.lang.String, boolean);
+    method public final void onPostDialWait(android.telecomm.Connection, java.lang.String);
     method public final void playDtmfTone(java.lang.String, char);
     method public final void reject(java.lang.String);
     method public final void setIncomingCallId(java.lang.String, android.os.Bundle);
@@ -27830,7 +27780,7 @@
     method public void holdCall(java.lang.String);
     method public void mute(boolean);
     method public void playDtmfTone(java.lang.String, char);
-    method public void postDialContinue(java.lang.String);
+    method public void postDialContinue(java.lang.String, boolean);
     method public void rejectCall(java.lang.String);
     method public void setAudioRoute(int);
     method public void stopDtmfTone(java.lang.String);
@@ -27842,7 +27792,8 @@
     method public int getCapabilities();
     method public long getConnectTimeMillis();
     method public android.telecomm.CallServiceDescriptor getCurrentCallServiceDescriptor();
-    method public int getDisconnectCause();
+    method public int getDisconnectCauseCode();
+    method public java.lang.String getDisconnectCauseMsg();
     method public android.telecomm.GatewayInfo getGatewayInfo();
     method public android.net.Uri getHandle();
     method public android.telecomm.CallServiceDescriptor getHandoffCallServiceDescriptor();
@@ -27866,7 +27817,7 @@
   }
 
   public abstract interface Response {
-    method public abstract void onError(IN, java.lang.String);
+    method public abstract void onError(IN, int, java.lang.String);
     method public abstract void onResult(IN, OUT...);
   }
 
@@ -28047,6 +27998,7 @@
     field public static final int CALL_BARRED = 20; // 0x14
     field public static final int CDMA_ACCESS_BLOCKED = 35; // 0x23
     field public static final int CDMA_ACCESS_FAILURE = 32; // 0x20
+    field public static final int CDMA_CALL_LOST = 41; // 0x29
     field public static final int CDMA_DROP = 27; // 0x1b
     field public static final int CDMA_INTERCEPT = 28; // 0x1c
     field public static final int CDMA_LOCKED_UNTIL_POWER_CYCLE = 26; // 0x1a
@@ -28059,6 +28011,8 @@
     field public static final int CS_RESTRICTED = 22; // 0x16
     field public static final int CS_RESTRICTED_EMERGENCY = 24; // 0x18
     field public static final int CS_RESTRICTED_NORMAL = 23; // 0x17
+    field public static final int DIALED_MMI = 39; // 0x27
+    field public static final int EMERGENCY_ONLY = 37; // 0x25
     field public static final int ERROR_UNSPECIFIED = 36; // 0x24
     field public static final int FDN_BLOCKED = 21; // 0x15
     field public static final int ICC_ERROR = 19; // 0x13
@@ -28069,12 +28023,13 @@
     field public static final int LIMIT_EXCEEDED = 15; // 0xf
     field public static final int LOCAL = 3; // 0x3
     field public static final int LOST_SIGNAL = 14; // 0xe
-    field public static final int MAXIMUM_VALID_VALUE = 36; // 0x24
+    field public static final int MAXIMUM_VALID_VALUE = 42; // 0x2a
     field public static final int MINIMUM_VALID_VALUE = 0; // 0x0
     field public static final int MMI = 6; // 0x6
     field public static final int NORMAL = 2; // 0x2
     field public static final int NOT_DISCONNECTED = 0; // 0x0
     field public static final int NOT_VALID = -1; // 0xffffffff
+    field public static final int NO_PHONE_NUMBER_SUPPLIED = 38; // 0x26
     field public static final int NUMBER_UNREACHABLE = 8; // 0x8
     field public static final int OUT_OF_NETWORK = 11; // 0xb
     field public static final int OUT_OF_SERVICE = 18; // 0x12
@@ -28083,6 +28038,7 @@
     field public static final int SERVER_UNREACHABLE = 9; // 0x9
     field public static final int TIMED_OUT = 13; // 0xd
     field public static final int UNOBTAINABLE_NUMBER = 25; // 0x19
+    field public static final int VOICEMAIL_NUMBER_MISSING = 40; // 0x28
   }
 
   public class NeighboringCellInfo implements android.os.Parcelable {
@@ -28136,7 +28092,7 @@
     method public static boolean isEmergencyNumber(java.lang.String);
     method public static boolean isGlobalPhoneNumber(java.lang.String);
     method public static boolean isISODigit(char);
-    method public static boolean isLocalEmergencyNumber(java.lang.String, android.content.Context);
+    method public static boolean isLocalEmergencyNumber(android.content.Context, java.lang.String);
     method public static final boolean isNonSeparator(char);
     method public static final boolean isReallyDialable(char);
     method public static final boolean isStartsPostDial(char);
@@ -30545,20 +30501,12 @@
     method public long getStartDelay(android.view.ViewGroup, android.transition.Transition, android.transition.TransitionValues, android.transition.TransitionValues);
     method public void setPropagationSpeed(float);
     method public void setSide(int);
-    field public static final int BOTTOM = 3; // 0x3
-    field public static final int LEFT = 0; // 0x0
-    field public static final int RIGHT = 2; // 0x2
-    field public static final int TOP = 1; // 0x1
   }
 
   public class Slide extends android.transition.Visibility {
     ctor public Slide();
     ctor public Slide(int);
     method public void setSlideEdge(int);
-    field public static final int BOTTOM = 3; // 0x3
-    field public static final int LEFT = 0; // 0x0
-    field public static final int RIGHT = 2; // 0x2
-    field public static final int TOP = 1; // 0x1
   }
 
   public abstract class Transition implements java.lang.Cloneable {
@@ -30612,7 +30560,7 @@
 
   public static abstract class Transition.EpicenterCallback {
     ctor public Transition.EpicenterCallback();
-    method public abstract android.graphics.Rect getEpicenter(android.transition.Transition);
+    method public abstract android.graphics.Rect onGetEpicenter(android.transition.Transition);
   }
 
   public static abstract interface Transition.TransitionListener {
@@ -32632,7 +32580,6 @@
     method protected int computeVerticalScrollRange();
     method public android.view.accessibility.AccessibilityNodeInfo createAccessibilityNodeInfo();
     method public void createContextMenu(android.view.ContextMenu);
-    method public final android.animation.ValueAnimator createRevealAnimator(int, int, float, float);
     method public void destroyDrawingCache();
     method public android.view.WindowInsets dispatchApplyWindowInsets(android.view.WindowInsets);
     method public void dispatchConfigurationChanged(android.content.res.Configuration);
@@ -33281,6 +33228,10 @@
     method public abstract boolean onTouch(android.view.View, android.view.MotionEvent);
   }
 
+  public class ViewAnimationUtils {
+    method public static final android.animation.ValueAnimator createCircularReveal(android.view.View, int, int, float, float);
+  }
+
   public class ViewConfiguration {
     ctor public deprecated ViewConfiguration();
     method public static android.view.ViewConfiguration get(android.content.Context);
@@ -34440,11 +34391,17 @@
 
   public static final class CaptioningManager.CaptionStyle {
     method public android.graphics.Typeface getTypeface();
+    method public boolean hasBackgroundColor();
+    method public boolean hasEdgeColor();
+    method public boolean hasEdgeType();
+    method public boolean hasForegroundColor();
+    method public boolean hasWindowColor();
     field public static final int EDGE_TYPE_DEPRESSED = 4; // 0x4
     field public static final int EDGE_TYPE_DROP_SHADOW = 2; // 0x2
     field public static final int EDGE_TYPE_NONE = 0; // 0x0
     field public static final int EDGE_TYPE_OUTLINE = 1; // 0x1
     field public static final int EDGE_TYPE_RAISED = 3; // 0x3
+    field public static final int EDGE_TYPE_UNSPECIFIED = -1; // 0xffffffff
     field public final int backgroundColor;
     field public final int edgeColor;
     field public final int edgeType;
diff --git a/core/java/android/annotation/PrivateApi.java b/core/java/android/annotation/PrivateApi.java
deleted file mode 100644
index 985eafe..0000000
--- a/core/java/android/annotation/PrivateApi.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2008 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.annotation;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Indicates an API is exposed for use by bundled applications.
- * <p>
- * These APIs are not guaranteed to remain consistent release-to-release,
- * and are not for use by apps linking against the SDK.
- * @hide
- */
-@Retention(RetentionPolicy.SOURCE)
-public @interface PrivateApi {
-}
diff --git a/core/java/android/annotation/SystemApi.java b/core/java/android/annotation/SystemApi.java
new file mode 100644
index 0000000..55028eb
--- /dev/null
+++ b/core/java/android/annotation/SystemApi.java
@@ -0,0 +1,44 @@
+/*
+ * 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.annotation;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PACKAGE;
+import static java.lang.annotation.ElementType.TYPE;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Indicates an API is exposed for use by bundled system applications.
+ * <p>
+ * These APIs are not guaranteed to remain consistent release-to-release,
+ * and are not for use by apps linking against the Android SDK.
+ * </p><p>
+ * This annotation should only appear on API that is already marked <pre>@hide</pre>.
+ * </p>
+ *
+ * @hide
+ */
+@Target({TYPE, FIELD, METHOD, CONSTRUCTOR, ANNOTATION_TYPE, PACKAGE})
+@Retention(RetentionPolicy.SOURCE)
+public @interface SystemApi {
+}
diff --git a/core/java/android/app/ActionBar.java b/core/java/android/app/ActionBar.java
index d4c4318..628875f 100644
--- a/core/java/android/app/ActionBar.java
+++ b/core/java/android/app/ActionBar.java
@@ -68,7 +68,7 @@
  * select items accessible directly from the action bar as "action items". You can also
  * modify various characteristics of the action bar or remove it completely.</p>
  *
- * <p>When using the Quantum themes (default in API 21 or newer) the navigation button
+ * <p>When using the Material themes (default in API 21 or newer) the navigation button
  * (formerly "Home") takes over the space previously occupied by the application icon.
  * Apps wishing to express a stronger branding should use their brand colors heavily
  * in the action bar and other application chrome or use a {@link #setLogo(int) logo}
diff --git a/core/java/android/app/ActivityTransitionCoordinator.java b/core/java/android/app/ActivityTransitionCoordinator.java
index b739387..b658597 100644
--- a/core/java/android/app/ActivityTransitionCoordinator.java
+++ b/core/java/android/app/ActivityTransitionCoordinator.java
@@ -563,7 +563,7 @@
         public void setEpicenter(Rect epicenter) { mEpicenter = epicenter; }
 
         @Override
-        public Rect getEpicenter(Transition transition) {
+        public Rect onGetEpicenter(Transition transition) {
             return mEpicenter;
         }
     }
diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java
index 097c64e..c29d75e 100644
--- a/core/java/android/app/ActivityView.java
+++ b/core/java/android/app/ActivityView.java
@@ -53,6 +53,7 @@
     private int mHeight;
     private Surface mSurface;
     private int mLastVisibility;
+    private ActivityViewCallback mActivityViewCallback;
 
     // Only one IIntentSender or Intent may be queued at a time. Most recent one wins.
     IIntentSender mQueuedPendingIntent;
@@ -254,6 +255,25 @@
         }
     }
 
+    /**
+     * Set the callback to use to report certain state changes.
+     * @param callback The callback to report events to.
+     *
+     * @see ActivityViewCallback
+     */
+    public void setCallback(ActivityViewCallback callback) {
+        mActivityViewCallback = callback;
+    }
+
+    public static abstract class ActivityViewCallback {
+        /**
+         * Called when all activities in the ActivityView have completed and been removed. Register
+         * using {@link ActivityView#setCallback(ActivityViewCallback)}. Each ActivityView may
+         * have at most one callback registered.
+         */
+        public abstract void onAllActivitiesComplete(ActivityView view);
+    }
+
     private class ActivityViewSurfaceTextureListener implements SurfaceTextureListener {
         @Override
         public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width,
@@ -313,6 +333,22 @@
             if (DEBUG) Log.v(TAG, "setVisible(): container=" + container + " visible=" + visible +
                     " ActivityView=" + mActivityViewWeakReference.get());
         }
+
+        @Override
+        public void onAllActivitiesComplete(IBinder container) {
+            final ActivityView activityView = mActivityViewWeakReference.get();
+            if (activityView != null) {
+                final ActivityViewCallback callback = activityView.mActivityViewCallback;
+                if (callback != null) {
+                    activityView.post(new Runnable() {
+                        @Override
+                        public void run() {
+                            callback.onAllActivitiesComplete(activityView);
+                        }
+                    });
+                }
+            }
+        }
     }
 
     private static class ActivityContainerWrapper {
diff --git a/core/java/android/app/IActivityContainerCallback.aidl b/core/java/android/app/IActivityContainerCallback.aidl
index 7f6d2c3..99d0a6f 100644
--- a/core/java/android/app/IActivityContainerCallback.aidl
+++ b/core/java/android/app/IActivityContainerCallback.aidl
@@ -21,4 +21,5 @@
 /** @hide */
 interface IActivityContainerCallback {
     oneway void setVisible(IBinder container, boolean visible);
+    oneway void onAllActivitiesComplete(IBinder container);
 }
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 8dba1dc..72b5cd90 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -21,7 +21,10 @@
 import android.content.Intent;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
 import android.graphics.PorterDuff;
+import android.graphics.drawable.Drawable;
 import android.media.AudioManager;
 import android.media.session.MediaSessionToken;
 import android.net.Uri;
@@ -32,6 +35,7 @@
 import android.os.Parcelable;
 import android.os.SystemClock;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.TypedValue;
@@ -2305,7 +2309,23 @@
             return this;
         }
 
+        private Bitmap getProfileBadge() {
+            UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+            Drawable badge = userManager.getBadgeForUser(android.os.Process.myUserHandle());
+            if (badge == null) {
+                return null;
+            }
+            final int width = badge.getIntrinsicWidth();
+            final int height = badge.getIntrinsicHeight();
+            Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+            Canvas canvas = new Canvas(bitmap);
+            badge.setBounds(0, 0, width, height);
+            badge.draw(canvas);
+            return bitmap;
+        }
+
         private RemoteViews applyStandardTemplate(int resId, boolean fitIn1U) {
+            Bitmap profileIcon = getProfileBadge();
             RemoteViews contentView = new RemoteViews(mContext.getPackageName(), resId);
             boolean showLine3 = false;
             boolean showLine2 = false;
@@ -2313,6 +2333,12 @@
             if (mPriority < PRIORITY_LOW) {
                 // TODO: Low priority presentation
             }
+            if (profileIcon != null) {
+                contentView.setImageViewBitmap(R.id.profile_icon, profileIcon);
+                contentView.setViewVisibility(R.id.profile_icon, View.VISIBLE);
+            } else {
+                contentView.setViewVisibility(R.id.profile_icon, View.GONE);
+            }
             if (mLargeIcon != null) {
                 contentView.setImageViewBitmap(R.id.icon, mLargeIcon);
                 processLargeIcon(mLargeIcon, contentView);
@@ -2473,7 +2499,7 @@
 
         /**
          * @return Whether we are currently building a notification from a legacy (an app that
-         *         doesn't create quantum notifications by itself) app.
+         *         doesn't create material notifications by itself) app.
          */
         private boolean isLegacy() {
             return mColorUtil != null;
@@ -2693,31 +2719,31 @@
 
 
         private int getBaseLayoutResource() {
-            return R.layout.notification_template_quantum_base;
+            return R.layout.notification_template_material_base;
         }
 
         private int getBigBaseLayoutResource() {
-            return R.layout.notification_template_quantum_big_base;
+            return R.layout.notification_template_material_big_base;
         }
 
         private int getBigPictureLayoutResource() {
-            return R.layout.notification_template_quantum_big_picture;
+            return R.layout.notification_template_material_big_picture;
         }
 
         private int getBigTextLayoutResource() {
-            return R.layout.notification_template_quantum_big_text;
+            return R.layout.notification_template_material_big_text;
         }
 
         private int getInboxLayoutResource() {
-            return R.layout.notification_template_quantum_inbox;
+            return R.layout.notification_template_material_inbox;
         }
 
         private int getActionLayoutResource() {
-            return R.layout.notification_quantum_action;
+            return R.layout.notification_material_action;
         }
 
         private int getActionTombstoneLayoutResource() {
-            return R.layout.notification_quantum_action_tombstone;
+            return R.layout.notification_material_action_tombstone;
         }
     }
 
@@ -3212,7 +3238,7 @@
         private RemoteViews generateMediaActionButton(Action action) {
             final boolean tombstone = (action.actionIntent == null);
             RemoteViews button = new RemoteViews(mBuilder.mContext.getPackageName(),
-                    R.layout.notification_quantum_media_action);
+                    R.layout.notification_material_media_action);
             button.setImageViewResource(R.id.action0, action.icon);
             if (!tombstone) {
                 button.setOnClickPendingIntent(R.id.action0, action.actionIntent);
@@ -3223,7 +3249,7 @@
 
         private RemoteViews makeMediaContentView() {
             RemoteViews view = mBuilder.applyStandardTemplate(
-                    R.layout.notification_template_quantum_media, true /* 1U */);
+                    R.layout.notification_template_material_media, true /* 1U */);
 
             final int numActions = mBuilder.mActions.size();
             final int N = mActionsToShowInCompact == null
@@ -3248,7 +3274,7 @@
 
         private RemoteViews makeMediaBigContentView() {
             RemoteViews big = mBuilder.applyStandardTemplate(
-                    R.layout.notification_template_quantum_big_media, false);
+                    R.layout.notification_template_material_big_media, false);
 
             final int N = Math.min(mBuilder.mActions.size(), MAX_MEDIA_BUTTONS);
             if (N > 0) {
diff --git a/core/java/android/app/admin/DeviceAdminReceiver.java b/core/java/android/app/admin/DeviceAdminReceiver.java
index ee222a9..2cc15e2 100644
--- a/core/java/android/app/admin/DeviceAdminReceiver.java
+++ b/core/java/android/app/admin/DeviceAdminReceiver.java
@@ -172,6 +172,9 @@
      * <p>The broadcast is limited to the DeviceAdminReceiver component specified in the message
      * that started the provisioning. It is also limited to the managed profile.
      *
+     * <p> The intent may contain the extra
+     * {@link DevicePolicyManager#EXTRA_PROVISIONING_EMAIL_ADDRESS}.
+     *
      * <p>Input: Nothing.</p>
      * <p>Output: Nothing</p>
      */
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 24a354f..785987f 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -26,6 +26,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.RestrictionsManager;
+import android.net.ProxyInfo;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Process;
@@ -83,6 +84,20 @@
     }
 
     /**
+     * Activity action: Used to indicate that the receiving activity is being started as part of the
+     * managed profile provisioning flow. This intent is typically sent to a mobile device
+     * management application (mdm) after the first part of the provisioning process is complete in
+     * the expectation that this app will (after optionally showing it's own UI) ultimately call
+     * {@link #ACTION_PROVISION_MANAGED_PROFILE} to complete the creation of the managed profile.
+     *
+     * <p> The intent may contain the extras {@link #EXTRA_PROVISIONING_TOKEN} and
+     * {@link #EXTRA_PROVISIONING_EMAIL_ADDRESS}.
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_SEND_PROVISIONING_VALUES
+        = "android.app.action.ACTION_SEND_PROVISIONING_VALUES";
+
+    /**
      * Activity action: Starts the provisioning flow which sets up a managed profile.
      * This intent will typically be sent by a mobile device management application(mdm).
      * Managed profile provisioning creates a profile, moves the mdm to the profile,
@@ -123,8 +138,13 @@
         = "deviceAdminPackageName";
 
     /**
-     * An int extra used to identify the consent of the user to create the managed profile.
-     * <p>Use with {@link #ACTION_PROVISION_MANAGED_PROFILE}
+     * An int extra used to identify that during the current setup process the user has already
+     * consented to setting up a managed profile. This is typically received by
+     * a mobile device management application when it is started with
+     * {@link #ACTION_SEND_PROVISIONING_VALUES} and passed on in an intent
+     * {@link #ACTION_PROVISION_MANAGED_PROFILE} which starts the setup of the managed profile. The
+     * token indicates that steps asking for user consent can be skipped as the user has previously
+     * consented.
      */
     public static final String EXTRA_PROVISIONING_TOKEN
         = "android.app.extra.token";
@@ -138,6 +158,17 @@
         = "defaultManagedProfileName";
 
     /**
+     * A String extra holding the email address of the profile that is created during managed
+     * profile provisioning. This is typically received by a mobile management application when it
+     * is started with {@link #ACTION_SEND_PROVISIONING_VALUES} and passed on in an intent
+     * {@link #ACTION_PROVISION_MANAGED_PROFILE} which starts the setup of the managed profile. It
+     * is eventually passed on in an intent
+     * {@link DeviceAdminReceiver#ACTION_PROFILE_PROVISIONING_COMPLETE}.
+     */
+    public static final String EXTRA_PROVISIONING_EMAIL_ADDRESS
+        = "android.app.extra.ManagedProfileEmailAddress";
+
+    /**
      * Activity action: ask the user to add a new device administrator to the system.
      * The desired policy is the ComponentName of the policy in the
      * {@link #EXTRA_DEVICE_ADMIN} extra field.  This will invoke a UI to
@@ -1246,6 +1277,32 @@
     }
 
     /**
+     * Set a network-independent global HTTP proxy.  This is not normally what you want
+     * for typical HTTP proxies - they are generally network dependent.  However if you're
+     * doing something unusual like general internal filtering this may be useful.  On
+     * a private network where the proxy is not accessible, you may break HTTP using this.
+     *
+     * <p>This method requires the caller to be the device owner.
+     *
+     * <p>This proxy is only a recommendation and it is possible that some apps will ignore it.
+     * @see ProxyInfo
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated
+     *            with.
+     * @param proxyInfo The a {@link ProxyInfo} object defining the new global
+     *        HTTP proxy.  A {@code null} value will clear the global HTTP proxy.
+     */
+    public void setRecommendedGlobalProxy(ComponentName admin, ProxyInfo proxyInfo) {
+        if (mService != null) {
+            try {
+                mService.setRecommendedGlobalProxy(admin, proxyInfo);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+    }
+
+    /**
      * Returns the component name setting the global proxy.
      * @return ComponentName object of the device admin that set the global proxy, or
      *            null if no admin has set the proxy.
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 7d7a312..3d80869 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -20,6 +20,7 @@
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.net.ProxyInfo;
 import android.os.Bundle;
 import android.os.RemoteCallback;
 import android.os.UserHandle;
@@ -78,6 +79,7 @@
 
     ComponentName setGlobalProxy(in ComponentName admin, String proxySpec, String exclusionList, int userHandle);
     ComponentName getGlobalProxyAdmin(int userHandle);
+    void setRecommendedGlobalProxy(in ComponentName admin, in ProxyInfo proxyInfo);
 
     int setStorageEncryption(in ComponentName who, boolean encrypt, int userHandle);
     boolean getStorageEncryption(in ComponentName who, int userHandle);
diff --git a/core/java/android/app/task/Task.java b/core/java/android/app/task/Task.java
index ca4aeb2..87d57fb4 100644
--- a/core/java/android/app/task/Task.java
+++ b/core/java/android/app/task/Task.java
@@ -20,6 +20,7 @@
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.PersistableBundle;
 
 /**
  * Container of data passed to the {@link android.app.task.TaskManager} fully encapsulating the
@@ -37,6 +38,18 @@
     }
 
     /**
+     * Amount of backoff a task has initially by default, in milliseconds.
+     * @hide.
+     */
+    public static final long DEFAULT_INITIAL_BACKOFF_MILLIS = 5000L;
+
+    /**
+     * Default type of backoff.
+     * @hide
+     */
+    public static final int DEFAULT_BACKOFF_POLICY = BackoffPolicy.EXPONENTIAL;
+
+    /**
      * Linear: retry_time(failure_time, t) = failure_time + initial_retry_delay * t, t >= 1
      * Expon: retry_time(failure_time, t) = failure_time + initial_retry_delay ^ t, t >= 1
      */
@@ -47,7 +60,7 @@
 
     private final int taskId;
     // TODO: Change this to use PersistableBundle when that lands in master.
-    private final Bundle extras;
+    private final PersistableBundle extras;
     private final ComponentName service;
     private final boolean requireCharging;
     private final boolean requireDeviceIdle;
@@ -71,7 +84,7 @@
     /**
      * Bundle of extras which are returned to your application at execution time.
      */
-    public Bundle getExtras() {
+    public PersistableBundle getExtras() {
         return extras;
     }
 
@@ -171,7 +184,7 @@
 
     private Task(Parcel in) {
         taskId = in.readInt();
-        extras = in.readBundle();
+        extras = in.readPersistableBundle();
         service = ComponentName.readFromParcel(in);
         requireCharging = in.readInt() == 1;
         requireDeviceIdle = in.readInt() == 1;
@@ -188,7 +201,7 @@
 
     private Task(Task.Builder b) {
         taskId = b.mTaskId;
-        extras = new Bundle(b.mExtras);
+        extras = new PersistableBundle(b.mExtras);
         service = b.mTaskService;
         requireCharging = b.mRequiresCharging;
         requireDeviceIdle = b.mRequiresDeviceIdle;
@@ -211,7 +224,7 @@
     @Override
     public void writeToParcel(Parcel out, int flags) {
         out.writeInt(taskId);
-        out.writeBundle(extras);
+        out.writePersistableBundle(extras);
         ComponentName.writeToParcel(service, out);
         out.writeInt(requireCharging ? 1 : 0);
         out.writeInt(requireDeviceIdle ? 1 : 0);
@@ -238,12 +251,10 @@
         }
     };
 
-    /**
-     * Builder class for constructing {@link Task} objects.
-     */
+    /** Builder class for constructing {@link Task} objects. */
     public static final class Builder {
         private int mTaskId;
-        private Bundle mExtras;
+        private PersistableBundle mExtras = PersistableBundle.EMPTY;
         private ComponentName mTaskService;
         // Requirements.
         private boolean mRequiresCharging;
@@ -258,8 +269,8 @@
         private boolean mHasLateConstraint;
         private long mIntervalMillis;
         // Back-off parameters.
-        private long mInitialBackoffMillis = 5000L;
-        private int mBackoffPolicy = BackoffPolicy.EXPONENTIAL;
+        private long mInitialBackoffMillis = DEFAULT_INITIAL_BACKOFF_MILLIS;
+        private int mBackoffPolicy = DEFAULT_BACKOFF_POLICY;
         /** Easy way to track whether the client has tried to set a back-off policy. */
         private boolean mBackoffPolicySet = false;
 
@@ -279,7 +290,7 @@
          * Set optional extras. This is persisted, so we only allow primitive types.
          * @param extras Bundle containing extras you want the scheduler to hold on to for you.
          */
-        public Builder setExtras(Bundle extras) {
+        public Builder setExtras(PersistableBundle extras) {
             mExtras = extras;
             return this;
         }
@@ -394,18 +405,13 @@
          * @return The task object to hand to the TaskManager. This object is immutable.
          */
         public Task build() {
-            if (mExtras == null) {
-                mExtras = Bundle.EMPTY;
-            }
-            if (mTaskId < 0) {
-                throw new IllegalArgumentException("Task id must be greater than 0.");
-            }
+            mExtras = new PersistableBundle(mExtras);  // Make our own copy.
             // Check that a deadline was not set on a periodic task.
-            if (mIsPeriodic && mHasLateConstraint) {
+            if (mIsPeriodic && (mMaxExecutionDelayMillis != 0L)) {
                 throw new IllegalArgumentException("Can't call setOverrideDeadline() on a " +
                         "periodic task.");
             }
-            if (mIsPeriodic && mHasEarlyConstraint) {
+            if (mIsPeriodic && (mMinLatencyMillis != 0L)) {
                 throw new IllegalArgumentException("Can't call setMinimumLatency() on a " +
                         "periodic task");
             }
diff --git a/core/java/android/app/task/TaskParams.java b/core/java/android/app/task/TaskParams.java
index dacb3480..f4908c6 100644
--- a/core/java/android/app/task/TaskParams.java
+++ b/core/java/android/app/task/TaskParams.java
@@ -16,10 +16,10 @@
 
 package android.app.task;
 
-import android.os.Bundle;
 import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.PersistableBundle;
 
 /**
  * Contains the parameters used to configure/identify your task. You do not create this object
@@ -28,11 +28,11 @@
 public class TaskParams implements Parcelable {
 
     private final int taskId;
-    private final Bundle extras;
+    private final PersistableBundle extras;
     private final IBinder callback;
 
     /** @hide */
-    public TaskParams(int taskId, Bundle extras, IBinder callback) {
+    public TaskParams(int taskId, PersistableBundle extras, IBinder callback) {
         this.taskId = taskId;
         this.extras = extras;
         this.callback = callback;
@@ -47,10 +47,10 @@
 
     /**
      * @return The extras you passed in when constructing this task with
-     * {@link android.app.task.Task.Builder#setExtras(android.os.Bundle)}. This will
+     * {@link android.app.task.Task.Builder#setExtras(android.os.PersistableBundle)}. This will
      * never be null. If you did not set any extras this will be an empty bundle.
      */
-    public Bundle getExtras() {
+    public PersistableBundle getExtras() {
         return extras;
     }
 
@@ -61,7 +61,7 @@
 
     private TaskParams(Parcel in) {
         taskId = in.readInt();
-        extras = in.readBundle();
+        extras = in.readPersistableBundle();
         callback = in.readStrongBinder();
     }
 
@@ -73,7 +73,7 @@
     @Override
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeInt(taskId);
-        dest.writeBundle(extras);
+        dest.writePersistableBundle(extras);
         dest.writeStrongBinder(callback);
     }
 
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 7642e13..392bfbc 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -1839,19 +1839,6 @@
     }
 
     /**
-     * Cancel any active or pending syncs that are running on this service.
-     *
-     * @param cname the service for which to cancel all active/pending operations.
-     */
-    public static void cancelSync(ComponentName cname) {
-        try {
-            getContentService().cancelSync(null, null, cname);
-        } catch (RemoteException e) {
-            
-        }
-    }
-
-    /**
      * Get information about the SyncAdapters that are known to the system.
      * @return an array of SyncAdapters that have registered with the system
      */
@@ -1991,13 +1978,13 @@
     /**
      * Remove the specified sync. This will cancel any pending or active syncs. If the request is
      * for a periodic sync, this call will remove any future occurrences.
-     * <p>If a periodic sync is specified, the caller must hold the permission
-     * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}. If this SyncRequest targets a
-     * SyncService adapter,the calling application must be signed with the same certificate as the
-     * adapter.
-     *</p>It is possible to cancel a sync using a SyncRequest object that is not the same object
+     * <p>
+     *     If a periodic sync is specified, the caller must hold the permission
+     *     {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}.
+     *</p>
+     * It is possible to cancel a sync using a SyncRequest object that is not the same object
      * with which you requested the sync. Do so by building a SyncRequest with the same
-     * service/adapter, frequency, <b>and</b> extras bundle.
+     * adapter, frequency, <b>and</b> extras bundle.
      *
      * @param request SyncRequest object containing information about sync to cancel.
      */
@@ -2031,22 +2018,6 @@
     }
 
     /**
-     * Return periodic syncs associated with the provided component.
-     * <p>The calling application must be signed with the same certificate as the target component,
-     * otherwise this call will fail.
-     */
-    public static List<PeriodicSync> getPeriodicSyncs(ComponentName cname) {
-        if (cname == null) {
-            throw new IllegalArgumentException("Component must not be null");
-        }
-        try {
-            return getContentService().getPeriodicSyncs(null, null, cname);
-        } catch (RemoteException e) {
-            throw new RuntimeException("the ContentService should always be reachable", e);
-        }
-    }
-
-    /**
      * Check if this account/provider is syncable.
      * <p>This method requires the caller to hold the permission
      * {@link android.Manifest.permission#READ_SYNC_SETTINGS}.
@@ -2076,38 +2047,6 @@
     }
 
     /**
-     * Set whether the provided {@link SyncService} is available to process work.
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}.
-     * <p>The calling application must be signed with the same certificate as the target component,
-     * otherwise this call will fail.
-     */
-    public static void setServiceActive(ComponentName cname, boolean active) {
-        try {
-            getContentService().setServiceActive(cname, active);
-        } catch (RemoteException e) {
-            // exception ignored; if this is thrown then it means the runtime is in the midst of
-            // being restarted
-        }
-    }
-
-    /**
-     * Query the state of this sync service.
-     * <p>Set with {@link #setServiceActive(ComponentName cname, boolean active)}.
-     * <p>The calling application must be signed with the same certificate as the target component,
-     * otherwise this call will fail.
-     * @param cname ComponentName referring to a {@link SyncService}
-     * @return true if jobs will be run on this service, false otherwise.
-     */
-    public static boolean isServiceActive(ComponentName cname) {
-        try {
-            return getContentService().isServiceActive(cname);
-        } catch (RemoteException e) {
-            throw new RuntimeException("the ContentService should always be reachable", e);
-        }
-    }
-
-    /**
      * Gets the master auto-sync setting that applies to all the providers and accounts.
      * If this is false then the per-provider auto-sync setting is ignored.
      * <p>This method requires the caller to hold the permission
@@ -2164,17 +2103,6 @@
         }
     }
 
-    public static boolean isSyncActive(ComponentName cname) {
-        if (cname == null) {
-            throw new IllegalArgumentException("component name must not be null");
-        }
-        try {
-            return getContentService().isSyncActive(null, null, cname);
-        } catch (RemoteException e) {
-            throw new RuntimeException("the ContentService should always be reachable", e);
-        }
-    }
-
     /**
      * If a sync is active returns the information about it, otherwise returns null.
      * <p>
@@ -2249,14 +2177,6 @@
         }
     }
 
-    public static boolean isSyncPending(ComponentName cname) {
-        try {
-            return getContentService().isSyncPending(null, null, cname);
-        } catch (RemoteException e) {
-            throw new RuntimeException("the ContentService should always be reachable", e);
-        }
-    }
-
     /**
      * Request notifications when the different aspects of the SyncManager change. The
      * different items that can be requested are:
diff --git a/core/java/android/content/IContentService.aidl b/core/java/android/content/IContentService.aidl
index 73a76e8..373f2fb 100644
--- a/core/java/android/content/IContentService.aidl
+++ b/core/java/android/content/IContentService.aidl
@@ -121,19 +121,6 @@
      */
     void setIsSyncable(in Account account, String providerName, int syncable);
 
-    /**
-     * Corresponds roughly to setIsSyncable(String account, String provider) for syncs that bind
-     * to a SyncService.
-     */
-    void setServiceActive(in ComponentName cname, boolean active);
-
-    /**
-     * Corresponds roughly to getIsSyncable(String account, String provider) for syncs that bind
-     * to a SyncService.
-     * @return 0 if this SyncService is not enabled, 1 if enabled, <0 if unknown.
-     */
-    boolean isServiceActive(in ComponentName cname);
-
     void setMasterSyncAutomatically(boolean flag);
 
     boolean getMasterSyncAutomatically();
diff --git a/core/java/android/content/PeriodicSync.java b/core/java/android/content/PeriodicSync.java
index 836c6f8..3efd89a 100644
--- a/core/java/android/content/PeriodicSync.java
+++ b/core/java/android/content/PeriodicSync.java
@@ -29,14 +29,10 @@
     public final Account account;
     /** The authority of the sync. Can be null. */
     public final String authority;
-    /** The service for syncing, if this is an anonymous sync. Can be null.*/
-    public final ComponentName service;
     /** Any extras that parameters that are to be passed to the sync adapter. */
     public final Bundle extras;
     /** How frequently the sync should be scheduled, in seconds. Kept around for API purposes. */
     public final long period;
-    /** Whether this periodic sync runs on a {@link SyncService}. */
-    public final boolean isService;
     /**
      * How much flexibility can be taken in scheduling the sync, in seconds.
      * {@hide}
@@ -44,16 +40,11 @@
     public final long flexTime;
 
       /**
-       * Creates a new PeriodicSync, copying the Bundle. SM no longer uses this ctor - kept around
-       * becuse it is part of the API.
-       * Note - even calls to the old API will not use this ctor, as
-       * they are given a default flex time.
+       * Creates a new PeriodicSync, copying the Bundle. This constructor is no longer used.
        */
     public PeriodicSync(Account account, String authority, Bundle extras, long periodInSeconds) {
         this.account = account;
         this.authority = authority;
-        this.service = null;
-        this.isService = false;
         if (extras == null) {
             this.extras = new Bundle();
         } else {
@@ -71,8 +62,6 @@
     public PeriodicSync(PeriodicSync other) {
         this.account = other.account;
         this.authority = other.authority;
-        this.service = other.service;
-        this.isService = other.isService;
         this.extras = new Bundle(other.extras);
         this.period = other.period;
         this.flexTime = other.flexTime;
@@ -86,40 +75,14 @@
             long period, long flexTime) {
         this.account = account;
         this.authority = authority;
-        this.service = null;
-        this.isService = false;
-        this.extras = new Bundle(extras);
-        this.period = period;
-        this.flexTime = flexTime;
-    }
-
-    /**
-     * A PeriodicSync for a sync with a specified SyncService.
-     * {@hide}
-     */
-    public PeriodicSync(ComponentName service, Bundle extras,
-            long period,
-            long flexTime) {
-        this.account = null;
-        this.authority = null;
-        this.service = service;
-        this.isService = true;
         this.extras = new Bundle(extras);
         this.period = period;
         this.flexTime = flexTime;
     }
 
     private PeriodicSync(Parcel in) {
-        this.isService = (in.readInt() != 0);
-        if (this.isService) {
-            this.service = in.readParcelable(null);
-            this.account = null;
-            this.authority = null;
-        } else {
-            this.account = in.readParcelable(null);
-            this.authority = in.readString();
-            this.service = null;
-        }
+        this.account = in.readParcelable(null);
+        this.authority = in.readString();
         this.extras = in.readBundle();
         this.period = in.readLong();
         this.flexTime = in.readLong();
@@ -132,13 +95,8 @@
 
     @Override
     public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(isService ? 1 : 0);
-        if (account == null && authority == null) {
-            dest.writeParcelable(service, flags);
-        } else {
-            dest.writeParcelable(account, flags);
-            dest.writeString(authority);
-        }
+        dest.writeParcelable(account, flags);
+        dest.writeString(authority);
         dest.writeBundle(extras);
         dest.writeLong(period);
         dest.writeLong(flexTime);
@@ -165,24 +123,14 @@
             return false;
         }
         final PeriodicSync other = (PeriodicSync) o;
-        if (this.isService != other.isService) {
-            return false;
-        }
-        boolean equal = false;
-        if (this.isService) {
-            equal = service.equals(other.service);
-        } else {
-            equal = account.equals(other.account)
-                    && authority.equals(other.authority);
-        }
-        return equal
-            && period == other.period
-            && syncExtrasEquals(extras, other.extras);
+        return account.equals(other.account)
+                && authority.equals(other.authority)
+                && period == other.period
+                && syncExtrasEquals(extras, other.extras);
     }
 
     /**
-     * Periodic sync extra comparison function. Duplicated from
-     * {@link com.android.server.content.SyncManager#syncExtrasEquals(Bundle b1, Bundle b2)}
+     * Periodic sync extra comparison function.
      * {@hide}
      */
     public static boolean syncExtrasEquals(Bundle b1, Bundle b2) {
@@ -207,7 +155,6 @@
     public String toString() {
         return "account: " + account +
                ", authority: " + authority +
-               ", service: " + service +
                ". period: " + period + "s " +
                ", flex: " + flexTime;
     }
diff --git a/core/java/android/content/SyncInfo.java b/core/java/android/content/SyncInfo.java
index 146dd99..a586d6f 100644
--- a/core/java/android/content/SyncInfo.java
+++ b/core/java/android/content/SyncInfo.java
@@ -28,24 +28,16 @@
     public final int authorityId;
 
     /**
-     * The {@link Account} that is currently being synced. Will be null if this sync is running via
-     * a {@link SyncService}.
+     * The {@link Account} that is currently being synced.
      */
     public final Account account;
 
     /**
-     * The authority of the provider that is currently being synced. Will be null if this sync
-     * is running via a {@link SyncService}.
+     * The authority of the provider that is currently being synced.
      */
     public final String authority;
 
     /**
-     * The {@link SyncService} that is targeted by this operation. Null if this sync is running via
-     * a {@link AbstractThreadedSyncAdapter}. 
-     */
-    public final ComponentName service;
-
-    /**
      * The start time of the current sync operation in milliseconds since boot.
      * This is represented in elapsed real time.
      * See {@link android.os.SystemClock#elapsedRealtime()}.
@@ -53,13 +45,11 @@
     public final long startTime;
 
     /** @hide */
-    public SyncInfo(int authorityId, Account account, String authority, ComponentName service,
-            long startTime) {
+    public SyncInfo(int authorityId, Account account, String authority, long startTime) {
         this.authorityId = authorityId;
         this.account = account;
         this.authority = authority;
         this.startTime = startTime;
-        this.service = service;
     }
 
     /** @hide */
@@ -68,7 +58,6 @@
         this.account = new Account(other.account.name, other.account.type);
         this.authority = other.authority;
         this.startTime = other.startTime;
-        this.service = other.service;
     }
 
     /** @hide */
@@ -82,8 +71,6 @@
         parcel.writeParcelable(account, flags);
         parcel.writeString(authority);
         parcel.writeLong(startTime);
-        parcel.writeParcelable(service, flags);
-        
     }
 
     /** @hide */
@@ -92,7 +79,6 @@
         account = parcel.readParcelable(Account.class.getClassLoader());
         authority = parcel.readString();
         startTime = parcel.readLong();
-        service = parcel.readParcelable(ComponentName.class.getClassLoader());
     }
 
     /** @hide */
diff --git a/core/java/android/content/SyncRequest.java b/core/java/android/content/SyncRequest.java
index 9ba45ca..869f85c 100644
--- a/core/java/android/content/SyncRequest.java
+++ b/core/java/android/content/SyncRequest.java
@@ -27,23 +27,11 @@
     private final Account mAccountToSync;
     /** Authority string that corresponds to a ContentProvider. */
     private final String mAuthority;
-    /** {@link SyncService} identifier. */
-    private final ComponentName mComponentInfo;
     /** Bundle containing user info as well as sync settings. */
     private final Bundle mExtras;
     /** Don't allow this sync request on metered networks. */
     private final boolean mDisallowMetered;
     /**
-     * Anticipated upload size in bytes.
-     * TODO: Not yet used - we put this information into the bundle for simplicity.
-     */
-    private final long mTxBytes;
-    /**
-     * Anticipated download size in bytes.
-     * TODO: Not yet used - we put this information into the bundle.
-     */
-    private final long mRxBytes;
-    /**
      * Amount of time before {@link #mSyncRunTimeSecs} from which the sync may optionally be
      * started.
      */
@@ -75,25 +63,12 @@
 
     /**
      * {@hide}
-     * @return true if this sync uses an account/authority pair, or false if
-     *         this is an anonymous sync bound to an @link AnonymousSyncService.
-     */
-    public boolean hasAuthority() {
-        return mIsAuthority;
-    }
-
-    /**
-     * {@hide}
      *
      * @return account object for this sync.
      * @throws IllegalArgumentException if this function is called for a request that targets a
      * sync service.
      */
     public Account getAccount() {
-        if (!hasAuthority()) {
-            throw new IllegalArgumentException("Cannot getAccount() for a sync that targets a sync"
-                    + "service.");
-        }
         return mAccountToSync;
     }
 
@@ -105,30 +80,11 @@
      * sync service.
      */
     public String getProvider() {
-        if (!hasAuthority()) {
-            throw new IllegalArgumentException("Cannot getProvider() for a sync that targets a"
-                    + "sync service.");
-        }
         return mAuthority;
     }
 
     /**
      * {@hide}
-     * Throws a runtime IllegalArgumentException if this function is called for a
-     * SyncRequest that is bound to an account/provider.
-     *
-     * @return ComponentName for the service that this sync will bind to.
-     */
-    public ComponentName getService() {
-        if (hasAuthority()) {
-            throw new IllegalArgumentException(
-                    "Cannot getAnonymousService() for a sync that has specified a provider.");
-        }
-        return mComponentInfo;
-    }
-
-    /**
-     * {@hide}
      * Retrieve bundle for this SyncRequest. Will not be null.
      */
     public Bundle getBundle() {
@@ -175,16 +131,10 @@
         parcel.writeLong(mSyncRunTimeSecs);
         parcel.writeInt((mIsPeriodic ? 1 : 0));
         parcel.writeInt((mDisallowMetered ? 1 : 0));
-        parcel.writeLong(mTxBytes);
-        parcel.writeLong(mRxBytes);
         parcel.writeInt((mIsAuthority ? 1 : 0));
         parcel.writeInt((mIsExpedited? 1 : 0));
-        if (mIsAuthority) {
-            parcel.writeParcelable(mAccountToSync, flags);
-            parcel.writeString(mAuthority);
-        } else {
-            parcel.writeParcelable(mComponentInfo, flags);
-        }
+        parcel.writeParcelable(mAccountToSync, flags);
+        parcel.writeString(mAuthority);
     }
 
     private SyncRequest(Parcel in) {
@@ -193,19 +143,10 @@
         mSyncRunTimeSecs = in.readLong();
         mIsPeriodic = (in.readInt() != 0);
         mDisallowMetered = (in.readInt() != 0);
-        mTxBytes = in.readLong();
-        mRxBytes = in.readLong();
         mIsAuthority = (in.readInt() != 0);
         mIsExpedited = (in.readInt() != 0);
-        if (mIsAuthority) {
-            mComponentInfo = null;
-            mAccountToSync = in.readParcelable(null);
-            mAuthority = in.readString();
-        } else {
-            mComponentInfo = in.readParcelable(null);
-            mAccountToSync = null;
-            mAuthority = null;
-        }
+        mAccountToSync = in.readParcelable(null);
+        mAuthority = in.readString();
     }
 
     /** {@hide} Protected ctor to instantiate anonymous SyncRequest. */
@@ -214,7 +155,6 @@
         mSyncRunTimeSecs = b.mSyncRunTimeSecs;
         mAccountToSync = b.mAccount;
         mAuthority = b.mAuthority;
-        mComponentInfo = b.mComponentName;
         mIsPeriodic = (b.mSyncType == Builder.SYNC_TYPE_PERIODIC);
         mIsAuthority = (b.mSyncTarget == Builder.SYNC_TARGET_ADAPTER);
         mIsExpedited = b.mExpedited;
@@ -223,8 +163,6 @@
         // TODO: pass the configuration extras through separately.
         mExtras.putAll(b.mSyncConfigExtras);
         mDisallowMetered = b.mDisallowMetered;
-        mTxBytes = b.mTxBytes;
-        mRxBytes = b.mRxBytes;
     }
 
     /**
@@ -240,8 +178,6 @@
         private static final int SYNC_TYPE_ONCE = 2;
         /** Unknown sync target. */
         private static final int SYNC_TARGET_UNKNOWN = 0;
-        /** Specify that this is an anonymous sync. */
-        private static final int SYNC_TARGET_SERVICE = 1;
         /** Specify that this is a sync with a provider. */
         private static final int SYNC_TARGET_ADAPTER = 2;
         /**
@@ -275,7 +211,7 @@
          * Whether this builder is building a periodic sync, or a one-time sync.
          */
         private int mSyncType = SYNC_TYPE_UNKNOWN;
-        /** Whether this will go to a sync adapter or to a sync service. */
+        /** Whether this will go to a sync adapter. */
         private int mSyncTarget = SYNC_TARGET_UNKNOWN;
         /** Whether this is a user-activated sync. */
         private boolean mIsManual;
@@ -298,12 +234,6 @@
         private boolean mExpedited;
 
         /**
-         * The {@link SyncService} component that
-         * contains the sync logic if this is a provider-less sync, otherwise
-         * null.
-         */
-        private ComponentName mComponentName;
-        /**
          * The Account object that together with an Authority name define the SyncAdapter (if
          * this sync is bound to a provider), otherwise null.
          */
@@ -336,7 +266,7 @@
 
         /**
          * Build a periodic sync. Either this or syncOnce() <b>must</b> be called for this builder.
-         * Syncs are identified by target {@link SyncService}/{@link android.provider} and by the
+         * Syncs are identified by target {@link android.provider} and by the
          * contents of the extras bundle.
          * You cannot reuse the same builder for one-time syncs after having specified a periodic
          * sync (by calling this function). If you do, an <code>IllegalArgumentException</code>
@@ -395,23 +325,10 @@
         }
 
         /**
-         * Developer can provide insight into their payload size; optional. -1 specifies unknown,
-         * so that you are not restricted to defining both fields.
-         *
-         * @param rxBytes Bytes expected to be downloaded.
-         * @param txBytes Bytes expected to be uploaded.
-         */
-        public Builder setTransferSize(long rxBytes, long txBytes) {
-            mRxBytes = rxBytes;
-            mTxBytes = txBytes;
-            return this;
-        }
-
-        /**
          * Will throw an <code>IllegalArgumentException</code> if called and
          * {@link #setIgnoreSettings(boolean ignoreSettings)} has already been called.
          * @param disallow true to allow this transfer on metered networks. Default false.
-         * 
+         *
          */
         public Builder setDisallowMetered(boolean disallow) {
             if (mIgnoreSettings && disallow) {
@@ -423,10 +340,9 @@
         }
 
         /**
-         * Specify an authority and account for this transfer. Cannot be used with
-         * {@link #setSyncAdapter(ComponentName cname)}.
+         * Specify an authority and account for this transfer.
          *
-         * @param authority
+         * @param authority A String identifying the content provider to be synced.
          * @param account Account to sync. Can be null unless this is a periodic
          *            sync, for which verification by the ContentResolver will
          *            fail. If a sync is performed without an account, the
@@ -441,25 +357,6 @@
             mSyncTarget = SYNC_TARGET_ADAPTER;
             mAccount = account;
             mAuthority = authority;
-            mComponentName = null;
-            return this;
-        }
-
-        /**
-         * Specify the {@link SyncService} component for this sync. This is not validated until
-         * sync time so providing an incorrect component name here will not fail. Cannot be used
-         * with {@link #setSyncAdapter(Account account, String authority)}.
-         *
-         * @param cname ComponentName to identify your Anonymous service
-         */
-        public Builder setSyncAdapter(ComponentName cname) {
-            if (mSyncTarget != SYNC_TARGET_UNKNOWN) {
-                throw new IllegalArgumentException("Sync target has already been defined.");
-            }
-            mSyncTarget = SYNC_TARGET_SERVICE;
-            mComponentName = cname;
-            mAccount = null;
-            mAuthority = null;
             return this;
         }
 
@@ -630,25 +527,17 @@
             mSyncConfigExtras.putInt(ContentResolver.SYNC_EXTRAS_PRIORITY, mPriority);
             if (mSyncType == SYNC_TYPE_PERIODIC) {
                 // If this is a periodic sync ensure than invalid extras were not set.
-                if (ContentResolver.invalidPeriodicExtras(mCustomExtras) || 
+                if (ContentResolver.invalidPeriodicExtras(mCustomExtras) ||
                         ContentResolver.invalidPeriodicExtras(mSyncConfigExtras)) {
                     throw new IllegalArgumentException("Illegal extras were set");
                 }
-            } else if (mSyncType == SYNC_TYPE_UNKNOWN) {
-                throw new IllegalArgumentException("Must call either syncOnce() or syncPeriodic()");
-            }
-            if (mSyncTarget == SYNC_TARGET_SERVICE) {
-                if (mSyncConfigExtras.getBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, false)) {
-                    throw new IllegalArgumentException("Cannot specify an initialisation sync"
-                            + " that targets a service.");
-                }
             }
             // Ensure that a target for the sync has been set.
             if (mSyncTarget == SYNC_TARGET_UNKNOWN) {
-                throw new IllegalArgumentException("Must specify an adapter with one of"
-                    + "setSyncAdapter(ComponentName) or setSyncAdapter(Account, String");
+                throw new IllegalArgumentException("Must specify an adapter with" +
+                        " setSyncAdapter(Account, String");
             }
             return new SyncRequest(this);
         }
-    }   
+    }
 }
diff --git a/core/java/android/content/SyncService.java b/core/java/android/content/SyncService.java
deleted file mode 100644
index 4df998c..0000000
--- a/core/java/android/content/SyncService.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright (C) 2013 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.content;
-
-import android.app.Service;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.Process;
-import android.os.Trace;
-import android.util.SparseArray;
-import android.util.Log;
-
-import com.android.internal.annotations.GuardedBy;
-
-/**
- * Simplified @link android.content.AbstractThreadedSyncAdapter. Folds that
- * behaviour into a service to which the system can bind when requesting an
- * anonymous (providerless/accountless) sync.
- * <p>
- * In order to perform an anonymous sync operation you must extend this service, implementing the
- * abstract methods. This service must be declared in the application's manifest as usual. You
- * can use this service for other work, however you <b> must not </b> override the onBind() method
- * unless you know what you're doing, which limits the usefulness of this service for other work.
- * <p>A {@link SyncService} can either be active or inactive. Different to an
- * {@link AbstractThreadedSyncAdapter}, there is no
- * {@link ContentResolver#setSyncAutomatically(android.accounts.Account account, String provider, boolean sync)},
- * as well as no concept of initialisation (you can handle your own if needed).
- *
- * <pre>
- * &lt;service android:name=".MySyncService"/&gt;
- * </pre>
- * Like @link android.content.AbstractThreadedSyncAdapter this service supports
- * multiple syncs at the same time. Each incoming startSync() with a unique tag
- * will spawn a thread to do the work of that sync. If startSync() is called
- * with a tag that already exists, a SyncResult.ALREADY_IN_PROGRESS is returned.
- * Remember that your service will spawn multiple threads if you schedule multiple syncs
- * at once, so if you mutate local objects you must ensure synchronization.
- */
-public abstract class SyncService extends Service {
-    private static final String TAG = "SyncService";
-
-    private final SyncAdapterImpl mSyncAdapter = new SyncAdapterImpl();
-
-    /** Keep track of on-going syncs, keyed by bundle. */
-    @GuardedBy("mSyncThreadLock")
-    private final SparseArray<SyncThread>
-            mSyncThreads = new SparseArray<SyncThread>();
-    /** Lock object for accessing the SyncThreads HashMap. */
-    private final Object mSyncThreadLock = new Object();
-    /**
-     * Default key for if this sync service does not support parallel operations. Currently not
-     * sure if null keys will make it into the ArrayMap for KLP, so keeping our default for now.
-     */
-    private static final int KEY_DEFAULT = 0;
-    /** Identifier for this sync service. */
-    private ComponentName mServiceComponent;
-
-    /** {@hide} */
-    public IBinder onBind(Intent intent) {
-        mServiceComponent = new ComponentName(this, getClass());
-        return mSyncAdapter.asBinder();
-    }
-
-    /** {@hide} */
-    private class SyncAdapterImpl extends ISyncServiceAdapter.Stub {
-        @Override
-        public void startSync(ISyncContext syncContext, Bundle extras) {
-            // Wrap the provided Sync Context because it may go away by the time
-            // we call it.
-            final SyncContext syncContextClient = new SyncContext(syncContext);
-            boolean alreadyInProgress = false;
-            final int extrasAsKey = extrasToKey(extras);
-            synchronized (mSyncThreadLock) {
-                if (mSyncThreads.get(extrasAsKey) == null) {
-                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                        Log.v(TAG, "starting sync for : " + mServiceComponent);
-                    }
-                    // Start sync.
-                    SyncThread syncThread = new SyncThread(syncContextClient, extras);
-                    mSyncThreads.put(extrasAsKey, syncThread);
-                    syncThread.start();
-                } else {
-                    // Don't want to call back to SyncManager while still
-                    // holding lock.
-                    alreadyInProgress = true;
-                }
-            }
-            if (alreadyInProgress) {
-                syncContextClient.onFinished(SyncResult.ALREADY_IN_PROGRESS);
-            }
-        }
-
-        /**
-         * Used by the SM to cancel a specific sync using the
-         * com.android.server.content.SyncManager.ActiveSyncContext as a handle.
-         */
-        @Override
-        public void cancelSync(ISyncContext syncContext) {
-            SyncThread runningSync = null;
-            synchronized (mSyncThreadLock) {
-                for (int i = 0; i < mSyncThreads.size(); i++) {
-                    SyncThread thread = mSyncThreads.valueAt(i);
-                    if (thread.mSyncContext.getSyncContextBinder() == syncContext.asBinder()) {
-                        runningSync = thread;
-                        break;
-                    }
-                }
-            }
-            if (runningSync != null) {
-                runningSync.interrupt();
-            }
-        }
-    }
-
-    /**
-     * 
-     * @param extras Bundle for which to compute hash
-     * @return an integer hash that is equal to that of another bundle if they both contain the
-     * same key -> value mappings, however, not necessarily in order.
-     * Based on the toString() representation of the value mapped.
-     */
-    private int extrasToKey(Bundle extras) {
-        int hash = KEY_DEFAULT; // Empty bundle, or no parallel operations enabled.
-        if (parallelSyncsEnabled()) {
-            for (String key : extras.keySet()) {
-                String mapping = key + " " + extras.get(key).toString();
-                hash += mapping.hashCode();
-            }
-        }
-        return hash;
-    }
-
-    /**
-     * {@hide}
-     * Similar to {@link android.content.AbstractThreadedSyncAdapter.SyncThread}. However while
-     * the ATSA considers an already in-progress sync to be if the account provided is currently
-     * syncing, this anonymous sync has no notion of account and considers a sync unique if the
-     * provided bundle is different.
-     */
-    private class SyncThread extends Thread {
-        private final SyncContext mSyncContext;
-        private final Bundle mExtras;
-        private final int mThreadsKey;
-
-        public SyncThread(SyncContext syncContext, Bundle extras) {
-            mSyncContext = syncContext;
-            mExtras = extras;
-            mThreadsKey = extrasToKey(extras);
-        }
-
-        @Override
-        public void run() {
-            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
-
-            Trace.traceBegin(Trace.TRACE_TAG_SYNC_MANAGER, getApplication().getPackageName());
-
-            SyncResult syncResult = new SyncResult();
-            try {
-                if (isCancelled()) return;
-                // Run the sync.
-                SyncService.this.onPerformSync(mExtras, syncResult);
-            } finally {
-                Trace.traceEnd(Trace.TRACE_TAG_SYNC_MANAGER);
-                if (!isCancelled()) {
-                    mSyncContext.onFinished(syncResult);
-                }
-                // Synchronize so that the assignment will be seen by other
-                // threads that also synchronize accesses to mSyncThreads.
-                synchronized (mSyncThreadLock) {
-                    mSyncThreads.remove(mThreadsKey);
-                }
-            }
-        }
-
-        private boolean isCancelled() {
-            return Thread.currentThread().isInterrupted();
-        }
-    }
-
-    /**
-     * Initiate an anonymous sync using this service. SyncAdapter-specific
-     * parameters may be specified in extras, which is guaranteed to not be
-     * null.
-     */
-    public abstract void onPerformSync(Bundle extras, SyncResult syncResult);
-
-    /**
-     * Override this function to indicated whether you want to support parallel syncs.
-     * <p>If you override and return true multiple threads will be spawned within your Service to
-     * handle each concurrent sync request.
-     *
-     * @return false to indicate that this service does not support parallel operations by default.
-     */
-    protected boolean parallelSyncsEnabled() {
-        return false;
-    }
-}
diff --git a/core/java/android/content/pm/ContainerEncryptionParams.java b/core/java/android/content/pm/ContainerEncryptionParams.java
index dd1332b..ab3aa27 100644
--- a/core/java/android/content/pm/ContainerEncryptionParams.java
+++ b/core/java/android/content/pm/ContainerEncryptionParams.java
@@ -16,7 +16,7 @@
 
 package android.content.pm;
 
-import android.annotation.PrivateApi;
+import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.TextUtils;
@@ -35,7 +35,7 @@
  * @deprecated encrypted containers are legacy.
  * @hide
  */
-@PrivateApi
+@SystemApi
 @Deprecated
 public class ContainerEncryptionParams implements Parcelable {
     protected static final String TAG = "ContainerEncryptionParams";
diff --git a/core/java/android/content/pm/ManifestDigest.java b/core/java/android/content/pm/ManifestDigest.java
index 943534f..1fbef7a 100644
--- a/core/java/android/content/pm/ManifestDigest.java
+++ b/core/java/android/content/pm/ManifestDigest.java
@@ -16,7 +16,7 @@
 
 package android.content.pm;
 
-import android.annotation.PrivateApi;
+import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.Slog;
@@ -37,7 +37,7 @@
  *
  * @hide
  */
-@PrivateApi
+@SystemApi
 public class ManifestDigest implements Parcelable {
     private static final String TAG = "ManifestDigest";
 
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index c5cd5c9..550c1f1 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -17,7 +17,7 @@
 package android.content.pm;
 
 import android.annotation.IntDef;
-import android.annotation.PrivateApi;
+import android.annotation.SystemApi;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.app.PackageInstallObserver;
@@ -370,7 +370,7 @@
      * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} on success.
      * @hide
      */
-    @PrivateApi
+    @SystemApi
     public static final int INSTALL_SUCCEEDED = 1;
 
     /**
@@ -379,7 +379,7 @@
      * already installed.
      * @hide
      */
-    @PrivateApi
+    @SystemApi
     public static final int INSTALL_FAILED_ALREADY_EXISTS = -1;
 
     /**
@@ -388,7 +388,7 @@
      * file is invalid.
      * @hide
      */
-    @PrivateApi
+    @SystemApi
     public static final int INSTALL_FAILED_INVALID_APK = -2;
 
     /**
@@ -397,7 +397,7 @@
      * is invalid.
      * @hide
      */
-    @PrivateApi
+    @SystemApi
     public static final int INSTALL_FAILED_INVALID_URI = -3;
 
     /**
@@ -406,7 +406,7 @@
      * service found that the device didn't have enough storage space to install the app.
      * @hide
      */
-    @PrivateApi
+    @SystemApi
     public static final int INSTALL_FAILED_INSUFFICIENT_STORAGE = -4;
 
     /**
@@ -415,7 +415,7 @@
      * package is already installed with the same name.
      * @hide
      */
-    @PrivateApi
+    @SystemApi
     public static final int INSTALL_FAILED_DUPLICATE_PACKAGE = -5;
 
     /**
@@ -424,7 +424,7 @@
      * the requested shared user does not exist.
      * @hide
      */
-    @PrivateApi
+    @SystemApi
     public static final int INSTALL_FAILED_NO_SHARED_USER = -6;
 
     /**
@@ -434,7 +434,7 @@
      * than the new package (and the old package's data was not removed).
      * @hide
      */
-    @PrivateApi
+    @SystemApi
     public static final int INSTALL_FAILED_UPDATE_INCOMPATIBLE = -7;
 
     /**
@@ -444,7 +444,7 @@
      * device and does not have matching signature.
      * @hide
      */
-    @PrivateApi
+    @SystemApi
     public static final int INSTALL_FAILED_SHARED_USER_INCOMPATIBLE = -8;
 
     /**
@@ -453,7 +453,7 @@
      * the new package uses a shared library that is not available.
      * @hide
      */
-    @PrivateApi
+    @SystemApi
     public static final int INSTALL_FAILED_MISSING_SHARED_LIBRARY = -9;
 
     /**
@@ -462,7 +462,7 @@
      * the new package uses a shared library that is not available.
      * @hide
      */
-    @PrivateApi
+    @SystemApi
     public static final int INSTALL_FAILED_REPLACE_COULDNT_DELETE = -10;
 
     /**
@@ -472,7 +472,7 @@
      * either because there was not enough storage or the validation failed.
      * @hide
      */
-    @PrivateApi
+    @SystemApi
     public static final int INSTALL_FAILED_DEXOPT = -11;
 
     /**
@@ -482,7 +482,7 @@
      * that required by the package.
      * @hide
      */
-    @PrivateApi
+    @SystemApi
     public static final int INSTALL_FAILED_OLDER_SDK = -12;
 
     /**
@@ -492,7 +492,7 @@
      * same authority as a provider already installed in the system.
      * @hide
      */
-    @PrivateApi
+    @SystemApi
     public static final int INSTALL_FAILED_CONFLICTING_PROVIDER = -13;
 
     /**
@@ -502,7 +502,7 @@
      * that required by the package.
      * @hide
      */
-    @PrivateApi
+    @SystemApi
     public static final int INSTALL_FAILED_NEWER_SDK = -14;
 
     /**
@@ -513,17 +513,17 @@
      * flag.
      * @hide
      */
-    @PrivateApi
+    @SystemApi
     public static final int INSTALL_FAILED_TEST_ONLY = -15;
 
     /**
      * Installation return code: this is passed to the {@link IPackageInstallObserver} by
      * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
      * the package being installed contains native code, but none that is
-     * compatible with the the device's CPU_ABI.
+     * compatible with the device's CPU_ABI.
      * @hide
      */
-    @PrivateApi
+    @SystemApi
     public static final int INSTALL_FAILED_CPU_ABI_INCOMPATIBLE = -16;
 
     /**
@@ -532,7 +532,7 @@
      * the new package uses a feature that is not available.
      * @hide
      */
-    @PrivateApi
+    @SystemApi
     public static final int INSTALL_FAILED_MISSING_FEATURE = -17;
 
     // ------ Errors related to sdcard
@@ -542,7 +542,7 @@
      * a secure container mount point couldn't be accessed on external media.
      * @hide
      */
-    @PrivateApi
+    @SystemApi
     public static final int INSTALL_FAILED_CONTAINER_ERROR = -18;
 
     /**
@@ -552,7 +552,7 @@
      * location.
      * @hide
      */
-    @PrivateApi
+    @SystemApi
     public static final int INSTALL_FAILED_INVALID_INSTALL_LOCATION = -19;
 
     /**
@@ -562,7 +562,7 @@
      * location because the media is not available.
      * @hide
      */
-    @PrivateApi
+    @SystemApi
     public static final int INSTALL_FAILED_MEDIA_UNAVAILABLE = -20;
 
     /**
@@ -571,7 +571,7 @@
      * the new package couldn't be installed because the verification timed out.
      * @hide
      */
-    @PrivateApi
+    @SystemApi
     public static final int INSTALL_FAILED_VERIFICATION_TIMEOUT = -21;
 
     /**
@@ -580,7 +580,7 @@
      * the new package couldn't be installed because the verification did not succeed.
      * @hide
      */
-    @PrivateApi
+    @SystemApi
     public static final int INSTALL_FAILED_VERIFICATION_FAILURE = -22;
 
     /**
@@ -589,7 +589,7 @@
      * the package changed from what the calling program expected.
      * @hide
      */
-    @PrivateApi
+    @SystemApi
     public static final int INSTALL_FAILED_PACKAGE_CHANGED = -23;
 
     /**
@@ -615,7 +615,7 @@
      * '.apk' extension.
      * @hide
      */
-    @PrivateApi
+    @SystemApi
     public static final int INSTALL_PARSE_FAILED_NOT_APK = -100;
 
     /**
@@ -624,7 +624,7 @@
      * if the parser was unable to retrieve the AndroidManifest.xml file.
      * @hide
      */
-    @PrivateApi
+    @SystemApi
     public static final int INSTALL_PARSE_FAILED_BAD_MANIFEST = -101;
 
     /**
@@ -633,7 +633,7 @@
      * if the parser encountered an unexpected exception.
      * @hide
      */
-    @PrivateApi
+    @SystemApi
     public static final int INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION = -102;
 
     /**
@@ -642,7 +642,7 @@
      * if the parser did not find any certificates in the .apk.
      * @hide
      */
-    @PrivateApi
+    @SystemApi
     public static final int INSTALL_PARSE_FAILED_NO_CERTIFICATES = -103;
 
     /**
@@ -651,7 +651,7 @@
      * if the parser found inconsistent certificates on the files in the .apk.
      * @hide
      */
-    @PrivateApi
+    @SystemApi
     public static final int INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES = -104;
 
     /**
@@ -661,7 +661,7 @@
      * files in the .apk.
      * @hide
      */
-    @PrivateApi
+    @SystemApi
     public static final int INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING = -105;
 
     /**
@@ -670,7 +670,7 @@
      * if the parser encountered a bad or missing package name in the manifest.
      * @hide
      */
-    @PrivateApi
+    @SystemApi
     public static final int INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME = -106;
 
     /**
@@ -679,7 +679,7 @@
      * if the parser encountered a bad shared user id name in the manifest.
      * @hide
      */
-    @PrivateApi
+    @SystemApi
     public static final int INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID = -107;
 
     /**
@@ -688,7 +688,7 @@
      * if the parser encountered some structural problem in the manifest.
      * @hide
      */
-    @PrivateApi
+    @SystemApi
     public static final int INSTALL_PARSE_FAILED_MANIFEST_MALFORMED = -108;
 
     /**
@@ -698,7 +698,7 @@
      * in the manifest.
      * @hide
      */
-    @PrivateApi
+    @SystemApi
     public static final int INSTALL_PARSE_FAILED_MANIFEST_EMPTY = -109;
 
     /**
@@ -707,7 +707,7 @@
      * if the system failed to install the package because of system issues.
      * @hide
      */
-    @PrivateApi
+    @SystemApi
     public static final int INSTALL_FAILED_INTERNAL_ERROR = -110;
 
     /**
@@ -1402,7 +1402,7 @@
      * The device supports managed profiles for enterprise users.
      */
     @SdkConstant(SdkConstantType.FEATURE)
-    public static final String FEATURE_MANAGEDPROFILES = "android.software.managedprofiles";
+    public static final String FEATURE_MANAGED_PROFILES = "android.software.managed_profiles";
 
     /**
      * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}:
@@ -1601,7 +1601,7 @@
      * <p>
      * Throws {@link NameNotFoundException} if a package with the given name
      * cannot be found on the system.
-     * 
+     *
      * @param packageName The name of the package to inspect.
      * @return Returns either a fully-qualified Intent that can be used to launch
      *         the main Leanback activity in the package, or null if the package
@@ -1615,7 +1615,7 @@
      * <p>
      * Throws {@link NameNotFoundException} if a package with the given name
      * cannot be found on the system.
-     * 
+     *
      * @param packageName The full name (i.e. com.google.apps.contacts) of the
      *            desired package.
      * @return Returns an int array of the assigned gids, or null if there are
@@ -2907,7 +2907,7 @@
      * instead.  This method will continue to be supported but the older observer interface
      * will not get additional failure details.
      */
-    // @PrivateApi
+    // @SystemApi
     public abstract void installPackage(
             Uri packageURI, IPackageInstallObserver observer, int flags,
             String installerPackageName);
@@ -2942,7 +2942,7 @@
      * continue to be supported but the older observer interface will not get additional failure
      * details.
      */
-    // @PrivateApi
+    // @SystemApi
     public abstract void installPackageWithVerification(Uri packageURI,
             IPackageInstallObserver observer, int flags, String installerPackageName,
             Uri verificationURI, ManifestDigest manifestDigest,
@@ -3071,7 +3071,7 @@
      * on the system for other users, also install it for the calling user.
      * @hide
      */
-    // @PrivateApi
+    // @SystemApi
     public abstract int installExistingPackage(String packageName)
             throws NameNotFoundException;
 
@@ -3161,7 +3161,7 @@
      *
      * @hide
      */
-    // @PrivateApi
+    // @SystemApi
     public abstract void deletePackage(
             String packageName, IPackageDeleteObserver observer, int flags);
 
@@ -3230,7 +3230,7 @@
      *
      * @hide
      */
-    // @PrivateApi
+    // @SystemApi
     public abstract void freeStorageAndNotify(long freeStorageSize, IPackageDataObserver observer);
 
     /**
@@ -3454,7 +3454,7 @@
 
 
     /**
-     * Return the the enabled setting for a package component (activity,
+     * Return the enabled setting for a package component (activity,
      * receiver, service, provider).  This returns the last value set by
      * {@link #setComponentEnabledSetting(ComponentName, int, int)}; in most
      * cases this value will be {@link #COMPONENT_ENABLED_STATE_DEFAULT} since
@@ -3492,14 +3492,14 @@
             int newState, int flags);
 
     /**
-     * Return the the enabled setting for an application.  This returns
+     * Return the enabled setting for an application. This returns
      * the last value set by
      * {@link #setApplicationEnabledSetting(String, int, int)}; in most
      * cases this value will be {@link #COMPONENT_ENABLED_STATE_DEFAULT} since
      * the value originally specified in the manifest has not been modified.
      *
-     * @param packageName The component to retrieve.
-     * @return Returns the current enabled state for the component.  May
+     * @param packageName The package name of the application to retrieve.
+     * @return Returns the current enabled state for the application.  May
      * be one of {@link #COMPONENT_ENABLED_STATE_ENABLED},
      * {@link #COMPONENT_ENABLED_STATE_DISABLED}, or
      * {@link #COMPONENT_ENABLED_STATE_DEFAULT}.  The last one means the
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index ed3f9aa..9625578 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -2239,9 +2239,7 @@
         }
 
         // First, check whether we have a cached version of this drawable
-        // that's valid for the specified theme. This may apply a theme to a
-        // cached drawable that has themeable attributes but was not previously
-        // themed.
+        // that was inflated against the specified theme.
         if (!mPreloading) {
             final Drawable cachedDrawable = getCachedDrawable(caches, key, theme);
             if (cachedDrawable != null) {
@@ -2267,8 +2265,8 @@
             dr = loadDrawableForCookie(value, id, theme);
         }
 
-        // If we were able to obtain a drawable, attempt to place it in the
-        // appropriate cache (e.g. no theme, themed, themeable).
+        // If we were able to obtain a drawable, store it in the appropriate
+        // cache (either preload or themed).
         if (dr != null) {
             dr.setChangingConfigurations(value.changingConfigurations);
             cacheDrawable(value, theme, isColorDrawable, caches, key, dr);
@@ -2376,7 +2374,7 @@
             ArrayMap<String, LongSparseArray<WeakReference<ConstantState>>> caches,
             long key, Theme theme) {
         synchronized (mAccessLock) {
-            final int themeKey = theme != null ? theme.mThemeResId : 0;
+            final String themeKey = theme != null ? theme.mKey : "";
             final LongSparseArray<WeakReference<ConstantState>> themedCache = caches.get(themeKey);
             if (themedCache != null) {
                 final Drawable themedDrawable = getCachedDrawableLocked(themedCache, key);
diff --git a/core/java/android/hardware/camera2/CameraCaptureSession.java b/core/java/android/hardware/camera2/CameraCaptureSession.java
index 7738d2d..5fd0f9b 100644
--- a/core/java/android/hardware/camera2/CameraCaptureSession.java
+++ b/core/java/android/hardware/camera2/CameraCaptureSession.java
@@ -54,7 +54,7 @@
 public abstract class CameraCaptureSession implements AutoCloseable {
 
     /**
-     * Get the camera device that this session is created for
+     * Get the camera device that this session is created for.
      */
     public abstract CameraDevice getDevice();
 
@@ -90,8 +90,9 @@
      *
      * @throws CameraAccessException if the camera device is no longer connected or has
      *                               encountered a fatal error
-     * @throws IllegalStateException if this session is no longer active, either because a new
-     *                               session has been created or the camera device has been closed.
+     * @throws IllegalStateException if this session is no longer active, either because the session
+     *                               was explicitly closed, a new session has been created
+     *                               or the camera device has been closed.
      * @throws IllegalArgumentException if the request targets Surfaces that are not configured as
      *                                  outputs for this session. Or if the handler is null, the
      *                                  listener is not null, and the calling thread has no looper.
@@ -99,6 +100,7 @@
      * @see #captureBurst
      * @see #setRepeatingRequest
      * @see #setRepeatingBurst
+     * @see #abortCaptures
      */
     public abstract int capture(CaptureRequest request, CaptureListener listener, Handler handler)
             throws CameraAccessException;
@@ -132,8 +134,9 @@
      *
      * @throws CameraAccessException if the camera device is no longer connected or has
      *                               encountered a fatal error
-     * @throws IllegalStateException if this session is no longer active, either because a new
-     *                               session has been created or the camera device has been closed.
+     * @throws IllegalStateException if this session is no longer active, either because the session
+     *                               was explicitly closed, a new session has been created
+     *                               or the camera device has been closed.
      * @throws IllegalArgumentException If the requests target Surfaces not currently configured as
      *                                  outputs. Or if the handler is null, the listener is not
      *                                  null, and the calling thread has no looper.
@@ -141,6 +144,7 @@
      * @see #capture
      * @see #setRepeatingRequest
      * @see #setRepeatingBurst
+     * @see #abortCaptures
      */
     public abstract int captureBurst(List<CaptureRequest> requests, CaptureListener listener,
             Handler handler) throws CameraAccessException;
@@ -188,11 +192,13 @@
      *
      * @throws CameraAccessException if the camera device is no longer connected or has
      *                               encountered a fatal error
-     * @throws IllegalStateException if this session is no longer active, either because a new
-     *                               session has been created or the camera device has been closed.
+     * @throws IllegalStateException if this session is no longer active, either because the session
+     *                               was explicitly closed, a new session has been created
+     *                               or the camera device has been closed.
      * @throws IllegalArgumentException If the requests reference Surfaces that are not currently
      *                                  configured as outputs. Or if the handler is null, the
      *                                  listener is not null, and the calling thread has no looper.
+     *                                  Or if no requests were passed in.
      *
      * @see #capture
      * @see #captureBurst
@@ -246,11 +252,13 @@
      *
      * @throws CameraAccessException if the camera device is no longer connected or has
      *                               encountered a fatal error
-     * @throws IllegalStateException if this session is no longer active, either because a new
-     *                               session has been created or the camera device has been closed.
+     * @throws IllegalStateException if this session is no longer active, either because the session
+     *                               was explicitly closed, a new session has been created
+     *                               or the camera device has been closed.
      * @throws IllegalArgumentException If the requests reference Surfaces not currently configured
      *                                  as outputs. Or if the handler is null, the listener is not
-     *                                  null, and the calling thread has no looper.
+     *                                  null, and the calling thread has no looper. Or if no
+     *                                  requests were passed in.
      *
      * @see #capture
      * @see #captureBurst
@@ -274,8 +282,9 @@
      *
      * @throws CameraAccessException if the camera device is no longer connected or has
      *                               encountered a fatal error
-     * @throws IllegalStateException if this session is no longer active, either because a new
-     *                               session has been created or the camera device has been closed.
+     * @throws IllegalStateException if this session is no longer active, either because the session
+     *                               was explicitly closed, a new session has been created
+     *                               or the camera device has been closed.
      *
      * @see #setRepeatingRequest
      * @see #setRepeatingBurst
@@ -308,8 +317,9 @@
      *
      * @throws CameraAccessException if the camera device is no longer connected or has
      *                               encountered a fatal error
-     * @throws IllegalStateException if this session is no longer active, either because a new
-     *                               session has been created or the camera device has been closed.
+     * @throws IllegalStateException if this session is no longer active, either because the session
+     *                               was explicitly closed, a new session has been created
+     *                               or the camera device has been closed.
      *
      * @see #setRepeatingRequest
      * @see #setRepeatingBurst
@@ -320,8 +330,8 @@
     /**
      * Close this capture session asynchronously.
      *
-     * <p>Closing a session frees up the target output Surfaces of the session for reuse with either a
-     * new session, or to other APIs that can draw to Surfaces.</p>
+     * <p>Closing a session frees up the target output Surfaces of the session for reuse with either
+     * a new session, or to other APIs that can draw to Surfaces.</p>
      *
      * <p>Note that creating a new capture session with {@link CameraDevice#createCaptureSession}
      * will close any existing capture session automatically, and call the older session listener's
@@ -334,6 +344,8 @@
      * However, any in-progress capture requests submitted to the session will be completed as
      * normal; once all captures have completed and the session has been torn down,
      * {@link StateListener#onClosed} will be called.</p>
+     *
+     * <p>Closing a session is idempotent; closing more than once has no effect.</p>
      */
     @Override
     public abstract void close();
@@ -358,6 +370,7 @@
          * <p>If the camera device configuration fails, then {@link #onConfigureFailed} will
          * be invoked instead of this callback.</p>
          *
+         * @param session the session returned by {@link CameraDevice#createCaptureSession}
          */
         public abstract void onConfigured(CameraCaptureSession session);
 
@@ -371,6 +384,8 @@
          * callback is invoked will throw an IllegalStateException. Any capture requests submitted
          * to the session prior to this callback will be discarded and will not produce any
          * callbacks on their listeners.</p>
+         *
+         * @param session the session returned by {@link CameraDevice#createCaptureSession}
          */
         public abstract void onConfigureFailed(CameraCaptureSession session);
 
@@ -384,6 +399,8 @@
          * <p>Otherwise, this callback will be invoked any time the session finishes processing
          * all of its active capture requests, and no repeating request or burst is set up.</p>
          *
+         * @param session the session returned by {@link CameraDevice#createCaptureSession}
+         *
          */
         public void onReady(CameraCaptureSession session) {
             // default empty implementation
@@ -398,6 +415,8 @@
          *
          * <p>If the session runs out of capture requests to process and calls {@link #onReady},
          * then this callback will be invoked again once new requests are submitted for capture.</p>
+         *
+         * @param session the session returned by {@link CameraDevice#createCaptureSession}
          */
         public void onActive(CameraCaptureSession session) {
             // default empty implementation
@@ -414,6 +433,8 @@
          * any repeating requests or bursts are stopped (as if {@link #stopRepeating()} was called).
          * However, any in-progress capture requests submitted to the session will be completed
          * as normal.</p>
+         *
+         * @param session the session returned by {@link CameraDevice#createCaptureSession}
          */
         public void onClosed(CameraCaptureSession session) {
             // default empty implementation
@@ -466,13 +487,13 @@
          *
          * <p>The default implementation of this method does nothing.</p>
          *
-         * @param camera the CameraDevice sending the callback
+         * @param session the session returned by {@link CameraDevice#createCaptureSession}
          * @param request the request for the capture that just begun
          * @param timestamp the timestamp at start of capture, in nanoseconds.
          *
          * @see android.media.MediaActionSound
          */
-        public void onCaptureStarted(CameraDevice camera,
+        public void onCaptureStarted(CameraCaptureSession session,
                 CaptureRequest request, long timestamp) {
             // default empty implementation
         }
@@ -490,7 +511,7 @@
          *
          * <p>The default implementation of this method does nothing.</p>
          *
-         * @param camera The CameraDevice sending the callback.
+         * @param session the session returned by {@link CameraDevice#createCaptureSession}
          * @param request The request that was given to the CameraDevice
          * @param result The partial output metadata from the capture, which
          * includes a subset of the CaptureResult fields.
@@ -502,7 +523,7 @@
          *
          * @hide
          */
-        public void onCapturePartial(CameraDevice camera,
+        public void onCapturePartial(CameraCaptureSession session,
                 CaptureRequest request, CaptureResult result) {
             // default empty implementation
         }
@@ -533,7 +554,7 @@
          *
          * <p>The default implementation of this method does nothing.</p>
          *
-         * @param camera The CameraDevice sending the callback.
+         * @param session the session returned by {@link CameraDevice#createCaptureSession}
          * @param request The request that was given to the CameraDevice
          * @param partialResult The partial output metadata from the capture, which
          * includes a subset of the {@link TotalCaptureResult} fields.
@@ -543,7 +564,7 @@
          * @see #setRepeatingRequest
          * @see #setRepeatingBurst
          */
-        public void onCaptureProgressed(CameraDevice camera,
+        public void onCaptureProgressed(CameraCaptureSession session,
                 CaptureRequest request, CaptureResult partialResult) {
             // default empty implementation
         }
@@ -561,7 +582,7 @@
          *
          * <p>The default implementation of this method does nothing.</p>
          *
-         * @param camera The CameraDevice sending the callback.
+         * @param session the session returned by {@link CameraDevice#createCaptureSession}
          * @param request The request that was given to the CameraDevice
          * @param result The total output metadata from the capture, including the
          * final capture parameters and the state of the camera system during
@@ -572,7 +593,7 @@
          * @see #setRepeatingRequest
          * @see #setRepeatingBurst
          */
-        public void onCaptureCompleted(CameraDevice camera,
+        public void onCaptureCompleted(CameraCaptureSession session,
                 CaptureRequest request, TotalCaptureResult result) {
             // default empty implementation
         }
@@ -588,8 +609,8 @@
          *
          * <p>The default implementation of this method does nothing.</p>
          *
-         * @param camera
-         *            The CameraDevice sending the callback.
+         * @param session
+         *            The session returned by {@link CameraDevice#createCaptureSession}
          * @param request
          *            The request that was given to the CameraDevice
          * @param failure
@@ -601,7 +622,7 @@
          * @see #setRepeatingRequest
          * @see #setRepeatingBurst
          */
-        public void onCaptureFailed(CameraDevice camera,
+        public void onCaptureFailed(CameraCaptureSession session,
                 CaptureRequest request, CaptureFailure failure) {
             // default empty implementation
         }
@@ -617,8 +638,8 @@
          *
          * <p>The default implementation does nothing.</p>
          *
-         * @param camera
-         *            The CameraDevice sending the callback.
+         * @param session
+         *            The session returned by {@link CameraDevice#createCaptureSession}
          * @param sequenceId
          *            A sequence ID returned by the {@link #capture} family of functions.
          * @param frameNumber
@@ -631,7 +652,7 @@
          * @see CaptureFailure#getSequenceId()
          * @see #onCaptureSequenceAborted
          */
-        public void onCaptureSequenceCompleted(CameraDevice camera,
+        public void onCaptureSequenceCompleted(CameraCaptureSession session,
                 int sequenceId, long frameNumber) {
             // default empty implementation
         }
@@ -649,8 +670,8 @@
          *
          * <p>The default implementation does nothing.</p>
          *
-         * @param camera
-         *            The CameraDevice sending the callback.
+         * @param session
+         *            The session returned by {@link CameraDevice#createCaptureSession}
          * @param sequenceId
          *            A sequence ID returned by the {@link #capture} family of functions.
          *
@@ -660,7 +681,7 @@
          * @see CaptureFailure#getSequenceId()
          * @see #onCaptureSequenceCompleted
          */
-        public void onCaptureSequenceAborted(CameraDevice camera,
+        public void onCaptureSequenceAborted(CameraCaptureSession session,
                 int sequenceId) {
             // default empty implementation
         }
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 2f5b4fe..08cfc87 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -751,6 +751,7 @@
      * <p>For example, for Zero Shutter Lag (ZSL) still capture use case, the input
      * stream image format will be RAW_OPAQUE, the associated output stream image format
      * should be JPEG.</p>
+     * @hide
      */
     public static final Key<Integer> REQUEST_MAX_NUM_INPUT_STREAMS =
             new Key<Integer>("android.request.maxNumInputStreams", int.class);
@@ -810,6 +811,7 @@
      * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} <code>==</code> FULL devices:</p>
      * <ul>
      * <li>MANUAL_SENSOR</li>
+     * <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>
@@ -973,7 +975,7 @@
      * <p>The mapping of image formats that are supported by this
      * camera device for input streams, to their corresponding output formats.</p>
      * <p>All camera devices with at least 1
-     * {@link CameraCharacteristics#REQUEST_MAX_NUM_INPUT_STREAMS android.request.maxNumInputStreams} will have at least one
+     * android.request.maxNumInputStreams will have at least one
      * available input format.</p>
      * <p>The camera device will support the following map of formats,
      * if its dependent capability is supported:</p>
@@ -1020,8 +1022,6 @@
      * <p>Attempting to configure an input stream with output streams not
      * listed as available in this map is not valid.</p>
      * <p>TODO: typedef to ReprocessFormatMap</p>
-     *
-     * @see CameraCharacteristics#REQUEST_MAX_NUM_INPUT_STREAMS
      * @hide
      */
     public static final Key<int[]> SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP =
@@ -1033,8 +1033,6 @@
      * (i.e. format, width, height, output/input stream).</p>
      * <p>The configurations are listed as <code>(format, width, height, input?)</code>
      * tuples.</p>
-     * <p>All camera devices will support sensor maximum resolution (defined by
-     * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}) for the JPEG format.</p>
      * <p>For a given use case, the actual maximum supported resolution
      * may be lower than what is listed here, depending on the destination
      * Surface for the image data. For example, for recording video,
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index 6f5099b..e9213c5 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -24,7 +24,7 @@
 import java.util.List;
 
 /**
- * <p>The CameraDevice class is an interface to a single camera connected to an
+ * <p>The CameraDevice class is a representation of a single camera connected to an
  * Android device, allowing for fine-grain control of image capture and
  * post-processing at high frame rates.</p>
  *
@@ -46,7 +46,7 @@
  * @see CameraManager#openCamera
  * @see android.Manifest.permission#CAMERA
  */
-public interface CameraDevice extends AutoCloseable {
+public abstract class CameraDevice implements AutoCloseable {
 
     /**
      * Create a request suitable for a camera preview window. Specifically, this
@@ -127,7 +127,7 @@
      * @see CameraManager#getCameraCharacteristics
      * @see CameraManager#getCameraIdList
      */
-    public String getId();
+    public abstract String getId();
 
     /**
      * <p>Set up a new output set of Surfaces for the camera device.</p>
@@ -244,7 +244,8 @@
      * @see StreamConfigurationMap#getOutputSizes(Class)
      * @deprecated Use {@link #createCaptureSession} instead
      */
-    public void configureOutputs(List<Surface> outputs) throws CameraAccessException;
+    @Deprecated
+    public abstract void configureOutputs(List<Surface> outputs) throws CameraAccessException;
 
     /**
      * <p>Create a new camera capture session by providing the target output set of Surfaces to the
@@ -357,7 +358,7 @@
      * @see StreamConfigurationMap#getOutputSizes(int)
      * @see StreamConfigurationMap#getOutputSizes(Class)
      */
-    public void createCaptureSession(List<Surface> outputs,
+    public abstract void createCaptureSession(List<Surface> outputs,
             CameraCaptureSession.StateListener listener, Handler handler)
             throws CameraAccessException;
 
@@ -386,7 +387,7 @@
      * @see #TEMPLATE_VIDEO_SNAPSHOT
      * @see #TEMPLATE_MANUAL
      */
-    public CaptureRequest.Builder createCaptureRequest(int templateType)
+    public abstract CaptureRequest.Builder createCaptureRequest(int templateType)
             throws CameraAccessException;
 
     /**
@@ -432,7 +433,8 @@
      * @see #setRepeatingBurst
      * @deprecated Use {@link CameraCaptureSession} instead
      */
-    public int capture(CaptureRequest request, CaptureListener listener, Handler handler)
+    @Deprecated
+    public abstract int capture(CaptureRequest request, CaptureListener listener, Handler handler)
             throws CameraAccessException;
 
     /**
@@ -470,14 +472,16 @@
      *                               or the camera device has been closed.
      * @throws IllegalArgumentException If the requests target Surfaces not
      * currently configured as outputs. Or if the handler is null, the listener
-     * is not null, and the calling thread has no looper.
+     * is not null, and the calling thread has no looper. Or if no requests were
+     * passed in.
      *
      * @see #capture
      * @see #setRepeatingRequest
      * @see #setRepeatingBurst
      * @deprecated Use {@link CameraCaptureSession} instead
      */
-    public int captureBurst(List<CaptureRequest> requests, CaptureListener listener,
+    @Deprecated
+    public abstract int captureBurst(List<CaptureRequest> requests, CaptureListener listener,
             Handler handler) throws CameraAccessException;
 
     /**
@@ -536,7 +540,8 @@
      * @see #flush
      * @deprecated Use {@link CameraCaptureSession} instead
      */
-    public int setRepeatingRequest(CaptureRequest request, CaptureListener listener,
+    @Deprecated
+    public abstract int setRepeatingRequest(CaptureRequest request, CaptureListener listener,
             Handler handler) throws CameraAccessException;
 
     /**
@@ -586,7 +591,8 @@
      *                               or the camera device has been closed.
      * @throws IllegalArgumentException If the requests reference Surfaces not
      * currently configured as outputs. Or if the handler is null, the listener
-     * is not null, and the calling thread has no looper.
+     * is not null, and the calling thread has no looper. Or if no requests were
+     * passed in.
      *
      * @see #capture
      * @see #captureBurst
@@ -595,7 +601,8 @@
      * @see #flush
      * @deprecated Use {@link CameraCaptureSession} instead
      */
-    public int setRepeatingBurst(List<CaptureRequest> requests, CaptureListener listener,
+    @Deprecated
+    public abstract int setRepeatingBurst(List<CaptureRequest> requests, CaptureListener listener,
             Handler handler) throws CameraAccessException;
 
     /**
@@ -620,7 +627,8 @@
      * @see StateListener#onIdle
      * @deprecated Use {@link CameraCaptureSession} instead
      */
-    public void stopRepeating() throws CameraAccessException;
+    @Deprecated
+    public abstract void stopRepeating() throws CameraAccessException;
 
     /**
      * Flush all captures currently pending and in-progress as fast as
@@ -657,7 +665,8 @@
      * @see #configureOutputs
      * @deprecated Use {@link CameraCaptureSession} instead
      */
-    public void flush() throws CameraAccessException;
+    @Deprecated
+    public abstract void flush() throws CameraAccessException;
 
     /**
      * Close the connection to this camera device as quickly as possible.
@@ -675,7 +684,7 @@
      *
      */
     @Override
-    public void close();
+    public abstract void close();
 
     /**
      * <p>A listener for tracking the progress of a {@link CaptureRequest}
@@ -691,6 +700,7 @@
      * @see #setRepeatingBurst
      * @deprecated Use {@link CameraCaptureSession} instead
      */
+    @Deprecated
     public static abstract class CaptureListener {
 
         /**
@@ -1042,6 +1052,7 @@
          * @param camera the camera device has that become unconfigured
          * @deprecated Use {@link CameraCaptureSession.StateListener} instead.
          */
+        @Deprecated
         public void onUnconfigured(CameraDevice camera) {
             // Default empty implementation
         }
@@ -1072,6 +1083,7 @@
          * @see CameraDevice#setRepeatingRequest
          * @deprecated Use {@link CameraCaptureSession.StateListener} instead.
          */
+        @Deprecated
         public void onActive(CameraDevice camera) {
             // Default empty implementation
         }
@@ -1106,6 +1118,7 @@
          * @see CameraDevice#flush
          * @deprecated Use {@link CameraCaptureSession.StateListener} instead.
          */
+        @Deprecated
         public void onBusy(CameraDevice camera) {
             // Default empty implementation
         }
@@ -1154,6 +1167,7 @@
          * @see CameraDevice#flush
          * @deprecated Use {@link CameraCaptureSession.StateListener} instead.
          */
+        @Deprecated
         public void onIdle(CameraDevice camera) {
             // Default empty implementation
         }
@@ -1216,4 +1230,10 @@
          */
         public abstract void onError(CameraDevice camera, int error); // Must implement
     }
+
+    /**
+     * To be inherited by android.hardware.camera2.* code only.
+     * @hide
+     */
+    public CameraDevice() {}
 }
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index 4a89fe7..7c0f37e6 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -225,10 +225,10 @@
 
             synchronized (mLock) {
 
-                ICameraDeviceUser cameraUser;
+                ICameraDeviceUser cameraUser = null;
 
-                android.hardware.camera2.impl.CameraDevice deviceImpl =
-                        new android.hardware.camera2.impl.CameraDevice(
+                android.hardware.camera2.impl.CameraDeviceImpl deviceImpl =
+                        new android.hardware.camera2.impl.CameraDeviceImpl(
                                 cameraId,
                                 listener,
                                 handler,
@@ -247,8 +247,23 @@
                         // Use legacy camera implementation for HAL1 devices
                         Log.i(TAG, "Using legacy camera HAL.");
                         cameraUser = CameraDeviceUserShim.connectBinderShim(callbacks, id);
+                    } else if (e.getReason() == CameraAccessException.CAMERA_IN_USE ||
+                            e.getReason() == CameraAccessException.MAX_CAMERAS_IN_USE ||
+                            e.getReason() == CameraAccessException.CAMERA_DISABLED ||
+                            e.getReason() == CameraAccessException.CAMERA_DISCONNECTED ||
+                            e.getReason() == CameraAccessException.CAMERA_ERROR) {
+                        // Received one of the known connection errors
+                        // The remote camera device cannot be connected to, so
+                        // set the local camera to the startup error state
+                        deviceImpl.setRemoteFailure(e);
+
+                        if (e.getReason() == CameraAccessException.CAMERA_DISABLED ||
+                                e.getReason() == CameraAccessException.CAMERA_DISCONNECTED) {
+                            // Per API docs, these failures call onError and throw
+                            throw e;
+                        }
                     } else {
-                        // Rethrow otherwise
+                        // Unexpected failure - rethrow
                         throw e;
                     }
                 }
@@ -298,7 +313,7 @@
      *
      * <p>If opening the camera device fails, then the device listener's
      * {@link CameraDevice.StateListener#onError onError} method will be called, and subsequent
-     * calls on the camera device will throw an {@link IllegalStateException}.</p>
+     * calls on the camera device will throw a {@link CameraAccessException}.</p>
      *
      * @param cameraId
      *             The unique identifier of the camera device to open
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index b3e165e..94a5a79 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -340,6 +340,7 @@
      * (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
      */
     public static final int REQUEST_AVAILABLE_CAPABILITIES_ZSL = 4;
diff --git a/core/java/android/hardware/camera2/DngCreator.java b/core/java/android/hardware/camera2/DngCreator.java
index 54568ed..3e3303c 100644
--- a/core/java/android/hardware/camera2/DngCreator.java
+++ b/core/java/android/hardware/camera2/DngCreator.java
@@ -22,12 +22,16 @@
 import android.location.Location;
 import android.media.ExifInterface;
 import android.media.Image;
+import android.os.SystemClock;
 import android.util.Size;
 
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.nio.ByteBuffer;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.TimeZone;
 
 /**
  * The {@link DngCreator} class provides functions to write raw pixel data as a DNG file.
@@ -55,6 +59,7 @@
  */
 public final class DngCreator implements AutoCloseable {
 
+    private static final String TAG = "DngCreator";
     /**
      * Create a new DNG object.
      *
@@ -75,7 +80,25 @@
         if (characteristics == null || metadata == null) {
             throw new NullPointerException("Null argument to DngCreator constructor");
         }
-        nativeInit(characteristics.getNativeCopy(), metadata.getNativeCopy());
+
+        // Find current time
+        long currentTime = System.currentTimeMillis();
+
+        // Find boot time
+        long bootTimeMillis = currentTime - SystemClock.elapsedRealtime();
+
+        // Find capture time (nanos since boot)
+        Long timestamp = metadata.get(CaptureResult.SENSOR_TIMESTAMP);
+        long captureTime = currentTime;
+        if (timestamp != null) {
+            captureTime = timestamp / 1000000 + bootTimeMillis;
+        }
+
+        // Format for metadata
+        String formattedCaptureTime = sDateTimeStampFormat.format(captureTime);
+
+        nativeInit(characteristics.getNativeCopy(), metadata.getNativeCopy(),
+                formattedCaptureTime);
     }
 
     /**
@@ -98,6 +121,7 @@
      *                      <li>{@link android.media.ExifInterface#ORIENTATION_ROTATE_270}</li>
      *                    </ul>
      * @return this {@link #DngCreator} object.
+     * @hide
      */
     public DngCreator setOrientation(int orientation) {
 
@@ -124,6 +148,7 @@
      *
      * @param pixels a {@link android.graphics.Bitmap} of pixel data.
      * @return this {@link #DngCreator} object.
+     * @hide
      */
     public DngCreator setThumbnail(Bitmap pixels) {
         if (pixels == null) {
@@ -157,6 +182,7 @@
      * @param pixels an {@link android.media.Image} object with the format
      *               {@link android.graphics.ImageFormat#YUV_420_888}.
      * @return this {@link #DngCreator} object.
+     * @hide
      */
     public DngCreator setThumbnail(Image pixels) {
         if (pixels == null) {
@@ -193,6 +219,7 @@
      *
      * @throws java.lang.IllegalArgumentException if the given location object doesn't
      *          contain enough information to set location metadata.
+     * @hide
      */
     public DngCreator setLocation(Location location) {
         /*TODO*/
@@ -208,6 +235,7 @@
      *
      * @param description the user description string.
      * @return this {@link #DngCreator} object.
+     * @hide
      */
     public DngCreator setDescription(String description) {
         /*TODO*/
@@ -240,6 +268,7 @@
      * @throws java.lang.IllegalStateException if not enough metadata information has been
      *          set to write a well-formatted DNG file.
      * @throws java.lang.IllegalArgumentException if the size passed in does not match the
+     * @hide
      */
     public void writeInputStream(OutputStream dngOutput, Size size, InputStream pixels, long offset)
             throws IOException {
@@ -274,6 +303,7 @@
      * @throws IOException if an error was encountered in the input or output stream.
      * @throws java.lang.IllegalStateException if not enough metadata information has been
      *          set to write a well-formatted DNG file.
+     * @hide
      */
     public void writeByteBuffer(OutputStream dngOutput, Size size, ByteBuffer pixels, long offset)
             throws IOException {
@@ -329,6 +359,13 @@
         }
     }
 
+    private static final String TIFF_DATETIME_FORMAT = "yyyy:MM:dd kk:mm:ss";
+    private static final DateFormat sDateTimeStampFormat =
+            new SimpleDateFormat(TIFF_DATETIME_FORMAT);
+
+    static {
+        sDateTimeStampFormat.setTimeZone(TimeZone.getDefault());
+    }
     /**
      * This field is used by native code, do not access or modify.
      */
@@ -337,7 +374,8 @@
     private static native void nativeClassInit();
 
     private synchronized native void nativeInit(CameraMetadataNative nativeCharacteristics,
-                                                CameraMetadataNative nativeResult);
+                                                CameraMetadataNative nativeResult,
+                                                String captureTime);
 
     private synchronized native void nativeDestroy();
 
diff --git a/core/java/android/hardware/camera2/dispatch/ArgumentReplacingDispatcher.java b/core/java/android/hardware/camera2/dispatch/ArgumentReplacingDispatcher.java
new file mode 100644
index 0000000..866f370
--- /dev/null
+++ b/core/java/android/hardware/camera2/dispatch/ArgumentReplacingDispatcher.java
@@ -0,0 +1,85 @@
+/*
+ * 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.hardware.camera2.dispatch;
+
+import java.lang.reflect.Method;
+
+import static com.android.internal.util.Preconditions.*;
+
+/**
+ * A dispatcher that replaces one argument with another; replaces any argument at an index
+ * with another argument.
+ *
+ * <p>For example, we can override an {@code void onSomething(int x)} calls to have {@code x} always
+ * equal to 1. Or, if using this with a duck typing dispatcher, we could even overwrite {@code x} to
+ * be something
+ * that's not an {@code int}.</p>
+ *
+ * @param <T>
+ *          source dispatch type, whose methods with {@link #dispatch} will be called
+ * @param <TArg>
+ *          argument replacement type, args in {@link #dispatch} matching {@code argumentIndex}
+ *          will be overriden to objects of this type
+ */
+public class ArgumentReplacingDispatcher<T, TArg> implements Dispatchable<T> {
+
+    private final Dispatchable<T> mTarget;
+    private final int mArgumentIndex;
+    private final TArg mReplaceWith;
+
+    /**
+     * Create a new argument replacing dispatcher; dispatches are forwarded to {@code target}
+     * after the argument is replaced.
+     *
+     * <p>For example, if a method {@code onAction(T1 a, Integer b, T2 c)} is invoked, and we wanted
+     * to replace all occurrences of {@code b} with {@code 0xDEADBEEF}, we would set
+     * {@code argumentIndex = 1} and {@code replaceWith = 0xDEADBEEF}.</p>
+     *
+     * <p>If a method dispatched has less arguments than {@code argumentIndex}, it is
+     * passed through with the arguments unchanged.</p>
+     *
+     * @param target destination dispatch type, methods will be redirected to this dispatcher
+     * @param argumentIndex the numeric index of the argument {@code >= 0}
+     * @param replaceWith arguments matching {@code argumentIndex} will be replaced with this object
+     */
+    public ArgumentReplacingDispatcher(Dispatchable<T> target, int argumentIndex,
+            TArg replaceWith) {
+        mTarget = checkNotNull(target, "target must not be null");
+        mArgumentIndex = checkArgumentNonnegative(argumentIndex,
+                "argumentIndex must not be negative");
+        mReplaceWith = checkNotNull(replaceWith, "replaceWith must not be null");
+    }
+
+    @Override
+    public Object dispatch(Method method, Object[] args) throws Throwable {
+
+        if (args.length > mArgumentIndex) {
+            args = arrayCopy(args); // don't change in-place since it can affect upstream dispatches
+            args[mArgumentIndex] = mReplaceWith;
+        }
+
+        return mTarget.dispatch(method, args);
+    }
+
+    private static Object[] arrayCopy(Object[] array) {
+        int length = array.length;
+        Object[] newArray = new Object[length];
+        for (int i = 0; i < length; ++i) {
+            newArray[i] = array[i];
+        }
+        return newArray;
+    }
+}
diff --git a/core/java/android/hardware/camera2/dispatch/BroadcastDispatcher.java b/core/java/android/hardware/camera2/dispatch/BroadcastDispatcher.java
new file mode 100644
index 0000000..fe575b2
--- /dev/null
+++ b/core/java/android/hardware/camera2/dispatch/BroadcastDispatcher.java
@@ -0,0 +1,64 @@
+/*
+ * 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.hardware.camera2.dispatch;
+
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.List;
+
+import static com.android.internal.util.Preconditions.*;
+
+/**
+ * Broadcast a single dispatch into multiple other dispatchables.
+ *
+ * <p>Every time {@link #dispatch} is invoked, all the broadcast targets will
+ * see the same dispatch as well. The first target's return value is returned.</p>
+ *
+ * <p>This enables a single listener to be converted into a multi-listener.</p>
+ */
+public class BroadcastDispatcher<T> implements Dispatchable<T> {
+
+    private final List<Dispatchable<T>> mDispatchTargets;
+
+    /**
+     * Create a broadcast dispatcher from the supplied dispatch targets.
+     *
+     * @param dispatchTargets one or more targets to dispatch to
+     */
+    @SafeVarargs
+    public BroadcastDispatcher(Dispatchable<T>... dispatchTargets) {
+        mDispatchTargets = Arrays.asList(
+                checkNotNull(dispatchTargets, "dispatchTargets must not be null"));
+    }
+
+    @Override
+    public Object dispatch(Method method, Object[] args) throws Throwable {
+        Object result = null;
+        boolean gotResult = false;
+
+        for (Dispatchable<T> dispatchTarget : mDispatchTargets) {
+            Object localResult = dispatchTarget.dispatch(method, args);
+
+            if (!gotResult) {
+                gotResult = true;
+                result = localResult;
+            }
+        }
+
+        return result;
+    }
+}
diff --git a/core/java/android/hardware/camera2/dispatch/Dispatchable.java b/core/java/android/hardware/camera2/dispatch/Dispatchable.java
new file mode 100644
index 0000000..753103f
--- /dev/null
+++ b/core/java/android/hardware/camera2/dispatch/Dispatchable.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.camera2.dispatch;
+
+import java.lang.reflect.Method;
+
+/**
+ * Dynamically dispatch a method and its argument to some object.
+ *
+ * <p>This can be used to intercept method calls and do work around them, redirect work,
+ * or block calls entirely.</p>
+ */
+public interface Dispatchable<T> {
+    /**
+     * Dispatch the method and arguments to this object.
+     * @param method a method defined in class {@code T}
+     * @param args arguments corresponding to said {@code method}
+     * @return the object returned when invoking {@code method}
+     * @throws Throwable any exception that might have been raised while invoking the method
+     */
+    public Object dispatch(Method method, Object[] args) throws Throwable;
+}
diff --git a/core/java/android/hardware/camera2/dispatch/DuckTypingDispatcher.java b/core/java/android/hardware/camera2/dispatch/DuckTypingDispatcher.java
new file mode 100644
index 0000000..75f97e4
--- /dev/null
+++ b/core/java/android/hardware/camera2/dispatch/DuckTypingDispatcher.java
@@ -0,0 +1,55 @@
+/*
+ * 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.hardware.camera2.dispatch;
+
+
+import java.lang.reflect.Method;
+
+import static com.android.internal.util.Preconditions.*;
+
+/**
+ * Duck typing dispatcher; converts dispatch methods calls from one class to another by
+ * looking up equivalently methods at runtime by name.
+ *
+ * <p>For example, if two types have identical method names and arguments, but
+ * are not subclasses/subinterfaces of each other, this dispatcher will allow calls to be
+ * made from one type to the other.</p>
+ *
+ * @param <TFrom> source dispatch type, whose methods with {@link #dispatch} will be called
+ * @param <T> destination dispatch type, methods will be converted to the class of {@code T}
+ */
+public class DuckTypingDispatcher<TFrom, T> implements Dispatchable<TFrom> {
+
+    private final MethodNameInvoker<T> mDuck;
+
+    /**
+     * Create a new duck typing dispatcher.
+     *
+     * @param target destination dispatch type, methods will be redirected to this dispatcher
+     * @param targetClass destination dispatch class, methods will be converted to this class's
+     */
+    public DuckTypingDispatcher(Dispatchable<T> target, Class<T> targetClass) {
+        checkNotNull(targetClass, "targetClass must not be null");
+        checkNotNull(target, "target must not be null");
+
+        mDuck = new MethodNameInvoker<T>(target, targetClass);
+    }
+
+    @Override
+    public Object dispatch(Method method, Object[] args) {
+        return mDuck.invoke(method.getName(), args);
+    }
+}
diff --git a/core/java/android/hardware/camera2/dispatch/HandlerDispatcher.java b/core/java/android/hardware/camera2/dispatch/HandlerDispatcher.java
new file mode 100644
index 0000000..f8e9d49
--- /dev/null
+++ b/core/java/android/hardware/camera2/dispatch/HandlerDispatcher.java
@@ -0,0 +1,85 @@
+/*
+ * 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.hardware.camera2.dispatch;
+
+import android.hardware.camera2.utils.UncheckedThrow;
+import android.os.Handler;
+import android.util.Log;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import static com.android.internal.util.Preconditions.*;
+
+/**
+ * Forward all interface calls into a handler by posting it as a {@code Runnable}.
+ *
+ * <p>All calls will return immediately; functions with return values will return a default
+ * value of {@code null}, {@code 0}, or {@code false} where that value is legal.</p>
+ *
+ * <p>Any exceptions thrown on the handler while trying to invoke a method
+ * will be re-thrown. Throwing checked exceptions on a handler which doesn't expect any
+ * checked exceptions to be thrown will result in "undefined" behavior
+ * (although in practice it is usually thrown as normal).</p>
+ */
+public class HandlerDispatcher<T> implements Dispatchable<T> {
+
+    private static final String TAG = "HandlerDispatcher";
+
+    private final Dispatchable<T> mDispatchTarget;
+    private final Handler mHandler;
+
+    /**
+     * Create a dispatcher that forwards it's dispatch calls by posting
+     * them onto the {@code handler} as a {@code Runnable}.
+     *
+     * @param dispatchTarget the destination whose method calls will be redirected into the handler
+     * @param handler all calls into {@code dispatchTarget} will be posted onto this handler
+     * @param <T> the type of the element you want to wrap.
+     * @return a dispatcher that will forward it's dispatch calls to a handler
+     */
+    public HandlerDispatcher(Dispatchable<T> dispatchTarget, Handler handler) {
+        mDispatchTarget = checkNotNull(dispatchTarget, "dispatchTarget must not be null");
+        mHandler = checkNotNull(handler, "handler must not be null");
+    }
+
+    @Override
+    public Object dispatch(final Method method, final Object[] args) throws Throwable {
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    mDispatchTarget.dispatch(method, args);
+                } catch (InvocationTargetException e) {
+                    Throwable t = e.getTargetException();
+                    // Potential UB. Hopefully 't' is a runtime exception.
+                    UncheckedThrow.throwAnyException(t);
+                } catch (IllegalAccessException e) {
+                    // Impossible
+                    Log.wtf(TAG, "IllegalAccessException while invoking " + method, e);
+                } catch (IllegalArgumentException e) {
+                    // Impossible
+                    Log.wtf(TAG, "IllegalArgumentException while invoking " + method, e);
+                } catch (Throwable e) {
+                    UncheckedThrow.throwAnyException(e);
+                }
+            }
+        });
+
+        // TODO handle primitive return values that would avoid NPE if unboxed
+        return null;
+    }
+}
diff --git a/core/java/android/hardware/camera2/dispatch/InvokeDispatcher.java b/core/java/android/hardware/camera2/dispatch/InvokeDispatcher.java
new file mode 100644
index 0000000..ac5f526
--- /dev/null
+++ b/core/java/android/hardware/camera2/dispatch/InvokeDispatcher.java
@@ -0,0 +1,55 @@
+/*
+ * 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.hardware.camera2.dispatch;
+
+import android.hardware.camera2.utils.UncheckedThrow;
+import android.util.Log;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import static com.android.internal.util.Preconditions.*;
+
+
+public class InvokeDispatcher<T> implements Dispatchable<T> {
+
+    private static final String TAG = "InvocationSink";
+    private final T mTarget;
+
+    public InvokeDispatcher(T target) {
+        mTarget = checkNotNull(target, "target must not be null");
+    }
+
+    @Override
+    public Object dispatch(Method method, Object[] args) {
+        try {
+            return method.invoke(mTarget, args);
+        } catch (InvocationTargetException e) {
+            Throwable t = e.getTargetException();
+            // Potential UB. Hopefully 't' is a runtime exception.
+            UncheckedThrow.throwAnyException(t);
+        } catch (IllegalAccessException e) {
+            // Impossible
+            Log.wtf(TAG, "IllegalAccessException while invoking " + method, e);
+        } catch (IllegalArgumentException e) {
+            // Impossible
+            Log.wtf(TAG, "IllegalArgumentException while invoking " + method, e);
+        }
+
+        // unreachable
+        return null;
+    }
+}
diff --git a/core/java/android/hardware/camera2/dispatch/MethodNameInvoker.java b/core/java/android/hardware/camera2/dispatch/MethodNameInvoker.java
new file mode 100644
index 0000000..02c3d87
--- /dev/null
+++ b/core/java/android/hardware/camera2/dispatch/MethodNameInvoker.java
@@ -0,0 +1,93 @@
+/*
+ * 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.hardware.camera2.dispatch;
+
+import android.hardware.camera2.utils.UncheckedThrow;
+
+import java.lang.reflect.Method;
+import java.util.concurrent.ConcurrentHashMap;
+
+import static com.android.internal.util.Preconditions.*;
+
+/**
+ * Invoke a method on a dispatchable by its name (without knowing the {@code Method} ahead of time).
+ *
+ * @param <T> destination dispatch type, methods will be looked up in the class of {@code T}
+ */
+public class MethodNameInvoker<T> {
+
+    private final Dispatchable<T> mTarget;
+    private final Class<T> mTargetClass;
+    private final ConcurrentHashMap<String, Method> mMethods =
+            new ConcurrentHashMap<>();
+
+    /**
+     * Create a new method name invoker.
+     *
+     * @param target destination dispatch type, invokes will be redirected to this dispatcher
+     * @param targetClass destination dispatch class, the invoked methods will be from this class
+     */
+    public MethodNameInvoker(Dispatchable<T> target, Class<T> targetClass) {
+        mTargetClass = targetClass;
+        mTarget = target;
+    }
+
+    /**
+     * Invoke a method by its name.
+     *
+     * <p>If more than one method exists in {@code targetClass}, the first method will be used.</p>
+     *
+     * @param methodName
+     *          The name of the method, which will be matched 1:1 to the destination method
+     * @param params
+     *          Variadic parameter list.
+     * @return
+     *          The same kind of value that would normally be returned by calling {@code methodName}
+     *          statically.
+     *
+     * @throws IllegalArgumentException if {@code methodName} does not exist on the target class
+     * @throws Throwable will rethrow anything that the target method would normally throw
+     */
+    @SuppressWarnings("unchecked")
+    public <K> K invoke(String methodName, Object... params) {
+        checkNotNull(methodName, "methodName must not be null");
+
+        Method targetMethod = mMethods.get(methodName);
+        if (targetMethod == null) {
+            for (Method method : mTargetClass.getMethods()) {
+                // TODO future: match by # of params and types of params if possible
+                if (method.getName().equals(methodName)) {
+                    targetMethod = method;
+                    mMethods.put(methodName, targetMethod);
+                    break;
+                }
+            }
+
+            if (targetMethod == null) {
+                throw new IllegalArgumentException(
+                        "Method " + methodName + " does not exist on class " + mTargetClass);
+            }
+        }
+
+        try {
+            return (K) mTarget.dispatch(targetMethod, params);
+        } catch (Throwable e) {
+            UncheckedThrow.throwAnyException(e);
+            // unreachable
+            return null;
+        }
+    }
+}
diff --git a/core/java/android/hardware/camera2/dispatch/NullDispatcher.java b/core/java/android/hardware/camera2/dispatch/NullDispatcher.java
new file mode 100644
index 0000000..fada075
--- /dev/null
+++ b/core/java/android/hardware/camera2/dispatch/NullDispatcher.java
@@ -0,0 +1,38 @@
+/*
+ * 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.hardware.camera2.dispatch;
+
+
+import java.lang.reflect.Method;
+
+/**
+ * Do nothing when dispatching; follows the null object pattern.
+ */
+public class NullDispatcher<T> implements Dispatchable<T> {
+    /**
+     * Create a dispatcher that does nothing when dispatched to.
+     */
+    public NullDispatcher() {
+    }
+
+    /**
+     * Do nothing; all parameters are ignored.
+     */
+    @Override
+    public Object dispatch(Method method, Object[] args) {
+        return null;
+    }
+}
diff --git a/core/java/android/hardware/camera2/dispatch/package.html b/core/java/android/hardware/camera2/dispatch/package.html
new file mode 100644
index 0000000..783d0a1
--- /dev/null
+++ b/core/java/android/hardware/camera2/dispatch/package.html
@@ -0,0 +1,3 @@
+<body>
+{@hide}
+</body>
diff --git a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
new file mode 100644
index 0000000..c3e042e
--- /dev/null
+++ b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
@@ -0,0 +1,584 @@
+/*
+ * 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.hardware.camera2.impl;
+
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraCaptureSession;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.dispatch.ArgumentReplacingDispatcher;
+import android.hardware.camera2.dispatch.BroadcastDispatcher;
+import android.hardware.camera2.dispatch.Dispatchable;
+import android.hardware.camera2.dispatch.DuckTypingDispatcher;
+import android.hardware.camera2.dispatch.HandlerDispatcher;
+import android.hardware.camera2.dispatch.InvokeDispatcher;
+import android.hardware.camera2.dispatch.NullDispatcher;
+import android.hardware.camera2.utils.TaskDrainer;
+import android.hardware.camera2.utils.TaskSingleDrainer;
+import android.os.Handler;
+import android.util.Log;
+import android.view.Surface;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static android.hardware.camera2.impl.CameraDeviceImpl.checkHandler;
+import static com.android.internal.util.Preconditions.*;
+
+public class CameraCaptureSessionImpl extends CameraCaptureSession {
+    private static final String TAG = "CameraCaptureSession";
+    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+
+    /** User-specified set of surfaces used as the configuration outputs */
+    private final List<Surface> mOutputs;
+    /**
+     * User-specified state listener, used for outgoing events; calls to this object will be
+     * automatically {@link Handler#post(Runnable) posted} to {@code mStateHandler}.
+     */
+    private final CameraCaptureSession.StateListener mStateListener;
+    /** User-specified state handler used for outgoing state listener events */
+    private final Handler mStateHandler;
+
+    /** Internal camera device; used to translate calls into existing deprecated API */
+    private final android.hardware.camera2.impl.CameraDeviceImpl mDeviceImpl;
+    /** Internal handler; used for all incoming events to preserve total order */
+    private final Handler mDeviceHandler;
+
+    /** Drain Sequence IDs which have been queued but not yet finished with aborted/completed */
+    private final TaskDrainer<Integer> mSequenceDrainer;
+    /** Drain state transitions from ACTIVE -> IDLE */
+    private final TaskSingleDrainer mIdleDrainer;
+    /** Drain state transitions from BUSY -> IDLE */
+    private final TaskSingleDrainer mAbortDrainer;
+    /** Drain the UNCONFIGURED state transition */
+    private final TaskSingleDrainer mUnconfigureDrainer;
+
+    /** This session is closed; all further calls will throw ISE */
+    private boolean mClosed = false;
+    /** Do not unconfigure if this is set; another session will overwrite configuration */
+    private boolean mSkipUnconfigure = false;
+
+    /** Is the session in the process of aborting? Pay attention to BUSY->IDLE transitions. */
+    private boolean mAborting;
+
+    /**
+     * Create a new CameraCaptureSession.
+     *
+     * <p>The camera device must already be in the {@code IDLE} state when this is invoked.
+     * There must be no pending actions
+     * (e.g. no pending captures, no repeating requests, no flush).</p>
+     */
+    CameraCaptureSessionImpl(List<Surface> outputs,
+            CameraCaptureSession.StateListener listener, Handler stateHandler,
+            android.hardware.camera2.impl.CameraDeviceImpl deviceImpl,
+            Handler deviceStateHandler, boolean configureSuccess) {
+        if (outputs == null || outputs.isEmpty()) {
+            throw new IllegalArgumentException("outputs must be a non-null, non-empty list");
+        } else if (listener == null) {
+            throw new IllegalArgumentException("listener must not be null");
+        }
+
+        // TODO: extra verification of outputs
+        mOutputs = outputs;
+        mStateHandler = checkHandler(stateHandler);
+        mStateListener = createUserStateListenerProxy(mStateHandler, listener);
+
+        mDeviceHandler = checkNotNull(deviceStateHandler, "deviceStateHandler must not be null");
+        mDeviceImpl = checkNotNull(deviceImpl, "deviceImpl must not be null");
+
+        /*
+         * Use the same handler as the device's StateListener for all the internal coming events
+         *
+         * This ensures total ordering between CameraDevice.StateListener and
+         * CameraDevice.CaptureListener events.
+         */
+        mSequenceDrainer = new TaskDrainer<>(mDeviceHandler, new SequenceDrainListener(),
+                /*name*/"seq");
+        mIdleDrainer = new TaskSingleDrainer(mDeviceHandler, new IdleDrainListener(),
+                /*name*/"idle");
+        mAbortDrainer = new TaskSingleDrainer(mDeviceHandler, new AbortDrainListener(),
+                /*name*/"abort");
+        mUnconfigureDrainer = new TaskSingleDrainer(mDeviceHandler, new UnconfigureDrainListener(),
+                /*name*/"unconf");
+
+        // CameraDevice should call configureOutputs and have it finish before constructing us
+
+        if (configureSuccess) {
+            mStateListener.onConfigured(this);
+        } else {
+            mStateListener.onConfigureFailed(this);
+            mClosed = true; // do not fire any other callbacks, do not allow any other work
+        }
+    }
+
+    @Override
+    public CameraDevice getDevice() {
+        return mDeviceImpl;
+    }
+
+    @Override
+    public synchronized int capture(CaptureRequest request, CaptureListener listener,
+            Handler handler) throws CameraAccessException {
+        checkNotClosed();
+        checkLegalToCapture();
+
+        handler = checkHandler(handler);
+
+        if (VERBOSE) {
+            Log.v(TAG, "capture - request " + request + ", listener " + listener + " handler" +
+                    "" + handler);
+        }
+
+        return addPendingSequence(mDeviceImpl.capture(request,
+                createCaptureListenerProxy(handler, listener), mDeviceHandler));
+    }
+
+    @Override
+    public synchronized int captureBurst(List<CaptureRequest> requests, CaptureListener listener,
+            Handler handler) throws CameraAccessException {
+        checkNotClosed();
+        checkLegalToCapture();
+
+        handler = checkHandler(handler);
+
+        if (VERBOSE) {
+            CaptureRequest[] requestArray = requests.toArray(new CaptureRequest[0]);
+            Log.v(TAG, "captureBurst - requests " + Arrays.toString(requestArray) + ", listener " +
+                    listener + " handler" + "" + handler);
+        }
+
+        return addPendingSequence(mDeviceImpl.captureBurst(requests,
+                createCaptureListenerProxy(handler, listener), mDeviceHandler));
+    }
+
+    @Override
+    public synchronized int setRepeatingRequest(CaptureRequest request, CaptureListener listener,
+            Handler handler) throws CameraAccessException {
+        checkNotClosed();
+        checkLegalToCapture();
+
+        handler = checkHandler(handler);
+
+        return addPendingSequence(mDeviceImpl.setRepeatingRequest(request,
+                createCaptureListenerProxy(handler, listener), mDeviceHandler));
+    }
+
+    @Override
+    public synchronized int setRepeatingBurst(List<CaptureRequest> requests,
+            CaptureListener listener, Handler handler) throws CameraAccessException {
+        checkNotClosed();
+        checkLegalToCapture();
+
+        handler = checkHandler(handler);
+
+        if (VERBOSE) {
+            CaptureRequest[] requestArray = requests.toArray(new CaptureRequest[0]);
+            Log.v(TAG, "setRepeatingBurst - requests " + Arrays.toString(requestArray) +
+                    ", listener " + listener + " handler" + "" + handler);
+        }
+
+        return addPendingSequence(mDeviceImpl.setRepeatingBurst(requests,
+                createCaptureListenerProxy(handler, listener), mDeviceHandler));
+    }
+
+    @Override
+    public synchronized void stopRepeating() throws CameraAccessException {
+        checkNotClosed();
+
+        if (VERBOSE) {
+            Log.v(TAG, "stopRepeating");
+        }
+
+        mDeviceImpl.stopRepeating();
+    }
+
+    @Override
+    public synchronized void abortCaptures() throws CameraAccessException {
+        checkNotClosed();
+
+        if (VERBOSE) {
+            Log.v(TAG, "abortCaptures");
+        }
+
+        if (mAborting) {
+            Log.w(TAG, "abortCaptures - Session is already aborting; doing nothing");
+            return;
+        }
+
+        mAborting = true;
+        mAbortDrainer.taskStarted();
+
+        mDeviceImpl.flush();
+        // The next BUSY -> IDLE set of transitions will mark the end of the abort.
+    }
+
+    /**
+     * Replace this session with another session.
+     *
+     * <p>This is an optimization to avoid unconfiguring and then immediately having to
+     * reconfigure again.</p>
+     *
+     * <p>The semantics are identical to {@link #close}, except that unconfiguring will be skipped.
+     * <p>
+     *
+     * @see CameraCaptureSession#close
+     */
+    synchronized void replaceSessionClose(CameraCaptureSession other) {
+        /*
+         * In order for creating new sessions to be fast, the new session should be created
+         * before the old session is closed.
+         *
+         * Otherwise the old session will always unconfigure if there is no new session to
+         * replace it.
+         *
+         * Unconfiguring could add hundreds of milliseconds of delay. We could race and attempt
+         * to skip unconfigure if a new session is created before the captures are all drained,
+         * but this would introduce nondeterministic behavior.
+         */
+
+        // #close was already called explicitly, keep going the slow route
+        if (mClosed) {
+            return;
+        }
+
+        mSkipUnconfigure = true;
+        close();
+    }
+
+    @Override
+    public synchronized void close() {
+        if (mClosed) {
+            return;
+        }
+
+        mClosed = true;
+
+        /*
+         * Flush out any repeating request. Since camera is closed, no new requests
+         * can be queued, and eventually the entire request queue will be drained.
+         *
+         * Once this is done, wait for camera to idle, then unconfigure the camera.
+         * Once that's done, fire #onClosed.
+         */
+        try {
+            mDeviceImpl.stopRepeating();
+        } catch (CameraAccessException e) {
+            // OK: close does not throw checked exceptions.
+            Log.e(TAG, "Exception while stopping repeating: ", e);
+
+            // TODO: call onError instead of onClosed if this happens
+        }
+
+        // If no sequences are pending, fire #onClosed immediately
+        mSequenceDrainer.beginDrain();
+    }
+
+    /**
+     * Post calls into a CameraCaptureSession.StateListener to the user-specified {@code handler}.
+     */
+    private StateListener createUserStateListenerProxy(Handler handler, StateListener listener) {
+        InvokeDispatcher<StateListener> userListenerSink = new InvokeDispatcher<>(listener);
+        HandlerDispatcher<StateListener> handlerPassthrough =
+                new HandlerDispatcher<>(userListenerSink, handler);
+
+        return new ListenerProxies.SessionStateListenerProxy(handlerPassthrough);
+    }
+
+    /**
+     * Forward callbacks from
+     * CameraDevice.CaptureListener to the CameraCaptureSession.CaptureListener.
+     *
+     * <p>In particular, all calls are automatically split to go both to our own
+     * internal listener, and to the user-specified listener (by transparently posting
+     * to the user-specified handler).</p>
+     *
+     * <p>When a capture sequence finishes, update the pending checked sequences set.</p>
+     */
+    @SuppressWarnings("deprecation")
+    private CameraDevice.CaptureListener createCaptureListenerProxy(
+            Handler handler, CaptureListener listener) {
+        CameraDevice.CaptureListener localListener = new CameraDevice.CaptureListener() {
+            @Override
+            public void onCaptureSequenceCompleted(CameraDevice camera,
+                    int sequenceId, long frameNumber) {
+                finishPendingSequence(sequenceId);
+            }
+
+            @Override
+            public void onCaptureSequenceAborted(CameraDevice camera,
+                    int sequenceId) {
+                finishPendingSequence(sequenceId);
+            }
+        };
+
+        /*
+         * Split the calls from the device listener into local listener and the following chain:
+         * - replace the first CameraDevice arg with a CameraCaptureSession
+         * - duck type from device listener to session listener
+         * - then forward the call to a handler
+         * - then finally invoke the destination method on the session listener object
+         */
+        Dispatchable<CaptureListener> userListenerSink;
+        if (listener == null) { // OK: API allows the user to not specify a listener
+            userListenerSink = new NullDispatcher<>();
+        } else {
+            userListenerSink = new InvokeDispatcher<>(listener);
+        }
+
+        InvokeDispatcher<CameraDevice.CaptureListener> localSink =
+                new InvokeDispatcher<>(localListener);
+        HandlerDispatcher<CaptureListener> handlerPassthrough =
+                new HandlerDispatcher<>(userListenerSink, handler);
+        DuckTypingDispatcher<CameraDevice.CaptureListener, CaptureListener> duckToSession
+                = new DuckTypingDispatcher<>(handlerPassthrough, CaptureListener.class);
+        ArgumentReplacingDispatcher<CameraDevice.CaptureListener, CameraCaptureSessionImpl>
+            replaceDeviceWithSession = new ArgumentReplacingDispatcher<>(duckToSession,
+                    /*argumentIndex*/0, this);
+
+        BroadcastDispatcher<CameraDevice.CaptureListener> broadcaster =
+                new BroadcastDispatcher<CameraDevice.CaptureListener>(
+                        replaceDeviceWithSession,
+                        localSink);
+
+        return new ListenerProxies.DeviceCaptureListenerProxy(broadcaster);
+    }
+
+    /**
+     *
+     * Create an internal state listener, to be invoked on the mDeviceHandler
+     *
+     * <p>It has a few behaviors:
+     * <ul>
+     * <li>Convert device state changes into session state changes.
+     * <li>Keep track of async tasks that the session began (idle, abort).
+     * </ul>
+     * </p>
+     * */
+    CameraDevice.StateListener getDeviceStateListener() {
+        final CameraCaptureSession session = this;
+
+        return new CameraDevice.StateListener() {
+            private boolean mBusy = false;
+            private boolean mActive = false;
+
+            @Override
+            public void onOpened(CameraDevice camera) {
+                throw new AssertionError("Camera must already be open before creating a session");
+            }
+
+            @Override
+            public void onDisconnected(CameraDevice camera) {
+                close();
+            }
+
+            @Override
+            public void onError(CameraDevice camera, int error) {
+                // TODO: Handle errors somehow.
+                Log.wtf(TAG, "Got device error " + error);
+            }
+
+            @Override
+            public void onActive(CameraDevice camera) {
+                mIdleDrainer.taskStarted();
+                mActive = true;
+
+                mStateListener.onActive(session);
+            }
+
+            @Override
+            public void onIdle(CameraDevice camera) {
+                boolean isAborting;
+                synchronized (session) {
+                    isAborting = mAborting;
+                }
+
+                /*
+                 * Check which states we transitioned through:
+                 *
+                 * (ACTIVE -> IDLE)
+                 * (BUSY -> IDLE)
+                 *
+                 * Note that this is also legal:
+                 * (ACTIVE -> BUSY -> IDLE)
+                 *
+                 * and mark those tasks as finished
+                 */
+                if (mBusy && isAborting) {
+                    mAbortDrainer.taskFinished();
+
+                    synchronized (session) {
+                        mAborting = false;
+                    }
+                }
+
+                if (mActive) {
+                    mIdleDrainer.taskFinished();
+                }
+
+                mBusy = false;
+                mActive = false;
+
+                mStateListener.onReady(session);
+            }
+
+            @Override
+            public void onBusy(CameraDevice camera) {
+                mBusy = true;
+
+                // TODO: Queue captures during abort instead of failing them
+                // since the app won't be able to distinguish the two actives
+                Log.w(TAG, "Device is now busy; do not submit new captures (TODO: allow this)");
+                mStateListener.onActive(session);
+            }
+
+            @Override
+            public void onUnconfigured(CameraDevice camera) {
+                synchronized (session) {
+                    // Ignore #onUnconfigured before #close is called
+                    if (mClosed) {
+                        mUnconfigureDrainer.taskFinished();
+                    }
+                }
+            }
+        };
+
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            close();
+        } finally {
+            super.finalize();
+        }
+    }
+
+    private void checkLegalToCapture() {
+        if (mAborting) {
+            throw new IllegalStateException(
+                    "Session is aborting captures; new captures are not permitted");
+        }
+    }
+
+    private void checkNotClosed() {
+        if (mClosed) {
+            throw new IllegalStateException(
+                    "Session has been closed; further changes are illegal.");
+        }
+    }
+
+    /**
+     * Notify the session that a pending capture sequence has just been queued.
+     *
+     * <p>During a shutdown/close, the session waits until all pending sessions are finished
+     * before taking any further steps to shut down itself.</p>
+     *
+     * @see #finishPendingSequence
+     */
+    private int addPendingSequence(int sequenceId) {
+        mSequenceDrainer.taskStarted(sequenceId);
+        return sequenceId;
+    }
+
+    /**
+     * Notify the session that a pending capture sequence is now finished.
+     *
+     * <p>During a shutdown/close, once all pending sequences finish, it is safe to
+     * close the camera further by unconfiguring and then firing {@code onClosed}.</p>
+     */
+    private void finishPendingSequence(int sequenceId) {
+        mSequenceDrainer.taskFinished(sequenceId);
+    }
+
+    private class SequenceDrainListener implements TaskDrainer.DrainListener {
+        @Override
+        public void onDrained() {
+            /*
+             * No repeating request is set; and the capture queue has fully drained.
+             *
+             * If no captures were queued to begin with, and an abort was queued,
+             * it's still possible to get another BUSY before the last IDLE.
+             *
+             * If the camera is already "IDLE" and no aborts are pending,
+             * then the drain immediately finishes.
+             */
+            mAbortDrainer.beginDrain();
+        }
+    }
+
+    private class AbortDrainListener implements TaskDrainer.DrainListener {
+        @Override
+        public void onDrained() {
+            synchronized (CameraCaptureSessionImpl.this) {
+                /*
+                 * Any queued aborts have now completed.
+                 *
+                 * It's now safe to wait to receive the final "IDLE" event, as the camera device
+                 * will no longer again transition to "ACTIVE" by itself.
+                 *
+                 * If the camera is already "IDLE", then the drain immediately finishes.
+                 */
+                mIdleDrainer.beginDrain();
+            }
+        }
+    }
+
+    private class IdleDrainListener implements TaskDrainer.DrainListener {
+        @Override
+        public void onDrained() {
+            synchronized (CameraCaptureSessionImpl.this) {
+                /*
+                 * The device is now IDLE, and has settled. It will not transition to
+                 * ACTIVE or BUSY again by itself.
+                 *
+                 * It's now safe to unconfigure the outputs and after it's done invoke #onClosed.
+                 *
+                 * This operation is idempotent; a session will not be closed twice.
+                 */
+
+                // Fast path: A new capture session has replaced this one; don't unconfigure.
+                if (mSkipUnconfigure) {
+                    mStateListener.onClosed(CameraCaptureSessionImpl.this);
+                    return;
+                }
+
+                // Slow path: #close was called explicitly on this session; unconfigure first
+
+                try {
+                    mUnconfigureDrainer.taskStarted();
+                    mDeviceImpl.configureOutputs(null); // begin transition to unconfigured state
+                } catch (CameraAccessException e) {
+                    // OK: do not throw checked exceptions.
+                    Log.e(TAG, "Exception while configuring outputs: ", e);
+
+                    // TODO: call onError instead of onClosed if this happens
+                }
+
+                mUnconfigureDrainer.beginDrain();
+            }
+        }
+    }
+
+    private class UnconfigureDrainListener implements TaskDrainer.DrainListener {
+        @Override
+        public void onDrained() {
+            synchronized (CameraCaptureSessionImpl.this) {
+                // The device has finished unconfiguring. It's now fully closed.
+                mStateListener.onClosed(CameraCaptureSessionImpl.this);
+            }
+        }
+    }
+}
diff --git a/core/java/android/hardware/camera2/impl/CameraDevice.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
similarity index 79%
rename from core/java/android/hardware/camera2/impl/CameraDevice.java
rename to core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index 9a4c531..d4adae1 100644
--- a/core/java/android/hardware/camera2/impl/CameraDevice.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -21,7 +21,6 @@
 import android.hardware.camera2.CameraAccessException;
 import android.hardware.camera2.CameraCaptureSession;
 import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CameraManager;
 import android.hardware.camera2.CaptureRequest;
 import android.hardware.camera2.CaptureResult;
 import android.hardware.camera2.ICameraDeviceCallbacks;
@@ -48,7 +47,7 @@
 /**
  * HAL2.1+ implementation of CameraDevice. Use CameraManager#open to instantiate
  */
-public class CameraDevice implements android.hardware.camera2.CameraDevice {
+public class CameraDeviceImpl extends android.hardware.camera2.CameraDevice {
 
     private final String TAG;
     private final boolean DEBUG;
@@ -62,10 +61,13 @@
     private final CameraDeviceCallbacks mCallbacks = new CameraDeviceCallbacks();
 
     private final StateListener mDeviceListener;
+    private volatile StateListener mSessionStateListener;
     private final Handler mDeviceHandler;
 
+    private boolean mInError = false;
     private boolean mIdle = true;
 
+    /** map request IDs to listener/request data */
     private final SparseArray<CaptureListenerHolder> mCaptureListenerMap =
             new SparseArray<CaptureListenerHolder>();
 
@@ -90,14 +92,20 @@
      */
     private final FrameNumberTracker mFrameNumberTracker = new FrameNumberTracker();
 
+    private CameraCaptureSessionImpl mCurrentSession;
+
     // Runnables for all state transitions, except error, which needs the
     // error code argument
 
     private final Runnable mCallOnOpened = new Runnable() {
         @Override
         public void run() {
-            if (!CameraDevice.this.isClosed()) {
-                mDeviceListener.onOpened(CameraDevice.this);
+            if (!CameraDeviceImpl.this.isClosed()) {
+                StateListener sessionListener = mSessionStateListener;
+                if (sessionListener != null) {
+                    sessionListener.onOpened(CameraDeviceImpl.this);
+                }
+                mDeviceListener.onOpened(CameraDeviceImpl.this);
             }
         }
     };
@@ -105,8 +113,12 @@
     private final Runnable mCallOnUnconfigured = new Runnable() {
         @Override
         public void run() {
-            if (!CameraDevice.this.isClosed()) {
-                mDeviceListener.onUnconfigured(CameraDevice.this);
+            if (!CameraDeviceImpl.this.isClosed()) {
+                StateListener sessionListener = mSessionStateListener;
+                if (sessionListener != null) {
+                    sessionListener.onUnconfigured(CameraDeviceImpl.this);
+                }
+                mDeviceListener.onUnconfigured(CameraDeviceImpl.this);
             }
         }
     };
@@ -114,8 +126,12 @@
     private final Runnable mCallOnActive = new Runnable() {
         @Override
         public void run() {
-            if (!CameraDevice.this.isClosed()) {
-                mDeviceListener.onActive(CameraDevice.this);
+            if (!CameraDeviceImpl.this.isClosed()) {
+                StateListener sessionListener = mSessionStateListener;
+                if (sessionListener != null) {
+                    sessionListener.onActive(CameraDeviceImpl.this);
+                }
+                mDeviceListener.onActive(CameraDeviceImpl.this);
             }
         }
     };
@@ -123,8 +139,12 @@
     private final Runnable mCallOnBusy = new Runnable() {
         @Override
         public void run() {
-            if (!CameraDevice.this.isClosed()) {
-                mDeviceListener.onBusy(CameraDevice.this);
+            if (!CameraDeviceImpl.this.isClosed()) {
+                StateListener sessionListener = mSessionStateListener;
+                if (sessionListener != null) {
+                    sessionListener.onBusy(CameraDeviceImpl.this);
+                }
+                mDeviceListener.onBusy(CameraDeviceImpl.this);
             }
         }
     };
@@ -132,15 +152,23 @@
     private final Runnable mCallOnClosed = new Runnable() {
         @Override
         public void run() {
-            mDeviceListener.onClosed(CameraDevice.this);
+            StateListener sessionListener = mSessionStateListener;
+            if (sessionListener != null) {
+                sessionListener.onClosed(CameraDeviceImpl.this);
+            }
+            mDeviceListener.onClosed(CameraDeviceImpl.this);
         }
     };
 
     private final Runnable mCallOnIdle = new Runnable() {
         @Override
         public void run() {
-            if (!CameraDevice.this.isClosed()) {
-                mDeviceListener.onIdle(CameraDevice.this);
+            if (!CameraDeviceImpl.this.isClosed()) {
+                StateListener sessionListener = mSessionStateListener;
+                if (sessionListener != null) {
+                    sessionListener.onIdle(CameraDeviceImpl.this);
+                }
+                mDeviceListener.onIdle(CameraDeviceImpl.this);
             }
         }
     };
@@ -148,13 +176,17 @@
     private final Runnable mCallOnDisconnected = new Runnable() {
         @Override
         public void run() {
-            if (!CameraDevice.this.isClosed()) {
-                mDeviceListener.onDisconnected(CameraDevice.this);
+            if (!CameraDeviceImpl.this.isClosed()) {
+                StateListener sessionListener = mSessionStateListener;
+                if (sessionListener != null) {
+                    sessionListener.onDisconnected(CameraDeviceImpl.this);
+                }
+                mDeviceListener.onDisconnected(CameraDeviceImpl.this);
             }
         }
     };
 
-    public CameraDevice(String cameraId, StateListener listener, Handler handler,
+    public CameraDeviceImpl(String cameraId, StateListener listener, Handler handler,
                         CameraCharacteristics characteristics) {
         if (cameraId == null || listener == null || handler == null) {
             throw new IllegalArgumentException("Null argument given");
@@ -170,7 +202,6 @@
             tag = tag.substring(0, MAX_TAG_LEN);
         }
         TAG = tag;
-
         DEBUG = Log.isLoggable(TAG, Log.DEBUG);
     }
 
@@ -181,6 +212,9 @@
     public void setRemoteDevice(ICameraDeviceUser remoteDevice) {
         // TODO: Move from decorator to direct binder-mediated exceptions
         synchronized(mLock) {
+            // If setRemoteFailure already called, do nothing
+            if (mInError) return;
+
             mRemoteDevice = CameraBinderDecorator.newInstance(remoteDevice);
 
             mDeviceHandler.post(mCallOnOpened);
@@ -188,6 +222,52 @@
         }
     }
 
+    /**
+     * Call to indicate failed connection to a remote camera device.
+     *
+     * <p>This places the camera device in the error state and informs the listener.
+     * Use in place of setRemoteDevice() when startup fails.</p>
+     */
+    public void setRemoteFailure(final CameraRuntimeException failure) {
+        int failureCode = StateListener.ERROR_CAMERA_DEVICE;
+        boolean failureIsError = true;
+
+        switch (failure.getReason()) {
+            case CameraAccessException.CAMERA_IN_USE:
+                failureCode = StateListener.ERROR_CAMERA_IN_USE;
+                break;
+            case CameraAccessException.MAX_CAMERAS_IN_USE:
+                failureCode = StateListener.ERROR_MAX_CAMERAS_IN_USE;
+                break;
+            case CameraAccessException.CAMERA_DISABLED:
+                failureCode = StateListener.ERROR_CAMERA_DISABLED;
+                break;
+            case CameraAccessException.CAMERA_DISCONNECTED:
+                failureIsError = false;
+                break;
+            case CameraAccessException.CAMERA_ERROR:
+                failureCode = StateListener.ERROR_CAMERA_DEVICE;
+                break;
+            default:
+                Log.wtf(TAG, "Unknown failure in opening camera device: " + failure.getReason());
+                break;
+        }
+        final int code = failureCode;
+        final boolean isError = failureIsError;
+        synchronized (mLock) {
+            mInError = true;
+            mDeviceHandler.post(new Runnable() {
+                public void run() {
+                    if (isError) {
+                        mDeviceListener.onError(CameraDeviceImpl.this, code);
+                    } else {
+                        mDeviceListener.onDisconnected(CameraDeviceImpl.this);
+                    }
+                }
+            });
+        }
+    }
+
     @Override
     public String getId() {
         return mCameraId;
@@ -200,7 +280,7 @@
             outputs = new ArrayList<Surface>();
         }
         synchronized (mLock) {
-            checkIfCameraClosed();
+            checkIfCameraClosedOrInError();
 
             HashSet<Surface> addSet = new HashSet<Surface>(outputs);    // Streams to create
             List<Integer> deleteList = new ArrayList<Integer>();        // Streams to delete
@@ -263,19 +343,55 @@
     public void createCaptureSession(List<Surface> outputs,
             CameraCaptureSession.StateListener listener, Handler handler)
             throws CameraAccessException {
-        // TODO
+        synchronized (mLock) {
+            if (DEBUG) {
+                Log.d(TAG, "createCaptureSession");
+            }
+
+            checkIfCameraClosedOrInError();
+
+            // TODO: we must be in UNCONFIGURED mode to begin with, or using another session
+
+            // TODO: dont block for this
+            boolean configureSuccess = true;
+            CameraAccessException pendingException = null;
+            try {
+                configureOutputs(outputs); // and then block until IDLE
+            } catch (CameraAccessException e) {
+                configureSuccess = false;
+                pendingException = e;
+            }
+
+            // Fire onConfigured if configureOutputs succeeded, fire onConfigureFailed otherwise.
+            CameraCaptureSessionImpl newSession =
+                    new CameraCaptureSessionImpl(outputs, listener, handler, this, mDeviceHandler,
+                            configureSuccess);
+
+            if (mCurrentSession != null) {
+                mCurrentSession.replaceSessionClose(newSession);
+            }
+
+            // TODO: wait until current session closes, then create the new session
+            mCurrentSession = newSession;
+
+            if (pendingException != null) {
+                throw pendingException;
+            }
+
+            mSessionStateListener = mCurrentSession.getDeviceStateListener();
+        }
     }
 
     @Override
     public CaptureRequest.Builder createCaptureRequest(int templateType)
             throws CameraAccessException {
         synchronized (mLock) {
-            checkIfCameraClosed();
+            checkIfCameraClosedOrInError();
 
             CameraMetadataNative templatedRequest = new CameraMetadataNative();
 
             try {
-                mRemoteDevice.createDefaultRequest(templateType, /* out */templatedRequest);
+                mRemoteDevice.createDefaultRequest(templateType, /*out*/templatedRequest);
             } catch (CameraRuntimeException e) {
                 throw e.asChecked();
             } catch (RemoteException e) {
@@ -304,10 +420,8 @@
     @Override
     public int captureBurst(List<CaptureRequest> requests, CaptureListener listener,
             Handler handler) throws CameraAccessException {
-        // TODO: remove this. Throw IAE if the request is null or empty. Need to update API doc.
-        if (requests.isEmpty()) {
-            Log.w(TAG, "Capture burst request list is empty, do nothing!");
-            return -1;
+        if (requests == null || requests.isEmpty()) {
+            throw new IllegalArgumentException("At least one request must be given");
         }
         return submitCaptureRequest(requests, listener, handler, /*streaming*/false);
     }
@@ -352,7 +466,7 @@
                 Runnable resultDispatch = new Runnable() {
                     @Override
                     public void run() {
-                        if (!CameraDevice.this.isClosed()) {
+                        if (!CameraDeviceImpl.this.isClosed()) {
                             if (DEBUG) {
                                 Log.d(TAG, String.format(
                                         "early trigger sequence complete for request %d",
@@ -363,7 +477,7 @@
                                 throw new AssertionError(lastFrameNumber + " cannot be cast to int");
                             }
                             holder.getListener().onCaptureSequenceCompleted(
-                                    CameraDevice.this,
+                                    CameraDeviceImpl.this,
                                     requestId,
                                     lastFrameNumber);
                         }
@@ -392,7 +506,7 @@
         }
 
         synchronized (mLock) {
-            checkIfCameraClosed();
+            checkIfCameraClosedOrInError();
             int requestId;
 
             if (repeating) {
@@ -454,10 +568,8 @@
     @Override
     public int setRepeatingBurst(List<CaptureRequest> requests, CaptureListener listener,
             Handler handler) throws CameraAccessException {
-        // TODO: remove this. Throw IAE if the request is null or empty. Need to update API doc.
-        if (requests.isEmpty()) {
-            Log.w(TAG, "Set Repeating burst request list is empty, do nothing!");
-            return -1;
+        if (requests == null || requests.isEmpty()) {
+            throw new IllegalArgumentException("At least one request must be given");
         }
         return submitCaptureRequest(requests, listener, handler, /*streaming*/true);
     }
@@ -466,7 +578,7 @@
     public void stopRepeating() throws CameraAccessException {
 
         synchronized (mLock) {
-            checkIfCameraClosed();
+            checkIfCameraClosedOrInError();
             if (mRepeatingRequestId != REQUEST_ID_NONE) {
 
                 int requestId = mRepeatingRequestId;
@@ -497,7 +609,7 @@
     private void waitUntilIdle() throws CameraAccessException {
 
         synchronized (mLock) {
-            checkIfCameraClosed();
+            checkIfCameraClosedOrInError();
             if (mRepeatingRequestId != REQUEST_ID_NONE) {
                 throw new IllegalStateException("Active repeating request ongoing");
             }
@@ -518,7 +630,7 @@
     @Override
     public void flush() throws CameraAccessException {
         synchronized (mLock) {
-            checkIfCameraClosed();
+            checkIfCameraClosedOrInError();
 
             mDeviceHandler.post(mCallOnBusy);
             try {
@@ -552,11 +664,15 @@
                 // impossible
             }
 
-            if (mRemoteDevice != null) {
+            // Only want to fire the onClosed callback once;
+            // either a normal close where the remote device is valid
+            // or a close after a startup error (no remote device but in error state)
+            if (mRemoteDevice != null || mInError) {
                 mDeviceHandler.post(mCallOnClosed);
             }
 
             mRemoteDevice = null;
+            mInError = false;
         }
     }
 
@@ -707,7 +823,7 @@
                     Runnable resultDispatch = new Runnable() {
                         @Override
                         public void run() {
-                            if (!CameraDevice.this.isClosed()){
+                            if (!CameraDeviceImpl.this.isClosed()){
                                 if (DEBUG) {
                                     Log.d(TAG, String.format(
                                             "fire sequence complete for request %d",
@@ -721,7 +837,7 @@
                                             + " cannot be cast to int");
                                 }
                                 holder.getListener().onCaptureSequenceCompleted(
-                                    CameraDevice.this,
+                                    CameraDeviceImpl.this,
                                     requestId,
                                     lastFrameNumber);
                             }
@@ -773,6 +889,7 @@
             if (isClosed()) return;
 
             synchronized(mLock) {
+                mInError = true;
                 switch (errorCode) {
                     case ERROR_CAMERA_DISCONNECTED:
                         r = mCallOnDisconnected;
@@ -785,14 +902,14 @@
                         r = new Runnable() {
                             @Override
                             public void run() {
-                                if (!CameraDevice.this.isClosed()) {
-                                    mDeviceListener.onError(CameraDevice.this, errorCode);
+                                if (!CameraDeviceImpl.this.isClosed()) {
+                                    mDeviceListener.onError(CameraDeviceImpl.this, errorCode);
                                 }
                             }
                         };
                         break;
                 }
-                CameraDevice.this.mDeviceHandler.post(r);
+                CameraDeviceImpl.this.mDeviceHandler.post(r);
             }
 
             // Fire onCaptureSequenceCompleted
@@ -812,10 +929,10 @@
                 Log.d(TAG, "Camera now idle");
             }
             synchronized (mLock) {
-                if (!CameraDevice.this.mIdle) {
-                    CameraDevice.this.mDeviceHandler.post(mCallOnIdle);
+                if (!CameraDeviceImpl.this.mIdle) {
+                    CameraDeviceImpl.this.mDeviceHandler.post(mCallOnIdle);
                 }
-                CameraDevice.this.mIdle = true;
+                CameraDeviceImpl.this.mIdle = true;
             }
         }
 
@@ -829,7 +946,7 @@
 
             // Get the listener for this frame ID, if there is one
             synchronized (mLock) {
-                holder = CameraDevice.this.mCaptureListenerMap.get(requestId);
+                holder = CameraDeviceImpl.this.mCaptureListenerMap.get(requestId);
             }
 
             if (holder == null) {
@@ -843,9 +960,9 @@
                 new Runnable() {
                     @Override
                     public void run() {
-                        if (!CameraDevice.this.isClosed()) {
+                        if (!CameraDeviceImpl.this.isClosed()) {
                             holder.getListener().onCaptureStarted(
-                                CameraDevice.this,
+                                CameraDeviceImpl.this,
                                 holder.getRequest(resultExtras.getSubsequenceId()),
                                 timestamp);
                         }
@@ -870,7 +987,7 @@
 
             final CaptureListenerHolder holder;
             synchronized (mLock) {
-                holder = CameraDevice.this.mCaptureListenerMap.get(requestId);
+                holder = CameraDeviceImpl.this.mCaptureListenerMap.get(requestId);
             }
 
             Boolean quirkPartial = result.get(CaptureResult.QUIRKS_PARTIAL_RESULT);
@@ -914,9 +1031,9 @@
                 resultDispatch = new Runnable() {
                     @Override
                     public void run() {
-                        if (!CameraDevice.this.isClosed()){
+                        if (!CameraDeviceImpl.this.isClosed()){
                             holder.getListener().onCapturePartial(
-                                CameraDevice.this,
+                                CameraDeviceImpl.this,
                                 request,
                                 resultAsCapture);
                         }
@@ -930,9 +1047,9 @@
                 resultDispatch = new Runnable() {
                     @Override
                     public void run() {
-                        if (!CameraDevice.this.isClosed()){
+                        if (!CameraDeviceImpl.this.isClosed()){
                             holder.getListener().onCaptureCompleted(
-                                CameraDevice.this,
+                                CameraDeviceImpl.this,
                                 request,
                                 resultAsCapture);
                         }
@@ -951,10 +1068,14 @@
     }
 
     /**
-     * Default handler management. If handler is null, get the current thread's
-     * Looper to create a Handler with. If no looper exists, throw exception.
+     * Default handler management.
+     *
+     * <p>
+     * If handler is null, get the current thread's
+     * Looper to create a Handler with. If no looper exists, throw {@code IllegalArgumentException}.
+     * </p>
      */
-    private Handler checkHandler(Handler handler) {
+    static Handler checkHandler(Handler handler) {
         if (handler == null) {
             Looper looper = Looper.myLooper();
             if (looper == null) {
@@ -966,7 +1087,11 @@
         return handler;
     }
 
-    private void checkIfCameraClosed() {
+    private void checkIfCameraClosedOrInError() throws CameraAccessException {
+        if (mInError) {
+            throw new CameraAccessException(CameraAccessException.CAMERA_ERROR,
+                    "The camera device has encountered a serious error");
+        }
         if (mRemoteDevice == null) {
             throw new IllegalStateException("CameraDevice was already closed");
         }
diff --git a/core/java/android/hardware/camera2/impl/ListenerProxies.java b/core/java/android/hardware/camera2/impl/ListenerProxies.java
new file mode 100644
index 0000000..04c43e3
--- /dev/null
+++ b/core/java/android/hardware/camera2/impl/ListenerProxies.java
@@ -0,0 +1,168 @@
+package android.hardware.camera2.impl;
+
+import android.hardware.camera2.CameraCaptureSession;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CaptureFailure;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.TotalCaptureResult;
+import android.hardware.camera2.dispatch.Dispatchable;
+import android.hardware.camera2.dispatch.MethodNameInvoker;
+
+import static com.android.internal.util.Preconditions.*;
+
+/**
+ * Proxy out invocations to the camera2 API listeners into a {@link Dispatchable}.
+ *
+ * <p>Since abstract classes do not support Java's dynamic {@code Proxy}, we have to
+ * to use our own proxy mechanism.</p>
+ */
+public class ListenerProxies {
+
+    // TODO: replace with codegen
+
+    public static class DeviceStateListenerProxy extends CameraDevice.StateListener {
+        private final MethodNameInvoker<CameraDevice.StateListener> mProxy;
+
+        public DeviceStateListenerProxy(
+                Dispatchable<CameraDevice.StateListener> dispatchTarget) {
+            dispatchTarget = checkNotNull(dispatchTarget, "dispatchTarget must not be null");
+            mProxy = new MethodNameInvoker<>(dispatchTarget, CameraDevice.StateListener.class);
+        }
+
+        @Override
+        public void onOpened(CameraDevice camera) {
+            mProxy.invoke("onOpened", camera);
+        }
+
+        @Override
+        public void onDisconnected(CameraDevice camera) {
+            mProxy.invoke("onDisconnected", camera);
+        }
+
+        @Override
+        public void onError(CameraDevice camera, int error) {
+            mProxy.invoke("onError", camera, error);
+        }
+
+        @Override
+        public void onUnconfigured(CameraDevice camera) {
+            mProxy.invoke("onUnconfigured", camera);
+        }
+
+        @Override
+        public void onActive(CameraDevice camera) {
+            mProxy.invoke("onActive", camera);
+        }
+
+        @Override
+        public void onBusy(CameraDevice camera) {
+            mProxy.invoke("onBusy", camera);
+        }
+
+        @Override
+        public void onClosed(CameraDevice camera) {
+            mProxy.invoke("onClosed", camera);
+        }
+
+        @Override
+        public void onIdle(CameraDevice camera) {
+            mProxy.invoke("onIdle", camera);
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public static class DeviceCaptureListenerProxy extends CameraDevice.CaptureListener {
+        private final MethodNameInvoker<CameraDevice.CaptureListener> mProxy;
+
+        public DeviceCaptureListenerProxy(
+                Dispatchable<CameraDevice.CaptureListener> dispatchTarget) {
+            dispatchTarget = checkNotNull(dispatchTarget, "dispatchTarget must not be null");
+            mProxy = new MethodNameInvoker<>(dispatchTarget, CameraDevice.CaptureListener.class);
+        }
+
+        @Override
+        public void onCaptureStarted(CameraDevice camera,
+                CaptureRequest request, long timestamp) {
+            mProxy.invoke("onCaptureStarted", camera, request, timestamp);
+        }
+
+        @Override
+        public void onCapturePartial(CameraDevice camera,
+                CaptureRequest request, CaptureResult result) {
+            mProxy.invoke("onCapturePartial", camera, request, result);
+        }
+
+        @Override
+        public void onCaptureProgressed(CameraDevice camera,
+                CaptureRequest request, CaptureResult partialResult) {
+            mProxy.invoke("onCaptureProgressed", camera, request, partialResult);
+        }
+
+        @Override
+        public void onCaptureCompleted(CameraDevice camera,
+                CaptureRequest request, TotalCaptureResult result) {
+            mProxy.invoke("onCaptureCompleted", camera, request, result);
+        }
+
+        @Override
+        public void onCaptureFailed(CameraDevice camera,
+                CaptureRequest request, CaptureFailure failure) {
+            mProxy.invoke("onCaptureFailed", camera, request, failure);
+        }
+
+        @Override
+        public void onCaptureSequenceCompleted(CameraDevice camera,
+                int sequenceId, long frameNumber) {
+            mProxy.invoke("onCaptureSequenceCompleted", camera, sequenceId, frameNumber);
+        }
+
+        @Override
+        public void onCaptureSequenceAborted(CameraDevice camera,
+                int sequenceId) {
+            mProxy.invoke("onCaptureSequenceAborted", camera, sequenceId);
+        }
+    }
+
+    public static class SessionStateListenerProxy
+            extends CameraCaptureSession.StateListener {
+        private final MethodNameInvoker<CameraCaptureSession.StateListener> mProxy;
+
+        public SessionStateListenerProxy(
+                Dispatchable<CameraCaptureSession.StateListener> dispatchTarget) {
+            dispatchTarget = checkNotNull(dispatchTarget, "dispatchTarget must not be null");
+            mProxy = new MethodNameInvoker<>(dispatchTarget,
+                    CameraCaptureSession.StateListener.class);
+        }
+
+        @Override
+        public void onConfigured(CameraCaptureSession session) {
+            mProxy.invoke("onConfigured", session);
+        }
+
+
+        @Override
+        public void onConfigureFailed(CameraCaptureSession session) {
+            mProxy.invoke("onConfigureFailed", session);
+        }
+
+        @Override
+        public void onReady(CameraCaptureSession session) {
+            mProxy.invoke("onReady", session);
+        }
+
+        @Override
+        public void onActive(CameraCaptureSession session) {
+            mProxy.invoke("onActive", session);
+        }
+
+        @Override
+        public void onClosed(CameraCaptureSession session) {
+            mProxy.invoke("onClosed", session);
+        }
+    }
+
+    private ListenerProxies() {
+        throw new AssertionError();
+    }
+}
diff --git a/core/java/android/hardware/camera2/params/TonemapCurve.java b/core/java/android/hardware/camera2/params/TonemapCurve.java
index 0fcffac..481d67a 100644
--- a/core/java/android/hardware/camera2/params/TonemapCurve.java
+++ b/core/java/android/hardware/camera2/params/TonemapCurve.java
@@ -78,7 +78,7 @@
     /**
      * Create a new immutable TonemapCurve instance.
      *
-     * <p>Values are stored as a contiguous {@code (Pin, Pout}) point.</p>
+     * <p>Values are stored as a contiguous array of {@code (Pin, Pout)} points.</p>
      *
      * <p>All parameters may have independent length but should have at most
      * {@link CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS} * {@value #POINT_SIZE} elements.</p>
@@ -88,15 +88,16 @@
      *
      * <p>This constructor copies the array contents and does not retain ownership of the array.</p>
      *
-     * @param elements An array of elements whose length is {@code CHANNEL_COUNT * rows * columns}
+     * @param red An array of elements whose length is divisible by {@value #POINT_SIZE}
+     * @param green An array of elements whose length is divisible by {@value #POINT_SIZE}
+     * @param blue An array of elements whose length is divisible by {@value #POINT_SIZE}
      *
      * @throws IllegalArgumentException
-     *            if the {@code elements} array length is invalid,
-     *            if any of the subelems are not finite
+     *            if any of input array length is invalid,
+     *            or if any of the elements in the array are not in the range of
+     *            [{@value #LEVEL_BLACK}, {@value #LEVEL_WHITE}]
      * @throws NullPointerException
-     *            if any of the parameters is {@code null}
-     *
-     * @hide
+     *            if any of the parameters are {@code null}
      */
     public TonemapCurve(float[] red, float[] green, float[] blue) {
         // TODO: maxCurvePoints check?
diff --git a/core/java/android/hardware/camera2/utils/TaskDrainer.java b/core/java/android/hardware/camera2/utils/TaskDrainer.java
new file mode 100644
index 0000000..3cba9a1
--- /dev/null
+++ b/core/java/android/hardware/camera2/utils/TaskDrainer.java
@@ -0,0 +1,201 @@
+/*
+ * 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.hardware.camera2.utils;
+
+import android.os.Handler;
+import android.util.Log;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import static com.android.internal.util.Preconditions.*;
+
+/**
+ * Keep track of multiple concurrent tasks starting and finishing by their key;
+ * allow draining existing tasks and figuring out when all tasks have finished
+ * (and new ones won't begin).
+ *
+ * <p>The initial state is to allow all tasks to be started and finished. A task may only be started
+ * once, after which it must be finished before starting again. Likewise, finishing a task
+ * that hasn't been started is also not allowed.</p>
+ *
+ * <p>When draining begins, no more new tasks can be started. This guarantees that at some
+ * point when all the tasks are finished there will be no more collective new tasks,
+ * at which point the {@link DrainListener#onDrained} callback will be invoked.</p>
+ *
+ *
+ * @param <T>
+ *          a type for the key that will represent tracked tasks;
+ *          must implement {@code Object#equals}
+ */
+public class TaskDrainer<T> {
+    /**
+     * Fired asynchronously after draining has begun with {@link TaskDrainer#beginDrain}
+     * <em>and</em> all tasks that were started have finished.
+     */
+    public interface DrainListener {
+        /** All tasks have fully finished draining; there will be no more pending tasks. */
+        public void onDrained();
+    }
+
+    private static final String TAG = "TaskDrainer";
+    private static final boolean VERBOSE = false;
+
+    private final Handler mHandler;
+    private final DrainListener mListener;
+    private final String mName;
+
+    /** Set of tasks which have been started but not yet finished with #taskFinished */
+    private final Set<T> mTaskSet = new HashSet<T>();
+    private final Object mLock = new Object();
+
+    private boolean mDraining = false;
+    private boolean mDrainFinished = false;
+
+    /**
+     * Create a new task drainer; {@code onDrained} callbacks will be posted to the listener
+     * via the {@code handler}.
+     *
+     * @param handler a non-{@code null} handler to use to post runnables to
+     * @param listener a non-{@code null} listener where {@code onDrained} will be called
+     */
+    public TaskDrainer(Handler handler, DrainListener listener) {
+        mHandler = checkNotNull(handler, "handler must not be null");
+        mListener = checkNotNull(listener, "listener must not be null");
+        mName = null;
+    }
+
+    /**
+     * Create a new task drainer; {@code onDrained} callbacks will be posted to the listener
+     * via the {@code handler}.
+     *
+     * @param handler a non-{@code null} handler to use to post runnables to
+     * @param listener a non-{@code null} listener where {@code onDrained} will be called
+     * @param name an optional name used for debug logging
+     */
+    public TaskDrainer(Handler handler, DrainListener listener, String name) {
+        // XX: Probably don't need a handler at all here
+        mHandler = checkNotNull(handler, "handler must not be null");
+        mListener = checkNotNull(listener, "listener must not be null");
+        mName = name;
+    }
+
+    /**
+     * Mark an asynchronous task as having started.
+     *
+     * <p>A task cannot be started more than once without first having finished. Once
+     * draining begins with {@link #beginDrain}, no new tasks can be started.</p>
+     *
+     * @param task a key to identify a task
+     *
+     * @see #taskFinished
+     * @see #beginDrain
+     *
+     * @throws IllegalStateException
+     *          If attempting to start a task which is already started (and not finished),
+     *          or if attempting to start a task after draining has begun.
+     */
+    public void taskStarted(T task) {
+        synchronized (mLock) {
+            if (VERBOSE) {
+                Log.v(TAG + "[" + mName + "]", "taskStarted " + task);
+            }
+
+            if (mDraining) {
+                throw new IllegalStateException("Can't start more tasks after draining has begun");
+            }
+
+            if (!mTaskSet.add(task)) {
+                throw new IllegalStateException("Task " + task + " was already started");
+            }
+        }
+    }
+
+
+    /**
+     * Mark an asynchronous task as having finished.
+     *
+     * <p>A task cannot be finished if it hasn't started. Once finished, a task
+     * cannot be finished again (unless it's started again).</p>
+     *
+     * @param task a key to identify a task
+     *
+     * @see #taskStarted
+     * @see #beginDrain
+     *
+     * @throws IllegalStateException
+     *          If attempting to start a task which is already finished (and not re-started),
+     */
+    public void taskFinished(T task) {
+        synchronized (mLock) {
+            if (VERBOSE) {
+                Log.v(TAG + "[" + mName + "]", "taskFinished " + task);
+            }
+
+            if (!mTaskSet.remove(task)) {
+                throw new IllegalStateException("Task " + task + " was already finished");
+            }
+
+            // If this is the last finished task and draining has already begun, fire #onDrained
+            checkIfDrainFinished();
+        }
+    }
+
+    /**
+     * Do not allow any more tasks to be started; once all existing started tasks are finished,
+     * fire the {@link DrainListener#onDrained} callback asynchronously.
+     *
+     * <p>This operation is idempotent; calling it more than once has no effect.</p>
+     */
+    public void beginDrain() {
+        synchronized (mLock) {
+            if (!mDraining) {
+                if (VERBOSE) {
+                    Log.v(TAG + "[" + mName + "]", "beginDrain started");
+                }
+
+                mDraining = true;
+
+                // If all tasks that had started had already finished by now, fire #onDrained
+                checkIfDrainFinished();
+            } else {
+                if (VERBOSE) {
+                    Log.v(TAG + "[" + mName + "]", "beginDrain ignored");
+                }
+            }
+        }
+    }
+
+    private void checkIfDrainFinished() {
+        if (mTaskSet.isEmpty() && mDraining && !mDrainFinished) {
+            mDrainFinished = true;
+            postDrained();
+        }
+    }
+
+    private void postDrained() {
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                if (VERBOSE) {
+                    Log.v(TAG + "[" + mName + "]", "onDrained");
+                }
+
+                mListener.onDrained();
+            }
+        });
+    }
+}
diff --git a/core/java/android/hardware/camera2/utils/TaskSingleDrainer.java b/core/java/android/hardware/camera2/utils/TaskSingleDrainer.java
new file mode 100644
index 0000000..f6272c9
--- /dev/null
+++ b/core/java/android/hardware/camera2/utils/TaskSingleDrainer.java
@@ -0,0 +1,104 @@
+/*
+ * 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.hardware.camera2.utils;
+
+import android.hardware.camera2.utils.TaskDrainer.DrainListener;
+import android.os.Handler;
+
+/**
+ * Keep track of a single concurrent task starting and finishing;
+ * allow draining the existing task and figuring out when the task has finished
+ * (and won't restart).
+ *
+ * <p>The initial state is to allow all tasks to be started and finished. A task may only be started
+ * once, after which it must be finished before starting again. Likewise, finishing a task
+ * that hasn't been started is also not allowed.</p>
+ *
+ * <p>When draining begins, the task cannot be started again. This guarantees that at some
+ * point the task will be finished forever, at which point the {@link DrainListener#onDrained}
+ * callback will be invoked.</p>
+ */
+public class TaskSingleDrainer {
+
+    private final TaskDrainer<Object> mTaskDrainer;
+    private final Object mSingleTask = new Object();
+
+    /**
+     * Create a new task drainer; {@code onDrained} callbacks will be posted to the listener
+     * via the {@code handler}.
+     *
+     * @param handler a non-{@code null} handler to use to post runnables to
+     * @param listener a non-{@code null} listener where {@code onDrained} will be called
+     */
+    public TaskSingleDrainer(Handler handler, DrainListener listener) {
+        mTaskDrainer = new TaskDrainer<>(handler, listener);
+    }
+
+    /**
+     * Create a new task drainer; {@code onDrained} callbacks will be posted to the listener
+     * via the {@code handler}.
+     *
+     * @param handler a non-{@code null} handler to use to post runnables to
+     * @param listener a non-{@code null} listener where {@code onDrained} will be called
+     * @param name an optional name used for debug logging
+     */
+    public TaskSingleDrainer(Handler handler, DrainListener listener, String name) {
+        mTaskDrainer = new TaskDrainer<>(handler, listener, name);
+    }
+
+    /**
+     * Mark this asynchronous task as having started.
+     *
+     * <p>The task cannot be started more than once without first having finished. Once
+     * draining begins with {@link #beginDrain}, no new tasks can be started.</p>
+     *
+     * @see #taskFinished
+     * @see #beginDrain
+     *
+     * @throws IllegalStateException
+     *          If attempting to start a task which is already started (and not finished),
+     *          or if attempting to start a task after draining has begun.
+     */
+    public void taskStarted() {
+        mTaskDrainer.taskStarted(mSingleTask);
+    }
+
+    /**
+     * Do not allow any more task re-starts; once the existing task is finished,
+     * fire the {@link DrainListener#onDrained} callback asynchronously.
+     *
+     * <p>This operation is idempotent; calling it more than once has no effect.</p>
+     */
+    public void beginDrain() {
+        mTaskDrainer.beginDrain();
+    }
+
+    /**
+     * Mark this asynchronous task as having finished.
+     *
+     * <p>The task cannot be finished if it hasn't started. Once finished, a task
+     * cannot be finished again (unless it's started again).</p>
+     *
+     * @see #taskStarted
+     * @see #beginDrain
+     *
+     * @throws IllegalStateException
+     *          If attempting to start a task which is already finished (and not re-started),
+     */
+    public void taskFinished() {
+        mTaskDrainer.taskFinished(mSingleTask);
+    }
+}
diff --git a/core/java/android/hardware/camera2/utils/UncheckedThrow.java b/core/java/android/hardware/camera2/utils/UncheckedThrow.java
index 8224fed..ffcb78b 100644
--- a/core/java/android/hardware/camera2/utils/UncheckedThrow.java
+++ b/core/java/android/hardware/camera2/utils/UncheckedThrow.java
@@ -33,8 +33,20 @@
         UncheckedThrow.<RuntimeException>throwAnyImpl(e);
     }
 
+    /**
+     * Throw any kind of throwable without needing it to be checked
+     * @param e any instance of a Throwable
+     */
+    public static void throwAnyException(Throwable e) {
+        /**
+         *  Abuse type erasure by making the compiler think we are throwing RuntimeException,
+         *  which is unchecked, but then inserting any exception in there.
+         */
+        UncheckedThrow.<RuntimeException>throwAnyImpl(e);
+    }
+
     @SuppressWarnings("unchecked")
-    private static<T extends Exception> void throwAnyImpl(Exception e) throws T {
+    private static<T extends Throwable> void throwAnyImpl(Throwable e) throws T {
         throw (T) e;
     }
 }
diff --git a/core/java/android/hardware/soundtrigger/SoundTrigger.java b/core/java/android/hardware/soundtrigger/SoundTrigger.java
new file mode 100644
index 0000000..2d7af85
--- /dev/null
+++ b/core/java/android/hardware/soundtrigger/SoundTrigger.java
@@ -0,0 +1,310 @@
+/*
+ * 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.hardware.soundtrigger;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.Handler;
+
+import java.util.ArrayList;
+import java.util.UUID;
+
+/**
+ * The SoundTrigger class provides access via JNI to the native service managing
+ * the sound trigger HAL.
+ *
+ * @hide
+ */
+public class SoundTrigger {
+
+    public static final int STATUS_OK = 0;
+    public static final int STATUS_ERROR = Integer.MIN_VALUE;
+    public static final int STATUS_PERMISSION_DENIED = -1;
+    public static final int STATUS_NO_INIT = -19;
+    public static final int STATUS_BAD_VALUE = -22;
+    public static final int STATUS_DEAD_OBJECT = -32;
+    public static final int STATUS_INVALID_OPERATION = -38;
+
+    /*****************************************************************************
+     * A ModuleProperties describes a given sound trigger hardware module
+     * managed by the native sound trigger service. Each module has a unique
+     * ID used to target any API call to this paricular module. Module
+     * properties are returned by listModules() method.
+     ****************************************************************************/
+    public static class ModuleProperties {
+        /** Unique module ID provided by the native service */
+        public final int id;
+
+        /** human readable voice detection engine implementor */
+        public final String implementor;
+
+        /** human readable voice detection engine description */
+        public final String description;
+
+        /** Unique voice engine Id (changes with each version) */
+        public final UUID uuid;
+
+        /** Voice detection engine version */
+        public final int version;
+
+        /** Maximum number of active sound models */
+        public final int maxSoundModels;
+
+        /** Maximum number of key phrases */
+        public final int maxKeyPhrases;
+
+        /** Maximum number of users per key phrase */
+        public final int maxUsers;
+
+        /** Supported recognition modes (bit field, RECOGNITION_MODE_VOICE_TRIGGER ...) */
+        public final int recognitionModes;
+
+        /** Supports seamless transition to capture mode after recognition */
+        public final boolean supportsCaptureTransition;
+
+        /** Maximum buffering capacity in ms if supportsCaptureTransition() is true */
+        public final int maxBufferMs;
+
+        /** Supports capture by other use cases while detection is active */
+        public final boolean supportsConcurrentCapture;
+
+        /** Rated power consumption when detection is active with TDB silence/sound/speech ratio */
+        public final int powerConsumptionMw;
+
+        ModuleProperties(int id, String implementor, String description,
+                String uuid, int version, int maxSoundModels, int maxKeyPhrases,
+                int maxUsers, int recognitionModes, boolean supportsCaptureTransition,
+                int maxBufferMs, boolean supportsConcurrentCapture,
+                int powerConsumptionMw) {
+            this.id = id;
+            this.implementor = implementor;
+            this.description = description;
+            this.uuid = UUID.fromString(uuid);
+            this.version = version;
+            this.maxSoundModels = maxSoundModels;
+            this.maxKeyPhrases = maxKeyPhrases;
+            this.maxUsers = maxUsers;
+            this.recognitionModes = recognitionModes;
+            this.supportsCaptureTransition = supportsCaptureTransition;
+            this.maxBufferMs = maxBufferMs;
+            this.supportsConcurrentCapture = supportsConcurrentCapture;
+            this.powerConsumptionMw = powerConsumptionMw;
+        }
+    }
+
+    /*****************************************************************************
+     * A SoundModel describes the attributes and contains the binary data used by the hardware
+     * implementation to detect a particular sound pattern.
+     * A specialized version {@link KeyPhraseSoundModel} is defined for key phrase
+     * sound models.
+     ****************************************************************************/
+    public static class SoundModel {
+        /** Undefined sound model type */
+        public static final int TYPE_UNKNOWN = -1;
+
+        /** Keyphrase sound model */
+        public static final int TYPE_KEYPHRASE = 0;
+
+        /** Sound model type (e.g. TYPE_KEYPHRASE); */
+        public final int type;
+
+        /** Opaque data. For use by vendor implementation and enrollment application */
+        public final byte[] data;
+
+        public SoundModel(int type, byte[] data) {
+            this.type = type;
+            this.data = data;
+        }
+    }
+
+    /*****************************************************************************
+     * A KeyPhrase describes a key phrase that can be detected by a
+     * {@link KeyPhraseSoundModel}
+     ****************************************************************************/
+    public static class KeyPhrase {
+        /** Recognition modes supported for this key phrase in the model */
+        public final int recognitionModes;
+
+        /** Locale of the keyphrase. JAVA Locale string e.g en_US */
+        public final String locale;
+
+        /** Key phrase text */
+        public final String text;
+
+        /** Number of users this key phrase has been trained for */
+        public final int numUsers;
+
+        public KeyPhrase(int recognitionModes, String locale, String text, int numUsers) {
+            this.recognitionModes = recognitionModes;
+            this.locale = locale;
+            this.text = text;
+            this.numUsers = numUsers;
+        }
+    }
+
+    /*****************************************************************************
+     * A KeyPhraseSoundModel is a specialized {@link SoundModel} for key phrases.
+     * It contains data needed by the hardware to detect a certain number of key phrases
+     * and the list of corresponding {@link KeyPhrase} descriptors.
+     ****************************************************************************/
+    public static class KeyPhraseSoundModel extends SoundModel {
+        /** Key phrases in this sound model */
+        public final KeyPhrase[] keyPhrases; // keyword phrases in model
+
+        public KeyPhraseSoundModel(byte[] data, KeyPhrase[] keyPhrases) {
+            super(TYPE_KEYPHRASE, data);
+            this.keyPhrases = keyPhrases;
+        }
+    }
+
+    /**
+     *  Modes for key phrase recognition
+     */
+    /** Simple recognition of the key phrase */
+    public static final int RECOGNITION_MODE_VOICE_TRIGGER = 0x1;
+    /** Trigger only if one user is identified */
+    public static final int RECOGNITION_MODE_USER_IDENTIFICATION = 0x2;
+    /** Trigger only if one user is authenticated */
+    public static final int RECOGNITION_MODE_USER_AUTHENTICATION = 0x4;
+
+    /**
+     *  Status codes for {@link RecognitionEvent}
+     */
+    /** Recognition success */
+    public static final int RECOGNITION_STATUS_SUCCESS = 0;
+    /** Recognition aborted (e.g. capture preempted by anotehr use case */
+    public static final int RECOGNITION_STATUS_ABORT = 1;
+    /** Recognition failure */
+    public static final int RECOGNITION_STATUS_FAILURE = 2;
+
+    /**
+     *  A RecognitionEvent is provided by the
+     *  {@link StatusListener#onRecognition(RecognitionEvent)}
+     *  callback upon recognition success or failure.
+     */
+    public static class RecognitionEvent {
+        /** Recognition status e.g {@link #RECOGNITION_STATUS_SUCCESS} */
+        public final int status;
+        /** Sound Model corresponding to this event callback */
+        public final int soundModelHandle;
+        /** True if it is possible to capture audio from this utterance buffered by the hardware */
+        public final boolean captureAvailable;
+        /** Audio session ID to be used when capturing the utterance with an AudioRecord
+         * if captureAvailable() is true. */
+        public final int captureSession;
+        /** Delay in ms between end of model detection and start of audio available for capture.
+         * A negative value is possible (e.g. if keyphrase is also available for capture) */
+        public final int captureDelayMs;
+        /** Opaque data for use by system applications who know about voice engine internals,
+         * typically during enrollment. */
+        public final byte[] data;
+
+        RecognitionEvent(int status, int soundModelHandle, boolean captureAvailable,
+                int captureSession, int captureDelayMs, byte[] data) {
+            this.status = status;
+            this.soundModelHandle = soundModelHandle;
+            this.captureAvailable = captureAvailable;
+            this.captureSession = captureSession;
+            this.captureDelayMs = captureDelayMs;
+            this.data = data;
+        }
+    }
+
+    /**
+     *  Additional data conveyed by a {@link KeyPhraseRecognitionEvent}
+     *  for a key phrase detection.
+     */
+    public static class KeyPhraseRecognitionExtra {
+        /** Confidence level for each user defined in the key phrase in the same order as
+         * users in the key phrase. The confidence level is expressed in percentage (0% -100%) */
+        public final int[] confidenceLevels;
+
+        /** Recognition modes matched for this event */
+        public final int recognitionModes;
+
+        KeyPhraseRecognitionExtra(int[] confidenceLevels, int recognitionModes) {
+            this.confidenceLevels = confidenceLevels;
+            this.recognitionModes = recognitionModes;
+        }
+    }
+
+    /**
+     *  Specialized {@link RecognitionEvent} for a key phrase detection.
+     */
+    public static class KeyPhraseRecognitionEvent extends RecognitionEvent {
+        /** Indicates if the key phrase is present in the buffered audio available for capture */
+        public final KeyPhraseRecognitionExtra[] keyPhraseExtras;
+
+        /** Additional data available for each recognized key phrases in the model */
+        public final boolean keyPhraseInCapture;
+
+        KeyPhraseRecognitionEvent(int status, int soundModelHandle, boolean captureAvailable,
+               int captureSession, int captureDelayMs, byte[] data,
+               boolean keyPhraseInCapture, KeyPhraseRecognitionExtra[] keyPhraseExtras) {
+            super(status, soundModelHandle, captureAvailable, captureSession, captureDelayMs, data);
+            this.keyPhraseInCapture = keyPhraseInCapture;
+            this.keyPhraseExtras = keyPhraseExtras;
+        }
+    }
+
+    /**
+     * Returns a list of descriptors for all harware modules loaded.
+     * @param modules A ModuleProperties array where the list will be returned.
+     * @return - {@link #STATUS_OK} in case of success
+     *         - {@link #STATUS_ERROR} in case of unspecified error
+     *         - {@link #STATUS_PERMISSION_DENIED} if the caller does not have system permission
+     *         - {@link #STATUS_NO_INIT} if the native service cannot be reached
+     *         - {@link #STATUS_BAD_VALUE} if modules is null
+     *         - {@link #STATUS_DEAD_OBJECT} if the binder transaction to the native service fails
+     */
+    public static native int listModules(ArrayList <ModuleProperties> modules);
+
+    /**
+     * Get an interface on a hardware module to control sound models and recognition on
+     * this module.
+     * @param moduleId Sound module system identifier {@link ModuleProperties#id}. mandatory.
+     * @param listener {@link StatusListener} interface. Mandatory.
+     * @param handler the Handler that will receive the callabcks. Can be null if default handler
+     *                is OK.
+     * @return a valid sound module in case of success or null in case of error.
+     */
+    public static SoundTriggerModule attachModule(int moduleId,
+                                                  StatusListener listener,
+                                                  Handler handler) {
+        if (listener == null) {
+            return null;
+        }
+        SoundTriggerModule module = new SoundTriggerModule(moduleId, listener, handler);
+        return module;
+    }
+
+    /**
+     * Interface provided by the client application when attaching to a {@link SoundTriggerModule}
+     * to received recognition and error notifications.
+     */
+    public static interface StatusListener {
+        /**
+         * Called when recognition succeeds of fails
+         */
+        public abstract void onRecognition(RecognitionEvent event);
+
+        /**
+         * Called when the sound trigger native service dies
+         */
+        public abstract void onServiceDied();
+    }
+}
diff --git a/core/java/android/hardware/soundtrigger/SoundTriggerModule.java b/core/java/android/hardware/soundtrigger/SoundTriggerModule.java
new file mode 100644
index 0000000..776f85d
--- /dev/null
+++ b/core/java/android/hardware/soundtrigger/SoundTriggerModule.java
@@ -0,0 +1,192 @@
+/*
+ * 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.hardware.soundtrigger;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import java.lang.ref.WeakReference;
+import java.util.UUID;
+
+/**
+ * The SoundTriggerModule provides APIs to control sound models and sound detection
+ * on a given sound trigger hardware module.
+ *
+ * @hide
+ */
+public class SoundTriggerModule {
+    private long mNativeContext;
+
+    private int mId;
+    private NativeEventHandlerDelegate mEventHandlerDelegate;
+
+    private static final int EVENT_RECOGNITION = 1;
+    private static final int EVENT_SERVICE_DIED = 2;
+
+    SoundTriggerModule(int moduleId, SoundTrigger.StatusListener listener, Handler handler) {
+        mId = moduleId;
+        mEventHandlerDelegate = new NativeEventHandlerDelegate(listener, handler);
+        native_setup(new WeakReference<SoundTriggerModule>(this));
+    }
+    private native void native_setup(Object module_this);
+
+    @Override
+    protected void finalize() {
+        native_finalize();
+    }
+    private native void native_finalize();
+
+    /**
+     * Detach from this module. The {@link SoundTrigger.StatusListener} callback will not be called
+     * anymore and associated resources will be released.
+     * */
+    public native void detach();
+
+    /**
+     * Load a {@link SoundTrigger.SoundModel} to the hardware. A sound model must be loaded in
+     * order to start listening to a key phrase in this model.
+     * @param model The sound model to load.
+     * @param soundModelHandle an array of int where the sound model handle will be returned.
+     * @return - {@link SoundTrigger#STATUS_OK} in case of success
+     *         - {@link SoundTrigger#STATUS_ERROR} in case of unspecified error
+     *         - {@link SoundTrigger#STATUS_PERMISSION_DENIED} if the caller does not have
+     *         system permission
+     *         - {@link SoundTrigger#STATUS_NO_INIT} if the native service cannot be reached
+     *         - {@link SoundTrigger#STATUS_BAD_VALUE} if parameters are invalid
+     *         - {@link SoundTrigger#STATUS_DEAD_OBJECT} if the binder transaction to the native
+     *         service fails
+     *         - {@link SoundTrigger#STATUS_INVALID_OPERATION} if the call is out of sequence
+     */
+    public native int loadSoundModel(SoundTrigger.SoundModel model, int[] soundModelHandle);
+
+    /**
+     * Unload a {@link SoundTrigger.SoundModel} and abort any pendiong recognition
+     * @param soundModelHandle The sound model handle
+     * @return - {@link SoundTrigger#STATUS_OK} in case of success
+     *         - {@link SoundTrigger#STATUS_ERROR} in case of unspecified error
+     *         - {@link SoundTrigger#STATUS_PERMISSION_DENIED} if the caller does not have
+     *         system permission
+     *         - {@link SoundTrigger#STATUS_NO_INIT} if the native service cannot be reached
+     *         - {@link SoundTrigger#STATUS_BAD_VALUE} if the sound model handle is invalid
+     *         - {@link SoundTrigger#STATUS_DEAD_OBJECT} if the binder transaction to the native
+     *         service fails
+     */
+    public native int unloadSoundModel(int soundModelHandle);
+
+    /**
+     * Start listening to all key phrases in a {@link SoundTrigger.SoundModel}.
+     * Recognition must be restarted after each callback (success or failure) received on
+     * the {@link SoundTrigger.StatusListener}.
+     * @param soundModelHandle The sound model handle to start listening to
+     * @param data Opaque data for use by the implementation for this recognition
+     * @return - {@link SoundTrigger#STATUS_OK} in case of success
+     *         - {@link SoundTrigger#STATUS_ERROR} in case of unspecified error
+     *         - {@link SoundTrigger#STATUS_PERMISSION_DENIED} if the caller does not have
+     *         system permission
+     *         - {@link SoundTrigger#STATUS_NO_INIT} if the native service cannot be reached
+     *         - {@link SoundTrigger#STATUS_BAD_VALUE} if the sound model handle is invalid
+     *         - {@link SoundTrigger#STATUS_DEAD_OBJECT} if the binder transaction to the native
+     *         service fails
+     *         - {@link SoundTrigger#STATUS_INVALID_OPERATION} if the call is out of sequence
+     */
+    public native int startRecognition(int soundModelHandle, byte[] data);
+
+    /**
+     * Stop listening to all key phrases in a {@link SoundTrigger.SoundModel}
+     * @param soundModelHandle The sound model handle to stop listening to
+     * @return - {@link SoundTrigger#STATUS_OK} in case of success
+     *         - {@link SoundTrigger#STATUS_ERROR} in case of unspecified error
+     *         - {@link SoundTrigger#STATUS_PERMISSION_DENIED} if the caller does not have
+     *         system permission
+     *         - {@link SoundTrigger#STATUS_NO_INIT} if the native service cannot be reached
+     *         - {@link SoundTrigger#STATUS_BAD_VALUE} if the sound model handle is invalid
+     *         - {@link SoundTrigger#STATUS_DEAD_OBJECT} if the binder transaction to the native
+     *         service fails
+     *         - {@link SoundTrigger#STATUS_INVALID_OPERATION} if the call is out of sequence
+     */
+    public native int stopRecognition(int soundModelHandle);
+
+    private class NativeEventHandlerDelegate {
+        private final Handler mHandler;
+
+        NativeEventHandlerDelegate(final SoundTrigger.StatusListener listener,
+                                   Handler handler) {
+            // find the looper for our new event handler
+            Looper looper;
+            if (handler != null) {
+                looper = handler.getLooper();
+            } else {
+                looper = Looper.myLooper();
+                if (looper == null) {
+                    looper = Looper.getMainLooper();
+                }
+            }
+
+            // construct the event handler with this looper
+            if (looper != null) {
+                // implement the event handler delegate
+                mHandler = new Handler(looper) {
+                    @Override
+                    public void handleMessage(Message msg) {
+                        switch(msg.what) {
+                        case EVENT_RECOGNITION:
+                            if (listener != null) {
+                                listener.onRecognition(
+                                        (SoundTrigger.RecognitionEvent)msg.obj);
+                            }
+                            break;
+                        case EVENT_SERVICE_DIED:
+                            if (listener != null) {
+                                listener.onServiceDied();
+                            }
+                            break;
+                        default:
+                            break;
+                        }
+                    }
+                };
+            } else {
+                mHandler = null;
+            }
+        }
+
+        Handler handler() {
+            return mHandler;
+        }
+    }
+
+    @SuppressWarnings("unused")
+    private static void postEventFromNative(Object module_ref,
+                                            int what, int arg1, int arg2, Object obj) {
+        SoundTriggerModule module = (SoundTriggerModule)((WeakReference)module_ref).get();
+        if (module == null) {
+            return;
+        }
+
+        NativeEventHandlerDelegate delegate = module.mEventHandlerDelegate;
+        if (delegate != null) {
+            Handler handler = delegate.handler();
+            if (handler != null) {
+                Message m = handler.obtainMessage(what, arg1, arg2, obj);
+                handler.sendMessage(m);
+            }
+        }
+    }
+}
+
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index a48a388..b96f166 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -870,6 +870,40 @@
         return 1;
     }
 
+    /**
+     * Removes the NET_CAPABILITY_NOT_RESTRICTED capability from the given
+     * NetworkCapabilities object if all the capabilities it provides are
+     * typically provided by restricted networks.
+     *
+     * TODO: consider:
+     * - Moving to NetworkCapabilities
+     * - Renaming it to guessRestrictedCapability and make it set the
+     *   restricted capability bit in addition to clearing it.
+     * @hide
+     */
+    public static void maybeMarkCapabilitiesRestricted(NetworkCapabilities nc) {
+        for (Integer capability : nc.getNetworkCapabilities()) {
+            switch (capability.intValue()) {
+                case NetworkCapabilities.NET_CAPABILITY_CBS:
+                case NetworkCapabilities.NET_CAPABILITY_DUN:
+                case NetworkCapabilities.NET_CAPABILITY_EIMS:
+                case NetworkCapabilities.NET_CAPABILITY_FOTA:
+                case NetworkCapabilities.NET_CAPABILITY_IA:
+                case NetworkCapabilities.NET_CAPABILITY_IMS:
+                case NetworkCapabilities.NET_CAPABILITY_RCS:
+                case NetworkCapabilities.NET_CAPABILITY_XCAP:
+                    continue;
+                default:
+                    // At least one capability usually provided by unrestricted
+                    // networks. Conclude that this network is unrestricted.
+                    return;
+            }
+        }
+        // All the capabilities are typically provided by restricted networks.
+        // Conclude that this network is restricted.
+        nc.removeNetworkCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
+    }
+
     private NetworkCapabilities networkCapabilitiesForFeature(int networkType, String feature) {
         if (networkType == TYPE_MOBILE) {
             int cap = -1;
@@ -893,12 +927,14 @@
             NetworkCapabilities netCap = new NetworkCapabilities();
             netCap.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
             netCap.addNetworkCapability(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);
+                maybeMarkCapabilitiesRestricted(netCap);
                 return netCap;
             }
         }
diff --git a/core/java/android/net/ProxyDataTracker.java b/core/java/android/net/ProxyDataTracker.java
index 4973b3d..0340e7e 100644
--- a/core/java/android/net/ProxyDataTracker.java
+++ b/core/java/android/net/ProxyDataTracker.java
@@ -48,6 +48,7 @@
     // TODO: investigate how to get these DNS addresses from the system.
     private static final String DNS1 = "8.8.8.8";
     private static final String DNS2 = "8.8.4.4";
+    private static final String INTERFACE_NAME = "ifb0";
     private static final String REASON_ENABLED = "enabled";
     private static final String REASON_DISABLED = "disabled";
     private static final String REASON_PROXY_DOWN = "proxy_down";
@@ -107,10 +108,11 @@
         mNetworkCapabilities = new NetworkCapabilities();
         mNetworkInfo.setIsAvailable(true);
         try {
-          mLinkProperties.addDns(InetAddress.getByName(DNS1));
-          mLinkProperties.addDns(InetAddress.getByName(DNS2));
+            mLinkProperties.addDns(InetAddress.getByName(DNS1));
+            mLinkProperties.addDns(InetAddress.getByName(DNS2));
+            mLinkProperties.setInterfaceName(INTERFACE_NAME);
         } catch (UnknownHostException e) {
-          Log.e(TAG, "Could not add DNS address", e);
+            Log.e(TAG, "Could not add DNS address", e);
         }
     }
 
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index e84b695..975bfc2 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -292,6 +292,17 @@
     }
 
     /**
+     * Returns the config directory for a user. This is for use by system services to store files
+     * relating to the user which should be readable by any app running as that user.
+     *
+     * @hide
+     */
+    public static File getUserConfigDirectory(int userId) {
+        return new File(new File(new File(
+                getDataDirectory(), "misc"), "user"), Integer.toString(userId));
+    }
+
+    /**
      * Returns whether the Encrypted File System feature is enabled on the device or not.
      * @return <code>true</code> if Encrypted File System feature is enabled, <code>false</code>
      * if disabled.
diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl
index 61194e9..658180b 100644
--- a/core/java/android/os/IPowerManager.aidl
+++ b/core/java/android/os/IPowerManager.aidl
@@ -41,6 +41,7 @@
     void goToSleep(long time, int reason, int flags);
     void nap(long time);
     boolean isInteractive();
+    boolean isPowerSaveMode();
 
     void reboot(boolean confirm, String reason, boolean wait);
     void shutdown(boolean confirm, boolean wait);
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index d5177e8..92e80a5 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -16,6 +16,7 @@
 
 package android.os;
 
+import android.annotation.SdkConstant;
 import android.content.Context;
 import android.util.Log;
 
@@ -685,6 +686,30 @@
     }
 
     /**
+     * Returns true if the device is currently in power save mode.  When in this mode,
+     * applications should reduce their functionality in order to conserve battery as
+     * much as possible.  You can monitor for changes to this state with
+     * {@link #ACTION_POWER_SAVE_MODE_CHANGED}.
+     *
+     * @return Returns true if currently in low power mode, else false.
+     */
+    public boolean isPowerSaveMode() {
+        try {
+            return mService.isPowerSaveMode();
+        } catch (RemoteException e) {
+            return false;
+        }
+    }
+
+    /**
+     * Intent that is broadcast when the state of {@link #isPowerSaveMode()} changes.
+     * This broadcast is only sent to registered receivers.
+     */
+    @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_POWER_SAVE_MODE_CHANGED
+            = "android.os.action.POWER_SAVE_MODE_CHANGED";
+
+    /**
      * A wake lock is a mechanism to indicate that your application needs
      * to have the device stay on.
      * <p>
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 112ec1d..86c749a 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -156,6 +156,12 @@
     public static final int LAST_ISOLATED_UID = 99999;
 
     /**
+     * Defines the gid shared by all applications running under the same profile.
+     * @hide
+     */
+    public static final int SHARED_USER_GID = 9997;
+
+    /**
      * First gid for applications to share resources. Used when forward-locking
      * is enabled but all UserHandles need to be able to read the resources.
      * @hide
diff --git a/core/java/android/os/UserHandle.java b/core/java/android/os/UserHandle.java
index 6e693a4..914c170 100644
--- a/core/java/android/os/UserHandle.java
+++ b/core/java/android/os/UserHandle.java
@@ -145,6 +145,14 @@
     }
 
     /**
+     * Returns the gid shared between all apps with this userId.
+     * @hide
+     */
+    public static final int getUserGid(int userId) {
+        return getUid(userId, Process.SHARED_USER_GID);
+    }
+
+    /**
      * Returns the shared app gid for a given uid or appId.
      * @hide
      */
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index ee219e3..f7a89ba 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -690,18 +690,47 @@
         }
     }
 
+    /**
+     * If the target user is a managed profile of the calling user or the caller
+     * is itself a managed profile, then this returns a drawable to use as a small
+     * icon to include in a view to distinguish it from the original icon.
+     *
+     * @param user The target user.
+     * @return the drawable or null if no drawable is required.
+     * @hide
+     */
+    public Drawable getBadgeForUser(UserHandle user) {
+        UserInfo userInfo = getUserIfProfile(user.getIdentifier());
+        if (userInfo != null && userInfo.isManagedProfile()) {
+            return Resources.getSystem().getDrawable(
+                    com.android.internal.R.drawable.ic_corp_badge);
+        }
+        return null;
+    }
+
     private int getBadgeResIdForUser(int userHandle) {
         // Return the framework-provided badge.
-        List<UserInfo> userProfiles = getProfiles(getUserHandle());
-        for (UserInfo user : userProfiles) {
-            if (user.id == userHandle
-                    && user.isManagedProfile()) {
-                return com.android.internal.R.drawable.ic_corp_badge;
-            }
+        UserInfo userInfo = getUserIfProfile(userHandle);
+        if (userInfo != null && userInfo.isManagedProfile()) {
+            return com.android.internal.R.drawable.ic_corp_icon_badge;
         }
         return 0;
     }
 
+    /**
+     * @return UserInfo for userHandle if it exists and is a profile of the current
+     *         user or null.
+     */
+    private UserInfo getUserIfProfile(int userHandle) {
+        List<UserInfo> userProfiles = getProfiles(getUserHandle());
+        for (UserInfo user : userProfiles) {
+            if (user.id == userHandle) {
+                return user;
+            }
+        }
+        return null;
+    }
+
     private Drawable getMergedDrawable(Drawable icon, Drawable badge) {
         final int width = icon.getIntrinsicWidth();
         final int height = icon.getIntrinsicHeight();
diff --git a/core/java/android/print/ILayoutResultCallback.aidl b/core/java/android/print/ILayoutResultCallback.aidl
index 43b8c30..68c1dac 100644
--- a/core/java/android/print/ILayoutResultCallback.aidl
+++ b/core/java/android/print/ILayoutResultCallback.aidl
@@ -16,6 +16,7 @@
 
 package android.print;
 
+import android.os.ICancellationSignal;
 import android.print.PrintDocumentInfo;
 
 /**
@@ -24,6 +25,8 @@
  * @hide
  */
 oneway interface ILayoutResultCallback {
+    void onLayoutStarted(ICancellationSignal cancellation, int sequence);
     void onLayoutFinished(in PrintDocumentInfo info, boolean changed, int sequence);
     void onLayoutFailed(CharSequence error, int sequence);
+    void onLayoutCanceled(int sequence);
 }
diff --git a/core/java/android/print/IPrintDocumentAdapter.aidl b/core/java/android/print/IPrintDocumentAdapter.aidl
index 2b95c12..9d384fb 100644
--- a/core/java/android/print/IPrintDocumentAdapter.aidl
+++ b/core/java/android/print/IPrintDocumentAdapter.aidl
@@ -37,5 +37,4 @@
     void write(in PageRange[] pages, in ParcelFileDescriptor fd,
             IWriteResultCallback callback, int sequence);
     void finish();
-    void cancel();
 }
diff --git a/core/java/android/print/IWriteResultCallback.aidl b/core/java/android/print/IWriteResultCallback.aidl
index 8281c4e..8fb33e1 100644
--- a/core/java/android/print/IWriteResultCallback.aidl
+++ b/core/java/android/print/IWriteResultCallback.aidl
@@ -16,6 +16,7 @@
 
 package android.print;
 
+import android.os.ICancellationSignal;
 import android.print.PageRange;
 
 /**
@@ -24,6 +25,8 @@
  * @hide
  */
 oneway interface IWriteResultCallback {
+    void onWriteStarted(ICancellationSignal cancellation, int sequence);
     void onWriteFinished(in PageRange[] pages, int sequence);
     void onWriteFailed(CharSequence error, int sequence);
+    void onWriteCanceled(int sequence);
 }
diff --git a/core/java/android/print/PrintAttributes.java b/core/java/android/print/PrintAttributes.java
index c6254e0..2810d55 100644
--- a/core/java/android/print/PrintAttributes.java
+++ b/core/java/android/print/PrintAttributes.java
@@ -151,6 +151,105 @@
         mColorMode = colorMode;
     }
 
+    /**
+     * Gets whether this print attributes are in portrait orientation,
+     * which is the media size is in portrait and all orientation dependent
+     * attributes such as resolution and margins are properly adjusted.
+     *
+     * @return Whether this print attributes are in portrait.
+     *
+     * @hide
+     */
+    public boolean isPortrait() {
+        return mMediaSize.isPortrait();
+    }
+
+    /**
+     * Gets a new print attributes instance which is in portrait orientation,
+     * which is the media size is in portrait and all orientation dependent
+     * attributes such as resolution and margins are properly adjusted.
+     *
+     * @return New instance in portrait orientation if this one is in
+     * landscape, otherwise this instance.
+     *
+     * @hide
+     */
+    public PrintAttributes asPortrait() {
+        if (isPortrait()) {
+            return this;
+        }
+
+        PrintAttributes attributes = new PrintAttributes();
+
+        // Rotate the media size.
+        attributes.setMediaSize(getMediaSize().asPortrait());
+
+        // Rotate the resolution.
+        Resolution oldResolution = getResolution();
+        Resolution newResolution = new Resolution(
+                oldResolution.getId(),
+                oldResolution.getLabel(),
+                oldResolution.getVerticalDpi(),
+                oldResolution.getHorizontalDpi());
+        attributes.setResolution(newResolution);
+
+        // Rotate the physical margins.
+        Margins oldMinMargins = getMinMargins();
+        Margins newMinMargins = new Margins(
+                oldMinMargins.getBottomMils(),
+                oldMinMargins.getLeftMils(),
+                oldMinMargins.getTopMils(),
+                oldMinMargins.getRightMils());
+        attributes.setMinMargins(newMinMargins);
+
+        attributes.setColorMode(getColorMode());
+
+        return attributes;
+    }
+
+    /**
+     * Gets a new print attributes instance which is in landscape orientation,
+     * which is the media size is in landscape and all orientation dependent
+     * attributes such as resolution and margins are properly adjusted.
+     *
+     * @return New instance in landscape orientation if this one is in
+     * portrait, otherwise this instance.
+     *
+     * @hide
+     */
+    public PrintAttributes asLandscape() {
+        if (!isPortrait()) {
+            return this;
+        }
+
+        PrintAttributes attributes = new PrintAttributes();
+
+        // Rotate the media size.
+        attributes.setMediaSize(getMediaSize().asLandscape());
+
+        // Rotate the resolution.
+        Resolution oldResolution = getResolution();
+        Resolution newResolution = new Resolution(
+                oldResolution.getId(),
+                oldResolution.getLabel(),
+                oldResolution.getVerticalDpi(),
+                oldResolution.getHorizontalDpi());
+        attributes.setResolution(newResolution);
+
+        // Rotate the physical margins.
+        Margins oldMinMargins = getMinMargins();
+        Margins newMargins = new Margins(
+                oldMinMargins.getTopMils(),
+                oldMinMargins.getRightMils(),
+                oldMinMargins.getBottomMils(),
+                oldMinMargins.getLeftMils());
+        attributes.setMinMargins(newMargins);
+
+        attributes.setColorMode(getColorMode());
+
+        return attributes;
+    }
+
     @Override
     public void writeToParcel(Parcel parcel, int flags) {
         if (mMediaSize != null) {
diff --git a/core/java/android/print/PrintManager.java b/core/java/android/print/PrintManager.java
index 811751d..9361286 100644
--- a/core/java/android/print/PrintManager.java
+++ b/core/java/android/print/PrintManager.java
@@ -24,6 +24,7 @@
 import android.os.Bundle;
 import android.os.CancellationSignal;
 import android.os.Handler;
+import android.os.ICancellationSignal;
 import android.os.Looper;
 import android.os.Message;
 import android.os.ParcelFileDescriptor;
@@ -41,6 +42,7 @@
 
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
@@ -50,12 +52,12 @@
  * <p>
  * To obtain a handle to the print manager do the following:
  * </p>
- * 
+ *
  * <pre>
  * PrintManager printManager =
  *         (PrintManager) context.getSystemService(Context.PRINT_SERVICE);
  * </pre>
- * 
+ *
  * <h3>Print mechanics</h3>
  * <p>
  * The key idea behind printing on the platform is that the content to be printed
@@ -344,7 +346,7 @@
         try {
             mService.cancelPrintJob(printJobId, mAppId, mUserId);
         } catch (RemoteException re) {
-            Log.e(LOG_TAG, "Error cancleing a print job: " + printJobId, re);
+            Log.e(LOG_TAG, "Error canceling a print job: " + printJobId, re);
         }
     }
 
@@ -505,30 +507,17 @@
 
     private static final class PrintDocumentAdapterDelegate extends IPrintDocumentAdapter.Stub
             implements ActivityLifecycleCallbacks {
-
         private final Object mLock = new Object();
 
-        private CancellationSignal mLayoutOrWriteCancellation;
+        private Activity mActivity; // Strong reference OK - cleared in destroy
 
-        private Activity mActivity; // Strong reference OK - cleared in finish()
+        private PrintDocumentAdapter mDocumentAdapter; // Strong reference OK - cleared in destroy
 
-        private PrintDocumentAdapter mDocumentAdapter; // Strong reference OK - cleared in finish
+        private Handler mHandler; // Strong reference OK - cleared in destroy
 
-        private Handler mHandler; // Strong reference OK - cleared in finish()
+        private IPrintDocumentAdapterObserver mObserver; // Strong reference OK - cleared in destroy
 
-        private IPrintDocumentAdapterObserver mObserver; // Strong reference OK - cleared in finish
-
-        private LayoutSpec mLastLayoutSpec;
-
-        private WriteSpec mLastWriteSpec;
-
-        private boolean mStartReqeusted;
-        private boolean mStarted;
-
-        private boolean mFinishRequested;
-        private boolean mFinished;
-
-        private boolean mDestroyed;
+        private DestroyableCallback mPendingCallback;
 
         public PrintDocumentAdapterDelegate(Activity activity,
                 PrintDocumentAdapter documentAdapter) {
@@ -542,11 +531,10 @@
         public void setObserver(IPrintDocumentAdapterObserver observer) {
             final boolean destroyed;
             synchronized (mLock) {
-                if (!mDestroyed) {
-                    mObserver = observer;
-                }
-                destroyed = mDestroyed;
+                mObserver = observer;
+                destroyed = isDestroyedLocked();
             }
+
             if (destroyed) {
                 try {
                     observer.onDestroy();
@@ -559,126 +547,89 @@
         @Override
         public void start() {
             synchronized (mLock) {
-                // Started called or finish called or destroyed - nothing to do.
-                if (mStartReqeusted || mFinishRequested || mDestroyed) {
-                    return;
+                // If destroyed the handler is null.
+                if (!isDestroyedLocked()) {
+                    mHandler.obtainMessage(MyHandler.MSG_ON_START,
+                            mDocumentAdapter).sendToTarget();
                 }
-
-                mStartReqeusted = true;
-
-                doPendingWorkLocked();
             }
         }
 
         @Override
         public void layout(PrintAttributes oldAttributes, PrintAttributes newAttributes,
                 ILayoutResultCallback callback, Bundle metadata, int sequence) {
-            final boolean destroyed;
-            synchronized (mLock) {
-                destroyed = mDestroyed;
-                // If start called and not finished called and not destroyed - do some work.
-                if (mStartReqeusted && !mFinishRequested && !mDestroyed) {
-                    // Layout cancels write and overrides layout.
-                    if (mLastWriteSpec != null) {
-                        IoUtils.closeQuietly(mLastWriteSpec.fd);
-                        mLastWriteSpec = null;
-                    }
 
-                    mLastLayoutSpec = new LayoutSpec();
-                    mLastLayoutSpec.callback = callback;
-                    mLastLayoutSpec.oldAttributes = oldAttributes;
-                    mLastLayoutSpec.newAttributes = newAttributes;
-                    mLastLayoutSpec.metadata = metadata;
-                    mLastLayoutSpec.sequence = sequence;
-
-                    // Cancel the previous cancellable operation.When the
-                    // cancellation completes we will do the pending work.
-                    if (cancelPreviousCancellableOperationLocked()) {
-                        return;
-                    }
-
-                    doPendingWorkLocked();
-                }
+            ICancellationSignal cancellationTransport = CancellationSignal.createTransport();
+            try {
+                callback.onLayoutStarted(cancellationTransport, sequence);
+            } catch (RemoteException re) {
+                // The spooler is dead - can't recover.
+                Log.e(LOG_TAG, "Error notifying for layout start", re);
+                return;
             }
-            if (destroyed) {
-                try {
-                    callback.onLayoutFailed(null, sequence);
-                } catch (RemoteException re) {
-                    Log.i(LOG_TAG, "Error notifying for cancelled layout", re);
+
+            synchronized (mLock) {
+                // If destroyed the handler is null.
+                if (isDestroyedLocked()) {
+                    return;
                 }
+
+                CancellationSignal cancellationSignal = CancellationSignal.fromTransport(
+                        cancellationTransport);
+
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = mDocumentAdapter;
+                args.arg2 = oldAttributes;
+                args.arg3 = newAttributes;
+                args.arg4 = cancellationSignal;
+                args.arg5 = new MyLayoutResultCallback(callback, sequence);
+                args.arg6 = metadata;
+
+                mHandler.obtainMessage(MyHandler.MSG_ON_LAYOUT, args).sendToTarget();
             }
         }
 
         @Override
         public void write(PageRange[] pages, ParcelFileDescriptor fd,
                 IWriteResultCallback callback, int sequence) {
-            final boolean destroyed;
-            synchronized (mLock) {
-                destroyed = mDestroyed;
-                // If start called and not finished called and not destroyed - do some work.
-                if (mStartReqeusted && !mFinishRequested && !mDestroyed) {
-                    // Write cancels previous writes.
-                    if (mLastWriteSpec != null) {
-                        IoUtils.closeQuietly(mLastWriteSpec.fd);
-                        mLastWriteSpec = null;
-                    }
 
-                    mLastWriteSpec = new WriteSpec();
-                    mLastWriteSpec.callback = callback;
-                    mLastWriteSpec.pages = pages;
-                    mLastWriteSpec.fd = fd;
-                    mLastWriteSpec.sequence = sequence;
-
-                    // Cancel the previous cancellable operation.When the
-                    // cancellation completes we will do the pending work.
-                    if (cancelPreviousCancellableOperationLocked()) {
-                        return;
-                    }
-
-                    doPendingWorkLocked();
-                }
+            ICancellationSignal cancellationTransport = CancellationSignal.createTransport();
+            try {
+                callback.onWriteStarted(cancellationTransport, sequence);
+            } catch (RemoteException re) {
+                // The spooler is dead - can't recover.
+                Log.e(LOG_TAG, "Error notifying for write start", re);
+                return;
             }
-            if (destroyed) {
-                try {
-                    callback.onWriteFailed(null, sequence);
-                } catch (RemoteException re) {
-                    Log.i(LOG_TAG, "Error notifying for cancelled write", re);
+
+            synchronized (mLock) {
+                // If destroyed the handler is null.
+                if (isDestroyedLocked()) {
+                    return;
                 }
+
+                CancellationSignal cancellationSignal = CancellationSignal.fromTransport(
+                        cancellationTransport);
+
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = mDocumentAdapter;
+                args.arg2 = pages;
+                args.arg3 = fd;
+                args.arg4 = cancellationSignal;
+                args.arg5 = new MyWriteResultCallback(callback, fd, sequence);
+
+                mHandler.obtainMessage(MyHandler.MSG_ON_WRITE, args).sendToTarget();
             }
         }
 
         @Override
         public void finish() {
             synchronized (mLock) {
-                // Start not called or finish called or destroyed - nothing to do.
-                if (!mStartReqeusted || mFinishRequested || mDestroyed) {
-                    return;
+                // If destroyed the handler is null.
+                if (!isDestroyedLocked()) {
+                    mHandler.obtainMessage(MyHandler.MSG_ON_FINISH,
+                            mDocumentAdapter).sendToTarget();
                 }
-
-                mFinishRequested = true;
-
-                // When the current write or layout complete we
-                // will do the pending work.
-                if (mLastLayoutSpec != null || mLastWriteSpec != null) {
-                    if (DEBUG) {
-                        Log.i(LOG_TAG, "Waiting for current operation");
-                    }
-                    return;
-                }
-
-                doPendingWorkLocked();
-            }
-        }
-
-        @Override
-        public void cancel() {
-            // Start not called or finish called or destroyed - nothing to do.
-            if (!mStartReqeusted || mFinishRequested || mDestroyed) {
-                return;
-            }
-            // Request cancellation of pending work if needed.
-            synchronized (mLock) {
-                cancelPreviousCancellableOperationLocked();
             }
         }
 
@@ -719,20 +670,14 @@
             // Note the the spooler has a death recipient that observes if
             // this process gets killed so we cover the case of onDestroy not
             // being called due to this process being killed to reclaim memory.
-            final IPrintDocumentAdapterObserver observer;
+            IPrintDocumentAdapterObserver observer = null;
             synchronized (mLock) {
                 if (activity == mActivity) {
-                    mDestroyed = true;
                     observer = mObserver;
-                    clearLocked();
-                } else {
-                    observer = null;
-                    activity = null;
+                    destroyLocked();
                 }
             }
             if (observer != null) {
-                activity.getApplication().unregisterActivityLifecycleCallbacks(
-                        PrintDocumentAdapterDelegate.this);
                 try {
                     observer.onDestroy();
                 } catch (RemoteException re) {
@@ -741,67 +686,39 @@
             }
         }
 
-        private boolean isFinished() {
-            return mDocumentAdapter == null;
+        private boolean isDestroyedLocked() {
+            return (mActivity == null);
         }
 
-        private void clearLocked() {
+        private void destroyLocked() {
+            mActivity.getApplication().unregisterActivityLifecycleCallbacks(
+                    PrintDocumentAdapterDelegate.this);
             mActivity = null;
+
             mDocumentAdapter = null;
+
+            // This method is only called from the main thread, so
+            // clearing the messages guarantees that any time a
+            // message is handled we are not in a destroyed state.
+            mHandler.removeMessages(MyHandler.MSG_ON_START);
+            mHandler.removeMessages(MyHandler.MSG_ON_LAYOUT);
+            mHandler.removeMessages(MyHandler.MSG_ON_WRITE);
+            mHandler.removeMessages(MyHandler.MSG_ON_FINISH);
             mHandler = null;
-            mLayoutOrWriteCancellation = null;
-            mLastLayoutSpec = null;
-            if (mLastWriteSpec != null) {
-                IoUtils.closeQuietly(mLastWriteSpec.fd);
-                mLastWriteSpec = null;
+
+            mObserver = null;
+
+            if (mPendingCallback != null) {
+                mPendingCallback.destroy();
+                mPendingCallback = null;
             }
         }
 
-        private boolean cancelPreviousCancellableOperationLocked() {
-            if (mLayoutOrWriteCancellation != null) {
-                mLayoutOrWriteCancellation.cancel();
-                if (DEBUG) {
-                    Log.i(LOG_TAG, "Cancelling previous operation");
-                }
-                return true;
-            }
-            return false;
-        }
-
-        private void doPendingWorkLocked() {
-            if (mStartReqeusted && !mStarted) {
-                mStarted = true;
-                mHandler.sendEmptyMessage(MyHandler.MSG_START);
-            } else if (mLastLayoutSpec != null) {
-                mHandler.sendEmptyMessage(MyHandler.MSG_LAYOUT);
-            } else if (mLastWriteSpec != null) {
-                mHandler.sendEmptyMessage(MyHandler.MSG_WRITE);
-            } else if (mFinishRequested && !mFinished) {
-                mFinished = true;
-                mHandler.sendEmptyMessage(MyHandler.MSG_FINISH);
-            }
-        }
-
-        private class LayoutSpec {
-            ILayoutResultCallback callback;
-            PrintAttributes oldAttributes;
-            PrintAttributes newAttributes;
-            Bundle metadata;
-            int sequence;
-        }
-
-        private class WriteSpec {
-            IWriteResultCallback callback;
-            PageRange[] pages;
-            ParcelFileDescriptor fd;
-            int sequence;
-        }
-
         private final class MyHandler extends Handler {
-            public static final int MSG_START = 1;
-            public static final int MSG_LAYOUT = 2;
-            public static final int MSG_WRITE = 3;
-            public static final int MSG_FINISH = 4;
+            public static final int MSG_ON_START = 1;
+            public static final int MSG_ON_LAYOUT = 2;
+            public static final int MSG_ON_WRITE = 3;
+            public static final int MSG_ON_FINISH = 4;
 
             public MyHandler(Looper looper) {
                 super(looper, null, true);
@@ -809,84 +726,71 @@
 
             @Override
             public void handleMessage(Message message) {
-                if (isFinished()) {
-                    return;
-                }
                 switch (message.what) {
-                    case MSG_START: {
-                        final PrintDocumentAdapter adapter;
-                        synchronized (mLock) {
-                            adapter = mDocumentAdapter;
-                        }
-                        if (adapter != null) {
-                            adapter.onStart();
-                        }
-                    } break;
-
-                    case MSG_LAYOUT: {
-                        final PrintDocumentAdapter adapter;
-                        final CancellationSignal cancellation;
-                        final LayoutSpec layoutSpec;
-
-                        synchronized (mLock) {
-                            adapter = mDocumentAdapter;
-                            layoutSpec = mLastLayoutSpec;
-                            mLastLayoutSpec = null;
-                            cancellation = new CancellationSignal();
-                            mLayoutOrWriteCancellation = cancellation;
-                        }
-
-                        if (layoutSpec != null && adapter != null) {
-                            if (DEBUG) {
-                                Log.i(LOG_TAG, "Performing layout");
-                            }
-                            adapter.onLayout(layoutSpec.oldAttributes,
-                                    layoutSpec.newAttributes, cancellation,
-                                    new MyLayoutResultCallback(layoutSpec.callback,
-                                            layoutSpec.sequence), layoutSpec.metadata);
-                        }
-                    } break;
-
-                    case MSG_WRITE: {
-                        final PrintDocumentAdapter adapter;
-                        final CancellationSignal cancellation;
-                        final WriteSpec writeSpec;
-
-                        synchronized (mLock) {
-                            adapter = mDocumentAdapter;
-                            writeSpec = mLastWriteSpec;
-                            mLastWriteSpec = null;
-                            cancellation = new CancellationSignal();
-                            mLayoutOrWriteCancellation = cancellation;
-                        }
-
-                        if (writeSpec != null && adapter != null) {
-                            if (DEBUG) {
-                                Log.i(LOG_TAG, "Performing write");
-                            }
-                            adapter.onWrite(writeSpec.pages, writeSpec.fd,
-                                    cancellation, new MyWriteResultCallback(writeSpec.callback,
-                                            writeSpec.fd, writeSpec.sequence));
-                        }
-                    } break;
-
-                    case MSG_FINISH: {
+                    case MSG_ON_START: {
                         if (DEBUG) {
-                            Log.i(LOG_TAG, "Performing finish");
+                            Log.i(LOG_TAG, "onStart()");
                         }
-                        final PrintDocumentAdapter adapter;
-                        final Activity activity;
+
+                        ((PrintDocumentAdapter) message.obj).onStart();
+                    } break;
+
+                    case MSG_ON_LAYOUT: {
+                        SomeArgs args = (SomeArgs) message.obj;
+                        PrintDocumentAdapter adapter = (PrintDocumentAdapter) args.arg1;
+                        PrintAttributes oldAttributes = (PrintAttributes) args.arg2;
+                        PrintAttributes newAttributes = (PrintAttributes) args.arg3;
+                        CancellationSignal cancellation = (CancellationSignal) args.arg4;
+                        LayoutResultCallback callback = (LayoutResultCallback) args.arg5;
+                        Bundle metadata = (Bundle) args.arg6;
+                        args.recycle();
+
+                        if (DEBUG) {
+                            StringBuilder builder = new StringBuilder();
+                            builder.append("PrintDocumentAdapter#onLayout() {\n");
+                            builder.append("\n  oldAttributes:").append(oldAttributes);
+                            builder.append("\n  newAttributes:").append(newAttributes);
+                            builder.append("\n  preview:").append(metadata.getBoolean(
+                                    PrintDocumentAdapter.EXTRA_PRINT_PREVIEW));
+                            builder.append("\n}");
+                            Log.i(LOG_TAG, builder.toString());
+                        }
+
+                        adapter.onLayout(oldAttributes, newAttributes, cancellation,
+                                callback, metadata);
+                    } break;
+
+                    case MSG_ON_WRITE: {
+                        SomeArgs args = (SomeArgs) message.obj;
+                        PrintDocumentAdapter adapter = (PrintDocumentAdapter) args.arg1;
+                        PageRange[] pages = (PageRange[]) args.arg2;
+                        ParcelFileDescriptor fd = (ParcelFileDescriptor) args.arg3;
+                        CancellationSignal cancellation = (CancellationSignal) args.arg4;
+                        WriteResultCallback callback = (WriteResultCallback) args.arg5;
+                        args.recycle();
+
+                        if (DEBUG) {
+                            StringBuilder builder = new StringBuilder();
+                            builder.append("PrintDocumentAdapter#onWrite() {\n");
+                            builder.append("\n  pages:").append(Arrays.toString(pages));
+                            builder.append("\n}");
+                            Log.i(LOG_TAG, builder.toString());
+                        }
+
+                        adapter.onWrite(pages, fd, cancellation, callback);
+                    } break;
+
+                    case MSG_ON_FINISH: {
+                        if (DEBUG) {
+                            Log.i(LOG_TAG, "onFinish()");
+                        }
+
+                        ((PrintDocumentAdapter) message.obj).onFinish();
+
+                        // Done printing, so destroy this instance as it
+                        // should not be used anymore.
                         synchronized (mLock) {
-                            adapter = mDocumentAdapter;
-                            activity = mActivity;
-                            clearLocked();
-                        }
-                        if (adapter != null) {
-                            adapter.onFinish();
-                        }
-                        if (activity != null) {
-                            activity.getApplication().unregisterActivityLifecycleCallbacks(
-                                    PrintDocumentAdapterDelegate.this);
+                            destroyLocked();
                         }
                     } break;
 
@@ -898,7 +802,12 @@
             }
         }
 
-        private final class MyLayoutResultCallback extends LayoutResultCallback {
+        private interface DestroyableCallback {
+            public void destroy();
+        }
+
+        private final class MyLayoutResultCallback extends LayoutResultCallback
+                implements DestroyableCallback {
             private ILayoutResultCallback mCallback;
             private final int mSequence;
 
@@ -910,25 +819,31 @@
 
             @Override
             public void onLayoutFinished(PrintDocumentInfo info, boolean changed) {
-                if (info == null) {
-                    throw new NullPointerException("document info cannot be null");
-                }
                 final ILayoutResultCallback callback;
                 synchronized (mLock) {
-                    if (mDestroyed) {
-                        Log.e(LOG_TAG, "PrintDocumentAdapter is destroyed. Did you "
-                                + "finish the printing activity before print completion?");
-                        return;
-                    }
                     callback = mCallback;
-                    clearLocked();
                 }
-                if (callback != null) {
+
+                // If the callback is null we are destroyed.
+                if (callback == null) {
+                    Log.e(LOG_TAG, "PrintDocumentAdapter is destroyed. Did you "
+                            + "finish the printing activity before print completion "
+                            + "or did you invoke a callback after finish?");
+                    return;
+                }
+
+                try {
+                    if (info == null) {
+                        throw new NullPointerException("document info cannot be null");
+                    }
+
                     try {
                         callback.onLayoutFinished(info, changed, mSequence);
                     } catch (RemoteException re) {
                         Log.e(LOG_TAG, "Error calling onLayoutFinished", re);
                     }
+                } finally {
+                    destroy();
                 }
             }
 
@@ -936,46 +851,64 @@
             public void onLayoutFailed(CharSequence error) {
                 final ILayoutResultCallback callback;
                 synchronized (mLock) {
-                    if (mDestroyed) {
-                        Log.e(LOG_TAG, "PrintDocumentAdapter is destroyed. Did you "
-                                + "finish the printing activity before print completion?");
-                        return;
-                    }
                     callback = mCallback;
-                    clearLocked();
                 }
-                if (callback != null) {
-                    try {
-                        callback.onLayoutFailed(error, mSequence);
-                    } catch (RemoteException re) {
-                        Log.e(LOG_TAG, "Error calling onLayoutFailed", re);
-                    }
+
+                // If the callback is null we are destroyed.
+                if (callback == null) {
+                    Log.e(LOG_TAG, "PrintDocumentAdapter is destroyed. Did you "
+                            + "finish the printing activity before print completion "
+                            + "or did you invoke a callback after finish?");
+                    return;
+                }
+
+                try {
+                    callback.onLayoutFailed(error, mSequence);
+                } catch (RemoteException re) {
+                    Log.e(LOG_TAG, "Error calling onLayoutFailed", re);
+                } finally {
+                    destroy();
                 }
             }
 
             @Override
             public void onLayoutCancelled() {
+                final ILayoutResultCallback callback;
                 synchronized (mLock) {
-                    if (mDestroyed) {
-                        Log.e(LOG_TAG, "PrintDocumentAdapter is destroyed. Did you "
-                                + "finish the printing activity before print completion?");
-                        return;
-                    }
-                    clearLocked();
+                    callback = mCallback;
+                }
+
+                // If the callback is null we are destroyed.
+                if (callback == null) {
+                    Log.e(LOG_TAG, "PrintDocumentAdapter is destroyed. Did you "
+                            + "finish the printing activity before print completion "
+                            + "or did you invoke a callback after finish?");
+                    return;
+                }
+
+                try {
+                    callback.onLayoutCanceled(mSequence);
+                } catch (RemoteException re) {
+                    Log.e(LOG_TAG, "Error calling onLayoutFailed", re);
+                } finally {
+                    destroy();
                 }
             }
 
-            private void clearLocked() {
-                mLayoutOrWriteCancellation = null;
-                mCallback = null;
-                doPendingWorkLocked();
+            @Override
+            public void destroy() {
+                synchronized (mLock) {
+                    mCallback = null;
+                    mPendingCallback = null;
+                }
             }
         }
 
-        private final class MyWriteResultCallback extends WriteResultCallback {
+        private final class MyWriteResultCallback extends WriteResultCallback
+                implements DestroyableCallback {
             private ParcelFileDescriptor mFd;
-            private int mSequence;
             private IWriteResultCallback mCallback;
+            private final int mSequence;
 
             public MyWriteResultCallback(IWriteResultCallback callback,
                     ParcelFileDescriptor fd, int sequence) {
@@ -988,26 +921,32 @@
             public void onWriteFinished(PageRange[] pages) {
                 final IWriteResultCallback callback;
                 synchronized (mLock) {
-                    if (mDestroyed) {
-                        Log.e(LOG_TAG, "PrintDocumentAdapter is destroyed. Did you "
-                                + "finish the printing activity before print completion?");
-                        return;
-                    }
                     callback = mCallback;
-                    clearLocked();
                 }
-                if (pages == null) {
-                    throw new IllegalArgumentException("pages cannot be null");
+
+                // If the callback is null we are destroyed.
+                if (callback == null) {
+                    Log.e(LOG_TAG, "PrintDocumentAdapter is destroyed. Did you "
+                            + "finish the printing activity before print completion "
+                            + "or did you invoke a callback after finish?");
+                    return;
                 }
-                if (pages.length == 0) {
-                    throw new IllegalArgumentException("pages cannot be empty");
-                }
-                if (callback != null) {
+
+                try {
+                    if (pages == null) {
+                        throw new IllegalArgumentException("pages cannot be null");
+                    }
+                    if (pages.length == 0) {
+                        throw new IllegalArgumentException("pages cannot be empty");
+                    }
+
                     try {
                         callback.onWriteFinished(pages, mSequence);
                     } catch (RemoteException re) {
                         Log.e(LOG_TAG, "Error calling onWriteFinished", re);
                     }
+                } finally {
+                    destroy();
                 }
             }
 
@@ -1015,41 +954,58 @@
             public void onWriteFailed(CharSequence error) {
                 final IWriteResultCallback callback;
                 synchronized (mLock) {
-                    if (mDestroyed) {
-                        Log.e(LOG_TAG, "PrintDocumentAdapter is destroyed. Did you "
-                                + "finish the printing activity before print completion?");
-                        return;
-                    }
                     callback = mCallback;
-                    clearLocked();
                 }
-                if (callback != null) {
-                    try {
-                        callback.onWriteFailed(error, mSequence);
-                    } catch (RemoteException re) {
-                        Log.e(LOG_TAG, "Error calling onWriteFailed", re);
-                    }
+
+                // If the callback is null we are destroyed.
+                if (callback == null) {
+                    Log.e(LOG_TAG, "PrintDocumentAdapter is destroyed. Did you "
+                            + "finish the printing activity before print completion "
+                            + "or did you invoke a callback after finish?");
+                    return;
+                }
+
+                try {
+                    callback.onWriteFailed(error, mSequence);
+                } catch (RemoteException re) {
+                    Log.e(LOG_TAG, "Error calling onWriteFailed", re);
+                } finally {
+                    destroy();
                 }
             }
 
             @Override
             public void onWriteCancelled() {
+                final IWriteResultCallback callback;
                 synchronized (mLock) {
-                    if (mDestroyed) {
-                        Log.e(LOG_TAG, "PrintDocumentAdapter is destroyed. Did you "
-                                + "finish the printing activity before print completion?");
-                        return;
-                    }
-                    clearLocked();
+                    callback = mCallback;
+                }
+
+                // If the callback is null we are destroyed.
+                if (callback == null) {
+                    Log.e(LOG_TAG, "PrintDocumentAdapter is destroyed. Did you "
+                            + "finish the printing activity before print completion "
+                            + "or did you invoke a callback after finish?");
+                    return;
+                }
+
+                try {
+                    callback.onWriteCanceled(mSequence);
+                } catch (RemoteException re) {
+                    Log.e(LOG_TAG, "Error calling onWriteCanceled", re);
+                } finally {
+                    destroy();
                 }
             }
 
-            private void clearLocked() {
-                mLayoutOrWriteCancellation = null;
-                IoUtils.closeQuietly(mFd);
-                mCallback = null;
-                mFd = null;
-                doPendingWorkLocked();
+            @Override
+            public void destroy() {
+                synchronized (mLock) {
+                    IoUtils.closeQuietly(mFd);
+                    mCallback = null;
+                    mFd = null;
+                    mPendingCallback = null;
+                }
             }
         }
     }
diff --git a/core/java/android/print/PrinterDiscoverySession.java b/core/java/android/print/PrinterDiscoverySession.java
index d32b71b..abb441b 100644
--- a/core/java/android/print/PrinterDiscoverySession.java
+++ b/core/java/android/print/PrinterDiscoverySession.java
@@ -72,9 +72,9 @@
         }
     }
 
-    public final void startPrinterDisovery(List<PrinterId> priorityList) {
+    public final void startPrinterDiscovery(List<PrinterId> priorityList) {
         if (isDestroyed()) {
-            Log.w(LOG_TAG, "Ignoring start printers dsicovery - session destroyed");
+            Log.w(LOG_TAG, "Ignoring start printers discovery - session destroyed");
             return;
         }
         if (!mIsPrinterDiscoveryStarted) {
@@ -122,7 +122,7 @@
         try {
             mPrintManager.stopPrinterStateTracking(printerId, mUserId);
         } catch (RemoteException re) {
-            Log.e(LOG_TAG, "Error stoping printer state tracking", re);
+            Log.e(LOG_TAG, "Error stopping printer state tracking", re);
         }
     }
 
diff --git a/core/java/android/printservice/PrintService.java b/core/java/android/printservice/PrintService.java
index eb0ac2e..1557ab0 100644
--- a/core/java/android/printservice/PrintService.java
+++ b/core/java/android/printservice/PrintService.java
@@ -201,9 +201,9 @@
      * should build another one using the {@link PrintJobInfo.Builder} class. You
      * can specify any standard properties and add advanced, printer specific,
      * ones via {@link PrintJobInfo.Builder#putAdvancedOption(String, String)
-     * PrintJobInfo.Builder#putAdvancedOption(String, String)} and {@link
+     * PrintJobInfo.Builder.putAdvancedOption(String, String)} and {@link
      * PrintJobInfo.Builder#putAdvancedOption(String, int)
-     * PrintJobInfo.Builder#putAdvancedOption(String, int)}. The advanced options
+     * PrintJobInfo.Builder.putAdvancedOption(String, int)}. The advanced options
      * are not interpreted by the system, they will not be visible to applications,
      * and can only be accessed by your print service via {@link
      * PrintJob#getAdvancedStringOption(String) PrintJob.getAdvancedStringOption(String)}
@@ -212,14 +212,26 @@
      * <p>
      * If the advanced print options activity offers changes to the standard print
      * options, you can get the current {@link android.print.PrinterInfo} using the
-     * "android.intent.extra.print.EXTRA_PRINTER_INFO" extra which will allow you to
-     * present the user with UI options supported by the current printer. For example,
-     * if the current printer does not support a give media size, you should not
-     * offer it in the advanced print options dialog.
+     * {@link #EXTRA_PRINTER_INFO} extra which will allow you to present the user
+     * with UI options supported by the current printer. For example, if the current
+     * printer does not support a given media size, you should not offer it in the
+     * advanced print options UI.
      * </p>
+     *
+     * @see #EXTRA_PRINTER_INFO
      */
     public static final String EXTRA_PRINT_JOB_INFO = "android.intent.extra.print.PRINT_JOB_INFO";
 
+    /**
+     * If you declared an optional activity with advanced print options via the
+     * {@link R.attr#advancedPrintOptionsActivity advancedPrintOptionsActivity}
+     * attribute, this extra is used to pass in the currently selected printer's
+     * {@link android.print.PrinterInfo} to your activity allowing you to inspect it.
+     *
+     * @see #EXTRA_PRINT_JOB_INFO
+     */
+    public static final String EXTRA_PRINTER_INFO = "android.intent.extra.print.PRINTER_INFO";
+
     private Handler mHandler;
 
     private IPrintServiceClient mClient;
diff --git a/core/java/android/provider/Contacts.java b/core/java/android/provider/Contacts.java
index 9e2aacd..d4c5cfb 100644
--- a/core/java/android/provider/Contacts.java
+++ b/core/java/android/provider/Contacts.java
@@ -58,7 +58,7 @@
     @Deprecated
     public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY);
 
-    /** 
+    /**
      * Signifies an email address row that is stored in the ContactMethods table
      * @deprecated see {@link android.provider.ContactsContract}
      */
@@ -337,7 +337,7 @@
      * @deprecated see {@link android.provider.ContactsContract}
      */
     @Deprecated
-    public static final class People implements BaseColumns, SyncConstValue, PeopleColumns,
+    public static final class People implements BaseColumns, PeopleColumns,
             PhonesColumns, PresenceColumns {
         /**
          * no public constructor since this is a utility class
@@ -790,7 +790,7 @@
      */
     @Deprecated
     public static final class Groups
-            implements BaseColumns, SyncConstValue, GroupsColumns {
+            implements BaseColumns, GroupsColumns {
         /**
          * no public constructor since this is a utility class
          */
@@ -1864,7 +1864,7 @@
      * @deprecated see {@link android.provider.ContactsContract}
      */
     @Deprecated
-    public static final class Photos implements BaseColumns, PhotosColumns, SyncConstValue {
+    public static final class Photos implements BaseColumns, PhotosColumns {
         /**
          * no public constructor since this is a utility class
          */
@@ -2199,7 +2199,7 @@
             }
 
             /** The action code to use when adding a contact
-             * @deprecated see {@link android.provider.ContactsContract} 
+             * @deprecated see {@link android.provider.ContactsContract}
              */
             @Deprecated
             public static final String ACTION = ContactsContract.Intents.Insert.ACTION;
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 6db78f4..ba66e65 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -184,9 +184,9 @@
     public static final String DEFERRED_SNIPPETING_QUERY = "deferred_snippeting_query";
 
     /**
-     * A boolean parameter for {@link CommonDataKinds.Phone#CONTENT_URI},
-     * {@link CommonDataKinds.Email#CONTENT_URI}, and
-     * {@link CommonDataKinds.StructuredPostal#CONTENT_URI}.
+     * A boolean parameter for {@link CommonDataKinds.Phone#CONTENT_URI Phone.CONTENT_URI},
+     * {@link CommonDataKinds.Email#CONTENT_URI Email.CONTENT_URI}, and
+     * {@link CommonDataKinds.StructuredPostal#CONTENT_URI StructuredPostal.CONTENT_URI}.
      * This enables a content provider to remove duplicate entries in results.
      */
     public static final String REMOVE_DUPLICATE_ENTRIES = "remove_duplicate_entries";
@@ -244,6 +244,9 @@
         public static final String KEY_AUTHORIZED_URI = "authorized_uri";
     }
 
+    /*
+     * @hide
+     */
     public static final class Preferences {
 
         /**
@@ -808,6 +811,7 @@
          * The position at which the contact is pinned. If {@link PinnedPositions#UNPINNED},
          * the contact is not pinned. Also see {@link PinnedPositions}.
          * <P>Type: INTEGER </P>
+         * @hide
          */
         public static final String PINNED = "pinned";
 
@@ -7775,6 +7779,8 @@
      * {@link PinnedPositions#STAR_WHEN_PINNING} to true to force all pinned and unpinned
      * contacts to be automatically starred and unstarred.
      * </p>
+     *
+     * @hide
      */
     public static final class PinnedPositions {
 
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index cfab1b3..0fe764f 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -1886,6 +1886,9 @@
              * The MIME type for entries in this table.
              */
             public static final String ENTRY_CONTENT_TYPE = "vnd.android.cursor.item/radio";
+
+            // Not instantiable.
+            private Radio() { }
         }
     }
 
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index 557f5a6..fd475cd 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -16,7 +16,7 @@
 
 package android.service.notification;
 
-import android.annotation.PrivateApi;
+import android.annotation.SystemApi;
 import android.annotation.SdkConstant;
 import android.app.INotificationManager;
 import android.app.Service;
@@ -279,7 +279,7 @@
      * @param currentUser the user to use as the stream filter
      * @hide
      */
-    @PrivateApi
+    @SystemApi
     public void registerAsSystemService(ComponentName componentName, int currentUser)
             throws RemoteException {
         if (mWrapper == null) {
@@ -297,7 +297,7 @@
      * with (@link registerAsService).
      * @hide
      */
-    @PrivateApi
+    @SystemApi
     public void unregisterAsSystemService() throws RemoteException {
         if (mWrapper != null) {
             INotificationManager noMan = getNotificationInterface();
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index d02fc7b..68a3d30 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -21,6 +21,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.TextUtils;
+import android.util.Slog;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -37,6 +38,7 @@
  * @hide
  */
 public class ZenModeConfig implements Parcelable {
+    private static String TAG = "ZenModeConfig";
 
     public static final String SLEEP_MODE_NIGHTS = "nights";
     public static final String SLEEP_MODE_WEEKNIGHTS = "weeknights";
@@ -65,6 +67,9 @@
     private static final String CONDITION_ATT_COMPONENT = "component";
     private static final String CONDITION_ATT_ID = "id";
 
+    private static final String EXIT_CONDITION_TAG = "exitCondition";
+    private static final String EXIT_CONDITION_ATT_ID = "id";
+
     public boolean allowCalls;
     public boolean allowMessages;
     public int allowFrom = SOURCE_ANYONE;
@@ -76,6 +81,7 @@
     public int sleepEndMinute;
     public ComponentName[] conditionComponents;
     public Uri[] conditionIds;
+    public Uri exitConditionId;
 
     public ZenModeConfig() { }
 
@@ -100,6 +106,7 @@
             source.readTypedArray(conditionIds, Uri.CREATOR);
         }
         allowFrom = source.readInt();
+        exitConditionId = source.readParcelable(null);
     }
 
     @Override
@@ -129,6 +136,7 @@
             dest.writeInt(0);
         }
         dest.writeInt(allowFrom);
+        dest.writeParcelable(exitConditionId, 0);
     }
 
     @Override
@@ -144,6 +152,7 @@
             .append(conditionComponents == null ? null : TextUtils.join(",", conditionComponents))
             .append(",conditionIds=")
             .append(conditionIds == null ? null : TextUtils.join(",", conditionIds))
+            .append(",exitConditionId=").append(exitConditionId)
             .append(']').toString();
     }
 
@@ -174,14 +183,16 @@
                 && other.sleepEndHour == sleepEndHour
                 && other.sleepEndMinute == sleepEndMinute
                 && Objects.deepEquals(other.conditionComponents, conditionComponents)
-                && Objects.deepEquals(other.conditionIds, conditionIds);
+                && Objects.deepEquals(other.conditionIds, conditionIds)
+                && Objects.equals(other.exitConditionId, exitConditionId);
     }
 
     @Override
     public int hashCode() {
         return Objects.hash(allowCalls, allowMessages, allowFrom, sleepMode,
                 sleepStartHour, sleepStartMinute, sleepEndHour, sleepEndMinute,
-                Arrays.hashCode(conditionComponents), Arrays.hashCode(conditionIds));
+                Arrays.hashCode(conditionComponents), Arrays.hashCode(conditionIds),
+                exitConditionId);
     }
 
     public boolean isValid() {
@@ -239,6 +250,8 @@
                         conditionComponents.add(component);
                         conditionIds.add(conditionId);
                     }
+                } else if (EXIT_CONDITION_TAG.equals(tag)) {
+                    rt.exitConditionId = safeUri(parser, EXIT_CONDITION_ATT_ID);
                 }
             }
         }
@@ -275,6 +288,11 @@
                 out.endTag(null, CONDITION_TAG);
             }
         }
+        if (exitConditionId != null) {
+            out.startTag(null, EXIT_CONDITION_TAG);
+            out.attribute(null, EXIT_CONDITION_ATT_ID, exitConditionId.toString());
+            out.endTag(null, EXIT_CONDITION_TAG);
+        }
         out.endTag(null, ZEN_TAG);
     }
 
@@ -338,4 +356,33 @@
             return new ZenModeConfig[size];
         }
     };
+
+    // Built-in countdown conditions, e.g. condition://android/countdown/1399917958951
+
+    private static final String COUNTDOWN_AUTHORITY = "android";
+    private static final String COUNTDOWN_PATH = "countdown";
+
+    public static Uri toCountdownConditionId(long time) {
+        return new Uri.Builder().scheme(Condition.SCHEME)
+                .authority(COUNTDOWN_AUTHORITY)
+                .appendPath(COUNTDOWN_PATH)
+                .appendPath(Long.toString(time))
+                .build();
+    }
+
+    public static long tryParseCountdownConditionId(Uri conditionId) {
+        if (!Condition.isValidId(conditionId, COUNTDOWN_AUTHORITY)) return 0;
+        if (conditionId.getPathSegments().size() != 2
+                || !COUNTDOWN_PATH.equals(conditionId.getPathSegments().get(0))) return 0;
+        try {
+            return Long.parseLong(conditionId.getPathSegments().get(1));
+        } catch (RuntimeException e) {
+            Slog.w(TAG, "Error parsing countdown condition: " + conditionId, e);
+            return 0;
+        }
+    }
+
+    public static boolean isValidCountdownConditionId(Uri conditionId) {
+        return tryParseCountdownConditionId(conditionId) != 0;
+    }
 }
diff --git a/core/java/android/service/trust/TrustAgentService.java b/core/java/android/service/trust/TrustAgentService.java
index 98f70f40..a6cddae 100644
--- a/core/java/android/service/trust/TrustAgentService.java
+++ b/core/java/android/service/trust/TrustAgentService.java
@@ -33,6 +33,8 @@
  * A service that notifies the system about whether it believes the environment of the device
  * to be trusted.
  *
+ * <p>Trust agents may only be provided by the platform.</p>
+ *
  * <p>To extend this class, you must declare the service in your manifest file with
  * the {@link android.Manifest.permission#BIND_TRUST_AGENT} permission
  * and include an intent filter with the {@link #SERVICE_INTERFACE} action. For example:</p>
diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java
index f06ae71..48122d6 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -48,10 +48,11 @@
 import android.text.style.UnderlineSpan;
 import android.util.Log;
 import android.util.Printer;
-
 import android.view.View;
+
 import com.android.internal.R;
 import com.android.internal.util.ArrayUtils;
+
 import libcore.icu.ICU;
 
 import java.lang.reflect.Array;
@@ -229,7 +230,12 @@
     public static boolean regionMatches(CharSequence one, int toffset,
                                         CharSequence two, int ooffset,
                                         int len) {
-        char[] temp = obtain(2 * len);
+        int tempLen = 2 * len;
+        if (tempLen < len) {
+            // Integer overflow; len is unreasonably large
+            throw new IndexOutOfBoundsException();
+        }
+        char[] temp = obtain(tempLen);
 
         getChars(one, toffset, toffset + len, temp, 0);
         getChars(two, ooffset, ooffset + len, temp, len);
diff --git a/core/java/android/transition/SidePropagation.java b/core/java/android/transition/SidePropagation.java
index 5d38ac8..623cdd1 100644
--- a/core/java/android/transition/SidePropagation.java
+++ b/core/java/android/transition/SidePropagation.java
@@ -18,6 +18,7 @@
 import android.graphics.Rect;
 import android.util.FloatMath;
 import android.util.Log;
+import android.view.Gravity;
 import android.view.View;
 import android.view.ViewGroup;
 
@@ -32,38 +33,19 @@
 public class SidePropagation extends VisibilityPropagation {
     private static final String TAG = "SlidePropagation";
 
-    /**
-     * Transition propagates relative to the distance of the left side of the scene.
-     */
-    public static final int LEFT = Slide.LEFT;
-
-    /**
-     * Transition propagates relative to the distance of the top of the scene.
-     */
-    public static final int TOP = Slide.TOP;
-
-    /**
-     * Transition propagates relative to the distance of the right side of the scene.
-     */
-    public static final int RIGHT = Slide.RIGHT;
-
-    /**
-     * Transition propagates relative to the distance of the bottom of the scene.
-     */
-    public static final int BOTTOM = Slide.BOTTOM;
-
     private float mPropagationSpeed = 3.0f;
-    private int mSide = BOTTOM;
+    private int mSide = Gravity.BOTTOM;
 
     /**
      * Sets the side that is used to calculate the transition propagation. If the transitioning
      * View is visible in the start of the transition, then it will transition sooner when
      * closer to the side and later when farther. If the view is not visible in the start of
      * the transition, then it will transition later when closer to the side and sooner when
-     * farther from the edge. The default is {@link #BOTTOM}.
+     * farther from the edge. The default is {@link Gravity#BOTTOM}.
      *
      * @param side The side that is used to calculate the transition propagation. Must be one of
-     *             {@link #LEFT}, {@link #TOP}, {@link #RIGHT}, or {@link #BOTTOM}.
+     *             {@link Gravity#LEFT}, {@link Gravity#TOP}, {@link Gravity#RIGHT}, or
+     *             {@link Gravity#BOTTOM}.
      */
     public void setSide(int side) {
         mSide = side;
@@ -141,16 +123,16 @@
             int left, int top, int right, int bottom) {
         int distance = 0;
         switch (mSide) {
-            case LEFT:
+            case Gravity.LEFT:
                 distance = right - viewX + Math.abs(epicenterY - viewY);
                 break;
-            case TOP:
+            case Gravity.TOP:
                 distance = bottom - viewY + Math.abs(epicenterX - viewX);
                 break;
-            case RIGHT:
+            case Gravity.RIGHT:
                 distance = viewX - left + Math.abs(epicenterY - viewY);
                 break;
-            case BOTTOM:
+            case Gravity.BOTTOM:
                 distance = viewY - top + Math.abs(epicenterX - viewX);
                 break;
         }
@@ -159,8 +141,8 @@
 
     private int getMaxDistance(ViewGroup sceneRoot) {
         switch (mSide) {
-            case LEFT:
-            case RIGHT:
+            case Gravity.LEFT:
+            case Gravity.RIGHT:
                 return sceneRoot.getWidth();
             default:
                 return sceneRoot.getHeight();
diff --git a/core/java/android/transition/Slide.java b/core/java/android/transition/Slide.java
index 0ff8ddd..8269258 100644
--- a/core/java/android/transition/Slide.java
+++ b/core/java/android/transition/Slide.java
@@ -24,6 +24,7 @@
 import android.graphics.Rect;
 import android.util.Log;
 import android.util.Property;
+import android.view.Gravity;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.animation.AccelerateInterpolator;
@@ -41,35 +42,9 @@
 public class Slide extends Visibility {
     private static final String TAG = "Slide";
 
-    /**
-     * Move Views in or out of the left edge of the scene.
-     * @see #setSlideEdge(int)
-     */
-    public static final int LEFT = 0;
-
-    /**
-     * Move Views in or out of the top edge of the scene.
-     * @see #setSlideEdge(int)
-     */
-    public static final int TOP = 1;
-
-    /**
-     * Move Views in or out of the right edge of the scene.
-     * @see #setSlideEdge(int)
-     */
-    public static final int RIGHT = 2;
-
-    /**
-     * Move Views in or out of the bottom edge of the scene. This is the
-     * default slide direction.
-     * @see #setSlideEdge(int)
-     */
-    public static final int BOTTOM = 3;
-
     private static final TimeInterpolator sDecelerate = new DecelerateInterpolator();
     private static final TimeInterpolator sAccelerate = new AccelerateInterpolator();
 
-    private int[] mTempLoc = new int[2];
     private CalculateSlide mSlideCalculator = sCalculateBottom;
 
     private interface CalculateSlide {
@@ -136,11 +111,11 @@
     };
 
     /**
-     * Constructor using the default {@link android.transition.Slide#BOTTOM}
+     * Constructor using the default {@link Gravity#BOTTOM}
      * slide edge direction.
      */
     public Slide() {
-        setSlideEdge(BOTTOM);
+        setSlideEdge(Gravity.BOTTOM);
     }
 
     /**
@@ -152,20 +127,22 @@
 
     /**
      * Change the edge that Views appear and disappear from.
-     * @param slideEdge The edge of the scene to use for Views appearing and disappearing.
+     * @param slideEdge The edge of the scene to use for Views appearing and disappearing. One of
+     *                  {@link android.view.Gravity#LEFT}, {@link android.view.Gravity#TOP},
+     *                  {@link android.view.Gravity#RIGHT}, {@link android.view.Gravity#BOTTOM}.
      */
     public void setSlideEdge(int slideEdge) {
         switch (slideEdge) {
-            case LEFT:
+            case Gravity.LEFT:
                 mSlideCalculator = sCalculateLeft;
                 break;
-            case TOP:
+            case Gravity.TOP:
                 mSlideCalculator = sCalculateTop;
                 break;
-            case RIGHT:
+            case Gravity.RIGHT:
                 mSlideCalculator = sCalculateRight;
                 break;
-            case BOTTOM:
+            case Gravity.BOTTOM:
                 mSlideCalculator = sCalculateBottom;
                 break;
             default:
diff --git a/core/java/android/transition/Transition.java b/core/java/android/transition/Transition.java
index 9a70099..e9c2bba 100644
--- a/core/java/android/transition/Transition.java
+++ b/core/java/android/transition/Transition.java
@@ -1763,7 +1763,7 @@
 
     /**
      * Sets the callback to use to find the epicenter of a Transition. A null value indicates
-     * that there is no epicenter in the Transition and getEpicenter() will return null.
+     * that there is no epicenter in the Transition and onGetEpicenter() will return null.
      * Transitions like {@link android.transition.Explode} use a point or Rect to orient
      * the direction of travel. This is called the epicenter of the Transition and is
      * typically centered on a touched View. The
@@ -1799,7 +1799,7 @@
         if (mEpicenterCallback == null) {
             return null;
         }
-        return mEpicenterCallback.getEpicenter(this);
+        return mEpicenterCallback.onGetEpicenter(this);
     }
 
     /**
@@ -2112,6 +2112,6 @@
          * @return The Rect region of the epicenter of <code>transition</code> or null if
          * there is no epicenter.
          */
-        public abstract Rect getEpicenter(Transition transition);
+        public abstract Rect onGetEpicenter(Transition transition);
     }
 }
diff --git a/core/java/android/transition/TransitionInflater.java b/core/java/android/transition/TransitionInflater.java
index f4b562f..5b7c737 100644
--- a/core/java/android/transition/TransitionInflater.java
+++ b/core/java/android/transition/TransitionInflater.java
@@ -22,6 +22,7 @@
 import android.content.res.XmlResourceParser;
 import android.util.AttributeSet;
 import android.util.Xml;
+import android.view.Gravity;
 import android.view.InflateException;
 import android.view.ViewGroup;
 import android.view.animation.AnimationUtils;
@@ -208,7 +209,7 @@
     private Slide createSlideTransition(AttributeSet attrs) {
         TypedArray a = mContext.obtainStyledAttributes(attrs,
                 com.android.internal.R.styleable.Slide);
-        int edge = a.getInt(com.android.internal.R.styleable.Slide_slideEdge, Slide.BOTTOM);
+        int edge = a.getInt(com.android.internal.R.styleable.Slide_slideEdge, Gravity.BOTTOM);
         Slide slide = new Slide(edge);
         a.recycle();
         return slide;
diff --git a/core/java/android/view/HardwareLayer.java b/core/java/android/view/HardwareLayer.java
index 6acb134..b5b9199 100644
--- a/core/java/android/view/HardwareLayer.java
+++ b/core/java/android/view/HardwareLayer.java
@@ -217,8 +217,6 @@
     private static native void nUpdateRenderLayer(long layerUpdater, long displayList,
             int left, int top, int right, int bottom);
 
-    private static native boolean nFlushChanges(long layerUpdater);
-
     private static native long nGetLayer(long layerUpdater);
     private static native int nGetTexName(long layerUpdater);
 }
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index d67c974..592dec8 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -363,8 +363,7 @@
      * @param callbacks Callbacks invoked when drawing happens.
      * @param dirty The dirty rectangle to update, can be null.
      */
-    abstract void draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks,
-            Rect dirty);
+    abstract void draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks);
 
     /**
      * Creates a new hardware layer. A hardware layer built by calling this
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index af16185..ae59bbc 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -30,6 +30,7 @@
 import android.view.IOnKeyguardExitResult;
 import android.view.IRotationWatcher;
 import android.view.IWindowSession;
+import android.view.IWindowSessionCallback;
 import android.view.KeyEvent;
 import android.view.InputEvent;
 import android.view.MagnificationSpec;
@@ -56,7 +57,7 @@
     boolean stopViewServer();            // Transaction #2
     boolean isViewServerRunning();       // Transaction #3
 
-    IWindowSession openSession(in IInputMethodClient client,
+    IWindowSession openSession(in IWindowSessionCallback callback, in IInputMethodClient client,
             in IInputContext inputContext);
     boolean inputMethodClientHasFocus(IInputMethodClient client);
 
@@ -130,6 +131,8 @@
     void setAnimationScale(int which, float scale);
     void setAnimationScales(in float[] scales);
 
+    float getCurrentAnimatorScale();
+
     // For testing
     void setInTouchMode(boolean showFocus);
 
@@ -216,12 +219,6 @@
     oneway void statusBarVisibilityChanged(int visibility);
 
     /**
-     * Block until the given window has been drawn to the screen.
-     * Returns true if really waiting, false if the window does not exist.
-     */
-    boolean waitForWindowDrawn(IBinder token, in IRemoteCallback callback);
-
-    /**
      * Device has a software navigation bar (separate from the status bar).
      */
     boolean hasNavigationBar();
diff --git a/core/java/android/view/IWindowSessionCallback.aidl b/core/java/android/view/IWindowSessionCallback.aidl
new file mode 100644
index 0000000..88931ce
--- /dev/null
+++ b/core/java/android/view/IWindowSessionCallback.aidl
@@ -0,0 +1,27 @@
+/*
+** Copyright 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.view;
+
+/**
+ * Callback to active sessions of the window manager
+ *
+ * {@hide}
+ */
+oneway interface IWindowSessionCallback
+{
+    void onAnimatorScaleChanged(float scale);
+}
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index 8a996d2..8b2ec7a 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -1716,6 +1716,7 @@
             case KeyEvent.KEYCODE_MENU:
             case KeyEvent.KEYCODE_SLEEP:
             case KeyEvent.KEYCODE_WAKEUP:
+            case KeyEvent.KEYCODE_PAIRING:
                 return true;
         }
         return false;
diff --git a/core/java/android/view/RenderNode.java b/core/java/android/view/RenderNode.java
index e63829e..4631b64 100644
--- a/core/java/android/view/RenderNode.java
+++ b/core/java/android/view/RenderNode.java
@@ -325,8 +325,8 @@
      *
      * @hide
      */
-    public void setCaching(boolean caching) {
-        nSetCaching(mNativeRenderNode, caching);
+    public boolean setCaching(boolean caching) {
+        return nSetCaching(mNativeRenderNode, caching);
     }
 
     /**
@@ -335,8 +335,8 @@
      *
      * @param clipToBounds true if the display list should clip to its bounds
      */
-    public void setClipToBounds(boolean clipToBounds) {
-        nSetClipToBounds(mNativeRenderNode, clipToBounds);
+    public boolean setClipToBounds(boolean clipToBounds) {
+        return nSetClipToBounds(mNativeRenderNode, clipToBounds);
     }
 
     /**
@@ -346,8 +346,8 @@
      * @param shouldProject true if the display list should be projected onto a
      *            containing volume.
      */
-    public void setProjectBackwards(boolean shouldProject) {
-        nSetProjectBackwards(mNativeRenderNode, shouldProject);
+    public boolean setProjectBackwards(boolean shouldProject) {
+        return nSetProjectBackwards(mNativeRenderNode, shouldProject);
     }
 
     /**
@@ -355,8 +355,8 @@
      * DisplayList should draw any descendent DisplayLists with
      * ProjectBackwards=true directly on top of it. Default value is false.
      */
-    public void setProjectionReceiver(boolean shouldRecieve) {
-        nSetProjectionReceiver(mNativeRenderNode, shouldRecieve);
+    public boolean setProjectionReceiver(boolean shouldRecieve) {
+        return nSetProjectionReceiver(mNativeRenderNode, shouldRecieve);
     }
 
     /**
@@ -365,15 +365,16 @@
      *
      * Deep copies the data into native to simplify reference ownership.
      */
-    public void setOutline(Outline outline) {
+    public boolean setOutline(Outline outline) {
         if (outline == null || outline.isEmpty()) {
-            nSetOutlineEmpty(mNativeRenderNode);
+            return nSetOutlineEmpty(mNativeRenderNode);
         } else if (outline.mRect != null) {
-            nSetOutlineRoundRect(mNativeRenderNode, outline.mRect.left, outline.mRect.top,
+            return nSetOutlineRoundRect(mNativeRenderNode, outline.mRect.left, outline.mRect.top,
                     outline.mRect.right, outline.mRect.bottom, outline.mRadius);
         } else if (outline.mPath != null) {
-            nSetOutlineConvexPath(mNativeRenderNode, outline.mPath.mNativePath);
+            return nSetOutlineConvexPath(mNativeRenderNode, outline.mPath.mNativePath);
         }
+        throw new IllegalArgumentException("Unrecognized outline?");
     }
 
     /**
@@ -381,8 +382,8 @@
      *
      * @param clipToOutline true if clipping to the outline.
      */
-    public void setClipToOutline(boolean clipToOutline) {
-        nSetClipToOutline(mNativeRenderNode, clipToOutline);
+    public boolean setClipToOutline(boolean clipToOutline) {
+        return nSetClipToOutline(mNativeRenderNode, clipToOutline);
     }
 
     public boolean getClipToOutline() {
@@ -392,9 +393,9 @@
     /**
      * Controls the RenderNode's circular reveal clip.
      */
-    public void setRevealClip(boolean shouldClip, boolean inverseClip,
+    public boolean setRevealClip(boolean shouldClip, boolean inverseClip,
             float x, float y, float radius) {
-        nSetRevealClip(mNativeRenderNode, shouldClip, inverseClip, x, y, radius);
+        return nSetRevealClip(mNativeRenderNode, shouldClip, inverseClip, x, y, radius);
     }
 
     /**
@@ -403,8 +404,8 @@
      *
      * @param matrix A transform matrix to apply to this display list
      */
-    public void setStaticMatrix(Matrix matrix) {
-        nSetStaticMatrix(mNativeRenderNode, matrix.native_instance);
+    public boolean setStaticMatrix(Matrix matrix) {
+        return nSetStaticMatrix(mNativeRenderNode, matrix.native_instance);
     }
 
     /**
@@ -417,8 +418,8 @@
      *
      * @hide
      */
-    public void setAnimationMatrix(Matrix matrix) {
-        nSetAnimationMatrix(mNativeRenderNode,
+    public boolean setAnimationMatrix(Matrix matrix) {
+        return nSetAnimationMatrix(mNativeRenderNode,
                 (matrix != null) ? matrix.native_instance : 0);
     }
 
@@ -430,8 +431,8 @@
      * @see View#setAlpha(float)
      * @see #getAlpha()
      */
-    public void setAlpha(float alpha) {
-        nSetAlpha(mNativeRenderNode, alpha);
+    public boolean setAlpha(float alpha) {
+        return nSetAlpha(mNativeRenderNode, alpha);
     }
 
     /**
@@ -456,8 +457,8 @@
      * @see android.view.View#hasOverlappingRendering()
      * @see #hasOverlappingRendering()
      */
-    public void setHasOverlappingRendering(boolean hasOverlappingRendering) {
-        nSetHasOverlappingRendering(mNativeRenderNode, hasOverlappingRendering);
+    public boolean setHasOverlappingRendering(boolean hasOverlappingRendering) {
+        return nSetHasOverlappingRendering(mNativeRenderNode, hasOverlappingRendering);
     }
 
     /**
@@ -472,8 +473,8 @@
         return nHasOverlappingRendering(mNativeRenderNode);
     }
 
-    public void setElevation(float lift) {
-        nSetElevation(mNativeRenderNode, lift);
+    public boolean setElevation(float lift) {
+        return nSetElevation(mNativeRenderNode, lift);
     }
 
     public float getElevation() {
@@ -488,8 +489,8 @@
      * @see View#setTranslationX(float)
      * @see #getTranslationX()
      */
-    public void setTranslationX(float translationX) {
-        nSetTranslationX(mNativeRenderNode, translationX);
+    public boolean setTranslationX(float translationX) {
+        return nSetTranslationX(mNativeRenderNode, translationX);
     }
 
     /**
@@ -509,8 +510,8 @@
      * @see View#setTranslationY(float)
      * @see #getTranslationY()
      */
-    public void setTranslationY(float translationY) {
-        nSetTranslationY(mNativeRenderNode, translationY);
+    public boolean setTranslationY(float translationY) {
+        return nSetTranslationY(mNativeRenderNode, translationY);
     }
 
     /**
@@ -528,8 +529,8 @@
      * @see View#setTranslationZ(float)
      * @see #getTranslationZ()
      */
-    public void setTranslationZ(float translationZ) {
-        nSetTranslationZ(mNativeRenderNode, translationZ);
+    public boolean setTranslationZ(float translationZ) {
+        return nSetTranslationZ(mNativeRenderNode, translationZ);
     }
 
     /**
@@ -549,8 +550,8 @@
      * @see View#setRotation(float)
      * @see #getRotation()
      */
-    public void setRotation(float rotation) {
-        nSetRotation(mNativeRenderNode, rotation);
+    public boolean setRotation(float rotation) {
+        return nSetRotation(mNativeRenderNode, rotation);
     }
 
     /**
@@ -570,8 +571,8 @@
      * @see View#setRotationX(float)
      * @see #getRotationX()
      */
-    public void setRotationX(float rotationX) {
-        nSetRotationX(mNativeRenderNode, rotationX);
+    public boolean setRotationX(float rotationX) {
+        return nSetRotationX(mNativeRenderNode, rotationX);
     }
 
     /**
@@ -591,8 +592,8 @@
      * @see View#setRotationY(float)
      * @see #getRotationY()
      */
-    public void setRotationY(float rotationY) {
-        nSetRotationY(mNativeRenderNode, rotationY);
+    public boolean setRotationY(float rotationY) {
+        return nSetRotationY(mNativeRenderNode, rotationY);
     }
 
     /**
@@ -612,8 +613,8 @@
      * @see View#setScaleX(float)
      * @see #getScaleX()
      */
-    public void setScaleX(float scaleX) {
-        nSetScaleX(mNativeRenderNode, scaleX);
+    public boolean setScaleX(float scaleX) {
+        return nSetScaleX(mNativeRenderNode, scaleX);
     }
 
     /**
@@ -633,8 +634,8 @@
      * @see View#setScaleY(float)
      * @see #getScaleY()
      */
-    public void setScaleY(float scaleY) {
-        nSetScaleY(mNativeRenderNode, scaleY);
+    public boolean setScaleY(float scaleY) {
+        return nSetScaleY(mNativeRenderNode, scaleY);
     }
 
     /**
@@ -654,8 +655,8 @@
      * @see View#setPivotX(float)
      * @see #getPivotX()
      */
-    public void setPivotX(float pivotX) {
-        nSetPivotX(mNativeRenderNode, pivotX);
+    public boolean setPivotX(float pivotX) {
+        return nSetPivotX(mNativeRenderNode, pivotX);
     }
 
     /**
@@ -675,8 +676,8 @@
      * @see View#setPivotY(float)
      * @see #getPivotY()
      */
-    public void setPivotY(float pivotY) {
-        nSetPivotY(mNativeRenderNode, pivotY);
+    public boolean setPivotY(float pivotY) {
+        return nSetPivotY(mNativeRenderNode, pivotY);
     }
 
     /**
@@ -702,8 +703,8 @@
      * @see View#setCameraDistance(float)
      * @see #getCameraDistance()
      */
-    public void setCameraDistance(float distance) {
-        nSetCameraDistance(mNativeRenderNode, distance);
+    public boolean setCameraDistance(float distance) {
+        return nSetCameraDistance(mNativeRenderNode, distance);
     }
 
     /**
@@ -723,8 +724,8 @@
      * @see View#setLeft(int)
      * @see #getLeft()
      */
-    public void setLeft(int left) {
-        nSetLeft(mNativeRenderNode, left);
+    public boolean setLeft(int left) {
+        return nSetLeft(mNativeRenderNode, left);
     }
 
     /**
@@ -744,8 +745,8 @@
      * @see View#setTop(int)
      * @see #getTop()
      */
-    public void setTop(int top) {
-        nSetTop(mNativeRenderNode, top);
+    public boolean setTop(int top) {
+        return nSetTop(mNativeRenderNode, top);
     }
 
     /**
@@ -765,8 +766,8 @@
      * @see View#setRight(int)
      * @see #getRight()
      */
-    public void setRight(int right) {
-        nSetRight(mNativeRenderNode, right);
+    public boolean setRight(int right) {
+        return nSetRight(mNativeRenderNode, right);
     }
 
     /**
@@ -786,8 +787,8 @@
      * @see View#setBottom(int)
      * @see #getBottom()
      */
-    public void setBottom(int bottom) {
-        nSetBottom(mNativeRenderNode, bottom);
+    public boolean setBottom(int bottom) {
+        return nSetBottom(mNativeRenderNode, bottom);
     }
 
     /**
@@ -812,8 +813,8 @@
      * @see View#setRight(int)
      * @see View#setBottom(int)
      */
-    public void setLeftTopRightBottom(int left, int top, int right, int bottom) {
-        nSetLeftTopRightBottom(mNativeRenderNode, left, top, right, bottom);
+    public boolean setLeftTopRightBottom(int left, int top, int right, int bottom) {
+        return nSetLeftTopRightBottom(mNativeRenderNode, left, top, right, bottom);
     }
 
     /**
@@ -824,8 +825,8 @@
      *
      * @see View#offsetLeftAndRight(int)
      */
-    public void offsetLeftAndRight(float offset) {
-        nOffsetLeftAndRight(mNativeRenderNode, offset);
+    public boolean offsetLeftAndRight(float offset) {
+        return nOffsetLeftAndRight(mNativeRenderNode, offset);
     }
 
     /**
@@ -836,8 +837,15 @@
      *
      * @see View#offsetTopAndBottom(int)
      */
-    public void offsetTopAndBottom(float offset) {
-        nOffsetTopAndBottom(mNativeRenderNode, offset);
+    public boolean offsetTopAndBottom(float offset) {
+        return nOffsetTopAndBottom(mNativeRenderNode, offset);
+    }
+
+    /**
+     * Sets the scroll position, this is used for damage calculations
+     */
+    public void setScrollPosition(int x, int y) {
+        nSetScrollPosition(mNativeRenderNode, x, y);
     }
 
     /**
@@ -890,42 +898,43 @@
 
     // Properties
 
-    private static native void nOffsetTopAndBottom(long renderNode, float offset);
-    private static native void nOffsetLeftAndRight(long renderNode, float offset);
-    private static native void nSetLeftTopRightBottom(long renderNode, int left, int top,
+    private static native boolean nOffsetTopAndBottom(long renderNode, float offset);
+    private static native boolean nOffsetLeftAndRight(long renderNode, float offset);
+    private static native boolean nSetLeftTopRightBottom(long renderNode, int left, int top,
             int right, int bottom);
-    private static native void nSetBottom(long renderNode, int bottom);
-    private static native void nSetRight(long renderNode, int right);
-    private static native void nSetTop(long renderNode, int top);
-    private static native void nSetLeft(long renderNode, int left);
-    private static native void nSetCameraDistance(long renderNode, float distance);
-    private static native void nSetPivotY(long renderNode, float pivotY);
-    private static native void nSetPivotX(long renderNode, float pivotX);
-    private static native void nSetCaching(long renderNode, boolean caching);
-    private static native void nSetClipToBounds(long renderNode, boolean clipToBounds);
-    private static native void nSetProjectBackwards(long renderNode, boolean shouldProject);
-    private static native void nSetProjectionReceiver(long renderNode, boolean shouldRecieve);
-    private static native void nSetOutlineRoundRect(long renderNode, int left, int top,
+    private static native boolean nSetBottom(long renderNode, int bottom);
+    private static native boolean nSetRight(long renderNode, int right);
+    private static native boolean nSetTop(long renderNode, int top);
+    private static native boolean nSetLeft(long renderNode, int left);
+    private static native void nSetScrollPosition(long renderNode, int scrollX, int scrollY);
+    private static native boolean nSetCameraDistance(long renderNode, float distance);
+    private static native boolean nSetPivotY(long renderNode, float pivotY);
+    private static native boolean nSetPivotX(long renderNode, float pivotX);
+    private static native boolean nSetCaching(long renderNode, boolean caching);
+    private static native boolean nSetClipToBounds(long renderNode, boolean clipToBounds);
+    private static native boolean nSetProjectBackwards(long renderNode, boolean shouldProject);
+    private static native boolean nSetProjectionReceiver(long renderNode, boolean shouldRecieve);
+    private static native boolean nSetOutlineRoundRect(long renderNode, int left, int top,
             int right, int bottom, float radius);
-    private static native void nSetOutlineConvexPath(long renderNode, long nativePath);
-    private static native void nSetOutlineEmpty(long renderNode);
-    private static native void nSetClipToOutline(long renderNode, boolean clipToOutline);
-    private static native void nSetRevealClip(long renderNode,
+    private static native boolean nSetOutlineConvexPath(long renderNode, long nativePath);
+    private static native boolean nSetOutlineEmpty(long renderNode);
+    private static native boolean nSetClipToOutline(long renderNode, boolean clipToOutline);
+    private static native boolean nSetRevealClip(long renderNode,
             boolean shouldClip, boolean inverseClip, float x, float y, float radius);
-    private static native void nSetAlpha(long renderNode, float alpha);
-    private static native void nSetHasOverlappingRendering(long renderNode,
+    private static native boolean nSetAlpha(long renderNode, float alpha);
+    private static native boolean nSetHasOverlappingRendering(long renderNode,
             boolean hasOverlappingRendering);
-    private static native void nSetElevation(long renderNode, float lift);
-    private static native void nSetTranslationX(long renderNode, float translationX);
-    private static native void nSetTranslationY(long renderNode, float translationY);
-    private static native void nSetTranslationZ(long renderNode, float translationZ);
-    private static native void nSetRotation(long renderNode, float rotation);
-    private static native void nSetRotationX(long renderNode, float rotationX);
-    private static native void nSetRotationY(long renderNode, float rotationY);
-    private static native void nSetScaleX(long renderNode, float scaleX);
-    private static native void nSetScaleY(long renderNode, float scaleY);
-    private static native void nSetStaticMatrix(long renderNode, long nativeMatrix);
-    private static native void nSetAnimationMatrix(long renderNode, long animationMatrix);
+    private static native boolean nSetElevation(long renderNode, float lift);
+    private static native boolean nSetTranslationX(long renderNode, float translationX);
+    private static native boolean nSetTranslationY(long renderNode, float translationY);
+    private static native boolean nSetTranslationZ(long renderNode, float translationZ);
+    private static native boolean nSetRotation(long renderNode, float rotation);
+    private static native boolean nSetRotationX(long renderNode, float rotationX);
+    private static native boolean nSetRotationY(long renderNode, float rotationY);
+    private static native boolean nSetScaleX(long renderNode, float scaleX);
+    private static native boolean nSetScaleY(long renderNode, float scaleY);
+    private static native boolean nSetStaticMatrix(long renderNode, long nativeMatrix);
+    private static native boolean nSetAnimationMatrix(long renderNode, long animationMatrix);
 
     private static native boolean nHasOverlappingRendering(long renderNode);
     private static native boolean nGetClipToOutline(long renderNode);
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 9b3ef7f..7bbe84e 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -54,8 +54,6 @@
 public class ThreadedRenderer extends HardwareRenderer {
     private static final String LOGTAG = "ThreadedRenderer";
 
-    private static final Rect NULL_RECT = new Rect();
-
     // Keep in sync with DrawFrameTask.h SYNC_* flags
     // Nothing interesting to report
     private static final int SYNC_OK = 0x0;
@@ -228,7 +226,7 @@
     }
 
     @Override
-    void draw(View view, AttachInfo attachInfo, HardwareDrawCallbacks callbacks, Rect dirty) {
+    void draw(View view, AttachInfo attachInfo, HardwareDrawCallbacks callbacks) {
         attachInfo.mIgnoreDirtyState = true;
         long frameTimeNanos = mChoreographer.getFrameTimeNanos();
         attachInfo.mDrawingTime = frameTimeNanos / TimeUtils.NANOS_PER_MS;
@@ -246,12 +244,8 @@
 
         attachInfo.mIgnoreDirtyState = false;
 
-        if (dirty == null) {
-            dirty = NULL_RECT;
-        }
         int syncResult = nSyncAndDrawFrame(mNativeProxy, frameTimeNanos,
-                recordDuration, view.getResources().getDisplayMetrics().density,
-                dirty.left, dirty.top, dirty.right, dirty.bottom);
+                recordDuration, view.getResources().getDisplayMetrics().density);
         if ((syncResult & SYNC_INVALIDATE_REQUIRED) != 0) {
             attachInfo.mViewRootImpl.invalidate();
         }
@@ -393,8 +387,7 @@
             float lightX, float lightY, float lightZ, float lightRadius);
     private static native void nSetOpaque(long nativeProxy, boolean opaque);
     private static native int nSyncAndDrawFrame(long nativeProxy,
-            long frameTimeNanos, long recordDuration, float density,
-            int dirtyLeft, int dirtyTop, int dirtyRight, int dirtyBottom);
+            long frameTimeNanos, long recordDuration, float density);
     private static native void nRunWithGlContext(long nativeProxy, Runnable runnable);
     private static native void nDestroyCanvasAndSurface(long nativeProxy);
 
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 622fa8c..c681919 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -7648,7 +7648,7 @@
      * notification is at at most once every
      * {@link ViewConfiguration#getSendRecurringAccessibilityEventsInterval()}
      * to avoid unnecessary load to the system. Also once a view has a pending
-     * notifucation this method is a NOP until the notification has been sent.
+     * notification this method is a NOP until the notification has been sent.
      *
      * @hide
      */
@@ -10521,13 +10521,18 @@
         setTranslationZ(z - getElevation());
     }
 
+    /**
+     * The base elevation of this view relative to its parent, in pixels.
+     *
+     * @return The base depth position of the view, in pixels.
+     */
     @ViewDebug.ExportedProperty(category = "drawing")
     public float getElevation() {
         return mRenderNode.getElevation();
     }
 
     /**
-     * Sets the base depth location of this view.
+     * Sets the base elevation of this view, in pixels.
      *
      * @attr ref android.R.styleable#View_elevation
      */
@@ -10633,24 +10638,6 @@
     }
 
     /**
-     * Returns a ValueAnimator which can animate a clipping circle.
-     * <p>
-     * The View will be clipped to the animating circle.
-     * <p>
-     * Any shadow cast by the View will respect the circular clip from this animator.
-     *
-     * @param centerX The x coordinate of the center of the animating circle.
-     * @param centerY The y coordinate of the center of the animating circle.
-     * @param startRadius The starting radius of the animating circle.
-     * @param endRadius The ending radius of the animating circle.
-     */
-    public final ValueAnimator createRevealAnimator(int centerX,  int centerY,
-            float startRadius, float endRadius) {
-        return RevealAnimator.ofRevealCircle(this, centerX, centerY,
-                startRadius, endRadius, false);
-    }
-
-    /**
      * Returns a ValueAnimator which can animate a clearing circle.
      * <p>
      * The View is prevented from drawing within the circle, so the content
@@ -13750,6 +13737,7 @@
             return;
         }
 
+        renderNode.setScrollPosition(mScrollX, mScrollY);
         if ((mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == 0
                 || !renderNode.isValid()
                 || (!isLayer && mRecreateDisplayList)) {
diff --git a/core/java/android/view/ViewAnimationUtils.java b/core/java/android/view/ViewAnimationUtils.java
new file mode 100644
index 0000000..3854f34
--- /dev/null
+++ b/core/java/android/view/ViewAnimationUtils.java
@@ -0,0 +1,44 @@
+/*
+ * 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.view;
+
+import android.animation.RevealAnimator;
+import android.animation.ValueAnimator;
+
+/**
+ * Defines common utilities for working with View's animations.
+ *
+ */
+public class ViewAnimationUtils {
+    private ViewAnimationUtils() {}
+    /**
+     * Returns a ValueAnimator which can animate a clipping circle.
+     *
+     * Any shadow cast by the View will respect the circular clip from this animator.
+     *
+     * @param view The View will be clipped to the animating circle.
+     * @param centerX The x coordinate of the center of the animating circle.
+     * @param centerY The y coordinate of the center of the animating circle.
+     * @param startRadius The starting radius of the animating circle.
+     * @param endRadius The ending radius of the animating circle.
+     */
+    public static final ValueAnimator createCircularReveal(View view,
+            int centerX,  int centerY, float startRadius, float endRadius) {
+        return RevealAnimator.ofRevealCircle(view, centerX, centerY,
+                startRadius, endRadius, false);
+    }
+}
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 0f40ee7..02011e0 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -4530,6 +4530,28 @@
     }
 
     /**
+     * Native-calculated damage path
+     * Returns false if this path was unable to complete successfully. This means
+     * it hit a ViewParent it doesn't recognize and needs to fall back to calculating
+     * damage area
+     * @hide
+     */
+    public boolean damageChildDeferred(View child) {
+        ViewParent parent = getParent();
+        while (parent != null) {
+            if (parent instanceof ViewGroup) {
+                parent = parent.getParent();
+            } else if (parent instanceof ViewRootImpl) {
+                ((ViewRootImpl) parent).invalidate();
+                return true;
+            } else {
+                parent = null;
+            }
+        }
+        return false;
+    }
+
+    /**
      * Quick invalidation method called by View.invalidateViewProperty. This doesn't set the
      * DRAWN flags and doesn't handle the Animation logic that the default invalidation methods
      * do; all we want to do here is schedule a traversal with the appropriate dirty rect.
@@ -4537,6 +4559,10 @@
      * @hide
      */
     public void damageChild(View child, final Rect dirty) {
+        if (damageChildDeferred(child)) {
+            return;
+        }
+
         ViewParent parent = this;
 
         final AttachInfo attachInfo = mAttachInfo;
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index f3d1e3c..76d5038 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -181,7 +181,6 @@
     int mWidth;
     int mHeight;
     Rect mDirty;
-    final Rect mCurrentDirty = new Rect();
     boolean mIsAnimating;
 
     CompatibilityInfo.Translator mTranslator;
@@ -861,7 +860,9 @@
 
     void invalidate() {
         mDirty.set(0, 0, mWidth, mHeight);
-        scheduleTraversals();
+        if (!mWillDrawSoon) {
+            scheduleTraversals();
+        }
     }
 
     void invalidateWorld(View view) {
@@ -2436,12 +2437,10 @@
                 mHardwareYOffset = yoff;
                 mResizeAlpha = resizeAlpha;
 
-                mCurrentDirty.set(dirty);
                 dirty.setEmpty();
 
                 mBlockResizeBuffer = false;
-                attachInfo.mHardwareRenderer.draw(mView, attachInfo, this,
-                        animating ? null : mCurrentDirty);
+                attachInfo.mHardwareRenderer.draw(mView, attachInfo, this);
             } else {
                 // If we get here with a disabled & requested hardware renderer, something went
                 // wrong (an invalidate posted right before we destroyed the hardware surface
diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java
index b4779f4..0ebf2e1 100644
--- a/core/java/android/view/WindowManagerGlobal.java
+++ b/core/java/android/view/WindowManagerGlobal.java
@@ -147,9 +147,14 @@
                     InputMethodManager imm = InputMethodManager.getInstance();
                     IWindowManager windowManager = getWindowManagerService();
                     sWindowSession = windowManager.openSession(
+                            new IWindowSessionCallback.Stub() {
+                                @Override
+                                public void onAnimatorScaleChanged(float scale) {
+                                    ValueAnimator.setDurationScale(scale);
+                                }
+                            },
                             imm.getClient(), imm.getInputContext());
-                    float animatorScale = windowManager.getAnimationScale(2);
-                    ValueAnimator.setDurationScale(animatorScale);
+                    ValueAnimator.setDurationScale(windowManager.getCurrentAnimatorScale());
                 } catch (RemoteException e) {
                     Log.e(TAG, "Failed to open window session", e);
                 }
diff --git a/core/java/android/view/WindowManagerInternal.java b/core/java/android/view/WindowManagerInternal.java
index 14dc356..a92bf59 100644
--- a/core/java/android/view/WindowManagerInternal.java
+++ b/core/java/android/view/WindowManagerInternal.java
@@ -20,6 +20,7 @@
 import android.graphics.Region;
 import android.hardware.display.DisplayManagerInternal;
 import android.os.IBinder;
+import android.os.IRemoteCallback;
 
 import java.util.List;
 
@@ -105,7 +106,7 @@
      * Set by the accessibility layer to specify the magnification and panning to
      * be applied to all windows that should be magnified.
      *
-     * @param callbacks The callbacks to invoke.
+     * @param spec The MagnficationSpec to set.
      *
      * @see #setMagnificationCallbacks(MagnificationCallbacks)
      */
@@ -161,4 +162,10 @@
      * @param outBounds The frame to populate.
      */
     public abstract void getWindowFrame(IBinder token, Rect outBounds);
+
+    /**
+     * Invalidate all visible windows. Then report back on the callback once all windows have
+     * redrawn.
+     */
+    public abstract void waitForAllWindowsDrawn(IRemoteCallback callback, long timeout);
 }
diff --git a/core/java/android/view/accessibility/CaptioningManager.java b/core/java/android/view/accessibility/CaptioningManager.java
index a0134d6..334ff43 100644
--- a/core/java/android/view/accessibility/CaptioningManager.java
+++ b/core/java/android/view/accessibility/CaptioningManager.java
@@ -16,6 +16,8 @@
 
 package android.view.accessibility;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.database.ContentObserver;
@@ -78,6 +80,7 @@
      *         language
      * @hide
      */
+    @Nullable
     public final String getRawLocale() {
         return Secure.getString(mContentResolver, Secure.ACCESSIBILITY_CAPTIONING_LOCALE);
     }
@@ -86,6 +89,7 @@
      * @return the locale for the user's preferred captioning language, or null
      *         if not specified
      */
+    @Nullable
     public final Locale getLocale() {
         final String rawLocale = getRawLocale();
         if (!TextUtils.isEmpty(rawLocale)) {
@@ -125,6 +129,7 @@
      * @return the user's preferred visual properties for captions as a
      *         {@link CaptionStyle}, or the default style if not specified
      */
+    @NonNull
     public CaptionStyle getUserStyle() {
         final int preset = getRawUserStyle();
         if (preset == CaptionStyle.PRESET_CUSTOM) {
@@ -140,17 +145,19 @@
      *
      * @param listener the listener to add
      */
-    public void addCaptioningChangeListener(CaptioningChangeListener listener) {
+    public void addCaptioningChangeListener(@NonNull CaptioningChangeListener listener) {
         synchronized (mListeners) {
             if (mListeners.isEmpty()) {
                 registerObserver(Secure.ACCESSIBILITY_CAPTIONING_ENABLED);
                 registerObserver(Secure.ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR);
                 registerObserver(Secure.ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR);
+                registerObserver(Secure.ACCESSIBILITY_CAPTIONING_WINDOW_COLOR);
                 registerObserver(Secure.ACCESSIBILITY_CAPTIONING_EDGE_TYPE);
                 registerObserver(Secure.ACCESSIBILITY_CAPTIONING_EDGE_COLOR);
                 registerObserver(Secure.ACCESSIBILITY_CAPTIONING_TYPEFACE);
                 registerObserver(Secure.ACCESSIBILITY_CAPTIONING_FONT_SCALE);
                 registerObserver(Secure.ACCESSIBILITY_CAPTIONING_LOCALE);
+                registerObserver(Secure.ACCESSIBILITY_CAPTIONING_PRESET);
             }
 
             mListeners.add(listener);
@@ -167,7 +174,7 @@
      *
      * @param listener the listener to remove
      */
-    public void removeCaptioningChangeListener(CaptioningChangeListener listener) {
+    public void removeCaptioningChangeListener(@NonNull CaptioningChangeListener listener) {
         synchronized (mListeners) {
             mListeners.remove(listener);
 
@@ -253,11 +260,18 @@
         /** Packed value for a color of 'none' and a cached opacity of 100%. */
         private static final int COLOR_NONE_OPAQUE = 0x000000FF;
 
+        /** Packed value for an unspecified color and opacity. */
+        private static final int COLOR_UNSPECIFIED = 0x000001FF;
+
         private static final CaptionStyle WHITE_ON_BLACK;
         private static final CaptionStyle BLACK_ON_WHITE;
         private static final CaptionStyle YELLOW_ON_BLACK;
         private static final CaptionStyle YELLOW_ON_BLUE;
         private static final CaptionStyle DEFAULT_CUSTOM;
+        private static final CaptionStyle UNSPECIFIED;
+
+        /** The default caption style used to fill in unspecified values. @hide */
+        public static final CaptionStyle DEFAULT;
 
         /** @hide */
         public static final CaptionStyle[] PRESETS;
@@ -265,6 +279,9 @@
         /** @hide */
         public static final int PRESET_CUSTOM = -1;
 
+        /** Unspecified edge type value. */
+        public static final int EDGE_TYPE_UNSPECIFIED = -1;
+
         /** Edge type value specifying no character edges. */
         public static final int EDGE_TYPE_NONE = 0;
 
@@ -289,6 +306,7 @@
         /**
          * The preferred edge type for video captions, one of:
          * <ul>
+         * <li>{@link #EDGE_TYPE_UNSPECIFIED}
          * <li>{@link #EDGE_TYPE_NONE}
          * <li>{@link #EDGE_TYPE_OUTLINE}
          * <li>{@link #EDGE_TYPE_DROP_SHADOW}
@@ -326,9 +344,81 @@
         }
 
         /**
+         * Applies a caption style, overriding any properties that are specified
+         * in the overlay caption.
+         *
+         * @param overlay The style to apply
+         * @return A caption style with the overlay style applied
+         * @hide
+         */
+        @NonNull
+        public CaptionStyle applyStyle(@NonNull CaptionStyle overlay) {
+            final int newForegroundColor = overlay.hasForegroundColor() ?
+                    overlay.foregroundColor : foregroundColor;
+            final int newBackgroundColor = overlay.hasBackgroundColor() ?
+                    overlay.backgroundColor : backgroundColor;
+            final int newEdgeType = overlay.hasEdgeType() ?
+                    overlay.edgeType : edgeType;
+            final int newEdgeColor = overlay.hasEdgeColor() ?
+                    overlay.edgeColor : edgeColor;
+            final int newWindowColor = overlay.hasWindowColor() ?
+                    overlay.windowColor : windowColor;
+            final String newRawTypeface = overlay.mRawTypeface != null ?
+                    overlay.mRawTypeface : mRawTypeface;
+            return new CaptionStyle(newForegroundColor, newBackgroundColor, newEdgeType,
+                    newEdgeColor, newWindowColor, newRawTypeface);
+        }
+
+        /**
+         * @return {@code true} if the user has specified a background color
+         *         that should override the application default, {@code false}
+         *         otherwise
+         */
+        public boolean hasBackgroundColor() {
+            return backgroundColor != COLOR_UNSPECIFIED;
+        }
+
+        /**
+         * @return {@code true} if the user has specified a foreground color
+         *         that should override the application default, {@code false}
+         *         otherwise
+         */
+        public boolean hasForegroundColor() {
+            return foregroundColor != COLOR_UNSPECIFIED;
+        }
+
+        /**
+         * @return {@code true} if the user has specified an edge type that
+         *         should override the application default, {@code false}
+         *         otherwise
+         */
+        public boolean hasEdgeType() {
+            return edgeType != EDGE_TYPE_UNSPECIFIED;
+        }
+
+        /**
+         * @return {@code true} if the user has specified an edge color that
+         *         should override the application default, {@code false}
+         *         otherwise
+         */
+        public boolean hasEdgeColor() {
+            return edgeColor != COLOR_UNSPECIFIED;
+        }
+
+        /**
+         * @return {@code true} if the user has specified a window color that
+         *         should override the application default, {@code false}
+         *         otherwise
+         */
+        public boolean hasWindowColor() {
+            return windowColor != COLOR_UNSPECIFIED;
+        }
+
+        /**
          * @return the preferred {@link Typeface} for video captions, or null if
          *         not specified
          */
+        @Nullable
         public Typeface getTypeface() {
             if (mParsedTypeface == null && !TextUtils.isEmpty(mRawTypeface)) {
                 mParsedTypeface = Typeface.create(mRawTypeface, Typeface.NORMAL);
@@ -339,6 +429,7 @@
         /**
          * @hide
          */
+        @NonNull
         public static CaptionStyle getCustomStyle(ContentResolver cr) {
             final CaptionStyle defStyle = CaptionStyle.DEFAULT_CUSTOM;
             final int foregroundColor = Secure.getInt(
@@ -370,12 +461,17 @@
                     Color.BLACK, COLOR_NONE_OPAQUE, null);
             YELLOW_ON_BLUE = new CaptionStyle(Color.YELLOW, Color.BLUE, EDGE_TYPE_NONE,
                     Color.BLACK, COLOR_NONE_OPAQUE, null);
+            UNSPECIFIED = new CaptionStyle(COLOR_UNSPECIFIED, COLOR_UNSPECIFIED,
+                    EDGE_TYPE_UNSPECIFIED, COLOR_UNSPECIFIED, COLOR_UNSPECIFIED, null);
 
+            // The ordering of these cannot change since we store the index
+            // directly in preferences.
             PRESETS = new CaptionStyle[] {
-                    WHITE_ON_BLACK, BLACK_ON_WHITE, YELLOW_ON_BLACK, YELLOW_ON_BLUE
+                    WHITE_ON_BLACK, BLACK_ON_WHITE, YELLOW_ON_BLACK, YELLOW_ON_BLUE, UNSPECIFIED
             };
 
             DEFAULT_CUSTOM = WHITE_ON_BLACK;
+            DEFAULT = WHITE_ON_BLACK;
         }
     }
 
@@ -389,8 +485,7 @@
          *
          * @param enabled the user's new preferred captioning enabled state
          */
-        public void onEnabledChanged(boolean enabled) {
-        }
+        public void onEnabledChanged(boolean enabled) {}
 
         /**
          * Called when the captioning user style changes.
@@ -398,17 +493,15 @@
          * @param userStyle the user's new preferred style
          * @see CaptioningManager#getUserStyle()
          */
-        public void onUserStyleChanged(CaptionStyle userStyle) {
-        }
+        public void onUserStyleChanged(@NonNull CaptionStyle userStyle) {}
 
         /**
          * Called when the captioning locale changes.
          *
-         * @param locale the preferred captioning locale
+         * @param locale the preferred captioning locale, or {@code null} if not specified
          * @see CaptioningManager#getLocale()
          */
-        public void onLocaleChanged(Locale locale) {
-        }
+        public void onLocaleChanged(@Nullable Locale locale) {}
 
         /**
          * Called when the captioning font scaling factor changes.
@@ -416,7 +509,6 @@
          * @param fontScale the preferred font scaling factor
          * @see CaptioningManager#getFontScale()
          */
-        public void onFontScaleChanged(float fontScale) {
-        }
+        public void onFontScaleChanged(float fontScale) {}
     }
 }
diff --git a/core/java/android/view/inputmethod/BaseInputConnection.java b/core/java/android/view/inputmethod/BaseInputConnection.java
index cccfa78..a74e3a0 100644
--- a/core/java/android/view/inputmethod/BaseInputConnection.java
+++ b/core/java/android/view/inputmethod/BaseInputConnection.java
@@ -602,8 +602,7 @@
         
         beginBatchEdit();
         if (!composing && !TextUtils.isEmpty(text)) {
-            // Notify the text is committed by the user to InputMethodManagerService
-            mIMM.notifyTextCommitted();
+            mIMM.notifyUserAction();
         }
 
         // delete composing text set previously.
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index f874eb7..0693617 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -363,7 +363,7 @@
     static final int MSG_SEND_INPUT_EVENT = 5;
     static final int MSG_TIMEOUT_INPUT_EVENT = 6;
     static final int MSG_FLUSH_INPUT_EVENT = 7;
-    static final int SET_CURSOR_ANCHOR_MONITOR_MODE = 8;
+    static final int MSG_SET_CURSOR_ANCHOR_MONITOR_MODE = 8;
 
     class H extends Handler {
         H(Looper looper) {
@@ -494,7 +494,7 @@
                     finishedInputEvent(msg.arg1, false, false);
                     return;
                 }
-                case SET_CURSOR_ANCHOR_MONITOR_MODE: {
+                case MSG_SET_CURSOR_ANCHOR_MONITOR_MODE: {
                     synchronized (mH) {
                         mCursorAnchorMonitorMode = msg.arg1;
                         // Clear the cache.
@@ -570,7 +570,7 @@
 
         @Override
         public void setCursorAnchorMonitorMode(int monitorMode) {
-            mH.sendMessage(mH.obtainMessage(SET_CURSOR_ANCHOR_MONITOR_MODE, monitorMode, 0));
+            mH.sendMessage(mH.obtainMessage(MSG_SET_CURSOR_ANCHOR_MONITOR_MODE, monitorMode, 0));
         }
     };
 
@@ -1913,13 +1913,13 @@
     }
 
     /**
-     * Notify the current IME commits text
+     * Notify that a user took some action with this input method.
      * @hide
      */
-    public void notifyTextCommitted() {
+    public void notifyUserAction() {
         synchronized (mH) {
             try {
-                mService.notifyTextCommitted();
+                mService.notifyUserAction();
             } catch (RemoteException e) {
                 Log.w(TAG, "IME died: " + mCurId, e);
             }
diff --git a/core/java/android/webkit/CookieManager.java b/core/java/android/webkit/CookieManager.java
index 2b75d83..abed082 100644
--- a/core/java/android/webkit/CookieManager.java
+++ b/core/java/android/webkit/CookieManager.java
@@ -70,8 +70,7 @@
      /**
      * Sets a cookie for the given URL. Any existing cookie with the same host,
      * path and name will be replaced with the new cookie. The cookie being set
-     * must not have expired and must not be a session cookie, otherwise it
-     * will be ignored.
+     * will be ignored if it is expired.
      *
      * @param url the URL for which the cookie is set
      * @param value the cookie as a string, using the format of the 'Set-Cookie'
diff --git a/core/java/android/webkit/WebViewFactoryProvider.java b/core/java/android/webkit/WebViewFactoryProvider.java
index 945e0e3..6e6a987 100644
--- a/core/java/android/webkit/WebViewFactoryProvider.java
+++ b/core/java/android/webkit/WebViewFactoryProvider.java
@@ -37,13 +37,6 @@
         String findAddress(String addr);
 
         /**
-         * Implements the API methods:
-         * {@link android.webkit.WebView#enablePlatformNotifications()}
-         * {@link android.webkit.WebView#disablePlatformNotifications()}
-         */
-        void setPlatformNotificationsEnabled(boolean enable);
-
-        /**
          * Implements the API method:
          * {@link android.webkit.WebSettings#getDefaultUserAgent(Context) }
          */
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 9a46052..372228c 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -4028,12 +4028,10 @@
             final int scrollY = mScrollY;
             if (!mEdgeGlowTop.isFinished()) {
                 final int restoreCount = canvas.save();
-                final int leftPadding = mListPadding.left + mGlowPaddingLeft;
-                final int rightPadding = mListPadding.right + mGlowPaddingRight;
-                final int width = getWidth() - leftPadding - rightPadding;
+                final int width = getWidth();
 
                 int edgeY = Math.min(0, scrollY + mFirstPositionDistanceGuess);
-                canvas.translate(leftPadding, edgeY);
+                canvas.translate(0, edgeY);
                 mEdgeGlowTop.setSize(width, getHeight());
                 if (mEdgeGlowTop.draw(canvas)) {
                     invalidate(0, 0, getWidth(),
@@ -4043,12 +4041,10 @@
             }
             if (!mEdgeGlowBottom.isFinished()) {
                 final int restoreCount = canvas.save();
-                final int leftPadding = mListPadding.left + mGlowPaddingLeft;
-                final int rightPadding = mListPadding.right + mGlowPaddingRight;
-                final int width = getWidth() - leftPadding - rightPadding;
+                final int width = getWidth();
                 final int height = getHeight();
 
-                int edgeX = -width + leftPadding;
+                int edgeX = -width;
                 int edgeY = Math.max(height, scrollY + mLastPositionDistanceGuess);
                 canvas.translate(edgeX, edgeY);
                 canvas.rotate(180, width, 0);
diff --git a/core/java/android/widget/EdgeEffect.java b/core/java/android/widget/EdgeEffect.java
index c4a40b4..2502954 100644
--- a/core/java/android/widget/EdgeEffect.java
+++ b/core/java/android/widget/EdgeEffect.java
@@ -122,7 +122,7 @@
         final TypedArray a = context.obtainStyledAttributes(
                 com.android.internal.R.styleable.EdgeEffect);
         final int themeColor = a.getColor(
-                com.android.internal.R.styleable.EdgeEffect_colorPrimaryLight, 0xff666666);
+                com.android.internal.R.styleable.EdgeEffect_colorPrimary, 0xff666666);
         a.recycle();
         mPaint.setColor((themeColor & 0xffffff) | 0x33000000);
         mPaint.setStyle(Paint.Style.FILL);
@@ -312,8 +312,7 @@
         final float displacement = Math.max(0, Math.min(mDisplacement, 1.f)) - 0.5f;
         float translateX = mBounds.width() * displacement / 2;
 
-        canvas.clipRect(Float.MIN_VALUE, mBounds.top,
-                Float.MAX_VALUE, Float.MAX_VALUE);
+        canvas.clipRect(mBounds);
         canvas.translate(translateX, 0);
         canvas.drawArc(mArcRect, 45, 90, true, mPaint);
         canvas.restoreToCount(count);
diff --git a/core/java/android/widget/RadialTimePickerView.java b/core/java/android/widget/RadialTimePickerView.java
index 1c9ab61..883183e 100644
--- a/core/java/android/widget/RadialTimePickerView.java
+++ b/core/java/android/widget/RadialTimePickerView.java
@@ -42,6 +42,7 @@
 import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
+
 import com.android.internal.R;
 
 import java.text.DateFormatSymbols;
@@ -82,13 +83,13 @@
     private static final int ALPHA_TRANSPARENT = 0;
 
     // Alpha level of color for selector.
-    private static final int ALPHA_SELECTOR = 51;
+    private static final int ALPHA_SELECTOR = 255; // was 51
 
     // Alpha level of color for selected circle.
     private static final int ALPHA_AMPM_SELECTED = ALPHA_SELECTOR;
 
     // Alpha level of color for pressed circle.
-    private static final int ALPHA_AMPM_PRESSED = 175;
+    private static final int ALPHA_AMPM_PRESSED = 255; // was 175
 
     private static final float COSINE_30_DEGREES = ((float) Math.sqrt(3)) * 0.5f;
     private static final float SINE_30_DEGREES = 0.5f;
@@ -112,8 +113,15 @@
     private final String[] mAmPmText = new String[2];
 
     private final Paint[] mPaint = new Paint[2];
+    private final int[] mColor = new int[2];
+    private final IntHolder[] mAlpha = new IntHolder[2];
+
     private final Paint mPaintCenter = new Paint();
+
     private final Paint[][] mPaintSelector = new Paint[2][3];
+    private final int[][] mColorSelector = new int[2][3];
+    private final IntHolder[][] mAlphaSelector = new IntHolder[2][3];
+
     private final Paint mPaintAmPmText = new Paint();
     private final Paint[] mPaintAmPmCircle = new Paint[2];
 
@@ -309,65 +317,80 @@
         final Resources res = getResources();
 
         mAmPmUnselectedColor = a.getColor(R.styleable.TimePicker_amPmUnselectedBackgroundColor,
-                res.getColor(
-                        R.color.timepicker_default_ampm_unselected_background_color_holo_light));
+                res.getColor(R.color.timepicker_default_ampm_unselected_background_color_material));
 
         mAmPmSelectedColor = a.getColor(R.styleable.TimePicker_amPmSelectedBackgroundColor,
-                res.getColor(R.color.timepicker_default_ampm_selected_background_color_holo_light));
+                res.getColor(R.color.timepicker_default_ampm_selected_background_color_material));
 
         mAmPmTextColor = a.getColor(R.styleable.TimePicker_amPmTextColor,
-                res.getColor(R.color.timepicker_default_text_color_holo_light));
-
-        final int numbersTextColor = a.getColor(R.styleable.TimePicker_numbersTextColor,
-                res.getColor(R.color.timepicker_default_text_color_holo_light));
+                res.getColor(R.color.timepicker_default_text_color_material));
 
         mTypeface = Typeface.create("sans-serif", Typeface.NORMAL);
 
+        // Initialize all alpha values to opaque.
+        for (int i = 0; i < mAlpha.length; i++) {
+            mAlpha[i] = new IntHolder(ALPHA_OPAQUE);
+        }
+        for (int i = 0; i < mAlphaSelector.length; i++) {
+            for (int j = 0; j < mAlphaSelector[i].length; j++) {
+                mAlphaSelector[i][j] = new IntHolder(ALPHA_OPAQUE);
+            }
+        }
+
+        final int numbersTextColor = a.getColor(R.styleable.TimePicker_numbersTextColor,
+                res.getColor(R.color.timepicker_default_text_color_material));
+
         mPaint[HOURS] = new Paint();
-        mPaint[HOURS].setColor(numbersTextColor);
         mPaint[HOURS].setAntiAlias(true);
         mPaint[HOURS].setTextAlign(Paint.Align.CENTER);
+        mColor[HOURS] = numbersTextColor;
 
         mPaint[MINUTES] = new Paint();
-        mPaint[MINUTES].setColor(numbersTextColor);
         mPaint[MINUTES].setAntiAlias(true);
         mPaint[MINUTES].setTextAlign(Paint.Align.CENTER);
+        mColor[MINUTES] = numbersTextColor;
 
         mPaintCenter.setColor(numbersTextColor);
         mPaintCenter.setAntiAlias(true);
         mPaintCenter.setTextAlign(Paint.Align.CENTER);
 
         mPaintSelector[HOURS][SELECTOR_CIRCLE] = new Paint();
-        mPaintSelector[HOURS][SELECTOR_CIRCLE].setColor(
-                a.getColor(R.styleable.TimePicker_numbersSelectorColor, R.color.holo_blue_light));
         mPaintSelector[HOURS][SELECTOR_CIRCLE].setAntiAlias(true);
+        mColorSelector[HOURS][SELECTOR_CIRCLE] = a.getColor(
+                R.styleable.TimePicker_numbersSelectorColor,
+                R.color.timepicker_default_selector_color_material);
 
         mPaintSelector[HOURS][SELECTOR_DOT] = new Paint();
-        mPaintSelector[HOURS][SELECTOR_DOT].setColor(
-                a.getColor(R.styleable.TimePicker_numbersSelectorColor, R.color.holo_blue_light));
         mPaintSelector[HOURS][SELECTOR_DOT].setAntiAlias(true);
+        mColorSelector[HOURS][SELECTOR_DOT] = a.getColor(
+                R.styleable.TimePicker_numbersSelectorColor,
+                R.color.timepicker_default_selector_color_material);
 
         mPaintSelector[HOURS][SELECTOR_LINE] = new Paint();
-        mPaintSelector[HOURS][SELECTOR_LINE].setColor(
-                a.getColor(R.styleable.TimePicker_numbersSelectorColor, R.color.holo_blue_light));
         mPaintSelector[HOURS][SELECTOR_LINE].setAntiAlias(true);
         mPaintSelector[HOURS][SELECTOR_LINE].setStrokeWidth(2);
+        mColorSelector[HOURS][SELECTOR_LINE] = a.getColor(
+                R.styleable.TimePicker_numbersSelectorColor,
+                R.color.timepicker_default_selector_color_material);
 
         mPaintSelector[MINUTES][SELECTOR_CIRCLE] = new Paint();
-        mPaintSelector[MINUTES][SELECTOR_CIRCLE].setColor(
-                a.getColor(R.styleable.TimePicker_numbersSelectorColor, R.color.holo_blue_light));
         mPaintSelector[MINUTES][SELECTOR_CIRCLE].setAntiAlias(true);
+        mColorSelector[MINUTES][SELECTOR_CIRCLE] = a.getColor(
+                R.styleable.TimePicker_numbersSelectorColor,
+                R.color.timepicker_default_selector_color_material);
 
         mPaintSelector[MINUTES][SELECTOR_DOT] = new Paint();
-        mPaintSelector[MINUTES][SELECTOR_DOT].setColor(
-                a.getColor(R.styleable.TimePicker_numbersSelectorColor, R.color.holo_blue_light));
         mPaintSelector[MINUTES][SELECTOR_DOT].setAntiAlias(true);
+        mColorSelector[MINUTES][SELECTOR_DOT] = a.getColor(
+                R.styleable.TimePicker_numbersSelectorColor,
+                R.color.timepicker_default_selector_color_material);
 
         mPaintSelector[MINUTES][SELECTOR_LINE] = new Paint();
-        mPaintSelector[MINUTES][SELECTOR_LINE].setColor(
-                a.getColor(R.styleable.TimePicker_numbersSelectorColor, R.color.holo_blue_light));
         mPaintSelector[MINUTES][SELECTOR_LINE].setAntiAlias(true);
         mPaintSelector[MINUTES][SELECTOR_LINE].setStrokeWidth(2);
+        mColorSelector[MINUTES][SELECTOR_LINE] = a.getColor(
+                R.styleable.TimePicker_numbersSelectorColor,
+                R.color.timepicker_default_selector_color_material);
 
         mPaintAmPmText.setColor(mAmPmTextColor);
         mPaintAmPmText.setTypeface(mTypeface);
@@ -379,13 +402,12 @@
         mPaintAmPmCircle[PM] = new Paint();
         mPaintAmPmCircle[PM].setAntiAlias(true);
 
-        mPaintBackground.setColor(
-                a.getColor(R.styleable.TimePicker_numbersBackgroundColor, Color.WHITE));
+        mPaintBackground.setColor(a.getColor(R.styleable.TimePicker_numbersBackgroundColor,
+                res.getColor(R.color.timepicker_default_numbers_background_color_material)));
         mPaintBackground.setAntiAlias(true);
 
-        final int disabledColor = a.getColor(R.styleable.TimePicker_disabledColor,
-                res.getColor(R.color.timepicker_default_disabled_color_holo_light));
-        mPaintDisabled.setColor(disabledColor);
+        mPaintDisabled.setColor(a.getColor(R.styleable.TimePicker_disabledColor,
+                res.getColor(R.color.timepicker_default_disabled_color_material)));
         mPaintDisabled.setAntiAlias(true);
 
         if (DEBUG) {
@@ -415,6 +437,8 @@
         mSelectionRadiusMultiplier = Float.parseFloat(
                 res.getString(R.string.timepicker_selection_radius_multiplier));
 
+        a.recycle();
+
         setOnTouchListener(this);
 
         // Initial values
@@ -622,21 +646,21 @@
         mAmPmCircleRadiusMultiplier = Float.parseFloat(
                 res.getString(R.string.timepicker_ampm_circle_radius_multiplier));
 
-        mPaint[HOURS].setAlpha(mShowHours ? ALPHA_OPAQUE : ALPHA_TRANSPARENT);
-        mPaint[MINUTES].setAlpha(mShowHours ? ALPHA_TRANSPARENT : ALPHA_OPAQUE);
+        mAlpha[HOURS].setValue(mShowHours ? ALPHA_OPAQUE : ALPHA_TRANSPARENT);
+        mAlpha[MINUTES].setValue(mShowHours ? ALPHA_TRANSPARENT : ALPHA_OPAQUE);
 
-        mPaintSelector[HOURS][SELECTOR_CIRCLE].setAlpha(
-                mShowHours ?ALPHA_SELECTOR : ALPHA_TRANSPARENT);
-        mPaintSelector[HOURS][SELECTOR_DOT].setAlpha(
+        mAlphaSelector[HOURS][SELECTOR_CIRCLE].setValue(
+                mShowHours ? ALPHA_SELECTOR : ALPHA_TRANSPARENT);
+        mAlphaSelector[HOURS][SELECTOR_DOT].setValue(
                 mShowHours ? ALPHA_OPAQUE : ALPHA_TRANSPARENT);
-        mPaintSelector[HOURS][SELECTOR_LINE].setAlpha(
+        mAlphaSelector[HOURS][SELECTOR_LINE].setValue(
                 mShowHours ? ALPHA_SELECTOR : ALPHA_TRANSPARENT);
 
-        mPaintSelector[MINUTES][SELECTOR_CIRCLE].setAlpha(
+        mAlphaSelector[MINUTES][SELECTOR_CIRCLE].setValue(
                 mShowHours ? ALPHA_TRANSPARENT : ALPHA_SELECTOR);
-        mPaintSelector[MINUTES][SELECTOR_DOT].setAlpha(
+        mAlphaSelector[MINUTES][SELECTOR_DOT].setValue(
                 mShowHours ? ALPHA_TRANSPARENT : ALPHA_OPAQUE);
-        mPaintSelector[MINUTES][SELECTOR_LINE].setAlpha(
+        mAlphaSelector[MINUTES][SELECTOR_LINE].setValue(
                 mShowHours ? ALPHA_TRANSPARENT : ALPHA_SELECTOR);
     }
 
@@ -704,20 +728,23 @@
         calculateGridSizesMinutes();
 
         drawCircleBackground(canvas);
+        drawSelector(canvas);
 
         drawTextElements(canvas, mTextSize[HOURS], mTypeface, mOuterTextHours,
-                mTextGridWidths[HOURS], mTextGridHeights[HOURS], mPaint[HOURS]);
+                mTextGridWidths[HOURS], mTextGridHeights[HOURS], mPaint[HOURS],
+                mColor[HOURS], mAlpha[HOURS].getValue());
 
         if (mIs24HourMode && mInnerTextHours != null) {
             drawTextElements(canvas, mInnerTextSize, mTypeface, mInnerTextHours,
-                    mInnerTextGridWidths, mInnerTextGridHeights, mPaint[HOURS]);
+                    mInnerTextGridWidths, mInnerTextGridHeights, mPaint[HOURS],
+                    mColor[HOURS], mAlpha[HOURS].getValue());
         }
 
         drawTextElements(canvas, mTextSize[MINUTES], mTypeface, mOuterTextMinutes,
-                mTextGridWidths[MINUTES], mTextGridHeights[MINUTES], mPaint[MINUTES]);
+                mTextGridWidths[MINUTES], mTextGridHeights[MINUTES], mPaint[MINUTES],
+                mColor[MINUTES], mAlpha[MINUTES].getValue());
 
         drawCenter(canvas);
-        drawSelector(canvas);
         if (!mIs24HourMode) {
             drawAmPm(canvas);
         }
@@ -772,12 +799,12 @@
 
         // Draw the two circles
         mPaintAmPmCircle[AM].setColor(amColor);
-        mPaintAmPmCircle[AM].setAlpha(amAlpha);
+        mPaintAmPmCircle[AM].setAlpha(getMultipliedAlpha(amColor, amAlpha));
         canvas.drawCircle(isLayoutRtl ? mRightIndicatorXCenter : mLeftIndicatorXCenter,
                 mAmPmYCenter, mAmPmCircleRadius, mPaintAmPmCircle[AM]);
 
         mPaintAmPmCircle[PM].setColor(pmColor);
-        mPaintAmPmCircle[PM].setAlpha(pmAlpha);
+        mPaintAmPmCircle[PM].setAlpha(getMultipliedAlpha(pmColor, pmAlpha));
         canvas.drawCircle(isLayoutRtl ? mLeftIndicatorXCenter : mRightIndicatorXCenter,
                 mAmPmYCenter, mAmPmCircleRadius, mPaintAmPmCircle[PM]);
 
@@ -792,6 +819,10 @@
                 textYCenter, mPaintAmPmText);
     }
 
+    private int getMultipliedAlpha(int argb, int alpha) {
+        return (int) (Color.alpha(argb) * (alpha / 255.0) + 0.5);
+    }
+
     private void drawSelector(Canvas canvas, int index) {
         // Calculate the current radius at which to place the selection circle.
         mLineLength[index] = (int) (mCircleRadius[index]
@@ -802,15 +833,27 @@
         int pointX = mXCenter + (int) (mLineLength[index] * Math.sin(selectionRadians));
         int pointY = mYCenter - (int) (mLineLength[index] * Math.cos(selectionRadians));
 
+        int color;
+        int alpha;
+        Paint paint;
+
         // Draw the selection circle
-        canvas.drawCircle(pointX, pointY, mSelectionRadius[index],
-                mPaintSelector[index % 2][SELECTOR_CIRCLE]);
+        color = mColorSelector[index % 2][SELECTOR_CIRCLE];
+        alpha = mAlphaSelector[index % 2][SELECTOR_CIRCLE].getValue();
+        paint = mPaintSelector[index % 2][SELECTOR_CIRCLE];
+        paint.setColor(color);
+        paint.setAlpha(getMultipliedAlpha(color, alpha));
+        canvas.drawCircle(pointX, pointY, mSelectionRadius[index], paint);
 
         // Draw the dot if needed
         if (mSelectionDegrees[index] % 30 != 0) {
             // We're not on a direct tick
-            canvas.drawCircle(pointX, pointY, (mSelectionRadius[index] * 2 / 7),
-                    mPaintSelector[index % 2][SELECTOR_DOT]);
+            color = mColorSelector[index % 2][SELECTOR_DOT];
+            alpha = mAlphaSelector[index % 2][SELECTOR_DOT].getValue();
+            paint = mPaintSelector[index % 2][SELECTOR_DOT];
+            paint.setColor(color);
+            paint.setAlpha(getMultipliedAlpha(color, alpha));
+            canvas.drawCircle(pointX, pointY, (mSelectionRadius[index] * 2 / 7), paint);
         } else {
             // We're not drawing the dot, so shorten the line to only go as far as the edge of the
             // selection circle
@@ -820,8 +863,12 @@
         }
 
         // Draw the line
-        canvas.drawLine(mXCenter, mYCenter, pointX, pointY,
-                mPaintSelector[index % 2][SELECTOR_LINE]);
+        color = mColorSelector[index % 2][SELECTOR_LINE];
+        alpha = mAlphaSelector[index % 2][SELECTOR_LINE].getValue();
+        paint = mPaintSelector[index % 2][SELECTOR_LINE];
+        paint.setColor(color);
+        paint.setAlpha(getMultipliedAlpha(color, alpha));
+        canvas.drawLine(mXCenter, mYCenter, pointX, pointY, paint);
     }
 
     private void drawDebug(Canvas canvas) {
@@ -948,9 +995,11 @@
      * Draw the 12 text values at the positions specified by the textGrid parameters.
      */
     private void drawTextElements(Canvas canvas, float textSize, Typeface typeface, String[] texts,
-            float[] textGridWidths, float[] textGridHeights, Paint paint) {
+            float[] textGridWidths, float[] textGridHeights, Paint paint, int color, int alpha) {
         paint.setTextSize(textSize);
         paint.setTypeface(typeface);
+        paint.setColor(color);
+        paint.setAlpha(getMultipliedAlpha(color, alpha));
         canvas.drawText(texts[0], textGridWidths[3], textGridHeights[0], paint);
         canvas.drawText(texts[1], textGridWidths[4], textGridHeights[1], paint);
         canvas.drawText(texts[2], textGridWidths[5], textGridHeights[2], paint);
@@ -1023,17 +1072,17 @@
         return animator;
     }
 
-    private static ObjectAnimator getFadeOutAnimator(Object target, int startAlpha, int endAlpha,
+    private static ObjectAnimator getFadeOutAnimator(IntHolder target, int startAlpha, int endAlpha,
                 InvalidateUpdateListener updateListener) {
         int duration = 500;
-        ObjectAnimator animator = ObjectAnimator.ofInt(target, "alpha", startAlpha, endAlpha);
+        ObjectAnimator animator = ObjectAnimator.ofInt(target, "value", startAlpha, endAlpha);
         animator.setDuration(duration);
         animator.addUpdateListener(updateListener);
 
         return animator;
     }
 
-    private static ObjectAnimator getFadeInAnimator(Object target, int startAlpha, int endAlpha,
+    private static ObjectAnimator getFadeInAnimator(IntHolder target, int startAlpha, int endAlpha,
                 InvalidateUpdateListener updateListener) {
         Keyframe kf0, kf1, kf2;
         int duration = 500;
@@ -1048,7 +1097,7 @@
         kf0 = Keyframe.ofInt(0f, startAlpha);
         kf1 = Keyframe.ofInt(delayPoint, startAlpha);
         kf2 = Keyframe.ofInt(1f, endAlpha);
-        PropertyValuesHolder fadeIn = PropertyValuesHolder.ofKeyframe("alpha", kf0, kf1, kf2);
+        PropertyValuesHolder fadeIn = PropertyValuesHolder.ofKeyframe("value", kf0, kf1, kf2);
 
         ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(
                 target, fadeIn).setDuration(totalDuration);
@@ -1068,25 +1117,25 @@
             mHoursToMinutesAnims.add(getRadiusDisappearAnimator(this,
                     "animationRadiusMultiplierHours", mInvalidateUpdateListener,
                     mTransitionMidRadiusMultiplier, mTransitionEndRadiusMultiplier));
-            mHoursToMinutesAnims.add(getFadeOutAnimator(mPaint[HOURS],
+            mHoursToMinutesAnims.add(getFadeOutAnimator(mAlpha[HOURS],
                     ALPHA_OPAQUE, ALPHA_TRANSPARENT, mInvalidateUpdateListener));
-            mHoursToMinutesAnims.add(getFadeOutAnimator(mPaintSelector[HOURS][SELECTOR_CIRCLE],
+            mHoursToMinutesAnims.add(getFadeOutAnimator(mAlphaSelector[HOURS][SELECTOR_CIRCLE],
                     ALPHA_SELECTOR, ALPHA_TRANSPARENT, mInvalidateUpdateListener));
-            mHoursToMinutesAnims.add(getFadeOutAnimator(mPaintSelector[HOURS][SELECTOR_DOT],
+            mHoursToMinutesAnims.add(getFadeOutAnimator(mAlphaSelector[HOURS][SELECTOR_DOT],
                     ALPHA_OPAQUE, ALPHA_TRANSPARENT, mInvalidateUpdateListener));
-            mHoursToMinutesAnims.add(getFadeOutAnimator(mPaintSelector[HOURS][SELECTOR_LINE],
+            mHoursToMinutesAnims.add(getFadeOutAnimator(mAlphaSelector[HOURS][SELECTOR_LINE],
                     ALPHA_SELECTOR, ALPHA_TRANSPARENT, mInvalidateUpdateListener));
 
             mHoursToMinutesAnims.add(getRadiusReappearAnimator(this,
                     "animationRadiusMultiplierMinutes", mInvalidateUpdateListener,
                     mTransitionMidRadiusMultiplier, mTransitionEndRadiusMultiplier));
-            mHoursToMinutesAnims.add(getFadeInAnimator(mPaint[MINUTES],
+            mHoursToMinutesAnims.add(getFadeInAnimator(mAlpha[MINUTES],
                     ALPHA_TRANSPARENT, ALPHA_OPAQUE, mInvalidateUpdateListener));
-            mHoursToMinutesAnims.add(getFadeInAnimator(mPaintSelector[MINUTES][SELECTOR_CIRCLE],
+            mHoursToMinutesAnims.add(getFadeInAnimator(mAlphaSelector[MINUTES][SELECTOR_CIRCLE],
                     ALPHA_TRANSPARENT, ALPHA_SELECTOR, mInvalidateUpdateListener));
-            mHoursToMinutesAnims.add(getFadeInAnimator(mPaintSelector[MINUTES][SELECTOR_DOT],
+            mHoursToMinutesAnims.add(getFadeInAnimator(mAlphaSelector[MINUTES][SELECTOR_DOT],
                     ALPHA_TRANSPARENT, ALPHA_OPAQUE, mInvalidateUpdateListener));
-            mHoursToMinutesAnims.add(getFadeInAnimator(mPaintSelector[MINUTES][SELECTOR_LINE],
+            mHoursToMinutesAnims.add(getFadeInAnimator(mAlphaSelector[MINUTES][SELECTOR_LINE],
                     ALPHA_TRANSPARENT, ALPHA_SELECTOR, mInvalidateUpdateListener));
         }
 
@@ -1103,25 +1152,25 @@
             mMinuteToHoursAnims.add(getRadiusDisappearAnimator(this,
                     "animationRadiusMultiplierMinutes", mInvalidateUpdateListener,
                     mTransitionMidRadiusMultiplier, mTransitionEndRadiusMultiplier));
-            mMinuteToHoursAnims.add(getFadeOutAnimator(mPaint[MINUTES],
+            mMinuteToHoursAnims.add(getFadeOutAnimator(mAlpha[MINUTES],
                     ALPHA_OPAQUE, ALPHA_TRANSPARENT, mInvalidateUpdateListener));
-            mMinuteToHoursAnims.add(getFadeOutAnimator(mPaintSelector[MINUTES][SELECTOR_CIRCLE],
+            mMinuteToHoursAnims.add(getFadeOutAnimator(mAlphaSelector[MINUTES][SELECTOR_CIRCLE],
                     ALPHA_SELECTOR, ALPHA_TRANSPARENT, mInvalidateUpdateListener));
-            mMinuteToHoursAnims.add(getFadeOutAnimator(mPaintSelector[MINUTES][SELECTOR_DOT],
+            mMinuteToHoursAnims.add(getFadeOutAnimator(mAlphaSelector[MINUTES][SELECTOR_DOT],
                     ALPHA_OPAQUE, ALPHA_TRANSPARENT, mInvalidateUpdateListener));
-            mMinuteToHoursAnims.add(getFadeOutAnimator(mPaintSelector[MINUTES][SELECTOR_LINE],
+            mMinuteToHoursAnims.add(getFadeOutAnimator(mAlphaSelector[MINUTES][SELECTOR_LINE],
                     ALPHA_SELECTOR, ALPHA_TRANSPARENT, mInvalidateUpdateListener));
 
             mMinuteToHoursAnims.add(getRadiusReappearAnimator(this,
                     "animationRadiusMultiplierHours", mInvalidateUpdateListener,
                     mTransitionMidRadiusMultiplier, mTransitionEndRadiusMultiplier));
-            mMinuteToHoursAnims.add(getFadeInAnimator(mPaint[HOURS],
+            mMinuteToHoursAnims.add(getFadeInAnimator(mAlpha[HOURS],
                     ALPHA_TRANSPARENT, ALPHA_OPAQUE, mInvalidateUpdateListener));
-            mMinuteToHoursAnims.add(getFadeInAnimator(mPaintSelector[HOURS][SELECTOR_CIRCLE],
+            mMinuteToHoursAnims.add(getFadeInAnimator(mAlphaSelector[HOURS][SELECTOR_CIRCLE],
                     ALPHA_TRANSPARENT, ALPHA_SELECTOR, mInvalidateUpdateListener));
-            mMinuteToHoursAnims.add(getFadeInAnimator(mPaintSelector[HOURS][SELECTOR_DOT],
+            mMinuteToHoursAnims.add(getFadeInAnimator(mAlphaSelector[HOURS][SELECTOR_DOT],
                     ALPHA_TRANSPARENT, ALPHA_OPAQUE, mInvalidateUpdateListener));
-            mMinuteToHoursAnims.add(getFadeInAnimator(mPaintSelector[HOURS][SELECTOR_LINE],
+            mMinuteToHoursAnims.add(getFadeInAnimator(mAlphaSelector[HOURS][SELECTOR_LINE],
                     ALPHA_TRANSPARENT, ALPHA_SELECTOR, mInvalidateUpdateListener));
         }
 
@@ -1393,4 +1442,20 @@
         mInputEnabled = inputEnabled;
         invalidate();
     }
+
+    private static class IntHolder {
+        private int mValue;
+
+        public IntHolder(int value) {
+            mValue = value;
+        }
+
+        public void setValue(int value) {
+            mValue = value;
+        }
+
+        public int getValue() {
+            return mValue;
+        }
+    }
 }
diff --git a/core/java/android/widget/ShareActionProvider.java b/core/java/android/widget/ShareActionProvider.java
index 99a7886..ac79d05 100644
--- a/core/java/android/widget/ShareActionProvider.java
+++ b/core/java/android/widget/ShareActionProvider.java
@@ -280,6 +280,7 @@
             final String action = shareIntent.getAction();
             if (Intent.ACTION_SEND.equals(action) || Intent.ACTION_SEND_MULTIPLE.equals(action)) {
                 shareIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT |
+                        Intent.FLAG_ACTIVITY_MULTIPLE_TASK |
                         Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS);
             }
         }
@@ -303,6 +304,7 @@
                 if (Intent.ACTION_SEND.equals(action) ||
                         Intent.ACTION_SEND_MULTIPLE.equals(action)) {
                     launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT |
+                            Intent.FLAG_ACTIVITY_MULTIPLE_TASK |
                             Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS);
                 }
                 mContext.startActivity(launchIntent);
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index a4a9680e..43c8dde 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -222,6 +222,7 @@
  * @attr ref android.R.styleable#TextView_imeActionLabel
  * @attr ref android.R.styleable#TextView_imeActionId
  * @attr ref android.R.styleable#TextView_editorExtras
+ * @attr ref android.R.styleable#TextView_elegantTextHeight
  */
 @RemoteView
 public class TextView extends View implements ViewTreeObserver.OnPreDrawListener {
@@ -2637,6 +2638,8 @@
      * metrics, and also increases top and bottom bounds to provide more space.
      *
      * @param elegant set the paint's elegant metrics flag.
+     *
+     * @attr ref android.R.styleable#TextView_elegantTextHeight
      */
     public void setElegantTextHeight(boolean elegant) {
         mTextPaint.setElegantTextHeight(elegant);
diff --git a/core/java/android/widget/TimePickerDelegate.java b/core/java/android/widget/TimePickerDelegate.java
index 79256e5..bf3971c 100644
--- a/core/java/android/widget/TimePickerDelegate.java
+++ b/core/java/android/widget/TimePickerDelegate.java
@@ -140,13 +140,12 @@
         mSelectMinutes = res.getString(R.string.select_minutes);
 
         mHeaderSelectedColor = a.getColor(R.styleable.TimePicker_headerSelectedTextColor,
-                android.R.color.holo_blue_light);
+                R.color.timepicker_default_selector_color_material);
 
-        mHeaderUnSelectedColor = getUnselectedColor(
-                R.color.timepicker_default_text_color_holo_light);
+        mHeaderUnSelectedColor = getUnselectedColor(R.color.timepicker_default_text_color_material);
         if (mHeaderUnSelectedColor == -1) {
             mHeaderUnSelectedColor = a.getColor(R.styleable.TimePicker_headerUnselectedTextColor,
-                    R.color.timepicker_default_text_color_holo_light);
+                    R.color.timepicker_default_text_color_material);
         }
 
         final int headerBackgroundColor = a.getColor(
@@ -296,7 +295,7 @@
         TypedArray a = mContext.obtainStyledAttributes(TEXT_APPEARANCE_TIME_LABEL_ATTR);
         final int textAppearanceResId = a.getResourceId(0, 0);
         tempView.setTextAppearance(mContext, (textAppearanceResId != 0) ?
-                textAppearanceResId : R.style.TextAppearance_Holo_TimePicker_TimeLabel);
+                textAppearanceResId : R.style.TextAppearance_Material_TimePicker_TimeLabel);
         a.recycle();
         ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                 ViewGroup.LayoutParams.WRAP_CONTENT);
diff --git a/core/java/android/widget/Toolbar.java b/core/java/android/widget/Toolbar.java
index 419c582..cbd9a6a 100644
--- a/core/java/android/widget/Toolbar.java
+++ b/core/java/android/widget/Toolbar.java
@@ -1339,7 +1339,8 @@
                 return getPaddingTop();
 
             case Gravity.BOTTOM:
-                return getPaddingBottom() - child.getMeasuredHeight() - lp.bottomMargin;
+                return getHeight() - getPaddingBottom() -
+                        child.getMeasuredHeight() - lp.bottomMargin;
 
             default:
             case Gravity.CENTER_VERTICAL:
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 106ac0b..877938e 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -38,6 +38,7 @@
             if (Intent.ACTION_SEND.equals(action) ||
                     Intent.ACTION_SEND_MULTIPLE.equals(action)) {
                 target.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT |
+                        Intent.FLAG_ACTIVITY_MULTIPLE_TASK |
                         Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS);
             }
         }
@@ -61,6 +62,7 @@
                 if (Intent.ACTION_SEND.equals(action) ||
                         Intent.ACTION_SEND_MULTIPLE.equals(action)) {
                     in.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT |
+                            Intent.FLAG_ACTIVITY_MULTIPLE_TASK |
                             Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS);
                 }
                 initialIntents[i] = in;
diff --git a/core/java/com/android/internal/app/NavItemSelectedListener.java b/core/java/com/android/internal/app/NavItemSelectedListener.java
new file mode 100644
index 0000000..545f44b
--- /dev/null
+++ b/core/java/com/android/internal/app/NavItemSelectedListener.java
@@ -0,0 +1,46 @@
+/*
+ * 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.internal.app;
+
+import android.app.ActionBar;
+import android.view.View;
+import android.widget.AdapterView;
+
+/**
+ * Wrapper to adapt the ActionBar.OnNavigationListener in an AdapterView.OnItemSelectedListener
+ * for use in Spinner widgets. Used by action bar implementations.
+ */
+class NavItemSelectedListener implements AdapterView.OnItemSelectedListener {
+    private final ActionBar.OnNavigationListener mListener;
+
+    public NavItemSelectedListener(ActionBar.OnNavigationListener listener) {
+        mListener = listener;
+    }
+
+    @Override
+    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+        if (mListener != null) {
+            mListener.onNavigationItemSelected(position, id);
+        }
+    }
+
+    @Override
+    public void onNothingSelected(AdapterView<?> parent) {
+        // Do nothing
+    }
+}
diff --git a/core/java/com/android/internal/app/ToolbarActionBar.java b/core/java/com/android/internal/app/ToolbarActionBar.java
index 6056bf2..e8a3f0a 100644
--- a/core/java/com/android/internal/app/ToolbarActionBar.java
+++ b/core/java/com/android/internal/app/ToolbarActionBar.java
@@ -173,14 +173,19 @@
 
     @Override
     public void setListNavigationCallbacks(SpinnerAdapter adapter, OnNavigationListener callback) {
-        throw new UnsupportedOperationException(
-                "Navigation modes are not supported in toolbar action bars");
+        mDecorToolbar.setDropdownParams(adapter, new NavItemSelectedListener(callback));
     }
 
     @Override
     public void setSelectedNavigationItem(int position) {
-        throw new UnsupportedOperationException(
-                "Navigation modes are not supported in toolbar action bars");
+        switch (mDecorToolbar.getNavigationMode()) {
+            case NAVIGATION_MODE_LIST:
+                mDecorToolbar.setDropdownSelectedPosition(position);
+                break;
+            default:
+                throw new IllegalStateException(
+                        "setSelectedNavigationIndex not valid for current navigation mode");
+        }
     }
 
     @Override
@@ -276,8 +281,10 @@
 
     @Override
     public void setNavigationMode(@NavigationMode int mode) {
-        throw new UnsupportedOperationException(
-                "Navigation modes are not supported in toolbar action bars");
+        if (mode == ActionBar.NAVIGATION_MODE_TABS) {
+            throw new IllegalArgumentException("Tabs not supported in this configuration");
+        }
+        mDecorToolbar.setNavigationMode(mode);
     }
 
     @Override
@@ -288,67 +295,67 @@
     @Override
     public Tab newTab() {
         throw new UnsupportedOperationException(
-                "Navigation modes are not supported in toolbar action bars");
+                "Tabs are not supported in toolbar action bars");
     }
 
     @Override
     public void addTab(Tab tab) {
         throw new UnsupportedOperationException(
-                "Navigation modes are not supported in toolbar action bars");
+                "Tabs are not supported in toolbar action bars");
     }
 
     @Override
     public void addTab(Tab tab, boolean setSelected) {
         throw new UnsupportedOperationException(
-                "Navigation modes are not supported in toolbar action bars");
+                "Tabs are not supported in toolbar action bars");
     }
 
     @Override
     public void addTab(Tab tab, int position) {
         throw new UnsupportedOperationException(
-                "Navigation modes are not supported in toolbar action bars");
+                "Tabs are not supported in toolbar action bars");
     }
 
     @Override
     public void addTab(Tab tab, int position, boolean setSelected) {
         throw new UnsupportedOperationException(
-                "Navigation modes are not supported in toolbar action bars");
+                "Tabs are not supported in toolbar action bars");
     }
 
     @Override
     public void removeTab(Tab tab) {
         throw new UnsupportedOperationException(
-                "Navigation modes are not supported in toolbar action bars");
+                "Tabs are not supported in toolbar action bars");
     }
 
     @Override
     public void removeTabAt(int position) {
         throw new UnsupportedOperationException(
-                "Navigation modes are not supported in toolbar action bars");
+                "Tabs are not supported in toolbar action bars");
     }
 
     @Override
     public void removeAllTabs() {
         throw new UnsupportedOperationException(
-                "Navigation modes are not supported in toolbar action bars");
+                "Tabs are not supported in toolbar action bars");
     }
 
     @Override
     public void selectTab(Tab tab) {
         throw new UnsupportedOperationException(
-                "Navigation modes are not supported in toolbar action bars");
+                "Tabs are not supported in toolbar action bars");
     }
 
     @Override
     public Tab getSelectedTab() {
         throw new UnsupportedOperationException(
-                "Navigation modes are not supported in toolbar action bars");
+                "Tabs are not supported in toolbar action bars");
     }
 
     @Override
     public Tab getTabAt(int index) {
         throw new UnsupportedOperationException(
-                "Navigation modes are not supported in toolbar action bars");
+                "Tabs are not supported in toolbar action bars");
     }
 
     @Override
diff --git a/core/java/com/android/internal/app/WindowDecorActionBar.java b/core/java/com/android/internal/app/WindowDecorActionBar.java
index c0b5b97..87a80ac 100644
--- a/core/java/com/android/internal/app/WindowDecorActionBar.java
+++ b/core/java/com/android/internal/app/WindowDecorActionBar.java
@@ -18,9 +18,7 @@
 
 import android.animation.ValueAnimator;
 import android.content.res.TypedArray;
-import android.view.ViewGroup;
 import android.view.ViewParent;
-import android.widget.AdapterView;
 import android.widget.Toolbar;
 import com.android.internal.R;
 import com.android.internal.view.ActionBarPolicy;
@@ -30,7 +28,6 @@
 import com.android.internal.widget.ActionBarContainer;
 import com.android.internal.widget.ActionBarContextView;
 import com.android.internal.widget.ActionBarOverlayLayout;
-import com.android.internal.widget.ActionBarView;
 import com.android.internal.widget.DecorToolbar;
 import com.android.internal.widget.ScrollingTabContainerView;
 
@@ -59,7 +56,6 @@
 import android.view.accessibility.AccessibilityEvent;
 import android.view.animation.AnimationUtils;
 import android.widget.SpinnerAdapter;
-import com.android.internal.widget.ToolbarWidgetWrapper;
 
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
@@ -1313,23 +1309,4 @@
         }
     }
 
-    static class NavItemSelectedListener implements AdapterView.OnItemSelectedListener {
-        private final OnNavigationListener mListener;
-
-        public NavItemSelectedListener(OnNavigationListener listener) {
-            mListener = listener;
-        }
-
-        @Override
-        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
-            if (mListener != null) {
-                mListener.onNavigationItemSelected(position, id);
-            }
-        }
-
-        @Override
-        public void onNothingSelected(AdapterView<?> parent) {
-            // Do nothing
-        }
-    }
 }
diff --git a/core/java/com/android/internal/inputmethod/InputMethodSubtypeSwitchingController.java b/core/java/com/android/internal/inputmethod/InputMethodSubtypeSwitchingController.java
index 7dbde69..fdd24a6 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodSubtypeSwitchingController.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodSubtypeSwitchingController.java
@@ -468,7 +468,7 @@
         return new InputMethodSubtypeSwitchingController(settings, context);
     }
 
-    public void onCommitTextLocked(InputMethodInfo imi, InputMethodSubtype subtype) {
+    public void onUserActionLocked(InputMethodInfo imi, InputMethodSubtype subtype) {
         if (mController == null) {
             if (DEBUG) {
                 Log.e(TAG, "mController shouldn't be null.");
diff --git a/core/java/com/android/internal/net/VpnConfig.java b/core/java/com/android/internal/net/VpnConfig.java
index 0d00f41..73d3738 100644
--- a/core/java/com/android/internal/net/VpnConfig.java
+++ b/core/java/com/android/internal/net/VpnConfig.java
@@ -17,8 +17,10 @@
 package com.android.internal.net;
 
 import android.app.PendingIntent;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.res.Resources;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.UserHandle;
@@ -45,7 +47,10 @@
 
     public static Intent getIntentForConfirmation() {
         Intent intent = new Intent();
-        intent.setClassName(DIALOGS_PACKAGE, DIALOGS_PACKAGE + ".ConfirmDialog");
+        ComponentName componentName = ComponentName.unflattenFromString(
+                Resources.getSystem().getString(
+                        com.android.internal.R.string.config_customVpnConfirmDialogComponent));
+        intent.setClassName(componentName.getPackageName(), componentName.getClassName());
         return intent;
     }
 
diff --git a/core/java/com/android/internal/os/SomeArgs.java b/core/java/com/android/internal/os/SomeArgs.java
index 7edf4cc..c977997 100644
--- a/core/java/com/android/internal/os/SomeArgs.java
+++ b/core/java/com/android/internal/os/SomeArgs.java
@@ -45,6 +45,7 @@
     public Object arg3;
     public Object arg4;
     public Object arg5;
+    public Object arg6;
     public int argi1;
     public int argi2;
     public int argi3;
@@ -95,6 +96,7 @@
         arg3 = null;
         arg4 = null;
         arg5 = null;
+        arg6 = null;
         argi1 = 0;
         argi2 = 0;
         argi3 = 0;
diff --git a/core/java/com/android/internal/util/NotificationColorUtil.java b/core/java/com/android/internal/util/NotificationColorUtil.java
index f38cbde..665055c 100644
--- a/core/java/com/android/internal/util/NotificationColorUtil.java
+++ b/core/java/com/android/internal/util/NotificationColorUtil.java
@@ -35,7 +35,7 @@
 import java.util.WeakHashMap;
 
 /**
- * Helper class to process legacy (Holo) notifications to make them look like quantum notifications.
+ * Helper class to process legacy (Holo) notifications to make them look like material notifications.
  *
  * @hide
  */
diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index 5336174..4590520 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -77,6 +77,6 @@
     boolean setInputMethodEnabled(String id, boolean enabled);
     void setAdditionalInputMethodSubtypes(String id, in InputMethodSubtype[] subtypes);
     int getInputMethodWindowVisibleHeight();
-    oneway void notifyTextCommitted();
+    oneway void notifyUserAction();
     void setCursorAnchorMonitorMode(in IBinder token, int monitorMode);
 }
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index af82778..77559c0 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -349,10 +349,7 @@
         return mIncludeTabs;
     }
 
-    public void setEmbeddedTabView(View view) {
-        setEmbeddedTabView((ScrollingTabContainerView) view);
-    }
-
+    @Override
     public void setEmbeddedTabView(ScrollingTabContainerView tabs) {
         if (mTabScrollView != null) {
             removeView(mTabScrollView);
@@ -758,6 +755,7 @@
         mNavItemSelectedListener = l;
         if (mSpinner != null) {
             mSpinner.setAdapter(adapter);
+            mSpinner.setOnItemSelectedListener(l);
         }
     }
 
diff --git a/core/java/com/android/internal/widget/DecorToolbar.java b/core/java/com/android/internal/widget/DecorToolbar.java
index ee6988e..5281045 100644
--- a/core/java/com/android/internal/widget/DecorToolbar.java
+++ b/core/java/com/android/internal/widget/DecorToolbar.java
@@ -71,7 +71,7 @@
 
     int getDisplayOptions();
     void setDisplayOptions(int opts);
-    void setEmbeddedTabView(View tabView);
+    void setEmbeddedTabView(ScrollingTabContainerView tabView);
     boolean hasEmbeddedTabs();
     boolean isTitleTruncated();
     void setCollapsible(boolean collapsible);
diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java
index d841d53..60e649b 100644
--- a/core/java/com/android/internal/widget/LockPatternView.java
+++ b/core/java/com/android/internal/widget/LockPatternView.java
@@ -22,17 +22,18 @@
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.Canvas;
-import android.graphics.Color;
+import android.graphics.ColorFilter;
 import android.graphics.Matrix;
 import android.graphics.Paint;
 import android.graphics.Path;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
 import android.graphics.Rect;
 import android.os.Debug;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.SystemClock;
 import android.util.AttributeSet;
-import android.util.TypedValue;
 import android.view.HapticFeedbackConstants;
 import android.view.MotionEvent;
 import android.view.View;
@@ -110,14 +111,11 @@
     private float mSquareWidth;
     private float mSquareHeight;
 
-    private Bitmap mBitmapBtnDefault;
-    private Bitmap mBitmapBtnTouched;
-    private Bitmap mBitmapCircleDefault;
-    private Bitmap mBitmapCircleGreen;
-    private Bitmap mBitmapCircleRed;
-
-    private Bitmap mBitmapArrowGreenUp;
-    private Bitmap mBitmapArrowRedUp;
+    private final Bitmap mBitmapBtnDefault;
+    private final Bitmap mBitmapBtnTouched;
+    private final Bitmap mBitmapCircleDefault;
+    private final Bitmap mBitmapCircleAlpha;
+    private final Bitmap mBitmapArrowAlphaUp;
 
     private final Path mCurrentPath = new Path();
     private final Rect mInvalidate = new Rect();
@@ -129,6 +127,10 @@
     private int mAspect;
     private final Matrix mArrowMatrix = new Matrix();
     private final Matrix mCircleMatrix = new Matrix();
+    private final PorterDuffColorFilter mRegularColorFilter;
+    private final PorterDuffColorFilter mErrorColorFilter;
+    private final PorterDuffColorFilter mSuccessColorFilter;
+
 
     /**
      * Represents a cell in the 3 X 3 matrix of the unlock pattern view.
@@ -266,17 +268,22 @@
 
         setClickable(true);
 
+
         mPathPaint.setAntiAlias(true);
         mPathPaint.setDither(true);
 
-        int defaultColor = Color.WHITE;
-        TypedValue outValue = new TypedValue();
-        if (context.getTheme().resolveAttribute(android.R.attr.textColorPrimary, outValue, true)) {
-            defaultColor = context.getResources().getColor(outValue.resourceId);
-        }
+        int regularColor = getResources().getColor(R.color.lock_pattern_view_regular_color);
+        int errorColor = getResources().getColor(R.color.lock_pattern_view_error_color);
+        int successColor = getResources().getColor(R.color.lock_pattern_view_success_color);
+        regularColor = a.getColor(R.styleable.LockPatternView_regularColor, regularColor);
+        errorColor = a.getColor(R.styleable.LockPatternView_errorColor, errorColor);
+        successColor = a.getColor(R.styleable.LockPatternView_successColor, successColor);
+        mRegularColorFilter = new PorterDuffColorFilter(regularColor, PorterDuff.Mode.SRC_ATOP);
+        mErrorColorFilter = new PorterDuffColorFilter(errorColor, PorterDuff.Mode.SRC_ATOP);
+        mSuccessColorFilter = new PorterDuffColorFilter(successColor, PorterDuff.Mode.SRC_ATOP);
 
-        final int color = a.getColor(R.styleable.LockPatternView_pathColor, defaultColor);
-        mPathPaint.setColor(color);
+        int pathColor = a.getColor(R.styleable.LockPatternView_pathColor, regularColor);
+        mPathPaint.setColor(pathColor);
 
         mPathPaint.setAlpha(mStrokeAlpha);
         mPathPaint.setStyle(Paint.Style.STROKE);
@@ -284,25 +291,26 @@
         mPathPaint.setStrokeCap(Paint.Cap.ROUND);
 
         // lot's of bitmaps!
-        // TODO: those bitmaps are hardcoded to the Holo Theme which should not be the case!
-        mBitmapBtnDefault = getBitmapFor(R.drawable.btn_code_lock_default_holo);
-        mBitmapBtnTouched = getBitmapFor(R.drawable.btn_code_lock_touched_holo);
-        mBitmapCircleDefault = getBitmapFor(R.drawable.indicator_code_lock_point_area_default_holo);
-        mBitmapCircleGreen = getBitmapFor(R.drawable.indicator_code_lock_point_area_green_holo);
-        mBitmapCircleRed = getBitmapFor(R.drawable.indicator_code_lock_point_area_red_holo);
-
-        mBitmapArrowGreenUp = getBitmapFor(R.drawable.indicator_code_lock_drag_direction_green_up);
-        mBitmapArrowRedUp = getBitmapFor(R.drawable.indicator_code_lock_drag_direction_red_up);
+        // TODO: those bitmaps are hardcoded to the Material Theme which should not be the case!
+        mBitmapBtnDefault = getBitmapFor(R.drawable.btn_code_lock_default_mtrl_alpha);
+        mBitmapBtnTouched = getBitmapFor(R.drawable.btn_code_lock_touched_mtrl_alpha);
+        mBitmapCircleDefault = getBitmapFor(
+                R.drawable.indicator_code_lock_point_area_default_mtrl_alpha);
+        mBitmapCircleAlpha = getBitmapFor(R.drawable.indicator_code_lock_point_area_mtrl_alpha);
+        mBitmapArrowAlphaUp = getBitmapFor(
+                R.drawable.indicator_code_lock_drag_direction_up_mtrl_alpha);
 
         // bitmaps have the size of the largest bitmap in this group
         final Bitmap bitmaps[] = { mBitmapBtnDefault, mBitmapBtnTouched, mBitmapCircleDefault,
-                mBitmapCircleGreen, mBitmapCircleRed };
+                mBitmapCircleAlpha};
 
         for (Bitmap bitmap : bitmaps) {
             mBitmapWidth = Math.max(mBitmapWidth, bitmap.getWidth());
             mBitmapHeight = Math.max(mBitmapHeight, bitmap.getHeight());
         }
 
+        mPaint.setAntiAlias(true);
+        mPaint.setDither(true);
         mPaint.setFilterBitmap(true);
 
         mCellStates = new CellState[3][3];
@@ -963,7 +971,12 @@
     }
 
     private void drawArrow(Canvas canvas, float leftX, float topY, Cell start, Cell end) {
-        boolean green = mPatternDisplayMode != DisplayMode.Wrong;
+        if (mPatternInProgress) {
+            mPaint.setColorFilter(mRegularColorFilter);
+        } else {
+            boolean success = mPatternDisplayMode != DisplayMode.Wrong;
+            mPaint.setColorFilter(success ? mSuccessColorFilter : mErrorColorFilter);
+        }
 
         final int endRow = end.row;
         final int startRow = start.row;
@@ -977,7 +990,6 @@
         // compute transform to place arrow bitmaps at correct angle inside circle.
         // This assumes that the arrow image is drawn at 12:00 with it's top edge
         // coincident with the circle bitmap's top edge.
-        Bitmap arrow = green ? mBitmapArrowGreenUp : mBitmapArrowRedUp;
         final int cellWidth = mBitmapWidth;
         final int cellHeight = mBitmapHeight;
 
@@ -994,8 +1006,8 @@
         mArrowMatrix.preScale(sx, sy);
         mArrowMatrix.preTranslate(-mBitmapWidth/2, -mBitmapHeight/2);
         mArrowMatrix.preRotate(angle, cellWidth / 2.0f, cellHeight / 2.0f);  // rotate about cell center
-        mArrowMatrix.preTranslate((cellWidth - arrow.getWidth()) / 2.0f, 0.0f); // translate to 12:00 pos
-        canvas.drawBitmap(arrow, mArrowMatrix, mPaint);
+        mArrowMatrix.preTranslate((cellWidth - mBitmapArrowAlphaUp.getWidth()) / 2.0f, 0.0f); // translate to 12:00 pos
+        canvas.drawBitmap(mBitmapArrowAlphaUp, mArrowMatrix, mPaint);
     }
 
     /**
@@ -1008,24 +1020,28 @@
             boolean partOfPattern) {
         Bitmap outerCircle;
         Bitmap innerCircle;
-
+        ColorFilter outerFilter;
         if (!partOfPattern || mInStealthMode) {
             // unselected circle
             outerCircle = mBitmapCircleDefault;
             innerCircle = mBitmapBtnDefault;
+            outerFilter = mRegularColorFilter;
         } else if (mPatternInProgress) {
             // user is in middle of drawing a pattern
-            outerCircle = mBitmapCircleGreen;
+            outerCircle = mBitmapCircleAlpha;
             innerCircle = mBitmapBtnTouched;
+            outerFilter = mRegularColorFilter;
         } else if (mPatternDisplayMode == DisplayMode.Wrong) {
             // the pattern is wrong
-            outerCircle = mBitmapCircleRed;
+            outerCircle = mBitmapCircleAlpha;
             innerCircle = mBitmapBtnDefault;
+            outerFilter = mErrorColorFilter;
         } else if (mPatternDisplayMode == DisplayMode.Correct ||
                 mPatternDisplayMode == DisplayMode.Animate) {
             // the pattern is correct
-            outerCircle = mBitmapCircleGreen;
+            outerCircle = mBitmapCircleAlpha;
             innerCircle = mBitmapBtnDefault;
+            outerFilter = mSuccessColorFilter;
         } else {
             throw new IllegalStateException("unknown display mode " + mPatternDisplayMode);
         }
@@ -1048,7 +1064,9 @@
         mCircleMatrix.preScale(sx * scale, sy * scale);
         mCircleMatrix.preTranslate(-mBitmapWidth/2, -mBitmapHeight/2);
 
+        mPaint.setColorFilter(outerFilter);
         canvas.drawBitmap(outerCircle, mCircleMatrix, mPaint);
+        mPaint.setColorFilter(mRegularColorFilter);
         canvas.drawBitmap(innerCircle, mCircleMatrix, mPaint);
     }
 
diff --git a/core/java/com/android/internal/widget/SubtitleView.java b/core/java/com/android/internal/widget/SubtitleView.java
index 117463a..2f987e9 100644
--- a/core/java/com/android/internal/widget/SubtitleView.java
+++ b/core/java/com/android/internal/widget/SubtitleView.java
@@ -271,10 +271,13 @@
             style = CaptionStyle.PRESETS[styleId];
         }
 
-        mForegroundColor = style.foregroundColor;
-        mBackgroundColor = style.backgroundColor;
-        mEdgeType = style.edgeType;
-        mEdgeColor = style.edgeColor;
+        final CaptionStyle defStyle = CaptionStyle.DEFAULT;
+        mForegroundColor = style.hasForegroundColor() ?
+                style.foregroundColor : defStyle.foregroundColor;
+        mBackgroundColor = style.hasBackgroundColor() ?
+                style.backgroundColor : defStyle.backgroundColor;
+        mEdgeType = style.hasEdgeType() ? style.edgeType : defStyle.edgeType;
+        mEdgeColor = style.hasEdgeColor() ? style.edgeColor : defStyle.edgeColor;
         mHasMeasurements = false;
 
         final Typeface typeface = style.getTypeface();
diff --git a/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java b/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java
index 3e15c32..b298d85 100644
--- a/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java
+++ b/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java
@@ -27,6 +27,7 @@
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.SparseArray;
+import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.View;
@@ -78,6 +79,8 @@
     private boolean mMenuPrepared;
     private ActionMenuPresenter mActionMenuPresenter;
 
+    private int mNavigationMode = ActionBar.NAVIGATION_MODE_STANDARD;
+
     public ToolbarWidgetWrapper(Toolbar toolbar) {
         mToolbar = toolbar;
 
@@ -394,8 +397,19 @@
     }
 
     @Override
-    public void setEmbeddedTabView(View tabView) {
+    public void setEmbeddedTabView(ScrollingTabContainerView tabView) {
+        if (mTabView != null && mTabView.getParent() == mToolbar) {
+            mToolbar.removeView(mTabView);
+        }
         mTabView = tabView;
+        if (tabView != null && mNavigationMode == ActionBar.NAVIGATION_MODE_TABS) {
+            mToolbar.addView(mTabView, 0);
+            Toolbar.LayoutParams lp = (Toolbar.LayoutParams) mTabView.getLayoutParams();
+            lp.width = ViewGroup.LayoutParams.WRAP_CONTENT;
+            lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+            lp.gravity = Gravity.START | Gravity.BOTTOM;
+            tabView.setAllowCollapse(true);
+        }
     }
 
     @Override
@@ -420,23 +434,63 @@
 
     @Override
     public int getNavigationMode() {
-        return 0;
+        return mNavigationMode;
     }
 
     @Override
     public void setNavigationMode(int mode) {
-        if (mode != ActionBar.NAVIGATION_MODE_STANDARD) {
-            throw new IllegalArgumentException(
-                    "Navigation modes not supported in this configuration");
+        final int oldMode = mNavigationMode;
+        if (mode != oldMode) {
+            switch (oldMode) {
+                case ActionBar.NAVIGATION_MODE_LIST:
+                    if (mSpinner != null && mSpinner.getParent() == mToolbar) {
+                        mToolbar.removeView(mSpinner);
+                    }
+                    break;
+                case ActionBar.NAVIGATION_MODE_TABS:
+                    if (mTabView != null && mTabView.getParent() == mToolbar) {
+                        mToolbar.removeView(mTabView);
+                    }
+                    break;
+            }
+
+            mNavigationMode = mode;
+
+            switch (mode) {
+                case ActionBar.NAVIGATION_MODE_STANDARD:
+                    break;
+                case ActionBar.NAVIGATION_MODE_LIST:
+                    ensureSpinner();
+                    mToolbar.addView(mSpinner, 0);
+                    break;
+                case ActionBar.NAVIGATION_MODE_TABS:
+                    if (mTabView != null) {
+                        mToolbar.addView(mTabView, 0);
+                        Toolbar.LayoutParams lp = (Toolbar.LayoutParams) mTabView.getLayoutParams();
+                        lp.width = ViewGroup.LayoutParams.WRAP_CONTENT;
+                        lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+                        lp.gravity = Gravity.START | Gravity.BOTTOM;
+                    }
+                    break;
+                default:
+                    throw new IllegalArgumentException("Invalid navigation mode " + mode);
+            }
+        }
+    }
+
+    private void ensureSpinner() {
+        if (mSpinner == null) {
+            mSpinner = new Spinner(getContext());
+            Toolbar.LayoutParams lp = new Toolbar.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
+                    ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.START | Gravity.CENTER_VERTICAL);
+            mSpinner.setLayoutParams(lp);
         }
     }
 
     @Override
     public void setDropdownParams(SpinnerAdapter adapter,
             AdapterView.OnItemSelectedListener listener) {
-        if (mSpinner == null) {
-            mSpinner = new Spinner(getContext());
-        }
+        ensureSpinner();
         mSpinner.setAdapter(adapter);
         mSpinner.setOnItemSelectedListener(listener);
     }
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index a1cd7f7..de46804 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -140,6 +140,7 @@
 	android_hardware_camera2_DngCreator.cpp \
 	android_hardware_SensorManager.cpp \
 	android_hardware_SerialPort.cpp \
+	android_hardware_SoundTrigger.cpp \
 	android_hardware_UsbDevice.cpp \
 	android_hardware_UsbDeviceConnection.cpp \
 	android_hardware_UsbRequest.cpp \
@@ -235,6 +236,7 @@
 	libpdfium \
 	libimg_utils \
 	libnetd_client \
+	libsoundtrigger
 
 ifeq ($(USE_OPENGL_RENDERER),true)
 	LOCAL_SHARED_LIBRARIES += libhwui
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index e0c5e96..9383f4e 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -29,7 +29,6 @@
 
 #include <SkGraphics.h>
 #include <SkImageDecoder.h>
-#include <SkImageRef_GlobalPool.h>
 
 #include "jni.h"
 #include "JNIHelp.h"
@@ -83,6 +82,7 @@
 extern int register_android_hardware_camera2_DngCreator(JNIEnv *env);
 extern int register_android_hardware_SensorManager(JNIEnv *env);
 extern int register_android_hardware_SerialPort(JNIEnv *env);
+extern int register_android_hardware_SoundTrigger(JNIEnv *env);
 extern int register_android_hardware_UsbDevice(JNIEnv *env);
 extern int register_android_hardware_UsbDeviceConnection(JNIEnv *env);
 extern int register_android_hardware_UsbRequest(JNIEnv *env);
@@ -247,11 +247,6 @@
     // this sets our preference for 16bit images during decode
     // in case the src is opaque and 24bit
     SkImageDecoder::SetDeviceConfig(SkBitmap::kRGB_565_Config);
-    // This cache is shared between browser native images, and java "purgeable"
-    // bitmaps. This globalpool is for images that do not either use the java
-    // heap, or are not backed by ashmem. See BitmapFactory.cpp for the key
-    // java call site.
-    SkImageRef_GlobalPool::SetRAMBudget(512 * 1024);
     // There is also a global font cache, but its budget is specified in code
     // see SkFontHost_android.cpp
 
@@ -498,6 +493,8 @@
     char profile_duration[sizeof("-Xprofile-duration:") + PROPERTY_VALUE_MAX];
     char profile_interval[sizeof("-Xprofile-interval:") + PROPERTY_VALUE_MAX];
     char profile_backoff[sizeof("-Xprofile-backoff:") + PROPERTY_VALUE_MAX];
+    char profile_top_k_threshold[sizeof("-Xprofile-top-k-threshold") + PROPERTY_VALUE_MAX];
+    char profile_top_k_change_threshold[sizeof("-Xprofile-top-k-change-threshold") + PROPERTY_VALUE_MAX];
     char langOption[sizeof("-Duser.language=") + 3];
     char regionOption[sizeof("-Duser.region=") + 3];
     char lockProfThresholdBuf[sizeof("-Xlockprofthreshold:") + sizeof(propBuf)];
@@ -821,31 +818,63 @@
      * Set profiler options
      */
     if (libart) {
-      // Number of seconds during profile runs.
-      strcpy(profile_period, "-Xprofile-period:");
-      property_get("dalvik.vm.profile.period_secs", profile_period+17, "10");
-      opt.optionString = profile_period;
-      mOptions.add(opt);
+        // Number of seconds during profile runs.
+        property_get("dalvik.vm.profiler", propBuf, "0");
+        if (propBuf[0] == '1') {
+            opt.optionString = "-Xenable-profiler";
+            mOptions.add(opt);
+        }
 
-      // Length of each profile run (seconds).
-      strcpy(profile_duration, "-Xprofile-duration:");
-      property_get("dalvik.vm.profile.duration_secs", profile_duration+19, "30");
-      opt.optionString = profile_duration;
-      mOptions.add(opt);
+        property_get("dalvik.vm.profile.start-immediately", propBuf, "0");
+        if (propBuf[0] == '1') {
+            opt.optionString = "-Xprofile-start-immediately";
+            mOptions.add(opt);
+        }
 
+        // Number of seconds during profile runs.
+        strcpy(profile_period, "-Xprofile-period:");
+        if (property_get("dalvik.vm.profile.period-secs", profile_period+17, NULL) > 0) {
+           opt.optionString = profile_period;
+           mOptions.add(opt);
+        }
 
-      // Polling interval during profile run (microseconds).
-      strcpy(profile_interval, "-Xprofile-interval:");
-      property_get("dalvik.vm.profile.interval_us", profile_interval+19, "10000");
-      opt.optionString = profile_interval;
-      mOptions.add(opt);
+        // Length of each profile run (seconds).
+        strcpy(profile_duration, "-Xprofile-duration:");
+        if (property_get("dalvik.vm.profile.duration-secs", profile_duration+19, NULL) > 0) {
+            opt.optionString = profile_duration;
+            mOptions.add(opt);
+        }
 
-      // Coefficient for period backoff.  The the period is multiplied
-      // by this value after each profile run.
-      strcpy(profile_backoff, "-Xprofile-backoff:");
-      property_get("dalvik.vm.profile.backoff_coeff", profile_backoff+18, "2.0");
-      opt.optionString = profile_backoff;
-      mOptions.add(opt);
+        // Polling interval during profile run (microseconds).
+        strcpy(profile_interval, "-Xprofile-interval:");
+        if (property_get("dalvik.vm.profile.interval-us", profile_interval+19, NULL) > 0) {
+            opt.optionString = profile_interval;
+            mOptions.add(opt);
+        }
+
+        // Coefficient for period backoff.  The the period is multiplied
+        // by this value after each profile run.
+        strcpy(profile_backoff, "-Xprofile-backoff:");
+        if (property_get("dalvik.vm.profile.backoff-coeff", profile_backoff+18, NULL) > 0) {
+            opt.optionString = profile_backoff;
+            mOptions.add(opt);
+        }
+
+        // Top K% of samples that are considered relevant when deciding if the app should be recompiled.
+        strcpy(profile_top_k_threshold, "-Xprofile-top-k-threshold:");
+        if (property_get("dalvik.vm.profile.top-k-thr", profile_top_k_threshold+26, NULL) > 0) {
+            opt.optionString = profile_top_k_threshold;
+            mOptions.add(opt);
+        }
+
+        // The threshold after which a change in the structure of the top K% profiled samples becomes significant
+        // and triggers recompilation. A change in profile is considered significant if X% (top-k-change-threshold)
+        // of the top K% (top-k-threshold property) samples has changed.
+        strcpy(profile_top_k_change_threshold, "-Xprofile-top-k-change-threshold:");
+        if (property_get("dalvik.vm.profile.top-k-ch-thr", profile_top_k_change_threshold+33, NULL) > 0) {
+            opt.optionString = profile_top_k_change_threshold;
+            mOptions.add(opt);
+        }
     }
 
     initArgs.version = JNI_VERSION_1_4;
@@ -1288,6 +1317,7 @@
     REG_JNI(register_android_hardware_camera2_DngCreator),
     REG_JNI(register_android_hardware_SensorManager),
     REG_JNI(register_android_hardware_SerialPort),
+    REG_JNI(register_android_hardware_SoundTrigger),
     REG_JNI(register_android_hardware_UsbDevice),
     REG_JNI(register_android_hardware_UsbDeviceConnection),
     REG_JNI(register_android_hardware_UsbRequest),
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index 928a7f8..5106f0d 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -2,11 +2,8 @@
 
 #include "BitmapFactory.h"
 #include "NinePatchPeeker.h"
-#include "SkData.h"
 #include "SkFrontBufferedStream.h"
 #include "SkImageDecoder.h"
-#include "SkImageRef_ashmem.h"
-#include "SkImageRef_GlobalPool.h"
 #include "SkMath.h"
 #include "SkPixelRef.h"
 #include "SkStream.h"
@@ -32,8 +29,6 @@
 jfieldID gOptions_premultipliedFieldID;
 jfieldID gOptions_mutableFieldID;
 jfieldID gOptions_ditherFieldID;
-jfieldID gOptions_purgeableFieldID;
-jfieldID gOptions_shareableFieldID;
 jfieldID gOptions_preferQualityOverSpeedFieldID;
 jfieldID gOptions_scaledFieldID;
 jfieldID gOptions_densityFieldID;
@@ -90,14 +85,6 @@
     return jstr;
 }
 
-static bool optionsPurgeable(JNIEnv* env, jobject options) {
-    return options != NULL && env->GetBooleanField(options, gOptions_purgeableFieldID);
-}
-
-static bool optionsShareable(JNIEnv* env, jobject options) {
-    return options != NULL && env->GetBooleanField(options, gOptions_shareableFieldID);
-}
-
 static bool optionsJustBounds(JNIEnv* env, jobject options) {
     return options != NULL && env->GetBooleanField(options, gOptions_justBoundsFieldID);
 }
@@ -125,27 +112,6 @@
     }
 }
 
-static SkPixelRef* installPixelRef(SkBitmap* bitmap, SkStreamRewindable* stream,
-        int sampleSize, bool ditherImage) {
-
-    if (kUnknown_SkColorType == bitmap->colorType()) {
-        ALOGW("bitmap has unknown configuration so no memory has been allocated");
-        return NULL;
-    }
-
-    SkImageRef* pr;
-    // only use ashmem for large images, since mmaps come at a price
-    if (bitmap->getSize() >= 32 * 1024) {
-        pr = new SkImageRef_ashmem(bitmap->info(), stream, sampleSize);
-    } else {
-        pr = new SkImageRef_GlobalPool(bitmap->info(), stream, sampleSize);
-    }
-    pr->setDitherImage(ditherImage);
-    bitmap->setPixelRef(pr)->unref();
-    pr->isOpaque(bitmap);
-    return pr;
-}
-
 static SkColorType colorTypeForScaledOutput(SkColorType colorType) {
     switch (colorType) {
         case kUnknown_SkColorType:
@@ -229,21 +195,17 @@
     const unsigned int mSize;
 };
 
-// since we "may" create a purgeable imageref, we require the stream be ref'able
-// i.e. dynamically allocated, since its lifetime may exceed the current stack
-// frame.
 static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding,
-        jobject options, bool allowPurgeable, bool forcePurgeable = false) {
+        jobject options) {
 
     int sampleSize = 1;
 
-    SkImageDecoder::Mode mode = SkImageDecoder::kDecodePixels_Mode;
+    SkImageDecoder::Mode decodeMode = SkImageDecoder::kDecodePixels_Mode;
     SkBitmap::Config prefConfig = SkBitmap::kARGB_8888_Config;
 
     bool doDither = true;
     bool isMutable = false;
     float scale = 1.0f;
-    bool isPurgeable = forcePurgeable || (allowPurgeable && optionsPurgeable(env, options));
     bool preferQualityOverSpeed = false;
     bool requireUnpremultiplied = false;
 
@@ -252,7 +214,7 @@
     if (options != NULL) {
         sampleSize = env->GetIntField(options, gOptions_sampleSizeFieldID);
         if (optionsJustBounds(env, options)) {
-            mode = SkImageDecoder::kDecodeBounds_Mode;
+            decodeMode = SkImageDecoder::kDecodeBounds_Mode;
         }
 
         // initialize these, in case we fail later on
@@ -280,7 +242,6 @@
     }
 
     const bool willScale = scale != 1.0f;
-    isPurgeable &= !willScale;
 
     SkImageDecoder* decoder = SkImageDecoder::Factory(stream);
     if (decoder == NULL) {
@@ -311,8 +272,6 @@
     NinePatchPeeker peeker(decoder);
     decoder->setPeeker(&peeker);
 
-    SkImageDecoder::Mode decodeMode = isPurgeable ? SkImageDecoder::kDecodeBounds_Mode : mode;
-
     JavaPixelAllocator javaAllocator(env);
     RecyclingPixelAllocator recyclingAllocator(outputBitmap->pixelRef(), existingBufferSize);
     ScaleCheckingAllocator scaleCheckingAllocator(scale, existingBufferSize);
@@ -353,7 +312,7 @@
     int scaledWidth = decodingBitmap.width();
     int scaledHeight = decodingBitmap.height();
 
-    if (willScale && mode != SkImageDecoder::kDecodeBounds_Mode) {
+    if (willScale && decodeMode != SkImageDecoder::kDecodeBounds_Mode) {
         scaledWidth = int(scaledWidth * scale + 0.5f);
         scaledHeight = int(scaledHeight * scale + 0.5f);
     }
@@ -367,7 +326,7 @@
     }
 
     // if we're in justBounds mode, return now (skip the java bitmap)
-    if (mode == SkImageDecoder::kDecodeBounds_Mode) {
+    if (decodeMode == SkImageDecoder::kDecodeBounds_Mode) {
         return NULL;
     }
 
@@ -459,21 +418,15 @@
         }
     }
 
-    SkPixelRef* pr;
-    if (isPurgeable) {
-        pr = installPixelRef(outputBitmap, stream, sampleSize, doDither);
-    } else {
-        // if we get here, we're in kDecodePixels_Mode and will therefore
-        // already have a pixelref installed.
-        pr = outputBitmap->pixelRef();
-    }
-    if (pr == NULL) {
+    // if we get here, we're in kDecodePixels_Mode and will therefore
+    // already have a pixelref installed.
+    if (outputBitmap->pixelRef() == NULL) {
         return nullObjectReturn("Got null SkPixelRef");
     }
 
     if (!isMutable && javaBitmap == NULL) {
         // promise we will never change our pixels (great for sharing and pictures)
-        pr->setImmutable();
+        outputBitmap->setImmutable();
     }
 
     // detach bitmap from its autodeleter, since we want to own it now
@@ -512,8 +465,7 @@
         SkAutoTUnref<SkStreamRewindable> bufferedStream(
                 SkFrontBufferedStream::Create(stream, BYTES_TO_BUFFER));
         SkASSERT(bufferedStream.get() != NULL);
-        // for now we don't allow purgeable with java inputstreams
-        bitmap = doDecode(env, bufferedStream, padding, options, false, false);
+        bitmap = doDecode(env, bufferedStream, padding, options);
     }
     return bitmap;
 }
@@ -542,76 +494,33 @@
     SkAutoTUnref<SkFILEStream> fileStream(new SkFILEStream(file,
                          SkFILEStream::kCallerRetains_Ownership));
 
-    SkAutoTUnref<SkStreamRewindable> stream;
+    // Use a buffered stream. Although an SkFILEStream can be rewound, this
+    // ensures that SkImageDecoder::Factory never rewinds beyond the
+    // current position of the file descriptor.
+    SkAutoTUnref<SkStreamRewindable> stream(SkFrontBufferedStream::Create(fileStream,
+            BYTES_TO_BUFFER));
 
-    // Retain the old behavior of allowing purgeable if both purgeable and
-    // shareable are set to true.
-    bool isPurgeable = optionsPurgeable(env, bitmapFactoryOptions)
-                       && optionsShareable(env, bitmapFactoryOptions);
-    if (isPurgeable) {
-        // Copy the stream, so the image can be decoded multiple times without
-        // continuing to modify the original file descriptor.
-        // Copy beginning from the current position.
-        const size_t fileSize = fileStream->getLength() - fileStream->getPosition();
-        void* buffer = sk_malloc_flags(fileSize, 0);
-        if (buffer == NULL) {
-            return nullObjectReturn("Could not make a copy for ashmem");
-        }
-
-        SkAutoTUnref<SkData> data(SkData::NewFromMalloc(buffer, fileSize));
-
-        if (fileStream->read(buffer, fileSize) != fileSize) {
-            return nullObjectReturn("Could not read the file.");
-        }
-
-        stream.reset(new SkMemoryStream(data));
-    } else {
-        // Use a buffered stream. Although an SkFILEStream can be rewound, this
-        // ensures that SkImageDecoder::Factory never rewinds beyond the
-        // current position of the file descriptor.
-        stream.reset(SkFrontBufferedStream::Create(fileStream, BYTES_TO_BUFFER));
-    }
-
-    return doDecode(env, stream, padding, bitmapFactoryOptions, isPurgeable);
+    return doDecode(env, stream, padding, bitmapFactoryOptions);
 }
 
 static jobject nativeDecodeAsset(JNIEnv* env, jobject clazz, jlong native_asset,
         jobject padding, jobject options) {
 
-    SkStreamRewindable* stream;
     Asset* asset = reinterpret_cast<Asset*>(native_asset);
-    bool forcePurgeable = optionsPurgeable(env, options);
-    if (forcePurgeable) {
-        // if we could "ref/reopen" the asset, we may not need to copy it here
-        // and we could assume optionsShareable, since assets are always RO
-        stream = CopyAssetToStream(asset);
-        if (stream == NULL) {
-            return NULL;
-        }
-    } else {
-        // since we know we'll be done with the asset when we return, we can
-        // just use a simple wrapper
-        stream = new AssetStreamAdaptor(asset,
-                                        AssetStreamAdaptor::kNo_OwnAsset,
-                                        AssetStreamAdaptor::kNo_HasMemoryBase);
-    }
-    SkAutoUnref aur(stream);
-    return doDecode(env, stream, padding, options, forcePurgeable, forcePurgeable);
+    // since we know we'll be done with the asset when we return, we can
+    // just use a simple wrapper
+    SkAutoTUnref<SkStreamRewindable> stream(new AssetStreamAdaptor(asset,
+            AssetStreamAdaptor::kNo_OwnAsset, AssetStreamAdaptor::kNo_HasMemoryBase));
+    return doDecode(env, stream, padding, options);
 }
 
 static jobject nativeDecodeByteArray(JNIEnv* env, jobject, jbyteArray byteArray,
         jint offset, jint length, jobject options) {
 
-    /*  If optionsShareable() we could decide to just wrap the java array and
-        share it, but that means adding a globalref to the java array object
-        and managing its lifetime. For now we just always copy the array's data
-        if optionsPurgeable(), unless we're just decoding bounds.
-     */
-    bool purgeable = optionsPurgeable(env, options) && !optionsJustBounds(env, options);
     AutoJavaByteArray ar(env, byteArray);
-    SkMemoryStream* stream = new SkMemoryStream(ar.ptr() + offset, length, purgeable);
+    SkMemoryStream* stream = new SkMemoryStream(ar.ptr() + offset, length, false);
     SkAutoUnref aur(stream);
-    return doDecode(env, stream, NULL, options, purgeable);
+    return doDecode(env, stream, NULL, options);
 }
 
 static void nativeRequestCancel(JNIEnv*, jobject joptions) {
@@ -675,8 +584,6 @@
     gOptions_premultipliedFieldID = getFieldIDCheck(env, options_class, "inPremultiplied", "Z");
     gOptions_mutableFieldID = getFieldIDCheck(env, options_class, "inMutable", "Z");
     gOptions_ditherFieldID = getFieldIDCheck(env, options_class, "inDither", "Z");
-    gOptions_purgeableFieldID = getFieldIDCheck(env, options_class, "inPurgeable", "Z");
-    gOptions_shareableFieldID = getFieldIDCheck(env, options_class, "inInputShareable", "Z");
     gOptions_preferQualityOverSpeedFieldID = getFieldIDCheck(env, options_class,
             "inPreferQualityOverSpeed", "Z");
     gOptions_scaledFieldID = getFieldIDCheck(env, options_class, "inScaled", "Z");
diff --git a/core/jni/android/graphics/Canvas.cpp b/core/jni/android/graphics/Canvas.cpp
index 5fca582..8b75e7d 100644
--- a/core/jni/android/graphics/Canvas.cpp
+++ b/core/jni/android/graphics/Canvas.cpp
@@ -22,7 +22,6 @@
 #include "SkDevice.h"
 #include "SkDrawFilter.h"
 #include "SkGraphics.h"
-#include "SkImageRef_GlobalPool.h"
 #include "SkPorterDuff.h"
 #include "SkShader.h"
 #include "SkTemplates.h"
@@ -161,8 +160,6 @@
     }
 
     static void freeCaches(JNIEnv* env, jobject) {
-        // these are called in no particular order
-        SkImageRef_GlobalPool::SetRAMUsed(0);
         SkGraphics::PurgeFontCache();
     }
 
@@ -170,56 +167,33 @@
         TextLayoutEngine::getInstance().purgeCaches();
     }
 
-    static jboolean isOpaque(JNIEnv* env, jobject jcanvas) {
-        NPE_CHECK_RETURN_ZERO(env, jcanvas);
-        SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas);
+    static jboolean isOpaque(JNIEnv*, jobject, jlong canvasHandle) {
+        SkCanvas* canvas = getNativeCanvas(canvasHandle);
         bool result = canvas->getDevice()->accessBitmap(false).isOpaque();
         return result ? JNI_TRUE : JNI_FALSE;
     }
 
-    static jint getWidth(JNIEnv* env, jobject jcanvas) {
-        NPE_CHECK_RETURN_ZERO(env, jcanvas);
-        SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas);
+    static jint getWidth(JNIEnv*, jobject, jlong canvasHandle) {
+        SkCanvas* canvas = getNativeCanvas(canvasHandle);
         int width = canvas->getDevice()->accessBitmap(false).width();
         return static_cast<jint>(width);
     }
 
-    static jint getHeight(JNIEnv* env, jobject jcanvas) {
-        NPE_CHECK_RETURN_ZERO(env, jcanvas);
-        SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas);
+    static jint getHeight(JNIEnv*, jobject, jlong canvasHandle) {
+        SkCanvas* canvas = getNativeCanvas(canvasHandle);
         int height = canvas->getDevice()->accessBitmap(false).height();
         return static_cast<jint>(height);
     }
 
-    static jint saveAll(JNIEnv* env, jobject jcanvas) {
-        NPE_CHECK_RETURN_ZERO(env, jcanvas);
-        int result = GraphicsJNI::getNativeCanvas(env, jcanvas)->save();
-        return static_cast<jint>(result);
-    }
-
-    static jint save(JNIEnv* env, jobject jcanvas, jint flagsHandle) {
-        SkCanvas::SaveFlags flags = static_cast<SkCanvas::SaveFlags>(flagsHandle);
-        NPE_CHECK_RETURN_ZERO(env, jcanvas);
-        int result = GraphicsJNI::getNativeCanvas(env, jcanvas)->save(flags);
-        return static_cast<jint>(result);
-    }
-
-    static jint saveLayer(JNIEnv* env, jobject, jlong canvasHandle, jobject bounds,
-                         jlong paintHandle, jint flags) {
+    static jint save(JNIEnv*, jobject, jlong canvasHandle, jint flagsHandle) {
         SkCanvas* canvas = getNativeCanvas(canvasHandle);
-        SkPaint* paint  = reinterpret_cast<SkPaint*>(paintHandle);
-        SkRect* bounds_ = NULL;
-        SkRect  storage;
-        if (bounds != NULL) {
-            GraphicsJNI::jrectf_to_rect(env, bounds, &storage);
-            bounds_ = &storage;
-        }
-        return canvas->saveLayer(bounds_, paint, static_cast<SkCanvas::SaveFlags>(flags));
+        SkCanvas::SaveFlags flags = static_cast<SkCanvas::SaveFlags>(flagsHandle);
+        return static_cast<jint>(canvas->save(flags));
     }
 
-    static jint saveLayer4F(JNIEnv* env, jobject, jlong canvasHandle,
-                           jfloat l, jfloat t, jfloat r, jfloat b,
-                           jlong paintHandle, jint flags) {
+    static jint saveLayer(JNIEnv* env, jobject, jlong canvasHandle,
+                          jfloat l, jfloat t, jfloat r, jfloat b,
+                          jlong paintHandle, jint flags) {
         SkCanvas* canvas = getNativeCanvas(canvasHandle);
         SkPaint* paint  = reinterpret_cast<SkPaint*>(paintHandle);
         SkRect bounds;
@@ -230,22 +204,8 @@
     }
 
     static jint saveLayerAlpha(JNIEnv* env, jobject, jlong canvasHandle,
-                              jobject bounds, jint alpha, jint flags) {
-        SkCanvas* canvas = getNativeCanvas(canvasHandle);
-        SkRect* bounds_ = NULL;
-        SkRect  storage;
-        if (bounds != NULL) {
-            GraphicsJNI::jrectf_to_rect(env, bounds, &storage);
-            bounds_ = &storage;
-        }
-        int result = canvas->saveLayerAlpha(bounds_, alpha,
-                                      static_cast<SkCanvas::SaveFlags>(flags));
-        return static_cast<jint>(result);
-    }
-
-    static jint saveLayerAlpha4F(JNIEnv* env, jobject, jlong canvasHandle,
-                                jfloat l, jfloat t, jfloat r, jfloat b,
-                                jint alpha, jint flags) {
+                               jfloat l, jfloat t, jfloat r, jfloat b,
+                               jint alpha, jint flags) {
         SkCanvas* canvas = getNativeCanvas(canvasHandle);
         SkRect  bounds;
         bounds.set(l, t, r, b);
@@ -254,9 +214,8 @@
         return static_cast<jint>(result);
     }
 
-    static void restore(JNIEnv* env, jobject jcanvas) {
-        NPE_CHECK_RETURN_VOID(env, jcanvas);
-        SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas);
+    static void restore(JNIEnv* env, jobject, jlong canvasHandle) {
+        SkCanvas* canvas = getNativeCanvas(canvasHandle);
         if (canvas->getSaveCount() <= 1) {  // cannot restore anymore
             doThrowISE(env, "Underflow in restore");
             return;
@@ -264,15 +223,14 @@
         canvas->restore();
     }
 
-    static jint getSaveCount(JNIEnv* env, jobject jcanvas) {
-        NPE_CHECK_RETURN_ZERO(env, jcanvas);
-        int result = GraphicsJNI::getNativeCanvas(env, jcanvas)->getSaveCount();
-        return static_cast<jint>(result);
+    static jint getSaveCount(JNIEnv*, jobject, jlong canvasHandle) {
+        SkCanvas* canvas = getNativeCanvas(canvasHandle);
+        return static_cast<jint>(canvas->getSaveCount());
     }
 
-    static void restoreToCount(JNIEnv* env, jobject jcanvas, jint restoreCount) {
-        NPE_CHECK_RETURN_VOID(env, jcanvas);
-        SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas);
+    static void restoreToCount(JNIEnv* env, jobject, jlong canvasHandle,
+                               jint restoreCount) {
+        SkCanvas* canvas = getNativeCanvas(canvasHandle);
         if (restoreCount < 1) {
             doThrowIAE(env, "Underflow in restoreToCount");
             return;
@@ -280,24 +238,24 @@
         canvas->restoreToCount(restoreCount);
     }
 
-    static void translate(JNIEnv* env, jobject jcanvas, jfloat dx, jfloat dy) {
-        NPE_CHECK_RETURN_VOID(env, jcanvas);
-        (void)GraphicsJNI::getNativeCanvas(env, jcanvas)->translate(dx, dy);
+    static void translate(JNIEnv*, jobject, jlong canvasHandle,
+                          jfloat dx, jfloat dy) {
+        getNativeCanvas(canvasHandle)->translate(dx, dy);
     }
 
-    static void scale__FF(JNIEnv* env, jobject jcanvas, jfloat sx, jfloat sy) {
-        NPE_CHECK_RETURN_VOID(env, jcanvas);
-        (void)GraphicsJNI::getNativeCanvas(env, jcanvas)->scale(sx, sy);
+    static void scale__FF(JNIEnv*, jobject, jlong canvasHandle,
+                          jfloat sx, jfloat sy) {
+        getNativeCanvas(canvasHandle)->scale(sx, sy);
     }
 
-    static void rotate__F(JNIEnv* env, jobject jcanvas, jfloat degrees) {
-        NPE_CHECK_RETURN_VOID(env, jcanvas);
-        (void)GraphicsJNI::getNativeCanvas(env, jcanvas)->rotate(degrees);
+    static void rotate__F(JNIEnv*, jobject, jlong canvasHandle,
+                          jfloat degrees) {
+        getNativeCanvas(canvasHandle)->rotate(degrees);
     }
 
-    static void skew__FF(JNIEnv* env, jobject jcanvas, jfloat sx, jfloat sy) {
-        NPE_CHECK_RETURN_VOID(env, jcanvas);
-        (void)GraphicsJNI::getNativeCanvas(env, jcanvas)->skew(sx, sy);
+    static void skew__FF(JNIEnv*, jobject, jlong canvasHandle,
+                         jfloat sx, jfloat sy) {
+        getNativeCanvas(canvasHandle)->skew(sx, sy);
     }
 
     static void concat(JNIEnv* env, jobject, jlong canvasHandle,
@@ -318,56 +276,16 @@
         }
     }
 
-    static jboolean clipRect_FFFF(JNIEnv* env, jobject jcanvas, jfloat left,
-                                  jfloat top, jfloat right, jfloat bottom) {
-        NPE_CHECK_RETURN_ZERO(env, jcanvas);
+    static jboolean clipRect(JNIEnv*, jobject, jlong canvasHandle,
+                                  jfloat left, jfloat top, jfloat right,
+                                  jfloat bottom, jint op) {
         SkRect  r;
         r.set(left, top, right, bottom);
-        SkCanvas* c = GraphicsJNI::getNativeCanvas(env, jcanvas);
-        c->clipRect(r);
+        SkCanvas* c = getNativeCanvas(canvasHandle);
+        c->clipRect(r, static_cast<SkRegion::Op>(op));
         return hasNonEmptyClip(*c);
     }
 
-    static jboolean clipRect_IIII(JNIEnv* env, jobject jcanvas, jint left,
-                                  jint top, jint right, jint bottom) {
-        NPE_CHECK_RETURN_ZERO(env, jcanvas);
-        SkRect  r;
-        r.set(SkIntToScalar(left), SkIntToScalar(top),
-              SkIntToScalar(right), SkIntToScalar(bottom));
-        SkCanvas* c = GraphicsJNI::getNativeCanvas(env, jcanvas);
-        c->clipRect(r);
-        return hasNonEmptyClip(*c);
-    }
-
-    static jboolean clipRect_RectF(JNIEnv* env, jobject jcanvas, jobject rectf) {
-        NPE_CHECK_RETURN_ZERO(env, jcanvas);
-        NPE_CHECK_RETURN_ZERO(env, rectf);
-        SkCanvas* c = GraphicsJNI::getNativeCanvas(env, jcanvas);
-        SkRect tmp;
-        c->clipRect(*GraphicsJNI::jrectf_to_rect(env, rectf, &tmp));
-        return hasNonEmptyClip(*c);
-    }
-
-    static jboolean clipRect_Rect(JNIEnv* env, jobject jcanvas, jobject rect) {
-        NPE_CHECK_RETURN_ZERO(env, jcanvas);
-        NPE_CHECK_RETURN_ZERO(env, rect);
-        SkCanvas* c = GraphicsJNI::getNativeCanvas(env, jcanvas);
-        SkRect tmp;
-        c->clipRect(*GraphicsJNI::jrect_to_rect(env, rect, &tmp));
-        return hasNonEmptyClip(*c);
-
-    }
-
-    static jboolean clipRect(JNIEnv* env, jobject, jlong canvasHandle,
-                             jfloat left, jfloat top, jfloat right, jfloat bottom,
-                             jint op) {
-        SkCanvas* canvas = getNativeCanvas(canvasHandle);
-        SkRect rect;
-        rect.set(left, top, right, bottom);
-        canvas->clipRect(rect, static_cast<SkRegion::Op>(op));
-        return hasNonEmptyClip(*canvas);
-    }
-
     static jboolean clipPath(JNIEnv* env, jobject, jlong canvasHandle,
                              jlong pathHandle, jint op) {
         SkCanvas* canvas = getNativeCanvas(canvasHandle);
@@ -380,7 +298,16 @@
                                jlong deviceRgnHandle, jint op) {
         SkCanvas* canvas = getNativeCanvas(canvasHandle);
         SkRegion* deviceRgn = reinterpret_cast<SkRegion*>(deviceRgnHandle);
-        canvas->clipRegion(*deviceRgn, static_cast<SkRegion::Op>(op));
+        SkPath rgnPath;
+        if (deviceRgn->getBoundaryPath(&rgnPath)) {
+            // The region is specified in device space.
+            SkMatrix savedMatrix = canvas->getTotalMatrix();
+            canvas->resetMatrix();
+            canvas->clipPath(rgnPath, static_cast<SkRegion::Op>(op));
+            canvas->setMatrix(savedMatrix);
+        } else {
+            canvas->clipRect(SkRect::MakeEmpty(), static_cast<SkRegion::Op>(op));
+        }
         return hasNonEmptyClip(*canvas);
     }
 
@@ -390,15 +317,6 @@
         canvas->setDrawFilter(reinterpret_cast<SkDrawFilter*>(filterHandle));
     }
 
-    static jboolean quickReject__RectF(JNIEnv* env, jobject, jlong canvasHandle,
-                                        jobject rect) {
-        SkCanvas* canvas = getNativeCanvas(canvasHandle);
-        SkRect rect_;
-        GraphicsJNI::jrectf_to_rect(env, rect, &rect_);
-        bool result = canvas->quickReject(rect_);
-        return result ? JNI_TRUE : JNI_FALSE;
-    }
-
     static jboolean quickReject__Path(JNIEnv* env, jobject, jlong canvasHandle,
                                        jlong pathHandle) {
         SkCanvas* canvas = getNativeCanvas(canvasHandle);
@@ -448,15 +366,13 @@
         canvas->drawPaint(*paint);
     }
 
-    static void doPoints(JNIEnv* env, jobject jcanvas, jfloatArray jptsArray,
-                         jint offset, jint count, jobject jpaint,
-                         jint modeHandle) {
-        NPE_CHECK_RETURN_VOID(env, jcanvas);
+    static void doPoints(JNIEnv* env, jlong canvasHandle,
+                         jfloatArray jptsArray, jint offset, jint count,
+                         jlong paintHandle, jint modeHandle) {
         NPE_CHECK_RETURN_VOID(env, jptsArray);
-        NPE_CHECK_RETURN_VOID(env, jpaint);
         SkCanvas::PointMode mode = static_cast<SkCanvas::PointMode>(modeHandle);
-        SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas);
-        const SkPaint& paint = *GraphicsJNI::getNativePaint(env, jpaint);
+        SkCanvas* canvas = getNativeCanvas(canvasHandle);
+        const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
 
         AutoJavaFloatArray autoPts(env, jptsArray);
         float* floats = autoPts.ptr();
@@ -476,29 +392,28 @@
             pts[i].set(src[0], src[1]);
             src += 2;
         }
-        canvas->drawPoints(mode, count, pts, paint);
+        canvas->drawPoints(mode, count, pts, *paint);
     }
 
-    static void drawPoints(JNIEnv* env, jobject jcanvas, jfloatArray jptsArray,
-                           jint offset, jint count, jobject jpaint) {
-        doPoints(env, jcanvas, jptsArray, offset, count, jpaint,
+    static void drawPoints(JNIEnv* env, jobject, jlong canvasHandle,
+                           jfloatArray jptsArray, jint offset,
+                           jint count, jlong paintHandle) {
+        doPoints(env, canvasHandle, jptsArray, offset, count, paintHandle,
                  SkCanvas::kPoints_PointMode);
     }
 
-    static void drawLines(JNIEnv* env, jobject jcanvas, jfloatArray jptsArray,
-                           jint offset, jint count, jobject jpaint) {
-        doPoints(env, jcanvas, jptsArray, offset, count, jpaint,
+    static void drawLines(JNIEnv* env, jobject, jlong canvasHandle,
+                          jfloatArray jptsArray, jint offset, jint count,
+                          jlong paintHandle) {
+        doPoints(env, canvasHandle, jptsArray, offset, count, paintHandle,
                  SkCanvas::kLines_PointMode);
     }
 
-    static void drawPoint(JNIEnv* env, jobject jcanvas, jfloat x, jfloat y,
-                          jobject jpaint) {
-        NPE_CHECK_RETURN_VOID(env, jcanvas);
-        NPE_CHECK_RETURN_VOID(env, jpaint);
-        SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas);
-        const SkPaint& paint = *GraphicsJNI::getNativePaint(env, jpaint);
-
-        canvas->drawPoint(x, y, paint);
+    static void drawPoint(JNIEnv*, jobject, jlong canvasHandle, jfloat x, jfloat y,
+                          jlong paintHandle) {
+        SkCanvas* canvas = getNativeCanvas(canvasHandle);
+        const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+        canvas->drawPoint(x, y, *paint);
     }
 
     static void drawLine__FFFFPaint(JNIEnv* env, jobject, jlong canvasHandle,
@@ -509,15 +424,6 @@
         canvas->drawLine(startX, startY, stopX, stopY, *paint);
     }
 
-    static void drawRect__RectFPaint(JNIEnv* env, jobject, jlong canvasHandle,
-                                     jobject rect, jlong paintHandle) {
-        SkCanvas* canvas = getNativeCanvas(canvasHandle);
-        SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
-        SkRect rect_;
-        GraphicsJNI::jrectf_to_rect(env, rect, &rect_);
-        canvas->drawRect(rect_, *paint);
-    }
-
     static void drawRect__FFFFPaint(JNIEnv* env, jobject, jlong canvasHandle,
                                     jfloat left, jfloat top, jfloat right,
                                     jfloat bottom, jlong paintHandle) {
@@ -863,32 +769,45 @@
     }
 
 #ifdef USE_MINIKIN
-    static void drawGlyphsToSkia(SkCanvas* canvas, SkPaint* paint, Layout* layout, float x, float y) {
-        size_t nGlyphs = layout->nGlyphs();
-        uint16_t *glyphs = new uint16_t[nGlyphs];
-        SkPoint *pos = new SkPoint[nGlyphs];
-        SkTypeface *lastFace = NULL;
-        SkTypeface *skFace = NULL;
-        size_t start = 0;
+    class DrawTextFunctor {
+    public:
+        DrawTextFunctor(const Layout& layout, SkCanvas* canvas, jfloat x, jfloat y, SkPaint* paint,
+                    uint16_t* glyphs, SkPoint* pos)
+                : layout(layout), canvas(canvas), x(x), y(y), paint(paint), glyphs(glyphs),
+                    pos(pos) { }
 
-        paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
-        for (size_t i = 0; i < nGlyphs; i++) {
-            MinikinFontSkia *mfs = static_cast<MinikinFontSkia *>(layout->getFont(i));
-            skFace = mfs->GetSkTypeface();
-            glyphs[i] = layout->getGlyphId(i);
-            pos[i].fX = x + layout->getX(i);
-            pos[i].fY = y + layout->getY(i);
-            if (i > 0 && skFace != lastFace) {
-                paint->setTypeface(lastFace);
-                canvas->drawPosText(glyphs + start, (i - start) << 1, pos + start, *paint);
-                start = i;
+        void operator()(SkTypeface* t, 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);
             }
-            lastFace = skFace;
+            paint->setTypeface(t);
+            canvas->drawPosText(glyphs + start, (end - start) << 1, pos + start, *paint);
         }
-        if (skFace != NULL) {
-            paint->setTypeface(skFace);
-            canvas->drawPosText(glyphs + start, (nGlyphs - start) << 1, pos + start, *paint);
-        }
+    private:
+        const Layout& layout;
+        SkCanvas* canvas;
+        jfloat x;
+        jfloat y;
+        SkPaint* paint;
+        uint16_t* glyphs;
+        SkPoint* pos;
+    };
+
+    static void drawGlyphsToSkia(SkCanvas* canvas, SkPaint* paint, const Layout& layout, float x, float y) {
+        size_t nGlyphs = layout.nGlyphs();
+        uint16_t* glyphs = new uint16_t[nGlyphs];
+        SkPoint* pos = new SkPoint[nGlyphs];
+
+        x += MinikinUtils::xOffsetForTextAlign(paint, layout);
+        SkPaint::Align align = paint->getTextAlign();
+        paint->setTextAlign(SkPaint::kLeft_Align);
+        paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+        DrawTextFunctor f(layout, canvas, x, y, paint, glyphs, pos);
+        MinikinUtils::forFontRun(layout, f);
+        doDrawTextDecorations(canvas, x, y, layout.getAdvance(), paint);
+        paint->setTextAlign(align);
         delete[] glyphs;
         delete[] pos;
     }
@@ -908,9 +827,9 @@
 
 #ifdef USE_MINIKIN
         Layout layout;
-        MinikinUtils::SetLayoutProperties(&layout, paint, flags, typeface);
-        layout.doLayout(textArray + start, count);
-        drawGlyphsToSkia(canvas, paint, &layout, x, y);
+        std::string css = MinikinUtils::setLayoutProperties(&layout, paint, flags, typeface);
+        layout.doLayout(textArray, start, count, contextCount, css);
+        drawGlyphsToSkia(canvas, paint, layout, x, y);
 #else
         sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint,
                 textArray, start, count, contextCount, flags);
@@ -1153,33 +1072,21 @@
     {"initRaster", "(J)J", (void*) SkCanvasGlue::initRaster},
     {"initCanvas", "(J)J", (void*) SkCanvasGlue::initCanvas},
     {"native_setBitmap", "(JJZ)V", (void*) SkCanvasGlue::setBitmap},
-    {"isOpaque","()Z", (void*) SkCanvasGlue::isOpaque},
-    {"getWidth","()I", (void*) SkCanvasGlue::getWidth},
-    {"getHeight","()I", (void*) SkCanvasGlue::getHeight},
-    {"save","()I", (void*) SkCanvasGlue::saveAll},
-    {"save","(I)I", (void*) SkCanvasGlue::save},
-    {"native_saveLayer","(JLandroid/graphics/RectF;JI)I",
-        (void*) SkCanvasGlue::saveLayer},
-    {"native_saveLayer","(JFFFFJI)I", (void*) SkCanvasGlue::saveLayer4F},
-    {"native_saveLayerAlpha","(JLandroid/graphics/RectF;II)I",
-        (void*) SkCanvasGlue::saveLayerAlpha},
-    {"native_saveLayerAlpha","(JFFFFII)I",
-        (void*) SkCanvasGlue::saveLayerAlpha4F},
-    {"restore","()V", (void*) SkCanvasGlue::restore},
-    {"getSaveCount","()I", (void*) SkCanvasGlue::getSaveCount},
-    {"restoreToCount","(I)V", (void*) SkCanvasGlue::restoreToCount},
-    {"translate","(FF)V", (void*) SkCanvasGlue::translate},
-    {"scale","(FF)V", (void*) SkCanvasGlue::scale__FF},
-    {"rotate","(F)V", (void*) SkCanvasGlue::rotate__F},
-    {"skew","(FF)V", (void*) SkCanvasGlue::skew__FF},
+    {"native_isOpaque","(J)Z", (void*) SkCanvasGlue::isOpaque},
+    {"native_getWidth","(J)I", (void*) SkCanvasGlue::getWidth},
+    {"native_getHeight","(J)I", (void*) SkCanvasGlue::getHeight},
+    {"native_save","(JI)I", (void*) SkCanvasGlue::save},
+    {"native_saveLayer","(JFFFFJI)I", (void*) SkCanvasGlue::saveLayer},
+    {"native_saveLayerAlpha","(JFFFFII)I", (void*) SkCanvasGlue::saveLayerAlpha},
+    {"native_restore","(J)V", (void*) SkCanvasGlue::restore},
+    {"native_getSaveCount","(J)I", (void*) SkCanvasGlue::getSaveCount},
+    {"native_restoreToCount","(JI)V", (void*) SkCanvasGlue::restoreToCount},
+    {"native_translate","(JFF)V", (void*) SkCanvasGlue::translate},
+    {"native_scale","(JFF)V", (void*) SkCanvasGlue::scale__FF},
+    {"native_rotate","(JF)V", (void*) SkCanvasGlue::rotate__F},
+    {"native_skew","(JFF)V", (void*) SkCanvasGlue::skew__FF},
     {"native_concat","(JJ)V", (void*) SkCanvasGlue::concat},
     {"native_setMatrix","(JJ)V", (void*) SkCanvasGlue::setMatrix},
-    {"clipRect","(FFFF)Z", (void*) SkCanvasGlue::clipRect_FFFF},
-    {"clipRect","(IIII)Z", (void*) SkCanvasGlue::clipRect_IIII},
-    {"clipRect","(Landroid/graphics/RectF;)Z",
-        (void*) SkCanvasGlue::clipRect_RectF},
-    {"clipRect","(Landroid/graphics/Rect;)Z",
-        (void*) SkCanvasGlue::clipRect_Rect},
     {"native_clipRect","(JFFFFI)Z", (void*) SkCanvasGlue::clipRect},
     {"native_clipPath","(JJI)Z", (void*) SkCanvasGlue::clipPath},
     {"native_clipRegion","(JJI)Z", (void*) SkCanvasGlue::clipRegion},
@@ -1187,8 +1094,6 @@
     {"native_getClipBounds","(JLandroid/graphics/Rect;)Z",
         (void*) SkCanvasGlue::getClipBounds},
     {"native_getCTM", "(JJ)V", (void*)SkCanvasGlue::getCTM},
-    {"native_quickReject","(JLandroid/graphics/RectF;)Z",
-        (void*) SkCanvasGlue::quickReject__RectF},
     {"native_quickReject","(JJ)Z", (void*) SkCanvasGlue::quickReject__Path},
     {"native_quickReject","(JFFFF)Z", (void*)SkCanvasGlue::quickReject__FFFF},
     {"native_drawRGB","(JIII)V", (void*) SkCanvasGlue::drawRGB},
@@ -1196,15 +1101,10 @@
     {"native_drawColor","(JI)V", (void*) SkCanvasGlue::drawColor__I},
     {"native_drawColor","(JII)V", (void*) SkCanvasGlue::drawColor__II},
     {"native_drawPaint","(JJ)V", (void*) SkCanvasGlue::drawPaint},
-    {"drawPoint", "(FFLandroid/graphics/Paint;)V",
-    (void*) SkCanvasGlue::drawPoint},
-    {"drawPoints", "([FIILandroid/graphics/Paint;)V",
-        (void*) SkCanvasGlue::drawPoints},
-    {"drawLines", "([FIILandroid/graphics/Paint;)V",
-        (void*) SkCanvasGlue::drawLines},
+    {"native_drawPoint", "(JFFJ)V", (void*) SkCanvasGlue::drawPoint},
+    {"native_drawPoints", "(J[FIIJ)V", (void*) SkCanvasGlue::drawPoints},
+    {"native_drawLines", "(J[FIIJ)V", (void*) SkCanvasGlue::drawLines},
     {"native_drawLine","(JFFFFJ)V", (void*) SkCanvasGlue::drawLine__FFFFPaint},
-    {"native_drawRect","(JLandroid/graphics/RectF;J)V",
-        (void*) SkCanvasGlue::drawRect__RectFPaint},
     {"native_drawRect","(JFFFFJ)V", (void*) SkCanvasGlue::drawRect__FFFFPaint},
     {"native_drawOval","(JLandroid/graphics/RectF;J)V",
         (void*) SkCanvasGlue::drawOval},
diff --git a/core/jni/android/graphics/MinikinSkia.cpp b/core/jni/android/graphics/MinikinSkia.cpp
index 243fa10..2b96f1b 100644
--- a/core/jni/android/graphics/MinikinSkia.cpp
+++ b/core/jni/android/graphics/MinikinSkia.cpp
@@ -46,8 +46,10 @@
 static void MinikinFontSkia_SetSkiaPaint(SkTypeface* typeface, SkPaint* skPaint, const MinikinPaint& paint) {
     skPaint->setTypeface(typeface);
     skPaint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
-    // TODO: set more paint parameters from Minikin
     skPaint->setTextSize(paint.size);
+    skPaint->setTextScaleX(paint.scaleX);
+    skPaint->setTextSkewX(paint.skewX);
+    MinikinFontSkia::unpackPaintFlags(skPaint, paint.paintFlags);
 }
 
 float MinikinFontSkia::GetHorizontalAdvance(uint32_t glyph_id,
@@ -96,4 +98,21 @@
     return mTypeface->uniqueID();
 }
 
+uint32_t MinikinFontSkia::packPaintFlags(const SkPaint* paint) {
+    uint32_t flags = paint->getFlags();
+    SkPaint::Hinting hinting = paint->getHinting();
+    // select only flags that might affect text layout
+    flags &= (SkPaint::kAntiAlias_Flag | SkPaint::kFakeBoldText_Flag | SkPaint::kLinearText_Flag |
+            SkPaint::kSubpixelText_Flag | SkPaint::kDevKernText_Flag |
+            SkPaint::kEmbeddedBitmapText_Flag | SkPaint::kAutoHinting_Flag |
+            SkPaint::kVerticalText_Flag);
+    flags |= (hinting << 16);
+    return flags;
+}
+
+void MinikinFontSkia::unpackPaintFlags(SkPaint* paint, uint32_t paintFlags) {
+    paint->setFlags(paintFlags & SkPaint::kAllFlags);
+    paint->setHinting(static_cast<SkPaint::Hinting>(paintFlags >> 16));
+}
+
 }
diff --git a/core/jni/android/graphics/MinikinSkia.h b/core/jni/android/graphics/MinikinSkia.h
index 1cc2c51..0452c57 100644
--- a/core/jni/android/graphics/MinikinSkia.h
+++ b/core/jni/android/graphics/MinikinSkia.h
@@ -38,6 +38,8 @@
 
     SkTypeface *GetSkTypeface();
 
+    static uint32_t packPaintFlags(const SkPaint* paint);
+    static void unpackPaintFlags(SkPaint* paint, uint32_t paintFlags);
 private:
     SkTypeface *mTypeface;
 };
diff --git a/core/jni/android/graphics/MinikinUtils.cpp b/core/jni/android/graphics/MinikinUtils.cpp
index 79381ad..a9360ea 100644
--- a/core/jni/android/graphics/MinikinUtils.cpp
+++ b/core/jni/android/graphics/MinikinUtils.cpp
@@ -14,32 +14,66 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "Minikin"
+#include <cutils/log.h>
+#include <string>
+
 #include "SkPaint.h"
 #include "minikin/Layout.h"
 #include "TypefaceImpl.h"
+#include "MinikinSkia.h"
 
 #include "MinikinUtils.h"
 
 namespace android {
 
-void MinikinUtils::SetLayoutProperties(Layout* layout, SkPaint* paint, int flags,
-    TypefaceImpl* typeface) {
+// Do an sprintf starting at offset n, abort on overflow
+static int snprintfcat(char* buf, int off, int size, const char* format, ...) {
+    va_list args;
+    va_start(args, format);
+    int n = vsnprintf(buf + off, size - off, format, args);
+    LOG_ALWAYS_FATAL_IF(n >= size - off, "String overflow in setting layout properties");
+    va_end(args);
+    return off + n;
+}
+
+std::string MinikinUtils::setLayoutProperties(Layout* layout, const SkPaint* paint, int bidiFlags,
+        TypefaceImpl* typeface) {
     TypefaceImpl* resolvedFace = TypefaceImpl_resolveDefault(typeface);
     layout->setFontCollection(resolvedFace->fFontCollection);
     FontStyle style = resolvedFace->fStyle;
     char css[256];
-    int off = snprintf(css, sizeof(css),
-        "font-size: %d; font-weight: %d; font-style: %s; -minikin-bidi: %d;",
+    int off = snprintfcat(css, 0, sizeof(css),
+        "font-size: %d; font-scale-x: %f; font-skew-x: %f; -paint-flags: %d;"
+        " font-weight: %d; font-style: %s; -minikin-bidi: %d;",
         (int)paint->getTextSize(),
+        paint->getTextScaleX(),
+        paint->getTextSkewX(),
+        MinikinFontSkia::packPaintFlags(paint),
         style.getWeight() * 100,
         style.getItalic() ? "italic" : "normal",
-        flags);
+        bidiFlags);
     SkString langString = paint->getPaintOptionsAndroid().getLanguage().getTag();
-    off += snprintf(css + off, sizeof(css) - off, " lang: %s;", langString.c_str());
+    off = snprintfcat(css, off, sizeof(css), " lang: %s;", langString.c_str());
     SkPaintOptionsAndroid::FontVariant var = paint->getPaintOptionsAndroid().getFontVariant();
     const char* varstr = var == SkPaintOptionsAndroid::kElegant_Variant ? "elegant" : "compact";
-    off += snprintf(css + off, sizeof(css) - off, " -minikin-variant: %s;", varstr);
+    off = snprintfcat(css, off, sizeof(css), " -minikin-variant: %s;", varstr);
     layout->setProperties(css);
+    return std::string(css);
 }
 
-}
\ No newline at end of file
+float MinikinUtils::xOffsetForTextAlign(SkPaint* paint, const Layout& layout) {
+    switch (paint->getTextAlign()) {
+        case SkPaint::kCenter_Align:
+            return layout.getAdvance() * -0.5f;
+            break;
+        case SkPaint::kRight_Align:
+            return -layout.getAdvance();
+            break;
+        default:
+            break;
+    }
+    return 0;
+}
+
+}
diff --git a/core/jni/android/graphics/MinikinUtils.h b/core/jni/android/graphics/MinikinUtils.h
index 42f5e2f..ea7eb5d 100644
--- a/core/jni/android/graphics/MinikinUtils.h
+++ b/core/jni/android/graphics/MinikinUtils.h
@@ -26,10 +26,35 @@
 
 namespace android {
 
+class Layout;
+class TypefaceImpl;
+
 class MinikinUtils {
 public:
-    static void SetLayoutProperties(Layout* layout, SkPaint* paint, int flags,
-        TypefaceImpl* face);
+    static std::string setLayoutProperties(Layout* layout, const SkPaint* paint, int bidiFlags,
+            TypefaceImpl* typeface);
+
+    static float xOffsetForTextAlign(SkPaint* paint, const Layout& layout);
+
+    // f is a functor of type void f(SkTypeface *, size_t start, size_t end);
+    template <typename F>
+    static void forFontRun(const Layout& layout, F& f) {
+        SkTypeface* lastFace = 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);
+                start = i;
+            }
+            lastFace = skFace;
+        }
+        if (nGlyphs > start) {
+            f(lastFace, start, nGlyphs);
+        }
+    }
 };
 
 }  // namespace android
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index 8418162..24731ac 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -429,26 +429,19 @@
         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);
+        MinikinFont* baseFont = typeface->fFontCollection->baseFont(typeface->fStyle);
+        paint->setTypeface(reinterpret_cast<MinikinFontSkia*>(baseFont)->GetSkTypeface());
+#endif
         SkScalar spacing = paint->getFontMetrics(metrics);
         SkPaintOptionsAndroid paintOpts = paint->getPaintOptionsAndroid();
         if (paintOpts.getFontVariant() == SkPaintOptionsAndroid::kElegant_Variant) {
@@ -463,10 +456,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 +490,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);
@@ -520,8 +527,8 @@
 #ifdef USE_MINIKIN
         Layout layout;
         TypefaceImpl* typeface = GraphicsJNI::getNativeTypeface(env, jpaint);
-        MinikinUtils::SetLayoutProperties(&layout, paint, bidiFlags, typeface);
-        layout.doLayout(textArray + index, count);
+        std::string css = MinikinUtils::setLayoutProperties(&layout, paint, bidiFlags, typeface);
+        layout.doLayout(textArray, index, count, textLength, css);
         result = layout.getAdvance();
 #else
         TextLayout::getTextRunAdvances(paint, textArray, index, count, textLength,
@@ -554,8 +561,8 @@
 #ifdef USE_MINIKIN
         Layout layout;
         TypefaceImpl* typeface = GraphicsJNI::getNativeTypeface(env, jpaint);
-        MinikinUtils::SetLayoutProperties(&layout, paint, bidiFlags, typeface);
-        layout.doLayout(textArray + start, count);
+        std::string css = MinikinUtils::setLayoutProperties(&layout, paint, bidiFlags, typeface);
+        layout.doLayout(textArray, start, count, textLength, css);
         width = layout.getAdvance();
 #else
         TextLayout::getTextRunAdvances(paint, textArray, start, count, textLength,
@@ -582,8 +589,8 @@
 #ifdef USE_MINIKIN
         Layout layout;
         TypefaceImpl* typeface = GraphicsJNI::getNativeTypeface(env, jpaint);
-        MinikinUtils::SetLayoutProperties(&layout, paint, bidiFlags, typeface);
-        layout.doLayout(textArray, textLength);
+        std::string css = MinikinUtils::setLayoutProperties(&layout, paint, bidiFlags, typeface);
+        layout.doLayout(textArray, 0, textLength, textLength, css);
         width = layout.getAdvance();
 #else
         TextLayout::getTextRunAdvances(paint, textArray, 0, textLength, textLength,
@@ -617,8 +624,8 @@
 
 #ifdef USE_MINIKIN
         Layout layout;
-        MinikinUtils::SetLayoutProperties(&layout, paint, bidiFlags, typeface);
-        layout.doLayout(text, count);
+        std::string css = MinikinUtils::setLayoutProperties(&layout, paint, bidiFlags, typeface);
+        layout.doLayout(text, 0, count, count, css);
         layout.getAdvances(widthsArray);
 #else
         TextLayout::getTextRunAdvances(paint, text, 0, count, count,
@@ -715,8 +722,8 @@
 
 #ifdef USE_MINIKIN
         Layout layout;
-        MinikinUtils::SetLayoutProperties(&layout, paint, flags, typeface);
-        layout.doLayout(text + start, count);
+        std::string css = MinikinUtils::setLayoutProperties(&layout, paint, flags, typeface);
+        layout.doLayout(text, start, count, contextCount, css);
         layout.getAdvances(advancesArray);
         totalAdvance = layout.getAdvance();
 #else
@@ -822,26 +829,83 @@
         return result;
     }
 
-    static void getTextPath(JNIEnv* env, SkPaint* paint, const jchar* text, jint count,
-                            jint bidiFlags, jfloat x, jfloat y, SkPath *path) {
+#ifdef USE_MINIKIN
+    class GetTextFunctor {
+    public:
+        GetTextFunctor(const Layout& layout, SkPath* path, jfloat x, jfloat y, SkPaint* paint,
+                    uint16_t* glyphs, SkPoint* pos)
+                : layout(layout), path(path), x(x), y(y), paint(paint), glyphs(glyphs), pos(pos) {
+        }
+
+        void operator()(SkTypeface* t, 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 {
+                paint->getPosTextPath(glyphs + start, (end - start) << 1, pos + start, &tmpPath);
+                path->addPath(tmpPath);
+            }
+        }
+    private:
+        const Layout& layout;
+        SkPath* path;
+        jfloat x;
+        jfloat y;
+        SkPaint* paint;
+        uint16_t* glyphs;
+        SkPoint* pos;
+        SkPath tmpPath;
+    };
+#endif
+
+    static void getTextPath(JNIEnv* env, SkPaint* paint, TypefaceImpl* typeface, const jchar* text,
+            jint count, jint bidiFlags, jfloat x, jfloat y, SkPath* path) {
+#ifdef USE_MINIKIN
+        Layout layout;
+        std::string css = MinikinUtils::setLayoutProperties(&layout, paint, bidiFlags, typeface);
+        layout.doLayout(text, 0, count, count, css);
+        size_t nGlyphs = layout.nGlyphs();
+        uint16_t* glyphs = new uint16_t[nGlyphs];
+        SkPoint* pos = new SkPoint[nGlyphs];
+
+        x += MinikinUtils::xOffsetForTextAlign(paint, layout);
+        SkPaint::Align align = paint->getTextAlign();
+        paint->setTextAlign(SkPaint::kLeft_Align);
+        paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+        GetTextFunctor f(layout, path, x, y, paint, glyphs, pos);
+        MinikinUtils::forFontRun(layout, f);
+        paint->setTextAlign(align);
+        delete[] glyphs;
+        delete[] pos;
+#else
         TextLayout::getTextPath(paint, text, count, bidiFlags, x, y, path);
+#endif
     }
 
-    static void getTextPath___C(JNIEnv* env, jobject clazz, jlong paintHandle, jint bidiFlags,
+    static void getTextPath___C(JNIEnv* env, jobject clazz, jlong paintHandle,
+            jlong typefaceHandle, jint bidiFlags,
             jcharArray text, jint index, jint count, jfloat x, jfloat y, jlong pathHandle) {
         SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+        TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
         SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
         const jchar* textArray = env->GetCharArrayElements(text, NULL);
-        getTextPath(env, paint, textArray + index, count, bidiFlags, x, y, path);
+        getTextPath(env, paint, typeface, textArray + index, count, bidiFlags, x, y, path);
         env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray), JNI_ABORT);
     }
 
-    static void getTextPath__String(JNIEnv* env, jobject clazz, jlong paintHandle, jint bidiFlags,
+    static void getTextPath__String(JNIEnv* env, jobject clazz, jlong paintHandle,
+            jlong typefaceHandle, jint bidiFlags,
             jstring text, jint start, jint end, jfloat x, jfloat y, jlong pathHandle) {
         SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+        TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
         SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
         const jchar* textArray = env->GetStringChars(text, NULL);
-        getTextPath(env, paint, textArray + start, end - start, bidiFlags, x, y, path);
+        getTextPath(env, paint, typeface, textArray + start, end - start, bidiFlags, x, y, path);
         env->ReleaseStringChars(text, textArray);
     }
 
@@ -928,34 +992,48 @@
         return count;
     }
 
-    static void doTextBounds(JNIEnv* env, const jchar* text, int count,
-                             jobject bounds, const SkPaint& paint, jint bidiFlags) {
+    static void doTextBounds(JNIEnv* env, const jchar* text, int count, jobject bounds,
+            const SkPaint& paint, TypefaceImpl* typeface, jint bidiFlags) {
         SkRect  r;
         SkIRect ir;
 
+#ifdef USE_MINIKIN
+        Layout layout;
+        std::string css = MinikinUtils::setLayoutProperties(&layout, &paint, bidiFlags, typeface);
+        layout.doLayout(text, 0, count, count, css);
+        MinikinRect rect;
+        layout.getBounds(&rect);
+        r.fLeft = rect.mLeft;
+        r.fTop = rect.mTop;
+        r.fRight = rect.mRight;
+        r.fBottom = rect.mBottom;
+#else
         sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(&paint,
                 text, 0, count, count, bidiFlags);
         if (value == NULL) {
             return;
         }
         paint.measureText(value->getGlyphs(), value->getGlyphsCount() << 1, &r);
+#endif
         r.roundOut(&ir);
         GraphicsJNI::irect_to_jrect(ir, env, bounds);
     }
 
-    static void getStringBounds(JNIEnv* env, jobject, jlong paintHandle,
+    static void getStringBounds(JNIEnv* env, jobject, jlong paintHandle, jlong typefaceHandle,
                                 jstring text, jint start, jint end, jint bidiFlags, jobject bounds) {
         const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);;
+        TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
         const jchar* textArray = env->GetStringChars(text, NULL);
-        doTextBounds(env, textArray + start, end - start, bounds, *paint, bidiFlags);
+        doTextBounds(env, textArray + start, end - start, bounds, *paint, typeface, bidiFlags);
         env->ReleaseStringChars(text, textArray);
     }
 
-    static void getCharArrayBounds(JNIEnv* env, jobject, jlong paintHandle,
+    static void getCharArrayBounds(JNIEnv* env, jobject, jlong paintHandle, jlong typefaceHandle,
                         jcharArray text, jint index, jint count, jint bidiFlags, jobject bounds) {
         const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+        TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
         const jchar* textArray = env->GetCharArrayElements(text, NULL);
-        doTextBounds(env, textArray + index, count, bounds, *paint, bidiFlags);
+        doTextBounds(env, textArray + index, count, bounds, *paint, typeface, bidiFlags);
         env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray),
                                       JNI_ABORT);
     }
@@ -1035,11 +1113,11 @@
     {"native_getTextRunCursor", "(J[CIIIII)I", (void*) SkPaintGlue::getTextRunCursor___C},
     {"native_getTextRunCursor", "(JLjava/lang/String;IIIII)I",
         (void*) SkPaintGlue::getTextRunCursor__String},
-    {"native_getTextPath","(JI[CIIFFJ)V", (void*) SkPaintGlue::getTextPath___C},
-    {"native_getTextPath","(JILjava/lang/String;IIFFJ)V", (void*) SkPaintGlue::getTextPath__String},
-    {"nativeGetStringBounds", "(JLjava/lang/String;IIILandroid/graphics/Rect;)V",
+    {"native_getTextPath","(JJI[CIIFFJ)V", (void*) SkPaintGlue::getTextPath___C},
+    {"native_getTextPath","(JJILjava/lang/String;IIFFJ)V", (void*) SkPaintGlue::getTextPath__String},
+    {"nativeGetStringBounds", "(JJLjava/lang/String;IIILandroid/graphics/Rect;)V",
                                         (void*) SkPaintGlue::getStringBounds },
-    {"nativeGetCharArrayBounds", "(J[CIIILandroid/graphics/Rect;)V",
+    {"nativeGetCharArrayBounds", "(JJ[CIIILandroid/graphics/Rect;)V",
                                     (void*) SkPaintGlue::getCharArrayBounds },
     {"native_setShadowLayer", "(JFFFI)V", (void*)SkPaintGlue::setShadowLayer},
     {"native_hasShadowLayer", "(J)Z", (void*)SkPaintGlue::hasShadowLayer}
diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp
index 9279758..495d08a 100644
--- a/core/jni/android/graphics/TextLayoutCache.cpp
+++ b/core/jni/android/graphics/TextLayoutCache.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "TextLayoutCache"
 
 #include <utils/JenkinsHash.h>
+#include <utils/CallStack.h>
 
 #include "TextLayoutCache.h"
 #include "TextLayout.h"
@@ -89,6 +90,11 @@
 sp<TextLayoutValue> TextLayoutCache::getValue(const SkPaint* paint,
             const jchar* text, jint start, jint count, jint contextCount, jint dirFlags) {
     AutoMutex _l(mLock);
+#ifdef USE_MINIKIN
+    // We want to get rid of all legacy calls in the Minikin case, so log
+    ALOGW("TextLayoutCache being invoked!");
+    CallStack _cs(LOG_TAG);
+#endif
     nsecs_t startTime = 0;
     if (mDebugEnabled) {
         startTime = systemTime(SYSTEM_TIME_MONOTONIC);
diff --git a/core/jni/android/graphics/TypefaceImpl.cpp b/core/jni/android/graphics/TypefaceImpl.cpp
index ff52b07..27df7cf 100644
--- a/core/jni/android/graphics/TypefaceImpl.cpp
+++ b/core/jni/android/graphics/TypefaceImpl.cpp
@@ -32,6 +32,7 @@
 #include <minikin/FontCollection.h>
 #include <minikin/FontFamily.h>
 #include <minikin/Layout.h>
+#include "SkPaint.h"
 #include "MinikinSkia.h"
 #endif
 
@@ -134,18 +135,19 @@
     return result;
 }
 
+// Delete when removing USE_MINIKIN ifdef
 TypefaceImpl* TypefaceImpl_createFromName(const char* name, SkTypeface::Style style) {
-    // TODO: should create a font collection with all styles corresponding to
-    // the name
     SkTypeface* face = SkTypeface::CreateFromName(name, style);
     return createFromSkTypeface(face);
 }
 
+// Delete when removing USE_MINIKIN ifdef
 TypefaceImpl* TypefaceImpl_createFromFile(const char* filename) {
     SkTypeface* face = SkTypeface::CreateFromFile(filename);
     return createFromSkTypeface(face);
 }
 
+// Delete when removing USE_MINIKIN ifdef
 TypefaceImpl* TypefaceImpl_createFromAsset(Asset* asset) {
     SkStream* stream = new AssetStreamAdaptor(asset,
                                               AssetStreamAdaptor::kYes_OwnAsset,
@@ -158,7 +160,6 @@
 }
 
 TypefaceImpl* TypefaceImpl_createFromFamilies(const jlong* families, size_t size) {
-    ALOGD("createFromFamilies size=%d", size);
     std::vector<FontFamily *>familyVec;
     for (size_t i = 0; i < size; i++) {
         FontFamily* family = reinterpret_cast<FontFamily*>(families[i]);
@@ -166,7 +167,18 @@
     }
     TypefaceImpl* result = new TypefaceImpl;
     result->fFontCollection = new FontCollection(familyVec);
-    result->fStyle = FontStyle();  // TODO: improve
+    if (size == 0) {
+        ALOGW("createFromFamilies creating empty collection");
+        result->fStyle = FontStyle();
+    } else {
+        const FontStyle defaultStyle;
+        FontFamily* firstFamily = reinterpret_cast<FontFamily*>(families[0]);
+        MinikinFont* mf = firstFamily->getClosestMatch(defaultStyle);
+        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
+        result->fStyle = styleFromSkiaStyle(skTypeface->style());
+    }
     return result;
 }
 
diff --git a/core/jni/android_hardware_SoundTrigger.cpp b/core/jni/android_hardware_SoundTrigger.cpp
new file mode 100644
index 0000000..69e991d
--- /dev/null
+++ b/core/jni/android_hardware_SoundTrigger.cpp
@@ -0,0 +1,661 @@
+/*
+**
+** Copyright 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.
+*/
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "SoundTrigger-JNI"
+#include <utils/Log.h>
+
+#include "jni.h"
+#include "JNIHelp.h"
+#include "android_runtime/AndroidRuntime.h"
+#include <system/sound_trigger.h>
+#include <soundtrigger/SoundTriggerCallback.h>
+#include <soundtrigger/SoundTrigger.h>
+#include <utils/RefBase.h>
+#include <utils/Vector.h>
+#include <binder/IMemory.h>
+#include <binder/MemoryDealer.h>
+
+using namespace android;
+
+static jclass gArrayListClass;
+static struct {
+    jmethodID    add;
+} gArrayListMethods;
+
+static const char* const kSoundTriggerClassPathName = "android/hardware/soundtrigger/SoundTrigger";
+static jclass gSoundTriggerClass;
+
+static const char* const kModuleClassPathName = "android/hardware/soundtrigger/SoundTriggerModule";
+static jclass gModuleClass;
+static struct {
+    jfieldID    mNativeContext;
+    jfieldID    mId;
+} gModuleFields;
+static jmethodID   gPostEventFromNative;
+
+static const char* const kModulePropertiesClassPathName =
+                                     "android/hardware/soundtrigger/SoundTrigger$ModuleProperties";
+static jclass gModulePropertiesClass;
+static jmethodID   gModulePropertiesCstor;
+
+static const char* const kSoundModelClassPathName =
+                                     "android/hardware/soundtrigger/SoundTrigger$SoundModel";
+static jclass gSoundModelClass;
+static struct {
+    jfieldID    data;
+} gSoundModelFields;
+
+static const char* const kKeyPhraseClassPathName =
+                                     "android/hardware/soundtrigger/SoundTrigger$KeyPhrase";
+static jclass gKeyPhraseClass;
+static struct {
+    jfieldID recognitionModes;
+    jfieldID locale;
+    jfieldID text;
+    jfieldID numUsers;
+} gKeyPhraseFields;
+
+static const char* const kKeyPhraseSoundModelClassPathName =
+                                 "android/hardware/soundtrigger/SoundTrigger$KeyPhraseSoundModel";
+static jclass gKeyPhraseSoundModelClass;
+static struct {
+    jfieldID    keyPhrases;
+} gKeyPhraseSoundModelFields;
+
+
+static const char* const kRecognitionEventClassPathName =
+                                     "android/hardware/soundtrigger/SoundTrigger$RecognitionEvent";
+static jclass gRecognitionEventClass;
+static jmethodID   gRecognitionEventCstor;
+
+static const char* const kKeyPhraseRecognitionEventClassPathName =
+                             "android/hardware/soundtrigger/SoundTrigger$KeyPhraseRecognitionEvent";
+static jclass gKeyPhraseRecognitionEventClass;
+static jmethodID   gKeyPhraseRecognitionEventCstor;
+
+static const char* const kKeyPhraseRecognitionExtraClassPathName =
+                             "android/hardware/soundtrigger/SoundTrigger$KeyPhraseRecognitionExtra";
+static jclass gKeyPhraseRecognitionExtraClass;
+static jmethodID   gKeyPhraseRecognitionExtraCstor;
+
+static Mutex gLock;
+
+enum {
+    SOUNDTRIGGER_STATUS_OK = 0,
+    SOUNDTRIGGER_STATUS_ERROR = INT_MIN,
+    SOUNDTRIGGER_PERMISSION_DENIED = -1,
+    SOUNDTRIGGER_STATUS_NO_INIT = -19,
+    SOUNDTRIGGER_STATUS_BAD_VALUE = -22,
+    SOUNDTRIGGER_STATUS_DEAD_OBJECT = -32,
+    SOUNDTRIGGER_INVALID_OPERATION = -38,
+};
+
+enum  {
+    SOUNDTRIGGER_EVENT_RECOGNITION = 1,
+    SOUNDTRIGGER_EVENT_SERVICE_DIED = 2,
+};
+
+// ----------------------------------------------------------------------------
+// ref-counted object for callbacks
+class JNISoundTriggerCallback: public SoundTriggerCallback
+{
+public:
+    JNISoundTriggerCallback(JNIEnv* env, jobject thiz, jobject weak_thiz);
+    ~JNISoundTriggerCallback();
+
+    virtual void onRecognitionEvent(struct sound_trigger_recognition_event *event);
+    virtual void onServiceDied();
+
+private:
+    jclass      mClass;     // Reference to SoundTrigger class
+    jobject     mObject;    // Weak ref to SoundTrigger Java object to call on
+};
+
+JNISoundTriggerCallback::JNISoundTriggerCallback(JNIEnv* env, jobject thiz, jobject weak_thiz)
+{
+
+    // Hold onto the SoundTriggerModule class for use in calling the static method
+    // that posts events to the application thread.
+    jclass clazz = env->GetObjectClass(thiz);
+    if (clazz == NULL) {
+        ALOGE("Can't find class %s", kModuleClassPathName);
+        return;
+    }
+    mClass = (jclass)env->NewGlobalRef(clazz);
+
+    // We use a weak reference so the SoundTriggerModule object can be garbage collected.
+    // The reference is only used as a proxy for callbacks.
+    mObject  = env->NewGlobalRef(weak_thiz);
+}
+
+JNISoundTriggerCallback::~JNISoundTriggerCallback()
+{
+    // remove global references
+    JNIEnv *env = AndroidRuntime::getJNIEnv();
+    env->DeleteGlobalRef(mObject);
+    env->DeleteGlobalRef(mClass);
+}
+
+void JNISoundTriggerCallback::onRecognitionEvent(struct sound_trigger_recognition_event *event)
+{
+    JNIEnv *env = AndroidRuntime::getJNIEnv();
+
+    jobject jEvent;
+
+    jbyteArray jData = NULL;
+    if (event->data_size) {
+        jData = env->NewByteArray(event->data_size);
+        jbyte *nData = env->GetByteArrayElements(jData, NULL);
+        memcpy(nData, (char *)event + event->data_offset, event->data_size);
+        env->ReleaseByteArrayElements(jData, nData, 0);
+    }
+
+    if (event->type == SOUND_MODEL_TYPE_KEYPHRASE) {
+        struct sound_trigger_phrase_recognition_event *phraseEvent =
+                (struct sound_trigger_phrase_recognition_event *)event;
+
+        jobjectArray jExtras = env->NewObjectArray(phraseEvent->num_phrases,
+                                                  gKeyPhraseRecognitionExtraClass, NULL);
+        if (jExtras == NULL) {
+            return;
+        }
+
+        for (size_t i = 0; i < phraseEvent->num_phrases; i++) {
+            jintArray jConfidenceLevels = env->NewIntArray(phraseEvent->phrase_extras[i].num_users);
+            if (jConfidenceLevels == NULL) {
+                return;
+            }
+            jint *nConfidenceLevels = env->GetIntArrayElements(jConfidenceLevels, NULL);
+            memcpy(nConfidenceLevels,
+                   phraseEvent->phrase_extras[i].confidence_levels,
+                   phraseEvent->phrase_extras[i].num_users * sizeof(int));
+            env->ReleaseIntArrayElements(jConfidenceLevels, nConfidenceLevels, 0);
+            jobject jNewExtra = env->NewObject(gKeyPhraseRecognitionExtraClass,
+                                               gKeyPhraseRecognitionExtraCstor,
+                                               jConfidenceLevels,
+                                               phraseEvent->phrase_extras[i].recognition_modes);
+
+            if (jNewExtra == NULL) {
+                return;
+            }
+            env->SetObjectArrayElement(jExtras, i, jNewExtra);
+
+        }
+        jEvent = env->NewObject(gKeyPhraseRecognitionEventClass, gKeyPhraseRecognitionEventCstor,
+                                event->status, event->model, event->capture_available,
+                               event->capture_session, event->capture_delay_ms, jData,
+                               phraseEvent->key_phrase_in_capture, jExtras);
+    } else {
+        jEvent = env->NewObject(gRecognitionEventClass, gRecognitionEventCstor,
+                                event->status, event->model, event->capture_available,
+                                event->capture_session, event->capture_delay_ms, jData);
+    }
+
+
+    env->CallStaticVoidMethod(mClass, gPostEventFromNative, mObject,
+                              SOUNDTRIGGER_EVENT_RECOGNITION, 0, 0, jEvent);
+    if (env->ExceptionCheck()) {
+        ALOGW("An exception occurred while notifying an event.");
+        env->ExceptionClear();
+    }
+}
+
+void JNISoundTriggerCallback::onServiceDied()
+{
+    JNIEnv *env = AndroidRuntime::getJNIEnv();
+
+    env->CallStaticVoidMethod(mClass, gPostEventFromNative, mObject,
+                              SOUNDTRIGGER_EVENT_SERVICE_DIED, 0, 0, NULL);
+    if (env->ExceptionCheck()) {
+        ALOGW("An exception occurred while notifying an event.");
+        env->ExceptionClear();
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+static sp<SoundTrigger> getSoundTrigger(JNIEnv* env, jobject thiz)
+{
+    Mutex::Autolock l(gLock);
+    SoundTrigger* const st = (SoundTrigger*)env->GetLongField(thiz,
+                                                         gModuleFields.mNativeContext);
+    return sp<SoundTrigger>(st);
+}
+
+static sp<SoundTrigger> setSoundTrigger(JNIEnv* env, jobject thiz, const sp<SoundTrigger>& module)
+{
+    Mutex::Autolock l(gLock);
+    sp<SoundTrigger> old = (SoundTrigger*)env->GetLongField(thiz,
+                                                         gModuleFields.mNativeContext);
+    if (module.get()) {
+        module->incStrong((void*)setSoundTrigger);
+    }
+    if (old != 0) {
+        old->decStrong((void*)setSoundTrigger);
+    }
+    env->SetLongField(thiz, gModuleFields.mNativeContext, (jlong)module.get());
+    return old;
+}
+
+
+static jint
+android_hardware_SoundTrigger_listModules(JNIEnv *env, jobject clazz,
+                                          jobject jModules)
+{
+    ALOGV("listModules");
+
+    if (jModules == NULL) {
+        ALOGE("listModules NULL AudioPatch ArrayList");
+        return SOUNDTRIGGER_STATUS_BAD_VALUE;
+    }
+    if (!env->IsInstanceOf(jModules, gArrayListClass)) {
+        ALOGE("listModules not an arraylist");
+        return SOUNDTRIGGER_STATUS_BAD_VALUE;
+    }
+
+    unsigned int numModules = 0;
+    struct sound_trigger_module_descriptor *nModules = NULL;
+
+    status_t status = SoundTrigger::listModules(nModules, &numModules);
+    if (status != NO_ERROR || numModules == 0) {
+        return (jint)status;
+    }
+
+    nModules = (struct sound_trigger_module_descriptor *)
+                            calloc(numModules, sizeof(struct sound_trigger_module_descriptor));
+
+    status = SoundTrigger::listModules(nModules, &numModules);
+    ALOGV("listModules SoundTrigger::listModules status %d numModules %d", status, numModules);
+
+    if (status != NO_ERROR) {
+        numModules = 0;
+    }
+
+    for (size_t i = 0; i < numModules; i++) {
+        char str[SOUND_TRIGGER_MAX_STRING_LEN];
+
+        jstring implementor = env->NewStringUTF(nModules[i].properties.implementor);
+        jstring description = env->NewStringUTF(nModules[i].properties.description);
+        SoundTrigger::guidToString(&nModules[i].properties.uuid,
+                                   str,
+                                   SOUND_TRIGGER_MAX_STRING_LEN);
+        jstring uuid = env->NewStringUTF(str);
+
+        ALOGV("listModules module %d id %d description %s maxSoundModels %d",
+              i, nModules[i].handle, nModules[i].properties.description,
+              nModules[i].properties.max_sound_models);
+
+        jobject newModuleDesc = env->NewObject(gModulePropertiesClass, gModulePropertiesCstor,
+                                               nModules[i].handle,
+                                               implementor, description, uuid,
+                                               nModules[i].properties.version,
+                                               nModules[i].properties.max_sound_models,
+                                               nModules[i].properties.max_key_phrases,
+                                               nModules[i].properties.max_users,
+                                               nModules[i].properties.recognition_modes,
+                                               nModules[i].properties.capture_transition,
+                                               nModules[i].properties.max_buffer_ms,
+                                               nModules[i].properties.concurrent_capture,
+                                               nModules[i].properties.power_consumption_mw);
+
+        env->DeleteLocalRef(implementor);
+        env->DeleteLocalRef(description);
+        env->DeleteLocalRef(uuid);
+        if (newModuleDesc == NULL) {
+            status = SOUNDTRIGGER_STATUS_ERROR;
+            goto exit;
+        }
+        env->CallBooleanMethod(jModules, gArrayListMethods.add, newModuleDesc);
+    }
+
+exit:
+    free(nModules);
+    return (jint) status;
+}
+
+static void
+android_hardware_SoundTrigger_setup(JNIEnv *env, jobject thiz, jobject weak_this)
+{
+    ALOGV("setup");
+
+    sp<JNISoundTriggerCallback> callback = new JNISoundTriggerCallback(env, thiz, weak_this);
+
+    sound_trigger_module_handle_t handle =
+            (sound_trigger_module_handle_t)env->GetIntField(thiz, gModuleFields.mId);
+
+    sp<SoundTrigger> module = SoundTrigger::attach(handle, callback);
+    if (module == 0) {
+        return;
+    }
+
+    setSoundTrigger(env, thiz, module);
+}
+
+static void
+android_hardware_SoundTrigger_detach(JNIEnv *env, jobject thiz)
+{
+    ALOGV("detach");
+    sp<SoundTrigger> module = setSoundTrigger(env, thiz, 0);
+    ALOGV("detach module %p", module.get());
+    if (module != 0) {
+        ALOGV("detach module->detach()");
+        module->detach();
+    }
+}
+
+static void
+android_hardware_SoundTrigger_finalize(JNIEnv *env, jobject thiz)
+{
+    ALOGV("finalize");
+    sp<SoundTrigger> module = getSoundTrigger(env, thiz);
+    if (module != 0) {
+        ALOGW("SoundTrigger finalized without being detached");
+    }
+    android_hardware_SoundTrigger_detach(env, thiz);
+}
+
+static jint
+android_hardware_SoundTrigger_loadSoundModel(JNIEnv *env, jobject thiz,
+                                             jobject jSoundModel, jintArray jHandle)
+{
+    jint status = SOUNDTRIGGER_STATUS_OK;
+    char *nData = NULL;
+    struct sound_trigger_sound_model *nSoundModel;
+    jbyteArray jData;
+    sp<MemoryDealer> memoryDealer;
+    sp<IMemory> memory;
+    size_t size;
+    sound_model_handle_t handle;
+
+    ALOGV("loadSoundModel");
+    sp<SoundTrigger> module = getSoundTrigger(env, thiz);
+    if (module == NULL) {
+        return SOUNDTRIGGER_STATUS_ERROR;
+    }
+    if (jHandle == NULL) {
+        return SOUNDTRIGGER_STATUS_BAD_VALUE;
+    }
+    jsize jHandleLen = env->GetArrayLength(jHandle);
+    if (jHandleLen == 0) {
+        return SOUNDTRIGGER_STATUS_BAD_VALUE;
+    }
+    jint *nHandle = env->GetIntArrayElements(jHandle, NULL);
+    if (nHandle == NULL) {
+        return SOUNDTRIGGER_STATUS_ERROR;
+    }
+    if (!env->IsInstanceOf(jSoundModel, gSoundModelClass)) {
+        status = SOUNDTRIGGER_STATUS_BAD_VALUE;
+        goto exit;
+    }
+    size_t offset;
+    sound_trigger_sound_model_type_t type;
+    if (env->IsInstanceOf(jSoundModel, gKeyPhraseSoundModelClass)) {
+        offset = sizeof(struct sound_trigger_phrase_sound_model);
+        type = SOUND_MODEL_TYPE_KEYPHRASE;
+    } else {
+        offset = sizeof(struct sound_trigger_sound_model);
+        type = SOUND_MODEL_TYPE_UNKNOWN;
+    }
+    jData = (jbyteArray)env->GetObjectField(jSoundModel, gSoundModelFields.data);
+    if (jData == NULL) {
+        status = SOUNDTRIGGER_STATUS_BAD_VALUE;
+        goto exit;
+    }
+    size = env->GetArrayLength(jData);
+
+    nData = (char *)env->GetByteArrayElements(jData, NULL);
+    if (jData == NULL) {
+        status = SOUNDTRIGGER_STATUS_ERROR;
+        goto exit;
+    }
+
+    memoryDealer = new MemoryDealer(offset + size, "SoundTrigge-JNI::LoadModel");
+    if (memoryDealer == 0) {
+        status = SOUNDTRIGGER_STATUS_ERROR;
+        goto exit;
+    }
+    memory = memoryDealer->allocate(offset + size);
+    if (memory == 0 || memory->pointer() == NULL) {
+        status = SOUNDTRIGGER_STATUS_ERROR;
+        goto exit;
+    }
+
+    nSoundModel = (struct sound_trigger_sound_model *)memory->pointer();
+
+    nSoundModel->type = type;
+    nSoundModel->data_size = size;
+    nSoundModel->data_offset = offset;
+    memcpy((char *)nSoundModel + offset, nData, size);
+    if (type == SOUND_MODEL_TYPE_KEYPHRASE) {
+        struct sound_trigger_phrase_sound_model *phraseModel =
+                (struct sound_trigger_phrase_sound_model *)nSoundModel;
+
+        jobjectArray jPhrases =
+            (jobjectArray)env->GetObjectField(jSoundModel, gKeyPhraseSoundModelFields.keyPhrases);
+        if (jPhrases == NULL) {
+            status = SOUNDTRIGGER_STATUS_BAD_VALUE;
+            goto exit;
+        }
+
+        size_t numPhrases = env->GetArrayLength(jPhrases);
+        phraseModel->num_phrases = numPhrases;
+        ALOGV("loadSoundModel numPhrases %d", numPhrases);
+        for (size_t i = 0; i < numPhrases; i++) {
+            jobject jPhrase = env->GetObjectArrayElement(jPhrases, i);
+            phraseModel->phrases[i].recognition_mode =
+                                    env->GetIntField(jPhrase,gKeyPhraseFields.recognitionModes);
+            phraseModel->phrases[i].num_users =
+                                    env->GetIntField(jPhrase, gKeyPhraseFields.numUsers);
+            jstring jLocale = (jstring)env->GetObjectField(jPhrase, gKeyPhraseFields.locale);
+            const char *nLocale = env->GetStringUTFChars(jLocale, NULL);
+            strncpy(phraseModel->phrases[i].locale,
+                    nLocale,
+                    SOUND_TRIGGER_MAX_LOCALE_LEN);
+            jstring jText = (jstring)env->GetObjectField(jPhrase, gKeyPhraseFields.text);
+            const char *nText = env->GetStringUTFChars(jText, NULL);
+            strncpy(phraseModel->phrases[i].text,
+                    nText,
+                    SOUND_TRIGGER_MAX_STRING_LEN);
+
+            env->ReleaseStringUTFChars(jLocale, nLocale);
+            env->DeleteLocalRef(jLocale);
+            env->ReleaseStringUTFChars(jText, nText);
+            env->DeleteLocalRef(jText);
+            ALOGV("loadSoundModel phrases %d text %s locale %s",
+                  i, phraseModel->phrases[i].text, phraseModel->phrases[i].locale);
+        }
+        env->DeleteLocalRef(jPhrases);
+    }
+    status = module->loadSoundModel(memory, &handle);
+    ALOGV("loadSoundModel status %d handle %d", status, handle);
+
+exit:
+    if (nHandle != NULL) {
+        nHandle[0] = (jint)handle;
+        env->ReleaseIntArrayElements(jHandle, nHandle, NULL);
+    }
+    if (nData != NULL) {
+        env->ReleaseByteArrayElements(jData, (jbyte *)nData, NULL);
+    }
+    return status;
+}
+
+static jint
+android_hardware_SoundTrigger_unloadSoundModel(JNIEnv *env, jobject thiz,
+                                               jint jHandle)
+{
+    jint status = SOUNDTRIGGER_STATUS_OK;
+    ALOGV("unloadSoundModel");
+    sp<SoundTrigger> module = getSoundTrigger(env, thiz);
+    if (module == NULL) {
+        return SOUNDTRIGGER_STATUS_ERROR;
+    }
+    status = module->unloadSoundModel((sound_model_handle_t)jHandle);
+
+    return status;
+}
+
+static jint
+android_hardware_SoundTrigger_startRecognition(JNIEnv *env, jobject thiz,
+                                               jint jHandle, jbyteArray jData)
+{
+    jint status = SOUNDTRIGGER_STATUS_OK;
+    ALOGV("startRecognition");
+    sp<SoundTrigger> module = getSoundTrigger(env, thiz);
+    if (module == NULL) {
+        return SOUNDTRIGGER_STATUS_ERROR;
+    }
+    jsize dataSize = 0;
+    char *nData = NULL;
+    sp<IMemory> memory;
+    if (jData != NULL) {
+        dataSize = env->GetArrayLength(jData);
+        if (dataSize == 0) {
+            return SOUNDTRIGGER_STATUS_BAD_VALUE;
+        }
+        nData = (char *)env->GetByteArrayElements(jData, NULL);
+        if (nData == NULL) {
+            return SOUNDTRIGGER_STATUS_ERROR;
+        }
+        sp<MemoryDealer> memoryDealer =
+                new MemoryDealer(dataSize, "SoundTrigge-JNI::StartRecognition");
+        if (memoryDealer == 0) {
+            return SOUNDTRIGGER_STATUS_ERROR;
+        }
+        memory = memoryDealer->allocate(dataSize);
+        if (memory == 0 || memory->pointer() == NULL) {
+            return SOUNDTRIGGER_STATUS_ERROR;
+        }
+        memcpy(memory->pointer(), nData, dataSize);
+    }
+
+    status = module->startRecognition(jHandle, memory);
+    return status;
+}
+
+static jint
+android_hardware_SoundTrigger_stopRecognition(JNIEnv *env, jobject thiz,
+                                               jint jHandle)
+{
+    jint status = SOUNDTRIGGER_STATUS_OK;
+    ALOGV("stopRecognition");
+    sp<SoundTrigger> module = getSoundTrigger(env, thiz);
+    if (module == NULL) {
+        return SOUNDTRIGGER_STATUS_ERROR;
+    }
+    status = module->stopRecognition(jHandle);
+    return status;
+}
+
+static JNINativeMethod gMethods[] = {
+    {"listModules",
+        "(Ljava/util/ArrayList;)I",
+        (void *)android_hardware_SoundTrigger_listModules},
+};
+
+
+static JNINativeMethod gModuleMethods[] = {
+    {"native_setup",
+        "(Ljava/lang/Object;)V",
+        (void *)android_hardware_SoundTrigger_setup},
+    {"native_finalize",
+        "()V",
+        (void *)android_hardware_SoundTrigger_finalize},
+    {"detach",
+        "()V",
+        (void *)android_hardware_SoundTrigger_detach},
+    {"loadSoundModel",
+        "(Landroid/hardware/soundtrigger/SoundTrigger$SoundModel;[I)I",
+        (void *)android_hardware_SoundTrigger_loadSoundModel},
+    {"unloadSoundModel",
+        "(I)I",
+        (void *)android_hardware_SoundTrigger_unloadSoundModel},
+    {"startRecognition",
+        "(I[B)I",
+        (void *)android_hardware_SoundTrigger_startRecognition},
+    {"stopRecognition",
+        "(I)I",
+        (void *)android_hardware_SoundTrigger_stopRecognition},
+};
+
+int register_android_hardware_SoundTrigger(JNIEnv *env)
+{
+    jclass arrayListClass = env->FindClass("java/util/ArrayList");
+    gArrayListClass = (jclass) env->NewGlobalRef(arrayListClass);
+    gArrayListMethods.add = env->GetMethodID(arrayListClass, "add", "(Ljava/lang/Object;)Z");
+
+    jclass lClass = env->FindClass(kSoundTriggerClassPathName);
+    gSoundTriggerClass = (jclass) env->NewGlobalRef(lClass);
+
+    jclass moduleClass = env->FindClass(kModuleClassPathName);
+    gModuleClass = (jclass) env->NewGlobalRef(moduleClass);
+    gPostEventFromNative = env->GetStaticMethodID(moduleClass, "postEventFromNative",
+                                            "(Ljava/lang/Object;IIILjava/lang/Object;)V");
+    gModuleFields.mNativeContext = env->GetFieldID(moduleClass, "mNativeContext", "J");
+    gModuleFields.mId = env->GetFieldID(moduleClass, "mId", "I");
+
+
+    jclass modulePropertiesClass = env->FindClass(kModulePropertiesClassPathName);
+    gModulePropertiesClass = (jclass) env->NewGlobalRef(modulePropertiesClass);
+    gModulePropertiesCstor = env->GetMethodID(modulePropertiesClass, "<init>",
+                              "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;IIIIIZIZI)V");
+
+    jclass soundModelClass = env->FindClass(kSoundModelClassPathName);
+    gSoundModelClass = (jclass) env->NewGlobalRef(soundModelClass);
+    gSoundModelFields.data = env->GetFieldID(soundModelClass, "data", "[B");
+
+    jclass keyPhraseClass = env->FindClass(kKeyPhraseClassPathName);
+    gKeyPhraseClass = (jclass) env->NewGlobalRef(keyPhraseClass);
+    gKeyPhraseFields.recognitionModes = env->GetFieldID(keyPhraseClass, "recognitionModes", "I");
+    gKeyPhraseFields.locale = env->GetFieldID(keyPhraseClass, "locale", "Ljava/lang/String;");
+    gKeyPhraseFields.text = env->GetFieldID(keyPhraseClass, "text", "Ljava/lang/String;");
+    gKeyPhraseFields.numUsers = env->GetFieldID(keyPhraseClass, "numUsers", "I");
+
+    jclass keyPhraseSoundModelClass = env->FindClass(kKeyPhraseSoundModelClassPathName);
+    gKeyPhraseSoundModelClass = (jclass) env->NewGlobalRef(keyPhraseSoundModelClass);
+    gKeyPhraseSoundModelFields.keyPhrases = env->GetFieldID(keyPhraseSoundModelClass,
+                                         "keyPhrases",
+                                         "[Landroid/hardware/soundtrigger/SoundTrigger$KeyPhrase;");
+
+
+    jclass recognitionEventClass = env->FindClass(kRecognitionEventClassPathName);
+    gRecognitionEventClass = (jclass) env->NewGlobalRef(recognitionEventClass);
+    gRecognitionEventCstor = env->GetMethodID(recognitionEventClass, "<init>",
+                                              "(IIZII[B)V");
+
+    jclass keyPhraseRecognitionEventClass = env->FindClass(kKeyPhraseRecognitionEventClassPathName);
+    gKeyPhraseRecognitionEventClass = (jclass) env->NewGlobalRef(keyPhraseRecognitionEventClass);
+    gKeyPhraseRecognitionEventCstor = env->GetMethodID(keyPhraseRecognitionEventClass, "<init>",
+              "(IIZII[BZ[Landroid/hardware/soundtrigger/SoundTrigger$KeyPhraseRecognitionExtra;)V");
+
+
+    jclass keyPhraseRecognitionExtraClass = env->FindClass(kKeyPhraseRecognitionExtraClassPathName);
+    gKeyPhraseRecognitionExtraClass = (jclass) env->NewGlobalRef(keyPhraseRecognitionExtraClass);
+    gKeyPhraseRecognitionExtraCstor = env->GetMethodID(keyPhraseRecognitionExtraClass, "<init>",
+                                              "([II)V");
+
+    int status = AndroidRuntime::registerNativeMethods(env,
+                kSoundTriggerClassPathName, gMethods, NELEM(gMethods));
+
+    if (status == 0) {
+        status = AndroidRuntime::registerNativeMethods(env,
+                kModuleClassPathName, gModuleMethods, NELEM(gModuleMethods));
+    }
+
+    return status;
+}
diff --git a/core/jni/android_hardware_camera2_DngCreator.cpp b/core/jni/android_hardware_camera2_DngCreator.cpp
index 7b686e7..33100bf 100644
--- a/core/jni/android_hardware_camera2_DngCreator.cpp
+++ b/core/jni/android_hardware_camera2_DngCreator.cpp
@@ -31,6 +31,8 @@
 #include <utils/RefBase.h>
 #include <cutils/properties.h>
 
+#include <string.h>
+
 #include "android_runtime/AndroidRuntime.h"
 #include "android_runtime/android_hardware_camera2_CameraMetadata.h"
 
@@ -175,7 +177,7 @@
 }
 
 static void DngCreator_init(JNIEnv* env, jobject thiz, jobject characteristicsPtr,
-        jobject resultsPtr) {
+        jobject resultsPtr, jstring formattedCaptureTime) {
     ALOGV("%s:", __FUNCTION__);
     CameraMetadata characteristics;
     CameraMetadata results;
@@ -205,7 +207,6 @@
     OpcodeListBuilder::CfaLayout opcodeCfaLayout = OpcodeListBuilder::CFA_RGGB;
 
     // TODO: Greensplit.
-    // TODO: UniqueCameraModel
     // TODO: Add remaining non-essential tags
     {
         // Set orientation
@@ -352,6 +353,176 @@
     }
 
     {
+        // image description
+        uint8_t imageDescription = '\0'; // empty
+        BAIL_IF_INVALID(writer->addEntry(TAG_IMAGEDESCRIPTION, 1, &imageDescription, TIFF_IFD_0),
+                env, TAG_IMAGEDESCRIPTION);
+    }
+
+    {
+        // make
+        char manufacturer[PROPERTY_VALUE_MAX];
+
+        // Use "" to represent unknown make as suggested in TIFF/EP spec.
+        property_get("ro.product.manufacturer", manufacturer, "");
+        uint32_t count = static_cast<uint32_t>(strlen(manufacturer)) + 1;
+
+        BAIL_IF_INVALID(writer->addEntry(TAG_MAKE, count, reinterpret_cast<uint8_t*>(manufacturer),
+                TIFF_IFD_0), env, TAG_MAKE);
+    }
+
+    {
+        // model
+        char model[PROPERTY_VALUE_MAX];
+
+        // Use "" to represent unknown model as suggested in TIFF/EP spec.
+        property_get("ro.product.model", model, "");
+        uint32_t count = static_cast<uint32_t>(strlen(model)) + 1;
+
+        BAIL_IF_INVALID(writer->addEntry(TAG_MODEL, count, reinterpret_cast<uint8_t*>(model),
+                TIFF_IFD_0), env, TAG_MODEL);
+    }
+
+    {
+        // x resolution
+        uint32_t xres[] = { 72, 1 }; // default 72 ppi
+        BAIL_IF_INVALID(writer->addEntry(TAG_XRESOLUTION, 1, xres, TIFF_IFD_0),
+                env, TAG_XRESOLUTION);
+
+        // y resolution
+        uint32_t yres[] = { 72, 1 }; // default 72 ppi
+        BAIL_IF_INVALID(writer->addEntry(TAG_YRESOLUTION, 1, yres, TIFF_IFD_0),
+                env, TAG_YRESOLUTION);
+
+        uint16_t unit = 2; // inches
+        BAIL_IF_INVALID(writer->addEntry(TAG_RESOLUTIONUNIT, 1, &unit, TIFF_IFD_0),
+                env, TAG_RESOLUTIONUNIT);
+    }
+
+    {
+        // software
+        char software[PROPERTY_VALUE_MAX];
+        property_get("ro.build.fingerprint", software, "");
+        uint32_t count = static_cast<uint32_t>(strlen(software)) + 1;
+        BAIL_IF_INVALID(writer->addEntry(TAG_SOFTWARE, count, reinterpret_cast<uint8_t*>(software),
+                TIFF_IFD_0), env, TAG_SOFTWARE);
+    }
+
+    {
+        // datetime
+        const size_t DATETIME_COUNT = 20;
+        const char* captureTime = env->GetStringUTFChars(formattedCaptureTime, NULL);
+
+        size_t len = strlen(captureTime) + 1;
+        if (len != DATETIME_COUNT) {
+            jniThrowException(env, "java/lang/IllegalArgumentException",
+                    "Timestamp string length is not required 20 characters");
+            return;
+        }
+
+        BAIL_IF_INVALID(writer->addEntry(TAG_DATETIME, DATETIME_COUNT,
+                reinterpret_cast<const uint8_t*>(captureTime), TIFF_IFD_0), env, TAG_DATETIMEORIGINAL);
+
+        // datetime original
+        BAIL_IF_INVALID(writer->addEntry(TAG_DATETIMEORIGINAL, DATETIME_COUNT,
+                reinterpret_cast<const uint8_t*>(captureTime), TIFF_IFD_0), env, TAG_DATETIMEORIGINAL);
+        env->ReleaseStringUTFChars(formattedCaptureTime, captureTime);
+    }
+
+    {
+        // TIFF/EP standard id
+        uint8_t standardId[] = { 1, 0, 0, 0 };
+        BAIL_IF_INVALID(writer->addEntry(TAG_TIFFEPSTANDARDID, 4, standardId,
+                TIFF_IFD_0), env, TAG_TIFFEPSTANDARDID);
+    }
+
+    {
+        // copyright
+        uint8_t copyright = '\0'; // empty
+        BAIL_IF_INVALID(writer->addEntry(TAG_COPYRIGHT, 1, &copyright,
+                TIFF_IFD_0), env, TAG_COPYRIGHT);
+    }
+
+    {
+        // exposure time
+        camera_metadata_entry entry =
+            results.find(ANDROID_SENSOR_EXPOSURE_TIME);
+        BAIL_IF_EMPTY(entry, env, TAG_EXPOSURETIME);
+
+        int64_t exposureTime = *(entry.data.i64);
+
+        if (exposureTime < 0) {
+            // Should be unreachable
+            jniThrowException(env, "java/lang/IllegalArgumentException",
+                    "Negative exposure time in metadata");
+            return;
+        }
+
+        // Ensure exposure time doesn't overflow (for exposures > 4s)
+        uint32_t denominator = 1000000000;
+        while (exposureTime > UINT32_MAX) {
+            exposureTime >>= 1;
+            denominator >>= 1;
+            if (denominator == 0) {
+                // Should be unreachable
+                jniThrowException(env, "java/lang/IllegalArgumentException",
+                        "Exposure time too long");
+                return;
+            }
+        }
+
+        uint32_t exposure[] = { static_cast<uint32_t>(exposureTime), denominator };
+        BAIL_IF_INVALID(writer->addEntry(TAG_EXPOSURETIME, 1, exposure,
+                TIFF_IFD_0), env, TAG_EXPOSURETIME);
+
+    }
+
+    {
+        // ISO speed ratings
+        camera_metadata_entry entry =
+            results.find(ANDROID_SENSOR_SENSITIVITY);
+        BAIL_IF_EMPTY(entry, env, TAG_ISOSPEEDRATINGS);
+
+        int32_t tempIso = *(entry.data.i32);
+        if (tempIso < 0) {
+            jniThrowException(env, "java/lang/IllegalArgumentException",
+                                    "Negative ISO value");
+            return;
+        }
+
+        if (tempIso > UINT16_MAX) {
+            ALOGW("%s: ISO value overflows UINT16_MAX, clamping to max", __FUNCTION__);
+            tempIso = UINT16_MAX;
+        }
+
+        uint16_t iso = static_cast<uint16_t>(tempIso);
+        BAIL_IF_INVALID(writer->addEntry(TAG_ISOSPEEDRATINGS, 1, &iso,
+                TIFF_IFD_0), env, TAG_ISOSPEEDRATINGS);
+    }
+
+    {
+        // focal length
+        camera_metadata_entry entry =
+            results.find(ANDROID_LENS_FOCAL_LENGTH);
+        BAIL_IF_EMPTY(entry, env, TAG_FOCALLENGTH);
+
+        uint32_t focalLength[] = { static_cast<uint32_t>(*(entry.data.f) * 100), 100 };
+        BAIL_IF_INVALID(writer->addEntry(TAG_FOCALLENGTH, 1, focalLength,
+                TIFF_IFD_0), env, TAG_FOCALLENGTH);
+    }
+
+    {
+        // f number
+        camera_metadata_entry entry =
+            results.find(ANDROID_LENS_APERTURE);
+        BAIL_IF_EMPTY(entry, env, TAG_FNUMBER);
+
+        uint32_t fnum[] = { static_cast<uint32_t>(*(entry.data.f) * 100), 100 };
+        BAIL_IF_INVALID(writer->addEntry(TAG_FNUMBER, 1, fnum,
+                TIFF_IFD_0), env, TAG_FNUMBER);
+    }
+
+    {
         // Set DNG version information
         uint8_t version[4] = {1, 4, 0, 0};
         BAIL_IF_INVALID(writer->addEntry(TAG_DNGVERSION, 4, version, TIFF_IFD_0),
@@ -751,7 +922,8 @@
 static JNINativeMethod gDngCreatorMethods[] = {
     {"nativeClassInit",        "()V", (void*) DngCreator_nativeClassInit},
     {"nativeInit", "(Landroid/hardware/camera2/impl/CameraMetadataNative;"
-            "Landroid/hardware/camera2/impl/CameraMetadataNative;)V", (void*) DngCreator_init},
+            "Landroid/hardware/camera2/impl/CameraMetadataNative;Ljava/lang/String;)V",
+            (void*) DngCreator_init},
     {"nativeDestroy",           "()V",      (void*) DngCreator_destroy},
     {"nativeSetOrientation",    "(I)V",     (void*) DngCreator_nativeSetOrientation},
     {"nativeSetThumbnailBitmap","(Landroid/graphics/Bitmap;)V",
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index 0f7e140..bf47dd3 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -613,8 +613,12 @@
                 goto exit;
             }
         }
-        //TODO: replace popcount by audio utils function mask to count
-        int numValues = popcount(nAudioPortConfig->gain.channel_mask);
+        int numValues;
+        if (useInMask) {
+            numValues = audio_channel_count_from_in_mask(nAudioPortConfig->gain.channel_mask);
+        } else {
+            numValues = audio_channel_count_from_out_mask(nAudioPortConfig->gain.channel_mask);
+        }
         jGainValues = env->NewIntArray(numValues);
         if (jGainValues == NULL) {
             ALOGV("convertAudioPortConfigFromNative could not create gain values %d", numValues);
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index ecdfeb2..33fd346 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -575,6 +575,7 @@
 // Text
 // ----------------------------------------------------------------------------
 
+// TODO: this is moving to MinikinUtils, remove with USE_MINIKIN ifdef
 static float xOffsetForTextAlign(SkPaint* paint, float totalAdvance) {
     switch (paint->getTextAlign()) {
         case SkPaint::kCenter_Align:
@@ -590,43 +591,51 @@
 }
 
 #ifdef USE_MINIKIN
+
+class RenderTextFunctor {
+public:
+    RenderTextFunctor(const Layout& layout, OpenGLRenderer* renderer, jfloat x, jfloat y,
+                SkPaint* paint, uint16_t* glyphs, float* pos, float totalAdvance,
+                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) {
+        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,
+            x, y, pos + 2 * start, paint, totalAdvance, bounds);
+    }
+private:
+    const Layout& layout;
+    OpenGLRenderer* renderer;
+    jfloat x;
+    jfloat y;
+    SkPaint* paint;
+    uint16_t* glyphs;
+    float* pos;
+    float totalAdvance;
+    uirenderer::Rect& bounds;
+};
+
 static void renderTextLayout(OpenGLRenderer* renderer, Layout* layout,
     jfloat x, jfloat y, SkPaint* paint) {
     size_t nGlyphs = layout->nGlyphs();
     float* pos = new float[nGlyphs * 2];
     uint16_t* glyphs = new uint16_t[nGlyphs];
-    SkTypeface* lastFace = 0;
-    SkTypeface* skFace = 0;
-    size_t start = 0;
     MinikinRect b;
     layout->getBounds(&b);
     android::uirenderer::Rect bounds(b.mLeft, b.mTop, b.mRight, b.mBottom);
     bounds.translate(x, y);
     float totalAdvance = layout->getAdvance();
 
-    for (size_t i = 0; i < nGlyphs; i++) {
-        MinikinFontSkia* mfs = static_cast<MinikinFontSkia *>(layout->getFont(i));
-        skFace = mfs->GetSkTypeface();
-        glyphs[i] = layout->getGlyphId(i);
-        pos[2 * i] = layout->getX(i);
-        pos[2 * i + 1] = layout->getY(i);
-        if (i > 0 && skFace != lastFace) {
-            paint->setTypeface(lastFace);
-            size_t glyphsCount = i - start;
-            int bytesCount = glyphsCount * sizeof(jchar);
-            renderer->drawText((const char*) (glyphs + start), bytesCount, glyphsCount,
-                x, y, pos + 2 * start, paint, totalAdvance, bounds);
-            start = i;
-        }
-        lastFace = skFace;
-    }
-    if (skFace != NULL) {
-        paint->setTypeface(skFace);
-        size_t glyphsCount = nGlyphs - start;
-        int bytesCount = glyphsCount * sizeof(jchar);
-        renderer->drawText((const char*) (glyphs + start), bytesCount, glyphsCount,
-            x, y, pos + 2 * start, paint, totalAdvance, bounds);
-    }
+    RenderTextFunctor f(*layout, renderer, x, y, paint, glyphs, pos, totalAdvance, bounds);
+    MinikinUtils::forFontRun(*layout, f);
     delete[] glyphs;
     delete[] pos;
 }
@@ -636,8 +645,8 @@
         jfloat x, jfloat y, int flags, SkPaint* paint, TypefaceImpl* typeface) {
 #ifdef USE_MINIKIN
     Layout layout;
-    MinikinUtils::SetLayoutProperties(&layout, paint, flags, typeface);
-    layout.doLayout(text, count);
+    std::string css = MinikinUtils::setLayoutProperties(&layout, paint, flags, typeface);
+    layout.doLayout(text, 0, count, count, css);
     x += xOffsetForTextAlign(paint, layout.getAdvance());
     renderTextLayout(renderer, &layout, x, y, paint);
 #else
@@ -680,8 +689,8 @@
         int flags, SkPaint* paint, TypefaceImpl* typeface) {
 #ifdef USE_MINIKIN
     Layout layout;
-    MinikinUtils::SetLayoutProperties(&layout, paint, flags, typeface);
-    layout.doLayout(text + start, count);
+    std::string css = MinikinUtils::setLayoutProperties(&layout, paint, flags, typeface);
+    layout.doLayout(text, start, count, contextCount, css);
     x += xOffsetForTextAlign(paint, layout.getAdvance());
     renderTextLayout(renderer, &layout, x, y, paint);
 #else
diff --git a/core/jni/android_view_HardwareLayer.cpp b/core/jni/android_view_HardwareLayer.cpp
index 879836d..64b077b 100644
--- a/core/jni/android_view_HardwareLayer.cpp
+++ b/core/jni/android_view_HardwareLayer.cpp
@@ -95,13 +95,6 @@
     layer->setDisplayList(displayList, left, top, right, bottom);
 }
 
-static jboolean android_view_HardwareLayer_flushChanges(JNIEnv* env, jobject clazz,
-        jlong layerUpdaterPtr) {
-    DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerUpdaterPtr);
-    TreeInfo ignoredInfo;
-    return layer->apply(ignoredInfo);
-}
-
 static jlong android_view_HardwareLayer_getLayer(JNIEnv* env, jobject clazz,
         jlong layerUpdaterPtr) {
     DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerUpdaterPtr);
@@ -135,8 +128,6 @@
     { "nUpdateSurfaceTexture",   "(J)V",       (void*) android_view_HardwareLayer_updateSurfaceTexture },
     { "nUpdateRenderLayer",      "(JJIIII)V",  (void*) android_view_HardwareLayer_updateRenderLayer },
 
-    { "nFlushChanges",           "(J)Z",       (void*) android_view_HardwareLayer_flushChanges },
-
     { "nGetLayer",               "(J)J",       (void*) android_view_HardwareLayer_getLayer },
     { "nGetTexName",             "(J)I",       (void*) android_view_HardwareLayer_getTexName },
 #endif
diff --git a/core/jni/android_view_RenderNode.cpp b/core/jni/android_view_RenderNode.cpp
index 26022e0..e5f79f2 100644
--- a/core/jni/android_view_RenderNode.cpp
+++ b/core/jni/android_view_RenderNode.cpp
@@ -38,6 +38,11 @@
  */
 #ifdef USE_OPENGL_RENDERER
 
+#define SET_AND_DIRTY(prop, val, dirtyFlag) \
+    (reinterpret_cast<RenderNode*>(renderNodePtr)->mutateStagingProperties().prop(val) \
+        ? (reinterpret_cast<RenderNode*>(renderNodePtr)->setPropertyFieldsDirty(dirtyFlag), true) \
+        : false)
+
 // ----------------------------------------------------------------------------
 // DisplayList view properties
 // ----------------------------------------------------------------------------
@@ -82,235 +87,199 @@
 // RenderProperties - setters
 // ----------------------------------------------------------------------------
 
-static void android_view_RenderNode_setCaching(JNIEnv* env,
+static jboolean android_view_RenderNode_setCaching(JNIEnv* env,
         jobject clazz, jlong renderNodePtr, jboolean caching) {
-    RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
-    renderNode->mutateStagingProperties().setCaching(caching);
-    renderNode->setPropertyFieldsDirty(RenderNode::GENERIC);
+    return SET_AND_DIRTY(setCaching, caching, RenderNode::GENERIC);
 }
 
-static void android_view_RenderNode_setStaticMatrix(JNIEnv* env,
+static jboolean android_view_RenderNode_setStaticMatrix(JNIEnv* env,
         jobject clazz, jlong renderNodePtr, jlong matrixPtr) {
-    RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
-    renderNode->mutateStagingProperties().setStaticMatrix(matrix);
-    renderNode->setPropertyFieldsDirty(RenderNode::GENERIC);
+    return SET_AND_DIRTY(setStaticMatrix, matrix, RenderNode::GENERIC);
 }
 
-static void android_view_RenderNode_setAnimationMatrix(JNIEnv* env,
+static jboolean android_view_RenderNode_setAnimationMatrix(JNIEnv* env,
         jobject clazz, jlong renderNodePtr, jlong matrixPtr) {
-    RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
-    renderNode->mutateStagingProperties().setAnimationMatrix(matrix);
-    renderNode->setPropertyFieldsDirty(RenderNode::GENERIC);
+    return SET_AND_DIRTY(setAnimationMatrix, matrix, RenderNode::GENERIC);
 }
 
-static void android_view_RenderNode_setClipToBounds(JNIEnv* env,
+static jboolean android_view_RenderNode_setClipToBounds(JNIEnv* env,
         jobject clazz, jlong renderNodePtr, jboolean clipToBounds) {
-    RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
-    renderNode->mutateStagingProperties().setClipToBounds(clipToBounds);
-    renderNode->setPropertyFieldsDirty(RenderNode::GENERIC);
+    return SET_AND_DIRTY(setClipToBounds, clipToBounds, RenderNode::GENERIC);
 }
 
-static void android_view_RenderNode_setProjectBackwards(JNIEnv* env,
+static jboolean android_view_RenderNode_setProjectBackwards(JNIEnv* env,
         jobject clazz, jlong renderNodePtr, jboolean shouldProject) {
-    RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
-    renderNode->mutateStagingProperties().setProjectBackwards(shouldProject);
-    renderNode->setPropertyFieldsDirty(RenderNode::GENERIC);
+    return SET_AND_DIRTY(setProjectBackwards, shouldProject, RenderNode::GENERIC);
 }
 
-static void android_view_RenderNode_setProjectionReceiver(JNIEnv* env,
+static jboolean android_view_RenderNode_setProjectionReceiver(JNIEnv* env,
         jobject clazz, jlong renderNodePtr, jboolean shouldRecieve) {
-    RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
-    renderNode->mutateStagingProperties().setProjectionReceiver(shouldRecieve);
-    renderNode->setPropertyFieldsDirty(RenderNode::GENERIC);
+    return SET_AND_DIRTY(setProjectionReceiver, shouldRecieve, RenderNode::GENERIC);
 }
 
-static void android_view_RenderNode_setOutlineRoundRect(JNIEnv* env,
+static jboolean android_view_RenderNode_setOutlineRoundRect(JNIEnv* env,
         jobject clazz, jlong renderNodePtr, jint left, jint top,
         jint right, jint bottom, jfloat radius) {
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     renderNode->mutateStagingProperties().mutableOutline().setRoundRect(left, top, right, bottom, radius);
     renderNode->setPropertyFieldsDirty(RenderNode::GENERIC);
+    return true;
 }
 
-static void android_view_RenderNode_setOutlineConvexPath(JNIEnv* env,
+static jboolean android_view_RenderNode_setOutlineConvexPath(JNIEnv* env,
         jobject clazz, jlong renderNodePtr, jlong outlinePathPtr) {
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     SkPath* outlinePath = reinterpret_cast<SkPath*>(outlinePathPtr);
     renderNode->mutateStagingProperties().mutableOutline().setConvexPath(outlinePath);
     renderNode->setPropertyFieldsDirty(RenderNode::GENERIC);
+    return true;
 }
 
-static void android_view_RenderNode_setOutlineEmpty(JNIEnv* env,
+static jboolean android_view_RenderNode_setOutlineEmpty(JNIEnv* env,
         jobject clazz, jlong renderNodePtr) {
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     renderNode->mutateStagingProperties().mutableOutline().setEmpty();
     renderNode->setPropertyFieldsDirty(RenderNode::GENERIC);
+    return true;
 }
 
-static void android_view_RenderNode_setClipToOutline(JNIEnv* env,
+static jboolean android_view_RenderNode_setClipToOutline(JNIEnv* env,
         jobject clazz, jlong renderNodePtr, jboolean clipToOutline) {
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     renderNode->mutateStagingProperties().mutableOutline().setShouldClip(clipToOutline);
     renderNode->setPropertyFieldsDirty(RenderNode::GENERIC);
+    return true;
 }
 
-static void android_view_RenderNode_setRevealClip(JNIEnv* env,
+static jboolean android_view_RenderNode_setRevealClip(JNIEnv* env,
         jobject clazz, jlong renderNodePtr, jboolean shouldClip, jboolean inverseClip,
         jfloat x, jfloat y, jfloat radius) {
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     renderNode->mutateStagingProperties().mutableRevealClip().set(
             shouldClip, inverseClip, x, y, radius);
     renderNode->setPropertyFieldsDirty(RenderNode::GENERIC);
+    return true;
 }
 
-static void android_view_RenderNode_setAlpha(JNIEnv* env,
+static jboolean android_view_RenderNode_setAlpha(JNIEnv* env,
         jobject clazz, jlong renderNodePtr, float alpha) {
-    RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
-    renderNode->mutateStagingProperties().setAlpha(alpha);
-    renderNode->setPropertyFieldsDirty(RenderNode::ALPHA);
+    return SET_AND_DIRTY(setAlpha, alpha, RenderNode::ALPHA);
 }
 
-static void android_view_RenderNode_setHasOverlappingRendering(JNIEnv* env,
+static jboolean android_view_RenderNode_setHasOverlappingRendering(JNIEnv* env,
         jobject clazz, jlong renderNodePtr, bool hasOverlappingRendering) {
-    RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
-    renderNode->mutateStagingProperties().setHasOverlappingRendering(hasOverlappingRendering);
-    renderNode->setPropertyFieldsDirty(RenderNode::GENERIC);
+    return SET_AND_DIRTY(setHasOverlappingRendering, hasOverlappingRendering,
+            RenderNode::GENERIC);
 }
 
-static void android_view_RenderNode_setElevation(JNIEnv* env,
+static jboolean android_view_RenderNode_setElevation(JNIEnv* env,
         jobject clazz, jlong renderNodePtr, float elevation) {
-    RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
-    renderNode->mutateStagingProperties().setElevation(elevation);
-    renderNode->setPropertyFieldsDirty(RenderNode::Z);
+    return SET_AND_DIRTY(setElevation, elevation, RenderNode::Z);
 }
 
-static void android_view_RenderNode_setTranslationX(JNIEnv* env,
+static jboolean android_view_RenderNode_setTranslationX(JNIEnv* env,
         jobject clazz, jlong renderNodePtr, float tx) {
-    RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
-    renderNode->mutateStagingProperties().setTranslationX(tx);
-    renderNode->setPropertyFieldsDirty(RenderNode::TRANSLATION_X | RenderNode::X);
+    return SET_AND_DIRTY(setTranslationX, tx, RenderNode::TRANSLATION_X | RenderNode::X);
 }
 
-static void android_view_RenderNode_setTranslationY(JNIEnv* env,
+static jboolean android_view_RenderNode_setTranslationY(JNIEnv* env,
         jobject clazz, jlong renderNodePtr, float ty) {
-    RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
-    renderNode->mutateStagingProperties().setTranslationY(ty);
-    renderNode->setPropertyFieldsDirty(RenderNode::TRANSLATION_Y | RenderNode::Y);
+    return SET_AND_DIRTY(setTranslationY, ty, RenderNode::TRANSLATION_Y | RenderNode::Y);
 }
 
-static void android_view_RenderNode_setTranslationZ(JNIEnv* env,
+static jboolean android_view_RenderNode_setTranslationZ(JNIEnv* env,
         jobject clazz, jlong renderNodePtr, float tz) {
-    RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
-    renderNode->mutateStagingProperties().setTranslationZ(tz);
-    renderNode->setPropertyFieldsDirty(RenderNode::TRANSLATION_Z | RenderNode::Z);
+    return SET_AND_DIRTY(setTranslationZ, tz, RenderNode::TRANSLATION_Z | RenderNode::Z);
 }
 
-static void android_view_RenderNode_setRotation(JNIEnv* env,
+static jboolean android_view_RenderNode_setRotation(JNIEnv* env,
         jobject clazz, jlong renderNodePtr, float rotation) {
-    RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
-    renderNode->mutateStagingProperties().setRotation(rotation);
-    renderNode->setPropertyFieldsDirty(RenderNode::ROTATION);
+    return SET_AND_DIRTY(setRotation, rotation, RenderNode::ROTATION);
 }
 
-static void android_view_RenderNode_setRotationX(JNIEnv* env,
+static jboolean android_view_RenderNode_setRotationX(JNIEnv* env,
         jobject clazz, jlong renderNodePtr, float rx) {
-    RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
-    renderNode->mutateStagingProperties().setRotationX(rx);
-    renderNode->setPropertyFieldsDirty(RenderNode::ROTATION_X);
+    return SET_AND_DIRTY(setRotationX, rx, RenderNode::ROTATION_X);
 }
 
-static void android_view_RenderNode_setRotationY(JNIEnv* env,
+static jboolean android_view_RenderNode_setRotationY(JNIEnv* env,
         jobject clazz, jlong renderNodePtr, float ry) {
-    RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
-    renderNode->mutateStagingProperties().setRotationY(ry);
-    renderNode->setPropertyFieldsDirty(RenderNode::ROTATION_Y);
+    return SET_AND_DIRTY(setRotationY, ry, RenderNode::ROTATION_Y);
 }
 
-static void android_view_RenderNode_setScaleX(JNIEnv* env,
+static jboolean android_view_RenderNode_setScaleX(JNIEnv* env,
         jobject clazz, jlong renderNodePtr, float sx) {
-    RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
-    renderNode->mutateStagingProperties().setScaleX(sx);
-    renderNode->setPropertyFieldsDirty(RenderNode::SCALE_X);
+    return SET_AND_DIRTY(setScaleX, sx, RenderNode::SCALE_X);
 }
 
-static void android_view_RenderNode_setScaleY(JNIEnv* env,
+static jboolean android_view_RenderNode_setScaleY(JNIEnv* env,
         jobject clazz, jlong renderNodePtr, float sy) {
-    RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
-    renderNode->mutateStagingProperties().setScaleY(sy);
-    renderNode->setPropertyFieldsDirty(RenderNode::SCALE_Y);
+    return SET_AND_DIRTY(setScaleY, sy, RenderNode::SCALE_Y);
 }
 
-static void android_view_RenderNode_setPivotX(JNIEnv* env,
+static jboolean android_view_RenderNode_setPivotX(JNIEnv* env,
         jobject clazz, jlong renderNodePtr, float px) {
-    RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
-    renderNode->mutateStagingProperties().setPivotX(px);
-    renderNode->setPropertyFieldsDirty(RenderNode::GENERIC);
+    return SET_AND_DIRTY(setPivotX, px, RenderNode::GENERIC);
 }
 
-static void android_view_RenderNode_setPivotY(JNIEnv* env,
+static jboolean android_view_RenderNode_setPivotY(JNIEnv* env,
         jobject clazz, jlong renderNodePtr, float py) {
-    RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
-    renderNode->mutateStagingProperties().setPivotY(py);
-    renderNode->setPropertyFieldsDirty(RenderNode::GENERIC);
+    return SET_AND_DIRTY(setPivotY, py, RenderNode::GENERIC);
 }
 
-static void android_view_RenderNode_setCameraDistance(JNIEnv* env,
+static jboolean android_view_RenderNode_setCameraDistance(JNIEnv* env,
         jobject clazz, jlong renderNodePtr, float distance) {
-    RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
-    renderNode->mutateStagingProperties().setCameraDistance(distance);
-    renderNode->setPropertyFieldsDirty(RenderNode::GENERIC);
+    return SET_AND_DIRTY(setCameraDistance, distance, RenderNode::GENERIC);
 }
 
-static void android_view_RenderNode_setLeft(JNIEnv* env,
+static jboolean android_view_RenderNode_setLeft(JNIEnv* env,
         jobject clazz, jlong renderNodePtr, int left) {
-    RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
-    renderNode->mutateStagingProperties().setLeft(left);
-    renderNode->setPropertyFieldsDirty(RenderNode::X);
+    return SET_AND_DIRTY(setLeft, left, RenderNode::X);
 }
 
-static void android_view_RenderNode_setTop(JNIEnv* env,
+static jboolean android_view_RenderNode_setTop(JNIEnv* env,
         jobject clazz, jlong renderNodePtr, int top) {
-    RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
-    renderNode->mutateStagingProperties().setTop(top);
-    renderNode->setPropertyFieldsDirty(RenderNode::Y);
+    return SET_AND_DIRTY(setTop, top, RenderNode::Y);
 }
 
-static void android_view_RenderNode_setRight(JNIEnv* env,
+static jboolean android_view_RenderNode_setRight(JNIEnv* env,
         jobject clazz, jlong renderNodePtr, int right) {
-    RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
-    renderNode->mutateStagingProperties().setRight(right);
-    renderNode->setPropertyFieldsDirty(RenderNode::X);
+    return SET_AND_DIRTY(setRight, right, RenderNode::X);
 }
 
-static void android_view_RenderNode_setBottom(JNIEnv* env,
+static jboolean android_view_RenderNode_setBottom(JNIEnv* env,
         jobject clazz, jlong renderNodePtr, int bottom) {
-    RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
-    renderNode->mutateStagingProperties().setBottom(bottom);
-    renderNode->setPropertyFieldsDirty(RenderNode::Y);
+    return SET_AND_DIRTY(setBottom, bottom, RenderNode::Y);
 }
 
-static void android_view_RenderNode_setLeftTopRightBottom(JNIEnv* env,
+static jboolean android_view_RenderNode_setLeftTopRightBottom(JNIEnv* env,
         jobject clazz, jlong renderNodePtr, int left, int top,
         int right, int bottom) {
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
-    renderNode->mutateStagingProperties().setLeftTopRightBottom(left, top, right, bottom);
-    renderNode->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y);
+    if (renderNode->mutateStagingProperties().setLeftTopRightBottom(left, top, right, bottom)) {
+        renderNode->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y);
+        return true;
+    }
+    return false;
 }
 
-static void android_view_RenderNode_offsetLeftAndRight(JNIEnv* env,
+static jboolean android_view_RenderNode_offsetLeftAndRight(JNIEnv* env,
         jobject clazz, jlong renderNodePtr, float offset) {
-    RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
-    renderNode->mutateStagingProperties().offsetLeftRight(offset);
-    renderNode->setPropertyFieldsDirty(RenderNode::X);
+    return SET_AND_DIRTY(offsetLeftRight, offset, RenderNode::X);
 }
 
-static void android_view_RenderNode_offsetTopAndBottom(JNIEnv* env,
+static jboolean android_view_RenderNode_offsetTopAndBottom(JNIEnv* env,
         jobject clazz, jlong renderNodePtr, float offset) {
+    return SET_AND_DIRTY(offsetTopBottom, offset, RenderNode::Y);
+}
+
+static void android_view_RenderNode_setScrollPosition(JNIEnv* env,
+        jobject clazz, jlong renderNodePtr, jint scrollX, jint scrollY) {
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
-    renderNode->mutateStagingProperties().offsetTopBottom(offset);
-    renderNode->setPropertyFieldsDirty(RenderNode::Y);
+    SET_AND_DIRTY(setScrollX, scrollX, RenderNode::GENERIC);
+    SET_AND_DIRTY(setScrollY, scrollY, RenderNode::GENERIC);
 }
 
 // ----------------------------------------------------------------------------
@@ -513,41 +482,42 @@
     { "nOutput",               "(J)V",  (void*) android_view_RenderNode_output },
     { "nGetDebugSize",         "(J)I",  (void*) android_view_RenderNode_getDebugSize },
 
-    { "nSetCaching",           "(JZ)V",  (void*) android_view_RenderNode_setCaching },
-    { "nSetStaticMatrix",      "(JJ)V",  (void*) android_view_RenderNode_setStaticMatrix },
-    { "nSetAnimationMatrix",   "(JJ)V",  (void*) android_view_RenderNode_setAnimationMatrix },
-    { "nSetClipToBounds",      "(JZ)V",  (void*) android_view_RenderNode_setClipToBounds },
-    { "nSetProjectBackwards",  "(JZ)V",  (void*) android_view_RenderNode_setProjectBackwards },
-    { "nSetProjectionReceiver","(JZ)V",  (void*) android_view_RenderNode_setProjectionReceiver },
+    { "nSetCaching",           "(JZ)Z",  (void*) android_view_RenderNode_setCaching },
+    { "nSetStaticMatrix",      "(JJ)Z",  (void*) android_view_RenderNode_setStaticMatrix },
+    { "nSetAnimationMatrix",   "(JJ)Z",  (void*) android_view_RenderNode_setAnimationMatrix },
+    { "nSetClipToBounds",      "(JZ)Z",  (void*) android_view_RenderNode_setClipToBounds },
+    { "nSetProjectBackwards",  "(JZ)Z",  (void*) android_view_RenderNode_setProjectBackwards },
+    { "nSetProjectionReceiver","(JZ)Z",  (void*) android_view_RenderNode_setProjectionReceiver },
 
-    { "nSetOutlineRoundRect",  "(JIIIIF)V", (void*) android_view_RenderNode_setOutlineRoundRect },
-    { "nSetOutlineConvexPath", "(JJ)V",  (void*) android_view_RenderNode_setOutlineConvexPath },
-    { "nSetOutlineEmpty",      "(J)V",   (void*) android_view_RenderNode_setOutlineEmpty },
-    { "nSetClipToOutline",     "(JZ)V",  (void*) android_view_RenderNode_setClipToOutline },
-    { "nSetRevealClip",        "(JZZFFF)V", (void*) android_view_RenderNode_setRevealClip },
+    { "nSetOutlineRoundRect",  "(JIIIIF)Z", (void*) android_view_RenderNode_setOutlineRoundRect },
+    { "nSetOutlineConvexPath", "(JJ)Z",  (void*) android_view_RenderNode_setOutlineConvexPath },
+    { "nSetOutlineEmpty",      "(J)Z",   (void*) android_view_RenderNode_setOutlineEmpty },
+    { "nSetClipToOutline",     "(JZ)Z",  (void*) android_view_RenderNode_setClipToOutline },
+    { "nSetRevealClip",        "(JZZFFF)Z", (void*) android_view_RenderNode_setRevealClip },
 
-    { "nSetAlpha",             "(JF)V",  (void*) android_view_RenderNode_setAlpha },
-    { "nSetHasOverlappingRendering", "(JZ)V",
+    { "nSetAlpha",             "(JF)Z",  (void*) android_view_RenderNode_setAlpha },
+    { "nSetHasOverlappingRendering", "(JZ)Z",
             (void*) android_view_RenderNode_setHasOverlappingRendering },
-    { "nSetElevation",         "(JF)V",  (void*) android_view_RenderNode_setElevation },
-    { "nSetTranslationX",      "(JF)V",  (void*) android_view_RenderNode_setTranslationX },
-    { "nSetTranslationY",      "(JF)V",  (void*) android_view_RenderNode_setTranslationY },
-    { "nSetTranslationZ",      "(JF)V",  (void*) android_view_RenderNode_setTranslationZ },
-    { "nSetRotation",          "(JF)V",  (void*) android_view_RenderNode_setRotation },
-    { "nSetRotationX",         "(JF)V",  (void*) android_view_RenderNode_setRotationX },
-    { "nSetRotationY",         "(JF)V",  (void*) android_view_RenderNode_setRotationY },
-    { "nSetScaleX",            "(JF)V",  (void*) android_view_RenderNode_setScaleX },
-    { "nSetScaleY",            "(JF)V",  (void*) android_view_RenderNode_setScaleY },
-    { "nSetPivotX",            "(JF)V",  (void*) android_view_RenderNode_setPivotX },
-    { "nSetPivotY",            "(JF)V",  (void*) android_view_RenderNode_setPivotY },
-    { "nSetCameraDistance",    "(JF)V",  (void*) android_view_RenderNode_setCameraDistance },
-    { "nSetLeft",              "(JI)V",  (void*) android_view_RenderNode_setLeft },
-    { "nSetTop",               "(JI)V",  (void*) android_view_RenderNode_setTop },
-    { "nSetRight",             "(JI)V",  (void*) android_view_RenderNode_setRight },
-    { "nSetBottom",            "(JI)V",  (void*) android_view_RenderNode_setBottom },
-    { "nSetLeftTopRightBottom","(JIIII)V", (void*) android_view_RenderNode_setLeftTopRightBottom },
-    { "nOffsetLeftAndRight",   "(JF)V",  (void*) android_view_RenderNode_offsetLeftAndRight },
-    { "nOffsetTopAndBottom",   "(JF)V",  (void*) android_view_RenderNode_offsetTopAndBottom },
+    { "nSetElevation",         "(JF)Z",  (void*) android_view_RenderNode_setElevation },
+    { "nSetTranslationX",      "(JF)Z",  (void*) android_view_RenderNode_setTranslationX },
+    { "nSetTranslationY",      "(JF)Z",  (void*) android_view_RenderNode_setTranslationY },
+    { "nSetTranslationZ",      "(JF)Z",  (void*) android_view_RenderNode_setTranslationZ },
+    { "nSetRotation",          "(JF)Z",  (void*) android_view_RenderNode_setRotation },
+    { "nSetRotationX",         "(JF)Z",  (void*) android_view_RenderNode_setRotationX },
+    { "nSetRotationY",         "(JF)Z",  (void*) android_view_RenderNode_setRotationY },
+    { "nSetScaleX",            "(JF)Z",  (void*) android_view_RenderNode_setScaleX },
+    { "nSetScaleY",            "(JF)Z",  (void*) android_view_RenderNode_setScaleY },
+    { "nSetPivotX",            "(JF)Z",  (void*) android_view_RenderNode_setPivotX },
+    { "nSetPivotY",            "(JF)Z",  (void*) android_view_RenderNode_setPivotY },
+    { "nSetCameraDistance",    "(JF)Z",  (void*) android_view_RenderNode_setCameraDistance },
+    { "nSetLeft",              "(JI)Z",  (void*) android_view_RenderNode_setLeft },
+    { "nSetTop",               "(JI)Z",  (void*) android_view_RenderNode_setTop },
+    { "nSetRight",             "(JI)Z",  (void*) android_view_RenderNode_setRight },
+    { "nSetBottom",            "(JI)Z",  (void*) android_view_RenderNode_setBottom },
+    { "nSetLeftTopRightBottom","(JIIII)Z", (void*) android_view_RenderNode_setLeftTopRightBottom },
+    { "nOffsetLeftAndRight",   "(JF)Z",  (void*) android_view_RenderNode_offsetLeftAndRight },
+    { "nOffsetTopAndBottom",   "(JF)Z",  (void*) android_view_RenderNode_offsetTopAndBottom },
+    { "nSetScrollPosition",    "(JII)V", (void*) android_view_RenderNode_setScrollPosition },
 
     { "nHasOverlappingRendering", "(J)Z",  (void*) android_view_RenderNode_hasOverlappingRendering },
     { "nGetClipToOutline",        "(J)Z",  (void*) android_view_RenderNode_getClipToOutline },
diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp
index a550649..815c4a7 100644
--- a/core/jni/android_view_ThreadedRenderer.cpp
+++ b/core/jni/android_view_ThreadedRenderer.cpp
@@ -150,6 +150,13 @@
         }
     }
 
+protected:
+    virtual void damageSelf(TreeInfo& info) {
+        // Intentionally a no-op. As RootRenderNode gets a new DisplayListData
+        // every frame this would result in every draw push being a full inval,
+        // which is wrong. Only RootRenderNode has this issue.
+    }
+
 private:
     sp<Looper> mLooper;
     std::vector<OnFinishedEvent> mOnFinishedEvents;
@@ -242,11 +249,9 @@
 }
 
 static int android_view_ThreadedRenderer_syncAndDrawFrame(JNIEnv* env, jobject clazz,
-        jlong proxyPtr, jlong frameTimeNanos, jlong recordDuration, jfloat density,
-        jint dirtyLeft, jint dirtyTop, jint dirtyRight, jint dirtyBottom) {
+        jlong proxyPtr, jlong frameTimeNanos, jlong recordDuration, jfloat density) {
     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
-    return proxy->syncAndDrawFrame(frameTimeNanos, recordDuration, density,
-            dirtyLeft, dirtyTop, dirtyRight, dirtyBottom);
+    return proxy->syncAndDrawFrame(frameTimeNanos, recordDuration, density);
 }
 
 static void android_view_ThreadedRenderer_destroyCanvasAndSurface(JNIEnv* env, jobject clazz,
@@ -363,7 +368,7 @@
     { "nPauseSurface", "(JLandroid/view/Surface;)V", (void*) android_view_ThreadedRenderer_pauseSurface },
     { "nSetup", "(JIIFFFF)V", (void*) android_view_ThreadedRenderer_setup },
     { "nSetOpaque", "(JZ)V", (void*) android_view_ThreadedRenderer_setOpaque },
-    { "nSyncAndDrawFrame", "(JJJFIIII)I", (void*) android_view_ThreadedRenderer_syncAndDrawFrame },
+    { "nSyncAndDrawFrame", "(JJJF)I", (void*) android_view_ThreadedRenderer_syncAndDrawFrame },
     { "nDestroyCanvasAndSurface", "(J)V", (void*) android_view_ThreadedRenderer_destroyCanvasAndSurface },
     { "nInvokeFunctor", "(JJZ)V", (void*) android_view_ThreadedRenderer_invokeFunctor },
     { "nRunWithGlContext", "(JLjava/lang/Runnable;)V", (void*) android_view_ThreadedRenderer_runWithGlContext },
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index fe703b2..e4cbf5f 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -74,6 +74,8 @@
     <protected-broadcast android:name="android.intent.action.USER_FOREGROUND" />
     <protected-broadcast android:name="android.intent.action.USER_SWITCHED" />
 
+    <protected-broadcast android:name="android.os.action.POWER_SAVE_MODE_CHANGED" />
+
     <protected-broadcast android:name="android.app.action.ENTER_CAR_MODE" />
     <protected-broadcast android:name="android.app.action.EXIT_CAR_MODE" />
     <protected-broadcast android:name="android.app.action.ENTER_DESK_MODE" />
@@ -2239,6 +2241,14 @@
         android:description="@string/permdesc_captureAudioHotword"
         android:protectionLevel="signature|system" />
 
+    <!-- Allows an application to modify audio routing and override policy decisions.
+         <p>Not for use by third-party applications.</p>
+         @hide -->
+    <permission android:name="android.permission.MODIFY_AUDIO_ROUTING"
+        android:label="@string/permlab_modifyAudioRouting"
+        android:description="@string/permdesc_modifyAudioRouting"
+        android:protectionLevel="signature|system" />
+
     <!-- Allows an application to capture video output.
          <p>Not for use by third-party applications.</p> -->
     <permission android:name="android.permission.CAPTURE_VIDEO_OUTPUT"
@@ -2616,6 +2626,13 @@
                 android:label="@string/permlab_trust_listener"
                 android:description="@string/permdesc_trust_listener" />
 
+    <!-- Allows an application to provide a trust agent.
+         @hide For security reasons, this is a platform-only permission. -->
+    <permission android:name="android.permission.PROVIDE_TRUST_AGENT"
+                android:protectionLevel="signatureOrSystem"
+                android:label="@string/permlab_provide_trust_agent"
+                android:description="@string/permdesc_provide_trust_agent" />
+
     <!-- Must be required by an {@link
          android.service.trust.TrustAgentService},
          to ensure that only the system can bind to it. -->
diff --git a/core/res/res/anim/button_state_list_anim_quantum.xml b/core/res/res/anim/button_state_list_anim_material.xml
similarity index 100%
rename from core/res/res/anim/button_state_list_anim_quantum.xml
rename to core/res/res/anim/button_state_list_anim_material.xml
diff --git a/core/res/res/anim/popup_enter_quantum.xml b/core/res/res/anim/popup_enter_material.xml
similarity index 100%
rename from core/res/res/anim/popup_enter_quantum.xml
rename to core/res/res/anim/popup_enter_material.xml
diff --git a/core/res/res/anim/popup_exit_quantum.xml b/core/res/res/anim/popup_exit_material.xml
similarity index 100%
rename from core/res/res/anim/popup_exit_quantum.xml
rename to core/res/res/anim/popup_exit_material.xml
diff --git a/core/res/res/color/background_cache_hint_selector_quantum_light.xml b/core/res/res/color/background_cache_hint_selector_material_dark.xml
similarity index 95%
copy from core/res/res/color/background_cache_hint_selector_quantum_light.xml
copy to core/res/res/color/background_cache_hint_selector_material_dark.xml
index fb940a9..e7c9426 100644
--- a/core/res/res/color/background_cache_hint_selector_quantum_light.xml
+++ b/core/res/res/color/background_cache_hint_selector_material_dark.xml
@@ -15,6 +15,6 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_accelerated="false" android:color="@android:color/background_quantum_light" />
+    <item android:state_accelerated="false" android:color="@android:color/background_material_dark" />
     <item android:color="@android:color/transparent" />
 </selector>
diff --git a/core/res/res/color/background_cache_hint_selector_quantum_light.xml b/core/res/res/color/background_cache_hint_selector_material_light.xml
similarity index 95%
rename from core/res/res/color/background_cache_hint_selector_quantum_light.xml
rename to core/res/res/color/background_cache_hint_selector_material_light.xml
index fb940a9..96f1f59 100644
--- a/core/res/res/color/background_cache_hint_selector_quantum_light.xml
+++ b/core/res/res/color/background_cache_hint_selector_material_light.xml
@@ -15,6 +15,6 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_accelerated="false" android:color="@android:color/background_quantum_light" />
+    <item android:state_accelerated="false" android:color="@android:color/background_material_light" />
     <item android:color="@android:color/transparent" />
 </selector>
diff --git a/core/res/res/color/background_cache_hint_selector_quantum_dark.xml b/core/res/res/color/background_cache_hint_selector_quantum_dark.xml
deleted file mode 100644
index ab66501..0000000
--- a/core/res/res/color/background_cache_hint_selector_quantum_dark.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_accelerated="false" android:color="@android:color/background_quantum_dark" />
-    <item android:color="@android:color/transparent" />
-</selector>
diff --git a/core/res/res/color/btn_default_quantum_dark.xml b/core/res/res/color/btn_default_material_dark.xml
similarity index 89%
rename from core/res/res/color/btn_default_quantum_dark.xml
rename to core/res/res/color/btn_default_material_dark.xml
index ec0f140..59555ae 100644
--- a/core/res/res/color/btn_default_quantum_dark.xml
+++ b/core/res/res/color/btn_default_material_dark.xml
@@ -15,6 +15,6 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_enabled="false" android:alpha="0.5" android:color="@color/button_quantum_dark"/>
-    <item android:color="@color/button_quantum_dark"/>
+    <item android:state_enabled="false" android:alpha="0.5" android:color="@color/button_material_dark"/>
+    <item android:color="@color/button_material_dark"/>
 </selector>
diff --git a/core/res/res/color/btn_default_quantum_dark.xml b/core/res/res/color/btn_default_material_light.xml
similarity index 88%
copy from core/res/res/color/btn_default_quantum_dark.xml
copy to core/res/res/color/btn_default_material_light.xml
index ec0f140..6511a22 100644
--- a/core/res/res/color/btn_default_quantum_dark.xml
+++ b/core/res/res/color/btn_default_material_light.xml
@@ -15,6 +15,6 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_enabled="false" android:alpha="0.5" android:color="@color/button_quantum_dark"/>
-    <item android:color="@color/button_quantum_dark"/>
+    <item android:state_enabled="false" android:alpha="0.5" android:color="@color/button_material_light"/>
+    <item android:color="@color/button_material_light"/>
 </selector>
diff --git a/core/res/res/color/btn_default_quantum_light.xml b/core/res/res/color/btn_default_quantum_light.xml
deleted file mode 100644
index 9536d24..0000000
--- a/core/res/res/color/btn_default_quantum_light.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_enabled="false" android:alpha="0.5" android:color="@color/button_quantum_light"/>
-    <item android:color="@color/button_quantum_light"/>
-</selector>
diff --git a/core/res/res/color/btn_default_quantum_dark.xml b/core/res/res/color/primary_text_disable_only_material_dark.xml
similarity index 85%
copy from core/res/res/color/btn_default_quantum_dark.xml
copy to core/res/res/color/primary_text_disable_only_material_dark.xml
index ec0f140..cf7acaa 100644
--- a/core/res/res/color/btn_default_quantum_dark.xml
+++ b/core/res/res/color/primary_text_disable_only_material_dark.xml
@@ -15,6 +15,6 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_enabled="false" android:alpha="0.5" android:color="@color/button_quantum_dark"/>
-    <item android:color="@color/button_quantum_dark"/>
+    <item android:state_enabled="false" android:alpha="0.5" android:color="@android:color/bright_foreground_material_dark"/>
+    <item android:color="@android:color/bright_foreground_material_dark"/>
 </selector>
diff --git a/core/res/res/color/btn_default_quantum_dark.xml b/core/res/res/color/primary_text_disable_only_material_light.xml
similarity index 85%
copy from core/res/res/color/btn_default_quantum_dark.xml
copy to core/res/res/color/primary_text_disable_only_material_light.xml
index ec0f140..bf5d2c0 100644
--- a/core/res/res/color/btn_default_quantum_dark.xml
+++ b/core/res/res/color/primary_text_disable_only_material_light.xml
@@ -15,6 +15,6 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_enabled="false" android:alpha="0.5" android:color="@color/button_quantum_dark"/>
-    <item android:color="@color/button_quantum_dark"/>
+    <item android:state_enabled="false" android:alpha="0.5" android:color="@android:color/bright_foreground_material_light"/>
+    <item android:color="@android:color/bright_foreground_material_light"/>
 </selector>
diff --git a/core/res/res/color/primary_text_disable_only_quantum_dark.xml b/core/res/res/color/primary_text_disable_only_quantum_dark.xml
deleted file mode 100644
index 60a91f2..0000000
--- a/core/res/res/color/primary_text_disable_only_quantum_dark.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_enabled="false" android:alpha="0.5" android:color="@android:color/bright_foreground_quantum_dark"/>
-    <item android:color="@android:color/bright_foreground_quantum_dark"/>
-</selector>
diff --git a/core/res/res/color/primary_text_disable_only_quantum_light.xml b/core/res/res/color/primary_text_disable_only_quantum_light.xml
deleted file mode 100644
index ced9051..0000000
--- a/core/res/res/color/primary_text_disable_only_quantum_light.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_enabled="false" android:alpha="0.5" android:color="@android:color/bright_foreground_quantum_light"/>
-    <item android:color="@android:color/bright_foreground_quantum_light"/>
-</selector>
diff --git a/core/res/res/color/primary_text_quantum_dark.xml b/core/res/res/color/primary_text_material_dark.xml
similarity index 86%
copy from core/res/res/color/primary_text_quantum_dark.xml
copy to core/res/res/color/primary_text_material_dark.xml
index 1fcd0e3..caef9d0 100644
--- a/core/res/res/color/primary_text_quantum_dark.xml
+++ b/core/res/res/color/primary_text_material_dark.xml
@@ -15,6 +15,6 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_enabled="false" android:alpha="0.5" android:color="@color/primary_text_default_quantum_dark"/>
-    <item android:color="@color/primary_text_default_quantum_dark"/>
+    <item android:state_enabled="false" android:alpha="0.5" android:color="@color/primary_text_default_material_dark"/>
+    <item android:color="@color/primary_text_default_material_dark"/>
 </selector>
diff --git a/core/res/res/color/primary_text_quantum_dark.xml b/core/res/res/color/primary_text_material_light.xml
similarity index 86%
rename from core/res/res/color/primary_text_quantum_dark.xml
rename to core/res/res/color/primary_text_material_light.xml
index 1fcd0e3..81a593b 100644
--- a/core/res/res/color/primary_text_quantum_dark.xml
+++ b/core/res/res/color/primary_text_material_light.xml
@@ -15,6 +15,6 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_enabled="false" android:alpha="0.5" android:color="@color/primary_text_default_quantum_dark"/>
-    <item android:color="@color/primary_text_default_quantum_dark"/>
+    <item android:state_enabled="false" android:alpha="0.5" android:color="@color/primary_text_default_material_light"/>
+    <item android:color="@color/primary_text_default_material_light"/>
 </selector>
diff --git a/core/res/res/color/primary_text_quantum_light.xml b/core/res/res/color/primary_text_quantum_light.xml
deleted file mode 100644
index 1ec1634..0000000
--- a/core/res/res/color/primary_text_quantum_light.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_enabled="false" android:alpha="0.5" android:color="@color/primary_text_default_quantum_light"/>
-    <item android:color="@color/primary_text_default_quantum_light"/>
-</selector>
diff --git a/core/res/res/color/search_url_text_quantum_dark.xml b/core/res/res/color/search_url_text_material_dark.xml
similarity index 100%
rename from core/res/res/color/search_url_text_quantum_dark.xml
rename to core/res/res/color/search_url_text_material_dark.xml
diff --git a/core/res/res/color/search_url_text_quantum_light.xml b/core/res/res/color/search_url_text_material_light.xml
similarity index 100%
rename from core/res/res/color/search_url_text_quantum_light.xml
rename to core/res/res/color/search_url_text_material_light.xml
diff --git a/core/res/res/drawable-hdpi/ab_share_pack_qntm_alpha.9.png b/core/res/res/drawable-hdpi/ab_share_pack_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ab_share_pack_qntm_alpha.9.png
rename to core/res/res/drawable-hdpi/ab_share_pack_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ab_solid_shadow_qntm_alpha.9.png b/core/res/res/drawable-hdpi/ab_solid_shadow_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ab_solid_shadow_qntm_alpha.9.png
rename to core/res/res/drawable-hdpi/ab_solid_shadow_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_cab_done_qntm_alpha.9.png b/core/res/res/drawable-hdpi/btn_cab_done_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_cab_done_qntm_alpha.9.png
rename to core/res/res/drawable-hdpi/btn_cab_done_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_qntm_000.png b/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_000.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_check_to_off_qntm_000.png
rename to core/res/res/drawable-hdpi/btn_check_to_off_mtrl_000.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_qntm_001.png b/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_001.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_check_to_off_qntm_001.png
rename to core/res/res/drawable-hdpi/btn_check_to_off_mtrl_001.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_qntm_002.png b/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_002.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_check_to_off_qntm_002.png
rename to core/res/res/drawable-hdpi/btn_check_to_off_mtrl_002.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_qntm_003.png b/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_003.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_check_to_off_qntm_003.png
rename to core/res/res/drawable-hdpi/btn_check_to_off_mtrl_003.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_qntm_004.png b/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_004.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_check_to_off_qntm_004.png
rename to core/res/res/drawable-hdpi/btn_check_to_off_mtrl_004.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_qntm_005.png b/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_005.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_check_to_off_qntm_005.png
rename to core/res/res/drawable-hdpi/btn_check_to_off_mtrl_005.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_qntm_006.png b/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_006.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_check_to_off_qntm_006.png
rename to core/res/res/drawable-hdpi/btn_check_to_off_mtrl_006.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_qntm_007.png b/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_007.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_check_to_off_qntm_007.png
rename to core/res/res/drawable-hdpi/btn_check_to_off_mtrl_007.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_qntm_008.png b/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_008.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_check_to_off_qntm_008.png
rename to core/res/res/drawable-hdpi/btn_check_to_off_mtrl_008.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_qntm_009.png b/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_009.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_check_to_off_qntm_009.png
rename to core/res/res/drawable-hdpi/btn_check_to_off_mtrl_009.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_qntm_010.png b/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_010.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_check_to_off_qntm_010.png
rename to core/res/res/drawable-hdpi/btn_check_to_off_mtrl_010.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_qntm_011.png b/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_011.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_check_to_off_qntm_011.png
rename to core/res/res/drawable-hdpi/btn_check_to_off_mtrl_011.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_qntm_012.png b/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_012.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_check_to_off_qntm_012.png
rename to core/res/res/drawable-hdpi/btn_check_to_off_mtrl_012.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_qntm_013.png b/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_013.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_check_to_off_qntm_013.png
rename to core/res/res/drawable-hdpi/btn_check_to_off_mtrl_013.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_qntm_014.png b/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_014.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_check_to_off_qntm_014.png
rename to core/res/res/drawable-hdpi/btn_check_to_off_mtrl_014.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_qntm_015.png b/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_015.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_check_to_off_qntm_015.png
rename to core/res/res/drawable-hdpi/btn_check_to_off_mtrl_015.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_qntm_000.png b/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_000.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_check_to_on_qntm_000.png
rename to core/res/res/drawable-hdpi/btn_check_to_on_mtrl_000.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_qntm_001.png b/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_001.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_check_to_on_qntm_001.png
rename to core/res/res/drawable-hdpi/btn_check_to_on_mtrl_001.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_qntm_002.png b/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_002.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_check_to_on_qntm_002.png
rename to core/res/res/drawable-hdpi/btn_check_to_on_mtrl_002.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_qntm_003.png b/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_003.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_check_to_on_qntm_003.png
rename to core/res/res/drawable-hdpi/btn_check_to_on_mtrl_003.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_qntm_004.png b/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_004.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_check_to_on_qntm_004.png
rename to core/res/res/drawable-hdpi/btn_check_to_on_mtrl_004.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_qntm_005.png b/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_005.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_check_to_on_qntm_005.png
rename to core/res/res/drawable-hdpi/btn_check_to_on_mtrl_005.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_qntm_006.png b/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_006.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_check_to_on_qntm_006.png
rename to core/res/res/drawable-hdpi/btn_check_to_on_mtrl_006.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_qntm_007.png b/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_007.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_check_to_on_qntm_007.png
rename to core/res/res/drawable-hdpi/btn_check_to_on_mtrl_007.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_qntm_008.png b/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_008.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_check_to_on_qntm_008.png
rename to core/res/res/drawable-hdpi/btn_check_to_on_mtrl_008.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_qntm_009.png b/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_009.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_check_to_on_qntm_009.png
rename to core/res/res/drawable-hdpi/btn_check_to_on_mtrl_009.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_qntm_010.png b/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_010.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_check_to_on_qntm_010.png
rename to core/res/res/drawable-hdpi/btn_check_to_on_mtrl_010.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_qntm_011.png b/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_011.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_check_to_on_qntm_011.png
rename to core/res/res/drawable-hdpi/btn_check_to_on_mtrl_011.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_qntm_012.png b/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_012.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_check_to_on_qntm_012.png
rename to core/res/res/drawable-hdpi/btn_check_to_on_mtrl_012.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_qntm_013.png b/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_013.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_check_to_on_qntm_013.png
rename to core/res/res/drawable-hdpi/btn_check_to_on_mtrl_013.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_qntm_014.png b/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_014.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_check_to_on_qntm_014.png
rename to core/res/res/drawable-hdpi/btn_check_to_on_mtrl_014.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_qntm_015.png b/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_015.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_check_to_on_qntm_015.png
rename to core/res/res/drawable-hdpi/btn_check_to_on_mtrl_015.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_code_lock_default.png b/core/res/res/drawable-hdpi/btn_code_lock_default.png
deleted file mode 100644
index 4469ce0..0000000
--- a/core/res/res/drawable-hdpi/btn_code_lock_default.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_code_lock_default_holo.png b/core/res/res/drawable-hdpi/btn_code_lock_default_holo.png
deleted file mode 100644
index 449d427..0000000
--- a/core/res/res/drawable-hdpi/btn_code_lock_default_holo.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_code_lock_default_mtrl_alpha.png b/core/res/res/drawable-hdpi/btn_code_lock_default_mtrl_alpha.png
new file mode 100644
index 0000000..7cc3c11
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_code_lock_default_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_code_lock_touched.png b/core/res/res/drawable-hdpi/btn_code_lock_touched.png
deleted file mode 100644
index 0410dd3..0000000
--- a/core/res/res/drawable-hdpi/btn_code_lock_touched.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_code_lock_touched_holo.png b/core/res/res/drawable-hdpi/btn_code_lock_touched_holo.png
deleted file mode 100644
index 66cb1ec..0000000
--- a/core/res/res/drawable-hdpi/btn_code_lock_touched_holo.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_code_lock_touched_mtrl_alpha.png b/core/res/res/drawable-hdpi/btn_code_lock_touched_mtrl_alpha.png
new file mode 100644
index 0000000..70397d21
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_code_lock_touched_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_qntm_alpha.9.png b/core/res/res/drawable-hdpi/btn_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_qntm_alpha.9.png
rename to core/res/res/drawable-hdpi/btn_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_000.png b/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_000.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_radio_to_off_qntm_000.png
rename to core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_000.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_001.png b/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_001.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_radio_to_off_qntm_001.png
rename to core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_001.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_002.png b/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_002.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_radio_to_off_qntm_002.png
rename to core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_002.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_003.png b/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_003.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_radio_to_off_qntm_003.png
rename to core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_003.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_004.png b/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_004.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_radio_to_off_qntm_004.png
rename to core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_004.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_005.png b/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_005.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_radio_to_off_qntm_005.png
rename to core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_005.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_006.png b/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_006.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_radio_to_off_qntm_006.png
rename to core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_006.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_007.png b/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_007.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_radio_to_off_qntm_007.png
rename to core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_007.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_008.png b/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_008.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_radio_to_off_qntm_008.png
rename to core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_008.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_009.png b/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_009.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_radio_to_off_qntm_009.png
rename to core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_009.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_010.png b/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_010.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_radio_to_off_qntm_010.png
rename to core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_010.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_011.png b/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_011.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_radio_to_off_qntm_011.png
rename to core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_011.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_012.png b/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_012.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_radio_to_off_qntm_012.png
rename to core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_012.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_013.png b/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_013.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_radio_to_off_qntm_013.png
rename to core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_013.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_014.png b/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_014.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_radio_to_off_qntm_014.png
rename to core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_014.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_015.png b/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_015.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_radio_to_off_qntm_015.png
rename to core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_015.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_000.png b/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_000.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_radio_to_on_qntm_000.png
rename to core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_000.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_001.png b/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_001.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_radio_to_on_qntm_001.png
rename to core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_001.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_002.png b/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_002.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_radio_to_on_qntm_002.png
rename to core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_002.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_003.png b/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_003.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_radio_to_on_qntm_003.png
rename to core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_003.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_004.png b/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_004.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_radio_to_on_qntm_004.png
rename to core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_004.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_005.png b/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_005.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_radio_to_on_qntm_005.png
rename to core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_005.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_006.png b/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_006.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_radio_to_on_qntm_006.png
rename to core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_006.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_007.png b/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_007.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_radio_to_on_qntm_007.png
rename to core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_007.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_008.png b/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_008.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_radio_to_on_qntm_008.png
rename to core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_008.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_009.png b/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_009.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_radio_to_on_qntm_009.png
rename to core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_009.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_010.png b/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_010.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_radio_to_on_qntm_010.png
rename to core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_010.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_011.png b/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_011.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_radio_to_on_qntm_011.png
rename to core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_011.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_012.png b/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_012.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_radio_to_on_qntm_012.png
rename to core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_012.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_013.png b/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_013.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_radio_to_on_qntm_013.png
rename to core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_013.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_014.png b/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_014.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_radio_to_on_qntm_014.png
rename to core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_014.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_015.png b/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_015.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_radio_to_on_qntm_015.png
rename to core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_015.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_rating_star_off_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_rating_star_off_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_rating_star_off_qntm_alpha.png
rename to core/res/res/drawable-hdpi/btn_rating_star_off_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_rating_star_on_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_rating_star_on_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_rating_star_on_qntm_alpha.png
rename to core/res/res/drawable-hdpi/btn_rating_star_on_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_star_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_star_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_star_qntm_alpha.png
rename to core/res/res/drawable-hdpi/btn_star_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_000.png b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_000.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_switch_to_off_qntm_000.png
rename to core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_000.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_001.png b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_001.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_switch_to_off_qntm_001.png
rename to core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_001.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_002.png b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_002.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_switch_to_off_qntm_002.png
rename to core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_002.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_003.png b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_003.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_switch_to_off_qntm_003.png
rename to core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_003.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_004.png b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_004.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_switch_to_off_qntm_004.png
rename to core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_004.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_005.png b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_005.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_switch_to_off_qntm_005.png
rename to core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_005.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_006.png b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_006.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_switch_to_off_qntm_006.png
rename to core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_006.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_007.png b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_007.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_switch_to_off_qntm_007.png
rename to core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_007.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_008.png b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_008.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_switch_to_off_qntm_008.png
rename to core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_008.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_009.png b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_009.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_switch_to_off_qntm_009.png
rename to core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_009.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_010.png b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_010.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_switch_to_off_qntm_010.png
rename to core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_010.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_011.png b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_011.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_switch_to_off_qntm_011.png
rename to core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_011.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_012.png b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_012.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_switch_to_off_qntm_012.png
rename to core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_012.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_013.png b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_013.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_switch_to_off_qntm_013.png
rename to core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_013.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_014.png b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_014.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_switch_to_off_qntm_014.png
rename to core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_014.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_000.png b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_000.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_switch_to_on_qntm_000.png
rename to core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_000.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_001.png b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_001.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_switch_to_on_qntm_001.png
rename to core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_001.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_002.png b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_002.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_switch_to_on_qntm_002.png
rename to core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_002.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_003.png b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_003.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_switch_to_on_qntm_003.png
rename to core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_003.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_004.png b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_004.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_switch_to_on_qntm_004.png
rename to core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_004.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_005.png b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_005.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_switch_to_on_qntm_005.png
rename to core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_005.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_006.png b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_006.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_switch_to_on_qntm_006.png
rename to core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_006.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_007.png b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_007.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_switch_to_on_qntm_007.png
rename to core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_007.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_008.png b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_008.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_switch_to_on_qntm_008.png
rename to core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_008.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_009.png b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_009.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_switch_to_on_qntm_009.png
rename to core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_009.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_010.png b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_010.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_switch_to_on_qntm_010.png
rename to core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_010.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_011.png b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_011.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_switch_to_on_qntm_011.png
rename to core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_011.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_012.png b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_012.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_switch_to_on_qntm_012.png
rename to core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_012.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_013.png b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_013.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_switch_to_on_qntm_013.png
rename to core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_013.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_014.png b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_014.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_switch_to_on_qntm_014.png
rename to core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_014.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_indicator_qntm_alpha.9.png b/core/res/res/drawable-hdpi/btn_toggle_indicator_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_toggle_indicator_qntm_alpha.9.png
rename to core/res/res/drawable-hdpi/btn_toggle_indicator_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_qntm_alpha.9.png b/core/res/res/drawable-hdpi/btn_toggle_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/btn_toggle_qntm_alpha.9.png
rename to core/res/res/drawable-hdpi/btn_toggle_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/expander_close_qntm_alpha.9.png b/core/res/res/drawable-hdpi/expander_close_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/expander_close_qntm_alpha.9.png
rename to core/res/res/drawable-hdpi/expander_close_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/expander_open_qntm_alpha.9.png b/core/res/res/drawable-hdpi/expander_open_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/expander_open_qntm_alpha.9.png
rename to core/res/res/drawable-hdpi/expander_open_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/fastscroll_thumb_qntm_alpha.png b/core/res/res/drawable-hdpi/fastscroll_thumb_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-hdpi/fastscroll_thumb_qntm_alpha.png
rename to core/res/res/drawable-hdpi/fastscroll_thumb_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/fastscroll_track_qntm_alpha.9.png b/core/res/res/drawable-hdpi/fastscroll_track_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/fastscroll_track_qntm_alpha.9.png
rename to core/res/res/drawable-hdpi/fastscroll_track_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_ab_back_qntm_am_alpha.png b/core/res/res/drawable-hdpi/ic_ab_back_mtrl_am_alpha.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_ab_back_qntm_am_alpha.png
rename to core/res/res/drawable-hdpi/ic_ab_back_mtrl_am_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_cab_done_qntm_alpha.png b/core/res/res/drawable-hdpi/ic_cab_done_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_cab_done_qntm_alpha.png
rename to core/res/res/drawable-hdpi/ic_cab_done_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_clear_qntm_alpha.png b/core/res/res/drawable-hdpi/ic_clear_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_clear_qntm_alpha.png
rename to core/res/res/drawable-hdpi/ic_clear_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_commit_search_api_qntm_alpha.png b/core/res/res/drawable-hdpi/ic_commit_search_api_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_commit_search_api_qntm_alpha.png
rename to core/res/res/drawable-hdpi/ic_commit_search_api_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_corp_badge.png b/core/res/res/drawable-hdpi/ic_corp_badge.png
deleted file mode 100644
index f647375..0000000
--- a/core/res/res/drawable-hdpi/ic_corp_badge.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_dialog_alert_qntm_alpha.png b/core/res/res/drawable-hdpi/ic_dialog_alert_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_dialog_alert_qntm_alpha.png
rename to core/res/res/drawable-hdpi/ic_dialog_alert_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_find_next_qntm_alpha.png b/core/res/res/drawable-hdpi/ic_find_next_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_find_next_qntm_alpha.png
rename to core/res/res/drawable-hdpi/ic_find_next_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_find_previous_qntm_alpha.png b/core/res/res/drawable-hdpi/ic_find_previous_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_find_previous_qntm_alpha.png
rename to core/res/res/drawable-hdpi/ic_find_previous_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_go_search_api_qntm_alpha.png b/core/res/res/drawable-hdpi/ic_go_search_api_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_go_search_api_qntm_alpha.png
rename to core/res/res/drawable-hdpi/ic_go_search_api_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_disabled_qntm_alpha.png b/core/res/res/drawable-hdpi/ic_media_route_disabled_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_media_route_disabled_qntm_alpha.png
rename to core/res/res/drawable-hdpi/ic_media_route_disabled_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_off_qntm_alpha.png b/core/res/res/drawable-hdpi/ic_media_route_off_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_media_route_off_qntm_alpha.png
rename to core/res/res/drawable-hdpi/ic_media_route_off_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_0_qntm_alpha.png b/core/res/res/drawable-hdpi/ic_media_route_on_0_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_media_route_on_0_qntm_alpha.png
rename to core/res/res/drawable-hdpi/ic_media_route_on_0_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_1_qntm_alpha.png b/core/res/res/drawable-hdpi/ic_media_route_on_1_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_media_route_on_1_qntm_alpha.png
rename to core/res/res/drawable-hdpi/ic_media_route_on_1_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_2_qntm_alpha.png b/core/res/res/drawable-hdpi/ic_media_route_on_2_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_media_route_on_2_qntm_alpha.png
rename to core/res/res/drawable-hdpi/ic_media_route_on_2_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_qntm_alpha.png b/core/res/res/drawable-hdpi/ic_media_route_on_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_media_route_on_qntm_alpha.png
rename to core/res/res/drawable-hdpi/ic_media_route_on_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_copy_qntm_am_alpha.png b/core/res/res/drawable-hdpi/ic_menu_copy_mtrl_am_alpha.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_menu_copy_qntm_am_alpha.png
rename to core/res/res/drawable-hdpi/ic_menu_copy_mtrl_am_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_cut_qntm_alpha.png b/core/res/res/drawable-hdpi/ic_menu_cut_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_menu_cut_qntm_alpha.png
rename to core/res/res/drawable-hdpi/ic_menu_cut_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_find_qntm_alpha.png b/core/res/res/drawable-hdpi/ic_menu_find_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_menu_find_qntm_alpha.png
rename to core/res/res/drawable-hdpi/ic_menu_find_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_moreoverflow_qntm_alpha.png b/core/res/res/drawable-hdpi/ic_menu_moreoverflow_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_menu_moreoverflow_qntm_alpha.png
rename to core/res/res/drawable-hdpi/ic_menu_moreoverflow_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_paste_qntm_am_alpha.png b/core/res/res/drawable-hdpi/ic_menu_paste_mtrl_am_alpha.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_menu_paste_qntm_am_alpha.png
rename to core/res/res/drawable-hdpi/ic_menu_paste_mtrl_am_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_search_qntm_alpha.png b/core/res/res/drawable-hdpi/ic_menu_search_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_menu_search_qntm_alpha.png
rename to core/res/res/drawable-hdpi/ic_menu_search_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_selectall_qntm_alpha.png b/core/res/res/drawable-hdpi/ic_menu_selectall_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_menu_selectall_qntm_alpha.png
rename to core/res/res/drawable-hdpi/ic_menu_selectall_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_share_qntm_alpha.png b/core/res/res/drawable-hdpi/ic_menu_share_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_menu_share_qntm_alpha.png
rename to core/res/res/drawable-hdpi/ic_menu_share_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_search_api_qntm_alpha.png b/core/res/res/drawable-hdpi/ic_search_api_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_search_api_qntm_alpha.png
rename to core/res/res/drawable-hdpi/ic_search_api_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_voice_search_api_qntm_alpha.png b/core/res/res/drawable-hdpi/ic_voice_search_api_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_voice_search_api_qntm_alpha.png
rename to core/res/res/drawable-hdpi/ic_voice_search_api_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/indicator_code_lock_drag_direction_red_up.png b/core/res/res/drawable-hdpi/indicator_code_lock_drag_direction_red_up.png
deleted file mode 100644
index 698c3ec..0000000
--- a/core/res/res/drawable-hdpi/indicator_code_lock_drag_direction_red_up.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/indicator_code_lock_drag_direction_up_mtrl_alpha.png b/core/res/res/drawable-hdpi/indicator_code_lock_drag_direction_up_mtrl_alpha.png
new file mode 100644
index 0000000..b9b400f
--- /dev/null
+++ b/core/res/res/drawable-hdpi/indicator_code_lock_drag_direction_up_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/indicator_code_lock_point_area_default.png b/core/res/res/drawable-hdpi/indicator_code_lock_point_area_default.png
deleted file mode 100644
index c45b956..0000000
--- a/core/res/res/drawable-hdpi/indicator_code_lock_point_area_default.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/indicator_code_lock_point_area_default_holo.png b/core/res/res/drawable-hdpi/indicator_code_lock_point_area_default_mtrl_alpha.png
similarity index 82%
rename from core/res/res/drawable-hdpi/indicator_code_lock_point_area_default_holo.png
rename to core/res/res/drawable-hdpi/indicator_code_lock_point_area_default_mtrl_alpha.png
index 7fe402a..b1601f4 100644
--- a/core/res/res/drawable-hdpi/indicator_code_lock_point_area_default_holo.png
+++ b/core/res/res/drawable-hdpi/indicator_code_lock_point_area_default_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/indicator_code_lock_point_area_green.png b/core/res/res/drawable-hdpi/indicator_code_lock_point_area_green.png
deleted file mode 100644
index b9fd0a4..0000000
--- a/core/res/res/drawable-hdpi/indicator_code_lock_point_area_green.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/indicator_code_lock_point_area_green_holo.png b/core/res/res/drawable-hdpi/indicator_code_lock_point_area_mtrl_alpha.png
similarity index 95%
rename from core/res/res/drawable-hdpi/indicator_code_lock_point_area_green_holo.png
rename to core/res/res/drawable-hdpi/indicator_code_lock_point_area_mtrl_alpha.png
index 4052eed..a038a13 100644
--- a/core/res/res/drawable-hdpi/indicator_code_lock_point_area_green_holo.png
+++ b/core/res/res/drawable-hdpi/indicator_code_lock_point_area_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/indicator_code_lock_point_area_red.png b/core/res/res/drawable-hdpi/indicator_code_lock_point_area_red.png
deleted file mode 100644
index 94e947d..0000000
--- a/core/res/res/drawable-hdpi/indicator_code_lock_point_area_red.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/indicator_code_lock_point_area_red_holo.png b/core/res/res/drawable-hdpi/indicator_code_lock_point_area_red_holo.png
deleted file mode 100644
index 738d0fe..0000000
--- a/core/res/res/drawable-hdpi/indicator_code_lock_point_area_red_holo.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/list_divider_qntm_alpha.9.png b/core/res/res/drawable-hdpi/list_divider_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/list_divider_qntm_alpha.9.png
rename to core/res/res/drawable-hdpi/list_divider_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/list_section_divider_qntm_alpha.9.png b/core/res/res/drawable-hdpi/list_section_divider_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/list_section_divider_qntm_alpha.9.png
rename to core/res/res/drawable-hdpi/list_section_divider_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/perm_group_accessibility_features.png b/core/res/res/drawable-hdpi/perm_group_accessibility_features.png
old mode 100755
new mode 100644
index 849c19c..7a1948e
--- a/core/res/res/drawable-hdpi/perm_group_accessibility_features.png
+++ b/core/res/res/drawable-hdpi/perm_group_accessibility_features.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/perm_group_accounts.png b/core/res/res/drawable-hdpi/perm_group_accounts.png
index db59ab0..68a7c88 100644
--- a/core/res/res/drawable-hdpi/perm_group_accounts.png
+++ b/core/res/res/drawable-hdpi/perm_group_accounts.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/perm_group_affects_battery.png b/core/res/res/drawable-hdpi/perm_group_affects_battery.png
index 8ca8154..14adad1 100644
--- a/core/res/res/drawable-hdpi/perm_group_affects_battery.png
+++ b/core/res/res/drawable-hdpi/perm_group_affects_battery.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/perm_group_app_info.png b/core/res/res/drawable-hdpi/perm_group_app_info.png
index b03e2f3..a263d33 100644
--- a/core/res/res/drawable-hdpi/perm_group_app_info.png
+++ b/core/res/res/drawable-hdpi/perm_group_app_info.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/perm_group_audio_settings.png b/core/res/res/drawable-hdpi/perm_group_audio_settings.png
index 4e652a8..4e152af 100644
--- a/core/res/res/drawable-hdpi/perm_group_audio_settings.png
+++ b/core/res/res/drawable-hdpi/perm_group_audio_settings.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/perm_group_bluetooth.png b/core/res/res/drawable-hdpi/perm_group_bluetooth.png
index 0f28454..22ab06a 100644
--- a/core/res/res/drawable-hdpi/perm_group_bluetooth.png
+++ b/core/res/res/drawable-hdpi/perm_group_bluetooth.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/perm_group_bookmarks.png b/core/res/res/drawable-hdpi/perm_group_bookmarks.png
index 06f63445..069bd85 100644
--- a/core/res/res/drawable-hdpi/perm_group_bookmarks.png
+++ b/core/res/res/drawable-hdpi/perm_group_bookmarks.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/perm_group_calendar.png b/core/res/res/drawable-hdpi/perm_group_calendar.png
index c0a4dfd..8fe55e7 100644
--- a/core/res/res/drawable-hdpi/perm_group_calendar.png
+++ b/core/res/res/drawable-hdpi/perm_group_calendar.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/perm_group_camera.png b/core/res/res/drawable-hdpi/perm_group_camera.png
index cbc07b0..0203147 100644
--- a/core/res/res/drawable-hdpi/perm_group_camera.png
+++ b/core/res/res/drawable-hdpi/perm_group_camera.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/perm_group_device_alarms.png b/core/res/res/drawable-hdpi/perm_group_device_alarms.png
index d44b9de..4010c7a 100644
--- a/core/res/res/drawable-hdpi/perm_group_device_alarms.png
+++ b/core/res/res/drawable-hdpi/perm_group_device_alarms.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/perm_group_display.png b/core/res/res/drawable-hdpi/perm_group_display.png
index e8afece..f60c7e2 100644
--- a/core/res/res/drawable-hdpi/perm_group_display.png
+++ b/core/res/res/drawable-hdpi/perm_group_display.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/perm_group_location.png b/core/res/res/drawable-hdpi/perm_group_location.png
index dc2f8ef..2cc0ba6 100644
--- a/core/res/res/drawable-hdpi/perm_group_location.png
+++ b/core/res/res/drawable-hdpi/perm_group_location.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/perm_group_messages.png b/core/res/res/drawable-hdpi/perm_group_messages.png
index 680c178..013bc8f 100644
--- a/core/res/res/drawable-hdpi/perm_group_messages.png
+++ b/core/res/res/drawable-hdpi/perm_group_messages.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/perm_group_microphone.png b/core/res/res/drawable-hdpi/perm_group_microphone.png
index a73a945..c94b0ba 100644
--- a/core/res/res/drawable-hdpi/perm_group_microphone.png
+++ b/core/res/res/drawable-hdpi/perm_group_microphone.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/perm_group_network.png b/core/res/res/drawable-hdpi/perm_group_network.png
index c750e2a..f7907ef 100644
--- a/core/res/res/drawable-hdpi/perm_group_network.png
+++ b/core/res/res/drawable-hdpi/perm_group_network.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/perm_group_personal_info.png b/core/res/res/drawable-hdpi/perm_group_personal_info.png
index 130e7ad..dcfb160 100644
--- a/core/res/res/drawable-hdpi/perm_group_personal_info.png
+++ b/core/res/res/drawable-hdpi/perm_group_personal_info.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/perm_group_phone_calls.png b/core/res/res/drawable-hdpi/perm_group_phone_calls.png
index 577855b..1decd84 100644
--- a/core/res/res/drawable-hdpi/perm_group_phone_calls.png
+++ b/core/res/res/drawable-hdpi/perm_group_phone_calls.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/perm_group_screenlock.png b/core/res/res/drawable-hdpi/perm_group_screenlock.png
index 9c5143d..6abde49 100644
--- a/core/res/res/drawable-hdpi/perm_group_screenlock.png
+++ b/core/res/res/drawable-hdpi/perm_group_screenlock.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/perm_group_shortrange_network.png b/core/res/res/drawable-hdpi/perm_group_shortrange_network.png
index 554a4e4..f7907ef 100644
--- a/core/res/res/drawable-hdpi/perm_group_shortrange_network.png
+++ b/core/res/res/drawable-hdpi/perm_group_shortrange_network.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/perm_group_social_info.png b/core/res/res/drawable-hdpi/perm_group_social_info.png
index 134990b..e7e2488 100644
--- a/core/res/res/drawable-hdpi/perm_group_social_info.png
+++ b/core/res/res/drawable-hdpi/perm_group_social_info.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/perm_group_status_bar.png b/core/res/res/drawable-hdpi/perm_group_status_bar.png
index bda963b..73760b2 100644
--- a/core/res/res/drawable-hdpi/perm_group_status_bar.png
+++ b/core/res/res/drawable-hdpi/perm_group_status_bar.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/perm_group_storage.png b/core/res/res/drawable-hdpi/perm_group_storage.png
index e6b3965..642ce20 100644
--- a/core/res/res/drawable-hdpi/perm_group_storage.png
+++ b/core/res/res/drawable-hdpi/perm_group_storage.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/perm_group_sync_settings.png b/core/res/res/drawable-hdpi/perm_group_sync_settings.png
index be70866..0bc1506 100644
--- a/core/res/res/drawable-hdpi/perm_group_sync_settings.png
+++ b/core/res/res/drawable-hdpi/perm_group_sync_settings.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/perm_group_system_clock.png b/core/res/res/drawable-hdpi/perm_group_system_clock.png
index 75794c3..7e4e293 100644
--- a/core/res/res/drawable-hdpi/perm_group_system_clock.png
+++ b/core/res/res/drawable-hdpi/perm_group_system_clock.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/perm_group_system_tools.png b/core/res/res/drawable-hdpi/perm_group_system_tools.png
index 3fd4385..00a4c03 100644
--- a/core/res/res/drawable-hdpi/perm_group_system_tools.png
+++ b/core/res/res/drawable-hdpi/perm_group_system_tools.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/perm_group_user_dictionary.png b/core/res/res/drawable-hdpi/perm_group_user_dictionary.png
index 98a0894..fc41348 100644
--- a/core/res/res/drawable-hdpi/perm_group_user_dictionary.png
+++ b/core/res/res/drawable-hdpi/perm_group_user_dictionary.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/perm_group_user_dictionary_write.png b/core/res/res/drawable-hdpi/perm_group_user_dictionary_write.png
index 784ea0f..7fa88aa 100644
--- a/core/res/res/drawable-hdpi/perm_group_user_dictionary_write.png
+++ b/core/res/res/drawable-hdpi/perm_group_user_dictionary_write.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/perm_group_voicemail.png b/core/res/res/drawable-hdpi/perm_group_voicemail.png
index b08b153..0ce5d1d 100644
--- a/core/res/res/drawable-hdpi/perm_group_voicemail.png
+++ b/core/res/res/drawable-hdpi/perm_group_voicemail.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/perm_group_wallpaper.png b/core/res/res/drawable-hdpi/perm_group_wallpaper.png
index cf073a4..5db0361 100644
--- a/core/res/res/drawable-hdpi/perm_group_wallpaper.png
+++ b/core/res/res/drawable-hdpi/perm_group_wallpaper.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/popup_background_qntm_mult.9.png b/core/res/res/drawable-hdpi/popup_background_mtrl_mult.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/popup_background_qntm_mult.9.png
rename to core/res/res/drawable-hdpi/popup_background_mtrl_mult.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/progress_qntm_alpha.9.png b/core/res/res/drawable-hdpi/progress_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/progress_qntm_alpha.9.png
rename to core/res/res/drawable-hdpi/progress_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/progress_primary_qntm_alpha.9.png b/core/res/res/drawable-hdpi/progress_primary_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/progress_primary_qntm_alpha.9.png
rename to core/res/res/drawable-hdpi/progress_primary_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/scrollbar_handle_qntm_alpha.9.png b/core/res/res/drawable-hdpi/scrollbar_handle_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/scrollbar_handle_qntm_alpha.9.png
rename to core/res/res/drawable-hdpi/scrollbar_handle_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/scrubber_control_from_pressed_qntm_000.png b/core/res/res/drawable-hdpi/scrubber_control_from_pressed_mtrl_000.png
similarity index 100%
rename from core/res/res/drawable-hdpi/scrubber_control_from_pressed_qntm_000.png
rename to core/res/res/drawable-hdpi/scrubber_control_from_pressed_mtrl_000.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/scrubber_control_from_pressed_qntm_001.png b/core/res/res/drawable-hdpi/scrubber_control_from_pressed_mtrl_001.png
similarity index 100%
rename from core/res/res/drawable-hdpi/scrubber_control_from_pressed_qntm_001.png
rename to core/res/res/drawable-hdpi/scrubber_control_from_pressed_mtrl_001.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/scrubber_control_from_pressed_qntm_002.png b/core/res/res/drawable-hdpi/scrubber_control_from_pressed_mtrl_002.png
similarity index 100%
rename from core/res/res/drawable-hdpi/scrubber_control_from_pressed_qntm_002.png
rename to core/res/res/drawable-hdpi/scrubber_control_from_pressed_mtrl_002.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/scrubber_control_from_pressed_qntm_003.png b/core/res/res/drawable-hdpi/scrubber_control_from_pressed_mtrl_003.png
similarity index 100%
rename from core/res/res/drawable-hdpi/scrubber_control_from_pressed_qntm_003.png
rename to core/res/res/drawable-hdpi/scrubber_control_from_pressed_mtrl_003.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/scrubber_control_from_pressed_qntm_004.png b/core/res/res/drawable-hdpi/scrubber_control_from_pressed_mtrl_004.png
similarity index 100%
rename from core/res/res/drawable-hdpi/scrubber_control_from_pressed_qntm_004.png
rename to core/res/res/drawable-hdpi/scrubber_control_from_pressed_mtrl_004.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/scrubber_control_from_pressed_qntm_005.png b/core/res/res/drawable-hdpi/scrubber_control_from_pressed_mtrl_005.png
similarity index 100%
rename from core/res/res/drawable-hdpi/scrubber_control_from_pressed_qntm_005.png
rename to core/res/res/drawable-hdpi/scrubber_control_from_pressed_mtrl_005.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/scrubber_control_off_qntm_alpha.png b/core/res/res/drawable-hdpi/scrubber_control_off_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-hdpi/scrubber_control_off_qntm_alpha.png
rename to core/res/res/drawable-hdpi/scrubber_control_off_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/scrubber_control_off_pressed_qntm_alpha.png b/core/res/res/drawable-hdpi/scrubber_control_off_pressed_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-hdpi/scrubber_control_off_pressed_qntm_alpha.png
rename to core/res/res/drawable-hdpi/scrubber_control_off_pressed_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/scrubber_control_on_qntm_alpha.png b/core/res/res/drawable-hdpi/scrubber_control_on_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-hdpi/scrubber_control_on_qntm_alpha.png
rename to core/res/res/drawable-hdpi/scrubber_control_on_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/scrubber_control_on_pressed_qntm_alpha.png b/core/res/res/drawable-hdpi/scrubber_control_on_pressed_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-hdpi/scrubber_control_on_pressed_qntm_alpha.png
rename to core/res/res/drawable-hdpi/scrubber_control_on_pressed_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/scrubber_control_to_pressed_qntm_000.png b/core/res/res/drawable-hdpi/scrubber_control_to_pressed_mtrl_000.png
similarity index 100%
rename from core/res/res/drawable-hdpi/scrubber_control_to_pressed_qntm_000.png
rename to core/res/res/drawable-hdpi/scrubber_control_to_pressed_mtrl_000.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/scrubber_control_to_pressed_qntm_001.png b/core/res/res/drawable-hdpi/scrubber_control_to_pressed_mtrl_001.png
similarity index 100%
rename from core/res/res/drawable-hdpi/scrubber_control_to_pressed_qntm_001.png
rename to core/res/res/drawable-hdpi/scrubber_control_to_pressed_mtrl_001.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/scrubber_control_to_pressed_qntm_002.png b/core/res/res/drawable-hdpi/scrubber_control_to_pressed_mtrl_002.png
similarity index 100%
rename from core/res/res/drawable-hdpi/scrubber_control_to_pressed_qntm_002.png
rename to core/res/res/drawable-hdpi/scrubber_control_to_pressed_mtrl_002.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/scrubber_control_to_pressed_qntm_003.png b/core/res/res/drawable-hdpi/scrubber_control_to_pressed_mtrl_003.png
similarity index 100%
rename from core/res/res/drawable-hdpi/scrubber_control_to_pressed_qntm_003.png
rename to core/res/res/drawable-hdpi/scrubber_control_to_pressed_mtrl_003.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/scrubber_control_to_pressed_qntm_004.png b/core/res/res/drawable-hdpi/scrubber_control_to_pressed_mtrl_004.png
similarity index 100%
rename from core/res/res/drawable-hdpi/scrubber_control_to_pressed_qntm_004.png
rename to core/res/res/drawable-hdpi/scrubber_control_to_pressed_mtrl_004.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/scrubber_control_to_pressed_qntm_005.png b/core/res/res/drawable-hdpi/scrubber_control_to_pressed_mtrl_005.png
similarity index 100%
rename from core/res/res/drawable-hdpi/scrubber_control_to_pressed_qntm_005.png
rename to core/res/res/drawable-hdpi/scrubber_control_to_pressed_mtrl_005.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/scrubber_primary_qntm_alpha.9.png b/core/res/res/drawable-hdpi/scrubber_primary_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/scrubber_primary_qntm_alpha.9.png
rename to core/res/res/drawable-hdpi/scrubber_primary_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/scrubber_track_qntm_alpha.9.png b/core/res/res/drawable-hdpi/scrubber_track_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/scrubber_track_qntm_alpha.9.png
rename to core/res/res/drawable-hdpi/scrubber_track_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_20_inner_holo.png b/core/res/res/drawable-hdpi/spinner_20_inner_holo.png
deleted file mode 100644
index 49841ea..0000000
--- a/core/res/res/drawable-hdpi/spinner_20_inner_holo.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_20_outer_holo.png b/core/res/res/drawable-hdpi/spinner_20_outer_holo.png
deleted file mode 100644
index 69f0070..0000000
--- a/core/res/res/drawable-hdpi/spinner_20_outer_holo.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_qntm_am_alpha.9.png b/core/res/res/drawable-hdpi/spinner_mtrl_am_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/spinner_qntm_am_alpha.9.png
rename to core/res/res/drawable-hdpi/spinner_mtrl_am_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/switch_track_qntm_alpha.9.png b/core/res/res/drawable-hdpi/switch_track_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/switch_track_qntm_alpha.9.png
rename to core/res/res/drawable-hdpi/switch_track_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/tab_indicator_mtrl_alpha.9.png b/core/res/res/drawable-hdpi/tab_indicator_mtrl_alpha.9.png
new file mode 100644
index 0000000..21b2135
--- /dev/null
+++ b/core/res/res/drawable-hdpi/tab_indicator_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/tab_indicator_normal_qntm_alpha.9.png b/core/res/res/drawable-hdpi/tab_indicator_normal_qntm_alpha.9.png
deleted file mode 100644
index 233d409..0000000
--- a/core/res/res/drawable-hdpi/tab_indicator_normal_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/tab_indicator_selected_qntm_alpha.9.png b/core/res/res/drawable-hdpi/tab_indicator_selected_qntm_alpha.9.png
deleted file mode 100644
index 68b1dd7..0000000
--- a/core/res/res/drawable-hdpi/tab_indicator_selected_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/text_cursor_qntm_alpha.9.png b/core/res/res/drawable-hdpi/text_cursor_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/text_cursor_qntm_alpha.9.png
rename to core/res/res/drawable-hdpi/text_cursor_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/text_select_handle_left_qntm_alpha.png b/core/res/res/drawable-hdpi/text_select_handle_left_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-hdpi/text_select_handle_left_qntm_alpha.png
rename to core/res/res/drawable-hdpi/text_select_handle_left_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/text_select_handle_middle_qntm_alpha.png b/core/res/res/drawable-hdpi/text_select_handle_middle_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-hdpi/text_select_handle_middle_qntm_alpha.png
rename to core/res/res/drawable-hdpi/text_select_handle_middle_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/text_select_handle_right_qntm_alpha.png b/core/res/res/drawable-hdpi/text_select_handle_right_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-hdpi/text_select_handle_right_qntm_alpha.png
rename to core/res/res/drawable-hdpi/text_select_handle_right_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_activated_qntm_alpha.9.png b/core/res/res/drawable-hdpi/textfield_activated_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/textfield_activated_qntm_alpha.9.png
rename to core/res/res/drawable-hdpi/textfield_activated_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_default_qntm_alpha.9.png b/core/res/res/drawable-hdpi/textfield_default_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/textfield_default_qntm_alpha.9.png
rename to core/res/res/drawable-hdpi/textfield_default_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_search_activated_qntm_alpha.9.png b/core/res/res/drawable-hdpi/textfield_search_activated_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/textfield_search_activated_qntm_alpha.9.png
rename to core/res/res/drawable-hdpi/textfield_search_activated_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_search_default_qntm_alpha.9.png b/core/res/res/drawable-hdpi/textfield_search_default_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/textfield_search_default_qntm_alpha.9.png
rename to core/res/res/drawable-hdpi/textfield_search_default_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ab_solid_shadow_qntm.9.png b/core/res/res/drawable-ldpi/ab_solid_shadow_mtrl.9.png
similarity index 100%
rename from core/res/res/drawable-ldpi/ab_solid_shadow_qntm.9.png
rename to core/res/res/drawable-ldpi/ab_solid_shadow_mtrl.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ab_transparent_qntm_alpha.9.png b/core/res/res/drawable-ldpi/ab_transparent_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-ldpi/ab_transparent_qntm_alpha.9.png
rename to core/res/res/drawable-ldpi/ab_transparent_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_check_off_qntm_alpha.png b/core/res/res/drawable-ldpi/btn_check_off_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-ldpi/btn_check_off_qntm_alpha.png
rename to core/res/res/drawable-ldpi/btn_check_off_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_check_on_qntm_alpha.png b/core/res/res/drawable-ldpi/btn_check_on_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-ldpi/btn_check_on_qntm_alpha.png
rename to core/res/res/drawable-ldpi/btn_check_on_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_code_lock_default.png b/core/res/res/drawable-ldpi/btn_code_lock_default.png
deleted file mode 100644
index 149da9b..0000000
--- a/core/res/res/drawable-ldpi/btn_code_lock_default.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_code_lock_touched.png b/core/res/res/drawable-ldpi/btn_code_lock_touched.png
deleted file mode 100644
index ad9a313..0000000
--- a/core/res/res/drawable-ldpi/btn_code_lock_touched.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_qntm_alpha.9.png b/core/res/res/drawable-ldpi/btn_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-ldpi/btn_qntm_alpha.9.png
rename to core/res/res/drawable-ldpi/btn_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_radio_off_qntm_alpha.png b/core/res/res/drawable-ldpi/btn_radio_off_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-ldpi/btn_radio_off_qntm_alpha.png
rename to core/res/res/drawable-ldpi/btn_radio_off_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_radio_off_pressed_qntm_alpha.png b/core/res/res/drawable-ldpi/btn_radio_off_pressed_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-ldpi/btn_radio_off_pressed_qntm_alpha.png
rename to core/res/res/drawable-ldpi/btn_radio_off_pressed_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_radio_on_qntm_alpha.png b/core/res/res/drawable-ldpi/btn_radio_on_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-ldpi/btn_radio_on_qntm_alpha.png
rename to core/res/res/drawable-ldpi/btn_radio_on_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_radio_on_pressed_qntm_alpha.png b/core/res/res/drawable-ldpi/btn_radio_on_pressed_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-ldpi/btn_radio_on_pressed_qntm_alpha.png
rename to core/res/res/drawable-ldpi/btn_radio_on_pressed_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_star_qntm_alpha.png b/core/res/res/drawable-ldpi/btn_star_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-ldpi/btn_star_qntm_alpha.png
rename to core/res/res/drawable-ldpi/btn_star_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/expander_close_qntm_alpha.9.png b/core/res/res/drawable-ldpi/expander_close_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-ldpi/expander_close_qntm_alpha.9.png
rename to core/res/res/drawable-ldpi/expander_close_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/expander_open_qntm_alpha.9.png b/core/res/res/drawable-ldpi/expander_open_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-ldpi/expander_open_qntm_alpha.9.png
rename to core/res/res/drawable-ldpi/expander_open_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/fastscroll_thumb_qntm_alpha.png b/core/res/res/drawable-ldpi/fastscroll_thumb_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-ldpi/fastscroll_thumb_qntm_alpha.png
rename to core/res/res/drawable-ldpi/fastscroll_thumb_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/fastscroll_track_qntm_alpha.9.png b/core/res/res/drawable-ldpi/fastscroll_track_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-ldpi/fastscroll_track_qntm_alpha.9.png
rename to core/res/res/drawable-ldpi/fastscroll_track_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_ab_back_qntm_am_alpha.png b/core/res/res/drawable-ldpi/ic_ab_back_mtrl_am_alpha.png
similarity index 100%
rename from core/res/res/drawable-ldpi/ic_ab_back_qntm_am_alpha.png
rename to core/res/res/drawable-ldpi/ic_ab_back_mtrl_am_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_cab_done_qntm_alpha.png b/core/res/res/drawable-ldpi/ic_cab_done_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-ldpi/ic_cab_done_qntm_alpha.png
rename to core/res/res/drawable-ldpi/ic_cab_done_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_dialog_alert_qntm_alpha.png b/core/res/res/drawable-ldpi/ic_dialog_alert_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-ldpi/ic_dialog_alert_qntm_alpha.png
rename to core/res/res/drawable-ldpi/ic_dialog_alert_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_find_next_qntm_alpha.png b/core/res/res/drawable-ldpi/ic_find_next_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-ldpi/ic_find_next_qntm_alpha.png
rename to core/res/res/drawable-ldpi/ic_find_next_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_find_previous_qntm_alpha.png b/core/res/res/drawable-ldpi/ic_find_previous_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-ldpi/ic_find_previous_qntm_alpha.png
rename to core/res/res/drawable-ldpi/ic_find_previous_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_copy_qntm_am_alpha.png b/core/res/res/drawable-ldpi/ic_menu_copy_mtrl_am_alpha.png
similarity index 100%
rename from core/res/res/drawable-ldpi/ic_menu_copy_qntm_am_alpha.png
rename to core/res/res/drawable-ldpi/ic_menu_copy_mtrl_am_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_cut_qntm_alpha.png b/core/res/res/drawable-ldpi/ic_menu_cut_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-ldpi/ic_menu_cut_qntm_alpha.png
rename to core/res/res/drawable-ldpi/ic_menu_cut_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_find_qntm_alpha.png b/core/res/res/drawable-ldpi/ic_menu_find_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-ldpi/ic_menu_find_qntm_alpha.png
rename to core/res/res/drawable-ldpi/ic_menu_find_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_moreoverflow_qntm_alpha.png b/core/res/res/drawable-ldpi/ic_menu_moreoverflow_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-ldpi/ic_menu_moreoverflow_qntm_alpha.png
rename to core/res/res/drawable-ldpi/ic_menu_moreoverflow_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_paste_qntm_am_alpha.png b/core/res/res/drawable-ldpi/ic_menu_paste_mtrl_am_alpha.png
similarity index 100%
rename from core/res/res/drawable-ldpi/ic_menu_paste_qntm_am_alpha.png
rename to core/res/res/drawable-ldpi/ic_menu_paste_mtrl_am_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_search_qntm_alpha.png b/core/res/res/drawable-ldpi/ic_menu_search_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-ldpi/ic_menu_search_qntm_alpha.png
rename to core/res/res/drawable-ldpi/ic_menu_search_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_selectall_qntm_alpha.png b/core/res/res/drawable-ldpi/ic_menu_selectall_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-ldpi/ic_menu_selectall_qntm_alpha.png
rename to core/res/res/drawable-ldpi/ic_menu_selectall_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_share_qntm_alpha.png b/core/res/res/drawable-ldpi/ic_menu_share_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-ldpi/ic_menu_share_qntm_alpha.png
rename to core/res/res/drawable-ldpi/ic_menu_share_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/indicator_code_lock_drag_direction_red_up.png b/core/res/res/drawable-ldpi/indicator_code_lock_drag_direction_red_up.png
deleted file mode 100644
index ac8e42a..0000000
--- a/core/res/res/drawable-ldpi/indicator_code_lock_drag_direction_red_up.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldpi/indicator_code_lock_point_area_default.png b/core/res/res/drawable-ldpi/indicator_code_lock_point_area_default.png
deleted file mode 100644
index 5b77b9f..0000000
--- a/core/res/res/drawable-ldpi/indicator_code_lock_point_area_default.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldpi/indicator_code_lock_point_area_green.png b/core/res/res/drawable-ldpi/indicator_code_lock_point_area_green.png
deleted file mode 100644
index c7c0b9a..0000000
--- a/core/res/res/drawable-ldpi/indicator_code_lock_point_area_green.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldpi/indicator_code_lock_point_area_red.png b/core/res/res/drawable-ldpi/indicator_code_lock_point_area_red.png
deleted file mode 100644
index ac02dc4..0000000
--- a/core/res/res/drawable-ldpi/indicator_code_lock_point_area_red.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldpi/list_divider_qntm_alpha.9.png b/core/res/res/drawable-ldpi/list_divider_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-ldpi/list_divider_qntm_alpha.9.png
rename to core/res/res/drawable-ldpi/list_divider_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/list_section_divider_qntm_alpha.9.png b/core/res/res/drawable-ldpi/list_section_divider_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-ldpi/list_section_divider_qntm_alpha.9.png
rename to core/res/res/drawable-ldpi/list_section_divider_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/progress_qntm_alpha.9.png b/core/res/res/drawable-ldpi/progress_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-ldpi/progress_qntm_alpha.9.png
rename to core/res/res/drawable-ldpi/progress_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/progress_primary_qntm_alpha.9.png b/core/res/res/drawable-ldpi/progress_primary_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-ldpi/progress_primary_qntm_alpha.9.png
rename to core/res/res/drawable-ldpi/progress_primary_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/scrollbar_handle_qntm_alpha.9.png b/core/res/res/drawable-ldpi/scrollbar_handle_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-ldpi/scrollbar_handle_qntm_alpha.9.png
rename to core/res/res/drawable-ldpi/scrollbar_handle_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/scrubber_control_off_qntm_alpha.png b/core/res/res/drawable-ldpi/scrubber_control_off_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-ldpi/scrubber_control_off_qntm_alpha.png
rename to core/res/res/drawable-ldpi/scrubber_control_off_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/scrubber_control_off_pressed_qntm_alpha.png b/core/res/res/drawable-ldpi/scrubber_control_off_pressed_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-ldpi/scrubber_control_off_pressed_qntm_alpha.png
rename to core/res/res/drawable-ldpi/scrubber_control_off_pressed_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/scrubber_control_on_qntm_alpha.png b/core/res/res/drawable-ldpi/scrubber_control_on_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-ldpi/scrubber_control_on_qntm_alpha.png
rename to core/res/res/drawable-ldpi/scrubber_control_on_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_radio_on_pressed_qntm_alpha.png b/core/res/res/drawable-ldpi/scrubber_control_on_pressed_mtrl_alpha.png
similarity index 100%
copy from core/res/res/drawable-ldpi/btn_radio_on_pressed_qntm_alpha.png
copy to core/res/res/drawable-ldpi/scrubber_control_on_pressed_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/scrubber_control_on_pressed_qntm_alpha.png b/core/res/res/drawable-ldpi/scrubber_control_on_pressed_qntm_alpha.png
deleted file mode 100644
index 458abaf..0000000
--- a/core/res/res/drawable-ldpi/scrubber_control_on_pressed_qntm_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldpi/scrubber_primary_qntm_alpha.9.png b/core/res/res/drawable-ldpi/scrubber_primary_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-ldpi/scrubber_primary_qntm_alpha.9.png
rename to core/res/res/drawable-ldpi/scrubber_primary_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/spinner_qntm_am_alpha.9.png b/core/res/res/drawable-ldpi/spinner_mtrl_am_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-ldpi/spinner_qntm_am_alpha.9.png
rename to core/res/res/drawable-ldpi/spinner_mtrl_am_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/switch_off_qntm_alpha.9.png b/core/res/res/drawable-ldpi/switch_off_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-ldpi/switch_off_qntm_alpha.9.png
rename to core/res/res/drawable-ldpi/switch_off_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/switch_on_qntm_alpha.9.png b/core/res/res/drawable-ldpi/switch_on_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-ldpi/switch_on_qntm_alpha.9.png
rename to core/res/res/drawable-ldpi/switch_on_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/progress_qntm_alpha.9.png b/core/res/res/drawable-ldpi/switch_track_mtrl_alpha.9.png
similarity index 100%
copy from core/res/res/drawable-ldpi/progress_qntm_alpha.9.png
copy to core/res/res/drawable-ldpi/switch_track_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/switch_track_qntm_alpha.9.png b/core/res/res/drawable-ldpi/switch_track_qntm_alpha.9.png
deleted file mode 100644
index a58128f..0000000
--- a/core/res/res/drawable-ldpi/switch_track_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldpi/tab_indicator_normal_qntm_alpha.9.png b/core/res/res/drawable-ldpi/tab_indicator_normal_qntm_alpha.9.png
deleted file mode 100644
index 2244362..0000000
--- a/core/res/res/drawable-ldpi/tab_indicator_normal_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldpi/tab_indicator_selected_qntm_alpha.9.png b/core/res/res/drawable-ldpi/tab_indicator_selected_qntm_alpha.9.png
deleted file mode 100644
index 22ea80e..0000000
--- a/core/res/res/drawable-ldpi/tab_indicator_selected_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldpi/text_cursor_qntm_alpha.9.png b/core/res/res/drawable-ldpi/text_cursor_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-ldpi/text_cursor_qntm_alpha.9.png
rename to core/res/res/drawable-ldpi/text_cursor_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/textfield_activated_qntm_alpha.9.png b/core/res/res/drawable-ldpi/textfield_activated_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-ldpi/textfield_activated_qntm_alpha.9.png
rename to core/res/res/drawable-ldpi/textfield_activated_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/textfield_default_qntm_alpha.9.png b/core/res/res/drawable-ldpi/textfield_default_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-ldpi/textfield_default_qntm_alpha.9.png
rename to core/res/res/drawable-ldpi/textfield_default_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_share_pack_qntm_alpha.9.png b/core/res/res/drawable-mdpi/ab_share_pack_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ab_share_pack_qntm_alpha.9.png
rename to core/res/res/drawable-mdpi/ab_share_pack_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_solid_shadow_qntm_alpha.9.png b/core/res/res/drawable-mdpi/ab_solid_shadow_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ab_solid_shadow_qntm_alpha.9.png
rename to core/res/res/drawable-mdpi/ab_solid_shadow_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_cab_done_qntm_alpha.9.png b/core/res/res/drawable-mdpi/btn_cab_done_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_cab_done_qntm_alpha.9.png
rename to core/res/res/drawable-mdpi/btn_cab_done_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_qntm_000.png b/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_000.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_check_to_off_qntm_000.png
rename to core/res/res/drawable-mdpi/btn_check_to_off_mtrl_000.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_qntm_001.png b/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_001.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_check_to_off_qntm_001.png
rename to core/res/res/drawable-mdpi/btn_check_to_off_mtrl_001.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_qntm_002.png b/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_002.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_check_to_off_qntm_002.png
rename to core/res/res/drawable-mdpi/btn_check_to_off_mtrl_002.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_qntm_003.png b/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_003.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_check_to_off_qntm_003.png
rename to core/res/res/drawable-mdpi/btn_check_to_off_mtrl_003.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_qntm_004.png b/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_004.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_check_to_off_qntm_004.png
rename to core/res/res/drawable-mdpi/btn_check_to_off_mtrl_004.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_qntm_005.png b/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_005.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_check_to_off_qntm_005.png
rename to core/res/res/drawable-mdpi/btn_check_to_off_mtrl_005.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_qntm_006.png b/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_006.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_check_to_off_qntm_006.png
rename to core/res/res/drawable-mdpi/btn_check_to_off_mtrl_006.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_qntm_007.png b/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_007.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_check_to_off_qntm_007.png
rename to core/res/res/drawable-mdpi/btn_check_to_off_mtrl_007.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_qntm_008.png b/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_008.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_check_to_off_qntm_008.png
rename to core/res/res/drawable-mdpi/btn_check_to_off_mtrl_008.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_qntm_009.png b/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_009.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_check_to_off_qntm_009.png
rename to core/res/res/drawable-mdpi/btn_check_to_off_mtrl_009.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_qntm_010.png b/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_010.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_check_to_off_qntm_010.png
rename to core/res/res/drawable-mdpi/btn_check_to_off_mtrl_010.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_qntm_011.png b/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_011.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_check_to_off_qntm_011.png
rename to core/res/res/drawable-mdpi/btn_check_to_off_mtrl_011.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_qntm_012.png b/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_012.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_check_to_off_qntm_012.png
rename to core/res/res/drawable-mdpi/btn_check_to_off_mtrl_012.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_qntm_013.png b/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_013.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_check_to_off_qntm_013.png
rename to core/res/res/drawable-mdpi/btn_check_to_off_mtrl_013.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_qntm_014.png b/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_014.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_check_to_off_qntm_014.png
rename to core/res/res/drawable-mdpi/btn_check_to_off_mtrl_014.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_qntm_015.png b/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_015.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_check_to_off_qntm_015.png
rename to core/res/res/drawable-mdpi/btn_check_to_off_mtrl_015.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_qntm_000.png b/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_000.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_check_to_on_qntm_000.png
rename to core/res/res/drawable-mdpi/btn_check_to_on_mtrl_000.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_qntm_001.png b/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_001.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_check_to_on_qntm_001.png
rename to core/res/res/drawable-mdpi/btn_check_to_on_mtrl_001.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_qntm_002.png b/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_002.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_check_to_on_qntm_002.png
rename to core/res/res/drawable-mdpi/btn_check_to_on_mtrl_002.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_qntm_003.png b/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_003.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_check_to_on_qntm_003.png
rename to core/res/res/drawable-mdpi/btn_check_to_on_mtrl_003.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_qntm_004.png b/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_004.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_check_to_on_qntm_004.png
rename to core/res/res/drawable-mdpi/btn_check_to_on_mtrl_004.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_qntm_005.png b/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_005.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_check_to_on_qntm_005.png
rename to core/res/res/drawable-mdpi/btn_check_to_on_mtrl_005.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_qntm_006.png b/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_006.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_check_to_on_qntm_006.png
rename to core/res/res/drawable-mdpi/btn_check_to_on_mtrl_006.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_qntm_007.png b/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_007.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_check_to_on_qntm_007.png
rename to core/res/res/drawable-mdpi/btn_check_to_on_mtrl_007.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_qntm_008.png b/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_008.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_check_to_on_qntm_008.png
rename to core/res/res/drawable-mdpi/btn_check_to_on_mtrl_008.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_qntm_009.png b/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_009.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_check_to_on_qntm_009.png
rename to core/res/res/drawable-mdpi/btn_check_to_on_mtrl_009.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_qntm_010.png b/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_010.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_check_to_on_qntm_010.png
rename to core/res/res/drawable-mdpi/btn_check_to_on_mtrl_010.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_qntm_011.png b/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_011.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_check_to_on_qntm_011.png
rename to core/res/res/drawable-mdpi/btn_check_to_on_mtrl_011.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_qntm_012.png b/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_012.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_check_to_on_qntm_012.png
rename to core/res/res/drawable-mdpi/btn_check_to_on_mtrl_012.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_qntm_013.png b/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_013.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_check_to_on_qntm_013.png
rename to core/res/res/drawable-mdpi/btn_check_to_on_mtrl_013.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_qntm_014.png b/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_014.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_check_to_on_qntm_014.png
rename to core/res/res/drawable-mdpi/btn_check_to_on_mtrl_014.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_qntm_015.png b/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_015.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_check_to_on_qntm_015.png
rename to core/res/res/drawable-mdpi/btn_check_to_on_mtrl_015.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_code_lock_default.png b/core/res/res/drawable-mdpi/btn_code_lock_default.png
deleted file mode 100644
index 206f9b3..0000000
--- a/core/res/res/drawable-mdpi/btn_code_lock_default.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_code_lock_default_holo.png b/core/res/res/drawable-mdpi/btn_code_lock_default_holo.png
deleted file mode 100644
index 4c4adf2..0000000
--- a/core/res/res/drawable-mdpi/btn_code_lock_default_holo.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_code_lock_default_mtrl_alpha.png b/core/res/res/drawable-mdpi/btn_code_lock_default_mtrl_alpha.png
new file mode 100644
index 0000000..14d0b32
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_code_lock_default_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_code_lock_touched.png b/core/res/res/drawable-mdpi/btn_code_lock_touched.png
deleted file mode 100644
index fe5c1af..0000000
--- a/core/res/res/drawable-mdpi/btn_code_lock_touched.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_code_lock_touched_holo.png b/core/res/res/drawable-mdpi/btn_code_lock_touched_holo.png
deleted file mode 100644
index ef701ed..0000000
--- a/core/res/res/drawable-mdpi/btn_code_lock_touched_holo.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_code_lock_touched_mtrl_alpha.png b/core/res/res/drawable-mdpi/btn_code_lock_touched_mtrl_alpha.png
new file mode 100644
index 0000000..9cfbdf9
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_code_lock_touched_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_qntm_alpha.9.png b/core/res/res/drawable-mdpi/btn_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_qntm_alpha.9.png
rename to core/res/res/drawable-mdpi/btn_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_on_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_radio_on_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_radio_on_qntm_alpha.png
rename to core/res/res/drawable-mdpi/btn_radio_on_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_on_pressed_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_radio_on_pressed_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_radio_on_pressed_qntm_alpha.png
rename to core/res/res/drawable-mdpi/btn_radio_on_pressed_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_000.png b/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_000.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_radio_to_off_qntm_000.png
rename to core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_000.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_001.png b/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_001.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_radio_to_off_qntm_001.png
rename to core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_001.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_002.png b/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_002.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_radio_to_off_qntm_002.png
rename to core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_002.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_003.png b/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_003.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_radio_to_off_qntm_003.png
rename to core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_003.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_004.png b/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_004.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_radio_to_off_qntm_004.png
rename to core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_004.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_005.png b/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_005.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_radio_to_off_qntm_005.png
rename to core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_005.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_006.png b/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_006.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_radio_to_off_qntm_006.png
rename to core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_006.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_007.png b/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_007.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_radio_to_off_qntm_007.png
rename to core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_007.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_008.png b/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_008.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_radio_to_off_qntm_008.png
rename to core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_008.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_009.png b/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_009.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_radio_to_off_qntm_009.png
rename to core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_009.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_010.png b/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_010.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_radio_to_off_qntm_010.png
rename to core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_010.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_011.png b/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_011.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_radio_to_off_qntm_011.png
rename to core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_011.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_012.png b/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_012.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_radio_to_off_qntm_012.png
rename to core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_012.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_013.png b/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_013.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_radio_to_off_qntm_013.png
rename to core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_013.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_014.png b/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_014.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_radio_to_off_qntm_014.png
rename to core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_014.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_015.png b/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_015.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_radio_to_off_qntm_015.png
rename to core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_015.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_000.png b/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_000.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_radio_to_on_qntm_000.png
rename to core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_000.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_001.png b/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_001.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_radio_to_on_qntm_001.png
rename to core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_001.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_002.png b/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_002.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_radio_to_on_qntm_002.png
rename to core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_002.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_003.png b/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_003.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_radio_to_on_qntm_003.png
rename to core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_003.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_004.png b/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_004.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_radio_to_on_qntm_004.png
rename to core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_004.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_005.png b/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_005.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_radio_to_on_qntm_005.png
rename to core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_005.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_006.png b/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_006.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_radio_to_on_qntm_006.png
rename to core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_006.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_007.png b/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_007.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_radio_to_on_qntm_007.png
rename to core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_007.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_008.png b/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_008.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_radio_to_on_qntm_008.png
rename to core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_008.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_009.png b/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_009.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_radio_to_on_qntm_009.png
rename to core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_009.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_010.png b/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_010.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_radio_to_on_qntm_010.png
rename to core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_010.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_011.png b/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_011.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_radio_to_on_qntm_011.png
rename to core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_011.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_012.png b/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_012.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_radio_to_on_qntm_012.png
rename to core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_012.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_013.png b/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_013.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_radio_to_on_qntm_013.png
rename to core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_013.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_014.png b/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_014.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_radio_to_on_qntm_014.png
rename to core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_014.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_015.png b/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_015.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_radio_to_on_qntm_015.png
rename to core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_015.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_rating_star_off_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_rating_star_off_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_rating_star_off_qntm_alpha.png
rename to core/res/res/drawable-mdpi/btn_rating_star_off_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_rating_star_on_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_rating_star_on_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_rating_star_on_qntm_alpha.png
rename to core/res/res/drawable-mdpi/btn_rating_star_on_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_star_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_star_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_star_qntm_alpha.png
rename to core/res/res/drawable-mdpi/btn_star_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_000.png b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_000.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_switch_to_off_qntm_000.png
rename to core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_000.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_001.png b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_001.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_switch_to_off_qntm_001.png
rename to core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_001.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_002.png b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_002.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_switch_to_off_qntm_002.png
rename to core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_002.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_003.png b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_003.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_switch_to_off_qntm_003.png
rename to core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_003.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_004.png b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_004.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_switch_to_off_qntm_004.png
rename to core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_004.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_005.png b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_005.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_switch_to_off_qntm_005.png
rename to core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_005.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_006.png b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_006.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_switch_to_off_qntm_006.png
rename to core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_006.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_007.png b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_007.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_switch_to_off_qntm_007.png
rename to core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_007.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_008.png b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_008.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_switch_to_off_qntm_008.png
rename to core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_008.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_009.png b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_009.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_switch_to_off_qntm_009.png
rename to core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_009.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_010.png b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_010.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_switch_to_off_qntm_010.png
rename to core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_010.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_011.png b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_011.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_switch_to_off_qntm_011.png
rename to core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_011.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_012.png b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_012.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_switch_to_off_qntm_012.png
rename to core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_012.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_013.png b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_013.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_switch_to_off_qntm_013.png
rename to core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_013.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_014.png b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_014.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_switch_to_off_qntm_014.png
rename to core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_014.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_000.png b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_000.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_switch_to_on_qntm_000.png
rename to core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_000.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_001.png b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_001.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_switch_to_on_qntm_001.png
rename to core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_001.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_002.png b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_002.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_switch_to_on_qntm_002.png
rename to core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_002.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_003.png b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_003.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_switch_to_on_qntm_003.png
rename to core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_003.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_004.png b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_004.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_switch_to_on_qntm_004.png
rename to core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_004.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_005.png b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_005.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_switch_to_on_qntm_005.png
rename to core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_005.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_006.png b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_006.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_switch_to_on_qntm_006.png
rename to core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_006.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_007.png b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_007.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_switch_to_on_qntm_007.png
rename to core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_007.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_008.png b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_008.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_switch_to_on_qntm_008.png
rename to core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_008.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_009.png b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_009.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_switch_to_on_qntm_009.png
rename to core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_009.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_010.png b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_010.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_switch_to_on_qntm_010.png
rename to core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_010.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_011.png b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_011.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_switch_to_on_qntm_011.png
rename to core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_011.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_012.png b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_012.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_switch_to_on_qntm_012.png
rename to core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_012.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_013.png b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_013.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_switch_to_on_qntm_013.png
rename to core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_013.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_014.png b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_014.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_switch_to_on_qntm_014.png
rename to core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_014.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_indicator_qntm_alpha.9.png b/core/res/res/drawable-mdpi/btn_toggle_indicator_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_toggle_indicator_qntm_alpha.9.png
rename to core/res/res/drawable-mdpi/btn_toggle_indicator_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_qntm_alpha.9.png b/core/res/res/drawable-mdpi/btn_toggle_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/btn_toggle_qntm_alpha.9.png
rename to core/res/res/drawable-mdpi/btn_toggle_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/expander_close_qntm_alpha.9.png b/core/res/res/drawable-mdpi/expander_close_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/expander_close_qntm_alpha.9.png
rename to core/res/res/drawable-mdpi/expander_close_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/expander_open_qntm_alpha.9.png b/core/res/res/drawable-mdpi/expander_open_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/expander_open_qntm_alpha.9.png
rename to core/res/res/drawable-mdpi/expander_open_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/fastscroll_thumb_qntm_alpha.png b/core/res/res/drawable-mdpi/fastscroll_thumb_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-mdpi/fastscroll_thumb_qntm_alpha.png
rename to core/res/res/drawable-mdpi/fastscroll_thumb_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/fastscroll_track_qntm_alpha.9.png b/core/res/res/drawable-mdpi/fastscroll_track_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/fastscroll_track_qntm_alpha.9.png
rename to core/res/res/drawable-mdpi/fastscroll_track_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_ab_back_qntm_am_alpha.png b/core/res/res/drawable-mdpi/ic_ab_back_mtrl_am_alpha.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_ab_back_qntm_am_alpha.png
rename to core/res/res/drawable-mdpi/ic_ab_back_mtrl_am_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_cab_done_qntm_alpha.png b/core/res/res/drawable-mdpi/ic_cab_done_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_cab_done_qntm_alpha.png
rename to core/res/res/drawable-mdpi/ic_cab_done_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_clear_qntm_alpha.png b/core/res/res/drawable-mdpi/ic_clear_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_clear_qntm_alpha.png
rename to core/res/res/drawable-mdpi/ic_clear_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_commit_search_api_qntm_alpha.png b/core/res/res/drawable-mdpi/ic_commit_search_api_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_commit_search_api_qntm_alpha.png
rename to core/res/res/drawable-mdpi/ic_commit_search_api_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_dialog_alert_qntm_alpha.png b/core/res/res/drawable-mdpi/ic_dialog_alert_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_dialog_alert_qntm_alpha.png
rename to core/res/res/drawable-mdpi/ic_dialog_alert_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_find_next_qntm_alpha.png b/core/res/res/drawable-mdpi/ic_find_next_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_find_next_qntm_alpha.png
rename to core/res/res/drawable-mdpi/ic_find_next_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_find_previous_qntm_alpha.png b/core/res/res/drawable-mdpi/ic_find_previous_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_find_previous_qntm_alpha.png
rename to core/res/res/drawable-mdpi/ic_find_previous_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_go_search_api_qntm_alpha.png b/core/res/res/drawable-mdpi/ic_go_search_api_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_go_search_api_qntm_alpha.png
rename to core/res/res/drawable-mdpi/ic_go_search_api_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_disabled_qntm_alpha.png b/core/res/res/drawable-mdpi/ic_media_route_disabled_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_media_route_disabled_qntm_alpha.png
rename to core/res/res/drawable-mdpi/ic_media_route_disabled_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_off_qntm_alpha.png b/core/res/res/drawable-mdpi/ic_media_route_off_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_media_route_off_qntm_alpha.png
rename to core/res/res/drawable-mdpi/ic_media_route_off_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_on_0_qntm_alpha.png b/core/res/res/drawable-mdpi/ic_media_route_on_0_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_media_route_on_0_qntm_alpha.png
rename to core/res/res/drawable-mdpi/ic_media_route_on_0_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_on_1_qntm_alpha.png b/core/res/res/drawable-mdpi/ic_media_route_on_1_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_media_route_on_1_qntm_alpha.png
rename to core/res/res/drawable-mdpi/ic_media_route_on_1_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_on_2_qntm_alpha.png b/core/res/res/drawable-mdpi/ic_media_route_on_2_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_media_route_on_2_qntm_alpha.png
rename to core/res/res/drawable-mdpi/ic_media_route_on_2_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_on_qntm_alpha.png b/core/res/res/drawable-mdpi/ic_media_route_on_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_media_route_on_qntm_alpha.png
rename to core/res/res/drawable-mdpi/ic_media_route_on_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_copy_qntm_am_alpha.png b/core/res/res/drawable-mdpi/ic_menu_copy_mtrl_am_alpha.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_menu_copy_qntm_am_alpha.png
rename to core/res/res/drawable-mdpi/ic_menu_copy_mtrl_am_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_cut_qntm_alpha.png b/core/res/res/drawable-mdpi/ic_menu_cut_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_menu_cut_qntm_alpha.png
rename to core/res/res/drawable-mdpi/ic_menu_cut_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_find_qntm_alpha.png b/core/res/res/drawable-mdpi/ic_menu_find_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_menu_find_qntm_alpha.png
rename to core/res/res/drawable-mdpi/ic_menu_find_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_moreoverflow_qntm_alpha.png b/core/res/res/drawable-mdpi/ic_menu_moreoverflow_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_menu_moreoverflow_qntm_alpha.png
rename to core/res/res/drawable-mdpi/ic_menu_moreoverflow_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_paste_qntm_am_alpha.png b/core/res/res/drawable-mdpi/ic_menu_paste_mtrl_am_alpha.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_menu_paste_qntm_am_alpha.png
rename to core/res/res/drawable-mdpi/ic_menu_paste_mtrl_am_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_search_qntm_alpha.png b/core/res/res/drawable-mdpi/ic_menu_search_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_menu_search_qntm_alpha.png
rename to core/res/res/drawable-mdpi/ic_menu_search_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_selectall_qntm_alpha.png b/core/res/res/drawable-mdpi/ic_menu_selectall_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_menu_selectall_qntm_alpha.png
rename to core/res/res/drawable-mdpi/ic_menu_selectall_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_share_qntm_alpha.png b/core/res/res/drawable-mdpi/ic_menu_share_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_menu_share_qntm_alpha.png
rename to core/res/res/drawable-mdpi/ic_menu_share_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_search_api_qntm_alpha.png b/core/res/res/drawable-mdpi/ic_search_api_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_search_api_qntm_alpha.png
rename to core/res/res/drawable-mdpi/ic_search_api_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_voice_search_api_qntm_alpha.png b/core/res/res/drawable-mdpi/ic_voice_search_api_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_voice_search_api_qntm_alpha.png
rename to core/res/res/drawable-mdpi/ic_voice_search_api_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/indicator_code_lock_drag_direction_red_up.png b/core/res/res/drawable-mdpi/indicator_code_lock_drag_direction_red_up.png
deleted file mode 100644
index 7201e58..0000000
--- a/core/res/res/drawable-mdpi/indicator_code_lock_drag_direction_red_up.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/indicator_code_lock_drag_direction_up_mtrl_alpha.png b/core/res/res/drawable-mdpi/indicator_code_lock_drag_direction_up_mtrl_alpha.png
new file mode 100644
index 0000000..2fb1325
--- /dev/null
+++ b/core/res/res/drawable-mdpi/indicator_code_lock_drag_direction_up_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/indicator_code_lock_point_area_default.png b/core/res/res/drawable-mdpi/indicator_code_lock_point_area_default.png
deleted file mode 100644
index 05c194b..0000000
--- a/core/res/res/drawable-mdpi/indicator_code_lock_point_area_default.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/indicator_code_lock_point_area_default_holo.png b/core/res/res/drawable-mdpi/indicator_code_lock_point_area_default_mtrl_alpha.png
similarity index 78%
rename from core/res/res/drawable-mdpi/indicator_code_lock_point_area_default_holo.png
rename to core/res/res/drawable-mdpi/indicator_code_lock_point_area_default_mtrl_alpha.png
index 5762e5f..07d4afd 100644
--- a/core/res/res/drawable-mdpi/indicator_code_lock_point_area_default_holo.png
+++ b/core/res/res/drawable-mdpi/indicator_code_lock_point_area_default_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/indicator_code_lock_point_area_green.png b/core/res/res/drawable-mdpi/indicator_code_lock_point_area_green.png
deleted file mode 100644
index 8f24832..0000000
--- a/core/res/res/drawable-mdpi/indicator_code_lock_point_area_green.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/indicator_code_lock_point_area_green_holo.png b/core/res/res/drawable-mdpi/indicator_code_lock_point_area_mtrl_alpha.png
similarity index 94%
rename from core/res/res/drawable-mdpi/indicator_code_lock_point_area_green_holo.png
rename to core/res/res/drawable-mdpi/indicator_code_lock_point_area_mtrl_alpha.png
index bfb0967..ea8c2b4 100644
--- a/core/res/res/drawable-mdpi/indicator_code_lock_point_area_green_holo.png
+++ b/core/res/res/drawable-mdpi/indicator_code_lock_point_area_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/indicator_code_lock_point_area_red_holo.png b/core/res/res/drawable-mdpi/indicator_code_lock_point_area_red_holo.png
deleted file mode 100644
index 8c0386f..0000000
--- a/core/res/res/drawable-mdpi/indicator_code_lock_point_area_red_holo.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/list_divider_qntm_alpha.9.png b/core/res/res/drawable-mdpi/list_divider_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/list_divider_qntm_alpha.9.png
rename to core/res/res/drawable-mdpi/list_divider_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/list_section_divider_qntm_alpha.9.png b/core/res/res/drawable-mdpi/list_section_divider_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/list_section_divider_qntm_alpha.9.png
rename to core/res/res/drawable-mdpi/list_section_divider_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/perm_group_accessibility_features.png b/core/res/res/drawable-mdpi/perm_group_accessibility_features.png
old mode 100755
new mode 100644
index ba86d3d..df5c147
--- a/core/res/res/drawable-mdpi/perm_group_accessibility_features.png
+++ b/core/res/res/drawable-mdpi/perm_group_accessibility_features.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/perm_group_accounts.png b/core/res/res/drawable-mdpi/perm_group_accounts.png
index 3dd4043..0c4dd02 100644
--- a/core/res/res/drawable-mdpi/perm_group_accounts.png
+++ b/core/res/res/drawable-mdpi/perm_group_accounts.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/perm_group_affects_battery.png b/core/res/res/drawable-mdpi/perm_group_affects_battery.png
index 7291916..511921d 100644
--- a/core/res/res/drawable-mdpi/perm_group_affects_battery.png
+++ b/core/res/res/drawable-mdpi/perm_group_affects_battery.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/perm_group_app_info.png b/core/res/res/drawable-mdpi/perm_group_app_info.png
index 8ba65bd..e715177 100644
--- a/core/res/res/drawable-mdpi/perm_group_app_info.png
+++ b/core/res/res/drawable-mdpi/perm_group_app_info.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/perm_group_audio_settings.png b/core/res/res/drawable-mdpi/perm_group_audio_settings.png
index f2f461b..26ff28e 100644
--- a/core/res/res/drawable-mdpi/perm_group_audio_settings.png
+++ b/core/res/res/drawable-mdpi/perm_group_audio_settings.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/perm_group_bluetooth.png b/core/res/res/drawable-mdpi/perm_group_bluetooth.png
index 6db6fde..effa405 100644
--- a/core/res/res/drawable-mdpi/perm_group_bluetooth.png
+++ b/core/res/res/drawable-mdpi/perm_group_bluetooth.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/perm_group_bookmarks.png b/core/res/res/drawable-mdpi/perm_group_bookmarks.png
index f908e14..2103632 100644
--- a/core/res/res/drawable-mdpi/perm_group_bookmarks.png
+++ b/core/res/res/drawable-mdpi/perm_group_bookmarks.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/perm_group_calendar.png b/core/res/res/drawable-mdpi/perm_group_calendar.png
index 5905973..e22fd7f 100644
--- a/core/res/res/drawable-mdpi/perm_group_calendar.png
+++ b/core/res/res/drawable-mdpi/perm_group_calendar.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/perm_group_camera.png b/core/res/res/drawable-mdpi/perm_group_camera.png
index be1c9e6..463654b 100644
--- a/core/res/res/drawable-mdpi/perm_group_camera.png
+++ b/core/res/res/drawable-mdpi/perm_group_camera.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/perm_group_device_alarms.png b/core/res/res/drawable-mdpi/perm_group_device_alarms.png
index 48d6d6a..1348131 100644
--- a/core/res/res/drawable-mdpi/perm_group_device_alarms.png
+++ b/core/res/res/drawable-mdpi/perm_group_device_alarms.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/perm_group_display.png b/core/res/res/drawable-mdpi/perm_group_display.png
index e10609c..ea51240 100644
--- a/core/res/res/drawable-mdpi/perm_group_display.png
+++ b/core/res/res/drawable-mdpi/perm_group_display.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/perm_group_location.png b/core/res/res/drawable-mdpi/perm_group_location.png
index e79ec25..2fcb124 100644
--- a/core/res/res/drawable-mdpi/perm_group_location.png
+++ b/core/res/res/drawable-mdpi/perm_group_location.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/perm_group_messages.png b/core/res/res/drawable-mdpi/perm_group_messages.png
index dfb3ba7..6f3ecf8 100644
--- a/core/res/res/drawable-mdpi/perm_group_messages.png
+++ b/core/res/res/drawable-mdpi/perm_group_messages.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/perm_group_microphone.png b/core/res/res/drawable-mdpi/perm_group_microphone.png
index 9bab315..b4717a3 100644
--- a/core/res/res/drawable-mdpi/perm_group_microphone.png
+++ b/core/res/res/drawable-mdpi/perm_group_microphone.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/perm_group_network.png b/core/res/res/drawable-mdpi/perm_group_network.png
index f2798a7..a624e42 100644
--- a/core/res/res/drawable-mdpi/perm_group_network.png
+++ b/core/res/res/drawable-mdpi/perm_group_network.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/perm_group_personal_info.png b/core/res/res/drawable-mdpi/perm_group_personal_info.png
index 6233a82..cf56fa50 100644
--- a/core/res/res/drawable-mdpi/perm_group_personal_info.png
+++ b/core/res/res/drawable-mdpi/perm_group_personal_info.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/perm_group_phone_calls.png b/core/res/res/drawable-mdpi/perm_group_phone_calls.png
index ff3ffd5..467f37f 100644
--- a/core/res/res/drawable-mdpi/perm_group_phone_calls.png
+++ b/core/res/res/drawable-mdpi/perm_group_phone_calls.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/perm_group_screenlock.png b/core/res/res/drawable-mdpi/perm_group_screenlock.png
index abfe6e4..f8b351e 100644
--- a/core/res/res/drawable-mdpi/perm_group_screenlock.png
+++ b/core/res/res/drawable-mdpi/perm_group_screenlock.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/perm_group_shortrange_network.png b/core/res/res/drawable-mdpi/perm_group_shortrange_network.png
index 5d73375..a624e42 100644
--- a/core/res/res/drawable-mdpi/perm_group_shortrange_network.png
+++ b/core/res/res/drawable-mdpi/perm_group_shortrange_network.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/perm_group_social_info.png b/core/res/res/drawable-mdpi/perm_group_social_info.png
index c862f9e..8ae10f1 100644
--- a/core/res/res/drawable-mdpi/perm_group_social_info.png
+++ b/core/res/res/drawable-mdpi/perm_group_social_info.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/perm_group_status_bar.png b/core/res/res/drawable-mdpi/perm_group_status_bar.png
index 4158fa6..86868ab 100644
--- a/core/res/res/drawable-mdpi/perm_group_status_bar.png
+++ b/core/res/res/drawable-mdpi/perm_group_status_bar.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/perm_group_storage.png b/core/res/res/drawable-mdpi/perm_group_storage.png
index 3dcfb22..61ff8a3 100644
--- a/core/res/res/drawable-mdpi/perm_group_storage.png
+++ b/core/res/res/drawable-mdpi/perm_group_storage.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/perm_group_sync_settings.png b/core/res/res/drawable-mdpi/perm_group_sync_settings.png
index 5a0e5ff..9049f47 100644
--- a/core/res/res/drawable-mdpi/perm_group_sync_settings.png
+++ b/core/res/res/drawable-mdpi/perm_group_sync_settings.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/perm_group_system_clock.png b/core/res/res/drawable-mdpi/perm_group_system_clock.png
index e4d5743..554dd0f 100644
--- a/core/res/res/drawable-mdpi/perm_group_system_clock.png
+++ b/core/res/res/drawable-mdpi/perm_group_system_clock.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/perm_group_system_tools.png b/core/res/res/drawable-mdpi/perm_group_system_tools.png
index fc7337d..845a593 100644
--- a/core/res/res/drawable-mdpi/perm_group_system_tools.png
+++ b/core/res/res/drawable-mdpi/perm_group_system_tools.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/perm_group_user_dictionary.png b/core/res/res/drawable-mdpi/perm_group_user_dictionary.png
index 92864ba..188343d 100644
--- a/core/res/res/drawable-mdpi/perm_group_user_dictionary.png
+++ b/core/res/res/drawable-mdpi/perm_group_user_dictionary.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/perm_group_user_dictionary_write.png b/core/res/res/drawable-mdpi/perm_group_user_dictionary_write.png
index 9f48713..04b9cdc 100644
--- a/core/res/res/drawable-mdpi/perm_group_user_dictionary_write.png
+++ b/core/res/res/drawable-mdpi/perm_group_user_dictionary_write.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/perm_group_voicemail.png b/core/res/res/drawable-mdpi/perm_group_voicemail.png
index a34d689..163046b 100644
--- a/core/res/res/drawable-mdpi/perm_group_voicemail.png
+++ b/core/res/res/drawable-mdpi/perm_group_voicemail.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/perm_group_wallpaper.png b/core/res/res/drawable-mdpi/perm_group_wallpaper.png
index b990e7f..5b96e08 100644
--- a/core/res/res/drawable-mdpi/perm_group_wallpaper.png
+++ b/core/res/res/drawable-mdpi/perm_group_wallpaper.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/popup_background_qntm_mult.9.png b/core/res/res/drawable-mdpi/popup_background_mtrl_mult.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/popup_background_qntm_mult.9.png
rename to core/res/res/drawable-mdpi/popup_background_mtrl_mult.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/progress_qntm_alpha.9.png b/core/res/res/drawable-mdpi/progress_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/progress_qntm_alpha.9.png
rename to core/res/res/drawable-mdpi/progress_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/progress_primary_qntm_alpha.9.png b/core/res/res/drawable-mdpi/progress_primary_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/progress_primary_qntm_alpha.9.png
rename to core/res/res/drawable-mdpi/progress_primary_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/scrollbar_handle_qntm_alpha.9.png b/core/res/res/drawable-mdpi/scrollbar_handle_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/scrollbar_handle_qntm_alpha.9.png
rename to core/res/res/drawable-mdpi/scrollbar_handle_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/scrubber_control_from_pressed_qntm_000.png b/core/res/res/drawable-mdpi/scrubber_control_from_pressed_mtrl_000.png
similarity index 100%
rename from core/res/res/drawable-mdpi/scrubber_control_from_pressed_qntm_000.png
rename to core/res/res/drawable-mdpi/scrubber_control_from_pressed_mtrl_000.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/scrubber_control_from_pressed_qntm_001.png b/core/res/res/drawable-mdpi/scrubber_control_from_pressed_mtrl_001.png
similarity index 100%
rename from core/res/res/drawable-mdpi/scrubber_control_from_pressed_qntm_001.png
rename to core/res/res/drawable-mdpi/scrubber_control_from_pressed_mtrl_001.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/scrubber_control_from_pressed_qntm_002.png b/core/res/res/drawable-mdpi/scrubber_control_from_pressed_mtrl_002.png
similarity index 100%
rename from core/res/res/drawable-mdpi/scrubber_control_from_pressed_qntm_002.png
rename to core/res/res/drawable-mdpi/scrubber_control_from_pressed_mtrl_002.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/scrubber_control_from_pressed_qntm_003.png b/core/res/res/drawable-mdpi/scrubber_control_from_pressed_mtrl_003.png
similarity index 100%
rename from core/res/res/drawable-mdpi/scrubber_control_from_pressed_qntm_003.png
rename to core/res/res/drawable-mdpi/scrubber_control_from_pressed_mtrl_003.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/scrubber_control_from_pressed_qntm_004.png b/core/res/res/drawable-mdpi/scrubber_control_from_pressed_mtrl_004.png
similarity index 100%
rename from core/res/res/drawable-mdpi/scrubber_control_from_pressed_qntm_004.png
rename to core/res/res/drawable-mdpi/scrubber_control_from_pressed_mtrl_004.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/scrubber_control_from_pressed_qntm_005.png b/core/res/res/drawable-mdpi/scrubber_control_from_pressed_mtrl_005.png
similarity index 100%
rename from core/res/res/drawable-mdpi/scrubber_control_from_pressed_qntm_005.png
rename to core/res/res/drawable-mdpi/scrubber_control_from_pressed_mtrl_005.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/scrubber_control_off_qntm_alpha.png b/core/res/res/drawable-mdpi/scrubber_control_off_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-mdpi/scrubber_control_off_qntm_alpha.png
rename to core/res/res/drawable-mdpi/scrubber_control_off_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/scrubber_control_off_pressed_qntm_alpha.png b/core/res/res/drawable-mdpi/scrubber_control_off_pressed_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-mdpi/scrubber_control_off_pressed_qntm_alpha.png
rename to core/res/res/drawable-mdpi/scrubber_control_off_pressed_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/scrubber_control_on_qntm_alpha.png b/core/res/res/drawable-mdpi/scrubber_control_on_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-mdpi/scrubber_control_on_qntm_alpha.png
rename to core/res/res/drawable-mdpi/scrubber_control_on_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_on_pressed_qntm_alpha.png b/core/res/res/drawable-mdpi/scrubber_control_on_pressed_mtrl_alpha.png
similarity index 100%
copy from core/res/res/drawable-mdpi/btn_radio_on_pressed_qntm_alpha.png
copy to core/res/res/drawable-mdpi/scrubber_control_on_pressed_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/scrubber_control_on_pressed_qntm_alpha.png b/core/res/res/drawable-mdpi/scrubber_control_on_pressed_qntm_alpha.png
deleted file mode 100644
index 3c304bf..0000000
--- a/core/res/res/drawable-mdpi/scrubber_control_on_pressed_qntm_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/scrubber_control_to_pressed_qntm_000.png b/core/res/res/drawable-mdpi/scrubber_control_to_pressed_mtrl_000.png
similarity index 100%
rename from core/res/res/drawable-mdpi/scrubber_control_to_pressed_qntm_000.png
rename to core/res/res/drawable-mdpi/scrubber_control_to_pressed_mtrl_000.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/scrubber_control_to_pressed_qntm_001.png b/core/res/res/drawable-mdpi/scrubber_control_to_pressed_mtrl_001.png
similarity index 100%
rename from core/res/res/drawable-mdpi/scrubber_control_to_pressed_qntm_001.png
rename to core/res/res/drawable-mdpi/scrubber_control_to_pressed_mtrl_001.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/scrubber_control_to_pressed_qntm_002.png b/core/res/res/drawable-mdpi/scrubber_control_to_pressed_mtrl_002.png
similarity index 100%
rename from core/res/res/drawable-mdpi/scrubber_control_to_pressed_qntm_002.png
rename to core/res/res/drawable-mdpi/scrubber_control_to_pressed_mtrl_002.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/scrubber_control_to_pressed_qntm_003.png b/core/res/res/drawable-mdpi/scrubber_control_to_pressed_mtrl_003.png
similarity index 100%
rename from core/res/res/drawable-mdpi/scrubber_control_to_pressed_qntm_003.png
rename to core/res/res/drawable-mdpi/scrubber_control_to_pressed_mtrl_003.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/scrubber_control_to_pressed_qntm_004.png b/core/res/res/drawable-mdpi/scrubber_control_to_pressed_mtrl_004.png
similarity index 100%
rename from core/res/res/drawable-mdpi/scrubber_control_to_pressed_qntm_004.png
rename to core/res/res/drawable-mdpi/scrubber_control_to_pressed_mtrl_004.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/scrubber_control_to_pressed_qntm_005.png b/core/res/res/drawable-mdpi/scrubber_control_to_pressed_mtrl_005.png
similarity index 100%
rename from core/res/res/drawable-mdpi/scrubber_control_to_pressed_qntm_005.png
rename to core/res/res/drawable-mdpi/scrubber_control_to_pressed_mtrl_005.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/scrubber_primary_qntm_alpha.9.png b/core/res/res/drawable-mdpi/scrubber_primary_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/scrubber_primary_qntm_alpha.9.png
rename to core/res/res/drawable-mdpi/scrubber_primary_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/scrubber_track_qntm_alpha.9.png b/core/res/res/drawable-mdpi/scrubber_track_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/scrubber_track_qntm_alpha.9.png
rename to core/res/res/drawable-mdpi/scrubber_track_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_20_inner_holo.png b/core/res/res/drawable-mdpi/spinner_20_inner_holo.png
deleted file mode 100644
index 4569fae..0000000
--- a/core/res/res/drawable-mdpi/spinner_20_inner_holo.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_20_outer_holo.png b/core/res/res/drawable-mdpi/spinner_20_outer_holo.png
deleted file mode 100644
index 9287dd7..0000000
--- a/core/res/res/drawable-mdpi/spinner_20_outer_holo.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_qntm_am_alpha.9.png b/core/res/res/drawable-mdpi/spinner_mtrl_am_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/spinner_qntm_am_alpha.9.png
rename to core/res/res/drawable-mdpi/spinner_mtrl_am_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/switch_track_qntm_alpha.9.png b/core/res/res/drawable-mdpi/switch_track_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/switch_track_qntm_alpha.9.png
rename to core/res/res/drawable-mdpi/switch_track_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/tab_indicator_mtrl_alpha.9.png b/core/res/res/drawable-mdpi/tab_indicator_mtrl_alpha.9.png
new file mode 100644
index 0000000..b69529c
--- /dev/null
+++ b/core/res/res/drawable-mdpi/tab_indicator_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/tab_indicator_normal_qntm_alpha.9.png b/core/res/res/drawable-mdpi/tab_indicator_normal_qntm_alpha.9.png
deleted file mode 100644
index fd668ee..0000000
--- a/core/res/res/drawable-mdpi/tab_indicator_normal_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/tab_indicator_selected_qntm_alpha.9.png b/core/res/res/drawable-mdpi/tab_indicator_selected_qntm_alpha.9.png
deleted file mode 100644
index ace579f..0000000
--- a/core/res/res/drawable-mdpi/tab_indicator_selected_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/text_cursor_qntm_alpha.9.png b/core/res/res/drawable-mdpi/text_cursor_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/text_cursor_qntm_alpha.9.png
rename to core/res/res/drawable-mdpi/text_cursor_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/text_select_handle_left_qntm_alpha.png b/core/res/res/drawable-mdpi/text_select_handle_left_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-mdpi/text_select_handle_left_qntm_alpha.png
rename to core/res/res/drawable-mdpi/text_select_handle_left_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/text_select_handle_middle_qntm_alpha.png b/core/res/res/drawable-mdpi/text_select_handle_middle_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-mdpi/text_select_handle_middle_qntm_alpha.png
rename to core/res/res/drawable-mdpi/text_select_handle_middle_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/text_select_handle_right_qntm_alpha.png b/core/res/res/drawable-mdpi/text_select_handle_right_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-mdpi/text_select_handle_right_qntm_alpha.png
rename to core/res/res/drawable-mdpi/text_select_handle_right_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_activated_qntm_alpha.9.png b/core/res/res/drawable-mdpi/textfield_activated_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/textfield_activated_qntm_alpha.9.png
rename to core/res/res/drawable-mdpi/textfield_activated_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_default_qntm_alpha.9.png b/core/res/res/drawable-mdpi/textfield_default_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/textfield_default_qntm_alpha.9.png
rename to core/res/res/drawable-mdpi/textfield_default_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_search_activated_qntm_alpha.9.png b/core/res/res/drawable-mdpi/textfield_search_activated_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/textfield_search_activated_qntm_alpha.9.png
rename to core/res/res/drawable-mdpi/textfield_search_activated_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_search_default_qntm_alpha.9.png b/core/res/res/drawable-mdpi/textfield_search_default_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/textfield_search_default_qntm_alpha.9.png
rename to core/res/res/drawable-mdpi/textfield_search_default_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-nodpi/indicator_code_lock_drag_direction_green_up.png b/core/res/res/drawable-nodpi/indicator_code_lock_drag_direction_green_up.png
deleted file mode 100644
index cc46f19..0000000
--- a/core/res/res/drawable-nodpi/indicator_code_lock_drag_direction_green_up.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-nodpi/indicator_code_lock_drag_direction_red_up.png b/core/res/res/drawable-nodpi/indicator_code_lock_drag_direction_red_up.png
deleted file mode 100644
index cc46f19..0000000
--- a/core/res/res/drawable-nodpi/indicator_code_lock_drag_direction_red_up.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-nodpi/platlogo.xml b/core/res/res/drawable-nodpi/platlogo.xml
index 668cff7..d1e2df3 100644
--- a/core/res/res/drawable-nodpi/platlogo.xml
+++ b/core/res/res/drawable-nodpi/platlogo.xml
@@ -19,18 +19,21 @@
     <viewport android:viewportHeight="25" android:viewportWidth="25" />
 
     <path
-        android:name="shadow"
-        android:pathData="m12,2.5 a11,11 0 1,0 1,0
-        M6.5,7.5
-        l5,0 l0,7 l7,0 l0,5 l-12,0 z"
-        android:fill="#40000000"
+        android:name="torso"
+        android:pathData="m2,2 l21,0 l0,21 l-21,0 z"
+        android:fill="#FFFFFFFF"
         />
+
     <path
-        android:name="circle-L-ranch"
-        android:pathData="m12,1.5 a11,11 0 1,0 1,0
-        M6.5,6.5
-        l5,0 l0,7 l7,0 l0,5 l-12,0 z"
-        android:fill="#FFFFFF40"
+        android:name="|"
+        android:pathData="m4,4 l8,0 l0,17 l-8,0 z"
+        android:fill="#FF0000FF"
+        />
+
+    <path
+        android:name="_"
+        android:pathData="m5,14 l16,0 l0,6 l-16,0 z"
+        android:fill="#FFFF0000"
         />
 
 </vector>
diff --git a/core/res/res/drawable-nodpi/stat_sys_adb.xml b/core/res/res/drawable-nodpi/stat_sys_adb.xml
index b8ddb77..6b3be4a 100644
--- a/core/res/res/drawable-nodpi/stat_sys_adb.xml
+++ b/core/res/res/drawable-nodpi/stat_sys_adb.xml
@@ -18,13 +18,26 @@
 
     <viewport android:viewportHeight="25" android:viewportWidth="25" />
 
-
     <path
-        android:name="adb"
-        android:pathData="m3,3l8,0l0,11l11,0l0,8l-19,0z"
+        android:name="L-card"
+
+        android:pathData="
+        m4,2
+        a2,2,0,0,0,-2,2 l0,17
+        a2,2,0,0,0,2,2  l17,0
+        a2,2,0,0,0,2,-2 l0,-17
+        a2,2,0,0,0,-2,-2
+        z
+
+        M7,2 l3,0 l0,13 l13,0 l0,3 l-16,0
+
+        M15,2 l3,0 l0,5 l5,0 l0,3 l-8,0
+
+        z"
         android:fill="#FFFFFFFF"
         />
 
+
 </vector>
 
 
diff --git a/core/res/res/drawable-sw600dp-mdpi/indicator_code_lock_drag_direction_red_up.png b/core/res/res/drawable-sw600dp-mdpi/indicator_code_lock_drag_direction_red_up.png
deleted file mode 100644
index 2ab4547..0000000
--- a/core/res/res/drawable-sw600dp-mdpi/indicator_code_lock_drag_direction_red_up.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_share_pack_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/ab_share_pack_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ab_share_pack_qntm_alpha.9.png
rename to core/res/res/drawable-xhdpi/ab_share_pack_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_solid_shadow_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/ab_solid_shadow_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ab_solid_shadow_qntm_alpha.9.png
rename to core/res/res/drawable-xhdpi/ab_solid_shadow_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_cab_done_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/btn_cab_done_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_cab_done_qntm_alpha.9.png
rename to core/res/res/drawable-xhdpi/btn_cab_done_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_000.png b/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_000.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_check_to_off_qntm_000.png
rename to core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_000.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_001.png b/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_001.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_check_to_off_qntm_001.png
rename to core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_001.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_002.png b/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_002.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_check_to_off_qntm_002.png
rename to core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_002.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_003.png b/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_003.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_check_to_off_qntm_003.png
rename to core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_003.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_004.png b/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_004.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_check_to_off_qntm_004.png
rename to core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_004.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_005.png b/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_005.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_check_to_off_qntm_005.png
rename to core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_005.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_006.png b/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_006.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_check_to_off_qntm_006.png
rename to core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_006.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_007.png b/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_007.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_check_to_off_qntm_007.png
rename to core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_007.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_008.png b/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_008.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_check_to_off_qntm_008.png
rename to core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_008.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_009.png b/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_009.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_check_to_off_qntm_009.png
rename to core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_009.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_010.png b/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_010.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_check_to_off_qntm_010.png
rename to core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_010.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_011.png b/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_011.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_check_to_off_qntm_011.png
rename to core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_011.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_012.png b/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_012.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_check_to_off_qntm_012.png
rename to core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_012.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_013.png b/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_013.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_check_to_off_qntm_013.png
rename to core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_013.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_014.png b/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_014.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_check_to_off_qntm_014.png
rename to core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_014.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_015.png b/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_015.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_check_to_off_qntm_015.png
rename to core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_015.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_000.png b/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_000.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_check_to_on_qntm_000.png
rename to core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_000.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_001.png b/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_001.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_check_to_on_qntm_001.png
rename to core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_001.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_002.png b/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_002.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_check_to_on_qntm_002.png
rename to core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_002.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_003.png b/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_003.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_check_to_on_qntm_003.png
rename to core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_003.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_004.png b/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_004.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_check_to_on_qntm_004.png
rename to core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_004.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_005.png b/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_005.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_check_to_on_qntm_005.png
rename to core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_005.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_006.png b/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_006.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_check_to_on_qntm_006.png
rename to core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_006.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_007.png b/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_007.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_check_to_on_qntm_007.png
rename to core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_007.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_008.png b/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_008.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_check_to_on_qntm_008.png
rename to core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_008.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_009.png b/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_009.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_check_to_on_qntm_009.png
rename to core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_009.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_010.png b/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_010.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_check_to_on_qntm_010.png
rename to core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_010.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_011.png b/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_011.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_check_to_on_qntm_011.png
rename to core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_011.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_012.png b/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_012.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_check_to_on_qntm_012.png
rename to core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_012.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_013.png b/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_013.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_check_to_on_qntm_013.png
rename to core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_013.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_014.png b/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_014.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_check_to_on_qntm_014.png
rename to core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_014.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_015.png b/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_015.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_check_to_on_qntm_015.png
rename to core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_015.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_code_lock_default.png b/core/res/res/drawable-xhdpi/btn_code_lock_default.png
deleted file mode 100644
index c1358a2..0000000
--- a/core/res/res/drawable-xhdpi/btn_code_lock_default.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_code_lock_default_holo.png b/core/res/res/drawable-xhdpi/btn_code_lock_default_holo.png
deleted file mode 100644
index db1cbe6..0000000
--- a/core/res/res/drawable-xhdpi/btn_code_lock_default_holo.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_code_lock_default_mtrl_alpha.png b/core/res/res/drawable-xhdpi/btn_code_lock_default_mtrl_alpha.png
new file mode 100644
index 0000000..0c457b4
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/btn_code_lock_default_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_code_lock_touched.png b/core/res/res/drawable-xhdpi/btn_code_lock_touched.png
deleted file mode 100644
index 0fafc3e..0000000
--- a/core/res/res/drawable-xhdpi/btn_code_lock_touched.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_code_lock_touched_holo.png b/core/res/res/drawable-xhdpi/btn_code_lock_touched_holo.png
deleted file mode 100644
index 073c3ac..0000000
--- a/core/res/res/drawable-xhdpi/btn_code_lock_touched_holo.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_code_lock_touched_mtrl_alpha.png b/core/res/res/drawable-xhdpi/btn_code_lock_touched_mtrl_alpha.png
new file mode 100644
index 0000000..020d699
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/btn_code_lock_touched_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/btn_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_qntm_alpha.9.png
rename to core/res/res/drawable-xhdpi/btn_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_on_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_radio_on_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_radio_on_qntm_alpha.png
rename to core/res/res/drawable-xhdpi/btn_radio_on_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_on_pressed_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_radio_on_pressed_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_radio_on_pressed_qntm_alpha.png
rename to core/res/res/drawable-xhdpi/btn_radio_on_pressed_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_000.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_000.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_000.png
rename to core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_000.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_001.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_001.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_001.png
rename to core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_001.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_002.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_002.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_002.png
rename to core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_002.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_003.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_003.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_003.png
rename to core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_003.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_004.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_004.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_004.png
rename to core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_004.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_005.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_005.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_005.png
rename to core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_005.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_006.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_006.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_006.png
rename to core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_006.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_007.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_007.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_007.png
rename to core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_007.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_008.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_008.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_008.png
rename to core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_008.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_009.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_009.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_009.png
rename to core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_009.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_010.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_010.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_010.png
rename to core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_010.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_011.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_011.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_011.png
rename to core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_011.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_012.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_012.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_012.png
rename to core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_012.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_013.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_013.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_013.png
rename to core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_013.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_014.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_014.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_014.png
rename to core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_014.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_015.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_015.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_015.png
rename to core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_015.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_000.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_000.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_000.png
rename to core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_000.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_001.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_001.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_001.png
rename to core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_001.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_002.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_002.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_002.png
rename to core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_002.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_003.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_003.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_003.png
rename to core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_003.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_004.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_004.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_004.png
rename to core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_004.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_005.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_005.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_005.png
rename to core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_005.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_006.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_006.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_006.png
rename to core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_006.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_007.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_007.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_007.png
rename to core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_007.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_008.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_008.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_008.png
rename to core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_008.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_009.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_009.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_009.png
rename to core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_009.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_010.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_010.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_010.png
rename to core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_010.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_011.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_011.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_011.png
rename to core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_011.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_012.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_012.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_012.png
rename to core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_012.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_013.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_013.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_013.png
rename to core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_013.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_014.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_014.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_014.png
rename to core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_014.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_015.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_015.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_015.png
rename to core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_015.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_rating_star_off_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_rating_star_off_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_rating_star_off_qntm_alpha.png
rename to core/res/res/drawable-xhdpi/btn_rating_star_off_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_rating_star_on_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_rating_star_on_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_rating_star_on_qntm_alpha.png
rename to core/res/res/drawable-xhdpi/btn_rating_star_on_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_star_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_star_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_star_qntm_alpha.png
rename to core/res/res/drawable-xhdpi/btn_star_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_000.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_000.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_000.png
rename to core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_000.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_001.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_001.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_001.png
rename to core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_001.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_002.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_002.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_002.png
rename to core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_002.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_003.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_003.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_003.png
rename to core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_003.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_004.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_004.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_004.png
rename to core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_004.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_005.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_005.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_005.png
rename to core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_005.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_006.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_006.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_006.png
rename to core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_006.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_007.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_007.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_007.png
rename to core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_007.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_008.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_008.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_008.png
rename to core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_008.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_009.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_009.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_009.png
rename to core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_009.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_010.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_010.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_010.png
rename to core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_010.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_011.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_011.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_011.png
rename to core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_011.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_012.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_012.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_012.png
rename to core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_012.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_013.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_013.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_013.png
rename to core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_013.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_014.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_014.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_014.png
rename to core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_014.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_000.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_000.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_000.png
rename to core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_000.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_001.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_001.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_001.png
rename to core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_001.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_002.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_002.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_002.png
rename to core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_002.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_003.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_003.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_003.png
rename to core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_003.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_004.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_004.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_004.png
rename to core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_004.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_005.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_005.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_005.png
rename to core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_005.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_006.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_006.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_006.png
rename to core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_006.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_007.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_007.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_007.png
rename to core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_007.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_008.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_008.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_008.png
rename to core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_008.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_009.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_009.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_009.png
rename to core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_009.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_010.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_010.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_010.png
rename to core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_010.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_011.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_011.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_011.png
rename to core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_011.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_012.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_012.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_012.png
rename to core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_012.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_013.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_013.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_013.png
rename to core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_013.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_014.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_014.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_014.png
rename to core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_014.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_indicator_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/btn_toggle_indicator_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_toggle_indicator_qntm_alpha.9.png
rename to core/res/res/drawable-xhdpi/btn_toggle_indicator_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/btn_toggle_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/btn_toggle_qntm_alpha.9.png
rename to core/res/res/drawable-xhdpi/btn_toggle_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/expander_close_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/expander_close_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/expander_close_qntm_alpha.9.png
rename to core/res/res/drawable-xhdpi/expander_close_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/expander_open_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/expander_open_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/expander_open_qntm_alpha.9.png
rename to core/res/res/drawable-xhdpi/expander_open_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/fastscroll_thumb_qntm_alpha.png b/core/res/res/drawable-xhdpi/fastscroll_thumb_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/fastscroll_thumb_qntm_alpha.png
rename to core/res/res/drawable-xhdpi/fastscroll_thumb_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/fastscroll_track_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/fastscroll_track_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/fastscroll_track_qntm_alpha.9.png
rename to core/res/res/drawable-xhdpi/fastscroll_track_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_ab_back_qntm_am_alpha.png b/core/res/res/drawable-xhdpi/ic_ab_back_mtrl_am_alpha.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_ab_back_qntm_am_alpha.png
rename to core/res/res/drawable-xhdpi/ic_ab_back_mtrl_am_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_cab_done_qntm_alpha.png b/core/res/res/drawable-xhdpi/ic_cab_done_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_cab_done_qntm_alpha.png
rename to core/res/res/drawable-xhdpi/ic_cab_done_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_clear_qntm_alpha.png b/core/res/res/drawable-xhdpi/ic_clear_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_clear_qntm_alpha.png
rename to core/res/res/drawable-xhdpi/ic_clear_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_commit_search_api_qntm_alpha.png b/core/res/res/drawable-xhdpi/ic_commit_search_api_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_commit_search_api_qntm_alpha.png
rename to core/res/res/drawable-xhdpi/ic_commit_search_api_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_corp_badge.png b/core/res/res/drawable-xhdpi/ic_corp_badge.png
deleted file mode 100644
index 80d848d..0000000
--- a/core/res/res/drawable-xhdpi/ic_corp_badge.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_dialog_alert_qntm_alpha.png b/core/res/res/drawable-xhdpi/ic_dialog_alert_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_dialog_alert_qntm_alpha.png
rename to core/res/res/drawable-xhdpi/ic_dialog_alert_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_find_next_qntm_alpha.png b/core/res/res/drawable-xhdpi/ic_find_next_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_find_next_qntm_alpha.png
rename to core/res/res/drawable-xhdpi/ic_find_next_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_find_previous_qntm_alpha.png b/core/res/res/drawable-xhdpi/ic_find_previous_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_find_previous_qntm_alpha.png
rename to core/res/res/drawable-xhdpi/ic_find_previous_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_go_search_api_qntm_alpha.png b/core/res/res/drawable-xhdpi/ic_go_search_api_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_go_search_api_qntm_alpha.png
rename to core/res/res/drawable-xhdpi/ic_go_search_api_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_disabled_qntm_alpha.png b/core/res/res/drawable-xhdpi/ic_media_route_disabled_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_media_route_disabled_qntm_alpha.png
rename to core/res/res/drawable-xhdpi/ic_media_route_disabled_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_off_qntm_alpha.png b/core/res/res/drawable-xhdpi/ic_media_route_off_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_media_route_off_qntm_alpha.png
rename to core/res/res/drawable-xhdpi/ic_media_route_off_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_on_0_qntm_alpha.png b/core/res/res/drawable-xhdpi/ic_media_route_on_0_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_media_route_on_0_qntm_alpha.png
rename to core/res/res/drawable-xhdpi/ic_media_route_on_0_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_on_1_qntm_alpha.png b/core/res/res/drawable-xhdpi/ic_media_route_on_1_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_media_route_on_1_qntm_alpha.png
rename to core/res/res/drawable-xhdpi/ic_media_route_on_1_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_on_2_qntm_alpha.png b/core/res/res/drawable-xhdpi/ic_media_route_on_2_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_media_route_on_2_qntm_alpha.png
rename to core/res/res/drawable-xhdpi/ic_media_route_on_2_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_on_qntm_alpha.png b/core/res/res/drawable-xhdpi/ic_media_route_on_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_media_route_on_qntm_alpha.png
rename to core/res/res/drawable-xhdpi/ic_media_route_on_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_copy_qntm_am_alpha.png b/core/res/res/drawable-xhdpi/ic_menu_copy_mtrl_am_alpha.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_menu_copy_qntm_am_alpha.png
rename to core/res/res/drawable-xhdpi/ic_menu_copy_mtrl_am_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_cut_qntm_alpha.png b/core/res/res/drawable-xhdpi/ic_menu_cut_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_menu_cut_qntm_alpha.png
rename to core/res/res/drawable-xhdpi/ic_menu_cut_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_find_qntm_alpha.png b/core/res/res/drawable-xhdpi/ic_menu_find_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_menu_find_qntm_alpha.png
rename to core/res/res/drawable-xhdpi/ic_menu_find_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_moreoverflow_qntm_alpha.png b/core/res/res/drawable-xhdpi/ic_menu_moreoverflow_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_menu_moreoverflow_qntm_alpha.png
rename to core/res/res/drawable-xhdpi/ic_menu_moreoverflow_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_paste_qntm_am_alpha.png b/core/res/res/drawable-xhdpi/ic_menu_paste_mtrl_am_alpha.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_menu_paste_qntm_am_alpha.png
rename to core/res/res/drawable-xhdpi/ic_menu_paste_mtrl_am_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_search_qntm_alpha.png b/core/res/res/drawable-xhdpi/ic_menu_search_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_menu_search_qntm_alpha.png
rename to core/res/res/drawable-xhdpi/ic_menu_search_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_selectall_qntm_alpha.png b/core/res/res/drawable-xhdpi/ic_menu_selectall_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_menu_selectall_qntm_alpha.png
rename to core/res/res/drawable-xhdpi/ic_menu_selectall_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_share_qntm_alpha.png b/core/res/res/drawable-xhdpi/ic_menu_share_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_menu_share_qntm_alpha.png
rename to core/res/res/drawable-xhdpi/ic_menu_share_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_search_api_qntm_alpha.png b/core/res/res/drawable-xhdpi/ic_search_api_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_search_api_qntm_alpha.png
rename to core/res/res/drawable-xhdpi/ic_search_api_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_voice_search_api_qntm_alpha.png b/core/res/res/drawable-xhdpi/ic_voice_search_api_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_voice_search_api_qntm_alpha.png
rename to core/res/res/drawable-xhdpi/ic_voice_search_api_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/indicator_code_lock_drag_direction_red_up.png b/core/res/res/drawable-xhdpi/indicator_code_lock_drag_direction_red_up.png
deleted file mode 100644
index 2d34cf6..0000000
--- a/core/res/res/drawable-xhdpi/indicator_code_lock_drag_direction_red_up.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/indicator_code_lock_drag_direction_up_mtrl_alpha.png b/core/res/res/drawable-xhdpi/indicator_code_lock_drag_direction_up_mtrl_alpha.png
new file mode 100644
index 0000000..fda5e37
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/indicator_code_lock_drag_direction_up_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/indicator_code_lock_point_area_default.png b/core/res/res/drawable-xhdpi/indicator_code_lock_point_area_default.png
deleted file mode 100644
index 0812cb5..0000000
--- a/core/res/res/drawable-xhdpi/indicator_code_lock_point_area_default.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/indicator_code_lock_point_area_default_holo.png b/core/res/res/drawable-xhdpi/indicator_code_lock_point_area_default_mtrl_alpha.png
similarity index 86%
rename from core/res/res/drawable-xhdpi/indicator_code_lock_point_area_default_holo.png
rename to core/res/res/drawable-xhdpi/indicator_code_lock_point_area_default_mtrl_alpha.png
index 6a97445..75d0221 100644
--- a/core/res/res/drawable-xhdpi/indicator_code_lock_point_area_default_holo.png
+++ b/core/res/res/drawable-xhdpi/indicator_code_lock_point_area_default_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/indicator_code_lock_point_area_green.png b/core/res/res/drawable-xhdpi/indicator_code_lock_point_area_green.png
deleted file mode 100644
index 3ab2e99..0000000
--- a/core/res/res/drawable-xhdpi/indicator_code_lock_point_area_green.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/indicator_code_lock_point_area_green_holo.png b/core/res/res/drawable-xhdpi/indicator_code_lock_point_area_mtrl_alpha.png
similarity index 96%
rename from core/res/res/drawable-xhdpi/indicator_code_lock_point_area_green_holo.png
rename to core/res/res/drawable-xhdpi/indicator_code_lock_point_area_mtrl_alpha.png
index f0e9ab9..225799b 100644
--- a/core/res/res/drawable-xhdpi/indicator_code_lock_point_area_green_holo.png
+++ b/core/res/res/drawable-xhdpi/indicator_code_lock_point_area_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/indicator_code_lock_point_area_red_holo.png b/core/res/res/drawable-xhdpi/indicator_code_lock_point_area_red_holo.png
deleted file mode 100644
index 170b833..0000000
--- a/core/res/res/drawable-xhdpi/indicator_code_lock_point_area_red_holo.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/list_divider_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/list_divider_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/list_divider_qntm_alpha.9.png
rename to core/res/res/drawable-xhdpi/list_divider_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/list_section_divider_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/list_section_divider_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/list_section_divider_qntm_alpha.9.png
rename to core/res/res/drawable-xhdpi/list_section_divider_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/perm_group_accessibility_features.png b/core/res/res/drawable-xhdpi/perm_group_accessibility_features.png
index 2fec7a3..9edbada 100644
--- a/core/res/res/drawable-xhdpi/perm_group_accessibility_features.png
+++ b/core/res/res/drawable-xhdpi/perm_group_accessibility_features.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/perm_group_accounts.png b/core/res/res/drawable-xhdpi/perm_group_accounts.png
index 74cd33b..b2cad91 100644
--- a/core/res/res/drawable-xhdpi/perm_group_accounts.png
+++ b/core/res/res/drawable-xhdpi/perm_group_accounts.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/perm_group_affects_battery.png b/core/res/res/drawable-xhdpi/perm_group_affects_battery.png
index d4a9bb5d..123e0a2 100644
--- a/core/res/res/drawable-xhdpi/perm_group_affects_battery.png
+++ b/core/res/res/drawable-xhdpi/perm_group_affects_battery.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/perm_group_app_info.png b/core/res/res/drawable-xhdpi/perm_group_app_info.png
index 46089e5..8373633 100644
--- a/core/res/res/drawable-xhdpi/perm_group_app_info.png
+++ b/core/res/res/drawable-xhdpi/perm_group_app_info.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/perm_group_audio_settings.png b/core/res/res/drawable-xhdpi/perm_group_audio_settings.png
index 2f7cbc3..7c10395 100644
--- a/core/res/res/drawable-xhdpi/perm_group_audio_settings.png
+++ b/core/res/res/drawable-xhdpi/perm_group_audio_settings.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/perm_group_bluetooth.png b/core/res/res/drawable-xhdpi/perm_group_bluetooth.png
index 6bbde52..ce58d66 100644
--- a/core/res/res/drawable-xhdpi/perm_group_bluetooth.png
+++ b/core/res/res/drawable-xhdpi/perm_group_bluetooth.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/perm_group_bookmarks.png b/core/res/res/drawable-xhdpi/perm_group_bookmarks.png
index 1277d03..db28d89 100644
--- a/core/res/res/drawable-xhdpi/perm_group_bookmarks.png
+++ b/core/res/res/drawable-xhdpi/perm_group_bookmarks.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/perm_group_calendar.png b/core/res/res/drawable-xhdpi/perm_group_calendar.png
index 3c7f2d3..d49b883 100644
--- a/core/res/res/drawable-xhdpi/perm_group_calendar.png
+++ b/core/res/res/drawable-xhdpi/perm_group_calendar.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/perm_group_camera.png b/core/res/res/drawable-xhdpi/perm_group_camera.png
index a454554..5287e00 100644
--- a/core/res/res/drawable-xhdpi/perm_group_camera.png
+++ b/core/res/res/drawable-xhdpi/perm_group_camera.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/perm_group_device_alarms.png b/core/res/res/drawable-xhdpi/perm_group_device_alarms.png
index 1bb151c..c52148d 100644
--- a/core/res/res/drawable-xhdpi/perm_group_device_alarms.png
+++ b/core/res/res/drawable-xhdpi/perm_group_device_alarms.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/perm_group_display.png b/core/res/res/drawable-xhdpi/perm_group_display.png
index 9e36cf8..90fcc73 100644
--- a/core/res/res/drawable-xhdpi/perm_group_display.png
+++ b/core/res/res/drawable-xhdpi/perm_group_display.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/perm_group_location.png b/core/res/res/drawable-xhdpi/perm_group_location.png
index 4c49521..99dbcbc 100644
--- a/core/res/res/drawable-xhdpi/perm_group_location.png
+++ b/core/res/res/drawable-xhdpi/perm_group_location.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/perm_group_messages.png b/core/res/res/drawable-xhdpi/perm_group_messages.png
index f046d46..c674d54 100644
--- a/core/res/res/drawable-xhdpi/perm_group_messages.png
+++ b/core/res/res/drawable-xhdpi/perm_group_messages.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/perm_group_microphone.png b/core/res/res/drawable-xhdpi/perm_group_microphone.png
index bdb66e2..9c2a6b6 100644
--- a/core/res/res/drawable-xhdpi/perm_group_microphone.png
+++ b/core/res/res/drawable-xhdpi/perm_group_microphone.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/perm_group_network.png b/core/res/res/drawable-xhdpi/perm_group_network.png
index fe1adad..8557889 100644
--- a/core/res/res/drawable-xhdpi/perm_group_network.png
+++ b/core/res/res/drawable-xhdpi/perm_group_network.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/perm_group_personal_info.png b/core/res/res/drawable-xhdpi/perm_group_personal_info.png
index 1ae418f..3a1419a 100644
--- a/core/res/res/drawable-xhdpi/perm_group_personal_info.png
+++ b/core/res/res/drawable-xhdpi/perm_group_personal_info.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/perm_group_phone_calls.png b/core/res/res/drawable-xhdpi/perm_group_phone_calls.png
index 288e15c..9a24905 100644
--- a/core/res/res/drawable-xhdpi/perm_group_phone_calls.png
+++ b/core/res/res/drawable-xhdpi/perm_group_phone_calls.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/perm_group_screenlock.png b/core/res/res/drawable-xhdpi/perm_group_screenlock.png
index bf3ec34..49f526e 100644
--- a/core/res/res/drawable-xhdpi/perm_group_screenlock.png
+++ b/core/res/res/drawable-xhdpi/perm_group_screenlock.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/perm_group_shortrange_network.png b/core/res/res/drawable-xhdpi/perm_group_shortrange_network.png
index 5e1e240..8557889 100644
--- a/core/res/res/drawable-xhdpi/perm_group_shortrange_network.png
+++ b/core/res/res/drawable-xhdpi/perm_group_shortrange_network.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/perm_group_social_info.png b/core/res/res/drawable-xhdpi/perm_group_social_info.png
index 2111a83..1ecda40 100644
--- a/core/res/res/drawable-xhdpi/perm_group_social_info.png
+++ b/core/res/res/drawable-xhdpi/perm_group_social_info.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/perm_group_status_bar.png b/core/res/res/drawable-xhdpi/perm_group_status_bar.png
index ce65380..19a611b 100644
--- a/core/res/res/drawable-xhdpi/perm_group_status_bar.png
+++ b/core/res/res/drawable-xhdpi/perm_group_status_bar.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/perm_group_storage.png b/core/res/res/drawable-xhdpi/perm_group_storage.png
index 4cd5c9b..85753f1 100644
--- a/core/res/res/drawable-xhdpi/perm_group_storage.png
+++ b/core/res/res/drawable-xhdpi/perm_group_storage.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/perm_group_sync_settings.png b/core/res/res/drawable-xhdpi/perm_group_sync_settings.png
index 24eb579..7249716 100644
--- a/core/res/res/drawable-xhdpi/perm_group_sync_settings.png
+++ b/core/res/res/drawable-xhdpi/perm_group_sync_settings.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/perm_group_system_clock.png b/core/res/res/drawable-xhdpi/perm_group_system_clock.png
index 36d1294..bf829e4 100644
--- a/core/res/res/drawable-xhdpi/perm_group_system_clock.png
+++ b/core/res/res/drawable-xhdpi/perm_group_system_clock.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/perm_group_system_tools.png b/core/res/res/drawable-xhdpi/perm_group_system_tools.png
index 7b6cdd8..8a942b6 100644
--- a/core/res/res/drawable-xhdpi/perm_group_system_tools.png
+++ b/core/res/res/drawable-xhdpi/perm_group_system_tools.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/perm_group_user_dictionary.png b/core/res/res/drawable-xhdpi/perm_group_user_dictionary.png
index c0106bb..345b29f 100644
--- a/core/res/res/drawable-xhdpi/perm_group_user_dictionary.png
+++ b/core/res/res/drawable-xhdpi/perm_group_user_dictionary.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/perm_group_user_dictionary_write.png b/core/res/res/drawable-xhdpi/perm_group_user_dictionary_write.png
index 36bb395..f0a98a3 100644
--- a/core/res/res/drawable-xhdpi/perm_group_user_dictionary_write.png
+++ b/core/res/res/drawable-xhdpi/perm_group_user_dictionary_write.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/perm_group_voicemail.png b/core/res/res/drawable-xhdpi/perm_group_voicemail.png
index eb17a63..53417ba 100644
--- a/core/res/res/drawable-xhdpi/perm_group_voicemail.png
+++ b/core/res/res/drawable-xhdpi/perm_group_voicemail.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/perm_group_wallpaper.png b/core/res/res/drawable-xhdpi/perm_group_wallpaper.png
index be4663c..6cac9bf 100644
--- a/core/res/res/drawable-xhdpi/perm_group_wallpaper.png
+++ b/core/res/res/drawable-xhdpi/perm_group_wallpaper.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/popup_background_qntm_mult.9.png b/core/res/res/drawable-xhdpi/popup_background_mtrl_mult.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/popup_background_qntm_mult.9.png
rename to core/res/res/drawable-xhdpi/popup_background_mtrl_mult.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/progress_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/progress_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/progress_qntm_alpha.9.png
rename to core/res/res/drawable-xhdpi/progress_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/progress_primary_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/progress_primary_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/progress_primary_qntm_alpha.9.png
rename to core/res/res/drawable-xhdpi/progress_primary_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/scrollbar_handle_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/scrollbar_handle_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/scrollbar_handle_qntm_alpha.9.png
rename to core/res/res/drawable-xhdpi/scrollbar_handle_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/scrubber_control_from_pressed_qntm_000.png b/core/res/res/drawable-xhdpi/scrubber_control_from_pressed_mtrl_000.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/scrubber_control_from_pressed_qntm_000.png
rename to core/res/res/drawable-xhdpi/scrubber_control_from_pressed_mtrl_000.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/scrubber_control_from_pressed_qntm_001.png b/core/res/res/drawable-xhdpi/scrubber_control_from_pressed_mtrl_001.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/scrubber_control_from_pressed_qntm_001.png
rename to core/res/res/drawable-xhdpi/scrubber_control_from_pressed_mtrl_001.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/scrubber_control_from_pressed_qntm_002.png b/core/res/res/drawable-xhdpi/scrubber_control_from_pressed_mtrl_002.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/scrubber_control_from_pressed_qntm_002.png
rename to core/res/res/drawable-xhdpi/scrubber_control_from_pressed_mtrl_002.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/scrubber_control_from_pressed_qntm_003.png b/core/res/res/drawable-xhdpi/scrubber_control_from_pressed_mtrl_003.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/scrubber_control_from_pressed_qntm_003.png
rename to core/res/res/drawable-xhdpi/scrubber_control_from_pressed_mtrl_003.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/scrubber_control_from_pressed_qntm_004.png b/core/res/res/drawable-xhdpi/scrubber_control_from_pressed_mtrl_004.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/scrubber_control_from_pressed_qntm_004.png
rename to core/res/res/drawable-xhdpi/scrubber_control_from_pressed_mtrl_004.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/scrubber_control_from_pressed_qntm_005.png b/core/res/res/drawable-xhdpi/scrubber_control_from_pressed_mtrl_005.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/scrubber_control_from_pressed_qntm_005.png
rename to core/res/res/drawable-xhdpi/scrubber_control_from_pressed_mtrl_005.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/scrubber_control_off_qntm_alpha.png b/core/res/res/drawable-xhdpi/scrubber_control_off_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/scrubber_control_off_qntm_alpha.png
rename to core/res/res/drawable-xhdpi/scrubber_control_off_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/scrubber_control_off_pressed_qntm_alpha.png b/core/res/res/drawable-xhdpi/scrubber_control_off_pressed_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/scrubber_control_off_pressed_qntm_alpha.png
rename to core/res/res/drawable-xhdpi/scrubber_control_off_pressed_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/scrubber_control_on_qntm_alpha.png b/core/res/res/drawable-xhdpi/scrubber_control_on_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/scrubber_control_on_qntm_alpha.png
rename to core/res/res/drawable-xhdpi/scrubber_control_on_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_on_pressed_qntm_alpha.png b/core/res/res/drawable-xhdpi/scrubber_control_on_pressed_mtrl_alpha.png
similarity index 100%
copy from core/res/res/drawable-xhdpi/btn_radio_on_pressed_qntm_alpha.png
copy to core/res/res/drawable-xhdpi/scrubber_control_on_pressed_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/scrubber_control_on_pressed_qntm_alpha.png b/core/res/res/drawable-xhdpi/scrubber_control_on_pressed_qntm_alpha.png
deleted file mode 100644
index a7ed0f8..0000000
--- a/core/res/res/drawable-xhdpi/scrubber_control_on_pressed_qntm_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/scrubber_control_to_pressed_qntm_000.png b/core/res/res/drawable-xhdpi/scrubber_control_to_pressed_mtrl_000.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/scrubber_control_to_pressed_qntm_000.png
rename to core/res/res/drawable-xhdpi/scrubber_control_to_pressed_mtrl_000.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/scrubber_control_to_pressed_qntm_001.png b/core/res/res/drawable-xhdpi/scrubber_control_to_pressed_mtrl_001.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/scrubber_control_to_pressed_qntm_001.png
rename to core/res/res/drawable-xhdpi/scrubber_control_to_pressed_mtrl_001.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/scrubber_control_to_pressed_qntm_002.png b/core/res/res/drawable-xhdpi/scrubber_control_to_pressed_mtrl_002.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/scrubber_control_to_pressed_qntm_002.png
rename to core/res/res/drawable-xhdpi/scrubber_control_to_pressed_mtrl_002.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/scrubber_control_to_pressed_qntm_003.png b/core/res/res/drawable-xhdpi/scrubber_control_to_pressed_mtrl_003.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/scrubber_control_to_pressed_qntm_003.png
rename to core/res/res/drawable-xhdpi/scrubber_control_to_pressed_mtrl_003.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/scrubber_control_to_pressed_qntm_004.png b/core/res/res/drawable-xhdpi/scrubber_control_to_pressed_mtrl_004.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/scrubber_control_to_pressed_qntm_004.png
rename to core/res/res/drawable-xhdpi/scrubber_control_to_pressed_mtrl_004.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/scrubber_control_to_pressed_qntm_005.png b/core/res/res/drawable-xhdpi/scrubber_control_to_pressed_mtrl_005.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/scrubber_control_to_pressed_qntm_005.png
rename to core/res/res/drawable-xhdpi/scrubber_control_to_pressed_mtrl_005.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/scrubber_primary_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/scrubber_primary_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/scrubber_primary_qntm_alpha.9.png
rename to core/res/res/drawable-xhdpi/scrubber_primary_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/scrubber_track_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/scrubber_track_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/scrubber_track_qntm_alpha.9.png
rename to core/res/res/drawable-xhdpi/scrubber_track_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_20_inner_holo.png b/core/res/res/drawable-xhdpi/spinner_20_inner_holo.png
deleted file mode 100644
index 76e9428..0000000
--- a/core/res/res/drawable-xhdpi/spinner_20_inner_holo.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_20_outer_holo.png b/core/res/res/drawable-xhdpi/spinner_20_outer_holo.png
deleted file mode 100644
index 6f693d6..0000000
--- a/core/res/res/drawable-xhdpi/spinner_20_outer_holo.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_qntm_am_alpha.9.png b/core/res/res/drawable-xhdpi/spinner_mtrl_am_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/spinner_qntm_am_alpha.9.png
rename to core/res/res/drawable-xhdpi/spinner_mtrl_am_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/switch_track_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/switch_track_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/switch_track_qntm_alpha.9.png
rename to core/res/res/drawable-xhdpi/switch_track_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/tab_indicator_mtrl_alpha.9.png b/core/res/res/drawable-xhdpi/tab_indicator_mtrl_alpha.9.png
new file mode 100644
index 0000000..5610d8c
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/tab_indicator_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/tab_indicator_normal_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/tab_indicator_normal_qntm_alpha.9.png
deleted file mode 100644
index a677f9a..0000000
--- a/core/res/res/drawable-xhdpi/tab_indicator_normal_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/tab_indicator_selected_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/tab_indicator_selected_qntm_alpha.9.png
deleted file mode 100644
index 7de791d..0000000
--- a/core/res/res/drawable-xhdpi/tab_indicator_selected_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/text_cursor_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/text_cursor_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/text_cursor_qntm_alpha.9.png
rename to core/res/res/drawable-xhdpi/text_cursor_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/text_select_handle_left_qntm_alpha.png b/core/res/res/drawable-xhdpi/text_select_handle_left_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/text_select_handle_left_qntm_alpha.png
rename to core/res/res/drawable-xhdpi/text_select_handle_left_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/text_select_handle_middle_qntm_alpha.png b/core/res/res/drawable-xhdpi/text_select_handle_middle_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/text_select_handle_middle_qntm_alpha.png
rename to core/res/res/drawable-xhdpi/text_select_handle_middle_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/text_select_handle_right_qntm_alpha.png b/core/res/res/drawable-xhdpi/text_select_handle_right_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/text_select_handle_right_qntm_alpha.png
rename to core/res/res/drawable-xhdpi/text_select_handle_right_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_activated_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/textfield_activated_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/textfield_activated_qntm_alpha.9.png
rename to core/res/res/drawable-xhdpi/textfield_activated_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_default_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/textfield_default_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/textfield_default_qntm_alpha.9.png
rename to core/res/res/drawable-xhdpi/textfield_default_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_search_activated_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/textfield_search_activated_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/textfield_search_activated_qntm_alpha.9.png
rename to core/res/res/drawable-xhdpi/textfield_search_activated_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_search_default_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/textfield_search_default_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/textfield_search_default_qntm_alpha.9.png
rename to core/res/res/drawable-xhdpi/textfield_search_default_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ab_share_pack_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/ab_share_pack_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/ab_share_pack_qntm_alpha.9.png
rename to core/res/res/drawable-xxhdpi/ab_share_pack_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ab_solid_shadow_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/ab_solid_shadow_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/ab_solid_shadow_qntm_alpha.9.png
rename to core/res/res/drawable-xxhdpi/ab_solid_shadow_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_cab_done_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/btn_cab_done_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_cab_done_qntm_alpha.9.png
rename to core/res/res/drawable-xxhdpi/btn_cab_done_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_000.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_000.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_000.png
rename to core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_000.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_001.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_001.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_001.png
rename to core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_001.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_002.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_002.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_002.png
rename to core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_002.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_003.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_003.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_003.png
rename to core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_003.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_004.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_004.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_004.png
rename to core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_004.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_005.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_005.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_005.png
rename to core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_005.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_006.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_006.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_006.png
rename to core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_006.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_007.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_007.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_007.png
rename to core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_007.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_008.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_008.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_008.png
rename to core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_008.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_009.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_009.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_009.png
rename to core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_009.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_010.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_010.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_010.png
rename to core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_010.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_011.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_011.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_011.png
rename to core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_011.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_012.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_012.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_012.png
rename to core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_012.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_013.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_013.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_013.png
rename to core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_013.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_014.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_014.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_014.png
rename to core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_014.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_015.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_015.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_015.png
rename to core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_015.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_000.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_000.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_000.png
rename to core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_000.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_001.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_001.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_001.png
rename to core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_001.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_002.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_002.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_002.png
rename to core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_002.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_003.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_003.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_003.png
rename to core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_003.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_004.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_004.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_004.png
rename to core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_004.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_005.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_005.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_005.png
rename to core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_005.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_006.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_006.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_006.png
rename to core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_006.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_007.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_007.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_007.png
rename to core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_007.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_008.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_008.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_008.png
rename to core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_008.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_009.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_009.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_009.png
rename to core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_009.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_010.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_010.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_010.png
rename to core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_010.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_011.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_011.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_011.png
rename to core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_011.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_012.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_012.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_012.png
rename to core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_012.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_013.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_013.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_013.png
rename to core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_013.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_014.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_014.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_014.png
rename to core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_014.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_015.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_015.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_015.png
rename to core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_015.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_code_lock_default_holo.png b/core/res/res/drawable-xxhdpi/btn_code_lock_default_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_code_lock_default_holo.png
rename to core/res/res/drawable-xxhdpi/btn_code_lock_default_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_code_lock_touched_holo.png b/core/res/res/drawable-xxhdpi/btn_code_lock_touched_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_code_lock_touched_holo.png
rename to core/res/res/drawable-xxhdpi/btn_code_lock_touched_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/btn_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_qntm_alpha.9.png
rename to core/res/res/drawable-xxhdpi/btn_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_anim_00000_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_radio_anim_00000_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_anim_00000_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/btn_radio_anim_00000_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_anim_00001_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_radio_anim_00001_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_anim_00001_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/btn_radio_anim_00001_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_anim_00002_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_radio_anim_00002_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_anim_00002_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/btn_radio_anim_00002_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_anim_00003_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_radio_anim_00003_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_anim_00003_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/btn_radio_anim_00003_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_anim_00004_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_radio_anim_00004_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_anim_00004_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/btn_radio_anim_00004_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_anim_00005_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_radio_anim_00005_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_anim_00005_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/btn_radio_anim_00005_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_anim_00006_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_radio_anim_00006_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_anim_00006_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/btn_radio_anim_00006_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_anim_00007_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_radio_anim_00007_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_anim_00007_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/btn_radio_anim_00007_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_anim_00008_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_radio_anim_00008_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_anim_00008_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/btn_radio_anim_00008_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_anim_00009_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_radio_anim_00009_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_anim_00009_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/btn_radio_anim_00009_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_anim_00010_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_radio_anim_00010_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_anim_00010_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/btn_radio_anim_00010_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_anim_00011_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_radio_anim_00011_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_anim_00011_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/btn_radio_anim_00011_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_anim_00012_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_radio_anim_00012_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_anim_00012_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/btn_radio_anim_00012_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_anim_00013_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_radio_anim_00013_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_anim_00013_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/btn_radio_anim_00013_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_anim_00014_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_radio_anim_00014_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_anim_00014_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/btn_radio_anim_00014_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_anim_00015_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_radio_anim_00015_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_anim_00015_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/btn_radio_anim_00015_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_000.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_000.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_000.png
rename to core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_000.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_001.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_001.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_001.png
rename to core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_001.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_002.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_002.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_002.png
rename to core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_002.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_003.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_003.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_003.png
rename to core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_003.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_004.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_004.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_004.png
rename to core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_004.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_005.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_005.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_005.png
rename to core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_005.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_006.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_006.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_006.png
rename to core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_006.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_007.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_007.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_007.png
rename to core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_007.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_008.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_008.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_008.png
rename to core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_008.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_009.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_009.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_009.png
rename to core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_009.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_010.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_010.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_010.png
rename to core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_010.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_011.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_011.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_011.png
rename to core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_011.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_012.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_012.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_012.png
rename to core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_012.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_013.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_013.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_013.png
rename to core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_013.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_014.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_014.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_014.png
rename to core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_014.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_015.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_015.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_015.png
rename to core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_015.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_000.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_000.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_000.png
rename to core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_000.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_001.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_001.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_001.png
rename to core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_001.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_002.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_002.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_002.png
rename to core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_002.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_003.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_003.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_003.png
rename to core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_003.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_004.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_004.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_004.png
rename to core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_004.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_005.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_005.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_005.png
rename to core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_005.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_006.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_006.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_006.png
rename to core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_006.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_007.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_007.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_007.png
rename to core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_007.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_008.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_008.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_008.png
rename to core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_008.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_009.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_009.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_009.png
rename to core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_009.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_010.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_010.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_010.png
rename to core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_010.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_011.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_011.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_011.png
rename to core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_011.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_012.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_012.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_012.png
rename to core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_012.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_013.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_013.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_013.png
rename to core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_013.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_014.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_014.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_014.png
rename to core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_014.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_015.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_015.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_015.png
rename to core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_015.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_rating_star_off_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_rating_star_off_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_rating_star_off_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/btn_rating_star_off_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_rating_star_on_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_rating_star_on_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_rating_star_on_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/btn_rating_star_on_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_star_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_star_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_star_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/btn_star_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_000.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_000.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_000.png
rename to core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_000.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_001.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_001.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_001.png
rename to core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_001.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_002.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_002.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_002.png
rename to core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_002.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_003.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_003.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_003.png
rename to core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_003.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_004.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_004.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_004.png
rename to core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_004.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_005.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_005.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_005.png
rename to core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_005.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_006.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_006.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_006.png
rename to core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_006.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_007.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_007.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_007.png
rename to core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_007.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_008.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_008.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_008.png
rename to core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_008.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_009.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_009.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_009.png
rename to core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_009.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_010.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_010.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_010.png
rename to core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_010.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_011.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_011.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_011.png
rename to core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_011.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_012.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_012.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_012.png
rename to core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_012.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_013.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_013.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_013.png
rename to core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_013.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_014.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_014.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_014.png
rename to core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_014.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_000.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_000.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_000.png
rename to core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_000.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_001.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_001.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_001.png
rename to core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_001.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_002.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_002.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_002.png
rename to core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_002.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_003.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_003.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_003.png
rename to core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_003.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_004.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_004.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_004.png
rename to core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_004.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_005.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_005.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_005.png
rename to core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_005.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_006.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_006.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_006.png
rename to core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_006.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_007.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_007.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_007.png
rename to core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_007.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_008.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_008.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_008.png
rename to core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_008.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_009.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_009.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_009.png
rename to core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_009.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_010.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_010.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_010.png
rename to core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_010.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_011.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_011.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_011.png
rename to core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_011.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_012.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_012.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_012.png
rename to core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_012.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_013.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_013.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_013.png
rename to core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_013.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_014.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_014.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_014.png
rename to core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_014.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_toggle_indicator_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/btn_toggle_indicator_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_toggle_indicator_qntm_alpha.9.png
rename to core/res/res/drawable-xxhdpi/btn_toggle_indicator_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_toggle_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/btn_toggle_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/btn_toggle_qntm_alpha.9.png
rename to core/res/res/drawable-xxhdpi/btn_toggle_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/expander_close_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/expander_close_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/expander_close_qntm_alpha.9.png
rename to core/res/res/drawable-xxhdpi/expander_close_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/expander_open_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/expander_open_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/expander_open_qntm_alpha.9.png
rename to core/res/res/drawable-xxhdpi/expander_open_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/fastscroll_thumb_qntm_alpha.png b/core/res/res/drawable-xxhdpi/fastscroll_thumb_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/fastscroll_thumb_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/fastscroll_thumb_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/fastscroll_track_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/fastscroll_track_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/fastscroll_track_qntm_alpha.9.png
rename to core/res/res/drawable-xxhdpi/fastscroll_track_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_ab_back_qntm_am_alpha.png b/core/res/res/drawable-xxhdpi/ic_ab_back_mtrl_am_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/ic_ab_back_qntm_am_alpha.png
rename to core/res/res/drawable-xxhdpi/ic_ab_back_mtrl_am_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_cab_done_qntm_alpha.png b/core/res/res/drawable-xxhdpi/ic_cab_done_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/ic_cab_done_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/ic_cab_done_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_clear_qntm_alpha.png b/core/res/res/drawable-xxhdpi/ic_clear_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/ic_clear_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/ic_clear_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_commit_search_api_qntm_alpha.png b/core/res/res/drawable-xxhdpi/ic_commit_search_api_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/ic_commit_search_api_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/ic_commit_search_api_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_corp_badge.png b/core/res/res/drawable-xxhdpi/ic_corp_badge.png
deleted file mode 100644
index 885e2ac..0000000
--- a/core/res/res/drawable-xxhdpi/ic_corp_badge.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_dialog_alert_qntm_alpha.png b/core/res/res/drawable-xxhdpi/ic_dialog_alert_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/ic_dialog_alert_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/ic_dialog_alert_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_find_next_qntm_alpha.png b/core/res/res/drawable-xxhdpi/ic_find_next_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/ic_find_next_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/ic_find_next_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_find_previous_qntm_alpha.png b/core/res/res/drawable-xxhdpi/ic_find_previous_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/ic_find_previous_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/ic_find_previous_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_go_search_api_qntm_alpha.png b/core/res/res/drawable-xxhdpi/ic_go_search_api_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/ic_go_search_api_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/ic_go_search_api_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_disabled_qntm_alpha.png b/core/res/res/drawable-xxhdpi/ic_media_route_disabled_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/ic_media_route_disabled_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/ic_media_route_disabled_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_off_qntm_alpha.png b/core/res/res/drawable-xxhdpi/ic_media_route_off_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/ic_media_route_off_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/ic_media_route_off_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_on_0_qntm_alpha.png b/core/res/res/drawable-xxhdpi/ic_media_route_on_0_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/ic_media_route_on_0_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/ic_media_route_on_0_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_on_1_qntm_alpha.png b/core/res/res/drawable-xxhdpi/ic_media_route_on_1_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/ic_media_route_on_1_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/ic_media_route_on_1_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_on_2_qntm_alpha.png b/core/res/res/drawable-xxhdpi/ic_media_route_on_2_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/ic_media_route_on_2_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/ic_media_route_on_2_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_on_qntm_alpha.png b/core/res/res/drawable-xxhdpi/ic_media_route_on_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/ic_media_route_on_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/ic_media_route_on_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_copy_qntm_am_alpha.png b/core/res/res/drawable-xxhdpi/ic_menu_copy_mtrl_am_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/ic_menu_copy_qntm_am_alpha.png
rename to core/res/res/drawable-xxhdpi/ic_menu_copy_mtrl_am_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_cut_qntm_alpha.png b/core/res/res/drawable-xxhdpi/ic_menu_cut_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/ic_menu_cut_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/ic_menu_cut_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_find_qntm_alpha.png b/core/res/res/drawable-xxhdpi/ic_menu_find_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/ic_menu_find_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/ic_menu_find_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_moreoverflow_qntm_alpha.png b/core/res/res/drawable-xxhdpi/ic_menu_moreoverflow_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/ic_menu_moreoverflow_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/ic_menu_moreoverflow_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_paste_qntm_am_alpha.png b/core/res/res/drawable-xxhdpi/ic_menu_paste_mtrl_am_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/ic_menu_paste_qntm_am_alpha.png
rename to core/res/res/drawable-xxhdpi/ic_menu_paste_mtrl_am_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_search_qntm_alpha.png b/core/res/res/drawable-xxhdpi/ic_menu_search_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/ic_menu_search_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/ic_menu_search_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_selectall_qntm_alpha.png b/core/res/res/drawable-xxhdpi/ic_menu_selectall_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/ic_menu_selectall_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/ic_menu_selectall_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_share_qntm_alpha.png b/core/res/res/drawable-xxhdpi/ic_menu_share_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/ic_menu_share_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/ic_menu_share_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_search_api_qntm_alpha.png b/core/res/res/drawable-xxhdpi/ic_search_api_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/ic_search_api_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/ic_search_api_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_voice_search_api_qntm_alpha.png b/core/res/res/drawable-xxhdpi/ic_voice_search_api_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/ic_voice_search_api_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/ic_voice_search_api_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/indicator_code_lock_drag_direction_up_mtrl_alpha.png b/core/res/res/drawable-xxhdpi/indicator_code_lock_drag_direction_up_mtrl_alpha.png
new file mode 100644
index 0000000..d3e80be
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/indicator_code_lock_drag_direction_up_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/indicator_code_lock_point_area_default_holo.png b/core/res/res/drawable-xxhdpi/indicator_code_lock_point_area_default_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/indicator_code_lock_point_area_default_holo.png
rename to core/res/res/drawable-xxhdpi/indicator_code_lock_point_area_default_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/indicator_code_lock_point_area_green_holo.png b/core/res/res/drawable-xxhdpi/indicator_code_lock_point_area_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/indicator_code_lock_point_area_green_holo.png
rename to core/res/res/drawable-xxhdpi/indicator_code_lock_point_area_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/indicator_code_lock_point_area_red_holo.png b/core/res/res/drawable-xxhdpi/indicator_code_lock_point_area_red_holo.png
deleted file mode 100644
index f6c3e27..0000000
--- a/core/res/res/drawable-xxhdpi/indicator_code_lock_point_area_red_holo.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/list_divider_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/list_divider_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/list_divider_qntm_alpha.9.png
rename to core/res/res/drawable-xxhdpi/list_divider_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/list_section_divider_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/list_section_divider_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/list_section_divider_qntm_alpha.9.png
rename to core/res/res/drawable-xxhdpi/list_section_divider_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/perm_group_accessibility_features.png b/core/res/res/drawable-xxhdpi/perm_group_accessibility_features.png
new file mode 100644
index 0000000..75cfa8f
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/perm_group_accessibility_features.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/perm_group_accounts.png b/core/res/res/drawable-xxhdpi/perm_group_accounts.png
new file mode 100644
index 0000000..148c5d1
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/perm_group_accounts.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/perm_group_affects_battery.png b/core/res/res/drawable-xxhdpi/perm_group_affects_battery.png
new file mode 100644
index 0000000..b453a97
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/perm_group_affects_battery.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/perm_group_app_info.png b/core/res/res/drawable-xxhdpi/perm_group_app_info.png
new file mode 100644
index 0000000..c723e78
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/perm_group_app_info.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/perm_group_audio_settings.png b/core/res/res/drawable-xxhdpi/perm_group_audio_settings.png
new file mode 100644
index 0000000..36109e5
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/perm_group_audio_settings.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/perm_group_bluetooth.png b/core/res/res/drawable-xxhdpi/perm_group_bluetooth.png
new file mode 100644
index 0000000..f545010
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/perm_group_bluetooth.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/perm_group_bookmarks.png b/core/res/res/drawable-xxhdpi/perm_group_bookmarks.png
new file mode 100644
index 0000000..ddfcfd5
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/perm_group_bookmarks.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/perm_group_calendar.png b/core/res/res/drawable-xxhdpi/perm_group_calendar.png
new file mode 100644
index 0000000..75f7f77
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/perm_group_calendar.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/perm_group_camera.png b/core/res/res/drawable-xxhdpi/perm_group_camera.png
new file mode 100644
index 0000000..2ee83f6
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/perm_group_camera.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/perm_group_device_alarms.png b/core/res/res/drawable-xxhdpi/perm_group_device_alarms.png
new file mode 100644
index 0000000..4218c29
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/perm_group_device_alarms.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/perm_group_display.png b/core/res/res/drawable-xxhdpi/perm_group_display.png
new file mode 100644
index 0000000..a03e670
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/perm_group_display.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/perm_group_location.png b/core/res/res/drawable-xxhdpi/perm_group_location.png
new file mode 100644
index 0000000..4ac3fb4
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/perm_group_location.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/perm_group_messages.png b/core/res/res/drawable-xxhdpi/perm_group_messages.png
new file mode 100644
index 0000000..f406a9d
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/perm_group_messages.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/perm_group_microphone.png b/core/res/res/drawable-xxhdpi/perm_group_microphone.png
new file mode 100644
index 0000000..6137b86
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/perm_group_microphone.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/perm_group_network.png b/core/res/res/drawable-xxhdpi/perm_group_network.png
new file mode 100644
index 0000000..72d2ef0
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/perm_group_network.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/perm_group_personal_info.png b/core/res/res/drawable-xxhdpi/perm_group_personal_info.png
new file mode 100644
index 0000000..fe18ec9
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/perm_group_personal_info.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/perm_group_phone_calls.png b/core/res/res/drawable-xxhdpi/perm_group_phone_calls.png
new file mode 100644
index 0000000..acfa435
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/perm_group_phone_calls.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/perm_group_screenlock.png b/core/res/res/drawable-xxhdpi/perm_group_screenlock.png
new file mode 100644
index 0000000..2fd88ff
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/perm_group_screenlock.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/perm_group_shortrange_network.png b/core/res/res/drawable-xxhdpi/perm_group_shortrange_network.png
new file mode 100644
index 0000000..72d2ef0
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/perm_group_shortrange_network.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/perm_group_social_info.png b/core/res/res/drawable-xxhdpi/perm_group_social_info.png
new file mode 100644
index 0000000..73076e0
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/perm_group_social_info.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/perm_group_status_bar.png b/core/res/res/drawable-xxhdpi/perm_group_status_bar.png
new file mode 100644
index 0000000..380fd66
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/perm_group_status_bar.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/perm_group_storage.png b/core/res/res/drawable-xxhdpi/perm_group_storage.png
new file mode 100644
index 0000000..b2da3ae
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/perm_group_storage.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/perm_group_sync_settings.png b/core/res/res/drawable-xxhdpi/perm_group_sync_settings.png
new file mode 100644
index 0000000..60aecd1
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/perm_group_sync_settings.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/perm_group_system_clock.png b/core/res/res/drawable-xxhdpi/perm_group_system_clock.png
new file mode 100644
index 0000000..30cc29c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/perm_group_system_clock.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/perm_group_system_tools.png b/core/res/res/drawable-xxhdpi/perm_group_system_tools.png
new file mode 100644
index 0000000..129c221
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/perm_group_system_tools.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/perm_group_user_dictionary.png b/core/res/res/drawable-xxhdpi/perm_group_user_dictionary.png
new file mode 100644
index 0000000..020167f
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/perm_group_user_dictionary.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/perm_group_user_dictionary_write.png b/core/res/res/drawable-xxhdpi/perm_group_user_dictionary_write.png
new file mode 100644
index 0000000..6218f62
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/perm_group_user_dictionary_write.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/perm_group_voicemail.png b/core/res/res/drawable-xxhdpi/perm_group_voicemail.png
new file mode 100644
index 0000000..336cb6b
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/perm_group_voicemail.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/perm_group_wallpaper.png b/core/res/res/drawable-xxhdpi/perm_group_wallpaper.png
new file mode 100644
index 0000000..e7d8f43
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/perm_group_wallpaper.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/popup_background_qntm_mult.9.png b/core/res/res/drawable-xxhdpi/popup_background_mtrl_mult.9.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/popup_background_qntm_mult.9.png
rename to core/res/res/drawable-xxhdpi/popup_background_mtrl_mult.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/progress_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/progress_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/progress_qntm_alpha.9.png
rename to core/res/res/drawable-xxhdpi/progress_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/progress_primary_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/progress_primary_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/progress_primary_qntm_alpha.9.png
rename to core/res/res/drawable-xxhdpi/progress_primary_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/scrollbar_handle_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/scrollbar_handle_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/scrollbar_handle_qntm_alpha.9.png
rename to core/res/res/drawable-xxhdpi/scrollbar_handle_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_qntm_000.png b/core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_mtrl_000.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_qntm_000.png
rename to core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_mtrl_000.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_qntm_001.png b/core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_mtrl_001.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_qntm_001.png
rename to core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_mtrl_001.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_qntm_002.png b/core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_mtrl_002.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_qntm_002.png
rename to core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_mtrl_002.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_qntm_003.png b/core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_mtrl_003.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_qntm_003.png
rename to core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_mtrl_003.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_qntm_004.png b/core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_mtrl_004.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_qntm_004.png
rename to core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_mtrl_004.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_qntm_005.png b/core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_mtrl_005.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_qntm_005.png
rename to core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_mtrl_005.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/scrubber_control_off_qntm_alpha.png b/core/res/res/drawable-xxhdpi/scrubber_control_off_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/scrubber_control_off_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/scrubber_control_off_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/scrubber_control_off_pressed_qntm_alpha.png b/core/res/res/drawable-xxhdpi/scrubber_control_off_pressed_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/scrubber_control_off_pressed_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/scrubber_control_off_pressed_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/scrubber_control_on_qntm_alpha.png b/core/res/res/drawable-xxhdpi/scrubber_control_on_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/scrubber_control_on_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/scrubber_control_on_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/scrubber_control_on_pressed_qntm_alpha.png b/core/res/res/drawable-xxhdpi/scrubber_control_on_pressed_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/scrubber_control_on_pressed_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/scrubber_control_on_pressed_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_qntm_000.png b/core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_mtrl_000.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_qntm_000.png
rename to core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_mtrl_000.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_qntm_001.png b/core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_mtrl_001.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_qntm_001.png
rename to core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_mtrl_001.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_qntm_002.png b/core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_mtrl_002.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_qntm_002.png
rename to core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_mtrl_002.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_qntm_003.png b/core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_mtrl_003.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_qntm_003.png
rename to core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_mtrl_003.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_qntm_004.png b/core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_mtrl_004.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_qntm_004.png
rename to core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_mtrl_004.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_qntm_005.png b/core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_mtrl_005.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_qntm_005.png
rename to core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_mtrl_005.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/scrubber_primary_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/scrubber_primary_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/scrubber_primary_qntm_alpha.9.png
rename to core/res/res/drawable-xxhdpi/scrubber_primary_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/scrubber_track_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/scrubber_track_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/scrubber_track_qntm_alpha.9.png
rename to core/res/res/drawable-xxhdpi/scrubber_track_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/spinner_20_inner_holo.png b/core/res/res/drawable-xxhdpi/spinner_20_inner_holo.png
deleted file mode 100644
index 6cbd1f4..0000000
--- a/core/res/res/drawable-xxhdpi/spinner_20_inner_holo.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/spinner_20_outer_holo.png b/core/res/res/drawable-xxhdpi/spinner_20_outer_holo.png
deleted file mode 100644
index b6af5e7..0000000
--- a/core/res/res/drawable-xxhdpi/spinner_20_outer_holo.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/spinner_qntm_am_alpha.9.png b/core/res/res/drawable-xxhdpi/spinner_mtrl_am_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/spinner_qntm_am_alpha.9.png
rename to core/res/res/drawable-xxhdpi/spinner_mtrl_am_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/switch_track_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/switch_track_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/switch_track_qntm_alpha.9.png
rename to core/res/res/drawable-xxhdpi/switch_track_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/tab_indicator_mtrl_alpha.9.png b/core/res/res/drawable-xxhdpi/tab_indicator_mtrl_alpha.9.png
new file mode 100644
index 0000000..248f4f8
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/tab_indicator_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/tab_indicator_normal_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/tab_indicator_normal_qntm_alpha.9.png
deleted file mode 100644
index 0a14025..0000000
--- a/core/res/res/drawable-xxhdpi/tab_indicator_normal_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/tab_indicator_selected_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/tab_indicator_selected_qntm_alpha.9.png
deleted file mode 100644
index 20e291a..0000000
--- a/core/res/res/drawable-xxhdpi/tab_indicator_selected_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/text_cursor_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/text_cursor_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/text_cursor_qntm_alpha.9.png
rename to core/res/res/drawable-xxhdpi/text_cursor_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/text_select_handle_left_qntm_alpha.png b/core/res/res/drawable-xxhdpi/text_select_handle_left_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/text_select_handle_left_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/text_select_handle_left_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/text_select_handle_middle_qntm_alpha.png b/core/res/res/drawable-xxhdpi/text_select_handle_middle_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/text_select_handle_middle_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/text_select_handle_middle_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/text_select_handle_right_qntm_alpha.png b/core/res/res/drawable-xxhdpi/text_select_handle_right_mtrl_alpha.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/text_select_handle_right_qntm_alpha.png
rename to core/res/res/drawable-xxhdpi/text_select_handle_right_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/textfield_activated_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/textfield_activated_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/textfield_activated_qntm_alpha.9.png
rename to core/res/res/drawable-xxhdpi/textfield_activated_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/textfield_default_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/textfield_default_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/textfield_default_qntm_alpha.9.png
rename to core/res/res/drawable-xxhdpi/textfield_default_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/textfield_search_activated_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/textfield_search_activated_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/textfield_search_activated_qntm_alpha.9.png
rename to core/res/res/drawable-xxhdpi/textfield_search_activated_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/textfield_search_default_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/textfield_search_default_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/textfield_search_default_qntm_alpha.9.png
rename to core/res/res/drawable-xxhdpi/textfield_search_default_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_000.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_000.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_000.png
rename to core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_000.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_001.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_001.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_001.png
rename to core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_001.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_002.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_002.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_002.png
rename to core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_002.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_003.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_003.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_003.png
rename to core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_003.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_004.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_004.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_004.png
rename to core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_004.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_005.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_005.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_005.png
rename to core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_005.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_006.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_006.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_006.png
rename to core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_006.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_007.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_007.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_007.png
rename to core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_007.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_008.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_008.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_008.png
rename to core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_008.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_009.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_009.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_009.png
rename to core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_009.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_010.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_010.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_010.png
rename to core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_010.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_011.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_011.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_011.png
rename to core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_011.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_012.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_012.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_012.png
rename to core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_012.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_013.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_013.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_013.png
rename to core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_013.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_014.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_014.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_014.png
rename to core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_014.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_015.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_015.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_015.png
rename to core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_015.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_000.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_000.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_000.png
rename to core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_000.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_001.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_001.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_001.png
rename to core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_001.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_002.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_002.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_002.png
rename to core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_002.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_003.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_003.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_003.png
rename to core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_003.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_004.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_004.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_004.png
rename to core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_004.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_005.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_005.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_005.png
rename to core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_005.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_006.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_006.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_006.png
rename to core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_006.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_007.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_007.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_007.png
rename to core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_007.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_008.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_008.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_008.png
rename to core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_008.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_009.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_009.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_009.png
rename to core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_009.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_010.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_010.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_010.png
rename to core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_010.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_011.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_011.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_011.png
rename to core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_011.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_012.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_012.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_012.png
rename to core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_012.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_013.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_013.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_013.png
rename to core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_013.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_014.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_014.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_014.png
rename to core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_014.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_015.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_015.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_015.png
rename to core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_015.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_qntm_alpha.9.png b/core/res/res/drawable-xxxhdpi/btn_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_qntm_alpha.9.png
rename to core/res/res/drawable-xxxhdpi/btn_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_000.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_000.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_000.png
rename to core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_000.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_001.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_001.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_001.png
rename to core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_001.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_002.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_002.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_002.png
rename to core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_002.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_003.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_003.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_003.png
rename to core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_003.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_004.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_004.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_004.png
rename to core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_004.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_005.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_005.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_005.png
rename to core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_005.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_006.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_006.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_006.png
rename to core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_006.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_007.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_007.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_007.png
rename to core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_007.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_008.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_008.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_008.png
rename to core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_008.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_009.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_009.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_009.png
rename to core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_009.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_010.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_010.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_010.png
rename to core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_010.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_011.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_011.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_011.png
rename to core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_011.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_012.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_012.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_012.png
rename to core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_012.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_013.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_013.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_013.png
rename to core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_013.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_014.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_014.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_014.png
rename to core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_014.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_015.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_015.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_015.png
rename to core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_015.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_000.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_000.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_000.png
rename to core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_000.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_001.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_001.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_001.png
rename to core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_001.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_002.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_002.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_002.png
rename to core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_002.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_003.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_003.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_003.png
rename to core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_003.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_004.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_004.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_004.png
rename to core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_004.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_005.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_005.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_005.png
rename to core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_005.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_006.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_006.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_006.png
rename to core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_006.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_007.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_007.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_007.png
rename to core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_007.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_008.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_008.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_008.png
rename to core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_008.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_009.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_009.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_009.png
rename to core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_009.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_010.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_010.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_010.png
rename to core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_010.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_011.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_011.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_011.png
rename to core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_011.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_012.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_012.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_012.png
rename to core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_012.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_013.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_013.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_013.png
rename to core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_013.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_014.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_014.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_014.png
rename to core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_014.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_015.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_015.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_015.png
rename to core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_015.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_000.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_000.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_000.png
rename to core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_000.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_001.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_001.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_001.png
rename to core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_001.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_002.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_002.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_002.png
rename to core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_002.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_003.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_003.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_003.png
rename to core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_003.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_004.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_004.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_004.png
rename to core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_004.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_005.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_005.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_005.png
rename to core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_005.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_006.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_006.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_006.png
rename to core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_006.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_007.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_007.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_007.png
rename to core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_007.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_008.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_008.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_008.png
rename to core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_008.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_009.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_009.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_009.png
rename to core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_009.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_010.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_010.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_010.png
rename to core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_010.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_011.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_011.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_011.png
rename to core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_011.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_012.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_012.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_012.png
rename to core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_012.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_013.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_013.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_013.png
rename to core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_013.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_014.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_014.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_014.png
rename to core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_014.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_000.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_000.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_000.png
rename to core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_000.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_001.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_001.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_001.png
rename to core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_001.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_002.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_002.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_002.png
rename to core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_002.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_003.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_003.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_003.png
rename to core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_003.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_004.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_004.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_004.png
rename to core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_004.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_005.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_005.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_005.png
rename to core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_005.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_006.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_006.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_006.png
rename to core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_006.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_007.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_007.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_007.png
rename to core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_007.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_008.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_008.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_008.png
rename to core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_008.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_009.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_009.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_009.png
rename to core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_009.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_010.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_010.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_010.png
rename to core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_010.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_011.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_011.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_011.png
rename to core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_011.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_012.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_012.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_012.png
rename to core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_012.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_013.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_013.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_013.png
rename to core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_013.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_014.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_014.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_014.png
rename to core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_014.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_toggle_indicator_qntm_alpha.9.png b/core/res/res/drawable-xxxhdpi/btn_toggle_indicator_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_toggle_indicator_qntm_alpha.9.png
rename to core/res/res/drawable-xxxhdpi/btn_toggle_indicator_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_toggle_qntm_alpha.9.png b/core/res/res/drawable-xxxhdpi/btn_toggle_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/btn_toggle_qntm_alpha.9.png
rename to core/res/res/drawable-xxxhdpi/btn_toggle_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/indicator_code_lock_drag_direction_up_mtrl_alpha.png b/core/res/res/drawable-xxxhdpi/indicator_code_lock_drag_direction_up_mtrl_alpha.png
new file mode 100644
index 0000000..23214fa
--- /dev/null
+++ b/core/res/res/drawable-xxxhdpi/indicator_code_lock_drag_direction_up_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_qntm_000.png b/core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_mtrl_000.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_qntm_000.png
rename to core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_mtrl_000.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_qntm_001.png b/core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_mtrl_001.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_qntm_001.png
rename to core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_mtrl_001.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_qntm_002.png b/core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_mtrl_002.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_qntm_002.png
rename to core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_mtrl_002.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_qntm_003.png b/core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_mtrl_003.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_qntm_003.png
rename to core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_mtrl_003.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_qntm_004.png b/core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_mtrl_004.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_qntm_004.png
rename to core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_mtrl_004.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_qntm_005.png b/core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_mtrl_005.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_qntm_005.png
rename to core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_mtrl_005.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_qntm_000.png b/core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_mtrl_000.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_qntm_000.png
rename to core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_mtrl_000.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_qntm_001.png b/core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_mtrl_001.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_qntm_001.png
rename to core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_mtrl_001.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_qntm_002.png b/core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_mtrl_002.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_qntm_002.png
rename to core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_mtrl_002.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_qntm_003.png b/core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_mtrl_003.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_qntm_003.png
rename to core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_mtrl_003.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_qntm_004.png b/core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_mtrl_004.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_qntm_004.png
rename to core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_mtrl_004.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_qntm_005.png b/core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_mtrl_005.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_qntm_005.png
rename to core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_mtrl_005.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/switch_track_qntm_alpha.9.png b/core/res/res/drawable-xxxhdpi/switch_track_mtrl_alpha.9.png
similarity index 100%
rename from core/res/res/drawable-xxxhdpi/switch_track_qntm_alpha.9.png
rename to core/res/res/drawable-xxxhdpi/switch_track_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/tab_indicator_mtrl_alpha.9.png b/core/res/res/drawable-xxxhdpi/tab_indicator_mtrl_alpha.9.png
new file mode 100644
index 0000000..5813179
--- /dev/null
+++ b/core/res/res/drawable-xxxhdpi/tab_indicator_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable/ic_find_next_quantum.xml b/core/res/res/drawable/ab_share_pack_material.xml
similarity index 93%
copy from core/res/res/drawable/ic_find_next_quantum.xml
copy to core/res/res/drawable/ab_share_pack_material.xml
index fee196c..1f0478e 100644
--- a/core/res/res/drawable/ic_find_next_quantum.xml
+++ b/core/res/res/drawable/ab_share_pack_material.xml
@@ -15,5 +15,5 @@
 -->
 
 <bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_find_next_qntm_alpha"
+    android:src="@drawable/ab_share_pack_mtrl_alpha"
     android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ab_share_pack_quantum.xml b/core/res/res/drawable/ab_share_pack_quantum.xml
deleted file mode 100644
index 7d33ff4d..0000000
--- a/core/res/res/drawable/ab_share_pack_quantum.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?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.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ab_share_pack_qntm_alpha"
-    android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ab_solid_shadow_quantum.xml b/core/res/res/drawable/ab_solid_shadow_material.xml
similarity index 93%
rename from core/res/res/drawable/ab_solid_shadow_quantum.xml
rename to core/res/res/drawable/ab_solid_shadow_material.xml
index 88e142a..eee52c8 100644
--- a/core/res/res/drawable/ab_solid_shadow_quantum.xml
+++ b/core/res/res/drawable/ab_solid_shadow_material.xml
@@ -15,5 +15,5 @@
 -->
 
 <nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ab_solid_shadow_qntm_alpha"
+    android:src="@drawable/ab_solid_shadow_mtrl_alpha"
     android:tint="@color/black" />
diff --git a/core/res/res/drawable/activated_background_quantum.xml b/core/res/res/drawable/activated_background_material.xml
similarity index 100%
rename from core/res/res/drawable/activated_background_quantum.xml
rename to core/res/res/drawable/activated_background_material.xml
diff --git a/core/res/res/drawable/btn_borderless_quantum.xml b/core/res/res/drawable/btn_borderless_material.xml
similarity index 93%
rename from core/res/res/drawable/btn_borderless_quantum.xml
rename to core/res/res/drawable/btn_borderless_material.xml
index 2cd7ed6..1967b38 100644
--- a/core/res/res/drawable/btn_borderless_quantum.xml
+++ b/core/res/res/drawable/btn_borderless_material.xml
@@ -17,5 +17,5 @@
 <ripple xmlns:android="http://schemas.android.com/apk/res/android"
     android:tint="?attr/colorControlHighlight">
     <item android:id="@id/mask"
-        android:drawable="@drawable/btn_qntm_alpha" />
+        android:drawable="@drawable/btn_mtrl_alpha" />
 </ripple>
diff --git a/core/res/res/drawable/btn_cab_done_quantum.xml b/core/res/res/drawable/btn_cab_done_material.xml
similarity index 89%
rename from core/res/res/drawable/btn_cab_done_quantum.xml
rename to core/res/res/drawable/btn_cab_done_material.xml
index 51e06bb..36cc196 100644
--- a/core/res/res/drawable/btn_cab_done_quantum.xml
+++ b/core/res/res/drawable/btn_cab_done_material.xml
@@ -21,11 +21,11 @@
         <color android:color="?attr/colorControlHighlight" />
     </item>
     <item android:state_focused="true" android:state_enabled="true">
-        <nine-patch android:src="@drawable/btn_cab_done_qntm_alpha"
+        <nine-patch android:src="@drawable/btn_cab_done_mtrl_alpha"
             android:tint="?attr/colorControlHighlight" />
     </item>
     <item android:state_enabled="true">
-        <nine-patch android:src="@drawable/btn_cab_done_qntm_alpha"
+        <nine-patch android:src="@drawable/btn_cab_done_mtrl_alpha"
             android:tint="?attr/colorButtonNormal" />
     </item>
 </selector>
diff --git a/core/res/res/drawable/btn_check_material_anim.xml b/core/res/res/drawable/btn_check_material_anim.xml
new file mode 100644
index 0000000..73b8a3e
--- /dev/null
+++ b/core/res/res/drawable/btn_check_material_anim.xml
@@ -0,0 +1,135 @@
+<?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.
+-->
+
+<animated-selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_enabled="false" android:state_checked="true">
+        <bitmap android:src="@drawable/btn_check_to_on_mtrl_015" android:tint="?attr/colorControlActivated" android:alpha="?attr/disabledAlpha" />
+    </item>
+    <item android:state_enabled="false">
+        <bitmap android:src="@drawable/btn_check_to_on_mtrl_000" android:tint="?attr/colorControlNormal" android:alpha="?attr/disabledAlpha" />
+    </item>
+    <item android:state_checked="true" android:id="@+id/on">
+        <bitmap android:src="@drawable/btn_check_to_on_mtrl_015" android:tint="?attr/colorControlActivated" />
+    </item>
+    <item android:id="@+id/off">
+        <bitmap android:src="@drawable/btn_check_to_on_mtrl_000" android:tint="?attr/colorControlNormal" />
+    </item>
+    <transition android:fromId="@+id/off" android:toId="@+id/on">
+        <animation-list>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_check_to_on_mtrl_000" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_check_to_on_mtrl_001" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_check_to_on_mtrl_002" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_check_to_on_mtrl_003" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_check_to_on_mtrl_004" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_check_to_on_mtrl_005" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_check_to_on_mtrl_006" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_check_to_on_mtrl_007" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_check_to_on_mtrl_008" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_check_to_on_mtrl_009" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_check_to_on_mtrl_010" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_check_to_on_mtrl_011" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_check_to_on_mtrl_012" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_check_to_on_mtrl_013" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_check_to_on_mtrl_014" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_check_to_on_mtrl_015" android:tint="?attr/colorControlActivated" />
+            </item>
+        </animation-list>
+    </transition>
+    <transition android:fromId="@+id/on" android:toId="@+id/off">
+        <animation-list>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_check_to_off_mtrl_000" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_check_to_off_mtrl_001" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_check_to_off_mtrl_002" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_check_to_off_mtrl_003" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_check_to_off_mtrl_004" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_check_to_off_mtrl_005" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_check_to_off_mtrl_006" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_check_to_off_mtrl_007" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_check_to_off_mtrl_008" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_check_to_off_mtrl_009" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_check_to_off_mtrl_010" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_check_to_off_mtrl_011" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_check_to_off_mtrl_012" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_check_to_off_mtrl_013" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_check_to_off_mtrl_014" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_check_to_off_mtrl_015" android:tint="?attr/colorControlActivated" />
+            </item>
+        </animation-list>
+    </transition>
+</animated-selector>
+
diff --git a/core/res/res/drawable/btn_check_quantum_anim.xml b/core/res/res/drawable/btn_check_quantum_anim.xml
deleted file mode 100644
index b16875e..0000000
--- a/core/res/res/drawable/btn_check_quantum_anim.xml
+++ /dev/null
@@ -1,135 +0,0 @@
-<?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.
--->
-
-<animated-selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_enabled="false" android:state_checked="true">
-        <bitmap android:src="@drawable/btn_check_to_on_qntm_015" android:tint="?attr/colorControlActivated" android:alpha="?attr/disabledAlpha" />
-    </item>
-    <item android:state_enabled="false">
-        <bitmap android:src="@drawable/btn_check_to_on_qntm_000" android:tint="?attr/colorControlNormal" android:alpha="?attr/disabledAlpha" />
-    </item>
-    <item android:state_checked="true" android:id="@+id/on">
-        <bitmap android:src="@drawable/btn_check_to_on_qntm_015" android:tint="?attr/colorControlActivated" />
-    </item>
-    <item android:id="@+id/off">
-        <bitmap android:src="@drawable/btn_check_to_on_qntm_000" android:tint="?attr/colorControlNormal" />
-    </item>
-    <transition android:fromId="@+id/off" android:toId="@+id/on">
-        <animation-list>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_check_to_on_qntm_000" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_check_to_on_qntm_001" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_check_to_on_qntm_002" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_check_to_on_qntm_003" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_check_to_on_qntm_004" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_check_to_on_qntm_005" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_check_to_on_qntm_006" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_check_to_on_qntm_007" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_check_to_on_qntm_008" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_check_to_on_qntm_009" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_check_to_on_qntm_010" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_check_to_on_qntm_011" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_check_to_on_qntm_012" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_check_to_on_qntm_013" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_check_to_on_qntm_014" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_check_to_on_qntm_015" android:tint="?attr/colorControlActivated" />
-            </item>
-        </animation-list>
-    </transition>
-    <transition android:fromId="@+id/on" android:toId="@+id/off">
-        <animation-list>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_check_to_off_qntm_000" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_check_to_off_qntm_001" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_check_to_off_qntm_002" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_check_to_off_qntm_003" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_check_to_off_qntm_004" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_check_to_off_qntm_005" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_check_to_off_qntm_006" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_check_to_off_qntm_007" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_check_to_off_qntm_008" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_check_to_off_qntm_009" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_check_to_off_qntm_010" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_check_to_off_qntm_011" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_check_to_off_qntm_012" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_check_to_off_qntm_013" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_check_to_off_qntm_014" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_check_to_off_qntm_015" android:tint="?attr/colorControlActivated" />
-            </item>
-        </animation-list>
-    </transition>
-</animated-selector>
-
diff --git a/core/res/res/drawable/btn_default_quantum.xml b/core/res/res/drawable/btn_default_material.xml
similarity index 93%
rename from core/res/res/drawable/btn_default_quantum.xml
rename to core/res/res/drawable/btn_default_material.xml
index 61193fe..acec900 100644
--- a/core/res/res/drawable/btn_default_quantum.xml
+++ b/core/res/res/drawable/btn_default_material.xml
@@ -17,7 +17,7 @@
 <ripple xmlns:android="http://schemas.android.com/apk/res/android"
     android:tint="?attr/colorControlHighlight">
     <item>
-        <nine-patch android:src="@drawable/btn_qntm_alpha"
+        <nine-patch android:src="@drawable/btn_mtrl_alpha"
             android:tint="?attr/colorButtonNormal" />
     </item>
 </ripple>
diff --git a/core/res/res/drawable/btn_radio_material_anim.xml b/core/res/res/drawable/btn_radio_material_anim.xml
new file mode 100644
index 0000000..0be590e
--- /dev/null
+++ b/core/res/res/drawable/btn_radio_material_anim.xml
@@ -0,0 +1,134 @@
+<?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.
+-->
+
+<animated-selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_enabled="false" android:state_checked="true">
+        <bitmap android:src="@drawable/btn_radio_to_on_mtrl_015" android:tint="?attr/colorControlActivated" android:alpha="?attr/disabledAlpha" />
+    </item>
+    <item android:state_enabled="false">
+        <bitmap android:src="@drawable/btn_radio_to_on_mtrl_000" android:tint="?attr/colorControlNormal" android:alpha="?attr/disabledAlpha" />
+    </item>
+    <item android:state_checked="true" android:id="@+id/on">
+        <bitmap android:src="@drawable/btn_radio_to_on_mtrl_015" android:tint="?attr/colorControlActivated" />
+    </item>
+    <item android:id="@+id/off">
+        <bitmap android:src="@drawable/btn_radio_to_on_mtrl_000" android:tint="?attr/colorControlNormal" />
+    </item>
+    <transition android:fromId="@+id/off" android:toId="@+id/on">
+        <animation-list>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_radio_to_on_mtrl_000" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_radio_to_on_mtrl_001" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_radio_to_on_mtrl_002" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_radio_to_on_mtrl_003" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_radio_to_on_mtrl_004" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_radio_to_on_mtrl_005" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_radio_to_on_mtrl_006" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_radio_to_on_mtrl_007" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_radio_to_on_mtrl_008" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_radio_to_on_mtrl_009" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_radio_to_on_mtrl_010" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_radio_to_on_mtrl_011" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_radio_to_on_mtrl_012" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_radio_to_on_mtrl_013" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_radio_to_on_mtrl_014" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_radio_to_on_mtrl_015" android:tint="?attr/colorControlActivated" />
+            </item>
+        </animation-list>
+    </transition>
+    <transition android:fromId="@+id/on" android:toId="@+id/off">
+        <animation-list>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_radio_to_off_mtrl_000" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_radio_to_off_mtrl_001" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_radio_to_off_mtrl_002" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_radio_to_off_mtrl_003" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_radio_to_off_mtrl_004" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_radio_to_off_mtrl_005" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_radio_to_off_mtrl_006" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_radio_to_off_mtrl_007" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_radio_to_off_mtrl_008" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_radio_to_off_mtrl_009" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_radio_to_off_mtrl_010" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_radio_to_off_mtrl_011" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_radio_to_off_mtrl_012" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_radio_to_off_mtrl_013" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_radio_to_off_mtrl_014" android:tint="?attr/colorControlActivated" />
+            </item>
+            <item android:duration="15">
+                <bitmap android:src="@drawable/btn_radio_to_off_mtrl_015" android:tint="?attr/colorControlActivated" />
+            </item>
+        </animation-list>
+    </transition>
+</animated-selector>
diff --git a/core/res/res/drawable/btn_radio_quantum_anim.xml b/core/res/res/drawable/btn_radio_quantum_anim.xml
deleted file mode 100644
index cd9b518..0000000
--- a/core/res/res/drawable/btn_radio_quantum_anim.xml
+++ /dev/null
@@ -1,134 +0,0 @@
-<?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.
--->
-
-<animated-selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_enabled="false" android:state_checked="true">
-        <bitmap android:src="@drawable/btn_radio_to_on_qntm_015" android:tint="?attr/colorControlActivated" android:alpha="?attr/disabledAlpha" />
-    </item>
-    <item android:state_enabled="false">
-        <bitmap android:src="@drawable/btn_radio_to_on_qntm_000" android:tint="?attr/colorControlNormal" android:alpha="?attr/disabledAlpha" />
-    </item>
-    <item android:state_checked="true" android:id="@+id/on">
-        <bitmap android:src="@drawable/btn_radio_to_on_qntm_015" android:tint="?attr/colorControlActivated" />
-    </item>
-    <item android:id="@+id/off">
-        <bitmap android:src="@drawable/btn_radio_to_on_qntm_000" android:tint="?attr/colorControlNormal" />
-    </item>
-    <transition android:fromId="@+id/off" android:toId="@+id/on">
-        <animation-list>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_on_qntm_000" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_on_qntm_001" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_on_qntm_002" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_on_qntm_003" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_on_qntm_004" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_on_qntm_005" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_on_qntm_006" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_on_qntm_007" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_on_qntm_008" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_on_qntm_009" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_on_qntm_010" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_on_qntm_011" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_on_qntm_012" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_on_qntm_013" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_on_qntm_014" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_on_qntm_015" android:tint="?attr/colorControlActivated" />
-            </item>
-        </animation-list>
-    </transition>
-    <transition android:fromId="@+id/on" android:toId="@+id/off">
-        <animation-list>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_off_qntm_000" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_off_qntm_001" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_off_qntm_002" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_off_qntm_003" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_off_qntm_004" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_off_qntm_005" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_off_qntm_006" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_off_qntm_007" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_off_qntm_008" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_off_qntm_009" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_off_qntm_010" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_off_qntm_011" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_off_qntm_012" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_off_qntm_013" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_off_qntm_014" android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_off_qntm_015" android:tint="?attr/colorControlActivated" />
-            </item>
-        </animation-list>
-    </transition>
-</animated-selector>
diff --git a/core/res/res/drawable/btn_star_quantum.xml b/core/res/res/drawable/btn_star_material.xml
similarity index 85%
rename from core/res/res/drawable/btn_star_quantum.xml
rename to core/res/res/drawable/btn_star_material.xml
index 512cd57..29862d2 100644
--- a/core/res/res/drawable/btn_star_quantum.xml
+++ b/core/res/res/drawable/btn_star_material.xml
@@ -16,15 +16,15 @@
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_checked="true">
-        <bitmap android:src="@drawable/btn_star_qntm_alpha"
+        <bitmap android:src="@drawable/btn_star_mtrl_alpha"
             android:tint="?attr/colorControlActivated" />
     </item>
     <item android:state_pressed="true">
-        <bitmap android:src="@drawable/btn_star_qntm_alpha"
+        <bitmap android:src="@drawable/btn_star_mtrl_alpha"
             android:tint="?attr/colorControlActivated" />
     </item>
     <item>
-        <bitmap android:src="@drawable/btn_star_qntm_alpha"
+        <bitmap android:src="@drawable/btn_star_mtrl_alpha"
             android:tint="?attr/colorControlNormal" />
     </item>
 </selector>
diff --git a/core/res/res/drawable/btn_toggle_quantum.xml b/core/res/res/drawable/btn_toggle_material.xml
similarity index 96%
rename from core/res/res/drawable/btn_toggle_quantum.xml
rename to core/res/res/drawable/btn_toggle_material.xml
index e235598..4532c77 100644
--- a/core/res/res/drawable/btn_toggle_quantum.xml
+++ b/core/res/res/drawable/btn_toggle_material.xml
@@ -23,7 +23,7 @@
         <item>
             <ripple android:tint="?attr/colorControlHighlight">
                 <item>
-                    <nine-patch android:src="@drawable/btn_toggle_qntm_alpha"
+                    <nine-patch android:src="@drawable/btn_toggle_mtrl_alpha"
                         android:tint="?attr/colorButtonNormal" />
                 </item>
             </ripple>
@@ -31,11 +31,11 @@
         <item>
             <selector xmlns:android="http://schemas.android.com/apk/res/android">
                 <item android:state_checked="false">
-                    <nine-patch android:src="@drawable/btn_toggle_indicator_qntm_alpha"
+                    <nine-patch android:src="@drawable/btn_toggle_indicator_mtrl_alpha"
                         android:tint="?attr/colorControlNormal" />
                 </item>
                 <item android:state_checked="true">
-                    <nine-patch android:src="@drawable/btn_toggle_indicator_qntm_alpha"
+                    <nine-patch android:src="@drawable/btn_toggle_indicator_mtrl_alpha"
                         android:tint="?attr/colorControlActivated" />
                 </item>
             </selector>
diff --git a/core/res/res/drawable/dialog_background_quantum.xml b/core/res/res/drawable/dialog_background_material.xml
similarity index 100%
rename from core/res/res/drawable/dialog_background_quantum.xml
rename to core/res/res/drawable/dialog_background_material.xml
diff --git a/core/res/res/drawable/edit_text_quantum.xml b/core/res/res/drawable/edit_text_material.xml
similarity index 64%
rename from core/res/res/drawable/edit_text_quantum.xml
rename to core/res/res/drawable/edit_text_material.xml
index 67339e8..26fd889 100644
--- a/core/res/res/drawable/edit_text_quantum.xml
+++ b/core/res/res/drawable/edit_text_material.xml
@@ -15,25 +15,20 @@
 -->
 
 <ripple xmlns:android="http://schemas.android.com/apk/res/android"
-    android:tint="?attr/colorControlActivated">
+    android:tint="?attr/colorControlActivated"
+    android:tintMode="src_over">
     <item>
         <selector>
-            <item android:state_window_focused="false">
-                <nine-patch android:src="@drawable/textfield_default_qntm_alpha"
-                    android:tint="?attr/colorControlNormal" />
-            </item>
             <item android:state_enabled="false">
-                <nine-patch android:src="@drawable/textfield_default_qntm_alpha"
-                    android:tint="?attr/colorControlNormal" />
-            </item>
-            <item android:state_focused="false" android:state_activated="false">
-                <nine-patch android:src="@drawable/textfield_default_qntm_alpha"
-                    android:tint="?attr/colorControlNormal" />
+                <nine-patch android:src="@drawable/textfield_default_mtrl_alpha"
+                    android:tint="?attr/colorControlNormal"
+                    android:alpha="?attr/disabledAlpha" />
             </item>
             <item>
-                <nine-patch android:src="@drawable/textfield_activated_qntm_alpha"
+                <nine-patch android:src="@drawable/textfield_default_mtrl_alpha"
                     android:tint="?attr/colorControlNormal" />
             </item>
         </selector>
     </item>
+    <item android:id="@+id/mask" android:drawable="@drawable/textfield_activated_mtrl_alpha" />
 </ripple>
diff --git a/core/res/res/drawable/expander_group_quantum.xml b/core/res/res/drawable/expander_group_material.xml
similarity index 87%
rename from core/res/res/drawable/expander_group_quantum.xml
rename to core/res/res/drawable/expander_group_material.xml
index 48245ea..aa41796 100644
--- a/core/res/res/drawable/expander_group_quantum.xml
+++ b/core/res/res/drawable/expander_group_material.xml
@@ -16,11 +16,11 @@
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_expanded="true">
-        <nine-patch android:src="@drawable/expander_close_qntm_alpha"
+        <nine-patch android:src="@drawable/expander_close_mtrl_alpha"
             android:tint="?attr/colorControlNormal" />
     </item>
     <item>
-        <nine-patch android:src="@drawable/expander_open_qntm_alpha"
+        <nine-patch android:src="@drawable/expander_open_mtrl_alpha"
             android:tint="?attr/colorControlNormal" />
     </item>
 </selector>
diff --git a/core/res/res/drawable/fastscroll_thumb_quantum.xml b/core/res/res/drawable/fastscroll_thumb_material.xml
similarity index 87%
rename from core/res/res/drawable/fastscroll_thumb_quantum.xml
rename to core/res/res/drawable/fastscroll_thumb_material.xml
index 496b2ae..1288f0d 100644
--- a/core/res/res/drawable/fastscroll_thumb_quantum.xml
+++ b/core/res/res/drawable/fastscroll_thumb_material.xml
@@ -16,11 +16,11 @@
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_pressed="true">
-        <bitmap android:src="@drawable/fastscroll_thumb_qntm_alpha"
+        <bitmap android:src="@drawable/fastscroll_thumb_mtrl_alpha"
             android:tint="?attr/colorControlActivated" />
     </item>
     <item>
-        <bitmap android:src="@drawable/fastscroll_thumb_qntm_alpha"
+        <bitmap android:src="@drawable/fastscroll_thumb_mtrl_alpha"
             android:tint="?attr/colorControlNormal" />
     </item>
 </selector>
diff --git a/core/res/res/drawable/list_divider_quantum.xml b/core/res/res/drawable/fastscroll_track_material.xml
similarity index 92%
copy from core/res/res/drawable/list_divider_quantum.xml
copy to core/res/res/drawable/fastscroll_track_material.xml
index e3d4ba2..60f79b1 100644
--- a/core/res/res/drawable/list_divider_quantum.xml
+++ b/core/res/res/drawable/fastscroll_track_material.xml
@@ -15,5 +15,5 @@
 -->
 
 <nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/list_divider_qntm_alpha"
+    android:src="@drawable/fastscroll_track_mtrl_alpha"
     android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/fastscroll_track_quantum.xml b/core/res/res/drawable/fastscroll_track_quantum.xml
deleted file mode 100644
index 59c35db..0000000
--- a/core/res/res/drawable/fastscroll_track_quantum.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?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/fastscroll_track_qntm_alpha"
-    android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_ab_back_quantum.xml b/core/res/res/drawable/ic_ab_back_material.xml
similarity index 93%
rename from core/res/res/drawable/ic_ab_back_quantum.xml
rename to core/res/res/drawable/ic_ab_back_material.xml
index 65c7584..37455d4 100644
--- a/core/res/res/drawable/ic_ab_back_quantum.xml
+++ b/core/res/res/drawable/ic_ab_back_material.xml
@@ -15,6 +15,6 @@
 -->
 
 <bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_ab_back_qntm_am_alpha"
+    android:src="@drawable/ic_ab_back_mtrl_am_alpha"
     android:autoMirrored="true"
     android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_find_next_quantum.xml b/core/res/res/drawable/ic_cab_done_material.xml
similarity index 93%
copy from core/res/res/drawable/ic_find_next_quantum.xml
copy to core/res/res/drawable/ic_cab_done_material.xml
index fee196c..a370288 100644
--- a/core/res/res/drawable/ic_find_next_quantum.xml
+++ b/core/res/res/drawable/ic_cab_done_material.xml
@@ -15,5 +15,5 @@
 -->
 
 <bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_find_next_qntm_alpha"
+    android:src="@drawable/ic_cab_done_mtrl_alpha"
     android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_cab_done_quantum.xml b/core/res/res/drawable/ic_cab_done_quantum.xml
deleted file mode 100644
index 97495a8..0000000
--- a/core/res/res/drawable/ic_cab_done_quantum.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?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.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_cab_done_qntm_alpha"
-    android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_find_next_quantum.xml b/core/res/res/drawable/ic_clear_material.xml
similarity index 93%
copy from core/res/res/drawable/ic_find_next_quantum.xml
copy to core/res/res/drawable/ic_clear_material.xml
index fee196c..076c0a2 100644
--- a/core/res/res/drawable/ic_find_next_quantum.xml
+++ b/core/res/res/drawable/ic_clear_material.xml
@@ -15,5 +15,5 @@
 -->
 
 <bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_find_next_qntm_alpha"
+    android:src="@drawable/ic_clear_mtrl_alpha"
     android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_find_next_quantum.xml b/core/res/res/drawable/ic_commit_search_api_material.xml
similarity index 92%
copy from core/res/res/drawable/ic_find_next_quantum.xml
copy to core/res/res/drawable/ic_commit_search_api_material.xml
index fee196c..59bd0fa 100644
--- a/core/res/res/drawable/ic_find_next_quantum.xml
+++ b/core/res/res/drawable/ic_commit_search_api_material.xml
@@ -15,5 +15,5 @@
 -->
 
 <bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_find_next_qntm_alpha"
+    android:src="@drawable/ic_commit_search_api_mtrl_alpha"
     android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_commit_search_api_quantum.xml b/core/res/res/drawable/ic_commit_search_api_quantum.xml
deleted file mode 100644
index 02d08b9..0000000
--- a/core/res/res/drawable/ic_commit_search_api_quantum.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?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.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_commit_search_api_qntm_alpha"
-    android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_corp_badge.xml b/core/res/res/drawable/ic_corp_badge.xml
new file mode 100644
index 0000000..5325712
--- /dev/null
+++ b/core/res/res/drawable/ic_corp_badge.xml
@@ -0,0 +1,34 @@
+<!--
+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="19.0dp"
+        android:height="19.0dp"/>
+
+    <viewport
+        android:viewportWidth="19.0"
+        android:viewportHeight="19.0"/>
+
+    <path
+        android:pathData="M9.5,9.5m-9.5,0.0a9.5,9.5 0.0,1.0 1.0,19.0 0.0a9.5,9.5 0.0,1.0 1.0,-19.0 0.0"
+        android:fill="#FF5722"/>
+    <path
+        android:pathData="M12.667,7.125l-1.583,0.0L11.084,6.333l-0.792,-0.792L8.708,5.5410004L7.917,6.333l0.0,0.792L6.333,7.125c-0.438,0.0 -0.788,0.354 -0.788,0.792l-0.004,4.354c0.0,0.438 0.354,0.792 0.792,0.792l6.333,0.0c0.438,0.0 0.792,-0.354 0.792,-0.792L13.458,7.917C13.458,7.479 13.104,7.125 12.667,7.125zM10.094,10.687L8.906,10.687L8.906,9.5l1.188,0.0L10.094,10.687zM10.292,7.125L8.708,7.125L8.708,6.333l1.583,0.0L10.291,7.125z"
+        android:fill="#FFFFFF"/>
+    <path
+        android:pathData="M4.75,4.75 h9.5 v9.5 h-9.5z"
+        android:fill="#00000000"/>
+</vector>
diff --git a/core/res/res/drawable/ic_corp_icon_badge.xml b/core/res/res/drawable/ic_corp_icon_badge.xml
new file mode 100644
index 0000000..7bfab4c
--- /dev/null
+++ b/core/res/res/drawable/ic_corp_icon_badge.xml
@@ -0,0 +1,40 @@
+<!--
+Copyright (C) 2014 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+    <size
+        android:width="64.0dp"
+        android:height="64.0dp"/>
+
+    <viewport
+        android:viewportWidth="64.0"
+        android:viewportHeight="64.0"/>
+
+    <path
+        android:fill="#FF000000"
+        android:pathData="M49.062,50.0m-14.0,0.0a14.0,14.0 0.0,1.0 1.0,28.0 0.0a14.0,14.0 0.0,1.0 1.0,-28.0 0.0"/>
+    <path
+        android:fill="#FF000000"
+        android:pathData="M49.0,49.5m-14.0,0.0a14.0,14.0 0.0,1.0 1.0,28.0 0.0a14.0,14.0 0.0,1.0 1.0,-28.0 0.0"/>
+    <path
+        android:pathData="M49.0,49.0m-14.0,0.0a14.0,14.0 0.0,1.0 1.0,28.0 0.0a14.0,14.0 0.0,1.0 1.0,-28.0 0.0"
+        android:fill="#FF5722"/>
+    <path
+        android:pathData="M53.667,45.5l-2.333,0.0l0.0,-1.167l-1.167,-1.167l-2.333,0.0l-1.167,1.167L46.667,45.5l-2.333,0.0c-0.645,0.0 -1.161,0.522 -1.161,1.167l-0.006,6.417c0.0,0.645 0.522,1.167 1.167,1.167l9.333,0.0c0.645,0.0 1.167,-0.522 1.167,-1.167l0.0,-6.417C54.833,46.022 54.311,45.5 53.667,45.5zM49.875,50.75l-1.75,0.0L48.125,49.0l1.75,0.0L49.875,50.75zM50.167,45.5l-2.333,0.0l0.0,-1.167l2.333,0.0L50.167,45.5z"
+        android:fill="#FFFFFF"/>
+    <path
+        android:pathData="M42.0,42.0 h14.0 v14.0 h-14.0z"
+        android:fill="#00000000"/>
+</vector>
diff --git a/core/res/res/drawable/ic_find_next_quantum.xml b/core/res/res/drawable/ic_dialog_alert_material.xml
similarity index 93%
copy from core/res/res/drawable/ic_find_next_quantum.xml
copy to core/res/res/drawable/ic_dialog_alert_material.xml
index fee196c..41e1ab1 100644
--- a/core/res/res/drawable/ic_find_next_quantum.xml
+++ b/core/res/res/drawable/ic_dialog_alert_material.xml
@@ -15,5 +15,5 @@
 -->
 
 <bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_find_next_qntm_alpha"
+    android:src="@drawable/ic_dialog_alert_mtrl_alpha"
     android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_dialog_alert_quantum.xml b/core/res/res/drawable/ic_dialog_alert_quantum.xml
deleted file mode 100644
index 05f3630..0000000
--- a/core/res/res/drawable/ic_dialog_alert_quantum.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?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.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_dialog_alert_qntm_alpha"
-    android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_find_next_quantum.xml b/core/res/res/drawable/ic_find_next_material.xml
similarity index 93%
rename from core/res/res/drawable/ic_find_next_quantum.xml
rename to core/res/res/drawable/ic_find_next_material.xml
index fee196c..c6674eb 100644
--- a/core/res/res/drawable/ic_find_next_quantum.xml
+++ b/core/res/res/drawable/ic_find_next_material.xml
@@ -15,5 +15,5 @@
 -->
 
 <bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_find_next_qntm_alpha"
+    android:src="@drawable/ic_find_next_mtrl_alpha"
     android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_find_next_quantum.xml b/core/res/res/drawable/ic_find_previous_material.xml
similarity index 92%
copy from core/res/res/drawable/ic_find_next_quantum.xml
copy to core/res/res/drawable/ic_find_previous_material.xml
index fee196c..32fcb31 100644
--- a/core/res/res/drawable/ic_find_next_quantum.xml
+++ b/core/res/res/drawable/ic_find_previous_material.xml
@@ -15,5 +15,5 @@
 -->
 
 <bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_find_next_qntm_alpha"
+    android:src="@drawable/ic_find_previous_mtrl_alpha"
     android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_find_previous_quantum.xml b/core/res/res/drawable/ic_find_previous_quantum.xml
deleted file mode 100644
index 28f887a..0000000
--- a/core/res/res/drawable/ic_find_previous_quantum.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?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.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_find_previous_qntm_alpha"
-    android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_find_next_quantum.xml b/core/res/res/drawable/ic_go_search_api_material.xml
similarity index 92%
copy from core/res/res/drawable/ic_find_next_quantum.xml
copy to core/res/res/drawable/ic_go_search_api_material.xml
index fee196c..03f6cd5 100644
--- a/core/res/res/drawable/ic_find_next_quantum.xml
+++ b/core/res/res/drawable/ic_go_search_api_material.xml
@@ -15,5 +15,5 @@
 -->
 
 <bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_find_next_qntm_alpha"
+    android:src="@drawable/ic_go_search_api_mtrl_alpha"
     android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_go_search_api_quantum.xml b/core/res/res/drawable/ic_go_search_api_quantum.xml
deleted file mode 100644
index b5b5cfb..0000000
--- a/core/res/res/drawable/ic_go_search_api_quantum.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?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.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_go_search_api_qntm_alpha"
-    android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_media_route_connecting_quantum.xml b/core/res/res/drawable/ic_media_route_connecting_material.xml
similarity index 82%
rename from core/res/res/drawable/ic_media_route_connecting_quantum.xml
rename to core/res/res/drawable/ic_media_route_connecting_material.xml
index 0029dd4..51decd3 100644
--- a/core/res/res/drawable/ic_media_route_connecting_quantum.xml
+++ b/core/res/res/drawable/ic_media_route_connecting_material.xml
@@ -18,19 +18,19 @@
 <animation-list xmlns:android="http://schemas.android.com/apk/res/android"
     android:oneshot="false">
     <item android:duration="500">
-        <bitmap android:src="@drawable/ic_media_route_on_0_qntm_alpha"
+        <bitmap android:src="@drawable/ic_media_route_on_0_mtrl_alpha"
             android:tint="?attr/colorControlNormal" />
     </item>
     <item android:duration="500">
-        <bitmap android:src="@drawable/ic_media_route_on_1_qntm_alpha"
+        <bitmap android:src="@drawable/ic_media_route_on_1_mtrl_alpha"
             android:tint="?attr/colorControlNormal" />
     </item>
     <item android:duration="500">
-        <bitmap android:src="@drawable/ic_media_route_on_2_qntm_alpha"
+        <bitmap android:src="@drawable/ic_media_route_on_2_mtrl_alpha"
             android:tint="?attr/colorControlNormal" />
     </item>
     <item android:duration="500">
-        <bitmap android:src="@drawable/ic_media_route_on_1_qntm_alpha"
+        <bitmap android:src="@drawable/ic_media_route_on_1_mtrl_alpha"
             android:tint="?attr/colorControlNormal" />
     </item>
 </animation-list>
diff --git a/core/res/res/drawable/ic_media_route_quantum.xml b/core/res/res/drawable/ic_media_route_material.xml
similarity index 95%
rename from core/res/res/drawable/ic_media_route_quantum.xml
rename to core/res/res/drawable/ic_media_route_material.xml
index 16b63d4..3e3f388 100644
--- a/core/res/res/drawable/ic_media_route_quantum.xml
+++ b/core/res/res/drawable/ic_media_route_material.xml
@@ -17,17 +17,17 @@
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_checked="true" android:state_enabled="true"
-        android:drawable="@android:drawable/ic_media_route_connecting_quantum" />
+        android:drawable="@android:drawable/ic_media_route_connecting_material" />
     <item android:state_activated="true" android:state_enabled="true">
-        <bitmap android:src="@android:drawable/ic_media_route_on_qntm_alpha"
+        <bitmap android:src="@android:drawable/ic_media_route_on_mtrl_alpha"
             android:tint="?attr/colorControlNormal" />
     </item>
     <item android:state_enabled="true">
-        <bitmap android:src="@android:drawable/ic_media_route_off_qntm_alpha"
+        <bitmap android:src="@android:drawable/ic_media_route_off_mtrl_alpha"
             android:tint="?attr/colorControlNormal" />
     </item>
     <item>
-        <bitmap android:src="@android:drawable/ic_media_route_disabled_qntm_alpha"
+        <bitmap android:src="@android:drawable/ic_media_route_disabled_mtrl_alpha"
             android:tint="?attr/colorControlNormal" />
     </item>
 </selector>
diff --git a/core/res/res/drawable/ic_menu_copy_quantum.xml b/core/res/res/drawable/ic_menu_copy_material.xml
similarity index 93%
copy from core/res/res/drawable/ic_menu_copy_quantum.xml
copy to core/res/res/drawable/ic_menu_copy_material.xml
index 5f6ce51..877b5ff 100644
--- a/core/res/res/drawable/ic_menu_copy_quantum.xml
+++ b/core/res/res/drawable/ic_menu_copy_material.xml
@@ -15,6 +15,6 @@
 -->
 
 <bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_menu_copy_qntm_am_alpha"
+    android:src="@drawable/ic_menu_copy_mtrl_am_alpha"
     android:tint="?attr/colorControlNormal"
     android:autoMirrored="true" />
diff --git a/core/res/res/drawable/ic_find_next_quantum.xml b/core/res/res/drawable/ic_menu_cut_material.xml
similarity index 93%
copy from core/res/res/drawable/ic_find_next_quantum.xml
copy to core/res/res/drawable/ic_menu_cut_material.xml
index fee196c..ff8d6e6 100644
--- a/core/res/res/drawable/ic_find_next_quantum.xml
+++ b/core/res/res/drawable/ic_menu_cut_material.xml
@@ -15,5 +15,5 @@
 -->
 
 <bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_find_next_qntm_alpha"
+    android:src="@drawable/ic_menu_cut_mtrl_alpha"
     android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_menu_cut_quantum.xml b/core/res/res/drawable/ic_menu_cut_quantum.xml
deleted file mode 100644
index 1e4996e..0000000
--- a/core/res/res/drawable/ic_menu_cut_quantum.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?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.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_menu_cut_qntm_alpha"
-    android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_find_next_quantum.xml b/core/res/res/drawable/ic_menu_find_material.xml
similarity index 93%
copy from core/res/res/drawable/ic_find_next_quantum.xml
copy to core/res/res/drawable/ic_menu_find_material.xml
index fee196c..00b294e 100644
--- a/core/res/res/drawable/ic_find_next_quantum.xml
+++ b/core/res/res/drawable/ic_menu_find_material.xml
@@ -15,5 +15,5 @@
 -->
 
 <bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_find_next_qntm_alpha"
+    android:src="@drawable/ic_menu_find_mtrl_alpha"
     android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_menu_find_quantum.xml b/core/res/res/drawable/ic_menu_find_quantum.xml
deleted file mode 100644
index a69c673..0000000
--- a/core/res/res/drawable/ic_menu_find_quantum.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?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.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_menu_find_qntm_alpha"
-    android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_find_next_quantum.xml b/core/res/res/drawable/ic_menu_moreoverflow_material.xml
similarity index 92%
copy from core/res/res/drawable/ic_find_next_quantum.xml
copy to core/res/res/drawable/ic_menu_moreoverflow_material.xml
index fee196c..16d4f0c 100644
--- a/core/res/res/drawable/ic_find_next_quantum.xml
+++ b/core/res/res/drawable/ic_menu_moreoverflow_material.xml
@@ -15,5 +15,5 @@
 -->
 
 <bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_find_next_qntm_alpha"
+    android:src="@drawable/ic_menu_moreoverflow_mtrl_alpha"
     android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_menu_moreoverflow_quantum.xml b/core/res/res/drawable/ic_menu_moreoverflow_quantum.xml
deleted file mode 100644
index 7d3fcac..0000000
--- a/core/res/res/drawable/ic_menu_moreoverflow_quantum.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?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.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_menu_moreoverflow_qntm_alpha"
-    android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_menu_copy_quantum.xml b/core/res/res/drawable/ic_menu_paste_material.xml
similarity index 93%
rename from core/res/res/drawable/ic_menu_copy_quantum.xml
rename to core/res/res/drawable/ic_menu_paste_material.xml
index 5f6ce51..f7bbbf9 100644
--- a/core/res/res/drawable/ic_menu_copy_quantum.xml
+++ b/core/res/res/drawable/ic_menu_paste_material.xml
@@ -15,6 +15,6 @@
 -->
 
 <bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_menu_copy_qntm_am_alpha"
+    android:src="@drawable/ic_menu_paste_mtrl_am_alpha"
     android:tint="?attr/colorControlNormal"
     android:autoMirrored="true" />
diff --git a/core/res/res/drawable/ic_menu_paste_quantum.xml b/core/res/res/drawable/ic_menu_paste_quantum.xml
deleted file mode 100644
index f590904..0000000
--- a/core/res/res/drawable/ic_menu_paste_quantum.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?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.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_menu_paste_qntm_am_alpha"
-    android:tint="?attr/colorControlNormal"
-    android:autoMirrored="true" />
diff --git a/core/res/res/drawable/ic_find_next_quantum.xml b/core/res/res/drawable/ic_menu_search_material.xml
similarity index 93%
copy from core/res/res/drawable/ic_find_next_quantum.xml
copy to core/res/res/drawable/ic_menu_search_material.xml
index fee196c..78dd62f 100644
--- a/core/res/res/drawable/ic_find_next_quantum.xml
+++ b/core/res/res/drawable/ic_menu_search_material.xml
@@ -15,5 +15,5 @@
 -->
 
 <bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_find_next_qntm_alpha"
+    android:src="@drawable/ic_menu_search_mtrl_alpha"
     android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_menu_search_quantum.xml b/core/res/res/drawable/ic_menu_search_quantum.xml
deleted file mode 100644
index 2ca8c20..0000000
--- a/core/res/res/drawable/ic_menu_search_quantum.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?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.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_menu_search_qntm_alpha"
-    android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_find_next_quantum.xml b/core/res/res/drawable/ic_menu_selectall_material.xml
similarity index 92%
copy from core/res/res/drawable/ic_find_next_quantum.xml
copy to core/res/res/drawable/ic_menu_selectall_material.xml
index fee196c..a431dd5 100644
--- a/core/res/res/drawable/ic_find_next_quantum.xml
+++ b/core/res/res/drawable/ic_menu_selectall_material.xml
@@ -15,5 +15,5 @@
 -->
 
 <bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_find_next_qntm_alpha"
+    android:src="@drawable/ic_menu_selectall_mtrl_alpha"
     android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_menu_selectall_quantum.xml b/core/res/res/drawable/ic_menu_selectall_quantum.xml
deleted file mode 100644
index fd72ebf..0000000
--- a/core/res/res/drawable/ic_menu_selectall_quantum.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?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.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_menu_selectall_qntm_alpha"
-    android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_find_next_quantum.xml b/core/res/res/drawable/ic_menu_share_material.xml
similarity index 93%
copy from core/res/res/drawable/ic_find_next_quantum.xml
copy to core/res/res/drawable/ic_menu_share_material.xml
index fee196c..d9153af 100644
--- a/core/res/res/drawable/ic_find_next_quantum.xml
+++ b/core/res/res/drawable/ic_menu_share_material.xml
@@ -15,5 +15,5 @@
 -->
 
 <bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_find_next_qntm_alpha"
+    android:src="@drawable/ic_menu_share_mtrl_alpha"
     android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_menu_share_quantum.xml b/core/res/res/drawable/ic_menu_share_quantum.xml
deleted file mode 100644
index f44e06c..0000000
--- a/core/res/res/drawable/ic_menu_share_quantum.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?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.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_menu_share_qntm_alpha"
-    android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_find_next_quantum.xml b/core/res/res/drawable/ic_search_api_material.xml
similarity index 93%
copy from core/res/res/drawable/ic_find_next_quantum.xml
copy to core/res/res/drawable/ic_search_api_material.xml
index fee196c..bc18398 100644
--- a/core/res/res/drawable/ic_find_next_quantum.xml
+++ b/core/res/res/drawable/ic_search_api_material.xml
@@ -15,5 +15,5 @@
 -->
 
 <bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_find_next_qntm_alpha"
+    android:src="@drawable/ic_search_api_mtrl_alpha"
     android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_search_api_quantum.xml b/core/res/res/drawable/ic_search_api_quantum.xml
deleted file mode 100644
index 2bbc294..0000000
--- a/core/res/res/drawable/ic_search_api_quantum.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?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.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_search_api_qntm_alpha"
-    android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_find_next_quantum.xml b/core/res/res/drawable/ic_voice_search_api_material.xml
similarity index 92%
copy from core/res/res/drawable/ic_find_next_quantum.xml
copy to core/res/res/drawable/ic_voice_search_api_material.xml
index fee196c..05488fb 100644
--- a/core/res/res/drawable/ic_find_next_quantum.xml
+++ b/core/res/res/drawable/ic_voice_search_api_material.xml
@@ -15,5 +15,5 @@
 -->
 
 <bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_find_next_qntm_alpha"
+    android:src="@drawable/ic_voice_search_api_mtrl_alpha"
     android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_voice_search_api_quantum.xml b/core/res/res/drawable/ic_voice_search_api_quantum.xml
deleted file mode 100644
index ddb14ef..0000000
--- a/core/res/res/drawable/ic_voice_search_api_quantum.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?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.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_voice_search_api_qntm_alpha"
-    android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/item_background_borderless_quantum.xml b/core/res/res/drawable/item_background_borderless_material.xml
similarity index 100%
rename from core/res/res/drawable/item_background_borderless_quantum.xml
rename to core/res/res/drawable/item_background_borderless_material.xml
diff --git a/core/res/res/drawable/item_background_quantum.xml b/core/res/res/drawable/item_background_material.xml
similarity index 100%
rename from core/res/res/drawable/item_background_quantum.xml
rename to core/res/res/drawable/item_background_material.xml
diff --git a/core/res/res/drawable/list_divider_quantum.xml b/core/res/res/drawable/list_divider_material.xml
similarity index 93%
rename from core/res/res/drawable/list_divider_quantum.xml
rename to core/res/res/drawable/list_divider_material.xml
index e3d4ba2..bf24933 100644
--- a/core/res/res/drawable/list_divider_quantum.xml
+++ b/core/res/res/drawable/list_divider_material.xml
@@ -15,5 +15,5 @@
 -->
 
 <nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/list_divider_qntm_alpha"
+    android:src="@drawable/list_divider_mtrl_alpha"
     android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/list_divider_quantum.xml b/core/res/res/drawable/list_section_divider_material.xml
similarity index 92%
copy from core/res/res/drawable/list_divider_quantum.xml
copy to core/res/res/drawable/list_section_divider_material.xml
index e3d4ba2..515634e 100644
--- a/core/res/res/drawable/list_divider_quantum.xml
+++ b/core/res/res/drawable/list_section_divider_material.xml
@@ -15,5 +15,5 @@
 -->
 
 <nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/list_divider_qntm_alpha"
+    android:src="@drawable/list_section_divider_mtrl_alpha"
     android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/list_section_divider_quantum.xml b/core/res/res/drawable/list_section_divider_quantum.xml
deleted file mode 100644
index 87a1439..0000000
--- a/core/res/res/drawable/list_section_divider_quantum.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?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/list_section_divider_qntm_alpha"
-    android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/notification_quantum_bg.xml b/core/res/res/drawable/notification_material_bg.xml
similarity index 84%
rename from core/res/res/drawable/notification_quantum_bg.xml
rename to core/res/res/drawable/notification_material_bg.xml
index 300a565..44c67be 100644
--- a/core/res/res/drawable/notification_quantum_bg.xml
+++ b/core/res/res/drawable/notification_material_bg.xml
@@ -19,13 +19,13 @@
     <item android:state_pressed="true">
         <shape>
             <solid android:color="#ffd0d0d0" />
-            <corners android:radius="@dimen/notification_quantum_rounded_rect_radius" />
+            <corners android:radius="@dimen/notification_material_rounded_rect_radius" />
         </shape>
     </item>
     <item>
         <shape>
             <solid android:color="#fffafafa" />
-            <corners android:radius="@dimen/notification_quantum_rounded_rect_radius" />
+            <corners android:radius="@dimen/notification_material_rounded_rect_radius" />
         </shape>
     </item>
 </selector>
\ No newline at end of file
diff --git a/core/res/res/drawable/notification_quantum_bg_dim.xml b/core/res/res/drawable/notification_material_bg_dim.xml
similarity index 90%
rename from core/res/res/drawable/notification_quantum_bg_dim.xml
rename to core/res/res/drawable/notification_material_bg_dim.xml
index eb9a4ab..a908be7 100644
--- a/core/res/res/drawable/notification_quantum_bg_dim.xml
+++ b/core/res/res/drawable/notification_material_bg_dim.xml
@@ -23,7 +23,7 @@
     <item>
         <shape>
             <solid android:color="#d4ffffff" />
-            <corners android:radius="@dimen/notification_quantum_rounded_rect_radius" />
+            <corners android:radius="@dimen/notification_material_rounded_rect_radius" />
         </shape>
     </item>
 </ripple>
\ No newline at end of file
diff --git a/core/res/res/drawable/notification_quantum_media_progress.xml b/core/res/res/drawable/notification_material_media_progress.xml
similarity index 100%
rename from core/res/res/drawable/notification_quantum_media_progress.xml
rename to core/res/res/drawable/notification_material_media_progress.xml
diff --git a/core/res/res/drawable/popup_background_quantum.xml b/core/res/res/drawable/popup_background_material.xml
similarity index 93%
rename from core/res/res/drawable/popup_background_quantum.xml
rename to core/res/res/drawable/popup_background_material.xml
index a4d0291..9e50790 100644
--- a/core/res/res/drawable/popup_background_quantum.xml
+++ b/core/res/res/drawable/popup_background_material.xml
@@ -15,6 +15,6 @@
 -->
 
 <nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/popup_background_qntm_mult"
+    android:src="@drawable/popup_background_mtrl_mult"
     android:tint="?attr/colorBackground"
     android:tintMode="multiply" />
diff --git a/core/res/res/drawable/progress_horizontal_quantum.xml b/core/res/res/drawable/progress_horizontal_material.xml
similarity index 89%
rename from core/res/res/drawable/progress_horizontal_quantum.xml
rename to core/res/res/drawable/progress_horizontal_material.xml
index 1c2d494..eca1a24 100644
--- a/core/res/res/drawable/progress_horizontal_quantum.xml
+++ b/core/res/res/drawable/progress_horizontal_material.xml
@@ -16,18 +16,18 @@
 
 <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:id="@id/background">
-        <nine-patch android:src="@drawable/progress_qntm_alpha"
+        <nine-patch android:src="@drawable/progress_mtrl_alpha"
             android:tint="?attr/colorControlNormal" />
     </item>
     <item android:id="@id/secondaryProgress">
         <scale android:scaleWidth="100%">
-            <nine-patch android:src="@drawable/progress_qntm_alpha"
+            <nine-patch android:src="@drawable/progress_mtrl_alpha"
                 android:tint="?attr/colorControlActivated" />
         </scale>
     </item>
     <item android:id="@id/progress">
         <scale android:scaleWidth="100%">
-            <nine-patch android:src="@drawable/progress_primary_qntm_alpha"
+            <nine-patch android:src="@drawable/progress_primary_mtrl_alpha"
                 android:tint="?attr/colorControlActivated" />
         </scale>
     </item>
diff --git a/core/res/res/drawable/ic_find_next_quantum.xml b/core/res/res/drawable/progress_large_material.xml
similarity index 73%
copy from core/res/res/drawable/ic_find_next_quantum.xml
copy to core/res/res/drawable/progress_large_material.xml
index fee196c..965b288 100644
--- a/core/res/res/drawable/ic_find_next_quantum.xml
+++ b/core/res/res/drawable/progress_large_material.xml
@@ -14,6 +14,9 @@
      limitations under the License.
 -->
 
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_find_next_qntm_alpha"
-    android:tint="?attr/colorControlNormal" />
+<material-progress xmlns:android="http://schemas.android.com/apk/res/android"
+    android:color="?attr/colorControlActivated"
+    android:width="76dp"
+    android:height="76dp"
+    android:thickness="6.3dp"
+    android:innerRadius="30.1dp" />
diff --git a/core/res/res/drawable/ic_find_next_quantum.xml b/core/res/res/drawable/progress_medium_material.xml
similarity index 73%
copy from core/res/res/drawable/ic_find_next_quantum.xml
copy to core/res/res/drawable/progress_medium_material.xml
index fee196c..c656026 100644
--- a/core/res/res/drawable/ic_find_next_quantum.xml
+++ b/core/res/res/drawable/progress_medium_material.xml
@@ -14,6 +14,9 @@
      limitations under the License.
 -->
 
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_find_next_qntm_alpha"
-    android:tint="?attr/colorControlNormal" />
+<material-progress xmlns:android="http://schemas.android.com/apk/res/android"
+    android:color="?attr/colorControlActivated"
+    android:width="48dp"
+    android:height="48dp"
+    android:thickness="4dp"
+    android:innerRadius="19dp" />
diff --git a/core/res/res/drawable/ic_find_next_quantum.xml b/core/res/res/drawable/progress_small_material.xml
similarity index 73%
copy from core/res/res/drawable/ic_find_next_quantum.xml
copy to core/res/res/drawable/progress_small_material.xml
index fee196c..67ae268 100644
--- a/core/res/res/drawable/ic_find_next_quantum.xml
+++ b/core/res/res/drawable/progress_small_material.xml
@@ -14,6 +14,9 @@
      limitations under the License.
 -->
 
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_find_next_qntm_alpha"
-    android:tint="?attr/colorControlNormal" />
+<material-progress xmlns:android="http://schemas.android.com/apk/res/android"
+    android:color="?attr/colorControlActivated"
+    android:width="16dp"
+    android:height="16dp"
+    android:thickness="1.3dp"
+    android:innerRadius="6.3dp" />
diff --git a/core/res/res/drawable/ratingbar_full_empty_quantum.xml b/core/res/res/drawable/ratingbar_full_empty_material.xml
similarity index 87%
rename from core/res/res/drawable/ratingbar_full_empty_quantum.xml
rename to core/res/res/drawable/ratingbar_full_empty_material.xml
index e5e4315..a2ae7d9 100644
--- a/core/res/res/drawable/ratingbar_full_empty_quantum.xml
+++ b/core/res/res/drawable/ratingbar_full_empty_material.xml
@@ -16,11 +16,11 @@
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_pressed="true">
-        <bitmap android:src="@drawable/btn_rating_star_off_qntm_alpha"
+        <bitmap android:src="@drawable/btn_rating_star_off_mtrl_alpha"
             android:tint="?attr/colorControlActivated" />
     </item>
     <item>
-        <bitmap android:src="@drawable/btn_rating_star_off_qntm_alpha"
+        <bitmap android:src="@drawable/btn_rating_star_off_mtrl_alpha"
             android:tint="?attr/colorControlNormal" />
     </item>
 </selector>
diff --git a/core/res/res/drawable/ratingbar_full_filled_quantum.xml b/core/res/res/drawable/ratingbar_full_filled_material.xml
similarity index 87%
rename from core/res/res/drawable/ratingbar_full_filled_quantum.xml
rename to core/res/res/drawable/ratingbar_full_filled_material.xml
index ad3aa5d..801c85f 100644
--- a/core/res/res/drawable/ratingbar_full_filled_quantum.xml
+++ b/core/res/res/drawable/ratingbar_full_filled_material.xml
@@ -16,11 +16,11 @@
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_pressed="true">
-        <bitmap android:src="@drawable/btn_rating_star_on_qntm_alpha"
+        <bitmap android:src="@drawable/btn_rating_star_on_mtrl_alpha"
             android:tint="?attr/colorControlActivated" />
     </item>
     <item>
-        <bitmap android:src="@drawable/btn_rating_star_on_qntm_alpha"
+        <bitmap android:src="@drawable/btn_rating_star_on_mtrl_alpha"
             android:tint="?attr/colorControlNormal" />
     </item>
 </selector>
diff --git a/core/res/res/drawable/ratingbar_full_quantum.xml b/core/res/res/drawable/ratingbar_full_material.xml
similarity index 80%
rename from core/res/res/drawable/ratingbar_full_quantum.xml
rename to core/res/res/drawable/ratingbar_full_material.xml
index 143e7c2..122dd1d 100644
--- a/core/res/res/drawable/ratingbar_full_quantum.xml
+++ b/core/res/res/drawable/ratingbar_full_material.xml
@@ -16,9 +16,9 @@
 
 <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:id="@id/background"
-        android:drawable="@drawable/ratingbar_full_empty_quantum" />
+        android:drawable="@drawable/ratingbar_full_empty_material" />
     <item android:id="@id/secondaryProgress"
-        android:drawable="@drawable/ratingbar_full_empty_quantum" />
+        android:drawable="@drawable/ratingbar_full_empty_material" />
     <item android:id="@id/progress" 
-        android:drawable="@drawable/ratingbar_full_filled_quantum" />
+        android:drawable="@drawable/ratingbar_full_filled_material" />
 </layer-list>
diff --git a/core/res/res/drawable/list_divider_quantum.xml b/core/res/res/drawable/scrollbar_handle_material.xml
similarity index 92%
copy from core/res/res/drawable/list_divider_quantum.xml
copy to core/res/res/drawable/scrollbar_handle_material.xml
index e3d4ba2..a241428 100644
--- a/core/res/res/drawable/list_divider_quantum.xml
+++ b/core/res/res/drawable/scrollbar_handle_material.xml
@@ -15,5 +15,5 @@
 -->
 
 <nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/list_divider_qntm_alpha"
+    android:src="@drawable/scrollbar_handle_mtrl_alpha"
     android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/scrollbar_handle_quantum.xml b/core/res/res/drawable/scrollbar_handle_quantum.xml
deleted file mode 100644
index f2de252..0000000
--- a/core/res/res/drawable/scrollbar_handle_quantum.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?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/scrollbar_handle_qntm_alpha"
-    android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/scrubber_control_quantum_anim.xml b/core/res/res/drawable/scrubber_control_material_anim.xml
similarity index 77%
rename from core/res/res/drawable/scrubber_control_quantum_anim.xml
rename to core/res/res/drawable/scrubber_control_material_anim.xml
index 87d3ae9..4b13259 100644
--- a/core/res/res/drawable/scrubber_control_quantum_anim.xml
+++ b/core/res/res/drawable/scrubber_control_material_anim.xml
@@ -16,58 +16,58 @@
 
 <animated-selector xmlns:android="http://schemas.android.com/apk/res/android" android:constantSize="true">
     <item android:state_enabled="false" android:state_pressed="true">
-        <bitmap android:src="@drawable/scrubber_control_off_qntm_alpha" android:gravity="center" android:tint="?attr/colorControlActivated" android:alpha="?attr/disabledAlpha" />
+        <bitmap android:src="@drawable/scrubber_control_off_mtrl_alpha" android:gravity="center" android:tint="?attr/colorControlActivated" android:alpha="?attr/disabledAlpha" />
     </item>
     <item android:state_enabled="false">
-        <bitmap android:src="@drawable/scrubber_control_off_qntm_alpha" android:gravity="center" android:tint="?attr/colorControlNormal" android:alpha="?attr/disabledAlpha" />
+        <bitmap android:src="@drawable/scrubber_control_off_mtrl_alpha" android:gravity="center" android:tint="?attr/colorControlNormal" android:alpha="?attr/disabledAlpha" />
     </item>
     <item android:state_pressed="true" android:id="@+id/pressed">
-        <bitmap android:src="@drawable/scrubber_control_to_pressed_qntm_005" android:gravity="center" android:tint="?attr/colorControlActivated" />
+        <bitmap android:src="@drawable/scrubber_control_to_pressed_mtrl_005" android:gravity="center" android:tint="?attr/colorControlActivated" />
     </item>
     <item android:id="@+id/not_pressed">
-        <bitmap android:src="@drawable/scrubber_control_to_pressed_qntm_000" android:gravity="center" android:tint="?attr/colorControlActivated" />
+        <bitmap android:src="@drawable/scrubber_control_to_pressed_mtrl_000" android:gravity="center" android:tint="?attr/colorControlActivated" />
     </item>
     <transition android:fromId="@+id/not_pressed" android:toId="@+id/pressed">
         <animation-list>
             <item android:duration="15">
-                <bitmap android:src="@drawable/scrubber_control_to_pressed_qntm_000" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/scrubber_control_to_pressed_mtrl_000" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
             <item android:duration="15">
-                <bitmap android:src="@drawable/scrubber_control_to_pressed_qntm_001" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/scrubber_control_to_pressed_mtrl_001" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
             <item android:duration="15">
-                <bitmap android:src="@drawable/scrubber_control_to_pressed_qntm_002" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/scrubber_control_to_pressed_mtrl_002" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
             <item android:duration="15">
-                <bitmap android:src="@drawable/scrubber_control_to_pressed_qntm_003" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/scrubber_control_to_pressed_mtrl_003" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
             <item android:duration="15">
-                <bitmap android:src="@drawable/scrubber_control_to_pressed_qntm_004" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/scrubber_control_to_pressed_mtrl_004" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
             <item android:duration="15">
-                <bitmap android:src="@drawable/scrubber_control_to_pressed_qntm_005" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/scrubber_control_to_pressed_mtrl_005" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
         </animation-list>
     </transition>
     <transition android:fromId="@+id/pressed" android:toId="@+id/not_pressed">
         <animation-list>
             <item android:duration="15">
-                <bitmap android:src="@drawable/scrubber_control_from_pressed_qntm_000" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/scrubber_control_from_pressed_mtrl_000" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
             <item android:duration="15">
-                <bitmap android:src="@drawable/scrubber_control_from_pressed_qntm_001" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/scrubber_control_from_pressed_mtrl_001" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
             <item android:duration="15">
-                <bitmap android:src="@drawable/scrubber_control_from_pressed_qntm_002" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/scrubber_control_from_pressed_mtrl_002" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
             <item android:duration="15">
-                <bitmap android:src="@drawable/scrubber_control_from_pressed_qntm_003" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/scrubber_control_from_pressed_mtrl_003" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
             <item android:duration="15">
-                <bitmap android:src="@drawable/scrubber_control_from_pressed_qntm_004" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/scrubber_control_from_pressed_mtrl_004" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
             <item android:duration="15">
-                <bitmap android:src="@drawable/scrubber_control_from_pressed_qntm_005" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/scrubber_control_from_pressed_mtrl_005" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
         </animation-list>
     </transition>
diff --git a/core/res/res/drawable/scrubber_control_selector_quantum.xml b/core/res/res/drawable/scrubber_control_selector_material.xml
similarity index 87%
rename from core/res/res/drawable/scrubber_control_selector_quantum.xml
rename to core/res/res/drawable/scrubber_control_selector_material.xml
index ef3af0c..9892676 100644
--- a/core/res/res/drawable/scrubber_control_selector_quantum.xml
+++ b/core/res/res/drawable/scrubber_control_selector_material.xml
@@ -16,11 +16,11 @@
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_enabled="false">
-        <bitmap android:src="@drawable/scrubber_control_off_qntm_alpha"
+        <bitmap android:src="@drawable/scrubber_control_off_mtrl_alpha"
             android:tint="?attr/colorControlNormal" />
     </item>
     <item>
-        <bitmap android:src="@drawable/scrubber_control_on_qntm_alpha"
+        <bitmap android:src="@drawable/scrubber_control_on_mtrl_alpha"
             android:tint="?attr/colorControlActivated" />
     </item>
 </selector>
diff --git a/core/res/res/drawable/scrubber_progress_horizontal_quantum.xml b/core/res/res/drawable/scrubber_progress_horizontal_material.xml
similarity index 93%
rename from core/res/res/drawable/scrubber_progress_horizontal_quantum.xml
rename to core/res/res/drawable/scrubber_progress_horizontal_material.xml
index f82fe7a..f2ea30f 100644
--- a/core/res/res/drawable/scrubber_progress_horizontal_quantum.xml
+++ b/core/res/res/drawable/scrubber_progress_horizontal_material.xml
@@ -16,24 +16,24 @@
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_enabled="false">
-        <nine-patch android:src="@drawable/scrubber_track_qntm_alpha"
+        <nine-patch android:src="@drawable/scrubber_track_mtrl_alpha"
             android:tint="?attr/colorControlNormal" />
     </item>
     <item>
         <layer-list>
             <item android:id="@id/background">
-                <nine-patch android:src="@drawable/scrubber_track_qntm_alpha"
+                <nine-patch android:src="@drawable/scrubber_track_mtrl_alpha"
                     android:tint="?attr/colorControlNormal" />
             </item>
             <item android:id="@id/secondaryProgress">
                 <scale android:scaleWidth="100%">
-                    <nine-patch android:src="@drawable/scrubber_primary_qntm_alpha"
+                    <nine-patch android:src="@drawable/scrubber_primary_mtrl_alpha"
                         android:tint="?attr/colorControlNormal" />
                 </scale>
             </item>
             <item android:id="@id/progress">
                 <scale android:scaleWidth="100%">
-                    <nine-patch android:src="@drawable/scrubber_primary_qntm_alpha"
+                    <nine-patch android:src="@drawable/scrubber_primary_mtrl_alpha"
                         android:tint="?attr/colorControlActivated" />
                 </scale>
             </item>
diff --git a/core/res/res/drawable/spinner_background_quantum.xml b/core/res/res/drawable/spinner_background_material.xml
similarity index 84%
rename from core/res/res/drawable/spinner_background_quantum.xml
rename to core/res/res/drawable/spinner_background_material.xml
index 727a78f..02ea11b 100644
--- a/core/res/res/drawable/spinner_background_quantum.xml
+++ b/core/res/res/drawable/spinner_background_material.xml
@@ -17,15 +17,15 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android"
     android:autoMirrored="true">
     <item android:state_checked="true">
-        <nine-patch android:src="@drawable/spinner_qntm_am_alpha"
+        <nine-patch android:src="@drawable/spinner_mtrl_am_alpha"
             android:tint="?attr/colorControlActivated" />
     </item>
     <item android:state_pressed="true">
-        <nine-patch android:src="@drawable/spinner_qntm_am_alpha"
+        <nine-patch android:src="@drawable/spinner_mtrl_am_alpha"
             android:tint="?attr/colorControlActivated" />
     </item>
     <item>
-        <nine-patch android:src="@drawable/spinner_qntm_am_alpha"
+        <nine-patch android:src="@drawable/spinner_mtrl_am_alpha"
             android:tint="?attr/colorControlNormal" />
     </item>
 </selector>
diff --git a/core/res/res/drawable/switch_thumb_quantum_anim.xml b/core/res/res/drawable/switch_thumb_material_anim.xml
similarity index 73%
rename from core/res/res/drawable/switch_thumb_quantum_anim.xml
rename to core/res/res/drawable/switch_thumb_material_anim.xml
index 1984d47..e7baa2c 100644
--- a/core/res/res/drawable/switch_thumb_quantum_anim.xml
+++ b/core/res/res/drawable/switch_thumb_material_anim.xml
@@ -16,112 +16,112 @@
 
 <animated-selector xmlns:android="http://schemas.android.com/apk/res/android" android:constantSize="true">
     <item android:state_enabled="false" android:state_checked="true">
-        <bitmap android:src="@drawable/btn_switch_to_on_qntm_014" android:gravity="center" android:tint="?attr/colorControlActivated" android:alpha="?attr/disabledAlpha" />
+        <bitmap android:src="@drawable/btn_switch_to_on_mtrl_014" android:gravity="center" android:tint="?attr/colorControlActivated" android:alpha="?attr/disabledAlpha" />
     </item>
     <item android:state_enabled="false">
-        <bitmap android:src="@drawable/btn_switch_to_on_qntm_000" android:gravity="center" android:tint="?attr/colorControlNormal" android:alpha="?attr/disabledAlpha" />
+        <bitmap android:src="@drawable/btn_switch_to_on_mtrl_000" android:gravity="center" android:tint="?attr/colorControlNormal" android:alpha="?attr/disabledAlpha" />
     </item>
     <item android:state_checked="true" android:id="@+id/on">
-        <bitmap android:src="@drawable/btn_switch_to_on_qntm_014" android:gravity="center" android:tint="?attr/colorControlActivated" />
+        <bitmap android:src="@drawable/btn_switch_to_on_mtrl_014" android:gravity="center" android:tint="?attr/colorControlActivated" />
     </item>
     <item android:id="@+id/off">
-        <bitmap android:src="@drawable/btn_switch_to_on_qntm_000" android:gravity="center" android:tint="?attr/colorControlNormal" />
+        <bitmap android:src="@drawable/btn_switch_to_on_mtrl_000" android:gravity="center" android:tint="?attr/colorControlNormal" />
     </item>
     <transition android:fromId="@+id/off" android:toId="@+id/on">
         <animation-list>
             <item android:duration="15">
-                <bitmap android:src="@drawable/btn_switch_to_on_qntm_000" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/btn_switch_to_on_mtrl_000" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
             <item android:duration="15">
-                <bitmap android:src="@drawable/btn_switch_to_on_qntm_001" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/btn_switch_to_on_mtrl_001" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
             <item android:duration="15">
-                <bitmap android:src="@drawable/btn_switch_to_on_qntm_002" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/btn_switch_to_on_mtrl_002" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
             <item android:duration="15">
-                <bitmap android:src="@drawable/btn_switch_to_on_qntm_003" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/btn_switch_to_on_mtrl_003" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
             <item android:duration="15">
-                <bitmap android:src="@drawable/btn_switch_to_on_qntm_004" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/btn_switch_to_on_mtrl_004" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
             <item android:duration="15">
-                <bitmap android:src="@drawable/btn_switch_to_on_qntm_005" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/btn_switch_to_on_mtrl_005" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
             <item android:duration="15">
-                <bitmap android:src="@drawable/btn_switch_to_on_qntm_006" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/btn_switch_to_on_mtrl_006" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
             <item android:duration="15">
-                <bitmap android:src="@drawable/btn_switch_to_on_qntm_007" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/btn_switch_to_on_mtrl_007" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
             <item android:duration="15">
-                <bitmap android:src="@drawable/btn_switch_to_on_qntm_008" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/btn_switch_to_on_mtrl_008" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
             <item android:duration="15">
-                <bitmap android:src="@drawable/btn_switch_to_on_qntm_009" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/btn_switch_to_on_mtrl_009" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
             <item android:duration="15">
-                <bitmap android:src="@drawable/btn_switch_to_on_qntm_010" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/btn_switch_to_on_mtrl_010" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
             <item android:duration="15">
-                <bitmap android:src="@drawable/btn_switch_to_on_qntm_011" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/btn_switch_to_on_mtrl_011" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
             <item android:duration="15">
-                <bitmap android:src="@drawable/btn_switch_to_on_qntm_012" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/btn_switch_to_on_mtrl_012" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
             <item android:duration="15">
-                <bitmap android:src="@drawable/btn_switch_to_on_qntm_013" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/btn_switch_to_on_mtrl_013" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
             <item android:duration="15">
-                <bitmap android:src="@drawable/btn_switch_to_on_qntm_014" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/btn_switch_to_on_mtrl_014" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
         </animation-list>
     </transition>
     <transition android:fromId="@+id/on" android:toId="@+id/off">
         <animation-list>
             <item android:duration="15">
-                <bitmap android:src="@drawable/btn_switch_to_off_qntm_000" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/btn_switch_to_off_mtrl_000" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
             <item android:duration="15">
-                <bitmap android:src="@drawable/btn_switch_to_off_qntm_001" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/btn_switch_to_off_mtrl_001" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
             <item android:duration="15">
-                <bitmap android:src="@drawable/btn_switch_to_off_qntm_002" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/btn_switch_to_off_mtrl_002" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
             <item android:duration="15">
-                <bitmap android:src="@drawable/btn_switch_to_off_qntm_003" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/btn_switch_to_off_mtrl_003" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
             <item android:duration="15">
-                <bitmap android:src="@drawable/btn_switch_to_off_qntm_004" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/btn_switch_to_off_mtrl_004" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
             <item android:duration="15">
-                <bitmap android:src="@drawable/btn_switch_to_off_qntm_005" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/btn_switch_to_off_mtrl_005" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
             <item android:duration="15">
-                <bitmap android:src="@drawable/btn_switch_to_off_qntm_006" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/btn_switch_to_off_mtrl_006" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
             <item android:duration="15">
-                <bitmap android:src="@drawable/btn_switch_to_off_qntm_007" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/btn_switch_to_off_mtrl_007" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
             <item android:duration="15">
-                <bitmap android:src="@drawable/btn_switch_to_off_qntm_008" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/btn_switch_to_off_mtrl_008" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
             <item android:duration="15">
-                <bitmap android:src="@drawable/btn_switch_to_off_qntm_009" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/btn_switch_to_off_mtrl_009" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
             <item android:duration="15">
-                <bitmap android:src="@drawable/btn_switch_to_off_qntm_010" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/btn_switch_to_off_mtrl_010" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
             <item android:duration="15">
-                <bitmap android:src="@drawable/btn_switch_to_off_qntm_011" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/btn_switch_to_off_mtrl_011" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
             <item android:duration="15">
-                <bitmap android:src="@drawable/btn_switch_to_off_qntm_012" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/btn_switch_to_off_mtrl_012" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
             <item android:duration="15">
-                <bitmap android:src="@drawable/btn_switch_to_off_qntm_013" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/btn_switch_to_off_mtrl_013" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
             <item android:duration="15">
-                <bitmap android:src="@drawable/btn_switch_to_off_qntm_014" android:gravity="center" android:tint="?attr/colorControlActivated" />
+                <bitmap android:src="@drawable/btn_switch_to_off_mtrl_014" android:gravity="center" android:tint="?attr/colorControlActivated" />
             </item>
         </animation-list>
     </transition>
diff --git a/core/res/res/drawable/switch_track_quantum.xml b/core/res/res/drawable/switch_track_material.xml
similarity index 83%
rename from core/res/res/drawable/switch_track_quantum.xml
rename to core/res/res/drawable/switch_track_material.xml
index 3651a0a..6ca2489 100644
--- a/core/res/res/drawable/switch_track_quantum.xml
+++ b/core/res/res/drawable/switch_track_material.xml
@@ -16,21 +16,21 @@
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_enabled="false" android:state_checked="true">
-        <nine-patch android:src="@drawable/switch_track_qntm_alpha"
+        <nine-patch android:src="@drawable/switch_track_mtrl_alpha"
             android:tint="?attr/colorControlActivated"
             android:alpha="?attr/disabledAlpha" />
     </item>
     <item android:state_enabled="false">
-        <nine-patch android:src="@drawable/switch_track_qntm_alpha"
+        <nine-patch android:src="@drawable/switch_track_mtrl_alpha"
             android:tint="?attr/colorControlNormal"
             android:alpha="?attr/disabledAlpha" />
     </item>
     <item android:state_checked="true">
-        <nine-patch android:src="@drawable/switch_track_qntm_alpha"
+        <nine-patch android:src="@drawable/switch_track_mtrl_alpha"
             android:tint="?attr/colorControlActivated" />
     </item>
     <item>
-        <nine-patch android:src="@drawable/switch_track_qntm_alpha"
+        <nine-patch android:src="@drawable/switch_track_mtrl_alpha"
             android:tint="?attr/colorControlNormal" />
     </item>
 </selector>
diff --git a/core/res/res/drawable/fastscroll_thumb_quantum.xml b/core/res/res/drawable/tab_indicator_material.xml
similarity index 76%
copy from core/res/res/drawable/fastscroll_thumb_quantum.xml
copy to core/res/res/drawable/tab_indicator_material.xml
index 496b2ae..16362c0 100644
--- a/core/res/res/drawable/fastscroll_thumb_quantum.xml
+++ b/core/res/res/drawable/tab_indicator_material.xml
@@ -15,12 +15,9 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_pressed="true">
-        <bitmap android:src="@drawable/fastscroll_thumb_qntm_alpha"
+    <item android:state_selected="true">
+        <nine-patch android:src="@drawable/tab_indicator_mtrl_alpha"
             android:tint="?attr/colorControlActivated" />
     </item>
-    <item>
-        <bitmap android:src="@drawable/fastscroll_thumb_qntm_alpha"
-            android:tint="?attr/colorControlNormal" />
-    </item>
+    <item android:drawable="@color/transparent" />
 </selector>
diff --git a/core/res/res/drawable/tab_indicator_quantum.xml b/core/res/res/drawable/tab_indicator_quantum.xml
deleted file mode 100644
index 6fabe23..0000000
--- a/core/res/res/drawable/tab_indicator_quantum.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_selected="true" android:state_pressed="true">
-        <nine-patch android:src="@drawable/tab_indicator_selected_qntm_alpha"
-            android:tint="?attr/colorControlActivated" />
-    </item>
-    <item android:state_selected="true" android:state_focused="true">
-        <nine-patch android:src="@drawable/tab_indicator_selected_qntm_alpha"
-            android:tint="?attr/colorControlActivated" />
-    </item>
-    <item android:state_selected="true">
-        <nine-patch android:src="@drawable/tab_indicator_selected_qntm_alpha"
-            android:tint="?attr/colorControlNormal" />
-    </item>
-
-    <item android:state_pressed="true">
-        <nine-patch android:src="@drawable/tab_indicator_normal_qntm_alpha"
-            android:tint="?attr/colorControlActivated" />
-    </item>
-    <item android:state_focused="true">
-        <nine-patch android:src="@drawable/tab_indicator_normal_qntm_alpha"
-            android:tint="?attr/colorControlActivated" />
-    </item>
-    <item>
-        <nine-patch android:src="@drawable/tab_indicator_normal_qntm_alpha"
-            android:tint="?attr/colorControlNormal" />
-    </item>
-</selector>
diff --git a/core/res/res/drawable/text_cursor_quantum.xml b/core/res/res/drawable/text_cursor_material.xml
similarity index 93%
rename from core/res/res/drawable/text_cursor_quantum.xml
rename to core/res/res/drawable/text_cursor_material.xml
index 23d4ae0..a350c47 100644
--- a/core/res/res/drawable/text_cursor_quantum.xml
+++ b/core/res/res/drawable/text_cursor_material.xml
@@ -15,5 +15,5 @@
 -->
 
 <nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/text_cursor_qntm_alpha"
+    android:src="@drawable/text_cursor_mtrl_alpha"
     android:tint="?attr/colorControlActivated" />
diff --git a/core/res/res/drawable/text_select_handle_right_quantum.xml b/core/res/res/drawable/text_select_handle_left_material.xml
similarity index 92%
rename from core/res/res/drawable/text_select_handle_right_quantum.xml
rename to core/res/res/drawable/text_select_handle_left_material.xml
index 413661f..b228d3f 100644
--- a/core/res/res/drawable/text_select_handle_right_quantum.xml
+++ b/core/res/res/drawable/text_select_handle_left_material.xml
@@ -15,5 +15,5 @@
 -->
 
 <bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/text_select_handle_right_qntm_alpha"
+    android:src="@drawable/text_select_handle_left_mtrl_alpha"
     android:tint="?attr/colorControlActivated" />
diff --git a/core/res/res/drawable/text_select_handle_left_quantum.xml b/core/res/res/drawable/text_select_handle_left_quantum.xml
deleted file mode 100644
index a0ad7cf..0000000
--- a/core/res/res/drawable/text_select_handle_left_quantum.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?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.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/text_select_handle_left_qntm_alpha"
-    android:tint="?attr/colorControlActivated" />
diff --git a/core/res/res/drawable/text_select_handle_middle_quantum.xml b/core/res/res/drawable/text_select_handle_middle_material.xml
similarity index 92%
rename from core/res/res/drawable/text_select_handle_middle_quantum.xml
rename to core/res/res/drawable/text_select_handle_middle_material.xml
index bff0b66..f0f4b3e 100644
--- a/core/res/res/drawable/text_select_handle_middle_quantum.xml
+++ b/core/res/res/drawable/text_select_handle_middle_material.xml
@@ -15,5 +15,5 @@
 -->
 
 <bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/text_select_handle_middle_qntm_alpha"
+    android:src="@drawable/text_select_handle_middle_mtrl_alpha"
     android:tint="?attr/colorControlActivated" />
diff --git a/core/res/res/drawable/text_select_handle_right_quantum.xml b/core/res/res/drawable/text_select_handle_right_material.xml
similarity index 92%
copy from core/res/res/drawable/text_select_handle_right_quantum.xml
copy to core/res/res/drawable/text_select_handle_right_material.xml
index 413661f..acacbf6 100644
--- a/core/res/res/drawable/text_select_handle_right_quantum.xml
+++ b/core/res/res/drawable/text_select_handle_right_material.xml
@@ -15,5 +15,5 @@
 -->
 
 <bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/text_select_handle_right_qntm_alpha"
+    android:src="@drawable/text_select_handle_right_mtrl_alpha"
     android:tint="?attr/colorControlActivated" />
diff --git a/core/res/res/drawable/textfield_search_quantum.xml b/core/res/res/drawable/textfield_search_material.xml
similarity index 94%
rename from core/res/res/drawable/textfield_search_quantum.xml
rename to core/res/res/drawable/textfield_search_material.xml
index 877de46..1c0f5eb 100644
--- a/core/res/res/drawable/textfield_search_quantum.xml
+++ b/core/res/res/drawable/textfield_search_material.xml
@@ -16,27 +16,27 @@
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_window_focused="false" android:state_enabled="true">
-        <nine-patch android:src="@drawable/textfield_search_default_qntm_alpha"
+        <nine-patch android:src="@drawable/textfield_search_default_mtrl_alpha"
             android:tint="?attr/colorControlNormal" />
     </item>
     <item android:state_window_focused="false" android:state_enabled="false">
-        <nine-patch android:src="@drawable/textfield_search_default_qntm_alpha"
+        <nine-patch android:src="@drawable/textfield_search_default_mtrl_alpha"
             android:tint="?attr/colorControlNormal" />
     </item>
     <item android:state_enabled="true" android:state_focused="true">
-        <nine-patch android:src="@drawable/textfield_search_activated_qntm_alpha"
+        <nine-patch android:src="@drawable/textfield_search_activated_mtrl_alpha"
             android:tint="?attr/colorControlActivated" />
     </item>
     <item android:state_enabled="true" android:state_activated="true">
-        <nine-patch android:src="@drawable/textfield_search_activated_qntm_alpha"
+        <nine-patch android:src="@drawable/textfield_search_activated_mtrl_alpha"
             android:tint="?attr/colorControlActivated" />
     </item>
     <item android:state_enabled="true">
-        <nine-patch android:src="@drawable/textfield_search_default_qntm_alpha"
+        <nine-patch android:src="@drawable/textfield_search_default_mtrl_alpha"
             android:tint="?attr/colorControlNormal" />
     </item>
     <item>
-        <nine-patch android:src="@drawable/textfield_search_default_qntm_alpha"
+        <nine-patch android:src="@drawable/textfield_search_default_mtrl_alpha"
             android:tint="?attr/colorControlNormal" />
     </item>
 </selector>
diff --git a/core/res/res/layout/action_bar_home_quantum.xml b/core/res/res/layout/action_bar_home_material.xml
similarity index 100%
rename from core/res/res/layout/action_bar_home_quantum.xml
rename to core/res/res/layout/action_bar_home_material.xml
diff --git a/core/res/res/layout/alert_dialog_quantum.xml b/core/res/res/layout/alert_dialog_material.xml
similarity index 98%
rename from core/res/res/layout/alert_dialog_quantum.xml
rename to core/res/res/layout/alert_dialog_material.xml
index 7fd22ad..57bdfc9 100644
--- a/core/res/res/layout/alert_dialog_quantum.xml
+++ b/core/res/res/layout/alert_dialog_material.xml
@@ -21,7 +21,7 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:orientation="vertical"
-    android:background="@drawable/dialog_background_quantum"
+    android:background="@drawable/dialog_background_material"
     android:translationZ="@dimen/floating_window_z"
     android:layout_marginLeft="@dimen/floating_window_margin_left"
     android:layout_marginTop="@dimen/floating_window_margin_top"
diff --git a/core/res/res/layout/alert_dialog_progress_quantum.xml b/core/res/res/layout/alert_dialog_progress_material.xml
similarity index 100%
rename from core/res/res/layout/alert_dialog_progress_quantum.xml
rename to core/res/res/layout/alert_dialog_progress_material.xml
diff --git a/core/res/res/layout/dialog_custom_title_quantum.xml b/core/res/res/layout/dialog_custom_title_material.xml
similarity index 100%
rename from core/res/res/layout/dialog_custom_title_quantum.xml
rename to core/res/res/layout/dialog_custom_title_material.xml
diff --git a/core/res/res/layout/dialog_title_icons_quantum.xml b/core/res/res/layout/dialog_title_icons_material.xml
similarity index 100%
rename from core/res/res/layout/dialog_title_icons_quantum.xml
rename to core/res/res/layout/dialog_title_icons_material.xml
diff --git a/core/res/res/layout/dialog_title_quantum.xml b/core/res/res/layout/dialog_title_material.xml
similarity index 100%
rename from core/res/res/layout/dialog_title_quantum.xml
rename to core/res/res/layout/dialog_title_material.xml
diff --git a/core/res/res/layout/notification_quantum_action.xml b/core/res/res/layout/notification_material_action.xml
similarity index 93%
rename from core/res/res/layout/notification_quantum_action.xml
rename to core/res/res/layout/notification_material_action.xml
index 0986343..7ccaad5 100644
--- a/core/res/res/layout/notification_quantum_action.xml
+++ b/core/res/res/layout/notification_material_action.xml
@@ -16,7 +16,7 @@
   -->
 
 <Button xmlns:android="http://schemas.android.com/apk/res/android"
-    style="@android:style/Widget.Quantum.Light.Button.Borderless.Small"
+    style="@android:style/Widget.Material.Light.Button.Borderless.Small"
     android:id="@+id/action0"
     android:layout_width="0dp"
     android:layout_height="48dp"
diff --git a/core/res/res/layout/notification_quantum_action_list.xml b/core/res/res/layout/notification_material_action_list.xml
similarity index 100%
rename from core/res/res/layout/notification_quantum_action_list.xml
rename to core/res/res/layout/notification_material_action_list.xml
diff --git a/core/res/res/layout/notification_quantum_action_tombstone.xml b/core/res/res/layout/notification_material_action_tombstone.xml
similarity index 93%
rename from core/res/res/layout/notification_quantum_action_tombstone.xml
rename to core/res/res/layout/notification_material_action_tombstone.xml
index 51e4205..8bf456e 100644
--- a/core/res/res/layout/notification_quantum_action_tombstone.xml
+++ b/core/res/res/layout/notification_material_action_tombstone.xml
@@ -16,7 +16,7 @@
   -->
 
 <Button xmlns:android="http://schemas.android.com/apk/res/android"
-    style="@android:style/Widget.Quantum.Light.Button.Borderless.Small"
+    style="@android:style/Widget.Material.Light.Button.Borderless.Small"
     android:id="@+id/action0"
     android:layout_width="0dp"
     android:layout_height="48dp"
diff --git a/core/res/res/layout/notification_quantum_media_action.xml b/core/res/res/layout/notification_material_media_action.xml
similarity index 92%
rename from core/res/res/layout/notification_quantum_media_action.xml
rename to core/res/res/layout/notification_material_media_action.xml
index 17f0848..331ee57 100644
--- a/core/res/res/layout/notification_quantum_media_action.xml
+++ b/core/res/res/layout/notification_material_media_action.xml
@@ -16,7 +16,7 @@
   -->
 
 <ImageButton xmlns:android="http://schemas.android.com/apk/res/android"
-    style="@android:style/Widget.Quantum.Light.Button.Borderless.Small"
+    style="@android:style/Widget.Material.Light.Button.Borderless.Small"
     android:id="@+id/action0"
     android:layout_width="60dp"
     android:layout_height="match_parent"
diff --git a/core/res/res/layout/notification_template_quantum_base.xml b/core/res/res/layout/notification_template_material_base.xml
similarity index 89%
rename from core/res/res/layout/notification_template_quantum_base.xml
rename to core/res/res/layout/notification_template_material_base.xml
index 789bf32..ab13b98 100644
--- a/core/res/res/layout/notification_template_quantum_base.xml
+++ b/core/res/res/layout/notification_template_material_base.xml
@@ -49,7 +49,7 @@
             android:orientation="horizontal"
             >
             <TextView android:id="@+id/title"
-                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent.Title"
+                android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent.Title"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:singleLine="true"
@@ -73,7 +73,7 @@
                 />
         </LinearLayout>
         <TextView android:id="@+id/text2"
-            android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent.Line2"
+            android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent.Line2"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_marginTop="-2dp"
@@ -90,7 +90,7 @@
             android:layout_height="12dp"
             android:layout_marginStart="8dp"
             android:visibility="gone"
-            style="@style/Widget.StatusBar.Quantum.ProgressBar"
+            style="@style/Widget.StatusBar.Material.ProgressBar"
             />
         <LinearLayout
             android:id="@+id/line3"
@@ -101,7 +101,7 @@
             android:layout_marginStart="8dp"
             >
             <TextView android:id="@+id/text"
-                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent"
+                android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent"
                 android:layout_width="0dp"
                 android:layout_height="wrap_content"
                 android:layout_weight="1"
@@ -111,7 +111,7 @@
                 android:fadingEdge="horizontal"
                 />
             <TextView android:id="@+id/info"
-                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent.Info"
+                android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent.Info"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_gravity="center"
@@ -120,6 +120,15 @@
                 android:gravity="center"
                 android:paddingStart="8dp"
                 />
+            <ImageView android:id="@+id/profile_icon"
+                android:layout_width="24dp"
+                android:layout_height="24dp"
+                android:layout_gravity="center"
+                android:layout_weight="0"
+                android:layout_marginStart="8dp"
+                android:scaleType="centerInside"
+                android:visibility="gone"
+                />
         </LinearLayout>
     </LinearLayout>
 </FrameLayout>
diff --git a/core/res/res/layout/notification_template_quantum_big_base.xml b/core/res/res/layout/notification_template_material_big_base.xml
similarity index 89%
rename from core/res/res/layout/notification_template_quantum_big_base.xml
rename to core/res/res/layout/notification_template_material_big_base.xml
index 8cb5549..bdf27c8 100644
--- a/core/res/res/layout/notification_template_quantum_big_base.xml
+++ b/core/res/res/layout/notification_template_material_big_base.xml
@@ -53,7 +53,7 @@
                 android:orientation="horizontal"
                 >
                 <TextView android:id="@+id/title"
-                    android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent.Title"
+                    android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent.Title"
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
                     android:singleLine="true"
@@ -77,7 +77,7 @@
                     />
             </LinearLayout>
             <TextView android:id="@+id/text2"
-                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent.Line2"
+                android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent.Line2"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:layout_marginTop="-2dp"
@@ -90,7 +90,7 @@
                 android:visibility="gone"
                 />
             <TextView android:id="@+id/big_text"
-                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent"
+                android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:layout_marginStart="8dp"
@@ -108,7 +108,7 @@
                 android:gravity="center_vertical"
                 >
                 <TextView android:id="@+id/text"
-                    android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent"
+                    android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent"
                     android:layout_width="0dp"
                     android:layout_height="wrap_content"
                     android:layout_weight="1"
@@ -118,7 +118,7 @@
                     android:fadingEdge="horizontal"
                     />
                 <TextView android:id="@+id/info"
-                    android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent.Info"
+                    android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent.Info"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:layout_gravity="center"
@@ -127,6 +127,15 @@
                     android:gravity="center"
                     android:paddingStart="8dp"
                     />
+                <ImageView android:id="@+id/profile_icon"
+                    android:layout_width="24dp"
+                    android:layout_height="24dp"
+                    android:layout_gravity="center"
+                    android:layout_weight="0"
+                    android:layout_marginStart="8dp"
+                    android:scaleType="centerInside"
+                    android:visibility="gone"
+                    />
             </LinearLayout>
             <ProgressBar
                 android:id="@android:id/progress"
@@ -136,7 +145,7 @@
                 android:layout_marginStart="8dp"
                 android:layout_marginEnd="8dp"
                 android:visibility="gone"
-                style="@style/Widget.Quantum.Light.ProgressBar.Horizontal"
+                style="@style/Widget.Material.Light.ProgressBar.Horizontal"
                 />
         </LinearLayout>
         <ImageView
@@ -146,7 +155,7 @@
             android:visibility="gone"
             android:background="@drawable/list_divider_holo_light" />
         <include
-            layout="@layout/notification_quantum_action_list"
+            layout="@layout/notification_material_action_list"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_marginStart="@dimen/notification_large_icon_width"
diff --git a/core/res/res/layout/notification_template_quantum_big_media.xml b/core/res/res/layout/notification_template_material_big_media.xml
similarity index 96%
rename from core/res/res/layout/notification_template_quantum_big_media.xml
rename to core/res/res/layout/notification_template_material_big_media.xml
index 5c9334e..c89b9f9 100644
--- a/core/res/res/layout/notification_template_quantum_big_media.xml
+++ b/core/res/res/layout/notification_template_material_big_media.xml
@@ -50,7 +50,7 @@
                 android:orientation="horizontal"
                 >
                 <TextView android:id="@+id/title"
-                    android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent.Title"
+                    android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent.Title"
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
                     android:singleLine="true"
@@ -74,7 +74,7 @@
                     />
             </LinearLayout>
             <TextView android:id="@+id/text2"
-                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent.Line2"
+                android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent.Line2"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:layout_marginTop="-2dp"
@@ -87,7 +87,7 @@
                 android:visibility="gone"
                 />
             <TextView android:id="@+id/big_text"
-                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent"
+                android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:layout_marginStart="8dp"
@@ -105,7 +105,7 @@
                 android:gravity="center_vertical"
                 >
                 <TextView android:id="@+id/text"
-                    android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent"
+                    android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent"
                     android:layout_width="0dp"
                     android:layout_height="wrap_content"
                     android:layout_weight="1"
@@ -115,7 +115,7 @@
                     android:fadingEdge="horizontal"
                     />
                 <TextView android:id="@+id/info"
-                    android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent.Info"
+                    android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent.Info"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:layout_gravity="center"
@@ -147,7 +147,7 @@
                 android:layout_height="6dp"
                 android:layout_gravity="top"
                 android:visibility="gone"
-                style="@style/Widget.StatusBar.Quantum.ProgressBar"
+                style="@style/Widget.StatusBar.Material.ProgressBar"
                 />
         </FrameLayout>
     </LinearLayout>
diff --git a/core/res/res/layout/notification_template_quantum_big_picture.xml b/core/res/res/layout/notification_template_material_big_picture.xml
similarity index 94%
rename from core/res/res/layout/notification_template_quantum_big_picture.xml
rename to core/res/res/layout/notification_template_material_big_picture.xml
index f68e414..74819fd 100644
--- a/core/res/res/layout/notification_template_quantum_big_picture.xml
+++ b/core/res/res/layout/notification_template_material_big_picture.xml
@@ -38,7 +38,7 @@
         android:scaleType="fitXY"
         android:src="@drawable/title_bar_shadow"
         />
-    <include layout="@layout/notification_template_quantum_base"
+    <include layout="@layout/notification_template_material_base"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         />
@@ -51,7 +51,7 @@
         android:background="#CCEEEEEE"
         >
         <include
-            layout="@layout/notification_quantum_action_list"
+            layout="@layout/notification_material_action_list"
             android:id="@+id/actions"
             android:layout_gravity="bottom"
             android:layout_width="match_parent"
diff --git a/core/res/res/layout/notification_template_quantum_big_text.xml b/core/res/res/layout/notification_template_material_big_text.xml
similarity index 90%
rename from core/res/res/layout/notification_template_quantum_big_text.xml
rename to core/res/res/layout/notification_template_material_big_text.xml
index bbd1071..6f8c3a9 100644
--- a/core/res/res/layout/notification_template_quantum_big_text.xml
+++ b/core/res/res/layout/notification_template_material_big_text.xml
@@ -55,7 +55,7 @@
                 android:layout_weight="0"
                 >
                 <TextView android:id="@+id/title"
-                    android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent.Title"
+                    android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent.Title"
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
                     android:singleLine="true"
@@ -79,7 +79,7 @@
                     />
             </LinearLayout>
             <TextView android:id="@+id/text2"
-                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent.Line2"
+                android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent.Line2"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:layout_marginTop="-2dp"
@@ -99,10 +99,10 @@
                 android:layout_marginEnd="8dp"
                 android:visibility="gone"
                 android:layout_weight="0"
-                style="@style/Widget.Quantum.Light.ProgressBar.Horizontal"
+                style="@style/Widget.Material.Light.ProgressBar.Horizontal"
                 />
             <TextView android:id="@+id/big_text"
-                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent"
+                android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent"
                 android:layout_width="match_parent"
                 android:layout_height="0dp"
                 android:layout_marginBottom="10dp"
@@ -121,7 +121,7 @@
             android:visibility="gone"
             android:background="@drawable/list_divider_holo_light" />
         <include
-            layout="@layout/notification_quantum_action_list"
+            layout="@layout/notification_material_action_list"
             android:layout_width="match_parent"
             android:layout_height="0dp"
             android:visibility="gone"
@@ -146,7 +146,7 @@
             android:gravity="center_vertical"
             >
             <TextView android:id="@+id/text"
-                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent"
+                android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent"
                 android:layout_width="0dp"
                 android:layout_height="wrap_content"
                 android:layout_weight="1"
@@ -156,7 +156,7 @@
                 android:fadingEdge="horizontal"
                 />
             <TextView android:id="@+id/info"
-                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent.Info"
+                android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent.Info"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_gravity="center"
@@ -165,6 +165,15 @@
                 android:gravity="center"
                 android:paddingStart="8dp"
                 />
+            <ImageView android:id="@+id/profile_icon"
+                android:layout_width="24dp"
+                android:layout_height="24dp"
+                android:layout_gravity="center"
+                android:layout_weight="0"
+                android:layout_marginStart="8dp"
+                android:scaleType="centerInside"
+                android:visibility="gone"
+                />
         </LinearLayout>
     </LinearLayout>
 </FrameLayout>
diff --git a/core/res/res/layout/notification_template_quantum_inbox.xml b/core/res/res/layout/notification_template_material_inbox.xml
similarity index 91%
rename from core/res/res/layout/notification_template_quantum_inbox.xml
rename to core/res/res/layout/notification_template_material_inbox.xml
index a071d59..8411ff5 100644
--- a/core/res/res/layout/notification_template_quantum_inbox.xml
+++ b/core/res/res/layout/notification_template_material_inbox.xml
@@ -56,7 +56,7 @@
                 android:layout_weight="0"
                 >
                 <TextView android:id="@+id/title"
-                    android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent.Title"
+                    android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent.Title"
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
                     android:singleLine="true"
@@ -80,7 +80,7 @@
                     />
             </LinearLayout>
             <TextView android:id="@+id/text2"
-                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent.Line2"
+                android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent.Line2"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:layout_marginTop="-2dp"
@@ -101,10 +101,10 @@
                 android:layout_marginEnd="8dp"
                 android:visibility="gone"
                 android:layout_weight="0"
-                style="@style/Widget.Quantum.Light.ProgressBar.Horizontal"
+                style="@style/Widget.Material.Light.ProgressBar.Horizontal"
                 />
             <TextView android:id="@+id/inbox_text0"
-                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent"
+                android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent"
                 android:layout_width="match_parent"
                 android:layout_height="0dp"
                 android:layout_marginStart="8dp"
@@ -115,7 +115,7 @@
                 android:layout_weight="1"
                 />
             <TextView android:id="@+id/inbox_text1"
-                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent"
+                android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent"
                 android:layout_width="match_parent"
                 android:layout_height="0dp"
                 android:layout_marginStart="8dp"
@@ -126,7 +126,7 @@
                 android:layout_weight="1"
                 />
             <TextView android:id="@+id/inbox_text2"
-                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent"
+                android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent"
                 android:layout_width="match_parent"
                 android:layout_height="0dp"
                 android:layout_marginStart="8dp"
@@ -137,7 +137,7 @@
                 android:layout_weight="1"
                 />
             <TextView android:id="@+id/inbox_text3"
-                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent"
+                android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent"
                 android:layout_width="match_parent"
                 android:layout_height="0dp"
                 android:layout_marginStart="8dp"
@@ -148,7 +148,7 @@
                 android:layout_weight="1"
                 />
             <TextView android:id="@+id/inbox_text4"
-                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent"
+                android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent"
                 android:layout_width="match_parent"
                 android:layout_height="0dp"
                 android:layout_marginStart="8dp"
@@ -158,7 +158,7 @@
                 android:layout_weight="1"
                 />
             <TextView android:id="@+id/inbox_text5"
-                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent"
+                android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent"
                 android:layout_width="match_parent"
                 android:layout_height="0dp"
                 android:layout_marginStart="8dp"
@@ -169,7 +169,7 @@
                 android:layout_weight="1"
                 />
             <TextView android:id="@+id/inbox_text6"
-                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent"
+                android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent"
                 android:layout_width="match_parent"
                 android:layout_height="0dp"
                 android:layout_marginStart="8dp"
@@ -180,7 +180,7 @@
                 android:layout_weight="1"
                 />
             <TextView android:id="@+id/inbox_more"
-                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent"
+                android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent"
                 android:layout_width="match_parent"
                 android:layout_height="0dp"
                 android:layout_marginStart="8dp"
@@ -206,7 +206,7 @@
             android:visibility="gone"
             android:background="@drawable/list_divider_holo_light" />
         <include
-            layout="@layout/notification_quantum_action_list"
+            layout="@layout/notification_material_action_list"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_weight="0"
@@ -230,7 +230,7 @@
             android:gravity="center_vertical"
             >
             <TextView android:id="@+id/text"
-                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent"
+                android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent"
                 android:layout_width="0dp"
                 android:layout_height="wrap_content"
                 android:layout_weight="1"
@@ -240,7 +240,7 @@
                 android:fadingEdge="horizontal"
                 />
             <TextView android:id="@+id/info"
-                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent.Info"
+                android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent.Info"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_gravity="center"
@@ -249,6 +249,15 @@
                 android:gravity="center"
                 android:paddingStart="8dp"
                 />
+            <ImageView android:id="@+id/profile_icon"
+                android:layout_width="24dp"
+                android:layout_height="24dp"
+                android:layout_gravity="center"
+                android:layout_weight="0"
+                android:layout_marginStart="8dp"
+                android:scaleType="centerInside"
+                android:visibility="gone"
+                />
         </LinearLayout>
     </LinearLayout>
 </FrameLayout>
diff --git a/core/res/res/layout/notification_template_quantum_media.xml b/core/res/res/layout/notification_template_material_media.xml
similarity index 96%
rename from core/res/res/layout/notification_template_quantum_media.xml
rename to core/res/res/layout/notification_template_material_media.xml
index 14fabce..c2fc006 100644
--- a/core/res/res/layout/notification_template_quantum_media.xml
+++ b/core/res/res/layout/notification_template_material_media.xml
@@ -50,7 +50,7 @@
             android:orientation="horizontal"
             >
             <TextView android:id="@+id/title"
-                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent.Title"
+                android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent.Title"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:singleLine="true"
@@ -74,7 +74,7 @@
                 />
         </LinearLayout>
         <TextView android:id="@+id/text2"
-            android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent.Line2"
+            android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent.Line2"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_marginTop="-2dp"
@@ -91,7 +91,7 @@
             android:layout_height="12dp"
             android:layout_marginStart="8dp"
             android:visibility="gone"
-            style="@style/Widget.StatusBar.Quantum.ProgressBar"
+            style="@style/Widget.StatusBar.Material.ProgressBar"
             />
         <LinearLayout
             android:id="@+id/line3"
@@ -102,7 +102,7 @@
             android:layout_marginStart="8dp"
             >
             <TextView android:id="@+id/text"
-                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent"
+                android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent"
                 android:layout_width="0dp"
                 android:layout_height="wrap_content"
                 android:layout_weight="1"
@@ -112,7 +112,7 @@
                 android:fadingEdge="horizontal"
                 />
             <TextView android:id="@+id/info"
-                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent.Info"
+                android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent.Info"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_gravity="center"
diff --git a/core/res/res/layout/notification_template_part_chronometer.xml b/core/res/res/layout/notification_template_part_chronometer.xml
index 9b6e6c5..87dfe1f 100644
--- a/core/res/res/layout/notification_template_part_chronometer.xml
+++ b/core/res/res/layout/notification_template_part_chronometer.xml
@@ -15,7 +15,7 @@
 -->
 
 <Chronometer android:id="@+id/chronometer" xmlns:android="http://schemas.android.com/apk/res/android"
-    android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent.Time"
+    android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent.Time"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:layout_gravity="center"
diff --git a/core/res/res/layout/notification_template_part_time.xml b/core/res/res/layout/notification_template_part_time.xml
index b559dce..5982c48 100644
--- a/core/res/res/layout/notification_template_part_time.xml
+++ b/core/res/res/layout/notification_template_part_time.xml
@@ -15,7 +15,7 @@
 -->
 
 <DateTimeView android:id="@+id/time" xmlns:android="http://schemas.android.com/apk/res/android"
-    android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent.Time"
+    android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent.Time"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:layout_gravity="center"
diff --git a/core/res/res/layout/preference_category_quantum.xml b/core/res/res/layout/preference_category_material.xml
similarity index 87%
rename from core/res/res/layout/preference_category_quantum.xml
rename to core/res/res/layout/preference_category_material.xml
index 032e09d..456b252 100644
--- a/core/res/res/layout/preference_category_quantum.xml
+++ b/core/res/res/layout/preference_category_material.xml
@@ -20,9 +20,8 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:layout_marginBottom="16dip"
-    android:textAppearance="@style/TextAppearance.Quantum.Body2"
-    android:textColor="?android:attr/textColorSecondary"
-    android:textStyle="bold"
+    android:textAppearance="@style/TextAppearance.Material.Body2"
+    android:textColor="?android:attr/colorAccent"
     android:paddingStart="?attr/listPreferredItemPaddingStart"
     android:paddingEnd="?attr/listPreferredItemPaddingEnd"
     android:paddingTop="16dip" />
diff --git a/core/res/res/layout/preference_child_quantum.xml b/core/res/res/layout/preference_child_material.xml
similarity index 100%
rename from core/res/res/layout/preference_child_quantum.xml
rename to core/res/res/layout/preference_child_material.xml
diff --git a/core/res/res/layout/preference_information_quantum.xml b/core/res/res/layout/preference_information_material.xml
similarity index 100%
rename from core/res/res/layout/preference_information_quantum.xml
rename to core/res/res/layout/preference_information_material.xml
diff --git a/core/res/res/layout/preference_quantum.xml b/core/res/res/layout/preference_material.xml
similarity index 100%
rename from core/res/res/layout/preference_quantum.xml
rename to core/res/res/layout/preference_material.xml
diff --git a/core/res/res/layout/progress_dialog_quantum.xml b/core/res/res/layout/progress_dialog_material.xml
similarity index 100%
rename from core/res/res/layout/progress_dialog_quantum.xml
rename to core/res/res/layout/progress_dialog_material.xml
diff --git a/core/res/res/layout/select_dialog_item_quantum.xml b/core/res/res/layout/select_dialog_item_material.xml
similarity index 100%
rename from core/res/res/layout/select_dialog_item_quantum.xml
rename to core/res/res/layout/select_dialog_item_material.xml
diff --git a/core/res/res/layout/select_dialog_quantum.xml b/core/res/res/layout/select_dialog_material.xml
similarity index 100%
rename from core/res/res/layout/select_dialog_quantum.xml
rename to core/res/res/layout/select_dialog_material.xml
diff --git a/core/res/res/layout/select_dialog_multichoice_quantum.xml b/core/res/res/layout/select_dialog_multichoice_material.xml
similarity index 100%
rename from core/res/res/layout/select_dialog_multichoice_quantum.xml
rename to core/res/res/layout/select_dialog_multichoice_material.xml
diff --git a/core/res/res/layout/select_dialog_singlechoice_quantum.xml b/core/res/res/layout/select_dialog_singlechoice_material.xml
similarity index 100%
rename from core/res/res/layout/select_dialog_singlechoice_quantum.xml
rename to core/res/res/layout/select_dialog_singlechoice_material.xml
diff --git a/core/res/res/layout/status_bar_latest_event_content.xml b/core/res/res/layout/status_bar_latest_event_content.xml
index dc78174..9444164 100644
--- a/core/res/res/layout/status_bar_latest_event_content.xml
+++ b/core/res/res/layout/status_bar_latest_event_content.xml
@@ -22,7 +22,7 @@
     android:layout_height="wrap_content"
     android:background="#FFFF00FF"
     >
-    <include layout="@layout/notification_template_quantum_base"
+    <include layout="@layout/notification_template_material_base"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         />
diff --git a/core/res/res/layout/tab_indicator_quantum.xml b/core/res/res/layout/tab_indicator_material.xml
similarity index 92%
rename from core/res/res/layout/tab_indicator_quantum.xml
rename to core/res/res/layout/tab_indicator_material.xml
index fcb2d5f..7dba219 100644
--- a/core/res/res/layout/tab_indicator_quantum.xml
+++ b/core/res/res/layout/tab_indicator_material.xml
@@ -18,7 +18,7 @@
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_height="?android:attr/actionBarSize"
     android:orientation="horizontal"
-    style="@android:style/Widget.Quantum.Tab">
+    style="@android:style/Widget.Material.Tab">
 
     <ImageView
         android:id="@android:id/icon"
@@ -32,6 +32,6 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_gravity="center_vertical"
-        style="@android:style/Widget.Quantum.TabText" />
+        style="@android:style/Widget.Material.TabText" />
 
 </LinearLayout>
diff --git a/core/res/res/drawable/ic_find_next_quantum.xml b/core/res/res/transition/fade.xml
similarity index 79%
copy from core/res/res/drawable/ic_find_next_quantum.xml
copy to core/res/res/transition/fade.xml
index fee196c..22397d4 100644
--- a/core/res/res/drawable/ic_find_next_quantum.xml
+++ b/core/res/res/transition/fade.xml
@@ -13,7 +13,4 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_find_next_qntm_alpha"
-    android:tint="?attr/colorControlNormal" />
+<fade xmlns:android="http://schemas.android.com/apk/res/android"/>
diff --git a/core/res/res/transition/move.xml b/core/res/res/transition/move.xml
new file mode 100644
index 0000000..d4863ee
--- /dev/null
+++ b/core/res/res/transition/move.xml
@@ -0,0 +1,30 @@
+<?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.
+-->
+<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
+    <transitionSet>
+        <changeBounds/>
+        <changeTransform/>
+        <changeClipBounds/>
+        <targets>
+            <target android:excludeClass="android.widget.ImageView"/>
+        </targets>
+    </transitionSet>
+    <moveImage>
+        <targets>
+            <target android:targetClass="android.widget.ImageView"/>
+        </targets>
+    </moveImage>
+</transitionSet>
diff --git a/core/res/res/values-land/dimens_quantum.xml b/core/res/res/values-land/dimens_material.xml
similarity index 85%
rename from core/res/res/values-land/dimens_quantum.xml
rename to core/res/res/values-land/dimens_material.xml
index 7789219..c8c95d7b 100644
--- a/core/res/res/values-land/dimens_quantum.xml
+++ b/core/res/res/values-land/dimens_material.xml
@@ -16,8 +16,8 @@
 <resources>
 
     <!-- Default height of an action bar. -->
-    <dimen name="action_bar_default_height_quantum">48dp</dimen>
+    <dimen name="action_bar_default_height_material">48dp</dimen>
     <!-- Default padding of an action bar. -->
-    <dimen name="action_bar_default_padding_quantum">0dp</dimen>
+    <dimen name="action_bar_default_padding_material">0dp</dimen>
 
 </resources>
diff --git a/core/res/res/values-television/themes.xml b/core/res/res/values-television/themes.xml
index 6e17cdd3..f92ff40 100644
--- a/core/res/res/values-television/themes.xml
+++ b/core/res/res/values-television/themes.xml
@@ -18,6 +18,6 @@
     <style name="Theme.Dialog.AppError" parent="Theme.Leanback.Dialog.AppError" />
     <style name="Theme.Holo.Dialog.Alert" parent="Theme.Leanback.Dialog.Alert" />
     <style name="Theme.Holo.Light.Dialog.Alert" parent="Theme.Leanback.Light.Dialog.Alert" />
-    <style name="Theme.Quantum.Dialog.Alert" parent="Theme.Leanback.Dialog.Alert" />
-    <style name="Theme.Quantum.Light.Dialog.Alert" parent="Theme.Leanback.Light.Dialog.Alert" />
+    <style name="Theme.Material.Dialog.Alert" parent="Theme.Leanback.Dialog.Alert" />
+    <style name="Theme.Material.Light.Dialog.Alert" parent="Theme.Leanback.Light.Dialog.Alert" />
 </resources>
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index f01f10e..c3036d5 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -298,6 +298,189 @@
        <item>@drawable/quickcontact_badge_overlay_light</item>
        <item>@drawable/quickcontact_badge_overlay_normal_light</item>
        <item>@drawable/quickcontact_badge_overlay_pressed_light</item>
+
+       <!-- Material assets -->
+       <item>@drawable/ab_share_pack_mtrl_alpha</item>
+       <item>@drawable/ab_solid_shadow_mtrl_alpha</item>
+       <item>@drawable/btn_cab_done_mtrl_alpha</item>
+       <item>@drawable/btn_check_to_off_mtrl_000</item>
+       <item>@drawable/btn_check_to_off_mtrl_001</item>
+       <item>@drawable/btn_check_to_off_mtrl_002</item>
+       <item>@drawable/btn_check_to_off_mtrl_003</item>
+       <item>@drawable/btn_check_to_off_mtrl_004</item>
+       <item>@drawable/btn_check_to_off_mtrl_005</item>
+       <item>@drawable/btn_check_to_off_mtrl_006</item>
+       <item>@drawable/btn_check_to_off_mtrl_007</item>
+       <item>@drawable/btn_check_to_off_mtrl_008</item>
+       <item>@drawable/btn_check_to_off_mtrl_009</item>
+       <item>@drawable/btn_check_to_off_mtrl_010</item>
+       <item>@drawable/btn_check_to_off_mtrl_011</item>
+       <item>@drawable/btn_check_to_off_mtrl_012</item>
+       <item>@drawable/btn_check_to_off_mtrl_013</item>
+       <item>@drawable/btn_check_to_off_mtrl_014</item>
+       <item>@drawable/btn_check_to_off_mtrl_015</item>
+       <item>@drawable/btn_check_to_on_mtrl_000</item>
+       <item>@drawable/btn_check_to_on_mtrl_001</item>
+       <item>@drawable/btn_check_to_on_mtrl_002</item>
+       <item>@drawable/btn_check_to_on_mtrl_003</item>
+       <item>@drawable/btn_check_to_on_mtrl_004</item>
+       <item>@drawable/btn_check_to_on_mtrl_005</item>
+       <item>@drawable/btn_check_to_on_mtrl_006</item>
+       <item>@drawable/btn_check_to_on_mtrl_007</item>
+       <item>@drawable/btn_check_to_on_mtrl_008</item>
+       <item>@drawable/btn_check_to_on_mtrl_009</item>
+       <item>@drawable/btn_check_to_on_mtrl_010</item>
+       <item>@drawable/btn_check_to_on_mtrl_011</item>
+       <item>@drawable/btn_check_to_on_mtrl_012</item>
+       <item>@drawable/btn_check_to_on_mtrl_013</item>
+       <item>@drawable/btn_check_to_on_mtrl_014</item>
+       <item>@drawable/btn_check_to_on_mtrl_015</item>
+       <item>@drawable/btn_mtrl_alpha</item>
+       <item>@drawable/btn_radio_anim_00000_mtrl_alpha</item>
+       <item>@drawable/btn_radio_anim_00001_mtrl_alpha</item>
+       <item>@drawable/btn_radio_anim_00002_mtrl_alpha</item>
+       <item>@drawable/btn_radio_anim_00003_mtrl_alpha</item>
+       <item>@drawable/btn_radio_anim_00004_mtrl_alpha</item>
+       <item>@drawable/btn_radio_anim_00005_mtrl_alpha</item>
+       <item>@drawable/btn_radio_anim_00006_mtrl_alpha</item>
+       <item>@drawable/btn_radio_anim_00007_mtrl_alpha</item>
+       <item>@drawable/btn_radio_anim_00008_mtrl_alpha</item>
+       <item>@drawable/btn_radio_anim_00009_mtrl_alpha</item>
+       <item>@drawable/btn_radio_anim_00010_mtrl_alpha</item>
+       <item>@drawable/btn_radio_anim_00011_mtrl_alpha</item>
+       <item>@drawable/btn_radio_anim_00012_mtrl_alpha</item>
+       <item>@drawable/btn_radio_anim_00013_mtrl_alpha</item>
+       <item>@drawable/btn_radio_anim_00014_mtrl_alpha</item>
+       <item>@drawable/btn_radio_anim_00015_mtrl_alpha</item>
+       <item>@drawable/btn_radio_to_off_mtrl_000</item>
+       <item>@drawable/btn_radio_to_off_mtrl_001</item>
+       <item>@drawable/btn_radio_to_off_mtrl_002</item>
+       <item>@drawable/btn_radio_to_off_mtrl_003</item>
+       <item>@drawable/btn_radio_to_off_mtrl_004</item>
+       <item>@drawable/btn_radio_to_off_mtrl_005</item>
+       <item>@drawable/btn_radio_to_off_mtrl_006</item>
+       <item>@drawable/btn_radio_to_off_mtrl_007</item>
+       <item>@drawable/btn_radio_to_off_mtrl_008</item>
+       <item>@drawable/btn_radio_to_off_mtrl_009</item>
+       <item>@drawable/btn_radio_to_off_mtrl_010</item>
+       <item>@drawable/btn_radio_to_off_mtrl_011</item>
+       <item>@drawable/btn_radio_to_off_mtrl_012</item>
+       <item>@drawable/btn_radio_to_off_mtrl_013</item>
+       <item>@drawable/btn_radio_to_off_mtrl_014</item>
+       <item>@drawable/btn_radio_to_off_mtrl_015</item>
+       <item>@drawable/btn_radio_to_on_mtrl_000</item>
+       <item>@drawable/btn_radio_to_on_mtrl_001</item>
+       <item>@drawable/btn_radio_to_on_mtrl_002</item>
+       <item>@drawable/btn_radio_to_on_mtrl_003</item>
+       <item>@drawable/btn_radio_to_on_mtrl_004</item>
+       <item>@drawable/btn_radio_to_on_mtrl_005</item>
+       <item>@drawable/btn_radio_to_on_mtrl_006</item>
+       <item>@drawable/btn_radio_to_on_mtrl_007</item>
+       <item>@drawable/btn_radio_to_on_mtrl_008</item>
+       <item>@drawable/btn_radio_to_on_mtrl_009</item>
+       <item>@drawable/btn_radio_to_on_mtrl_010</item>
+       <item>@drawable/btn_radio_to_on_mtrl_011</item>
+       <item>@drawable/btn_radio_to_on_mtrl_012</item>
+       <item>@drawable/btn_radio_to_on_mtrl_013</item>
+       <item>@drawable/btn_radio_to_on_mtrl_014</item>
+       <item>@drawable/btn_radio_to_on_mtrl_015</item>
+       <item>@drawable/btn_rating_star_off_mtrl_alpha</item>
+       <item>@drawable/btn_rating_star_on_mtrl_alpha</item>
+       <item>@drawable/btn_star_mtrl_alpha</item>
+       <item>@drawable/btn_switch_to_off_mtrl_000</item>
+       <item>@drawable/btn_switch_to_off_mtrl_001</item>
+       <item>@drawable/btn_switch_to_off_mtrl_002</item>
+       <item>@drawable/btn_switch_to_off_mtrl_003</item>
+       <item>@drawable/btn_switch_to_off_mtrl_004</item>
+       <item>@drawable/btn_switch_to_off_mtrl_005</item>
+       <item>@drawable/btn_switch_to_off_mtrl_006</item>
+       <item>@drawable/btn_switch_to_off_mtrl_007</item>
+       <item>@drawable/btn_switch_to_off_mtrl_008</item>
+       <item>@drawable/btn_switch_to_off_mtrl_009</item>
+       <item>@drawable/btn_switch_to_off_mtrl_010</item>
+       <item>@drawable/btn_switch_to_off_mtrl_011</item>
+       <item>@drawable/btn_switch_to_off_mtrl_012</item>
+       <item>@drawable/btn_switch_to_off_mtrl_013</item>
+       <item>@drawable/btn_switch_to_off_mtrl_014</item>
+       <item>@drawable/btn_switch_to_on_mtrl_000</item>
+       <item>@drawable/btn_switch_to_on_mtrl_001</item>
+       <item>@drawable/btn_switch_to_on_mtrl_002</item>
+       <item>@drawable/btn_switch_to_on_mtrl_003</item>
+       <item>@drawable/btn_switch_to_on_mtrl_004</item>
+       <item>@drawable/btn_switch_to_on_mtrl_005</item>
+       <item>@drawable/btn_switch_to_on_mtrl_006</item>
+       <item>@drawable/btn_switch_to_on_mtrl_007</item>
+       <item>@drawable/btn_switch_to_on_mtrl_008</item>
+       <item>@drawable/btn_switch_to_on_mtrl_009</item>
+       <item>@drawable/btn_switch_to_on_mtrl_010</item>
+       <item>@drawable/btn_switch_to_on_mtrl_011</item>
+       <item>@drawable/btn_switch_to_on_mtrl_012</item>
+       <item>@drawable/btn_switch_to_on_mtrl_013</item>
+       <item>@drawable/btn_switch_to_on_mtrl_014</item>
+       <item>@drawable/btn_toggle_indicator_mtrl_alpha</item>
+       <item>@drawable/btn_toggle_mtrl_alpha</item>
+       <item>@drawable/expander_close_mtrl_alpha</item>
+       <item>@drawable/expander_open_mtrl_alpha</item>
+       <item>@drawable/fastscroll_thumb_mtrl_alpha</item>
+       <item>@drawable/fastscroll_track_mtrl_alpha</item>
+       <item>@drawable/ic_ab_back_mtrl_am_alpha</item>
+       <item>@drawable/ic_cab_done_mtrl_alpha</item>
+       <item>@drawable/ic_clear_mtrl_alpha</item>
+       <item>@drawable/ic_commit_search_api_mtrl_alpha</item>
+       <item>@drawable/ic_dialog_alert_mtrl_alpha</item>
+       <item>@drawable/ic_find_next_mtrl_alpha</item>
+       <item>@drawable/ic_find_previous_mtrl_alpha</item>
+       <item>@drawable/ic_go_search_api_mtrl_alpha</item>
+       <item>@drawable/ic_media_route_disabled_mtrl_alpha</item>
+       <item>@drawable/ic_media_route_off_mtrl_alpha</item>
+       <item>@drawable/ic_media_route_on_0_mtrl_alpha</item>
+       <item>@drawable/ic_media_route_on_1_mtrl_alpha</item>
+       <item>@drawable/ic_media_route_on_2_mtrl_alpha</item>
+       <item>@drawable/ic_media_route_on_mtrl_alpha</item>
+       <item>@drawable/ic_menu_copy_mtrl_am_alpha</item>
+       <item>@drawable/ic_menu_cut_mtrl_alpha</item>
+       <item>@drawable/ic_menu_find_mtrl_alpha</item>
+       <item>@drawable/ic_menu_moreoverflow_mtrl_alpha</item>
+       <item>@drawable/ic_menu_paste_mtrl_am_alpha</item>
+       <item>@drawable/ic_menu_search_mtrl_alpha</item>
+       <item>@drawable/ic_menu_selectall_mtrl_alpha</item>
+       <item>@drawable/ic_menu_share_mtrl_alpha</item>
+       <item>@drawable/ic_search_api_mtrl_alpha</item>
+       <item>@drawable/ic_voice_search_api_mtrl_alpha</item>
+       <item>@drawable/list_divider_mtrl_alpha</item>
+       <item>@drawable/list_section_divider_mtrl_alpha</item>
+       <item>@drawable/popup_background_mtrl_mult</item>
+       <item>@drawable/progress_primary_mtrl_alpha</item>
+       <item>@drawable/progress_mtrl_alpha</item>
+       <item>@drawable/scrollbar_handle_mtrl_alpha</item>
+       <item>@drawable/scrubber_control_from_pressed_mtrl_000</item>
+       <item>@drawable/scrubber_control_from_pressed_mtrl_001</item>
+       <item>@drawable/scrubber_control_from_pressed_mtrl_002</item>
+       <item>@drawable/scrubber_control_from_pressed_mtrl_003</item>
+       <item>@drawable/scrubber_control_from_pressed_mtrl_004</item>
+       <item>@drawable/scrubber_control_from_pressed_mtrl_005</item>
+       <item>@drawable/scrubber_control_off_pressed_mtrl_alpha</item>
+       <item>@drawable/scrubber_control_off_mtrl_alpha</item>
+       <item>@drawable/scrubber_control_on_pressed_mtrl_alpha</item>
+       <item>@drawable/scrubber_control_on_mtrl_alpha</item>
+       <item>@drawable/scrubber_control_to_pressed_mtrl_000</item>
+       <item>@drawable/scrubber_control_to_pressed_mtrl_001</item>
+       <item>@drawable/scrubber_control_to_pressed_mtrl_002</item>
+       <item>@drawable/scrubber_control_to_pressed_mtrl_003</item>
+       <item>@drawable/scrubber_control_to_pressed_mtrl_004</item>
+       <item>@drawable/scrubber_control_to_pressed_mtrl_005</item>
+       <item>@drawable/scrubber_primary_mtrl_alpha</item>
+       <item>@drawable/scrubber_track_mtrl_alpha</item>
+       <item>@drawable/spinner_mtrl_am_alpha</item>
+       <item>@drawable/switch_track_mtrl_alpha</item>
+       <item>@drawable/text_cursor_mtrl_alpha</item>
+       <item>@drawable/textfield_activated_mtrl_alpha</item>
+       <item>@drawable/textfield_default_mtrl_alpha</item>
+       <item>@drawable/textfield_search_activated_mtrl_alpha</item>
+       <item>@drawable/textfield_search_default_mtrl_alpha</item>
+       <item>@drawable/text_select_handle_left_mtrl_alpha</item>
+       <item>@drawable/text_select_handle_middle_mtrl_alpha</item>
+       <item>@drawable/text_select_handle_right_mtrl_alpha</item>
     </array>
 
     <!-- Do not translate. These are all of the color state list resources that should be
@@ -334,6 +517,18 @@
         <item>#ff000000</item>
         <item>#00000000</item>
         <item>#ffffffff</item>
+
+        <!-- Material color state lists -->
+       <item>@color/background_cache_hint_selector_material_dark</item>
+       <item>@color/background_cache_hint_selector_material_light</item>
+       <item>@color/btn_default_material_dark</item>
+       <item>@color/btn_default_material_light</item>
+       <item>@color/primary_text_disable_only_material_dark</item>
+       <item>@color/primary_text_disable_only_material_light</item>
+       <item>@color/primary_text_material_dark</item>
+       <item>@color/primary_text_material_light</item>
+       <item>@color/search_url_text_material_dark</item>
+       <item>@color/search_url_text_material_light</item>
     </array>
 
     <!-- Used in LocalePicker -->
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index b8086be..d063fb7 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -963,17 +963,15 @@
         <eat-comment />
 
         <!-- The primary branding color for the app. By default, this is the color applied to the
-             action bar background and framework controls (via colorControlActivated). -->
+             action bar background. -->
         <attr name="colorPrimary" format="color" />
 
         <!-- Dark variant of the primary branding color. By default, this is the color applied to
              the status bar (via statusBarColor) and navigation bar (via navigationBarColor). -->
         <attr name="colorPrimaryDark" format="color" />
 
-        <!-- Light variant of the primary branding color. TODO: Not used? -->
-        <attr name="colorPrimaryLight" format="color" />
-
-        <!-- Bright complement to the primary branding color. TODO: Not used? -->
+        <!-- Bright complement to the primary branding color. By default, this is the color applied
+             to framework controls (via colorControlActivated). -->
         <attr name="colorAccent" format="color" />
 
         <!-- The color applied to framework controls in their normal state. -->
@@ -982,7 +980,7 @@
         <!-- The color applied to framework controls in their activated (ex. checked) state. -->
         <attr name="colorControlActivated" format="color" />
 
-        <!-- The color applied to framework control highlights (ex. ripples, selection). -->
+        <!-- The color applied to framework control highlights (ex. ripples, list selectors). -->
         <attr name="colorControlHighlight" format="color" />
 
         <!-- The color applied to framework buttons in their normal state. -->
@@ -4564,6 +4562,16 @@
         <attr name="drawable" />
     </declare-styleable>
 
+    <!-- Drawable used to render the Material progress indicator. -->
+    <declare-styleable name="MaterialProgressDrawable">
+        <attr name="visible" />
+        <attr name="thickness" />
+        <attr name="innerRadius" />
+        <attr name="width" />
+        <attr name="height" />
+        <attr name="color" />
+    </declare-styleable>
+
     <declare-styleable name="InsetDrawable">
         <attr name="visible" />
         <attr name="drawable" />
@@ -6361,6 +6369,12 @@
         <attr name="aspect" format="string" />
         <!-- Color to use when drawing LockPatternView paths. -->
         <attr name="pathColor" format="color|reference" />
+        <!-- The regular pattern color -->
+        <attr name="regularColor" format="color|reference" />
+        <!-- The error color -->
+        <attr name="errorColor" format="color|reference" />
+        <!-- The success color -->
+        <attr name="successColor" format="color|reference"/>
     </declare-styleable>
 
     <!-- Use <code>recognition-service</code> as the root tag of the XML resource that
@@ -6719,7 +6733,7 @@
 
     <!-- Used as a filter array on the theme to pull out only the EdgeEffect-relevant bits. -->
     <declare-styleable name="EdgeEffect">
-        <attr name="colorPrimaryLight" />
+        <attr name="colorPrimary" />
     </declare-styleable>
 
     <!-- Use <code>tv-input</code> as the root tag of the XML resource that describes an
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index 5a2609e..9bf2ce8 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -115,6 +115,11 @@
     <color name="kg_multi_user_text_inactive">#ff808080</color>
     <color name="kg_widget_pager_gradient">#ffffffff</color>
 
+    <!-- LockPatternView -->
+    <color name="lock_pattern_view_regular_color">#ffffffff</color>
+    <color name="lock_pattern_view_success_color">#ffffffff</color>
+    <color name="lock_pattern_view_error_color">#fff4511e</color>
+
     <!-- FaceLock -->
     <color name="facelock_spotlight_mask">#CC000000</color>
 
diff --git a/core/res/res/values/colors_holo.xml b/core/res/res/values/colors_holo.xml
index d1f4e38..97b4803 100644
--- a/core/res/res/values/colors_holo.xml
+++ b/core/res/res/values/colors_holo.xml
@@ -75,7 +75,7 @@
     <!-- A really bright Holo shade of gray -->
     <color name="holo_gray_bright">#33CCCCCC</color>
 
-    <!-- Forward compatibility for Quantum-style theme colors -->
+    <!-- Forward compatibility for Material-style theme colors -->
     <eat-comment />
 
     <color name="holo_primary_dark">#ff000000</color>
diff --git a/core/res/res/values/colors_legacy.xml b/core/res/res/values/colors_legacy.xml
index 48d4b42..ad22845 100644
--- a/core/res/res/values/colors_legacy.xml
+++ b/core/res/res/values/colors_legacy.xml
@@ -24,7 +24,7 @@
     <color name="legacy_selected_highlight">#fff17a0a</color>
     <color name="legacy_long_pressed_highlight">#ffffffff</color>
 
-    <!-- Forward compatibility for Quantum-style theme colors -->
+    <!-- Forward compatibility for Material-style theme colors -->
     <eat-comment />
 
     <color name="legacy_primary_dark">#ff000000</color>
diff --git a/core/res/res/values/colors_material.xml b/core/res/res/values/colors_material.xml
new file mode 100644
index 0000000..fdbe0a0
--- /dev/null
+++ b/core/res/res/values/colors_material.xml
@@ -0,0 +1,163 @@
+<?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.
+-->
+
+<!-- Colors specific to Material themes. -->
+<resources>
+    <color name="background_material_dark">#ff212121</color>
+    <color name="background_material_light">#fffafafa</color>
+
+    <color name="ripple_material_light">#20444444</color>
+    <color name="ripple_material_dark">#20ffffff</color>
+
+    <color name="button_material_dark">#ff5a595b</color>
+    <color name="button_material_light">#ffd6d7d7</color>
+
+    <color name="bright_foreground_material_dark">@color/white</color>
+    <color name="bright_foreground_material_light">@color/black</color>
+    <!-- Black 50% -->
+    <color name="bright_foreground_disabled_material_dark">#80000000</color>
+    <!-- White 50% -->
+    <color name="bright_foreground_disabled_material_light">#80ffffff</color>
+    <color name="bright_foreground_inverse_material_dark">@color/bright_foreground_material_light</color>
+    <color name="bright_foreground_inverse_material_light">@color/bright_foreground_material_dark</color>
+
+    <color name="dim_foreground_material_dark">#ffbebebe</color>
+    <color name="dim_foreground_material_light">#ff323232</color>
+    <color name="dim_foreground_disabled_material_dark">#80bebebe</color>
+    <color name="dim_foreground_disabled_material_light">#80323232</color>
+
+    <color name="hint_foreground_material_dark">@color/bright_foreground_disabled_material_dark</color>
+    <color name="hint_foreground_material_light">@color/bright_foreground_disabled_material_light</color>
+    <!-- TODO: This is 40% alpha on the default accent color. -->
+    <color name="highlighted_text_material_dark">#6640c4ff</color>
+    <!-- TODO: This is 40% alpha on the default accent color. -->
+    <color name="highlighted_text_material_light">#6640c4ff</color>
+
+    <!-- Text & foreground colors -->
+    <eat-comment />
+
+    <!-- Black 87% -->
+    <color name="primary_text_default_material_light">#de000000</color>
+    <!-- Black 54% -->
+    <color name="secondary_text_material_light">#8a000000</color>
+    <!-- Black 54% (TODO: same as secondary?) -->
+    <color name="tertiary_text_material_light">#8a000000</color>
+
+    <!-- White 87% -->
+    <color name="primary_text_default_material_dark">#deffffff</color>
+    <!-- White 38% -->
+    <color name="secondary_text_material_dark">#61ffffff</color>
+    <!-- White 38% (TODO: same as secondary?) -->
+    <color name="tertiary_text_material_dark">#61ffffff</color>
+
+    <!-- Primary & accent colors -->
+    <eat-comment />
+
+    <color name="material_red_100">#fff4c7c3</color>
+    <color name="material_red_300">#ffe67c73</color>
+    <color name="material_red_500">#ffdb4437</color>
+    <color name="material_red_700">#ffc53929</color>
+    <color name="material_red_A200">#ffff5252</color>
+    <color name="material_red_A400">#ffff1744</color>
+
+    <color name="material_blue_100">#ffc6dafc</color>
+    <color name="material_blue_300">#ff7baaf7</color>
+    <color name="material_blue_500">#ff4285f4</color>
+    <color name="material_blue_700">#ff3367d6</color>
+    <color name="material_blue_A200">#ff448aff</color>
+    <color name="material_blue_A400">#ff2979ff</color>
+
+    <color name="material_light_blue_A200">#ff40c4ff</color>
+
+    <color name="material_teal_100">#ffb2ebf2</color>
+    <color name="material_teal_300">#ff4dd0e1</color>
+    <color name="material_teal_500">#ff00bcd4</color>
+    <color name="material_teal_700">#ff0097a7</color>
+    <color name="material_teal_A200">#ff18ffff</color>
+    <color name="material_teal_A400">#ff00e5ff</color>
+
+    <color name="material_green_100">#ffb7e1cd</color>
+    <color name="material_green_300">#ff57bb8a</color>
+    <color name="material_green_500">#ff0f9d58</color>
+    <color name="material_green_700">#ff0b8043</color>
+    <color name="material_green_A200">#ff69f0ae</color>
+    <color name="material_green_A400">#ff00e676</color>
+
+    <color name="material_lime_100">#fff0f4c3</color>
+    <color name="material_lime_300">#ffdce775</color>
+    <color name="material_lime_500">#ffcddc39</color>
+    <color name="material_lime_700">#ffafb42b</color>
+    <color name="material_lime_A200">#ffeeff41</color>
+    <color name="material_lime_A400">#ffc6ff00</color>
+
+    <color name="material_yellow_100">#fffce8b2</color>
+    <color name="material_yellow_300">#fff7cb4d</color>
+    <color name="material_yellow_500">#fff4b400</color>
+    <color name="material_yellow_700">#fff09300</color>
+    <color name="material_yellow_A200">#ffffcd40</color>
+    <color name="material_yellow_A400">#ffffbc00</color>
+
+    <color name="material_orange_100">#ffffe0b2</color>
+    <color name="material_orange_300">#ffffb74d</color>
+    <color name="material_orange_500">#ffff9800</color>
+    <color name="material_orange_700">#fff57c00</color>
+    <color name="material_orange_A200">#ffffab40</color>
+    <color name="material_orange_A400">#ffff9100</color>
+
+    <color name="material_deep_orange_100">#fff4c7c3</color>
+    <color name="material_deep_orange_300">#ffe67c73</color>
+    <color name="material_deep_orange_500">#ffff5722</color>
+    <color name="material_deep_orange_700">#ffc53929</color>
+    <color name="material_deep_orange_A200">#ffff5252</color>
+    <color name="material_deep_orange_A400">#ffff1744</color>
+
+    <!-- Neutral colors -->
+    <eat-comment />
+
+    <color name="material_grey_50">#fffafafa</color>
+    <color name="material_grey_100">#fff5f5f5</color>
+    <color name="material_grey_300">#ffeeeeee</color>
+    <color name="material_grey_500">#ffa3a3a3</color>
+    <color name="material_grey_600">#ff757575</color>
+    <color name="material_grey_700">#ff717171</color>
+    <color name="material_grey_900">#ff212121</color>
+
+    <color name="material_blue_grey_50">#ffeceff1</color>
+    <color name="material_blue_grey_100">#ffcfd8dc</color>
+    <color name="material_blue_grey_300">#ff90a4ae</color>
+    <color name="material_blue_grey_400">#ff78909c</color>
+    <color name="material_blue_grey_500">#ff607d8b</color>
+    <color name="material_blue_grey_600">#ff546e7a</color>
+    <color name="material_blue_grey_700">#ff455a64</color>
+    <color name="material_blue_grey_800">#ff37474f</color>
+    <color name="material_blue_grey_900">#ff263238</color>
+
+    <color name="material_brown_100">#ffd7ccc8</color>
+    <color name="material_brown_300">#ffa1887f</color>
+    <color name="material_brown_500">#ff795548</color>
+    <color name="material_brown_700">#ff5d4037</color>
+
+    <!-- Time picker defaults when no theme is set -->
+    <eat-comment />
+
+    <color name="timepicker_default_background_material">@color/primary_text_default_material_light</color>
+    <color name="timepicker_default_text_color_material">@color/black</color>
+    <color name="timepicker_default_disabled_color_material">@color/bright_foreground_disabled_material_dark</color>
+    <color name="timepicker_default_ampm_selected_background_color_material">@color/material_light_blue_A200</color>
+    <color name="timepicker_default_ampm_unselected_background_color_material">@color/transparent</color>
+    <color name="timepicker_default_selector_color_material">@color/material_light_blue_A200</color>
+    <color name="timepicker_default_numbers_background_color_material">@color/transparent</color>
+</resources>
diff --git a/core/res/res/values/colors_quantum.xml b/core/res/res/values/colors_quantum.xml
deleted file mode 100644
index 976930c0..0000000
--- a/core/res/res/values/colors_quantum.xml
+++ /dev/null
@@ -1,138 +0,0 @@
-<?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.
--->
-
-<!-- Colors specific to Quantum themes. -->
-<resources>
-    <color name="background_quantum_dark">#ff414042</color>
-    <color name="background_quantum_light">#fff1f2f2</color>
-
-    <color name="ripple_quantum_dark">#30ffffff</color>
-    <color name="ripple_quantum_light">#30000000</color>
-
-    <color name="button_quantum_dark">#ff5a595b</color>
-    <color name="button_quantum_light">#ffd6d7d7</color>
-
-    <color name="bright_foreground_quantum_dark">@color/white</color>
-    <color name="bright_foreground_quantum_light">@color/black</color>
-    <!-- TODO: This is 50% alpha black -->
-    <color name="bright_foreground_disabled_quantum_dark">#80000000</color>
-    <!-- TODO: This is 50% alpha white -->
-    <color name="bright_foreground_disabled_quantum_light">#80ffffff</color>
-    <color name="bright_foreground_inverse_quantum_dark">@color/bright_foreground_quantum_light</color>
-    <color name="bright_foreground_inverse_quantum_light">@color/bright_foreground_quantum_dark</color>
-
-    <color name="dim_foreground_quantum_dark">#ffbebebe</color>
-    <color name="dim_foreground_quantum_light">#ff323232</color>
-    <color name="dim_foreground_disabled_quantum_dark">#80bebebe</color>
-    <color name="dim_foreground_disabled_quantum_light">#80323232</color>
-
-    <color name="hint_foreground_quantum_dark">@color/bright_foreground_disabled_quantum_dark</color>
-    <color name="hint_foreground_quantum_light">@color/bright_foreground_disabled_quantum_light</color>
-    <!-- TODO: This is 40% alpha teal_A200 -->
-    <color name="highlighted_text_quantum_dark">#660097a7</color>
-    <!-- TODO: This is 40% alpha teal_A200 -->
-    <color name="highlighted_text_quantum_light">#660097a7</color>
-
-    <!-- Primary & accent colors -->
-    <eat-comment />
-
-    <color name="quantum_red_100">#fff4c7c3</color>
-    <color name="quantum_red_300">#ffe67c73</color>
-    <color name="quantum_red_500">#ffdb4437</color>
-    <color name="quantum_red_700">#ffc53929</color>
-    <color name="quantum_red_A200">#ffff5252</color>
-    <color name="quantum_red_A400">#ffff1744</color>
-
-    <color name="quantum_blue_100">#ffc6dafc</color>
-    <color name="quantum_blue_300">#ff7baaf7</color>
-    <color name="quantum_blue_500">#ff4285f4</color>
-    <color name="quantum_blue_700">#ff3367d6</color>
-    <color name="quantum_blue_A200">#ff448aff</color>
-    <color name="quantum_blue_A400">#ff2979ff</color>
-
-    <color name="quantum_teal_100">#ffb2ebf2</color>
-    <color name="quantum_teal_300">#ff4dd0e1</color>
-    <color name="quantum_teal_500">#ff00bcd4</color>
-    <color name="quantum_teal_700">#ff0097a7</color>
-    <color name="quantum_teal_A200">#ff18ffff</color>
-    <color name="quantum_teal_A400">#ff00e5ff</color>
-
-    <color name="quantum_green_100">#ffb7e1cd</color>
-    <color name="quantum_green_300">#ff57bb8a</color>
-    <color name="quantum_green_500">#ff0f9d58</color>
-    <color name="quantum_green_700">#ff0b8043</color>
-    <color name="quantum_green_A200">#ff69f0ae</color>
-    <color name="quantum_green_A400">#ff00e676</color>
-
-    <color name="quantum_lime_100">#fff0f4c3</color>
-    <color name="quantum_lime_300">#ffdce775</color>
-    <color name="quantum_lime_500">#ffcddc39</color>
-    <color name="quantum_lime_700">#ffafb42b</color>
-    <color name="quantum_lime_A200">#ffeeff41</color>
-    <color name="quantum_lime_A400">#ffc6ff00</color>
-
-    <color name="quantum_yellow_100">#fffce8b2</color>
-    <color name="quantum_yellow_300">#fff7cb4d</color>
-    <color name="quantum_yellow_500">#fff4b400</color>
-    <color name="quantum_yellow_700">#fff09300</color>
-    <color name="quantum_yellow_A200">#ffffcd40</color>
-    <color name="quantum_yellow_A400">#ffffbc00</color>
-
-    <color name="quantum_orange_100">#ffffe0b2</color>
-    <color name="quantum_orange_300">#ffffb74d</color>
-    <color name="quantum_orange_500">#ffff9800</color>
-    <color name="quantum_orange_700">#fff57c00</color>
-    <color name="quantum_orange_A200">#ffffab40</color>
-    <color name="quantum_orange_A400">#ffff9100</color>
-
-    <color name="quantum_deep_orange_100">#fff4c7c3</color>
-    <color name="quantum_deep_orange_300">#ffe67c73</color>
-    <color name="quantum_deep_orange_500">#ffff5722</color>
-    <color name="quantum_deep_orange_700">#ffc53929</color>
-    <color name="quantum_deep_orange_A200">#ffff5252</color>
-    <color name="quantum_deep_orange_A400">#ffff1744</color>
-
-    <!-- Neutral colors -->
-    <eat-comment />
-
-    <color name="quantum_grey_50">#fffafafa</color>
-    <color name="quantum_grey_100">#fff5f5f5</color>
-    <color name="quantum_grey_300">#ffeeeeee</color>
-    <color name="quantum_grey_500">#ffa3a3a3</color>
-    <color name="quantum_grey_700">#ff717171</color>
-
-    <color name="quantum_blue_grey_50">#ffeceff1</color>
-    <color name="quantum_blue_grey_100">#ffcfd8dc</color>
-    <color name="quantum_blue_grey_300">#ff90a4ae</color>
-    <color name="quantum_blue_grey_500">#ff607d8b</color>
-    <color name="quantum_blue_grey_700">#ff455a64</color>
-
-    <color name="quantum_brown_100">#ffd7ccc8</color>
-    <color name="quantum_brown_300">#ffa1887f</color>
-    <color name="quantum_brown_500">#ff795548</color>
-    <color name="quantum_brown_700">#ff5d4037</color>
-
-    <!-- Text & foreground colors -->
-    <eat-comment />
-
-    <color name="primary_text_default_quantum_light">#de000000</color>
-    <color name="secondary_text_quantum_light">#8a000000</color>
-    <color name="tertiary_text_quantum_light">#4d000000</color>
-
-    <color name="primary_text_default_quantum_dark">#deffffff</color>
-    <color name="secondary_text_quantum_dark">#8affffff</color>
-    <color name="tertiary_text_quantum_dark">#4dffffff</color>
-</resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index f6732d3..5555cf6 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -364,6 +364,9 @@
     <!-- If this is true, the screen will come on when you unplug usb/power/whatever. -->
     <bool name="config_unplugTurnsOnScreen">false</bool>
 
+    <!-- Set this true only if the device has separate attention and notification lights. -->
+    <bool name="config_useAttentionLight">false</bool>
+
     <!-- If this is true, the screen will fade off. -->
     <bool name="config_animateScreenLights">true</bool>
 
@@ -858,6 +861,14 @@
     <!-- Boolean indicating if current platform supports BLE peripheral mode -->
     <bool name="config_bluetooth_le_peripheral_mode_supported">false</bool>
 
+    <!-- Max number of scan filters supported by blutooth controller. 0 if the
+         device does not support hardware scan filters-->
+    <integer translatable="false" name="config_bluetooth_max_scan_filters">0</integer>
+
+    <!-- Max number of advertisers supported by bluetooth controller. 0 if the
+         device does not support multiple advertisement-->
+    <integer translatable="false" name="config_bluetooth_max_advertisers">0</integer>
+
     <!-- The default data-use polling period. -->
     <integer name="config_datause_polling_period_sec">600</integer>
 
@@ -1434,6 +1445,10 @@
     <string name="config_customAdbPublicKeyConfirmationComponent"
             >com.android.systemui/com.android.systemui.usb.UsbDebuggingActivity</string>
 
+    <!-- Name of the CustomDialog that is used for VPN -->
+    <string name="config_customVpnConfirmDialogComponent"
+            >com.android.vpndialogs/com.android.vpndialogs.CustomDialog</string>
+
     <!-- Apps that are authorized to access shared accounts, overridden by product overlays -->
     <string name="config_appsAuthorizedForSharedAccounts">;com.android.settings;</string>
 
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 657f614..e94b9dd 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -365,7 +365,7 @@
     <!-- width of ImmersiveModeConfirmation (-1 for match_parent) -->
     <dimen name="immersive_mode_cling_width">-1px</dimen>
 
-    <!-- radius of the corners of the quantum rounded rect background -->
-    <dimen name="notification_quantum_rounded_rect_radius">2dp</dimen>
+    <!-- radius of the corners of the material rounded rect background -->
+    <dimen name="notification_material_rounded_rect_radius">2dp</dimen>
 
 </resources>
diff --git a/core/res/res/values/dimens_material.xml b/core/res/res/values/dimens_material.xml
new file mode 100644
index 0000000..be7e6c1
--- /dev/null
+++ b/core/res/res/values/dimens_material.xml
@@ -0,0 +1,58 @@
+<?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.
+-->
+<resources>
+
+    <!-- Default height of an action bar. -->
+    <dimen name="action_bar_default_height_material">56dp</dimen>
+    <!-- Default padding of an action bar. -->
+    <dimen name="action_bar_default_padding_material">4dp</dimen>
+    <!-- Vertical padding around action bar icons. -->
+    <dimen name="action_bar_icon_vertical_padding_material">16dp</dimen>
+    <!-- Top margin for action bar subtitles -->
+    <dimen name="action_bar_subtitle_top_margin_material">-3dp</dimen>
+    <!-- Bottom margin for action bar subtitles -->
+    <dimen name="action_bar_subtitle_bottom_margin_material">5dp</dimen>
+
+    <dimen name="action_button_min_width_material">48dp</dimen>
+    <dimen name="action_button_min_height_material">48dp</dimen>
+    <dimen name="action_overflow_min_width_material">36dp</dimen>
+
+    <dimen name="text_size_display_4_material">112sp</dimen>
+    <dimen name="text_size_display_3_material">56sp</dimen>
+    <dimen name="text_size_display_2_material">45sp</dimen>
+    <dimen name="text_size_display_1_material">34sp</dimen>
+    <dimen name="text_size_headline_material">24sp</dimen>
+    <dimen name="text_size_title_material">20sp</dimen>
+    <dimen name="text_size_subhead_material">16sp</dimen>
+    <dimen name="text_size_body_2_material">14sp</dimen>
+    <dimen name="text_size_body_1_material">14sp</dimen>
+    <dimen name="text_size_caption_material">12sp</dimen>
+    <dimen name="text_size_menu_material">14sp</dimen>
+    <dimen name="text_size_button_material">14sp</dimen>
+
+    <dimen name="text_size_large_material">22sp</dimen>
+    <dimen name="text_size_medium_material">18sp</dimen>
+    <dimen name="text_size_small_material">14sp</dimen>
+
+    <dimen name="floating_window_z">16dp</dimen>
+    <dimen name="floating_window_margin_left">16dp</dimen>
+    <dimen name="floating_window_margin_top">8dp</dimen>
+    <dimen name="floating_window_margin_right">16dp</dimen>
+    <dimen name="floating_window_margin_bottom">32dp</dimen>
+
+    <!-- Amount of elevation for pressed button state -->
+    <dimen name="button_pressed_z">2dp</dimen>
+</resources>
diff --git a/core/res/res/values/dimens_quantum.xml b/core/res/res/values/dimens_quantum.xml
deleted file mode 100644
index b5ba1ca..0000000
--- a/core/res/res/values/dimens_quantum.xml
+++ /dev/null
@@ -1,62 +0,0 @@
-<?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.
--->
-<resources>
-
-    <!-- Default height of an action bar. -->
-    <dimen name="action_bar_default_height_quantum">56dp</dimen>
-    <!-- Default padding of an action bar. -->
-    <dimen name="action_bar_default_padding_quantum">4dp</dimen>
-    <!-- Vertical padding around action bar icons. -->
-    <dimen name="action_bar_icon_vertical_padding_quantum">16dp</dimen>
-    <!-- Text size for action bar titles -->
-    <dimen name="action_bar_title_text_size_quantum">20sp</dimen>
-    <!-- Text size for action bar subtitles -->
-    <dimen name="action_bar_subtitle_text_size_quantum">16sp</dimen>
-    <!-- Top margin for action bar subtitles -->
-    <dimen name="action_bar_subtitle_top_margin_quantum">-3dp</dimen>
-    <!-- Bottom margin for action bar subtitles -->
-    <dimen name="action_bar_subtitle_bottom_margin_quantum">5dp</dimen>
-
-    <dimen name="action_button_min_width_quantum">48dp</dimen>
-    <dimen name="action_button_min_height_quantum">48dp</dimen>
-    <dimen name="action_overflow_min_width_quantum">36dp</dimen>
-
-    <dimen name="text_size_display_4_quantum">112sp</dimen>
-    <dimen name="text_size_display_3_quantum">56sp</dimen>
-    <dimen name="text_size_display_2_quantum">45sp</dimen>
-    <dimen name="text_size_display_1_quantum">34sp</dimen>
-    <dimen name="text_size_headline_quantum">24sp</dimen>
-    <dimen name="text_size_title_quantum">20sp</dimen>
-    <dimen name="text_size_subhead_quantum">16sp</dimen>
-    <dimen name="text_size_body_2_quantum">14sp</dimen>
-    <dimen name="text_size_body_1_quantum">14sp</dimen>
-    <dimen name="text_size_caption_quantum">12sp</dimen>
-    <dimen name="text_size_menu_quantum">14sp</dimen>
-    <dimen name="text_size_button_quantum">14sp</dimen>
-
-    <dimen name="text_size_large_quantum">22sp</dimen>
-    <dimen name="text_size_medium_quantum">18sp</dimen>
-    <dimen name="text_size_small_quantum">14sp</dimen>
-
-    <dimen name="floating_window_z">16dp</dimen>
-    <dimen name="floating_window_margin_left">16dp</dimen>
-    <dimen name="floating_window_margin_top">8dp</dimen>
-    <dimen name="floating_window_margin_right">16dp</dimen>
-    <dimen name="floating_window_margin_bottom">32dp</dimen>
-
-    <!-- the amount of elevation for pressed button state-->
-    <dimen name="button_pressed_z">2dp</dimen>
-</resources>
diff --git a/core/res/res/values/donottranslate_material.xml b/core/res/res/values/donottranslate_material.xml
new file mode 100644
index 0000000..9ed9553
--- /dev/null
+++ b/core/res/res/values/donottranslate_material.xml
@@ -0,0 +1,32 @@
+<?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.
+-->
+
+<resources>
+
+    <string name="font_family_display_4_material">sans-serif-light</string>
+    <string name="font_family_display_3_material">sans-serif</string>
+    <string name="font_family_display_2_material">sans-serif</string>
+    <string name="font_family_display_1_material">sans-serif</string>
+    <string name="font_family_headline_material">sans-serif</string>
+    <string name="font_family_title_material">sans-serif-medium</string>
+    <string name="font_family_subhead_material">sans-serif</string>
+    <string name="font_family_body_2_material">sans-serif-medium</string>
+    <string name="font_family_body_1_material">sans-serif</string>
+    <string name="font_family_caption_material">sans-serif</string>
+    <string name="font_family_menu_material">sans-serif-medium</string>
+    <string name="font_family_button_material">sans-serif-medium</string>
+
+</resources>
diff --git a/core/res/res/values/donottranslate_quantum.xml b/core/res/res/values/donottranslate_quantum.xml
deleted file mode 100644
index e53c40e..0000000
--- a/core/res/res/values/donottranslate_quantum.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?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.
--->
-
-<resources>
-
-    <string name="font_family_display_4_quantum">sans-serif-light</string>
-    <string name="font_family_display_3_quantum">sans-serif</string>
-    <string name="font_family_display_2_quantum">sans-serif</string>
-    <string name="font_family_display_1_quantum">sans-serif</string>
-    <string name="font_family_headline_quantum">sans-serif</string>
-    <string name="font_family_title_quantum">sans-serif-medium</string>
-    <string name="font_family_subhead_quantum">sans-serif</string>
-    <string name="font_family_body_2_quantum">sans-serif-medium</string>
-    <string name="font_family_body_1_quantum">sans-serif</string>
-    <string name="font_family_caption_quantum">sans-serif</string>
-    <string name="font_family_menu_quantum">sans-serif-medium</string>
-    <string name="font_family_button_quantum">sans-serif-medium</string>
-
-</resources>
diff --git a/core/res/res/values/ids.xml b/core/res/res/values/ids.xml
index c966a12..639091e 100644
--- a/core/res/res/values/ids.xml
+++ b/core/res/res/values/ids.xml
@@ -23,6 +23,7 @@
   <item type="id" name="empty" />
   <item type="id" name="hint" />
   <item type="id" name="icon" />
+  <item type="id" name="icon_badge" />
   <item type="id" name="icon1" />
   <item type="id" name="icon2" />
   <item type="id" name="input" />
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index f6ffd15..dd075d5 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2142,7 +2142,6 @@
   <public type="attr" name="slideEdge" />
   <public type="attr" name="actionBarTheme" />
   <public type="attr" name="textAppearanceListItemSecondary" />
-  <public type="attr" name="colorPrimaryLight" />
   <public type="attr" name="colorPrimary" />
   <public type="attr" name="colorPrimaryDark" />
   <public type="attr" name="colorAccent" />
@@ -2184,6 +2183,7 @@
   <public type="attr" name="translateX" />
   <public type="attr" name="translateY" />
   <public type="attr" name="selectableItemBackgroundBorderless" />
+  <public type="attr" name="elegantTextHeight" />
 
   <public-padding type="dimen" name="l_resource_pad" end="0x01050010" />
 
@@ -2209,214 +2209,215 @@
   <public type="style" name="Widget.DeviceDefault.Light.FastScroll" />
   <public type="style" name="Widget.DeviceDefault.Light.StackView" />
 
-  <public type="style" name="TextAppearance.Quantum" />
-  <public type="style" name="TextAppearance.Quantum.DialogWindowTitle" />
-  <public type="style" name="TextAppearance.Quantum.Inverse" />
-  <public type="style" name="TextAppearance.Quantum.Large" />
-  <public type="style" name="TextAppearance.Quantum.Large.Inverse" />
-  <public type="style" name="TextAppearance.Quantum.Medium" />
-  <public type="style" name="TextAppearance.Quantum.Medium.Inverse" />
-  <public type="style" name="TextAppearance.Quantum.SearchResult.Subtitle" />
-  <public type="style" name="TextAppearance.Quantum.SearchResult.Title" />
-  <public type="style" name="TextAppearance.Quantum.Small" />
-  <public type="style" name="TextAppearance.Quantum.Small.Inverse" />
-  <public type="style" name="TextAppearance.Quantum.WindowTitle" />
+  <public type="style" name="TextAppearance.Material" />
+  <public type="style" name="TextAppearance.Material.DialogWindowTitle" />
+  <public type="style" name="TextAppearance.Material.Inverse" />
+  <public type="style" name="TextAppearance.Material.Large" />
+  <public type="style" name="TextAppearance.Material.Large.Inverse" />
+  <public type="style" name="TextAppearance.Material.Medium" />
+  <public type="style" name="TextAppearance.Material.Medium.Inverse" />
+  <public type="style" name="TextAppearance.Material.SearchResult.Subtitle" />
+  <public type="style" name="TextAppearance.Material.SearchResult.Title" />
+  <public type="style" name="TextAppearance.Material.Small" />
+  <public type="style" name="TextAppearance.Material.Small.Inverse" />
+  <public type="style" name="TextAppearance.Material.WindowTitle" />
 
-  <public type="style" name="TextAppearance.Quantum.Widget" />
-  <public type="style" name="TextAppearance.Quantum.Widget.ActionBar.Menu" />
-  <public type="style" name="TextAppearance.Quantum.Widget.ActionBar.Subtitle" />
-  <public type="style" name="TextAppearance.Quantum.Widget.ActionBar.Subtitle.Inverse" />
-  <public type="style" name="TextAppearance.Quantum.Widget.ActionBar.Title" />
-  <public type="style" name="TextAppearance.Quantum.Widget.ActionBar.Title.Inverse" />
-  <public type="style" name="TextAppearance.Quantum.Widget.ActionMode.Subtitle" />
-  <public type="style" name="TextAppearance.Quantum.Widget.ActionMode.Subtitle.Inverse" />
-  <public type="style" name="TextAppearance.Quantum.Widget.ActionMode.Title" />
-  <public type="style" name="TextAppearance.Quantum.Widget.ActionMode.Title.Inverse" />
-  <public type="style" name="TextAppearance.Quantum.Widget.Button" />
-  <public type="style" name="TextAppearance.Quantum.Widget.DropDownHint" />
-  <public type="style" name="TextAppearance.Quantum.Widget.DropDownItem" />
-  <public type="style" name="TextAppearance.Quantum.Widget.EditText" />
-  <public type="style" name="TextAppearance.Quantum.Widget.IconMenu.Item" />
-  <public type="style" name="TextAppearance.Quantum.Widget.PopupMenu" />
-  <public type="style" name="TextAppearance.Quantum.Widget.PopupMenu.Large" />
-  <public type="style" name="TextAppearance.Quantum.Widget.PopupMenu.Small" />
-  <public type="style" name="TextAppearance.Quantum.Widget.TabWidget" />
-  <public type="style" name="TextAppearance.Quantum.Widget.TextView" />
-  <public type="style" name="TextAppearance.Quantum.Widget.TextView.PopupMenu" />
-  <public type="style" name="TextAppearance.Quantum.Widget.TextView.SpinnerItem" />
+  <public type="style" name="TextAppearance.Material.Widget" />
+  <public type="style" name="TextAppearance.Material.Widget.ActionBar.Menu" />
+  <public type="style" name="TextAppearance.Material.Widget.ActionBar.Subtitle" />
+  <public type="style" name="TextAppearance.Material.Widget.ActionBar.Subtitle.Inverse" />
+  <public type="style" name="TextAppearance.Material.Widget.ActionBar.Title" />
+  <public type="style" name="TextAppearance.Material.Widget.ActionBar.Title.Inverse" />
+  <public type="style" name="TextAppearance.Material.Widget.ActionMode.Subtitle" />
+  <public type="style" name="TextAppearance.Material.Widget.ActionMode.Subtitle.Inverse" />
+  <public type="style" name="TextAppearance.Material.Widget.ActionMode.Title" />
+  <public type="style" name="TextAppearance.Material.Widget.ActionMode.Title.Inverse" />
+  <public type="style" name="TextAppearance.Material.Widget.Button" />
+  <public type="style" name="TextAppearance.Material.Widget.DropDownHint" />
+  <public type="style" name="TextAppearance.Material.Widget.DropDownItem" />
+  <public type="style" name="TextAppearance.Material.Widget.EditText" />
+  <public type="style" name="TextAppearance.Material.Widget.IconMenu.Item" />
+  <public type="style" name="TextAppearance.Material.Widget.PopupMenu" />
+  <public type="style" name="TextAppearance.Material.Widget.PopupMenu.Large" />
+  <public type="style" name="TextAppearance.Material.Widget.PopupMenu.Small" />
+  <public type="style" name="TextAppearance.Material.Widget.TabWidget" />
+  <public type="style" name="TextAppearance.Material.Widget.TextView" />
+  <public type="style" name="TextAppearance.Material.Widget.TextView.PopupMenu" />
+  <public type="style" name="TextAppearance.Material.Widget.TextView.SpinnerItem" />
 
-  <public type="style" name="Theme.Quantum" />
-  <public type="style" name="Theme.Quantum.Dialog" />
-  <public type="style" name="Theme.Quantum.Dialog.MinWidth" />
-  <public type="style" name="Theme.Quantum.Dialog.NoActionBar" />
-  <public type="style" name="Theme.Quantum.Dialog.NoActionBar.MinWidth" />
-  <public type="style" name="Theme.Quantum.DialogWhenLarge" />
-  <public type="style" name="Theme.Quantum.DialogWhenLarge.NoActionBar" />
-  <public type="style" name="Theme.Quantum.InputMethod" />
-  <public type="style" name="Theme.Quantum.NoActionBar" />
-  <public type="style" name="Theme.Quantum.NoActionBar.Fullscreen" />
-  <public type="style" name="Theme.Quantum.NoActionBar.Overscan" />
-  <public type="style" name="Theme.Quantum.NoActionBar.TranslucentDecor" />
-  <public type="style" name="Theme.Quantum.Panel" />
-  <public type="style" name="Theme.Quantum.Voice" />
-  <public type="style" name="Theme.Quantum.Wallpaper" />
-  <public type="style" name="Theme.Quantum.Wallpaper.NoTitleBar" />
+  <public type="style" name="Theme.Material" />
+  <public type="style" name="Theme.Material.Dialog" />
+  <public type="style" name="Theme.Material.Dialog.MinWidth" />
+  <public type="style" name="Theme.Material.Dialog.NoActionBar" />
+  <public type="style" name="Theme.Material.Dialog.NoActionBar.MinWidth" />
+  <public type="style" name="Theme.Material.DialogWhenLarge" />
+  <public type="style" name="Theme.Material.DialogWhenLarge.NoActionBar" />
+  <public type="style" name="Theme.Material.InputMethod" />
+  <public type="style" name="Theme.Material.NoActionBar" />
+  <public type="style" name="Theme.Material.NoActionBar.Fullscreen" />
+  <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.Voice" />
+  <public type="style" name="Theme.Material.Wallpaper" />
+  <public type="style" name="Theme.Material.Wallpaper.NoTitleBar" />
 
-  <public type="style" name="Theme.Quantum.Light" />
-  <public type="style" name="Theme.Quantum.Light.DarkActionBar" />
-  <public type="style" name="Theme.Quantum.Light.Dialog" />
-  <public type="style" name="Theme.Quantum.Light.Dialog.MinWidth" />
-  <public type="style" name="Theme.Quantum.Light.Dialog.NoActionBar" />
-  <public type="style" name="Theme.Quantum.Light.Dialog.NoActionBar.MinWidth" />
-  <public type="style" name="Theme.Quantum.Light.DialogWhenLarge" />
-  <public type="style" name="Theme.Quantum.Light.DialogWhenLarge.NoActionBar" />
-  <public type="style" name="Theme.Quantum.Light.NoActionBar" />
-  <public type="style" name="Theme.Quantum.Light.NoActionBar.Fullscreen" />
-  <public type="style" name="Theme.Quantum.Light.NoActionBar.Overscan" />
-  <public type="style" name="Theme.Quantum.Light.NoActionBar.TranslucentDecor" />
-  <public type="style" name="Theme.Quantum.Light.Panel" />
-  <public type="style" name="Theme.Quantum.Light.Voice" />
+  <public type="style" name="Theme.Material.Light" />
+  <public type="style" name="Theme.Material.Light.DarkActionBar" />
+  <public type="style" name="Theme.Material.Light.Dialog" />
+  <public type="style" name="Theme.Material.Light.Dialog.MinWidth" />
+  <public type="style" name="Theme.Material.Light.Dialog.NoActionBar" />
+  <public type="style" name="Theme.Material.Light.Dialog.NoActionBar.MinWidth" />
+  <public type="style" name="Theme.Material.Light.DialogWhenLarge" />
+  <public type="style" name="Theme.Material.Light.DialogWhenLarge.NoActionBar" />
+  <public type="style" name="Theme.Material.Light.NoActionBar" />
+  <public type="style" name="Theme.Material.Light.NoActionBar.Fullscreen" />
+  <public type="style" name="Theme.Material.Light.NoActionBar.Overscan" />
+  <public type="style" name="Theme.Material.Light.NoActionBar.TranslucentDecor" />
+  <public type="style" name="Theme.Material.Light.Panel" />
+  <public type="style" name="Theme.Material.Light.Voice" />
 
   <public type="style" name="ThemeOverlay" />
-  <public type="style" name="ThemeOverlay.Quantum" />
-  <public type="style" name="ThemeOverlay.Quantum.Light" />
-  <public type="style" name="ThemeOverlay.Quantum.Dark" />
-  <public type="style" name="ThemeOverlay.Quantum.ActionBarWidget" />
+  <public type="style" name="ThemeOverlay.Material" />
+  <public type="style" name="ThemeOverlay.Material.ActionBar" />
+  <public type="style" name="ThemeOverlay.Material.Light" />
+  <public type="style" name="ThemeOverlay.Material.Dark" />
+  <public type="style" name="ThemeOverlay.Material.Dark.ActionBar" />
 
-  <public type="style" name="Widget.Quantum" />
-  <public type="style" name="Widget.Quantum.ActionBar" />
-  <public type="style" name="Widget.Quantum.ActionBar.Solid" />
-  <public type="style" name="Widget.Quantum.ActionBar.TabBar" />
-  <public type="style" name="Widget.Quantum.ActionBar.TabText" />
-  <public type="style" name="Widget.Quantum.ActionBar.TabView" />
-  <public type="style" name="Widget.Quantum.ActionButton" />
-  <public type="style" name="Widget.Quantum.ActionButton.CloseMode" />
-  <public type="style" name="Widget.Quantum.ActionButton.Overflow" />
-  <public type="style" name="Widget.Quantum.ActionMode" />
-  <public type="style" name="Widget.Quantum.AutoCompleteTextView" />
-  <public type="style" name="Widget.Quantum.Button" />
-  <public type="style" name="Widget.Quantum.Button.Borderless" />
-  <public type="style" name="Widget.Quantum.Button.Borderless.Small" />
-  <public type="style" name="Widget.Quantum.Button.Inset" />
-  <public type="style" name="Widget.Quantum.Button.Small" />
-  <public type="style" name="Widget.Quantum.Button.Toggle" />
-  <public type="style" name="Widget.Quantum.ButtonBar" />
-  <public type="style" name="Widget.Quantum.ButtonBar.AlertDialog" />
-  <public type="style" name="Widget.Quantum.CalendarView" />
-  <public type="style" name="Widget.Quantum.CheckedTextView" />
-  <public type="style" name="Widget.Quantum.CompoundButton.CheckBox" />
-  <public type="style" name="Widget.Quantum.CompoundButton.RadioButton" />
-  <public type="style" name="Widget.Quantum.CompoundButton.Star" />
-  <public type="style" name="Widget.Quantum.DatePicker" />
-  <public type="style" name="Widget.Quantum.DropDownItem" />
-  <public type="style" name="Widget.Quantum.DropDownItem.Spinner" />
-  <public type="style" name="Widget.Quantum.EditText" />
-  <public type="style" name="Widget.Quantum.ExpandableListView" />
-  <public type="style" name="Widget.Quantum.FastScroll" />
-  <public type="style" name="Widget.Quantum.GridView" />
-  <public type="style" name="Widget.Quantum.HorizontalScrollView" />
-  <public type="style" name="Widget.Quantum.ImageButton" />
-  <public type="style" name="Widget.Quantum.ListPopupWindow" />
-  <public type="style" name="Widget.Quantum.ListView" />
-  <public type="style" name="Widget.Quantum.ListView.DropDown" />
-  <public type="style" name="Widget.Quantum.MediaRouteButton" />
-  <public type="style" name="Widget.Quantum.PopupMenu" />
-  <public type="style" name="Widget.Quantum.PopupMenu.Overflow" />
-  <public type="style" name="Widget.Quantum.PopupWindow" />
-  <public type="style" name="Widget.Quantum.ProgressBar" />
-  <public type="style" name="Widget.Quantum.ProgressBar.Horizontal" />
-  <public type="style" name="Widget.Quantum.ProgressBar.Large" />
-  <public type="style" name="Widget.Quantum.ProgressBar.Small" />
-  <public type="style" name="Widget.Quantum.ProgressBar.Small.Title" />
-  <public type="style" name="Widget.Quantum.RatingBar" />
-  <public type="style" name="Widget.Quantum.RatingBar.Indicator" />
-  <public type="style" name="Widget.Quantum.RatingBar.Small" />
-  <public type="style" name="Widget.Quantum.ScrollView" />
-  <public type="style" name="Widget.Quantum.SeekBar" />
-  <public type="style" name="Widget.Quantum.SegmentedButton" />
-  <public type="style" name="Widget.Quantum.StackView" />
-  <public type="style" name="Widget.Quantum.Spinner" />
-  <public type="style" name="Widget.Quantum.Tab" />
-  <public type="style" name="Widget.Quantum.TabWidget" />
-  <public type="style" name="Widget.Quantum.TextView" />
-  <public type="style" name="Widget.Quantum.TextView.SpinnerItem" />
-  <public type="style" name="Widget.Quantum.WebTextView" />
-  <public type="style" name="Widget.Quantum.WebView" />
+  <public type="style" name="Widget.Material" />
+  <public type="style" name="Widget.Material.ActionBar" />
+  <public type="style" name="Widget.Material.ActionBar.Solid" />
+  <public type="style" name="Widget.Material.ActionBar.TabBar" />
+  <public type="style" name="Widget.Material.ActionBar.TabText" />
+  <public type="style" name="Widget.Material.ActionBar.TabView" />
+  <public type="style" name="Widget.Material.ActionButton" />
+  <public type="style" name="Widget.Material.ActionButton.CloseMode" />
+  <public type="style" name="Widget.Material.ActionButton.Overflow" />
+  <public type="style" name="Widget.Material.ActionMode" />
+  <public type="style" name="Widget.Material.AutoCompleteTextView" />
+  <public type="style" name="Widget.Material.Button" />
+  <public type="style" name="Widget.Material.Button.Borderless" />
+  <public type="style" name="Widget.Material.Button.Borderless.Small" />
+  <public type="style" name="Widget.Material.Button.Inset" />
+  <public type="style" name="Widget.Material.Button.Small" />
+  <public type="style" name="Widget.Material.Button.Toggle" />
+  <public type="style" name="Widget.Material.ButtonBar" />
+  <public type="style" name="Widget.Material.ButtonBar.AlertDialog" />
+  <public type="style" name="Widget.Material.CalendarView" />
+  <public type="style" name="Widget.Material.CheckedTextView" />
+  <public type="style" name="Widget.Material.CompoundButton.CheckBox" />
+  <public type="style" name="Widget.Material.CompoundButton.RadioButton" />
+  <public type="style" name="Widget.Material.CompoundButton.Star" />
+  <public type="style" name="Widget.Material.DatePicker" />
+  <public type="style" name="Widget.Material.DropDownItem" />
+  <public type="style" name="Widget.Material.DropDownItem.Spinner" />
+  <public type="style" name="Widget.Material.EditText" />
+  <public type="style" name="Widget.Material.ExpandableListView" />
+  <public type="style" name="Widget.Material.FastScroll" />
+  <public type="style" name="Widget.Material.GridView" />
+  <public type="style" name="Widget.Material.HorizontalScrollView" />
+  <public type="style" name="Widget.Material.ImageButton" />
+  <public type="style" name="Widget.Material.ListPopupWindow" />
+  <public type="style" name="Widget.Material.ListView" />
+  <public type="style" name="Widget.Material.ListView.DropDown" />
+  <public type="style" name="Widget.Material.MediaRouteButton" />
+  <public type="style" name="Widget.Material.PopupMenu" />
+  <public type="style" name="Widget.Material.PopupMenu.Overflow" />
+  <public type="style" name="Widget.Material.PopupWindow" />
+  <public type="style" name="Widget.Material.ProgressBar" />
+  <public type="style" name="Widget.Material.ProgressBar.Horizontal" />
+  <public type="style" name="Widget.Material.ProgressBar.Large" />
+  <public type="style" name="Widget.Material.ProgressBar.Small" />
+  <public type="style" name="Widget.Material.ProgressBar.Small.Title" />
+  <public type="style" name="Widget.Material.RatingBar" />
+  <public type="style" name="Widget.Material.RatingBar.Indicator" />
+  <public type="style" name="Widget.Material.RatingBar.Small" />
+  <public type="style" name="Widget.Material.ScrollView" />
+  <public type="style" name="Widget.Material.SeekBar" />
+  <public type="style" name="Widget.Material.SegmentedButton" />
+  <public type="style" name="Widget.Material.StackView" />
+  <public type="style" name="Widget.Material.Spinner" />
+  <public type="style" name="Widget.Material.Tab" />
+  <public type="style" name="Widget.Material.TabWidget" />
+  <public type="style" name="Widget.Material.TextView" />
+  <public type="style" name="Widget.Material.TextView.SpinnerItem" />
+  <public type="style" name="Widget.Material.WebTextView" />
+  <public type="style" name="Widget.Material.WebView" />
 
-  <public type="style" name="Widget.Quantum.Light" />
-  <public type="style" name="Widget.Quantum.Light.ActionBar" />
-  <public type="style" name="Widget.Quantum.Light.ActionBar.Solid" />
-  <public type="style" name="Widget.Quantum.Light.ActionBar.TabBar" />
-  <public type="style" name="Widget.Quantum.Light.ActionBar.TabText" />
-  <public type="style" name="Widget.Quantum.Light.ActionBar.TabView" />
-  <public type="style" name="Widget.Quantum.Light.ActionButton" />
-  <public type="style" name="Widget.Quantum.Light.ActionButton.CloseMode" />
-  <public type="style" name="Widget.Quantum.Light.ActionButton.Overflow" />
-  <public type="style" name="Widget.Quantum.Light.ActionMode" />
-  <public type="style" name="Widget.Quantum.Light.AutoCompleteTextView" />
-  <public type="style" name="Widget.Quantum.Light.Button" />
-  <public type="style" name="Widget.Quantum.Light.Button.Borderless" />
-  <public type="style" name="Widget.Quantum.Light.Button.Borderless.Small" />
-  <public type="style" name="Widget.Quantum.Light.Button.Inset" />
-  <public type="style" name="Widget.Quantum.Light.Button.Small" />
-  <public type="style" name="Widget.Quantum.Light.Button.Toggle" />
-  <public type="style" name="Widget.Quantum.Light.ButtonBar" />
-  <public type="style" name="Widget.Quantum.Light.ButtonBar.AlertDialog" />
-  <public type="style" name="Widget.Quantum.Light.CalendarView" />
-  <public type="style" name="Widget.Quantum.Light.CheckedTextView" />
-  <public type="style" name="Widget.Quantum.Light.CompoundButton.CheckBox" />
-  <public type="style" name="Widget.Quantum.Light.CompoundButton.RadioButton" />
-  <public type="style" name="Widget.Quantum.Light.CompoundButton.Star" />
-  <public type="style" name="Widget.Quantum.Light.DropDownItem" />
-  <public type="style" name="Widget.Quantum.Light.DropDownItem.Spinner" />
-  <public type="style" name="Widget.Quantum.Light.EditText" />
-  <public type="style" name="Widget.Quantum.Light.ExpandableListView" />
-  <public type="style" name="Widget.Quantum.Light.FastScroll" />
-  <public type="style" name="Widget.Quantum.Light.GridView" />
-  <public type="style" name="Widget.Quantum.Light.HorizontalScrollView" />
-  <public type="style" name="Widget.Quantum.Light.ImageButton" />
-  <public type="style" name="Widget.Quantum.Light.ListPopupWindow" />
-  <public type="style" name="Widget.Quantum.Light.ListView" />
-  <public type="style" name="Widget.Quantum.Light.ListView.DropDown" />
-  <public type="style" name="Widget.Quantum.Light.MediaRouteButton" />
-  <public type="style" name="Widget.Quantum.Light.PopupMenu" />
-  <public type="style" name="Widget.Quantum.Light.PopupMenu.Overflow" />
-  <public type="style" name="Widget.Quantum.Light.PopupWindow" />
-  <public type="style" name="Widget.Quantum.Light.ProgressBar" />
-  <public type="style" name="Widget.Quantum.Light.ProgressBar.Horizontal" />
-  <public type="style" name="Widget.Quantum.Light.ProgressBar.Inverse" />
-  <public type="style" name="Widget.Quantum.Light.ProgressBar.Large" />
-  <public type="style" name="Widget.Quantum.Light.ProgressBar.Large.Inverse" />
-  <public type="style" name="Widget.Quantum.Light.ProgressBar.Small" />
-  <public type="style" name="Widget.Quantum.Light.ProgressBar.Small.Inverse" />
-  <public type="style" name="Widget.Quantum.Light.ProgressBar.Small.Title" />
-  <public type="style" name="Widget.Quantum.Light.RatingBar" />
-  <public type="style" name="Widget.Quantum.Light.RatingBar.Indicator" />
-  <public type="style" name="Widget.Quantum.Light.RatingBar.Small" />
-  <public type="style" name="Widget.Quantum.Light.ScrollView" />
-  <public type="style" name="Widget.Quantum.Light.SeekBar" />
-  <public type="style" name="Widget.Quantum.Light.SegmentedButton" />
-  <public type="style" name="Widget.Quantum.Light.StackView" />
-  <public type="style" name="Widget.Quantum.Light.Spinner" />
-  <public type="style" name="Widget.Quantum.Light.Tab" />
-  <public type="style" name="Widget.Quantum.Light.TabWidget" />
-  <public type="style" name="Widget.Quantum.Light.TextView" />
-  <public type="style" name="Widget.Quantum.Light.TextView.SpinnerItem" />
-  <public type="style" name="Widget.Quantum.Light.WebTextView" />
-  <public type="style" name="Widget.Quantum.Light.WebView" />
+  <public type="style" name="Widget.Material.Light" />
+  <public type="style" name="Widget.Material.Light.ActionBar" />
+  <public type="style" name="Widget.Material.Light.ActionBar.Solid" />
+  <public type="style" name="Widget.Material.Light.ActionBar.TabBar" />
+  <public type="style" name="Widget.Material.Light.ActionBar.TabText" />
+  <public type="style" name="Widget.Material.Light.ActionBar.TabView" />
+  <public type="style" name="Widget.Material.Light.ActionButton" />
+  <public type="style" name="Widget.Material.Light.ActionButton.CloseMode" />
+  <public type="style" name="Widget.Material.Light.ActionButton.Overflow" />
+  <public type="style" name="Widget.Material.Light.ActionMode" />
+  <public type="style" name="Widget.Material.Light.AutoCompleteTextView" />
+  <public type="style" name="Widget.Material.Light.Button" />
+  <public type="style" name="Widget.Material.Light.Button.Borderless" />
+  <public type="style" name="Widget.Material.Light.Button.Borderless.Small" />
+  <public type="style" name="Widget.Material.Light.Button.Inset" />
+  <public type="style" name="Widget.Material.Light.Button.Small" />
+  <public type="style" name="Widget.Material.Light.Button.Toggle" />
+  <public type="style" name="Widget.Material.Light.ButtonBar" />
+  <public type="style" name="Widget.Material.Light.ButtonBar.AlertDialog" />
+  <public type="style" name="Widget.Material.Light.CalendarView" />
+  <public type="style" name="Widget.Material.Light.CheckedTextView" />
+  <public type="style" name="Widget.Material.Light.CompoundButton.CheckBox" />
+  <public type="style" name="Widget.Material.Light.CompoundButton.RadioButton" />
+  <public type="style" name="Widget.Material.Light.CompoundButton.Star" />
+  <public type="style" name="Widget.Material.Light.DropDownItem" />
+  <public type="style" name="Widget.Material.Light.DropDownItem.Spinner" />
+  <public type="style" name="Widget.Material.Light.EditText" />
+  <public type="style" name="Widget.Material.Light.ExpandableListView" />
+  <public type="style" name="Widget.Material.Light.FastScroll" />
+  <public type="style" name="Widget.Material.Light.GridView" />
+  <public type="style" name="Widget.Material.Light.HorizontalScrollView" />
+  <public type="style" name="Widget.Material.Light.ImageButton" />
+  <public type="style" name="Widget.Material.Light.ListPopupWindow" />
+  <public type="style" name="Widget.Material.Light.ListView" />
+  <public type="style" name="Widget.Material.Light.ListView.DropDown" />
+  <public type="style" name="Widget.Material.Light.MediaRouteButton" />
+  <public type="style" name="Widget.Material.Light.PopupMenu" />
+  <public type="style" name="Widget.Material.Light.PopupMenu.Overflow" />
+  <public type="style" name="Widget.Material.Light.PopupWindow" />
+  <public type="style" name="Widget.Material.Light.ProgressBar" />
+  <public type="style" name="Widget.Material.Light.ProgressBar.Horizontal" />
+  <public type="style" name="Widget.Material.Light.ProgressBar.Inverse" />
+  <public type="style" name="Widget.Material.Light.ProgressBar.Large" />
+  <public type="style" name="Widget.Material.Light.ProgressBar.Large.Inverse" />
+  <public type="style" name="Widget.Material.Light.ProgressBar.Small" />
+  <public type="style" name="Widget.Material.Light.ProgressBar.Small.Inverse" />
+  <public type="style" name="Widget.Material.Light.ProgressBar.Small.Title" />
+  <public type="style" name="Widget.Material.Light.RatingBar" />
+  <public type="style" name="Widget.Material.Light.RatingBar.Indicator" />
+  <public type="style" name="Widget.Material.Light.RatingBar.Small" />
+  <public type="style" name="Widget.Material.Light.ScrollView" />
+  <public type="style" name="Widget.Material.Light.SeekBar" />
+  <public type="style" name="Widget.Material.Light.SegmentedButton" />
+  <public type="style" name="Widget.Material.Light.StackView" />
+  <public type="style" name="Widget.Material.Light.Spinner" />
+  <public type="style" name="Widget.Material.Light.Tab" />
+  <public type="style" name="Widget.Material.Light.TabWidget" />
+  <public type="style" name="Widget.Material.Light.TextView" />
+  <public type="style" name="Widget.Material.Light.TextView.SpinnerItem" />
+  <public type="style" name="Widget.Material.Light.WebTextView" />
+  <public type="style" name="Widget.Material.Light.WebView" />
 
-  <public type="style" name="TextAppearance.Quantum.Display4" />
-  <public type="style" name="TextAppearance.Quantum.Display3" />
-  <public type="style" name="TextAppearance.Quantum.Display2" />
-  <public type="style" name="TextAppearance.Quantum.Display1" />
-  <public type="style" name="TextAppearance.Quantum.Headline" />
-  <public type="style" name="TextAppearance.Quantum.Title" />
-  <public type="style" name="TextAppearance.Quantum.Subhead" />
-  <public type="style" name="TextAppearance.Quantum.Body2" />
-  <public type="style" name="TextAppearance.Quantum.Body1" />
-  <public type="style" name="TextAppearance.Quantum.Caption" />
-  <public type="style" name="TextAppearance.Quantum.Menu" />
-  <public type="style" name="TextAppearance.Quantum.Button" />
+  <public type="style" name="TextAppearance.Material.Display4" />
+  <public type="style" name="TextAppearance.Material.Display3" />
+  <public type="style" name="TextAppearance.Material.Display2" />
+  <public type="style" name="TextAppearance.Material.Display1" />
+  <public type="style" name="TextAppearance.Material.Headline" />
+  <public type="style" name="TextAppearance.Material.Title" />
+  <public type="style" name="TextAppearance.Material.Subhead" />
+  <public type="style" name="TextAppearance.Material.Body2" />
+  <public type="style" name="TextAppearance.Material.Body1" />
+  <public type="style" name="TextAppearance.Material.Caption" />
+  <public type="style" name="TextAppearance.Material.Menu" />
+  <public type="style" name="TextAppearance.Material.Button" />
 
   <public-padding type="interpolator" name="l_resource_pad" end="0x010c0010" />
 
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 9ff67b4..391a32c 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1556,6 +1556,12 @@
       happen in the background but does not prevent other audio capture (e.g. Camcorder).</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_modifyAudioRouting">Audio Routing</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_modifyAudioRouting">Allows the app to directly control audio routing and
+      override audio policy decisions.</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_captureVideoOutput">capture video output</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permdesc_captureVideoOutput">Allows the app to capture and redirect video output.</string>
@@ -3779,6 +3785,11 @@
     <!-- Description of an application permission that lets it listen to trust state changes. -->
     <string name="permdesc_trust_listener">Allows an application to listen for changes in trust state.</string>
 
+    <!-- Title of an application permission that lets it provide a trust agent. -->
+    <string name="permlab_provide_trust_agent">Provide a trust agent.</string>
+    <!-- Description of an application permission that lets it provide a trust agent. -->
+    <string name="permdesc_provide_trust_agent">Allows an application to provide a trust agent.</string>
+
     <!-- Title of an application permission that lets it bind to a trust agent service. -->
     <string name="permlab_bind_trust_agent_service">Bind to a trust agent service</string>
     <!-- Description of an application permission that lets it bind to a trust agent service. -->
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 59bd667..5bd6122 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1199,6 +1199,7 @@
         <item name="android:buttonGravity">top</item>
         <item name="android:navigationButtonStyle">@android:style/Widget.Toolbar.Button.Navigation</item>
         <item name="android:collapseIcon">?android:attr/homeAsUpIndicator</item>
+        <item name="android:contentInsetStart">16dp</item>
     </style>
 
     <style name="Widget.Toolbar.Button.Navigation" parent="@android:style/Widget">
diff --git a/core/res/res/values/styles_device_defaults.xml b/core/res/res/values/styles_device_defaults.xml
index 609a0f3..84dbc79 100644
--- a/core/res/res/values/styles_device_defaults.xml
+++ b/core/res/res/values/styles_device_defaults.xml
@@ -32,149 +32,149 @@
  -->
 <resources>
     <!-- Widget Styles -->
-    <style name="Widget.DeviceDefault" parent="Widget.Quantum"/>
-    <style name="Widget.DeviceDefault.Button" parent="Widget.Quantum.Button"/>
-    <style name="Widget.DeviceDefault.Button.Small" parent="Widget.Quantum.Button.Small"/>
-    <style name="Widget.DeviceDefault.Button.Inset" parent="Widget.Quantum.Button.Inset"/>
-    <style name="Widget.DeviceDefault.Button.Toggle" parent="Widget.Quantum.Button.Toggle"/>
-    <style name="Widget.DeviceDefault.TextView" parent="Widget.Quantum.TextView"/>
-    <style name="Widget.DeviceDefault.CheckedTextView" parent="Widget.Quantum.CheckedTextView"/>
-    <style name="Widget.DeviceDefault.AutoCompleteTextView" parent="Widget.Quantum.AutoCompleteTextView"/>
-    <style name="Widget.DeviceDefault.CompoundButton.CheckBox" parent="Widget.Quantum.CompoundButton.CheckBox"/>
-    <style name="Widget.DeviceDefault.ListView.DropDown" parent="Widget.Quantum.ListView.DropDown"/>
-    <style name="Widget.DeviceDefault.EditText" parent="Widget.Quantum.EditText"/>
-    <style name="Widget.DeviceDefault.ExpandableListView" parent="Widget.Quantum.ExpandableListView"/>
-    <style name="Widget.DeviceDefault.GridView" parent="Widget.Quantum.GridView"/>
-    <style name="Widget.DeviceDefault.ImageButton" parent="Widget.Quantum.ImageButton"/>
-    <style name="Widget.DeviceDefault.ListView" parent="Widget.Quantum.ListView"/>
-    <style name="Widget.DeviceDefault.PopupWindow" parent="Widget.Quantum.PopupWindow"/>
-    <style name="Widget.DeviceDefault.ProgressBar" parent="Widget.Quantum.ProgressBar"/>
-    <style name="Widget.DeviceDefault.ProgressBar.Horizontal" parent="Widget.Quantum.ProgressBar.Horizontal"/>
-    <style name="Widget.DeviceDefault.ProgressBar.Small" parent="Widget.Quantum.ProgressBar.Small"/>
-    <style name="Widget.DeviceDefault.ProgressBar.Small.Title" parent="Widget.Quantum.ProgressBar.Small.Title"/>
-    <style name="Widget.DeviceDefault.ProgressBar.Large" parent="Widget.Quantum.ProgressBar.Large"/>
-    <style name="Widget.DeviceDefault.SeekBar" parent="Widget.Quantum.SeekBar"/>
-    <style name="Widget.DeviceDefault.RatingBar" parent="Widget.Quantum.RatingBar"/>
-    <style name="Widget.DeviceDefault.RatingBar.Indicator" parent="Widget.Quantum.RatingBar.Indicator"/>
-    <style name="Widget.DeviceDefault.RatingBar.Small" parent="Widget.Quantum.RatingBar.Small"/>
-    <style name="Widget.DeviceDefault.CompoundButton.RadioButton" parent="Widget.Quantum.CompoundButton.RadioButton"/>
-    <style name="Widget.DeviceDefault.ScrollView" parent="Widget.Quantum.ScrollView"/>
-    <style name="Widget.DeviceDefault.HorizontalScrollView" parent="Widget.Quantum.HorizontalScrollView"/>
-    <style name="Widget.DeviceDefault.Spinner" parent="Widget.Quantum.Spinner"/>
-    <style name="Widget.DeviceDefault.CompoundButton.Star" parent="Widget.Quantum.CompoundButton.Star"/>
-    <style name="Widget.DeviceDefault.TabWidget" parent="Widget.Quantum.TabWidget"/>
-    <style name="Widget.DeviceDefault.WebTextView" parent="Widget.Quantum.WebTextView"/>
-    <style name="Widget.DeviceDefault.WebView" parent="Widget.Quantum.WebView"/>
-    <style name="Widget.DeviceDefault.DropDownItem" parent="Widget.Quantum.DropDownItem"/>
-    <style name="Widget.DeviceDefault.DropDownItem.Spinner" parent="Widget.Quantum.DropDownItem.Spinner"/>
-    <style name="Widget.DeviceDefault.TextView.SpinnerItem" parent="Widget.Quantum.TextView.SpinnerItem"/>
-    <style name="Widget.DeviceDefault.ListPopupWindow" parent="Widget.Quantum.ListPopupWindow"/>
-    <style name="Widget.DeviceDefault.PopupMenu" parent="Widget.Quantum.PopupMenu"/>
-    <style name="Widget.DeviceDefault.ActionButton" parent="Widget.Quantum.ActionButton"/>
-    <style name="Widget.DeviceDefault.ActionButton.Overflow" parent="Widget.Quantum.ActionButton.Overflow"/>
-    <style name="Widget.DeviceDefault.ActionButton.TextButton" parent="Widget.Quantum.ActionButton"/>
-    <style name="Widget.DeviceDefault.ActionMode" parent="Widget.Quantum.ActionMode"/>
-    <style name="Widget.DeviceDefault.ActionButton.CloseMode" parent="Widget.Quantum.ActionButton.CloseMode"/>
-    <style name="Widget.DeviceDefault.ActionBar" parent="Widget.Quantum.ActionBar"/>
-    <style name="Widget.DeviceDefault.Button.Borderless" parent="Widget.Quantum.Button.Borderless"/>
-    <style name="Widget.DeviceDefault.Tab" parent="Widget.Quantum.Tab"/>
-    <style name="Widget.DeviceDefault.CalendarView" parent="Widget.Quantum.CalendarView"/>
-    <style name="Widget.DeviceDefault.DatePicker" parent="Widget.Quantum.DatePicker"/>
-    <style name="Widget.DeviceDefault.ActionBar.TabView" parent="Widget.Quantum.ActionBar.TabView"/>
-    <style name="Widget.DeviceDefault.ActionBar.TabText" parent="Widget.Quantum.ActionBar.TabText"/>
-    <style name="Widget.DeviceDefault.ActionBar.TabBar" parent="Widget.Quantum.ActionBar.TabBar"/>
-    <style name="Widget.DeviceDefault.ActionBar.Solid" parent="Widget.Quantum.ActionBar.Solid"/>
-    <style name="Widget.DeviceDefault.Button.Borderless.Small" parent="Widget.Quantum.Button.Borderless.Small"/>
-    <style name="Widget.DeviceDefault.AbsListView" parent="Widget.Quantum.AbsListView"/>
-    <style name="Widget.DeviceDefault.Spinner.DropDown.ActionBar" parent="Widget.Quantum.Spinner.DropDown.ActionBar"/>
-    <style name="Widget.DeviceDefault.PopupWindow.ActionMode" parent="Widget.Quantum.PopupWindow.ActionMode"/>
-    <style name="Widget.DeviceDefault.CompoundButton.Switch" parent="Widget.Quantum.CompoundButton.Switch"/>
-    <style name="Widget.DeviceDefault.ExpandableListView.White" parent="Widget.Quantum.ExpandableListView.White"/>
-    <style name="Widget.DeviceDefault.FastScroll" parent="Widget.Quantum.FastScroll"/>
+    <style name="Widget.DeviceDefault" parent="Widget.Material"/>
+    <style name="Widget.DeviceDefault.Button" parent="Widget.Material.Button"/>
+    <style name="Widget.DeviceDefault.Button.Small" parent="Widget.Material.Button.Small"/>
+    <style name="Widget.DeviceDefault.Button.Inset" parent="Widget.Material.Button.Inset"/>
+    <style name="Widget.DeviceDefault.Button.Toggle" parent="Widget.Material.Button.Toggle"/>
+    <style name="Widget.DeviceDefault.TextView" parent="Widget.Material.TextView"/>
+    <style name="Widget.DeviceDefault.CheckedTextView" parent="Widget.Material.CheckedTextView"/>
+    <style name="Widget.DeviceDefault.AutoCompleteTextView" parent="Widget.Material.AutoCompleteTextView"/>
+    <style name="Widget.DeviceDefault.CompoundButton.CheckBox" parent="Widget.Material.CompoundButton.CheckBox"/>
+    <style name="Widget.DeviceDefault.ListView.DropDown" parent="Widget.Material.ListView.DropDown"/>
+    <style name="Widget.DeviceDefault.EditText" parent="Widget.Material.EditText"/>
+    <style name="Widget.DeviceDefault.ExpandableListView" parent="Widget.Material.ExpandableListView"/>
+    <style name="Widget.DeviceDefault.GridView" parent="Widget.Material.GridView"/>
+    <style name="Widget.DeviceDefault.ImageButton" parent="Widget.Material.ImageButton"/>
+    <style name="Widget.DeviceDefault.ListView" parent="Widget.Material.ListView"/>
+    <style name="Widget.DeviceDefault.PopupWindow" parent="Widget.Material.PopupWindow"/>
+    <style name="Widget.DeviceDefault.ProgressBar" parent="Widget.Material.ProgressBar"/>
+    <style name="Widget.DeviceDefault.ProgressBar.Horizontal" parent="Widget.Material.ProgressBar.Horizontal"/>
+    <style name="Widget.DeviceDefault.ProgressBar.Small" parent="Widget.Material.ProgressBar.Small"/>
+    <style name="Widget.DeviceDefault.ProgressBar.Small.Title" parent="Widget.Material.ProgressBar.Small.Title"/>
+    <style name="Widget.DeviceDefault.ProgressBar.Large" parent="Widget.Material.ProgressBar.Large"/>
+    <style name="Widget.DeviceDefault.SeekBar" parent="Widget.Material.SeekBar"/>
+    <style name="Widget.DeviceDefault.RatingBar" parent="Widget.Material.RatingBar"/>
+    <style name="Widget.DeviceDefault.RatingBar.Indicator" parent="Widget.Material.RatingBar.Indicator"/>
+    <style name="Widget.DeviceDefault.RatingBar.Small" parent="Widget.Material.RatingBar.Small"/>
+    <style name="Widget.DeviceDefault.CompoundButton.RadioButton" parent="Widget.Material.CompoundButton.RadioButton"/>
+    <style name="Widget.DeviceDefault.ScrollView" parent="Widget.Material.ScrollView"/>
+    <style name="Widget.DeviceDefault.HorizontalScrollView" parent="Widget.Material.HorizontalScrollView"/>
+    <style name="Widget.DeviceDefault.Spinner" parent="Widget.Material.Spinner"/>
+    <style name="Widget.DeviceDefault.CompoundButton.Star" parent="Widget.Material.CompoundButton.Star"/>
+    <style name="Widget.DeviceDefault.TabWidget" parent="Widget.Material.TabWidget"/>
+    <style name="Widget.DeviceDefault.WebTextView" parent="Widget.Material.WebTextView"/>
+    <style name="Widget.DeviceDefault.WebView" parent="Widget.Material.WebView"/>
+    <style name="Widget.DeviceDefault.DropDownItem" parent="Widget.Material.DropDownItem"/>
+    <style name="Widget.DeviceDefault.DropDownItem.Spinner" parent="Widget.Material.DropDownItem.Spinner"/>
+    <style name="Widget.DeviceDefault.TextView.SpinnerItem" parent="Widget.Material.TextView.SpinnerItem"/>
+    <style name="Widget.DeviceDefault.ListPopupWindow" parent="Widget.Material.ListPopupWindow"/>
+    <style name="Widget.DeviceDefault.PopupMenu" parent="Widget.Material.PopupMenu"/>
+    <style name="Widget.DeviceDefault.ActionButton" parent="Widget.Material.ActionButton"/>
+    <style name="Widget.DeviceDefault.ActionButton.Overflow" parent="Widget.Material.ActionButton.Overflow"/>
+    <style name="Widget.DeviceDefault.ActionButton.TextButton" parent="Widget.Material.ActionButton"/>
+    <style name="Widget.DeviceDefault.ActionMode" parent="Widget.Material.ActionMode"/>
+    <style name="Widget.DeviceDefault.ActionButton.CloseMode" parent="Widget.Material.ActionButton.CloseMode"/>
+    <style name="Widget.DeviceDefault.ActionBar" parent="Widget.Material.ActionBar"/>
+    <style name="Widget.DeviceDefault.Button.Borderless" parent="Widget.Material.Button.Borderless"/>
+    <style name="Widget.DeviceDefault.Tab" parent="Widget.Material.Tab"/>
+    <style name="Widget.DeviceDefault.CalendarView" parent="Widget.Material.CalendarView"/>
+    <style name="Widget.DeviceDefault.DatePicker" parent="Widget.Material.DatePicker"/>
+    <style name="Widget.DeviceDefault.ActionBar.TabView" parent="Widget.Material.ActionBar.TabView"/>
+    <style name="Widget.DeviceDefault.ActionBar.TabText" parent="Widget.Material.ActionBar.TabText"/>
+    <style name="Widget.DeviceDefault.ActionBar.TabBar" parent="Widget.Material.ActionBar.TabBar"/>
+    <style name="Widget.DeviceDefault.ActionBar.Solid" parent="Widget.Material.ActionBar.Solid"/>
+    <style name="Widget.DeviceDefault.Button.Borderless.Small" parent="Widget.Material.Button.Borderless.Small"/>
+    <style name="Widget.DeviceDefault.AbsListView" parent="Widget.Material.AbsListView"/>
+    <style name="Widget.DeviceDefault.Spinner.DropDown.ActionBar" parent="Widget.Material.Spinner.DropDown.ActionBar"/>
+    <style name="Widget.DeviceDefault.PopupWindow.ActionMode" parent="Widget.Material.PopupWindow.ActionMode"/>
+    <style name="Widget.DeviceDefault.CompoundButton.Switch" parent="Widget.Material.CompoundButton.Switch"/>
+    <style name="Widget.DeviceDefault.ExpandableListView.White" parent="Widget.Material.ExpandableListView.White"/>
+    <style name="Widget.DeviceDefault.FastScroll" parent="Widget.Material.FastScroll"/>
     <!-- The FragmentBreadCrumbs widget is deprecated starting in API level 21 ({@link android.os.Build.VERSION_CODES#.L}). -->
     <style name="Widget.DeviceDefault.FragmentBreadCrumbs" parent="Widget.Holo.FragmentBreadCrumbs"/>
-    <style name="Widget.DeviceDefault.Gallery" parent="Widget.Quantum.Gallery"/>
-    <style name="Widget.DeviceDefault.GestureOverlayView" parent="Widget.Quantum.GestureOverlayView"/>
-    <style name="Widget.DeviceDefault.ImageWell" parent="Widget.Quantum.ImageWell"/>
-    <style name="Widget.DeviceDefault.KeyboardView" parent="Widget.Quantum.KeyboardView"/>
-    <style name="Widget.DeviceDefault.ListView.White" parent="Widget.Quantum.ListView.White"/>
-    <style name="Widget.DeviceDefault.MediaRouteButton" parent="Widget.Quantum.MediaRouteButton" />
-    <style name="Widget.DeviceDefault.NumberPicker" parent="Widget.Quantum.NumberPicker"/>
-    <style name="Widget.DeviceDefault.PreferenceFrameLayout" parent="Widget.Quantum.PreferenceFrameLayout"/>
-    <style name="Widget.DeviceDefault.ProgressBar.Inverse" parent="Widget.Quantum.ProgressBar.Inverse"/>
-    <style name="Widget.DeviceDefault.ProgressBar.Large.Inverse" parent="Widget.Quantum.ProgressBar.Large.Inverse"/>
-    <style name="Widget.DeviceDefault.ProgressBar.Small.Inverse" parent="Widget.Quantum.ProgressBar.Small.Inverse"/>
-    <style name="Widget.DeviceDefault.QuickContactBadge.WindowLarge" parent="Widget.Quantum.QuickContactBadge.WindowLarge"/>
-    <style name="Widget.DeviceDefault.QuickContactBadge.WindowMedium" parent="Widget.Quantum.QuickContactBadge.WindowMedium"/>
-    <style name="Widget.DeviceDefault.QuickContactBadge.WindowSmall" parent="Widget.Quantum.QuickContactBadge.WindowSmall"/>
-    <style name="Widget.DeviceDefault.QuickContactBadgeSmall.WindowLarge" parent="Widget.Quantum.QuickContactBadgeSmall.WindowLarge"/>
-    <style name="Widget.DeviceDefault.QuickContactBadgeSmall.WindowMedium" parent="Widget.Quantum.QuickContactBadgeSmall.WindowMedium"/>
-    <style name="Widget.DeviceDefault.QuickContactBadgeSmall.WindowSmall" parent="Widget.Quantum.QuickContactBadgeSmall.WindowSmall"/>
-    <style name="Widget.DeviceDefault.Spinner.DropDown" parent="Widget.Quantum.Spinner.DropDown"/>
-    <style name="Widget.DeviceDefault.StackView" parent="Widget.Quantum.StackView"/>
-    <style name="Widget.DeviceDefault.TextSelectHandle" parent="Widget.Quantum.TextSelectHandle"/>
-    <style name="Widget.DeviceDefault.TextSuggestionsPopupWindow" parent="Widget.Quantum.TextSuggestionsPopupWindow"/>
-    <style name="Widget.DeviceDefault.TextView.ListSeparator" parent="Widget.Quantum.TextView.ListSeparator"/>
-    <style name="Widget.DeviceDefault.TimePicker" parent="Widget.Quantum.TimePicker"/>
+    <style name="Widget.DeviceDefault.Gallery" parent="Widget.Material.Gallery"/>
+    <style name="Widget.DeviceDefault.GestureOverlayView" parent="Widget.Material.GestureOverlayView"/>
+    <style name="Widget.DeviceDefault.ImageWell" parent="Widget.Material.ImageWell"/>
+    <style name="Widget.DeviceDefault.KeyboardView" parent="Widget.Material.KeyboardView"/>
+    <style name="Widget.DeviceDefault.ListView.White" parent="Widget.Material.ListView.White"/>
+    <style name="Widget.DeviceDefault.MediaRouteButton" parent="Widget.Material.MediaRouteButton" />
+    <style name="Widget.DeviceDefault.NumberPicker" parent="Widget.Material.NumberPicker"/>
+    <style name="Widget.DeviceDefault.PreferenceFrameLayout" parent="Widget.Material.PreferenceFrameLayout"/>
+    <style name="Widget.DeviceDefault.ProgressBar.Inverse" parent="Widget.Material.ProgressBar.Inverse"/>
+    <style name="Widget.DeviceDefault.ProgressBar.Large.Inverse" parent="Widget.Material.ProgressBar.Large.Inverse"/>
+    <style name="Widget.DeviceDefault.ProgressBar.Small.Inverse" parent="Widget.Material.ProgressBar.Small.Inverse"/>
+    <style name="Widget.DeviceDefault.QuickContactBadge.WindowLarge" parent="Widget.Material.QuickContactBadge.WindowLarge"/>
+    <style name="Widget.DeviceDefault.QuickContactBadge.WindowMedium" parent="Widget.Material.QuickContactBadge.WindowMedium"/>
+    <style name="Widget.DeviceDefault.QuickContactBadge.WindowSmall" parent="Widget.Material.QuickContactBadge.WindowSmall"/>
+    <style name="Widget.DeviceDefault.QuickContactBadgeSmall.WindowLarge" parent="Widget.Material.QuickContactBadgeSmall.WindowLarge"/>
+    <style name="Widget.DeviceDefault.QuickContactBadgeSmall.WindowMedium" parent="Widget.Material.QuickContactBadgeSmall.WindowMedium"/>
+    <style name="Widget.DeviceDefault.QuickContactBadgeSmall.WindowSmall" parent="Widget.Material.QuickContactBadgeSmall.WindowSmall"/>
+    <style name="Widget.DeviceDefault.Spinner.DropDown" parent="Widget.Material.Spinner.DropDown"/>
+    <style name="Widget.DeviceDefault.StackView" parent="Widget.Material.StackView"/>
+    <style name="Widget.DeviceDefault.TextSelectHandle" parent="Widget.Material.TextSelectHandle"/>
+    <style name="Widget.DeviceDefault.TextSuggestionsPopupWindow" parent="Widget.Material.TextSuggestionsPopupWindow"/>
+    <style name="Widget.DeviceDefault.TextView.ListSeparator" parent="Widget.Material.TextView.ListSeparator"/>
+    <style name="Widget.DeviceDefault.TimePicker" parent="Widget.Material.TimePicker"/>
 
-    <style name="Widget.DeviceDefault.Light" parent="Widget.Quantum.Light"/>
-    <style name="Widget.DeviceDefault.Light.Button" parent="Widget.Quantum.Light.Button"/>
-    <style name="Widget.DeviceDefault.Light.Button.Small" parent="Widget.Quantum.Light.Button.Small"/>
-    <style name="Widget.DeviceDefault.Light.Button.Inset" parent="Widget.Quantum.Light.Button.Inset"/>
-    <style name="Widget.DeviceDefault.Light.Button.Toggle" parent="Widget.Quantum.Light.Button.Toggle"/>
-    <style name="Widget.DeviceDefault.Light.StackView" parent="Widget.Quantum.Light.StackView"/>
-    <style name="Widget.DeviceDefault.Light.TextView" parent="Widget.Quantum.Light.TextView"/>
-    <style name="Widget.DeviceDefault.Light.CheckedTextView" parent="Widget.Quantum.Light.CheckedTextView"/>
-    <style name="Widget.DeviceDefault.Light.AutoCompleteTextView" parent="Widget.Quantum.Light.AutoCompleteTextView"/>
-    <style name="Widget.DeviceDefault.Light.CompoundButton.CheckBox" parent="Widget.Quantum.Light.CompoundButton.CheckBox"/>
-    <style name="Widget.DeviceDefault.Light.ListView.DropDown" parent="Widget.Quantum.Light.ListView.DropDown"/>
-    <style name="Widget.DeviceDefault.Light.EditText" parent="Widget.Quantum.Light.EditText"/>
-    <style name="Widget.DeviceDefault.Light.ExpandableListView" parent="Widget.Quantum.Light.ExpandableListView"/>
-    <style name="Widget.DeviceDefault.Light.FastScroll" parent="Widget.Quantum.Light.FastScroll"/>
+    <style name="Widget.DeviceDefault.Light" parent="Widget.Material.Light"/>
+    <style name="Widget.DeviceDefault.Light.Button" parent="Widget.Material.Light.Button"/>
+    <style name="Widget.DeviceDefault.Light.Button.Small" parent="Widget.Material.Light.Button.Small"/>
+    <style name="Widget.DeviceDefault.Light.Button.Inset" parent="Widget.Material.Light.Button.Inset"/>
+    <style name="Widget.DeviceDefault.Light.Button.Toggle" parent="Widget.Material.Light.Button.Toggle"/>
+    <style name="Widget.DeviceDefault.Light.StackView" parent="Widget.Material.Light.StackView"/>
+    <style name="Widget.DeviceDefault.Light.TextView" parent="Widget.Material.Light.TextView"/>
+    <style name="Widget.DeviceDefault.Light.CheckedTextView" parent="Widget.Material.Light.CheckedTextView"/>
+    <style name="Widget.DeviceDefault.Light.AutoCompleteTextView" parent="Widget.Material.Light.AutoCompleteTextView"/>
+    <style name="Widget.DeviceDefault.Light.CompoundButton.CheckBox" parent="Widget.Material.Light.CompoundButton.CheckBox"/>
+    <style name="Widget.DeviceDefault.Light.ListView.DropDown" parent="Widget.Material.Light.ListView.DropDown"/>
+    <style name="Widget.DeviceDefault.Light.EditText" parent="Widget.Material.Light.EditText"/>
+    <style name="Widget.DeviceDefault.Light.ExpandableListView" parent="Widget.Material.Light.ExpandableListView"/>
+    <style name="Widget.DeviceDefault.Light.FastScroll" parent="Widget.Material.Light.FastScroll"/>
     <!-- The FragmentBreadCrumbs widget is deprecated starting in API level 21 ({@link android.os.Build.VERSION_CODES#.L}). -->
     <style name="Widget.DeviceDefault.Light.FragmentBreadCrumbs" parent="Widget.Holo.Light.FragmentBreadCrumbs"/>
-    <style name="Widget.DeviceDefault.Light.GridView" parent="Widget.Quantum.Light.GridView"/>
-    <style name="Widget.DeviceDefault.Light.ImageButton" parent="Widget.Quantum.Light.ImageButton"/>
-    <style name="Widget.DeviceDefault.Light.ListView" parent="Widget.Quantum.Light.ListView"/>
-    <style name="Widget.DeviceDefault.Light.MediaRouteButton" parent="Widget.Quantum.Light.MediaRouteButton" />
-    <style name="Widget.DeviceDefault.Light.PopupWindow" parent="Widget.Quantum.Light.PopupWindow"/>
-    <style name="Widget.DeviceDefault.Light.ProgressBar" parent="Widget.Quantum.Light.ProgressBar"/>
-    <style name="Widget.DeviceDefault.Light.ProgressBar.Horizontal" parent="Widget.Quantum.Light.ProgressBar.Horizontal"/>
-    <style name="Widget.DeviceDefault.Light.ProgressBar.Small" parent="Widget.Quantum.Light.ProgressBar.Small"/>
-    <style name="Widget.DeviceDefault.Light.ProgressBar.Small.Title" parent="Widget.Quantum.Light.ProgressBar.Small.Title"/>
-    <style name="Widget.DeviceDefault.Light.ProgressBar.Large" parent="Widget.Quantum.Light.ProgressBar.Large"/>
-    <style name="Widget.DeviceDefault.Light.ProgressBar.Inverse" parent="Widget.Quantum.Light.ProgressBar.Inverse"/>
-    <style name="Widget.DeviceDefault.Light.ProgressBar.Small.Inverse" parent="Widget.Quantum.Light.ProgressBar.Small.Inverse"/>
-    <style name="Widget.DeviceDefault.Light.ProgressBar.Large.Inverse" parent="Widget.Quantum.Light.ProgressBar.Large.Inverse"/>
-    <style name="Widget.DeviceDefault.Light.SeekBar" parent="Widget.Quantum.Light.SeekBar"/>
-    <style name="Widget.DeviceDefault.Light.RatingBar" parent="Widget.Quantum.Light.RatingBar"/>
-    <style name="Widget.DeviceDefault.Light.RatingBar.Indicator" parent="Widget.Quantum.Light.RatingBar.Indicator"/>
-    <style name="Widget.DeviceDefault.Light.RatingBar.Small" parent="Widget.Quantum.Light.RatingBar.Small"/>
-    <style name="Widget.DeviceDefault.Light.CompoundButton.RadioButton" parent="Widget.Quantum.Light.CompoundButton.RadioButton"/>
-    <style name="Widget.DeviceDefault.Light.ScrollView" parent="Widget.Quantum.Light.ScrollView"/>
-    <style name="Widget.DeviceDefault.Light.HorizontalScrollView" parent="Widget.Quantum.Light.HorizontalScrollView"/>
-    <style name="Widget.DeviceDefault.Light.Spinner" parent="Widget.Quantum.Light.Spinner"/>
-    <style name="Widget.DeviceDefault.Light.CompoundButton.Star" parent="Widget.Quantum.Light.CompoundButton.Star"/>
-    <style name="Widget.DeviceDefault.Light.TabWidget" parent="Widget.Quantum.Light.TabWidget"/>
-    <style name="Widget.DeviceDefault.Light.WebTextView" parent="Widget.Quantum.Light.WebTextView"/>
-    <style name="Widget.DeviceDefault.Light.WebView" parent="Widget.Quantum.Light.WebView"/>
-    <style name="Widget.DeviceDefault.Light.DropDownItem" parent="Widget.Quantum.Light.DropDownItem"/>
-    <style name="Widget.DeviceDefault.Light.DropDownItem.Spinner" parent="Widget.Quantum.Light.DropDownItem.Spinner"/>
-    <style name="Widget.DeviceDefault.Light.TextView.SpinnerItem" parent="Widget.Quantum.Light.TextView.SpinnerItem"/>
-    <style name="Widget.DeviceDefault.Light.ListPopupWindow" parent="Widget.Quantum.Light.ListPopupWindow"/>
-    <style name="Widget.DeviceDefault.Light.PopupMenu" parent="Widget.Quantum.Light.PopupMenu"/>
-    <style name="Widget.DeviceDefault.Light.Tab" parent="Widget.Quantum.Light.Tab"/>
-    <style name="Widget.DeviceDefault.Light.CalendarView" parent="Widget.Quantum.Light.CalendarView"/>
-    <style name="Widget.DeviceDefault.Light.Button.Borderless.Small" parent="Widget.Quantum.Light.Button.Borderless.Small"/>
-    <style name="Widget.DeviceDefault.Light.ActionButton" parent="Widget.Quantum.Light.ActionButton"/>
-    <style name="Widget.DeviceDefault.Light.ActionButton.Overflow" parent="Widget.Quantum.Light.ActionButton.Overflow"/>
-    <style name="Widget.DeviceDefault.Light.ActionMode" parent="Widget.Quantum.Light.ActionMode"/>
-    <style name="Widget.DeviceDefault.Light.ActionButton.CloseMode" parent="Widget.Quantum.Light.ActionButton.CloseMode"/>
-    <style name="Widget.DeviceDefault.Light.ActionBar" parent="Widget.Quantum.Light.ActionBar"/>
-    <style name="Widget.DeviceDefault.Light.ActionBar.TabView" parent="Widget.Quantum.Light.ActionBar.TabView"/>
-    <style name="Widget.DeviceDefault.Light.ActionBar.TabText" parent="Widget.Quantum.Light.ActionBar.TabText"/>
-    <style name="Widget.DeviceDefault.Light.ActionBar.TabBar" parent="Widget.Quantum.Light.ActionBar.TabBar"/>
-    <style name="Widget.DeviceDefault.Light.ActionBar.Solid" parent="Widget.Quantum.Light.ActionBar.Solid"/>
+    <style name="Widget.DeviceDefault.Light.GridView" parent="Widget.Material.Light.GridView"/>
+    <style name="Widget.DeviceDefault.Light.ImageButton" parent="Widget.Material.Light.ImageButton"/>
+    <style name="Widget.DeviceDefault.Light.ListView" parent="Widget.Material.Light.ListView"/>
+    <style name="Widget.DeviceDefault.Light.MediaRouteButton" parent="Widget.Material.Light.MediaRouteButton" />
+    <style name="Widget.DeviceDefault.Light.PopupWindow" parent="Widget.Material.Light.PopupWindow"/>
+    <style name="Widget.DeviceDefault.Light.ProgressBar" parent="Widget.Material.Light.ProgressBar"/>
+    <style name="Widget.DeviceDefault.Light.ProgressBar.Horizontal" parent="Widget.Material.Light.ProgressBar.Horizontal"/>
+    <style name="Widget.DeviceDefault.Light.ProgressBar.Small" parent="Widget.Material.Light.ProgressBar.Small"/>
+    <style name="Widget.DeviceDefault.Light.ProgressBar.Small.Title" parent="Widget.Material.Light.ProgressBar.Small.Title"/>
+    <style name="Widget.DeviceDefault.Light.ProgressBar.Large" parent="Widget.Material.Light.ProgressBar.Large"/>
+    <style name="Widget.DeviceDefault.Light.ProgressBar.Inverse" parent="Widget.Material.Light.ProgressBar.Inverse"/>
+    <style name="Widget.DeviceDefault.Light.ProgressBar.Small.Inverse" parent="Widget.Material.Light.ProgressBar.Small.Inverse"/>
+    <style name="Widget.DeviceDefault.Light.ProgressBar.Large.Inverse" parent="Widget.Material.Light.ProgressBar.Large.Inverse"/>
+    <style name="Widget.DeviceDefault.Light.SeekBar" parent="Widget.Material.Light.SeekBar"/>
+    <style name="Widget.DeviceDefault.Light.RatingBar" parent="Widget.Material.Light.RatingBar"/>
+    <style name="Widget.DeviceDefault.Light.RatingBar.Indicator" parent="Widget.Material.Light.RatingBar.Indicator"/>
+    <style name="Widget.DeviceDefault.Light.RatingBar.Small" parent="Widget.Material.Light.RatingBar.Small"/>
+    <style name="Widget.DeviceDefault.Light.CompoundButton.RadioButton" parent="Widget.Material.Light.CompoundButton.RadioButton"/>
+    <style name="Widget.DeviceDefault.Light.ScrollView" parent="Widget.Material.Light.ScrollView"/>
+    <style name="Widget.DeviceDefault.Light.HorizontalScrollView" parent="Widget.Material.Light.HorizontalScrollView"/>
+    <style name="Widget.DeviceDefault.Light.Spinner" parent="Widget.Material.Light.Spinner"/>
+    <style name="Widget.DeviceDefault.Light.CompoundButton.Star" parent="Widget.Material.Light.CompoundButton.Star"/>
+    <style name="Widget.DeviceDefault.Light.TabWidget" parent="Widget.Material.Light.TabWidget"/>
+    <style name="Widget.DeviceDefault.Light.WebTextView" parent="Widget.Material.Light.WebTextView"/>
+    <style name="Widget.DeviceDefault.Light.WebView" parent="Widget.Material.Light.WebView"/>
+    <style name="Widget.DeviceDefault.Light.DropDownItem" parent="Widget.Material.Light.DropDownItem"/>
+    <style name="Widget.DeviceDefault.Light.DropDownItem.Spinner" parent="Widget.Material.Light.DropDownItem.Spinner"/>
+    <style name="Widget.DeviceDefault.Light.TextView.SpinnerItem" parent="Widget.Material.Light.TextView.SpinnerItem"/>
+    <style name="Widget.DeviceDefault.Light.ListPopupWindow" parent="Widget.Material.Light.ListPopupWindow"/>
+    <style name="Widget.DeviceDefault.Light.PopupMenu" parent="Widget.Material.Light.PopupMenu"/>
+    <style name="Widget.DeviceDefault.Light.Tab" parent="Widget.Material.Light.Tab"/>
+    <style name="Widget.DeviceDefault.Light.CalendarView" parent="Widget.Material.Light.CalendarView"/>
+    <style name="Widget.DeviceDefault.Light.Button.Borderless.Small" parent="Widget.Material.Light.Button.Borderless.Small"/>
+    <style name="Widget.DeviceDefault.Light.ActionButton" parent="Widget.Material.Light.ActionButton"/>
+    <style name="Widget.DeviceDefault.Light.ActionButton.Overflow" parent="Widget.Material.Light.ActionButton.Overflow"/>
+    <style name="Widget.DeviceDefault.Light.ActionMode" parent="Widget.Material.Light.ActionMode"/>
+    <style name="Widget.DeviceDefault.Light.ActionButton.CloseMode" parent="Widget.Material.Light.ActionButton.CloseMode"/>
+    <style name="Widget.DeviceDefault.Light.ActionBar" parent="Widget.Material.Light.ActionBar"/>
+    <style name="Widget.DeviceDefault.Light.ActionBar.TabView" parent="Widget.Material.Light.ActionBar.TabView"/>
+    <style name="Widget.DeviceDefault.Light.ActionBar.TabText" parent="Widget.Material.Light.ActionBar.TabText"/>
+    <style name="Widget.DeviceDefault.Light.ActionBar.TabBar" parent="Widget.Material.Light.ActionBar.TabBar"/>
+    <style name="Widget.DeviceDefault.Light.ActionBar.Solid" parent="Widget.Material.Light.ActionBar.Solid"/>
     <!-- @deprecated Action bars are now themed using the inheritable android:theme attribute. -->
     <style name="Widget.DeviceDefault.Light.ActionBar.Solid.Inverse" parent="Widget.Holo.Light.ActionBar.Solid.Inverse"/>
     <!-- @deprecated Action bars are now themed using the inheritable android:theme attribute. -->
@@ -185,98 +185,98 @@
     <style name="Widget.DeviceDefault.Light.ActionBar.TabText.Inverse" parent="Widget.Holo.Light.ActionBar.TabText.Inverse"/>
     <!-- @deprecated Action bars are now themed using the inheritable android:theme attribute. -->
     <style name="Widget.DeviceDefault.Light.ActionMode.Inverse" parent="Widget.Holo.Light.ActionMode.Inverse"/>
-    <style name="Widget.DeviceDefault.Light.AbsListView" parent="Widget.Quantum.Light.AbsListView"/>
-    <style name="Widget.DeviceDefault.Light.Spinner.DropDown.ActionBar" parent="Widget.Quantum.Light.Spinner.DropDown.ActionBar"/>
-    <style name="Widget.DeviceDefault.Light.PopupWindow.ActionMode" parent="Widget.Quantum.Light.PopupWindow.ActionMode"/>
-    <style name="Widget.DeviceDefault.Light.Button.Borderless" parent="Widget.Quantum.Light.Button.Borderless"/>
-    <style name="Widget.DeviceDefault.Light.DatePicker" parent="Widget.Quantum.Light.DatePicker"/>
-    <style name="Widget.DeviceDefault.Light.ExpandableListView.White" parent="Widget.Quantum.Light.ExpandableListView.White"/>
-    <style name="Widget.DeviceDefault.Light.Gallery" parent="Widget.Quantum.Light.Gallery"/>
-    <style name="Widget.DeviceDefault.Light.GestureOverlayView" parent="Widget.Quantum.Light.GestureOverlayView"/>
-    <style name="Widget.DeviceDefault.Light.ImageWell" parent="Widget.Quantum.Light.ImageWell"/>
-    <style name="Widget.DeviceDefault.Light.ListView.White" parent="Widget.Quantum.Light.ListView.White"/>
-    <style name="Widget.DeviceDefault.Light.NumberPicker" parent="Widget.Quantum.Light.NumberPicker"/>
-    <style name="Widget.DeviceDefault.Light.Spinner.DropDown" parent="Widget.Quantum.Light.Spinner.DropDown"/>
-    <style name="Widget.DeviceDefault.Light.TextView.ListSeparator" parent="Widget.Quantum.Light.TextView.ListSeparator"/>
-    <style name="Widget.DeviceDefault.Light.TimePicker" parent="Widget.Quantum.Light.TimePicker"/>
-    <style name="Widget.DeviceDefault.Light.TextSuggestionsPopupWindow" parent="Widget.Quantum.Light.TextSuggestionsPopupWindow"/>
+    <style name="Widget.DeviceDefault.Light.AbsListView" parent="Widget.Material.Light.AbsListView"/>
+    <style name="Widget.DeviceDefault.Light.Spinner.DropDown.ActionBar" parent="Widget.Material.Light.Spinner.DropDown.ActionBar"/>
+    <style name="Widget.DeviceDefault.Light.PopupWindow.ActionMode" parent="Widget.Material.Light.PopupWindow.ActionMode"/>
+    <style name="Widget.DeviceDefault.Light.Button.Borderless" parent="Widget.Material.Light.Button.Borderless"/>
+    <style name="Widget.DeviceDefault.Light.DatePicker" parent="Widget.Material.Light.DatePicker"/>
+    <style name="Widget.DeviceDefault.Light.ExpandableListView.White" parent="Widget.Material.Light.ExpandableListView.White"/>
+    <style name="Widget.DeviceDefault.Light.Gallery" parent="Widget.Material.Light.Gallery"/>
+    <style name="Widget.DeviceDefault.Light.GestureOverlayView" parent="Widget.Material.Light.GestureOverlayView"/>
+    <style name="Widget.DeviceDefault.Light.ImageWell" parent="Widget.Material.Light.ImageWell"/>
+    <style name="Widget.DeviceDefault.Light.ListView.White" parent="Widget.Material.Light.ListView.White"/>
+    <style name="Widget.DeviceDefault.Light.NumberPicker" parent="Widget.Material.Light.NumberPicker"/>
+    <style name="Widget.DeviceDefault.Light.Spinner.DropDown" parent="Widget.Material.Light.Spinner.DropDown"/>
+    <style name="Widget.DeviceDefault.Light.TextView.ListSeparator" parent="Widget.Material.Light.TextView.ListSeparator"/>
+    <style name="Widget.DeviceDefault.Light.TimePicker" parent="Widget.Material.Light.TimePicker"/>
+    <style name="Widget.DeviceDefault.Light.TextSuggestionsPopupWindow" parent="Widget.Material.Light.TextSuggestionsPopupWindow"/>
 
     <!-- Text Appearance Styles -->
-    <style name="TextAppearance.DeviceDefault" parent="TextAppearance.Quantum"/>
-    <style name="TextAppearance.DeviceDefault.Inverse" parent="TextAppearance.Quantum.Inverse"/>
-    <style name="TextAppearance.DeviceDefault.Large" parent="TextAppearance.Quantum.Large"/>
-    <style name="TextAppearance.DeviceDefault.Large.Inverse" parent="TextAppearance.Quantum.Large.Inverse"/>
-    <style name="TextAppearance.DeviceDefault.Medium" parent="TextAppearance.Quantum.Medium"/>
-    <style name="TextAppearance.DeviceDefault.Medium.Inverse" parent="TextAppearance.Quantum.Medium.Inverse"/>
-    <style name="TextAppearance.DeviceDefault.Small" parent="TextAppearance.Quantum.Small"/>
-    <style name="TextAppearance.DeviceDefault.Small.Inverse" parent="TextAppearance.Quantum.Small.Inverse"/>
-    <style name="TextAppearance.DeviceDefault.SearchResult.Title" parent="TextAppearance.Quantum.SearchResult.Title"/>
-    <style name="TextAppearance.DeviceDefault.SearchResult.Subtitle" parent="TextAppearance.Quantum.SearchResult.Subtitle"/>
-    <style name="TextAppearance.DeviceDefault.TimePicker.TimeLabel" parent="TextAppearance.Quantum.TimePicker.TimeLabel"/>
-    <style name="TextAppearance.DeviceDefault.TimePicker.AmPmLabel" parent="TextAppearance.Quantum.TimePicker.AmPmLabel"/>
-    <style name="TextAppearance.DeviceDefault.Widget" parent="TextAppearance.Quantum.Widget"/>
-    <style name="TextAppearance.DeviceDefault.Widget.Button" parent="TextAppearance.Quantum.Widget.Button"/>
-    <style name="TextAppearance.DeviceDefault.Widget.IconMenu.Item" parent="TextAppearance.Quantum.Widget.IconMenu.Item"/>
-    <style name="TextAppearance.DeviceDefault.Widget.TabWidget" parent="TextAppearance.Quantum.Widget.TabWidget"/>
-    <style name="TextAppearance.DeviceDefault.Widget.TextView" parent="TextAppearance.Quantum.Widget.TextView"/>
-    <style name="TextAppearance.DeviceDefault.Widget.TextView.PopupMenu" parent="TextAppearance.Quantum.Widget.TextView.PopupMenu"/>
-    <style name="TextAppearance.DeviceDefault.Widget.DropDownHint" parent="TextAppearance.Quantum.Widget.DropDownHint"/>
-    <style name="TextAppearance.DeviceDefault.Widget.DropDownItem" parent="TextAppearance.Quantum.Widget.DropDownItem"/>
-    <style name="TextAppearance.DeviceDefault.Widget.TextView.SpinnerItem" parent="TextAppearance.Quantum.Widget.TextView.SpinnerItem"/>
-    <style name="TextAppearance.DeviceDefault.Widget.EditText" parent="TextAppearance.Quantum.Widget.EditText"/>
-    <style name="TextAppearance.DeviceDefault.Widget.PopupMenu" parent="TextAppearance.Quantum.Widget.PopupMenu"/>
-    <style name="TextAppearance.DeviceDefault.Widget.PopupMenu.Large" parent="TextAppearance.Quantum.Widget.PopupMenu.Large"/>
-    <style name="TextAppearance.DeviceDefault.Widget.PopupMenu.Small" parent="TextAppearance.Quantum.Widget.PopupMenu.Small"/>
-    <style name="TextAppearance.DeviceDefault.Widget.ActionBar.Title" parent="TextAppearance.Quantum.Widget.ActionBar.Title"/>
-    <style name="TextAppearance.DeviceDefault.Widget.ActionBar.Subtitle" parent="TextAppearance.Quantum.Widget.ActionBar.Subtitle"/>
-    <style name="TextAppearance.DeviceDefault.Widget.ActionMode.Title" parent="TextAppearance.Quantum.Widget.ActionMode.Title"/>
-    <style name="TextAppearance.DeviceDefault.Widget.ActionMode.Subtitle" parent="TextAppearance.Quantum.Widget.ActionMode.Subtitle"/>
-    <style name="TextAppearance.DeviceDefault.WindowTitle" parent="TextAppearance.Quantum.WindowTitle"/>
-    <style name="TextAppearance.DeviceDefault.DialogWindowTitle" parent="TextAppearance.Quantum.DialogWindowTitle"/>
+    <style name="TextAppearance.DeviceDefault" parent="TextAppearance.Material"/>
+    <style name="TextAppearance.DeviceDefault.Inverse" parent="TextAppearance.Material.Inverse"/>
+    <style name="TextAppearance.DeviceDefault.Large" parent="TextAppearance.Material.Large"/>
+    <style name="TextAppearance.DeviceDefault.Large.Inverse" parent="TextAppearance.Material.Large.Inverse"/>
+    <style name="TextAppearance.DeviceDefault.Medium" parent="TextAppearance.Material.Medium"/>
+    <style name="TextAppearance.DeviceDefault.Medium.Inverse" parent="TextAppearance.Material.Medium.Inverse"/>
+    <style name="TextAppearance.DeviceDefault.Small" parent="TextAppearance.Material.Small"/>
+    <style name="TextAppearance.DeviceDefault.Small.Inverse" parent="TextAppearance.Material.Small.Inverse"/>
+    <style name="TextAppearance.DeviceDefault.SearchResult.Title" parent="TextAppearance.Material.SearchResult.Title"/>
+    <style name="TextAppearance.DeviceDefault.SearchResult.Subtitle" parent="TextAppearance.Material.SearchResult.Subtitle"/>
+    <style name="TextAppearance.DeviceDefault.TimePicker.TimeLabel" parent="TextAppearance.Material.TimePicker.TimeLabel"/>
+    <style name="TextAppearance.DeviceDefault.TimePicker.AmPmLabel" parent="TextAppearance.Material.TimePicker.AmPmLabel"/>
+    <style name="TextAppearance.DeviceDefault.Widget" parent="TextAppearance.Material.Widget"/>
+    <style name="TextAppearance.DeviceDefault.Widget.Button" parent="TextAppearance.Material.Widget.Button"/>
+    <style name="TextAppearance.DeviceDefault.Widget.IconMenu.Item" parent="TextAppearance.Material.Widget.IconMenu.Item"/>
+    <style name="TextAppearance.DeviceDefault.Widget.TabWidget" parent="TextAppearance.Material.Widget.TabWidget"/>
+    <style name="TextAppearance.DeviceDefault.Widget.TextView" parent="TextAppearance.Material.Widget.TextView"/>
+    <style name="TextAppearance.DeviceDefault.Widget.TextView.PopupMenu" parent="TextAppearance.Material.Widget.TextView.PopupMenu"/>
+    <style name="TextAppearance.DeviceDefault.Widget.DropDownHint" parent="TextAppearance.Material.Widget.DropDownHint"/>
+    <style name="TextAppearance.DeviceDefault.Widget.DropDownItem" parent="TextAppearance.Material.Widget.DropDownItem"/>
+    <style name="TextAppearance.DeviceDefault.Widget.TextView.SpinnerItem" parent="TextAppearance.Material.Widget.TextView.SpinnerItem"/>
+    <style name="TextAppearance.DeviceDefault.Widget.EditText" parent="TextAppearance.Material.Widget.EditText"/>
+    <style name="TextAppearance.DeviceDefault.Widget.PopupMenu" parent="TextAppearance.Material.Widget.PopupMenu"/>
+    <style name="TextAppearance.DeviceDefault.Widget.PopupMenu.Large" parent="TextAppearance.Material.Widget.PopupMenu.Large"/>
+    <style name="TextAppearance.DeviceDefault.Widget.PopupMenu.Small" parent="TextAppearance.Material.Widget.PopupMenu.Small"/>
+    <style name="TextAppearance.DeviceDefault.Widget.ActionBar.Title" parent="TextAppearance.Material.Widget.ActionBar.Title"/>
+    <style name="TextAppearance.DeviceDefault.Widget.ActionBar.Subtitle" parent="TextAppearance.Material.Widget.ActionBar.Subtitle"/>
+    <style name="TextAppearance.DeviceDefault.Widget.ActionMode.Title" parent="TextAppearance.Material.Widget.ActionMode.Title"/>
+    <style name="TextAppearance.DeviceDefault.Widget.ActionMode.Subtitle" parent="TextAppearance.Material.Widget.ActionMode.Subtitle"/>
+    <style name="TextAppearance.DeviceDefault.WindowTitle" parent="TextAppearance.Material.WindowTitle"/>
+    <style name="TextAppearance.DeviceDefault.DialogWindowTitle" parent="TextAppearance.Material.DialogWindowTitle"/>
     <!-- @deprecated Action bars are now themed using the inheritable android:theme attribute. -->
-    <style name="TextAppearance.DeviceDefault.Widget.ActionBar.Title.Inverse" parent="TextAppearance.Quantum.Widget.ActionBar.Title.Inverse"/>
+    <style name="TextAppearance.DeviceDefault.Widget.ActionBar.Title.Inverse" parent="TextAppearance.Material.Widget.ActionBar.Title.Inverse"/>
     <!-- @deprecated Action bars are now themed using the inheritable android:theme attribute. -->
-    <style name="TextAppearance.DeviceDefault.Widget.ActionBar.Subtitle.Inverse" parent="TextAppearance.Quantum.Widget.ActionBar.Subtitle.Inverse"/>
+    <style name="TextAppearance.DeviceDefault.Widget.ActionBar.Subtitle.Inverse" parent="TextAppearance.Material.Widget.ActionBar.Subtitle.Inverse"/>
     <!-- @deprecated Action bars are now themed using the inheritable android:theme attribute. -->
-    <style name="TextAppearance.DeviceDefault.Widget.ActionMode.Title.Inverse" parent="TextAppearance.Quantum.Widget.ActionMode.Title.Inverse"/>
+    <style name="TextAppearance.DeviceDefault.Widget.ActionMode.Title.Inverse" parent="TextAppearance.Material.Widget.ActionMode.Title.Inverse"/>
     <!-- @deprecated Action bars are now themed using the inheritable android:theme attribute. -->
-    <style name="TextAppearance.DeviceDefault.Widget.ActionMode.Subtitle.Inverse" parent="TextAppearance.Quantum.Widget.ActionMode.Subtitle.Inverse"/>
-    <style name="TextAppearance.DeviceDefault.Widget.ActionBar.Menu" parent="TextAppearance.Quantum.Widget.ActionBar.Menu"/>
+    <style name="TextAppearance.DeviceDefault.Widget.ActionMode.Subtitle.Inverse" parent="TextAppearance.Material.Widget.ActionMode.Subtitle.Inverse"/>
+    <style name="TextAppearance.DeviceDefault.Widget.ActionBar.Menu" parent="TextAppearance.Material.Widget.ActionBar.Menu"/>
 
     <!-- Preference Styles -->
-    <style name="Preference.DeviceDefault" parent="Preference.Quantum"/>
-    <style name="Preference.DeviceDefault.Category" parent="Preference.Quantum.Category"/>
-    <style name="Preference.DeviceDefault.CheckBoxPreference" parent="Preference.Quantum.CheckBoxPreference"/>
-    <style name="Preference.DeviceDefault.DialogPreference" parent="Preference.Quantum.DialogPreference"/>
-    <style name="Preference.DeviceDefault.DialogPreference.EditTextPreference" parent="Preference.Quantum.DialogPreference.EditTextPreference"/>
-    <style name="Preference.DeviceDefault.DialogPreference.YesNoPreference" parent="Preference.Quantum.DialogPreference.YesNoPreference"/>
-    <style name="Preference.DeviceDefault.Information" parent="Preference.Quantum.Information"/>
-    <style name="Preference.DeviceDefault.PreferenceScreen" parent="Preference.Quantum.PreferenceScreen"/>
-    <style name="Preference.DeviceDefault.RingtonePreference" parent="Preference.Quantum.RingtonePreference"/>
-    <style name="Preference.DeviceDefault.SwitchPreference" parent="Preference.Quantum.SwitchPreference"/>
+    <style name="Preference.DeviceDefault" parent="Preference.Material"/>
+    <style name="Preference.DeviceDefault.Category" parent="Preference.Material.Category"/>
+    <style name="Preference.DeviceDefault.CheckBoxPreference" parent="Preference.Material.CheckBoxPreference"/>
+    <style name="Preference.DeviceDefault.DialogPreference" parent="Preference.Material.DialogPreference"/>
+    <style name="Preference.DeviceDefault.DialogPreference.EditTextPreference" parent="Preference.Material.DialogPreference.EditTextPreference"/>
+    <style name="Preference.DeviceDefault.DialogPreference.YesNoPreference" parent="Preference.Material.DialogPreference.YesNoPreference"/>
+    <style name="Preference.DeviceDefault.Information" parent="Preference.Material.Information"/>
+    <style name="Preference.DeviceDefault.PreferenceScreen" parent="Preference.Material.PreferenceScreen"/>
+    <style name="Preference.DeviceDefault.RingtonePreference" parent="Preference.Material.RingtonePreference"/>
+    <style name="Preference.DeviceDefault.SwitchPreference" parent="Preference.Material.SwitchPreference"/>
 
     <!-- AlertDialog Styles -->
-    <style name="AlertDialog.DeviceDefault" parent="AlertDialog.Quantum"/>
-    <style name="AlertDialog.DeviceDefault.Light" parent="AlertDialog.Quantum.Light"/>
+    <style name="AlertDialog.DeviceDefault" parent="AlertDialog.Material"/>
+    <style name="AlertDialog.DeviceDefault.Light" parent="AlertDialog.Material.Light"/>
 
     <!-- Animation Styles -->
-    <style name="Animation.DeviceDefault.Activity" parent="Animation.Quantum.Activity"/>
-    <style name="Animation.DeviceDefault.Dialog" parent="Animation.Quantum.Dialog"/>
+    <style name="Animation.DeviceDefault.Activity" parent="Animation.Material.Activity"/>
+    <style name="Animation.DeviceDefault.Dialog" parent="Animation.Material.Dialog"/>
 
     <!-- DialogWindowTitle Styles -->
-    <style name="DialogWindowTitle.DeviceDefault" parent="DialogWindowTitle.Quantum"/>
-    <style name="DialogWindowTitle.DeviceDefault.Light" parent="DialogWindowTitle.Quantum.Light"/>
+    <style name="DialogWindowTitle.DeviceDefault" parent="DialogWindowTitle.Material"/>
+    <style name="DialogWindowTitle.DeviceDefault.Light" parent="DialogWindowTitle.Material.Light"/>
 
     <!-- WindowTitle Styles -->
-    <style name="WindowTitle.DeviceDefault" parent="WindowTitle.Quantum"/>
-    <style name="WindowTitleBackground.DeviceDefault" parent="WindowTitleBackground.Quantum"/>
+    <style name="WindowTitle.DeviceDefault" parent="WindowTitle.Material"/>
+    <style name="WindowTitleBackground.DeviceDefault" parent="WindowTitleBackground.Material"/>
 
     <!-- Other Styles -->
-    <style name="DeviceDefault.ButtonBar" parent="Widget.Quantum.ButtonBar"/>
-    <style name="DeviceDefault.ButtonBar.AlertDialog" parent="Widget.Quantum.ButtonBar.AlertDialog"/>
-    <style name="DeviceDefault.SegmentedButton" parent="Widget.Quantum.SegmentedButton"/>
+    <style name="DeviceDefault.ButtonBar" parent="Widget.Material.ButtonBar"/>
+    <style name="DeviceDefault.ButtonBar.AlertDialog" parent="Widget.Material.ButtonBar.AlertDialog"/>
+    <style name="DeviceDefault.SegmentedButton" parent="Widget.Material.SegmentedButton"/>
 
-    <style name="DeviceDefault.Light.ButtonBar" parent="Widget.Quantum.Light.ButtonBar"/>
-    <style name="DeviceDefault.Light.ButtonBar.AlertDialog" parent="Widget.Quantum.Light.ButtonBar.AlertDialog"/>
-    <style name="DeviceDefault.Light.SegmentedButton" parent="Widget.Quantum.Light.SegmentedButton"/>
+    <style name="DeviceDefault.Light.ButtonBar" parent="Widget.Material.Light.ButtonBar"/>
+    <style name="DeviceDefault.Light.ButtonBar.AlertDialog" parent="Widget.Material.Light.ButtonBar.AlertDialog"/>
+    <style name="DeviceDefault.Light.SegmentedButton" parent="Widget.Material.Light.SegmentedButton"/>
 </resources>
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
new file mode 100644
index 0000000..929e615
--- /dev/null
+++ b/core/res/res/values/styles_material.xml
@@ -0,0 +1,973 @@
+<?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 styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+ -->
+<resources>
+    <!-- Preference styles -->
+    <eat-comment/>
+
+    <style name="Preference.Material">
+        <item name="layout">@layout/preference_material</item>
+    </style>
+
+    <style name="PreferenceFragment.Material">
+        <item name="paddingStart">@dimen/preference_fragment_padding_side</item>
+        <item name="paddingEnd">@dimen/preference_fragment_padding_side</item>
+    </style>
+
+    <style name="Preference.Material.Information">
+        <item name="layout">@layout/preference_information_material</item>
+        <item name="enabled">false</item>
+        <item name="shouldDisableView">false</item>
+    </style>
+
+    <style name="Preference.Material.Category">
+        <item name="layout">@layout/preference_category_material</item>
+        <!-- The title should not dim if the category is disabled, instead only the preference children should dim. -->
+        <item name="shouldDisableView">false</item>
+        <item name="selectable">false</item>
+    </style>
+
+    <style name="Preference.Material.CheckBoxPreference">
+        <item name="widgetLayout">@layout/preference_widget_checkbox</item>
+    </style>
+
+    <style name="Preference.Material.SwitchPreference">
+        <item name="widgetLayout">@layout/preference_widget_switch</item>
+        <item name="switchTextOn">@string/capital_on</item>
+        <item name="switchTextOff">@string/capital_off</item>
+    </style>
+
+    <style name="Preference.Material.PreferenceScreen"/>
+
+    <style name="Preference.Material.DialogPreference">
+        <item name="positiveButtonText">@string/ok</item>
+        <item name="negativeButtonText">@string/cancel</item>
+    </style>
+
+    <style name="Preference.Material.DialogPreference.YesNoPreference">
+        <item name="positiveButtonText">@string/yes</item>
+        <item name="negativeButtonText">@string/no</item>
+    </style>
+
+    <style name="Preference.Material.DialogPreference.EditTextPreference">
+        <item name="dialogLayout">@layout/preference_dialog_edittext</item>
+    </style>
+
+    <style name="Preference.Material.RingtonePreference">
+        <item name="ringtoneType">ringtone</item>
+        <item name="showSilent">true</item>
+        <item name="showDefault">true</item>
+    </style>
+
+    <!-- Begin Material theme styles -->
+
+    <!-- Text styles -->
+
+    <style name="TextAppearance.Material">
+        <item name="textColor">?attr/textColorPrimary</item>
+        <item name="textColorHint">?attr/textColorHint</item>
+        <item name="textColorHighlight">?attr/textColorHighlight</item>
+        <item name="textColorLink">?attr/textColorLink</item>
+        <item name="textSize">@dimen/text_size_body_1_material</item>
+        <item name="fontFamily">@string/font_family_body_1_material</item>
+    </style>
+
+    <style name="TextAppearance.Material.Display4">
+        <item name="textSize">@dimen/text_size_display_4_material</item>
+        <item name="fontFamily">@string/font_family_display_4_material</item>
+        <item name="textColor">?attr/textColorSecondary</item>
+    </style>
+
+    <style name="TextAppearance.Material.Display3">
+        <item name="textSize">@dimen/text_size_display_3_material</item>
+        <item name="fontFamily">@string/font_family_display_3_material</item>
+        <item name="textColor">?attr/textColorSecondary</item>
+    </style>
+
+    <style name="TextAppearance.Material.Display2">
+        <item name="textSize">@dimen/text_size_display_2_material</item>
+        <item name="fontFamily">@string/font_family_display_2_material</item>
+        <item name="textColor">?attr/textColorSecondary</item>
+    </style>
+
+    <style name="TextAppearance.Material.Display1">
+        <item name="textSize">@dimen/text_size_display_1_material</item>
+        <item name="fontFamily">@string/font_family_display_1_material</item>
+        <item name="textColor">?attr/textColorSecondary</item>
+    </style>
+
+    <style name="TextAppearance.Material.Headline">
+        <item name="textSize">@dimen/text_size_headline_material</item>
+        <item name="fontFamily">@string/font_family_headline_material</item>
+        <item name="textColor">?attr/textColorPrimary</item>
+    </style>
+
+    <style name="TextAppearance.Material.Title">
+        <item name="textSize">@dimen/text_size_title_material</item>
+        <item name="fontFamily">@string/font_family_title_material</item>
+        <item name="textColor">?attr/textColorPrimary</item>
+    </style>
+
+    <style name="TextAppearance.Material.Title.Inverse">
+        <item name="textColor">?attr/textColorPrimaryInverse</item>
+        <item name="textColorHint">?attr/textColorHintInverse</item>
+        <item name="textColorHighlight">?attr/textColorHighlightInverse</item>
+        <item name="textColorLink">?attr/textColorLinkInverse</item>
+    </style>
+
+    <style name="TextAppearance.Material.Subhead">
+        <item name="textSize">@dimen/text_size_subhead_material</item>
+        <item name="fontFamily">@string/font_family_subhead_material</item>
+        <item name="textColor">?attr/textColorPrimary</item>
+    </style>
+
+    <style name="TextAppearance.Material.Subhead.Inverse">
+        <item name="textColor">?attr/textColorSecondaryInverse</item>
+        <item name="textColorHint">?attr/textColorHintInverse</item>
+        <item name="textColorHighlight">?attr/textColorHighlightInverse</item>
+        <item name="textColorLink">?attr/textColorLinkInverse</item>
+    </style>
+
+    <style name="TextAppearance.Material.Body2">
+        <item name="textSize">@dimen/text_size_body_2_material</item>
+        <item name="fontFamily">@string/font_family_body_2_material</item>
+        <item name="textColor">?attr/textColorPrimary</item>
+    </style>
+
+    <style name="TextAppearance.Material.Body1">
+        <item name="textSize">@dimen/text_size_body_1_material</item>
+        <item name="fontFamily">@string/font_family_body_1_material</item>
+        <item name="textColor">?attr/textColorPrimary</item>
+    </style>
+
+    <style name="TextAppearance.Material.Caption">
+        <item name="textSize">@dimen/text_size_caption_material</item>
+        <item name="fontFamily">@string/font_family_caption_material</item>
+        <item name="textColor">?attr/textColorSecondary</item>
+    </style>
+
+    <style name="TextAppearance.Material.Menu">
+        <item name="textSize">@dimen/text_size_menu_material</item>
+        <item name="fontFamily">@string/font_family_menu_material</item>
+    </style>
+
+    <style name="TextAppearance.Material.Menu.Inverse">
+        <item name="textColor">?attr/textColorSecondaryInverse</item>
+        <item name="textColorHint">?attr/textColorHintInverse</item>
+        <item name="textColorHighlight">?attr/textColorHighlightInverse</item>
+        <item name="textColorLink">?attr/textColorLinkInverse</item>
+    </style>
+
+    <style name="TextAppearance.Material.Button">
+        <item name="textSize">@dimen/text_size_button_material</item>
+        <item name="fontFamily">@string/font_family_button_material</item>
+        <item name="textAllCaps">true</item>
+        <item name="textColor">?attr/textColorPrimary</item>
+    </style>
+
+    <!-- Deprecated text styles -->
+
+    <style name="TextAppearance.Material.Inverse">
+        <item name="textColor">?attr/textColorPrimaryInverse</item>
+        <item name="textColorHint">?attr/textColorHintInverse</item>
+        <item name="textColorHighlight">?attr/textColorHighlightInverse</item>
+        <item name="textColorLink">?attr/textColorLinkInverse</item>
+    </style>
+
+    <style name="TextAppearance.Material.Large">
+        <item name="textSize">@dimen/text_size_large_material</item>
+        <item name="textColor">?attr/textColorPrimary</item>
+    </style>
+
+    <style name="TextAppearance.Material.Large.Inverse">
+        <item name="textColor">?attr/textColorPrimaryInverse</item>
+        <item name="textColorHint">?attr/textColorHintInverse</item>
+        <item name="textColorHighlight">?attr/textColorHighlightInverse</item>
+        <item name="textColorLink">?attr/textColorLinkInverse</item>
+    </style>
+
+    <style name="TextAppearance.Material.Medium">
+        <item name="textSize">@dimen/text_size_medium_material</item>
+        <item name="textColor">?attr/textColorSecondary</item>
+    </style>
+
+    <style name="TextAppearance.Material.Medium.Inverse">
+        <item name="textColor">?attr/textColorSecondaryInverse</item>
+        <item name="textColorHint">?attr/textColorHintInverse</item>
+        <item name="textColorHighlight">?attr/textColorHighlightInverse</item>
+        <item name="textColorLink">?attr/textColorLinkInverse</item>
+    </style>
+
+    <style name="TextAppearance.Material.Small">
+        <item name="textSize">@dimen/text_size_small_material</item>
+        <item name="textColor">?attr/textColorTertiary</item>
+    </style>
+
+    <style name="TextAppearance.Material.Small.Inverse">
+        <item name="textColor">?attr/textColorTertiaryInverse</item>
+        <item name="textColorHint">?attr/textColorHintInverse</item>
+        <item name="textColorHighlight">?attr/textColorHighlightInverse</item>
+        <item name="textColorLink">?attr/textColorLinkInverse</item>
+    </style>
+
+    <style name="TextAppearance.Material.SearchResult" />
+    <style name="TextAppearance.Material.SearchResult.Title" parent="TextAppearance.Material.Title" />
+    <style name="TextAppearance.Material.SearchResult.Subtitle" parent="TextAppearance.Material.Subhead" />
+
+    <style name="TextAppearance.Material.Widget"/>
+    <style name="TextAppearance.Material.Widget.Button" parent="TextAppearance.Material.Button" />
+
+    <style name="TextAppearance.Material.Widget.EditText">
+        <item name="textColor">?attr/textColorPrimaryInverse</item>
+        <item name="textColorHint">?attr/textColorHintInverse</item>
+    </style>
+
+    <style name="TextAppearance.Material.Widget.Switch" parent="TextAppearance.Material.Button" />
+
+    <style name="TextAppearance.Material.Widget.PopupMenu"/>
+    <style name="TextAppearance.Material.Widget.PopupMenu.Large" parent="TextAppearance.Material.Menu" />
+    <style name="TextAppearance.Material.Widget.PopupMenu.Small" parent="TextAppearance.Material.Menu" />
+
+    <style name="TextAppearance.Material.Widget.DropDownHint" parent="TextAppearance.Material.Menu" />
+
+    <style name="TextAppearance.Material.Widget.IconMenu.Item" parent="TextAppearance.Material.Small">
+        <item name="textColor">?attr/textColorPrimary</item>
+    </style>
+
+    <style name="TextAppearance.Material.Widget.TabWidget" parent="TextAppearance.Material.Button" />
+
+    <style name="TextAppearance.Material.Widget.TextView">
+        <item name="textColor">?attr/textColorPrimaryDisableOnly</item>
+        <item name="textColorHint">?attr/textColorHint</item>
+    </style>
+
+    <style name="TextAppearance.Material.Widget.TextView.PopupMenu" parent="TextAppearance.Material.Menu" />
+    <style name="TextAppearance.Material.Widget.TextView.SpinnerItem" />
+
+    <style name="TextAppearance.Material.Widget.DropDownItem">
+        <item name="textColor">?attr/textColorPrimaryDisableOnly</item>
+    </style>
+
+    <style name="TextAppearance.Material.Widget.ActionMode"/>
+    <style name="TextAppearance.Material.Widget.ActionMode.Title" parent="TextAppearance.Material.Title" />
+    <style name="TextAppearance.Material.Widget.ActionMode.Title.Inverse" parent="TextAppearance.Material.Title.Inverse" />
+    <style name="TextAppearance.Material.Widget.ActionMode.Subtitle" parent="TextAppearance.Material.Subhead" />
+    <style name="TextAppearance.Material.Widget.ActionMode.Subtitle.Inverse" parent="TextAppearance.Material.Subhead.Inverse" />
+
+    <style name="TextAppearance.Material.Widget.ActionBar.Title" parent="TextAppearance.Material.Title" />
+    <style name="TextAppearance.Material.Widget.ActionBar.Title.Inverse" parent="TextAppearance.Material.Title.Inverse" />
+    <style name="TextAppearance.Material.Widget.ActionBar.Subtitle" parent="TextAppearance.Material.Subhead" />
+    <style name="TextAppearance.Material.Widget.ActionBar.Subtitle.Inverse" parent="TextAppearance.Material.Subhead.Inverse" />
+
+    <style name="TextAppearance.Material.Widget.ActionBar.Menu" parent="TextAppearance.Material.Menu">
+        <item name="textColor">?attr/actionMenuTextColor</item>
+        <item name="textAllCaps">@bool/config_actionMenuItemAllCaps</item>
+    </style>
+
+    <style name="TextAppearance.Material.Widget.ActionBar.Menu.Inverse" parent="TextAppearance.Material.Menu.Inverse">
+        <item name="textColor">?attr/actionMenuTextColor</item>
+        <item name="textAllCaps">@bool/config_actionMenuItemAllCaps</item>
+    </style>
+
+    <style name="TextAppearance.Material.WindowTitle" parent="TextAppearance.Material.Headline" />
+    <style name="TextAppearance.Material.DialogWindowTitle" parent="TextAppearance.Material.Headline" />
+
+    <style name="TextAppearance.Material.CalendarViewWeekDayView" parent="TextAppearance.Material.Small">
+        <item name="textStyle">bold</item>
+        <item name="textColor">#505050</item>
+    </style>
+
+    <style name="TextAppearance.Material.TimePicker.TimeLabel" parent="TextAppearance.Material">
+        <item name="textSize">@dimen/timepicker_time_label_size</item>
+        <item name="textColor">?attr/textColorSecondary</item>
+    </style>
+
+    <style name="TextAppearance.Material.TimePicker.AmPmLabel" parent="TextAppearance.Material">
+        <item name="textSize">@dimen/timepicker_ampm_label_size</item>
+        <item name="textAllCaps">true</item>
+        <item name="textColor">?attr/textColorSecondary</item>
+        <item name="textStyle">bold</item>
+    </style>
+
+    <style name="TextAppearance.StatusBar.Material" />
+
+    <style name="TextAppearance.StatusBar.Material.EventContent">
+        <item name="android:textColor">#90000000</item>
+        <item name="android:textSize">@dimen/notification_text_size</item>
+    </style>
+
+    <style name="TextAppearance.StatusBar.Material.EventContent.Title">
+        <item name="android:textColor">#DD000000</item>
+        <item name="android:textSize">@dimen/notification_title_text_size</item>
+    </style>
+
+    <style name="TextAppearance.StatusBar.Material.EventContent.Line2">
+        <item name="android:textSize">@dimen/notification_subtext_size</item>
+    </style>
+
+    <style name="TextAppearance.StatusBar.Material.EventContent.Info">
+        <item name="android:textSize">@dimen/notification_subtext_size</item>
+    </style>
+
+    <style name="TextAppearance.StatusBar.Material.EventContent.Time">
+        <item name="android:textSize">@dimen/notification_subtext_size</item>
+    </style>
+
+    <style name="TextAppearance.StatusBar.Material.EventContent.Emphasis">
+        <item name="android:textColor">#66000000</item>
+    </style>
+
+    <style name="Widget.StatusBar.Material.ProgressBar" parent="Widget.Material.Light.ProgressBar.Horizontal">
+        <item name="android:progressDrawable">@drawable/notification_material_media_progress</item>
+    </style>
+
+    <!-- Widget Styles -->
+
+    <style name="Material"/>
+    <style name="Material.Light"/>
+    <style name="Widget.Material" parent="Widget" />
+
+    <!-- Bordered ink button -->
+    <style name="Widget.Material.Button" parent="Widget.Button">
+        <item name="background">@drawable/btn_default_material</item>
+        <item name="textAppearance">?attr/textAppearanceButton</item>
+        <item name="textColor">?attr/textColorPrimary</item>
+        <item name="minHeight">48dip</item>
+        <item name="minWidth">88dip</item>
+
+        <!-- TODO: Turn this back on when we support inset drawable outlines. -->
+        <!-- <item name="stateListAnimator">@anim/button_state_list_anim_material</item> -->
+    </style>
+
+    <!-- Small bordered ink button -->
+    <style name="Widget.Material.Button.Small">
+        <item name="minHeight">48dip</item>
+        <item name="minWidth">48dip</item>
+    </style>
+
+    <!-- Borderless ink button -->
+    <style name="Widget.Material.Button.Borderless">
+        <item name="background">@drawable/btn_borderless_material</item>
+        <item name="stateListAnimator">@null</item>
+    </style>
+
+    <!-- Small borderless ink button -->
+    <style name="Widget.Material.Button.Borderless.Small">
+        <item name="minHeight">48dip</item>
+        <item name="minWidth">48dip</item>
+    </style>
+
+    <style name="Widget.Material.Button.Inset">
+        <item name="background">@drawable/button_inset</item>
+    </style>
+
+    <style name="Widget.Material.Button.Toggle">
+        <item name="background">@drawable/btn_toggle_material</item>
+        <item name="textOn">@string/capital_on</item>
+        <item name="textOff">@string/capital_off</item>
+        <item name="minHeight">48dip</item>
+    </style>
+
+    <style name="Widget.Material.ButtonBar">
+        <item name="background">@null</item>
+    </style>
+
+    <style name="Widget.Material.ButtonBar.AlertDialog">
+        <item name="background">@null</item>
+    </style>
+
+    <style name="Widget.Material.SegmentedButton" parent="SegmentedButton">
+        <item name="background">@drawable/btn_group_holo_dark</item>
+    </style>
+
+    <style name="Widget.Material.StackView">
+        <item name="resOutColor">@color/holo_blue_light</item>
+        <item name="clickColor">@color/holo_blue_light</item>
+    </style>
+
+    <style name="Widget.Material.TextView" parent="Widget.TextView"/>
+
+    <style name="Widget.Material.TextView.ListSeparator" parent="Widget.TextView.ListSeparator">
+        <item name="background">@drawable/list_section_divider_material</item>
+        <item name="textAllCaps">true</item>
+    </style>
+
+    <style name="Widget.Material.TextView.SpinnerItem" parent="Widget.TextView.SpinnerItem">
+        <item name="textAppearance">@style/TextAppearance.Material.Widget.TextView.SpinnerItem</item>
+        <item name="paddingStart">8dp</item>
+        <item name="paddingEnd">8dp</item>
+    </style>
+
+    <style name="Widget.Material.CheckedTextView" parent="Widget.CheckedTextView" />
+    <style name="Widget.Material.TextSelectHandle" parent="Widget.TextSelectHandle"/>
+    <style name="Widget.Material.TextSuggestionsPopupWindow" parent="Widget.TextSuggestionsPopupWindow"/>
+    <style name="Widget.Material.AbsListView" parent="Widget.AbsListView"/>
+
+    <style name="Widget.Material.AutoCompleteTextView" parent="Widget.AutoCompleteTextView">
+        <item name="dropDownSelector">?attr/listChoiceBackgroundIndicator</item>
+        <item name="popupBackground">@drawable/popup_background_material</item>
+    </style>
+
+    <style name="Widget.Material.CompoundButton" parent="Widget.CompoundButton"/>
+
+    <style name="Widget.Material.CompoundButton.CheckBox" parent="Widget.CompoundButton.CheckBox">
+        <item name="background">?attr/selectableItemBackgroundBorderless</item>
+    </style>
+
+    <style name="Widget.Material.CompoundButton.RadioButton" parent="Widget.CompoundButton.RadioButton">
+        <item name="background">?attr/selectableItemBackgroundBorderless</item>
+    </style>
+
+    <style name="Widget.Material.CompoundButton.Star" parent="Widget.CompoundButton.Star">
+        <item name="button">@drawable/btn_star_material</item>
+        <item name="background">?attr/selectableItemBackgroundBorderless</item>
+    </style>
+
+    <style name="Widget.Material.CompoundButton.Switch">
+        <item name="track">@drawable/switch_track_material</item>
+        <item name="thumb">@drawable/switch_thumb_material_anim</item>
+        <item name="splitTrack">true</item>
+        <item name="switchTextAppearance">@style/TextAppearance.Material.Widget.Switch</item>
+        <item name="textOn"></item>
+        <item name="textOff"></item>
+        <item name="switchMinWidth">4dip</item>
+        <item name="switchPadding">4dip</item>
+        <item name="background">?attr/selectableItemBackgroundBorderless</item>
+    </style>
+
+    <style name="Widget.Material.EditText" parent="Widget.EditText"/>
+
+    <style name="Widget.Material.ExpandableListView" parent="Widget.Material.ListView">
+        <item name="groupIndicator">@drawable/expander_group_material</item>
+        <item name="indicatorLeft">?attr/expandableListPreferredItemIndicatorLeft</item>
+        <item name="indicatorRight">?attr/expandableListPreferredItemIndicatorRight</item>
+        <item name="childDivider">?attr/listDivider</item>
+    </style>
+
+    <style name="Widget.Material.ExpandableListView.White"/>
+    <style name="Widget.Material.Gallery" parent="Widget.Gallery"/>
+    <style name="Widget.Material.GestureOverlayView" parent="Widget.GestureOverlayView"/>
+
+    <style name="Widget.Material.GridView" parent="Widget.GridView">
+        <item name="android:listSelector">?attr/selectableItemBackground</item>
+    </style>
+
+    <style name="Widget.Material.CalendarView" parent="Widget.CalendarView">
+        <item name="selectedWeekBackgroundColor">#330099FF</item>
+        <item name="focusedMonthDateColor">#FFFFFFFF</item>
+        <item name="unfocusedMonthDateColor">#66FFFFFF</item>
+        <item name="weekNumberColor">#33FFFFFF</item>
+        <item name="weekSeparatorLineColor">#19FFFFFF</item>
+        <item name="selectedDateVerticalBar">@drawable/day_picker_week_view_dayline_holo</item>
+        <item name="weekDayTextAppearance">@style/TextAppearance.Material.CalendarViewWeekDayView</item>
+    </style>
+
+    <style name="Widget.Material.ImageButton" parent="Widget.ImageButton">
+        <item name="background">@drawable/btn_default_material</item>
+    </style>
+
+    <style name="Widget.Material.NumberPicker" parent="Widget.NumberPicker">
+        <item name="internalLayout">@layout/number_picker_with_selector_wheel</item>
+        <item name="solidColor">@color/transparent</item>
+        <item name="selectionDivider">@drawable/numberpicker_selection_divider</item>
+        <item name="selectionDividerHeight">2dip</item>
+        <item name="selectionDividersDistance">48dip</item>
+        <item name="internalMinWidth">64dip</item>
+        <item name="internalMaxHeight">180dip</item>
+        <item name="virtualButtonPressedDrawable">?attr/selectableItemBackground</item>
+    </style>
+
+    <style name="Widget.Material.TimePicker" parent="Widget.TimePicker">
+        <item name="legacyLayout">@layout/time_picker_legacy_holo</item>
+        <item name="internalLayout">@layout/time_picker_holo</item>
+        <item name="disabledColor">@color/bright_foreground_disabled_material_dark</item>
+        <item name="headerSelectedTextColor">?attr/colorControlActivated</item>
+        <item name="headerUnselectedTextColor">?attr/textColorPrimary</item>
+        <item name="headerBackgroundColor">@color/transparent</item>
+        <item name="numbersTextColor">?attr/textColorSecondary</item>
+        <item name="numbersBackgroundColor">@color/transparent</item>
+        <item name="amPmTextColor">?attr/textColorSecondary</item>
+        <item name="amPmUnselectedBackgroundColor">@color/transparent</item>
+        <item name="amPmSelectedBackgroundColor">?attr/colorControlActivated</item>
+        <item name="numbersSelectorColor">?attr/colorControlActivated</item>
+    </style>
+
+    <style name="Widget.Material.DatePicker" parent="Widget.DatePicker">
+        <item name="internalLayout">@layout/date_picker_holo</item>
+        <item name="calendarViewShown">true</item>
+    </style>
+
+    <style name="Widget.Material.ActivityChooserView" parent="Widget.ActivityChooserView">
+        <item name="background">@drawable/ab_share_pack_material</item>
+    </style>
+
+    <style name="Widget.Material.ImageWell" parent="Widget.ImageWell"/>
+
+    <style name="Widget.Material.ListView" parent="Widget.ListView">
+        <item name="divider">?attr/listDivider</item>
+        <item name="listSelector">?attr/listChoiceBackgroundIndicator</item>
+    </style>
+
+    <style name="Widget.Material.ListView.DropDown"/>
+    <style name="Widget.Material.ListView.White"/>
+
+    <style name="Widget.Material.PopupWindow" parent="Widget.PopupWindow"/>
+
+    <style name="Widget.Material.PopupWindow.ActionMode">
+        <item name="popupBackground">@drawable/popup_background_material</item>
+        <item name="popupAnimationStyle">@style/Animation.PopupWindow.ActionMode</item>
+    </style>
+
+    <style name="Widget.Material.ProgressBar" parent="Widget.ProgressBar">
+        <item name="indeterminateDrawable">@drawable/progress_medium_material</item>
+    </style>
+
+    <style name="Widget.Material.ProgressBar.Inverse"/>
+
+    <style name="Widget.Material.ProgressBar.Horizontal" parent="Widget.ProgressBar.Horizontal">
+        <item name="progressDrawable">@drawable/progress_horizontal_material</item>
+        <item name="indeterminateDrawable">@drawable/progress_indeterminate_horizontal_holo</item>
+        <item name="minHeight">16dip</item>
+        <item name="maxHeight">16dip</item>
+    </style>
+
+    <style name="Widget.Material.ProgressBar.Small" parent="Widget.ProgressBar.Small">
+        <item name="indeterminateDrawable">@drawable/progress_small_material</item>
+    </style>
+
+    <style name="Widget.Material.ProgressBar.Small.Inverse"/>
+    <style name="Widget.Material.ProgressBar.Small.Title"/>
+
+    <style name="Widget.Material.ProgressBar.Large" parent="Widget.ProgressBar.Large">
+        <item name="indeterminateDrawable">@drawable/progress_large_material</item>
+    </style>
+
+    <style name="Widget.Material.ProgressBar.Large.Inverse"/>
+
+    <style name="Widget.Material.SeekBar">
+        <item name="indeterminateOnly">false</item>
+        <item name="progressDrawable">@drawable/scrubber_progress_horizontal_material</item>
+        <item name="indeterminateDrawable">@drawable/scrubber_progress_horizontal_material</item>
+        <item name="thumb">@drawable/scrubber_control_material_anim</item>
+        <item name="splitTrack">true</item>
+        <item name="focusable">true</item>
+        <item name="paddingStart">16dip</item>
+        <item name="paddingEnd">16dip</item>
+        <item name="mirrorForRtl">true</item>
+        <item name="background">?attr/selectableItemBackgroundBorderless</item>
+    </style>
+
+    <style name="Widget.Material.RatingBar" parent="Widget.RatingBar">
+        <item name="progressDrawable">@drawable/ratingbar_full_material</item>
+        <item name="indeterminateDrawable">@drawable/ratingbar_full_material</item>
+    </style>
+
+    <style name="Widget.Material.RatingBar.Indicator" parent="Widget.RatingBar.Indicator">
+        <item name="progressDrawable">@drawable/ratingbar_holo_dark</item>
+        <item name="indeterminateDrawable">@drawable/ratingbar_holo_dark</item>
+        <item name="minHeight">35dip</item>
+        <item name="maxHeight">35dip</item>
+    </style>
+
+    <style name="Widget.Material.RatingBar.Small" parent="Widget.RatingBar.Small">
+        <item name="progressDrawable">@drawable/ratingbar_small_holo_dark</item>
+        <item name="indeterminateDrawable">@drawable/ratingbar_small_holo_dark</item>
+        <item name="minHeight">16dip</item>
+        <item name="maxHeight">16dip</item>
+    </style>
+
+    <style name="Widget.Material.ScrollView" parent="Widget.ScrollView"/>
+    <style name="Widget.Material.HorizontalScrollView" parent="Widget.HorizontalScrollView"/>
+
+    <style name="Widget.Material.Spinner" parent="Widget.Spinner.DropDown">
+        <item name="background">@drawable/spinner_background_material</item>
+        <item name="dropDownSelector">?attr/listChoiceBackgroundIndicator</item>
+        <item name="popupBackground">@drawable/popup_background_material</item>
+        <item name="dropDownVerticalOffset">0dip</item>
+        <item name="dropDownHorizontalOffset">0dip</item>
+        <item name="dropDownWidth">wrap_content</item>
+        <item name="popupPromptView">@layout/simple_dropdown_hint</item>
+        <item name="gravity">start|center_vertical</item>
+        <item name="disableChildrenWhenDisabled">true</item>
+    </style>
+
+    <style name="Widget.Material.Spinner.DropDown"/>
+
+    <style name="Widget.Material.Spinner.DropDown.ActionBar">
+        <item name="background">@drawable/spinner_background_material</item>
+    </style>
+
+    <style name="Widget.Material.TabWidget" parent="Widget.TabWidget">
+        <item name="tabStripLeft">@null</item>
+        <item name="tabStripRight">@null</item>
+        <item name="tabStripEnabled">false</item>
+        <item name="divider">?attr/dividerVertical</item>
+        <item name="showDividers">middle</item>
+        <item name="dividerPadding">8dip</item>
+        <item name="measureWithLargestChild">true</item>
+        <item name="tabLayout">@layout/tab_indicator_material</item>
+    </style>
+
+    <style name="Widget.Material.Tab" parent="Widget.Material.ActionBar.TabView">
+        <item name="background">@drawable/tab_indicator_material</item>
+        <item name="layout_width">0dip</item>
+        <item name="layout_weight">1</item>
+        <item name="minWidth">80dip</item>
+    </style>
+
+    <style name="Widget.Material.TabText" parent="Widget.Material.ActionBar.TabText">
+        <item name="maxWidth">180dip</item>
+    </style>
+
+    <style name="Widget.Material.WebTextView" parent="Widget.WebTextView"/>
+
+    <style name="Widget.Material.WebView" parent="Widget.WebView"/>
+
+    <style name="Widget.Material.DropDownItem" parent="Widget.DropDownItem">
+        <item name="textAppearance">@style/TextAppearance.Material.Widget.DropDownItem</item>
+        <item name="paddingStart">8dp</item>
+        <item name="paddingEnd">8dp</item>
+    </style>
+
+    <style name="Widget.Material.DropDownItem.Spinner"/>
+
+    <style name="Widget.Material.KeyboardView" parent="Widget.KeyboardView"/>
+    <style name="Widget.Material.QuickContactBadge.WindowSmall" parent="Widget.QuickContactBadge.WindowSmall"/>
+    <style name="Widget.Material.QuickContactBadge.WindowMedium" parent="Widget.QuickContactBadge.WindowMedium"/>
+    <style name="Widget.Material.QuickContactBadge.WindowLarge" parent="Widget.QuickContactBadge.WindowLarge"/>
+    <style name="Widget.Material.QuickContactBadgeSmall.WindowSmall" parent="Widget.QuickContactBadgeSmall.WindowSmall"/>
+    <style name="Widget.Material.QuickContactBadgeSmall.WindowMedium" parent="Widget.QuickContactBadgeSmall.WindowMedium"/>
+    <style name="Widget.Material.QuickContactBadgeSmall.WindowLarge" parent="Widget.QuickContactBadgeSmall.WindowLarge"/>
+
+    <style name="Widget.Material.ListPopupWindow" parent="Widget.ListPopupWindow">
+        <item name="dropDownSelector">?attr/listChoiceBackgroundIndicator</item>
+        <item name="popupBackground">@drawable/popup_background_material</item>
+        <item name="popupAnimationStyle">@style/Animation.Material.Popup</item>
+        <item name="dropDownVerticalOffset">0dip</item>
+        <item name="dropDownHorizontalOffset">0dip</item>
+        <item name="dropDownWidth">wrap_content</item>
+    </style>
+
+    <style name="Widget.Material.PopupMenu" parent="Widget.Material.ListPopupWindow"/>
+
+    <style name="Widget.Material.PopupMenu.Overflow">
+        <item name="overlapAnchor">true</item>
+    </style>
+
+    <style name="Widget.Material.ActionButton" parent="Widget.ActionButton">
+        <item name="minWidth">@dimen/action_button_min_width_material</item>
+        <item name="minHeight">@dimen/action_button_min_height_material</item>
+        <item name="gravity">center</item>
+        <item name="scaleType">center</item>
+        <item name="maxLines">2</item>
+    </style>
+
+    <style name="Widget.Material.ActionButton.CloseMode">
+        <item name="background">@drawable/btn_cab_done_material</item>
+    </style>
+
+    <style name="Widget.Material.ActionButton.Overflow">
+        <item name="src">@drawable/ic_menu_moreoverflow_material</item>
+        <item name="background">?attr/actionBarItemBackground</item>
+        <item name="contentDescription">@string/action_menu_overflow_description</item>
+        <item name="minWidth">@dimen/action_overflow_min_width_material</item>
+        <item name="minHeight">@dimen/action_button_min_height_material</item>
+        <item name="scaleType">center</item>
+    </style>
+
+    <style name="Widget.Material.ActionBar.TabView" parent="Widget.ActionBar.TabView">
+        <item name="background">@drawable/tab_indicator_material</item>
+        <item name="paddingStart">16dip</item>
+        <item name="paddingEnd">16dip</item>
+    </style>
+
+    <style name="Widget.Material.ActionBar.TabBar" parent="Widget.ActionBar.TabBar">
+        <item name="divider">?attr/actionBarDivider</item>
+        <item name="showDividers">middle</item>
+        <item name="dividerPadding">12dip</item>
+    </style>
+
+    <style name="Widget.Material.ActionBar.TabText" parent="Widget.ActionBar.TabText">
+        <item name="textAppearance">@style/TextAppearance.Material.Medium</item>
+        <item name="textColor">?attr/textColorPrimary</item>
+        <item name="textSize">12sp</item>
+        <item name="textStyle">bold</item>
+        <item name="textAllCaps">true</item>
+        <item name="ellipsize">marquee</item>
+        <item name="maxLines">2</item>
+    </style>
+
+    <style name="Widget.Material.ActionBar" parent="Widget.ActionBar">
+        <item name="background">@null</item>
+        <item name="backgroundStacked">@null</item>
+        <item name="backgroundSplit">@null</item>
+        <item name="displayOptions">showTitle</item>
+        <item name="divider">?attr/dividerVertical</item>
+        <item name="titleTextStyle">@style/TextAppearance.Material.Widget.ActionBar.Title</item>
+        <item name="subtitleTextStyle">@style/TextAppearance.Material.Widget.ActionBar.Subtitle</item>
+        <item name="progressBarStyle">@style/Widget.Material.ProgressBar.Horizontal</item>
+        <item name="indeterminateProgressStyle">@style/Widget.Material.ProgressBar</item>
+        <item name="progressBarPadding">32dip</item>
+        <item name="itemPadding">8dip</item>
+        <item name="homeLayout">@layout/action_bar_home_material</item>
+        <item name="gravity">center_vertical</item>
+        <item name="contentInsetStart">16dp</item>
+    </style>
+
+    <style name="Widget.Material.ActionBar.Solid">
+        <item name="background">?attr/colorPrimary</item>
+        <item name="backgroundStacked">?attr/colorPrimary</item>
+        <item name="backgroundSplit">?attr/colorPrimary</item>
+    </style>
+
+    <style name="Widget.Material.ActionMode" parent="Widget.ActionMode">
+        <item name="titleTextStyle">@style/TextAppearance.Material.Widget.ActionMode.Title</item>
+        <item name="subtitleTextStyle">@style/TextAppearance.Material.Widget.ActionMode.Subtitle</item>
+    </style>
+
+    <style name="Widget.Material.FastScroll" parent="Widget.FastScroll">
+        <item name="thumbMinWidth">0dp</item>
+        <item name="thumbMinHeight">0dp</item>
+    </style>
+
+    <style name="Widget.Material.PreferenceFrameLayout">
+        <item name="borderTop">0dip</item>
+        <item name="borderBottom">@dimen/preference_fragment_padding_bottom</item>
+        <item name="borderLeft">?attr/preferenceFragmentPaddingSide</item>
+        <item name="borderRight">?attr/preferenceFragmentPaddingSide</item>
+    </style>
+
+    <style name="Widget.Material.MediaRouteButton">
+        <item name="background">?attr/selectableItemBackgroundBorderless</item>
+        <item name="externalRouteEnabledDrawable">@drawable/ic_media_route_material</item>
+        <item name="minWidth">56dp</item>
+        <item name="minHeight">48dp</item>
+        <item name="focusable">true</item>
+        <item name="contentDescription">@string/media_route_button_content_description</item>
+    </style>
+
+    <!-- Light widget styles -->
+
+    <style name="Widget.Material.Light" parent="Widget.Material"/>
+    <style name="Widget.Material.Light.Button" parent="Widget.Material.Button"/>
+    <style name="Widget.Material.Light.Button.Small" parent="Widget.Material.Button.Small"/>
+    <style name="Widget.Material.Light.Button.Borderless" parent="Widget.Material.Button.Borderless"/>
+    <style name="Widget.Material.Light.Button.Borderless.Small" parent="Widget.Material.Button.Borderless.Small"/>
+    <style name="Widget.Material.Light.Button.Inset" parent="Widget.Material.Button.Inset"/>
+    <style name="Widget.Material.Light.Button.Toggle" parent="Widget.Material.Button.Toggle" />
+    <style name="Widget.Material.Light.ButtonBar" parent="Widget.Material.ButtonBar"/>
+    <style name="Widget.Material.Light.ButtonBar.AlertDialog" parent="Widget.Material.ButtonBar.AlertDialog"/>
+
+    <style name="Widget.Material.Light.SegmentedButton" parent="Widget.Material.SegmentedButton">
+        <item name="background">@drawable/btn_group_holo_light</item>
+    </style>
+
+    <style name="Widget.Material.Light.StackView" parent="Widget.Material.StackView"/>
+    <style name="Widget.Material.Light.TextView" parent="Widget.Material.TextView"/>
+    <style name="Widget.Material.Light.TextView.ListSeparator" parent="Widget.Material.TextView.ListSeparator"/>
+    <style name="Widget.Material.Light.TextView.SpinnerItem" parent="Widget.Material.TextView.SpinnerItem"/>
+    <style name="Widget.Material.Light.CheckedTextView" parent="Widget.Material.CheckedTextView"/>
+    <style name="Widget.Material.Light.TextSelectHandle" parent="Widget.Material.TextSelectHandle"/>
+    <style name="Widget.Material.Light.TextSuggestionsPopupWindow" parent="Widget.Material.TextSuggestionsPopupWindow"/>
+    <style name="Widget.Material.Light.AbsListView" parent="Widget.Material.AbsListView"/>
+    <style name="Widget.Material.Light.AutoCompleteTextView" parent="Widget.Material.AutoCompleteTextView" />
+    <style name="Widget.Material.Light.CompoundButton" parent="Widget.Material.CompoundButton"/>
+    <style name="Widget.Material.Light.CompoundButton.CheckBox" parent="Widget.Material.CompoundButton.CheckBox"/>
+    <style name="Widget.Material.Light.CompoundButton.RadioButton" parent="Widget.Material.CompoundButton.RadioButton"/>
+    <style name="Widget.Material.Light.CompoundButton.Star" parent="Widget.Material.CompoundButton.Star"/>
+    <style name="Widget.Material.Light.CompoundButton.Switch" parent="Widget.Material.CompoundButton.Switch" />
+    <style name="Widget.Material.Light.ListView.DropDown" parent="Widget.Material.ListView.DropDown"/>
+    <style name="Widget.Material.Light.EditText" parent="Widget.Material.EditText"/>
+    <style name="Widget.Material.Light.ExpandableListView" parent="Widget.Material.ExpandableListView"/>
+    <style name="Widget.Material.Light.ExpandableListView.White" parent="Widget.Material.ExpandableListView.White"/>
+    <style name="Widget.Material.Light.Gallery" parent="Widget.Material.Gallery"/>
+    <style name="Widget.Material.Light.GestureOverlayView" parent="Widget.Material.GestureOverlayView"/>
+    <style name="Widget.Material.Light.GridView" parent="Widget.Material.GridView"/>
+    <style name="Widget.Material.Light.ImageButton" parent="Widget.Material.ImageButton"/>
+
+    <style name="Widget.Material.Light.CalendarView" parent="Widget.CalendarView">
+        <item name="selectedWeekBackgroundColor">#330066ff</item>
+        <item name="focusedMonthDateColor">#FF000000</item>
+        <item name="unfocusedMonthDateColor">#7F08002B</item>
+        <item name="weekNumberColor">#7F080021</item>
+        <item name="weekSeparatorLineColor">#7F08002A</item>
+        <item name="weekDayTextAppearance">@style/TextAppearance.Material.CalendarViewWeekDayView</item>
+    </style>
+
+    <style name="Widget.Material.Light.NumberPicker" parent="Widget.Material.NumberPicker"/>
+
+    <style name="Widget.Material.Light.TimePicker" parent="Widget.Material.TimePicker">
+        <item name="legacyLayout">@layout/time_picker_legacy_holo</item>
+        <item name="internalLayout">@layout/time_picker_holo</item>
+        <item name="disabledColor">@color/bright_foreground_disabled_material_light</item>
+    </style>
+
+    <style name="Widget.Material.Light.DatePicker" parent="Widget.Material.DatePicker"/>
+    <style name="Widget.Material.Light.ActivityChooserView" parent="Widget.Material.ActivityChooserView" />
+    <style name="Widget.Material.Light.ImageWell" parent="Widget.Material.ImageWell"/>
+    <style name="Widget.Material.Light.ListView" parent="Widget.Material.ListView"/>
+    <style name="Widget.Material.Light.ListView.White" parent="Widget.Material.ListView.White"/>
+    <style name="Widget.Material.Light.PopupWindow" parent="Widget.Material.PopupWindow"/>
+    <style name="Widget.Material.Light.PopupWindow.ActionMode" parent="Widget.Material.PopupWindow.ActionMode"/>
+    <style name="Widget.Material.Light.ProgressBar" parent="Widget.Material.ProgressBar"/>
+    <style name="Widget.Material.Light.ProgressBar.Horizontal" parent="Widget.Material.ProgressBar.Horizontal"/>
+    <style name="Widget.Material.Light.ProgressBar.Small" parent="Widget.Material.ProgressBar.Small"/>
+    <style name="Widget.Material.Light.ProgressBar.Small.Title" parent="Widget.Material.ProgressBar.Small.Title"/>
+    <style name="Widget.Material.Light.ProgressBar.Large" parent="Widget.Material.ProgressBar.Large"/>
+    <style name="Widget.Material.Light.ProgressBar.Inverse" parent="Widget.Material.ProgressBar.Inverse"/>
+    <style name="Widget.Material.Light.ProgressBar.Small.Inverse" parent="Widget.Material.ProgressBar.Small.Inverse"/>
+    <style name="Widget.Material.Light.ProgressBar.Large.Inverse" parent="Widget.Material.ProgressBar.Large.Inverse"/>
+    <style name="Widget.Material.Light.SeekBar" parent="Widget.Material.SeekBar"/>
+    <style name="Widget.Material.Light.RatingBar" parent="Widget.Material.RatingBar" />
+
+    <style name="Widget.Material.Light.RatingBar.Indicator" parent="Widget.RatingBar.Indicator">
+        <item name="progressDrawable">@drawable/ratingbar_holo_light</item>
+        <item name="indeterminateDrawable">@drawable/ratingbar_holo_light</item>
+        <item name="minHeight">35dip</item>
+        <item name="maxHeight">35dip</item>
+    </style>
+
+    <style name="Widget.Material.Light.RatingBar.Small" parent="Widget.RatingBar.Small">
+        <item name="progressDrawable">@drawable/ratingbar_small_holo_light</item>
+        <item name="indeterminateDrawable">@drawable/ratingbar_small_holo_light</item>
+        <item name="minHeight">16dip</item>
+        <item name="maxHeight">16dip</item>
+    </style>
+
+    <style name="Widget.Material.Light.ScrollView" parent="Widget.Material.ScrollView"/>
+    <style name="Widget.Material.Light.HorizontalScrollView" parent="Widget.Material.HorizontalScrollView"/>
+    <style name="Widget.Material.Light.Spinner" parent="Widget.Material.Spinner" />
+    <style name="Widget.Material.Light.Spinner.DropDown" parent="Widget.Material.Spinner.DropDown"/>
+    <style name="Widget.Material.Light.Spinner.DropDown.ActionBar" parent="Widget.Material.Spinner.DropDown.ActionBar"/>
+    <style name="Widget.Material.Light.TabWidget" parent="Widget.Material.TabWidget"/>
+    <style name="Widget.Material.Light.WebTextView" parent="Widget.Material.WebTextView"/>
+    <style name="Widget.Material.Light.WebView" parent="Widget.Material.WebView"/>
+    <style name="Widget.Material.Light.DropDownItem" parent="Widget.Material.DropDownItem"/>
+    <style name="Widget.Material.Light.DropDownItem.Spinner" parent="Widget.Material.DropDownItem.Spinner"/>
+    <style name="Widget.Material.Light.KeyboardView" parent="Widget.Material.KeyboardView"/>
+    <style name="Widget.Material.Light.QuickContactBadge.WindowSmall" parent="Widget.Material.QuickContactBadge.WindowSmall"/>
+    <style name="Widget.Material.Light.QuickContactBadge.WindowMedium" parent="Widget.Material.QuickContactBadge.WindowMedium"/>
+    <style name="Widget.Material.Light.QuickContactBadge.WindowLarge" parent="Widget.Material.QuickContactBadge.WindowLarge"/>
+    <style name="Widget.Material.Light.QuickContactBadgeSmall.WindowSmall" parent="Widget.Material.QuickContactBadgeSmall.WindowSmall"/>
+    <style name="Widget.Material.Light.QuickContactBadgeSmall.WindowMedium" parent="Widget.Material.QuickContactBadgeSmall.WindowMedium"/>
+    <style name="Widget.Material.Light.QuickContactBadgeSmall.WindowLarge" parent="Widget.Material.QuickContactBadgeSmall.WindowLarge"/>
+    <style name="Widget.Material.Light.ListPopupWindow" parent="Widget.Material.ListPopupWindow"/>
+    <style name="Widget.Material.Light.PopupMenu" parent="Widget.Material.ListPopupWindow"/>
+    <style name="Widget.Material.Light.PopupMenu.Overflow" parent="Widget.Material.PopupMenu.Overflow"/>
+    <style name="Widget.Material.Light.ActionButton" parent="Widget.Material.ActionButton"/>
+    <style name="Widget.Material.Light.ActionButton.Overflow" parent="Widget.Material.ActionButton.Overflow"/>
+    <style name="Widget.Material.Light.Tab" parent="Widget.Material.Tab"/>
+    <style name="Widget.Material.Light.ActionBar.TabView" parent="Widget.Material.ActionBar.TabView"/>
+    <style name="Widget.Material.Light.ActionBar.TabBar" parent="Widget.Material.ActionBar.TabBar"/>
+    <style name="Widget.Material.Light.ActionBar.TabText" parent="Widget.Material.ActionBar.TabText"/>
+    <style name="Widget.Material.Light.ActionMode" parent="Widget.Material.ActionMode" />
+    <style name="Widget.Material.Light.ActionButton.CloseMode" parent="Widget.Material.ActionButton.CloseMode" />
+
+    <style name="Widget.Material.Light.ActionBar" parent="Widget.Material.ActionBar">
+        <item name="titleTextStyle">@style/TextAppearance.Material.Widget.ActionBar.Title</item>
+        <item name="subtitleTextStyle">@style/TextAppearance.Material.Widget.ActionBar.Subtitle</item>
+        <item name="background">@null</item>
+        <item name="backgroundStacked">@null</item>
+        <item name="backgroundSplit">@null</item>
+        <item name="homeAsUpIndicator">@drawable/ic_ab_back_material</item>
+        <item name="progressBarStyle">@style/Widget.Material.Light.ProgressBar.Horizontal</item>
+        <item name="indeterminateProgressStyle">@style/Widget.Material.Light.ProgressBar</item>
+    </style>
+
+    <style name="Widget.Material.Light.ActionBar.Solid">
+        <item name="background">?attr/colorPrimary</item>
+        <item name="backgroundStacked">?attr/colorPrimary</item>
+        <item name="backgroundSplit">?attr/colorPrimary</item>
+    </style>
+
+    <style name="Widget.Material.Light.FastScroll" parent="Widget.Material.FastScroll"/>
+    <style name="Widget.Material.Light.MediaRouteButton" parent="Widget.Material.MediaRouteButton" />
+
+    <!-- Animation Styles -->
+
+    <style name="Animation.Material" parent="Animation"/>
+    <style name="Animation.Material.Activity" parent="Animation.Activity"/>
+
+    <style name="Animation.Material.Dialog">
+        <item name="windowEnterAnimation">@anim/popup_enter_material</item>
+        <item name="windowExitAnimation">@anim/popup_exit_material</item>
+    </style>
+
+    <style name="Animation.Material.Popup">
+        <item name="windowEnterAnimation">@anim/popup_enter_material</item>
+        <item name="windowExitAnimation">@anim/popup_exit_material</item>
+    </style>
+
+    <!-- Dialog styles -->
+
+    <style name="AlertDialog.Material" parent="AlertDialog">
+        <item name="fullDark">@color/transparent</item>
+        <item name="topDark">@color/transparent</item>
+        <item name="centerDark">@color/transparent</item>
+        <item name="bottomDark">@color/transparent</item>
+        <item name="fullBright">@color/transparent</item>
+        <item name="topBright">@color/transparent</item>
+        <item name="centerBright">@color/transparent</item>
+        <item name="bottomBright">@color/transparent</item>
+        <item name="bottomMedium">@color/transparent</item>
+        <item name="centerMedium">@color/transparent</item>
+        <item name="layout">@layout/alert_dialog_material</item>
+        <item name="listLayout">@layout/select_dialog_material</item>
+        <item name="progressLayout">@layout/progress_dialog_material</item>
+        <item name="horizontalProgressLayout">@layout/alert_dialog_progress_material</item>
+        <item name="listItemLayout">@layout/select_dialog_item_material</item>
+        <item name="multiChoiceItemLayout">@layout/select_dialog_multichoice_material</item>
+        <item name="singleChoiceItemLayout">@layout/select_dialog_singlechoice_material</item>
+    </style>
+
+    <style name="AlertDialog.Material.Light"/>
+
+    <!-- Window title -->
+    <style name="WindowTitleBackground.Material">
+        <item name="background">@null</item>
+    </style>
+
+    <style name="WindowTitle.Material">
+        <item name="singleLine">true</item>
+        <item name="textAppearance">@style/TextAppearance.Material.WindowTitle</item>
+        <item name="shadowRadius">0</item>
+    </style>
+
+    <style name="DialogWindowTitle.Material">
+        <item name="maxLines">1</item>
+        <item name="scrollHorizontally">true</item>
+        <item name="textAppearance">@style/TextAppearance.Material.DialogWindowTitle</item>
+    </style>
+
+    <style name="DialogWindowTitle.Material.Light">
+        <item name="textAppearance">@style/TextAppearance.Material.DialogWindowTitle</item>
+    </style>
+
+</resources>
diff --git a/core/res/res/values/styles_quantum.xml b/core/res/res/values/styles_quantum.xml
deleted file mode 100644
index 108334fa..0000000
--- a/core/res/res/values/styles_quantum.xml
+++ /dev/null
@@ -1,1016 +0,0 @@
-<?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 Quantum 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 styles_device_defaults.xml.
-
-===============================================================
-                        PLEASE READ
-===============================================================
- -->
-<resources>
-    <!-- Preference styles -->
-    <eat-comment/>
-
-    <style name="Preference.Quantum">
-        <item name="layout">@layout/preference_quantum</item>
-    </style>
-
-    <style name="PreferenceFragment.Quantum">
-        <item name="paddingStart">@dimen/preference_fragment_padding_side</item>
-        <item name="paddingEnd">@dimen/preference_fragment_padding_side</item>
-    </style>
-
-    <style name="Preference.Quantum.Information">
-        <item name="layout">@layout/preference_information_quantum</item>
-        <item name="enabled">false</item>
-        <item name="shouldDisableView">false</item>
-    </style>
-
-    <style name="Preference.Quantum.Category">
-        <item name="layout">@layout/preference_category_quantum</item>
-        <!-- The title should not dim if the category is disabled, instead only the preference children should dim. -->
-        <item name="shouldDisableView">false</item>
-        <item name="selectable">false</item>
-    </style>
-
-    <style name="Preference.Quantum.CheckBoxPreference">
-        <item name="widgetLayout">@layout/preference_widget_checkbox</item>
-    </style>
-
-    <style name="Preference.Quantum.SwitchPreference">
-        <item name="widgetLayout">@layout/preference_widget_switch</item>
-        <item name="switchTextOn">@string/capital_on</item>
-        <item name="switchTextOff">@string/capital_off</item>
-    </style>
-
-    <style name="Preference.Quantum.PreferenceScreen"/>
-
-    <style name="Preference.Quantum.DialogPreference">
-        <item name="positiveButtonText">@string/ok</item>
-        <item name="negativeButtonText">@string/cancel</item>
-    </style>
-
-    <style name="Preference.Quantum.DialogPreference.YesNoPreference">
-        <item name="positiveButtonText">@string/yes</item>
-        <item name="negativeButtonText">@string/no</item>
-    </style>
-
-    <style name="Preference.Quantum.DialogPreference.EditTextPreference">
-        <item name="dialogLayout">@layout/preference_dialog_edittext</item>
-    </style>
-
-    <style name="Preference.Quantum.RingtonePreference">
-        <item name="ringtoneType">ringtone</item>
-        <item name="showSilent">true</item>
-        <item name="showDefault">true</item>
-    </style>
-
-    <!-- Begin Quantum theme styles -->
-
-    <!-- Text styles -->
-
-    <style name="TextAppearance.Quantum">
-        <item name="textColor">?textColorPrimary</item>
-        <item name="textColorHint">?textColorHint</item>
-        <item name="textColorHighlight">?textColorHighlight</item>
-        <item name="textColorLink">?textColorLink</item>
-        <item name="textSize">@dimen/text_size_body_1_quantum</item>
-        <item name="fontFamily">@string/font_family_body_1_quantum</item>
-        <item name="elegantTextHeight">true</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Display4">
-        <item name="textSize">@dimen/text_size_display_4_quantum</item>
-        <item name="fontFamily">@string/font_family_display_4_quantum</item>
-        <item name="textColor">?textColorSecondary</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Display3">
-        <item name="textSize">@dimen/text_size_display_3_quantum</item>
-        <item name="fontFamily">@string/font_family_display_3_quantum</item>
-        <item name="textColor">?textColorSecondary</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Display2">
-        <item name="textSize">@dimen/text_size_display_2_quantum</item>
-        <item name="fontFamily">@string/font_family_display_2_quantum</item>
-        <item name="textColor">?textColorSecondary</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Display1">
-        <item name="textSize">@dimen/text_size_display_1_quantum</item>
-        <item name="fontFamily">@string/font_family_display_1_quantum</item>
-        <item name="textColor">?textColorSecondary</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Headline">
-        <item name="textSize">@dimen/text_size_headline_quantum</item>
-        <item name="fontFamily">@string/font_family_headline_quantum</item>
-        <item name="textColor">?textColorPrimary</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Title">
-        <item name="textSize">@dimen/text_size_title_quantum</item>
-        <item name="fontFamily">@string/font_family_title_quantum</item>
-        <item name="textColor">?textColorPrimary</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Subhead">
-        <item name="textSize">@dimen/text_size_subhead_quantum</item>
-        <item name="fontFamily">@string/font_family_subhead_quantum</item>
-        <item name="textColor">?textColorPrimary</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Body2">
-        <item name="textSize">@dimen/text_size_body_2_quantum</item>
-        <item name="fontFamily">@string/font_family_body_2_quantum</item>
-        <item name="textColor">?textColorPrimary</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Body1">
-        <item name="textSize">@dimen/text_size_body_1_quantum</item>
-        <item name="fontFamily">@string/font_family_body_1_quantum</item>
-        <item name="textColor">?textColorPrimary</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Caption">
-        <item name="textSize">@dimen/text_size_caption_quantum</item>
-        <item name="fontFamily">@string/font_family_caption_quantum</item>
-        <item name="textColor">?textColorSecondary</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Menu">
-        <item name="textSize">@dimen/text_size_menu_quantum</item>
-        <item name="fontFamily">@string/font_family_menu_quantum</item>
-        <item name="textColor">?textColorPrimary</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Button">
-        <item name="textSize">@dimen/text_size_button_quantum</item>
-        <item name="fontFamily">@string/font_family_button_quantum</item>
-        <item name="textAllCaps">true</item>
-        <item name="textColor">?textColorPrimary</item>
-    </style>
-
-    <!-- Deprecated text styles -->
-
-    <style name="TextAppearance.Quantum.Inverse">
-        <item name="textColor">?attr/textColorPrimaryInverse</item>
-        <item name="textColorHint">?attr/textColorHintInverse</item>
-        <item name="textColorHighlight">?attr/textColorHighlightInverse</item>
-        <item name="textColorLink">?attr/textColorLinkInverse</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Large">
-        <item name="textSize">@dimen/text_size_large_quantum</item>
-        <item name="textColor">?attr/textColorPrimary</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Large.Inverse">
-        <item name="textColor">?attr/textColorPrimaryInverse</item>
-        <item name="textColorHint">?attr/textColorHintInverse</item>
-        <item name="textColorHighlight">?attr/textColorHighlightInverse</item>
-        <item name="textColorLink">?attr/textColorLinkInverse</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Medium">
-        <item name="textSize">@dimen/text_size_medium_quantum</item>
-        <item name="textColor">?attr/textColorSecondary</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Medium.Inverse">
-        <item name="textColor">?attr/textColorSecondaryInverse</item>
-        <item name="textColorHint">?attr/textColorHintInverse</item>
-        <item name="textColorHighlight">?attr/textColorHighlightInverse</item>
-        <item name="textColorLink">?attr/textColorLinkInverse</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Small">
-        <item name="textSize">@dimen/text_size_small_quantum</item>
-        <item name="textColor">?attr/textColorTertiary</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Small.Inverse">
-        <item name="textColor">?attr/textColorTertiaryInverse</item>
-        <item name="textColorHint">?attr/textColorHintInverse</item>
-        <item name="textColorHighlight">?attr/textColorHighlightInverse</item>
-        <item name="textColorLink">?attr/textColorLinkInverse</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.SearchResult">
-    </style>
-
-    <style name="TextAppearance.Quantum.SearchResult.Title" parent="TextAppearance.Quantum.Title" />
-    <style name="TextAppearance.Quantum.SearchResult.Subtitle" parent="TextAppearance.Quantum.Subhead" />
-
-    <style name="TextAppearance.Quantum.Widget"/>
-    <style name="TextAppearance.Quantum.Widget.Button" parent="TextAppearance.Quantum.Button" />
-
-    <style name="TextAppearance.Quantum.Widget.EditText">
-        <item name="textColor">?attr/textColorPrimaryInverse</item>
-        <item name="textColorHint">?attr/textColorHintInverse</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Widget.Switch">
-        <item name="textSize">14sp</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Widget.PopupMenu"/>
-
-    <style name="TextAppearance.Quantum.Widget.PopupMenu.Large">
-        <item name="fontFamily">@string/font_family_menu_quantum</item>
-        <item name="textSize">@dimen/text_size_menu_quantum</item>>
-    </style>
-
-    <style name="TextAppearance.Quantum.Widget.PopupMenu.Small">
-        <item name="fontFamily">@string/font_family_menu_quantum</item>
-        <item name="textSize">@dimen/text_size_menu_quantum</item>>
-    </style>
-
-    <style name="TextAppearance.Quantum.Widget.DropDownHint">
-        <item name="fontFamily">@string/font_family_menu_quantum</item>
-        <item name="textSize">@dimen/text_size_menu_quantum</item>>
-    </style>
-
-    <style name="TextAppearance.Quantum.Widget.IconMenu.Item" parent="TextAppearance.Quantum.Small">
-        <item name="textColor">?attr/textColorPrimary</item>
-    </style>
-
-    <!-- This style is for smaller screens; values-xlarge defines a version
-         for larger screens. -->
-    <style name="TextAppearance.Quantum.Widget.TabWidget">
-        <item name="textSize">14sp</item>
-        <item name="textStyle">normal</item>
-        <item name="textColor">@color/tab_indicator_text</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Widget.TextView">
-        <item name="textColor">?attr/textColorPrimaryDisableOnly</item>
-        <item name="textColorHint">?attr/textColorHint</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Widget.TextView.PopupMenu">
-        <item name="fontFamily">@string/font_family_menu_quantum</item>
-        <item name="textSize">@dimen/text_size_menu_quantum</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Widget.TextView.SpinnerItem"/>
-
-    <style name="TextAppearance.Quantum.Widget.DropDownItem">
-        <item name="textColor">?attr/textColorPrimaryDisableOnly</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Widget.ActionMode"/>
-
-    <style name="TextAppearance.Quantum.Widget.ActionMode.Title" parent="TextAppearance.Quantum.Medium">
-        <item name="textSize">@dimen/action_bar_title_text_size_quantum</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Widget.ActionMode.Title.Inverse" parent="TextAppearance.Quantum.Medium.Inverse">
-        <item name="textSize">@dimen/action_bar_title_text_size_quantum</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Widget.ActionMode.Subtitle" parent="TextAppearance.Quantum.Small">
-        <item name="textSize">@dimen/action_bar_subtitle_text_size_quantum</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Widget.ActionMode.Subtitle.Inverse" parent="TextAppearance.Quantum.Small.Inverse">
-        <item name="textSize">@dimen/action_bar_subtitle_text_size_quantum</item>
-    </style>
-
-    <!-- Text styles with no light versions -->
-
-    <style name="TextAppearance.Quantum.Widget.ActionBar.Title" parent="TextAppearance.Quantum.Medium">
-        <item name="textSize">@dimen/action_bar_title_text_size_quantum</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Widget.ActionBar.Title.Inverse" parent="TextAppearance.Quantum.Medium.Inverse">
-        <item name="textSize">@dimen/action_bar_title_text_size_quantum</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Widget.ActionBar.Subtitle" parent="TextAppearance.Quantum.Small">
-        <item name="textSize">@dimen/action_bar_subtitle_text_size_quantum</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Widget.ActionBar.Subtitle.Inverse" parent="TextAppearance.Quantum.Small.Inverse">
-        <item name="textSize">@dimen/action_bar_subtitle_text_size_quantum</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Widget.ActionBar.Menu" parent="TextAppearance.Quantum.Small">
-        <item name="fontFamily">@string/font_family_menu_quantum</item>
-        <item name="textSize">@dimen/text_size_menu_quantum</item>>
-        <item name="textColor">?attr/actionMenuTextColor</item>
-        <item name="textAllCaps">@bool/config_actionMenuItemAllCaps</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Widget.ActionBar.Menu.Inverse" parent="TextAppearance.Quantum.Small.Inverse">
-        <item name="fontFamily">@string/font_family_menu_quantum</item>
-        <item name="textSize">@dimen/text_size_menu_quantum</item>>
-        <item name="textColor">?attr/actionMenuTextColor</item>
-        <item name="textAllCaps">@bool/config_actionMenuItemAllCaps</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.WindowTitle">
-        <item name="textColor">?attr/textColorPrimary</item>
-        <item name="fontFamily">@string/font_family_headline_quantum</item>
-        <item name="textSize">@dimen/text_size_headline_quantum</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.DialogWindowTitle">
-        <item name="fontFamily">@string/font_family_headline_quantum</item>
-        <item name="textSize">@dimen/text_size_headline_quantum</item>
-        <item name="textColor">?attr/textColorPrimary</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.CalendarViewWeekDayView" parent="TextAppearance.Quantum.Small">
-        <item name="textStyle">bold</item>
-        <item name="textColor">#505050</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.TimePicker.TimeLabel" parent="TextAppearance.Quantum">
-        <item name="textSize">@dimen/timepicker_time_label_size</item>
-        <item name="textColor">?attr/textColorSecondary</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.TimePicker.AmPmLabel" parent="TextAppearance.Quantum">
-        <item name="textSize">@dimen/timepicker_ampm_label_size</item>
-        <item name="textAllCaps">true</item>
-        <item name="textColor">?attr/textColorSecondary</item>
-        <item name="textStyle">bold</item>
-    </style>
-
-    <style name="TextAppearance.StatusBar.Quantum" />
-
-    <style name="TextAppearance.StatusBar.Quantum.EventContent">
-        <item name="android:textColor">#90000000</item>
-        <item name="android:textSize">@dimen/notification_text_size</item>
-    </style>
-
-    <style name="TextAppearance.StatusBar.Quantum.EventContent.Title">
-        <item name="android:textColor">#DD000000</item>
-        <item name="android:textSize">@dimen/notification_title_text_size</item>
-    </style>
-
-    <style name="TextAppearance.StatusBar.Quantum.EventContent.Line2">
-        <item name="android:textSize">@dimen/notification_subtext_size</item>
-    </style>
-
-    <style name="TextAppearance.StatusBar.Quantum.EventContent.Info">
-        <item name="android:textSize">@dimen/notification_subtext_size</item>
-    </style>
-
-    <style name="TextAppearance.StatusBar.Quantum.EventContent.Time">
-        <item name="android:textSize">@dimen/notification_subtext_size</item>
-    </style>
-
-    <style name="TextAppearance.StatusBar.Quantum.EventContent.Emphasis">
-        <item name="android:textColor">#66000000</item>
-    </style>
-
-    <style name="Widget.StatusBar.Quantum.ProgressBar" parent="Widget.Quantum.Light.ProgressBar.Horizontal">
-        <item name="android:progressDrawable">@drawable/notification_quantum_media_progress</item>
-    </style>
-
-    <!-- Widget Styles -->
-
-    <style name="Quantum"/>
-    <style name="Quantum.Light"/>
-    <style name="Widget.Quantum" parent="Widget" />
-
-    <!-- Bordered ink button -->
-    <style name="Widget.Quantum.Button" parent="Widget.Button">
-        <item name="background">@drawable/btn_default_quantum</item>
-        <item name="textAppearance">?attr/textAppearanceButton</item>
-        <item name="textColor">?attr/textColorPrimary</item>
-        <item name="minHeight">48dip</item>
-        <item name="minWidth">88dip</item>
-
-        <!-- TODO: Turn this back on when we support inset drawable outlines. -->
-        <!-- <item name="stateListAnimator">@anim/button_state_list_anim_quantum</item> -->
-    </style>
-
-    <!-- Small bordered ink button -->
-    <style name="Widget.Quantum.Button.Small">
-        <item name="minHeight">48dip</item>
-        <item name="minWidth">48dip</item>
-    </style>
-
-    <!-- Borderless ink button -->
-    <style name="Widget.Quantum.Button.Borderless">
-        <item name="background">@drawable/btn_borderless_quantum</item>
-        <item name="stateListAnimator">@null</item>
-    </style>
-
-    <!-- Small borderless ink button -->
-    <style name="Widget.Quantum.Button.Borderless.Small">
-        <item name="minHeight">48dip</item>
-        <item name="minWidth">48dip</item>
-    </style>
-
-    <style name="Widget.Quantum.Button.Inset">
-        <item name="background">@drawable/button_inset</item>
-    </style>
-
-    <style name="Widget.Quantum.Button.Toggle">
-        <item name="background">@drawable/btn_toggle_quantum</item>
-        <item name="textOn">@string/capital_on</item>
-        <item name="textOff">@string/capital_off</item>
-        <item name="minHeight">48dip</item>
-    </style>
-
-    <style name="Widget.Quantum.ButtonBar">
-        <item name="background">@null</item>
-    </style>
-
-    <style name="Widget.Quantum.ButtonBar.AlertDialog">
-        <item name="background">@null</item>
-    </style>
-
-    <style name="Widget.Quantum.SegmentedButton" parent="SegmentedButton">
-        <item name="background">@drawable/btn_group_holo_dark</item>
-    </style>
-
-    <style name="Widget.Quantum.StackView">
-        <item name="resOutColor">@color/holo_blue_light</item>
-        <item name="clickColor">@color/holo_blue_light</item>
-    </style>
-
-    <style name="Widget.Quantum.TextView" parent="Widget.TextView"/>
-
-    <style name="Widget.Quantum.TextView.ListSeparator" parent="Widget.TextView.ListSeparator">
-        <item name="background">@drawable/list_section_divider_quantum</item>
-        <item name="textAllCaps">true</item>
-    </style>
-
-    <style name="Widget.Quantum.TextView.SpinnerItem" parent="Widget.TextView.SpinnerItem">
-        <item name="textAppearance">@style/TextAppearance.Quantum.Widget.TextView.SpinnerItem</item>
-        <item name="paddingStart">8dp</item>
-        <item name="paddingEnd">8dp</item>
-    </style>
-
-    <style name="Widget.Quantum.CheckedTextView" parent="Widget.CheckedTextView" />
-    <style name="Widget.Quantum.TextSelectHandle" parent="Widget.TextSelectHandle"/>
-    <style name="Widget.Quantum.TextSuggestionsPopupWindow" parent="Widget.TextSuggestionsPopupWindow"/>
-    <style name="Widget.Quantum.AbsListView" parent="Widget.AbsListView"/>
-
-    <style name="Widget.Quantum.AutoCompleteTextView" parent="Widget.AutoCompleteTextView">
-        <item name="dropDownSelector">?attr/listChoiceBackgroundIndicator</item>
-        <item name="popupBackground">@drawable/popup_background_quantum</item>
-    </style>
-
-    <style name="Widget.Quantum.CompoundButton" parent="Widget.CompoundButton"/>
-
-    <style name="Widget.Quantum.CompoundButton.CheckBox" parent="Widget.CompoundButton.CheckBox">
-        <item name="background">?attr/selectableItemBackgroundBorderless</item>
-    </style>
-
-    <style name="Widget.Quantum.CompoundButton.RadioButton" parent="Widget.CompoundButton.RadioButton">
-        <item name="background">?attr/selectableItemBackgroundBorderless</item>
-    </style>
-
-    <style name="Widget.Quantum.CompoundButton.Star" parent="Widget.CompoundButton.Star">
-        <item name="button">@drawable/btn_star_quantum</item>
-        <item name="background">?attr/selectableItemBackgroundBorderless</item>
-    </style>
-
-    <style name="Widget.Quantum.CompoundButton.Switch">
-        <item name="track">@drawable/switch_track_quantum</item>
-        <item name="thumb">@drawable/switch_thumb_quantum_anim</item>
-        <item name="splitTrack">true</item>
-        <item name="switchTextAppearance">@style/TextAppearance.Quantum.Widget.Switch</item>
-        <item name="textOn"></item>
-        <item name="textOff"></item>
-        <item name="switchMinWidth">4dip</item>
-        <item name="switchPadding">4dip</item>
-        <item name="background">?attr/selectableItemBackgroundBorderless</item>
-    </style>
-
-    <style name="Widget.Quantum.EditText" parent="Widget.EditText"/>
-
-    <style name="Widget.Quantum.ExpandableListView" parent="Widget.Quantum.ListView">
-        <item name="groupIndicator">@drawable/expander_group_quantum</item>
-        <item name="indicatorLeft">?attr/expandableListPreferredItemIndicatorLeft</item>
-        <item name="indicatorRight">?attr/expandableListPreferredItemIndicatorRight</item>
-        <item name="childDivider">?attr/listDivider</item>
-    </style>
-
-    <style name="Widget.Quantum.ExpandableListView.White"/>
-    <style name="Widget.Quantum.Gallery" parent="Widget.Gallery"/>
-    <style name="Widget.Quantum.GestureOverlayView" parent="Widget.GestureOverlayView"/>
-
-    <style name="Widget.Quantum.GridView" parent="Widget.GridView">
-        <item name="android:listSelector">?attr/selectableItemBackground</item>
-    </style>
-
-    <style name="Widget.Quantum.CalendarView" parent="Widget.CalendarView">
-        <item name="selectedWeekBackgroundColor">#330099FF</item>
-        <item name="focusedMonthDateColor">#FFFFFFFF</item>
-        <item name="unfocusedMonthDateColor">#66FFFFFF</item>
-        <item name="weekNumberColor">#33FFFFFF</item>
-        <item name="weekSeparatorLineColor">#19FFFFFF</item>
-        <item name="selectedDateVerticalBar">@drawable/day_picker_week_view_dayline_holo</item>
-        <item name="weekDayTextAppearance">@style/TextAppearance.Quantum.CalendarViewWeekDayView</item>
-    </style>
-
-    <style name="Widget.Quantum.ImageButton" parent="Widget.ImageButton">
-        <item name="background">@drawable/btn_default_quantum</item>
-    </style>
-
-    <style name="Widget.Quantum.NumberPicker" parent="Widget.NumberPicker">
-        <item name="internalLayout">@layout/number_picker_with_selector_wheel</item>
-        <item name="solidColor">@color/transparent</item>
-        <item name="selectionDivider">@drawable/numberpicker_selection_divider</item>
-        <item name="selectionDividerHeight">2dip</item>
-        <item name="selectionDividersDistance">48dip</item>
-        <item name="internalMinWidth">64dip</item>
-        <item name="internalMaxHeight">180dip</item>
-        <item name="virtualButtonPressedDrawable">?attr/selectableItemBackground</item>
-    </style>
-
-    <style name="Widget.Quantum.TimePicker" parent="Widget.TimePicker">
-        <item name="legacyLayout">@layout/time_picker_legacy_holo</item>
-        <item name="internalLayout">@layout/time_picker_holo</item>
-        <item name="disabledColor">@color/bright_foreground_disabled_quantum_dark</item>
-        <item name="headerSelectedTextColor">?attr/colorControlActivated</item>
-        <item name="headerUnselectedTextColor">?attr/textColorPrimary</item>
-        <item name="headerBackgroundColor">?attr/colorBackground</item>
-        <item name="numbersTextColor">?attr/textColorSecondary</item>
-        <item name="numbersBackgroundColor">?attr/colorControlNormal</item>
-        <item name="amPmTextColor">?attr/textColorSecondary</item>
-        <item name="amPmUnselectedBackgroundColor">?attr/colorControlNormal</item>
-        <item name="amPmSelectedBackgroundColor">?attr/colorControlActivated</item>
-        <item name="numbersSelectorColor">?attr/colorControlActivated</item>
-    </style>
-
-    <style name="Widget.Quantum.DatePicker" parent="Widget.DatePicker">
-        <item name="internalLayout">@layout/date_picker_holo</item>
-        <item name="calendarViewShown">true</item>
-    </style>
-
-    <style name="Widget.Quantum.ActivityChooserView" parent="Widget.ActivityChooserView">
-        <item name="background">@drawable/ab_share_pack_quantum</item>
-    </style>
-
-    <style name="Widget.Quantum.ImageWell" parent="Widget.ImageWell"/>
-
-    <style name="Widget.Quantum.ListView" parent="Widget.ListView">
-        <item name="divider">?attr/listDivider</item>
-        <item name="listSelector">?attr/listChoiceBackgroundIndicator</item>
-    </style>
-
-    <style name="Widget.Quantum.ListView.DropDown"/>
-    <style name="Widget.Quantum.ListView.White"/>
-
-    <style name="Widget.Quantum.PopupWindow" parent="Widget.PopupWindow"/>
-
-    <style name="Widget.Quantum.PopupWindow.ActionMode">
-        <item name="popupBackground">@drawable/popup_background_quantum</item>
-        <item name="popupAnimationStyle">@style/Animation.PopupWindow.ActionMode</item>
-    </style>
-
-    <style name="Widget.Quantum.ProgressBar" parent="Widget.ProgressBar">
-        <item name="indeterminateDrawable">@drawable/progress_medium_holo</item>
-    </style>
-
-    <style name="Widget.Quantum.ProgressBar.Inverse"/>
-
-    <style name="Widget.Quantum.ProgressBar.Horizontal" parent="Widget.ProgressBar.Horizontal">
-        <item name="progressDrawable">@drawable/progress_horizontal_quantum</item>
-        <item name="indeterminateDrawable">@drawable/progress_indeterminate_horizontal_holo</item>
-        <item name="minHeight">16dip</item>
-        <item name="maxHeight">16dip</item>
-    </style>
-
-    <style name="Widget.Quantum.ProgressBar.Small" parent="Widget.ProgressBar.Small">
-        <item name="indeterminateDrawable">@drawable/progress_small_holo</item>
-    </style>
-
-    <style name="Widget.Quantum.ProgressBar.Small.Inverse"/>
-    <style name="Widget.Quantum.ProgressBar.Small.Title"/>
-
-    <style name="Widget.Quantum.ProgressBar.Large" parent="Widget.ProgressBar.Large">
-        <item name="indeterminateDrawable">@drawable/progress_large_holo</item>
-    </style>
-
-    <style name="Widget.Quantum.ProgressBar.Large.Inverse"/>
-
-    <style name="Widget.Quantum.SeekBar">
-        <item name="indeterminateOnly">false</item>
-        <item name="progressDrawable">@drawable/scrubber_progress_horizontal_quantum</item>
-        <item name="indeterminateDrawable">@drawable/scrubber_progress_horizontal_quantum</item>
-        <item name="thumb">@drawable/scrubber_control_quantum_anim</item>
-        <item name="splitTrack">true</item>
-        <item name="focusable">true</item>
-        <item name="paddingStart">16dip</item>
-        <item name="paddingEnd">16dip</item>
-        <item name="mirrorForRtl">true</item>
-        <item name="background">?attr/selectableItemBackgroundBorderless</item>
-    </style>
-
-    <style name="Widget.Quantum.RatingBar" parent="Widget.RatingBar">
-        <item name="progressDrawable">@drawable/ratingbar_full_quantum</item>
-        <item name="indeterminateDrawable">@drawable/ratingbar_full_quantum</item>
-    </style>
-
-    <style name="Widget.Quantum.RatingBar.Indicator" parent="Widget.RatingBar.Indicator">
-        <item name="progressDrawable">@drawable/ratingbar_holo_dark</item>
-        <item name="indeterminateDrawable">@drawable/ratingbar_holo_dark</item>
-        <item name="minHeight">35dip</item>
-        <item name="maxHeight">35dip</item>
-    </style>
-
-    <style name="Widget.Quantum.RatingBar.Small" parent="Widget.RatingBar.Small">
-        <item name="progressDrawable">@drawable/ratingbar_small_holo_dark</item>
-        <item name="indeterminateDrawable">@drawable/ratingbar_small_holo_dark</item>
-        <item name="minHeight">16dip</item>
-        <item name="maxHeight">16dip</item>
-    </style>
-
-    <style name="Widget.Quantum.ScrollView" parent="Widget.ScrollView"/>
-    <style name="Widget.Quantum.HorizontalScrollView" parent="Widget.HorizontalScrollView"/>
-
-    <style name="Widget.Quantum.Spinner" parent="Widget.Spinner.DropDown">
-        <item name="background">@drawable/spinner_background_quantum</item>
-        <item name="dropDownSelector">?attr/listChoiceBackgroundIndicator</item>
-        <item name="popupBackground">@drawable/popup_background_quantum</item>
-        <item name="dropDownVerticalOffset">0dip</item>
-        <item name="dropDownHorizontalOffset">0dip</item>
-        <item name="dropDownWidth">wrap_content</item>
-        <item name="popupPromptView">@layout/simple_dropdown_hint</item>
-        <item name="gravity">start|center_vertical</item>
-        <item name="disableChildrenWhenDisabled">true</item>
-    </style>
-
-    <style name="Widget.Quantum.Spinner.DropDown"/>
-
-    <style name="Widget.Quantum.Spinner.DropDown.ActionBar">
-        <item name="background">@drawable/spinner_background_quantum</item>
-    </style>
-
-    <style name="Widget.Quantum.TabWidget" parent="Widget.TabWidget">
-        <item name="tabStripLeft">@null</item>
-        <item name="tabStripRight">@null</item>
-        <item name="tabStripEnabled">false</item>
-        <item name="divider">?attr/dividerVertical</item>
-        <item name="showDividers">middle</item>
-        <item name="dividerPadding">8dip</item>
-        <item name="measureWithLargestChild">true</item>
-        <item name="tabLayout">@layout/tab_indicator_quantum</item>
-    </style>
-
-    <style name="Widget.Quantum.Tab" parent="Widget.Quantum.ActionBar.TabView">
-        <item name="background">@drawable/tab_indicator_quantum</item>
-        <item name="layout_width">0dip</item>
-        <item name="layout_weight">1</item>
-        <item name="minWidth">80dip</item>
-    </style>
-
-    <style name="Widget.Quantum.TabText" parent="Widget.Quantum.ActionBar.TabText">
-        <item name="maxWidth">180dip</item>
-    </style>
-
-    <style name="Widget.Quantum.WebTextView" parent="Widget.WebTextView"/>
-
-    <style name="Widget.Quantum.WebView" parent="Widget.WebView"/>
-
-    <style name="Widget.Quantum.DropDownItem" parent="Widget.DropDownItem">
-        <item name="textAppearance">@style/TextAppearance.Quantum.Widget.DropDownItem</item>
-        <item name="paddingStart">8dp</item>
-        <item name="paddingEnd">8dp</item>
-    </style>
-
-    <style name="Widget.Quantum.DropDownItem.Spinner"/>
-
-    <style name="Widget.Quantum.KeyboardView" parent="Widget.KeyboardView"/>
-    <style name="Widget.Quantum.QuickContactBadge.WindowSmall" parent="Widget.QuickContactBadge.WindowSmall"/>
-    <style name="Widget.Quantum.QuickContactBadge.WindowMedium" parent="Widget.QuickContactBadge.WindowMedium"/>
-    <style name="Widget.Quantum.QuickContactBadge.WindowLarge" parent="Widget.QuickContactBadge.WindowLarge"/>
-    <style name="Widget.Quantum.QuickContactBadgeSmall.WindowSmall" parent="Widget.QuickContactBadgeSmall.WindowSmall"/>
-    <style name="Widget.Quantum.QuickContactBadgeSmall.WindowMedium" parent="Widget.QuickContactBadgeSmall.WindowMedium"/>
-    <style name="Widget.Quantum.QuickContactBadgeSmall.WindowLarge" parent="Widget.QuickContactBadgeSmall.WindowLarge"/>
-
-    <style name="Widget.Quantum.ListPopupWindow" parent="Widget.ListPopupWindow">
-        <item name="dropDownSelector">?attr/listChoiceBackgroundIndicator</item>
-        <item name="popupBackground">@drawable/popup_background_quantum</item>
-        <item name="popupAnimationStyle">@style/Animation.Quantum.Popup</item>
-        <item name="dropDownVerticalOffset">0dip</item>
-        <item name="dropDownHorizontalOffset">0dip</item>
-        <item name="dropDownWidth">wrap_content</item>
-    </style>
-
-    <style name="Widget.Quantum.PopupMenu" parent="Widget.Quantum.ListPopupWindow"/>
-
-    <style name="Widget.Quantum.PopupMenu.Overflow">
-        <item name="overlapAnchor">true</item>
-    </style>
-
-    <style name="Widget.Quantum.ActionButton" parent="Widget.ActionButton">
-        <item name="minWidth">@dimen/action_button_min_width_quantum</item>
-        <item name="minHeight">@dimen/action_button_min_height_quantum</item>
-        <item name="gravity">center</item>
-        <item name="scaleType">center</item>
-        <item name="maxLines">2</item>
-    </style>
-
-    <style name="Widget.Quantum.ActionButton.CloseMode">
-        <item name="background">@drawable/btn_cab_done_quantum</item>
-    </style>
-
-    <style name="Widget.Quantum.ActionButton.Overflow">
-        <item name="src">@drawable/ic_menu_moreoverflow_quantum</item>
-        <item name="background">?attr/actionBarItemBackground</item>
-        <item name="contentDescription">@string/action_menu_overflow_description</item>
-        <item name="minWidth">@dimen/action_overflow_min_width_quantum</item>
-        <item name="minHeight">@dimen/action_button_min_height_quantum</item>
-        <item name="scaleType">center</item>
-    </style>
-
-    <style name="Widget.Quantum.ActionBar.TabView" parent="Widget.ActionBar.TabView">
-        <item name="background">@drawable/tab_indicator_quantum</item>
-        <item name="paddingStart">16dip</item>
-        <item name="paddingEnd">16dip</item>
-    </style>
-
-    <style name="Widget.Quantum.ActionBar.TabBar" parent="Widget.ActionBar.TabBar">
-        <item name="divider">?attr/actionBarDivider</item>
-        <item name="showDividers">middle</item>
-        <item name="dividerPadding">12dip</item>
-    </style>
-
-    <style name="Widget.Quantum.ActionBar.TabText" parent="Widget.ActionBar.TabText">
-        <item name="textAppearance">@style/TextAppearance.Quantum.Medium</item>
-        <item name="textColor">?attr/textColorPrimary</item>
-        <item name="textSize">12sp</item>
-        <item name="textStyle">bold</item>
-        <item name="textAllCaps">true</item>
-        <item name="ellipsize">marquee</item>
-        <item name="maxLines">2</item>
-    </style>
-
-    <style name="Widget.Quantum.ActionBar" parent="Widget.ActionBar">
-        <item name="background">@null</item>
-        <item name="backgroundStacked">@null</item>
-        <item name="backgroundSplit">@null</item>
-        <item name="displayOptions">showTitle</item>
-        <item name="divider">?attr/dividerVertical</item>
-        <item name="titleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Title</item>
-        <item name="subtitleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Subtitle</item>
-        <item name="progressBarStyle">@style/Widget.Quantum.ProgressBar.Horizontal</item>
-        <item name="indeterminateProgressStyle">@style/Widget.Quantum.ProgressBar</item>
-        <item name="progressBarPadding">32dip</item>
-        <item name="itemPadding">8dip</item>
-        <item name="homeLayout">@layout/action_bar_home_quantum</item>
-        <item name="gravity">center_vertical</item>
-    </style>
-
-    <style name="Widget.Quantum.ActionBar.Solid">
-        <item name="background">?attr/colorPrimary</item>
-        <item name="backgroundStacked">?attr/colorPrimary</item>
-        <item name="backgroundSplit">?attr/colorPrimary</item>
-    </style>
-
-    <style name="Widget.Quantum.ActionMode" parent="Widget.ActionMode">
-        <item name="titleTextStyle">@style/TextAppearance.Quantum.Widget.ActionMode.Title</item>
-        <item name="subtitleTextStyle">@style/TextAppearance.Quantum.Widget.ActionMode.Subtitle</item>
-    </style>
-
-    <style name="Widget.Quantum.FastScroll" parent="Widget.FastScroll">
-        <item name="thumbMinWidth">0dp</item>
-        <item name="thumbMinHeight">0dp</item>
-    </style>
-
-    <style name="Widget.Quantum.PreferenceFrameLayout">
-        <item name="borderTop">0dip</item>
-        <item name="borderBottom">@dimen/preference_fragment_padding_bottom</item>
-        <item name="borderLeft">?attr/preferenceFragmentPaddingSide</item>
-        <item name="borderRight">?attr/preferenceFragmentPaddingSide</item>
-    </style>
-
-    <style name="Widget.Quantum.MediaRouteButton">
-        <item name="background">?attr/selectableItemBackgroundBorderless</item>
-        <item name="externalRouteEnabledDrawable">@drawable/ic_media_route_quantum</item>
-        <item name="minWidth">56dp</item>
-        <item name="minHeight">48dp</item>
-        <item name="focusable">true</item>
-        <item name="contentDescription">@string/media_route_button_content_description</item>
-    </style>
-
-    <!-- Light widget styles -->
-
-    <style name="Widget.Quantum.Light" parent="Widget.Quantum"/>
-    <style name="Widget.Quantum.Light.Button" parent="Widget.Quantum.Button"/>
-    <style name="Widget.Quantum.Light.Button.Small" parent="Widget.Quantum.Button.Small"/>
-    <style name="Widget.Quantum.Light.Button.Borderless" parent="Widget.Quantum.Button.Borderless"/>
-    <style name="Widget.Quantum.Light.Button.Borderless.Small" parent="Widget.Quantum.Button.Borderless.Small"/>
-    <style name="Widget.Quantum.Light.Button.Inset" parent="Widget.Quantum.Button.Inset"/>
-    <style name="Widget.Quantum.Light.Button.Toggle" parent="Widget.Quantum.Button.Toggle" />
-    <style name="Widget.Quantum.Light.ButtonBar" parent="Widget.Quantum.ButtonBar"/>
-    <style name="Widget.Quantum.Light.ButtonBar.AlertDialog" parent="Widget.Quantum.ButtonBar.AlertDialog"/>
-
-    <style name="Widget.Quantum.Light.SegmentedButton" parent="Widget.Quantum.SegmentedButton">
-        <item name="background">@drawable/btn_group_holo_light</item>
-    </style>
-
-    <style name="Widget.Quantum.Light.StackView" parent="Widget.Quantum.StackView"/>
-    <style name="Widget.Quantum.Light.TextView" parent="Widget.Quantum.TextView"/>
-    <style name="Widget.Quantum.Light.TextView.ListSeparator" parent="Widget.Quantum.TextView.ListSeparator"/>
-    <style name="Widget.Quantum.Light.TextView.SpinnerItem" parent="Widget.Quantum.TextView.SpinnerItem"/>
-    <style name="Widget.Quantum.Light.CheckedTextView" parent="Widget.Quantum.CheckedTextView"/>
-    <style name="Widget.Quantum.Light.TextSelectHandle" parent="Widget.Quantum.TextSelectHandle"/>
-    <style name="Widget.Quantum.Light.TextSuggestionsPopupWindow" parent="Widget.Quantum.TextSuggestionsPopupWindow"/>
-    <style name="Widget.Quantum.Light.AbsListView" parent="Widget.Quantum.AbsListView"/>
-    <style name="Widget.Quantum.Light.AutoCompleteTextView" parent="Widget.Quantum.AutoCompleteTextView" />
-    <style name="Widget.Quantum.Light.CompoundButton" parent="Widget.Quantum.CompoundButton"/>
-    <style name="Widget.Quantum.Light.CompoundButton.CheckBox" parent="Widget.Quantum.CompoundButton.CheckBox"/>
-    <style name="Widget.Quantum.Light.CompoundButton.RadioButton" parent="Widget.Quantum.CompoundButton.RadioButton"/>
-    <style name="Widget.Quantum.Light.CompoundButton.Star" parent="Widget.Quantum.CompoundButton.Star"/>
-    <style name="Widget.Quantum.Light.CompoundButton.Switch" parent="Widget.Quantum.CompoundButton.Switch" />
-    <style name="Widget.Quantum.Light.ListView.DropDown" parent="Widget.Quantum.ListView.DropDown"/>
-    <style name="Widget.Quantum.Light.EditText" parent="Widget.Quantum.EditText"/>
-    <style name="Widget.Quantum.Light.ExpandableListView" parent="Widget.Quantum.ExpandableListView"/>
-    <style name="Widget.Quantum.Light.ExpandableListView.White" parent="Widget.Quantum.ExpandableListView.White"/>
-    <style name="Widget.Quantum.Light.Gallery" parent="Widget.Quantum.Gallery"/>
-    <style name="Widget.Quantum.Light.GestureOverlayView" parent="Widget.Quantum.GestureOverlayView"/>
-    <style name="Widget.Quantum.Light.GridView" parent="Widget.Quantum.GridView"/>
-    <style name="Widget.Quantum.Light.ImageButton" parent="Widget.Quantum.ImageButton"/>
-
-    <style name="Widget.Quantum.Light.CalendarView" parent="Widget.CalendarView">
-        <item name="selectedWeekBackgroundColor">#330066ff</item>
-        <item name="focusedMonthDateColor">#FF000000</item>
-        <item name="unfocusedMonthDateColor">#7F08002B</item>
-        <item name="weekNumberColor">#7F080021</item>
-        <item name="weekSeparatorLineColor">#7F08002A</item>
-        <item name="weekDayTextAppearance">@style/TextAppearance.Quantum.CalendarViewWeekDayView</item>
-    </style>
-
-    <style name="Widget.Quantum.Light.NumberPicker" parent="Widget.Quantum.NumberPicker"/>
-
-    <style name="Widget.Quantum.Light.TimePicker" parent="Widget.Quantum.TimePicker">
-        <item name="legacyLayout">@layout/time_picker_legacy_holo</item>
-        <item name="internalLayout">@layout/time_picker_holo</item>
-        <item name="disabledColor">@color/bright_foreground_disabled_quantum_light</item>
-    </style>
-
-    <style name="Widget.Quantum.Light.DatePicker" parent="Widget.Quantum.DatePicker"/>
-    <style name="Widget.Quantum.Light.ActivityChooserView" parent="Widget.Quantum.ActivityChooserView" />
-    <style name="Widget.Quantum.Light.ImageWell" parent="Widget.Quantum.ImageWell"/>
-    <style name="Widget.Quantum.Light.ListView" parent="Widget.Quantum.ListView"/>
-    <style name="Widget.Quantum.Light.ListView.White" parent="Widget.Quantum.ListView.White"/>
-    <style name="Widget.Quantum.Light.PopupWindow" parent="Widget.Quantum.PopupWindow"/>
-    <style name="Widget.Quantum.Light.PopupWindow.ActionMode" parent="Widget.Quantum.PopupWindow.ActionMode"/>
-    <style name="Widget.Quantum.Light.ProgressBar" parent="Widget.Quantum.ProgressBar"/>
-    <style name="Widget.Quantum.Light.ProgressBar.Horizontal" parent="Widget.Quantum.ProgressBar.Horizontal"/>
-    <style name="Widget.Quantum.Light.ProgressBar.Small" parent="Widget.Quantum.ProgressBar.Small"/>
-    <style name="Widget.Quantum.Light.ProgressBar.Small.Title" parent="Widget.Quantum.ProgressBar.Small.Title"/>
-    <style name="Widget.Quantum.Light.ProgressBar.Large" parent="Widget.Quantum.ProgressBar.Large"/>
-    <style name="Widget.Quantum.Light.ProgressBar.Inverse" parent="Widget.Quantum.ProgressBar.Inverse"/>
-    <style name="Widget.Quantum.Light.ProgressBar.Small.Inverse" parent="Widget.Quantum.ProgressBar.Small.Inverse"/>
-    <style name="Widget.Quantum.Light.ProgressBar.Large.Inverse" parent="Widget.Quantum.ProgressBar.Large.Inverse"/>
-    <style name="Widget.Quantum.Light.SeekBar" parent="Widget.Quantum.SeekBar"/>
-    <style name="Widget.Quantum.Light.RatingBar" parent="Widget.Quantum.RatingBar" />
-
-    <style name="Widget.Quantum.Light.RatingBar.Indicator" parent="Widget.RatingBar.Indicator">
-        <item name="progressDrawable">@drawable/ratingbar_holo_light</item>
-        <item name="indeterminateDrawable">@drawable/ratingbar_holo_light</item>
-        <item name="minHeight">35dip</item>
-        <item name="maxHeight">35dip</item>
-    </style>
-
-    <style name="Widget.Quantum.Light.RatingBar.Small" parent="Widget.RatingBar.Small">
-        <item name="progressDrawable">@drawable/ratingbar_small_holo_light</item>
-        <item name="indeterminateDrawable">@drawable/ratingbar_small_holo_light</item>
-        <item name="minHeight">16dip</item>
-        <item name="maxHeight">16dip</item>
-    </style>
-
-    <style name="Widget.Quantum.Light.ScrollView" parent="Widget.Quantum.ScrollView"/>
-    <style name="Widget.Quantum.Light.HorizontalScrollView" parent="Widget.Quantum.HorizontalScrollView"/>
-    <style name="Widget.Quantum.Light.Spinner" parent="Widget.Quantum.Spinner" />
-    <style name="Widget.Quantum.Light.Spinner.DropDown" parent="Widget.Quantum.Spinner.DropDown"/>
-    <style name="Widget.Quantum.Light.Spinner.DropDown.ActionBar" parent="Widget.Quantum.Spinner.DropDown.ActionBar"/>
-    <style name="Widget.Quantum.Light.TabWidget" parent="Widget.Quantum.TabWidget"/>
-    <style name="Widget.Quantum.Light.WebTextView" parent="Widget.Quantum.WebTextView"/>
-    <style name="Widget.Quantum.Light.WebView" parent="Widget.Quantum.WebView"/>
-    <style name="Widget.Quantum.Light.DropDownItem" parent="Widget.Quantum.DropDownItem"/>
-    <style name="Widget.Quantum.Light.DropDownItem.Spinner" parent="Widget.Quantum.DropDownItem.Spinner"/>
-    <style name="Widget.Quantum.Light.KeyboardView" parent="Widget.Quantum.KeyboardView"/>
-    <style name="Widget.Quantum.Light.QuickContactBadge.WindowSmall" parent="Widget.Quantum.QuickContactBadge.WindowSmall"/>
-    <style name="Widget.Quantum.Light.QuickContactBadge.WindowMedium" parent="Widget.Quantum.QuickContactBadge.WindowMedium"/>
-    <style name="Widget.Quantum.Light.QuickContactBadge.WindowLarge" parent="Widget.Quantum.QuickContactBadge.WindowLarge"/>
-    <style name="Widget.Quantum.Light.QuickContactBadgeSmall.WindowSmall" parent="Widget.Quantum.QuickContactBadgeSmall.WindowSmall"/>
-    <style name="Widget.Quantum.Light.QuickContactBadgeSmall.WindowMedium" parent="Widget.Quantum.QuickContactBadgeSmall.WindowMedium"/>
-    <style name="Widget.Quantum.Light.QuickContactBadgeSmall.WindowLarge" parent="Widget.Quantum.QuickContactBadgeSmall.WindowLarge"/>
-    <style name="Widget.Quantum.Light.ListPopupWindow" parent="Widget.Quantum.ListPopupWindow"/>
-    <style name="Widget.Quantum.Light.PopupMenu" parent="Widget.Quantum.ListPopupWindow"/>
-    <style name="Widget.Quantum.Light.PopupMenu.Overflow" parent="Widget.Quantum.PopupMenu.Overflow"/>
-    <style name="Widget.Quantum.Light.ActionButton" parent="Widget.Quantum.ActionButton"/>
-    <style name="Widget.Quantum.Light.ActionButton.Overflow" parent="Widget.Quantum.ActionButton.Overflow"/>
-    <style name="Widget.Quantum.Light.Tab" parent="Widget.Quantum.Tab"/>
-    <style name="Widget.Quantum.Light.ActionBar.TabView" parent="Widget.Quantum.ActionBar.TabView"/>
-    <style name="Widget.Quantum.Light.ActionBar.TabBar" parent="Widget.Quantum.ActionBar.TabBar"/>
-    <style name="Widget.Quantum.Light.ActionBar.TabText" parent="Widget.Quantum.ActionBar.TabText"/>
-    <style name="Widget.Quantum.Light.ActionMode" parent="Widget.Quantum.ActionMode" />
-    <style name="Widget.Quantum.Light.ActionButton.CloseMode" parent="Widget.Quantum.ActionButton.CloseMode" />
-
-    <style name="Widget.Quantum.Light.ActionBar" parent="Widget.Quantum.ActionBar">
-        <item name="titleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Title</item>
-        <item name="subtitleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Subtitle</item>
-        <item name="background">@null</item>
-        <item name="backgroundStacked">@null</item>
-        <item name="backgroundSplit">@null</item>
-        <item name="homeAsUpIndicator">@drawable/ic_ab_back_quantum</item>
-        <item name="progressBarStyle">@style/Widget.Quantum.Light.ProgressBar.Horizontal</item>
-        <item name="indeterminateProgressStyle">@style/Widget.Quantum.Light.ProgressBar</item>
-    </style>
-
-    <style name="Widget.Quantum.Light.ActionBar.Solid">
-        <item name="background">?attr/colorPrimary</item>
-        <item name="backgroundStacked">?attr/colorPrimary</item>
-        <item name="backgroundSplit">?attr/colorPrimary</item>
-    </style>
-
-    <style name="Widget.Quantum.Light.FastScroll" parent="Widget.Quantum.FastScroll"/>
-    <style name="Widget.Quantum.Light.MediaRouteButton" parent="Widget.Quantum.MediaRouteButton" />
-
-    <!-- Animation Styles -->
-
-    <style name="Animation.Quantum" parent="Animation"/>
-    <style name="Animation.Quantum.Activity" parent="Animation.Activity"/>
-
-    <style name="Animation.Quantum.Dialog">
-        <item name="windowEnterAnimation">@anim/popup_enter_quantum</item>
-        <item name="windowExitAnimation">@anim/popup_exit_quantum</item>
-    </style>
-
-    <style name="Animation.Quantum.Popup">
-        <item name="windowEnterAnimation">@anim/popup_enter_quantum</item>
-        <item name="windowExitAnimation">@anim/popup_exit_quantum</item>
-    </style>
-
-    <!-- Dialog styles -->
-
-    <style name="AlertDialog.Quantum" parent="AlertDialog">
-        <item name="fullDark">@color/transparent</item>
-        <item name="topDark">@color/transparent</item>
-        <item name="centerDark">@color/transparent</item>
-        <item name="bottomDark">@color/transparent</item>
-        <item name="fullBright">@color/transparent</item>
-        <item name="topBright">@color/transparent</item>
-        <item name="centerBright">@color/transparent</item>
-        <item name="bottomBright">@color/transparent</item>
-        <item name="bottomMedium">@color/transparent</item>
-        <item name="centerMedium">@color/transparent</item>
-        <item name="layout">@layout/alert_dialog_quantum</item>
-        <item name="listLayout">@layout/select_dialog_quantum</item>
-        <item name="progressLayout">@layout/progress_dialog_quantum</item>
-        <item name="horizontalProgressLayout">@layout/alert_dialog_progress_quantum</item>
-        <item name="listItemLayout">@layout/select_dialog_item_quantum</item>
-        <item name="multiChoiceItemLayout">@layout/select_dialog_multichoice_quantum</item>
-        <item name="singleChoiceItemLayout">@layout/select_dialog_singlechoice_quantum</item>
-    </style>
-
-    <style name="AlertDialog.Quantum.Light"/>
-
-    <!-- Window title -->
-    <style name="WindowTitleBackground.Quantum">
-        <item name="background">@null</item>
-    </style>
-
-    <style name="WindowTitle.Quantum">
-        <item name="singleLine">true</item>
-        <item name="textAppearance">@style/TextAppearance.Quantum.WindowTitle</item>
-        <item name="shadowRadius">0</item>
-    </style>
-
-    <style name="DialogWindowTitle.Quantum">
-        <item name="maxLines">1</item>
-        <item name="scrollHorizontally">true</item>
-        <item name="textAppearance">@style/TextAppearance.Quantum.DialogWindowTitle</item>
-    </style>
-
-    <style name="DialogWindowTitle.Quantum.Light">
-        <item name="textAppearance">@style/TextAppearance.Quantum.DialogWindowTitle</item>
-    </style>
-
-</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 8b1ca31..2ea7421 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -217,6 +217,7 @@
   <java-symbol type="id" name="pin_confirm_text" />
   <java-symbol type="id" name="pin_error_message" />
   <java-symbol type="id" name="timePickerLayout" />
+  <java-symbol type="id" name="profile_icon" />
 
   <java-symbol type="attr" name="actionModeShareDrawable" />
   <java-symbol type="attr" name="alertDialogCenterButtons" />
@@ -287,6 +288,8 @@
   <java-symbol type="bool" name="config_disableUsbPermissionDialogs"/>
   <java-symbol type="bool" name="config_windowIsRound" />
 
+  <java-symbol type="integer" name="config_bluetooth_max_advertisers" />
+  <java-symbol type="integer" name="config_bluetooth_max_scan_filters" />
   <java-symbol type="integer" name="config_cursorWindowSize" />
   <java-symbol type="integer" name="config_extraFreeKbytesAdjust" />
   <java-symbol type="integer" name="config_extraFreeKbytesAbsolute" />
@@ -344,7 +347,7 @@
   <java-symbol type="dimen" name="notification_title_text_size" />
   <java-symbol type="dimen" name="notification_subtext_size" />
   <java-symbol type="dimen" name="immersive_mode_cling_width" />
-  <java-symbol type="dimen" name="notification_quantum_rounded_rect_radius" />
+  <java-symbol type="dimen" name="notification_material_rounded_rect_radius" />
 
   <java-symbol type="string" name="add_account_button_label" />
   <java-symbol type="string" name="addToDictionary" />
@@ -1015,8 +1018,14 @@
   <java-symbol type="drawable" name="text_edit_side_paste_window" />
   <java-symbol type="drawable" name="text_edit_paste_window" />
   <java-symbol type="drawable" name="btn_check_off" />
-  <java-symbol type="drawable" name="btn_code_lock_default_holo" />
-  <java-symbol type="drawable" name="btn_code_lock_touched_holo" />
+  <java-symbol type="drawable" name="btn_code_lock_default_mtrl_alpha" />
+  <java-symbol type="drawable" name="btn_code_lock_touched_mtrl_alpha" />
+  <java-symbol type="drawable" name="indicator_code_lock_point_area_default_mtrl_alpha" />
+  <java-symbol type="drawable" name="indicator_code_lock_point_area_mtrl_alpha" />
+  <java-symbol type="drawable" name="indicator_code_lock_drag_direction_up_mtrl_alpha" />
+  <java-symbol type="color" name="lock_pattern_view_regular_color" />
+  <java-symbol type="color" name="lock_pattern_view_success_color" />
+  <java-symbol type="color" name="lock_pattern_view_error_color" />
   <java-symbol type="drawable" name="clock_dial" />
   <java-symbol type="drawable" name="clock_hand_hour" />
   <java-symbol type="drawable" name="clock_hand_minute" />
@@ -1060,11 +1069,6 @@
   <java-symbol type="drawable" name="ic_print" />
   <java-symbol type="drawable" name="ic_print_error" />
   <java-symbol type="drawable" name="ic_grayedout_printer" />
-  <java-symbol type="drawable" name="indicator_code_lock_drag_direction_green_up" />
-  <java-symbol type="drawable" name="indicator_code_lock_drag_direction_red_up" />
-  <java-symbol type="drawable" name="indicator_code_lock_point_area_default_holo" />
-  <java-symbol type="drawable" name="indicator_code_lock_point_area_green_holo" />
-  <java-symbol type="drawable" name="indicator_code_lock_point_area_red_holo" />
   <java-symbol type="drawable" name="jog_dial_arrow_long_left_green" />
   <java-symbol type="drawable" name="jog_dial_arrow_long_right_red" />
   <java-symbol type="drawable" name="jog_dial_arrow_short_left_and_right" />
@@ -1116,6 +1120,7 @@
   <java-symbol type="drawable" name="cling_arrow_up" />
   <java-symbol type="drawable" name="cling_bg" />
   <java-symbol type="drawable" name="ic_corp_badge" />
+  <java-symbol type="drawable" name="ic_corp_icon_badge" />
 
   <java-symbol type="layout" name="action_bar_home" />
   <java-symbol type="layout" name="action_bar_title_item" />
@@ -1453,6 +1458,7 @@
   <java-symbol type="array" name="config_defaultNotificationVibePattern" />
   <java-symbol type="array" name="config_notificationFallbackVibePattern" />
   <java-symbol type="array" name="config_onlySingleDcAllowed" />
+  <java-symbol type="bool" name="config_useAttentionLight" />
   <java-symbol type="bool" name="config_animateScreenLights" />
   <java-symbol type="bool" name="config_automatic_brightness_available" />
   <java-symbol type="bool" name="config_enableFusedLocationOverlay" />
@@ -1641,6 +1647,7 @@
   <java-symbol type="integer" name="config_maximumScreenDimDuration" />
   <java-symbol type="fraction" name="config_maximumScreenDimRatio" />
   <java-symbol type="string" name="config_customAdbPublicKeyConfirmationComponent" />
+  <java-symbol type="string" name="config_customVpnConfirmDialogComponent" />
   <java-symbol type="string" name="config_defaultNetworkScorerPackageName" />
 
   <java-symbol type="layout" name="resolver_list" />
@@ -1651,25 +1658,25 @@
   <java-symbol type="integer" name="config_maxResolverActivityColumns" />
   <java-symbol type="array" name="config_notificationSignalExtractors" />
 
-  <java-symbol type="layout" name="notification_quantum_action" />
-  <java-symbol type="layout" name="notification_quantum_action_list" />
-  <java-symbol type="layout" name="notification_quantum_action_tombstone" />
-  <java-symbol type="layout" name="notification_template_quantum_base" />
-  <java-symbol type="layout" name="notification_template_quantum_big_base" />
-  <java-symbol type="layout" name="notification_template_quantum_big_picture" />
-  <java-symbol type="layout" name="notification_template_quantum_big_text" />
-  <java-symbol type="layout" name="notification_template_quantum_inbox" />
-  <java-symbol type="layout" name="notification_template_quantum_media" />
-  <java-symbol type="layout" name="notification_template_quantum_big_media" />
+  <java-symbol type="layout" name="notification_material_action" />
+  <java-symbol type="layout" name="notification_material_action_list" />
+  <java-symbol type="layout" name="notification_material_action_tombstone" />
+  <java-symbol type="layout" name="notification_template_material_base" />
+  <java-symbol type="layout" name="notification_template_material_big_base" />
+  <java-symbol type="layout" name="notification_template_material_big_picture" />
+  <java-symbol type="layout" name="notification_template_material_big_text" />
+  <java-symbol type="layout" name="notification_template_material_inbox" />
+  <java-symbol type="layout" name="notification_template_material_media" />
+  <java-symbol type="layout" name="notification_template_material_big_media" />
   <java-symbol type="layout" name="notification_template_icon_group" />
-  <java-symbol type="layout" name="notification_quantum_media_action" />
+  <java-symbol type="layout" name="notification_material_media_action" />
   <java-symbol type="color" name="notification_action_legacy_color_filter" />
   <java-symbol type="color" name="notification_icon_bg_color" />
   <java-symbol type="drawable" name="notification_icon_legacy_bg" />
   <java-symbol type="drawable" name="notification_icon_legacy_bg_inset" />
-  <java-symbol type="drawable" name="notification_quantum_bg_dim" />
-  <java-symbol type="drawable" name="notification_quantum_bg" />
-  <java-symbol type="drawable" name="notification_quantum_media_progress" />
+  <java-symbol type="drawable" name="notification_material_bg_dim" />
+  <java-symbol type="drawable" name="notification_material_bg" />
+  <java-symbol type="drawable" name="notification_material_media_progress" />
   <java-symbol type="color" name="notification_media_action_bg" />
   <java-symbol type="color" name="notification_media_info_bg" />
   <java-symbol type="color" name="notification_media_progress" />
@@ -1856,13 +1863,9 @@
   <java-symbol type="string" name="timepicker_numbers_radius_multiplier_normal" />
   <java-symbol type="string" name="timepicker_transition_mid_radius_multiplier" />
   <java-symbol type="string" name="timepicker_transition_end_radius_multiplier" />
-  <java-symbol type="color" name="timepicker_default_text_color_holo_light" />
-  <java-symbol type="color" name="timepicker_default_disabled_color_holo_light" />
-  <java-symbol type="color" name="timepicker_default_ampm_unselected_background_color_holo_light" />
-  <java-symbol type="color" name="timepicker_default_ampm_selected_background_color_holo_light" />
   <java-symbol type="array" name="config_clockTickVibePattern" />
 
-  <!-- From various Quantum changes -->
+  <!-- From various Material changes -->
   <java-symbol type="attr" name="toolbarStyle" />
   <java-symbol type="attr" name="titleTextAppearance" />
   <java-symbol type="attr" name="subtitleTextAppearance" />
@@ -1871,5 +1874,12 @@
   <java-symbol type="id" name="icon_frame" />
   <java-symbol type="style" name="Animation.VolumePanel" />
   <java-symbol type="transition" name="no_transition" />
+  <java-symbol type="color" name="timepicker_default_text_color_material" />
+  <java-symbol type="color" name="timepicker_default_disabled_color_material" />
+  <java-symbol type="color" name="timepicker_default_ampm_unselected_background_color_material" />
+  <java-symbol type="color" name="timepicker_default_ampm_selected_background_color_material" />
+  <java-symbol type="color" name="timepicker_default_selector_color_material" />
+  <java-symbol type="color" name="timepicker_default_numbers_background_color_material" />
+  <java-symbol type="style" name="TextAppearance.Material.TimePicker.TimeLabel" />
 
 </resources>
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 648660b..cb5cb0c 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -55,7 +55,6 @@
 
         <item name="colorPrimaryDark">@color/legacy_primary_dark</item>
         <item name="colorPrimary">@color/legacy_primary</item>
-        <item name="colorPrimaryLight">@color/legacy_primary_light</item>
         <item name="colorControlActivated">@color/legacy_control_activated</item>
         <item name="colorControlNormal">@color/legacy_control_normal</item>
         <item name="colorControlHighlight">@color/legacy_button_pressed</item>
@@ -454,7 +453,6 @@
 
         <item name="colorPrimaryDark">@color/legacy_light_primary_dark</item>
         <item name="colorPrimary">@color/legacy_light_primary</item>
-        <item name="colorPrimaryLight">@color/legacy_light_primary_light</item>
         <item name="colorControlActivated">@color/legacy_light_control_activated</item>
         <item name="colorControlNormal">@color/legacy_light_control_normal</item>
         <item name="colorControlHighlight">@color/legacy_light_button_pressed</item>
@@ -969,7 +967,6 @@
 
         <item name="colorPrimaryDark">@color/holo_primary_dark</item>
         <item name="colorPrimary">@color/holo_primary</item>
-        <item name="colorPrimaryLight">@color/holo_primary_light</item>
         <item name="colorControlActivated">@color/holo_control_activated</item>
         <item name="colorControlNormal">@color/holo_control_normal</item>
         <item name="colorControlHighlight">@color/holo_button_pressed</item>
@@ -1310,7 +1307,6 @@
 
         <item name="colorPrimaryDark">@color/holo_light_primary_dark</item>
         <item name="colorPrimary">@color/holo_light_primary</item>
-        <item name="colorPrimaryLight">@color/holo_light_primary_light</item>
         <item name="colorControlActivated">@color/holo_light_control_activated</item>
         <item name="colorControlNormal">@color/holo_light_control_normal</item>
         <item name="colorControlHighlight">@color/holo_light_button_pressed</item>
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index aee35ef..6b7d861 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -38,18 +38,18 @@
          to a device’s native theme with all device customizations intact.</p>
          <p>For example, when you set your app's {@code targetSdkVersion} to XX or higher, this
          theme is applied to your application by default. As such, your app might appear with the
-         {@link #Theme_Quantum Quantum} styles on one device, but with a different set of styles on
+         {@link #Theme_Material Material} styles on one device, but with a different set of styles on
          another device. This is great if you want your app to fit with the device's native look and
          feel. If, however, you prefer to keep your UI style the same across all devices, you should
-         apply a specific theme such as {@link #Theme_Quantum Quantum} or one of your own design.
+         apply a specific theme such as {@link #Theme_Material Material} or one of your own design.
          For more information, read <a
-         href="http://android-developers.blogspot.com/20XX/XX/quantum-everywhere.html">Quantum
+         href="http://android-developers.blogspot.com/20XX/XX/material-everywhere.html">Material
          Everywhere</a>.</p>
          <p>Styles used by the DeviceDefault theme are named using the convention
          Type.DeviceDefault.Etc (for example, {@code Widget.DeviceDefault.Button} and
          {@code TextAppearance.DeviceDefault.Widget.PopupMenu.Large}).</p>
           -->
-    <style name="Theme.DeviceDefault" parent="Theme.Quantum" >
+    <style name="Theme.DeviceDefault" parent="Theme.Material" >
         <!-- Text styles -->
         <item name="textAppearance">@style/TextAppearance.DeviceDefault</item>
         <item name="textAppearanceInverse">@style/TextAppearance.DeviceDefault.Inverse</item>
@@ -210,27 +210,27 @@
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault} with no action bar -->
-    <style name="Theme.DeviceDefault.NoActionBar" parent="Theme.Quantum.NoActionBar"  />
+    <style name="Theme.DeviceDefault.NoActionBar" parent="Theme.Material.NoActionBar"  />
 
     <!-- Variant of {@link #Theme_DeviceDefault} with no action bar and no status bar.  This theme
          sets {@link android.R.attr#windowFullscreen} to true.  -->
-    <style name="Theme.DeviceDefault.NoActionBar.Fullscreen" parent="Theme.Quantum.NoActionBar.Fullscreen"  />
+    <style name="Theme.DeviceDefault.NoActionBar.Fullscreen" parent="Theme.Material.NoActionBar.Fullscreen"  />
 
     <!-- Variant of {@link #Theme_DeviceDefault} with no action bar and no status bar and
     extending in to overscan region.  This theme
     sets {@link android.R.attr#windowFullscreen} and {@link android.R.attr#windowOverscan}
     to true. -->
-    <style name="Theme.DeviceDefault.NoActionBar.Overscan" parent="Theme.Quantum.NoActionBar.Overscan"  />
+    <style name="Theme.DeviceDefault.NoActionBar.Overscan" parent="Theme.Material.NoActionBar.Overscan"  />
 
     <!-- Variant of {@link #Theme_DeviceDefault} that has no title bar and translucent
          system decor.  This theme sets {@link android.R.attr#windowTranslucentStatus} and
          {@link android.R.attr#windowTranslucentNavigation} to true. -->
-    <style name="Theme.DeviceDefault.NoActionBar.TranslucentDecor" parent="Theme.Quantum.NoActionBar.TranslucentDecor"  />
+    <style name="Theme.DeviceDefault.NoActionBar.TranslucentDecor" parent="Theme.Material.NoActionBar.TranslucentDecor"  />
 
     <!-- DeviceDefault theme for dialog windows and activities. This changes the window to be
     floating (not fill the entire screen), and puts a frame around its contents. You can set this
     theme on an activity if you would like to make an activity that looks like a Dialog. -->
-    <style name="Theme.DeviceDefault.Dialog" parent="Theme.Quantum.Dialog" >
+    <style name="Theme.DeviceDefault.Dialog" parent="Theme.Material.Dialog" >
         <item name="windowTitleStyle">@style/DialogWindowTitle.DeviceDefault</item>
         <item name="windowAnimationStyle">@style/Animation.DeviceDefault.Dialog</item>
 
@@ -243,14 +243,14 @@
 
     <!-- Variant of {@link #Theme_DeviceDefault_Dialog} that has a nice minimum width for a
     regular dialog. -->
-    <style name="Theme.DeviceDefault.Dialog.MinWidth" parent="Theme.Quantum.Dialog.MinWidth" />
+    <style name="Theme.DeviceDefault.Dialog.MinWidth" parent="Theme.Material.Dialog.MinWidth" />
 
     <!-- Variant of {@link #Theme_DeviceDefault_Dialog} without an action bar -->
-    <style name="Theme.DeviceDefault.Dialog.NoActionBar" parent="Theme.Quantum.Dialog.NoActionBar" />
+    <style name="Theme.DeviceDefault.Dialog.NoActionBar" parent="Theme.Material.Dialog.NoActionBar" />
 
     <!-- Variant of {@link #Theme_DeviceDefault_Dialog_NoActionBar} that has a nice minimum width
     for a regular dialog. -->
-    <style name="Theme.DeviceDefault.Dialog.NoActionBar.MinWidth" parent="Theme.Quantum.Dialog.NoActionBar.MinWidth" />
+    <style name="Theme.DeviceDefault.Dialog.NoActionBar.MinWidth" parent="Theme.Material.Dialog.NoActionBar.MinWidth" />
 
     <!-- Variant of Theme.DeviceDefault.Dialog that has a fixed size. -->
     <style name="Theme.DeviceDefault.Dialog.FixedSize">
@@ -270,49 +270,49 @@
 
     <!-- DeviceDefault 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.DeviceDefault.DialogWhenLarge" parent="Theme.Quantum.DialogWhenLarge"  />
+    <style name="Theme.DeviceDefault.DialogWhenLarge" parent="Theme.Material.DialogWhenLarge"  />
 
     <!-- DeviceDefault 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.DeviceDefault.DialogWhenLarge.NoActionBar" parent="Theme.Quantum.DialogWhenLarge.NoActionBar"  />
+    <style name="Theme.DeviceDefault.DialogWhenLarge.NoActionBar" parent="Theme.Material.DialogWhenLarge.NoActionBar"  />
 
     <!-- DeviceDefault theme for a presentation window on a secondary display. -->
-    <style name="Theme.DeviceDefault.Dialog.Presentation" parent="Theme.Quantum.Dialog.Presentation" />
+    <style name="Theme.DeviceDefault.Dialog.Presentation" parent="Theme.Material.Dialog.Presentation" />
 
-    <style name="Theme.DeviceDefault.Dialog.TimePicker" parent="Theme.Quantum.Dialog.TimePicker"/>
+    <style name="Theme.DeviceDefault.Dialog.TimePicker" parent="Theme.Material.Dialog.TimePicker"/>
 
     <!-- DeviceDefault theme for panel windows. This removes all extraneous window
     decorations, so you basically have an empty rectangle in which to place your content. It makes
     the window floating, with a transparent background, and turns off dimming behind the window. -->
-    <style name="Theme.DeviceDefault.Panel" parent="Theme.Quantum.Panel"  />
+    <style name="Theme.DeviceDefault.Panel" parent="Theme.Material.Panel"  />
 
     <!-- DeviceDefault theme for windows that want to have the user's selected wallpaper appear
     behind them. -->
-    <style name="Theme.DeviceDefault.Wallpaper" parent="Theme.Quantum.Wallpaper"  />
+    <style name="Theme.DeviceDefault.Wallpaper" parent="Theme.Material.Wallpaper"  />
 
     <!-- DeviceDefault theme for windows that want to have the user's selected wallpaper appear
     behind them and without an action bar. -->
-    <style name="Theme.DeviceDefault.Wallpaper.NoTitleBar" parent="Theme.Quantum.Wallpaper.NoTitleBar"  />
+    <style name="Theme.DeviceDefault.Wallpaper.NoTitleBar" parent="Theme.Material.Wallpaper.NoTitleBar"  />
 
     <!-- DeviceDefault style for input methods, which is used by the
          {@link android.inputmethodservice.InputMethodService} class.-->
-    <style name="Theme.DeviceDefault.InputMethod" parent="Theme.Quantum.InputMethod"  />
+    <style name="Theme.DeviceDefault.InputMethod" parent="Theme.Material.InputMethod"  />
 
     <!-- DeviceDefault style for input methods, which is used by the
          {@link android.service.voice.VoiceInteractionSession} class.-->
-    <style name="Theme.DeviceDefault.VoiceInteractionSession" parent="Theme.Quantum.VoiceInteractionSession" >
+    <style name="Theme.DeviceDefault.VoiceInteractionSession" parent="Theme.Material.VoiceInteractionSession" >
 
     </style>
-    <style name="Theme.DeviceDefault.Dialog.Alert" parent="Theme.Quantum.Dialog.Alert">
+    <style name="Theme.DeviceDefault.Dialog.Alert" parent="Theme.Material.Dialog.Alert">
         <item name="windowTitleStyle">@style/DialogWindowTitle.DeviceDefault</item>
     </style>
 
-    <style name="Theme.DeviceDefault.SearchBar" parent="Theme.Quantum.SearchBar" />
-    <style name="Theme.DeviceDefault.Dialog.NoFrame" parent="Theme.Quantum.Dialog.NoFrame" />
+    <style name="Theme.DeviceDefault.SearchBar" parent="Theme.Material.SearchBar" />
+    <style name="Theme.DeviceDefault.Dialog.NoFrame" parent="Theme.Material.Dialog.NoFrame" />
 
     <!-- Variant of {@link #Theme_DeviceDefault} with a light-colored style -->
-    <style name="Theme.DeviceDefault.Light" parent="Theme.Quantum.Light" >
+    <style name="Theme.DeviceDefault.Light" parent="Theme.Material.Light" >
         <!-- Text styles -->
         <item name="textAppearance">@style/TextAppearance.DeviceDefault</item>
         <item name="textAppearanceInverse">@style/TextAppearance.DeviceDefault.Inverse</item>
@@ -469,30 +469,30 @@
 
     <!-- Variant of the DeviceDefault (light) theme that has a solid (opaque) action bar with an
     inverse color profile. -->
-    <style name="Theme.DeviceDefault.Light.DarkActionBar" parent="Theme.Quantum.Light.DarkActionBar" />
+    <style name="Theme.DeviceDefault.Light.DarkActionBar" parent="Theme.Material.Light.DarkActionBar" />
 
     <!-- Variant of {@link #Theme_DeviceDefault_Light} with no action bar -->
-    <style name="Theme.DeviceDefault.Light.NoActionBar" parent="Theme.Quantum.Light.NoActionBar"  />
+    <style name="Theme.DeviceDefault.Light.NoActionBar" parent="Theme.Material.Light.NoActionBar"  />
 
     <!-- Variant of {@link #Theme_DeviceDefault_Light} with no action bar and no status bar.
          This theme sets {@link android.R.attr#windowFullscreen} to true.  -->
-    <style name="Theme.DeviceDefault.Light.NoActionBar.Fullscreen" parent="Theme.Quantum.Light.NoActionBar.Fullscreen"  />
+    <style name="Theme.DeviceDefault.Light.NoActionBar.Fullscreen" parent="Theme.Material.Light.NoActionBar.Fullscreen"  />
 
     <!-- Variant of {@link #Theme_DeviceDefault_Light} with no action bar and no status bar
     and extending in to overscan region.  This theme
     sets {@link android.R.attr#windowFullscreen} and {@link android.R.attr#windowOverscan}
     to true. -->
-    <style name="Theme.DeviceDefault.Light.NoActionBar.Overscan" parent="Theme.Quantum.Light.NoActionBar.Overscan" />
+    <style name="Theme.DeviceDefault.Light.NoActionBar.Overscan" parent="Theme.Material.Light.NoActionBar.Overscan" />
 
     <!-- Variant of {@link #Theme_DeviceDefault_Light} that has no title bar and translucent
          system decor.  This theme sets {@link android.R.attr#windowTranslucentStatus} and
          {@link android.R.attr#windowTranslucentNavigation} to true. -->
-    <style name="Theme.DeviceDefault.Light.NoActionBar.TranslucentDecor" parent="Theme.Quantum.Light.NoActionBar.TranslucentDecor" />
+    <style name="Theme.DeviceDefault.Light.NoActionBar.TranslucentDecor" parent="Theme.Material.Light.NoActionBar.TranslucentDecor" />
 
     <!-- DeviceDefault light theme for dialog windows and activities. This changes the window to be
     floating (not fill the entire screen), and puts a frame around its contents. You can set this
     theme on an activity if you would like to make an activity that looks like a Dialog.-->
-    <style name="Theme.DeviceDefault.Light.Dialog" parent="Theme.Quantum.Light.Dialog" >
+    <style name="Theme.DeviceDefault.Light.Dialog" parent="Theme.Material.Light.Dialog" >
         <item name="windowTitleStyle">@style/DialogWindowTitle.DeviceDefault.Light</item>
         <item name="windowAnimationStyle">@style/Animation.DeviceDefault.Dialog</item>
 
@@ -505,14 +505,14 @@
 
     <!-- Variant of {@link #Theme_DeviceDefault_Light_Dialog} that has a nice minimum width for a
     regular dialog. -->
-    <style name="Theme.DeviceDefault.Light.Dialog.MinWidth" parent="Theme.Quantum.Light.Dialog.MinWidth" />
+    <style name="Theme.DeviceDefault.Light.Dialog.MinWidth" parent="Theme.Material.Light.Dialog.MinWidth" />
 
      <!-- Variant of {@link #Theme_DeviceDefault_Light_Dialog} without an action bar -->
-    <style name="Theme.DeviceDefault.Light.Dialog.NoActionBar" parent="Theme.Quantum.Light.Dialog.NoActionBar" />
+    <style name="Theme.DeviceDefault.Light.Dialog.NoActionBar" parent="Theme.Material.Light.Dialog.NoActionBar" />
 
     <!-- Variant of {@link #Theme_DeviceDefault_Light_Dialog_NoActionBar} that has a nice minimum
     width for a regular dialog. -->
-    <style name="Theme.DeviceDefault.Light.Dialog.NoActionBar.MinWidth" parent="Theme.Quantum.Light.Dialog.NoActionBar.MinWidth" />
+    <style name="Theme.DeviceDefault.Light.Dialog.NoActionBar.MinWidth" parent="Theme.Material.Light.Dialog.NoActionBar.MinWidth" />
 
     <!-- Variant of Theme.DeviceDefault.Dialog that has a fixed size. -->
     <style name="Theme.DeviceDefault.Light.Dialog.FixedSize">
@@ -532,27 +532,27 @@
 
     <!-- DeviceDefault light 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.DeviceDefault.Light.DialogWhenLarge" parent="Theme.Quantum.Light.DialogWhenLarge"  />
+    <style name="Theme.DeviceDefault.Light.DialogWhenLarge" parent="Theme.Material.Light.DialogWhenLarge"  />
 
     <!-- DeviceDefault 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.DeviceDefault.Light.DialogWhenLarge.NoActionBar" parent="Theme.Quantum.Light.DialogWhenLarge.NoActionBar"  />
+    <style name="Theme.DeviceDefault.Light.DialogWhenLarge.NoActionBar" parent="Theme.Material.Light.DialogWhenLarge.NoActionBar"  />
 
     <!-- DeviceDefault light theme for a presentation window on a secondary display. -->
-    <style name="Theme.DeviceDefault.Light.Dialog.Presentation" parent="Theme.Quantum.Light.Dialog.Presentation" />
+    <style name="Theme.DeviceDefault.Light.Dialog.Presentation" parent="Theme.Material.Light.Dialog.Presentation" />
 
-    <style name="Theme.DeviceDefault.Light.Dialog.TimePicker" parent="Theme.Quantum.Light.Dialog.TimePicker"/>
+    <style name="Theme.DeviceDefault.Light.Dialog.TimePicker" parent="Theme.Material.Light.Dialog.TimePicker"/>
 
     <!-- DeviceDefault light theme for panel windows. This removes all extraneous window
     decorations, so you basically have an empty rectangle in which to place your content. It makes
     the window floating, with a transparent background, and turns off dimming behind the window. -->
-    <style name="Theme.DeviceDefault.Light.Panel" parent="Theme.Quantum.Light.Panel"  />
+    <style name="Theme.DeviceDefault.Light.Panel" parent="Theme.Material.Light.Panel"  />
 
-    <style name="Theme.DeviceDefault.Light.Dialog.Alert" parent="Theme.Quantum.Light.Dialog.Alert">
+    <style name="Theme.DeviceDefault.Light.Dialog.Alert" parent="Theme.Material.Light.Dialog.Alert">
         <item name="windowTitleStyle">@style/DialogWindowTitle.DeviceDefault.Light</item>
     </style>
 
-    <style name="Theme.DeviceDefault.Light.SearchBar" parent="Theme.Quantum.Light.SearchBar" />
+    <style name="Theme.DeviceDefault.Light.SearchBar" parent="Theme.Material.Light.SearchBar" />
 
 </resources>
diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml
new file mode 100644
index 0000000..c14d7fc9
--- /dev/null
+++ b/core/res/res/values/themes_material.xml
@@ -0,0 +1,1235 @@
+<?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>
+
+    <!-- Material theme (dark version).
+         <p>If you want to ensure that your
+         app consistently uses the Material theme at all times, you must explicitly declare it in your
+         manifest. For example, {@code &lt;application android:theme="@style/Theme.Material"&gt;}.
+
+         <p>Styles used by the Material theme are named using the convention Type.Material.Etc
+         (for example, {@code Widget.Material.Button} and {@code
+         TextAppearance.Material.Widget.PopupMenu.Large}).
+         Specific resources used by Material are named using the convention @type/foo_bar_baz_material
+         with trailing _dark or _light specifiers if they are not shared between both light and
+         dark versions of the theme. -->
+    <style name="Theme.Material">
+        <item name="colorForeground">@color/bright_foreground_material_dark</item>
+        <item name="colorForegroundInverse">@color/bright_foreground_material_light</item>
+        <item name="colorBackground">@color/background_material_dark</item>
+        <item name="colorBackgroundCacheHint">@color/background_cache_hint_selector_material_dark</item>
+        <item name="disabledAlpha">0.5</item>
+        <item name="backgroundDimAmount">0.6</item>
+
+        <!-- Text styles -->
+        <item name="textAppearance">@style/TextAppearance.Material</item>
+        <item name="textAppearanceInverse">@style/TextAppearance.Material.Inverse</item>
+
+        <item name="textColorPrimary">@color/primary_text_material_dark</item>
+        <item name="textColorPrimaryInverse">@color/primary_text_material_light</item>
+        <item name="textColorPrimaryDisableOnly">@color/primary_text_disable_only_material_dark</item>
+        <item name="textColorSecondary">@color/secondary_text_material_dark</item>
+        <item name="textColorSecondaryInverse">@color/secondary_text_material_light</item>
+        <item name="textColorTertiary">@color/tertiary_text_material_dark</item>
+        <item name="textColorTertiaryInverse">@color/tertiary_text_material_light</item>
+        <item name="textColorHint">@color/hint_foreground_material_dark</item>
+        <item name="textColorHintInverse">@color/hint_foreground_material_light</item>
+        <item name="textColorHighlight">@color/highlighted_text_material_dark</item>
+        <item name="textColorHighlightInverse">@color/highlighted_text_material_light</item>
+        <item name="textColorLink">@color/material_teal_500</item>
+        <item name="textColorLinkInverse">@color/material_teal_500</item>
+        <item name="textColorSearchUrl">@color/search_url_text_material_dark</item>
+        <item name="textColorAlertDialogListItem">@color/primary_text_material_dark</item>
+
+        <item name="textAppearanceLarge">@style/TextAppearance.Material.Large</item>
+        <item name="textAppearanceLargeInverse">@style/TextAppearance.Material.Large.Inverse</item>
+        <item name="textAppearanceMedium">@style/TextAppearance.Material.Medium</item>
+        <item name="textAppearanceMediumInverse">@style/TextAppearance.Material.Medium.Inverse</item>
+        <item name="textAppearanceSmall">@style/TextAppearance.Material.Small</item>
+        <item name="textAppearanceSmallInverse">@style/TextAppearance.Material.Small.Inverse</item>
+        <item name="textAppearanceSearchResultTitle">@style/TextAppearance.Material.SearchResult.Title</item>
+        <item name="textAppearanceSearchResultSubtitle">@style/TextAppearance.Material.SearchResult.Subtitle</item>
+
+        <item name="textAppearanceButton">@style/TextAppearance.Material.Widget.Button</item>
+
+        <item name="editTextColor">?attr/textColorPrimary</item>
+        <item name="editTextBackground">@drawable/edit_text_material</item>
+
+        <item name="candidatesTextStyleSpans">@string/candidates_style</item>
+
+        <item name="textCheckMark">@drawable/indicator_check_mark_dark</item>
+        <item name="textCheckMarkInverse">@drawable/indicator_check_mark_light</item>
+
+        <item name="textAppearanceLargePopupMenu">@style/TextAppearance.Material.Widget.PopupMenu.Large</item>
+        <item name="textAppearanceSmallPopupMenu">@style/TextAppearance.Material.Widget.PopupMenu.Small</item>
+
+        <!-- Button styles -->
+        <item name="buttonStyle">@style/Widget.Material.Button</item>
+        <item name="buttonStyleSmall">@style/Widget.Material.Button.Small</item>
+        <item name="buttonStyleInset">@style/Widget.Material.Button.Inset</item>
+        <item name="buttonStyleToggle">@style/Widget.Material.Button.Toggle</item>
+
+        <item name="switchStyle">@style/Widget.Material.CompoundButton.Switch</item>
+        <item name="mediaRouteButtonStyle">@style/Widget.Material.MediaRouteButton</item>
+
+        <item name="selectableItemBackground">@drawable/item_background_material</item>
+        <item name="selectableItemBackgroundBorderless">@drawable/item_background_borderless_material</item>
+        <item name="borderlessButtonStyle">@style/Widget.Material.Button.Borderless</item>
+        <item name="homeAsUpIndicator">@drawable/ic_ab_back_material</item>
+
+        <!-- List attributes -->
+        <item name="listPreferredItemHeight">64dip</item>
+        <item name="listPreferredItemHeightSmall">48dip</item>
+        <item name="listPreferredItemHeightLarge">80dip</item>
+        <item name="dropdownListPreferredItemHeight">?attr/listPreferredItemHeightSmall</item>
+        <item name="textAppearanceListItem">@style/TextAppearance.Material.Subhead</item>
+        <item name="textAppearanceListItemSmall">@style/TextAppearance.Material.Subhead</item>
+        <item name="textAppearanceListItemSecondary">@style/TextAppearance.Material.Body1</item>
+        <item name="listPreferredItemPaddingLeft">16dip</item>
+        <item name="listPreferredItemPaddingRight">16dip</item>
+        <item name="listPreferredItemPaddingStart">16dip</item>
+        <item name="listPreferredItemPaddingEnd">16dip</item>
+
+        <!-- @hide -->
+        <item name="searchResultListItemHeight">58dip</item>
+        <item name="listDivider">@drawable/list_divider_material</item>
+        <item name="listSeparatorTextViewStyle">@style/Widget.Material.TextView.ListSeparator</item>
+
+        <item name="listChoiceIndicatorSingle">@drawable/btn_radio_material_anim</item>
+        <item name="listChoiceIndicatorMultiple">@drawable/btn_check_material_anim</item>
+
+        <item name="listChoiceBackgroundIndicator">?attr/selectableItemBackground</item>
+        <item name="activatedBackgroundIndicator">@drawable/activated_background_material</item>
+
+        <item name="listDividerAlertDialog">@drawable/list_divider_material</item>
+
+        <item name="expandableListPreferredItemPaddingLeft">40dip</item>
+        <item name="expandableListPreferredChildPaddingLeft">?attr/expandableListPreferredItemPaddingLeft</item>
+
+        <item name="expandableListPreferredItemIndicatorLeft">3dip</item>
+        <item name="expandableListPreferredItemIndicatorRight">0dip</item>
+        <item name="expandableListPreferredChildIndicatorLeft">?attr/expandableListPreferredItemIndicatorLeft</item>
+        <item name="expandableListPreferredChildIndicatorRight">?attr/expandableListPreferredItemIndicatorRight</item>
+        <item name="findOnPageNextDrawable">@drawable/ic_find_next_material</item>
+        <item name="findOnPagePreviousDrawable">@drawable/ic_find_previous_material</item>
+
+        <!-- Gallery attributes -->
+        <item name="galleryItemBackground">@drawable/gallery_item_background</item>
+
+        <!-- Window attributes -->
+        <item name="windowBackground">@color/background_material_dark</item>
+        <item name="windowFrame">@null</item>
+        <item name="windowNoTitle">false</item>
+        <item name="windowFullscreen">false</item>
+        <item name="windowOverscan">false</item>
+        <item name="windowIsFloating">false</item>
+        <item name="windowContentOverlay">@null</item>
+        <item name="windowShowWallpaper">false</item>
+        <item name="windowTitleStyle">@style/WindowTitle.Material</item>
+        <item name="windowTitleSize">25dip</item>
+        <item name="windowTitleBackgroundStyle">@style/WindowTitleBackground.Material</item>
+        <item name="windowContentTransitions">false</item>
+        <item name="windowAnimationStyle">@style/Animation.Material.Activity</item>
+        <item name="windowSoftInputMode">stateUnspecified|adjustUnspecified</item>
+        <item name="windowActionBar">true</item>
+        <item name="windowActionModeOverlay">false</item>
+        <item name="windowDrawsSystemBarBackgrounds">true</item>
+        <item name="windowActionBarFullscreenDecorLayout">@layout/screen_toolbar</item>
+        <item name="statusBarColor">?attr/colorPrimaryDark</item>
+        <item name="navigationBarColor">@color/black</item>
+        <item name="windowEnterTransition">@transition/fade</item>
+        <item name="windowSharedElementEnterTransition">@transition/move</item>
+        <item name="windowSharedElementExitTransition">@transition/move</item>
+
+        <!-- Dialog attributes -->
+        <item name="dialogTheme">@style/Theme.Material.Dialog</item>
+        <item name="dialogTitleIconsDecorLayout">@layout/dialog_title_icons_material</item>
+        <item name="dialogCustomTitleDecorLayout">@layout/dialog_custom_title_material</item>
+        <item name="dialogTitleDecorLayout">@layout/dialog_title_material</item>
+
+        <!-- AlertDialog attributes -->
+        <item name="alertDialogTheme">@style/Theme.Material.Dialog.Alert</item>
+        <item name="alertDialogStyle">@style/AlertDialog.Material</item>
+        <item name="alertDialogCenterButtons">false</item>
+        <item name="alertDialogIcon">@drawable/ic_dialog_alert_material</item>
+
+        <!-- Presentation attributes -->
+        <item name="presentationTheme">@style/Theme.Material.Dialog.Presentation</item>
+
+        <!-- Toast attributes -->
+        <item name="toastFrameBackground">@drawable/toast_frame</item>
+
+        <!-- Panel attributes -->
+        <item name="panelBackground">?attr/colorBackground</item>
+        <item name="panelFullBackground">@drawable/menu_background_fill_parent_width</item>
+        <!-- These three attributes do not seems to be used by the framework. Declared public though -->
+        <item name="panelColorBackground">#000</item>
+        <item name="panelColorForeground">?attr/textColorPrimary</item>
+        <item name="panelTextAppearance">?attr/textAppearance</item>
+
+        <item name="panelMenuIsCompact">true</item>
+        <item name="panelMenuListWidth">250dip</item>
+        <item name="panelMenuListTheme">@style/Theme.Material.CompactMenu</item>
+
+        <!-- Scrollbar attributes -->
+        <item name="scrollbarFadeDuration">250</item>
+        <item name="scrollbarDefaultDelayBeforeFade">300</item>
+        <item name="scrollbarSize">10dip</item>
+        <item name="scrollbarThumbHorizontal">@drawable/scrollbar_handle_material</item>
+        <item name="scrollbarThumbVertical">@drawable/scrollbar_handle_material</item>
+        <item name="scrollbarTrackHorizontal">@null</item>
+        <item name="scrollbarTrackVertical">@null</item>
+
+        <!-- Text selection handle attributes -->
+        <item name="textSelectHandleLeft">@drawable/text_select_handle_left_material</item>
+        <item name="textSelectHandleRight">@drawable/text_select_handle_right_material</item>
+        <item name="textSelectHandle">@drawable/text_select_handle_middle_material</item>
+        <item name="textSelectHandleWindowStyle">@style/Widget.Material.TextSelectHandle</item>
+        <item name="textSuggestionsWindowStyle">@style/Widget.Material.TextSuggestionsPopupWindow</item>
+        <item name="textCursorDrawable">@drawable/text_cursor_material</item>
+
+        <!-- Widget styles -->
+        <item name="absListViewStyle">@style/Widget.Material.AbsListView</item>
+        <item name="autoCompleteTextViewStyle">@style/Widget.Material.AutoCompleteTextView</item>
+        <item name="checkboxStyle">@style/Widget.Material.CompoundButton.CheckBox</item>
+        <item name="checkedTextViewStyle">@style/Widget.Material.CheckedTextView</item>
+        <item name="dropDownListViewStyle">@style/Widget.Material.ListView.DropDown</item>
+        <item name="editTextStyle">@style/Widget.Material.EditText</item>
+        <item name="expandableListViewStyle">@style/Widget.Material.ExpandableListView</item>
+        <item name="expandableListViewWhiteStyle">@style/Widget.Material.ExpandableListView.White</item>
+        <item name="fastScrollStyle">@style/Widget.Material.FastScroll</item>
+        <item name="galleryStyle">@style/Widget.Material.Gallery</item>
+        <item name="gestureOverlayViewStyle">@style/Widget.Material.GestureOverlayView</item>
+        <item name="gridViewStyle">@style/Widget.Material.GridView</item>
+        <item name="imageButtonStyle">@style/Widget.Material.ImageButton</item>
+        <item name="imageWellStyle">@style/Widget.Material.ImageWell</item>
+        <item name="listViewStyle">@style/Widget.Material.ListView</item>
+        <item name="listViewWhiteStyle">@style/Widget.Material.ListView.White</item>
+        <item name="popupWindowStyle">@style/Widget.Material.PopupWindow</item>
+        <item name="progressBarStyle">@style/Widget.Material.ProgressBar</item>
+        <item name="progressBarStyleHorizontal">@style/Widget.Material.ProgressBar.Horizontal</item>
+        <item name="progressBarStyleSmall">@style/Widget.Material.ProgressBar.Small</item>
+        <item name="progressBarStyleSmallTitle">@style/Widget.Material.ProgressBar.Small.Title</item>
+        <item name="progressBarStyleLarge">@style/Widget.Material.ProgressBar.Large</item>
+        <item name="progressBarStyleInverse">@style/Widget.Material.ProgressBar.Inverse</item>
+        <item name="progressBarStyleSmallInverse">@style/Widget.Material.ProgressBar.Small.Inverse</item>
+        <item name="progressBarStyleLargeInverse">@style/Widget.Material.ProgressBar.Large.Inverse</item>
+        <item name="seekBarStyle">@style/Widget.Material.SeekBar</item>
+        <item name="ratingBarStyle">@style/Widget.Material.RatingBar</item>
+        <item name="ratingBarStyleIndicator">@style/Widget.Material.RatingBar.Indicator</item>
+        <item name="ratingBarStyleSmall">@style/Widget.Material.RatingBar.Small</item>
+        <item name="radioButtonStyle">@style/Widget.Material.CompoundButton.RadioButton</item>
+        <item name="scrollViewStyle">@style/Widget.Material.ScrollView</item>
+        <item name="horizontalScrollViewStyle">@style/Widget.Material.HorizontalScrollView</item>
+        <item name="spinnerStyle">?attr/dropDownSpinnerStyle</item>
+        <item name="dropDownSpinnerStyle">@style/Widget.Material.Spinner.DropDown</item>
+        <item name="starStyle">@style/Widget.Material.CompoundButton.Star</item>
+        <item name="tabWidgetStyle">@style/Widget.Material.TabWidget</item>
+        <item name="textViewStyle">@style/Widget.Material.TextView</item>
+        <item name="errorMessageBackground">@drawable/popup_inline_error_holo_dark</item>
+        <item name="errorMessageAboveBackground">@drawable/popup_inline_error_above_holo_dark</item>
+        <item name="webTextViewStyle">@style/Widget.Material.WebTextView</item>
+        <item name="webViewStyle">@style/Widget.Material.WebView</item>
+        <item name="dropDownItemStyle">@style/Widget.Material.DropDownItem</item>
+        <item name="spinnerDropDownItemStyle">@style/Widget.Material.DropDownItem.Spinner</item>
+        <item name="spinnerItemStyle">@style/Widget.Material.TextView.SpinnerItem</item>
+        <item name="dropDownHintAppearance">@style/TextAppearance.Material.Widget.DropDownHint</item>
+        <item name="keyboardViewStyle">@style/Widget.Material.KeyboardView</item>
+        <item name="quickContactBadgeStyleWindowSmall">@style/Widget.Material.QuickContactBadge.WindowSmall</item>
+        <item name="quickContactBadgeStyleWindowMedium">@style/Widget.Material.QuickContactBadge.WindowMedium</item>
+        <item name="quickContactBadgeStyleWindowLarge">@style/Widget.Material.QuickContactBadge.WindowLarge</item>
+        <item name="quickContactBadgeStyleSmallWindowSmall">@style/Widget.Material.QuickContactBadgeSmall.WindowSmall</item>
+        <item name="quickContactBadgeStyleSmallWindowMedium">@style/Widget.Material.QuickContactBadgeSmall.WindowMedium</item>
+        <item name="quickContactBadgeStyleSmallWindowLarge">@style/Widget.Material.QuickContactBadgeSmall.WindowLarge</item>
+        <item name="listPopupWindowStyle">@style/Widget.Material.ListPopupWindow</item>
+        <item name="popupMenuStyle">@style/Widget.Material.PopupMenu</item>
+        <item name="stackViewStyle">@style/Widget.Material.StackView</item>
+        <item name="activityChooserViewStyle">@style/Widget.Material.ActivityChooserView</item>
+
+        <!-- Preference styles -->
+        <item name="preferenceScreenStyle">@style/Preference.Material.PreferenceScreen</item>
+        <item name="preferenceFragmentStyle">@style/PreferenceFragment.Material</item>
+        <item name="preferenceFragmentPaddingSide">0dip</item>
+        <item name="preferenceCategoryStyle">@style/Preference.Material.Category</item>
+        <item name="preferenceStyle">@style/Preference.Material</item>
+        <item name="preferenceInformationStyle">@style/Preference.Material.Information</item>
+        <item name="checkBoxPreferenceStyle">@style/Preference.Material.CheckBoxPreference</item>
+        <item name="switchPreferenceStyle">@style/Preference.Material.SwitchPreference</item>
+        <item name="yesNoPreferenceStyle">@style/Preference.Material.DialogPreference.YesNoPreference</item>
+        <item name="dialogPreferenceStyle">@style/Preference.Material.DialogPreference</item>
+        <item name="editTextPreferenceStyle">@style/Preference.Material.DialogPreference.EditTextPreference</item>
+        <item name="ringtonePreferenceStyle">@style/Preference.Material.RingtonePreference</item>
+        <item name="preferenceLayoutChild">@layout/preference_child_material</item>
+        <item name="detailsElementBackground">?attr/colorBackground</item>
+
+        <!-- Search widget styles -->
+        <item name="searchWidgetCorpusItemBackground">@color/search_widget_corpus_item_background</item>
+
+        <!-- Action bar styles -->
+        <item name="actionDropDownStyle">@style/Widget.Material.Spinner.DropDown.ActionBar</item>
+        <item name="actionButtonStyle">@style/Widget.Material.ActionButton</item>
+        <item name="actionOverflowButtonStyle">@style/Widget.Material.ActionButton.Overflow</item>
+        <item name="actionOverflowMenuStyle">@android:style/Widget.Material.PopupMenu.Overflow</item>
+        <item name="actionModeBackground">?attr/colorPrimaryDark</item>
+        <item name="actionModeSplitBackground">?attr/colorPrimaryDark</item>
+        <item name="actionModeCloseDrawable">@drawable/ic_cab_done_material</item>
+        <item name="actionBarTabStyle">@style/Widget.Material.ActionBar.TabView</item>
+        <item name="actionBarTabBarStyle">@style/Widget.Material.ActionBar.TabBar</item>
+        <item name="actionBarTabTextStyle">@style/Widget.Material.ActionBar.TabText</item>
+        <item name="actionModeStyle">@style/Widget.Material.ActionMode</item>
+        <item name="actionModeCloseButtonStyle">@style/Widget.Material.ActionButton.CloseMode</item>
+        <item name="actionBarStyle">@style/Widget.Material.ActionBar.Solid</item>
+        <item name="actionBarSize">@dimen/action_bar_default_height_material</item>
+        <item name="actionModePopupWindowStyle">@style/Widget.Material.PopupWindow.ActionMode</item>
+        <item name="actionBarWidgetTheme">@null</item>
+        <item name="actionBarTheme">@style/ThemeOverlay.Material.ActionBar</item>
+        <item name="actionBarItemBackground">?attr/selectableItemBackgroundBorderless</item>
+
+        <item name="actionModeCutDrawable">@drawable/ic_menu_cut_material</item>
+        <item name="actionModeCopyDrawable">@drawable/ic_menu_copy_material</item>
+        <item name="actionModePasteDrawable">@drawable/ic_menu_paste_material</item>
+        <item name="actionModeSelectAllDrawable">@drawable/ic_menu_selectall_material</item>
+        <item name="actionModeShareDrawable">@drawable/ic_menu_share_material</item>
+        <item name="actionModeFindDrawable">@drawable/ic_menu_find_material</item>
+        <item name="actionModeWebSearchDrawable">@drawable/ic_menu_search_material</item>
+
+        <item name="dividerVertical">?attr/listDivider</item>
+        <item name="dividerHorizontal">?attr/listDivider</item>
+        <item name="buttonBarStyle">@style/Widget.Material.ButtonBar</item>
+        <item name="buttonBarButtonStyle">@style/Widget.Material.Button.Borderless</item>
+        <item name="segmentedButtonStyle">@style/Widget.Material.SegmentedButton</item>
+
+        <!-- SearchView attributes -->
+        <item name="searchDropdownBackground">?attr/colorBackground</item>
+        <item name="searchViewTextField">@drawable/textfield_search_material</item>
+        <item name="searchViewTextFieldRight">@drawable/textfield_search_material</item>
+        <item name="searchViewCloseIcon">@android:drawable/ic_clear_material</item>
+        <item name="searchViewSearchIcon">@android:drawable/ic_search_api_material</item>
+        <item name="searchViewGoIcon">@android:drawable/ic_go_search_api_material</item>
+        <item name="searchViewVoiceIcon">@android:drawable/ic_voice_search_api_material</item>
+        <item name="searchViewEditQuery">@android:drawable/ic_commit_search_api_material</item>
+
+        <item name="searchDialogTheme">@style/Theme.Material.SearchBar</item>
+
+        <!-- PreferenceFrameLayout attributes -->
+        <item name="preferenceFrameLayoutStyle">@style/Widget.Material.PreferenceFrameLayout</item>
+
+        <!-- NumberPicker style-->
+        <item name="numberPickerStyle">@style/Widget.Material.NumberPicker</item>
+
+        <!-- CalendarView style-->
+        <item name="calendarViewStyle">@style/Widget.Material.CalendarView</item>
+
+        <!-- TimePicker style -->
+        <item name="timePickerStyle">@style/Widget.Material.TimePicker</item>
+
+        <!-- TimePicker background color -->
+        <item name="timePickerHeaderBackgroundColor">?colorBackground</item>
+
+        <!-- TimePicker Header time label text appearance -->
+        <item name="timePickerHeaderTimeLabelTextAppearance">@style/TextAppearance.Material.TimePicker.TimeLabel</item>
+
+        <!-- TimePicker Header am pm label text appearance -->
+        <item name="timePickerHeaderAmPmLabelTextAppearance">@style/TextAppearance.Material.TimePicker.AmPmLabel</item>
+
+        <!-- TimePicker dialog theme -->
+        <item name="timePickerDialogTheme">@style/Theme.Material.Dialog.TimePicker</item>
+
+        <!-- DatePicker style -->
+        <item name="datePickerStyle">@style/Widget.Material.DatePicker</item>
+
+        <!-- TODO: This belongs in a FastScroll style -->
+        <item name="fastScrollThumbDrawable">@drawable/fastscroll_thumb_material</item>
+        <item name="fastScrollPreviewBackgroundLeft">@drawable/fastscroll_label_left_holo_dark</item>
+        <item name="fastScrollPreviewBackgroundRight">@drawable/fastscroll_label_right_holo_dark</item>
+        <item name="fastScrollTrackDrawable">@drawable/fastscroll_track_material</item>
+        <item name="fastScrollOverlayPosition">atThumb</item>
+
+        <!-- Color palette -->
+        <item name="colorPrimaryDark">@color/material_blue_grey_900</item>
+        <item name="colorPrimary">@color/material_blue_grey_800</item>
+        <item name="colorAccent">@color/material_light_blue_A200</item>
+
+        <item name="colorControlNormal">?attr/textColorSecondary</item>
+        <item name="colorControlActivated">?attr/colorAccent</item>
+
+        <item name="colorControlHighlight">@color/ripple_material_dark</item>
+        <item name="colorButtonNormal">@color/btn_default_material_dark</item>
+    </style>
+
+    <!-- Material theme (light version). -->
+    <style name="Theme.Material.Light" parent="Theme.Light">
+        <item name="colorForeground">@color/bright_foreground_material_light</item>
+        <item name="colorForegroundInverse">@color/bright_foreground_material_dark</item>
+        <item name="colorBackground">@color/background_material_light</item>
+        <item name="colorBackgroundCacheHint">@color/background_cache_hint_selector_material_light</item>
+        <item name="disabledAlpha">0.5</item>
+        <item name="backgroundDimAmount">0.6</item>
+
+        <!-- Text styles -->
+        <item name="textAppearance">@style/TextAppearance.Material</item>
+        <item name="textAppearanceInverse">@style/TextAppearance.Material.Inverse</item>
+
+        <item name="textColorPrimary">@color/primary_text_material_light</item>
+        <item name="textColorPrimaryInverse">@color/primary_text_material_dark</item>
+        <item name="textColorSecondary">@color/secondary_text_material_light</item>
+        <item name="textColorSecondaryInverse">@color/secondary_text_material_dark</item>
+        <item name="textColorTertiary">@color/tertiary_text_material_light</item>
+        <item name="textColorTertiaryInverse">@color/tertiary_text_material_dark</item>
+        <item name="textColorPrimaryDisableOnly">@color/primary_text_disable_only_material_light</item>
+        <item name="textColorPrimaryInverseDisableOnly">@color/primary_text_disable_only_material_dark</item>
+        <item name="textColorHint">@color/hint_foreground_material_light</item>
+        <item name="textColorHintInverse">@color/hint_foreground_material_dark</item>
+        <item name="textColorHighlight">@color/highlighted_text_material_light</item>
+        <item name="textColorHighlightInverse">@color/highlighted_text_material_dark</item>
+        <item name="textColorLink">@color/material_teal_500</item>
+        <item name="textColorLinkInverse">@color/material_teal_500</item>
+        <item name="textColorSearchUrl">@color/search_url_text_material_light</item>
+        <item name="textColorAlertDialogListItem">@color/primary_text_material_light</item>
+
+        <item name="textAppearanceLarge">@style/TextAppearance.Material.Large</item>
+        <item name="textAppearanceLargeInverse">@style/TextAppearance.Material.Large.Inverse</item>
+        <item name="textAppearanceMedium">@style/TextAppearance.Material.Medium</item>
+        <item name="textAppearanceMediumInverse">@style/TextAppearance.Material.Medium.Inverse</item>
+        <item name="textAppearanceSmall">@style/TextAppearance.Material.Small</item>
+        <item name="textAppearanceSmallInverse">@style/TextAppearance.Material.Small.Inverse</item>
+        <item name="textAppearanceSearchResultTitle">@style/TextAppearance.Material.SearchResult.Title</item>
+        <item name="textAppearanceSearchResultSubtitle">@style/TextAppearance.Material.SearchResult.Subtitle</item>
+
+        <item name="textAppearanceButton">@style/TextAppearance.Material.Widget.Button</item>
+
+        <item name="editTextColor">?attr/textColorPrimary</item>
+        <item name="editTextBackground">@drawable/edit_text_material</item>
+
+        <item name="candidatesTextStyleSpans">@string/candidates_style</item>
+
+        <item name="textCheckMark">@drawable/indicator_check_mark_light</item>
+        <item name="textCheckMarkInverse">@drawable/indicator_check_mark_dark</item>
+
+        <item name="textAppearanceLargePopupMenu">@style/TextAppearance.Material.Widget.PopupMenu.Large</item>
+        <item name="textAppearanceSmallPopupMenu">@style/TextAppearance.Material.Widget.PopupMenu.Small</item>
+
+        <!-- Button styles -->
+        <item name="buttonStyle">@style/Widget.Material.Light.Button</item>
+
+        <item name="buttonStyleSmall">@style/Widget.Material.Light.Button.Small</item>
+        <item name="buttonStyleInset">@style/Widget.Material.Light.Button.Inset</item>
+
+        <item name="buttonStyleToggle">@style/Widget.Material.Light.Button.Toggle</item>
+        <item name="switchStyle">@style/Widget.Material.Light.CompoundButton.Switch</item>
+        <item name="mediaRouteButtonStyle">@style/Widget.Material.Light.MediaRouteButton</item>
+
+        <item name="selectableItemBackground">@drawable/item_background_material</item>
+        <item name="selectableItemBackgroundBorderless">@drawable/item_background_borderless_material</item>
+        <item name="borderlessButtonStyle">@style/Widget.Material.Light.Button.Borderless</item>
+        <item name="homeAsUpIndicator">@drawable/ic_ab_back_material</item>
+
+        <!-- List attributes -->
+        <item name="listPreferredItemHeight">64dip</item>
+        <item name="listPreferredItemHeightSmall">48dip</item>
+        <item name="listPreferredItemHeightLarge">80dip</item>
+        <item name="dropdownListPreferredItemHeight">?attr/listPreferredItemHeightSmall</item>
+        <item name="textAppearanceListItem">@style/TextAppearance.Material.Subhead</item>
+        <item name="textAppearanceListItemSmall">@style/TextAppearance.Material.Subhead</item>
+        <item name="textAppearanceListItemSecondary">@style/TextAppearance.Material.Body1</item>
+        <item name="listPreferredItemPaddingLeft">16dip</item>
+        <item name="listPreferredItemPaddingRight">16dip</item>
+        <item name="listPreferredItemPaddingStart">16dip</item>
+        <item name="listPreferredItemPaddingEnd">16dip</item>
+
+        <!-- @hide -->
+        <item name="searchResultListItemHeight">58dip</item>
+        <item name="listDivider">@drawable/list_divider_material</item>
+        <item name="listSeparatorTextViewStyle">@style/Widget.Material.Light.TextView.ListSeparator</item>
+
+        <item name="listChoiceIndicatorSingle">@drawable/btn_radio_material_anim</item>
+        <item name="listChoiceIndicatorMultiple">@drawable/btn_check_material_anim</item>
+
+        <item name="listChoiceBackgroundIndicator">?attr/selectableItemBackground</item>
+        <item name="activatedBackgroundIndicator">@drawable/activated_background_material</item>
+
+        <item name="expandableListPreferredItemPaddingLeft">40dip</item>
+        <item name="expandableListPreferredChildPaddingLeft">?attr/expandableListPreferredItemPaddingLeft</item>
+
+        <item name="expandableListPreferredItemIndicatorLeft">3dip</item>
+        <item name="expandableListPreferredItemIndicatorRight">0dip</item>
+        <item name="expandableListPreferredChildIndicatorLeft">?attr/expandableListPreferredItemIndicatorLeft</item>
+        <item name="expandableListPreferredChildIndicatorRight">?attr/expandableListPreferredItemIndicatorRight</item>
+
+        <item name="listDividerAlertDialog">@drawable/list_divider_material</item>
+        <item name="findOnPageNextDrawable">@drawable/ic_find_next_material</item>
+        <item name="findOnPagePreviousDrawable">@drawable/ic_find_previous_material</item>
+
+        <!-- Gallery attributes -->
+        <item name="galleryItemBackground">@drawable/gallery_item_background</item>
+
+        <!-- Window attributes -->
+        <item name="windowBackground">@color/background_material_light</item>
+        <item name="windowFrame">@null</item>
+        <item name="windowNoTitle">false</item>
+        <item name="windowFullscreen">false</item>
+        <item name="windowOverscan">false</item>
+        <item name="windowIsFloating">false</item>
+        <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="windowTitleBackgroundStyle">@style/WindowTitleBackground.Material</item>
+        <item name="windowAnimationStyle">@style/Animation.Material.Activity</item>
+        <item name="windowSoftInputMode">stateUnspecified|adjustUnspecified</item>
+        <item name="windowActionBar">true</item>
+        <item name="windowActionModeOverlay">false</item>
+        <item name="windowDrawsSystemBarBackgrounds">true</item>
+        <item name="windowActionBarFullscreenDecorLayout">@layout/screen_toolbar</item>
+        <item name="statusBarColor">?attr/colorPrimaryDark</item>
+        <item name="navigationBarColor">@color/black</item>
+
+        <!-- Dialog attributes -->
+        <item name="dialogTheme">@style/Theme.Material.Light.Dialog</item>
+        <item name="dialogTitleIconsDecorLayout">@layout/dialog_title_icons_material</item>
+        <item name="dialogCustomTitleDecorLayout">@layout/dialog_custom_title_material</item>
+        <item name="dialogTitleDecorLayout">@layout/dialog_title_material</item>
+
+        <!-- AlertDialog attributes -->
+        <item name="alertDialogTheme">@style/Theme.Material.Light.Dialog.Alert</item>
+        <item name="alertDialogStyle">@style/AlertDialog.Material.Light</item>
+        <item name="alertDialogCenterButtons">false</item>
+        <item name="alertDialogIcon">@drawable/ic_dialog_alert_material</item>
+
+        <!-- Presentation attributes -->
+        <item name="presentationTheme">@style/Theme.Material.Light.Dialog.Presentation</item>
+
+        <!-- Toast attributes -->
+        <item name="toastFrameBackground">@drawable/toast_frame</item>
+
+        <!-- Panel attributes -->
+        <item name="panelBackground">?attr/colorBackground</item>
+        <item name="panelFullBackground">@drawable/menu_background_fill_parent_width</item>
+        <!-- These three attributes do not seems to be used by the framework. Declared public though -->
+        <item name="panelColorBackground">#000</item>
+        <item name="panelColorForeground">?attr/textColorPrimary</item>
+        <item name="panelTextAppearance">?attr/textAppearance</item>
+
+        <item name="panelMenuIsCompact">true</item>
+        <item name="panelMenuListWidth">250dip</item>
+        <item name="panelMenuListTheme">@style/Theme.Material.Light.CompactMenu</item>
+
+        <!-- Scrollbar attributes -->
+        <item name="scrollbarFadeDuration">250</item>
+        <item name="scrollbarDefaultDelayBeforeFade">300</item>
+        <item name="scrollbarSize">10dip</item>
+        <item name="scrollbarThumbHorizontal">@drawable/scrollbar_handle_material</item>
+        <item name="scrollbarThumbVertical">@drawable/scrollbar_handle_material</item>
+        <item name="scrollbarTrackHorizontal">@null</item>
+        <item name="scrollbarTrackVertical">@null</item>
+
+        <!-- Text selection handle attributes -->
+        <item name="textSelectHandleLeft">@drawable/text_select_handle_left_material</item>
+        <item name="textSelectHandleRight">@drawable/text_select_handle_right_material</item>
+        <item name="textSelectHandle">@drawable/text_select_handle_middle_material</item>
+        <item name="textSelectHandleWindowStyle">@style/Widget.Material.TextSelectHandle</item>
+        <item name="textSuggestionsWindowStyle">@style/Widget.Material.Light.TextSuggestionsPopupWindow</item>
+        <item name="textCursorDrawable">@drawable/text_cursor_material</item>
+
+        <!-- Widget styles -->
+        <item name="absListViewStyle">@style/Widget.Material.Light.AbsListView</item>
+        <item name="autoCompleteTextViewStyle">@style/Widget.Material.Light.AutoCompleteTextView</item>
+        <item name="checkboxStyle">@style/Widget.Material.Light.CompoundButton.CheckBox</item>
+        <item name="checkedTextViewStyle">@style/Widget.Material.Light.CheckedTextView</item>
+        <item name="dropDownListViewStyle">@style/Widget.Material.ListView.DropDown</item>
+        <item name="editTextStyle">@style/Widget.Material.Light.EditText</item>
+        <item name="expandableListViewStyle">@style/Widget.Material.Light.ExpandableListView</item>
+        <item name="expandableListViewWhiteStyle">@style/Widget.Material.Light.ExpandableListView.White</item>
+        <item name="fastScrollStyle">@style/Widget.Material.Light.FastScroll</item>
+        <item name="galleryStyle">@style/Widget.Material.Light.Gallery</item>
+        <item name="gestureOverlayViewStyle">@style/Widget.Material.Light.GestureOverlayView</item>
+        <item name="gridViewStyle">@style/Widget.Material.Light.GridView</item>
+        <item name="imageButtonStyle">@style/Widget.Material.Light.ImageButton</item>
+        <item name="imageWellStyle">@style/Widget.Material.Light.ImageWell</item>
+        <item name="listViewStyle">@style/Widget.Material.Light.ListView</item>
+        <item name="listViewWhiteStyle">@style/Widget.Material.Light.ListView.White</item>
+        <item name="popupWindowStyle">@style/Widget.Material.Light.PopupWindow</item>
+        <item name="progressBarStyle">@style/Widget.Material.Light.ProgressBar</item>
+        <item name="progressBarStyleHorizontal">@style/Widget.Material.Light.ProgressBar.Horizontal</item>
+        <item name="progressBarStyleSmall">@style/Widget.Material.Light.ProgressBar.Small</item>
+        <item name="progressBarStyleSmallTitle">@style/Widget.Material.Light.ProgressBar.Small.Title</item>
+        <item name="progressBarStyleLarge">@style/Widget.Material.Light.ProgressBar.Large</item>
+        <item name="progressBarStyleInverse">@style/Widget.Material.Light.ProgressBar.Inverse</item>
+        <item name="progressBarStyleSmallInverse">@style/Widget.Material.Light.ProgressBar.Small.Inverse</item>
+        <item name="progressBarStyleLargeInverse">@style/Widget.Material.Light.ProgressBar.Large.Inverse</item>
+        <item name="seekBarStyle">@style/Widget.Material.Light.SeekBar</item>
+        <item name="ratingBarStyle">@style/Widget.Material.Light.RatingBar</item>
+        <item name="ratingBarStyleIndicator">@style/Widget.Material.Light.RatingBar.Indicator</item>
+        <item name="ratingBarStyleSmall">@style/Widget.Material.Light.RatingBar.Small</item>
+        <item name="radioButtonStyle">@style/Widget.Material.Light.CompoundButton.RadioButton</item>
+        <item name="scrollViewStyle">@style/Widget.Material.Light.ScrollView</item>
+        <item name="horizontalScrollViewStyle">@style/Widget.Material.Light.HorizontalScrollView</item>
+        <item name="spinnerStyle">?attr/dropDownSpinnerStyle</item>
+        <item name="dropDownSpinnerStyle">@style/Widget.Material.Light.Spinner.DropDown</item>
+        <item name="starStyle">@style/Widget.Material.Light.CompoundButton.Star</item>
+        <item name="tabWidgetStyle">@style/Widget.Material.Light.TabWidget</item>
+        <item name="textViewStyle">@style/Widget.Material.Light.TextView</item>
+        <item name="errorMessageBackground">@drawable/popup_inline_error_holo_light</item>
+        <item name="errorMessageAboveBackground">@drawable/popup_inline_error_above_holo_light</item>
+        <item name="webTextViewStyle">@style/Widget.Material.Light.WebTextView</item>
+        <item name="webViewStyle">@style/Widget.Material.Light.WebView</item>
+        <item name="dropDownItemStyle">@style/Widget.Material.Light.DropDownItem</item>
+        <item name="spinnerDropDownItemStyle">@style/Widget.Material.Light.DropDownItem.Spinner</item>
+        <item name="spinnerItemStyle">@style/Widget.Material.TextView.SpinnerItem</item>
+        <item name="dropDownHintAppearance">@style/TextAppearance.Material.Widget.DropDownHint</item>
+        <item name="keyboardViewStyle">@style/Widget.Material.KeyboardView</item>
+        <item name="quickContactBadgeStyleWindowSmall">@style/Widget.Material.QuickContactBadge.WindowSmall</item>
+        <item name="quickContactBadgeStyleWindowMedium">@style/Widget.Material.QuickContactBadge.WindowMedium</item>
+        <item name="quickContactBadgeStyleWindowLarge">@style/Widget.Material.QuickContactBadge.WindowLarge</item>
+        <item name="quickContactBadgeStyleSmallWindowSmall">@style/Widget.Material.QuickContactBadgeSmall.WindowSmall</item>
+        <item name="quickContactBadgeStyleSmallWindowMedium">@style/Widget.Material.QuickContactBadgeSmall.WindowMedium</item>
+        <item name="quickContactBadgeStyleSmallWindowLarge">@style/Widget.Material.QuickContactBadgeSmall.WindowLarge</item>
+        <item name="listPopupWindowStyle">@style/Widget.Material.Light.ListPopupWindow</item>
+        <item name="popupMenuStyle">@style/Widget.Material.Light.PopupMenu</item>
+        <item name="stackViewStyle">@style/Widget.Material.Light.StackView</item>
+        <item name="activityChooserViewStyle">@style/Widget.Material.Light.ActivityChooserView</item>
+
+        <!-- Preference styles -->
+        <item name="preferenceScreenStyle">@style/Preference.Material.PreferenceScreen</item>
+        <item name="preferenceFragmentStyle">@style/PreferenceFragment.Material</item>
+        <item name="preferenceFragmentPaddingSide">0dip</item>
+        <item name="preferenceCategoryStyle">@style/Preference.Material.Category</item>
+        <item name="preferenceStyle">@style/Preference.Material</item>
+        <item name="preferenceInformationStyle">@style/Preference.Material.Information</item>
+        <item name="checkBoxPreferenceStyle">@style/Preference.Material.CheckBoxPreference</item>
+        <item name="switchPreferenceStyle">@style/Preference.Material.SwitchPreference</item>
+        <item name="yesNoPreferenceStyle">@style/Preference.Material.DialogPreference.YesNoPreference</item>
+        <item name="dialogPreferenceStyle">@style/Preference.Material.DialogPreference</item>
+        <item name="editTextPreferenceStyle">@style/Preference.Material.DialogPreference.EditTextPreference</item>
+        <item name="ringtonePreferenceStyle">@style/Preference.Material.RingtonePreference</item>
+        <item name="preferenceLayoutChild">@layout/preference_child_material</item>
+        <item name="detailsElementBackground">?attr/colorBackground</item>
+
+        <!-- PreferenceFrameLayout attributes -->
+        <item name="preferenceFrameLayoutStyle">@style/Widget.Material.PreferenceFrameLayout</item>
+
+        <!-- Search widget styles -->
+        <item name="searchWidgetCorpusItemBackground">@color/search_widget_corpus_item_background</item>
+
+        <!-- Action bar styles -->
+        <item name="actionDropDownStyle">@style/Widget.Material.Light.Spinner.DropDown.ActionBar</item>
+        <item name="actionButtonStyle">@style/Widget.Material.Light.ActionButton</item>
+        <item name="actionOverflowButtonStyle">@style/Widget.Material.Light.ActionButton.Overflow</item>
+        <item name="actionOverflowMenuStyle">@android:style/Widget.Material.Light.PopupMenu.Overflow</item>
+        <item name="actionModeBackground">@drawable/cab_background_top_holo_light</item>
+        <item name="actionModeSplitBackground">@drawable/cab_background_bottom_holo_light</item>
+        <item name="actionModeCloseDrawable">@drawable/ic_cab_done_material</item>
+        <item name="actionBarTabStyle">@style/Widget.Material.Light.ActionBar.TabView</item>
+        <item name="actionBarTabBarStyle">@style/Widget.Material.Light.ActionBar.TabBar</item>
+        <item name="actionBarTabTextStyle">@style/Widget.Material.Light.ActionBar.TabText</item>
+        <item name="actionModeStyle">@style/Widget.Material.Light.ActionMode</item>
+        <item name="actionModeCloseButtonStyle">@style/Widget.Material.Light.ActionButton.CloseMode</item>
+        <item name="actionBarStyle">@style/Widget.Material.Light.ActionBar.Solid</item>
+        <item name="actionBarSize">@dimen/action_bar_default_height_material</item>
+        <item name="actionModePopupWindowStyle">@style/Widget.Material.Light.PopupWindow.ActionMode</item>
+        <item name="actionBarWidgetTheme">@null</item>
+        <item name="actionBarTheme">@style/ThemeOverlay.Material.ActionBar</item>
+        <item name="actionBarItemBackground">?attr/selectableItemBackgroundBorderless</item>
+
+        <item name="actionModeCutDrawable">@drawable/ic_menu_cut_material</item>
+        <item name="actionModeCopyDrawable">@drawable/ic_menu_copy_material</item>
+        <item name="actionModePasteDrawable">@drawable/ic_menu_paste_material</item>
+        <item name="actionModeSelectAllDrawable">@drawable/ic_menu_selectall_material</item>
+        <item name="actionModeShareDrawable">@drawable/ic_menu_share_material</item>
+        <item name="actionModeFindDrawable">@drawable/ic_menu_find_material</item>
+        <item name="actionModeWebSearchDrawable">@drawable/ic_menu_search_material</item>
+
+        <item name="dividerVertical">?attr/listDivider</item>
+        <item name="dividerHorizontal">?attr/listDivider</item>
+        <item name="buttonBarStyle">@style/Widget.Material.Light.ButtonBar</item>
+        <item name="buttonBarButtonStyle">@style/Widget.Material.Light.Button.Borderless</item>
+        <item name="segmentedButtonStyle">@style/Widget.Material.Light.SegmentedButton</item>
+
+        <!-- SearchView attributes -->
+        <item name="searchDropdownBackground">?attr/colorBackground</item>
+        <item name="searchViewTextField">@drawable/textfield_search_material</item>
+        <item name="searchViewTextFieldRight">@drawable/textfield_search_material</item>
+        <item name="searchViewCloseIcon">@android:drawable/ic_clear_material</item>
+        <item name="searchViewSearchIcon">@android:drawable/ic_search_api_material</item>
+        <item name="searchViewGoIcon">@android:drawable/ic_go_search_api_material</item>
+        <item name="searchViewVoiceIcon">@android:drawable/ic_voice_search_api_material</item>
+        <item name="searchViewEditQuery">@android:drawable/ic_commit_search_api_material</item>
+
+        <item name="searchDialogTheme">@style/Theme.Material.Light.SearchBar</item>
+
+        <!-- NumberPicker style-->
+        <item name="numberPickerStyle">@style/Widget.Material.Light.NumberPicker</item>
+
+        <!-- CalendarView style-->
+        <item name="calendarViewStyle">@style/Widget.Material.Light.CalendarView</item>
+
+        <!-- TimePicker style -->
+        <item name="timePickerStyle">@style/Widget.Material.Light.TimePicker</item>
+
+        <!-- TimePicker Header background color -->
+        <item name="timePickerHeaderBackgroundColor">?attr/colorBackground</item>
+
+        <!-- TimePicker Header time label text appearance -->
+        <item name="timePickerHeaderTimeLabelTextAppearance">@style/TextAppearance.Material.TimePicker.TimeLabel</item>
+
+        <!-- TimePicker Header am pm label text appearance -->
+        <item name="timePickerHeaderAmPmLabelTextAppearance">@style/TextAppearance.Material.TimePicker.AmPmLabel</item>
+
+        <!-- TimePicker dialog theme -->
+        <item name="timePickerDialogTheme">@style/Theme.Material.Light.Dialog.TimePicker</item>
+
+        <!-- DatePicker style -->
+        <item name="datePickerStyle">@style/Widget.Material.Light.DatePicker</item>
+
+        <item name="fastScrollThumbDrawable">@drawable/fastscroll_thumb_material</item>
+        <item name="fastScrollPreviewBackgroundLeft">@drawable/fastscroll_label_left_holo_light</item>
+        <item name="fastScrollPreviewBackgroundRight">@drawable/fastscroll_label_right_holo_light</item>
+        <item name="fastScrollTrackDrawable">@drawable/fastscroll_track_material</item>
+        <item name="fastScrollOverlayPosition">atThumb</item>
+
+        <!-- Color palette -->
+        <item name="colorPrimaryDark">@color/material_blue_grey_600</item>
+        <item name="colorPrimary">@color/material_blue_grey_400</item>
+        <item name="colorAccent">@color/material_light_blue_A200</item>
+
+        <item name="colorControlNormal">?attr/textColorSecondary</item>
+        <item name="colorControlActivated">?attr/colorAccent</item>
+
+        <item name="colorControlHighlight">@color/ripple_material_light</item>
+        <item name="colorButtonNormal">@color/btn_default_material_light</item>
+    </style>
+
+    <!-- Variant of the material (light) theme that has a solid (opaque) action bar
+         with an inverse color profile. The dark action bar sharply stands out against
+         the light content. -->
+    <style name="Theme.Material.Light.DarkActionBar">
+        <item name="actionBarWidgetTheme">@null</item>
+        <item name="actionBarTheme">@style/ThemeOverlay.Material.Dark.ActionBar</item>
+
+        <item name="colorPrimaryDark">@color/material_blue_grey_900</item>
+        <item name="colorPrimary">@color/material_blue_grey_800</item>
+    </style>
+
+    <style name="ThemeOverlay" />
+    <style name="ThemeOverlay.Material" />
+
+    <!-- Theme overlay that replaces colors with their light versions but preserves
+         the value of colorAccent, colorPrimary and its variants. -->
+    <style name="ThemeOverlay.Material.Light">
+        <item name="colorForeground">@color/bright_foreground_material_light</item>
+        <item name="colorForegroundInverse">@color/bright_foreground_material_dark</item>
+        <item name="colorBackground">@color/background_material_light</item>
+        <item name="colorBackgroundCacheHint">@color/background_cache_hint_selector_material_light</item>
+
+        <item name="textColorPrimary">@color/primary_text_material_light</item>
+        <item name="textColorPrimaryInverse">@color/primary_text_material_dark</item>
+        <item name="textColorSecondary">@color/secondary_text_material_light</item>
+        <item name="textColorSecondaryInverse">@color/secondary_text_material_dark</item>
+        <item name="textColorTertiary">@color/tertiary_text_material_light</item>
+        <item name="textColorTertiaryInverse">@color/tertiary_text_material_dark</item>
+        <item name="textColorPrimaryDisableOnly">@color/primary_text_disable_only_material_light</item>
+        <item name="textColorPrimaryInverseDisableOnly">@color/primary_text_disable_only_material_dark</item>
+        <item name="textColorHint">@color/hint_foreground_material_light</item>
+        <item name="textColorHintInverse">@color/hint_foreground_material_dark</item>
+        <item name="textColorHighlight">@color/highlighted_text_material_light</item>
+        <item name="textColorHighlightInverse">@color/highlighted_text_material_dark</item>
+        <item name="textColorLink">@color/material_teal_500</item>
+        <item name="textColorLinkInverse">@color/material_teal_500</item>
+        <item name="textColorSearchUrl">@color/search_url_text_material_light</item>
+        <item name="textColorAlertDialogListItem">@color/primary_text_material_light</item>
+
+        <item name="textCheckMark">@drawable/indicator_check_mark_light</item>
+        <item name="textCheckMarkInverse">@drawable/indicator_check_mark_dark</item>
+
+        <item name="windowBackground">@color/background_material_light</item>
+
+        <item name="fastScrollPreviewBackgroundLeft">@drawable/fastscroll_label_left_holo_light</item>
+        <item name="fastScrollPreviewBackgroundRight">@drawable/fastscroll_label_right_holo_light</item>
+
+        <item name="colorControlHighlight">@color/ripple_material_light</item>
+        <item name="colorButtonNormal">@color/btn_default_material_light</item>
+    </style>
+
+    <!-- Theme overlay that replaces colors with their dark versions but preserves
+         the value of colorAccent, colorPrimary and its variants. -->
+    <style name="ThemeOverlay.Material.Dark">
+        <item name="colorForeground">@color/bright_foreground_material_dark</item>
+        <item name="colorForegroundInverse">@color/bright_foreground_material_light</item>
+        <item name="colorBackground">@color/background_material_dark</item>
+        <item name="colorBackgroundCacheHint">@color/background_cache_hint_selector_material_dark</item>
+
+        <item name="textColorPrimary">@color/primary_text_material_dark</item>
+        <item name="textColorPrimaryInverse">@color/primary_text_material_light</item>
+        <item name="textColorPrimaryDisableOnly">@color/primary_text_disable_only_material_dark</item>
+        <item name="textColorSecondary">@color/secondary_text_material_dark</item>
+        <item name="textColorSecondaryInverse">@color/secondary_text_material_light</item>
+        <item name="textColorTertiary">@color/tertiary_text_material_dark</item>
+        <item name="textColorTertiaryInverse">@color/tertiary_text_material_light</item>
+        <item name="textColorHint">@color/hint_foreground_material_dark</item>
+        <item name="textColorHintInverse">@color/hint_foreground_material_light</item>
+        <item name="textColorHighlight">@color/highlighted_text_material_dark</item>
+        <item name="textColorHighlightInverse">@color/highlighted_text_material_light</item>
+        <item name="textColorLink">@color/material_teal_500</item>
+        <item name="textColorLinkInverse">@color/material_teal_500</item>
+        <item name="textColorSearchUrl">@color/search_url_text_material_dark</item>
+        <item name="textColorAlertDialogListItem">@color/primary_text_material_dark</item>
+
+        <item name="textCheckMark">@drawable/indicator_check_mark_dark</item>
+        <item name="textCheckMarkInverse">@drawable/indicator_check_mark_light</item>
+
+        <item name="windowBackground">@color/background_material_dark</item>
+
+        <item name="fastScrollPreviewBackgroundLeft">@drawable/fastscroll_label_left_holo_dark</item>
+        <item name="fastScrollPreviewBackgroundRight">@drawable/fastscroll_label_right_holo_dark</item>
+
+        <item name="colorControlHighlight">@color/ripple_material_dark</item>
+        <item name="colorButtonNormal">@color/btn_default_material_dark</item>
+    </style>
+
+    <!-- Theme overlay that replaces the normal control color, which by default is the same as the
+         secondary text color, with the primary text color. -->
+    <style name="ThemeOverlay.Material.ActionBar">
+        <item name="colorControlNormal">?attr/textColorPrimary</item>
+    </style>
+
+    <!-- Theme overlay that replaces colors with their dark versions and replaces the normal
+         control color, which by default is the same as the secondary text color, with the primary
+         text color. -->
+    <style name="ThemeOverlay.Material.Dark.ActionBar">
+        <item name="colorControlNormal">?attr/textColorPrimary</item>
+    </style>
+
+    <!-- Variant of the material (dark) theme with no action bar. -->
+    <style name="Theme.Material.NoActionBar">
+        <item name="windowActionBar">false</item>
+        <item name="windowNoTitle">true</item>
+    </style>
+
+    <!-- Variant of the material (dark) theme that has no title bar and fills
+         the entire screen.  This theme
+         sets {@link android.R.attr#windowFullscreen} to true.  -->
+    <style name="Theme.Material.NoActionBar.Fullscreen">
+        <item name="windowFullscreen">true</item>
+        <item name="windowContentOverlay">@null</item>
+    </style>
+
+    <!-- Variant of the material (dark) theme that has no title bar and fills
+         the entire screen and extends into the display overscan region.  This theme
+         sets {@link android.R.attr#windowFullscreen} and {@link android.R.attr#windowOverscan}
+         to true. -->
+    <style name="Theme.Material.NoActionBar.Overscan">
+        <item name="windowFullscreen">true</item>
+        <item name="windowOverscan">true</item>
+        <item name="windowContentOverlay">@null</item>
+    </style>
+
+    <!-- Variant of the material (dark) theme that has no title bar and translucent
+         system decor.  This theme sets {@link android.R.attr#windowTranslucentStatus} and
+         {@link android.R.attr#windowTranslucentNavigation} to true. -->
+    <style name="Theme.Material.NoActionBar.TranslucentDecor">
+        <item name="windowTranslucentStatus">true</item>
+        <item name="windowTranslucentNavigation">true</item>
+        <item name="windowContentOverlay">@null</item>
+    </style>
+
+    <!-- Variant of the material (light) theme with no action bar. -->
+    <style name="Theme.Material.Light.NoActionBar">
+        <item name="windowActionBar">false</item>
+        <item name="windowNoTitle">true</item>
+    </style>
+
+    <!-- Variant of the material (light) theme that has no title bar and fills
+         the entire screen.  This theme
+         sets {@link android.R.attr#windowFullscreen} to true.  -->
+    <style name="Theme.Material.Light.NoActionBar.Fullscreen">
+        <item name="windowFullscreen">true</item>
+        <item name="windowContentOverlay">@null</item>
+    </style>
+
+    <!-- Variant of the material (light) theme that has no title bar and fills
+         the entire screen and extends into the display overscan region.  This theme
+         sets {@link android.R.attr#windowFullscreen} and {@link android.R.attr#windowOverscan}
+         to true. -->
+    <style name="Theme.Material.Light.NoActionBar.Overscan">
+        <item name="windowFullscreen">true</item>
+        <item name="windowOverscan">true</item>
+        <item name="windowContentOverlay">@null</item>
+    </style>
+
+    <!-- Variant of the material (light) theme that has no title bar and translucent
+         system decor.  This theme sets {@link android.R.attr#windowTranslucentStatus} and
+         {@link android.R.attr#windowTranslucentNavigation} to true. -->
+    <style name="Theme.Material.Light.NoActionBar.TranslucentDecor">
+        <item name="windowTranslucentStatus">true</item>
+        <item name="windowTranslucentNavigation">true</item>
+        <item name="windowContentOverlay">@null</item>
+    </style>
+
+    <!-- Default material dark theme for panel windows.  This removes all extraneous
+         window decorations, so you basically have an empty rectangle in which
+         to place your content.  It makes the window floating, with a transparent
+         background, and turns off dimming behind the window. -->
+    <style name="Theme.Material.Panel">
+        <item name="windowBackground">@color/transparent</item>
+        <item name="colorBackgroundCacheHint">@null</item>
+        <item name="windowFrame">@null</item>
+        <item name="windowContentOverlay">@null</item>
+        <item name="windowAnimationStyle">@null</item>
+        <item name="windowIsFloating">true</item>
+        <item name="backgroundDimEnabled">false</item>
+        <item name="windowIsTranslucent">true</item>
+        <item name="windowNoTitle">true</item>
+    </style>
+
+    <!-- Default material light theme for panel windows.  This removes all extraneous
+         window decorations, so you basically have an empty rectangle in which
+         to place your content.  It makes the window floating, with a transparent
+         background, and turns off dimming behind the window. -->
+    <style name="Theme.Material.Light.Panel">
+        <item name="windowBackground">@color/transparent</item>
+        <item name="colorBackgroundCacheHint">@null</item>
+        <item name="windowFrame">@null</item>
+        <item name="windowContentOverlay">@null</item>
+        <item name="windowAnimationStyle">@null</item>
+        <item name="windowIsFloating">true</item>
+        <item name="backgroundDimEnabled">false</item>
+        <item name="windowIsTranslucent">true</item>
+        <item name="windowNoTitle">true</item>
+    </style>
+
+    <!-- Material theme for an activity that is to be used for voice interaction.
+         This gives the activity a floating dialog style, to incorporate with the
+         system voice experience. -->
+    <style name="Theme.Material.Voice" parent="@style/Theme.Material.Dialog">
+        <item name="windowAnimationStyle">@style/Animation.VoiceActivity</item>
+        <item name="backgroundDimEnabled">false</item>
+    </style>
+
+    <!-- Material light theme for an activity that is to be used for voice interaction.
+         This gives the activity a floating dialog style, to incorporate with the
+         system voice experience. -->
+    <style name="Theme.Material.Light.Voice" parent="@style/Theme.Material.Light.Dialog">
+        <item name="windowAnimationStyle">@style/Animation.VoiceActivity</item>
+        <item name="backgroundDimEnabled">false</item>
+    </style>
+
+    <!-- Default theme for material style input methods, which is used by the
+         {@link android.inputmethodservice.InputMethodService} class.
+         this inherits from Theme.Panel, but sets up IME appropriate animations
+         and a few custom attributes. -->
+    <style name="Theme.Material.InputMethod" parent="Theme.Material.Light.Panel">
+        <item name="windowAnimationStyle">@style/Animation.InputMethod</item>
+        <item name="imeFullscreenBackground">@drawable/screen_background_selector_light</item>
+        <item name="imeExtractEnterAnimation">@anim/input_method_extract_enter</item>
+        <item name="imeExtractExitAnimation">@anim/input_method_extract_exit</item>
+    </style>
+
+    <!-- Default theme for material style voice interaction, which is used by the
+         {@link android.service.voice.VoiceInteractionSession} class.
+         this inherits from Theme.Panel, but sets up appropriate animations
+         and a few custom attributes. -->
+    <style name="Theme.Material.VoiceInteractionSession" parent="Theme.Material.Light.Panel">
+        <item name="windowAnimationStyle">@style/Animation.VoiceInteractionSession</item>
+    </style>
+
+    <!-- Theme for the search input bar. -->
+
+    <style name="Theme.Material.SearchBar" parent="Theme.Material.Panel">
+        <item name="actionModeBackground">@drawable/cab_background_top_holo_dark</item>
+        <item name="actionModeSplitBackground">@drawable/cab_background_bottom_holo_light</item>
+    </style>
+
+    <style name="Theme.Material.Light.SearchBar" parent="Theme.Material.Light.Panel">
+        <item name="actionModeBackground">@drawable/cab_background_top_holo_light</item>
+        <item name="actionModeSplitBackground">@drawable/cab_background_bottom_holo_light</item>
+    </style>
+
+    <!-- Menu Themes -->
+    <eat-comment />
+
+    <style name="Theme.Material.CompactMenu">
+        <!-- Menu/item attributes -->
+        <item name="itemTextAppearance">?attr/textAppearanceMedium</item>
+        <item name="listViewStyle">@style/Widget.Material.ListView</item>
+        <item name="windowAnimationStyle">@style/Animation.DropDownUp</item>
+        <item name="background">@null</item>
+    </style>
+
+    <style name="Theme.Material.Light.CompactMenu">
+        <!-- Menu/item attributes -->
+        <item name="itemTextAppearance">?attr/textAppearanceMedium</item>
+        <item name="listViewStyle">@style/Widget.Material.Light.ListView</item>
+        <item name="windowAnimationStyle">@style/Animation.DropDownUp</item>
+        <item name="background">@null</item>
+    </style>
+
+    <!-- Dialog themes for Material -->
+    <eat-comment />
+
+    <!-- Material theme for dialog windows and activities, which is used by the
+         {@link android.app.Dialog} class.  This changes the window to be
+         floating (not fill the entire screen), and puts a frame around its
+         contents.  You can set this theme on an activity if you would like to
+         make an activity that looks like a Dialog. -->
+    <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="windowIsFloating">true</item>
+        <item name="windowContentOverlay">@null</item>
+        <item name="windowAnimationStyle">@style/Animation.Material.Dialog</item>
+        <item name="windowSoftInputMode">stateUnspecified|adjustPan</item>
+        <item name="windowActionBar">false</item>
+        <item name="windowActionModeOverlay">true</item>
+        <item name="windowCloseOnTouchOutside">@bool/config_closeDialogWhenTouchOutside</item>
+
+        <item name="colorBackgroundCacheHint">@null</item>
+
+        <item name="buttonBarStyle">@style/Widget.Material.ButtonBar.AlertDialog</item>
+        <item name="borderlessButtonStyle">@style/Widget.Material.Button.Borderless</item>
+
+        <item name="textAppearance">@style/TextAppearance.Material</item>
+        <item name="textAppearanceInverse">@style/TextAppearance.Material.Inverse</item>
+
+        <item name="listPreferredItemPaddingLeft">16dip</item>
+        <item name="listPreferredItemPaddingRight">16dip</item>
+        <item name="listPreferredItemPaddingStart">16dip</item>
+        <item name="listPreferredItemPaddingEnd">16dip</item>
+
+        <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
+    </style>
+
+    <!-- Variant of Theme.Material.Dialog that has a nice minimum width for
+         a regular dialog. -->
+    <style name="Theme.Material.Dialog.MinWidth">
+        <item name="windowMinWidthMajor">@dimen/dialog_min_width_major</item>
+        <item name="windowMinWidthMinor">@dimen/dialog_min_width_minor</item>
+    </style>
+
+    <!-- Variant of Theme.Material.Dialog that does not include a title bar. -->
+    <style name="Theme.Material.Dialog.NoActionBar">
+        <item name="windowActionBar">false</item>
+        <item name="windowNoTitle">true</item>
+    </style>
+
+    <!-- Variant of Theme.Material.Dialog.NoActionBar that has a nice minimum width for
+         a regular dialog. -->
+    <style name="Theme.Material.Dialog.NoActionBar.MinWidth">
+        <item name="windowMinWidthMajor">@dimen/dialog_min_width_major</item>
+        <item name="windowMinWidthMinor">@dimen/dialog_min_width_minor</item>
+    </style>
+
+    <!-- Variant of Theme.Material.Dialog that has a fixed size. -->
+    <style name="Theme.Material.Dialog.FixedSize">
+        <item name="windowFixedWidthMajor">@dimen/dialog_fixed_width_major</item>
+        <item name="windowFixedWidthMinor">@dimen/dialog_fixed_width_minor</item>
+        <item name="windowFixedHeightMajor">@dimen/dialog_fixed_height_major</item>
+        <item name="windowFixedHeightMinor">@dimen/dialog_fixed_height_minor</item>
+    </style>
+
+    <!-- Variant of Theme.Material.Dialog.NoActionBar that has a fixed size. -->
+    <style name="Theme.Material.Dialog.NoActionBar.FixedSize">
+        <item name="windowFixedWidthMajor">@dimen/dialog_fixed_width_major</item>
+        <item name="windowFixedWidthMinor">@dimen/dialog_fixed_width_minor</item>
+        <item name="windowFixedHeightMajor">@dimen/dialog_fixed_height_major</item>
+        <item name="windowFixedHeightMinor">@dimen/dialog_fixed_height_minor</item>
+    </style>
+
+    <!-- Variant of Theme.Material.Dialog that does not include a frame (or background).
+         The view hierarchy of the dialog is responsible for drawing all of
+         its pixels. -->
+    <style name="Theme.Material.Dialog.NoFrame">
+        <item name="windowBackground">@color/transparent</item>
+        <item name="windowAnimationStyle">@null</item>
+        <item name="backgroundDimEnabled">false</item>
+        <item name="windowIsTranslucent">true</item>
+        <item name="windowNoTitle">true</item>
+        <item name="windowCloseOnTouchOutside">false</item>
+    </style>
+
+    <!-- Material theme for alert dialog windows, which is used by the
+         {@link android.app.AlertDialog} class.  This is basically a dialog
+         but sets the background to empty so it can do two-tone backgrounds.
+         For applications targeting Honeycomb or newer, this is the default
+         AlertDialog theme. -->
+    <style name="Theme.Material.Dialog.Alert">
+        <item name="windowBackground">@color/transparent</item>
+        <item name="windowTitleStyle">@style/DialogWindowTitle.Material</item>
+        <item name="windowMinWidthMajor">@dimen/dialog_min_width_major</item>
+        <item name="windowMinWidthMinor">@dimen/dialog_min_width_minor</item>
+    </style>
+
+    <!-- Material theme for the TimePicker dialog windows, which is used by the
+         {@link android.app.TimePickerDialog} class. -->
+    <style name="Theme.Material.Dialog.TimePicker">
+        <item name="windowBackground">@color/transparent</item>
+        <item name="windowTitleStyle">@style/DialogWindowTitle.Material</item>
+        <item name="windowContentOverlay">@null</item>
+    </style>
+
+    <!-- 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>
+
+    <!-- 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>
+
+    <!-- Theme for a presentation window on a secondary display. -->
+    <style name="Theme.Material.Dialog.Presentation" parent="@style/Theme.Material.NoActionBar.Fullscreen">
+    </style>
+
+    <!-- Light material dialog themes -->
+
+    <!-- Material light theme for dialog windows and activities, which is used by the
+         {@link android.app.Dialog} class.  This changes the window to be
+         floating (not fill the entire screen), and puts a frame around its
+         contents.  You can set this theme on an activity if you would like to
+         make an activity that looks like a Dialog. -->
+    <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="windowIsFloating">true</item>
+        <item name="windowContentOverlay">@null</item>
+        <item name="windowAnimationStyle">@style/Animation.Material.Dialog</item>
+        <item name="windowSoftInputMode">stateUnspecified|adjustPan</item>
+        <item name="windowActionBar">false</item>
+        <item name="windowActionModeOverlay">true</item>
+        <item name="windowCloseOnTouchOutside">@bool/config_closeDialogWhenTouchOutside</item>
+
+        <item name="colorBackgroundCacheHint">@null</item>
+
+        <item name="buttonBarStyle">@style/Widget.Material.Light.ButtonBar.AlertDialog</item>
+        <item name="borderlessButtonStyle">@style/Widget.Material.Light.Button.Borderless</item>
+
+        <item name="textAppearance">@style/TextAppearance.Material</item>
+        <item name="textAppearanceInverse">@style/TextAppearance.Material.Inverse</item>
+
+        <item name="listPreferredItemPaddingLeft">16dip</item>
+        <item name="listPreferredItemPaddingRight">16dip</item>
+        <item name="listPreferredItemPaddingStart">16dip</item>
+        <item name="listPreferredItemPaddingEnd">16dip</item>
+
+        <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
+    </style>
+
+    <!-- Variant of Theme.Material.Light.Dialog that has a nice minimum width for
+         a regular dialog. -->
+    <style name="Theme.Material.Light.Dialog.MinWidth">
+        <item name="windowMinWidthMajor">@dimen/dialog_min_width_major</item>
+        <item name="windowMinWidthMinor">@dimen/dialog_min_width_minor</item>
+    </style>
+
+    <!-- Variant of Theme.Material.Light.Dialog that does not include a title bar. -->
+    <style name="Theme.Material.Light.Dialog.NoActionBar">
+        <item name="windowActionBar">false</item>
+        <item name="windowNoTitle">true</item>
+    </style>
+
+    <!-- Variant of Theme.Material.Light.Dialog.NoActionBar that has a nice minimum width for
+         a regular dialog. -->
+    <style name="Theme.Material.Light.Dialog.NoActionBar.MinWidth">
+        <item name="windowMinWidthMajor">@dimen/dialog_min_width_major</item>
+        <item name="windowMinWidthMinor">@dimen/dialog_min_width_minor</item>
+    </style>
+
+    <!-- Variant of Theme.Material.Light.Dialog that has a fixed size. -->
+    <style name="Theme.Material.Light.Dialog.FixedSize">
+        <item name="windowFixedWidthMajor">@dimen/dialog_fixed_width_major</item>
+        <item name="windowFixedWidthMinor">@dimen/dialog_fixed_width_minor</item>
+        <item name="windowFixedHeightMajor">@dimen/dialog_fixed_height_major</item>
+        <item name="windowFixedHeightMinor">@dimen/dialog_fixed_height_minor</item>
+    </style>
+
+    <!-- Variant of Theme.Material.Light.Dialog.NoActionBar that has a fixed size. -->
+    <style name="Theme.Material.Light.Dialog.NoActionBar.FixedSize">
+        <item name="windowFixedWidthMajor">@dimen/dialog_fixed_width_major</item>
+        <item name="windowFixedWidthMinor">@dimen/dialog_fixed_width_minor</item>
+        <item name="windowFixedHeightMajor">@dimen/dialog_fixed_height_major</item>
+        <item name="windowFixedHeightMinor">@dimen/dialog_fixed_height_minor</item>
+    </style>
+
+    <!-- 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>
+
+    <!-- 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>
+
+    <!-- Material light theme for alert dialog windows, which is used by the
+         {@link android.app.AlertDialog} class.  This is basically a dialog
+         but sets the background to empty so it can do two-tone backgrounds.
+         For applications targeting Honeycomb or newer, this is the default
+         AlertDialog theme. -->
+    <style name="Theme.Material.Light.Dialog.Alert">
+        <item name="windowBackground">@color/transparent</item>
+        <item name="windowTitleStyle">@style/DialogWindowTitle.Material.Light</item>
+        <item name="windowMinWidthMajor">@dimen/dialog_min_width_major</item>
+        <item name="windowMinWidthMinor">@dimen/dialog_min_width_minor</item>
+    </style>
+
+    <!-- Material Light theme for the TimePicker dialog windows, which is used by the
+         {@link android.app.TimePickerDialog} class. -->
+    <style name="Theme.Material.Light.Dialog.TimePicker">
+        <item name="windowBackground">@color/transparent</item>
+        <item name="windowTitleStyle">@style/DialogWindowTitle.Material.Light</item>
+    </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>
+
+    <!-- Default material (dark) for windows that want to have the user's selected
+         wallpaper appear behind them.  -->
+    <style name="Theme.Material.Wallpaper">
+        <item name="windowBackground">@color/transparent</item>
+        <item name="colorBackgroundCacheHint">@null</item>
+        <item name="windowShowWallpaper">true</item>
+    </style>
+
+    <!--Default material (dark) for windows that want to have the user's selected
+         wallpaper appear behind them and without an action bar. -->
+    <style name="Theme.Material.Wallpaper.NoTitleBar">
+        <item name="windowNoTitle">true</item>
+    </style>
+
+</resources>
diff --git a/core/res/res/values/themes_quantum.xml b/core/res/res/values/themes_quantum.xml
deleted file mode 100644
index cdbd771..0000000
--- a/core/res/res/values/themes_quantum.xml
+++ /dev/null
@@ -1,1225 +0,0 @@
-<?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 Quantum 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>
-
-    <!-- Quantum Paper theme (dark version).
-         <p>If you want to ensure that your
-         app consistently uses the Quantum theme at all times, you must explicitly declare it in your
-         manifest. For example, {@code &lt;application android:theme="@style/Theme.Quantum"&gt;}.
-
-         <p>Styles used by the Quantum theme are named using the convention Type.Quantum.Etc
-         (for example, {@code Widget.Quantum.Button} and {@code
-         TextAppearance.Quantum.Widget.PopupMenu.Large}).
-         Specific resources used by Quantum are named using the convention @type/foo_bar_baz_quantum
-         with trailing _dark or _light specifiers if they are not shared between both light and
-         dark versions of the theme. -->
-    <style name="Theme.Quantum">
-        <item name="colorForeground">@color/bright_foreground_quantum_dark</item>
-        <item name="colorForegroundInverse">@color/bright_foreground_quantum_light</item>
-        <item name="colorBackground">@color/background_quantum_dark</item>
-        <item name="colorBackgroundCacheHint">@color/background_cache_hint_selector_quantum_dark</item>
-        <item name="disabledAlpha">0.5</item>
-        <item name="backgroundDimAmount">0.6</item>
-
-        <!-- Text styles -->
-        <item name="textAppearance">@style/TextAppearance.Quantum</item>
-        <item name="textAppearanceInverse">@style/TextAppearance.Quantum.Inverse</item>
-
-        <item name="textColorPrimary">@color/primary_text_quantum_dark</item>
-        <item name="textColorPrimaryInverse">@color/primary_text_quantum_light</item>
-        <item name="textColorPrimaryDisableOnly">@color/primary_text_disable_only_quantum_dark</item>
-        <item name="textColorSecondary">@color/secondary_text_quantum_dark</item>
-        <item name="textColorSecondaryInverse">@color/secondary_text_quantum_light</item>
-        <item name="textColorTertiary">@color/tertiary_text_quantum_dark</item>
-        <item name="textColorTertiaryInverse">@color/tertiary_text_quantum_light</item>
-        <item name="textColorHint">@color/hint_foreground_quantum_dark</item>
-        <item name="textColorHintInverse">@color/hint_foreground_quantum_light</item>
-        <item name="textColorHighlight">@color/highlighted_text_quantum_dark</item>
-        <item name="textColorHighlightInverse">@color/highlighted_text_quantum_light</item>
-        <item name="textColorLink">@color/quantum_teal_500</item>
-        <item name="textColorLinkInverse">@color/quantum_teal_500</item>
-        <item name="textColorSearchUrl">@color/search_url_text_quantum_dark</item>
-        <item name="textColorAlertDialogListItem">@color/primary_text_quantum_dark</item>
-
-        <item name="textAppearanceLarge">@style/TextAppearance.Quantum.Large</item>
-        <item name="textAppearanceLargeInverse">@style/TextAppearance.Quantum.Large.Inverse</item>
-        <item name="textAppearanceMedium">@style/TextAppearance.Quantum.Medium</item>
-        <item name="textAppearanceMediumInverse">@style/TextAppearance.Quantum.Medium.Inverse</item>
-        <item name="textAppearanceSmall">@style/TextAppearance.Quantum.Small</item>
-        <item name="textAppearanceSmallInverse">@style/TextAppearance.Quantum.Small.Inverse</item>
-        <item name="textAppearanceSearchResultTitle">@style/TextAppearance.Quantum.SearchResult.Title</item>
-        <item name="textAppearanceSearchResultSubtitle">@style/TextAppearance.Quantum.SearchResult.Subtitle</item>
-
-        <item name="textAppearanceButton">@style/TextAppearance.Quantum.Widget.Button</item>
-
-        <item name="editTextColor">?attr/textColorPrimary</item>
-        <item name="editTextBackground">@drawable/edit_text_quantum</item>
-
-        <item name="candidatesTextStyleSpans">@string/candidates_style</item>
-
-        <item name="textCheckMark">@drawable/indicator_check_mark_dark</item>
-        <item name="textCheckMarkInverse">@drawable/indicator_check_mark_light</item>
-
-        <item name="textAppearanceLargePopupMenu">@style/TextAppearance.Quantum.Widget.PopupMenu.Large</item>
-        <item name="textAppearanceSmallPopupMenu">@style/TextAppearance.Quantum.Widget.PopupMenu.Small</item>
-
-        <!-- Button styles -->
-        <item name="buttonStyle">@style/Widget.Quantum.Button</item>
-        <item name="buttonStyleSmall">@style/Widget.Quantum.Button.Small</item>
-        <item name="buttonStyleInset">@style/Widget.Quantum.Button.Inset</item>
-        <item name="buttonStyleToggle">@style/Widget.Quantum.Button.Toggle</item>
-
-        <item name="switchStyle">@style/Widget.Quantum.CompoundButton.Switch</item>
-        <item name="mediaRouteButtonStyle">@style/Widget.Quantum.MediaRouteButton</item>
-
-        <item name="selectableItemBackground">@drawable/item_background_quantum</item>
-        <item name="selectableItemBackgroundBorderless">@drawable/item_background_borderless_quantum</item>
-        <item name="borderlessButtonStyle">@style/Widget.Quantum.Button.Borderless</item>
-        <item name="homeAsUpIndicator">@drawable/ic_ab_back_quantum</item>
-
-        <!-- List attributes -->
-        <item name="listPreferredItemHeight">64dip</item>
-        <item name="listPreferredItemHeightSmall">48dip</item>
-        <item name="listPreferredItemHeightLarge">80dip</item>
-        <item name="dropdownListPreferredItemHeight">?attr/listPreferredItemHeightSmall</item>
-        <item name="textAppearanceListItem">@style/TextAppearance.Quantum.Subhead</item>
-        <item name="textAppearanceListItemSmall">@style/TextAppearance.Quantum.Subhead</item>
-        <item name="textAppearanceListItemSecondary">@style/TextAppearance.Quantum.Body1</item>
-        <item name="listPreferredItemPaddingLeft">16dip</item>
-        <item name="listPreferredItemPaddingRight">16dip</item>
-        <item name="listPreferredItemPaddingStart">16dip</item>
-        <item name="listPreferredItemPaddingEnd">16dip</item>
-
-        <!-- @hide -->
-        <item name="searchResultListItemHeight">58dip</item>
-        <item name="listDivider">@drawable/list_divider_quantum</item>
-        <item name="listSeparatorTextViewStyle">@style/Widget.Quantum.TextView.ListSeparator</item>
-
-        <item name="listChoiceIndicatorSingle">@drawable/btn_radio_quantum_anim</item>
-        <item name="listChoiceIndicatorMultiple">@drawable/btn_check_quantum_anim</item>
-
-        <item name="listChoiceBackgroundIndicator">?attr/selectableItemBackground</item>
-        <item name="activatedBackgroundIndicator">@drawable/activated_background_quantum</item>
-
-        <item name="listDividerAlertDialog">@drawable/list_divider_quantum</item>
-
-        <item name="expandableListPreferredItemPaddingLeft">40dip</item>
-        <item name="expandableListPreferredChildPaddingLeft">?attr/expandableListPreferredItemPaddingLeft</item>
-
-        <item name="expandableListPreferredItemIndicatorLeft">3dip</item>
-        <item name="expandableListPreferredItemIndicatorRight">0dip</item>
-        <item name="expandableListPreferredChildIndicatorLeft">?attr/expandableListPreferredItemIndicatorLeft</item>
-        <item name="expandableListPreferredChildIndicatorRight">?attr/expandableListPreferredItemIndicatorRight</item>
-        <item name="findOnPageNextDrawable">@drawable/ic_find_next_quantum</item>
-        <item name="findOnPagePreviousDrawable">@drawable/ic_find_previous_quantum</item>
-
-        <!-- Gallery attributes -->
-        <item name="galleryItemBackground">@drawable/gallery_item_background</item>
-
-        <!-- Window attributes -->
-        <item name="windowBackground">@color/background_quantum_dark</item>
-        <item name="windowFrame">@null</item>
-        <item name="windowNoTitle">false</item>
-        <item name="windowFullscreen">false</item>
-        <item name="windowOverscan">false</item>
-        <item name="windowIsFloating">false</item>
-        <item name="windowContentOverlay">@null</item>
-        <item name="windowShowWallpaper">false</item>
-        <item name="windowTitleStyle">@style/WindowTitle.Quantum</item>
-        <item name="windowTitleSize">25dip</item>
-        <item name="windowTitleBackgroundStyle">@style/WindowTitleBackground.Quantum</item>
-        <item name="windowContentTransitions">false</item>
-        <item name="windowAnimationStyle">@style/Animation.Quantum.Activity</item>
-        <item name="windowSoftInputMode">stateUnspecified|adjustUnspecified</item>
-        <item name="windowActionBar">true</item>
-        <item name="windowActionModeOverlay">false</item>
-        <item name="windowDrawsSystemBarBackgrounds">true</item>
-        <item name="windowActionBarFullscreenDecorLayout">@layout/screen_toolbar</item>
-        <item name="statusBarColor">?attr/colorPrimaryDark</item>
-        <item name="navigationBarColor">?attr/colorPrimaryDark</item>
-
-        <!-- Dialog attributes -->
-        <item name="dialogTheme">@style/Theme.Quantum.Dialog</item>
-        <item name="dialogTitleIconsDecorLayout">@layout/dialog_title_icons_quantum</item>
-        <item name="dialogCustomTitleDecorLayout">@layout/dialog_custom_title_quantum</item>
-        <item name="dialogTitleDecorLayout">@layout/dialog_title_quantum</item>
-
-        <!-- AlertDialog attributes -->
-        <item name="alertDialogTheme">@style/Theme.Quantum.Dialog.Alert</item>
-        <item name="alertDialogStyle">@style/AlertDialog.Quantum</item>
-        <item name="alertDialogCenterButtons">false</item>
-        <item name="alertDialogIcon">@drawable/ic_dialog_alert_quantum</item>
-
-        <!-- Presentation attributes -->
-        <item name="presentationTheme">@style/Theme.Quantum.Dialog.Presentation</item>
-
-        <!-- Toast attributes -->
-        <item name="toastFrameBackground">@drawable/toast_frame</item>
-
-        <!-- Panel attributes -->
-        <item name="panelBackground">?attr/colorBackground</item>
-        <item name="panelFullBackground">@drawable/menu_background_fill_parent_width</item>
-        <!-- These three attributes do not seems to be used by the framework. Declared public though -->
-        <item name="panelColorBackground">#000</item>
-        <item name="panelColorForeground">?attr/textColorPrimary</item>
-        <item name="panelTextAppearance">?attr/textAppearance</item>
-
-        <item name="panelMenuIsCompact">true</item>
-        <item name="panelMenuListWidth">250dip</item>
-        <item name="panelMenuListTheme">@style/Theme.Quantum.CompactMenu</item>
-
-        <!-- Scrollbar attributes -->
-        <item name="scrollbarFadeDuration">250</item>
-        <item name="scrollbarDefaultDelayBeforeFade">300</item>
-        <item name="scrollbarSize">10dip</item>
-        <item name="scrollbarThumbHorizontal">@drawable/scrollbar_handle_quantum</item>
-        <item name="scrollbarThumbVertical">@drawable/scrollbar_handle_quantum</item>
-        <item name="scrollbarTrackHorizontal">@null</item>
-        <item name="scrollbarTrackVertical">@null</item>
-
-        <!-- Text selection handle attributes -->
-        <item name="textSelectHandleLeft">@drawable/text_select_handle_left_quantum</item>
-        <item name="textSelectHandleRight">@drawable/text_select_handle_right_quantum</item>
-        <item name="textSelectHandle">@drawable/text_select_handle_middle_quantum</item>
-        <item name="textSelectHandleWindowStyle">@style/Widget.Quantum.TextSelectHandle</item>
-        <item name="textSuggestionsWindowStyle">@style/Widget.Quantum.TextSuggestionsPopupWindow</item>
-        <item name="textCursorDrawable">@drawable/text_cursor_quantum</item>
-
-        <!-- Widget styles -->
-        <item name="absListViewStyle">@style/Widget.Quantum.AbsListView</item>
-        <item name="autoCompleteTextViewStyle">@style/Widget.Quantum.AutoCompleteTextView</item>
-        <item name="checkboxStyle">@style/Widget.Quantum.CompoundButton.CheckBox</item>
-        <item name="checkedTextViewStyle">@style/Widget.Quantum.CheckedTextView</item>
-        <item name="dropDownListViewStyle">@style/Widget.Quantum.ListView.DropDown</item>
-        <item name="editTextStyle">@style/Widget.Quantum.EditText</item>
-        <item name="expandableListViewStyle">@style/Widget.Quantum.ExpandableListView</item>
-        <item name="expandableListViewWhiteStyle">@style/Widget.Quantum.ExpandableListView.White</item>
-        <item name="fastScrollStyle">@style/Widget.Quantum.FastScroll</item>
-        <item name="galleryStyle">@style/Widget.Quantum.Gallery</item>
-        <item name="gestureOverlayViewStyle">@style/Widget.Quantum.GestureOverlayView</item>
-        <item name="gridViewStyle">@style/Widget.Quantum.GridView</item>
-        <item name="imageButtonStyle">@style/Widget.Quantum.ImageButton</item>
-        <item name="imageWellStyle">@style/Widget.Quantum.ImageWell</item>
-        <item name="listViewStyle">@style/Widget.Quantum.ListView</item>
-        <item name="listViewWhiteStyle">@style/Widget.Quantum.ListView.White</item>
-        <item name="popupWindowStyle">@style/Widget.Quantum.PopupWindow</item>
-        <item name="progressBarStyle">@style/Widget.Quantum.ProgressBar</item>
-        <item name="progressBarStyleHorizontal">@style/Widget.Quantum.ProgressBar.Horizontal</item>
-        <item name="progressBarStyleSmall">@style/Widget.Quantum.ProgressBar.Small</item>
-        <item name="progressBarStyleSmallTitle">@style/Widget.Quantum.ProgressBar.Small.Title</item>
-        <item name="progressBarStyleLarge">@style/Widget.Quantum.ProgressBar.Large</item>
-        <item name="progressBarStyleInverse">@style/Widget.Quantum.ProgressBar.Inverse</item>
-        <item name="progressBarStyleSmallInverse">@style/Widget.Quantum.ProgressBar.Small.Inverse</item>
-        <item name="progressBarStyleLargeInverse">@style/Widget.Quantum.ProgressBar.Large.Inverse</item>
-        <item name="seekBarStyle">@style/Widget.Quantum.SeekBar</item>
-        <item name="ratingBarStyle">@style/Widget.Quantum.RatingBar</item>
-        <item name="ratingBarStyleIndicator">@style/Widget.Quantum.RatingBar.Indicator</item>
-        <item name="ratingBarStyleSmall">@style/Widget.Quantum.RatingBar.Small</item>
-        <item name="radioButtonStyle">@style/Widget.Quantum.CompoundButton.RadioButton</item>
-        <item name="scrollViewStyle">@style/Widget.Quantum.ScrollView</item>
-        <item name="horizontalScrollViewStyle">@style/Widget.Quantum.HorizontalScrollView</item>
-        <item name="spinnerStyle">?attr/dropDownSpinnerStyle</item>
-        <item name="dropDownSpinnerStyle">@style/Widget.Quantum.Spinner.DropDown</item>
-        <item name="starStyle">@style/Widget.Quantum.CompoundButton.Star</item>
-        <item name="tabWidgetStyle">@style/Widget.Quantum.TabWidget</item>
-        <item name="textViewStyle">@style/Widget.Quantum.TextView</item>
-        <item name="errorMessageBackground">@drawable/popup_inline_error_holo_dark</item>
-        <item name="errorMessageAboveBackground">@drawable/popup_inline_error_above_holo_dark</item>
-        <item name="webTextViewStyle">@style/Widget.Quantum.WebTextView</item>
-        <item name="webViewStyle">@style/Widget.Quantum.WebView</item>
-        <item name="dropDownItemStyle">@style/Widget.Quantum.DropDownItem</item>
-        <item name="spinnerDropDownItemStyle">@style/Widget.Quantum.DropDownItem.Spinner</item>
-        <item name="spinnerItemStyle">@style/Widget.Quantum.TextView.SpinnerItem</item>
-        <item name="dropDownHintAppearance">@style/TextAppearance.Quantum.Widget.DropDownHint</item>
-        <item name="keyboardViewStyle">@style/Widget.Quantum.KeyboardView</item>
-        <item name="quickContactBadgeStyleWindowSmall">@style/Widget.Quantum.QuickContactBadge.WindowSmall</item>
-        <item name="quickContactBadgeStyleWindowMedium">@style/Widget.Quantum.QuickContactBadge.WindowMedium</item>
-        <item name="quickContactBadgeStyleWindowLarge">@style/Widget.Quantum.QuickContactBadge.WindowLarge</item>
-        <item name="quickContactBadgeStyleSmallWindowSmall">@style/Widget.Quantum.QuickContactBadgeSmall.WindowSmall</item>
-        <item name="quickContactBadgeStyleSmallWindowMedium">@style/Widget.Quantum.QuickContactBadgeSmall.WindowMedium</item>
-        <item name="quickContactBadgeStyleSmallWindowLarge">@style/Widget.Quantum.QuickContactBadgeSmall.WindowLarge</item>
-        <item name="listPopupWindowStyle">@style/Widget.Quantum.ListPopupWindow</item>
-        <item name="popupMenuStyle">@style/Widget.Quantum.PopupMenu</item>
-        <item name="stackViewStyle">@style/Widget.Quantum.StackView</item>
-        <item name="activityChooserViewStyle">@style/Widget.Quantum.ActivityChooserView</item>
-
-        <!-- Preference styles -->
-        <item name="preferenceScreenStyle">@style/Preference.Quantum.PreferenceScreen</item>
-        <item name="preferenceFragmentStyle">@style/PreferenceFragment.Quantum</item>
-        <item name="preferenceFragmentPaddingSide">0dip</item>
-        <item name="preferenceCategoryStyle">@style/Preference.Quantum.Category</item>
-        <item name="preferenceStyle">@style/Preference.Quantum</item>
-        <item name="preferenceInformationStyle">@style/Preference.Quantum.Information</item>
-        <item name="checkBoxPreferenceStyle">@style/Preference.Quantum.CheckBoxPreference</item>
-        <item name="switchPreferenceStyle">@style/Preference.Quantum.SwitchPreference</item>
-        <item name="yesNoPreferenceStyle">@style/Preference.Quantum.DialogPreference.YesNoPreference</item>
-        <item name="dialogPreferenceStyle">@style/Preference.Quantum.DialogPreference</item>
-        <item name="editTextPreferenceStyle">@style/Preference.Quantum.DialogPreference.EditTextPreference</item>
-        <item name="ringtonePreferenceStyle">@style/Preference.Quantum.RingtonePreference</item>
-        <item name="preferenceLayoutChild">@layout/preference_child_quantum</item>
-        <item name="detailsElementBackground">?attr/colorBackground</item>
-
-        <!-- Search widget styles -->
-        <item name="searchWidgetCorpusItemBackground">@color/search_widget_corpus_item_background</item>
-
-        <!-- Action bar styles -->
-        <item name="actionDropDownStyle">@style/Widget.Quantum.Spinner.DropDown.ActionBar</item>
-        <item name="actionButtonStyle">@style/Widget.Quantum.ActionButton</item>
-        <item name="actionOverflowButtonStyle">@style/Widget.Quantum.ActionButton.Overflow</item>
-        <item name="actionOverflowMenuStyle">@android:style/Widget.Quantum.PopupMenu.Overflow</item>
-        <item name="actionModeBackground">?attr/colorPrimaryDark</item>
-        <item name="actionModeSplitBackground">?attr/colorPrimaryDark</item>
-        <item name="actionModeCloseDrawable">@drawable/ic_cab_done_quantum</item>
-        <item name="actionBarTabStyle">@style/Widget.Quantum.ActionBar.TabView</item>
-        <item name="actionBarTabBarStyle">@style/Widget.Quantum.ActionBar.TabBar</item>
-        <item name="actionBarTabTextStyle">@style/Widget.Quantum.ActionBar.TabText</item>
-        <item name="actionModeStyle">@style/Widget.Quantum.ActionMode</item>
-        <item name="actionModeCloseButtonStyle">@style/Widget.Quantum.ActionButton.CloseMode</item>
-        <item name="actionBarStyle">@style/Widget.Quantum.ActionBar.Solid</item>
-        <item name="actionBarSize">@dimen/action_bar_default_height_quantum</item>
-        <item name="actionModePopupWindowStyle">@style/Widget.Quantum.PopupWindow.ActionMode</item>
-        <item name="actionBarWidgetTheme">@style/ThemeOverlay.Quantum.ActionBarWidget</item>
-        <item name="actionBarTheme">@null</item>
-        <item name="actionBarItemBackground">?attr/selectableItemBackgroundBorderless</item>
-
-        <item name="actionModeCutDrawable">@drawable/ic_menu_cut_quantum</item>
-        <item name="actionModeCopyDrawable">@drawable/ic_menu_copy_quantum</item>
-        <item name="actionModePasteDrawable">@drawable/ic_menu_paste_quantum</item>
-        <item name="actionModeSelectAllDrawable">@drawable/ic_menu_selectall_quantum</item>
-        <item name="actionModeShareDrawable">@drawable/ic_menu_share_quantum</item>
-        <item name="actionModeFindDrawable">@drawable/ic_menu_find_quantum</item>
-        <item name="actionModeWebSearchDrawable">@drawable/ic_menu_search_quantum</item>
-
-        <item name="dividerVertical">?attr/listDivider</item>
-        <item name="dividerHorizontal">?attr/listDivider</item>
-        <item name="buttonBarStyle">@style/Widget.Quantum.ButtonBar</item>
-        <item name="buttonBarButtonStyle">@style/Widget.Quantum.Button.Borderless</item>
-        <item name="segmentedButtonStyle">@style/Widget.Quantum.SegmentedButton</item>
-
-        <!-- SearchView attributes -->
-        <item name="searchDropdownBackground">?attr/colorBackground</item>
-        <item name="searchViewTextField">@drawable/textfield_search_quantum</item>
-        <item name="searchViewTextFieldRight">@drawable/textfield_search_quantum</item>
-        <item name="searchViewCloseIcon">@android:drawable/ic_clear_quantum</item>
-        <item name="searchViewSearchIcon">@android:drawable/ic_search_api_quantum</item>
-        <item name="searchViewGoIcon">@android:drawable/ic_go_search_api_quantum</item>
-        <item name="searchViewVoiceIcon">@android:drawable/ic_voice_search_api_quantum</item>
-        <item name="searchViewEditQuery">@android:drawable/ic_commit_search_api_quantum</item>
-
-        <item name="searchDialogTheme">@style/Theme.Quantum.SearchBar</item>
-
-        <!-- PreferenceFrameLayout attributes -->
-        <item name="preferenceFrameLayoutStyle">@style/Widget.Quantum.PreferenceFrameLayout</item>
-
-        <!-- NumberPicker style-->
-        <item name="numberPickerStyle">@style/Widget.Quantum.NumberPicker</item>
-
-        <!-- CalendarView style-->
-        <item name="calendarViewStyle">@style/Widget.Quantum.CalendarView</item>
-
-        <!-- TimePicker style -->
-        <item name="timePickerStyle">@style/Widget.Quantum.TimePicker</item>
-
-        <!-- TimePicker background color -->
-        <item name="timePickerHeaderBackgroundColor">?colorBackground</item>
-
-        <!-- TimePicker Header time label text appearance -->
-        <item name="timePickerHeaderTimeLabelTextAppearance">@style/TextAppearance.Quantum.TimePicker.TimeLabel</item>
-
-        <!-- TimePicker Header am pm label text appearance -->
-        <item name="timePickerHeaderAmPmLabelTextAppearance">@style/TextAppearance.Quantum.TimePicker.AmPmLabel</item>
-
-        <!-- TimePicker dialog theme -->
-        <item name="timePickerDialogTheme">@style/Theme.Quantum.Dialog.TimePicker</item>
-
-        <!-- DatePicker style -->
-        <item name="datePickerStyle">@style/Widget.Quantum.DatePicker</item>
-
-        <!-- TODO: This belongs in a FastScroll style -->
-        <item name="fastScrollThumbDrawable">@drawable/fastscroll_thumb_quantum</item>
-        <item name="fastScrollPreviewBackgroundLeft">@drawable/fastscroll_label_left_holo_dark</item>
-        <item name="fastScrollPreviewBackgroundRight">@drawable/fastscroll_label_right_holo_dark</item>
-        <item name="fastScrollTrackDrawable">@drawable/fastscroll_track_quantum</item>
-        <item name="fastScrollOverlayPosition">atThumb</item>
-
-        <!-- Color palette -->
-        <item name="colorPrimaryDark">@color/quantum_blue_700</item>
-        <item name="colorPrimary">@color/quantum_blue_500</item>
-        <item name="colorPrimaryLight">@color/quantum_blue_100</item>
-        <item name="colorAccent">@color/quantum_teal_A200</item>
-
-        <item name="colorControlNormal">?attr/textColorSecondary</item>
-        <item name="colorControlActivated">?attr/colorPrimary</item>
-
-        <item name="colorControlHighlight">@color/ripple_quantum_dark</item>
-        <item name="colorButtonNormal">@color/btn_default_quantum_dark</item>
-    </style>
-
-    <!-- Quantum Paper theme (light version). -->
-    <style name="Theme.Quantum.Light" parent="Theme.Light">
-        <item name="colorForeground">@color/bright_foreground_quantum_light</item>
-        <item name="colorForegroundInverse">@color/bright_foreground_quantum_dark</item>
-        <item name="colorBackground">@color/background_quantum_light</item>
-        <item name="colorBackgroundCacheHint">@color/background_cache_hint_selector_quantum_light</item>
-        <item name="disabledAlpha">0.5</item>
-        <item name="backgroundDimAmount">0.6</item>
-
-        <!-- Text styles -->
-        <item name="textAppearance">@style/TextAppearance.Quantum</item>
-        <item name="textAppearanceInverse">@style/TextAppearance.Quantum.Inverse</item>
-
-        <item name="textColorPrimary">@color/primary_text_quantum_light</item>
-        <item name="textColorPrimaryInverse">@color/primary_text_quantum_dark</item>
-        <item name="textColorSecondary">@color/secondary_text_quantum_light</item>
-        <item name="textColorSecondaryInverse">@color/secondary_text_quantum_dark</item>
-        <item name="textColorTertiary">@color/tertiary_text_quantum_light</item>
-        <item name="textColorTertiaryInverse">@color/tertiary_text_quantum_dark</item>
-        <item name="textColorPrimaryDisableOnly">@color/primary_text_disable_only_quantum_light</item>
-        <item name="textColorPrimaryInverseDisableOnly">@color/primary_text_disable_only_quantum_dark</item>
-        <item name="textColorHint">@color/hint_foreground_quantum_light</item>
-        <item name="textColorHintInverse">@color/hint_foreground_quantum_dark</item>
-        <item name="textColorHighlight">@color/highlighted_text_quantum_light</item>
-        <item name="textColorHighlightInverse">@color/highlighted_text_quantum_dark</item>
-        <item name="textColorLink">@color/quantum_teal_500</item>
-        <item name="textColorLinkInverse">@color/quantum_teal_500</item>
-        <item name="textColorSearchUrl">@color/search_url_text_quantum_light</item>
-        <item name="textColorAlertDialogListItem">@color/primary_text_quantum_light</item>
-
-        <item name="textAppearanceLarge">@style/TextAppearance.Quantum.Large</item>
-        <item name="textAppearanceLargeInverse">@style/TextAppearance.Quantum.Large.Inverse</item>
-        <item name="textAppearanceMedium">@style/TextAppearance.Quantum.Medium</item>
-        <item name="textAppearanceMediumInverse">@style/TextAppearance.Quantum.Medium.Inverse</item>
-        <item name="textAppearanceSmall">@style/TextAppearance.Quantum.Small</item>
-        <item name="textAppearanceSmallInverse">@style/TextAppearance.Quantum.Small.Inverse</item>
-        <item name="textAppearanceSearchResultTitle">@style/TextAppearance.Quantum.SearchResult.Title</item>
-        <item name="textAppearanceSearchResultSubtitle">@style/TextAppearance.Quantum.SearchResult.Subtitle</item>
-
-        <item name="textAppearanceButton">@style/TextAppearance.Quantum.Widget.Button</item>
-
-        <item name="editTextColor">?attr/textColorPrimary</item>
-        <item name="editTextBackground">@drawable/edit_text_quantum</item>
-
-        <item name="candidatesTextStyleSpans">@string/candidates_style</item>
-
-        <item name="textCheckMark">@drawable/indicator_check_mark_light</item>
-        <item name="textCheckMarkInverse">@drawable/indicator_check_mark_dark</item>
-
-        <item name="textAppearanceLargePopupMenu">@style/TextAppearance.Quantum.Widget.PopupMenu.Large</item>
-        <item name="textAppearanceSmallPopupMenu">@style/TextAppearance.Quantum.Widget.PopupMenu.Small</item>
-
-        <!-- Button styles -->
-        <item name="buttonStyle">@style/Widget.Quantum.Light.Button</item>
-
-        <item name="buttonStyleSmall">@style/Widget.Quantum.Light.Button.Small</item>
-        <item name="buttonStyleInset">@style/Widget.Quantum.Light.Button.Inset</item>
-
-        <item name="buttonStyleToggle">@style/Widget.Quantum.Light.Button.Toggle</item>
-        <item name="switchStyle">@style/Widget.Quantum.Light.CompoundButton.Switch</item>
-        <item name="mediaRouteButtonStyle">@style/Widget.Quantum.Light.MediaRouteButton</item>
-
-        <item name="selectableItemBackground">@drawable/item_background_quantum</item>
-        <item name="selectableItemBackgroundBorderless">@drawable/item_background_borderless_quantum</item>
-        <item name="borderlessButtonStyle">@style/Widget.Quantum.Light.Button.Borderless</item>
-        <item name="homeAsUpIndicator">@drawable/ic_ab_back_quantum</item>
-
-        <!-- List attributes -->
-        <item name="listPreferredItemHeight">64dip</item>
-        <item name="listPreferredItemHeightSmall">48dip</item>
-        <item name="listPreferredItemHeightLarge">80dip</item>
-        <item name="dropdownListPreferredItemHeight">?attr/listPreferredItemHeightSmall</item>
-        <item name="textAppearanceListItem">@style/TextAppearance.Quantum.Subhead</item>
-        <item name="textAppearanceListItemSmall">@style/TextAppearance.Quantum.Subhead</item>
-        <item name="textAppearanceListItemSecondary">@style/TextAppearance.Quantum.Body1</item>
-        <item name="listPreferredItemPaddingLeft">16dip</item>
-        <item name="listPreferredItemPaddingRight">16dip</item>
-        <item name="listPreferredItemPaddingStart">16dip</item>
-        <item name="listPreferredItemPaddingEnd">16dip</item>
-
-        <!-- @hide -->
-        <item name="searchResultListItemHeight">58dip</item>
-        <item name="listDivider">@drawable/list_divider_quantum</item>
-        <item name="listSeparatorTextViewStyle">@style/Widget.Quantum.Light.TextView.ListSeparator</item>
-
-        <item name="listChoiceIndicatorSingle">@drawable/btn_radio_quantum_anim</item>
-        <item name="listChoiceIndicatorMultiple">@drawable/btn_check_quantum_anim</item>
-
-        <item name="listChoiceBackgroundIndicator">?attr/selectableItemBackground</item>
-        <item name="activatedBackgroundIndicator">@drawable/activated_background_quantum</item>
-
-        <item name="expandableListPreferredItemPaddingLeft">40dip</item>
-        <item name="expandableListPreferredChildPaddingLeft">?attr/expandableListPreferredItemPaddingLeft</item>
-
-        <item name="expandableListPreferredItemIndicatorLeft">3dip</item>
-        <item name="expandableListPreferredItemIndicatorRight">0dip</item>
-        <item name="expandableListPreferredChildIndicatorLeft">?attr/expandableListPreferredItemIndicatorLeft</item>
-        <item name="expandableListPreferredChildIndicatorRight">?attr/expandableListPreferredItemIndicatorRight</item>
-
-        <item name="listDividerAlertDialog">@drawable/list_divider_quantum</item>
-        <item name="findOnPageNextDrawable">@drawable/ic_find_next_quantum</item>
-        <item name="findOnPagePreviousDrawable">@drawable/ic_find_previous_quantum</item>
-
-        <!-- Gallery attributes -->
-        <item name="galleryItemBackground">@drawable/gallery_item_background</item>
-
-        <!-- Window attributes -->
-        <item name="windowBackground">@color/background_quantum_light</item>
-        <item name="windowFrame">@null</item>
-        <item name="windowNoTitle">false</item>
-        <item name="windowFullscreen">false</item>
-        <item name="windowOverscan">false</item>
-        <item name="windowIsFloating">false</item>
-        <item name="windowContentOverlay">@drawable/ab_solid_shadow_quantum</item>
-        <item name="windowShowWallpaper">false</item>
-        <item name="windowTitleStyle">@style/WindowTitle.Quantum</item>
-        <item name="windowTitleSize">25dip</item>
-        <item name="windowTitleBackgroundStyle">@style/WindowTitleBackground.Quantum</item>
-        <item name="windowAnimationStyle">@style/Animation.Quantum.Activity</item>
-        <item name="windowSoftInputMode">stateUnspecified|adjustUnspecified</item>
-        <item name="windowActionBar">true</item>
-        <item name="windowActionModeOverlay">false</item>
-        <item name="windowDrawsSystemBarBackgrounds">true</item>
-        <item name="windowActionBarFullscreenDecorLayout">@layout/screen_toolbar</item>
-        <item name="statusBarColor">?attr/colorPrimaryDark</item>
-        <item name="navigationBarColor">?attr/colorPrimaryDark</item>
-
-        <!-- Dialog attributes -->
-        <item name="dialogTheme">@style/Theme.Quantum.Light.Dialog</item>
-        <item name="dialogTitleIconsDecorLayout">@layout/dialog_title_icons_quantum</item>
-        <item name="dialogCustomTitleDecorLayout">@layout/dialog_custom_title_quantum</item>
-        <item name="dialogTitleDecorLayout">@layout/dialog_title_quantum</item>
-
-        <!-- AlertDialog attributes -->
-        <item name="alertDialogTheme">@style/Theme.Quantum.Light.Dialog.Alert</item>
-        <item name="alertDialogStyle">@style/AlertDialog.Quantum.Light</item>
-        <item name="alertDialogCenterButtons">false</item>
-        <item name="alertDialogIcon">@drawable/ic_dialog_alert_quantum</item>
-
-        <!-- Presentation attributes -->
-        <item name="presentationTheme">@style/Theme.Quantum.Light.Dialog.Presentation</item>
-
-        <!-- Toast attributes -->
-        <item name="toastFrameBackground">@drawable/toast_frame</item>
-
-        <!-- Panel attributes -->
-        <item name="panelBackground">?attr/colorBackground</item>
-        <item name="panelFullBackground">@drawable/menu_background_fill_parent_width</item>
-        <!-- These three attributes do not seems to be used by the framework. Declared public though -->
-        <item name="panelColorBackground">#000</item>
-        <item name="panelColorForeground">?attr/textColorPrimary</item>
-        <item name="panelTextAppearance">?attr/textAppearance</item>
-
-        <item name="panelMenuIsCompact">true</item>
-        <item name="panelMenuListWidth">250dip</item>
-        <item name="panelMenuListTheme">@style/Theme.Quantum.Light.CompactMenu</item>
-
-        <!-- Scrollbar attributes -->
-        <item name="scrollbarFadeDuration">250</item>
-        <item name="scrollbarDefaultDelayBeforeFade">300</item>
-        <item name="scrollbarSize">10dip</item>
-        <item name="scrollbarThumbHorizontal">@drawable/scrollbar_handle_quantum</item>
-        <item name="scrollbarThumbVertical">@drawable/scrollbar_handle_quantum</item>
-        <item name="scrollbarTrackHorizontal">@null</item>
-        <item name="scrollbarTrackVertical">@null</item>
-
-        <!-- Text selection handle attributes -->
-        <item name="textSelectHandleLeft">@drawable/text_select_handle_left_quantum</item>
-        <item name="textSelectHandleRight">@drawable/text_select_handle_right_quantum</item>
-        <item name="textSelectHandle">@drawable/text_select_handle_middle_quantum</item>
-        <item name="textSelectHandleWindowStyle">@style/Widget.Quantum.TextSelectHandle</item>
-        <item name="textSuggestionsWindowStyle">@style/Widget.Quantum.Light.TextSuggestionsPopupWindow</item>
-        <item name="textCursorDrawable">@drawable/text_cursor_quantum</item>
-
-        <!-- Widget styles -->
-        <item name="absListViewStyle">@style/Widget.Quantum.Light.AbsListView</item>
-        <item name="autoCompleteTextViewStyle">@style/Widget.Quantum.Light.AutoCompleteTextView</item>
-        <item name="checkboxStyle">@style/Widget.Quantum.Light.CompoundButton.CheckBox</item>
-        <item name="checkedTextViewStyle">@style/Widget.Quantum.Light.CheckedTextView</item>
-        <item name="dropDownListViewStyle">@style/Widget.Quantum.ListView.DropDown</item>
-        <item name="editTextStyle">@style/Widget.Quantum.Light.EditText</item>
-        <item name="expandableListViewStyle">@style/Widget.Quantum.Light.ExpandableListView</item>
-        <item name="expandableListViewWhiteStyle">@style/Widget.Quantum.Light.ExpandableListView.White</item>
-        <item name="fastScrollStyle">@style/Widget.Quantum.Light.FastScroll</item>
-        <item name="galleryStyle">@style/Widget.Quantum.Light.Gallery</item>
-        <item name="gestureOverlayViewStyle">@style/Widget.Quantum.Light.GestureOverlayView</item>
-        <item name="gridViewStyle">@style/Widget.Quantum.Light.GridView</item>
-        <item name="imageButtonStyle">@style/Widget.Quantum.Light.ImageButton</item>
-        <item name="imageWellStyle">@style/Widget.Quantum.Light.ImageWell</item>
-        <item name="listViewStyle">@style/Widget.Quantum.Light.ListView</item>
-        <item name="listViewWhiteStyle">@style/Widget.Quantum.Light.ListView.White</item>
-        <item name="popupWindowStyle">@style/Widget.Quantum.Light.PopupWindow</item>
-        <item name="progressBarStyle">@style/Widget.Quantum.Light.ProgressBar</item>
-        <item name="progressBarStyleHorizontal">@style/Widget.Quantum.Light.ProgressBar.Horizontal</item>
-        <item name="progressBarStyleSmall">@style/Widget.Quantum.Light.ProgressBar.Small</item>
-        <item name="progressBarStyleSmallTitle">@style/Widget.Quantum.Light.ProgressBar.Small.Title</item>
-        <item name="progressBarStyleLarge">@style/Widget.Quantum.Light.ProgressBar.Large</item>
-        <item name="progressBarStyleInverse">@style/Widget.Quantum.Light.ProgressBar.Inverse</item>
-        <item name="progressBarStyleSmallInverse">@style/Widget.Quantum.Light.ProgressBar.Small.Inverse</item>
-        <item name="progressBarStyleLargeInverse">@style/Widget.Quantum.Light.ProgressBar.Large.Inverse</item>
-        <item name="seekBarStyle">@style/Widget.Quantum.Light.SeekBar</item>
-        <item name="ratingBarStyle">@style/Widget.Quantum.Light.RatingBar</item>
-        <item name="ratingBarStyleIndicator">@style/Widget.Quantum.Light.RatingBar.Indicator</item>
-        <item name="ratingBarStyleSmall">@style/Widget.Quantum.Light.RatingBar.Small</item>
-        <item name="radioButtonStyle">@style/Widget.Quantum.Light.CompoundButton.RadioButton</item>
-        <item name="scrollViewStyle">@style/Widget.Quantum.Light.ScrollView</item>
-        <item name="horizontalScrollViewStyle">@style/Widget.Quantum.Light.HorizontalScrollView</item>
-        <item name="spinnerStyle">?attr/dropDownSpinnerStyle</item>
-        <item name="dropDownSpinnerStyle">@style/Widget.Quantum.Light.Spinner.DropDown</item>
-        <item name="starStyle">@style/Widget.Quantum.Light.CompoundButton.Star</item>
-        <item name="tabWidgetStyle">@style/Widget.Quantum.Light.TabWidget</item>
-        <item name="textViewStyle">@style/Widget.Quantum.Light.TextView</item>
-        <item name="errorMessageBackground">@drawable/popup_inline_error_holo_light</item>
-        <item name="errorMessageAboveBackground">@drawable/popup_inline_error_above_holo_light</item>
-        <item name="webTextViewStyle">@style/Widget.Quantum.Light.WebTextView</item>
-        <item name="webViewStyle">@style/Widget.Quantum.Light.WebView</item>
-        <item name="dropDownItemStyle">@style/Widget.Quantum.Light.DropDownItem</item>
-        <item name="spinnerDropDownItemStyle">@style/Widget.Quantum.Light.DropDownItem.Spinner</item>
-        <item name="spinnerItemStyle">@style/Widget.Quantum.TextView.SpinnerItem</item>
-        <item name="dropDownHintAppearance">@style/TextAppearance.Quantum.Widget.DropDownHint</item>
-        <item name="keyboardViewStyle">@style/Widget.Quantum.KeyboardView</item>
-        <item name="quickContactBadgeStyleWindowSmall">@style/Widget.Quantum.QuickContactBadge.WindowSmall</item>
-        <item name="quickContactBadgeStyleWindowMedium">@style/Widget.Quantum.QuickContactBadge.WindowMedium</item>
-        <item name="quickContactBadgeStyleWindowLarge">@style/Widget.Quantum.QuickContactBadge.WindowLarge</item>
-        <item name="quickContactBadgeStyleSmallWindowSmall">@style/Widget.Quantum.QuickContactBadgeSmall.WindowSmall</item>
-        <item name="quickContactBadgeStyleSmallWindowMedium">@style/Widget.Quantum.QuickContactBadgeSmall.WindowMedium</item>
-        <item name="quickContactBadgeStyleSmallWindowLarge">@style/Widget.Quantum.QuickContactBadgeSmall.WindowLarge</item>
-        <item name="listPopupWindowStyle">@style/Widget.Quantum.Light.ListPopupWindow</item>
-        <item name="popupMenuStyle">@style/Widget.Quantum.Light.PopupMenu</item>
-        <item name="stackViewStyle">@style/Widget.Quantum.Light.StackView</item>
-        <item name="activityChooserViewStyle">@style/Widget.Quantum.Light.ActivityChooserView</item>
-
-        <!-- Preference styles -->
-        <item name="preferenceScreenStyle">@style/Preference.Quantum.PreferenceScreen</item>
-        <item name="preferenceFragmentStyle">@style/PreferenceFragment.Quantum</item>
-        <item name="preferenceFragmentPaddingSide">0dip</item>
-        <item name="preferenceCategoryStyle">@style/Preference.Quantum.Category</item>
-        <item name="preferenceStyle">@style/Preference.Quantum</item>
-        <item name="preferenceInformationStyle">@style/Preference.Quantum.Information</item>
-        <item name="checkBoxPreferenceStyle">@style/Preference.Quantum.CheckBoxPreference</item>
-        <item name="switchPreferenceStyle">@style/Preference.Quantum.SwitchPreference</item>
-        <item name="yesNoPreferenceStyle">@style/Preference.Quantum.DialogPreference.YesNoPreference</item>
-        <item name="dialogPreferenceStyle">@style/Preference.Quantum.DialogPreference</item>
-        <item name="editTextPreferenceStyle">@style/Preference.Quantum.DialogPreference.EditTextPreference</item>
-        <item name="ringtonePreferenceStyle">@style/Preference.Quantum.RingtonePreference</item>
-        <item name="preferenceLayoutChild">@layout/preference_child_quantum</item>
-        <item name="detailsElementBackground">?attr/colorBackground</item>
-
-        <!-- PreferenceFrameLayout attributes -->
-        <item name="preferenceFrameLayoutStyle">@style/Widget.Quantum.PreferenceFrameLayout</item>
-
-        <!-- Search widget styles -->
-        <item name="searchWidgetCorpusItemBackground">@color/search_widget_corpus_item_background</item>
-
-        <!-- Action bar styles -->
-        <item name="actionDropDownStyle">@style/Widget.Quantum.Light.Spinner.DropDown.ActionBar</item>
-        <item name="actionButtonStyle">@style/Widget.Quantum.Light.ActionButton</item>
-        <item name="actionOverflowButtonStyle">@style/Widget.Quantum.Light.ActionButton.Overflow</item>
-        <item name="actionOverflowMenuStyle">@android:style/Widget.Quantum.Light.PopupMenu.Overflow</item>
-        <item name="actionModeBackground">@drawable/cab_background_top_holo_light</item>
-        <item name="actionModeSplitBackground">@drawable/cab_background_bottom_holo_light</item>
-        <item name="actionModeCloseDrawable">@drawable/ic_cab_done_quantum</item>
-        <item name="actionBarTabStyle">@style/Widget.Quantum.Light.ActionBar.TabView</item>
-        <item name="actionBarTabBarStyle">@style/Widget.Quantum.Light.ActionBar.TabBar</item>
-        <item name="actionBarTabTextStyle">@style/Widget.Quantum.Light.ActionBar.TabText</item>
-        <item name="actionModeStyle">@style/Widget.Quantum.Light.ActionMode</item>
-        <item name="actionModeCloseButtonStyle">@style/Widget.Quantum.Light.ActionButton.CloseMode</item>
-        <item name="actionBarStyle">@style/Widget.Quantum.Light.ActionBar.Solid</item>
-        <item name="actionBarSize">@dimen/action_bar_default_height_quantum</item>
-        <item name="actionModePopupWindowStyle">@style/Widget.Quantum.Light.PopupWindow.ActionMode</item>
-        <item name="actionBarWidgetTheme">@style/ThemeOverlay.Quantum.ActionBarWidget</item>
-        <item name="actionBarTheme">@null</item>
-        <item name="actionBarItemBackground">?attr/selectableItemBackgroundBorderless</item>
-
-        <item name="actionModeCutDrawable">@drawable/ic_menu_cut_quantum</item>
-        <item name="actionModeCopyDrawable">@drawable/ic_menu_copy_quantum</item>
-        <item name="actionModePasteDrawable">@drawable/ic_menu_paste_quantum</item>
-        <item name="actionModeSelectAllDrawable">@drawable/ic_menu_selectall_quantum</item>
-        <item name="actionModeShareDrawable">@drawable/ic_menu_share_quantum</item>
-        <item name="actionModeFindDrawable">@drawable/ic_menu_find_quantum</item>
-        <item name="actionModeWebSearchDrawable">@drawable/ic_menu_search_quantum</item>
-
-        <item name="dividerVertical">?attr/listDivider</item>
-        <item name="dividerHorizontal">?attr/listDivider</item>
-        <item name="buttonBarStyle">@style/Widget.Quantum.Light.ButtonBar</item>
-        <item name="buttonBarButtonStyle">@style/Widget.Quantum.Light.Button.Borderless</item>
-        <item name="segmentedButtonStyle">@style/Widget.Quantum.Light.SegmentedButton</item>
-
-        <!-- SearchView attributes -->
-        <item name="searchDropdownBackground">?attr/colorBackground</item>
-        <item name="searchViewTextField">@drawable/textfield_search_quantum</item>
-        <item name="searchViewTextFieldRight">@drawable/textfield_search_quantum</item>
-        <item name="searchViewCloseIcon">@android:drawable/ic_clear_quantum</item>
-        <item name="searchViewSearchIcon">@android:drawable/ic_search_api_quantum</item>
-        <item name="searchViewGoIcon">@android:drawable/ic_go_search_api_quantum</item>
-        <item name="searchViewVoiceIcon">@android:drawable/ic_voice_search_api_quantum</item>
-        <item name="searchViewEditQuery">@android:drawable/ic_commit_search_api_quantum</item>
-
-        <item name="searchDialogTheme">@style/Theme.Quantum.Light.SearchBar</item>
-
-        <!-- NumberPicker style-->
-        <item name="numberPickerStyle">@style/Widget.Quantum.Light.NumberPicker</item>
-
-        <!-- CalendarView style-->
-        <item name="calendarViewStyle">@style/Widget.Quantum.Light.CalendarView</item>
-
-        <!-- TimePicker style -->
-        <item name="timePickerStyle">@style/Widget.Quantum.Light.TimePicker</item>
-
-        <!-- TimePicker Header background color -->
-        <item name="timePickerHeaderBackgroundColor">?attr/colorBackground</item>
-
-        <!-- TimePicker Header time label text appearance -->
-        <item name="timePickerHeaderTimeLabelTextAppearance">@style/TextAppearance.Quantum.TimePicker.TimeLabel</item>
-
-        <!-- TimePicker Header am pm label text appearance -->
-        <item name="timePickerHeaderAmPmLabelTextAppearance">@style/TextAppearance.Quantum.TimePicker.AmPmLabel</item>
-
-        <!-- TimePicker dialog theme -->
-        <item name="timePickerDialogTheme">@style/Theme.Quantum.Light.Dialog.TimePicker</item>
-
-        <!-- DatePicker style -->
-        <item name="datePickerStyle">@style/Widget.Quantum.Light.DatePicker</item>
-
-        <item name="fastScrollThumbDrawable">@drawable/fastscroll_thumb_quantum</item>
-        <item name="fastScrollPreviewBackgroundLeft">@drawable/fastscroll_label_left_holo_light</item>
-        <item name="fastScrollPreviewBackgroundRight">@drawable/fastscroll_label_right_holo_light</item>
-        <item name="fastScrollTrackDrawable">@drawable/fastscroll_track_quantum</item>
-        <item name="fastScrollOverlayPosition">atThumb</item>
-
-        <!-- Color palette -->
-        <item name="colorPrimaryDark">@color/quantum_blue_700</item>
-        <item name="colorPrimary">@color/quantum_blue_500</item>
-        <item name="colorPrimaryLight">@color/quantum_blue_100</item>
-        <item name="colorAccent">@color/quantum_teal_A200</item>
-
-        <item name="colorControlNormal">?attr/textColorSecondary</item>
-        <item name="colorControlActivated">?attr/colorPrimary</item>
-
-        <item name="colorControlHighlight">@color/ripple_quantum_light</item>
-        <item name="colorButtonNormal">@color/btn_default_quantum_light</item>
-    </style>
-
-    <!-- Variant of the quantum (light) theme that has a solid (opaque) action bar
-         with an inverse color profile. The dark action bar sharply stands out against
-         the light content. -->
-    <style name="Theme.Quantum.Light.DarkActionBar">
-        <item name="actionBarWidgetTheme">@style/ThemeOverlay.Quantum.ActionBarWidget</item>
-        <item name="actionBarTheme">@style/ThemeOverlay.Quantum.Dark</item>
-    </style>
-
-    <style name="ThemeOverlay" />
-    <style name="ThemeOverlay.Quantum" />
-
-    <!-- Theme overlay that replaces colors with their light versions but preserves
-         the value of colorAccent, colorPrimary and its variants. -->
-    <style name="ThemeOverlay.Quantum.Light">
-        <item name="colorForeground">@color/bright_foreground_quantum_light</item>
-        <item name="colorForegroundInverse">@color/bright_foreground_quantum_dark</item>
-        <item name="colorBackground">@color/background_quantum_light</item>
-        <item name="colorBackgroundCacheHint">@color/background_cache_hint_selector_quantum_light</item>
-
-        <item name="textColorPrimary">@color/primary_text_quantum_light</item>
-        <item name="textColorPrimaryInverse">@color/primary_text_quantum_dark</item>
-        <item name="textColorSecondary">@color/secondary_text_quantum_light</item>
-        <item name="textColorSecondaryInverse">@color/secondary_text_quantum_dark</item>
-        <item name="textColorTertiary">@color/tertiary_text_quantum_light</item>
-        <item name="textColorTertiaryInverse">@color/tertiary_text_quantum_dark</item>
-        <item name="textColorPrimaryDisableOnly">@color/primary_text_disable_only_quantum_light</item>
-        <item name="textColorPrimaryInverseDisableOnly">@color/primary_text_disable_only_quantum_dark</item>
-        <item name="textColorHint">@color/hint_foreground_quantum_light</item>
-        <item name="textColorHintInverse">@color/hint_foreground_quantum_dark</item>
-        <item name="textColorHighlight">@color/highlighted_text_quantum_light</item>
-        <item name="textColorHighlightInverse">@color/highlighted_text_quantum_dark</item>
-        <item name="textColorLink">@color/quantum_teal_500</item>
-        <item name="textColorLinkInverse">@color/quantum_teal_500</item>
-        <item name="textColorSearchUrl">@color/search_url_text_quantum_light</item>
-        <item name="textColorAlertDialogListItem">@color/primary_text_quantum_light</item>
-
-        <item name="textCheckMark">@drawable/indicator_check_mark_light</item>
-        <item name="textCheckMarkInverse">@drawable/indicator_check_mark_dark</item>
-
-        <item name="windowBackground">@color/background_quantum_light</item>
-
-        <item name="fastScrollPreviewBackgroundLeft">@drawable/fastscroll_label_left_holo_light</item>
-        <item name="fastScrollPreviewBackgroundRight">@drawable/fastscroll_label_right_holo_light</item>
-
-        <item name="colorControlHighlight">@color/ripple_quantum_light</item>
-        <item name="colorButtonNormal">@color/btn_default_quantum_light</item>
-    </style>
-
-    <!-- Theme overlay that replaces colors with their dark versions but preserves
-         the value of colorAccent, colorPrimary and its variants. -->
-    <style name="ThemeOverlay.Quantum.Dark">
-        <item name="colorForeground">@color/bright_foreground_quantum_dark</item>
-        <item name="colorForegroundInverse">@color/bright_foreground_quantum_light</item>
-        <item name="colorBackground">@color/background_quantum_dark</item>
-        <item name="colorBackgroundCacheHint">@color/background_cache_hint_selector_quantum_dark</item>
-
-        <item name="textColorPrimary">@color/primary_text_quantum_dark</item>
-        <item name="textColorPrimaryInverse">@color/primary_text_quantum_light</item>
-        <item name="textColorPrimaryDisableOnly">@color/primary_text_disable_only_quantum_dark</item>
-        <item name="textColorSecondary">@color/secondary_text_quantum_dark</item>
-        <item name="textColorSecondaryInverse">@color/secondary_text_quantum_light</item>
-        <item name="textColorTertiary">@color/tertiary_text_quantum_dark</item>
-        <item name="textColorTertiaryInverse">@color/tertiary_text_quantum_light</item>
-        <item name="textColorHint">@color/hint_foreground_quantum_dark</item>
-        <item name="textColorHintInverse">@color/hint_foreground_quantum_light</item>
-        <item name="textColorHighlight">@color/highlighted_text_quantum_dark</item>
-        <item name="textColorHighlightInverse">@color/highlighted_text_quantum_light</item>
-        <item name="textColorLink">@color/quantum_teal_500</item>
-        <item name="textColorLinkInverse">@color/quantum_teal_500</item>
-        <item name="textColorSearchUrl">@color/search_url_text_quantum_dark</item>
-        <item name="textColorAlertDialogListItem">@color/primary_text_quantum_dark</item>
-
-        <item name="textCheckMark">@drawable/indicator_check_mark_dark</item>
-        <item name="textCheckMarkInverse">@drawable/indicator_check_mark_light</item>
-
-        <item name="windowBackground">@color/background_quantum_dark</item>
-
-        <item name="fastScrollPreviewBackgroundLeft">@drawable/fastscroll_label_left_holo_dark</item>
-        <item name="fastScrollPreviewBackgroundRight">@drawable/fastscroll_label_right_holo_dark</item>
-
-        <item name="colorControlHighlight">@color/ripple_quantum_dark</item>
-        <item name="colorButtonNormal">@color/btn_default_quantum_dark</item>
-    </style>
-
-    <!-- Theme overlay that replaces the activated control color (which by default
-         is identical to the action bar background color) with the normal control
-         color. -->
-    <style name="ThemeOverlay.Quantum.ActionBarWidget">
-        <item name="colorControlActivated">?attr/colorControlNormal</item>
-    </style>
-
-    <!-- Variant of the quantum (dark) theme with no action bar. -->
-    <style name="Theme.Quantum.NoActionBar">
-        <item name="windowActionBar">false</item>
-        <item name="windowNoTitle">true</item>
-    </style>
-
-    <!-- Variant of the quantum (dark) theme that has no title bar and fills
-         the entire screen.  This theme
-         sets {@link android.R.attr#windowFullscreen} to true.  -->
-    <style name="Theme.Quantum.NoActionBar.Fullscreen">
-        <item name="windowFullscreen">true</item>
-        <item name="windowContentOverlay">@null</item>
-    </style>
-
-    <!-- Variant of the quantum (dark) theme that has no title bar and fills
-         the entire screen and extends into the display overscan region.  This theme
-         sets {@link android.R.attr#windowFullscreen} and {@link android.R.attr#windowOverscan}
-         to true. -->
-    <style name="Theme.Quantum.NoActionBar.Overscan">
-        <item name="windowFullscreen">true</item>
-        <item name="windowOverscan">true</item>
-        <item name="windowContentOverlay">@null</item>
-    </style>
-
-    <!-- Variant of the quantum (dark) theme that has no title bar and translucent
-         system decor.  This theme sets {@link android.R.attr#windowTranslucentStatus} and
-         {@link android.R.attr#windowTranslucentNavigation} to true. -->
-    <style name="Theme.Quantum.NoActionBar.TranslucentDecor">
-        <item name="windowTranslucentStatus">true</item>
-        <item name="windowTranslucentNavigation">true</item>
-        <item name="windowContentOverlay">@null</item>
-    </style>
-
-    <!-- Variant of the quantum (light) theme with no action bar. -->
-    <style name="Theme.Quantum.Light.NoActionBar">
-        <item name="windowActionBar">false</item>
-        <item name="windowNoTitle">true</item>
-    </style>
-
-    <!-- Variant of the quantum (light) theme that has no title bar and fills
-         the entire screen.  This theme
-         sets {@link android.R.attr#windowFullscreen} to true.  -->
-    <style name="Theme.Quantum.Light.NoActionBar.Fullscreen">
-        <item name="windowFullscreen">true</item>
-        <item name="windowContentOverlay">@null</item>
-    </style>
-
-    <!-- Variant of the quantum (light) theme that has no title bar and fills
-         the entire screen and extends into the display overscan region.  This theme
-         sets {@link android.R.attr#windowFullscreen} and {@link android.R.attr#windowOverscan}
-         to true. -->
-    <style name="Theme.Quantum.Light.NoActionBar.Overscan">
-        <item name="windowFullscreen">true</item>
-        <item name="windowOverscan">true</item>
-        <item name="windowContentOverlay">@null</item>
-    </style>
-
-    <!-- Variant of the quantum (light) theme that has no title bar and translucent
-         system decor.  This theme sets {@link android.R.attr#windowTranslucentStatus} and
-         {@link android.R.attr#windowTranslucentNavigation} to true. -->
-    <style name="Theme.Quantum.Light.NoActionBar.TranslucentDecor">
-        <item name="windowTranslucentStatus">true</item>
-        <item name="windowTranslucentNavigation">true</item>
-        <item name="windowContentOverlay">@null</item>
-    </style>
-
-    <!-- Default quantum dark theme for panel windows.  This removes all extraneous
-         window decorations, so you basically have an empty rectangle in which
-         to place your content.  It makes the window floating, with a transparent
-         background, and turns off dimming behind the window. -->
-    <style name="Theme.Quantum.Panel">
-        <item name="windowBackground">@color/transparent</item>
-        <item name="colorBackgroundCacheHint">@null</item>
-        <item name="windowFrame">@null</item>
-        <item name="windowContentOverlay">@null</item>
-        <item name="windowAnimationStyle">@null</item>
-        <item name="windowIsFloating">true</item>
-        <item name="backgroundDimEnabled">false</item>
-        <item name="windowIsTranslucent">true</item>
-        <item name="windowNoTitle">true</item>
-    </style>
-
-    <!-- Default quantum light theme for panel windows.  This removes all extraneous
-         window decorations, so you basically have an empty rectangle in which
-         to place your content.  It makes the window floating, with a transparent
-         background, and turns off dimming behind the window. -->
-    <style name="Theme.Quantum.Light.Panel">
-        <item name="windowBackground">@color/transparent</item>
-        <item name="colorBackgroundCacheHint">@null</item>
-        <item name="windowFrame">@null</item>
-        <item name="windowContentOverlay">@null</item>
-        <item name="windowAnimationStyle">@null</item>
-        <item name="windowIsFloating">true</item>
-        <item name="backgroundDimEnabled">false</item>
-        <item name="windowIsTranslucent">true</item>
-        <item name="windowNoTitle">true</item>
-    </style>
-
-    <!-- Quantum theme for an activity that is to be used for voice interaction.
-         This gives the activity a floating dialog style, to incorporate with the
-         system voice experience. -->
-    <style name="Theme.Quantum.Voice" parent="@style/Theme.Quantum.Dialog">
-        <item name="windowAnimationStyle">@style/Animation.VoiceActivity</item>
-        <item name="backgroundDimEnabled">false</item>
-    </style>
-
-    <!-- Quantum light theme for an activity that is to be used for voice interaction.
-         This gives the activity a floating dialog style, to incorporate with the
-         system voice experience. -->
-    <style name="Theme.Quantum.Light.Voice" parent="@style/Theme.Quantum.Light.Dialog">
-        <item name="windowAnimationStyle">@style/Animation.VoiceActivity</item>
-        <item name="backgroundDimEnabled">false</item>
-    </style>
-
-    <!-- Default theme for quantum style input methods, which is used by the
-         {@link android.inputmethodservice.InputMethodService} class.
-         this inherits from Theme.Panel, but sets up IME appropriate animations
-         and a few custom attributes. -->
-    <style name="Theme.Quantum.InputMethod" parent="Theme.Quantum.Light.Panel">
-        <item name="windowAnimationStyle">@style/Animation.InputMethod</item>
-        <item name="imeFullscreenBackground">@drawable/screen_background_selector_light</item>
-        <item name="imeExtractEnterAnimation">@anim/input_method_extract_enter</item>
-        <item name="imeExtractExitAnimation">@anim/input_method_extract_exit</item>
-    </style>
-
-    <!-- Default theme for quantum style voice interaction, which is used by the
-         {@link android.service.voice.VoiceInteractionSession} class.
-         this inherits from Theme.Panel, but sets up appropriate animations
-         and a few custom attributes. -->
-    <style name="Theme.Quantum.VoiceInteractionSession" parent="Theme.Quantum.Light.Panel">
-        <item name="windowAnimationStyle">@style/Animation.VoiceInteractionSession</item>
-    </style>
-
-    <!-- Theme for the search input bar. -->
-
-    <style name="Theme.Quantum.SearchBar" parent="Theme.Quantum.Panel">
-        <item name="actionModeBackground">@drawable/cab_background_top_holo_dark</item>
-        <item name="actionModeSplitBackground">@drawable/cab_background_bottom_holo_light</item>
-    </style>
-
-    <style name="Theme.Quantum.Light.SearchBar" parent="Theme.Quantum.Light.Panel">
-        <item name="actionModeBackground">@drawable/cab_background_top_holo_light</item>
-        <item name="actionModeSplitBackground">@drawable/cab_background_bottom_holo_light</item>
-    </style>
-
-    <!-- Menu Themes -->
-    <eat-comment />
-
-    <style name="Theme.Quantum.CompactMenu">
-        <!-- Menu/item attributes -->
-        <item name="itemTextAppearance">?attr/textAppearanceMedium</item>
-        <item name="listViewStyle">@style/Widget.Quantum.ListView</item>
-        <item name="windowAnimationStyle">@style/Animation.DropDownUp</item>
-        <item name="background">@null</item>
-    </style>
-
-    <style name="Theme.Quantum.Light.CompactMenu">
-        <!-- Menu/item attributes -->
-        <item name="itemTextAppearance">?attr/textAppearanceMedium</item>
-        <item name="listViewStyle">@style/Widget.Quantum.Light.ListView</item>
-        <item name="windowAnimationStyle">@style/Animation.DropDownUp</item>
-        <item name="background">@null</item>
-    </style>
-
-    <!-- Dialog themes for Quantum -->
-    <eat-comment />
-
-    <!-- Quantum theme for dialog windows and activities, which is used by the
-         {@link android.app.Dialog} class.  This changes the window to be
-         floating (not fill the entire screen), and puts a frame around its
-         contents.  You can set this theme on an activity if you would like to
-         make an activity that looks like a Dialog. -->
-    <style name="Theme.Quantum.Dialog">
-        <item name="windowFrame">@null</item>
-        <item name="windowTitleStyle">@style/DialogWindowTitle.Quantum</item>
-        <item name="windowBackground">@drawable/dialog_background_quantum</item>
-        <item name="windowIsFloating">true</item>
-        <item name="windowContentOverlay">@null</item>
-        <item name="windowAnimationStyle">@style/Animation.Quantum.Dialog</item>
-        <item name="windowSoftInputMode">stateUnspecified|adjustPan</item>
-        <item name="windowActionBar">false</item>
-        <item name="windowActionModeOverlay">true</item>
-        <item name="windowCloseOnTouchOutside">@bool/config_closeDialogWhenTouchOutside</item>
-
-        <item name="colorBackgroundCacheHint">@null</item>
-
-        <item name="buttonBarStyle">@style/Widget.Quantum.ButtonBar.AlertDialog</item>
-        <item name="borderlessButtonStyle">@style/Widget.Quantum.Button.Borderless</item>
-
-        <item name="textAppearance">@style/TextAppearance.Quantum</item>
-        <item name="textAppearanceInverse">@style/TextAppearance.Quantum.Inverse</item>
-
-        <item name="listPreferredItemPaddingLeft">16dip</item>
-        <item name="listPreferredItemPaddingRight">16dip</item>
-        <item name="listPreferredItemPaddingStart">16dip</item>
-        <item name="listPreferredItemPaddingEnd">16dip</item>
-
-        <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
-    </style>
-
-    <!-- Variant of Theme.Quantum.Dialog that has a nice minimum width for
-         a regular dialog. -->
-    <style name="Theme.Quantum.Dialog.MinWidth">
-        <item name="windowMinWidthMajor">@dimen/dialog_min_width_major</item>
-        <item name="windowMinWidthMinor">@dimen/dialog_min_width_minor</item>
-    </style>
-
-    <!-- Variant of Theme.Quantum.Dialog that does not include a title bar. -->
-    <style name="Theme.Quantum.Dialog.NoActionBar">
-        <item name="windowActionBar">false</item>
-        <item name="windowNoTitle">true</item>
-    </style>
-
-    <!-- Variant of Theme.Quantum.Dialog.NoActionBar that has a nice minimum width for
-         a regular dialog. -->
-    <style name="Theme.Quantum.Dialog.NoActionBar.MinWidth">
-        <item name="windowMinWidthMajor">@dimen/dialog_min_width_major</item>
-        <item name="windowMinWidthMinor">@dimen/dialog_min_width_minor</item>
-    </style>
-
-    <!-- Variant of Theme.Quantum.Dialog that has a fixed size. -->
-    <style name="Theme.Quantum.Dialog.FixedSize">
-        <item name="windowFixedWidthMajor">@dimen/dialog_fixed_width_major</item>
-        <item name="windowFixedWidthMinor">@dimen/dialog_fixed_width_minor</item>
-        <item name="windowFixedHeightMajor">@dimen/dialog_fixed_height_major</item>
-        <item name="windowFixedHeightMinor">@dimen/dialog_fixed_height_minor</item>
-    </style>
-
-    <!-- Variant of Theme.Quantum.Dialog.NoActionBar that has a fixed size. -->
-    <style name="Theme.Quantum.Dialog.NoActionBar.FixedSize">
-        <item name="windowFixedWidthMajor">@dimen/dialog_fixed_width_major</item>
-        <item name="windowFixedWidthMinor">@dimen/dialog_fixed_width_minor</item>
-        <item name="windowFixedHeightMajor">@dimen/dialog_fixed_height_major</item>
-        <item name="windowFixedHeightMinor">@dimen/dialog_fixed_height_minor</item>
-    </style>
-
-    <!-- Variant of Theme.Quantum.Dialog that does not include a frame (or background).
-         The view hierarchy of the dialog is responsible for drawing all of
-         its pixels. -->
-    <style name="Theme.Quantum.Dialog.NoFrame">
-        <item name="windowBackground">@color/transparent</item>
-        <item name="windowAnimationStyle">@null</item>
-        <item name="backgroundDimEnabled">false</item>
-        <item name="windowIsTranslucent">true</item>
-        <item name="windowNoTitle">true</item>
-        <item name="windowCloseOnTouchOutside">false</item>
-    </style>
-
-    <!-- Quantum theme for alert dialog windows, which is used by the
-         {@link android.app.AlertDialog} class.  This is basically a dialog
-         but sets the background to empty so it can do two-tone backgrounds.
-         For applications targeting Honeycomb or newer, this is the default
-         AlertDialog theme. -->
-    <style name="Theme.Quantum.Dialog.Alert">
-        <item name="windowBackground">@color/transparent</item>
-        <item name="windowTitleStyle">@style/DialogWindowTitle.Quantum</item>
-        <item name="windowMinWidthMajor">@dimen/dialog_min_width_major</item>
-        <item name="windowMinWidthMinor">@dimen/dialog_min_width_minor</item>
-    </style>
-
-    <!-- Quantum theme for the TimePicker dialog windows, which is used by the
-         {@link android.app.TimePickerDialog} class. -->
-    <style name="Theme.Quantum.Dialog.TimePicker">
-        <item name="windowBackground">@color/transparent</item>
-        <item name="windowTitleStyle">@style/DialogWindowTitle.Quantum</item>
-        <item name="windowContentOverlay">@null</item>
-    </style>
-
-    <!-- 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.Quantum.DialogWhenLarge" parent="@style/Theme.Quantum">
-    </style>
-
-    <!-- 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.Quantum.DialogWhenLarge.NoActionBar" parent="@style/Theme.Quantum.NoActionBar">
-    </style>
-
-    <!-- Theme for a presentation window on a secondary display. -->
-    <style name="Theme.Quantum.Dialog.Presentation" parent="@style/Theme.Quantum.NoActionBar.Fullscreen">
-    </style>
-
-    <!-- Light quantum dialog themes -->
-
-    <!-- Quantum light theme for dialog windows and activities, which is used by the
-         {@link android.app.Dialog} class.  This changes the window to be
-         floating (not fill the entire screen), and puts a frame around its
-         contents.  You can set this theme on an activity if you would like to
-         make an activity that looks like a Dialog. -->
-    <style name="Theme.Quantum.Light.Dialog">
-        <item name="windowFrame">@null</item>
-        <item name="windowTitleStyle">@style/DialogWindowTitle.Quantum.Light</item>
-        <item name="windowBackground">?attr/colorBackground</item>
-        <item name="windowIsFloating">true</item>
-        <item name="windowContentOverlay">@null</item>
-        <item name="windowAnimationStyle">@style/Animation.Quantum.Dialog</item>
-        <item name="windowSoftInputMode">stateUnspecified|adjustPan</item>
-        <item name="windowActionBar">false</item>
-        <item name="windowActionModeOverlay">true</item>
-        <item name="windowCloseOnTouchOutside">@bool/config_closeDialogWhenTouchOutside</item>
-
-        <item name="colorBackgroundCacheHint">@null</item>
-
-        <item name="buttonBarStyle">@style/Widget.Quantum.Light.ButtonBar.AlertDialog</item>
-        <item name="borderlessButtonStyle">@style/Widget.Quantum.Light.Button.Borderless</item>
-
-        <item name="textAppearance">@style/TextAppearance.Quantum</item>
-        <item name="textAppearanceInverse">@style/TextAppearance.Quantum.Inverse</item>
-
-        <item name="listPreferredItemPaddingLeft">16dip</item>
-        <item name="listPreferredItemPaddingRight">16dip</item>
-        <item name="listPreferredItemPaddingStart">16dip</item>
-        <item name="listPreferredItemPaddingEnd">16dip</item>
-
-        <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
-    </style>
-
-    <!-- Variant of Theme.Quantum.Light.Dialog that has a nice minimum width for
-         a regular dialog. -->
-    <style name="Theme.Quantum.Light.Dialog.MinWidth">
-        <item name="windowMinWidthMajor">@dimen/dialog_min_width_major</item>
-        <item name="windowMinWidthMinor">@dimen/dialog_min_width_minor</item>
-    </style>
-
-    <!-- Variant of Theme.Quantum.Light.Dialog that does not include a title bar. -->
-    <style name="Theme.Quantum.Light.Dialog.NoActionBar">
-        <item name="windowActionBar">false</item>
-        <item name="windowNoTitle">true</item>
-    </style>
-
-    <!-- Variant of Theme.Quantum.Light.Dialog.NoActionBar that has a nice minimum width for
-         a regular dialog. -->
-    <style name="Theme.Quantum.Light.Dialog.NoActionBar.MinWidth">
-        <item name="windowMinWidthMajor">@dimen/dialog_min_width_major</item>
-        <item name="windowMinWidthMinor">@dimen/dialog_min_width_minor</item>
-    </style>
-
-    <!-- Variant of Theme.Quantum.Light.Dialog that has a fixed size. -->
-    <style name="Theme.Quantum.Light.Dialog.FixedSize">
-        <item name="windowFixedWidthMajor">@dimen/dialog_fixed_width_major</item>
-        <item name="windowFixedWidthMinor">@dimen/dialog_fixed_width_minor</item>
-        <item name="windowFixedHeightMajor">@dimen/dialog_fixed_height_major</item>
-        <item name="windowFixedHeightMinor">@dimen/dialog_fixed_height_minor</item>
-    </style>
-
-    <!-- Variant of Theme.Quantum.Light.Dialog.NoActionBar that has a fixed size. -->
-    <style name="Theme.Quantum.Light.Dialog.NoActionBar.FixedSize">
-        <item name="windowFixedWidthMajor">@dimen/dialog_fixed_width_major</item>
-        <item name="windowFixedWidthMinor">@dimen/dialog_fixed_width_minor</item>
-        <item name="windowFixedHeightMajor">@dimen/dialog_fixed_height_major</item>
-        <item name="windowFixedHeightMinor">@dimen/dialog_fixed_height_minor</item>
-    </style>
-
-    <!-- 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.Quantum.Light.DialogWhenLarge" parent="@style/Theme.Quantum.Light">
-    </style>
-
-    <!-- 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.Quantum.Light.DialogWhenLarge.NoActionBar"
-            parent="@style/Theme.Quantum.Light.NoActionBar">
-    </style>
-
-    <!-- Quantum light theme for alert dialog windows, which is used by the
-         {@link android.app.AlertDialog} class.  This is basically a dialog
-         but sets the background to empty so it can do two-tone backgrounds.
-         For applications targeting Honeycomb or newer, this is the default
-         AlertDialog theme. -->
-    <style name="Theme.Quantum.Light.Dialog.Alert">
-        <item name="windowBackground">@color/transparent</item>
-        <item name="windowTitleStyle">@style/DialogWindowTitle.Quantum.Light</item>
-        <item name="windowMinWidthMajor">@dimen/dialog_min_width_major</item>
-        <item name="windowMinWidthMinor">@dimen/dialog_min_width_minor</item>
-    </style>
-
-    <!-- Quantum Light theme for the TimePicker dialog windows, which is used by the
-         {@link android.app.TimePickerDialog} class. -->
-    <style name="Theme.Quantum.Light.Dialog.TimePicker">
-        <item name="windowBackground">@color/transparent</item>
-        <item name="windowTitleStyle">@style/DialogWindowTitle.Quantum.Light</item>
-    </style>
-
-    <!-- Theme for a presentation window on a secondary display. -->
-    <style name="Theme.Quantum.Light.Dialog.Presentation" parent="@style/Theme.Quantum.Light.NoActionBar.Fullscreen" >
-    </style>
-
-    <!-- Default quantum (dark) for windows that want to have the user's selected
-         wallpaper appear behind them.  -->
-    <style name="Theme.Quantum.Wallpaper">
-        <item name="windowBackground">@color/transparent</item>
-        <item name="colorBackgroundCacheHint">@null</item>
-        <item name="windowShowWallpaper">true</item>
-    </style>
-
-    <!--Default quantum (dark) for windows that want to have the user's selected
-         wallpaper appear behind them and without an action bar. -->
-    <style name="Theme.Quantum.Wallpaper.NoTitleBar">
-        <item name="windowNoTitle">true</item>
-    </style>
-
-</resources>
diff --git a/data/fonts/Roboto-MediumItalic.ttf b/data/fonts/Roboto-MediumItalic.ttf
index a30aa0c..b828205 100644
--- a/data/fonts/Roboto-MediumItalic.ttf
+++ b/data/fonts/Roboto-MediumItalic.ttf
Binary files differ
diff --git a/docs/html/about/dashboards/index.jd b/docs/html/about/dashboards/index.jd
index c61a94b..32b9c9e 100644
--- a/docs/html/about/dashboards/index.jd
+++ b/docs/html/about/dashboards/index.jd
@@ -64,7 +64,7 @@
 </div>
 
 
-<p style="clear:both"><em>Data collected during a 7-day period ending on May 1, 2014.
+<p style="clear:both"><em>Data collected during a 7-day period ending on June 4, 2014.
 <br/>Any versions with less than 0.1% distribution are not shown.</em>
 </p>
 
@@ -95,7 +95,7 @@
 </div>
 
 
-<p style="clear:both"><em>Data collected during a 7-day period ending on May 1, 2014.
+<p style="clear:both"><em>Data collected during a 7-day period ending on June 4, 2014.
 <br/>Any screen configurations with less than 0.1% distribution are not shown.</em></p>
 
 
@@ -114,7 +114,7 @@
 
 
 <img alt="" style="float:right"
-src="//chart.googleapis.com/chart?chs=400x250&cht=p&chd=t%3A0.1%2C87.0%2C12.9&chf=bg%2Cs%2C00000000&chl=GL%201.1%20only%7CGL%202.0%7CGL%203.0&chco=c4df9b%2C6fad0c" />
+src="//chart.googleapis.com/chart?chs=400x250&cht=p&chd=t%3A0.1%2C83.6%2C16.3&chf=bg%2Cs%2C00000000&chl=GL%201.1%20only%7CGL%202.0%7CGL%203.0&chco=c4df9b%2C6fad0c" />
 
 <p>To declare which version of OpenGL ES your application requires, you should use the {@code
 android:glEsVersion} attribute of the <a
@@ -136,17 +136,17 @@
 </tr>
 <tr>
 <td>2.0</th>
-<td>87.0%</td>
+<td>83.6%</td>
 </tr>
 <tr>
 <td>3.0</th>
-<td>12.9%</td>
+<td>16.3%</td>
 </tr>
 </table>
 
 
 
-<p style="clear:both"><em>Data collected during a 7-day period ending on May 1, 2014</em></p>
+<p style="clear:both"><em>Data collected during a 7-day period ending on June 4, 2014</em></p>
 
 
 
@@ -164,47 +164,42 @@
 var VERSION_DATA =
 [
   {
-    "chart": "//chart.googleapis.com/chart?chs=500x250&cht=p&chd=t%3A1.0%2C16.2%2C0.1%2C13.4%2C60.8%2C8.5&chf=bg%2Cs%2C00000000&chl=Froyo%7CGingerbread%7CHoneycomb%7CIce%20Cream%20Sandwich%7CJelly%20Bean%7CKitKat&chco=c4df9b%2C6fad0c",
+    "chart": "//chart.googleapis.com/chart?chl=Froyo%7CGingerbread%7CIce%20Cream%20Sandwich%7CJelly%20Bean%7CKitKat&chf=bg%2Cs%2C00000000&chd=t%3A0.8%2C14.9%2C12.3%2C58.4%2C13.6&chco=c4df9b%2C6fad0c&cht=p&chs=500x250",
     "data": [
       {
         "api": 8,
         "name": "Froyo",
-        "perc": "1.0"
+        "perc": "0.8"
       },
       {
         "api": 10,
         "name": "Gingerbread",
-        "perc": "16.2"
-      },
-      {
-        "api": 13,
-        "name": "Honeycomb",
-        "perc": "0.1"
+        "perc": "14.9"
       },
       {
         "api": 15,
         "name": "Ice Cream Sandwich",
-        "perc": "13.4"
+        "perc": "12.3"
       },
       {
         "api": 16,
         "name": "Jelly Bean",
-        "perc": "33.5"
+        "perc": "29.0"
       },
       {
         "api": 17,
         "name": "Jelly Bean",
-        "perc": "18.8"
+        "perc": "19.1"
       },
       {
         "api": 18,
         "name": "Jelly Bean",
-        "perc": "8.5"
+        "perc": "10.3"
       },
       {
         "api": 19,
         "name": "KitKat",
-        "perc": "8.5"
+        "perc": "13.6"
       }
     ]
   }
@@ -226,23 +221,22 @@
         "xhdpi": "0.6"
       },
       "Normal": {
-        "hdpi": "33.9",
-        "mdpi": "12.5",
-        "xhdpi": "19.9",
-        "xxhdpi": "13.5"
+        "hdpi": "34.2",
+        "mdpi": "12.0",
+        "xhdpi": "19.6",
+        "xxhdpi": "14.6"
       },
       "Small": {
-        "ldpi": "7.5"
+        "ldpi": "7.2"
       },
       "Xlarge": {
         "hdpi": "0.3",
-        "ldpi": "0.1",
-        "mdpi": "4.2",
+        "mdpi": "4.0",
         "xhdpi": "0.3"
       }
     },
-    "densitychart": "//chart.googleapis.com/chart?chs=400x250&cht=p&chd=t%3A8.2%2C21.1%2C1.6%2C34.8%2C20.8%2C13.5&chf=bg%2Cs%2C00000000&chl=ldpi%7Cmdpi%7Ctvdpi%7Chdpi%7Cxhdpi%7Cxxhdpi&chco=c4df9b%2C6fad0c",
-    "layoutchart": "//chart.googleapis.com/chart?chs=400x250&cht=p&chd=t%3A4.9%2C7.8%2C80.0%2C7.5&chf=bg%2Cs%2C00000000&chl=Xlarge%7CLarge%7CNormal%7CSmall&chco=c4df9b%2C6fad0c"
+    "densitychart": "//chart.googleapis.com/chart?chl=ldpi%7Cmdpi%7Ctvdpi%7Chdpi%7Cxhdpi%7Cxxhdpi&chf=bg%2Cs%2C00000000&chd=t%3A7.8%2C20.4%2C1.6%2C35.1%2C20.5%2C14.6&chco=c4df9b%2C6fad0c&cht=p&chs=400x250",
+    "layoutchart": "//chart.googleapis.com/chart?chl=Xlarge%7CLarge%7CNormal%7CSmall&chf=bg%2Cs%2C00000000&chd=t%3A4.6%2C7.8%2C80.4%2C7.2&chco=c4df9b%2C6fad0c&cht=p&chs=400x250"
   }
 ];
 
diff --git a/docs/html/google/play-services/setup.jd b/docs/html/google/play-services/setup.jd
index d502e8d..744e191 100644
--- a/docs/html/google/play-services/setup.jd
+++ b/docs/html/google/play-services/setup.jd
@@ -95,7 +95,9 @@
   <li>Open the <code>build.gradle</code> file inside your application module directory. 
       <p class="note"><strong>Note:</strong> Android Studio projects contain a top-level 
       <code>build.gradle</code> file and a <code>build.gradle</code> file for each module. 
-      Be sure to edit the file for your application module.</p></li>
+      Be sure to edit the file for your application module. See
+      <a href="{@docRoot}sdk/installing/studio-build.html">Building Your Project with
+      Gradle</a> for more information about Gradle.</p></li>
   <li>Add a new build rule under <code>dependencies</code> for the latest version of
 <code>play-services</code>. For example:
 <pre class="no-pretty-print">
diff --git a/docs/html/sdk/installing/studio.jd b/docs/html/sdk/installing/studio.jd
index a2c32f0..1b47f7f 100644
--- a/docs/html/sdk/installing/studio.jd
+++ b/docs/html/sdk/installing/studio.jd
@@ -395,7 +395,9 @@
     <p class="note"><strong>Note:</strong> If you previously developed your Android project
     with Eclipse, you should first use the new export feature in the ADT plugin to prepare
     your project with the new Gradle build system. For more information, read
-    <a href="{@docRoot}sdk/installing/migrate.html">Migrating from Eclipse</a>.</p>
+    <a href="{@docRoot}sdk/installing/migrate.html">Migrating from Eclipse</a> and
+    <a href="{@docRoot}sdk/installing/studio-build.html">Building Your Project with
+    Gradle</a>.</p>
   </li>
 </ul>
 
diff --git a/docs/html/tools/sdk/tools-notes.jd b/docs/html/tools/sdk/tools-notes.jd
index 9b06a9d..f490053 100644
--- a/docs/html/tools/sdk/tools-notes.jd
+++ b/docs/html/tools/sdk/tools-notes.jd
@@ -28,6 +28,39 @@
 <div class="toggle-content opened">
   <p><a href="#" onclick="return toggleContent(this)">
     <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img"
+      alt=""/>SDK Tools, Revision 22.6.4</a> <em>(June 2014)</em>
+  </p>
+
+  <div class="toggle-content-toggleme">
+
+    <dl>
+    <dt>Dependencies:</dt>
+
+    <dd>
+      <ul>
+        <li>Android SDK Platform-tools revision 18 or later.</li>
+        <li>If you are developing in Eclipse with ADT, note that this version of SDK Tools is
+          designed for use with ADT 22.6.3 and later. If you haven't already, update your
+        <a href="{@docRoot}tools/sdk/eclipse-adt.html">ADT Plugin</a> to 22.6.3.</li>
+        <li>If you are developing outside Eclipse, you must have
+          <a href="http://ant.apache.org/">Apache Ant</a> 1.8 or later.</li>
+      </ul>
+    </dd>
+
+    <dt>General Notes:</dt>
+    <dd>
+      <ul>
+        <li>Fixed an issue with the x86 emulator that caused Google Maps to crash.
+            (<a href="http://b.android.com/69385">Issue 69385</a>)</li>
+        <li>Fixed minor OpenGL issues.</li>
+      </ul>
+    </dd>
+  </div>
+</div>
+
+<div class="toggle-content closed">
+  <p><a href="#" onclick="return toggleContent(this)">
+    <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img"
       alt=""/>SDK Tools, Revision 22.6.3</a> <em>(April 2014)</em>
   </p>
 
diff --git a/docs/html/training/contacts-provider/retrieve-names.jd b/docs/html/training/contacts-provider/retrieve-names.jd
index b034a6a..7106889a 100644
--- a/docs/html/training/contacts-provider/retrieve-names.jd
+++ b/docs/html/training/contacts-provider/retrieve-names.jd
@@ -102,9 +102,9 @@
 <p>
     To display the search results in a {@link android.widget.ListView}, you need a main layout file
     that defines the entire UI including the {@link android.widget.ListView}, and an item layout
-    file that defines one line of the {@link android.widget.ListView}. For example, you can define
-    the main layout file <code>res/layout/contacts_list_view.xml</code> that contains the
-    following XML:
+    file that defines one line of the {@link android.widget.ListView}. For example, you could create
+    the main layout file <code>res/layout/contacts_list_view.xml</code> with
+    the following XML:
 </p>
 <pre>
 &lt;?xml version="1.0" encoding="utf-8"?&gt;
@@ -250,7 +250,8 @@
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
             Bundle savedInstanceState) {
         // Inflate the fragment layout
-        return inflater.inflate(R.layout.contacts_list_layout, container, false);
+        return inflater.inflate(R.layout.contact_list_fragment,
+            container, false);
     }
 </pre>
 <h3 id="DefineAdapter">Set up the CursorAdapter for the ListView</h3>
@@ -268,7 +269,8 @@
         super.onActivityCreated(savedInstanceState);
         ...
         // Gets the ListView from the View list of the parent activity
-        mContactsList = (ListView) getActivity().findViewById(R.layout.contact_list_view);
+        mContactsList =
+            (ListView) getActivity().findViewById(R.layout.contact_list_view);
         // Gets a CursorAdapter
         mCursorAdapter = new SimpleCursorAdapter(
                 getActivity(),
diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java
index c20502f..bc20ea5 100644
--- a/graphics/java/android/graphics/BitmapFactory.java
+++ b/graphics/java/android/graphics/BitmapFactory.java
@@ -260,7 +260,11 @@
         public boolean inScaled;
 
         /**
-         * If this is set to true, then the resulting bitmap will allocate its
+         * @deprecated As of {@link android.os.Build.VERSION_CODES#L}, this is
+         * ignored.
+         *
+         * In {@link android.os.Build.VERSION_CODES#KITKAT} and below, if this
+         * is set to true, then the resulting bitmap will allocate its
          * pixels such that they can be purged if the system needs to reclaim
          * memory. In that instance, when the pixels need to be accessed again
          * (e.g. the bitmap is drawn, getPixels() is called), they will be
@@ -287,14 +291,20 @@
          * android.graphics.BitmapFactory.Options)} or {@link #decodeFile(String,
          * android.graphics.BitmapFactory.Options)}.</p>
          */
+        @Deprecated
         public boolean inPurgeable;
 
         /**
-         * This field works in conjuction with inPurgeable. If inPurgeable is
-         * false, then this field is ignored. If inPurgeable is true, then this
-         * field determines whether the bitmap can share a reference to the
-         * input data (inputstream, array, etc.) or if it must make a deep copy.
+         * @deprecated As of {@link android.os.Build.VERSION_CODES#L}, this is
+         * ignored.
+         *
+         * In {@link android.os.Build.VERSION_CODES#KITKAT} and below, this
+         * field works in conjuction with inPurgeable. If inPurgeable is false,
+         * then this field is ignored. If inPurgeable is true, then this field
+         * determines whether the bitmap can share a reference to the input
+         * data (inputstream, array, etc.) or if it must make a deep copy.
          */
+        @Deprecated
         public boolean inInputShareable;
 
         /**
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index bd868f2..12877de 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -242,21 +242,27 @@
      *
      * @return true if the device that the current layer draws into is opaque
      */
-    public native boolean isOpaque();
+    public boolean isOpaque() {
+        return native_isOpaque(mNativeCanvasWrapper);
+    }
 
     /**
      * Returns the width of the current drawing layer
      *
      * @return the width of the current drawing layer
      */
-    public native int getWidth();
+    public int getWidth() {
+        return native_getWidth(mNativeCanvasWrapper);
+    }
 
     /**
      * Returns the height of the current drawing layer
      *
      * @return the height of the current drawing layer
      */
-    public native int getHeight();
+    public int getHeight() {
+        return native_getHeight(mNativeCanvasWrapper);
+    }
 
     /**
      * <p>Returns the target density of the canvas.  The default density is
@@ -343,7 +349,9 @@
      *
      * @return The value to pass to restoreToCount() to balance this save()
      */
-    public native int save();
+    public int save() {
+        return native_save(mNativeCanvasWrapper, MATRIX_SAVE_FLAG | CLIP_SAVE_FLAG);
+    }
     
     /**
      * Based on saveFlags, can save the current matrix and clip onto a private
@@ -356,7 +364,9 @@
      *                  to save/restore
      * @return The value to pass to restoreToCount() to balance this save()
      */
-    public native int save(int saveFlags);
+    public int save(int saveFlags) {
+        return native_save(mNativeCanvasWrapper, saveFlags);
+    }
 
     /**
      * This behaves the same as save(), but in addition it allocates an
@@ -375,7 +385,8 @@
      * @return       value to pass to restoreToCount() to balance this save()
      */
     public int saveLayer(RectF bounds, Paint paint, int saveFlags) {
-        return native_saveLayer(mNativeCanvasWrapper, bounds,
+        return native_saveLayer(mNativeCanvasWrapper,
+                bounds.left, bounds.top, bounds.right, bounds.bottom,
                 paint != null ? paint.mNativePaint : 0,
                 saveFlags);
     }
@@ -422,7 +433,9 @@
      */
     public int saveLayerAlpha(RectF bounds, int alpha, int saveFlags) {
         alpha = Math.min(255, Math.max(0, alpha));
-        return native_saveLayerAlpha(mNativeCanvasWrapper, bounds, alpha, saveFlags);
+        return native_saveLayerAlpha(mNativeCanvasWrapper,
+                bounds.left, bounds.top, bounds.right, bounds.bottom,
+                alpha, saveFlags);
     }
 
     /**
@@ -453,13 +466,17 @@
      * modifications to the matrix/clip state since the last save call. It is
      * an error to call restore() more times than save() was called.
      */
-    public native void restore();
+    public void restore() {
+        native_restore(mNativeCanvasWrapper);
+    }
 
     /**
      * Returns the number of matrix/clip states on the Canvas' private stack.
      * This will equal # save() calls - # restore() calls.
      */
-    public native int getSaveCount();
+    public int getSaveCount() {
+        return native_getSaveCount(mNativeCanvasWrapper);
+    }
 
     /**
      * Efficient way to pop any calls to save() that happened after the save
@@ -474,7 +491,9 @@
      *
      * @param saveCount The save level to restore to.
      */
-    public native void restoreToCount(int saveCount);
+    public void restoreToCount(int saveCount) {
+        native_restoreToCount(mNativeCanvasWrapper, saveCount);
+    }
 
     /**
      * Preconcat the current matrix with the specified translation
@@ -482,7 +501,9 @@
      * @param dx The distance to translate in X
      * @param dy The distance to translate in Y
     */
-    public native void translate(float dx, float dy);
+    public void translate(float dx, float dy) {
+        native_translate(mNativeCanvasWrapper, dx, dy);
+    }
 
     /**
      * Preconcat the current matrix with the specified scale.
@@ -490,7 +511,9 @@
      * @param sx The amount to scale in X
      * @param sy The amount to scale in Y
      */
-    public native void scale(float sx, float sy);
+    public void scale(float sx, float sy) {
+        native_scale(mNativeCanvasWrapper, sx, sy);
+    }
 
     /**
      * Preconcat the current matrix with the specified scale.
@@ -511,7 +534,9 @@
      *
      * @param degrees The amount to rotate, in degrees
      */
-    public native void rotate(float degrees);
+    public void rotate(float degrees) {
+        native_rotate(mNativeCanvasWrapper, degrees);
+    }
 
     /**
      * Preconcat the current matrix with the specified rotation.
@@ -532,7 +557,9 @@
      * @param sx The amount to skew in X
      * @param sy The amount to skew in Y
      */
-    public native void skew(float sx, float sy);
+    public void skew(float sx, float sy) {
+        native_skew(mNativeCanvasWrapper, sx, sy);
+    }
 
     /**
      * Preconcat the current matrix with the specified matrix. If the specified
@@ -615,8 +642,11 @@
      * @param rect The rectangle to intersect with the current clip.
      * @return true if the resulting clip is non-empty
      */
-    public native boolean clipRect(RectF rect);
-    
+    public boolean clipRect(RectF rect) {
+        return native_clipRect(mNativeCanvasWrapper, rect.left, rect.top, rect.right, rect.bottom,
+                Region.Op.INTERSECT.nativeInt);
+    }
+
     /**
      * Intersect the current clip with the specified rectangle, which is
      * expressed in local coordinates.
@@ -624,7 +654,10 @@
      * @param rect The rectangle to intersect with the current clip.
      * @return true if the resulting clip is non-empty
      */
-    public native boolean clipRect(Rect rect);
+    public boolean clipRect(Rect rect) {
+        return native_clipRect(mNativeCanvasWrapper, rect.left, rect.top, rect.right, rect.bottom,
+                Region.Op.INTERSECT.nativeInt);
+    }
     
     /**
      * Modify the current clip with the specified rectangle, which is
@@ -658,7 +691,10 @@
      *               clip
      * @return       true if the resulting clip is non-empty
      */
-    public native boolean clipRect(float left, float top, float right, float bottom);
+    public boolean clipRect(float left, float top, float right, float bottom) {
+        return native_clipRect(mNativeCanvasWrapper, left, top, right, bottom,
+                Region.Op.INTERSECT.nativeInt);
+    }
 
     /**
      * Intersect the current clip with the specified rectangle, which is
@@ -673,7 +709,10 @@
      *               clip
      * @return       true if the resulting clip is non-empty
      */
-    public native boolean clipRect(int left, int top, int right, int bottom);
+    public boolean clipRect(int left, int top, int right, int bottom) {
+        return native_clipRect(mNativeCanvasWrapper, left, top, right, bottom,
+                Region.Op.INTERSECT.nativeInt);
+    }
 
     /**
         * Modify the current clip with the specified path.
@@ -780,7 +819,8 @@
      *              does not intersect with the canvas' clip
      */
     public boolean quickReject(RectF rect, EdgeType type) {
-        return native_quickReject(mNativeCanvasWrapper, rect);
+        return native_quickReject(mNativeCanvasWrapper,
+                rect.left, rect.top, rect.right, rect.bottom);
     }
 
     /**
@@ -925,7 +965,9 @@
      *                 "points" that are drawn is really (count >> 1).
      * @param paint    The paint used to draw the points
      */
-    public native void drawPoints(float[] pts, int offset, int count, Paint paint);
+    public void drawPoints(float[] pts, int offset, int count, Paint paint) {
+        native_drawPoints(mNativeCanvasWrapper, pts, offset, count, paint.mNativePaint);
+    }
 
     /**
      * Helper for drawPoints() that assumes you want to draw the entire array
@@ -937,7 +979,9 @@
     /**
      * Helper for drawPoints() for drawing a single point.
      */
-    public native void drawPoint(float x, float y, Paint paint);
+    public void drawPoint(float x, float y, Paint paint) {
+        native_drawPoint(mNativeCanvasWrapper, x, y, paint.mNativePaint);
+    }
 
     /**
      * Draw a line segment with the specified start and stop x,y coordinates,
@@ -970,7 +1014,9 @@
      *                 (count >> 2).
      * @param paint    The paint used to draw the points
      */
-    public native void drawLines(float[] pts, int offset, int count, Paint paint);
+    public void drawLines(float[] pts, int offset, int count, Paint paint) {
+        native_drawLines(mNativeCanvasWrapper, pts, offset, count, paint.mNativePaint);
+    }
 
     public void drawLines(float[] pts, Paint paint) {
         drawLines(pts, 0, pts.length, paint);
@@ -984,7 +1030,8 @@
      * @param paint The paint used to draw the rect
      */
     public void drawRect(RectF rect, Paint paint) {
-        native_drawRect(mNativeCanvasWrapper, rect, paint.mNativePaint);
+        native_drawRect(mNativeCanvasWrapper,
+                rect.left, rect.top, rect.right, rect.bottom, paint.mNativePaint);
     }
 
     /**
@@ -1764,21 +1811,30 @@
     private static native void native_setBitmap(long canvasHandle,
                                                 long bitmapHandle,
                                                 boolean copyState);
-    private static native int native_saveLayer(long nativeCanvas,
-                                               RectF bounds,
-                                               long nativePaint,
-                                               int layerFlags);
+    private static native boolean native_isOpaque(long canvasHandle);
+    private static native int native_getWidth(long canvasHandle);
+    private static native int native_getHeight(long canvasHandle);
+
+    private static native int native_save(long canvasHandle, int saveFlags);
     private static native int native_saveLayer(long nativeCanvas, float l,
                                                float t, float r, float b,
                                                long nativePaint,
                                                int layerFlags);
-    private static native int native_saveLayerAlpha(long nativeCanvas,
-                                                    RectF bounds, int alpha,
-                                                    int layerFlags);
     private static native int native_saveLayerAlpha(long nativeCanvas, float l,
                                                     float t, float r, float b,
                                                     int alpha, int layerFlags);
+    private static native void native_restore(long canvasHandle);
+    private static native void native_restoreToCount(long canvasHandle,
+                                                     int saveCount);
+    private static native int native_getSaveCount(long canvasHandle);
 
+    private static native void native_translate(long canvasHandle,
+                                                float dx, float dy);
+    private static native void native_scale(long canvasHandle,
+                                            float sx, float sy);
+    private static native void native_rotate(long canvasHandle, float degrees);
+    private static native void native_skew(long canvasHandle,
+                                           float sx, float sy);
     private static native void native_concat(long nativeCanvas,
                                              long nativeMatrix);
     private static native void native_setMatrix(long nativeCanvas,
@@ -1800,8 +1856,6 @@
     private static native void native_getCTM(long nativeCanvas,
                                              long nativeMatrix);
     private static native boolean native_quickReject(long nativeCanvas,
-                                                     RectF rect);
-    private static native boolean native_quickReject(long nativeCanvas,
                                                      long nativePath);
     private static native boolean native_quickReject(long nativeCanvas,
                                                      float left, float top,
@@ -1815,11 +1869,17 @@
                                                 int mode);
     private static native void native_drawPaint(long nativeCanvas,
                                                 long nativePaint);
+    private static native void native_drawPoint(long canvasHandle, float x, float y,
+                                                long paintHandle);
+    private static native void native_drawPoints(long canvasHandle, float[] pts,
+                                                 int offset, int count,
+                                                 long paintHandle);
     private static native void native_drawLine(long nativeCanvas, float startX,
                                                float startY, float stopX,
                                                float stopY, long nativePaint);
-    private static native void native_drawRect(long nativeCanvas, RectF rect,
-                                               long nativePaint);
+    private static native void native_drawLines(long canvasHandle, float[] pts,
+                                                int offset, int count,
+                                                long paintHandle);
     private static native void native_drawRect(long nativeCanvas, float left,
                                                float top, float right,
                                                float bottom,
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index 92cfd6b..4268a24 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -2131,7 +2131,7 @@
         if ((index | count) < 0 || index + count > text.length) {
             throw new ArrayIndexOutOfBoundsException();
         }
-        native_getTextPath(mNativePaint, mBidiFlags, text, index, count, x, y, 
+        native_getTextPath(mNativePaint, mNativeTypeface, mBidiFlags, text, index, count, x, y,
                 path.ni());
     }
 
@@ -2153,7 +2153,7 @@
         if ((start | end | (end - start) | (text.length() - end)) < 0) {
             throw new IndexOutOfBoundsException();
         }
-        native_getTextPath(mNativePaint, mBidiFlags, text, start, end, x, y, 
+        native_getTextPath(mNativePaint, mNativeTypeface, mBidiFlags, text, start, end, x, y,
                 path.ni());
     }
     
@@ -2174,7 +2174,7 @@
         if (bounds == null) {
             throw new NullPointerException("need bounds Rect");
         }
-        nativeGetStringBounds(mNativePaint, text, start, end, mBidiFlags, bounds);
+        nativeGetStringBounds(mNativePaint, mNativeTypeface, text, start, end, mBidiFlags, bounds);
     }
     
     /**
@@ -2194,7 +2194,8 @@
         if (bounds == null) {
             throw new NullPointerException("need bounds Rect");
         }
-        nativeGetCharArrayBounds(mNativePaint, text, index, count, mBidiFlags, bounds);
+        nativeGetCharArrayBounds(mNativePaint, mNativeTypeface, text, index, count, mBidiFlags,
+            bounds);
     }
     
     @Override
@@ -2261,13 +2262,13 @@
     private native int native_getTextRunCursor(long native_object, String text,
             int contextStart, int contextEnd, int flags, int offset, int cursorOpt);
 
-    private static native void native_getTextPath(long native_object, int bidiFlags,
-                char[] text, int index, int count, float x, float y, long path);
-    private static native void native_getTextPath(long native_object, int bidiFlags,
-                String text, int start, int end, float x, float y, long path);
-    private static native void nativeGetStringBounds(long nativePaint,
+    private static native void native_getTextPath(long native_object, long native_typeface,
+            int bidiFlags, char[] text, int index, int count, float x, float y, long path);
+    private static native void native_getTextPath(long native_object, long native_typeface,
+            int bidiFlags, String text, int start, int end, float x, float y, long path);
+    private static native void nativeGetStringBounds(long nativePaint, long native_typeface,
                                 String text, int start, int end, int bidiFlags, Rect bounds);
-    private static native void nativeGetCharArrayBounds(long nativePaint,
+    private static native void nativeGetCharArrayBounds(long nativePaint, long native_typeface,
                                 char[] text, int index, int count, int bidiFlags, Rect bounds);
     private static native void finalizer(long nativePaint);
 
diff --git a/graphics/java/android/graphics/drawable/AnimationDrawable.java b/graphics/java/android/graphics/drawable/AnimationDrawable.java
index 0ee253a..16548d0 100644
--- a/graphics/java/android/graphics/drawable/AnimationDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimationDrawable.java
@@ -94,7 +94,7 @@
         boolean changed = super.setVisible(visible, restart);
         if (visible) {
             if (changed || restart) {
-                setFrame(0, true, mCurFrame >= 0);
+                setFrame(0, true, restart || mCurFrame >= 0);
             }
         } else {
             unscheduleSelf(this);
diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java
index c95ac82..ef6c085 100644
--- a/graphics/java/android/graphics/drawable/BitmapDrawable.java
+++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java
@@ -706,10 +706,24 @@
 
         final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.BitmapDrawable);
         updateStateFromTypedArray(a);
+        verifyState(a);
         a.recycle();
     }
 
     /**
+     * Ensures all required attributes are set.
+     *
+     * @throws XmlPullParserException if any required attributes are missing
+     */
+    private void verifyState(TypedArray a) throws XmlPullParserException {
+        final BitmapState state = mBitmapState;
+        if (state.mBitmap == null) {
+            throw new XmlPullParserException(a.getPositionDescription() +
+                    ": <bitmap> requires a valid src attribute");
+        }
+    }
+
+    /**
      * Updates the constant state from the values in the typed array.
      */
     private void updateStateFromTypedArray(TypedArray a) throws XmlPullParserException {
@@ -912,6 +926,7 @@
      */
     private BitmapDrawable(BitmapState state, Resources res, Theme theme) {
         if (theme != null && state.canApplyTheme()) {
+            // If we need to apply a theme, implicitly mutate.
             mBitmapState = new BitmapState(state);
             applyTheme(theme);
         } else {
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index f29b9f0..18e8e52 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -908,7 +908,7 @@
             InputStream is, String srcName) {
         Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, srcName != null ? srcName : "Unknown drawable");
         try {
-            return createFromResourceStream(res, value, is, srcName);
+            return createFromResourceStream(res, value, is, srcName, null);
         } finally {
             Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
         }
@@ -1023,6 +1023,9 @@
             drawable = new StateListDrawable();
         } else if (name.equals("animated-selector")) {
             drawable = new AnimatedStateListDrawable();
+        } else if (name.equals("material-progress")) {
+            // TODO: Replace this with something less ridiculous.
+            drawable = new MaterialProgressDrawable();
         } else if (name.equals("level-list")) {
             drawable = new LevelListDrawable();
         } else if (name.equals("layer-list")) {
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index 1512da5..005b8ef 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -1203,8 +1203,11 @@
 
         st.mAttrStroke = a.extractThemeAttrs();
 
+        // We have an explicit stroke defined, so the default stroke width
+        // must be at least 0 or the current stroke width.
+        final int defaultStrokeWidth = Math.max(0, st.mStrokeWidth);
         final int width = a.getDimensionPixelSize(
-                R.styleable.GradientDrawableStroke_width, st.mStrokeWidth);
+                R.styleable.GradientDrawableStroke_width, defaultStrokeWidth);
         final float dashWidth = a.getDimension(
                 R.styleable.GradientDrawableStroke_dashWidth, st.mStrokeDashWidth);
 
@@ -1406,10 +1409,13 @@
                 outline.setOval(bounds);
                 return true;
             case LINE:
-                float halfStrokeWidth = mStrokePaint.getStrokeWidth() * 0.5f;
-                float centerY = bounds.centerY();
-                int top = (int) Math.floor(centerY - halfStrokeWidth);
-                int bottom = (int) Math.ceil(centerY + halfStrokeWidth);
+                // Hairlines (0-width stroke) must have a non-empty outline for
+                // shadows to draw correctly, so we'll use a very small width.
+                final float halfStrokeWidth = mStrokePaint == null ?
+                        0.0001f : mStrokePaint.getStrokeWidth() * 0.5f;
+                final float centerY = bounds.centerY();
+                final int top = (int) Math.floor(centerY - halfStrokeWidth);
+                final int bottom = (int) Math.ceil(centerY + halfStrokeWidth);
 
                 outline.setRect(bounds.left, top, bounds.right, bottom);
                 return true;
@@ -1656,9 +1662,12 @@
      * @param theme Theme to apply to the drawable
      */
     private GradientDrawable(GradientState state, Theme theme) {
-        mGradientState = new GradientState(state);
         if (theme != null && state.canApplyTheme()) {
+            // If we need to apply a theme, implicitly mutate.
+            mGradientState = new GradientState(state);
             applyTheme(theme);
+        } else {
+            mGradientState = state;
         }
 
         initializeWithState(state);
diff --git a/graphics/java/android/graphics/drawable/MaterialProgressDrawable.java b/graphics/java/android/graphics/drawable/MaterialProgressDrawable.java
new file mode 100644
index 0000000..9e56f67
--- /dev/null
+++ b/graphics/java/android/graphics/drawable/MaterialProgressDrawable.java
@@ -0,0 +1,520 @@
+/*
+ * 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.graphics.drawable;
+
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
+import android.animation.TimeInterpolator;
+import android.content.res.ColorStateList;
+import android.content.res.Resources;
+import android.content.res.Resources.Theme;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.Paint.Cap;
+import android.graphics.Paint.Style;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.util.AttributeSet;
+import android.view.animation.AccelerateDecelerateInterpolator;
+import android.view.animation.LinearInterpolator;
+
+import com.android.internal.R;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+/**
+ * Fancy progress indicator for Material theme.
+ *
+ * TODO: Replace this class with something less ridiculous.
+ */
+class MaterialProgressDrawable extends Drawable implements Animatable {
+    private static final TimeInterpolator LINEAR_INTERPOLATOR = new LinearInterpolator();
+    private static final TimeInterpolator END_CURVE_INTERPOLATOR = new EndCurveInterpolator();
+    private static final TimeInterpolator START_CURVE_INTERPOLATOR = new StartCurveInterpolator();
+
+    /** The duration of a single progress spin in milliseconds. */
+    private static final int ANIMATION_DURATION = 1000 * 80 / 60;
+
+    /** The number of points in the progress "star". */
+    private static final int NUM_POINTS = 5;
+
+    /** The list of animators operating on this drawable. */
+    private final ArrayList<Animator> mAnimators = new ArrayList<Animator>();
+
+    /** The indicator ring, used to manage animation state. */
+    private final Ring mRing;
+
+    private MaterialProgressState mState;
+
+    /** Canvas rotation in degrees. */
+    private float mRotation;
+
+    private boolean mMutated;
+
+    public MaterialProgressDrawable() {
+        this(new MaterialProgressState(null), null);
+    }
+
+    private MaterialProgressDrawable(MaterialProgressState state, Theme theme) {
+        mState = state;
+        if (theme != null && state.canApplyTheme()) {
+            applyTheme(theme);
+        }
+
+        mRing = new Ring(mCallback);
+        mMutated = false;
+
+        initializeFromState();
+        setupAnimators();
+    }
+
+    private void initializeFromState() {
+        final MaterialProgressState state = mState;
+
+        final Ring ring = mRing;
+        ring.setStrokeWidth(state.mStrokeWidth);
+
+        final int color = state.mColor.getColorForState(getState(), Color.TRANSPARENT);
+        ring.setColor(color);
+
+        final float minEdge = Math.min(state.mWidth, state.mHeight);
+        if (state.mInnerRadius <= 0 || minEdge < 0) {
+            ring.setInsets((int) Math.ceil(state.mStrokeWidth / 2.0f));
+        } else {
+            float insets = minEdge / 2.0f - state.mInnerRadius;
+            ring.setInsets(insets);
+        }
+    }
+
+    @Override
+    public Drawable mutate() {
+        if (!mMutated && super.mutate() == this) {
+            mState = new MaterialProgressState(mState);
+            mMutated = true;
+        }
+        return this;
+    }
+
+    @Override
+    protected boolean onStateChange(int[] state) {
+        boolean changed = super.onStateChange(state);
+
+        final int color = mState.mColor.getColorForState(state, Color.TRANSPARENT);
+        if (color != mRing.getColor()) {
+            mRing.setColor(color);
+            changed = true;
+        }
+
+        return changed;
+    }
+
+    @Override
+    public boolean isStateful() {
+        return super.isStateful() || mState.mColor.isStateful();
+    }
+
+    @Override
+    public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme)
+            throws XmlPullParserException, IOException {
+        final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.MaterialProgressDrawable);
+        super.inflateWithAttributes(r, parser, a, R.styleable.MaterialProgressDrawable_visible);
+        updateStateFromTypedArray(a);
+        a.recycle();
+
+        initializeFromState();
+    }
+
+    @Override
+    public void applyTheme(Theme t) {
+        final TypedArray a = t.resolveAttributes(mState.mThemeAttrs,
+                R.styleable.MaterialProgressDrawable);
+        updateStateFromTypedArray(a);
+        a.recycle();
+    }
+
+    private void updateStateFromTypedArray(TypedArray a) {
+        final MaterialProgressState state = mState;
+        state.mThemeAttrs = a.extractThemeAttrs();
+        state.mWidth = a.getDimensionPixelSize(
+                R.styleable.MaterialProgressDrawable_width, state.mWidth);
+        state.mHeight = a.getDimensionPixelSize(
+                R.styleable.MaterialProgressDrawable_height, state.mHeight);
+        state.mInnerRadius = a.getDimension(
+                R.styleable.MaterialProgressDrawable_innerRadius, state.mInnerRadius);
+        state.mStrokeWidth = a.getDimension(
+                R.styleable.MaterialProgressDrawable_thickness, state.mStrokeWidth);
+
+        if (a.hasValue(R.styleable.MaterialProgressDrawable_color)) {
+            state.mColor = a.getColorStateList(R.styleable.MaterialProgressDrawable_color);
+        }
+    }
+
+    @Override
+    public boolean setVisible(boolean visible, boolean restart) {
+        boolean changed = super.setVisible(visible, restart);
+        if (visible) {
+            if (changed || restart) {
+                start();
+            }
+        } else {
+            stop();
+        }
+        return changed;
+    }
+
+    @Override
+    public int getIntrinsicHeight() {
+        return mState.mHeight;
+    }
+
+    @Override
+    public int getIntrinsicWidth() {
+        return mState.mWidth;
+    }
+
+    @Override
+    public void draw(Canvas c) {
+        final Rect bounds = getBounds();
+        final int saveCount = c.save();
+        c.rotate(mRotation, bounds.exactCenterX(), bounds.exactCenterY());
+        mRing.draw(c, bounds);
+        c.restoreToCount(saveCount);
+    }
+
+    @Override
+    public void setAlpha(int alpha) {
+        mRing.setAlpha(alpha);
+    }
+
+    @Override
+    public int getAlpha() {
+        return mRing.getAlpha();
+    }
+
+    @Override
+    public void setColorFilter(ColorFilter colorFilter) {
+        mRing.setColorFilter(colorFilter);
+    }
+
+    @Override
+    public ColorFilter getColorFilter() {
+        return mRing.getColorFilter();
+    }
+
+    private void setRotation(float rotation) {
+        mRotation = rotation;
+        invalidateSelf();
+    }
+
+    private float getRotation() {
+        return mRotation;
+    }
+
+    @Override
+    public int getOpacity() {
+        return PixelFormat.TRANSLUCENT;
+    }
+
+    @Override
+    public boolean isRunning() {
+        final ArrayList<Animator> animators = mAnimators;
+        final int N = animators.size();
+        for (int i = 0; i < N; i++) {
+            final Animator animator = animators.get(i);
+            if (animator.isRunning()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public void start() {
+        final ArrayList<Animator> animators = mAnimators;
+        final int N = animators.size();
+        for (int i = 0; i < N; i++) {
+            final Animator animator = animators.get(i);
+            if (animator.isPaused()) {
+                animator.resume();
+            } else if (!animator.isRunning()){
+                animator.start();
+            }
+        }
+    }
+
+    @Override
+    public void stop() {
+        final ArrayList<Animator> animators = mAnimators;
+        final int N = animators.size();
+        for (int i = 0; i < N; i++) {
+            final Animator animator = animators.get(i);
+            animator.pause();
+        }
+    }
+
+    private void setupAnimators() {
+        final Ring ring = mRing;
+
+        final ObjectAnimator endTrim = ObjectAnimator.ofFloat(ring, "endTrim", 0, 0.75f);
+        endTrim.setDuration(ANIMATION_DURATION);
+        endTrim.setInterpolator(START_CURVE_INTERPOLATOR);
+        endTrim.setRepeatCount(ObjectAnimator.INFINITE);
+        endTrim.setRepeatMode(ObjectAnimator.RESTART);
+
+        final ObjectAnimator startTrim = ObjectAnimator.ofFloat(ring, "startTrim", 0.0f, 0.75f);
+        startTrim.setDuration(ANIMATION_DURATION);
+        startTrim.setInterpolator(END_CURVE_INTERPOLATOR);
+        startTrim.setRepeatCount(ObjectAnimator.INFINITE);
+        startTrim.setRepeatMode(ObjectAnimator.RESTART);
+
+        final ObjectAnimator rotation = ObjectAnimator.ofFloat(ring, "rotation", 0.0f, 0.25f);
+        rotation.setDuration(ANIMATION_DURATION);
+        rotation.setInterpolator(LINEAR_INTERPOLATOR);
+        rotation.setRepeatCount(ObjectAnimator.INFINITE);
+        rotation.setRepeatMode(ObjectAnimator.RESTART);
+
+        final ObjectAnimator groupRotation = ObjectAnimator.ofFloat(this, "rotation", 0.0f, 360.0f);
+        groupRotation.setDuration(NUM_POINTS * ANIMATION_DURATION);
+        groupRotation.setInterpolator(LINEAR_INTERPOLATOR);
+        groupRotation.setRepeatCount(ObjectAnimator.INFINITE);
+        groupRotation.setRepeatMode(ObjectAnimator.RESTART);
+
+        mAnimators.add(endTrim);
+        mAnimators.add(startTrim);
+        mAnimators.add(rotation);
+        mAnimators.add(groupRotation);
+    }
+
+    private final Callback mCallback = new Callback() {
+        @Override
+        public void invalidateDrawable(Drawable d) {
+            invalidateSelf();
+        }
+
+        @Override
+        public void scheduleDrawable(Drawable d, Runnable what, long when) {
+            scheduleSelf(what, when);
+        }
+
+        @Override
+        public void unscheduleDrawable(Drawable d, Runnable what) {
+            unscheduleSelf(what);
+        }
+    };
+
+    private static class MaterialProgressState extends ConstantState {
+        private int[] mThemeAttrs = null;
+        private float mStrokeWidth = 5.0f;
+        private float mInnerRadius = -1.0f;
+        private int mWidth = -1;
+        private int mHeight = -1;
+        private ColorStateList mColor = ColorStateList.valueOf(Color.TRANSPARENT);
+
+        public MaterialProgressState(MaterialProgressState orig) {
+            if (orig != null) {
+                mThemeAttrs = orig.mThemeAttrs;
+                mStrokeWidth = orig.mStrokeWidth;
+                mInnerRadius = orig.mInnerRadius;
+                mWidth = orig.mWidth;
+                mHeight = orig.mHeight;
+                mColor = orig.mColor;
+            }
+        }
+
+        @Override
+        public boolean canApplyTheme() {
+            return mThemeAttrs != null;
+        }
+
+        @Override
+        public Drawable newDrawable() {
+            return newDrawable(null, null);
+        }
+
+        @Override
+        public Drawable newDrawable(Resources res) {
+            return newDrawable(res, null);
+        }
+
+        @Override
+        public Drawable newDrawable(Resources res, Theme theme) {
+            return new MaterialProgressDrawable(this, theme);
+        }
+
+        @Override
+        public int getChangingConfigurations() {
+            return 0;
+        }
+    }
+
+    private static class Ring {
+        private final RectF mTempBounds = new RectF();
+        private final Paint mPaint = new Paint();
+
+        private final Callback mCallback;
+
+        private float mStartTrim = 0.0f;
+        private float mEndTrim = 0.0f;
+        private float mRotation = 0.0f;
+        private float mStrokeWidth = 5.0f;
+        private float mStrokeInset = 2.5f;
+
+        private int mAlpha = 0xFF;
+        private int mColor = Color.BLACK;
+
+        public Ring(Callback callback) {
+            mCallback = callback;
+
+            mPaint.setStrokeCap(Cap.ROUND);
+            mPaint.setAntiAlias(true);
+            mPaint.setStyle(Style.STROKE);
+        }
+
+        public void draw(Canvas c, Rect bounds) {
+            final RectF arcBounds = mTempBounds;
+            arcBounds.set(bounds);
+            arcBounds.inset(mStrokeInset, mStrokeInset);
+
+            final float startAngle = (mStartTrim + mRotation) * 360;
+            final float endAngle = (mEndTrim + mRotation) * 360;
+            float sweepAngle = endAngle - startAngle;
+
+            // Ensure the sweep angle isn't too small to draw.
+            final float diameter = Math.min(arcBounds.width(), arcBounds.height());
+            final float minAngle = (float) (360.0 / (diameter * Math.PI));
+            if (sweepAngle < minAngle && sweepAngle > -minAngle) {
+                sweepAngle = Math.signum(sweepAngle) * minAngle;
+            }
+
+            c.drawArc(arcBounds, startAngle, sweepAngle, false, mPaint);
+        }
+
+        public void setColorFilter(ColorFilter filter) {
+            mPaint.setColorFilter(filter);
+            invalidateSelf();
+        }
+
+        public ColorFilter getColorFilter() {
+            return mPaint.getColorFilter();
+        }
+
+        public void setAlpha(int alpha) {
+            mAlpha = alpha;
+            mPaint.setColor(mColor & 0xFFFFFF | alpha << 24);
+            invalidateSelf();
+        }
+
+        public int getAlpha() {
+            return mAlpha;
+        }
+
+        public void setColor(int color) {
+            mColor = color;
+            mPaint.setColor(color & 0xFFFFFF | mAlpha << 24);
+            invalidateSelf();
+        }
+
+        public int getColor() {
+            return mColor;
+        }
+
+        public void setStrokeWidth(float strokeWidth) {
+            mStrokeWidth = strokeWidth;
+            mPaint.setStrokeWidth(strokeWidth);
+            invalidateSelf();
+        }
+
+        @SuppressWarnings("unused")
+        public float getStrokeWidth() {
+            return mStrokeWidth;
+        }
+
+        @SuppressWarnings("unused")
+        public void setStartTrim(float startTrim) {
+            mStartTrim = startTrim;
+            invalidateSelf();
+        }
+
+        @SuppressWarnings("unused")
+        public float getStartTrim() {
+            return mStartTrim;
+        }
+
+        @SuppressWarnings("unused")
+        public void setEndTrim(float endTrim) {
+            mEndTrim = endTrim;
+            invalidateSelf();
+        }
+
+        @SuppressWarnings("unused")
+        public float getEndTrim() {
+            return mEndTrim;
+        }
+
+        @SuppressWarnings("unused")
+        public void setRotation(float rotation) {
+            mRotation = rotation;
+            invalidateSelf();
+        }
+
+        @SuppressWarnings("unused")
+        public float getRotation() {
+            return mRotation;
+        }
+
+        public void setInsets(float insets) {
+            mStrokeInset = insets;
+        }
+
+        @SuppressWarnings("unused")
+        public float getInsets() {
+            return mStrokeInset;
+        }
+
+        private void invalidateSelf() {
+            mCallback.invalidateDrawable(null);
+        }
+    }
+
+    /**
+     * Squishes the interpolation curve into the second half of the animation.
+     */
+    private static class EndCurveInterpolator extends AccelerateDecelerateInterpolator {
+        @Override
+        public float getInterpolation(float input) {
+            return super.getInterpolation(Math.max(0, (input - 0.5f) * 2.0f));
+        }
+    }
+
+    /**
+     * Squishes the interpolation curve into the first half of the animation.
+     */
+    private static class StartCurveInterpolator extends AccelerateDecelerateInterpolator {
+        @Override
+        public float getInterpolation(float input) {
+            return super.getInterpolation(Math.min(1, input * 2.0f));
+        }
+    }
+}
diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
index 0a07332..fea68ee 100644
--- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java
+++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
@@ -23,10 +23,12 @@
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.Canvas;
+import android.graphics.Color;
 import android.graphics.ColorFilter;
 import android.graphics.Insets;
 import android.graphics.NinePatch;
 import android.graphics.Paint;
+import android.graphics.Paint.Style;
 import android.graphics.PixelFormat;
 import android.graphics.PorterDuff;
 import android.graphics.PorterDuff.Mode;
@@ -236,7 +238,6 @@
 
         final boolean needsMirroring = needsMirroring();
         if (needsMirroring) {
-            canvas.save();
             // Mirror the 9patch
             canvas.translate(bounds.right - bounds.left, 0);
             canvas.scale(-1.0f, 1.0f);
@@ -253,10 +254,6 @@
 
         mNinePatch.draw(canvas, bounds, mPaint);
 
-        if (needsMirroring) {
-            canvas.restore();
-        }
-
         if (clearColorFilter) {
             mPaint.setColorFilter(null);
         }
@@ -662,6 +659,7 @@
      */
     private NinePatchDrawable(NinePatchState state, Resources res, Theme theme) {
         if (theme != null && state.canApplyTheme()) {
+            // If we need to apply a theme, implicitly mutate.
             mNinePatchState = new NinePatchState(state);
             applyTheme(theme);
         } else {
diff --git a/graphics/java/android/graphics/drawable/Ripple.java b/graphics/java/android/graphics/drawable/Ripple.java
index ada741b..b3187c7 100644
--- a/graphics/java/android/graphics/drawable/Ripple.java
+++ b/graphics/java/android/graphics/drawable/Ripple.java
@@ -28,22 +28,26 @@
 import android.util.MathUtils;
 import android.view.HardwareCanvas;
 import android.view.RenderNodeAnimator;
+import android.view.animation.DecelerateInterpolator;
 import android.view.animation.LinearInterpolator;
 
 import java.util.ArrayList;
 
 /**
- * Draws a Quantum Paper ripple.
+ * Draws a Material ripple.
  */
 class Ripple {
     private static final TimeInterpolator LINEAR_INTERPOLATOR = new LinearInterpolator();
+    private static final TimeInterpolator DECEL_INTERPOLATOR = new DecelerateInterpolator(4);
 
     private static final float GLOBAL_SPEED = 1.0f;
-    private static final float WAVE_TOUCH_DOWN_ACCELERATION = 512.0f * GLOBAL_SPEED;
-    private static final float WAVE_TOUCH_UP_ACCELERATION = 1024.0f * GLOBAL_SPEED;
-    private static final float WAVE_OPACITY_DECAY_VELOCITY = 1.6f / GLOBAL_SPEED;
+    private static final float WAVE_TOUCH_DOWN_ACCELERATION = 1024.0f * GLOBAL_SPEED;
+    private static final float WAVE_TOUCH_UP_ACCELERATION = 3096.0f * GLOBAL_SPEED;
+    private static final float WAVE_OPACITY_DECAY_VELOCITY = 1.9f / GLOBAL_SPEED;
     private static final float WAVE_OUTER_OPACITY_VELOCITY = 1.2f * GLOBAL_SPEED;
 
+    private static final long RIPPLE_ENTER_DELAY = 100;
+
     // Hardware animators.
     private final ArrayList<RenderNodeAnimator> mRunningAnimations = new ArrayList<>();
     private final ArrayList<RenderNodeAnimator> mPendingAnimations = new ArrayList<>();
@@ -287,14 +291,19 @@
         radius.setAutoCancel(true);
         radius.setDuration(radiusDuration);
         radius.setInterpolator(LINEAR_INTERPOLATOR);
+        radius.setStartDelay(RIPPLE_ENTER_DELAY);
 
         final ObjectAnimator cX = ObjectAnimator.ofFloat(this, "xGravity", 1);
         cX.setAutoCancel(true);
         cX.setDuration(radiusDuration);
+        cX.setInterpolator(LINEAR_INTERPOLATOR);
+        cX.setStartDelay(RIPPLE_ENTER_DELAY);
 
         final ObjectAnimator cY = ObjectAnimator.ofFloat(this, "yGravity", 1);
         cY.setAutoCancel(true);
         cY.setDuration(radiusDuration);
+        cY.setInterpolator(LINEAR_INTERPOLATOR);
+        cY.setStartDelay(RIPPLE_ENTER_DELAY);
 
         final ObjectAnimator outer = ObjectAnimator.ofFloat(this, "outerOpacity", 0, 1);
         outer.setAutoCancel(true);
@@ -377,15 +386,15 @@
 
         final RenderNodeAnimator radiusAnim = new RenderNodeAnimator(mPropRadius, mOuterRadius);
         radiusAnim.setDuration(radiusDuration);
-        radiusAnim.setInterpolator(LINEAR_INTERPOLATOR);
+        radiusAnim.setInterpolator(DECEL_INTERPOLATOR);
 
         final RenderNodeAnimator xAnim = new RenderNodeAnimator(mPropX, mOuterX);
         xAnim.setDuration(radiusDuration);
-        xAnim.setInterpolator(LINEAR_INTERPOLATOR);
+        xAnim.setInterpolator(DECEL_INTERPOLATOR);
 
         final RenderNodeAnimator yAnim = new RenderNodeAnimator(mPropY, mOuterY);
         yAnim.setDuration(radiusDuration);
-        yAnim.setInterpolator(LINEAR_INTERPOLATOR);
+        yAnim.setInterpolator(DECEL_INTERPOLATOR);
 
         final RenderNodeAnimator opacityAnim = new RenderNodeAnimator(mPropPaint,
                 RenderNodeAnimator.PAINT_ALPHA, 0);
@@ -408,6 +417,7 @@
                 outerFadeOutAnim.setDuration(outerDuration);
                 outerFadeOutAnim.setInterpolator(LINEAR_INTERPOLATOR);
                 outerFadeOutAnim.setStartDelay(outerInflection);
+                outerFadeOutAnim.setStartValue(inflectionOpacity);
                 outerFadeOutAnim.addListener(mAnimationListener);
 
                 mPendingAnimations.add(outerFadeOutAnim);
@@ -438,17 +448,17 @@
         final ObjectAnimator radiusAnim = ObjectAnimator.ofFloat(this, "radiusGravity", 1);
         radiusAnim.setAutoCancel(true);
         radiusAnim.setDuration(radiusDuration);
-        radiusAnim.setInterpolator(LINEAR_INTERPOLATOR);
+        radiusAnim.setInterpolator(DECEL_INTERPOLATOR);
 
         final ObjectAnimator xAnim = ObjectAnimator.ofFloat(this, "xGravity", 1);
         xAnim.setAutoCancel(true);
         xAnim.setDuration(radiusDuration);
-        xAnim.setInterpolator(LINEAR_INTERPOLATOR);
+        xAnim.setInterpolator(DECEL_INTERPOLATOR);
 
         final ObjectAnimator yAnim = ObjectAnimator.ofFloat(this, "yGravity", 1);
         yAnim.setAutoCancel(true);
         yAnim.setDuration(radiusDuration);
-        yAnim.setInterpolator(LINEAR_INTERPOLATOR);
+        yAnim.setInterpolator(DECEL_INTERPOLATOR);
 
         final ObjectAnimator opacityAnim = ObjectAnimator.ofFloat(this, "opacity", 0);
         opacityAnim.setAutoCancel(true);
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index 9d7a8b6..58f6eaa 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -95,6 +95,9 @@
 
     private final RippleState mState;
 
+    /** The masking layer, e.g. the layer with id R.id.mask. */
+    private Drawable mMask;
+
     /** The current hotspot. May be actively animating or pending entry. */
     private Ripple mHotspot;
 
@@ -261,21 +264,14 @@
         super.inflate(r, parser, attrs, theme);
 
         setTargetDensity(r.getDisplayMetrics());
-
-        // Find the mask
-        final int N = getNumberOfLayers();
-        for (int i = 0; i < N; i++) {
-            if (mLayerState.mChildren[i].mId == R.id.mask) {
-                mState.mMask = mLayerState.mChildren[i].mDrawable;
-            }
-        }
+        initializeFromState();
     }
 
     @Override
     public boolean setDrawableByLayerId(int id, Drawable drawable) {
         if (super.setDrawableByLayerId(id, drawable)) {
             if (id == R.id.mask) {
-                mState.mMask = drawable;
+                mMask = drawable;
             }
 
             return true;
@@ -361,6 +357,8 @@
         } finally {
             a.recycle();
         }
+
+        initializeFromState();
     }
 
     @Override
@@ -441,8 +439,11 @@
         final int count = mAnimatingRipplesCount;
         final Ripple[] ripples = mAnimatingRipples;
         for (int i = 0; i < count; i++) {
-            ripples[i].cancel();
+            // Calling cancel may remove the ripple from the animating ripple
+            // array, so cache the reference before nulling it out.
+            final Ripple ripple = ripples[i];
             ripples[i] = null;
+            ripple.cancel();
         }
 
         mAnimatingRipplesCount = 0;
@@ -524,7 +525,7 @@
 
     private int drawContentLayer(Canvas canvas, Rect bounds, PorterDuffXfermode mode) {
         final int count = mLayerState.mNum;
-        if (count == 0 || (mState.mMask != null && count == 1)) {
+        if (count == 0 || (mMask != null && count == 1)) {
             return -1;
         }
 
@@ -608,7 +609,7 @@
     }
 
     private int drawMaskingLayer(Canvas canvas, Rect bounds, PorterDuffXfermode mode) {
-        final Drawable mask = mState.mMask;
+        final Drawable mask = mMask;
         if (mask == null) {
             return -1;
         }
@@ -616,6 +617,9 @@
         final int restoreToCount = canvas.saveLayer(bounds.left, bounds.top,
                 bounds.right, bounds.bottom, getMaskingPaint(mode));
 
+        // Ensure that DST_IN blends using the entire layer.
+        canvas.drawColor(Color.TRANSPARENT);
+
         mask.draw(canvas);
 
         return restoreToCount;
@@ -661,7 +665,6 @@
         int[] mTouchThemeAttrs;
         ColorStateList mTint = null;
         PorterDuffXfermode mTintXfermode = SRC_ATOP;
-        Drawable mMask;
         int mMaxRadius = RADIUS_AUTO;
         boolean mPinned = false;
 
@@ -757,8 +760,6 @@
         }
 
         mState = ns;
-        mState.mMask = findDrawableByLayerId(R.id.mask);
-
         mLayerState = ns;
 
         if (ns.mNum > 0) {
@@ -768,5 +769,12 @@
         if (needsTheme) {
             applyTheme(theme);
         }
+
+        initializeFromState();
+    }
+
+    private void initializeFromState() {
+        // Initialize from constant state.
+        mMask = findDrawableByLayerId(R.id.mask);
     }
 }
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index e5c8898..cc62170 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -14,6 +14,7 @@
 		AmbientShadow.cpp \
 		Animator.cpp \
 		AssetAtlas.cpp \
+		DamageAccumulator.cpp \
 		FontRenderer.cpp \
 		GammaFontRenderer.cpp \
 		Caches.cpp \
diff --git a/libs/hwui/Animator.h b/libs/hwui/Animator.h
index a0c7c55..203cdff 100644
--- a/libs/hwui/Animator.h
+++ b/libs/hwui/Animator.h
@@ -117,7 +117,7 @@
     virtual void setValue(RenderNode* target, float value);
 
 private:
-    typedef void (RenderProperties::*SetFloatProperty)(float value);
+    typedef bool (RenderProperties::*SetFloatProperty)(float value);
     typedef float (RenderProperties::*GetFloatProperty)() const;
 
     struct PropertyAccessors;
diff --git a/libs/hwui/DamageAccumulator.cpp b/libs/hwui/DamageAccumulator.cpp
new file mode 100644
index 0000000..8aa8c92
--- /dev/null
+++ b/libs/hwui/DamageAccumulator.cpp
@@ -0,0 +1,105 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "DamageAccumulator"
+
+#include "DamageAccumulator.h"
+
+#include <cutils/log.h>
+
+#include "RenderNode.h"
+#include "utils/MathUtils.h"
+
+namespace android {
+namespace uirenderer {
+
+struct DirtyStack {
+    const RenderNode* node;
+    // When this frame is pop'd, this rect is mapped through the above transform
+    // and applied to the previous (aka parent) frame
+    SkRect pendingDirty;
+    DirtyStack* prev;
+    DirtyStack* next;
+};
+
+DamageAccumulator::DamageAccumulator() {
+    mHead = (DirtyStack*) mAllocator.alloc(sizeof(DirtyStack));
+    memset(mHead, 0, sizeof(DirtyStack));
+    // Create a root that we will not pop off
+    mHead->prev = mHead;
+}
+
+void DamageAccumulator::pushNode(const RenderNode* node) {
+    if (!mHead->next) {
+        DirtyStack* nextFrame = (DirtyStack*) mAllocator.alloc(sizeof(DirtyStack));
+        nextFrame->next = 0;
+        nextFrame->prev = mHead;
+        mHead->next = nextFrame;
+    }
+    mHead = mHead->next;
+    mHead->node = node;
+    mHead->pendingDirty.setEmpty();
+}
+
+void DamageAccumulator::popNode() {
+    LOG_ALWAYS_FATAL_IF(mHead->prev == mHead, "Cannot pop the root frame!");
+    DirtyStack* dirtyFrame = mHead;
+    mHead = mHead->prev;
+    if (!dirtyFrame->pendingDirty.isEmpty()) {
+        SkRect mappedDirty;
+        const RenderProperties& props = dirtyFrame->node->properties();
+        const SkMatrix* transform = props.getTransformMatrix();
+        if (transform && !transform->isIdentity()) {
+            transform->mapRect(&mappedDirty, dirtyFrame->pendingDirty);
+        } else {
+            mappedDirty = dirtyFrame->pendingDirty;
+        }
+        if (CC_LIKELY(mHead->node)) {
+            const RenderProperties& parentProps = mHead->node->properties();
+            mappedDirty.offset(props.getLeft() - parentProps.getScrollX(),
+                    props.getTop() - parentProps.getScrollY());
+            if (props.getClipToBounds()) {
+                if (!mappedDirty.intersect(0, 0, parentProps.getWidth(), parentProps.getHeight())) {
+                    mappedDirty.setEmpty();
+                }
+            }
+            if (CC_UNLIKELY(!MathUtils::isZero(props.getTranslationZ()))) {
+                // TODO: Can we better bound the shadow damage area? For now
+                // match the old damageShadowReceiver() path and just dirty
+                // the entire parent bounds
+                mappedDirty.join(0, 0, parentProps.getWidth(), parentProps.getHeight());
+            }
+        } else {
+            mappedDirty.offset(props.getLeft(), props.getTop());
+        }
+        dirty(mappedDirty.fLeft, mappedDirty.fTop, mappedDirty.fRight, mappedDirty.fBottom);
+    }
+}
+
+void DamageAccumulator::dirty(float left, float top, float right, float bottom) {
+    mHead->pendingDirty.join(left, top, right, bottom);
+}
+
+void DamageAccumulator::finish(SkRect* totalDirty) {
+    LOG_ALWAYS_FATAL_IF(mHead->prev != mHead, "Cannot finish, mismatched push/pop calls! %p vs. %p", mHead->prev, mHead);
+    // Root node never has a transform, so this is the fully mapped dirty rect
+    *totalDirty = mHead->pendingDirty;
+    totalDirty->roundOut();
+    mHead->pendingDirty.setEmpty();
+}
+
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/DamageAccumulator.h b/libs/hwui/DamageAccumulator.h
new file mode 100644
index 0000000..c62a351
--- /dev/null
+++ b/libs/hwui/DamageAccumulator.h
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+#ifndef DAMAGEACCUMULATOR_H
+#define DAMAGEACCUMULATOR_H
+
+#include <utils/LinearAllocator.h>
+
+#include <SkMatrix.h>
+#include <SkRect.h>
+
+#include "utils/Macros.h"
+
+namespace android {
+namespace uirenderer {
+
+struct DirtyStack;
+class RenderNode;
+
+class DamageAccumulator {
+    PREVENT_COPY_AND_ASSIGN(DamageAccumulator);
+public:
+    DamageAccumulator();
+    // mAllocator will clean everything up for us, no need for a dtor
+
+    // Push a transform node onto the stack. This should be called prior
+    // to any dirty() calls. Subsequent calls to dirty()
+    // will be affected by the node's transform when popNode() is called.
+    void pushNode(const RenderNode* node);
+    // Pops a transform node from the stack, propagating the dirty rect
+    // up to the parent node.
+    void popNode();
+    void dirty(float left, float top, float right, float bottom);
+
+    void finish(SkRect* totalDirty);
+
+private:
+    LinearAllocator mAllocator;
+    DirtyStack* mHead;
+};
+
+} /* namespace uirenderer */
+} /* namespace android */
+
+#endif /* DAMAGEACCUMULATOR_H */
diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp
index 97e9bf6..d494c4c 100644
--- a/libs/hwui/DeferredLayerUpdater.cpp
+++ b/libs/hwui/DeferredLayerUpdater.cpp
@@ -81,6 +81,10 @@
             success = LayerRenderer::resizeLayer(mLayer, mWidth, mHeight);
         }
         mLayer->setBlend(mBlend);
+        // TODO: Use DamageAccumulator to get the damage area for the layer's
+        // subtree to only update that part of the layer. Do this as part of
+        // reworking layers to be a RenderProperty instead of a View-managed object
+        mDirtyRect.set(0, 0, mWidth, mHeight);
         mDisplayList->prepareTree(info);
         mLayer->updateDeferred(mDisplayList.get(),
                 mDirtyRect.left, mDirtyRect.top, mDirtyRect.right, mDirtyRect.bottom);
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 195b00b..2eaa671 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -153,6 +153,11 @@
 
     // TODO: rename for consistency
     virtual status_t callDrawGLFunction(Functor* functor, Rect& dirty);
+protected:
+    // NOTE: must override these to avoid calling into super class, which calls GL. These may be
+    // removed once DisplayListRenderer no longer inherits from OpenGLRenderer
+    virtual void onViewportInitialized() {};
+    virtual void onSnapshotRestored() {};
 
 private:
     void insertRestoreToCount();
diff --git a/libs/hwui/DrawProfiler.cpp b/libs/hwui/DrawProfiler.cpp
index 971a66e..2409554 100644
--- a/libs/hwui/DrawProfiler.cpp
+++ b/libs/hwui/DrawProfiler.cpp
@@ -109,7 +109,7 @@
     mCurrentFrame = (mCurrentFrame + 1) % mDataSize;
 }
 
-void DrawProfiler::unionDirty(Rect* dirty) {
+void DrawProfiler::unionDirty(SkRect* dirty) {
     RETURN_IF_DISABLED();
     // Not worth worrying about minimizing the dirty region for debugging, so just
     // dirty the entire viewport.
diff --git a/libs/hwui/DrawProfiler.h b/libs/hwui/DrawProfiler.h
index c1aa1c6..7c06e5d 100644
--- a/libs/hwui/DrawProfiler.h
+++ b/libs/hwui/DrawProfiler.h
@@ -37,7 +37,7 @@
     void markPlaybackEnd();
     void finishFrame();
 
-    void unionDirty(Rect* dirty);
+    void unionDirty(SkRect* dirty);
     void draw(OpenGLRenderer* canvas);
 
     void dumpData(int fd);
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index baf372a..c2f6df8 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -25,6 +25,7 @@
 
 #include <utils/Trace.h>
 
+#include "DamageAccumulator.h"
 #include "Debug.h"
 #include "DisplayListOp.h"
 #include "DisplayListLogBuffer.h"
@@ -110,14 +111,36 @@
     prepareTreeImpl(info);
 }
 
-void RenderNode::prepareTreeImpl(TreeInfo& info) {
-    if (info.performStagingPush) {
-        pushStagingChanges(info);
+static inline void pushNode(RenderNode* self, TreeInfo& info) {
+    if (info.damageAccumulator) {
+        info.damageAccumulator->pushNode(self);
     }
-    if (info.evaluateAnimations) {
+}
+
+static inline void popNode(TreeInfo& info) {
+    if (info.damageAccumulator) {
+        info.damageAccumulator->popNode();
+    }
+}
+
+void RenderNode::damageSelf(TreeInfo& info) {
+    if (info.damageAccumulator && isRenderable() && properties().getAlpha() > 0) {
+        info.damageAccumulator->dirty(0, 0, properties().getWidth(), properties().getHeight());
+    }
+}
+
+void RenderNode::prepareTreeImpl(TreeInfo& info) {
+    pushNode(this, info);
+    if (info.mode == TreeInfo::MODE_FULL) {
+        pushStagingChanges(info);
+        evaluateAnimations(info);
+    } else if (info.mode == TreeInfo::MODE_MAYBE_DETACHING) {
+        pushStagingChanges(info);
+    } else if (info.mode == TreeInfo::MODE_RT_ONLY) {
         evaluateAnimations(info);
     }
     prepareSubTree(info, mDisplayListData);
+    popNode(info);
 }
 
 class PushAnimatorsFunctor {
@@ -149,18 +172,28 @@
     }
     if (mDirtyPropertyFields) {
         mDirtyPropertyFields = 0;
+        damageSelf(info);
+        popNode(info);
         mProperties = mStagingProperties;
+        pushNode(this, info);
+        // We could try to be clever and only re-damage if the matrix changed.
+        // However, we don't need to worry about that. The cost of over-damaging
+        // here is only going to be a single additional map rect of this node
+        // plus a rect join(). The parent's transform (and up) will only be
+        // performed once.
+        damageSelf(info);
     }
     if (mNeedsDisplayListDataSync) {
         mNeedsDisplayListDataSync = false;
         // Do a push pass on the old tree to handle freeing DisplayListData
         // that are no longer used
-        TreeInfo oldTreeInfo;
+        TreeInfo oldTreeInfo(TreeInfo::MODE_MAYBE_DETACHING);
+        oldTreeInfo.damageAccumulator = info.damageAccumulator;
         prepareSubTree(oldTreeInfo, mDisplayListData);
-        // TODO: The damage for the old tree should be accounted for
         delete mDisplayListData;
         mDisplayListData = mStagingDisplayListData;
         mStagingDisplayListData = 0;
+        damageSelf(info);
     }
 }
 
@@ -180,12 +213,21 @@
 void RenderNode::evaluateAnimations(TreeInfo& info) {
     if (!mAnimators.size()) return;
 
+    // TODO: Can we target this better? For now treat it like any other staging
+    // property push and just damage self before and after animators are run
+
+    damageSelf(info);
+    popNode(info);
+
     AnimateFunctor functor(this, info);
     std::vector< sp<BaseRenderNodeAnimator> >::iterator newEnd;
     newEnd = std::remove_if(mAnimators.begin(), mAnimators.end(), functor);
     mAnimators.erase(newEnd, mAnimators.end());
     mProperties.updateMatrix();
     info.out.hasAnimations |= mAnimators.size();
+
+    pushNode(this, info);
+    damageSelf(info);
 }
 
 void RenderNode::prepareSubTree(TreeInfo& info, DisplayListData* subtree) {
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index 1a5377b..393d4ea 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -148,7 +148,7 @@
         mDirtyPropertyFields |= fields;
     }
 
-    const RenderProperties& properties() {
+    const RenderProperties& properties() const {
         return mProperties;
     }
 
@@ -187,6 +187,9 @@
         mNeedsAnimatorsSync = true;
     }
 
+protected:
+    virtual void damageSelf(TreeInfo& info);
+
 private:
     typedef key_value_pair_t<float, DrawDisplayListOp*> ZDrawDisplayListOpPair;
 
diff --git a/libs/hwui/RenderProperties.cpp b/libs/hwui/RenderProperties.cpp
index 5f7d4e3..6163df5 100644
--- a/libs/hwui/RenderProperties.cpp
+++ b/libs/hwui/RenderProperties.cpp
@@ -44,6 +44,7 @@
         , mPivotX(0), mPivotY(0)
         , mLeft(0), mTop(0), mRight(0), mBottom(0)
         , mWidth(0), mHeight(0)
+        , mScrollX(0), mScrollY(0)
         , mPivotExplicitlySet(false)
         , mMatrixOrPivotDirty(false)
         , mCaching(false) {
diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h
index c0e3ce7..c294f38 100644
--- a/libs/hwui/RenderProperties.h
+++ b/libs/hwui/RenderProperties.h
@@ -40,6 +40,10 @@
 class Matrix4;
 class RenderNode;
 
+// The __VA_ARGS__ will be executed if a & b are not equal
+#define RP_SET(a, b, ...) (a != b ? (a = b, ##__VA_ARGS__, true) : false)
+#define RP_SET_AND_DIRTY(a, b) RP_SET(a, b, mPrimitiveFields.mMatrixOrPivotDirty = true)
+
 /*
  * Data structure that holds the properties for a RenderNode
  */
@@ -50,29 +54,30 @@
 
     RenderProperties& operator=(const RenderProperties& other);
 
-    void setClipToBounds(bool clipToBounds) {
-        mPrimitiveFields.mClipToBounds = clipToBounds;
+    bool setClipToBounds(bool clipToBounds) {
+        return RP_SET(mPrimitiveFields.mClipToBounds, clipToBounds);
     }
 
-    void setProjectBackwards(bool shouldProject) {
-        mPrimitiveFields.mProjectBackwards = shouldProject;
+    bool setProjectBackwards(bool shouldProject) {
+        return RP_SET(mPrimitiveFields.mProjectBackwards, shouldProject);
     }
 
-    void setProjectionReceiver(bool shouldRecieve) {
-        mPrimitiveFields.mProjectionReceiver = shouldRecieve;
+    bool setProjectionReceiver(bool shouldRecieve) {
+        return RP_SET(mPrimitiveFields.mProjectionReceiver, shouldRecieve);
     }
 
     bool isProjectionReceiver() const {
         return mPrimitiveFields.mProjectionReceiver;
     }
 
-    void setStaticMatrix(const SkMatrix* matrix) {
+    bool setStaticMatrix(const SkMatrix* matrix) {
         delete mStaticMatrix;
         if (matrix) {
             mStaticMatrix = new SkMatrix(*matrix);
         } else {
             mStaticMatrix = NULL;
         }
+        return true;
     }
 
     // Can return NULL
@@ -80,72 +85,61 @@
         return mStaticMatrix;
     }
 
-    void setAnimationMatrix(const SkMatrix* matrix) {
+    bool setAnimationMatrix(const SkMatrix* matrix) {
         delete mAnimationMatrix;
         if (matrix) {
             mAnimationMatrix = new SkMatrix(*matrix);
         } else {
             mAnimationMatrix = NULL;
         }
+        return true;
     }
 
-    void setAlpha(float alpha) {
+    bool setAlpha(float alpha) {
         alpha = fminf(1.0f, fmaxf(0.0f, alpha));
-        if (alpha != mPrimitiveFields.mAlpha) {
-            mPrimitiveFields.mAlpha = alpha;
-        }
+        return RP_SET(mPrimitiveFields.mAlpha, alpha);
     }
 
     float getAlpha() const {
         return mPrimitiveFields.mAlpha;
     }
 
-    void setHasOverlappingRendering(bool hasOverlappingRendering) {
-        mPrimitiveFields.mHasOverlappingRendering = hasOverlappingRendering;
+    bool setHasOverlappingRendering(bool hasOverlappingRendering) {
+        return RP_SET(mPrimitiveFields.mHasOverlappingRendering, hasOverlappingRendering);
     }
 
     bool hasOverlappingRendering() const {
         return mPrimitiveFields.mHasOverlappingRendering;
     }
 
-    void setElevation(float elevation) {
-        if (elevation != mPrimitiveFields.mElevation) {
-            mPrimitiveFields.mElevation = elevation;
-            // mMatrixOrPivotDirty not set, since matrix doesn't respect Z
-        }
+    bool setElevation(float elevation) {
+        return RP_SET(mPrimitiveFields.mElevation, elevation);
+        // Don't dirty matrix/pivot, since they don't respect Z
     }
 
     float getElevation() const {
         return mPrimitiveFields.mElevation;
     }
 
-    void setTranslationX(float translationX) {
-        if (translationX != mPrimitiveFields.mTranslationX) {
-            mPrimitiveFields.mTranslationX = translationX;
-            mPrimitiveFields.mMatrixOrPivotDirty = true;
-        }
+    bool setTranslationX(float translationX) {
+        return RP_SET_AND_DIRTY(mPrimitiveFields.mTranslationX, translationX);
     }
 
     float getTranslationX() const {
         return mPrimitiveFields.mTranslationX;
     }
 
-    void setTranslationY(float translationY) {
-        if (translationY != mPrimitiveFields.mTranslationY) {
-            mPrimitiveFields.mTranslationY = translationY;
-            mPrimitiveFields.mMatrixOrPivotDirty = true;
-        }
+    bool setTranslationY(float translationY) {
+        return RP_SET_AND_DIRTY(mPrimitiveFields.mTranslationY, translationY);
     }
 
     float getTranslationY() const {
         return mPrimitiveFields.mTranslationY;
     }
 
-    void setTranslationZ(float translationZ) {
-        if (translationZ != mPrimitiveFields.mTranslationZ) {
-            mPrimitiveFields.mTranslationZ = translationZ;
-            // mMatrixOrPivotDirty not set, since matrix doesn't respect Z
-        }
+    bool setTranslationZ(float translationZ) {
+        return RP_SET(mPrimitiveFields.mTranslationZ, translationZ);
+        // mMatrixOrPivotDirty not set, since matrix doesn't respect Z
     }
 
     float getTranslationZ() const {
@@ -153,8 +147,8 @@
     }
 
     // Animation helper
-    void setX(float value) {
-        setTranslationX(value - getLeft());
+    bool setX(float value) {
+        return setTranslationX(value - getLeft());
     }
 
     // Animation helper
@@ -163,8 +157,8 @@
     }
 
     // Animation helper
-    void setY(float value) {
-        setTranslationY(value - getTop());
+    bool setY(float value) {
+        return setTranslationY(value - getTop());
     }
 
     // Animation helper
@@ -173,87 +167,80 @@
     }
 
     // Animation helper
-    void setZ(float value) {
-        setTranslationZ(value - getElevation());
+    bool setZ(float value) {
+        return setTranslationZ(value - getElevation());
     }
 
     float getZ() const {
         return getElevation() + getTranslationZ();
     }
 
-    void setRotation(float rotation) {
-        if (rotation != mPrimitiveFields.mRotation) {
-            mPrimitiveFields.mRotation = rotation;
-            mPrimitiveFields.mMatrixOrPivotDirty = true;
-        }
+    bool setRotation(float rotation) {
+        return RP_SET_AND_DIRTY(mPrimitiveFields.mRotation, rotation);
     }
 
     float getRotation() const {
         return mPrimitiveFields.mRotation;
     }
 
-    void setRotationX(float rotationX) {
-        if (rotationX != mPrimitiveFields.mRotationX) {
-            mPrimitiveFields.mRotationX = rotationX;
-            mPrimitiveFields.mMatrixOrPivotDirty = true;
-        }
+    bool setRotationX(float rotationX) {
+        return RP_SET_AND_DIRTY(mPrimitiveFields.mRotationX, rotationX);
     }
 
     float getRotationX() const {
         return mPrimitiveFields.mRotationX;
     }
 
-    void setRotationY(float rotationY) {
-        if (rotationY != mPrimitiveFields.mRotationY) {
-            mPrimitiveFields.mRotationY = rotationY;
-            mPrimitiveFields.mMatrixOrPivotDirty = true;
-        }
+    bool setRotationY(float rotationY) {
+        return RP_SET_AND_DIRTY(mPrimitiveFields.mRotationY, rotationY);
     }
 
     float getRotationY() const {
         return mPrimitiveFields.mRotationY;
     }
 
-    void setScaleX(float scaleX) {
-        if (scaleX != mPrimitiveFields.mScaleX) {
-            mPrimitiveFields.mScaleX = scaleX;
-            mPrimitiveFields.mMatrixOrPivotDirty = true;
-        }
+    bool setScaleX(float scaleX) {
+        return RP_SET_AND_DIRTY(mPrimitiveFields.mScaleX, scaleX);
     }
 
     float getScaleX() const {
         return mPrimitiveFields.mScaleX;
     }
 
-    void setScaleY(float scaleY) {
-        if (scaleY != mPrimitiveFields.mScaleY) {
-            mPrimitiveFields.mScaleY = scaleY;
-            mPrimitiveFields.mMatrixOrPivotDirty = true;
-        }
+    bool setScaleY(float scaleY) {
+        return RP_SET_AND_DIRTY(mPrimitiveFields.mScaleY, scaleY);
     }
 
     float getScaleY() const {
         return mPrimitiveFields.mScaleY;
     }
 
-    void setPivotX(float pivotX) {
-        mPrimitiveFields.mPivotX = pivotX;
-        mPrimitiveFields.mMatrixOrPivotDirty = true;
-        mPrimitiveFields.mPivotExplicitlySet = true;
+    bool setPivotX(float pivotX) {
+        if (RP_SET(mPrimitiveFields.mPivotX, pivotX)
+                || !mPrimitiveFields.mPivotExplicitlySet) {
+            mPrimitiveFields.mMatrixOrPivotDirty = true;
+            mPrimitiveFields.mPivotExplicitlySet = true;
+            return true;
+        }
+        return false;
     }
 
     /* Note that getPivotX and getPivotY are adjusted by updateMatrix(),
-     * so the value returned mPrimitiveFields.may be stale if the RenderProperties has been
-     * mPrimitiveFields.modified since the last call to updateMatrix()
+     * so the value returned may be stale if the RenderProperties has been
+     * modified since the last call to updateMatrix()
      */
     float getPivotX() const {
         return mPrimitiveFields.mPivotX;
     }
 
-    void setPivotY(float pivotY) {
-        mPrimitiveFields.mPivotY = pivotY;
-        mPrimitiveFields.mMatrixOrPivotDirty = true;
-        mPrimitiveFields.mPivotExplicitlySet = true;
+    bool setPivotY(float pivotY) {
+        if (RP_SET(mPrimitiveFields.mPivotY, pivotY)
+                || !mPrimitiveFields.mPivotExplicitlySet) {
+            mPrimitiveFields.mMatrixOrPivotDirty = true;
+            mPrimitiveFields.mPivotExplicitlySet = true;
+            return true;
+        }
+        return false;
     }
 
     float getPivotY() const {
@@ -264,11 +251,13 @@
         return mPrimitiveFields.mPivotExplicitlySet;
     }
 
-    void setCameraDistance(float distance) {
+    bool setCameraDistance(float distance) {
         if (distance != getCameraDistance()) {
             mPrimitiveFields.mMatrixOrPivotDirty = true;
             mComputedFields.mTransformCamera.setCameraLocation(0, 0, distance);
+            return true;
         }
+        return false;
     }
 
     float getCameraDistance() const {
@@ -276,75 +265,73 @@
         return const_cast<Sk3DView*>(&mComputedFields.mTransformCamera)->getCameraLocationZ();
     }
 
-    void setLeft(int left) {
-        if (left != mPrimitiveFields.mLeft) {
-            mPrimitiveFields.mLeft = left;
+    bool setLeft(int left) {
+        if (RP_SET(mPrimitiveFields.mLeft, left)) {
             mPrimitiveFields.mWidth = mPrimitiveFields.mRight - mPrimitiveFields.mLeft;
             if (!mPrimitiveFields.mPivotExplicitlySet) {
                 mPrimitiveFields.mMatrixOrPivotDirty = true;
             }
+            return true;
         }
+        return false;
     }
 
     float getLeft() const {
         return mPrimitiveFields.mLeft;
     }
 
-    void setTop(int top) {
-        if (top != mPrimitiveFields.mTop) {
-            mPrimitiveFields.mTop = top;
+    bool setTop(int top) {
+        if (RP_SET(mPrimitiveFields.mTop, top)) {
             mPrimitiveFields.mHeight = mPrimitiveFields.mBottom - mPrimitiveFields.mTop;
             if (!mPrimitiveFields.mPivotExplicitlySet) {
                 mPrimitiveFields.mMatrixOrPivotDirty = true;
             }
+            return true;
         }
+        return false;
     }
 
     float getTop() const {
         return mPrimitiveFields.mTop;
     }
 
-    void setRight(int right) {
-        if (right != mPrimitiveFields.mRight) {
-            mPrimitiveFields.mRight = right;
+    bool setRight(int right) {
+        if (RP_SET(mPrimitiveFields.mRight, right)) {
             mPrimitiveFields.mWidth = mPrimitiveFields.mRight - mPrimitiveFields.mLeft;
             if (!mPrimitiveFields.mPivotExplicitlySet) {
                 mPrimitiveFields.mMatrixOrPivotDirty = true;
             }
+            return true;
         }
+        return false;
     }
 
     float getRight() const {
         return mPrimitiveFields.mRight;
     }
 
-    void setBottom(int bottom) {
-        if (bottom != mPrimitiveFields.mBottom) {
-            mPrimitiveFields.mBottom = bottom;
+    bool setBottom(int bottom) {
+        if (RP_SET(mPrimitiveFields.mBottom, bottom)) {
             mPrimitiveFields.mHeight = mPrimitiveFields.mBottom - mPrimitiveFields.mTop;
             if (!mPrimitiveFields.mPivotExplicitlySet) {
                 mPrimitiveFields.mMatrixOrPivotDirty = true;
             }
+            return true;
         }
+        return false;
     }
 
     float getBottom() const {
         return mPrimitiveFields.mBottom;
     }
 
-    void setLeftTop(int left, int top) {
-        if (left != mPrimitiveFields.mLeft || top != mPrimitiveFields.mTop) {
-            mPrimitiveFields.mLeft = left;
-            mPrimitiveFields.mTop = top;
-            mPrimitiveFields.mWidth = mPrimitiveFields.mRight - mPrimitiveFields.mLeft;
-            mPrimitiveFields.mHeight = mPrimitiveFields.mBottom - mPrimitiveFields.mTop;
-            if (!mPrimitiveFields.mPivotExplicitlySet) {
-                mPrimitiveFields.mMatrixOrPivotDirty = true;
-            }
-        }
+    bool setLeftTop(int left, int top) {
+        bool leftResult = setLeft(left);
+        bool topResult = setTop(top);
+        return leftResult || topResult;
     }
 
-    void setLeftTopRightBottom(int left, int top, int right, int bottom) {
+    bool setLeftTopRightBottom(int left, int top, int right, int bottom) {
         if (left != mPrimitiveFields.mLeft || top != mPrimitiveFields.mTop
                 || right != mPrimitiveFields.mRight || bottom != mPrimitiveFields.mBottom) {
             mPrimitiveFields.mLeft = left;
@@ -356,31 +343,47 @@
             if (!mPrimitiveFields.mPivotExplicitlySet) {
                 mPrimitiveFields.mMatrixOrPivotDirty = true;
             }
+            return true;
         }
+        return false;
     }
 
-    void offsetLeftRight(float offset) {
+    bool offsetLeftRight(float offset) {
         if (offset != 0) {
             mPrimitiveFields.mLeft += offset;
             mPrimitiveFields.mRight += offset;
-            if (!mPrimitiveFields.mPivotExplicitlySet) {
-                mPrimitiveFields.mMatrixOrPivotDirty = true;
-            }
+            return true;
         }
+        return false;
     }
 
-    void offsetTopBottom(float offset) {
+    bool offsetTopBottom(float offset) {
         if (offset != 0) {
             mPrimitiveFields.mTop += offset;
             mPrimitiveFields.mBottom += offset;
-            if (!mPrimitiveFields.mPivotExplicitlySet) {
-                mPrimitiveFields.mMatrixOrPivotDirty = true;
-            }
+            return true;
         }
+        return false;
     }
 
-    void setCaching(bool caching) {
-        mPrimitiveFields.mCaching = caching;
+    bool setScrollX(int scrollX) {
+        return RP_SET(mPrimitiveFields.mScrollX, scrollX);
+    }
+
+    bool setScrollY(int scrollY) {
+        return RP_SET(mPrimitiveFields.mScrollY, scrollY);
+    }
+
+    int getScrollX() const {
+        return mPrimitiveFields.mScrollX;
+    }
+
+    int getScrollY() const {
+        return mPrimitiveFields.mScrollY;
+    }
+
+    bool setCaching(bool caching) {
+        return RP_SET(mPrimitiveFields.mCaching, caching);
     }
 
     int getWidth() const {
@@ -478,6 +481,7 @@
         float mPivotX, mPivotY;
         int mLeft, mTop, mRight, mBottom;
         int mWidth, mHeight;
+        int mScrollX, mScrollY;
         bool mPivotExplicitlySet;
         bool mMatrixOrPivotDirty;
         bool mCaching;
diff --git a/libs/hwui/TreeInfo.h b/libs/hwui/TreeInfo.h
index 8355f83..2096f98 100644
--- a/libs/hwui/TreeInfo.h
+++ b/libs/hwui/TreeInfo.h
@@ -18,11 +18,14 @@
 
 #include <utils/Timers.h>
 
+#include "utils/Macros.h"
+
 namespace android {
 namespace uirenderer {
 
 class BaseRenderNodeAnimator;
 class AnimationListener;
+class DamageAccumulator;
 
 class AnimationHook {
 public:
@@ -31,21 +34,44 @@
     ~AnimationHook() {}
 };
 
-struct TreeInfo {
-    // The defaults here should be safe for everyone but DrawFrameTask to use as-is.
-    TreeInfo()
-        : frameTimeMs(0)
+// This would be a struct, but we want to PREVENT_COPY_AND_ASSIGN
+class TreeInfo {
+    PREVENT_COPY_AND_ASSIGN(TreeInfo);
+public:
+    enum TraversalMode {
+        // The full monty - sync, push, run animators, etc... Used by DrawFrameTask
+        // May only be used if both the UI thread and RT thread are blocked on the
+        // prepare
+        MODE_FULL,
+        // Run only what can be done safely on RT thread. Currently this only means
+        // animators, but potentially things like SurfaceTexture updates
+        // could be handled by this as well if there are no listeners
+        MODE_RT_ONLY,
+        // The subtree is being detached. Maybe. If the RenderNode is present
+        // in both the old and new display list's children then it will get a
+        // MODE_MAYBE_DETACHING followed shortly by a MODE_FULL.
+        // Push any pending display list changes in case it is detached,
+        // but don't evaluate animators and such as if it isn't detached as a
+        // MODE_FULL will follow shortly.
+        MODE_MAYBE_DETACHING,
+        // TODO: TRIM_MEMORY?
+    };
+
+    explicit TreeInfo(TraversalMode mode)
+        : mode(mode)
+        , frameTimeMs(0)
         , animationHook(NULL)
-        , prepareTextures(false)
-        , performStagingPush(true)
-        , evaluateAnimations(false)
+        , prepareTextures(mode == MODE_FULL)
+        , damageAccumulator(0)
     {}
 
+    const TraversalMode mode;
     nsecs_t frameTimeMs;
     AnimationHook* animationHook;
+    // TODO: Remove this? Currently this is used to signal to stop preparing
+    // textures if we run out of cache space.
     bool prepareTextures;
-    bool performStagingPush;
-    bool evaluateAnimations;
+    DamageAccumulator* damageAccumulator;
 
     struct Out {
         Out()
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 9ebee1d..8a5c857 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -439,6 +439,7 @@
     mRenderThread.removeFrameCallback(this);
 
     info.frameTimeMs = mRenderThread.timeLord().frameTimeMs();
+    info.damageAccumulator = &mDamageAccumulator;
     mRootRenderNode->prepareTree(info);
 
     int runningBehind = 0;
@@ -465,27 +466,30 @@
     mRenderThread.pushBackFrameCallback(this);
 }
 
-void CanvasContext::draw(Rect* dirty) {
+void CanvasContext::draw() {
     LOG_ALWAYS_FATAL_IF(!mCanvas || mEglSurface == EGL_NO_SURFACE,
             "drawDisplayList called on a context with no canvas or surface!");
 
     profiler().markPlaybackStart();
 
+    SkRect dirty;
+    mDamageAccumulator.finish(&dirty);
+
     EGLint width, height;
     mGlobalContext->beginFrame(mEglSurface, &width, &height);
     if (width != mCanvas->getViewportWidth() || height != mCanvas->getViewportHeight()) {
         mCanvas->setViewport(width, height);
-        dirty = NULL;
+        dirty.setEmpty();
     } else if (!mDirtyRegionsEnabled || mHaveNewSurface) {
-        dirty = NULL;
+        dirty.setEmpty();
     } else {
-        profiler().unionDirty(dirty);
+        profiler().unionDirty(&dirty);
     }
 
     status_t status;
-    if (dirty && !dirty->isEmpty()) {
-        status = mCanvas->prepareDirty(dirty->left, dirty->top,
-                dirty->right, dirty->bottom, mOpaque);
+    if (!dirty.isEmpty()) {
+        status = mCanvas->prepareDirty(dirty.fLeft, dirty.fTop,
+                dirty.fRight, dirty.fBottom, mOpaque);
     } else {
         status = mCanvas->prepare(mOpaque);
     }
@@ -516,14 +520,12 @@
 
     profiler().startFrame();
 
-    TreeInfo info;
-    info.evaluateAnimations = true;
-    info.performStagingPush = false;
+    TreeInfo info(TreeInfo::MODE_RT_ONLY);
     info.prepareTextures = false;
 
     prepareTree(info);
     if (info.out.canDrawThisFrame) {
-        draw(NULL);
+        draw();
     }
 }
 
@@ -543,7 +545,7 @@
 
 bool CanvasContext::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) {
     requireGlContext();
-    TreeInfo info;
+    TreeInfo info(TreeInfo::MODE_FULL);
     layer->apply(info);
     return LayerRenderer::copyLayer(layer->backingLayer(), bitmap);
 }
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 00c5bf0..d926b38 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -23,6 +23,7 @@
 #include <utils/Functor.h>
 #include <utils/Vector.h>
 
+#include "../DamageAccumulator.h"
 #include "../DrawProfiler.h"
 #include "../RenderNode.h"
 #include "RenderTask.h"
@@ -57,7 +58,7 @@
     void makeCurrent();
     void processLayerUpdate(DeferredLayerUpdater* layerUpdater, TreeInfo& info);
     void prepareTree(TreeInfo& info);
-    void draw(Rect* dirty);
+    void draw();
     void destroyCanvasAndSurface();
 
     // IFrameCallback, Chroreographer-driven frame callback entry point
@@ -99,6 +100,7 @@
     bool mOpaque;
     OpenGLRenderer* mCanvas;
     bool mHaveNewSurface;
+    DamageAccumulator mDamageAccumulator;
 
     const sp<RenderNode> mRootRenderNode;
 
diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp
index 61d67ca..bdfdd21 100644
--- a/libs/hwui/renderthread/DrawFrameTask.cpp
+++ b/libs/hwui/renderthread/DrawFrameTask.cpp
@@ -68,10 +68,6 @@
     }
 }
 
-void DrawFrameTask::setDirty(int left, int top, int right, int bottom) {
-    mDirty.set(left, top, right, bottom);
-}
-
 int DrawFrameTask::drawFrame(nsecs_t frameTimeNanos, nsecs_t recordDurationNanos) {
     LOG_ALWAYS_FATAL_IF(!mContext, "Cannot drawFrame with no CanvasContext!");
 
@@ -83,7 +79,6 @@
     // Reset the single-frame data
     mFrameTimeNanos = 0;
     mRecordDurationNanos = 0;
-    mDirty.setEmpty();
 
     return mSyncResult;
 }
@@ -103,13 +98,12 @@
     bool canUnblockUiThread;
     bool canDrawThisFrame;
     {
-        TreeInfo info;
+        TreeInfo info(TreeInfo::MODE_FULL);
         canUnblockUiThread = syncFrameState(info);
         canDrawThisFrame = info.out.canDrawThisFrame;
     }
 
     // Grab a copy of everything we need
-    Rect dirty(mDirty);
     CanvasContext* context = mContext;
 
     // From this point on anything in "this" is *UNSAFE TO ACCESS*
@@ -118,7 +112,7 @@
     }
 
     if (CC_LIKELY(canDrawThisFrame)) {
-        context->draw(&dirty);
+        context->draw();
     }
 
     if (!canUnblockUiThread) {
@@ -126,18 +120,11 @@
     }
 }
 
-static void initTreeInfo(TreeInfo& info) {
-    info.prepareTextures = true;
-    info.performStagingPush = true;
-    info.evaluateAnimations = true;
-}
-
 bool DrawFrameTask::syncFrameState(TreeInfo& info) {
     ATRACE_CALL();
     mRenderThread->timeLord().vsyncReceived(mFrameTimeNanos);
     mContext->makeCurrent();
     Caches::getInstance().textureCache.resetMarkInUse();
-    initTreeInfo(info);
 
     for (size_t i = 0; i < mLayers.size(); i++) {
         mContext->processLayerUpdate(mLayers[i].get(), info);
@@ -149,8 +136,6 @@
     mContext->prepareTree(info);
 
     if (info.out.hasAnimations) {
-        // TODO: dirty calculations, for now just do a full-screen inval
-        mDirty.setEmpty();
         if (info.out.requiresUiRedraw) {
             mSyncResult |= kSync_UIRedrawRequired;
         }
diff --git a/libs/hwui/renderthread/DrawFrameTask.h b/libs/hwui/renderthread/DrawFrameTask.h
index d4129b6..96f0add 100644
--- a/libs/hwui/renderthread/DrawFrameTask.h
+++ b/libs/hwui/renderthread/DrawFrameTask.h
@@ -60,7 +60,6 @@
     void pushLayerUpdate(DeferredLayerUpdater* layer);
     void removeLayerUpdate(DeferredLayerUpdater* layer);
 
-    void setDirty(int left, int top, int right, int bottom);
     void setDensity(float density) { mDensity = density; }
     int drawFrame(nsecs_t frameTimeNanos, nsecs_t recordDurationNanos);
 
@@ -80,7 +79,6 @@
     /*********************************************
      *  Single frame data
      *********************************************/
-    Rect mDirty;
     nsecs_t mFrameTimeNanos;
     nsecs_t mRecordDurationNanos;
     float mDensity;
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 0901963..ded10a1 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -180,8 +180,7 @@
 }
 
 int RenderProxy::syncAndDrawFrame(nsecs_t frameTimeNanos, nsecs_t recordDurationNanos,
-        float density, int dirtyLeft, int dirtyTop, int dirtyRight, int dirtyBottom) {
-    mDrawFrameTask.setDirty(dirtyLeft, dirtyTop, dirtyRight, dirtyBottom);
+        float density) {
     mDrawFrameTask.setDensity(density);
     return mDrawFrameTask.drawFrame(frameTimeNanos, recordDurationNanos);
 }
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index 944ff9c..a95f8f0 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -70,7 +70,7 @@
     ANDROID_API void setup(int width, int height, const Vector3& lightCenter, float lightRadius);
     ANDROID_API void setOpaque(bool opaque);
     ANDROID_API int syncAndDrawFrame(nsecs_t frameTimeNanos, nsecs_t recordDurationNanos,
-            float density, int dirtyLeft, int dirtyTop, int dirtyRight, int dirtyBottom);
+            float density);
     ANDROID_API void destroyCanvasAndSurface();
 
     ANDROID_API void invokeFunctor(Functor* functor, bool waitForCompletion);
diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java
index bb23a36..394e437 100644
--- a/media/java/android/media/AudioAttributes.java
+++ b/media/java/android/media/AudioAttributes.java
@@ -17,6 +17,8 @@
 package android.media;
 
 import android.annotation.IntDef;
+import android.os.Parcel;
+import android.os.Parcelable;
 import android.util.Log;
 
 import java.lang.annotation.Retention;
@@ -29,7 +31,7 @@
  * A class to encapsulate a collection of attributes describing information about an audio
  * player or recorder.
  */
-public final class AudioAttributes {
+public final class AudioAttributes implements Parcelable {
     private final static String TAG = "AudioAttributes";
 
     /**
@@ -192,6 +194,7 @@
     }
 
     /**
+     * @hide
      * Return the set of tags.
      * @return a read-only set of all tags stored as strings.
      */
@@ -324,6 +327,7 @@
         }
 
         /**
+         * @hide
          * Add a custom tag stored as a string
          * @param tag
          * @return the same Builder instance.
@@ -410,6 +414,49 @@
                 + " tags=" + mTags);
     }
 
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mUsage);
+        dest.writeInt(mContentType);
+        dest.writeInt(mFlags);
+        String[] tagsArray = new String[mTags.size()];
+        mTags.toArray(tagsArray);
+        dest.writeStringArray(tagsArray);
+    }
+
+    private AudioAttributes(Parcel in) {
+        mUsage = in.readInt();
+        mContentType = in.readInt();
+        mFlags = in.readInt();
+        mTags = new HashSet<String>();
+        String[] tagsArray = in.readStringArray();
+        for (int i = tagsArray.length - 1 ; i >= 0 ; i--) {
+            mTags.add(tagsArray[i]);
+        }
+    }
+
+    /** @hide */
+    public static final Parcelable.Creator<AudioAttributes> CREATOR
+            = new Parcelable.Creator<AudioAttributes>() {
+        /**
+         * Rebuilds an AudioAttributes previously stored with writeToParcel().
+         * @param p Parcel object to read the AudioAttributes from
+         * @return a new AudioAttributes created from the data in the parcel
+         */
+        public AudioAttributes createFromParcel(Parcel p) {
+            return new AudioAttributes(p);
+        }
+        public AudioAttributes[] newArray(int size) {
+            return new AudioAttributes[size];
+        }
+    };
+
+
     /** @hide */
     @IntDef({
         USAGE_UNKNOWN,
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 84d4ab6..88756d7 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -3188,15 +3188,11 @@
                 do {
                     newPorts.clear();
                     status = AudioSystem.listAudioPorts(newPorts, portGeneration);
-                    Log.i(TAG, "updateAudioPortCache AudioSystem.listAudioPorts() status: "+
-                                    status+" num ports: "+ newPorts.size() +" portGeneration: "+portGeneration[0]);
                     if (status != SUCCESS) {
                         return status;
                     }
                     newPatches.clear();
                     status = AudioSystem.listAudioPatches(newPatches, patchGeneration);
-                    Log.i(TAG, "updateAudioPortCache AudioSystem.listAudioPatches() status: "+
-                            status+" num patches: "+ newPatches.size() +" patchGeneration: "+patchGeneration[0]);
                     if (status != SUCCESS) {
                         return status;
                     }
@@ -3204,14 +3200,16 @@
 
                 for (int i = 0; i < newPatches.size(); i++) {
                     for (int j = 0; j < newPatches.get(i).sources().length; j++) {
-                        AudioPortConfig portCfg = updatePortConfig(newPatches.get(i).sources()[j], newPorts);
+                        AudioPortConfig portCfg = updatePortConfig(newPatches.get(i).sources()[j],
+                                                                   newPorts);
                         if (portCfg == null) {
                             return ERROR;
                         }
                         newPatches.get(i).sources()[j] = portCfg;
                     }
                     for (int j = 0; j < newPatches.get(i).sinks().length; j++) {
-                        AudioPortConfig portCfg = updatePortConfig(newPatches.get(i).sinks()[j], newPorts);
+                        AudioPortConfig portCfg = updatePortConfig(newPatches.get(i).sinks()[j],
+                                                                   newPorts);
                         if (portCfg == null) {
                             return ERROR;
                         }
@@ -3242,8 +3240,6 @@
             // compare handles because the port returned by JNI is not of the correct
             // subclass
             if (ports.get(k).handle().equals(port.handle())) {
-                Log.i(TAG, "updatePortConfig match found for port handle: "+
-                            port.handle().id()+" port: "+ k);
                 port = ports.get(k);
                 break;
             }
diff --git a/media/java/android/media/AudioPort.java b/media/java/android/media/AudioPort.java
index fbd5022..8b74842 100644
--- a/media/java/android/media/AudioPort.java
+++ b/media/java/android/media/AudioPort.java
@@ -133,7 +133,7 @@
      * Get the gain descriptor at a given index
      */
     AudioGain gain(int index) {
-        if (index < mGains.length) {
+        if (index < 0 || index >= mGains.length) {
             return null;
         }
         return mGains[index];
diff --git a/media/java/android/media/AudioPortEventHandler.java b/media/java/android/media/AudioPortEventHandler.java
index 782ecd8..d5fea07 100644
--- a/media/java/android/media/AudioPortEventHandler.java
+++ b/media/java/android/media/AudioPortEventHandler.java
@@ -56,7 +56,6 @@
             mHandler = new Handler(looper) {
                 @Override
                 public void handleMessage(Message msg) {
-                    Log.i(TAG, "handleMessage: "+msg.what);
                     ArrayList<AudioManager.OnAudioPortUpdateListener> listeners;
                     synchronized (this) {
                         if (msg.what == AUDIOPORT_EVENT_NEW_LISTENER) {
diff --git a/media/java/android/media/WebVttRenderer.java b/media/java/android/media/WebVttRenderer.java
index 1c9730f..7977988 100644
--- a/media/java/android/media/WebVttRenderer.java
+++ b/media/java/android/media/WebVttRenderer.java
@@ -1103,6 +1103,9 @@
  */
 class WebVttRenderingWidget extends ViewGroup implements SubtitleTrack.RenderingWidget {
     private static final boolean DEBUG = false;
+
+    private static final CaptionStyle DEFAULT_CAPTION_STYLE = CaptionStyle.DEFAULT;
+
     private static final int DEBUG_REGION_BACKGROUND = 0x800000FF;
     private static final int DEBUG_CUE_BACKGROUND = 0x80FF0000;
 
@@ -1144,7 +1147,8 @@
         this(context, attrs, defStyleAttr, 0);
     }
 
-    public WebVttRenderingWidget(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+    public WebVttRenderingWidget(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
 
         // Cannot render text over video when layer type is hardware.
@@ -1259,6 +1263,7 @@
     }
 
     private void setCaptionStyle(CaptionStyle captionStyle, float fontSize) {
+        captionStyle = DEFAULT_CAPTION_STYLE.applyStyle(captionStyle);
         mCaptionStyle = captionStyle;
         mFontSize = fontSize;
 
diff --git a/media/java/android/media/tv/ITvInputClient.aidl b/media/java/android/media/tv/ITvInputClient.aidl
index dc79a73..011da35 100644
--- a/media/java/android/media/tv/ITvInputClient.aidl
+++ b/media/java/android/media/tv/ITvInputClient.aidl
@@ -31,5 +31,7 @@
     void onAvailabilityChanged(in String inputId, boolean isAvailable);
     void onSessionReleased(int seq);
     void onSessionEvent(in String name, in Bundle args, int seq);
-    void onVideoSizeChanged(int width, int height, int seq);
+    void onVideoStreamChanged(int width, int height, boolean interlaced, int seq);
+    void onAudioStreamChanged(int channelCount, int seq);
+    void onClosedCaptionStreamChanged(boolean hasClosedCaption, int seq);
 }
diff --git a/media/java/android/media/tv/ITvInputSessionCallback.aidl b/media/java/android/media/tv/ITvInputSessionCallback.aidl
index 71f2d07..00f2922a 100644
--- a/media/java/android/media/tv/ITvInputSessionCallback.aidl
+++ b/media/java/android/media/tv/ITvInputSessionCallback.aidl
@@ -27,5 +27,7 @@
 oneway interface ITvInputSessionCallback {
     void onSessionCreated(ITvInputSession session);
     void onSessionEvent(in String name, in Bundle args);
-    void onVideoSizeChanged(int width, int height);
+    void onVideoStreamChanged(int width, int height, boolean interlaced);
+    void onAudioStreamChanged(int channelCount);
+    void onClosedCaptionStreamChanged(boolean hasClosedCaption);
 }
diff --git a/media/java/android/media/tv/ITvInputSessionWrapper.java b/media/java/android/media/tv/ITvInputSessionWrapper.java
index 975e391..d20ee0e 100644
--- a/media/java/android/media/tv/ITvInputSessionWrapper.java
+++ b/media/java/android/media/tv/ITvInputSessionWrapper.java
@@ -18,8 +18,6 @@
 
 import android.content.Context;
 import android.graphics.Rect;
-import android.media.tv.TvInputManager.Session;
-import android.media.tv.TvInputService.TvInputSessionImpl;
 import android.net.Uri;
 import android.os.IBinder;
 import android.os.Looper;
@@ -52,11 +50,11 @@
 
     private final HandlerCaller mCaller;
 
-    private TvInputSessionImpl mTvInputSessionImpl;
+    private TvInputService.Session mTvInputSessionImpl;
     private InputChannel mChannel;
     private TvInputEventReceiver mReceiver;
 
-    public ITvInputSessionWrapper(Context context, TvInputSessionImpl sessionImpl,
+    public ITvInputSessionWrapper(Context context, TvInputService.Session sessionImpl,
             InputChannel channel) {
         mCaller = new HandlerCaller(context, null, this, true /* asyncHandler */);
         mTvInputSessionImpl = sessionImpl;
@@ -169,8 +167,8 @@
             }
 
             int handled = mTvInputSessionImpl.dispatchInputEvent(event, this);
-            if (handled != Session.DISPATCH_IN_PROGRESS) {
-                finishInputEvent(event, handled == Session.DISPATCH_HANDLED);
+            if (handled != TvInputManager.Session.DISPATCH_IN_PROGRESS) {
+                finishInputEvent(event, handled == TvInputManager.Session.DISPATCH_HANDLED);
             }
         }
     }
diff --git a/media/java/android/media/tv/TvContract.java b/media/java/android/media/tv/TvContract.java
index 6e0586e..5e650c2 100644
--- a/media/java/android/media/tv/TvContract.java
+++ b/media/java/android/media/tv/TvContract.java
@@ -86,6 +86,27 @@
     }
 
     /**
+     * Builds a URI that points to a channel logo. See {@link Channels.Logo}.
+     *
+     * @param channelId The ID of the channel whose logo is pointed to.
+     */
+    public static final Uri buildChannelLogoUri(long channelId) {
+        return buildChannelLogoUri(buildChannelUri(channelId));
+    }
+
+    /**
+     * Builds a URI that points to a channel logo. See {@link Channels.Logo}.
+     *
+     * @param channelUri The URI of the channel whose logo is pointed to.
+     */
+    public static final Uri buildChannelLogoUri(Uri channelUri) {
+        if (!PATH_CHANNEL.equals(channelUri.getPathSegments().get(0))) {
+            throw new IllegalArgumentException("Not a channel: " + channelUri);
+        }
+        return Uri.withAppendedPath(channelUri, Channels.Logo.CONTENT_DIRECTORY);
+    }
+
+    /**
      * Builds a URI that points to all browsable channels from a given TV input.
      *
      * @param name {@link ComponentName} of the {@link android.media.tv.TvInputService} that
@@ -523,6 +544,48 @@
         public static final String COLUMN_VERSION_NUMBER = "version_number";
 
         private Channels() {}
+
+        /**
+         * A sub-directory of a single TV channel that represents its primary logo.
+         * <p>
+         * To access this directory, append {@link Channels.Logo#CONTENT_DIRECTORY} to the raw
+         * channel URI.  The resulting URI represents an image file, and should be interacted
+         * using ContentResolver.openAssetFileDescriptor.
+         * </p>
+         * <p>
+         * Note that this sub-directory also supports opening the logo as an asset file in write
+         * mode.  Callers can create or replace the primary logo associated with this channel by
+         * opening the asset file and writing the full-size photo contents into it.  When the file
+         * is closed, the image will be parsed, sized down if necessary, and stored.
+         * </p>
+         * <p>
+         * Usage example:
+         * <pre>
+         * public void writeChannelLogo(long channelId, byte[] logo) {
+         *     Uri channelLogoUri = TvContract.buildChannelLogoUri(channelId);
+         *     try {
+         *         AssetFileDescriptor fd =
+         *             getContentResolver().openAssetFileDescriptor(channelLogoUri, "rw");
+         *         OutputStream os = fd.createOutputStream();
+         *         os.write(logo);
+         *         os.close();
+         *         fd.close();
+         *     } catch (IOException e) {
+         *         // Handle error cases.
+         *     }
+         * }
+         * </pre>
+         * </p>
+         */
+        public static final class Logo {
+
+            /**
+             * The directory twig for this sub-table.
+             */
+            public static final String CONTENT_DIRECTORY = "logo";
+
+            private Logo() {}
+        }
     }
 
     /** Column definitions for the TV programs table. */
@@ -631,6 +694,26 @@
         public static final String COLUMN_AUDIO_LANGUAGE = "audio_language";
 
         /**
+         * The URI for the poster art of this TV program.
+         * <p>
+         * Can be empty.
+         * </p><p>
+         * Type: TEXT
+         * </p>
+         */
+        public static final String COLUMN_POSTER_ART_URI = "poster_art_uri";
+
+        /**
+         * The URI for the thumbnail of this TV program.
+         * <p>
+         * Can be empty.
+         * </p><p>
+         * Type: TEXT
+         * </p>
+         */
+        public static final String COLUMN_THUMBNAIL_URI = "thumbnail_uri";
+
+        /**
          * Internal data used by individual TV input services.
          * <p>
          * This is internal to the provider that inserted it, and should not be decoded by other
diff --git a/media/java/android/media/tv/TvInputInfo.java b/media/java/android/media/tv/TvInputInfo.java
index ed599ed..9525c08 100644
--- a/media/java/android/media/tv/TvInputInfo.java
+++ b/media/java/android/media/tv/TvInputInfo.java
@@ -138,21 +138,15 @@
     }
 
     /**
-     * Returns the .apk package that implements this TV input service.
+     * Returns the information of the service that implements this TV input.
      */
-    public String getPackageName() {
-        return mService.serviceInfo.packageName;
-    }
-
-    /**
-     * Returns the class name of the service component that implements this TV input service.
-     */
-    public String getServiceName() {
-        return mService.serviceInfo.name;
+    public ServiceInfo getServiceInfo() {
+        return mService.serviceInfo;
     }
 
     /**
      * Returns the component of the service that implements this TV input.
+     * @hide
      */
     public ComponentName getComponent() {
         return new ComponentName(mService.serviceInfo.packageName, mService.serviceInfo.name);
@@ -164,8 +158,8 @@
     public Intent getIntentForSetupActivity() {
         if (!TextUtils.isEmpty(mSetupActivity)) {
             Intent intent = new Intent(Intent.ACTION_MAIN);
-            intent.setClassName(getPackageName(), mSetupActivity);
-            intent.putExtra(EXTRA_SERVICE_NAME, getServiceName());
+            intent.setClassName(mService.serviceInfo.packageName, mSetupActivity);
+            intent.putExtra(EXTRA_SERVICE_NAME, mService.serviceInfo.name);
             return intent;
         }
         return null;
@@ -177,8 +171,8 @@
     public Intent getIntentForSettingsActivity() {
         if (!TextUtils.isEmpty(mSettingsActivity)) {
             Intent intent = new Intent(Intent.ACTION_MAIN);
-            intent.setClassName(getPackageName(), mSettingsActivity);
-            intent.putExtra(EXTRA_SERVICE_NAME, getServiceName());
+            intent.setClassName(mService.serviceInfo.packageName, mSettingsActivity);
+            intent.putExtra(EXTRA_SERVICE_NAME, mService.serviceInfo.name);
             return intent;
         }
         return null;
diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java
index 1335a1b..edfdd60 100644
--- a/media/java/android/media/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -67,6 +67,7 @@
 
     /**
      * Interface used to receive the created session.
+     * @hide
      */
     public abstract static class SessionCallback {
         /**
@@ -88,15 +89,39 @@
         }
 
         /**
-         * This is called at the beginning of the playback of a channel and later when the size of
-         * the video has been changed.
+         * This is called at the beginning of the playback of a channel and later when the format of
+         * the video stream has been changed.
          *
          * @param session A {@link TvInputManager.Session} associated with this callback
-         * @param width the width of the video
-         * @param height the height of the video
+         * @param width The width of the video.
+         * @param height The height of the video.
+         * @param interlaced whether the video is interlaced mode or planer mode.
          * @hide
          */
-        public void onVideoSizeChanged(Session session, int width, int height) {
+        public void onVideoStreamChanged(Session session, int width, int height,
+                boolean interlaced) {
+        }
+
+        /**
+         * This is called at the beginning of the playback of a channel and later when the format of
+         * the audio stream has been changed.
+         *
+         * @param session A {@link TvInputManager.Session} associated with this callback
+         * @param channelCount The number of channels in the audio stream.
+         * @hide
+         */
+        public void onAudioStreamChanged(Session session, int channelCount) {
+        }
+
+        /**
+         * This is called at the beginning of the playback of a channel and later when the closed
+         * caption stream has been changed.
+         *
+         * @param session A {@link TvInputManager.Session} associated with this callback
+         * @param hasClosedCaption Whether the stream has closed caption or not.
+         * @hide
+         */
+        public void onClosedCaptionStreamChanged(Session session, boolean hasClosedCaption) {
         }
 
         /**
@@ -141,11 +166,30 @@
             });
         }
 
-        public void postVideoSizeChanged(final int width, final int height) {
+        public void postVideoStreamChanged(final int width, final int height,
+                final boolean interlaced) {
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
-                    mSessionCallback.onVideoSizeChanged(mSession, width, height);
+                    mSessionCallback.onVideoStreamChanged(mSession, width, height, interlaced);
+                }
+            });
+        }
+
+        public void postAudioStreamChanged(final int channelCount) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mSessionCallback.onAudioStreamChanged(mSession, channelCount);
+                }
+            });
+        }
+
+        public void postClosedCaptionStreamChanged(final boolean hasClosedCaption) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mSessionCallback.onClosedCaptionStreamChanged(mSession, hasClosedCaption);
                 }
             });
         }
@@ -238,14 +282,38 @@
             }
 
             @Override
-            public void onVideoSizeChanged(int width, int height, int seq) {
+            public void onVideoStreamChanged(int width, int height, boolean interlaced, int seq) {
                 synchronized (mSessionCallbackRecordMap) {
                     SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
                     if (record == null) {
                         Log.e(TAG, "Callback not found for seq " + seq);
                         return;
                     }
-                    record.postVideoSizeChanged(width, height);
+                    record.postVideoStreamChanged(width, height, interlaced);
+                }
+            }
+
+            @Override
+            public void onAudioStreamChanged(int channelCount, int seq) {
+                synchronized (mSessionCallbackRecordMap) {
+                    SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
+                    if (record == null) {
+                        Log.e(TAG, "Callback not found for seq " + seq);
+                        return;
+                    }
+                    record.postAudioStreamChanged(channelCount);
+                }
+            }
+
+            @Override
+            public void onClosedCaptionStreamChanged(boolean hasClosedCaption, int seq) {
+                synchronized (mSessionCallbackRecordMap) {
+                    SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
+                    if (record == null) {
+                        Log.e(TAG, "Callback not found for seq " + seq);
+                        return;
+                    }
+                    record.postClosedCaptionStreamChanged(hasClosedCaption);
                 }
             }
 
@@ -323,6 +391,7 @@
      * @param listener a listener used to monitor status of the given TV input.
      * @param handler a {@link Handler} that the status change will be delivered to.
      * @throws IllegalArgumentException if any of the arguments is {@code null}.
+     * @hide
      */
     public void registerListener(String inputId, TvInputListener listener, Handler handler) {
         if (inputId == null) {
@@ -355,6 +424,7 @@
      * @param inputId the id of the TV input.
      * @param listener the existing listener to remove for the given TV input.
      * @throws IllegalArgumentException if any of the arguments is {@code null}.
+     * @hide
      */
     public void unregisterListener(String inputId, final TvInputListener listener) {
         if (inputId == null) {
@@ -398,6 +468,7 @@
      * @param callback a callback used to receive the created session.
      * @param handler a {@link Handler} that the session creation will be delivered to.
      * @throws IllegalArgumentException if any of the arguments is {@code null}.
+     * @hide
      */
     public void createSession(String inputId, final SessionCallback callback,
             Handler handler) {
@@ -422,7 +493,10 @@
         }
     }
 
-    /** The Session provides the per-session functionality of TV inputs. */
+    /**
+     * The Session provides the per-session functionality of TV inputs.
+     * @hide
+     */
     public static final class Session {
         static final int DISPATCH_IN_PROGRESS = -1;
         static final int DISPATCH_NOT_HANDLED = 0;
@@ -495,13 +569,13 @@
         }
 
         /**
-         * Sets the relative volume of this session to handle a change of audio focus.
+         * Sets the relative stream volume of this session to handle a change of audio focus.
          *
          * @param volume A volume value between 0.0f to 1.0f.
          * @throws IllegalArgumentException if the volume value is out of range.
          * @throws IllegalStateException if the session has been already released.
          */
-        public void setVolume(float volume) {
+        public void setStreamVolume(float volume) {
             if (mToken == null) {
                 throw new IllegalStateException("the session has been already released");
             }
diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java
index 3213019..409a33c 100644
--- a/media/java/android/media/tv/TvInputService.java
+++ b/media/java/android/media/tv/TvInputService.java
@@ -22,8 +22,6 @@
 import android.content.Intent;
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
-import android.media.tv.ITvInputService;
-import android.media.tv.TvInputManager.Session;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
@@ -47,7 +45,17 @@
 import com.android.internal.os.SomeArgs;
 
 /**
- * A base class for implementing television input service.
+ * The TvInputService class represents a TV input or source such as HDMI or built-in tuner which
+ * provides pass-through video or broadcast TV programs.
+ * <p>
+ * Applications will not normally use this service themselves, instead relying on the standard
+ * interaction provided by {@link TvView}. Those implementing TV input services should normally do
+ * so by deriving from this class and providing their own session implementation based on
+ * {@link TvInputService.Session}. All TV input services must require that clients hold the
+ * {@link android.Manifest.permission#BIND_TV_INPUT} in order to interact with the service; if this
+ * permission is not specified in the manifest, the system will refuse to bind to that TV input
+ * service.
+ * </p>
  */
 public abstract class TvInputService extends Service {
     // STOPSHIP: Turn debugging off.
@@ -74,7 +82,9 @@
     private final Handler mHandler = new ServiceHandler();
     private final RemoteCallbackList<ITvInputServiceCallback> mCallbacks =
             new RemoteCallbackList<ITvInputServiceCallback>();
-    private boolean mAvailable;
+    // STOPSHIP: Redesign the API around the availability change. For now, the service will be
+    // always available.
+    private final boolean mAvailable = true;
 
     @Override
     public void onCreate() {
@@ -124,19 +134,6 @@
     }
 
     /**
-     * Convenience method to notify an availability change of this TV input service.
-     *
-     * @param available {@code true} if the input service is available to show TV programs.
-     */
-    public final void setAvailable(boolean available) {
-        if (available != mAvailable) {
-            mAvailable = available;
-            mHandler.obtainMessage(ServiceHandler.DO_BROADCAST_AVAILABILITY_CHANGE, available)
-                    .sendToTarget();
-        }
-    }
-
-    /**
      * Get the number of callbacks that are registered.
      *
      * @hide
@@ -147,17 +144,17 @@
     }
 
     /**
-     * Returns a concrete implementation of {@link TvInputSessionImpl}.
+     * Returns a concrete implementation of {@link Session}.
      * <p>
      * May return {@code null} if this TV input service fails to create a session for some reason.
      * </p>
      */
-    public abstract TvInputSessionImpl onCreateSession();
+    public abstract Session onCreateSession();
 
     /**
-     * Base class for derived classes to implement to provide {@link TvInputManager.Session}.
+     * Base class for derived classes to implement to provide a TV input session.
      */
-    public abstract class TvInputSessionImpl implements KeyEvent.Callback {
+    public abstract class Session implements KeyEvent.Callback {
         private final KeyEvent.DispatcherState mDispatcherState = new KeyEvent.DispatcherState();
         private final WindowManager mWindowManager;
         private WindowManager.LayoutParams mWindowParams;
@@ -168,7 +165,7 @@
         private Rect mOverlayFrame;
         private ITvInputSessionCallback mSessionCallback;
 
-        public TvInputSessionImpl() {
+        public Session() {
             mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
         }
 
@@ -223,20 +220,22 @@
         }
 
         /**
-         * Sends the change on the size of the video. This is expected to be called at the
-         * beginning of the playback and later when the size has been changed.
+         * Sends the change on the format of the video stream. This is expected to be called at the
+         * beginning of the playback and later when the format has been changed.
          *
          * @param width The width of the video.
          * @param height The height of the video.
+         * @param interlaced Whether the video is interlaced mode or planer mode.
          * @hide
          */
-        public void dispatchVideoSizeChanged(final int width, final int height) {
+        public void dispatchVideoStreamChanged(final int width, final int height,
+                final boolean interlaced) {
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
                     try {
                         if (DEBUG) Log.d(TAG, "dispatchVideoSizeChanged");
-                        mSessionCallback.onVideoSizeChanged(width, height);
+                        mSessionCallback.onVideoStreamChanged(width, height, interlaced);
                     } catch (RemoteException e) {
                         Log.w(TAG, "error in dispatchVideoSizeChanged");
                     }
@@ -245,6 +244,48 @@
         }
 
         /**
+         * Sends the change on the format of the audio stream. This is expected to be called at the
+         * beginning of the playback and later when the format has been changed.
+         *
+         * @param channelNumber The number of channels in the audio stream.
+         * @hide
+         */
+        public void dispatchAudioStreamChanged(final int channelNumber) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    try {
+                        if (DEBUG) Log.d(TAG, "dispatchAudioStreamChanged");
+                        mSessionCallback.onAudioStreamChanged(channelNumber);
+                    } catch (RemoteException e) {
+                        Log.w(TAG, "error in dispatchAudioStreamChanged");
+                    }
+                }
+            });
+        }
+
+        /**
+         * Sends the change on the closed caption stream. This is expected to be called at the
+         * beginning of the playback and later when the stream has been changed.
+         *
+         * @param hasClosedCaption Whether the stream has closed caption or not.
+         * @hide
+         */
+        public void dispatchClosedCaptionStreamChanged(final boolean hasClosedCaption) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    try {
+                        if (DEBUG) Log.d(TAG, "dispatchClosedCaptionStreamChanged");
+                        mSessionCallback.onClosedCaptionStreamChanged(hasClosedCaption);
+                    } catch (RemoteException e) {
+                        Log.w(TAG, "error in dispatchClosedCaptionStreamChanged");
+                    }
+                }
+            });
+        }
+
+        /**
          * Called when the session is released.
          */
         public abstract void onRelease();
@@ -259,12 +300,12 @@
         public abstract boolean onSetSurface(Surface surface);
 
         /**
-         * Sets the relative volume of the current TV input session to handle the change of audio
-         * focus by setting.
+         * Sets the relative stream volume of the current TV input session to handle the change of
+         * audio focus by setting.
          *
          * @param volume Volume scale from 0.0 to 1.0.
          */
-        public abstract void onSetVolume(float volume);
+        public abstract void onSetStreamVolume(float volume);
 
         /**
          * Tunes to a given channel.
@@ -425,10 +466,10 @@
         }
 
         /**
-         * Calls {@link #onSetVolume}.
+         * Calls {@link #onSetStreamVolume}.
          */
         void setVolume(float volume) {
-            onSetVolume(volume);
+            onSetStreamVolume(volume);
         }
 
         /**
@@ -521,33 +562,33 @@
             if (DEBUG) Log.d(TAG, "dispatchInputEvent(" + event + ")");
             if (event instanceof KeyEvent) {
                 if (((KeyEvent) event).dispatch(this, mDispatcherState, this)) {
-                    return Session.DISPATCH_HANDLED;
+                    return TvInputManager.Session.DISPATCH_HANDLED;
                 }
             } else if (event instanceof MotionEvent) {
                 MotionEvent motionEvent = (MotionEvent) event;
                 final int source = motionEvent.getSource();
                 if (motionEvent.isTouchEvent()) {
                     if (onTouchEvent(motionEvent)) {
-                        return Session.DISPATCH_HANDLED;
+                        return TvInputManager.Session.DISPATCH_HANDLED;
                     }
                 } else if ((source & InputDevice.SOURCE_CLASS_TRACKBALL) != 0) {
                     if (onTrackballEvent(motionEvent)) {
-                        return Session.DISPATCH_HANDLED;
+                        return TvInputManager.Session.DISPATCH_HANDLED;
                     }
                 } else {
                     if (onGenericMotionEvent(motionEvent)) {
-                        return Session.DISPATCH_HANDLED;
+                        return TvInputManager.Session.DISPATCH_HANDLED;
                     }
                 }
             }
             if (mOverlayView == null || !mOverlayView.isAttachedToWindow()) {
-                return Session.DISPATCH_NOT_HANDLED;
+                return TvInputManager.Session.DISPATCH_NOT_HANDLED;
             }
             if (!mOverlayView.hasWindowFocus()) {
                 mOverlayView.getViewRootImpl().windowFocusChanged(true, true);
             }
             mOverlayView.getViewRootImpl().dispatchInputEvent(event, receiver);
-            return Session.DISPATCH_IN_PROGRESS;
+            return TvInputManager.Session.DISPATCH_IN_PROGRESS;
         }
 
         private void setSessionCallback(ITvInputSessionCallback callback) {
@@ -567,7 +608,7 @@
                     InputChannel channel = (InputChannel) args.arg1;
                     ITvInputSessionCallback cb = (ITvInputSessionCallback) args.arg2;
                     try {
-                        TvInputSessionImpl sessionImpl = onCreateSession();
+                        Session sessionImpl = onCreateSession();
                         if (sessionImpl == null) {
                             // Failed to create a session.
                             cb.onSessionCreated(null);
diff --git a/media/java/android/media/tv/TvView.java b/media/java/android/media/tv/TvView.java
index 126d739..c2459a6 100644
--- a/media/java/android/media/tv/TvView.java
+++ b/media/java/android/media/tv/TvView.java
@@ -21,6 +21,7 @@
 import android.media.tv.TvInputManager.Session;
 import android.media.tv.TvInputManager.Session.FinishedInputEventCallback;
 import android.media.tv.TvInputManager.SessionCallback;
+import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
 import android.text.TextUtils;
@@ -38,9 +39,21 @@
  * View playing TV
  */
 public class TvView extends SurfaceView {
+    private static final String TAG = "TvView";
     // STOPSHIP: Turn debugging off.
     private static final boolean DEBUG = true;
-    private static final String TAG = "TvView";
+
+    /**
+     * Passed with {@link TvInputListener#onError(String, int)}. Indicates that the requested TV
+     * input is busy and unable to handle the request.
+     */
+    public static final int ERROR_BUSY = 0;
+
+    /**
+     * Passed with {@link TvInputListener#onError(String, int)}. Indicates that the underlying TV
+     * input has been disconnected.
+     */
+    public static final int ERROR_TV_INPUT_DISCONNECTED = 1;
 
     private final Handler mHandler = new Handler();
     private TvInputManager.Session mSession;
@@ -48,7 +61,8 @@
     private boolean mOverlayViewCreated;
     private Rect mOverlayViewFrame;
     private final TvInputManager mTvInputManager;
-    private SessionCallback mSessionCallback;
+    private MySessionCallback mSessionCallback;
+    private TvInputListener mListener;
     private OnUnhandledInputEventListener mOnUnhandledInputEventListener;
 
     private final SurfaceHolder.Callback mSurfaceHolderCallback = new SurfaceHolder.Callback() {
@@ -113,44 +127,70 @@
     }
 
     /**
-     * Binds a TV input to this view. {@link SessionCallback#onSessionCreated} will be
-     * called to send the result of this binding with {@link TvInputManager.Session}.
-     * If a TV input is already bound, the input will be unbound from this view and its session
-     * will be released.
+     * Sets a listener for events in this TvView.
      *
-     * @param inputId the id of TV input which will be bound to this view.
-     * @param callback called when TV input is bound. The callback sends
-     *        {@link TvInputManager.Session}
-     * @throws IllegalArgumentException if any of the arguments is {@code null}.
+     * @param listener The listener to be called with events. A value of {@code null} removes any
+     *         existing listener.
      */
-    public void bindTvInput(String inputId, SessionCallback callback) {
-        if (TextUtils.isEmpty(inputId)) {
-            throw new IllegalArgumentException("inputId cannot be null or an empty string");
-        }
-        if (callback == null) {
-            throw new IllegalArgumentException("callback cannot be null");
-        }
-        if (mSession != null) {
-            release();
-        }
-        // When bindTvInput is called multiple times before the callback is called,
-        // only the callback of the last bindTvInput call will be actually called back.
-        // The previous callbacks will be ignored. For the logic, mSessionCallback
-        // is newly assigned for every bindTvInput call and compared with
-        // MySessionCreateCallback.this.
-        mSessionCallback = new MySessionCallback(callback);
-        mTvInputManager.createSession(inputId, mSessionCallback, mHandler);
+    public void setTvInputListener(TvInputListener listener) {
+        mListener = listener;
     }
 
     /**
-     * Unbinds a TV input currently bound. Its corresponding {@link TvInputManager.Session}
-     * is released.
+     * Sets the relative stream volume of this session to handle a change of audio focus.
+     *
+     * @param volume A volume value between 0.0f to 1.0f.
      */
-    public void unbindTvInput() {
+    public void setStreamVolume(float volume) {
+        if (DEBUG) Log.d(TAG, "setStreamVolume(" + volume + ")");
+        if (mSession == null) {
+            return;
+        }
+        mSession.setStreamVolume(volume);
+    }
+
+    /**
+     * Tunes to a given channel.
+     *
+     * @param inputId the id of TV input which will play the given channel.
+     * @param channelUri The URI of a channel.
+     */
+    public void tune(String inputId, Uri channelUri) {
+        if (DEBUG) Log.d(TAG, "tune(" + channelUri + ")");
+        if (TextUtils.isEmpty(inputId)) {
+            throw new IllegalArgumentException("inputId cannot be null or an empty string");
+        }
+        if (mSessionCallback != null && mSessionCallback.mInputId.equals(inputId)) {
+            if (mSession != null) {
+                mSession.tune(channelUri);
+            } else {
+                // Session is not created yet. Replace the channel which will be set once the
+                // session is made.
+                mSessionCallback.mChannelUri = channelUri;
+            }
+        } else {
+            if (mSession != null) {
+                release();
+            }
+            // When createSession() is called multiple times before the callback is called,
+            // only the callback of the last createSession() call will be actually called back.
+            // The previous callbacks will be ignored. For the logic, mSessionCallback
+            // is newly assigned for every createSession request and compared with
+            // MySessionCreateCallback.this.
+            mSessionCallback = new MySessionCallback(inputId, channelUri);
+            mTvInputManager.createSession(inputId, mSessionCallback, mHandler);
+        }
+    }
+
+    /**
+     * Resets this TvView.
+     * <p>
+     * This method is primarily used to un-tune the current TvView.
+     */
+    public void reset() {
         if (mSession != null) {
             release();
         }
-        mSessionCallback = null;
     }
 
     /**
@@ -277,6 +317,7 @@
         removeSessionOverlayView();
         mSession.release();
         mSession = null;
+        mSessionCallback = null;
     }
 
     private void setSessionSurface(Surface surface) {
@@ -326,6 +367,71 @@
     }
 
     /**
+     * Interface used to receive various status updates on the {@link TvView}.
+     */
+    public abstract static class TvInputListener {
+
+        /**
+         * This is invoked when an error occurred while handling requested operation.
+         *
+         * @param inputId The ID of the TV input bound to this view.
+         * @param errorCode The error code. For the details of error code, please see
+         *         {@link TvView}.
+         */
+        public void onError(String inputId, int errorCode) {
+        }
+
+        /**
+         * This is invoked when the view is tuned to a specific channel and starts decoding video
+         * stream from there. It is also called later when the video format is changed.
+         *
+         * @param inputId The ID of the TV input bound to this view.
+         * @param width The width of the video.
+         * @param height The height of the video.
+         * @param interlaced {@code true} if the video is interlaced, {@code false} if the video is
+         *            progressive.
+         * @hide
+         */
+        public void onVideoStreamChanged(String inputId, int width, int height,
+                boolean interlaced) {
+        }
+
+        /**
+         * This is invoked when the view is tuned to a specific channel and starts decoding audio
+         * stream from there. It is also called later when the audio format is changed.
+         *
+         * @param inputId The ID of the TV input bound to this view.
+         * @param channelCount The number of channels in the audio stream.
+         * @hide
+         */
+        public void onAudioStreamChanged(String inputId, int channelCount) {
+        }
+
+        /**
+         * This is invoked when the view is tuned to a specific channel and starts decoding data
+         * stream that includes subtitle information from the channel. It is also called later when
+         * the information disappears or appears.
+         *
+         * @param inputId The ID of the TV input bound to this view.
+         * @param hasClosedCaption {@code true} if the stream contains closed caption, {@code false}
+         *            otherwise.
+         * @hide
+         */
+        public void onClosedCaptionStreamChanged(String inputId, boolean hasClosedCaption) {
+        }
+
+        /**
+         * This is invoked when a custom event from the bound TV input is sent to this view.
+         *
+         * @param eventType The type of the event.
+         * @param eventArgs Optional arguments of the event.
+         * @hide
+         */
+        public void onEvent(String inputId, String eventType, Bundle eventArgs) {
+        }
+    }
+
+    /**
      * Interface definition for a callback to be invoked when the unhandled input event is received.
      */
     public interface OnUnhandledInputEventListener {
@@ -343,10 +449,12 @@
     }
 
     private class MySessionCallback extends SessionCallback {
-        final SessionCallback mExternalCallback;
+        final String mInputId;
+        Uri mChannelUri;
 
-        MySessionCallback(SessionCallback externalCallback) {
-            mExternalCallback = externalCallback;
+        MySessionCallback(String inputId, Uri channelUri) {
+            mInputId = inputId;
+            mChannelUri = channelUri;
         }
 
         @Override
@@ -367,35 +475,59 @@
                     setSessionSurface(mSurface);
                 }
                 createSessionOverlayView();
-            }
-            if (mExternalCallback != null) {
-                mExternalCallback.onSessionCreated(session);
+                mSession.tune(mChannelUri);
+            } else {
+                if (mListener != null) {
+                    mListener.onError(mInputId, ERROR_BUSY);
+                }
             }
         }
 
         @Override
         public void onSessionReleased(Session session) {
             mSession = null;
-            if (mExternalCallback != null) {
-                mExternalCallback.onSessionReleased(session);
+            mSessionCallback = null;
+            if (mListener != null) {
+                mListener.onError(mInputId, ERROR_TV_INPUT_DISCONNECTED);
             }
         }
 
         @Override
-        public void onVideoSizeChanged(Session session, int width, int height) {
+        public void onVideoStreamChanged(Session session, int width, int height,
+                boolean interlaced) {
             if (DEBUG) {
                 Log.d(TAG, "onVideoSizeChanged(" + width + ", " + height + ")");
             }
-            if (mExternalCallback != null) {
-                mExternalCallback.onVideoSizeChanged(session, width, height);
+            if (mListener != null) {
+                mListener.onVideoStreamChanged(mInputId, width, height, interlaced);
+            }
+        }
+
+        @Override
+        public void onAudioStreamChanged(Session session, int channelCount) {
+            if (DEBUG) {
+                Log.d(TAG, "onAudioStreamChanged(" + channelCount + ")");
+            }
+            if (mListener != null) {
+                mListener.onAudioStreamChanged(mInputId, channelCount);
+            }
+        }
+
+        @Override
+        public void onClosedCaptionStreamChanged(Session session, boolean hasClosedCaption) {
+            if (DEBUG) {
+                Log.d(TAG, "onClosedCaptionStreamChanged(" + hasClosedCaption + ")");
+            }
+            if (mListener != null) {
+                mListener.onClosedCaptionStreamChanged(mInputId, hasClosedCaption);
             }
         }
 
         @Override
         public void onSessionEvent(TvInputManager.Session session, String eventType,
                 Bundle eventArgs) {
-            if (mExternalCallback != null) {
-                mExternalCallback.onSessionEvent(session, eventType, eventArgs);
+            if (mListener != null) {
+                mListener.onEvent(mInputId, eventType, eventArgs);
             }
         }
     }
diff --git a/media/jni/android_media_MediaScanner.cpp b/media/jni/android_media_MediaScanner.cpp
index d21b442..6730e0a 100644
--- a/media/jni/android_media_MediaScanner.cpp
+++ b/media/jni/android_media_MediaScanner.cpp
@@ -21,6 +21,7 @@
 #include <utils/threads.h>
 #include <media/mediascanner.h>
 #include <media/stagefright/StagefrightMediaScanner.h>
+#include <private/media/VideoFrame.h>
 
 #include "jni.h"
 #include "JNIHelp.h"
@@ -347,21 +348,21 @@
     }
 
     int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
-    char* data = mp->extractAlbumArt(fd);
-    if (!data) {
+    MediaAlbumArt* mediaAlbumArt =
+            reinterpret_cast<MediaAlbumArt*>(mp->extractAlbumArt(fd));
+    if (mediaAlbumArt != NULL) {
         return NULL;
     }
-    jsize len = *((uint32_t*)data);
 
-    jbyteArray array = env->NewByteArray(len);
+    jbyteArray array = env->NewByteArray(mediaAlbumArt->mSize);
     if (array != NULL) {
         jbyte* bytes = env->GetByteArrayElements(array, NULL);
-        memcpy(bytes, data + 4, len);
+        memcpy(bytes, &mediaAlbumArt->mData[0], mediaAlbumArt->mSize);
         env->ReleaseByteArrayElements(array, bytes, 0);
     }
 
 done:
-    free(data);
+    free(mediaAlbumArt);
     // if NewByteArray() returned NULL, an out-of-memory
     // exception will have been raised. I just want to
     // return null in that case.
diff --git a/packages/Keyguard/res/layout/keyguard_status_view.xml b/packages/Keyguard/res/layout/keyguard_status_view.xml
index 112e371a..2917faa 100644
--- a/packages/Keyguard/res/layout/keyguard_status_view.xml
+++ b/packages/Keyguard/res/layout/keyguard_status_view.xml
@@ -48,5 +48,18 @@
             android:layout_marginBottom="@dimen/bottom_text_spacing_digital" />
 
         <include layout="@layout/keyguard_status_area" />
+        <TextView
+            android:id="@+id/owner_info"
+            android:layout_marginLeft="16dp"
+            android:layout_marginRight="16dp"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="@dimen/date_owner_info_margin"
+            android:layout_gravity="center_horizontal"
+            android:textColor="#99ffffff"
+            android:textSize="@dimen/widget_label_font_size"
+            android:ellipsize="marquee"
+            android:singleLine="true" />
+
     </LinearLayout>
 </com.android.keyguard.KeyguardStatusView>
diff --git a/packages/Keyguard/res/values-sw600dp/dimens.xml b/packages/Keyguard/res/values-sw600dp/dimens.xml
index b954792..e9e9b89 100644
--- a/packages/Keyguard/res/values-sw600dp/dimens.xml
+++ b/packages/Keyguard/res/values-sw600dp/dimens.xml
@@ -70,4 +70,7 @@
     <!-- EmergencyCarrierArea overlap - amount to overlap the emergency button and carrier text.
          Should be 0 on devices with plenty of room (e.g. tablets) -->
     <dimen name="eca_overlap">0dip</dimen>
+
+    <!-- The vertical margin between the date and the owner info. -->
+    <dimen name="date_owner_info_margin">4dp</dimen>
 </resources>
diff --git a/packages/Keyguard/res/values/dimens.xml b/packages/Keyguard/res/values/dimens.xml
index e9cdfcd..f971522 100644
--- a/packages/Keyguard/res/values/dimens.xml
+++ b/packages/Keyguard/res/values/dimens.xml
@@ -163,4 +163,7 @@
 
     <!-- The y translation to apply at the start in appear animations. -->
     <dimen name="appear_y_translation_start">32dp</dimen>
+
+    <!-- The vertical margin between the date and the owner info. -->
+    <dimen name="date_owner_info_margin">2dp</dimen>
 </resources>
diff --git a/packages/Keyguard/res/values/strings.xml b/packages/Keyguard/res/values/strings.xml
index 8cf07fa..55d8d81 100644
--- a/packages/Keyguard/res/values/strings.xml
+++ b/packages/Keyguard/res/values/strings.xml
@@ -59,8 +59,8 @@
     <string name="keyguard_charged">Charged</string>
 
     <!-- When the lock screen is showing and the phone plugged in, and the battery
-         is not fully charged, show the current charge %.  -->
-    <string name="keyguard_plugged_in">Charging, <xliff:g id="number">%d</xliff:g><xliff:g id="percent">%%</xliff:g></string>
+         is not fully charged, say that it's charging.  -->
+    <string name="keyguard_plugged_in">Charging</string>
 
     <!-- When the lock screen is showing and the battery is low, warn user to plug
          in the phone soon. -->
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java b/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java
index d589283..9bc2a4d 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java
@@ -186,42 +186,16 @@
      */
     void update() {
         MutableInt icon = new MutableInt(0);
-        CharSequence status = concat(getOwnerInfo(), getCurrentMessage());
+        CharSequence status = getCurrentMessage();
         setCompoundDrawablesWithIntrinsicBounds(icon.value, 0, 0, 0);
         setText(status);
     }
 
-    private CharSequence concat(CharSequence... args) {
-        StringBuilder b = new StringBuilder();
-        if (!TextUtils.isEmpty(args[0])) {
-            b.append(args[0]);
-        }
-        for (int i = 1; i < args.length; i++) {
-            CharSequence text = args[i];
-            if (!TextUtils.isEmpty(text)) {
-                if (b.length() > 0) {
-                    b.append(mSeparator);
-                }
-                b.append(text);
-            }
-        }
-        return b.toString();
-    }
 
     CharSequence getCurrentMessage() {
         return mShowingMessage ? mMessage : null;
     }
 
-    String getOwnerInfo() {
-        ContentResolver res = getContext().getContentResolver();
-        String info = null;
-        final boolean ownerInfoEnabled = mLockPatternUtils.isOwnerInfoEnabled();
-        if (ownerInfoEnabled && !mShowingMessage) {
-            info = mLockPatternUtils.getOwnerInfo(mLockPatternUtils.getCurrentUser());
-        }
-        return info;
-    }
-
     private void hideMessage(int duration, boolean thenUpdate) {
         if (duration > 0) {
             Animator anim = ObjectAnimator.ofFloat(this, "alpha", 0f);
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
index e6de72f..a0b5536 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
@@ -475,7 +475,8 @@
             interpolator, null);
 
             // And the forgot pattern button
-            if (mForgotPatternButton.getVisibility() == View.VISIBLE) {
+            if (mForgotPatternButton != null
+                    && mForgotPatternButton.getVisibility() == View.VISIBLE) {
                 mAppearAnimationUtils.createAnimation(mForgotPatternButton, delay, duration,
                         startTranslationY, interpolator, null);
             }
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
index bef94fa..7918755 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
@@ -16,6 +16,7 @@
 
 package com.android.keyguard;
 
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.res.Resources;
 import android.text.TextUtils;
@@ -41,6 +42,7 @@
     private TextView mAlarmStatusView;
     private TextClock mDateView;
     private TextClock mClockView;
+    private TextView mOwnerInfo;
 
     private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
 
@@ -54,6 +56,7 @@
             if (showing) {
                 if (DEBUG) Slog.v(TAG, "refresh statusview showing:" + showing);
                 refresh();
+                updateOwnerInfo();
             }
         }
 
@@ -83,6 +86,7 @@
     private void setEnableMarquee(boolean enabled) {
         if (DEBUG) Log.v(TAG, (enabled ? "Enable" : "Disable") + " transport text marquee");
         if (mAlarmStatusView != null) mAlarmStatusView.setSelected(enabled);
+        mOwnerInfo.setSelected(enabled);
     }
 
     @Override
@@ -91,10 +95,12 @@
         mAlarmStatusView = (TextView) findViewById(R.id.alarm_status);
         mDateView = (TextClock) findViewById(R.id.date_view);
         mClockView = (TextClock) findViewById(R.id.clock_view);
+        mOwnerInfo = (TextView) findViewById(R.id.owner_info);
         mLockPatternUtils = new LockPatternUtils(getContext());
         final boolean screenOn = KeyguardUpdateMonitor.getInstance(mContext).isScreenOn();
         setEnableMarquee(screenOn);
         refresh();
+        updateOwnerInfo();
 
         // Disable elegant text height because our fancy colon makes the ymin value huge for no
         // reason.
@@ -124,6 +130,16 @@
         }
     }
 
+    private void updateOwnerInfo() {
+        String ownerInfo = getOwnerInfo();
+        if (!TextUtils.isEmpty(ownerInfo)) {
+            mOwnerInfo.setVisibility(View.VISIBLE);
+            mOwnerInfo.setText(ownerInfo);
+        } else {
+            mOwnerInfo.setVisibility(View.GONE);
+        }
+    }
+
     @Override
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
@@ -140,6 +156,16 @@
         return LockPatternUtils.ID_DEFAULT_STATUS_WIDGET;
     }
 
+    private String getOwnerInfo() {
+        ContentResolver res = getContext().getContentResolver();
+        String info = null;
+        final boolean ownerInfoEnabled = mLockPatternUtils.isOwnerInfoEnabled();
+        if (ownerInfoEnabled) {
+            info = mLockPatternUtils.getOwnerInfo(mLockPatternUtils.getCurrentUser());
+        }
+        return info;
+    }
+
     // DateFormat.getBestDateTimePattern is extremely expensive, and refresh is called often.
     // This is an optimization to ensure we only recompute the patterns when the inputs change.
     private static final class Patterns {
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
index fef971c..668e1ef 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -418,7 +418,7 @@
         }
     }
 
-    /* package */ static class BatteryStatus {
+    public static class BatteryStatus {
         public final int status;
         public final int level;
         public final int plugged;
diff --git a/packages/Keyguard/test/SampleTrustAgent/Android.mk b/packages/Keyguard/test/SampleTrustAgent/Android.mk
index 7551fdf..2a18ee1 100644
--- a/packages/Keyguard/test/SampleTrustAgent/Android.mk
+++ b/packages/Keyguard/test/SampleTrustAgent/Android.mk
@@ -20,9 +20,8 @@
 
 LOCAL_PACKAGE_NAME := SampleTrustAgent
 
-# Remove these to verify permission checks are working correctly
-#LOCAL_CERTIFICATE := platform
-#LOCAL_PRIVILEGED_MODULE := true
+# Remove this to verify permission checks are working correctly
+LOCAL_CERTIFICATE := platform
 
 LOCAL_MODULE_TAGS := tests
 
diff --git a/packages/Keyguard/test/SampleTrustAgent/AndroidManifest.xml b/packages/Keyguard/test/SampleTrustAgent/AndroidManifest.xml
index 7904927..f3125f1 100644
--- a/packages/Keyguard/test/SampleTrustAgent/AndroidManifest.xml
+++ b/packages/Keyguard/test/SampleTrustAgent/AndroidManifest.xml
@@ -18,6 +18,7 @@
     package="com.android.trustagent.test">
     <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="17"/>
     <uses-permission android:name="android.permission.CONTROL_KEYGUARD" />
+    <uses-permission android:name="android.permission.PROVIDE_TRUST_AGENT" />
     <application android:label="@string/app_name">
       <service
           android:name=".SampleTrustAgent"
diff --git a/packages/PrintSpooler/Android.mk b/packages/PrintSpooler/Android.mk
index 9e7b969..96592b4 100644
--- a/packages/PrintSpooler/Android.mk
+++ b/packages/PrintSpooler/Android.mk
@@ -24,4 +24,6 @@
 
 LOCAL_JAVA_LIBRARIES := framework-base
 
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4
+
 include $(BUILD_PACKAGE)
diff --git a/packages/PrintSpooler/AndroidManifest.xml b/packages/PrintSpooler/AndroidManifest.xml
index e1d0aec..4c0bbb8 100644
--- a/packages/PrintSpooler/AndroidManifest.xml
+++ b/packages/PrintSpooler/AndroidManifest.xml
@@ -42,23 +42,23 @@
     <uses-permission android:name="android.permission.START_PRINT_SERVICE_CONFIG_ACTIVITY"/>
 
     <application
-            android:allowClearUserData="true"
-            android:label="@string/app_label"
-            android:allowBackup= "false"
-            android:supportsRtl="true"
-            android:icon="@*android:drawable/ic_print">
+        android:allowClearUserData="true"
+        android:label="@string/app_label"
+        android:allowBackup= "false"
+        android:supportsRtl="true"
+        android:icon="@*android:drawable/ic_print">
 
         <service
-            android:name=".PrintSpoolerService"
+            android:name=".model.PrintSpoolerService"
             android:exported="true"
             android:permission="android.permission.BIND_PRINT_SPOOLER_SERVICE">
         </service>
 
         <activity
-            android:name=".PrintJobConfigActivity"
+            android:name=".ui.PrintActivity"
             android:configChanges="orientation|screenSize"
             android:permission="android.permission.BIND_PRINT_SPOOLER_SERVICE"
-            android:theme="@style/PrintJobConfigActivityTheme">
+            android:theme="@android:style/Theme.DeviceDefault.NoActionBar">
             <intent-filter>
                 <action android:name="android.print.PRINT_DIALOG" />
                 <category android:name="android.intent.category.DEFAULT" />
@@ -67,7 +67,7 @@
         </activity>
 
         <activity
-            android:name=".SelectPrinterActivity"
+            android:name=".ui.SelectPrinterActivity"
             android:label="@string/all_printers_label"
             android:theme="@style/SelectPrinterActivityTheme"
             android:exported="false">
diff --git a/packages/PrintSpooler/res/drawable-hdpi/ic_expand_less_24dp.png b/packages/PrintSpooler/res/drawable-hdpi/ic_expand_less_24dp.png
new file mode 100644
index 0000000..d2e5408
--- /dev/null
+++ b/packages/PrintSpooler/res/drawable-hdpi/ic_expand_less_24dp.png
Binary files differ
diff --git a/packages/PrintSpooler/res/drawable-hdpi/ic_expand_more_24dp.png b/packages/PrintSpooler/res/drawable-hdpi/ic_expand_more_24dp.png
new file mode 100644
index 0000000..f4c4b0c
--- /dev/null
+++ b/packages/PrintSpooler/res/drawable-hdpi/ic_expand_more_24dp.png
Binary files differ
diff --git a/packages/PrintSpooler/res/drawable-hdpi/ic_grayedout_printer.png b/packages/PrintSpooler/res/drawable-hdpi/ic_grayedout_printer.png
new file mode 100644
index 0000000..5e54970
--- /dev/null
+++ b/packages/PrintSpooler/res/drawable-hdpi/ic_grayedout_printer.png
Binary files differ
diff --git a/packages/PrintSpooler/res/drawable-hdpi/print_button_background.png b/packages/PrintSpooler/res/drawable-hdpi/print_button_background.png
new file mode 100644
index 0000000..88e8495
--- /dev/null
+++ b/packages/PrintSpooler/res/drawable-hdpi/print_button_background.png
Binary files differ
diff --git a/packages/PrintSpooler/res/drawable-mdpi/ic_expand_less_24dp.png b/packages/PrintSpooler/res/drawable-mdpi/ic_expand_less_24dp.png
new file mode 100644
index 0000000..3220eea
--- /dev/null
+++ b/packages/PrintSpooler/res/drawable-mdpi/ic_expand_less_24dp.png
Binary files differ
diff --git a/packages/PrintSpooler/res/drawable-mdpi/ic_expand_more_24dp.png b/packages/PrintSpooler/res/drawable-mdpi/ic_expand_more_24dp.png
new file mode 100644
index 0000000..5530f52
--- /dev/null
+++ b/packages/PrintSpooler/res/drawable-mdpi/ic_expand_more_24dp.png
Binary files differ
diff --git a/packages/PrintSpooler/res/drawable-mdpi/ic_grayedout_printer.png b/packages/PrintSpooler/res/drawable-mdpi/ic_grayedout_printer.png
new file mode 100644
index 0000000..5e54970
--- /dev/null
+++ b/packages/PrintSpooler/res/drawable-mdpi/ic_grayedout_printer.png
Binary files differ
diff --git a/packages/PrintSpooler/res/drawable-mdpi/print_button_background.png b/packages/PrintSpooler/res/drawable-mdpi/print_button_background.png
new file mode 100644
index 0000000..3a37b27
--- /dev/null
+++ b/packages/PrintSpooler/res/drawable-mdpi/print_button_background.png
Binary files differ
diff --git a/packages/PrintSpooler/res/drawable-xhdpi/ic_expand_less_24dp.png b/packages/PrintSpooler/res/drawable-xhdpi/ic_expand_less_24dp.png
new file mode 100644
index 0000000..f0074275
--- /dev/null
+++ b/packages/PrintSpooler/res/drawable-xhdpi/ic_expand_less_24dp.png
Binary files differ
diff --git a/packages/PrintSpooler/res/drawable-xhdpi/ic_expand_more_24dp.png b/packages/PrintSpooler/res/drawable-xhdpi/ic_expand_more_24dp.png
new file mode 100644
index 0000000..43debb3
--- /dev/null
+++ b/packages/PrintSpooler/res/drawable-xhdpi/ic_expand_more_24dp.png
Binary files differ
diff --git a/packages/PrintSpooler/res/drawable-xhdpi/ic_grayedout_printer.png b/packages/PrintSpooler/res/drawable-xhdpi/ic_grayedout_printer.png
new file mode 100644
index 0000000..5e54970
--- /dev/null
+++ b/packages/PrintSpooler/res/drawable-xhdpi/ic_grayedout_printer.png
Binary files differ
diff --git a/packages/PrintSpooler/res/drawable-xhdpi/print_button_background.png b/packages/PrintSpooler/res/drawable-xhdpi/print_button_background.png
new file mode 100644
index 0000000..b2ed8cd
--- /dev/null
+++ b/packages/PrintSpooler/res/drawable-xhdpi/print_button_background.png
Binary files differ
diff --git a/packages/PrintSpooler/res/drawable-xxhdpi/ic_expand_less_24dp.png b/packages/PrintSpooler/res/drawable-xxhdpi/ic_expand_less_24dp.png
new file mode 100644
index 0000000..39bc2ba
--- /dev/null
+++ b/packages/PrintSpooler/res/drawable-xxhdpi/ic_expand_less_24dp.png
Binary files differ
diff --git a/packages/PrintSpooler/res/drawable-xxhdpi/ic_expand_more_24dp.png b/packages/PrintSpooler/res/drawable-xxhdpi/ic_expand_more_24dp.png
new file mode 100644
index 0000000..664f3f2
--- /dev/null
+++ b/packages/PrintSpooler/res/drawable-xxhdpi/ic_expand_more_24dp.png
Binary files differ
diff --git a/packages/PrintSpooler/res/drawable-xxxhdpi/ic_expand_less_24dp.png b/packages/PrintSpooler/res/drawable-xxxhdpi/ic_expand_less_24dp.png
new file mode 100644
index 0000000..fe9c539
--- /dev/null
+++ b/packages/PrintSpooler/res/drawable-xxxhdpi/ic_expand_less_24dp.png
Binary files differ
diff --git a/packages/PrintSpooler/res/drawable-xxxhdpi/ic_expand_more_24dp.png b/packages/PrintSpooler/res/drawable-xxxhdpi/ic_expand_more_24dp.png
new file mode 100644
index 0000000..18d075c
--- /dev/null
+++ b/packages/PrintSpooler/res/drawable-xxxhdpi/ic_expand_more_24dp.png
Binary files differ
diff --git a/packages/PrintSpooler/res/drawable/ic_expand_less.xml b/packages/PrintSpooler/res/drawable/ic_expand_less.xml
new file mode 100644
index 0000000..b0c7d51
--- /dev/null
+++ b/packages/PrintSpooler/res/drawable/ic_expand_less.xml
@@ -0,0 +1,43 @@
+<?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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:autoMirrored="true">
+
+    <item
+        android:state_checked="true">
+        <bitmap
+            android:src="@drawable/ic_expand_less_24dp"
+            android:tint="?android:attr/colorControlActivated">
+        </bitmap>
+    </item>
+
+    <item
+        android:state_pressed="true">
+        <bitmap
+            android:src="@drawable/ic_expand_less_24dp"
+            android:tint="?android:attr/colorControlActivated">
+        </bitmap>
+    </item>
+
+    <item>
+        <bitmap
+            android:src="@drawable/ic_expand_less_24dp"
+            android:tint="?android:attr/colorControlNormal">
+        </bitmap>
+    </item>
+
+</selector>
diff --git a/packages/PrintSpooler/res/drawable/ic_expand_more.xml b/packages/PrintSpooler/res/drawable/ic_expand_more.xml
new file mode 100644
index 0000000..b809c25
--- /dev/null
+++ b/packages/PrintSpooler/res/drawable/ic_expand_more.xml
@@ -0,0 +1,43 @@
+<?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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:autoMirrored="true">
+
+    <item
+        android:state_checked="true">
+        <bitmap
+            android:src="@drawable/ic_expand_more_24dp"
+            android:tint="?android:attr/colorControlActivated">
+        </bitmap>
+    </item>
+
+    <item
+        android:state_pressed="true">
+        <bitmap
+            android:src="@drawable/ic_expand_more_24dp"
+            android:tint="?android:attr/colorControlActivated">
+        </bitmap>
+    </item>
+
+    <item>
+        <bitmap
+            android:src="@drawable/ic_expand_more_24dp"
+            android:tint="?android:attr/colorControlNormal">
+        </bitmap>
+    </item>
+
+</selector>
diff --git a/core/res/res/drawable/btn_borderless_quantum.xml b/packages/PrintSpooler/res/drawable/print_button.xml
similarity index 75%
copy from core/res/res/drawable/btn_borderless_quantum.xml
copy to packages/PrintSpooler/res/drawable/print_button.xml
index 2cd7ed6..d4b6a82 100644
--- a/core/res/res/drawable/btn_borderless_quantum.xml
+++ b/packages/PrintSpooler/res/drawable/print_button.xml
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
+<!--
+     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.
@@ -15,7 +16,9 @@
 -->
 
 <ripple xmlns:android="http://schemas.android.com/apk/res/android"
-    android:tint="?attr/colorControlHighlight">
-    <item android:id="@id/mask"
-        android:drawable="@drawable/btn_qntm_alpha" />
+    android:tint="@color/print_button_tint_color"
+    android:pinned="true">
+    <item
+        android:drawable="@drawable/print_button_background">
+    </item>
 </ripple>
diff --git a/packages/PrintSpooler/res/layout/print_activity.xml b/packages/PrintSpooler/res/layout/print_activity.xml
new file mode 100644
index 0000000..9715322
--- /dev/null
+++ b/packages/PrintSpooler/res/layout/print_activity.xml
@@ -0,0 +1,389 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 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.
+-->
+
+<com.android.printspooler.widget.ContentView
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        xmlns:printspooler="http://schemas.android.com/apk/res/com.android.printspooler"
+    android:id="@+id/options_content"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:visibility="invisible"
+    android:background="?android:attr/colorForeground">
+
+    <FrameLayout
+        android:id="@+id/static_content"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:padding="16dip"
+        android:background="?android:attr/colorForegroundInverse">
+
+        <!-- Destination -->
+
+        <Spinner
+            android:id="@+id/destination_spinner"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:dropDownWidth="wrap_content"
+            android:minHeight="?android:attr/listPreferredItemHeightSmall">
+        </Spinner>
+
+    </FrameLayout>
+
+    <!-- Summary -->
+
+    <LinearLayout
+        android:id="@+id/summary_content"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:paddingStart="16dip"
+        android:paddingEnd="16dip"
+        android:orientation="horizontal"
+        android:background="?android:attr/colorForegroundInverse">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="8dip"
+            android:layout_marginStart="12dip"
+            android:textAppearance="?android:attr/textAppearanceSmall"
+            android:labelFor="@+id/copies_count_summary"
+            android:text="@string/label_copies_summary">
+        </TextView>
+
+        <TextView
+            android:id="@+id/copies_count_summary"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="8dip"
+            android:layout_marginStart="16dip"
+            android:textAppearance="?android:attr/textAppearanceMedium">
+        </TextView>
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="8dip"
+            android:layout_marginStart="32dip"
+            android:textAppearance="?android:attr/textAppearanceSmall"
+            android:labelFor="@+id/paper_size_summary"
+            android:text="@string/label_paper_size_summary">
+        </TextView>
+
+        <TextView
+            android:id="@+id/paper_size_summary"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="8dip"
+            android:layout_marginStart="16dip"
+            android:textAppearance="?android:attr/textAppearanceMedium">
+        </TextView>
+
+    </LinearLayout>
+
+    <FrameLayout
+        android:id="@+id/dynamic_content"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:paddingBottom="16dip">
+
+        <LinearLayout
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:orientation="vertical">
+
+            <LinearLayout
+                android:id="@+id/draggable_content"
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:orientation="vertical">
+
+                <com.android.printspooler.widget.PrintOptionsLayout
+                    android:id="@+id/options_container"
+                    android:layout_width="fill_parent"
+                    android:layout_height="wrap_content"
+                    android:background="?android:attr/colorForegroundInverse"
+                    printspooler:columnCount="@integer/print_option_column_count">
+
+                    <LinearLayout
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_marginStart="16dip"
+                        android:layout_marginEnd="16dip"
+                        android:orientation="vertical">
+
+                        <!-- Copies -->
+
+                        <TextView
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:layout_marginTop="8dip"
+                            android:layout_marginStart="12dip"
+                            android:textAppearance="?android:attr/textAppearanceSmall"
+                            android:labelFor="@+id/copies_edittext"
+                            android:text="@string/label_copies">
+                        </TextView>
+
+                        <view
+                            class="com.android.printspooler.widget.FirstFocusableEditText"
+                            android:id="@+id/copies_edittext"
+                            android:layout_width="fill_parent"
+                            android:layout_height="wrap_content"
+                            style="?android:attr/editTextStyle"
+                            android:inputType="numberDecimal">
+                        </view>
+
+                    </LinearLayout>
+
+                    <LinearLayout
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_marginStart="16dip"
+                        android:layout_marginEnd="16dip"
+                        android:orientation="vertical">
+
+                        <!-- Paper size -->
+
+                        <TextView
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:layout_marginTop="8dip"
+                            android:layout_marginStart="12dip"
+                            android:textAppearance="?android:attr/textAppearanceSmall"
+                            android:labelFor="@+id/paper_size_spinner"
+                            android:text="@string/label_paper_size">
+                        </TextView>
+
+                        <Spinner
+                            android:id="@+id/paper_size_spinner"
+                            android:layout_width="fill_parent"
+                            android:layout_height="wrap_content"
+                            style="@style/PrintOptionSpinnerStyle">
+                        </Spinner>
+
+                    </LinearLayout>
+
+                    <LinearLayout
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_marginStart="16dip"
+                        android:layout_marginEnd="16dip"
+                        android:orientation="vertical">
+
+                        <!-- Color -->
+
+                        <TextView
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:layout_marginTop="8dip"
+                            android:layout_marginStart="12dip"
+                            android:textAppearance="?android:attr/textAppearanceSmall"
+                            android:labelFor="@+id/color_spinner"
+                            android:text="@string/label_color">
+                        </TextView>
+
+                        <Spinner
+                            android:id="@+id/color_spinner"
+                            android:layout_width="fill_parent"
+                            android:layout_height="wrap_content"
+                            style="@style/PrintOptionSpinnerStyle">
+                        </Spinner>
+
+                    </LinearLayout>
+
+                    <LinearLayout
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_marginStart="16dip"
+                        android:layout_marginEnd="16dip"
+                        android:orientation="vertical">
+
+                        <!-- Orientation -->
+
+                        <TextView
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:layout_marginTop="8dip"
+                            android:layout_marginStart="12dip"
+                            android:textAppearance="?android:attr/textAppearanceSmall"
+                            android:labelFor="@+id/orientation_spinner"
+                            android:text="@string/label_orientation">
+                        </TextView>
+
+                        <Spinner
+                            android:id="@+id/orientation_spinner"
+                            android:layout_width="fill_parent"
+                            android:layout_height="wrap_content"
+                            style="@style/PrintOptionSpinnerStyle">
+                        </Spinner>
+
+                    </LinearLayout>
+
+                    <LinearLayout
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_marginStart="16dip"
+                        android:layout_marginEnd="16dip"
+                        android:orientation="vertical">
+
+                        <!-- Range options -->
+
+                        <TextView
+                            android:id="@+id/range_options_title"
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:layout_marginTop="8dip"
+                            android:layout_marginStart="12dip"
+                            android:textAppearance="?android:attr/textAppearanceSmall"
+                            android:labelFor="@+id/range_options_spinner"
+                            android:text="@string/page_count_unknown">
+                        </TextView>
+
+                        <Spinner
+                            android:id="@+id/range_options_spinner"
+                            android:layout_width="fill_parent"
+                            android:layout_height="wrap_content"
+                            style="@style/PrintOptionSpinnerStyle">
+                        </Spinner>
+
+                    </LinearLayout>
+
+                    <LinearLayout
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_marginStart="16dip"
+                        android:layout_marginEnd="16dip"
+                        android:orientation="vertical">
+
+                        <!-- Pages -->
+
+                        <TextView
+                            android:id="@+id/page_range_title"
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:layout_marginTop="8dip"
+                            android:layout_marginStart="12dip"
+                            android:textAppearance="?android:attr/textAppearanceSmall"
+                            android:text="@string/pages_range_example"
+                            android:labelFor="@+id/page_range_edittext"
+                            android:textAllCaps="false"
+                            android:visibility="visible">
+                        </TextView>
+
+                        <view
+                            class="com.android.printspooler.widget.FirstFocusableEditText"
+                            android:id="@+id/page_range_edittext"
+                            android:layout_width="fill_parent"
+                            android:layout_height="wrap_content"
+                            android:layout_gravity="bottom|fill_horizontal"
+                            style="@style/PrintOptionEditTextStyle"
+                            android:visibility="visible"
+                            android:inputType="textNoSuggestions">
+                        </view>
+
+                    </LinearLayout>
+
+                </com.android.printspooler.widget.PrintOptionsLayout>
+
+                <!-- More options -->
+
+                <LinearLayout
+                    android:id="@+id/more_options_container"
+                    android:layout_width="fill_parent"
+                    android:layout_height="wrap_content"
+                    android:paddingStart="28dip"
+                    android:paddingEnd="28dip"
+                    android:orientation="vertical"
+                    android:visibility="visible"
+                    android:background="?android:attr/colorForegroundInverse">
+
+                    <ImageView
+                        android:layout_width="fill_parent"
+                        android:layout_height="1dip"
+                        android:layout_gravity="fill_horizontal"
+                        android:background="?android:attr/colorControlNormal"
+                        android:contentDescription="@null">
+                    </ImageView>
+
+                    <Button
+                        android:id="@+id/more_options_button"
+                        style="?android:attr/borderlessButtonStyle"
+                        android:layout_width="fill_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_gravity="fill_horizontal"
+                        android:text="@string/more_options_button"
+                        android:gravity="start|center_vertical"
+                        android:textAllCaps="false">
+                    </Button>
+
+                    <ImageView
+                        android:layout_width="fill_parent"
+                        android:layout_height="1dip"
+                        android:layout_gravity="fill_horizontal"
+                        android:background="?android:attr/colorControlNormal"
+                        android:contentDescription="@null">
+                    </ImageView>
+
+                </LinearLayout>
+
+            </LinearLayout>
+
+            <!-- Expand/collapse handle -->
+
+            <FrameLayout
+                android:id="@+id/expand_collapse_handle"
+                android:layout_width="fill_parent"
+                android:layout_height="?android:attr/listPreferredItemHeightSmall"
+                android:layout_marginBottom="28dip"
+                android:background="?android:attr/colorForegroundInverse"
+                android:elevation="12dip">
+
+                <ImageButton
+                    android:id="@+id/expand_collapse_icon"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="center"
+                    android:background="@drawable/ic_expand_more">
+                </ImageButton>
+
+            </FrameLayout>
+
+        </LinearLayout>
+
+        <!-- Print button -->
+
+        <ImageButton
+            android:id="@+id/print_button"
+            style="?android:attr/buttonStyleSmall"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="end|bottom"
+            android:layout_marginEnd="16dip"
+            android:elevation="12dip"
+            android:background="@drawable/print_button"
+            android:src="@*android:drawable/ic_print">
+        </ImageButton>
+
+    </FrameLayout>
+
+
+    <FrameLayout
+        android:id="@+id/embedded_content_container"
+        android:layout_width="fill_parent"
+        android:layout_height="0dip"
+        android:animateLayoutChanges="true">
+    </FrameLayout>
+
+</com.android.printspooler.widget.ContentView>
diff --git a/packages/PrintSpooler/res/layout/print_error_fragment.xml b/packages/PrintSpooler/res/layout/print_error_fragment.xml
new file mode 100644
index 0000000..dc44339
--- /dev/null
+++ b/packages/PrintSpooler/res/layout/print_error_fragment.xml
@@ -0,0 +1,47 @@
+<?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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:gravity="center"
+    android:orientation="vertical">
+
+    <ImageView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginBottom="12dip"
+        android:src="@drawable/ic_grayedout_printer"
+        android:contentDescription="@null">
+    </ImageView>
+
+    <TextView
+        android:id="@+id/message"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/print_error_default_message"
+        android:textAppearance="?android:attr/textAppearanceLargeInverse">
+    </TextView>
+
+    <Button
+        android:id="@+id/action_button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/print_error_retry">
+    </Button>
+
+</LinearLayout>
diff --git a/packages/PrintSpooler/res/layout/print_job_config_activity_container.xml b/packages/PrintSpooler/res/layout/print_job_config_activity_container.xml
deleted file mode 100644
index 3303ef1..0000000
--- a/packages/PrintSpooler/res/layout/print_job_config_activity_container.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 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.
--->
-
-<com.android.printspooler.PrintDialogFrame xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="fill_parent"
-    android:layout_height="wrap_content">
-    <FrameLayout
-        android:id="@+id/content_container"
-        android:layout_width="fill_parent"
-        android:layout_height="fill_parent"
-        android:background="@color/container_background">
-    </FrameLayout>
-</com.android.printspooler.PrintDialogFrame>
diff --git a/packages/PrintSpooler/res/layout/print_job_config_activity_content_editing.xml b/packages/PrintSpooler/res/layout/print_job_config_activity_content_editing.xml
deleted file mode 100644
index e50a7af..0000000
--- a/packages/PrintSpooler/res/layout/print_job_config_activity_content_editing.xml
+++ /dev/null
@@ -1,282 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 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.
--->
-
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="fill_parent"
-    android:layout_height="wrap_content"
-    android:orientation="vertical"
-    android:scrollbars="vertical">
-
-    <LinearLayout
-        android:layout_width="fill_parent"
-        android:layout_height="wrap_content"
-        android:orientation="vertical">
-
-        <!-- Destination -->
-
-        <Spinner
-            android:id="@+id/destination_spinner"
-            android:layout_width="fill_parent"
-            android:layout_height="wrap_content"
-            android:layout_gravity="fill_horizontal"
-            android:layout_marginTop="24dip"
-            android:layout_marginStart="24dip"
-            android:layout_marginEnd="24dip"
-            android:minHeight="?android:attr/listPreferredItemHeightSmall">
-        </Spinner>
-
-        <LinearLayout
-            android:layout_width="fill_parent"
-            android:layout_height="wrap_content"
-            android:layout_marginBottom="24dip"
-            android:orientation="horizontal"
-            android:baselineAligned="false">
-
-            <LinearLayout
-                android:layout_width="0dip"
-                android:layout_height="wrap_content"
-                android:layout_weight="1"
-                android:orientation="vertical">
-
-                <!-- Copies -->
-
-                <TextView
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_marginTop="12dip"
-                    android:layout_marginStart="36dip"
-                    android:layout_marginEnd="6dip"
-                    android:textAppearance="@style/PrintOptionTitleTextAppearance"
-                    android:labelFor="@+id/copies_edittext"
-                    android:text="@string/label_copies">
-                </TextView>
-
-                <view
-                    class="com.android.printspooler.PrintJobConfigActivity$CustomEditText"
-                    android:id="@+id/copies_edittext"
-                    android:layout_width="fill_parent"
-                    android:layout_height="wrap_content"
-                    android:layout_marginStart="24dip"
-                    android:layout_marginEnd="6dip"
-                    style="@style/PrintOptionEditTextStyle"
-                    android:inputType="numberDecimal">
-                </view>
-
-                <!-- Color -->
-
-                <TextView
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_marginTop="12dip"
-                    android:layout_marginStart="36dip"
-                    android:layout_marginEnd="6dip"
-                    android:textAppearance="@style/PrintOptionTitleTextAppearance"
-                    android:labelFor="@+id/color_spinner"
-                    android:text="@string/label_color">
-                </TextView>
-
-                <Spinner
-                    android:id="@+id/color_spinner"
-                    android:layout_width="fill_parent"
-                    android:layout_height="wrap_content"
-                    android:layout_marginStart="24dip"
-                    android:layout_marginEnd="6dip"
-                    style="@style/PrintOptionSpinnerStyle">
-                </Spinner>
-
-                <!-- Range options -->
-
-                <TextView
-                    android:id="@+id/range_options_title"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_marginTop="12dip"
-                    android:layout_marginStart="36dip"
-                    android:textAppearance="@style/PrintOptionTitleTextAppearance"
-                    android:labelFor="@+id/range_options_spinner"
-                    android:text="@string/page_count_unknown">
-                </TextView>
-
-                <Spinner
-                    android:id="@+id/range_options_spinner"
-                    android:layout_width="fill_parent"
-                    android:layout_height="wrap_content"
-                    android:layout_marginStart="24dip"
-                    android:layout_marginEnd="6dip"
-                    style="@style/PrintOptionSpinnerStyle">
-                </Spinner>
-
-            </LinearLayout>
-
-            <LinearLayout
-                android:layout_width="0dip"
-                android:layout_height="wrap_content"
-                android:layout_weight="1"
-                android:orientation="vertical">
-
-                <!-- Paper size -->
-
-                <TextView
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_marginTop="12dip"
-                    android:layout_marginStart="18dip"
-                    android:layout_marginEnd="24dip"
-                    android:textAppearance="@style/PrintOptionTitleTextAppearance"
-                    android:labelFor="@+id/paper_size_spinner"
-                    android:text="@string/label_paper_size">
-                </TextView>
-
-                <Spinner
-                    android:id="@+id/paper_size_spinner"
-                    android:layout_width="fill_parent"
-                    android:layout_height="wrap_content"
-                    android:layout_marginStart="6dip"
-                    android:layout_marginEnd="24dip"
-                    style="@style/PrintOptionSpinnerStyle">
-                </Spinner>
-
-                <!-- Orientation -->
-
-                <TextView
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_marginTop="12dip"
-                    android:layout_marginStart="18dip"
-                    android:layout_marginEnd="24dip"
-                    android:textAppearance="@style/PrintOptionTitleTextAppearance"
-                    android:labelFor="@+id/orientation_spinner"
-                    android:text="@string/label_orientation">
-                </TextView>
-
-                <Spinner
-                    android:id="@+id/orientation_spinner"
-                    android:layout_width="fill_parent"
-                    android:layout_height="wrap_content"
-                    android:layout_marginStart="6dip"
-                    android:layout_marginEnd="24dip"
-                    style="@style/PrintOptionSpinnerStyle">
-                </Spinner>
-
-                <!-- Pages -->
-
-               <TextView
-                    android:id="@+id/page_range_title"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_marginTop="12dip"
-                    android:layout_marginStart="12dip"
-                    android:layout_marginEnd="24dip"
-                    android:textAppearance="@style/PrintOptionTitleTextAppearance"
-                    android:text="@string/pages_range_example"
-                    android:labelFor="@+id/page_range_edittext"
-                    android:textAllCaps="false">
-                </TextView>
-
-                <view
-                    class="com.android.printspooler.PrintJobConfigActivity$CustomEditText"
-                    android:id="@+id/page_range_edittext"
-                    android:layout_width="fill_parent"
-                    android:layout_height="wrap_content"
-                    android:layout_marginStart="6dip"
-                    android:layout_marginEnd="24dip"
-                    android:layout_gravity="bottom|fill_horizontal"
-                    style="@style/PrintOptionEditTextStyle"
-                    android:visibility="gone"
-                    android:inputType="textNoSuggestions">
-                </view>
-
-            </LinearLayout>
-
-        </LinearLayout>
-
-        <!-- Advanced settings button -->
-
-        <LinearLayout
-           android:id="@+id/advanced_settings_container"
-           android:layout_width="fill_parent"
-           android:layout_height="wrap_content"
-           android:orientation="vertical"
-           android:visibility="gone">
-
-            <ImageView
-                android:layout_width="fill_parent"
-                android:layout_height="1dip"
-                android:layout_marginStart="24dip"
-                android:layout_marginEnd="24dip"
-                android:layout_gravity="fill_horizontal"
-                android:background="@color/separator"
-                android:contentDescription="@null">
-            </ImageView>
-
-            <Button
-                android:id="@+id/advanced_settings_button"
-                style="?android:attr/buttonBarButtonStyle"
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content"
-                android:layout_marginStart="24dip"
-                android:layout_marginEnd="24dip"
-                android:layout_gravity="fill_horizontal"
-                android:text="@string/advanced_settings_button"
-                android:gravity="start|center_vertical"
-                android:textSize="16sp"
-                android:textColor="@color/item_text_color">
-            </Button>
-
-            <ImageView
-                android:layout_width="fill_parent"
-                android:layout_height="1dip"
-                android:layout_gravity="fill_horizontal"
-                android:layout_marginStart="24dip"
-                android:layout_marginEnd="24dip"
-                android:background="@color/separator"
-                android:contentDescription="@null">
-            </ImageView>
-
-        </LinearLayout>
-
-        <!-- Print button -->
-
-        <FrameLayout
-            android:layout_width="fill_parent"
-            android:layout_height="wrap_content"
-            android:layout_marginTop="24dip"
-            android:background="@color/action_button_background">
-
-            <ImageView
-                android:layout_width="fill_parent"
-                android:layout_height="1dip"
-                android:layout_gravity="fill_horizontal"
-                android:background="@color/separator"
-                android:contentDescription="@null">
-            </ImageView>
-
-            <Button
-                android:id="@+id/print_button"
-                style="?android:attr/buttonBarButtonStyle"
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content"
-                android:layout_gravity="fill_horizontal"
-                android:text="@string/print_button"
-                android:textSize="16sp"
-                android:textColor="@color/item_text_color">
-            </Button>
-
-        </FrameLayout>
-
-    </LinearLayout>
-
-</ScrollView>
diff --git a/packages/PrintSpooler/res/layout/print_job_config_activity_content_error.xml b/packages/PrintSpooler/res/layout/print_job_config_activity_content_error.xml
deleted file mode 100644
index d9f0a9a..0000000
--- a/packages/PrintSpooler/res/layout/print_job_config_activity_content_error.xml
+++ /dev/null
@@ -1,70 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 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/content_generating"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:orientation="vertical">
-
-    <LinearLayout
-        android:layout_width="fill_parent"
-        android:layout_height="fill_parent"
-        android:orientation="vertical">
-
-        <TextView
-            android:id="@+id/message"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginStart="16dip"
-            android:layout_marginEnd="16dip"
-            android:layout_marginTop="32dip"
-            android:layout_marginBottom="32dip"
-            android:layout_gravity="center"
-            style="?android:attr/buttonBarButtonStyle"
-            android:ellipsize="end"
-            android:text="@string/print_error_default_message"
-            android:textColor="@color/important_text"
-            android:textSize="16sp">
-        </TextView>
-
-    </LinearLayout>
-
-    <FrameLayout
-        android:layout_width="fill_parent"
-        android:layout_height="wrap_content"
-        android:background="@color/action_button_background">
-
-        <View
-            android:layout_width="fill_parent"
-            android:layout_height="1dip"
-            android:background="@color/separator">
-        </View>
-
-        <Button
-            android:id="@+id/ok_button"
-            android:layout_width="fill_parent"
-            android:layout_height="wrap_content"
-            android:layout_gravity="fill_horizontal"
-            style="?android:attr/buttonBarButtonStyle"
-            android:text="@android:string/ok"
-            android:textSize="16sp"
-            android:textColor="@color/important_text">
-        </Button>
-
-    </FrameLayout>
-
-</LinearLayout>
diff --git a/packages/PrintSpooler/res/layout/print_job_config_activity_content_generating.xml b/packages/PrintSpooler/res/layout/print_job_config_activity_content_generating.xml
deleted file mode 100644
index 10602ee..0000000
--- a/packages/PrintSpooler/res/layout/print_job_config_activity_content_generating.xml
+++ /dev/null
@@ -1,79 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 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/content_generating"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:orientation="vertical">
-
-    <LinearLayout
-        android:layout_width="fill_parent"
-        android:layout_height="fill_parent"
-        android:orientation="vertical">
-
-        <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginStart="16dip"
-            android:layout_marginEnd="16dip"
-            android:layout_gravity="center"
-            style="?android:attr/buttonBarButtonStyle"
-            android:singleLine="true"
-            android:ellipsize="end"
-            android:text="@string/generating_print_job"
-            android:textColor="@color/important_text"
-            android:textSize="16sp">
-        </TextView>
-
-        <ProgressBar
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginStart="32dip"
-            android:layout_marginEnd="32dip"
-            android:layout_marginTop="16dip"
-            android:layout_marginBottom="32dip"
-            android:layout_gravity="center_horizontal"
-            style="?android:attr/progressBarStyleLarge">
-        </ProgressBar>
-
-    </LinearLayout>
-
-    <FrameLayout
-        android:layout_width="fill_parent"
-        android:layout_height="wrap_content"
-        android:background="@color/action_button_background">
-
-        <View
-            android:layout_width="fill_parent"
-            android:layout_height="1dip"
-            android:background="@color/separator">
-        </View>
-
-        <Button
-            android:id="@+id/cancel_button"
-            android:layout_width="fill_parent"
-            android:layout_height="wrap_content"
-            android:layout_gravity="fill_horizontal"
-            style="?android:attr/buttonBarButtonStyle"
-            android:text="@string/cancel"
-            android:textSize="16sp"
-            android:textColor="@color/important_text">
-        </Button>
-
-    </FrameLayout>
-
-</LinearLayout>
diff --git a/packages/PrintSpooler/res/layout/print_progress_fragment.xml b/packages/PrintSpooler/res/layout/print_progress_fragment.xml
new file mode 100644
index 0000000..212da9e
--- /dev/null
+++ b/packages/PrintSpooler/res/layout/print_progress_fragment.xml
@@ -0,0 +1,65 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_gravity="center"
+    android:gravity="center"
+    android:orientation="vertical">
+
+    <ImageView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginBottom="12dip"
+        android:src="@drawable/ic_grayedout_printer"
+        android:contentDescription="@null">
+    </ImageView>
+
+    <ProgressBar
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:indeterminate="true"
+        style="?android:attr/progressBarStyleHorizontal">
+    </ProgressBar>
+
+    <FrameLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:minHeight="?android:attr/listPreferredItemHeight"
+        android:gravity="center"
+        android:animateLayoutChanges="true">
+
+        <TextView
+            android:id="@+id/message"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textAppearance="?android:attr/textAppearanceLargeInverse"
+            android:text="@string/print_operation_canceling"
+            android:visibility="gone">
+        </TextView>
+
+        <Button
+            android:id="@+id/cancel_button"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@android:string/cancel">
+        </Button>
+
+    </FrameLayout>
+
+</LinearLayout>
+
diff --git a/packages/PrintSpooler/res/layout/printer_dropdown_item.xml b/packages/PrintSpooler/res/layout/printer_dropdown_item.xml
index 1a61b99..43d8aaf 100644
--- a/packages/PrintSpooler/res/layout/printer_dropdown_item.xml
+++ b/packages/PrintSpooler/res/layout/printer_dropdown_item.xml
@@ -19,7 +19,7 @@
       android:layout_height="wrap_content"
       android:paddingStart="16dip"
       android:paddingEnd="16dip"
-      android:minHeight="?android:attr/listPreferredItemHeightSmall"
+      android:minHeight="56dip"
       android:orientation="horizontal"
       android:gravity="start|center_vertical">
 
@@ -49,7 +49,7 @@
             android:ellipsize="end"
             android:textIsSelectable="false"
             android:gravity="top|start"
-            android:textColor="@color/item_text_color"
+            android:textColor="?android:attr/textColorPrimary"
             android:duplicateParentState="true">
         </TextView>
 
@@ -62,7 +62,7 @@
             android:ellipsize="end"
             android:textIsSelectable="false"
             android:visibility="gone"
-            android:textColor="@color/print_option_title"
+            android:textColor="?android:attr/textColorPrimary"
             android:duplicateParentState="true">
         </TextView>
 
diff --git a/packages/PrintSpooler/res/layout/printer_list_item.xml b/packages/PrintSpooler/res/layout/printer_list_item.xml
index 47eb0b5..1f5efbc 100644
--- a/packages/PrintSpooler/res/layout/printer_list_item.xml
+++ b/packages/PrintSpooler/res/layout/printer_list_item.xml
@@ -15,13 +15,13 @@
 -->
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-        android:layout_width="fill_parent"
-        android:layout_height="wrap_content"
-        android:paddingStart="?android:attr/listPreferredItemPaddingStart"
-        android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
-        android:minHeight="?android:attr/listPreferredItemHeight"
-        android:orientation="horizontal"
-        android:gravity="start|center_vertical">
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content"
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+    android:minHeight="?android:attr/listPreferredItemHeight"
+    android:orientation="horizontal"
+    android:gravity="start|center_vertical">
 
     <ImageView
         android:id="@+id/icon"
@@ -31,7 +31,7 @@
         android:layout_marginEnd="8dip"
         android:duplicateParentState="true"
         android:contentDescription="@null"
-        android:visibility="gone">
+        android:visibility="invisible">
     </ImageView>
 
     <LinearLayout
@@ -49,7 +49,7 @@
             android:ellipsize="end"
             android:textIsSelectable="false"
             android:gravity="top|start"
-            android:textColor="@color/item_text_color"
+            android:textColor="?android:attr/textColorSecondary"
             android:duplicateParentState="true">
         </TextView>
 
@@ -62,7 +62,7 @@
             android:ellipsize="end"
             android:textIsSelectable="false"
             android:visibility="gone"
-            android:textColor="@color/print_option_title"
+            android:textColor="?android:attr/textColorSecondary"
             android:duplicateParentState="true">
         </TextView>
 
diff --git a/packages/PrintSpooler/res/layout/select_printer_activity.xml b/packages/PrintSpooler/res/layout/select_printer_activity.xml
index 4488b6a..173057b 100644
--- a/packages/PrintSpooler/res/layout/select_printer_activity.xml
+++ b/packages/PrintSpooler/res/layout/select_printer_activity.xml
@@ -19,12 +19,16 @@
     android:layout_width="fill_parent"
     android:layout_height="fill_parent">
 
-    <fragment
-        android:name="com.android.printspooler.SelectPrinterFragment"
-        android:id="@+id/select_printer_fragment"
+    <ListView
+        android:id="@android:id/list"
         android:layout_width="fill_parent"
-        android:layout_height="wrap_content">
-    </fragment>
+        android:layout_height="fill_parent"
+        android:paddingStart="@dimen/printer_list_view_padding_start"
+        android:paddingEnd="@dimen/printer_list_view_padding_end"
+        android:scrollbarStyle="outsideOverlay"
+        android:cacheColorHint="@android:color/transparent"
+        android:scrollbarAlwaysDrawVerticalTrack="true" >
+    </ListView>
 
     <FrameLayout
         android:id="@+id/empty_print_state"
diff --git a/packages/PrintSpooler/res/layout/select_printer_fragment.xml b/packages/PrintSpooler/res/layout/select_printer_fragment.xml
deleted file mode 100644
index bbd012e..0000000
--- a/packages/PrintSpooler/res/layout/select_printer_fragment.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 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.
--->
-
-<ListView xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@android:id/list"
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent"
-    android:paddingStart="@dimen/printer_list_view_padding_start"
-    android:paddingEnd="@dimen/printer_list_view_padding_end"
-    android:scrollbarStyle="outsideOverlay"
-    android:cacheColorHint="@android:color/transparent"
-    android:scrollbarAlwaysDrawVerticalTrack="true" >
-</ListView>
diff --git a/packages/PrintSpooler/res/layout/spinner_dropdown_item.xml b/packages/PrintSpooler/res/layout/spinner_dropdown_item.xml
index c3c5021..1fb221a 100644
--- a/packages/PrintSpooler/res/layout/spinner_dropdown_item.xml
+++ b/packages/PrintSpooler/res/layout/spinner_dropdown_item.xml
@@ -32,7 +32,7 @@
         android:ellipsize="end"
         android:textIsSelectable="false"
         android:gravity="top|left"
-        android:textColor="@color/item_text_color"
+        android:textColor="?android:attr/textColorPrimary"
         android:duplicateParentState="true">
     </TextView>
 
@@ -45,7 +45,7 @@
         android:ellipsize="end"
         android:textIsSelectable="false"
         android:visibility="gone"
-        android:textColor="@color/print_option_title"
+        android:textColor="?android:attr/textColorPrimary"
         android:duplicateParentState="true">
     </TextView>
 
diff --git a/packages/PrintSpooler/res/values-land/constants.xml b/packages/PrintSpooler/res/values-land/constants.xml
index d68b77e..0db7513 100644
--- a/packages/PrintSpooler/res/values-land/constants.xml
+++ b/packages/PrintSpooler/res/values-land/constants.xml
@@ -18,5 +18,6 @@
 
     <dimen name="printer_list_view_padding_start">48dip</dimen>
     <dimen name="printer_list_view_padding_end">48dip</dimen>
+    <integer name="print_option_column_count">3</integer>
 
 </resources>
diff --git a/core/res/res/drawable/ic_find_next_quantum.xml b/packages/PrintSpooler/res/values-sw600dp-land/constants.xml
similarity index 79%
copy from core/res/res/drawable/ic_find_next_quantum.xml
copy to packages/PrintSpooler/res/values-sw600dp-land/constants.xml
index fee196c..cacdf98 100644
--- a/core/res/res/drawable/ic_find_next_quantum.xml
+++ b/packages/PrintSpooler/res/values-sw600dp-land/constants.xml
@@ -14,6 +14,8 @@
      limitations under the License.
 -->
 
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_find_next_qntm_alpha"
-    android:tint="?attr/colorControlNormal" />
+<resources>
+
+    <integer name="print_option_column_count">6</integer>
+
+</resources>
diff --git a/core/res/res/drawable/ic_clear_quantum.xml b/packages/PrintSpooler/res/values-sw600dp/constants.xml
similarity index 73%
rename from core/res/res/drawable/ic_clear_quantum.xml
rename to packages/PrintSpooler/res/values-sw600dp/constants.xml
index 02f0929..14c099c 100644
--- a/core/res/res/drawable/ic_clear_quantum.xml
+++ b/packages/PrintSpooler/res/values-sw600dp/constants.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
+<!-- Copyright (C) 2013 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.
@@ -14,6 +14,8 @@
      limitations under the License.
 -->
 
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_clear_qntm_alpha"
-    android:tint="?attr/colorControlNormal" />
+<resources>
+
+    <integer name="print_option_column_count">3</integer>
+
+</resources>
diff --git a/core/res/res/drawable/ic_find_next_quantum.xml b/packages/PrintSpooler/res/values/attrs.xml
similarity index 79%
copy from core/res/res/drawable/ic_find_next_quantum.xml
copy to packages/PrintSpooler/res/values/attrs.xml
index fee196c..feb8be1 100644
--- a/core/res/res/drawable/ic_find_next_quantum.xml
+++ b/packages/PrintSpooler/res/values/attrs.xml
@@ -14,6 +14,12 @@
      limitations under the License.
 -->
 
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_find_next_qntm_alpha"
-    android:tint="?attr/colorControlNormal" />
+<resources>
+
+    <declare-styleable name="PrintOptionsLayout">
+
+        <attr name="columnCount" format="integer" />
+
+    </declare-styleable>
+
+</resources>
diff --git a/packages/PrintSpooler/res/values/colors.xml b/packages/PrintSpooler/res/values/colors.xml
index 4fc25b3..fd6ae195 100644
--- a/packages/PrintSpooler/res/values/colors.xml
+++ b/packages/PrintSpooler/res/values/colors.xml
@@ -16,10 +16,6 @@
 
 <resources>
 
-    <color name="container_background">#F2F2F2</color>
-    <color name="important_text">#333333</color>
-    <color name="print_option_title">#888888</color>
-    <color name="separator">#CCCCCC</color>
-    <color name="action_button_background">#FFFFFF</color>
+    <color name="print_button_tint_color">#EEFF41</color>
 
 </resources>
diff --git a/packages/PrintSpooler/res/values/constants.xml b/packages/PrintSpooler/res/values/constants.xml
index e9c925c..9a2c14e 100644
--- a/packages/PrintSpooler/res/values/constants.xml
+++ b/packages/PrintSpooler/res/values/constants.xml
@@ -19,6 +19,8 @@
     <integer name="page_option_value_all">0</integer>
     <integer name="page_option_value_page_range">1</integer>
 
+    <integer name="print_option_column_count">2</integer>
+
     <integer-array name="page_options_values" translatable="false">
         <item>@integer/page_option_value_all</item>
         <item>@integer/page_option_value_page_range</item>
diff --git a/packages/PrintSpooler/res/values/strings.xml b/packages/PrintSpooler/res/values/strings.xml
index d2613d0..d85529c 100644
--- a/packages/PrintSpooler/res/values/strings.xml
+++ b/packages/PrintSpooler/res/values/strings.xml
@@ -19,14 +19,8 @@
     <!-- Title of the PrintSpooler application. [CHAR LIMIT=50] -->
     <string name="app_label">Print Spooler</string>
 
-    <!-- Label of the print dialog's button for advanced printer settings. [CHAR LIMIT=25] -->
-    <string name="advanced_settings_button">Printer settings</string>
-
-    <!-- Label of the print dialog's print button. [CHAR LIMIT=16] -->
-    <string name="print_button">Print</string>
-
-    <!-- Label of the print dialog's save button. [CHAR LIMIT=16] -->
-    <string name="save_button">Save</string>
+    <!-- Label of the print dialog's button for more print options. [CHAR LIMIT=25] -->
+    <string name="more_options_button">More options</string>
 
     <!-- Label of the destination widget. [CHAR LIMIT=20] -->
     <string name="label_destination">Destination</string>
@@ -34,8 +28,14 @@
     <!-- Label of the copies count widget. [CHAR LIMIT=20] -->
     <string name="label_copies">Copies</string>
 
+    <!-- Label of the copies count for the print options summary. [CHAR LIMIT=20] -->
+    <string name="label_copies_summary">Copies:</string>
+
     <!-- Label of the paper size widget. [CHAR LIMIT=20] -->
-    <string name="label_paper_size">Paper Size</string>
+    <string name="label_paper_size">Paper size</string>
+
+    <!-- Label of the paper size for the print options summary. [CHAR LIMIT=20] -->
+    <string name="label_paper_size_summary">Paper size:</string>
 
     <!-- Label of the color mode widget. [CHAR LIMIT=20] -->
     <string name="label_color">Color</string>
@@ -118,19 +118,19 @@
 
     <!-- Notifications -->
 
-    <!-- Template for the notificaiton label for a printing print job. [CHAR LIMIT=25] -->
+    <!-- Template for the notification label for a printing print job. [CHAR LIMIT=25] -->
     <string name="printing_notification_title_template">Printing <xliff:g id="print_job_name" example="foo.jpg">%1$s</xliff:g></string>
 
-    <!-- Template for the notificaiton label for a cancelling print job. [CHAR LIMIT=25] -->
+    <!-- Template for the notification label for a cancelling print job. [CHAR LIMIT=25] -->
     <string name="cancelling_notification_title_template">Cancelling <xliff:g id="print_job_name" example="foo.jpg">%1$s</xliff:g></string>
 
-    <!-- Template for the notificaiton label for a failed print job. [CHAR LIMIT=25] -->
+    <!-- Template for the notification label for a failed print job. [CHAR LIMIT=25] -->
     <string name="failed_notification_title_template">Printer error <xliff:g id="print_job_name" example="foo.jpg">%1$s</xliff:g></string>
 
-    <!-- Template for the notificaiton label for a blocked print job. [CHAR LIMIT=25] -->
+    <!-- Template for the notification label for a blocked print job. [CHAR LIMIT=25] -->
     <string name="blocked_notification_title_template">Printer blocked <xliff:g id="print_job_name" example="foo.jpg">%1$s</xliff:g></string>
 
-    <!-- Template for the notificaiton label for a composite (multiple items) print jobs notification. [CHAR LIMIT=25] -->
+    <!-- Template for the notification label for a composite (multiple items) print jobs notification. [CHAR LIMIT=25] -->
     <plurals name="composite_notification_title_template">
         <item quantity="one"><xliff:g id="print_job_name" example="foo.jpg">%1$d</xliff:g> print job</item>
         <item quantity="other"><xliff:g id="print_job_name" example="foo.jpg">%1$d</xliff:g> print jobs</item>
@@ -139,7 +139,7 @@
     <!-- Label for the notification button for cancelling a print job. [CHAR LIMIT=25] -->
     <string name="cancel">Cancel</string>
 
-    <!-- Label for the notification button for restrating a filed print job. [CHAR LIMIT=25] -->
+    <!-- Label for the notification button for restarting a filed print job. [CHAR LIMIT=25] -->
     <string name="restart">Restart</string>
 
     <!-- Message that there is no connection to a printer. [CHAR LIMIT=40] -->
@@ -151,9 +151,6 @@
     <!-- Label for a printer that is not available. [CHAR LIMIT=25] -->
     <string name="printer_unavailable"><xliff:g id="print_job_name" example="Canon-123GHT">%1$s</xliff:g> &#8211; unavailable</string>
 
-    <!-- Default message of an alert dialog for app error while generating a print job. [CHAR LIMIT=50] -->
-    <string name="print_error_default_message">Couldn\'t generate print job</string>
-
     <!-- Arrays -->
 
     <!-- Color mode labels. -->
@@ -200,4 +197,23 @@
         holder to start the configuration activities of a print service. Should never be needed
         for normal apps.</string>
 
+    <!-- Error messages -->
+
+    <!-- Message for an error when trying to print to a PDF file. [CHAR LIMIT=50] -->
+    <string name="print_write_error_message">Couldn\'t write to file</string>
+
+    <!-- Default message for an error while generating a print job. [CHAR LIMIT=50] -->
+    <string name="print_error_default_message">Couldn\'t generate print job</string>
+
+    <!-- Label for the retry button in the error message. [CHAR LIMIT=50] -->
+    <string name="print_error_retry">Retry</string>
+
+    <!-- Message for the currently selected printer becoming unavailable. [CHAR LIMIT=50] -->
+    <string name="print_error_printer_unavailable">Printer unavailable</string>
+
+    <!-- Long running operations -->
+
+    <!-- Message for the cancel print operation UI while waiting for cancel to be performed. [CHAR LIMIT=50] -->
+    <string name="print_operation_canceling">Cancelling\u2026</string>
+
 </resources>
diff --git a/packages/PrintSpooler/res/values/styles.xml b/packages/PrintSpooler/res/values/styles.xml
index d64380a..9637847 100644
--- a/packages/PrintSpooler/res/values/styles.xml
+++ b/packages/PrintSpooler/res/values/styles.xml
@@ -16,13 +16,6 @@
 
 <resources>
 
-    <style name="PrintOptionTitleTextAppearance">
-        <item name="android:textStyle">normal</item>
-        <item name="android:textSize">14sp</item>
-        <item name="android:textAllCaps">true</item>
-        <item name="android:textColor">@color/print_option_title</item>
-    </style>
-
     <style name="PrintOptionSpinnerStyle">
         <item name="android:paddingTop">0dip</item>
         <item name="android:paddingBottom">0dip</item>
@@ -30,7 +23,7 @@
     </style>
 
     <style name="PrintOptionEditTextStyle">
-         <item name="android:minHeight">?android:attr/listPreferredItemHeightSmall</item>
+
          <item name="android:singleLine">true</item>
          <item name="android:ellipsize">end</item>
     </style>
diff --git a/packages/PrintSpooler/res/values/themes.xml b/packages/PrintSpooler/res/values/themes.xml
index 94ab895..40bf725 100644
--- a/packages/PrintSpooler/res/values/themes.xml
+++ b/packages/PrintSpooler/res/values/themes.xml
@@ -16,15 +16,6 @@
 
 <resources>
 
-    <style name="PrintJobConfigActivityTheme" parent="@android:style/Theme.DeviceDefault.Light.NoActionBar">
-        <item name="android:windowBackground">@android:color/transparent</item>
-        <item name="android:windowSoftInputMode">stateAlwaysHidden|adjustResize</item>
-        <item name="android:windowIsTranslucent">true</item>
-        <item name="android:backgroundDimEnabled">true</item>
-        <item name="android:colorBackgroundCacheHint">@android:color/transparent</item>
-        <item name="android:windowIsFloating">true</item>
-    </style>
-
     <style name="SelectPrinterActivityTheme" parent="@android:style/Theme.DeviceDefault.Light">
         <item name="android:actionBarStyle">@style/SelectPrinterActivityActionBarStyle</item>
     </style>
diff --git a/packages/PrintSpooler/src/com/android/printspooler/PrintDialogFrame.java b/packages/PrintSpooler/src/com/android/printspooler/PrintDialogFrame.java
deleted file mode 100644
index c1c4d21..0000000
--- a/packages/PrintSpooler/src/com/android/printspooler/PrintDialogFrame.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2013 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.printspooler;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.FrameLayout;
-
-public class PrintDialogFrame extends FrameLayout {
-
-    public final int mMaxWidth;
-
-    public int mHeight;
-
-    public PrintDialogFrame(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        mMaxWidth = context.getResources().getDimensionPixelSize(
-                R.dimen.print_dialog_frame_max_width_dip);
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-
-        int measuredWidth  = getMeasuredWidth();
-        final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
-        switch (widthMode) {
-            case MeasureSpec.UNSPECIFIED: {
-                measuredWidth = mMaxWidth;
-            } break;
-
-            case MeasureSpec.AT_MOST: {
-                final int receivedWidth = MeasureSpec.getSize(widthMeasureSpec);
-                measuredWidth = Math.min(mMaxWidth, receivedWidth);
-            } break;
-        }
-
-        mHeight = Math.max(mHeight, getMeasuredHeight());
-
-        int measuredHeight  = getMeasuredHeight();
-        final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
-        switch (heightMode) {
-            case MeasureSpec.UNSPECIFIED: {
-                measuredHeight = mHeight;
-            } break;
-
-             case MeasureSpec.AT_MOST: {
-                final int receivedHeight = MeasureSpec.getSize(heightMeasureSpec);
-                measuredHeight = Math.min(mHeight, receivedHeight);
-            } break;
-        }
-
-        setMeasuredDimension(measuredWidth, measuredHeight);
-    }
-}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java b/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java
deleted file mode 100644
index e3d8d05..0000000
--- a/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java
+++ /dev/null
@@ -1,2966 +0,0 @@
-/*
- * Copyright (C) 2013 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.printspooler;
-
-import android.app.Activity;
-import android.app.Dialog;
-import android.app.LoaderManager;
-import android.content.ActivityNotFoundException;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.Loader;
-import android.content.ServiceConnection;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.ResolveInfo;
-import android.content.pm.ServiceInfo;
-import android.database.DataSetObserver;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.IBinder.DeathRecipient;
-import android.os.Looper;
-import android.os.Message;
-import android.os.RemoteException;
-import android.print.ILayoutResultCallback;
-import android.print.IPrintDocumentAdapter;
-import android.print.IPrintDocumentAdapterObserver;
-import android.print.IWriteResultCallback;
-import android.print.PageRange;
-import android.print.PrintAttributes;
-import android.print.PrintAttributes.Margins;
-import android.print.PrintAttributes.MediaSize;
-import android.print.PrintAttributes.Resolution;
-import android.print.PrintDocumentAdapter;
-import android.print.PrintDocumentInfo;
-import android.print.PrintJobId;
-import android.print.PrintJobInfo;
-import android.print.PrintManager;
-import android.print.PrinterCapabilitiesInfo;
-import android.print.PrinterId;
-import android.print.PrinterInfo;
-import android.printservice.PrintService;
-import android.printservice.PrintServiceInfo;
-import android.provider.DocumentsContract;
-import android.text.Editable;
-import android.text.TextUtils;
-import android.text.TextUtils.SimpleStringSplitter;
-import android.text.TextWatcher;
-import android.util.ArrayMap;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.Gravity;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.View.MeasureSpec;
-import android.view.View.OnAttachStateChangeListener;
-import android.view.View.OnClickListener;
-import android.view.View.OnFocusChangeListener;
-import android.view.ViewConfiguration;
-import android.view.ViewGroup;
-import android.view.ViewGroup.LayoutParams;
-import android.view.ViewPropertyAnimator;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemSelectedListener;
-import android.widget.ArrayAdapter;
-import android.widget.BaseAdapter;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-import android.widget.Spinner;
-import android.widget.TextView;
-
-import com.android.printspooler.MediaSizeUtils.MediaSizeComparator;
-
-import libcore.io.IoUtils;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Activity for configuring a print job.
- */
-public class PrintJobConfigActivity extends Activity {
-
-    private static final String LOG_TAG = "PrintJobConfigActivity";
-
-    private static final boolean DEBUG = false;
-
-    public static final String INTENT_EXTRA_PRINTER_ID = "INTENT_EXTRA_PRINTER_ID";
-
-    private static final int LOADER_ID_PRINTERS_LOADER = 1;
-
-    private static final int ORIENTATION_PORTRAIT = 0;
-    private static final int ORIENTATION_LANDSCAPE = 1;
-
-    private static final int DEST_ADAPTER_MAX_ITEM_COUNT = 9;
-
-    private static final int DEST_ADAPTER_ITEM_ID_SAVE_AS_PDF = Integer.MAX_VALUE;
-    private static final int DEST_ADAPTER_ITEM_ID_ALL_PRINTERS = Integer.MAX_VALUE - 1;
-
-    private static final int ACTIVITY_REQUEST_CREATE_FILE = 1;
-    private static final int ACTIVITY_REQUEST_SELECT_PRINTER = 2;
-    private static final int ACTIVITY_POPULATE_ADVANCED_PRINT_OPTIONS = 3;
-
-    private static final int CONTROLLER_STATE_FINISHED = 1;
-    private static final int CONTROLLER_STATE_FAILED = 2;
-    private static final int CONTROLLER_STATE_CANCELLED = 3;
-    private static final int CONTROLLER_STATE_INITIALIZED = 4;
-    private static final int CONTROLLER_STATE_STARTED = 5;
-    private static final int CONTROLLER_STATE_LAYOUT_STARTED = 6;
-    private static final int CONTROLLER_STATE_LAYOUT_COMPLETED = 7;
-    private static final int CONTROLLER_STATE_WRITE_STARTED = 8;
-    private static final int CONTROLLER_STATE_WRITE_COMPLETED = 9;
-
-    private static final int EDITOR_STATE_INITIALIZED = 1;
-    private static final int EDITOR_STATE_CONFIRMED_PRINT = 2;
-    private static final int EDITOR_STATE_CANCELLED = 3;
-
-    private static final int MIN_COPIES = 1;
-    private static final String MIN_COPIES_STRING = String.valueOf(MIN_COPIES);
-
-    private static final Pattern PATTERN_DIGITS = Pattern.compile("[\\d]+");
-
-    private static final Pattern PATTERN_ESCAPE_SPECIAL_CHARS = Pattern.compile(
-            "(?=[]\\[+&|!(){}^\"~*?:\\\\])");
-
-    private static final Pattern PATTERN_PAGE_RANGE = Pattern.compile(
-            "[\\s]*[0-9]*[\\s]*[\\-]?[\\s]*[0-9]*[\\s]*?(([,])"
-            + "[\\s]*[0-9]*[\\s]*[\\-]?[\\s]*[0-9]*[\\s]*|[\\s]*)+");
-
-    public static final PageRange[] ALL_PAGES_ARRAY = new PageRange[] {PageRange.ALL_PAGES};
-
-    private final PrintAttributes mOldPrintAttributes = new PrintAttributes.Builder().build();
-    private final PrintAttributes mCurrPrintAttributes = new PrintAttributes.Builder().build();
-
-    private final DeathRecipient mDeathRecipient = new DeathRecipient() {
-        @Override
-        public void binderDied() {
-            finish();
-        }
-    };
-
-    private Editor mEditor;
-    private Document mDocument;
-    private PrintController mController;
-
-    private PrintJobId mPrintJobId;
-
-    private IBinder mIPrintDocumentAdapter;
-
-    private Dialog mGeneratingPrintJobDialog;
-
-    private PrintSpoolerProvider mSpoolerProvider;
-
-    private String mCallingPackageName;
-
-    @Override
-    protected void onCreate(Bundle bundle) {
-        super.onCreate(bundle);
-
-        setTitle(R.string.print_dialog);
-
-        Bundle extras = getIntent().getExtras();
-
-        PrintJobInfo printJob = extras.getParcelable(PrintManager.EXTRA_PRINT_JOB);
-        if (printJob == null) {
-            throw new IllegalArgumentException("printJob cannot be null");
-        }
-
-        mPrintJobId = printJob.getId();
-        mIPrintDocumentAdapter = extras.getBinder(PrintManager.EXTRA_PRINT_DOCUMENT_ADAPTER);
-        if (mIPrintDocumentAdapter == null) {
-            throw new IllegalArgumentException("PrintDocumentAdapter cannot be null");
-        }
-
-        try {
-            IPrintDocumentAdapter.Stub.asInterface(mIPrintDocumentAdapter)
-                    .setObserver(new PrintDocumentAdapterObserver(this));
-        } catch (RemoteException re) {
-            finish();
-            return;
-        }
-
-        PrintAttributes attributes = printJob.getAttributes();
-        if (attributes != null) {
-            mCurrPrintAttributes.copyFrom(attributes);
-        }
-
-        mCallingPackageName = extras.getString(DocumentsContract.EXTRA_PACKAGE_NAME);
-
-        setContentView(R.layout.print_job_config_activity_container);
-
-        try {
-            mIPrintDocumentAdapter.linkToDeath(mDeathRecipient, 0);
-        } catch (RemoteException re) {
-            finish();
-            return;
-        }
-
-        mDocument = new Document();
-        mEditor = new Editor();
-
-        mSpoolerProvider = new PrintSpoolerProvider(this,
-                new Runnable() {
-            @Override
-            public void run() {
-                // We got the spooler so unleash the UI.
-                mController = new PrintController(new RemotePrintDocumentAdapter(
-                        IPrintDocumentAdapter.Stub.asInterface(mIPrintDocumentAdapter),
-                        mSpoolerProvider.getSpooler().generateFileForPrintJob(mPrintJobId)));
-                mController.initialize();
-
-                mEditor.initialize();
-                mEditor.postCreate();
-            }
-        });
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        if (mSpoolerProvider.getSpooler() != null) {
-            mEditor.refreshCurrentPrinter();
-        }
-    }
-
-    @Override
-    public void onPause() {
-       if (isFinishing()) {
-           if (mController != null && mController.hasStarted()) {
-               mController.finish();
-           }
-           if (mEditor != null && mEditor.isPrintConfirmed()
-                   && mController != null && mController.isFinished()) {
-                   mSpoolerProvider.getSpooler().setPrintJobState(mPrintJobId,
-                           PrintJobInfo.STATE_QUEUED, null);
-           } else {
-               mSpoolerProvider.getSpooler().setPrintJobState(mPrintJobId,
-                       PrintJobInfo.STATE_CANCELED, null);
-           }
-           if (mGeneratingPrintJobDialog != null) {
-               mGeneratingPrintJobDialog.dismiss();
-               mGeneratingPrintJobDialog = null;
-           }
-           mIPrintDocumentAdapter.unlinkToDeath(mDeathRecipient, 0);
-           mSpoolerProvider.destroy();
-       }
-        super.onPause();
-    }
-
-    public boolean onTouchEvent(MotionEvent event) {
-        if (mController != null && mEditor != null &&
-                !mEditor.isPrintConfirmed() && mEditor.shouldCloseOnTouch(event)) {
-            if (!mController.isWorking()) {
-                PrintJobConfigActivity.this.finish();
-            }
-            mEditor.cancel();
-            return true;
-        }
-        return super.onTouchEvent(event);
-    }
-
-    public boolean onKeyDown(int keyCode, KeyEvent event) {
-        if (keyCode == KeyEvent.KEYCODE_BACK) {
-            event.startTracking();
-        }
-        return super.onKeyDown(keyCode, event);
-    }
-
-    public boolean onKeyUp(int keyCode, KeyEvent event) {
-        if (mController != null && mEditor != null) {
-            if (keyCode == KeyEvent.KEYCODE_BACK) {
-                if (mEditor.isShwoingGeneratingPrintJobUi()) {
-                    return true;
-                }
-                if (event.isTracking() && !event.isCanceled()) {
-                    if (!mController.isWorking()) {
-                        PrintJobConfigActivity.this.finish();
-                    }
-                }
-                mEditor.cancel();
-                return true;
-            }
-        }
-        return super.onKeyUp(keyCode, event);
-    }
-
-    private boolean printAttributesChanged() {
-        return !mOldPrintAttributes.equals(mCurrPrintAttributes);
-    }
-
-    private class PrintController {
-        private final AtomicInteger mRequestCounter = new AtomicInteger();
-
-        private final RemotePrintDocumentAdapter mRemotePrintAdapter;
-
-        private final Bundle mMetadata;
-
-        private final ControllerHandler mHandler;
-
-        private final LayoutResultCallback mLayoutResultCallback;
-
-        private final WriteResultCallback mWriteResultCallback;
-
-        private int mControllerState = CONTROLLER_STATE_INITIALIZED;
-
-        private boolean mHasStarted;
-
-        private PageRange[] mRequestedPages;
-
-        public PrintController(RemotePrintDocumentAdapter adapter) {
-            mRemotePrintAdapter = adapter;
-            mMetadata = new Bundle();
-            mHandler = new ControllerHandler(getMainLooper());
-            mLayoutResultCallback = new LayoutResultCallback(mHandler);
-            mWriteResultCallback = new WriteResultCallback(mHandler);
-        }
-
-        public void initialize() {
-            mHasStarted = false;
-            mControllerState = CONTROLLER_STATE_INITIALIZED;
-        }
-
-        public void cancel() {
-            if (isWorking()) {
-                mRemotePrintAdapter.cancel();
-            }
-            mControllerState = CONTROLLER_STATE_CANCELLED;
-        }
-
-        public boolean isCancelled() {
-            return (mControllerState == CONTROLLER_STATE_CANCELLED);
-        }
-
-        public boolean isFinished() {
-            return (mControllerState == CONTROLLER_STATE_FINISHED);
-        }
-
-        public boolean hasStarted() {
-            return mHasStarted;
-        }
-
-        public boolean hasPerformedLayout() {
-            return mControllerState >= CONTROLLER_STATE_LAYOUT_COMPLETED;
-        }
-
-        public boolean isPerformingLayout() {
-            return mControllerState == CONTROLLER_STATE_LAYOUT_STARTED;
-        }
-
-        public boolean isWorking() {
-            return mControllerState == CONTROLLER_STATE_LAYOUT_STARTED
-                    || mControllerState == CONTROLLER_STATE_WRITE_STARTED;
-        }
-
-        public void start() {
-            mControllerState = CONTROLLER_STATE_STARTED;
-            mHasStarted = true;
-            mRemotePrintAdapter.start();
-        }
-
-        public void update() {
-            if (!mController.hasStarted()) {
-                mController.start();
-            }
-
-            // If the print attributes are the same and we are performing
-            // a layout, then we have to wait for it to completed which will
-            // trigger writing of the necessary pages.
-            final boolean printAttributesChanged = printAttributesChanged();
-            if (!printAttributesChanged && isPerformingLayout()) {
-                return;
-            }
-
-            // If print is confirmed we always do a layout since the previous
-            // ones were for preview and this one is for printing.
-            if (!printAttributesChanged && !mEditor.isPrintConfirmed()) {
-                if (mDocument.info == null) {
-                    // We are waiting for the result of a layout, so do nothing.
-                    return;
-                }
-                // If the attributes didn't change and we have done a layout, then
-                // we do not do a layout but may have to ask the app to write some
-                // pages. Hence, pretend layout completed and nothing changed, so
-                // we handle writing as usual.
-                handleOnLayoutFinished(mDocument.info, false, mRequestCounter.get());
-            } else {
-                mSpoolerProvider.getSpooler().setPrintJobAttributesNoPersistence(
-                        mPrintJobId, mCurrPrintAttributes);
-
-                mMetadata.putBoolean(PrintDocumentAdapter.EXTRA_PRINT_PREVIEW,
-                        !mEditor.isPrintConfirmed());
-
-                mControllerState = CONTROLLER_STATE_LAYOUT_STARTED;
-
-                mRemotePrintAdapter.layout(mOldPrintAttributes, mCurrPrintAttributes,
-                        mLayoutResultCallback, mMetadata, mRequestCounter.incrementAndGet());
-
-                mOldPrintAttributes.copyFrom(mCurrPrintAttributes);
-            }
-        }
-
-        public void finish() {
-            mControllerState = CONTROLLER_STATE_FINISHED;
-            mRemotePrintAdapter.finish();
-        }
-
-        private void handleOnLayoutFinished(PrintDocumentInfo info,
-                boolean layoutChanged, int sequence) {
-            if (mRequestCounter.get() != sequence) {
-                return;
-            }
-
-            if (isCancelled()) {
-                mEditor.updateUi();
-                if (mEditor.isDone()) {
-                    PrintJobConfigActivity.this.finish();
-                }
-                return;
-            }
-
-            final int oldControllerState = mControllerState;
-
-            if (mControllerState == CONTROLLER_STATE_LAYOUT_STARTED) {
-                mControllerState = CONTROLLER_STATE_LAYOUT_COMPLETED;
-            }
-
-            // For layout purposes we care only whether the type or the page
-            // count changed. We still do not have the size since we did not
-            // call write. We use "layoutChanged" set by the application to
-            // know whether something else changed about the document.
-            final boolean infoChanged = !equalsIgnoreSize(info, mDocument.info);
-            // If the info changed, we update the document and the print job.
-            if (infoChanged) {
-                mDocument.info = info;
-                // Set the info.
-                mSpoolerProvider.getSpooler().setPrintJobPrintDocumentInfoNoPersistence(
-                        mPrintJobId, info);
-            }
-
-            // If the document info or the layout changed, then
-            // drop the pages since we have to fetch them again.
-            if (infoChanged || layoutChanged) {
-                mDocument.pages = null;
-                mSpoolerProvider.getSpooler().setPrintJobPagesNoPersistence(
-                        mPrintJobId, null);
-            }
-
-            PageRange[] oldRequestedPages = mRequestedPages;
-
-            // No pages means that the user selected an invalid range while we
-            // were doing a layout or the layout returned a document info for
-            // which the selected range is invalid. In such a case we do not
-            // write anything and wait for the user to fix the range which will
-            // trigger an update.
-            mRequestedPages = mEditor.getRequestedPages();
-            if (mRequestedPages == null || mRequestedPages.length == 0) {
-                mEditor.updateUi();
-                if (mEditor.isDone()) {
-                    PrintJobConfigActivity.this.finish();
-                }
-                return;
-            } else {
-                // If print is not confirmed we just ask for the first of the
-                // selected pages to emulate a behavior that shows preview
-                // increasing the chances that apps will implement the APIs
-                // correctly.
-                if (!mEditor.isPrintConfirmed()) {
-                    if (ALL_PAGES_ARRAY.equals(mRequestedPages)) {
-                        mRequestedPages = new PageRange[] {new PageRange(0, 0)};
-                    } else {
-                        final int firstPage = mRequestedPages[0].getStart();
-                        mRequestedPages = new PageRange[] {new PageRange(firstPage, firstPage)};
-                    }
-                }
-            }
-
-            // If the info and the layout did not change...
-            if (!infoChanged && !layoutChanged
-                    // and we have the requested pages ... 
-                    && (PageRangeUtils.contains(mDocument.pages, mRequestedPages))
-                        // ...or the requested pages are being written...
-                        || (oldControllerState == CONTROLLER_STATE_WRITE_STARTED
-                            && oldRequestedPages != null
-                            && PageRangeUtils.contains(oldRequestedPages, mRequestedPages))) {
-                // Nothing interesting changed and we have all requested pages.
-                // Then update the print jobs's pages as we will not do a write
-                // and we usually update the pages in the write complete callback.
-                if (mDocument.pages != null) {
-                    // Update the print job's pages given we have them.
-                    updatePrintJobPages(mDocument.pages, mRequestedPages);
-                }
-                mEditor.updateUi();
-                if (mEditor.isDone()) {
-                    requestCreatePdfFileOrFinish();
-                }
-                return;
-            }
-
-            mEditor.updateUi();
-
-            // Request a write of the pages of interest.
-            mControllerState = CONTROLLER_STATE_WRITE_STARTED;
-            mRemotePrintAdapter.write(mRequestedPages, mWriteResultCallback,
-                    mRequestCounter.incrementAndGet());
-        }
-
-        private void handleOnLayoutFailed(final CharSequence error, int sequence) {
-            if (mRequestCounter.get() != sequence) {
-                return;
-            }
-            mControllerState = CONTROLLER_STATE_FAILED;
-            mEditor.showUi(Editor.UI_ERROR, new Runnable() {
-                @Override
-                public void run() {
-                    if (!TextUtils.isEmpty(error)) {
-                        TextView messageView = (TextView) findViewById(R.id.message);
-                        messageView.setText(error);
-                    }
-                }
-            });
-        }
-
-        private void handleOnWriteFinished(PageRange[] pages, int sequence) {
-            if (mRequestCounter.get() != sequence) {
-                return;
-            }
-
-            if (isCancelled()) {
-                if (mEditor.isDone()) {
-                    PrintJobConfigActivity.this.finish();
-                }
-                return;
-            }
-
-            mControllerState = CONTROLLER_STATE_WRITE_COMPLETED;
-
-            // Update the document size.
-            File file = mSpoolerProvider.getSpooler()
-                    .generateFileForPrintJob(mPrintJobId);
-            mDocument.info.setDataSize(file.length());
-
-            // Update the print job with the updated info.
-            mSpoolerProvider.getSpooler().setPrintJobPrintDocumentInfoNoPersistence(
-                    mPrintJobId, mDocument.info);
-
-            // Update which pages we have fetched.
-            mDocument.pages = PageRangeUtils.normalize(pages);
-
-            if (DEBUG) {
-                Log.i(LOG_TAG, "Requested: " + Arrays.toString(mRequestedPages)
-                        + " and got: " + Arrays.toString(mDocument.pages));
-            }
-
-            updatePrintJobPages(mDocument.pages, mRequestedPages);
-
-            if (mEditor.isDone()) {
-                requestCreatePdfFileOrFinish();
-            }
-        }
-
-        private void updatePrintJobPages(PageRange[] writtenPages, PageRange[] requestedPages) {
-            // Adjust the print job pages based on what was requested and written.
-            // The cases are ordered in the most expected to the least expected.
-            if (Arrays.equals(writtenPages, requestedPages)) {
-                // We got a document with exactly the pages we wanted. Hence,
-                // the printer has to print all pages in the data.
-                mSpoolerProvider.getSpooler().setPrintJobPagesNoPersistence(mPrintJobId,
-                        ALL_PAGES_ARRAY);
-            } else if (Arrays.equals(writtenPages, ALL_PAGES_ARRAY)) {
-                // We requested specific pages but got all of them. Hence,
-                // the printer has to print only the requested pages.
-                mSpoolerProvider.getSpooler().setPrintJobPagesNoPersistence(mPrintJobId,
-                        requestedPages);
-            } else if (PageRangeUtils.contains(writtenPages, requestedPages)) {
-                // We requested specific pages and got more but not all pages.
-                // Hence, we have to offset appropriately the printed pages to
-                // be based off the start of the written ones instead of zero.
-                // The written pages are always non-null and not empty.
-                final int offset = -writtenPages[0].getStart();
-                PageRange[] offsetPages = Arrays.copyOf(requestedPages, requestedPages.length);
-                PageRangeUtils.offset(offsetPages, offset);
-                mSpoolerProvider.getSpooler().setPrintJobPagesNoPersistence(mPrintJobId,
-                        offsetPages);
-            } else if (Arrays.equals(requestedPages, ALL_PAGES_ARRAY)
-                    && writtenPages.length == 1 && writtenPages[0].getStart() == 0
-                    && writtenPages[0].getEnd() == mDocument.info.getPageCount() - 1) {
-                // We requested all pages via the special constant and got all
-                // of them as an explicit enumeration. Hence, the printer has
-                // to print only the requested pages.
-                mSpoolerProvider.getSpooler().setPrintJobPagesNoPersistence(mPrintJobId,
-                        writtenPages);
-            } else {
-                // We did not get the pages we requested, then the application
-                // misbehaves, so we fail quickly.
-                mControllerState = CONTROLLER_STATE_FAILED;
-                Log.e(LOG_TAG, "Received invalid pages from the app: requested="
-                        + Arrays.toString(requestedPages) + " written="
-                        + Arrays.toString(writtenPages));
-                mEditor.showUi(Editor.UI_ERROR, null);
-            }
-        }
-
-        private void requestCreatePdfFileOrFinish() {
-            if (mEditor.isPrintingToPdf()) {
-                Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
-                intent.setType("application/pdf");
-                intent.putExtra(Intent.EXTRA_TITLE, mDocument.info.getName());
-                intent.putExtra(DocumentsContract.EXTRA_PACKAGE_NAME, mCallingPackageName);
-                startActivityForResult(intent, ACTIVITY_REQUEST_CREATE_FILE);
-            } else {
-                PrintJobConfigActivity.this.finish();
-            }
-        }
-
-        private void handleOnWriteFailed(final CharSequence error, int sequence) {
-            if (mRequestCounter.get() != sequence) {
-                return;
-            }
-            mControllerState = CONTROLLER_STATE_FAILED;
-            mEditor.showUi(Editor.UI_ERROR, new Runnable() {
-                @Override
-                public void run() {
-                    if (!TextUtils.isEmpty(error)) {
-                        TextView messageView = (TextView) findViewById(R.id.message);
-                        messageView.setText(error);
-                    }
-                }
-            });
-        }
-
-        private boolean equalsIgnoreSize(PrintDocumentInfo lhs, PrintDocumentInfo rhs) {
-            if (lhs == rhs) {
-                return true;
-            }
-            if (lhs == null) {
-                if (rhs != null) {
-                    return false;
-                }
-            } else {
-                if (rhs == null) {
-                    return false;
-                }
-                if (lhs.getContentType() != rhs.getContentType()
-                        || lhs.getPageCount() != rhs.getPageCount()) {
-                    return false;
-                }
-            }
-            return true;
-        }
-
-        private final class ControllerHandler extends Handler {
-            public static final int MSG_ON_LAYOUT_FINISHED = 1;
-            public static final int MSG_ON_LAYOUT_FAILED = 2;
-            public static final int MSG_ON_WRITE_FINISHED = 3;
-            public static final int MSG_ON_WRITE_FAILED = 4;
-
-            public ControllerHandler(Looper looper) {
-                super(looper, null, false);
-            }
-
-            @Override
-            public void handleMessage(Message message) {
-                switch (message.what) {
-                    case MSG_ON_LAYOUT_FINISHED: {
-                        PrintDocumentInfo info = (PrintDocumentInfo) message.obj;
-                        final boolean changed = (message.arg1 == 1);
-                        final int sequence = message.arg2;
-                        handleOnLayoutFinished(info, changed, sequence);
-                    } break;
-
-                    case MSG_ON_LAYOUT_FAILED: {
-                        CharSequence error = (CharSequence) message.obj;
-                        final int sequence = message.arg1;
-                        handleOnLayoutFailed(error, sequence);
-                    } break;
-
-                    case MSG_ON_WRITE_FINISHED: {
-                        PageRange[] pages = (PageRange[]) message.obj;
-                        final int sequence = message.arg1;
-                        handleOnWriteFinished(pages, sequence);
-                    } break;
-
-                    case MSG_ON_WRITE_FAILED: {
-                        CharSequence error = (CharSequence) message.obj;
-                        final int sequence = message.arg1;
-                        handleOnWriteFailed(error, sequence);
-                    } break;
-                }
-            }
-        }
-    }
-
-    private static final class LayoutResultCallback extends ILayoutResultCallback.Stub {
-        private final WeakReference<PrintController.ControllerHandler> mWeakHandler;
-
-        public LayoutResultCallback(PrintController.ControllerHandler handler) {
-            mWeakHandler = new WeakReference<PrintController.ControllerHandler>(handler);
-        }
-
-        @Override
-        public void onLayoutFinished(PrintDocumentInfo info, boolean changed, int sequence) {
-            Handler handler = mWeakHandler.get();
-            if (handler != null) {
-                handler.obtainMessage(PrintController.ControllerHandler.MSG_ON_LAYOUT_FINISHED,
-                        changed ? 1 : 0, sequence, info).sendToTarget();
-            }
-        }
-
-        @Override
-        public void onLayoutFailed(CharSequence error, int sequence) {
-            Handler handler = mWeakHandler.get();
-            if (handler != null) {
-                handler.obtainMessage(PrintController.ControllerHandler.MSG_ON_LAYOUT_FAILED,
-                        sequence, 0, error).sendToTarget();
-            }
-        }
-    }
-
-    private static final class WriteResultCallback extends IWriteResultCallback.Stub {
-        private final WeakReference<PrintController.ControllerHandler> mWeakHandler;
-
-        public WriteResultCallback(PrintController.ControllerHandler handler) {
-            mWeakHandler = new WeakReference<PrintController.ControllerHandler>(handler);
-        }
-
-        @Override
-        public void onWriteFinished(PageRange[] pages, int sequence) {
-            Handler handler = mWeakHandler.get();
-            if (handler != null) {
-                handler.obtainMessage(PrintController.ControllerHandler.MSG_ON_WRITE_FINISHED,
-                        sequence, 0, pages).sendToTarget();
-            }
-        }
-
-        @Override
-        public void onWriteFailed(CharSequence error, int sequence) {
-            Handler handler = mWeakHandler.get();
-            if (handler != null) {
-                handler.obtainMessage(PrintController.ControllerHandler.MSG_ON_WRITE_FAILED,
-                    sequence, 0, error).sendToTarget();
-            }
-        }
-    }
-
-    @Override
-    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-        switch (requestCode) {
-            case ACTIVITY_REQUEST_CREATE_FILE: {
-                if (data != null) {
-                    Uri uri = data.getData();
-                    writePrintJobDataAndFinish(uri);
-                } else {
-                    mEditor.showUi(Editor.UI_EDITING_PRINT_JOB,
-                            new Runnable() {
-                        @Override
-                        public void run() {
-                            mEditor.initialize();
-                            mEditor.bindUi();
-                            mEditor.reselectCurrentPrinter();
-                            mEditor.updateUi();
-                        }
-                    });
-                }
-            } break;
-
-            case ACTIVITY_REQUEST_SELECT_PRINTER: {
-                if (resultCode == RESULT_OK) {
-                    PrinterId printerId = (PrinterId) data.getParcelableExtra(
-                            INTENT_EXTRA_PRINTER_ID);
-                    if (printerId != null) {
-                        mEditor.ensurePrinterSelected(printerId);
-                        break;
-                    }
-                }
-                mEditor.ensureCurrentPrinterSelected();
-            } break;
-
-            case ACTIVITY_POPULATE_ADVANCED_PRINT_OPTIONS: {
-                if (resultCode == RESULT_OK) {
-                    PrintJobInfo printJobInfo = (PrintJobInfo) data.getParcelableExtra(
-                            PrintService.EXTRA_PRINT_JOB_INFO);
-                    if (printJobInfo != null) {
-                        mEditor.updateFromAdvancedOptions(printJobInfo);
-                        break;
-                    }
-                }
-                mEditor.cancel();
-                PrintJobConfigActivity.this.finish();
-            } break;
-        }
-    }
-
-    private void writePrintJobDataAndFinish(final Uri uri) {
-        new AsyncTask<Void, Void, Void>() {
-            @Override
-            protected Void doInBackground(Void... params) {
-                InputStream in = null;
-                OutputStream out = null;
-                try {
-                    PrintJobInfo printJob = mSpoolerProvider.getSpooler()
-                            .getPrintJobInfo(mPrintJobId, PrintManager.APP_ID_ANY);
-                    if (printJob == null) {
-                        return null;
-                    }
-                    File file = mSpoolerProvider.getSpooler()
-                            .generateFileForPrintJob(mPrintJobId);
-                    in = new FileInputStream(file);
-                    out = getContentResolver().openOutputStream(uri);
-                    final byte[] buffer = new byte[8192];
-                    while (true) {
-                        final int readByteCount = in.read(buffer);
-                        if (readByteCount < 0) {
-                            break;
-                        }
-                        out.write(buffer, 0, readByteCount);
-                    }
-                } catch (FileNotFoundException fnfe) {
-                    Log.e(LOG_TAG, "Error writing print job data!", fnfe);
-                } catch (IOException ioe) {
-                    Log.e(LOG_TAG, "Error writing print job data!", ioe);
-                } finally {
-                    IoUtils.closeQuietly(in);
-                    IoUtils.closeQuietly(out);
-                }
-                return null;
-            }
-
-            @Override
-            public void onPostExecute(Void result) {
-                mEditor.cancel();
-                PrintJobConfigActivity.this.finish();
-            }
-        }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, (Void[]) null);
-    }
-
-    private final class Editor {
-        private static final int UI_NONE = 0;
-        private static final int UI_EDITING_PRINT_JOB = 1;
-        private static final int UI_GENERATING_PRINT_JOB = 2;
-        private static final int UI_ERROR = 3;
-
-        private EditText mCopiesEditText;
-
-        private TextView mRangeOptionsTitle;
-        private TextView mPageRangeTitle;
-        private EditText mPageRangeEditText;
-
-        private Spinner mDestinationSpinner;
-        private DestinationAdapter mDestinationSpinnerAdapter;
-
-        private Spinner mMediaSizeSpinner;
-        private ArrayAdapter<SpinnerItem<MediaSize>> mMediaSizeSpinnerAdapter;
-
-        private Spinner mColorModeSpinner;
-        private ArrayAdapter<SpinnerItem<Integer>> mColorModeSpinnerAdapter;
-
-        private Spinner mOrientationSpinner;
-        private  ArrayAdapter<SpinnerItem<Integer>> mOrientationSpinnerAdapter;
-
-        private Spinner mRangeOptionsSpinner;
-        private ArrayAdapter<SpinnerItem<Integer>> mRangeOptionsSpinnerAdapter;
-
-        private SimpleStringSplitter mStringCommaSplitter =
-                new SimpleStringSplitter(',');
-
-        private View mContentContainer;
-
-        private View mAdvancedPrintOptionsContainer;
-
-        private Button mAdvancedOptionsButton;
-
-        private Button mPrintButton;
-
-        private PrinterId mNextPrinterId;
-
-        private PrinterInfo mCurrentPrinter;
-
-        private MediaSizeComparator mMediaSizeComparator;
-
-        private final OnFocusChangeListener mFocusListener = new OnFocusChangeListener() {
-            @Override
-            public void onFocusChange(View view, boolean hasFocus) {
-                EditText editText = (EditText) view;
-                if (!TextUtils.isEmpty(editText.getText())) {
-                    editText.setSelection(editText.getText().length());
-                }
-            }
-        };
-
-        private final OnItemSelectedListener mOnItemSelectedListener =
-                new AdapterView.OnItemSelectedListener() {
-            @Override
-            public void onItemSelected(AdapterView<?> spinner, View view, int position, long id) {
-                if (spinner == mDestinationSpinner) {
-                    if (mIgnoreNextDestinationChange) {
-                        mIgnoreNextDestinationChange = false;
-                        return;
-                    }
-
-                    if (position == AdapterView.INVALID_POSITION) {
-                        updateUi();
-                        return;
-                    }
-
-                    if (id == DEST_ADAPTER_ITEM_ID_ALL_PRINTERS) {
-                        startSelectPrinterActivity();
-                        return;
-                    }
-
-                    mCapabilitiesTimeout.remove();
-
-                    mCurrentPrinter = (PrinterInfo) mDestinationSpinnerAdapter
-                            .getItem(position);
-
-                    mSpoolerProvider.getSpooler().setPrintJobPrinterNoPersistence(
-                            mPrintJobId, mCurrentPrinter);
-
-                    if (mCurrentPrinter.getStatus() == PrinterInfo.STATUS_UNAVAILABLE) {
-                        mCapabilitiesTimeout.post();
-                        updateUi();
-                        return;
-                    }
-
-                    PrinterCapabilitiesInfo capabilities = mCurrentPrinter.getCapabilities();
-                    if (capabilities == null) {
-                        mCapabilitiesTimeout.post();
-                        updateUi();
-                        refreshCurrentPrinter();
-                    } else {
-                        updatePrintAttributes(capabilities);
-                        updateUi();
-                        mController.update();
-                        refreshCurrentPrinter();
-                    }
-                } else if (spinner == mMediaSizeSpinner) {
-                    if (mIgnoreNextMediaSizeChange) {
-                        mIgnoreNextMediaSizeChange = false;
-                        return;
-                    }
-                    if (mOldMediaSizeSelectionIndex
-                            == mMediaSizeSpinner.getSelectedItemPosition()) {
-                        mOldMediaSizeSelectionIndex = AdapterView.INVALID_POSITION;
-                        return;
-                    }
-                    SpinnerItem<MediaSize> mediaItem = mMediaSizeSpinnerAdapter.getItem(position);
-                    if (mOrientationSpinner.getSelectedItemPosition() == 0) {
-                        mCurrPrintAttributes.setMediaSize(mediaItem.value.asPortrait());
-                    } else {
-                        mCurrPrintAttributes.setMediaSize(mediaItem.value.asLandscape());
-                    }
-                    if (!hasErrors()) {
-                        mController.update();
-                    }
-                } else if (spinner == mColorModeSpinner) {
-                    if (mIgnoreNextColorChange) {
-                        mIgnoreNextColorChange = false;
-                        return;
-                    }
-                    if (mOldColorModeSelectionIndex
-                            == mColorModeSpinner.getSelectedItemPosition()) {
-                        mOldColorModeSelectionIndex = AdapterView.INVALID_POSITION;
-                        return;
-                    }
-                    SpinnerItem<Integer> colorModeItem =
-                            mColorModeSpinnerAdapter.getItem(position);
-                    mCurrPrintAttributes.setColorMode(colorModeItem.value);
-                    if (!hasErrors()) {
-                        mController.update();
-                    }
-                } else if (spinner == mOrientationSpinner) {
-                    if (mIgnoreNextOrientationChange) {
-                        mIgnoreNextOrientationChange = false;
-                        return;
-                    }
-                    SpinnerItem<Integer> orientationItem =
-                            mOrientationSpinnerAdapter.getItem(position);
-                    setCurrentPrintAttributesOrientation(orientationItem.value);
-                    if (!hasErrors()) {
-                        mController.update();
-                    }
-                } else if (spinner == mRangeOptionsSpinner) {
-                    if (mIgnoreNextRangeOptionChange) {
-                        mIgnoreNextRangeOptionChange = false;
-                        return;
-                    }
-                    updateUi();
-                    if (!hasErrors()) {
-                        mController.update();
-                    }
-                }
-            }
-
-            @Override
-            public void onNothingSelected(AdapterView<?> parent) {
-                /* do nothing*/
-            }
-        };
-
-        private void setCurrentPrintAttributesOrientation(int orientation) {
-            MediaSize mediaSize = mCurrPrintAttributes.getMediaSize();
-            if (orientation == ORIENTATION_PORTRAIT) {
-                if (!mediaSize.isPortrait()) {
-                    // Rotate the media size.
-                    mCurrPrintAttributes.setMediaSize(mediaSize.asPortrait());
-
-                    // Rotate the resolution.
-                    Resolution oldResolution = mCurrPrintAttributes.getResolution();
-                    Resolution newResolution = new Resolution(
-                            oldResolution.getId(),
-                            oldResolution.getLabel(),
-                            oldResolution.getVerticalDpi(),
-                            oldResolution.getHorizontalDpi());
-                    mCurrPrintAttributes.setResolution(newResolution);
-
-                    // Rotate the physical margins.
-                    Margins oldMinMargins = mCurrPrintAttributes.getMinMargins();
-                    Margins newMinMargins = new Margins(
-                            oldMinMargins.getBottomMils(),
-                            oldMinMargins.getLeftMils(),
-                            oldMinMargins.getTopMils(),
-                            oldMinMargins.getRightMils());
-                    mCurrPrintAttributes.setMinMargins(newMinMargins);
-                }
-            } else {
-                if (mediaSize.isPortrait()) {
-                    // Rotate the media size.
-                    mCurrPrintAttributes.setMediaSize(mediaSize.asLandscape());
-
-                    // Rotate the resolution.
-                    Resolution oldResolution = mCurrPrintAttributes.getResolution();
-                    Resolution newResolution = new Resolution(
-                            oldResolution.getId(),
-                            oldResolution.getLabel(),
-                            oldResolution.getVerticalDpi(),
-                            oldResolution.getHorizontalDpi());
-                    mCurrPrintAttributes.setResolution(newResolution);
-
-                    // Rotate the physical margins.
-                    Margins oldMinMargins = mCurrPrintAttributes.getMinMargins();
-                    Margins newMargins = new Margins(
-                            oldMinMargins.getTopMils(),
-                            oldMinMargins.getRightMils(),
-                            oldMinMargins.getBottomMils(),
-                            oldMinMargins.getLeftMils());
-                    mCurrPrintAttributes.setMinMargins(newMargins);
-                }
-            }
-        }
-
-        private void updatePrintAttributes(PrinterCapabilitiesInfo capabilities) {
-            PrintAttributes defaults = capabilities.getDefaults();
-
-            // Sort the media sizes based on the current locale.
-            List<MediaSize> sortedMediaSizes = new ArrayList<MediaSize>(
-                    capabilities.getMediaSizes());
-            Collections.sort(sortedMediaSizes, mMediaSizeComparator);
-
-            // Media size.
-            MediaSize currMediaSize = mCurrPrintAttributes.getMediaSize();
-            if (currMediaSize == null) {
-                mCurrPrintAttributes.setMediaSize(defaults.getMediaSize());
-            } else {
-                MediaSize currMediaSizePortrait = currMediaSize.asPortrait();
-                final int mediaSizeCount = sortedMediaSizes.size();
-                for (int i = 0; i < mediaSizeCount; i++) {
-                    MediaSize mediaSize = sortedMediaSizes.get(i);
-                    if (currMediaSizePortrait.equals(mediaSize.asPortrait())) {
-                        mCurrPrintAttributes.setMediaSize(currMediaSize);
-                        break;
-                    }
-                }
-            }
-
-            // Color mode.
-            final int colorMode = mCurrPrintAttributes.getColorMode();
-            if ((capabilities.getColorModes() & colorMode) == 0) {
-                mCurrPrintAttributes.setColorMode(colorMode);
-            }
-
-            // Resolution
-            Resolution resolution = mCurrPrintAttributes.getResolution();
-            if (resolution == null || !capabilities.getResolutions().contains(resolution)) {
-                mCurrPrintAttributes.setResolution(defaults.getResolution());
-            }
-
-            // Margins.
-            Margins margins = mCurrPrintAttributes.getMinMargins();
-            if (margins == null) {
-                mCurrPrintAttributes.setMinMargins(defaults.getMinMargins());
-            } else {
-                Margins minMargins = capabilities.getMinMargins();
-                if (margins.getLeftMils() < minMargins.getLeftMils()
-                        || margins.getTopMils() < minMargins.getTopMils()
-                        || margins.getRightMils() > minMargins.getRightMils()
-                        || margins.getBottomMils() > minMargins.getBottomMils()) {
-                    mCurrPrintAttributes.setMinMargins(defaults.getMinMargins());
-                }
-            }
-        }
-
-        private final TextWatcher mCopiesTextWatcher = new TextWatcher() {
-            @Override
-            public void onTextChanged(CharSequence s, int start, int before, int count) {
-                /* do nothing */
-            }
-
-            @Override
-            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
-                /* do nothing */
-            }
-
-            @Override
-            public void afterTextChanged(Editable editable) {
-                if (mIgnoreNextCopiesChange) {
-                    mIgnoreNextCopiesChange = false;
-                    return;
-                }
-
-                final boolean hadErrors = hasErrors();
-
-                if (editable.length() == 0) {
-                    mCopiesEditText.setError("");
-                    updateUi();
-                    return;
-                }
-
-                int copies = 0;
-                try {
-                    copies = Integer.parseInt(editable.toString());
-                } catch (NumberFormatException nfe) {
-                    /* ignore */
-                }
-
-                if (copies < MIN_COPIES) {
-                    mCopiesEditText.setError("");
-                    updateUi();
-                    return;
-                }
-
-                mCopiesEditText.setError(null);
-                mSpoolerProvider.getSpooler().setPrintJobCopiesNoPersistence(
-                        mPrintJobId, copies);
-                updateUi();
-
-                if (hadErrors && !hasErrors() && printAttributesChanged()) {
-                    mController.update();
-                }
-            }
-        };
-
-        private final TextWatcher mRangeTextWatcher = new TextWatcher() {
-            @Override
-            public void onTextChanged(CharSequence s, int start, int before, int count) {
-                /* do nothing */
-            }
-
-            @Override
-            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
-                /* do nothing */
-            }
-
-            @Override
-            public void afterTextChanged(Editable editable) {
-                if (mIgnoreNextRangeChange) {
-                    mIgnoreNextRangeChange = false;
-                    return;
-                }
-
-                final boolean hadErrors = hasErrors();
-
-                String text = editable.toString();
-
-                if (TextUtils.isEmpty(text)) {
-                    mPageRangeEditText.setError("");
-                    updateUi();
-                    return;
-                }
-
-                String escapedText = PATTERN_ESCAPE_SPECIAL_CHARS.matcher(text).replaceAll("////");
-                if (!PATTERN_PAGE_RANGE.matcher(escapedText).matches()) {
-                    mPageRangeEditText.setError("");
-                    updateUi();
-                    return;
-                }
-
-                // The range
-                Matcher matcher = PATTERN_DIGITS.matcher(text);
-                while (matcher.find()) {
-                    String numericString = text.substring(matcher.start(), matcher.end()).trim();
-                    if (TextUtils.isEmpty(numericString)) {
-                        continue;
-                    }
-                    final int pageIndex = Integer.parseInt(numericString);
-                    if (pageIndex < 1 || pageIndex > mDocument.info.getPageCount()) {
-                        mPageRangeEditText.setError("");
-                        updateUi();
-                        return;
-                    }
-                }
-
-                // We intentionally do not catch the case of the from page being
-                // greater than the to page. When computing the requested pages
-                // we just swap them if necessary.
-
-                // Keep the print job up to date with the selected pages if we
-                // know how many pages are there in the document.
-                PageRange[] requestedPages = getRequestedPages();
-                if (requestedPages != null && requestedPages.length > 0
-                        && requestedPages[requestedPages.length - 1].getEnd()
-                                < mDocument.info.getPageCount()) {
-                    mSpoolerProvider.getSpooler().setPrintJobPagesNoPersistence(
-                            mPrintJobId, requestedPages);
-                }
-
-                mPageRangeEditText.setError(null);
-                mPrintButton.setEnabled(true);
-                updateUi();
-
-                if (hadErrors && !hasErrors() && printAttributesChanged()) {
-                    updateUi();
-                }
-            }
-        };
-
-        private final WaitForPrinterCapabilitiesTimeout mCapabilitiesTimeout =
-                new WaitForPrinterCapabilitiesTimeout();
-
-        private int mEditorState;
-
-        private boolean mIgnoreNextDestinationChange;
-        private int mOldMediaSizeSelectionIndex;
-        private int mOldColorModeSelectionIndex;
-        private boolean mIgnoreNextOrientationChange;
-        private boolean mIgnoreNextRangeOptionChange;
-        private boolean mIgnoreNextCopiesChange;
-        private boolean mIgnoreNextRangeChange;
-        private boolean mIgnoreNextMediaSizeChange;
-        private boolean mIgnoreNextColorChange;
-
-        private int mCurrentUi = UI_NONE;
-
-        private boolean mFavoritePrinterSelected;
-
-        public Editor() {
-            showUi(UI_EDITING_PRINT_JOB, null);
-        }
-
-        public void postCreate() {
-            // Destination.
-            mMediaSizeComparator = new MediaSizeComparator(PrintJobConfigActivity.this);
-            mDestinationSpinnerAdapter = new DestinationAdapter();
-            mDestinationSpinnerAdapter.registerDataSetObserver(new DataSetObserver() {
-                @Override
-                public void onChanged() {
-                    // Initially, we have only safe to PDF as a printer but after some
-                    // printers are loaded we want to select the user's favorite one
-                    // which is the first.
-                    if (!mFavoritePrinterSelected && mDestinationSpinnerAdapter.getCount() > 1) {
-                        mFavoritePrinterSelected = true;
-                        mDestinationSpinner.setSelection(0);
-                        // Workaround again the weird spinner behavior to notify for selection
-                        // change on the next layout pass as the current printer is used below.
-                        mCurrentPrinter = (PrinterInfo) mDestinationSpinnerAdapter.getItem(0);
-                    }
-
-                    // If there is a next printer to select and we succeed selecting
-                    // it - done. Let the selection handling code make everything right.
-                    if (mNextPrinterId != null && selectPrinter(mNextPrinterId)) {
-                        mNextPrinterId = null;
-                        return;
-                    }
-
-                    // If the current printer properties changed, we update the UI.
-                    if (mCurrentPrinter != null) {
-                        final int printerCount = mDestinationSpinnerAdapter.getCount();
-                        for (int i = 0; i < printerCount; i++) {
-                            Object item = mDestinationSpinnerAdapter.getItem(i);
-                            // Some items are not printers
-                            if (item instanceof PrinterInfo) {
-                                PrinterInfo printer = (PrinterInfo) item;
-                                if (!printer.getId().equals(mCurrentPrinter.getId())) {
-                                    continue;
-                                }
-
-                                // If nothing changed - done.
-                                if (mCurrentPrinter.equals(printer)) {
-                                    return;
-                                }
-
-                                // If the current printer became available and has no
-                                // capabilities, we refresh it.
-                                if (mCurrentPrinter.getStatus() == PrinterInfo.STATUS_UNAVAILABLE
-                                        && printer.getStatus() != PrinterInfo.STATUS_UNAVAILABLE
-                                        && printer.getCapabilities() == null) {
-                                    if (!mCapabilitiesTimeout.isPosted()) {
-                                        mCapabilitiesTimeout.post();
-                                    }
-                                    mCurrentPrinter.copyFrom(printer);
-                                    refreshCurrentPrinter();
-                                    return;
-                                }
-
-                                // If the current printer became unavailable or its
-                                // capabilities go away, we update the UI and add a
-                                // timeout to declare the printer as unavailable.
-                                if ((mCurrentPrinter.getStatus() != PrinterInfo.STATUS_UNAVAILABLE
-                                        && printer.getStatus() == PrinterInfo.STATUS_UNAVAILABLE)
-                                    || (mCurrentPrinter.getCapabilities() != null
-                                        && printer.getCapabilities() == null)) {
-                                    if (!mCapabilitiesTimeout.isPosted()) {
-                                        mCapabilitiesTimeout.post();
-                                    }
-                                    mCurrentPrinter.copyFrom(printer);
-                                    updateUi();
-                                    return;
-                                }
-
-                                // We just refreshed the current printer.
-                                if (printer.getCapabilities() != null
-                                        && mCapabilitiesTimeout.isPosted()) {
-                                    mCapabilitiesTimeout.remove();
-                                    updatePrintAttributes(printer.getCapabilities());
-                                    updateUi();
-                                    mController.update();
-                                }
-
-                                // Update the UI if capabilities changed.
-                                boolean capabilitiesChanged = false;
-
-                                if (mCurrentPrinter.getCapabilities() == null) {
-                                    if (printer.getCapabilities() != null) {
-                                        updatePrintAttributes(printer.getCapabilities());
-                                        capabilitiesChanged = true;
-                                    }
-                                } else if (!mCurrentPrinter.getCapabilities().equals(
-                                        printer.getCapabilities())) {
-                                    capabilitiesChanged = true;
-                                }
-
-                                // Update the UI if the status changed.
-                                final boolean statusChanged = mCurrentPrinter.getStatus()
-                                        != printer.getStatus();
-
-                                // Update the printer with the latest info.
-                                if (!mCurrentPrinter.equals(printer)) {
-                                    mCurrentPrinter.copyFrom(printer);
-                                }
-
-                                if (capabilitiesChanged || statusChanged) {
-                                    // If something changed during update...
-                                    if (updateUi() || !mController.hasPerformedLayout()) {
-                                        // Update the document.
-                                        mController.update();
-                                    }
-                                }
-
-                                break;
-                            }
-                        }
-                    }
-                }
-
-                @Override
-                public void onInvalidated() {
-                    /* do nothing - we always have one fake PDF printer */
-                }
-            });
-
-            // Media size.
-            mMediaSizeSpinnerAdapter = new ArrayAdapter<SpinnerItem<MediaSize>>(
-                    PrintJobConfigActivity.this,
-                    R.layout.spinner_dropdown_item, R.id.title);
-
-            // Color mode.
-            mColorModeSpinnerAdapter = new ArrayAdapter<SpinnerItem<Integer>>(
-                    PrintJobConfigActivity.this,
-                    R.layout.spinner_dropdown_item, R.id.title);
-
-            // Orientation
-            mOrientationSpinnerAdapter = new ArrayAdapter<SpinnerItem<Integer>>(
-                    PrintJobConfigActivity.this,
-                    R.layout.spinner_dropdown_item, R.id.title);
-            String[] orientationLabels = getResources().getStringArray(
-                  R.array.orientation_labels);
-            mOrientationSpinnerAdapter.add(new SpinnerItem<Integer>(
-                    ORIENTATION_PORTRAIT, orientationLabels[0]));
-            mOrientationSpinnerAdapter.add(new SpinnerItem<Integer>(
-                    ORIENTATION_LANDSCAPE, orientationLabels[1]));
-
-            // Range options
-            mRangeOptionsSpinnerAdapter = new ArrayAdapter<SpinnerItem<Integer>>(
-                    PrintJobConfigActivity.this,
-                    R.layout.spinner_dropdown_item, R.id.title);
-            final int[] rangeOptionsValues = getResources().getIntArray(
-                    R.array.page_options_values);
-            String[] rangeOptionsLabels = getResources().getStringArray(
-                    R.array.page_options_labels);
-            final int rangeOptionsCount = rangeOptionsLabels.length;
-            for (int i = 0; i < rangeOptionsCount; i++) {
-                mRangeOptionsSpinnerAdapter.add(new SpinnerItem<Integer>(
-                        rangeOptionsValues[i], rangeOptionsLabels[i]));
-            }
-
-            showUi(UI_EDITING_PRINT_JOB, null);
-            bindUi();
-            updateUi();
-        }
-
-        public void reselectCurrentPrinter() {
-            if (mCurrentPrinter != null) {
-                // TODO: While the data did not change and we set the adapter
-                // to a newly inflated spinner, the latter does not show the
-                // current item unless we poke the adapter. This requires more
-                // investigation. Maybe an optimization in AdapterView does not
-                // call into the adapter if the view is not visible which is the
-                // case when we set the adapter.
-                mDestinationSpinnerAdapter.notifyDataSetChanged();
-                final int position = mDestinationSpinnerAdapter.getPrinterIndex(
-                        mCurrentPrinter.getId());
-                mDestinationSpinner.setSelection(position);
-            }
-        }
-
-        public void refreshCurrentPrinter() {
-            PrinterInfo printer = (PrinterInfo) mDestinationSpinner.getSelectedItem();
-            if (printer != null) {
-                FusedPrintersProvider printersLoader = (FusedPrintersProvider)
-                        (Loader<?>) getLoaderManager().getLoader(
-                                LOADER_ID_PRINTERS_LOADER);
-                if (printersLoader != null) {
-                    printersLoader.setTrackedPrinter(printer.getId());
-                }
-            }
-        }
-
-        public void addCurrentPrinterToHistory() {
-            PrinterInfo printer = (PrinterInfo) mDestinationSpinner.getSelectedItem();
-            PrinterId fakePdfPritnerId = mDestinationSpinnerAdapter.mFakePdfPrinter.getId();
-            if (printer != null && !printer.getId().equals(fakePdfPritnerId)) {
-                FusedPrintersProvider printersLoader = (FusedPrintersProvider)
-                        (Loader<?>) getLoaderManager().getLoader(
-                                LOADER_ID_PRINTERS_LOADER);
-                if (printersLoader != null) {
-                    printersLoader.addHistoricalPrinter(printer);
-                }
-            }
-        }
-
-        public void updateFromAdvancedOptions(PrintJobInfo printJobInfo) {
-            boolean updateContent = false;
-
-            // Copies.
-            mCopiesEditText.setText(String.valueOf(printJobInfo.getCopies()));
-
-            // Media size and orientation
-            PrintAttributes attributes = printJobInfo.getAttributes();
-            if (!mCurrPrintAttributes.getMediaSize().equals(attributes.getMediaSize())) {
-                final int mediaSizeCount = mMediaSizeSpinnerAdapter.getCount();
-                for (int i = 0; i < mediaSizeCount; i++) {
-                    MediaSize mediaSize = mMediaSizeSpinnerAdapter.getItem(i).value;
-                    if (mediaSize.asPortrait().equals(attributes.getMediaSize().asPortrait())) {
-                        updateContent = true;
-                        mCurrPrintAttributes.setMediaSize(attributes.getMediaSize());
-                        mMediaSizeSpinner.setSelection(i);
-                        mIgnoreNextMediaSizeChange = true;
-                        if (attributes.getMediaSize().isPortrait()) {
-                            mOrientationSpinner.setSelection(0);
-                            mIgnoreNextOrientationChange = true;
-                        } else {
-                            mOrientationSpinner.setSelection(1);
-                            mIgnoreNextOrientationChange = true;
-                        }
-                        break;
-                    }
-                }
-            }
-
-            // Color mode.
-            final int colorMode = attributes.getColorMode();
-            if (mCurrPrintAttributes.getColorMode() != colorMode) {
-                if (colorMode == PrintAttributes.COLOR_MODE_MONOCHROME) {
-                    updateContent = true;
-                    mColorModeSpinner.setSelection(0);
-                    mIgnoreNextColorChange = true;
-                    mCurrPrintAttributes.setColorMode(attributes.getColorMode());
-                } else if (colorMode == PrintAttributes.COLOR_MODE_COLOR) {
-                    updateContent = true;
-                    mColorModeSpinner.setSelection(1);
-                    mIgnoreNextColorChange = true;
-                    mCurrPrintAttributes.setColorMode(attributes.getColorMode());
-                }
-            }
-
-            // Range.
-            PageRange[] pageRanges = printJobInfo.getPages();
-            if (pageRanges != null && pageRanges.length > 0) {
-                pageRanges = PageRangeUtils.normalize(pageRanges);
-                final int pageRangeCount = pageRanges.length;
-                if (pageRangeCount == 1 && pageRanges[0] == PageRange.ALL_PAGES) {
-                    mRangeOptionsSpinner.setSelection(0);
-                } else {
-                    final int pageCount = mDocument.info.getPageCount();
-                    if (pageRanges[0].getStart() >= 0
-                            && pageRanges[pageRanges.length - 1].getEnd() < pageCount) {
-                        mRangeOptionsSpinner.setSelection(1);
-                        StringBuilder builder = new StringBuilder();
-                        for (int i = 0; i < pageRangeCount; i++) {
-                            if (builder.length() > 0) {
-                                builder.append(',');
-                            }
-                            PageRange pageRange = pageRanges[i];
-                            final int shownStartPage = pageRange.getStart() + 1;
-                            final int shownEndPage = pageRange.getEnd() + 1;
-                            builder.append(shownStartPage);
-                            if (shownStartPage != shownEndPage) {
-                                builder.append('-');
-                                builder.append(shownEndPage);
-                            }
-                        }
-                        mPageRangeEditText.setText(builder.toString());
-                    }
-                }
-            }
-
-            // Update the advanced options.
-            mSpoolerProvider.getSpooler().setPrintJobAdvancedOptionsNoPersistence(
-                    mPrintJobId, printJobInfo.getAdvancedOptions());
-
-            // Update the content if needed.
-            if (updateContent) {
-                mController.update();
-            }
-        }
-
-        public void ensurePrinterSelected(PrinterId printerId) {
-            // If the printer is not present maybe the loader is not
-            // updated yet. In this case make a note and as soon as
-            // the printer appears will will select it.
-            if (!selectPrinter(printerId)) {
-                mNextPrinterId = printerId;
-            }
-        }
-
-        public boolean selectPrinter(PrinterId printerId) {
-            mDestinationSpinnerAdapter.ensurePrinterInVisibleAdapterPosition(printerId);
-            final int position = mDestinationSpinnerAdapter.getPrinterIndex(printerId);
-            if (position != AdapterView.INVALID_POSITION
-                    && position != mDestinationSpinner.getSelectedItemPosition()) {
-                Object item = mDestinationSpinnerAdapter.getItem(position);
-                mCurrentPrinter = (PrinterInfo) item;
-                mDestinationSpinner.setSelection(position);
-                return true;
-            }
-            return false;
-        }
-
-        public void ensureCurrentPrinterSelected() {
-            if (mCurrentPrinter != null) {
-                selectPrinter(mCurrentPrinter.getId());
-            }
-        }
-
-        public boolean isPrintingToPdf() {
-            return mDestinationSpinner.getSelectedItem()
-                    == mDestinationSpinnerAdapter.mFakePdfPrinter;
-        }
-
-        public boolean shouldCloseOnTouch(MotionEvent event) {
-            if (event.getAction() != MotionEvent.ACTION_DOWN) {
-                return false;
-            }
-
-            final int[] locationInWindow = new int[2];
-            mContentContainer.getLocationInWindow(locationInWindow);
-
-            final int windowTouchSlop = ViewConfiguration.get(PrintJobConfigActivity.this)
-                    .getScaledWindowTouchSlop();
-            final int eventX = (int) event.getX();
-            final int eventY = (int) event.getY();
-            final int lenientWindowLeft = locationInWindow[0] - windowTouchSlop;
-            final int lenientWindowRight = lenientWindowLeft + mContentContainer.getWidth()
-                    + windowTouchSlop;
-            final int lenientWindowTop = locationInWindow[1] - windowTouchSlop;
-            final int lenientWindowBottom = lenientWindowTop + mContentContainer.getHeight()
-                    + windowTouchSlop;
-
-            if (eventX < lenientWindowLeft || eventX > lenientWindowRight
-                    || eventY < lenientWindowTop || eventY > lenientWindowBottom) {
-                return true;
-            }
-            return false;
-        }
-
-        public boolean isShwoingGeneratingPrintJobUi() {
-            return (mCurrentUi == UI_GENERATING_PRINT_JOB);
-        }
-
-        public void showUi(int ui, final Runnable postSwitchCallback) {
-            if (ui == UI_NONE) {
-                throw new IllegalStateException("cannot remove the ui");
-            }
-
-            if (mCurrentUi == ui) {
-                return;
-            }
-
-            final int oldUi = mCurrentUi;
-            mCurrentUi = ui;
-
-            switch (oldUi) {
-                case UI_NONE: {
-                    switch (ui) {
-                        case UI_EDITING_PRINT_JOB: {
-                            doUiSwitch(R.layout.print_job_config_activity_content_editing);
-                            registerPrintButtonClickListener();
-                            if (postSwitchCallback != null) {
-                                postSwitchCallback.run();
-                            }
-                        } break;
-
-                        case UI_GENERATING_PRINT_JOB: {
-                            doUiSwitch(R.layout.print_job_config_activity_content_generating);
-                            registerCancelButtonClickListener();
-                            if (postSwitchCallback != null) {
-                                postSwitchCallback.run();
-                            }
-                        } break;
-                    }
-                } break;
-
-                case UI_EDITING_PRINT_JOB: {
-                    switch (ui) {
-                        case UI_GENERATING_PRINT_JOB: {
-                            animateUiSwitch(R.layout.print_job_config_activity_content_generating,
-                                    new Runnable() {
-                                @Override
-                                public void run() {
-                                    registerCancelButtonClickListener();
-                                    if (postSwitchCallback != null) {
-                                        postSwitchCallback.run();
-                                    }
-                                }
-                            },
-                            new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
-                                    ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER));
-                        } break;
-
-                        case UI_ERROR: {
-                            animateUiSwitch(R.layout.print_job_config_activity_content_error,
-                                    new Runnable() {
-                                @Override
-                                public void run() {
-                                    registerOkButtonClickListener();
-                                    if (postSwitchCallback != null) {
-                                        postSwitchCallback.run();
-                                    }
-                                }
-                            },
-                            new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
-                                    ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER));
-                        } break;
-                    }
-                } break;
-
-                case UI_GENERATING_PRINT_JOB: {
-                    switch (ui) {
-                        case UI_EDITING_PRINT_JOB: {
-                            animateUiSwitch(R.layout.print_job_config_activity_content_editing,
-                                    new Runnable() {
-                                @Override
-                                public void run() {
-                                    registerPrintButtonClickListener();
-                                    if (postSwitchCallback != null) {
-                                        postSwitchCallback.run();
-                                    }
-                                }
-                            },
-                            new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
-                                    ViewGroup.LayoutParams.MATCH_PARENT, Gravity.CENTER));
-                        } break;
-
-                        case UI_ERROR: {
-                            animateUiSwitch(R.layout.print_job_config_activity_content_error,
-                                    new Runnable() {
-                                @Override
-                                public void run() {
-                                    registerOkButtonClickListener();
-                                    if (postSwitchCallback != null) {
-                                        postSwitchCallback.run();
-                                    }
-                                }
-                            },
-                            new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
-                                    ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER));
-                        } break;
-                    }
-                } break;
-
-                case UI_ERROR: {
-                    switch (ui) {
-                        case UI_EDITING_PRINT_JOB: {
-                            animateUiSwitch(R.layout.print_job_config_activity_content_editing,
-                                    new Runnable() {
-                                @Override
-                                public void run() {
-                                    registerPrintButtonClickListener();
-                                    if (postSwitchCallback != null) {
-                                        postSwitchCallback.run();
-                                    }
-                                }
-                            },
-                            new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
-                                    ViewGroup.LayoutParams.MATCH_PARENT, Gravity.CENTER));
-                        } break;
-                    }
-                } break;
-            }
-        }
-
-        private void registerAdvancedPrintOptionsButtonClickListener() {
-            Button advancedOptionsButton = (Button) findViewById(R.id.advanced_settings_button);
-            advancedOptionsButton.setOnClickListener(new OnClickListener() {
-                @Override
-                public void onClick(View v) {
-                    ComponentName serviceName = mCurrentPrinter.getId().getServiceName();
-                    String activityName = getAdvancedOptionsActivityName(serviceName);
-                    if (TextUtils.isEmpty(activityName)) {
-                        return;
-                    }
-                    Intent intent = new Intent(Intent.ACTION_MAIN);
-                    intent.setComponent(new ComponentName(serviceName.getPackageName(),
-                            activityName));
-
-                    List<ResolveInfo> resolvedActivities = getPackageManager()
-                            .queryIntentActivities(intent, 0);
-                    if (resolvedActivities.isEmpty()) {
-                        return;
-                    }
-                    // The activity is a component name, therefore it is one or none.
-                    if (resolvedActivities.get(0).activityInfo.exported) {
-                        PrintJobInfo printJobInfo = mSpoolerProvider.getSpooler().getPrintJobInfo(
-                                mPrintJobId, PrintManager.APP_ID_ANY);
-                        intent.putExtra(PrintService.EXTRA_PRINT_JOB_INFO, printJobInfo);
-                        // TODO: Make this an API for the next release.
-                        intent.putExtra("android.intent.extra.print.EXTRA_PRINTER_INFO",
-                                mCurrentPrinter);
-                        try {
-                            startActivityForResult(intent,
-                                    ACTIVITY_POPULATE_ADVANCED_PRINT_OPTIONS);
-                        } catch (ActivityNotFoundException anfe) {
-                            Log.e(LOG_TAG, "Error starting activity for intent: " + intent, anfe);
-                        }
-                    }
-                }
-            });
-        }
-
-        private void registerPrintButtonClickListener() {
-            Button printButton = (Button) findViewById(R.id.print_button);
-            printButton.setOnClickListener(new OnClickListener() {
-                @Override
-                public void onClick(View v) {
-                    PrinterInfo printer = (PrinterInfo) mDestinationSpinner.getSelectedItem();
-                    if (printer != null) {
-                        mEditor.confirmPrint();
-                        mController.update();
-                        if (!printer.equals(mDestinationSpinnerAdapter.mFakePdfPrinter)) {
-                            mEditor.refreshCurrentPrinter();
-                        }
-                    } else {
-                        mEditor.cancel();
-                        PrintJobConfigActivity.this.finish();
-                    }
-                }
-            });
-        }
-
-        private void registerCancelButtonClickListener() {
-            Button cancelButton = (Button) findViewById(R.id.cancel_button);
-            cancelButton.setOnClickListener(new OnClickListener() {
-                @Override
-                public void onClick(View v) {
-                    if (!mController.isWorking()) {
-                        PrintJobConfigActivity.this.finish();
-                    }
-                    mEditor.cancel();
-                }
-            });
-        }
-
-        private void registerOkButtonClickListener() {
-            Button okButton = (Button) findViewById(R.id.ok_button);
-            okButton.setOnClickListener(new OnClickListener() {
-                @Override
-                public void onClick(View v) {
-                    mEditor.showUi(Editor.UI_EDITING_PRINT_JOB, new Runnable() {
-                        @Override
-                        public void run() {
-                            // Start over with a clean slate.
-                            mOldPrintAttributes.clear();
-                            mController.initialize();
-                            mEditor.initialize();
-                            mEditor.bindUi();
-                            mEditor.reselectCurrentPrinter();
-                            if (!mController.hasPerformedLayout()) {
-                                mController.update();
-                            }
-                        }
-                    });
-                }
-            });
-        }
-
-        private void doUiSwitch(int showLayoutId) {
-            ViewGroup contentContainer = (ViewGroup) findViewById(R.id.content_container);
-            contentContainer.removeAllViews();
-            getLayoutInflater().inflate(showLayoutId, contentContainer, true);
-        }
-
-        private void animateUiSwitch(int showLayoutId, final Runnable beforeShowNewUiAction,
-                final LayoutParams containerParams) {
-            // Find everything we will shuffle around.
-            final ViewGroup contentContainer = (ViewGroup) findViewById(R.id.content_container);
-            final View hidingView = contentContainer.getChildAt(0);
-            final View showingView = getLayoutInflater().inflate(showLayoutId,
-                    null, false);
-
-            // First animation - fade out the old content.
-            AutoCancellingAnimator.animate(hidingView).alpha(0.0f)
-                    .withLayer().withEndAction(new Runnable() {
-                @Override
-                public void run() {
-                    hidingView.setVisibility(View.INVISIBLE);
-
-                    // Prepare the new content with correct size and alpha.
-                    showingView.setMinimumWidth(contentContainer.getWidth());
-                    showingView.setAlpha(0.0f);
-
-                    // Compute how to much shrink /stretch the content.
-                    final int widthSpec = MeasureSpec.makeMeasureSpec(
-                            contentContainer.getWidth(), MeasureSpec.UNSPECIFIED);
-                    final int heightSpec = MeasureSpec.makeMeasureSpec(
-                            contentContainer.getHeight(), MeasureSpec.UNSPECIFIED);
-                    showingView.measure(widthSpec, heightSpec);
-                    final float scaleY = (float) showingView.getMeasuredHeight()
-                            / (float) contentContainer.getHeight();
-
-                    // Second animation - resize the container.
-                    AutoCancellingAnimator.animate(contentContainer).scaleY(scaleY)
-                            .withEndAction(new Runnable() {
-                        @Override
-                        public void run() {
-                            // Swap the old and the new content.
-                            contentContainer.removeAllViews();
-                            contentContainer.setScaleY(1.0f);
-                            contentContainer.addView(showingView);
-
-                            contentContainer.setLayoutParams(containerParams);
-
-                            beforeShowNewUiAction.run();
-
-                            // Third animation - show the new content.
-                            AutoCancellingAnimator.animate(showingView).alpha(1.0f);
-                        }
-                    });
-                }
-            });
-        }
-
-        public void initialize() {
-            mEditorState = EDITOR_STATE_INITIALIZED;
-        }
-
-        public boolean isCancelled() {
-            return mEditorState == EDITOR_STATE_CANCELLED;
-        }
-
-        public void cancel() {
-            mEditorState = EDITOR_STATE_CANCELLED;
-            mController.cancel();
-            updateUi();
-        }
-
-        public boolean isDone() {
-            return isPrintConfirmed() || isCancelled();
-        }
-
-        public boolean isPrintConfirmed() {
-            return mEditorState == EDITOR_STATE_CONFIRMED_PRINT;
-        }
-
-        public void confirmPrint() {
-            addCurrentPrinterToHistory();
-            mEditorState = EDITOR_STATE_CONFIRMED_PRINT;
-            showUi(UI_GENERATING_PRINT_JOB, null);
-        }
-
-        public PageRange[] getRequestedPages() {
-            if (hasErrors()) {
-                return null;
-            }
-            if (mRangeOptionsSpinner.getSelectedItemPosition() > 0) {
-                List<PageRange> pageRanges = new ArrayList<PageRange>();
-                mStringCommaSplitter.setString(mPageRangeEditText.getText().toString());
-
-                while (mStringCommaSplitter.hasNext()) {
-                    String range = mStringCommaSplitter.next().trim();
-                    if (TextUtils.isEmpty(range)) {
-                        continue;
-                    }
-                    final int dashIndex = range.indexOf('-');
-                    final int fromIndex;
-                    final int toIndex;
-
-                    if (dashIndex > 0) {
-                        fromIndex = Integer.parseInt(range.substring(0, dashIndex).trim()) - 1;
-                        // It is possible that the dash is at the end since the input
-                        // verification can has to allow the user to keep entering if
-                        // this would lead to a valid input. So we handle this.
-                        toIndex = (dashIndex < range.length() - 1)
-                                ? Integer.parseInt(range.substring(dashIndex + 1,
-                                        range.length()).trim()) - 1 : fromIndex;
-                    } else {
-                        fromIndex = toIndex = Integer.parseInt(range) - 1;
-                    }
-
-                    PageRange pageRange = new PageRange(Math.min(fromIndex, toIndex),
-                            Math.max(fromIndex, toIndex));
-                    pageRanges.add(pageRange);
-                }
-
-                PageRange[] pageRangesArray = new PageRange[pageRanges.size()];
-                pageRanges.toArray(pageRangesArray);
-
-                return PageRangeUtils.normalize(pageRangesArray);
-            }
-
-            return ALL_PAGES_ARRAY;
-        }
-
-        private void bindUi() {
-            if (mCurrentUi != UI_EDITING_PRINT_JOB) {
-                return;
-            }
-
-            // Content container
-            mContentContainer = findViewById(R.id.content_container);
-
-            // Copies
-            mCopiesEditText = (EditText) findViewById(R.id.copies_edittext);
-            mCopiesEditText.setOnFocusChangeListener(mFocusListener);
-            mCopiesEditText.setText(MIN_COPIES_STRING);
-            mCopiesEditText.setSelection(mCopiesEditText.getText().length());
-            mCopiesEditText.addTextChangedListener(mCopiesTextWatcher);
-            if (!TextUtils.equals(mCopiesEditText.getText(), MIN_COPIES_STRING)) {
-                mIgnoreNextCopiesChange = true;
-            }
-            mSpoolerProvider.getSpooler().setPrintJobCopiesNoPersistence(
-                    mPrintJobId, MIN_COPIES);
-
-            // Destination.
-            mDestinationSpinner = (Spinner) findViewById(R.id.destination_spinner);
-            mDestinationSpinner.setDropDownWidth(ViewGroup.LayoutParams.MATCH_PARENT);
-            mDestinationSpinner.setAdapter(mDestinationSpinnerAdapter);
-            mDestinationSpinner.setOnItemSelectedListener(mOnItemSelectedListener);
-            if (mDestinationSpinnerAdapter.getCount() > 0) {
-                mIgnoreNextDestinationChange = true;
-            }
-
-            // Media size.
-            mMediaSizeSpinner = (Spinner) findViewById(R.id.paper_size_spinner);
-            mMediaSizeSpinner.setAdapter(mMediaSizeSpinnerAdapter);
-            mMediaSizeSpinner.setOnItemSelectedListener(mOnItemSelectedListener);
-            if (mMediaSizeSpinnerAdapter.getCount() > 0) {
-                mOldMediaSizeSelectionIndex = 0;
-            }
-
-            // Color mode.
-            mColorModeSpinner = (Spinner) findViewById(R.id.color_spinner);
-            mColorModeSpinner.setAdapter(mColorModeSpinnerAdapter);
-            mColorModeSpinner.setOnItemSelectedListener(mOnItemSelectedListener);
-            if (mColorModeSpinnerAdapter.getCount() > 0) {
-                mOldColorModeSelectionIndex = 0;
-            }
-
-            // Orientation
-            mOrientationSpinner = (Spinner) findViewById(R.id.orientation_spinner);
-            mOrientationSpinner.setAdapter(mOrientationSpinnerAdapter);
-            mOrientationSpinner.setOnItemSelectedListener(mOnItemSelectedListener);
-            if (mOrientationSpinnerAdapter.getCount() > 0) {
-                mIgnoreNextOrientationChange = true;
-            }
-
-            // Range options
-            mRangeOptionsTitle = (TextView) findViewById(R.id.range_options_title);
-            mRangeOptionsSpinner = (Spinner) findViewById(R.id.range_options_spinner);
-            mRangeOptionsSpinner.setAdapter(mRangeOptionsSpinnerAdapter);
-            mRangeOptionsSpinner.setOnItemSelectedListener(mOnItemSelectedListener);
-            if (mRangeOptionsSpinnerAdapter.getCount() > 0) {
-                mIgnoreNextRangeOptionChange = true;
-            }
-
-            // Page range
-            mPageRangeTitle = (TextView) findViewById(R.id.page_range_title);
-            mPageRangeEditText = (EditText) findViewById(R.id.page_range_edittext);
-            mPageRangeEditText.setOnFocusChangeListener(mFocusListener);
-            mPageRangeEditText.addTextChangedListener(mRangeTextWatcher);
-
-            // Advanced options button.
-            mAdvancedPrintOptionsContainer = findViewById(R.id.advanced_settings_container);
-            mAdvancedOptionsButton = (Button) findViewById(R.id.advanced_settings_button);
-            registerAdvancedPrintOptionsButtonClickListener();
-
-            // Print button
-            mPrintButton = (Button) findViewById(R.id.print_button);
-            registerPrintButtonClickListener();
-        }
-
-        public boolean updateUi() {
-            if (mCurrentUi != UI_EDITING_PRINT_JOB) {
-                return false;
-            }
-            if (isPrintConfirmed() || isCancelled()) {
-                mDestinationSpinner.setEnabled(false);
-                mCopiesEditText.setEnabled(false);
-                mMediaSizeSpinner.setEnabled(false);
-                mColorModeSpinner.setEnabled(false);
-                mOrientationSpinner.setEnabled(false);
-                mRangeOptionsSpinner.setEnabled(false);
-                mPageRangeEditText.setEnabled(false);
-                mPrintButton.setEnabled(false);
-                mAdvancedOptionsButton.setEnabled(false);
-                return false;
-            }
-
-            // If a printer with capabilities is selected, then we enabled all options.
-            boolean allOptionsEnabled = false;
-            final int selectedIndex = mDestinationSpinner.getSelectedItemPosition();
-            if (selectedIndex >= 0) {
-                Object item = mDestinationSpinnerAdapter.getItem(selectedIndex);
-                if (item instanceof PrinterInfo) {
-                    PrinterInfo printer = (PrinterInfo) item;
-                    if (printer.getCapabilities() != null
-                            && printer.getStatus() != PrinterInfo.STATUS_UNAVAILABLE) {
-                        allOptionsEnabled = true;
-                    }
-                }
-            }
-
-            if (!allOptionsEnabled) {
-                mCopiesEditText.setEnabled(false);
-                mMediaSizeSpinner.setEnabled(false);
-                mColorModeSpinner.setEnabled(false);
-                mOrientationSpinner.setEnabled(false);
-                mRangeOptionsSpinner.setEnabled(false);
-                mPageRangeEditText.setEnabled(false);
-                mPrintButton.setEnabled(false);
-                mAdvancedOptionsButton.setEnabled(false);
-                return false;
-            } else {
-                boolean someAttributeSelectionChanged = false;
-
-                PrinterInfo printer = (PrinterInfo) mDestinationSpinner.getSelectedItem();
-                PrinterCapabilitiesInfo capabilities = printer.getCapabilities();
-                PrintAttributes defaultAttributes = printer.getCapabilities().getDefaults();
-
-                // Media size.
-                // Sort the media sizes based on the current locale.
-                List<MediaSize> mediaSizes = new ArrayList<MediaSize>(capabilities.getMediaSizes());
-                Collections.sort(mediaSizes, mMediaSizeComparator);
-
-                // If the media sizes changed, we update the adapter and the spinner.
-                boolean mediaSizesChanged = false;
-                final int mediaSizeCount = mediaSizes.size();
-                if (mediaSizeCount != mMediaSizeSpinnerAdapter.getCount()) {
-                    mediaSizesChanged = true;
-                } else {
-                    for (int i = 0; i < mediaSizeCount; i++) {
-                        if (!mediaSizes.get(i).equals(mMediaSizeSpinnerAdapter.getItem(i).value)) {
-                            mediaSizesChanged = true;
-                            break;
-                        }
-                    }
-                }
-                if (mediaSizesChanged) {
-                    // Remember the old media size to try selecting it again.
-                    int oldMediaSizeNewIndex = AdapterView.INVALID_POSITION;
-                    MediaSize oldMediaSize = mCurrPrintAttributes.getMediaSize();
-
-                    // Rebuild the adapter data.
-                    mMediaSizeSpinnerAdapter.clear();
-                    for (int i = 0; i < mediaSizeCount; i++) {
-                        MediaSize mediaSize = mediaSizes.get(i);
-                        if (mediaSize.asPortrait().equals(oldMediaSize.asPortrait())) {
-                            // Update the index of the old selection.
-                            oldMediaSizeNewIndex = i;
-                        }
-                        mMediaSizeSpinnerAdapter.add(new SpinnerItem<MediaSize>(
-                                mediaSize, mediaSize.getLabel(getPackageManager())));
-                    }
-
-                    mMediaSizeSpinner.setEnabled(true);
-
-                    if (oldMediaSizeNewIndex != AdapterView.INVALID_POSITION) {
-                        // Select the old media size - nothing really changed.
-                        setMediaSizeSpinnerSelectionNoCallback(oldMediaSizeNewIndex);
-                    } else {
-                        // Select the first or the default and mark if selection changed.
-                        final int mediaSizeIndex = Math.max(mediaSizes.indexOf(
-                                defaultAttributes.getMediaSize()), 0);
-                        setMediaSizeSpinnerSelectionNoCallback(mediaSizeIndex);
-                        if (oldMediaSize.isPortrait()) {
-                            mCurrPrintAttributes.setMediaSize(mMediaSizeSpinnerAdapter
-                                    .getItem(mediaSizeIndex).value.asPortrait());
-                        } else {
-                            mCurrPrintAttributes.setMediaSize(mMediaSizeSpinnerAdapter
-                                    .getItem(mediaSizeIndex).value.asLandscape());
-                        }
-                        someAttributeSelectionChanged = true;
-                    }
-                }
-                mMediaSizeSpinner.setEnabled(true);
-
-                // Color mode.
-                final int colorModes = capabilities.getColorModes();
-
-                // If the color modes changed, we update the adapter and the spinner.
-                boolean colorModesChanged = false;
-                if (Integer.bitCount(colorModes) != mColorModeSpinnerAdapter.getCount()) {
-                    colorModesChanged = true;
-                } else {
-                    int remainingColorModes = colorModes;
-                    int adapterIndex = 0;
-                    while (remainingColorModes != 0) {
-                        final int colorBitOffset = Integer.numberOfTrailingZeros(
-                                remainingColorModes);
-                        final int colorMode = 1 << colorBitOffset;
-                        remainingColorModes &= ~colorMode;
-                        if (colorMode != mColorModeSpinnerAdapter.getItem(adapterIndex).value) {
-                            colorModesChanged = true;
-                            break;
-                        }
-                        adapterIndex++;
-                    }
-                }
-                if (colorModesChanged) {
-                    // Remember the old color mode to try selecting it again.
-                    int oldColorModeNewIndex = AdapterView.INVALID_POSITION;
-                    final int oldColorMode = mCurrPrintAttributes.getColorMode();
-
-                    // Rebuild the adapter data.
-                    mColorModeSpinnerAdapter.clear();
-                    String[] colorModeLabels = getResources().getStringArray(
-                            R.array.color_mode_labels);
-                    int remainingColorModes = colorModes;
-                    while (remainingColorModes != 0) {
-                        final int colorBitOffset = Integer.numberOfTrailingZeros(
-                                remainingColorModes);
-                        final int colorMode = 1 << colorBitOffset;
-                        if (colorMode == oldColorMode) {
-                            // Update the index of the old selection.
-                            oldColorModeNewIndex = colorBitOffset;
-                        }
-                        remainingColorModes &= ~colorMode;
-                        mColorModeSpinnerAdapter.add(new SpinnerItem<Integer>(colorMode,
-                                colorModeLabels[colorBitOffset]));
-                    }
-                    mColorModeSpinner.setEnabled(true);
-                    if (oldColorModeNewIndex != AdapterView.INVALID_POSITION) {
-                        // Select the old color mode - nothing really changed.
-                        setColorModeSpinnerSelectionNoCallback(oldColorModeNewIndex);
-                    } else {
-                        final int selectedColorMode = colorModes & defaultAttributes.getColorMode();
-                        final int itemCount = mColorModeSpinnerAdapter.getCount();
-                        for (int i = 0; i < itemCount; i++) {
-                            SpinnerItem<Integer> item = mColorModeSpinnerAdapter.getItem(i);
-                            if (selectedColorMode == item.value) {
-                                setColorModeSpinnerSelectionNoCallback(i);
-                                mCurrPrintAttributes.setColorMode(selectedColorMode);
-                                someAttributeSelectionChanged = true;
-                            }
-                        }
-                    }
-                }
-                mColorModeSpinner.setEnabled(true);
-
-                // Orientation
-                MediaSize mediaSize = mCurrPrintAttributes.getMediaSize();
-                if (mediaSize.isPortrait()
-                        && mOrientationSpinner.getSelectedItemPosition() != 0) {
-                    mIgnoreNextOrientationChange = true;
-                    mOrientationSpinner.setSelection(0);
-                } else if (!mediaSize.isPortrait()
-                        && mOrientationSpinner.getSelectedItemPosition() != 1) {
-                    mIgnoreNextOrientationChange = true;
-                    mOrientationSpinner.setSelection(1);
-                }
-                mOrientationSpinner.setEnabled(true);
-
-                // Range options
-                PrintDocumentInfo info = mDocument.info;
-                if (info != null && info.getPageCount() > 0) {
-                    if (info.getPageCount() == 1) {
-                        mRangeOptionsSpinner.setEnabled(false);
-                    } else {
-                        mRangeOptionsSpinner.setEnabled(true);
-                        if (mRangeOptionsSpinner.getSelectedItemPosition() > 0) {
-                            if (!mPageRangeEditText.isEnabled()) {
-                                mPageRangeEditText.setEnabled(true);
-                                mPageRangeEditText.setVisibility(View.VISIBLE);
-                                mPageRangeTitle.setVisibility(View.VISIBLE);
-                                mPageRangeEditText.requestFocus();
-                                InputMethodManager imm = (InputMethodManager)
-                                        getSystemService(INPUT_METHOD_SERVICE);
-                                imm.showSoftInput(mPageRangeEditText, 0);
-                            }
-                        } else {
-                            mPageRangeEditText.setEnabled(false);
-                            mPageRangeEditText.setVisibility(View.INVISIBLE);
-                            mPageRangeTitle.setVisibility(View.INVISIBLE);
-                        }
-                    }
-                    final int pageCount = mDocument.info.getPageCount();
-                    String title = (pageCount != PrintDocumentInfo.PAGE_COUNT_UNKNOWN)
-                            ? getString(R.string.label_pages, String.valueOf(pageCount))
-                            : getString(R.string.page_count_unknown);
-                    mRangeOptionsTitle.setText(title);
-                } else {
-                    if (mRangeOptionsSpinner.getSelectedItemPosition() != 0) {
-                        mIgnoreNextRangeOptionChange = true;
-                        mRangeOptionsSpinner.setSelection(0);
-                    }
-                    mRangeOptionsSpinner.setEnabled(false);
-                    mRangeOptionsTitle.setText(getString(R.string.page_count_unknown));
-                    mPageRangeEditText.setEnabled(false);
-                    mPageRangeEditText.setVisibility(View.INVISIBLE);
-                    mPageRangeTitle.setVisibility(View.INVISIBLE);
-                }
-
-                // Advanced print options
-                ComponentName serviceName = mCurrentPrinter.getId().getServiceName();
-                if (!TextUtils.isEmpty(getAdvancedOptionsActivityName(serviceName))) {
-                    mAdvancedPrintOptionsContainer.setVisibility(View.VISIBLE);
-                    mAdvancedOptionsButton.setEnabled(true);
-                } else {
-                    mAdvancedPrintOptionsContainer.setVisibility(View.GONE);
-                    mAdvancedOptionsButton.setEnabled(false);
-                }
-
-                // Print
-                if (mDestinationSpinner.getSelectedItemId()
-                        != DEST_ADAPTER_ITEM_ID_SAVE_AS_PDF) {
-                    String newText = getString(R.string.print_button);
-                    if (!TextUtils.equals(newText, mPrintButton.getText())) {
-                        mPrintButton.setText(R.string.print_button);
-                    }
-                } else {
-                    String newText = getString(R.string.save_button);
-                    if (!TextUtils.equals(newText, mPrintButton.getText())) {
-                        mPrintButton.setText(R.string.save_button);
-                    }
-                }
-                if ((mRangeOptionsSpinner.getSelectedItemPosition() == 1
-                            && (TextUtils.isEmpty(mPageRangeEditText.getText()) || hasErrors()))
-                        || (mRangeOptionsSpinner.getSelectedItemPosition() == 0
-                            && (!mController.hasPerformedLayout() || hasErrors()))) {
-                    mPrintButton.setEnabled(false);
-                } else {
-                    mPrintButton.setEnabled(true);
-                }
-
-                // Copies
-                if (mDestinationSpinner.getSelectedItemId()
-                        != DEST_ADAPTER_ITEM_ID_SAVE_AS_PDF) {
-                    mCopiesEditText.setEnabled(true);
-                } else {
-                    mCopiesEditText.setEnabled(false);
-                }
-                if (mCopiesEditText.getError() == null
-                        && TextUtils.isEmpty(mCopiesEditText.getText())) {
-                    mIgnoreNextCopiesChange = true;
-                    mCopiesEditText.setText(String.valueOf(MIN_COPIES));
-                    mCopiesEditText.requestFocus();
-                }
-
-                return someAttributeSelectionChanged;
-            }
-        }
-
-        private String getAdvancedOptionsActivityName(ComponentName serviceName) {
-            PrintManager printManager = (PrintManager) getSystemService(Context.PRINT_SERVICE);
-            List<PrintServiceInfo> printServices = printManager.getEnabledPrintServices();
-            final int printServiceCount = printServices.size();
-            for (int i = 0; i < printServiceCount; i ++) {
-                PrintServiceInfo printServiceInfo = printServices.get(i);
-                ServiceInfo serviceInfo = printServiceInfo.getResolveInfo().serviceInfo;
-                if (serviceInfo.name.equals(serviceName.getClassName())
-                        && serviceInfo.packageName.equals(serviceName.getPackageName())) {
-                    return printServiceInfo.getAdvancedOptionsActivityName();
-                }
-            }
-            return null;
-        }
-
-        private void setMediaSizeSpinnerSelectionNoCallback(int position) {
-            if (mMediaSizeSpinner.getSelectedItemPosition() != position) {
-                mOldMediaSizeSelectionIndex = position;
-                mMediaSizeSpinner.setSelection(position);
-            }
-        }
-
-        private void setColorModeSpinnerSelectionNoCallback(int position) {
-            if (mColorModeSpinner.getSelectedItemPosition() != position) {
-                mOldColorModeSelectionIndex = position;
-                mColorModeSpinner.setSelection(position);
-            }
-        }
-
-        private void startSelectPrinterActivity() {
-            Intent intent = new Intent(PrintJobConfigActivity.this,
-                    SelectPrinterActivity.class);
-            startActivityForResult(intent, ACTIVITY_REQUEST_SELECT_PRINTER);
-        }
-
-        private boolean hasErrors() {
-            if (mCopiesEditText.getError() != null) {
-                return true;
-            }
-            return mPageRangeEditText.getVisibility() == View.VISIBLE
-                    && mPageRangeEditText.getError() != null;
-        }
-
-        private final class SpinnerItem<T> {
-            final T value;
-            CharSequence label;
-
-            public SpinnerItem(T value, CharSequence label) {
-                this.value = value;
-                this.label = label;
-            }
-
-            public String toString() {
-                return label.toString();
-            }
-        }
-
-        private final class WaitForPrinterCapabilitiesTimeout implements Runnable {
-            private static final long GET_CAPABILITIES_TIMEOUT_MILLIS = 10000; // 10sec
-
-            private boolean mIsPosted;
-
-            public void post() {
-                if (!mIsPosted) {
-                    mDestinationSpinner.postDelayed(this,
-                            GET_CAPABILITIES_TIMEOUT_MILLIS);
-                    mIsPosted = true;
-                }
-            }
-
-            public void remove() {
-                if (mIsPosted) {
-                    mIsPosted = false;
-                    mDestinationSpinner.removeCallbacks(this);
-                }
-            }
-
-            public boolean isPosted() {
-                return mIsPosted;
-            }
-
-            @Override
-            public void run() {
-                mIsPosted = false;
-                if (mDestinationSpinner.getSelectedItemPosition() >= 0) {
-                    View itemView = mDestinationSpinner.getSelectedView();
-                    TextView titleView = (TextView) itemView.findViewById(R.id.subtitle);
-                    try {
-                        PackageInfo packageInfo = getPackageManager().getPackageInfo(
-                                mCurrentPrinter.getId().getServiceName().getPackageName(), 0);
-                        CharSequence service = packageInfo.applicationInfo.loadLabel(
-                                getPackageManager());
-                        String subtitle = getString(R.string.printer_unavailable, service.toString());
-                        titleView.setText(subtitle);
-                    } catch (NameNotFoundException nnfe) {
-                        /* ignore */
-                    }
-                }
-            }
-        }
-
-        private final class DestinationAdapter extends BaseAdapter
-                implements LoaderManager.LoaderCallbacks<List<PrinterInfo>>{
-            private final List<PrinterInfo> mPrinters = new ArrayList<PrinterInfo>();
-
-            private PrinterInfo mFakePdfPrinter;
-
-            public DestinationAdapter() {
-                getLoaderManager().initLoader(LOADER_ID_PRINTERS_LOADER, null, this);
-            }
-
-            public int getPrinterIndex(PrinterId printerId) {
-                for (int i = 0; i < getCount(); i++) {
-                    PrinterInfo printer = (PrinterInfo) getItem(i);
-                    if (printer != null && printer.getId().equals(printerId)) {
-                        return i;
-                    }
-                }
-                return AdapterView.INVALID_POSITION;
-            }
-
-            public void ensurePrinterInVisibleAdapterPosition(PrinterId printerId) {
-                final int printerCount = mPrinters.size();
-                for (int i = 0; i < printerCount; i++) {
-                    PrinterInfo printer = (PrinterInfo) mPrinters.get(i);
-                    if (printer.getId().equals(printerId)) {
-                        // If already in the list - do nothing.
-                        if (i < getCount() - 2) {
-                            return;
-                        }
-                        // Else replace the last one (two items are not printers).
-                        final int lastPrinterIndex = getCount() - 3;
-                        mPrinters.set(i, mPrinters.get(lastPrinterIndex));
-                        mPrinters.set(lastPrinterIndex, printer);
-                        notifyDataSetChanged();
-                        return;
-                    }
-                }
-            }
-
-            @Override
-            public int getCount() {
-                if (mFakePdfPrinter == null) {
-                    return 0;
-                }
-                return Math.min(mPrinters.size() + 2, DEST_ADAPTER_MAX_ITEM_COUNT);
-            }
-
-            @Override
-            public boolean isEnabled(int position) {
-                Object item = getItem(position);
-                if (item instanceof PrinterInfo) {
-                    PrinterInfo printer = (PrinterInfo) item;
-                    return printer.getStatus() != PrinterInfo.STATUS_UNAVAILABLE;
-                }
-                return true;
-            }
-
-            @Override
-            public Object getItem(int position) {
-                if (mPrinters.isEmpty()) {
-                    if (position == 0 && mFakePdfPrinter != null) {
-                        return mFakePdfPrinter;
-                    }
-                } else {
-                    if (position < 1) {
-                        return mPrinters.get(position);
-                    }
-                    if (position == 1 && mFakePdfPrinter != null) {
-                        return mFakePdfPrinter;
-                    }
-                    if (position < getCount() - 1) {
-                        return mPrinters.get(position - 1);
-                    }
-                }
-                return null;
-            }
-
-            @Override
-            public long getItemId(int position) {
-                if (mPrinters.isEmpty()) {
-                    if (mFakePdfPrinter != null) {
-                        if (position == 0) {
-                            return DEST_ADAPTER_ITEM_ID_SAVE_AS_PDF;
-                        } else if (position == 1) {
-                            return DEST_ADAPTER_ITEM_ID_ALL_PRINTERS;
-                        }
-                    }
-                } else {
-                    if (position == 1 && mFakePdfPrinter != null) {
-                        return DEST_ADAPTER_ITEM_ID_SAVE_AS_PDF;
-                    }
-                    if (position == getCount() - 1) {
-                        return DEST_ADAPTER_ITEM_ID_ALL_PRINTERS;
-                    }
-                }
-                return position;
-            }
-
-            @Override
-            public View getDropDownView(int position, View convertView,
-                    ViewGroup parent) {
-                View view = getView(position, convertView, parent);
-                view.setEnabled(isEnabled(position));
-                return view;
-            }
-
-            @Override
-            public View getView(int position, View convertView, ViewGroup parent) {
-                if (convertView == null) {
-                    convertView = getLayoutInflater().inflate(
-                            R.layout.printer_dropdown_item, parent, false);
-                }
-
-                CharSequence title = null;
-                CharSequence subtitle = null;
-                Drawable icon = null;
-
-                if (mPrinters.isEmpty()) {
-                    if (position == 0 && mFakePdfPrinter != null) {
-                        PrinterInfo printer = (PrinterInfo) getItem(position);
-                        title = printer.getName();
-                    } else if (position == 1) {
-                        title = getString(R.string.all_printers);
-                    }
-                } else {
-                    if (position == 1 && mFakePdfPrinter != null) {
-                        PrinterInfo printer = (PrinterInfo) getItem(position);
-                        title = printer.getName();
-                    } else if (position == getCount() - 1) {
-                        title = getString(R.string.all_printers);
-                    } else {
-                        PrinterInfo printer = (PrinterInfo) getItem(position);
-                        title = printer.getName();
-                        try {
-                            PackageInfo packageInfo = getPackageManager().getPackageInfo(
-                                    printer.getId().getServiceName().getPackageName(), 0);
-                            subtitle = packageInfo.applicationInfo.loadLabel(getPackageManager());
-                            icon = packageInfo.applicationInfo.loadIcon(getPackageManager());
-                        } catch (NameNotFoundException nnfe) {
-                            /* ignore */
-                        }
-                    }
-                }
-
-                TextView titleView = (TextView) convertView.findViewById(R.id.title);
-                titleView.setText(title);
-
-                TextView subtitleView = (TextView) convertView.findViewById(R.id.subtitle);
-                if (!TextUtils.isEmpty(subtitle)) {
-                    subtitleView.setText(subtitle);
-                    subtitleView.setVisibility(View.VISIBLE);
-                } else {
-                    subtitleView.setText(null);
-                    subtitleView.setVisibility(View.GONE);
-                }
-
-                ImageView iconView = (ImageView) convertView.findViewById(R.id.icon);
-                if (icon != null) {
-                    iconView.setImageDrawable(icon);
-                    iconView.setVisibility(View.VISIBLE);
-                } else {
-                    iconView.setVisibility(View.INVISIBLE);
-                }
-
-                return convertView;
-            }
-
-            @Override
-            public Loader<List<PrinterInfo>> onCreateLoader(int id, Bundle args) {
-                if (id == LOADER_ID_PRINTERS_LOADER) {
-                    return new FusedPrintersProvider(PrintJobConfigActivity.this);
-                }
-                return null;
-            }
-
-            @Override
-            public void onLoadFinished(Loader<List<PrinterInfo>> loader,
-                    List<PrinterInfo> printers) {
-                // If this is the first load, create the fake PDF printer.
-                // We do this to avoid flicker where the PDF printer is the
-                // only one and as soon as the loader loads the favorites
-                // it gets switched. Not a great user experience.
-                if (mFakePdfPrinter == null) {
-                    mCurrentPrinter = mFakePdfPrinter = createFakePdfPrinter();
-                    updatePrintAttributes(mCurrentPrinter.getCapabilities());
-                    updateUi();
-                }
-
-                // We rearrange the printers if the user selects a printer
-                // not shown in the initial short list. Therefore, we have
-                // to keep the printer order.
-
-                // No old printers - do not bother keeping their position.
-                if (mPrinters.isEmpty()) {
-                    mPrinters.addAll(printers);
-                    mEditor.ensureCurrentPrinterSelected();
-                    notifyDataSetChanged();
-                    return;
-                }
-
-                // Add the new printers to a map.
-                ArrayMap<PrinterId, PrinterInfo> newPrintersMap =
-                        new ArrayMap<PrinterId, PrinterInfo>();
-                final int printerCount = printers.size();
-                for (int i = 0; i < printerCount; i++) {
-                    PrinterInfo printer = printers.get(i);
-                    newPrintersMap.put(printer.getId(), printer);
-                }
-
-                List<PrinterInfo> newPrinters = new ArrayList<PrinterInfo>();
-
-                // Update printers we already have.
-                final int oldPrinterCount = mPrinters.size();
-                for (int i = 0; i < oldPrinterCount; i++) {
-                    PrinterId oldPrinterId = mPrinters.get(i).getId();
-                    PrinterInfo updatedPrinter = newPrintersMap.remove(oldPrinterId);
-                    if (updatedPrinter != null) {
-                        newPrinters.add(updatedPrinter);
-                    }
-                }
-
-                // Add the rest of the new printers, i.e. what is left.
-                newPrinters.addAll(newPrintersMap.values());
-
-                mPrinters.clear();
-                mPrinters.addAll(newPrinters);
-
-                mEditor.ensureCurrentPrinterSelected();
-                notifyDataSetChanged();
-            }
-
-            @Override
-            public void onLoaderReset(Loader<List<PrinterInfo>> loader) {
-                mPrinters.clear();
-                notifyDataSetInvalidated();
-            }
-
-
-            private PrinterInfo createFakePdfPrinter() {
-                MediaSize defaultMediaSize = MediaSizeUtils.getDefault(PrintJobConfigActivity.this);
-
-                PrinterId printerId = new PrinterId(getComponentName(), "PDF printer");
-
-                PrinterCapabilitiesInfo.Builder builder =
-                        new PrinterCapabilitiesInfo.Builder(printerId);
-
-                String[] mediaSizeIds = getResources().getStringArray(
-                        R.array.pdf_printer_media_sizes);
-                final int mediaSizeIdCount = mediaSizeIds.length;
-                for (int i = 0; i < mediaSizeIdCount; i++) {
-                    String id = mediaSizeIds[i];
-                    MediaSize mediaSize = MediaSize.getStandardMediaSizeById(id);
-                    builder.addMediaSize(mediaSize, mediaSize.equals(defaultMediaSize));
-                }
-
-                builder.addResolution(new Resolution("PDF resolution", "PDF resolution",
-                            300, 300), true);
-                builder.setColorModes(PrintAttributes.COLOR_MODE_COLOR
-                        | PrintAttributes.COLOR_MODE_MONOCHROME,
-                        PrintAttributes.COLOR_MODE_COLOR);
-
-                return new PrinterInfo.Builder(printerId, getString(R.string.save_as_pdf),
-                        PrinterInfo.STATUS_IDLE)
-                    .setCapabilities(builder.build())
-                    .build();
-            }
-        }
-    }
-
-    /**
-     * An instance of this class class is intended to be the first focusable
-     * in a layout to which the system automatically gives focus. It performs
-     * some voodoo to avoid the first tap on it to start an edit mode, rather
-     * to bring up the IME, i.e. to get the behavior as if the view was not
-     * focused.
-     */
-    public static final class CustomEditText extends EditText {
-        private boolean mClickedBeforeFocus;
-        private CharSequence mError;
-
-        public CustomEditText(Context context, AttributeSet attrs) {
-            super(context, attrs);
-        }
-
-        @Override
-        public boolean performClick() {
-            super.performClick();
-            if (isFocused() && !mClickedBeforeFocus) {
-                clearFocus();
-                requestFocus();
-            }
-            mClickedBeforeFocus = true;
-            return true;
-        }
-
-        @Override
-        public CharSequence getError() {
-            return mError;
-        }
-
-        @Override
-        public void setError(CharSequence error, Drawable icon) {
-            setCompoundDrawables(null, null, icon, null);
-            mError = error;
-        }
-
-        protected void onFocusChanged(boolean gainFocus, int direction,
-                Rect previouslyFocusedRect) {
-            if (!gainFocus) {
-                mClickedBeforeFocus = false;
-            }
-            super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
-        }
-    }
-
-    private static final class Document {
-        public PrintDocumentInfo info;
-        public PageRange[] pages;
-    }
-
-    private static final class PageRangeUtils {
-
-        private static final Comparator<PageRange> sComparator = new Comparator<PageRange>() {
-            @Override
-            public int compare(PageRange lhs, PageRange rhs) {
-                return lhs.getStart() - rhs.getStart();
-            }
-        };
-
-        private PageRangeUtils() {
-            throw new UnsupportedOperationException();
-        }
-
-        public static boolean contains(PageRange[] ourRanges, PageRange[] otherRanges) {
-            if (ourRanges == null || otherRanges == null) {
-                return false;
-            }
-
-            if (ourRanges.length == 1
-                    && PageRange.ALL_PAGES.equals(ourRanges[0])) {
-                return true;
-            }
-
-            ourRanges = normalize(ourRanges);
-            otherRanges = normalize(otherRanges);
-
-            // Note that the code below relies on the ranges being normalized
-            // which is they contain monotonically increasing non-intersecting
-            // subranges whose start is less that or equal to the end.
-            int otherRangeIdx = 0;
-            final int ourRangeCount = ourRanges.length;
-            final int otherRangeCount = otherRanges.length;
-            for (int ourRangeIdx = 0; ourRangeIdx < ourRangeCount; ourRangeIdx++) {
-                PageRange ourRange = ourRanges[ourRangeIdx];
-                for (; otherRangeIdx < otherRangeCount; otherRangeIdx++) {
-                    PageRange otherRange = otherRanges[otherRangeIdx];
-                    if (otherRange.getStart() > ourRange.getEnd()) {
-                        break;
-                    }
-                    if (otherRange.getStart() < ourRange.getStart()
-                            || otherRange.getEnd() > ourRange.getEnd()) {
-                        return false;
-                    }
-                }
-            }
-            if (otherRangeIdx < otherRangeCount) {
-                return false;
-            }
-            return true;
-        }
-
-        public static PageRange[] normalize(PageRange[] pageRanges) {
-            if (pageRanges == null) {
-                return null;
-            }
-            final int oldRangeCount = pageRanges.length;
-            if (oldRangeCount <= 1) {
-                return pageRanges;
-            }
-            Arrays.sort(pageRanges, sComparator);
-            int newRangeCount = 1;
-            for (int i = 0; i < oldRangeCount - 1; i++) {
-                newRangeCount++;
-                PageRange currentRange = pageRanges[i];
-                PageRange nextRange = pageRanges[i + 1];
-                if (currentRange.getEnd() + 1 >= nextRange.getStart()) {
-                    newRangeCount--;
-                    pageRanges[i] = null;
-                    pageRanges[i + 1] = new PageRange(currentRange.getStart(),
-                            Math.max(currentRange.getEnd(), nextRange.getEnd()));
-                }
-            }
-            if (newRangeCount == oldRangeCount) {
-                return pageRanges;
-            }
-            return Arrays.copyOfRange(pageRanges, oldRangeCount - newRangeCount,
-                    oldRangeCount);
-        }
-
-        public static void offset(PageRange[] pageRanges, int offset) {
-            if (offset == 0) {
-                return;
-            }
-            final int pageRangeCount = pageRanges.length;
-            for (int i = 0; i < pageRangeCount; i++) {
-                final int start = pageRanges[i].getStart() + offset;
-                final int end = pageRanges[i].getEnd() + offset;
-                pageRanges[i] = new PageRange(start, end);
-            }
-        }
-    }
-
-    private static final class AutoCancellingAnimator
-            implements OnAttachStateChangeListener, Runnable {
-
-        private ViewPropertyAnimator mAnimator;
-
-        private boolean mCancelled;
-        private Runnable mEndCallback;
-
-        public static AutoCancellingAnimator animate(View view) {
-            ViewPropertyAnimator animator = view.animate();
-            AutoCancellingAnimator cancellingWrapper =
-                    new AutoCancellingAnimator(animator);
-            view.addOnAttachStateChangeListener(cancellingWrapper);
-            return cancellingWrapper;
-        }
-
-        private AutoCancellingAnimator(ViewPropertyAnimator animator) {
-            mAnimator = animator;
-        }
-
-        public AutoCancellingAnimator alpha(float alpha) {
-            mAnimator = mAnimator.alpha(alpha);
-            return this;
-        }
-
-        public void cancel() {
-            mAnimator.cancel();
-        }
-
-        public AutoCancellingAnimator withLayer() {
-            mAnimator = mAnimator.withLayer();
-            return this;
-        }
-
-        public AutoCancellingAnimator withEndAction(Runnable callback) {
-            mEndCallback = callback;
-            mAnimator = mAnimator.withEndAction(this);
-            return this;
-        }
-
-        public AutoCancellingAnimator scaleY(float scale) {
-            mAnimator = mAnimator.scaleY(scale);
-            return this;
-        }
-
-        @Override
-        public void onViewAttachedToWindow(View v) {
-            /* do nothing */
-        }
-
-        @Override
-        public void onViewDetachedFromWindow(View v) {
-            cancel();
-        }
-
-        @Override
-        public void run() {
-            if (!mCancelled) {
-                mEndCallback.run();
-            }
-        }
-    }
-
-    private static final class PrintSpoolerProvider implements ServiceConnection {
-        private final Context mContext;
-        private final Runnable mCallback;
-
-        private PrintSpoolerService mSpooler;
-
-        public PrintSpoolerProvider(Context context, Runnable callback) {
-            mContext = context;
-            mCallback = callback;
-            Intent intent = new Intent(mContext, PrintSpoolerService.class);
-            mContext.bindService(intent, this, 0);
-        }
-
-        public PrintSpoolerService getSpooler() {
-            return mSpooler;
-        }
-
-        public void destroy() {
-            if (mSpooler != null) {
-                mContext.unbindService(this);
-            }
-        }
-
-        @Override
-        public void onServiceConnected(ComponentName name, IBinder service) {
-            mSpooler = ((PrintSpoolerService.PrintSpooler) service).getService();
-            if (mSpooler != null) {
-                mCallback.run();
-            }
-        }
-
-        @Override
-        public void onServiceDisconnected(ComponentName name) {
-            /* do noting - we are in the same process */
-        }
-    }
-
-    private static final class PrintDocumentAdapterObserver
-            extends IPrintDocumentAdapterObserver.Stub {
-        private final WeakReference<PrintJobConfigActivity> mWeakActvity;
-
-        public PrintDocumentAdapterObserver(PrintJobConfigActivity activity) {
-            mWeakActvity = new WeakReference<PrintJobConfigActivity>(activity);
-        }
-
-        @Override
-        public void onDestroy() {
-            final PrintJobConfigActivity activity = mWeakActvity.get();
-            if (activity != null) {
-                activity.mController.mHandler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        if (activity.mController != null) {
-                            activity.mController.cancel();
-                        }
-                        if (activity.mEditor != null) {
-                            activity.mEditor.cancel();
-                        }
-                        activity.finish();
-                    }
-                });
-            }
-        }
-    }
-}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/RemotePrintDocumentAdapter.java b/packages/PrintSpooler/src/com/android/printspooler/RemotePrintDocumentAdapter.java
deleted file mode 100644
index d9ccb5d..0000000
--- a/packages/PrintSpooler/src/com/android/printspooler/RemotePrintDocumentAdapter.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2013 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.printspooler;
-
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-import android.print.ILayoutResultCallback;
-import android.print.IPrintDocumentAdapter;
-import android.print.IWriteResultCallback;
-import android.print.PageRange;
-import android.print.PrintAttributes;
-import android.util.Log;
-
-import libcore.io.IoUtils;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-/**
- * This class represents a remote print document adapter instance.
- */
-final class RemotePrintDocumentAdapter {
-    private static final String LOG_TAG = "RemotePrintDocumentAdapter";
-
-    private static final boolean DEBUG = false;
-
-    private final IPrintDocumentAdapter mRemoteInterface;
-
-    private final File mFile;
-
-    public RemotePrintDocumentAdapter(IPrintDocumentAdapter printAdatper, File file) {
-        mRemoteInterface = printAdatper;
-        mFile = file;
-    }
-
-    public void start()  {
-        if (DEBUG) {
-            Log.i(LOG_TAG, "start()");
-        }
-        try {
-            mRemoteInterface.start();
-        } catch (RemoteException re) {
-            Log.e(LOG_TAG, "Error calling start()", re);
-        }
-    }
-
-    public void layout(PrintAttributes oldAttributes, PrintAttributes newAttributes,
-            ILayoutResultCallback callback, Bundle metadata, int sequence) {
-        if (DEBUG) {
-            Log.i(LOG_TAG, "layout()");
-        }
-        try {
-            mRemoteInterface.layout(oldAttributes, newAttributes, callback, metadata, sequence);
-        } catch (RemoteException re) {
-            Log.e(LOG_TAG, "Error calling layout()", re);
-        }
-    }
-
-    public void write(final PageRange[] pages, final IWriteResultCallback callback,
-            final int sequence) {
-        if (DEBUG) {
-            Log.i(LOG_TAG, "write()");
-        }
-        new AsyncTask<Void, Void, Void>() {
-            @Override
-            protected Void doInBackground(Void... params) {
-                InputStream in = null;
-                OutputStream out = null;
-                ParcelFileDescriptor source = null;
-                ParcelFileDescriptor sink = null;
-                try {
-                    ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
-                    source = pipe[0];
-                    sink = pipe[1];
-
-                    in = new FileInputStream(source.getFileDescriptor());
-                    out = new FileOutputStream(mFile);
-
-                    // Async call to initiate the other process writing the data.
-                    mRemoteInterface.write(pages, sink, callback, sequence);
-
-                    // Close the source. It is now held by the client.
-                    sink.close();
-                    sink = null;
-
-                    // Read the data.
-                    final byte[] buffer = new byte[8192];
-                    while (true) {
-                        final int readByteCount = in.read(buffer);
-                        if (readByteCount < 0) {
-                            break;
-                        }
-                        out.write(buffer, 0, readByteCount);
-                    }
-                } catch (RemoteException re) {
-                    Log.e(LOG_TAG, "Error calling write()", re);
-                } catch (IOException ioe) {
-                    Log.e(LOG_TAG, "Error calling write()", ioe);
-                } finally {
-                    IoUtils.closeQuietly(in);
-                    IoUtils.closeQuietly(out);
-                    IoUtils.closeQuietly(sink);
-                    IoUtils.closeQuietly(source);
-                }
-                return null;
-            }
-        }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
-    }
-
-    public void finish() {
-        if (DEBUG) {
-            Log.i(LOG_TAG, "finish()");
-        }
-        try {
-            mRemoteInterface.finish();
-        } catch (RemoteException re) {
-            Log.e(LOG_TAG, "Error calling finish()", re);
-        }
-    }
-
-    public void cancel() {
-        if (DEBUG) {
-            Log.i(LOG_TAG, "cancel()");
-        }
-        try {
-            mRemoteInterface.cancel();
-        } catch (RemoteException re) {
-            Log.e(LOG_TAG, "Error calling cancel()", re);
-        }
-    }
-}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/SelectPrinterActivity.java b/packages/PrintSpooler/src/com/android/printspooler/SelectPrinterActivity.java
deleted file mode 100644
index 141dbd1..0000000
--- a/packages/PrintSpooler/src/com/android/printspooler/SelectPrinterActivity.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2013 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.printspooler;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.os.Bundle;
-import android.print.PrinterId;
-
-import com.android.printspooler.SelectPrinterFragment.OnPrinterSelectedListener;
-
-public class SelectPrinterActivity extends Activity implements OnPrinterSelectedListener {
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.select_printer_activity);
-    }
-
-    @Override
-    public void onPrinterSelected(PrinterId printer) {
-        Intent intent = new Intent();
-        intent.putExtra(PrintJobConfigActivity.INTENT_EXTRA_PRINTER_ID, printer);
-        setResult(RESULT_OK, intent);
-        finish();
-    }
-}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/NotificationController.java b/packages/PrintSpooler/src/com/android/printspooler/model/NotificationController.java
similarity index 99%
rename from packages/PrintSpooler/src/com/android/printspooler/NotificationController.java
rename to packages/PrintSpooler/src/com/android/printspooler/model/NotificationController.java
index 968a8bf..929f0fc 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/NotificationController.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/NotificationController.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.printspooler;
+package com.android.printspooler.model;
 
 import android.app.Notification;
 import android.app.Notification.InboxStyle;
@@ -38,6 +38,8 @@
 import android.provider.Settings;
 import android.util.Log;
 
+import com.android.printspooler.R;
+
 import java.util.ArrayList;
 import java.util.List;
 
@@ -45,7 +47,7 @@
  * This class is responsible for updating the print notifications
  * based on print job state transitions.
  */
-public class NotificationController {
+final class NotificationController {
     public static final boolean DEBUG = false;
 
     public static final String LOG_TAG = "NotificationController";
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerProvider.java b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerProvider.java
new file mode 100644
index 0000000..06723c3
--- /dev/null
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerProvider.java
@@ -0,0 +1,60 @@
+/*
+ * 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.printspooler.model;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.IBinder;
+
+public class PrintSpoolerProvider implements ServiceConnection {
+    private final Context mContext;
+    private final Runnable mCallback;
+
+    private PrintSpoolerService mSpooler;
+
+    public PrintSpoolerProvider(Context context, Runnable callback) {
+        mContext = context;
+        mCallback = callback;
+        Intent intent = new Intent(mContext, PrintSpoolerService.class);
+        mContext.bindService(intent, this, 0);
+    }
+
+    public PrintSpoolerService getSpooler() {
+        return mSpooler;
+    }
+
+    public void destroy() {
+        if (mSpooler != null) {
+            mContext.unbindService(this);
+        }
+    }
+
+    @Override
+    public void onServiceConnected(ComponentName name, IBinder service) {
+        mSpooler = ((PrintSpoolerService.PrintSpooler) service).getService();
+        if (mSpooler != null) {
+            mCallback.run();
+        }
+    }
+
+    @Override
+    public void onServiceDisconnected(ComponentName name) {
+        /* do nothing - we are in the same process */
+    }
+}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/PrintSpoolerService.java b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java
similarity index 95%
rename from packages/PrintSpooler/src/com/android/printspooler/PrintSpoolerService.java
rename to packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java
index 615d667..045a2f9 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/PrintSpoolerService.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java
@@ -14,10 +14,11 @@
  * limitations under the License.
  */
 
-package com.android.printspooler;
+package com.android.printspooler.model;
 
 import android.app.Service;
 import android.content.ComponentName;
+import android.content.Context;
 import android.content.Intent;
 import android.os.AsyncTask;
 import android.os.Bundle;
@@ -38,7 +39,6 @@
 import android.print.PrintJobInfo;
 import android.print.PrintManager;
 import android.print.PrinterId;
-import android.print.PrinterInfo;
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.AtomicFile;
@@ -48,6 +48,7 @@
 
 import com.android.internal.os.HandlerCaller;
 import com.android.internal.util.FastXmlSerializer;
+import com.android.printspooler.R;
 
 import libcore.io.IoUtils;
 
@@ -89,7 +90,7 @@
 
     private final Object mLock = new Object();
 
-    private final List<PrintJobInfo> mPrintJobs = new ArrayList<PrintJobInfo>();
+    private final List<PrintJobInfo> mPrintJobs = new ArrayList<>();
 
     private static PrintSpoolerService sInstance;
 
@@ -274,7 +275,7 @@
                             && isScheduledState(printJob.getState()));
                 if (sameComponent && sameAppId && sameState) {
                     if (foundPrintJobs == null) {
-                        foundPrintJobs = new ArrayList<PrintJobInfo>();
+                        foundPrintJobs = new ArrayList<>();
                     }
                     foundPrintJobs.add(printJob);
                 }
@@ -400,7 +401,7 @@
                 FileOutputStream out = null;
                 try {
                     if (printJob != null) {
-                        File file = generateFileForPrintJob(printJobId);
+                        File file = generateFileForPrintJob(PrintSpoolerService.this, printJobId);
                         in = new FileInputStream(file);
                         out = new FileOutputStream(fd.getFileDescriptor());
                     }
@@ -427,8 +428,8 @@
         }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
     }
 
-    public File generateFileForPrintJob(PrintJobId printJobId) {
-        return new File(getFilesDir(), PRINT_JOB_FILE_PREFIX
+    public static File generateFileForPrintJob(Context context, PrintJobId printJobId) {
+        return new File(context.getFilesDir(), PRINT_JOB_FILE_PREFIX
                 + printJobId.flattenToString() + "." + PRINT_FILE_EXTENSION);
     }
 
@@ -461,7 +462,7 @@
     }
 
     private void removePrintJobFileLocked(PrintJobId printJobId) {
-        File file = generateFileForPrintJob(printJobId);
+        File file = generateFileForPrintJob(PrintSpoolerService.this, printJobId);
         if (file.exists()) {
             file.delete();
             if (DEBUG_PRINT_JOB_LIFECYCLE) {
@@ -557,7 +558,7 @@
     }
 
     private boolean isObsoleteState(int printJobState) {
-        return (isTeminalState(printJobState)
+        return (isTerminalState(printJobState)
                 || printJobState == PrintJobInfo.STATE_QUEUED);
     }
 
@@ -574,7 +575,7 @@
                 || printJobState == PrintJobInfo.STATE_BLOCKED;
     }
 
-    private boolean isTeminalState(int printJobState) {
+    private boolean isTerminalState(int printJobState) {
         return printJobState == PrintJobInfo.STATE_COMPLETED
                 || printJobState == PrintJobInfo.STATE_CANCELED;
     }
@@ -619,61 +620,23 @@
         }
     }
 
-    public void setPrintJobCopiesNoPersistence(PrintJobId printJobId, int copies) {
+    public void updatePrintJobUserConfigurableOptionsNoPersistence(PrintJobInfo printJob) {
         synchronized (mLock) {
-            PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY);
-            if (printJob != null) {
-                printJob.setCopies(copies);
+            final int printJobCount = mPrintJobs.size();
+            for (int i = 0; i < printJobCount; i++) {
+                PrintJobInfo cachedPrintJob = mPrintJobs.get(i);
+                if (cachedPrintJob.getId().equals(printJob.getId())) {
+                    cachedPrintJob.setPrinterId(printJob.getPrinterId());
+                    cachedPrintJob.setPrinterName(printJob.getPrinterName());
+                    cachedPrintJob.setCopies(printJob.getCopies());
+                    cachedPrintJob.setDocumentInfo(printJob.getDocumentInfo());
+                    cachedPrintJob.setPages(printJob.getPages());
+                    cachedPrintJob.setAttributes(printJob.getAttributes());
+                    cachedPrintJob.setAdvancedOptions(printJob.getAdvancedOptions());
+                    return;
+                }
             }
-        }
-    }
-
-    public void setPrintJobAdvancedOptionsNoPersistence(PrintJobId printJobId,
-            Bundle advancedOptions) {
-        synchronized (mLock) {
-            PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY);
-            if (printJob != null) {
-                printJob.setAdvancedOptions(advancedOptions);
-            }
-        }
-    }
-
-    public void setPrintJobPrintDocumentInfoNoPersistence(PrintJobId printJobId,
-            PrintDocumentInfo info) {
-        synchronized (mLock) {
-            PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY);
-            if (printJob != null) {
-                printJob.setDocumentInfo(info);
-            }
-        }
-    }
-
-    public void setPrintJobAttributesNoPersistence(PrintJobId printJobId,
-            PrintAttributes attributes) {
-        synchronized (mLock) {
-            PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY);
-            if (printJob != null) {
-                printJob.setAttributes(attributes);
-            }
-        }
-    }
-
-    public void setPrintJobPrinterNoPersistence(PrintJobId printJobId, PrinterInfo printer) {
-        synchronized (mLock) {
-            PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY);
-            if (printJob != null) {
-                printJob.setPrinterId(printer.getId());
-                printJob.setPrinterName(printer.getName());
-            }
-        }
-    }
-
-    public void setPrintJobPagesNoPersistence(PrintJobId printJobId, PageRange[] pages) {
-        synchronized (mLock) {
-            PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY);
-            if (printJob != null) {
-                printJob.setPages(pages);
-            }
+            throw new IllegalArgumentException("No print job with id:" + printJob.getId());
         }
     }
 
@@ -1250,7 +1213,7 @@
         }
     }
 
-    final class PrintSpooler extends IPrintSpooler.Stub {
+    public final class PrintSpooler extends IPrintSpooler.Stub {
         @Override
         public void getPrintJobInfos(IPrintSpoolerCallbacks callback,
                 ComponentName componentName, int state, int appId, int sequence)
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java b/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java
new file mode 100644
index 0000000..e70c361
--- /dev/null
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java
@@ -0,0 +1,1148 @@
+/*
+ * 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.printspooler.model;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder.DeathRecipient;
+import android.os.ICancellationSignal;
+import android.os.Looper;
+import android.os.Message;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.print.ILayoutResultCallback;
+import android.print.IPrintDocumentAdapter;
+import android.print.IPrintDocumentAdapterObserver;
+import android.print.IWriteResultCallback;
+import android.print.PageRange;
+import android.print.PrintAttributes;
+import android.print.PrintDocumentAdapter;
+import android.print.PrintDocumentInfo;
+import android.util.Log;
+
+import com.android.printspooler.R;
+import com.android.printspooler.util.PageRangeUtils;
+
+import libcore.io.IoUtils;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.ref.WeakReference;
+import java.util.Arrays;
+
+public final class RemotePrintDocument {
+    private static final String LOG_TAG = "RemotePrintDocument";
+
+    private static final boolean DEBUG = false;
+
+    private static final int STATE_INITIAL = 0;
+    private static final int STATE_STARTED = 1;
+    private static final int STATE_UPDATING = 2;
+    private static final int STATE_UPDATED = 3;
+    private static final int STATE_FAILED = 4;
+    private static final int STATE_FINISHED = 5;
+    private static final int STATE_CANCELING = 6;
+    private static final int STATE_CANCELED = 7;
+    private static final int STATE_DESTROYED = 8;
+
+    private static final PageRange[] ALL_PAGES_ARRAY = new PageRange[] {
+            PageRange.ALL_PAGES
+    };
+
+    private final Context mContext;
+
+    private final RemotePrintDocumentInfo mDocumentInfo;
+    private final UpdateSpec mUpdateSpec = new UpdateSpec();
+
+    private final Looper mLooper;
+    private final IPrintDocumentAdapter mPrintDocumentAdapter;
+    private final DocumentObserver mDocumentObserver;
+
+    private final UpdateResultCallbacks mUpdateCallbacks;
+
+    private final CommandDoneCallback mCommandResultCallback =
+            new CommandDoneCallback() {
+        @Override
+        public void onDone() {
+            if (mCurrentCommand.isCompleted()) {
+                if (mCurrentCommand instanceof LayoutCommand) {
+                    // If there is a next command after a layout is done, then another
+                    // update was issued and the next command is another layout, so we
+                    // do nothing. However, if there is no next command we may need to
+                    // ask for some pages given we do not already have them or we do
+                    // but the content has changed.
+                    LayoutCommand layoutCommand = (LayoutCommand) mCurrentCommand;
+                    if (mNextCommand == null) {
+                        if (layoutCommand.isDocumentChanged() || !PageRangeUtils.contains(
+                                mDocumentInfo.writtenPages, mUpdateSpec.pages)) {
+                            mNextCommand = new WriteCommand(mContext, mLooper,
+                                    mPrintDocumentAdapter, mDocumentInfo,
+                                    mDocumentInfo.info.getPageCount(), mUpdateSpec.pages,
+                                    mDocumentInfo.file, mCommandResultCallback);
+                        } else {
+                            // If we have the requested pages just update that ones to be printed.
+                            mDocumentInfo.printedPages = computePrintedPages(mUpdateSpec.pages,
+                                    mDocumentInfo.writtenPages, mDocumentInfo.info.getPageCount());
+                            // Notify we are done.
+                            notifyUpdateCompleted();
+                        }
+                    }
+                } else {
+                    // We always notify after a write.
+                    notifyUpdateCompleted();
+                }
+                runPendingCommand();
+            } else if (mCurrentCommand.isFailed()) {
+                mState = STATE_FAILED;
+                CharSequence error = mCurrentCommand.getError();
+                mCurrentCommand = null;
+                mNextCommand = null;
+                mUpdateSpec.reset();
+                notifyUpdateFailed(error);
+            } else if (mCurrentCommand.isCanceled()) {
+                if (mState == STATE_CANCELING) {
+                    mState = STATE_CANCELED;
+                    notifyUpdateCanceled();
+                }
+                runPendingCommand();
+            }
+        }
+    };
+
+    private final DeathRecipient mDeathRecipient = new DeathRecipient() {
+        @Override
+        public void binderDied() {
+            finish();
+        }
+    };
+
+    private int mState = STATE_INITIAL;
+
+    private AsyncCommand mCurrentCommand;
+    private AsyncCommand mNextCommand;
+
+    public interface DocumentObserver {
+        public void onDestroy();
+    }
+
+    public interface UpdateResultCallbacks {
+        public void onUpdateCompleted(RemotePrintDocumentInfo document);
+        public void onUpdateCanceled();
+        public void onUpdateFailed(CharSequence error);
+    }
+
+    public RemotePrintDocument(Context context, IPrintDocumentAdapter adapter,
+            File file, DocumentObserver destroyListener, UpdateResultCallbacks callbacks) {
+        mPrintDocumentAdapter = adapter;
+        mLooper = context.getMainLooper();
+        mContext = context;
+        mDocumentObserver = destroyListener;
+        mDocumentInfo = new RemotePrintDocumentInfo();
+        mDocumentInfo.file = file;
+        mUpdateCallbacks = callbacks;
+        connectToRemoteDocument();
+    }
+
+    public void start() {
+        if (DEBUG) {
+            Log.i(LOG_TAG, "[CALLED] start()");
+        }
+        if (mState != STATE_INITIAL) {
+            throw new IllegalStateException("Cannot start in state:" + stateToString(mState));
+        }
+        try {
+            mPrintDocumentAdapter.start();
+            mState = STATE_STARTED;
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Error calling start()", re);
+            mState = STATE_FAILED;
+            mDocumentObserver.onDestroy();
+        }
+    }
+
+    public boolean update(PrintAttributes attributes, PageRange[] pages, boolean preview) {
+        boolean willUpdate;
+
+        if (DEBUG) {
+            Log.i(LOG_TAG, "[CALLED] update()");
+        }
+
+        if (hasUpdateError()) {
+            throw new IllegalStateException("Cannot update without a clearing the failure");
+        }
+
+        if (mState == STATE_INITIAL || mState == STATE_FINISHED || mState == STATE_DESTROYED) {
+            throw new IllegalStateException("Cannot update in state:" + stateToString(mState));
+        }
+
+        // We schedule a layout if the constraints changed.
+        if (!mUpdateSpec.hasSameConstraints(attributes, preview)) {
+            willUpdate = true;
+
+            // If there is a current command that is running we ask for a
+            // cancellation and start over.
+            if (mCurrentCommand != null && (mCurrentCommand.isRunning()
+                    || mCurrentCommand.isPending())) {
+                mCurrentCommand.cancel();
+            }
+
+            // Schedule a layout command.
+            PrintAttributes oldAttributes = mDocumentInfo.attributes != null
+                    ? mDocumentInfo.attributes : new PrintAttributes.Builder().build();
+            AsyncCommand command = new LayoutCommand(mLooper, mPrintDocumentAdapter,
+                  mDocumentInfo, oldAttributes, attributes, preview, mCommandResultCallback);
+            scheduleCommand(command);
+
+            mState = STATE_UPDATING;
+        // If no layout in progress and we don't have all pages - schedule a write.
+        } else if ((!(mCurrentCommand instanceof LayoutCommand)
+                || (!mCurrentCommand.isPending() && !mCurrentCommand.isRunning()))
+                && !PageRangeUtils.contains(mUpdateSpec.pages, pages)) {
+            willUpdate = true;
+
+            // Cancel the current write as a new one is to be scheduled.
+            if (mCurrentCommand instanceof WriteCommand
+                    && (mCurrentCommand.isPending() || mCurrentCommand.isRunning())) {
+                mCurrentCommand.cancel();
+            }
+
+            // Schedule a write command.
+            AsyncCommand command = new WriteCommand(mContext, mLooper, mPrintDocumentAdapter,
+                    mDocumentInfo, mDocumentInfo.info.getPageCount(), pages,
+                    mDocumentInfo.file, mCommandResultCallback);
+            scheduleCommand(command);
+
+            mState = STATE_UPDATING;
+        } else {
+            willUpdate = false;
+            if (DEBUG) {
+                Log.i(LOG_TAG, "[SKIPPING] No update needed");
+            }
+        }
+
+        // Keep track of what is requested.
+        mUpdateSpec.update(attributes, preview, pages);
+
+        runPendingCommand();
+
+        return willUpdate;
+    }
+
+    public void finish() {
+        if (DEBUG) {
+            Log.i(LOG_TAG, "[CALLED] finish()");
+        }
+        if (mState != STATE_STARTED && mState != STATE_UPDATED
+                && mState != STATE_FAILED && mState != STATE_CANCELING) {
+            throw new IllegalStateException("Cannot finish in state:"
+                    + stateToString(mState));
+        }
+        try {
+            mPrintDocumentAdapter.finish();
+            mState = STATE_FINISHED;
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Error calling finish()", re);
+            mState = STATE_FAILED;
+            mDocumentObserver.onDestroy();
+        }
+    }
+
+    public void cancel() {
+        if (DEBUG) {
+            Log.i(LOG_TAG, "[CALLED] cancel()");
+        }
+
+        if (mState == STATE_CANCELING) {
+            return;
+        }
+
+        if (mState != STATE_UPDATING) {
+            throw new IllegalStateException("Cannot cancel in state:" + stateToString(mState));
+        }
+
+        mState = STATE_CANCELING;
+
+        mCurrentCommand.cancel();
+    }
+
+    public void destroy() {
+        if (DEBUG) {
+            Log.i(LOG_TAG, "[CALLED] destroy()");
+        }
+        if (mState == STATE_DESTROYED) {
+            throw new IllegalStateException("Cannot destroy in state:" + stateToString(mState));
+        }
+
+        mState = STATE_DESTROYED;
+
+        disconnectFromRemoteDocument();
+        mDocumentObserver.onDestroy();
+    }
+
+    public boolean isUpdating() {
+        return mState == STATE_UPDATING || mState == STATE_CANCELING;
+    }
+
+    public boolean isDestroyed() {
+        return mState == STATE_DESTROYED;
+    }
+
+    public boolean hasUpdateError() {
+        return mState == STATE_FAILED;
+    }
+
+    public void clearUpdateError() {
+        if (!hasUpdateError()) {
+            throw new IllegalStateException("No update error to clear");
+        }
+        mState = STATE_STARTED;
+    }
+
+    public RemotePrintDocumentInfo getDocumentInfo() {
+        return mDocumentInfo;
+    }
+
+    public void writeContent(ContentResolver contentResolver, Uri uri) {
+        InputStream in = null;
+        OutputStream out = null;
+        try {
+            in = new FileInputStream(mDocumentInfo.file);
+            out = contentResolver.openOutputStream(uri);
+            final byte[] buffer = new byte[8192];
+            while (true) {
+                final int readByteCount = in.read(buffer);
+                if (readByteCount < 0) {
+                    break;
+                }
+                out.write(buffer, 0, readByteCount);
+            }
+        } catch (IOException e) {
+            Log.e(LOG_TAG, "Error writing document content.", e);
+        } finally {
+            IoUtils.closeQuietly(in);
+            IoUtils.closeQuietly(out);
+        }
+    }
+
+    private void notifyUpdateCanceled() {
+        if (DEBUG) {
+            Log.i(LOG_TAG, "[CALLING] onUpdateCanceled()");
+        }
+        mUpdateCallbacks.onUpdateCanceled();
+    }
+
+    private void notifyUpdateCompleted() {
+        if (DEBUG) {
+            Log.i(LOG_TAG, "[CALLING] onUpdateCompleted()");
+        }
+        mUpdateCallbacks.onUpdateCompleted(mDocumentInfo);
+    }
+
+    private void notifyUpdateFailed(CharSequence error) {
+        if (DEBUG) {
+            Log.i(LOG_TAG, "[CALLING] onUpdateCompleted()");
+        }
+        mUpdateCallbacks.onUpdateFailed(error);
+    }
+
+    private void connectToRemoteDocument() {
+        try {
+            mPrintDocumentAdapter.asBinder().linkToDeath(mDeathRecipient, 0);
+        } catch (RemoteException re) {
+            Log.w(LOG_TAG, "The printing process is dead.");
+            destroy();
+            return;
+        }
+
+        try {
+            mPrintDocumentAdapter.setObserver(new PrintDocumentAdapterObserver(this));
+        } catch (RemoteException re) {
+            Log.w(LOG_TAG, "Error setting observer to the print adapter.");
+            destroy();
+        }
+    }
+
+    private void disconnectFromRemoteDocument() {
+        try {
+            mPrintDocumentAdapter.setObserver(null);
+        } catch (RemoteException re) {
+            Log.w(LOG_TAG, "Error setting observer to the print adapter.");
+            // Keep going - best effort...
+        }
+
+        mPrintDocumentAdapter.asBinder().unlinkToDeath(mDeathRecipient, 0);
+    }
+
+    private void scheduleCommand(AsyncCommand command) {
+        if (mCurrentCommand == null) {
+            mCurrentCommand = command;
+        } else {
+            mNextCommand = command;
+        }
+    }
+
+    private void runPendingCommand() {
+        if (mCurrentCommand != null
+                && (mCurrentCommand.isCompleted()
+                        || mCurrentCommand.isCanceled())) {
+            mCurrentCommand = mNextCommand;
+            mNextCommand = null;
+        }
+
+        if (mCurrentCommand != null) {
+            if (mCurrentCommand.isPending()) {
+                mCurrentCommand.run();
+            }
+            mState = STATE_UPDATING;
+        } else {
+            mState = STATE_UPDATED;
+        }
+    }
+
+    private static String stateToString(int state) {
+        switch (state) {
+            case STATE_FINISHED: {
+                return "STATE_FINISHED";
+            }
+            case STATE_FAILED: {
+                return "STATE_FAILED";
+            }
+            case STATE_STARTED: {
+                return "STATE_STARTED";
+            }
+            case STATE_UPDATING: {
+                return "STATE_UPDATING";
+            }
+            case STATE_UPDATED: {
+                return "STATE_UPDATED";
+            }
+            case STATE_CANCELING: {
+                return "STATE_CANCELING";
+            }
+            case STATE_CANCELED: {
+                return "STATE_CANCELED";
+            }
+            case STATE_DESTROYED: {
+                return "STATE_DESTROYED";
+            }
+            default: {
+                return "STATE_UNKNOWN";
+            }
+        }
+    }
+
+    private static PageRange[] computePrintedPages(PageRange[] requestedPages,
+                                                   PageRange[] writtenPages, int pageCount) {
+        // Adjust the print job pages based on what was requested and written.
+        // The cases are ordered in the most expected to the least expected.
+        if (Arrays.equals(writtenPages, requestedPages)) {
+            // We got a document with exactly the pages we wanted. Hence,
+            // the printer has to print all pages in the data.
+            return ALL_PAGES_ARRAY;
+        } else if (Arrays.equals(writtenPages, ALL_PAGES_ARRAY)) {
+            // We requested specific pages but got all of them. Hence,
+            // the printer has to print only the requested pages.
+            return requestedPages;
+        } else if (PageRangeUtils.contains(writtenPages, requestedPages)) {
+            // We requested specific pages and got more but not all pages.
+            // Hence, we have to offset appropriately the printed pages to
+            // be based off the start of the written ones instead of zero.
+            // The written pages are always non-null and not empty.
+            final int offset = -writtenPages[0].getStart();
+            PageRangeUtils.offset(requestedPages, offset);
+            return requestedPages;
+        } else if (Arrays.equals(requestedPages, ALL_PAGES_ARRAY)
+                && isAllPages(writtenPages, pageCount)) {
+            // We requested all pages via the special constant and got all
+            // of them as an explicit enumeration. Hence, the printer has
+            // to print only the requested pages.
+            return ALL_PAGES_ARRAY;
+        }
+
+        return null;
+    }
+
+    private static boolean isAllPages(PageRange[] pageRanges, int pageCount) {
+        return pageRanges.length > 0 && pageRanges[0].getStart() == 0
+                && pageRanges[pageRanges.length - 1].getEnd() == pageCount - 1;
+    }
+
+    static final class UpdateSpec {
+        final PrintAttributes attributes = new PrintAttributes.Builder().build();
+        boolean preview;
+        PageRange[] pages;
+
+        public void update(PrintAttributes attributes, boolean preview,
+                PageRange[] pages) {
+            this.attributes.copyFrom(attributes);
+            this.preview = preview;
+            this.pages = Arrays.copyOf(pages, pages.length);
+        }
+
+        public void reset() {
+            attributes.clear();
+            preview = false;
+            pages = null;
+        }
+
+        public boolean hasSameConstraints(PrintAttributes attributes, boolean preview) {
+            return this.attributes.equals(attributes) && this.preview == preview;
+        }
+    }
+
+    public static final class RemotePrintDocumentInfo {
+        public PrintAttributes attributes;
+        public Bundle metadata;
+        public PrintDocumentInfo info;
+        public PageRange[] printedPages;
+        public PageRange[] writtenPages;
+        public File file;
+    }
+
+    private interface CommandDoneCallback {
+        public void onDone();
+    }
+
+    private static abstract class AsyncCommand implements Runnable {
+        private static final int STATE_PENDING = 0;
+        private static final int STATE_RUNNING = 1;
+        private static final int STATE_COMPLETED = 2;
+        private static final int STATE_CANCELED = 3;
+        private static final int STATE_CANCELING = 4;
+        private static final int STATE_FAILED = 5;
+
+        private static int sSequenceCounter;
+
+        protected final int mSequence = sSequenceCounter++;
+        protected final IPrintDocumentAdapter mAdapter;
+        protected final RemotePrintDocumentInfo mDocument;
+
+        protected final CommandDoneCallback mDoneCallback;
+
+        protected ICancellationSignal mCancellation;
+
+        private CharSequence mError;
+
+        private int mState = STATE_PENDING;
+
+        public AsyncCommand(IPrintDocumentAdapter adapter, RemotePrintDocumentInfo document,
+                CommandDoneCallback doneCallback) {
+            mAdapter = adapter;
+            mDocument = document;
+            mDoneCallback = doneCallback;
+        }
+
+        protected final boolean isCanceling() {
+            return mState == STATE_CANCELING;
+        }
+
+        public final boolean isCanceled() {
+            return mState == STATE_CANCELED;
+        }
+
+        public final void cancel() {
+            if (isRunning()) {
+                canceling();
+                if (mCancellation != null) {
+                    try {
+                        mCancellation.cancel();
+                    } catch (RemoteException re) {
+                        Log.w(LOG_TAG, "Error while canceling", re);
+                    }
+                }
+            } else {
+                canceled();
+
+                // Done.
+                mDoneCallback.onDone();
+            }
+        }
+
+        protected final void canceling() {
+            if (mState != STATE_PENDING && mState != STATE_RUNNING) {
+                throw new IllegalStateException("Command not pending or running.");
+            }
+            mState = STATE_CANCELING;
+        }
+
+        protected final void canceled() {
+            if (mState != STATE_CANCELING) {
+                throw new IllegalStateException("Not canceling.");
+            }
+            mState = STATE_CANCELED;
+        }
+
+        public final boolean isPending() {
+            return mState == STATE_PENDING;
+        }
+
+        protected final void running() {
+            if (mState != STATE_PENDING) {
+                throw new IllegalStateException("Not pending.");
+            }
+            mState = STATE_RUNNING;
+        }
+
+        public final boolean isRunning() {
+            return mState == STATE_RUNNING;
+        }
+
+        protected final void completed() {
+            if (mState != STATE_RUNNING && mState != STATE_CANCELING) {
+                throw new IllegalStateException("Not running.");
+            }
+            mState = STATE_COMPLETED;
+        }
+
+        public final boolean isCompleted() {
+            return mState == STATE_COMPLETED;
+        }
+
+        protected final void failed(CharSequence error) {
+            if (mState != STATE_RUNNING) {
+                throw new IllegalStateException("Not running.");
+            }
+            mState = STATE_FAILED;
+
+            mError = error;
+        }
+
+        public final boolean isFailed() {
+            return mState == STATE_FAILED;
+        }
+
+        public CharSequence getError() {
+            return mError;
+        }
+    }
+
+    private static final class LayoutCommand extends AsyncCommand {
+        private final PrintAttributes mOldAttributes = new PrintAttributes.Builder().build();
+        private final PrintAttributes mNewAttributes = new PrintAttributes.Builder().build();
+        private final Bundle mMetadata = new Bundle();
+
+        private final ILayoutResultCallback mRemoteResultCallback;
+
+        private final Handler mHandler;
+
+        private boolean mDocumentChanged;
+
+        public LayoutCommand(Looper looper, IPrintDocumentAdapter adapter,
+                RemotePrintDocumentInfo document, PrintAttributes oldAttributes,
+                PrintAttributes newAttributes, boolean preview, CommandDoneCallback callback) {
+            super(adapter, document, callback);
+            mHandler = new LayoutHandler(looper);
+            mRemoteResultCallback = new LayoutResultCallback(mHandler);
+            mOldAttributes.copyFrom(oldAttributes);
+            mNewAttributes.copyFrom(newAttributes);
+            mMetadata.putBoolean(PrintDocumentAdapter.EXTRA_PRINT_PREVIEW, preview);
+        }
+
+        public boolean isDocumentChanged() {
+            return mDocumentChanged;
+        }
+
+        @Override
+        public void run() {
+            running();
+
+            try {
+                if (DEBUG) {
+                    Log.i(LOG_TAG, "[PERFORMING] layout");
+                }
+                mAdapter.layout(mOldAttributes, mNewAttributes, mRemoteResultCallback,
+                        mMetadata, mSequence);
+            } catch (RemoteException re) {
+                Log.e(LOG_TAG, "Error calling layout", re);
+                handleOnLayoutFailed(null, mSequence);
+            }
+        }
+
+        private void handleOnLayoutStarted(ICancellationSignal cancellation, int sequence) {
+            if (sequence != mSequence) {
+                return;
+            }
+
+            if (DEBUG) {
+                Log.i(LOG_TAG, "[CALLBACK] onLayoutStarted");
+            }
+
+            if (isCanceling()) {
+                try {
+                    cancellation.cancel();
+                } catch (RemoteException re) {
+                    Log.e(LOG_TAG, "Error cancelling", re);
+                    handleOnLayoutFailed(null, mSequence);
+                }
+            } else {
+                mCancellation = cancellation;
+            }
+        }
+
+        private void handleOnLayoutFinished(PrintDocumentInfo info,
+                boolean changed, int sequence) {
+            if (sequence != mSequence) {
+                return;
+            }
+
+            if (DEBUG) {
+                Log.i(LOG_TAG, "[CALLBACK] onLayoutFinished");
+            }
+
+            completed();
+
+            // If the document description changed or the content in the
+            // document changed, the we need to invalidate the pages.
+            if (changed || !equalsIgnoreSize(mDocument.info, info)) {
+                // If the content changed we throw away all pages as
+                // we will request them again with the new content.
+                mDocument.writtenPages = null;
+                mDocument.printedPages = null;
+                mDocumentChanged = true;
+            }
+
+            // Update the document with data from the layout pass.
+            mDocument.attributes = mNewAttributes;
+            mDocument.metadata = mMetadata;
+            mDocument.info = info;
+
+            // Release the remote cancellation interface.
+            mCancellation = null;
+
+            // Done.
+            mDoneCallback.onDone();
+        }
+
+        private void handleOnLayoutFailed(CharSequence error, int sequence) {
+            if (sequence != mSequence) {
+                return;
+            }
+
+            if (DEBUG) {
+                Log.i(LOG_TAG, "[CALLBACK] onLayoutFailed");
+            }
+
+            failed(error);
+
+            // Release the remote cancellation interface.
+            mCancellation = null;
+
+            // Failed.
+            mDoneCallback.onDone();
+        }
+
+        private void handleOnLayoutCanceled(int sequence) {
+            if (sequence != mSequence) {
+                return;
+            }
+
+            if (DEBUG) {
+                Log.i(LOG_TAG, "[CALLBACK] onLayoutCanceled");
+            }
+
+            canceled();
+
+            // Release the remote cancellation interface.
+            mCancellation = null;
+
+            // Done.
+            mDoneCallback.onDone();
+        }
+
+        private boolean equalsIgnoreSize(PrintDocumentInfo lhs, PrintDocumentInfo rhs) {
+            if (lhs == rhs) {
+                return true;
+            }
+            if (lhs == null) {
+                return false;
+            } else {
+                if (rhs == null) {
+                    return false;
+                }
+                if (lhs.getContentType() != rhs.getContentType()
+                        || lhs.getPageCount() != rhs.getPageCount()) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        private final class LayoutHandler extends Handler {
+            public static final int MSG_ON_LAYOUT_STARTED = 1;
+            public static final int MSG_ON_LAYOUT_FINISHED = 2;
+            public static final int MSG_ON_LAYOUT_FAILED = 3;
+            public static final int MSG_ON_LAYOUT_CANCELED = 4;
+
+            public LayoutHandler(Looper looper) {
+                super(looper, null, false);
+            }
+
+            @Override
+            public void handleMessage(Message message) {
+                switch (message.what) {
+                    case MSG_ON_LAYOUT_STARTED: {
+                        ICancellationSignal cancellation = (ICancellationSignal) message.obj;
+                        final int sequence = message.arg1;
+                        handleOnLayoutStarted(cancellation, sequence);
+                    } break;
+
+                    case MSG_ON_LAYOUT_FINISHED: {
+                        PrintDocumentInfo info = (PrintDocumentInfo) message.obj;
+                        final boolean changed = (message.arg1 == 1);
+                        final int sequence = message.arg2;
+                        handleOnLayoutFinished(info, changed, sequence);
+                    } break;
+
+                    case MSG_ON_LAYOUT_FAILED: {
+                        CharSequence error = (CharSequence) message.obj;
+                        final int sequence = message.arg1;
+                        handleOnLayoutFailed(error, sequence);
+                    } break;
+
+                    case MSG_ON_LAYOUT_CANCELED: {
+                        final int sequence = message.arg1;
+                        handleOnLayoutCanceled(sequence);
+                    } break;
+                }
+            }
+        }
+
+        private static final class LayoutResultCallback extends ILayoutResultCallback.Stub {
+            private final WeakReference<Handler> mWeakHandler;
+
+            public LayoutResultCallback(Handler handler) {
+                mWeakHandler = new WeakReference<>(handler);
+            }
+
+            @Override
+            public void onLayoutStarted(ICancellationSignal cancellation, int sequence) {
+                Handler handler = mWeakHandler.get();
+                if (handler != null) {
+                    handler.obtainMessage(LayoutHandler.MSG_ON_LAYOUT_STARTED,
+                            sequence, 0, cancellation).sendToTarget();
+                }
+            }
+
+            @Override
+            public void onLayoutFinished(PrintDocumentInfo info, boolean changed, int sequence) {
+                Handler handler = mWeakHandler.get();
+                if (handler != null) {
+                    handler.obtainMessage(LayoutHandler.MSG_ON_LAYOUT_FINISHED,
+                            changed ? 1 : 0, sequence, info).sendToTarget();
+                }
+            }
+
+            @Override
+            public void onLayoutFailed(CharSequence error, int sequence) {
+                Handler handler = mWeakHandler.get();
+                if (handler != null) {
+                    handler.obtainMessage(LayoutHandler.MSG_ON_LAYOUT_FAILED,
+                            sequence, 0, error).sendToTarget();
+                }
+            }
+
+            @Override
+            public void onLayoutCanceled(int sequence) {
+                Handler handler = mWeakHandler.get();
+                if (handler != null) {
+                    handler.obtainMessage(LayoutHandler.MSG_ON_LAYOUT_CANCELED,
+                            sequence, 0).sendToTarget();
+                }
+            }
+        }
+    }
+
+    private static final class WriteCommand extends AsyncCommand {
+        private final int mPageCount;
+        private final PageRange[] mPages;
+        private final File mContentFile;
+
+        private final IWriteResultCallback mRemoteResultCallback;
+        private final CommandDoneCallback mDoneCallback;
+
+        private final Context mContext;
+        private final Handler mHandler;
+
+        public WriteCommand(Context context, Looper looper, IPrintDocumentAdapter adapter,
+                RemotePrintDocumentInfo document, int pageCount, PageRange[] pages,
+                File contentFile, CommandDoneCallback callback) {
+            super(adapter, document, callback);
+            mContext = context;
+            mHandler = new WriteHandler(looper);
+            mRemoteResultCallback = new WriteResultCallback(mHandler);
+            mPageCount = pageCount;
+            mPages = Arrays.copyOf(pages, pages.length);
+            mContentFile = contentFile;
+            mDoneCallback = callback;
+        }
+
+        @Override
+        public void run() {
+            running();
+
+            // This is a long running operation as we will be reading fully
+            // the written data. In case of a cancellation, we ask the client
+            // to stop writing data and close the file descriptor after
+            // which we will reach the end of the stream, thus stop reading.
+            new AsyncTask<Void, Void, Void>() {
+                @Override
+                protected Void doInBackground(Void... params) {
+                    InputStream in = null;
+                    OutputStream out = null;
+                    ParcelFileDescriptor source = null;
+                    ParcelFileDescriptor sink = null;
+                    try {
+                        ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
+                        source = pipe[0];
+                        sink = pipe[1];
+
+                        in = new FileInputStream(source.getFileDescriptor());
+                        out = new FileOutputStream(mContentFile);
+
+                        // Async call to initiate the other process writing the data.
+                        if (DEBUG) {
+                            Log.i(LOG_TAG, "[PERFORMING] write");
+                        }
+                        mAdapter.write(mPages, sink, mRemoteResultCallback, mSequence);
+
+                        // Close the source. It is now held by the client.
+                        sink.close();
+                        sink = null;
+
+                        // Read the data.
+                        final byte[] buffer = new byte[8192];
+                        while (true) {
+                            final int readByteCount = in.read(buffer);
+                            if (readByteCount < 0) {
+                                break;
+                            }
+                            out.write(buffer, 0, readByteCount);
+                        }
+                    } catch (RemoteException | IOException e) {
+                        Log.e(LOG_TAG, "Error calling write()", e);
+                    } finally {
+                        IoUtils.closeQuietly(in);
+                        IoUtils.closeQuietly(out);
+                        IoUtils.closeQuietly(sink);
+                        IoUtils.closeQuietly(source);
+                    }
+                    return null;
+                }
+            }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
+        }
+
+        private void handleOnWriteStarted(ICancellationSignal cancellation, int sequence) {
+            if (sequence != mSequence) {
+                return;
+            }
+
+            if (DEBUG) {
+                Log.i(LOG_TAG, "[CALLBACK] onWriteStarted");
+            }
+
+            if (isCanceling()) {
+                try {
+                    cancellation.cancel();
+                } catch (RemoteException re) {
+                    Log.e(LOG_TAG, "Error cancelling", re);
+                    handleOnWriteFailed(null, sequence);
+                }
+            } else {
+                mCancellation = cancellation;
+            }
+        }
+
+        private void handleOnWriteFinished(PageRange[] pages, int sequence) {
+            if (sequence != mSequence) {
+                return;
+            }
+
+            if (DEBUG) {
+                Log.i(LOG_TAG, "[CALLBACK] onWriteFinished");
+            }
+
+            PageRange[] writtenPages = PageRangeUtils.normalize(pages);
+            PageRange[] printedPages = computePrintedPages(mPages, writtenPages, mPageCount);
+
+            // Handle if we got invalid pages
+            if (printedPages != null) {
+                mDocument.writtenPages = writtenPages;
+                mDocument.printedPages = printedPages;
+                completed();
+            } else {
+                mDocument.writtenPages = null;
+                mDocument.printedPages = null;
+                failed(mContext.getString(R.string.print_error_default_message));
+            }
+
+            // Release the remote cancellation interface.
+            mCancellation = null;
+
+            // Done.
+            mDoneCallback.onDone();
+        }
+
+        private void handleOnWriteFailed(CharSequence error, int sequence) {
+            if (sequence != mSequence) {
+                return;
+            }
+
+            if (DEBUG) {
+                Log.i(LOG_TAG, "[CALLBACK] onWriteFailed");
+            }
+
+            failed(error);
+
+            // Release the remote cancellation interface.
+            mCancellation = null;
+
+            // Done.
+            mDoneCallback.onDone();
+        }
+
+        private void handleOnWriteCanceled(int sequence) {
+            if (sequence != mSequence) {
+                return;
+            }
+
+            if (DEBUG) {
+                Log.i(LOG_TAG, "[CALLBACK] onWriteCanceled");
+            }
+
+            canceled();
+
+            // Release the remote cancellation interface.
+            mCancellation = null;
+
+            // Done.
+            mDoneCallback.onDone();
+        }
+
+        private final class WriteHandler extends Handler {
+            public static final int MSG_ON_WRITE_STARTED = 1;
+            public static final int MSG_ON_WRITE_FINISHED = 2;
+            public static final int MSG_ON_WRITE_FAILED = 3;
+            public static final int MSG_ON_WRITE_CANCELED = 4;
+
+            public WriteHandler(Looper looper) {
+                super(looper, null, false);
+            }
+
+            @Override
+            public void handleMessage(Message message) {
+                switch (message.what) {
+                    case MSG_ON_WRITE_STARTED: {
+                        ICancellationSignal cancellation = (ICancellationSignal) message.obj;
+                        final int sequence = message.arg1;
+                        handleOnWriteStarted(cancellation, sequence);
+                    } break;
+
+                    case MSG_ON_WRITE_FINISHED: {
+                        PageRange[] pages = (PageRange[]) message.obj;
+                        final int sequence = message.arg1;
+                        handleOnWriteFinished(pages, sequence);
+                    } break;
+
+                    case MSG_ON_WRITE_FAILED: {
+                        CharSequence error = (CharSequence) message.obj;
+                        final int sequence = message.arg1;
+                        handleOnWriteFailed(error, sequence);
+                    } break;
+
+                    case MSG_ON_WRITE_CANCELED: {
+                        final int sequence = message.arg1;
+                        handleOnWriteCanceled(sequence);
+                    } break;
+                }
+            }
+        }
+
+        private static final class WriteResultCallback extends IWriteResultCallback.Stub {
+            private final WeakReference<Handler> mWeakHandler;
+
+            public WriteResultCallback(Handler handler) {
+                mWeakHandler = new WeakReference<>(handler);
+            }
+
+            @Override
+            public void onWriteStarted(ICancellationSignal cancellation, int sequence) {
+                Handler handler = mWeakHandler.get();
+                if (handler != null) {
+                    handler.obtainMessage(WriteHandler.MSG_ON_WRITE_STARTED,
+                            sequence, 0, cancellation).sendToTarget();
+                }
+            }
+
+            @Override
+            public void onWriteFinished(PageRange[] pages, int sequence) {
+                Handler handler = mWeakHandler.get();
+                if (handler != null) {
+                    handler.obtainMessage(WriteHandler.MSG_ON_WRITE_FINISHED,
+                            sequence, 0, pages).sendToTarget();
+                }
+            }
+
+            @Override
+            public void onWriteFailed(CharSequence error, int sequence) {
+                Handler handler = mWeakHandler.get();
+                if (handler != null) {
+                    handler.obtainMessage(WriteHandler.MSG_ON_WRITE_FAILED,
+                        sequence, 0, error).sendToTarget();
+                }
+            }
+
+            @Override
+            public void onWriteCanceled(int sequence) {
+                Handler handler = mWeakHandler.get();
+                if (handler != null) {
+                    handler.obtainMessage(WriteHandler.MSG_ON_WRITE_CANCELED,
+                        sequence, 0).sendToTarget();
+                }
+            }
+        }
+    }
+
+    private static final class PrintDocumentAdapterObserver
+            extends IPrintDocumentAdapterObserver.Stub {
+        private final WeakReference<RemotePrintDocument> mWeakDocument;
+
+        public PrintDocumentAdapterObserver(RemotePrintDocument document) {
+            mWeakDocument = new WeakReference<>(document);
+        }
+
+        @Override
+        public void onDestroy() {
+            final RemotePrintDocument document = mWeakDocument.get();
+            if (document != null) {
+                new Handler(document.mLooper).post(new Runnable() {
+                    @Override
+                    public void run() {
+                        document.mDocumentObserver.onDestroy();
+                    }
+                });
+            }
+        }
+    }
+}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/FusedPrintersProvider.java b/packages/PrintSpooler/src/com/android/printspooler/ui/FusedPrintersProvider.java
similarity index 98%
rename from packages/PrintSpooler/src/com/android/printspooler/FusedPrintersProvider.java
rename to packages/PrintSpooler/src/com/android/printspooler/ui/FusedPrintersProvider.java
index 9831839..d802cd8 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/FusedPrintersProvider.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/FusedPrintersProvider.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.printspooler;
+package com.android.printspooler.ui;
 
 import android.content.ComponentName;
 import android.content.Context;
@@ -57,7 +57,7 @@
  * This class is responsible for loading printers by doing discovery
  * and merging the discovered printers with the previously used ones.
  */
-public class FusedPrintersProvider extends Loader<List<PrinterInfo>> {
+public final class FusedPrintersProvider extends Loader<List<PrinterInfo>> {
     private static final String LOG_TAG = "FusedPrintersProvider";
 
     private static final boolean DEBUG = false;
@@ -192,7 +192,7 @@
             for (int i = 0; i < favoriteCount; i++) {
                 printerIds.add(mFavoritePrinters.get(i).getId());
             }
-            mDiscoverySession.startPrinterDisovery(printerIds);
+            mDiscoverySession.startPrinterDiscovery(printerIds);
             List<PrinterInfo> printers = mDiscoverySession.getPrinters();
             if (!printers.isEmpty()) {
                 updatePrinters(printers, mFavoritePrinters);
@@ -281,7 +281,9 @@
                 mDiscoverySession.stopPrinterStateTracking(mTrackedPrinter);
             }
             mTrackedPrinter = printerId;
-            mDiscoverySession.startPrinterStateTracking(printerId);
+            if (printerId != null) {
+                mDiscoverySession.startPrinterStateTracking(printerId);
+            }
         }
     }
 
@@ -514,7 +516,7 @@
             }
 
             private List<PrinterInfo> doReadPrinterHistory() {
-                FileInputStream in = null;
+                final FileInputStream in;
                 try {
                     in = mStatePersistFile.openRead();
                 } catch (FileNotFoundException fnfe) {
@@ -641,7 +643,7 @@
                 }
                 return true;
             }
-        };
+        }
 
         private final class WriteTask extends AsyncTask<List<PrinterInfo>, Void, Void> {
             @Override
@@ -703,6 +705,6 @@
                     IoUtils.closeQuietly(out);
                 }
             }
-        };
+        }
     }
 }
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
new file mode 100644
index 0000000..f71cafe
--- /dev/null
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
@@ -0,0 +1,1953 @@
+/*
+ * 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.printspooler.ui;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.app.FragmentTransaction;
+import android.content.ActivityNotFoundException;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ResolveInfo;
+import android.database.DataSetObserver;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.print.IPrintDocumentAdapter;
+import android.print.PageRange;
+import android.print.PrintAttributes;
+import android.print.PrintAttributes.MediaSize;
+import android.print.PrintAttributes.Resolution;
+import android.print.PrintDocumentInfo;
+import android.print.PrintJobInfo;
+import android.print.PrintManager;
+import android.print.PrinterCapabilitiesInfo;
+import android.print.PrinterId;
+import android.print.PrinterInfo;
+import android.printservice.PrintService;
+import android.provider.DocumentsContract;
+import android.text.Editable;
+import android.text.TextUtils;
+import android.text.TextUtils.SimpleStringSplitter;
+import android.text.TextWatcher;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.View.OnFocusChangeListener;
+import android.view.ViewGroup;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemSelectedListener;
+import android.widget.ArrayAdapter;
+import android.widget.BaseAdapter;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.Spinner;
+import android.widget.TextView;
+
+import com.android.printspooler.R;
+import com.android.printspooler.model.PrintSpoolerProvider;
+import com.android.printspooler.model.PrintSpoolerService;
+import com.android.printspooler.model.RemotePrintDocument;
+import com.android.printspooler.util.MediaSizeUtils;
+import com.android.printspooler.util.MediaSizeUtils.MediaSizeComparator;
+import com.android.printspooler.util.PageRangeUtils;
+import com.android.printspooler.util.PrintOptionUtils;
+import com.android.printspooler.widget.ContentView;
+import com.android.printspooler.widget.ContentView.OptionsStateChangeListener;
+
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class PrintActivity extends Activity implements RemotePrintDocument.UpdateResultCallbacks,
+        PrintErrorFragment.OnActionListener, PrintProgressFragment.OnCancelRequestListener {
+    private static final String LOG_TAG = "PrintActivity";
+
+    public static final String INTENT_EXTRA_PRINTER_ID = "INTENT_EXTRA_PRINTER_ID";
+
+    private static final int ORIENTATION_PORTRAIT = 0;
+    private static final int ORIENTATION_LANDSCAPE = 1;
+
+    private static final int ACTIVITY_REQUEST_CREATE_FILE = 1;
+    private static final int ACTIVITY_REQUEST_SELECT_PRINTER = 2;
+    private static final int ACTIVITY_REQUEST_POPULATE_ADVANCED_PRINT_OPTIONS = 3;
+
+    private static final int DEST_ADAPTER_MAX_ITEM_COUNT = 9;
+
+    private static final int DEST_ADAPTER_ITEM_ID_SAVE_AS_PDF = Integer.MAX_VALUE;
+    private static final int DEST_ADAPTER_ITEM_ID_ALL_PRINTERS = Integer.MAX_VALUE - 1;
+
+    private static final int STATE_CONFIGURING = 0;
+    private static final int STATE_PRINT_CONFIRMED = 1;
+    private static final int STATE_PRINT_CANCELED = 2;
+    private static final int STATE_UPDATE_FAILED = 3;
+    private static final int STATE_CREATE_FILE_FAILED = 4;
+    private static final int STATE_PRINTER_UNAVAILABLE = 5;
+
+    private static final int UI_STATE_PREVIEW = 0;
+    private static final int UI_STATE_ERROR = 1;
+    private static final int UI_STATE_PROGRESS = 2;
+
+    private static final int MIN_COPIES = 1;
+    private static final String MIN_COPIES_STRING = String.valueOf(MIN_COPIES);
+
+    private static final Pattern PATTERN_DIGITS = Pattern.compile("[\\d]+");
+
+    private static final Pattern PATTERN_ESCAPE_SPECIAL_CHARS = Pattern.compile(
+            "(?=[]\\[+&|!(){}^\"~*?:\\\\])");
+
+    private static final Pattern PATTERN_PAGE_RANGE = Pattern.compile(
+            "[\\s]*[0-9]*[\\s]*[\\-]?[\\s]*[0-9]*[\\s]*?(([,])"
+            + "[\\s]*[0-9]*[\\s]*[\\-]?[\\s]*[0-9]*[\\s]*|[\\s]*)+");
+
+    public static final PageRange[] ALL_PAGES_ARRAY = new PageRange[] {PageRange.ALL_PAGES};
+
+    private final PrinterAvailabilityDetector mPrinterAvailabilityDetector =
+            new PrinterAvailabilityDetector();
+
+    private final SimpleStringSplitter mStringCommaSplitter = new SimpleStringSplitter(',');
+
+    private final OnFocusChangeListener mSelectAllOnFocusListener = new SelectAllOnFocusListener();
+
+    private PrintSpoolerProvider mSpoolerProvider;
+
+    private PrintJobInfo mPrintJob;
+    private RemotePrintDocument mPrintedDocument;
+    private PrinterRegistry mPrinterRegistry;
+
+    private EditText mCopiesEditText;
+
+    private TextView mPageRangeOptionsTitle;
+    private TextView mPageRangeTitle;
+    private EditText mPageRangeEditText;
+
+    private Spinner mDestinationSpinner;
+    private DestinationAdapter mDestinationSpinnerAdapter;
+
+    private Spinner mMediaSizeSpinner;
+    private ArrayAdapter<SpinnerItem<MediaSize>> mMediaSizeSpinnerAdapter;
+
+    private Spinner mColorModeSpinner;
+    private ArrayAdapter<SpinnerItem<Integer>> mColorModeSpinnerAdapter;
+
+    private Spinner mOrientationSpinner;
+    private ArrayAdapter<SpinnerItem<Integer>> mOrientationSpinnerAdapter;
+
+    private Spinner mRangeOptionsSpinner;
+
+    private ContentView mOptionsContent;
+
+    private TextView mSummaryCopies;
+    private TextView mSummaryPaperSize;
+
+    private View mAdvancedPrintOptionsContainer;
+
+    private Button mMoreOptionsButton;
+
+    private ImageView mPrintButton;
+
+    private ProgressMessageController mProgressMessageController;
+
+    private MediaSizeComparator mMediaSizeComparator;
+
+    private PageRange[] mRequestedPages;
+
+    private PrinterInfo mOldCurrentPrinter;
+
+    private String mCallingPackageName;
+
+    private int mState = STATE_CONFIGURING;
+
+    private int mUiState = UI_STATE_PREVIEW;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        Bundle extras = getIntent().getExtras();
+
+        mPrintJob = extras.getParcelable(PrintManager.EXTRA_PRINT_JOB);
+        if (mPrintJob == null) {
+            throw new IllegalArgumentException(PrintManager.EXTRA_PRINT_JOB
+                    + " cannot be null");
+        }
+        mPrintJob.setAttributes(new PrintAttributes.Builder().build());
+
+        final IBinder adapter = extras.getBinder(PrintManager.EXTRA_PRINT_DOCUMENT_ADAPTER);
+        if (adapter == null) {
+            throw new IllegalArgumentException(PrintManager.EXTRA_PRINT_DOCUMENT_ADAPTER
+                    + " cannot be null");
+        }
+
+        mCallingPackageName = extras.getString(DocumentsContract.EXTRA_PACKAGE_NAME);
+
+        // This will take just a few milliseconds, so just wait to
+        // bind to the local service before showing the UI.
+        mSpoolerProvider = new PrintSpoolerProvider(this,
+                new Runnable() {
+            @Override
+            public void run() {
+                // Now that we are bound to the print spooler service,
+                // create the printer registry and wait for it to get
+                // the first batch of results which will be delivered
+                // after reading historical data. This should be pretty
+                // fast, so just wait before showing the UI.
+                mPrinterRegistry = new PrinterRegistry(PrintActivity.this,
+                        new Runnable() {
+                    @Override
+                    public void run() {
+                        setTitle(R.string.print_dialog);
+                        setContentView(R.layout.print_activity);
+
+                        mPrintedDocument = new RemotePrintDocument(PrintActivity.this,
+                                IPrintDocumentAdapter.Stub.asInterface(adapter),
+                                PrintSpoolerService.generateFileForPrintJob(PrintActivity.this,
+                                        mPrintJob.getId()),
+                                new RemotePrintDocument.DocumentObserver() {
+                                    @Override
+                                    public void onDestroy() {
+                                        finish();
+                                    }
+                                }, PrintActivity.this);
+
+                        mProgressMessageController = new ProgressMessageController(PrintActivity.this);
+
+                        mMediaSizeComparator = new MediaSizeComparator(PrintActivity.this);
+
+                        mDestinationSpinnerAdapter = new DestinationAdapter();
+
+                        bindUi();
+
+                        updateOptionsUi();
+
+                        // Now show the updated UI to avoid flicker.
+                        mOptionsContent.setVisibility(View.VISIBLE);
+
+                        mRequestedPages = computeRequestedPages();
+
+                        mPrintedDocument.start();
+
+                        ensurePreviewUiShown();
+                    }
+                });
+            }
+        });
+    }
+
+    @Override
+    public void onPause() {
+        if (isFinishing()) {
+            PrintSpoolerService spooler = mSpoolerProvider.getSpooler();
+            if (mState == STATE_PRINT_CONFIRMED) {
+                spooler.updatePrintJobUserConfigurableOptionsNoPersistence(mPrintJob);
+                spooler.setPrintJobState(mPrintJob.getId(), PrintJobInfo.STATE_QUEUED, null);
+            } else {
+                spooler.setPrintJobState(mPrintJob.getId(), PrintJobInfo.STATE_CANCELED, null);
+            }
+            mProgressMessageController.cancel();
+            mPrinterRegistry.setTrackedPrinter(null);
+            mSpoolerProvider.destroy();
+            mPrintedDocument.finish();
+            mPrintedDocument.destroy();
+        }
+
+        mPrinterAvailabilityDetector.cancel();
+
+        super.onPause();
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        if (keyCode == KeyEvent.KEYCODE_BACK) {
+            event.startTracking();
+            return true;
+        }
+        return super.onKeyDown(keyCode, event);
+    }
+
+    @Override
+    public boolean onKeyUp(int keyCode, KeyEvent event) {
+        if (keyCode == KeyEvent.KEYCODE_BACK
+                && event.isTracking() && !event.isCanceled()) {
+            cancelPrint();
+            return true;
+        }
+        return super.onKeyUp(keyCode, event);
+    }
+
+    @Override
+    public void onActionPerformed() {
+        switch (mState) {
+            case STATE_UPDATE_FAILED: {
+                if (canUpdateDocument()) {
+                    updateDocument(true, true);
+                    ensurePreviewUiShown();
+                    mState = STATE_CONFIGURING;
+                    updateOptionsUi();
+                }
+            } break;
+
+            case STATE_CREATE_FILE_FAILED: {
+                mState = STATE_CONFIGURING;
+                ensurePreviewUiShown();
+                updateOptionsUi();
+            } break;
+        }
+    }
+
+    @Override
+    public void onCancelRequest() {
+        if (mPrintedDocument.isUpdating()) {
+            mPrintedDocument.cancel();
+        }
+    }
+
+    public void onUpdateCanceled() {
+        mProgressMessageController.cancel();
+        ensurePreviewUiShown();
+        finishIfConfirmedOrCanceled();
+        updateOptionsUi();
+    }
+
+    @Override
+    public void onUpdateCompleted(RemotePrintDocument.RemotePrintDocumentInfo document) {
+        mProgressMessageController.cancel();
+        ensurePreviewUiShown();
+
+        // Update the print job with the info for the written document. The page
+        // count we get from the remote document is the pages in the document from
+        // the app perspective but the print job should contain the page count from
+        // print service perspective which is the pages in the written PDF not the
+        // pages in the printed document.
+        PrintDocumentInfo info = document.info;
+        if (info == null) {
+            return;
+        }
+        final int pageCount = PageRangeUtils.getNormalizedPageCount(document.writtenPages,
+                info.getPageCount());
+        PrintDocumentInfo adjustedInfo = new PrintDocumentInfo.Builder(info.getName())
+                .setContentType(info.getContentType())
+                .setPageCount(pageCount)
+                .build();
+        mPrintJob.setDocumentInfo(adjustedInfo);
+        mPrintJob.setPages(document.printedPages);
+        finishIfConfirmedOrCanceled();
+        updateOptionsUi();
+    }
+
+    @Override
+    public void onUpdateFailed(CharSequence error) {
+        mState = STATE_UPDATE_FAILED;
+        ensureErrorUiShown(error, PrintErrorFragment.ACTION_RETRY);
+        updateOptionsUi();
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        switch (requestCode) {
+            case ACTIVITY_REQUEST_CREATE_FILE: {
+                onStartCreateDocumentActivityResult(resultCode, data);
+            } break;
+
+            case ACTIVITY_REQUEST_SELECT_PRINTER: {
+                onSelectPrinterActivityResult(resultCode, data);
+            } break;
+
+            case ACTIVITY_REQUEST_POPULATE_ADVANCED_PRINT_OPTIONS: {
+                onAdvancedPrintOptionsActivityResult(resultCode, data);
+            } break;
+        }
+    }
+
+    private void startCreateDocumentActivity() {
+        PrintDocumentInfo info = mPrintedDocument.getDocumentInfo().info;
+        if (info == null) {
+            return;
+        }
+        Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
+        intent.setType("application/pdf");
+        intent.putExtra(Intent.EXTRA_TITLE, info.getName());
+        intent.putExtra(DocumentsContract.EXTRA_PACKAGE_NAME, mCallingPackageName);
+        startActivityForResult(intent, ACTIVITY_REQUEST_CREATE_FILE);
+    }
+
+    private void onStartCreateDocumentActivityResult(int resultCode, Intent data) {
+        if (resultCode == RESULT_OK && data != null) {
+            Uri uri = data.getData();
+            mPrintedDocument.writeContent(getContentResolver(), uri);
+            finish();
+        } else if (resultCode == RESULT_CANCELED) {
+            mState = STATE_CONFIGURING;
+            updateOptionsUi();
+        } else {
+            ensureErrorUiShown(getString(R.string.print_write_error_message),
+                    PrintErrorFragment.ACTION_CONFIRM);
+            mState = STATE_CREATE_FILE_FAILED;
+            updateOptionsUi();
+        }
+    }
+
+    private void startSelectPrinterActivity() {
+        Intent intent = new Intent(this, SelectPrinterActivity.class);
+        startActivityForResult(intent, ACTIVITY_REQUEST_SELECT_PRINTER);
+    }
+
+    private void onSelectPrinterActivityResult(int resultCode, Intent data) {
+        if (resultCode == RESULT_OK && data != null) {
+            PrinterId printerId = data.getParcelableExtra(INTENT_EXTRA_PRINTER_ID);
+            if (printerId != null) {
+                mDestinationSpinnerAdapter.ensurePrinterInVisibleAdapterPosition(printerId);
+                final int index = mDestinationSpinnerAdapter.getPrinterIndex(printerId);
+                if (index != AdapterView.INVALID_POSITION) {
+                    mDestinationSpinner.setSelection(index);
+                    return;
+                }
+            }
+        }
+
+        PrinterId printerId = mOldCurrentPrinter.getId();
+        final int index = mDestinationSpinnerAdapter.getPrinterIndex(printerId);
+        mDestinationSpinner.setSelection(index);
+    }
+
+    private void startAdvancedPrintOptionsActivity(PrinterInfo printer) {
+        ComponentName serviceName = printer.getId().getServiceName();
+
+        String activityName = PrintOptionUtils.getAdvancedOptionsActivityName(this, serviceName);
+        if (TextUtils.isEmpty(activityName)) {
+            return;
+        }
+
+        Intent intent = new Intent(Intent.ACTION_MAIN);
+        intent.setComponent(new ComponentName(serviceName.getPackageName(), activityName));
+
+        List<ResolveInfo> resolvedActivities = getPackageManager()
+                .queryIntentActivities(intent, 0);
+        if (resolvedActivities.isEmpty()) {
+            return;
+        }
+
+        // The activity is a component name, therefore it is one or none.
+        if (resolvedActivities.get(0).activityInfo.exported) {
+            intent.putExtra(PrintService.EXTRA_PRINT_JOB_INFO, mPrintJob);
+            intent.putExtra(PrintService.EXTRA_PRINTER_INFO, printer);
+
+            // This is external activity and may not be there.
+            try {
+                startActivityForResult(intent, ACTIVITY_REQUEST_POPULATE_ADVANCED_PRINT_OPTIONS);
+            } catch (ActivityNotFoundException anfe) {
+                Log.e(LOG_TAG, "Error starting activity for intent: " + intent, anfe);
+            }
+        }
+    }
+
+    private void onAdvancedPrintOptionsActivityResult(int resultCode, Intent data) {
+        if (resultCode != RESULT_OK || data == null) {
+            return;
+        }
+
+        PrintJobInfo printJobInfo = data.getParcelableExtra(PrintService.EXTRA_PRINT_JOB_INFO);
+
+        if (printJobInfo == null) {
+            return;
+        }
+
+        // Take the advanced options without interpretation.
+        mPrintJob.setAdvancedOptions(printJobInfo.getAdvancedOptions());
+
+        // Take copies without interpretation as the advanced print dialog
+        // cannot create a print job info with invalid copies.
+        mCopiesEditText.setText(String.valueOf(printJobInfo.getCopies()));
+        mPrintJob.setCopies(printJobInfo.getCopies());
+
+        PrintAttributes currAttributes = mPrintJob.getAttributes();
+        PrintAttributes newAttributes = printJobInfo.getAttributes();
+
+        // Take the media size only if the current printer supports is.
+        MediaSize oldMediaSize = currAttributes.getMediaSize();
+        MediaSize newMediaSize = newAttributes.getMediaSize();
+        if (!oldMediaSize.equals(newMediaSize)) {
+            final int mediaSizeCount = mMediaSizeSpinnerAdapter.getCount();
+            MediaSize newMediaSizePortrait = newAttributes.getMediaSize().asPortrait();
+            for (int i = 0; i < mediaSizeCount; i++) {
+                MediaSize supportedSizePortrait = mMediaSizeSpinnerAdapter.getItem(i).value.asPortrait();
+                if (supportedSizePortrait.equals(newMediaSizePortrait)) {
+                    currAttributes.setMediaSize(newMediaSize);
+                    mMediaSizeSpinner.setSelection(i);
+                    if (currAttributes.getMediaSize().isPortrait()) {
+                        if (mOrientationSpinner.getSelectedItemPosition() != 0) {
+                            mOrientationSpinner.setSelection(0);
+                        }
+                    } else {
+                        if (mOrientationSpinner.getSelectedItemPosition() != 1) {
+                            mOrientationSpinner.setSelection(1);
+                        }
+                    }
+                    break;
+                }
+            }
+        }
+
+        // Take the color mode only if the current printer supports it.
+        final int currColorMode = currAttributes.getColorMode();
+        final int newColorMode = newAttributes.getColorMode();
+        if (currColorMode != newColorMode) {
+            final int colorModeCount = mColorModeSpinner.getCount();
+            for (int i = 0; i < colorModeCount; i++) {
+                final int supportedColorMode = mColorModeSpinnerAdapter.getItem(i).value;
+                if (supportedColorMode == newColorMode) {
+                    currAttributes.setColorMode(newColorMode);
+                    mColorModeSpinner.setSelection(i);
+                    break;
+                }
+            }
+        }
+
+        // Take the page range only if it is valid.
+        PageRange[] pageRanges = printJobInfo.getPages();
+        if (pageRanges != null && pageRanges.length > 0) {
+            pageRanges = PageRangeUtils.normalize(pageRanges);
+
+            PrintDocumentInfo info = mPrintedDocument.getDocumentInfo().info;
+            final int pageCount = (info != null) ? info.getPageCount() : 0;
+
+            // Handle the case where all pages are specified explicitly
+            // instead of the *all pages* constant.
+            if (pageRanges.length == 1) {
+                if (pageRanges[0].getStart() == 0 && pageRanges[0].getEnd() == pageCount - 1) {
+                    pageRanges[0] = PageRange.ALL_PAGES;
+                }
+            }
+
+            if (Arrays.equals(pageRanges, ALL_PAGES_ARRAY)) {
+                mPrintJob.setPages(pageRanges);
+
+                if (mRangeOptionsSpinner.getSelectedItemPosition() != 0) {
+                    mRangeOptionsSpinner.setSelection(0);
+                }
+            } else if (pageRanges[0].getStart() >= 0
+                    && pageRanges[pageRanges.length - 1].getEnd() < pageCount) {
+                mPrintJob.setPages(pageRanges);
+
+                if (mRangeOptionsSpinner.getSelectedItemPosition() != 1) {
+                    mRangeOptionsSpinner.setSelection(1);
+                }
+
+                StringBuilder builder = new StringBuilder();
+                final int pageRangeCount = pageRanges.length;
+                for (int i = 0; i < pageRangeCount; i++) {
+                    if (builder.length() > 0) {
+                         builder.append(',');
+                    }
+
+                    final int shownStartPage;
+                    final int shownEndPage;
+                    PageRange pageRange = pageRanges[i];
+                    if (pageRange.equals(PageRange.ALL_PAGES)) {
+                        shownStartPage = 1;
+                        shownEndPage = pageCount;
+                    } else {
+                        shownStartPage = pageRange.getStart() + 1;
+                        shownEndPage = pageRange.getEnd() + 1;
+                    }
+
+                    builder.append(shownStartPage);
+
+                    if (shownStartPage != shownEndPage) {
+                        builder.append('-');
+                        builder.append(shownEndPage);
+                    }
+                }
+                mPageRangeEditText.setText(builder.toString());
+            }
+        }
+
+        // Update the content if needed.
+        if (canUpdateDocument()) {
+            updateDocument(true, false);
+        }
+    }
+
+    private void ensureProgressUiShown() {
+        if (mUiState != UI_STATE_PROGRESS) {
+            mUiState = UI_STATE_PROGRESS;
+            Fragment fragment = PrintProgressFragment.newInstance();
+            showFragment(fragment);
+        }
+    }
+
+    private void ensurePreviewUiShown() {
+        if (mUiState != UI_STATE_PREVIEW) {
+            mUiState = UI_STATE_PREVIEW;
+            Fragment fragment = PrintPreviewFragment.newInstance();
+            showFragment(fragment);
+        }
+    }
+
+    private void ensureErrorUiShown(CharSequence message, int action) {
+        if (mUiState != UI_STATE_ERROR) {
+            mUiState = UI_STATE_ERROR;
+            Fragment fragment = PrintErrorFragment.newInstance(message, action);
+            showFragment(fragment);
+        }
+    }
+
+    private void showFragment(Fragment fragment) {
+        FragmentTransaction transaction = getFragmentManager().beginTransaction();
+        Fragment oldFragment = getFragmentManager().findFragmentById(
+                R.id.embedded_content_container);
+        if (oldFragment != null) {
+            transaction.remove(oldFragment);
+        }
+        transaction.add(R.id.embedded_content_container, fragment);
+        transaction.commit();
+    }
+
+    private void requestCreatePdfFileOrFinish() {
+        if (getCurrentPrinter() == mDestinationSpinnerAdapter.getPdfPrinter()) {
+            startCreateDocumentActivity();
+        } else {
+            finish();
+        }
+    }
+
+    private void finishIfConfirmedOrCanceled() {
+        if (mState == STATE_PRINT_CONFIRMED) {
+            requestCreatePdfFileOrFinish();
+        } else if (mState == STATE_PRINT_CANCELED) {
+            finish();
+        }
+    }
+
+    private void updatePrintAttributesFromCapabilities(PrinterCapabilitiesInfo capabilities) {
+        PrintAttributes defaults = capabilities.getDefaults();
+
+        // Sort the media sizes based on the current locale.
+        List<MediaSize> sortedMediaSizes = new ArrayList<>(capabilities.getMediaSizes());
+        Collections.sort(sortedMediaSizes, mMediaSizeComparator);
+
+        PrintAttributes attributes = mPrintJob.getAttributes();
+
+        // Media size.
+        MediaSize currMediaSize = attributes.getMediaSize();
+        if (currMediaSize == null) {
+            attributes.setMediaSize(defaults.getMediaSize());
+        } else {
+            boolean foundCurrentMediaSize = false;
+            // Try to find the current media size in the capabilities as
+            // it may be in a different orientation.
+            MediaSize currMediaSizePortrait = currMediaSize.asPortrait();
+            final int mediaSizeCount = sortedMediaSizes.size();
+            for (int i = 0; i < mediaSizeCount; i++) {
+                MediaSize mediaSize = sortedMediaSizes.get(i);
+                if (currMediaSizePortrait.equals(mediaSize.asPortrait())) {
+                    attributes.setMediaSize(currMediaSize);
+                    foundCurrentMediaSize = true;
+                    break;
+                }
+            }
+            // If we did not find the current media size fall back to default.
+            if (!foundCurrentMediaSize) {
+                attributes.setMediaSize(defaults.getMediaSize());
+            }
+        }
+
+        // Color mode.
+        final int colorMode = attributes.getColorMode();
+        if ((capabilities.getColorModes() & colorMode) == 0) {
+            attributes.setColorMode(defaults.getColorMode());
+        }
+
+        // Resolution
+        Resolution resolution = attributes.getResolution();
+        if (resolution == null || !capabilities.getResolutions().contains(resolution)) {
+            attributes.setResolution(defaults.getResolution());
+        }
+
+        // Margins.
+        attributes.setMinMargins(defaults.getMinMargins());
+    }
+
+    private boolean updateDocument(boolean preview, boolean clearLastError) {
+        if (!clearLastError && mPrintedDocument.hasUpdateError()) {
+            return false;
+        }
+
+        if (clearLastError && mPrintedDocument.hasUpdateError()) {
+            mPrintedDocument.clearUpdateError();
+        }
+
+        if (mRequestedPages != null && mRequestedPages.length > 0) {
+            final PageRange[] pages;
+            if (preview) {
+                final int firstPage = mRequestedPages[0].getStart();
+                pages = new PageRange[]{new PageRange(firstPage, firstPage)};
+            } else {
+                pages = mRequestedPages;
+            }
+            final boolean willUpdate = mPrintedDocument.update(mPrintJob.getAttributes(),
+                    pages, preview);
+
+            if (willUpdate) {
+                mProgressMessageController.post();
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    private void addCurrentPrinterToHistory() {
+        PrinterInfo currentPrinter = getCurrentPrinter();
+        if (currentPrinter != null) {
+            PrinterId fakePdfPrinterId = mDestinationSpinnerAdapter.getPdfPrinter().getId();
+            if (!currentPrinter.getId().equals(fakePdfPrinterId)) {
+                mPrinterRegistry.addHistoricalPrinter(currentPrinter);
+            }
+        }
+    }
+
+    private PrinterInfo getCurrentPrinter() {
+        return ((PrinterHolder) mDestinationSpinner.getSelectedItem()).printer;
+    }
+
+    private void cancelPrint() {
+        mState = STATE_PRINT_CANCELED;
+        updateOptionsUi();
+        if (mPrintedDocument.isUpdating()) {
+            mPrintedDocument.cancel();
+        }
+        finish();
+    }
+
+    private void confirmPrint() {
+        mState = STATE_PRINT_CONFIRMED;
+        updateOptionsUi();
+        if (canUpdateDocument()) {
+            updateDocument(false, false);
+        }
+        addCurrentPrinterToHistory();
+        if (!mPrintedDocument.isUpdating()) {
+            requestCreatePdfFileOrFinish();
+        }
+    }
+
+    private void bindUi() {
+        // Summary
+        mSummaryCopies = (TextView) findViewById(R.id.copies_count_summary);
+        mSummaryPaperSize = (TextView) findViewById(R.id.paper_size_summary);
+
+        // Options container
+        mOptionsContent = (ContentView) findViewById(R.id.options_content);
+        mOptionsContent.setOptionsStateChangeListener(new OptionsStateChangeListener() {
+            @Override
+            public void onOptionsOpened() {
+                // TODO: Update preview.
+            }
+
+            @Override
+            public void onOptionsClosed() {
+                // TODO: Update preview.
+            }
+        });
+
+        OnItemSelectedListener itemSelectedListener = new MyOnItemSelectedListener();
+        OnClickListener clickListener = new MyClickListener();
+
+        // Copies
+        mCopiesEditText = (EditText) findViewById(R.id.copies_edittext);
+        mCopiesEditText.setOnFocusChangeListener(mSelectAllOnFocusListener);
+        mCopiesEditText.setText(MIN_COPIES_STRING);
+        mCopiesEditText.setSelection(mCopiesEditText.getText().length());
+        mCopiesEditText.addTextChangedListener(new EditTextWatcher());
+
+        // Destination.
+        mDestinationSpinnerAdapter.registerDataSetObserver(new PrintersObserver());
+        mDestinationSpinner = (Spinner) findViewById(R.id.destination_spinner);
+        mDestinationSpinner.setAdapter(mDestinationSpinnerAdapter);
+        mDestinationSpinner.setOnItemSelectedListener(itemSelectedListener);
+        mDestinationSpinner.setSelection(0);
+
+        // Media size.
+        mMediaSizeSpinnerAdapter = new ArrayAdapter<>(
+                this, R.layout.spinner_dropdown_item, R.id.title);
+        mMediaSizeSpinner = (Spinner) findViewById(R.id.paper_size_spinner);
+        mMediaSizeSpinner.setAdapter(mMediaSizeSpinnerAdapter);
+        mMediaSizeSpinner.setOnItemSelectedListener(itemSelectedListener);
+
+        // Color mode.
+        mColorModeSpinnerAdapter = new ArrayAdapter<>(
+                this, R.layout.spinner_dropdown_item, R.id.title);
+        mColorModeSpinner = (Spinner) findViewById(R.id.color_spinner);
+        mColorModeSpinner.setAdapter(mColorModeSpinnerAdapter);
+        mColorModeSpinner.setOnItemSelectedListener(itemSelectedListener);
+
+        // Orientation
+        mOrientationSpinnerAdapter = new ArrayAdapter<>(
+                this, R.layout.spinner_dropdown_item, R.id.title);
+        String[] orientationLabels = getResources().getStringArray(
+              R.array.orientation_labels);
+        mOrientationSpinnerAdapter.add(new SpinnerItem<>(
+                ORIENTATION_PORTRAIT, orientationLabels[0]));
+        mOrientationSpinnerAdapter.add(new SpinnerItem<>(
+                ORIENTATION_LANDSCAPE, orientationLabels[1]));
+        mOrientationSpinner = (Spinner) findViewById(R.id.orientation_spinner);
+        mOrientationSpinner.setAdapter(mOrientationSpinnerAdapter);
+        mOrientationSpinner.setOnItemSelectedListener(itemSelectedListener);
+
+        // Range options
+        ArrayAdapter<SpinnerItem<Integer>> rangeOptionsSpinnerAdapter =
+                new ArrayAdapter<>(this, R.layout.spinner_dropdown_item, R.id.title);
+        final int[] rangeOptionsValues = getResources().getIntArray(
+                R.array.page_options_values);
+        String[] rangeOptionsLabels = getResources().getStringArray(
+                R.array.page_options_labels);
+        final int rangeOptionsCount = rangeOptionsLabels.length;
+        for (int i = 0; i < rangeOptionsCount; i++) {
+            rangeOptionsSpinnerAdapter.add(new SpinnerItem<>(
+                    rangeOptionsValues[i], rangeOptionsLabels[i]));
+        }
+        mPageRangeOptionsTitle = (TextView) findViewById(R.id.range_options_title);
+        mRangeOptionsSpinner = (Spinner) findViewById(R.id.range_options_spinner);
+        mRangeOptionsSpinner.setAdapter(rangeOptionsSpinnerAdapter);
+        mRangeOptionsSpinner.setOnItemSelectedListener(itemSelectedListener);
+
+        // Page range
+        mPageRangeTitle = (TextView) findViewById(R.id.page_range_title);
+        mPageRangeEditText = (EditText) findViewById(R.id.page_range_edittext);
+        mPageRangeEditText.setOnFocusChangeListener(mSelectAllOnFocusListener);
+        mPageRangeEditText.addTextChangedListener(new RangeTextWatcher());
+
+        // Advanced options button.
+        mAdvancedPrintOptionsContainer = findViewById(R.id.more_options_container);
+        mMoreOptionsButton = (Button) findViewById(R.id.more_options_button);
+        mMoreOptionsButton.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                PrinterInfo currentPrinter = getCurrentPrinter();
+                if (currentPrinter != null) {
+                    startAdvancedPrintOptionsActivity(currentPrinter);
+                }
+            }
+        });
+
+        // Print button
+        mPrintButton = (ImageView) findViewById(R.id.print_button);
+        mPrintButton.setOnClickListener(clickListener);
+    }
+
+    private final class MyClickListener implements OnClickListener {
+        @Override
+        public void onClick(View view) {
+            if (view == mPrintButton) {
+                PrinterInfo currentPrinter = getCurrentPrinter();
+                if (currentPrinter != null) {
+                    confirmPrint();
+                } else {
+                    cancelPrint();
+                }
+            } else if (view == mMoreOptionsButton) {
+                PrinterInfo currentPrinter = getCurrentPrinter();
+                if (currentPrinter != null) {
+                    startAdvancedPrintOptionsActivity(currentPrinter);
+                }
+            }
+        }
+    }
+
+    private static boolean canPrint(PrinterInfo printer) {
+        return printer.getCapabilities() != null
+                && printer.getStatus() != PrinterInfo.STATUS_UNAVAILABLE;
+    }
+
+    private void updateOptionsUi() {
+        // Always update the summary.
+        if (!TextUtils.isEmpty(mCopiesEditText.getText())) {
+            mSummaryCopies.setText(mCopiesEditText.getText());
+        }
+
+        final int selectedMediaIndex = mMediaSizeSpinner.getSelectedItemPosition();
+        if (selectedMediaIndex >= 0) {
+            SpinnerItem<MediaSize> mediaItem = mMediaSizeSpinnerAdapter.getItem(selectedMediaIndex);
+            mSummaryPaperSize.setText(mediaItem.label);
+        }
+
+        if (mState == STATE_PRINT_CONFIRMED
+                || mState == STATE_PRINT_CANCELED
+                || mState == STATE_UPDATE_FAILED
+                || mState == STATE_CREATE_FILE_FAILED
+                || mState == STATE_PRINTER_UNAVAILABLE) {
+            if (mState != STATE_PRINTER_UNAVAILABLE) {
+                mDestinationSpinner.setEnabled(false);
+            }
+            mCopiesEditText.setEnabled(false);
+            mMediaSizeSpinner.setEnabled(false);
+            mColorModeSpinner.setEnabled(false);
+            mOrientationSpinner.setEnabled(false);
+            mRangeOptionsSpinner.setEnabled(false);
+            mPageRangeEditText.setEnabled(false);
+            mPrintButton.setEnabled(false);
+            mMoreOptionsButton.setEnabled(false);
+            return;
+        }
+
+        // If no current printer, or it has no capabilities, or it is not
+        // available, we disable all print options except the destination.
+        PrinterInfo currentPrinter =  getCurrentPrinter();
+        if (currentPrinter == null || !canPrint(currentPrinter)) {
+            mCopiesEditText.setEnabled(false);
+            mMediaSizeSpinner.setEnabled(false);
+            mColorModeSpinner.setEnabled(false);
+            mOrientationSpinner.setEnabled(false);
+            mRangeOptionsSpinner.setEnabled(false);
+            mPageRangeEditText.setEnabled(false);
+            mPrintButton.setEnabled(false);
+            mMoreOptionsButton.setEnabled(false);
+            return;
+        }
+
+        PrinterCapabilitiesInfo capabilities = currentPrinter.getCapabilities();
+        PrintAttributes defaultAttributes = capabilities.getDefaults();
+
+        // Media size.
+        mMediaSizeSpinner.setEnabled(true);
+
+        List<MediaSize> mediaSizes = new ArrayList<>(capabilities.getMediaSizes());
+        // Sort the media sizes based on the current locale.
+        Collections.sort(mediaSizes, mMediaSizeComparator);
+
+        PrintAttributes attributes = mPrintJob.getAttributes();
+
+        // If the media sizes changed, we update the adapter and the spinner.
+        boolean mediaSizesChanged = false;
+        final int mediaSizeCount = mediaSizes.size();
+        if (mediaSizeCount != mMediaSizeSpinnerAdapter.getCount()) {
+            mediaSizesChanged = true;
+        } else {
+            for (int i = 0; i < mediaSizeCount; i++) {
+                if (!mediaSizes.get(i).equals(mMediaSizeSpinnerAdapter.getItem(i).value)) {
+                    mediaSizesChanged = true;
+                    break;
+                }
+            }
+        }
+        if (mediaSizesChanged) {
+            // Remember the old media size to try selecting it again.
+            int oldMediaSizeNewIndex = AdapterView.INVALID_POSITION;
+            MediaSize oldMediaSize = attributes.getMediaSize();
+
+            // Rebuild the adapter data.
+            mMediaSizeSpinnerAdapter.clear();
+            for (int i = 0; i < mediaSizeCount; i++) {
+                MediaSize mediaSize = mediaSizes.get(i);
+                if (oldMediaSize != null
+                        && mediaSize.asPortrait().equals(oldMediaSize.asPortrait())) {
+                    // Update the index of the old selection.
+                    oldMediaSizeNewIndex = i;
+                }
+                mMediaSizeSpinnerAdapter.add(new SpinnerItem<>(
+                        mediaSize, mediaSize.getLabel(getPackageManager())));
+            }
+
+            if (oldMediaSizeNewIndex != AdapterView.INVALID_POSITION) {
+                // Select the old media size - nothing really changed.
+                if (mMediaSizeSpinner.getSelectedItemPosition() != oldMediaSizeNewIndex) {
+                    mMediaSizeSpinner.setSelection(oldMediaSizeNewIndex);
+                }
+            } else {
+                // Select the first or the default.
+                final int mediaSizeIndex = Math.max(mediaSizes.indexOf(
+                        defaultAttributes.getMediaSize()), 0);
+                if (mMediaSizeSpinner.getSelectedItemPosition() != mediaSizeIndex) {
+                    mMediaSizeSpinner.setSelection(mediaSizeIndex);
+                }
+                // Respect the orientation of the old selection.
+                if (oldMediaSize != null) {
+                    if (oldMediaSize.isPortrait()) {
+                        attributes.setMediaSize(mMediaSizeSpinnerAdapter
+                                .getItem(mediaSizeIndex).value.asPortrait());
+                    } else {
+                        attributes.setMediaSize(mMediaSizeSpinnerAdapter
+                                .getItem(mediaSizeIndex).value.asLandscape());
+                    }
+                }
+            }
+        }
+
+        // Color mode.
+        mColorModeSpinner.setEnabled(true);
+        final int colorModes = capabilities.getColorModes();
+
+        // If the color modes changed, we update the adapter and the spinner.
+        boolean colorModesChanged = false;
+        if (Integer.bitCount(colorModes) != mColorModeSpinnerAdapter.getCount()) {
+            colorModesChanged = true;
+        } else {
+            int remainingColorModes = colorModes;
+            int adapterIndex = 0;
+            while (remainingColorModes != 0) {
+                final int colorBitOffset = Integer.numberOfTrailingZeros(remainingColorModes);
+                final int colorMode = 1 << colorBitOffset;
+                remainingColorModes &= ~colorMode;
+                if (colorMode != mColorModeSpinnerAdapter.getItem(adapterIndex).value) {
+                    colorModesChanged = true;
+                    break;
+                }
+                adapterIndex++;
+            }
+        }
+        if (colorModesChanged) {
+            // Remember the old color mode to try selecting it again.
+            int oldColorModeNewIndex = AdapterView.INVALID_POSITION;
+            final int oldColorMode = attributes.getColorMode();
+
+            // Rebuild the adapter data.
+            mColorModeSpinnerAdapter.clear();
+            String[] colorModeLabels = getResources().getStringArray(R.array.color_mode_labels);
+            int remainingColorModes = colorModes;
+            while (remainingColorModes != 0) {
+                final int colorBitOffset = Integer.numberOfTrailingZeros(remainingColorModes);
+                final int colorMode = 1 << colorBitOffset;
+                if (colorMode == oldColorMode) {
+                    // Update the index of the old selection.
+                    oldColorModeNewIndex = colorBitOffset;
+                }
+                remainingColorModes &= ~colorMode;
+                mColorModeSpinnerAdapter.add(new SpinnerItem<>(colorMode,
+                        colorModeLabels[colorBitOffset]));
+            }
+            if (oldColorModeNewIndex != AdapterView.INVALID_POSITION) {
+                // Select the old color mode - nothing really changed.
+                if (mColorModeSpinner.getSelectedItemPosition() != oldColorModeNewIndex) {
+                    mColorModeSpinner.setSelection(oldColorModeNewIndex);
+                }
+            } else {
+                // Select the default.
+                final int selectedColorMode = colorModes & defaultAttributes.getColorMode();
+                final int itemCount = mColorModeSpinnerAdapter.getCount();
+                for (int i = 0; i < itemCount; i++) {
+                    SpinnerItem<Integer> item = mColorModeSpinnerAdapter.getItem(i);
+                    if (selectedColorMode == item.value) {
+                        if (mColorModeSpinner.getSelectedItemPosition() != i) {
+                            mColorModeSpinner.setSelection(i);
+                        }
+                        attributes.setColorMode(selectedColorMode);
+                    }
+                }
+            }
+        }
+
+        // Orientation
+        mOrientationSpinner.setEnabled(true);
+        MediaSize mediaSize = attributes.getMediaSize();
+        if (mediaSize != null) {
+            if (mediaSize.isPortrait()
+                    && mOrientationSpinner.getSelectedItemPosition() != 0) {
+                mOrientationSpinner.setSelection(0);
+            } else if (!mediaSize.isPortrait()
+                    && mOrientationSpinner.getSelectedItemPosition() != 1) {
+                mOrientationSpinner.setSelection(1);
+            }
+        }
+
+        // Range options
+        PrintDocumentInfo info = mPrintedDocument.getDocumentInfo().info;
+        if (info != null && info.getPageCount() > 0) {
+            if (info.getPageCount() == 1) {
+                mRangeOptionsSpinner.setEnabled(false);
+            } else {
+                mRangeOptionsSpinner.setEnabled(true);
+                if (mRangeOptionsSpinner.getSelectedItemPosition() > 0) {
+                    if (!mPageRangeEditText.isEnabled()) {
+                        mPageRangeEditText.setEnabled(true);
+                        mPageRangeEditText.setVisibility(View.VISIBLE);
+                        mPageRangeTitle.setVisibility(View.VISIBLE);
+                        mPageRangeEditText.requestFocus();
+                        InputMethodManager imm = (InputMethodManager)
+                                getSystemService(Context.INPUT_METHOD_SERVICE);
+                        imm.showSoftInput(mPageRangeEditText, 0);
+                    }
+                } else {
+                    mPageRangeEditText.setEnabled(false);
+                    mPageRangeEditText.setVisibility(View.INVISIBLE);
+                    mPageRangeTitle.setVisibility(View.INVISIBLE);
+                }
+            }
+            String title = (info.getPageCount() != PrintDocumentInfo.PAGE_COUNT_UNKNOWN)
+                    ? getString(R.string.label_pages, String.valueOf(info.getPageCount()))
+                    : getString(R.string.page_count_unknown);
+            mPageRangeOptionsTitle.setText(title);
+        } else {
+            if (mRangeOptionsSpinner.getSelectedItemPosition() != 0) {
+                mRangeOptionsSpinner.setSelection(0);
+            }
+            mRangeOptionsSpinner.setEnabled(false);
+            mPageRangeOptionsTitle.setText(getString(R.string.page_count_unknown));
+            mPageRangeEditText.setEnabled(false);
+            mPageRangeEditText.setVisibility(View.INVISIBLE);
+            mPageRangeTitle.setVisibility(View.INVISIBLE);
+        }
+
+        // Advanced print options
+        ComponentName serviceName = currentPrinter.getId().getServiceName();
+        if (!TextUtils.isEmpty(PrintOptionUtils.getAdvancedOptionsActivityName(
+                this, serviceName))) {
+            mAdvancedPrintOptionsContainer.setVisibility(View.VISIBLE);
+            mMoreOptionsButton.setEnabled(true);
+        } else {
+            mAdvancedPrintOptionsContainer.setVisibility(View.GONE);
+            mMoreOptionsButton.setEnabled(false);
+        }
+
+        // Print
+        if (mDestinationSpinnerAdapter.getPdfPrinter() != currentPrinter) {
+            mPrintButton.setImageResource(com.android.internal.R.drawable.ic_print);
+        } else {
+            mPrintButton.setImageResource(com.android.internal.R.drawable.ic_menu_save);
+        }
+        if ((mRangeOptionsSpinner.getSelectedItemPosition() == 1
+                && (TextUtils.isEmpty(mPageRangeEditText.getText()) || hasErrors()))
+            || (mRangeOptionsSpinner.getSelectedItemPosition() == 0
+                && (mPrintedDocument.getDocumentInfo() == null || hasErrors()))) {
+            mPrintButton.setEnabled(false);
+        } else {
+            mPrintButton.setEnabled(true);
+        }
+
+        // Copies
+        if (mDestinationSpinnerAdapter.getPdfPrinter() != currentPrinter) {
+            mCopiesEditText.setEnabled(true);
+        } else {
+            mCopiesEditText.setEnabled(false);
+        }
+        if (mCopiesEditText.getError() == null
+                && TextUtils.isEmpty(mCopiesEditText.getText())) {
+            mCopiesEditText.setText(String.valueOf(MIN_COPIES));
+            mCopiesEditText.requestFocus();
+        }
+    }
+
+    private PageRange[] computeRequestedPages() {
+        if (hasErrors()) {
+            return null;
+        }
+
+        if (mRangeOptionsSpinner.getSelectedItemPosition() > 0) {
+            List<PageRange> pageRanges = new ArrayList<>();
+            mStringCommaSplitter.setString(mPageRangeEditText.getText().toString());
+
+            while (mStringCommaSplitter.hasNext()) {
+                String range = mStringCommaSplitter.next().trim();
+                if (TextUtils.isEmpty(range)) {
+                    continue;
+                }
+                final int dashIndex = range.indexOf('-');
+                final int fromIndex;
+                final int toIndex;
+
+                if (dashIndex > 0) {
+                    fromIndex = Integer.parseInt(range.substring(0, dashIndex).trim()) - 1;
+                    // It is possible that the dash is at the end since the input
+                    // verification can has to allow the user to keep entering if
+                    // this would lead to a valid input. So we handle this.
+                    if (dashIndex < range.length() - 1) {
+                        String fromString = range.substring(dashIndex + 1, range.length()).trim();
+                        toIndex = Integer.parseInt(fromString) - 1;
+                    } else {
+                        toIndex = fromIndex;
+                    }
+                } else {
+                    fromIndex = toIndex = Integer.parseInt(range) - 1;
+                }
+
+                PageRange pageRange = new PageRange(Math.min(fromIndex, toIndex),
+                        Math.max(fromIndex, toIndex));
+                pageRanges.add(pageRange);
+            }
+
+            PageRange[] pageRangesArray = new PageRange[pageRanges.size()];
+            pageRanges.toArray(pageRangesArray);
+
+            return PageRangeUtils.normalize(pageRangesArray);
+        }
+
+        return ALL_PAGES_ARRAY;
+    }
+
+    private boolean hasErrors() {
+        return (mCopiesEditText.getError() != null)
+                || (mPageRangeEditText.getVisibility() == View.VISIBLE
+                    && mPageRangeEditText.getError() != null);
+    }
+
+    public void onPrinterAvailable(PrinterInfo printer) {
+        PrinterInfo currentPrinter = getCurrentPrinter();
+        if (currentPrinter.equals(printer)) {
+            mState = STATE_CONFIGURING;
+            if (canUpdateDocument()) {
+                updateDocument(true, false);
+            }
+            ensurePreviewUiShown();
+            updateOptionsUi();
+        }
+    }
+
+    public void onPrinterUnavailable(PrinterInfo printer) {
+        if (getCurrentPrinter().getId().equals(printer.getId())) {
+            mState = STATE_PRINTER_UNAVAILABLE;
+            if (mPrintedDocument.isUpdating()) {
+                mPrintedDocument.cancel();
+            }
+            ensureErrorUiShown(getString(R.string.print_error_printer_unavailable),
+                    PrintErrorFragment.ACTION_NONE);
+            updateOptionsUi();
+        }
+    }
+
+    private final class SpinnerItem<T> {
+        final T value;
+        final CharSequence label;
+
+        public SpinnerItem(T value, CharSequence label) {
+            this.value = value;
+            this.label = label;
+        }
+
+        public String toString() {
+            return label.toString();
+        }
+    }
+
+    private final class PrinterAvailabilityDetector implements Runnable {
+        private static final long UNAVAILABLE_TIMEOUT_MILLIS = 10000; // 10sec
+
+        private boolean mPosted;
+
+        private boolean mPrinterUnavailable;
+
+        private PrinterInfo mPrinter;
+
+        public void updatePrinter(PrinterInfo printer) {
+            if (printer.equals(mDestinationSpinnerAdapter.getPdfPrinter())) {
+                return;
+            }
+
+            final boolean available = printer.getStatus() != PrinterInfo.STATUS_UNAVAILABLE
+                    && printer.getCapabilities() != null;
+            final boolean notifyIfAvailable;
+
+            if (mPrinter == null || !mPrinter.getId().equals(printer.getId())) {
+                notifyIfAvailable = true;
+                unpostIfNeeded();
+                mPrinterUnavailable = false;
+                mPrinter = new PrinterInfo.Builder(printer).build();
+            } else {
+                notifyIfAvailable =
+                     (mPrinter.getStatus() == PrinterInfo.STATUS_UNAVAILABLE
+                        && printer.getStatus() != PrinterInfo.STATUS_UNAVAILABLE)
+                    || (mPrinter.getCapabilities() == null
+                        && printer.getCapabilities() != null);
+                mPrinter.copyFrom(printer);
+            }
+
+            if (available) {
+                unpostIfNeeded();
+                mPrinterUnavailable = false;
+                if (notifyIfAvailable) {
+                    onPrinterAvailable(mPrinter);
+                }
+            } else {
+                if (!mPrinterUnavailable) {
+                    postIfNeeded();
+                }
+            }
+        }
+
+        public void cancel() {
+            unpostIfNeeded();
+            mPrinterUnavailable = false;
+        }
+
+        private void postIfNeeded() {
+            if (!mPosted) {
+                mPosted = true;
+                mDestinationSpinner.postDelayed(this, UNAVAILABLE_TIMEOUT_MILLIS);
+            }
+        }
+
+        private void unpostIfNeeded() {
+            if (mPosted) {
+                mPosted = false;
+                mDestinationSpinner.removeCallbacks(this);
+            }
+        }
+
+        @Override
+        public void run() {
+            mPosted = false;
+            mPrinterUnavailable = true;
+            onPrinterUnavailable(mPrinter);
+        }
+    }
+
+    private static final class PrinterHolder {
+        PrinterInfo printer;
+        boolean removed;
+
+        public PrinterHolder(PrinterInfo printer) {
+            this.printer = printer;
+        }
+    }
+
+    private final class DestinationAdapter extends BaseAdapter
+            implements PrinterRegistry.OnPrintersChangeListener {
+        private final List<PrinterHolder> mPrinterHolders = new ArrayList<>();
+
+        private final PrinterHolder mFakePdfPrinterHolder;
+
+        public DestinationAdapter() {
+            addPrinters(mPrinterHolders, mPrinterRegistry.getPrinters());
+            mPrinterRegistry.setOnPrintersChangeListener(this);
+            mFakePdfPrinterHolder = new PrinterHolder(createFakePdfPrinter());
+        }
+
+        public PrinterInfo getPdfPrinter() {
+            return mFakePdfPrinterHolder.printer;
+        }
+
+        public int getPrinterIndex(PrinterId printerId) {
+            for (int i = 0; i < getCount(); i++) {
+                PrinterHolder printerHolder = (PrinterHolder) getItem(i);
+                if (printerHolder != null && !printerHolder.removed
+                        && printerHolder.printer.getId().equals(printerId)) {
+                    return i;
+                }
+            }
+            return AdapterView.INVALID_POSITION;
+        }
+
+        public void ensurePrinterInVisibleAdapterPosition(PrinterId printerId) {
+            final int printerCount = mPrinterHolders.size();
+            for (int i = 0; i < printerCount; i++) {
+                PrinterHolder printerHolder = mPrinterHolders.get(i);
+                if (printerHolder.printer.getId().equals(printerId)) {
+                    // If already in the list - do nothing.
+                    if (i < getCount() - 2) {
+                        return;
+                    }
+                    // Else replace the last one (two items are not printers).
+                    final int lastPrinterIndex = getCount() - 3;
+                    mPrinterHolders.set(i, mPrinterHolders.get(lastPrinterIndex));
+                    mPrinterHolders.set(lastPrinterIndex, printerHolder);
+                    notifyDataSetChanged();
+                    return;
+                }
+            }
+        }
+
+        @Override
+        public int getCount() {
+            return Math.min(mPrinterHolders.size() + 2, DEST_ADAPTER_MAX_ITEM_COUNT);
+        }
+
+        @Override
+        public boolean isEnabled(int position) {
+            Object item = getItem(position);
+            if (item instanceof PrinterHolder) {
+                PrinterHolder printerHolder = (PrinterHolder) item;
+                return !printerHolder.removed
+                        && printerHolder.printer.getStatus() != PrinterInfo.STATUS_UNAVAILABLE;
+            }
+            return true;
+        }
+
+        @Override
+        public Object getItem(int position) {
+            if (mPrinterHolders.isEmpty()) {
+                if (position == 0) {
+                    return mFakePdfPrinterHolder;
+                }
+            } else {
+                if (position < 1) {
+                    return mPrinterHolders.get(position);
+                }
+                if (position == 1) {
+                    return mFakePdfPrinterHolder;
+                }
+                if (position < getCount() - 1) {
+                    return mPrinterHolders.get(position - 1);
+                }
+            }
+            return null;
+        }
+
+        @Override
+        public long getItemId(int position) {
+            if (mPrinterHolders.isEmpty()) {
+                if (position == 0) {
+                    return DEST_ADAPTER_ITEM_ID_SAVE_AS_PDF;
+                } else if (position == 1) {
+                    return DEST_ADAPTER_ITEM_ID_ALL_PRINTERS;
+                }
+            } else {
+                if (position == 1) {
+                    return DEST_ADAPTER_ITEM_ID_SAVE_AS_PDF;
+                }
+                if (position == getCount() - 1) {
+                    return DEST_ADAPTER_ITEM_ID_ALL_PRINTERS;
+                }
+            }
+            return position;
+        }
+
+        @Override
+        public View getDropDownView(int position, View convertView, ViewGroup parent) {
+            View view = getView(position, convertView, parent);
+            view.setEnabled(isEnabled(position));
+            return view;
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            if (convertView == null) {
+                convertView = getLayoutInflater().inflate(
+                        R.layout.printer_dropdown_item, parent, false);
+            }
+
+            CharSequence title = null;
+            CharSequence subtitle = null;
+            Drawable icon = null;
+
+            if (mPrinterHolders.isEmpty()) {
+                if (position == 0 && getPdfPrinter() != null) {
+                    PrinterHolder printerHolder = (PrinterHolder) getItem(position);
+                    title = printerHolder.printer.getName();
+                    icon = getResources().getDrawable(com.android.internal.R.drawable.ic_menu_save);
+                } else if (position == 1) {
+                    title = getString(R.string.all_printers);
+                }
+            } else {
+                if (position == 1 && getPdfPrinter() != null) {
+                    PrinterHolder printerHolder = (PrinterHolder) getItem(position);
+                    title = printerHolder.printer.getName();
+                    icon = getResources().getDrawable(com.android.internal.R.drawable.ic_menu_save);
+                } else if (position == getCount() - 1) {
+                    title = getString(R.string.all_printers);
+                } else {
+                    PrinterHolder printerHolder = (PrinterHolder) getItem(position);
+                    title = printerHolder.printer.getName();
+                    try {
+                        PackageInfo packageInfo = getPackageManager().getPackageInfo(
+                                printerHolder.printer.getId().getServiceName().getPackageName(), 0);
+                        subtitle = packageInfo.applicationInfo.loadLabel(getPackageManager());
+                        icon = packageInfo.applicationInfo.loadIcon(getPackageManager());
+                    } catch (NameNotFoundException nnfe) {
+                        /* ignore */
+                    }
+                }
+            }
+
+            TextView titleView = (TextView) convertView.findViewById(R.id.title);
+            titleView.setText(title);
+
+            TextView subtitleView = (TextView) convertView.findViewById(R.id.subtitle);
+            if (!TextUtils.isEmpty(subtitle)) {
+                subtitleView.setText(subtitle);
+                subtitleView.setVisibility(View.VISIBLE);
+            } else {
+                subtitleView.setText(null);
+                subtitleView.setVisibility(View.GONE);
+            }
+
+            ImageView iconView = (ImageView) convertView.findViewById(R.id.icon);
+            if (icon != null) {
+                iconView.setImageDrawable(icon);
+                iconView.setVisibility(View.VISIBLE);
+            } else {
+                iconView.setVisibility(View.INVISIBLE);
+            }
+
+            return convertView;
+        }
+
+        @Override
+        public void onPrintersChanged(List<PrinterInfo> printers) {
+            // We rearrange the printers if the user selects a printer
+            // not shown in the initial short list. Therefore, we have
+            // to keep the printer order.
+
+            // No old printers - do not bother keeping their position.
+            if (mPrinterHolders.isEmpty()) {
+                addPrinters(mPrinterHolders, printers);
+                notifyDataSetChanged();
+                return;
+            }
+
+            // Add the new printers to a map.
+            ArrayMap<PrinterId, PrinterInfo> newPrintersMap = new ArrayMap<>();
+            final int printerCount = printers.size();
+            for (int i = 0; i < printerCount; i++) {
+                PrinterInfo printer = printers.get(i);
+                newPrintersMap.put(printer.getId(), printer);
+            }
+
+            List<PrinterHolder> newPrinterHolders = new ArrayList<>();
+
+            // Update printers we already have which are either updated or removed.
+            // We do not remove printers if the currently selected printer is removed
+            // to prevent the user printing to a wrong printer.
+            final int oldPrinterCount = mPrinterHolders.size();
+            for (int i = 0; i < oldPrinterCount; i++) {
+                PrinterHolder printerHolder = mPrinterHolders.get(i);
+                PrinterId oldPrinterId = printerHolder.printer.getId();
+                PrinterInfo updatedPrinter = newPrintersMap.remove(oldPrinterId);
+                if (updatedPrinter != null) {
+                    printerHolder.printer = updatedPrinter;
+                } else {
+                    printerHolder.removed = true;
+                }
+                newPrinterHolders.add(printerHolder);
+            }
+
+            // Add the rest of the new printers, i.e. what is left.
+            addPrinters(newPrinterHolders, newPrintersMap.values());
+
+            mPrinterHolders.clear();
+            mPrinterHolders.addAll(newPrinterHolders);
+
+            notifyDataSetChanged();
+        }
+
+        @Override
+        public void onPrintersInvalid() {
+            mPrinterHolders.clear();
+            notifyDataSetInvalidated();
+        }
+
+        public PrinterHolder getPrinterHolder(PrinterId printerId) {
+            final int itemCount = getCount();
+            for (int i = 0; i < itemCount; i++) {
+                Object item = getItem(i);
+                if (item instanceof PrinterHolder) {
+                    PrinterHolder printerHolder = (PrinterHolder) item;
+                    if (printerId.equals(printerHolder.printer.getId())) {
+                        return printerHolder;
+                    }
+                }
+            }
+            return null;
+        }
+
+        public void pruneRemovedPrinters() {
+            final int holderCounts = mPrinterHolders.size();
+            for (int i = holderCounts - 1; i >= 0; i--) {
+                PrinterHolder printerHolder = mPrinterHolders.get(i);
+                if (printerHolder.removed) {
+                    mPrinterHolders.remove(i);
+                }
+            }
+        }
+
+        private void addPrinters(List<PrinterHolder> list, Collection<PrinterInfo> printers) {
+            for (PrinterInfo printer : printers) {
+                PrinterHolder printerHolder = new PrinterHolder(printer);
+                list.add(printerHolder);
+            }
+        }
+
+        private PrinterInfo createFakePdfPrinter() {
+            MediaSize defaultMediaSize = MediaSizeUtils.getDefault(PrintActivity.this);
+
+            PrinterId printerId = new PrinterId(getComponentName(), "PDF printer");
+
+            PrinterCapabilitiesInfo.Builder builder =
+                    new PrinterCapabilitiesInfo.Builder(printerId);
+
+            String[] mediaSizeIds = getResources().getStringArray(R.array.pdf_printer_media_sizes);
+            final int mediaSizeIdCount = mediaSizeIds.length;
+            for (int i = 0; i < mediaSizeIdCount; i++) {
+                String id = mediaSizeIds[i];
+                MediaSize mediaSize = MediaSize.getStandardMediaSizeById(id);
+                builder.addMediaSize(mediaSize, mediaSize.equals(defaultMediaSize));
+            }
+
+            builder.addResolution(new Resolution("PDF resolution", "PDF resolution", 300, 300),
+                    true);
+            builder.setColorModes(PrintAttributes.COLOR_MODE_COLOR
+                    | PrintAttributes.COLOR_MODE_MONOCHROME, PrintAttributes.COLOR_MODE_COLOR);
+
+            return new PrinterInfo.Builder(printerId, getString(R.string.save_as_pdf),
+                    PrinterInfo.STATUS_IDLE).setCapabilities(builder.build()).build();
+        }
+    }
+
+    private final class PrintersObserver extends DataSetObserver {
+        @Override
+        public void onChanged() {
+            PrinterInfo oldPrinterState = mOldCurrentPrinter;
+            if (oldPrinterState == null) {
+                return;
+            }
+
+            PrinterHolder printerHolder = mDestinationSpinnerAdapter.getPrinterHolder(
+                    oldPrinterState.getId());
+            if (printerHolder == null) {
+                return;
+            }
+            PrinterInfo newPrinterState = printerHolder.printer;
+
+            if (!printerHolder.removed) {
+                mDestinationSpinnerAdapter.pruneRemovedPrinters();
+            } else {
+                onPrinterUnavailable(newPrinterState);
+            }
+
+            if (oldPrinterState.equals(newPrinterState)) {
+                return;
+            }
+
+            PrinterCapabilitiesInfo oldCapab = oldPrinterState.getCapabilities();
+            PrinterCapabilitiesInfo newCapab = newPrinterState.getCapabilities();
+
+            final boolean hasCapab = newCapab != null;
+            final boolean gotCapab = oldCapab == null && newCapab != null;
+            final boolean lostCapab = oldCapab != null && newCapab == null;
+            final boolean capabChanged = capabilitiesChanged(oldCapab, newCapab);
+
+            final int oldStatus = oldPrinterState.getStatus();
+            final int newStatus = newPrinterState.getStatus();
+
+            final boolean isActive = newStatus != PrinterInfo.STATUS_UNAVAILABLE;
+            final boolean becameActive = (oldStatus == PrinterInfo.STATUS_UNAVAILABLE
+                    && oldStatus != newStatus);
+            final boolean becameInactive = (newStatus == PrinterInfo.STATUS_UNAVAILABLE
+                    && oldStatus != newStatus);
+
+            mPrinterAvailabilityDetector.updatePrinter(newPrinterState);
+
+            oldPrinterState.copyFrom(newPrinterState);
+
+            if ((isActive && gotCapab) || (becameActive && hasCapab)) {
+                onPrinterAvailable(newPrinterState);
+            } else if ((becameInactive && hasCapab)|| (isActive && lostCapab)) {
+                onPrinterUnavailable(newPrinterState);
+            }
+
+            if (hasCapab && capabChanged) {
+                updatePrintAttributesFromCapabilities(newCapab);
+            }
+
+            final boolean updateNeeded = ((capabChanged && hasCapab && isActive)
+                    || (becameActive && hasCapab) || (isActive && gotCapab));
+
+            if (updateNeeded && canUpdateDocument()) {
+                updateDocument(true, false);
+            }
+
+            updateOptionsUi();
+        }
+
+        private boolean capabilitiesChanged(PrinterCapabilitiesInfo oldCapabilities,
+                PrinterCapabilitiesInfo newCapabilities) {
+            if (oldCapabilities == null) {
+                if (newCapabilities != null) {
+                    return true;
+                }
+            } else if (!oldCapabilities.equals(newCapabilities)) {
+                return true;
+            }
+            return false;
+        }
+    }
+
+    private final class MyOnItemSelectedListener implements AdapterView.OnItemSelectedListener {
+        @Override
+        public void onItemSelected(AdapterView<?> spinner, View view, int position, long id) {
+            if (spinner == mDestinationSpinner) {
+                if (position == AdapterView.INVALID_POSITION) {
+                    return;
+                }
+
+                if (id == DEST_ADAPTER_ITEM_ID_ALL_PRINTERS) {
+                    startSelectPrinterActivity();
+                    return;
+                }
+
+                PrinterInfo currentPrinter = getCurrentPrinter();
+
+                // Why on earth item selected is called if no selection changed.
+                if (mOldCurrentPrinter == currentPrinter) {
+                    return;
+                }
+                mOldCurrentPrinter = currentPrinter;
+
+                PrinterHolder printerHolder = mDestinationSpinnerAdapter.getPrinterHolder(
+                        currentPrinter.getId());
+                if (!printerHolder.removed) {
+                    mDestinationSpinnerAdapter.pruneRemovedPrinters();
+                    ensurePreviewUiShown();
+                }
+
+                mPrintJob.setPrinterId(currentPrinter.getId());
+                mPrintJob.setPrinterName(currentPrinter.getName());
+
+                mPrinterRegistry.setTrackedPrinter(currentPrinter.getId());
+
+                PrinterCapabilitiesInfo capabilities = currentPrinter.getCapabilities();
+                if (capabilities != null) {
+                   updatePrintAttributesFromCapabilities(capabilities);
+                }
+
+                mPrinterAvailabilityDetector.updatePrinter(currentPrinter);
+            } else if (spinner == mMediaSizeSpinner) {
+                SpinnerItem<MediaSize> mediaItem = mMediaSizeSpinnerAdapter.getItem(position);
+                if (mOrientationSpinner.getSelectedItemPosition() == 0) {
+                    mPrintJob.getAttributes().setMediaSize(mediaItem.value.asPortrait());
+                } else {
+                    mPrintJob.getAttributes().setMediaSize(mediaItem.value.asLandscape());
+                }
+            } else if (spinner == mColorModeSpinner) {
+                SpinnerItem<Integer> colorModeItem = mColorModeSpinnerAdapter.getItem(position);
+                mPrintJob.getAttributes().setColorMode(colorModeItem.value);
+            } else if (spinner == mOrientationSpinner) {
+                SpinnerItem<Integer> orientationItem = mOrientationSpinnerAdapter.getItem(position);
+                PrintAttributes attributes = mPrintJob.getAttributes();
+                if (orientationItem.value == ORIENTATION_PORTRAIT) {
+                    attributes.copyFrom(attributes.asPortrait());
+                } else {
+                    attributes.copyFrom(attributes.asLandscape());
+                }
+            }
+
+            if (canUpdateDocument()) {
+                updateDocument(true, false);
+            }
+
+            updateOptionsUi();
+        }
+
+        @Override
+        public void onNothingSelected(AdapterView<?> parent) {
+            /* do nothing*/
+        }
+    }
+
+    private boolean canUpdateDocument() {
+        if (mPrintedDocument.isDestroyed()) {
+            return false;
+        }
+
+        if (hasErrors()) {
+            return false;
+        }
+
+        PrintAttributes attributes = mPrintJob.getAttributes();
+
+        final int colorMode = attributes.getColorMode();
+        if (colorMode != PrintAttributes.COLOR_MODE_COLOR
+                && colorMode != PrintAttributes.COLOR_MODE_MONOCHROME) {
+            return false;
+        }
+        if (attributes.getMediaSize() == null) {
+            return false;
+        }
+        if (attributes.getMinMargins() == null) {
+            return false;
+        }
+        if (attributes.getResolution() == null) {
+            return false;
+        }
+
+        PrinterInfo currentPrinter = getCurrentPrinter();
+        if (currentPrinter == null) {
+            return false;
+        }
+        PrinterCapabilitiesInfo capabilities = currentPrinter.getCapabilities();
+        if (capabilities == null) {
+            return false;
+        }
+        if (currentPrinter.getStatus() == PrinterInfo.STATUS_UNAVAILABLE) {
+            return false;
+        }
+
+        return true;
+    }
+
+    private final class SelectAllOnFocusListener implements OnFocusChangeListener {
+        @Override
+        public void onFocusChange(View view, boolean hasFocus) {
+            EditText editText = (EditText) view;
+            if (!TextUtils.isEmpty(editText.getText())) {
+                editText.setSelection(editText.getText().length());
+            }
+        }
+    }
+
+    private final class RangeTextWatcher implements TextWatcher {
+        @Override
+        public void onTextChanged(CharSequence s, int start, int before, int count) {
+            /* do nothing */
+        }
+
+        @Override
+        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+            /* do nothing */
+        }
+
+        @Override
+        public void afterTextChanged(Editable editable) {
+            final boolean hadErrors = hasErrors();
+
+            String text = editable.toString();
+
+            if (TextUtils.isEmpty(text)) {
+                mPageRangeEditText.setError("");
+                updateOptionsUi();
+                return;
+            }
+
+            String escapedText = PATTERN_ESCAPE_SPECIAL_CHARS.matcher(text).replaceAll("////");
+            if (!PATTERN_PAGE_RANGE.matcher(escapedText).matches()) {
+                mPageRangeEditText.setError("");
+                updateOptionsUi();
+                return;
+            }
+
+            PrintDocumentInfo info = mPrintedDocument.getDocumentInfo().info;
+            final int pageCount = (info != null) ? info.getPageCount() : 0;
+
+            // The range
+            Matcher matcher = PATTERN_DIGITS.matcher(text);
+            while (matcher.find()) {
+                String numericString = text.substring(matcher.start(), matcher.end()).trim();
+                if (TextUtils.isEmpty(numericString)) {
+                    continue;
+                }
+                final int pageIndex = Integer.parseInt(numericString);
+                if (pageIndex < 1 || pageIndex > pageCount) {
+                    mPageRangeEditText.setError("");
+                    updateOptionsUi();
+                    return;
+                }
+            }
+
+            // We intentionally do not catch the case of the from page being
+            // greater than the to page. When computing the requested pages
+            // we just swap them if necessary.
+
+            // Keep the print job up to date with the selected pages if we
+            // know how many pages are there in the document.
+            mRequestedPages = computeRequestedPages();
+
+            mPageRangeEditText.setError(null);
+            mPrintButton.setEnabled(true);
+            updateOptionsUi();
+
+            if (hadErrors && !hasErrors()) {
+                updateOptionsUi();
+            }
+        }
+    }
+
+    private final class EditTextWatcher implements TextWatcher {
+        @Override
+        public void onTextChanged(CharSequence s, int start, int before, int count) {
+            /* do nothing */
+        }
+
+        @Override
+        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+            /* do nothing */
+        }
+
+        @Override
+        public void afterTextChanged(Editable editable) {
+            final boolean hadErrors = hasErrors();
+
+            if (editable.length() == 0) {
+                mCopiesEditText.setError("");
+                updateOptionsUi();
+                return;
+            }
+
+            int copies = 0;
+            try {
+                copies = Integer.parseInt(editable.toString());
+            } catch (NumberFormatException nfe) {
+                /* ignore */
+            }
+
+            if (copies < MIN_COPIES) {
+                mCopiesEditText.setError("");
+                updateOptionsUi();
+                return;
+            }
+
+            mPrintJob.setCopies(copies);
+
+            mCopiesEditText.setError(null);
+
+            updateOptionsUi();
+
+            if (hadErrors && canUpdateDocument()) {
+                updateDocument(true, false);
+            }
+        }
+    }
+
+    private final class ProgressMessageController implements Runnable {
+        private static final long PROGRESS_TIMEOUT_MILLIS = 1000;
+
+        private final Handler mHandler;
+
+        private boolean mPosted;
+
+        public ProgressMessageController(Context context) {
+            mHandler = new Handler(context.getMainLooper(), null, false);
+        }
+
+        public void post() {
+            if (mPosted) {
+                return;
+            }
+            mPosted = true;
+            mHandler.postDelayed(this, PROGRESS_TIMEOUT_MILLIS);
+        }
+
+        public void cancel() {
+            if (!mPosted) {
+                return;
+            }
+            mPosted = false;
+            mHandler.removeCallbacks(this);
+        }
+
+        @Override
+        public void run() {
+            ensureProgressUiShown();
+        }
+    }
+}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintErrorFragment.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintErrorFragment.java
new file mode 100644
index 0000000..b708356
--- /dev/null
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintErrorFragment.java
@@ -0,0 +1,103 @@
+/*
+ * 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.printspooler.ui;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.TextView;
+
+import com.android.printspooler.R;
+
+/**
+ * Fragment for showing an error UI.
+ */
+public final class PrintErrorFragment extends Fragment {
+    public static final int ACTION_NONE = 0;
+    public static final int ACTION_RETRY = 1;
+    public static final int ACTION_CONFIRM = 2;
+
+    public interface OnActionListener {
+        public void onActionPerformed();
+    }
+
+    private static final String EXTRA_ERROR_MESSAGE = "EXTRA_ERROR_MESSAGE";
+    private static final String EXTRA_ACTION = "EXTRA_ACTION";
+
+    public static PrintErrorFragment newInstance(CharSequence errorMessage, int action) {
+        PrintErrorFragment instance = new PrintErrorFragment();
+        Bundle arguments = new Bundle();
+        arguments.putCharSequence(EXTRA_ERROR_MESSAGE, errorMessage);
+        arguments.putInt(EXTRA_ACTION, action);
+        instance.setArguments(arguments);
+        return instance;
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup root,
+            Bundle savedInstanceState) {
+        return inflater.inflate(R.layout.print_error_fragment, root, false);
+    }
+
+    @Override
+    public void onViewCreated(View view, Bundle savedInstanceState) {
+        super.onViewCreated(view, savedInstanceState);
+
+        Bundle arguments = getArguments();
+
+        CharSequence error = arguments.getString(EXTRA_ERROR_MESSAGE);
+        if (!TextUtils.isEmpty(error)) {
+            TextView message = (TextView) view.findViewById(R.id.message);
+            message.setText(error);
+        }
+
+        Button actionButton = (Button) view.findViewById(R.id.action_button);
+
+        final int action = getArguments().getInt(EXTRA_ACTION);
+        switch (action) {
+            case ACTION_RETRY: {
+                actionButton.setVisibility(View.VISIBLE);
+                actionButton.setText(R.string.print_error_retry);
+            } break;
+
+            case ACTION_CONFIRM: {
+                actionButton.setVisibility(View.VISIBLE);
+                actionButton.setText(android.R.string.ok);
+            } break;
+
+            case ACTION_NONE: {
+                actionButton.setVisibility(View.GONE);
+            } break;
+        }
+
+        actionButton.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                Activity activity = getActivity();
+                if (activity instanceof OnActionListener) {
+                    ((OnActionListener) getActivity()).onActionPerformed();
+                }
+            }
+        });
+    }
+}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintPreviewFragment.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintPreviewFragment.java
new file mode 100644
index 0000000..d68a6aa
--- /dev/null
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintPreviewFragment.java
@@ -0,0 +1,12 @@
+package com.android.printspooler.ui;
+
+import android.app.Fragment;
+
+public class PrintPreviewFragment extends Fragment {
+
+    public static PrintPreviewFragment newInstance() {
+        return new PrintPreviewFragment();
+    }
+
+    // TODO: Implement
+}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintProgressFragment.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintProgressFragment.java
new file mode 100644
index 0000000..96aa153d
--- /dev/null
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintProgressFragment.java
@@ -0,0 +1,69 @@
+/*
+ * 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.printspooler.ui;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+
+import android.widget.TextView;
+import com.android.printspooler.R;
+
+/**
+ * Fragment for showing a work in progress UI.
+ */
+public final class PrintProgressFragment extends Fragment {
+
+    public interface OnCancelRequestListener {
+        public void onCancelRequest();
+    }
+
+    public static PrintProgressFragment newInstance() {
+        return new PrintProgressFragment();
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup root,
+            Bundle savedInstanceState) {
+        return inflater.inflate(R.layout.print_progress_fragment, root, false);
+    }
+
+    @Override
+    public void onViewCreated(View view, Bundle savedInstanceState) {
+        super.onViewCreated(view, savedInstanceState);
+
+        final Button cancelButton = (Button) view.findViewById(R.id.cancel_button);
+        final TextView message = (TextView) view.findViewById(R.id.message);
+
+        cancelButton.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                Activity activity = getActivity();
+                if (activity instanceof OnCancelRequestListener) {
+                    ((OnCancelRequestListener) getActivity()).onCancelRequest();
+                }
+                cancelButton.setVisibility(View.GONE);
+                message.setVisibility(View.VISIBLE);
+            }
+        });
+    }
+}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrinterRegistry.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrinterRegistry.java
new file mode 100644
index 0000000..7816d66
--- /dev/null
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrinterRegistry.java
@@ -0,0 +1,168 @@
+/*
+ * 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.printspooler.ui;
+
+import android.app.Activity;
+import android.app.LoaderManager.LoaderCallbacks;
+import android.content.Loader;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.print.PrinterId;
+import android.print.PrinterInfo;
+import com.android.internal.os.SomeArgs;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class PrinterRegistry {
+
+    private static final int LOADER_ID_PRINTERS_LOADER = 1;
+
+    private final Activity mActivity;
+
+    private final List<PrinterInfo> mPrinters = new ArrayList<>();
+
+    private final Runnable mReadyCallback;
+
+    private final Handler mHandler;
+
+    private boolean mReady;
+
+    private OnPrintersChangeListener mOnPrintersChangeListener;
+
+    public interface OnPrintersChangeListener {
+        public void onPrintersChanged(List<PrinterInfo> printers);
+        public void onPrintersInvalid();
+    }
+
+    public PrinterRegistry(Activity activity, Runnable readyCallback) {
+        mActivity = activity;
+        mReadyCallback = readyCallback;
+        mHandler = new MyHandler(activity.getMainLooper());
+        activity.getLoaderManager().initLoader(LOADER_ID_PRINTERS_LOADER,
+                null, mLoaderCallbacks);
+    }
+
+    public void setOnPrintersChangeListener(OnPrintersChangeListener listener) {
+        mOnPrintersChangeListener = listener;
+    }
+
+    public List<PrinterInfo> getPrinters() {
+        return mPrinters;
+    }
+
+    public void addHistoricalPrinter(PrinterInfo printer) {
+        getPrinterProvider().addHistoricalPrinter(printer);
+    }
+
+    public void forgetFavoritePrinter(PrinterId printerId) {
+        getPrinterProvider().forgetFavoritePrinter(printerId);
+    }
+
+    public boolean isFavoritePrinter(PrinterId printerId) {
+        return getPrinterProvider().isFavoritePrinter(printerId);
+    }
+
+    public void setTrackedPrinter(PrinterId printerId) {
+        getPrinterProvider().setTrackedPrinter(printerId);
+    }
+
+    private FusedPrintersProvider getPrinterProvider() {
+        Loader<?> loader = mActivity.getLoaderManager().getLoader(LOADER_ID_PRINTERS_LOADER);
+        return (FusedPrintersProvider) loader;
+    }
+
+    private final LoaderCallbacks<List<PrinterInfo>> mLoaderCallbacks =
+            new LoaderCallbacks<List<PrinterInfo>>() {
+        @Override
+        public void onLoaderReset(Loader<List<PrinterInfo>> loader) {
+            if (loader.getId() == LOADER_ID_PRINTERS_LOADER) {
+                mPrinters.clear();
+                if (mOnPrintersChangeListener != null) {
+                    // Post a message as we are in onLoadFinished and certain operations
+                    // are not allowed in this callback, such as fragment transactions.
+                    // Clients should not handle this explicitly.
+                    mHandler.obtainMessage(MyHandler.MSG_PRINTERS_INVALID,
+                            mOnPrintersChangeListener).sendToTarget();
+                }
+            }
+        }
+
+        // LoaderCallbacks#onLoadFinished
+        @Override
+        public void onLoadFinished(Loader<List<PrinterInfo>> loader, List<PrinterInfo> printers) {
+            if (loader.getId() == LOADER_ID_PRINTERS_LOADER) {
+                mPrinters.clear();
+                mPrinters.addAll(printers);
+                if (mOnPrintersChangeListener != null) {
+                    // Post a message as we are in onLoadFinished and certain operations
+                    // are not allowed in this callback, such as fragment transactions.
+                    // Clients should not handle this explicitly.
+                    SomeArgs args = SomeArgs.obtain();
+                    args.arg1 = mOnPrintersChangeListener;
+                    args.arg2 = printers;
+                    mHandler.obtainMessage(MyHandler.MSG_PRINTERS_CHANGED, args).sendToTarget();
+                }
+                if (!mReady) {
+                    mReady = true;
+                    if (mReadyCallback != null) {
+                        mReadyCallback.run();
+                    }
+                }
+            }
+        }
+
+        // LoaderCallbacks#onCreateLoader
+        @Override
+        public Loader<List<PrinterInfo>> onCreateLoader(int id, Bundle args) {
+            if (id == LOADER_ID_PRINTERS_LOADER) {
+                return new FusedPrintersProvider(mActivity);
+            }
+            return null;
+        }
+    };
+
+    private static final class MyHandler extends Handler {
+        public static final int MSG_PRINTERS_CHANGED = 0;
+        public static final int MSG_PRINTERS_INVALID = 1;
+
+        public MyHandler(Looper looper) {
+            super(looper, null , false);
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public void handleMessage(Message message) {
+            switch (message.what) {
+                case MSG_PRINTERS_CHANGED: {
+                    SomeArgs args = (SomeArgs) message.obj;
+                    OnPrintersChangeListener callback = (OnPrintersChangeListener) args.arg1;
+                    List<PrinterInfo> printers = (List<PrinterInfo>) args.arg2;
+                    args.recycle();
+                    callback.onPrintersChanged(printers);
+                } break;
+
+                case MSG_PRINTERS_INVALID: {
+                    OnPrintersChangeListener callback = (OnPrintersChangeListener) message.obj;
+                    callback.onPrintersInvalid();
+                } break;
+            }
+        }
+    }
+}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/SelectPrinterFragment.java b/packages/PrintSpooler/src/com/android/printspooler/ui/SelectPrinterActivity.java
similarity index 73%
rename from packages/PrintSpooler/src/com/android/printspooler/SelectPrinterFragment.java
rename to packages/PrintSpooler/src/com/android/printspooler/ui/SelectPrinterActivity.java
index fe5920c..7715579 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/SelectPrinterFragment.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/SelectPrinterActivity.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.printspooler;
+package com.android.printspooler.ui;
 
 import android.app.Activity;
 import android.app.AlertDialog;
@@ -22,13 +22,11 @@
 import android.app.DialogFragment;
 import android.app.Fragment;
 import android.app.FragmentTransaction;
-import android.app.LoaderManager;
 import android.content.ActivityNotFoundException;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
-import android.content.Loader;
 import android.content.pm.ActivityInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
@@ -48,9 +46,7 @@
 import android.util.Log;
 import android.view.ContextMenu;
 import android.view.ContextMenu.ContextMenuInfo;
-import android.view.LayoutInflater;
 import android.view.Menu;
-import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
@@ -66,63 +62,60 @@
 import android.widget.SearchView;
 import android.widget.TextView;
 
+import com.android.printspooler.R;
+
 import java.util.ArrayList;
 import java.util.List;
 
 /**
- * This is a fragment for selecting a printer.
+ * This is an activity for selecting a printer.
  */
-public final class SelectPrinterFragment extends Fragment {
+public final class SelectPrinterActivity extends Activity {
 
     private static final String LOG_TAG = "SelectPrinterFragment";
 
-    private static final int LOADER_ID_PRINTERS_LOADER = 1;
+    public static final String INTENT_EXTRA_PRINTER_ID = "INTENT_EXTRA_PRINTER_ID";
 
-    private static final String FRAGMRNT_TAG_ADD_PRINTER_DIALOG =
-            "FRAGMRNT_TAG_ADD_PRINTER_DIALOG";
+    private static final String FRAGMENT_TAG_ADD_PRINTER_DIALOG =
+            "FRAGMENT_TAG_ADD_PRINTER_DIALOG";
 
-    private static final String FRAGMRNT_ARGUMENT_PRINT_SERVICE_INFOS =
-            "FRAGMRNT_ARGUMENT_PRINT_SERVICE_INFOS";
+    private static final String FRAGMENT_ARGUMENT_PRINT_SERVICE_INFOS =
+            "FRAGMENT_ARGUMENT_PRINT_SERVICE_INFOS";
 
     private static final String EXTRA_PRINTER_ID = "EXTRA_PRINTER_ID";
 
     private final ArrayList<PrintServiceInfo> mAddPrinterServices =
-            new ArrayList<PrintServiceInfo>();
+            new ArrayList<>();
+
+    private PrinterRegistry mPrinterRegistry;
 
     private ListView mListView;
 
     private AnnounceFilterResult mAnnounceFilterResult;
 
-    public static interface OnPrinterSelectedListener {
-        public void onPrinterSelected(PrinterId printerId);
-    }
-
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        setHasOptionsMenu(true);
-        getActivity().getActionBar().setIcon(R.drawable.ic_menu_print);
-    }
+        getActionBar().setIcon(R.drawable.ic_menu_print);
 
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container,
-            Bundle savedInstanceState) {
-        View content = inflater.inflate(R.layout.select_printer_fragment, container, false);
+        setContentView(R.layout.select_printer_activity);
+
+        mPrinterRegistry = new PrinterRegistry(this, null);
 
         // Hook up the list view.
-        mListView = (ListView) content.findViewById(android.R.id.list);
+        mListView = (ListView) findViewById(android.R.id.list);
         final DestinationAdapter adapter = new DestinationAdapter();
         adapter.registerDataSetObserver(new DataSetObserver() {
             @Override
             public void onChanged() {
-                if (!getActivity().isFinishing() && adapter.getCount() <= 0) {
+                if (!isFinishing() && adapter.getCount() <= 0) {
                     updateEmptyView(adapter);
                 }
             }
 
             @Override
             public void onInvalidated() {
-                if (!getActivity().isFinishing()) {
+                if (!isFinishing()) {
                     updateEmptyView(adapter);
                 }
             }
@@ -135,26 +128,20 @@
                 if (!((DestinationAdapter) mListView.getAdapter()).isActionable(position)) {
                     return;
                 }
+
                 PrinterInfo printer = (PrinterInfo) mListView.getAdapter().getItem(position);
-                Activity activity = getActivity();
-                if (activity instanceof OnPrinterSelectedListener) {
-                    ((OnPrinterSelectedListener) activity).onPrinterSelected(printer.getId());
-                } else {
-                    throw new IllegalStateException("the host activity must implement"
-                            + " OnPrinterSelectedListener");
-                }
+                onPrinterSelected(printer.getId());
             }
         });
 
         registerForContextMenu(mListView);
-
-        return content;
     }
 
     @Override
-    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
-        super.onCreateOptionsMenu(menu, inflater);
-        inflater.inflate(R.menu.select_printer_activity, menu);
+    public boolean onCreateOptionsMenu(Menu menu) {
+        super.onCreateOptionsMenu(menu);
+
+        getMenuInflater().inflate(R.menu.select_printer_activity, menu);
 
         MenuItem searchItem = menu.findItem(R.id.action_search);
         SearchView searchView = (SearchView) searchItem.getActionView();
@@ -173,16 +160,15 @@
         searchView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
             @Override
             public void onViewAttachedToWindow(View view) {
-                if (AccessibilityManager.getInstance(getActivity()).isEnabled()) {
+                if (AccessibilityManager.getInstance(SelectPrinterActivity.this).isEnabled()) {
                     view.announceForAccessibility(getString(
                             R.string.print_search_box_shown_utterance));
                 }
             }
             @Override
             public void onViewDetachedFromWindow(View view) {
-                Activity activity = getActivity();
-                if (activity != null && !activity.isFinishing()
-                        && AccessibilityManager.getInstance(activity).isEnabled()) {
+                if (!isFinishing() && AccessibilityManager.getInstance(
+                        SelectPrinterActivity.this).isEnabled()) {
                     view.announceForAccessibility(getString(
                             R.string.print_search_box_hidden_utterance));
                 }
@@ -192,6 +178,8 @@
         if (mAddPrinterServices.isEmpty()) {
             menu.removeItem(R.id.action_add_printer);
         }
+
+        return true;
     }
 
     @Override
@@ -212,9 +200,7 @@
             }
 
             // Add the forget menu item if applicable.
-            FusedPrintersProvider provider = (FusedPrintersProvider) (Loader<?>)
-                    getLoaderManager().getLoader(LOADER_ID_PRINTERS_LOADER);
-            if (provider.isFavoritePrinter(printer.getId())) {
+            if (mPrinterRegistry.isFavoritePrinter(printer.getId())) {
                 MenuItem forgetItem = menu.add(Menu.NONE, R.string.print_forget_printer,
                         Menu.NONE, R.string.print_forget_printer);
                 Intent intent = new Intent();
@@ -228,23 +214,13 @@
     public boolean onContextItemSelected(MenuItem item) {
         switch (item.getItemId()) {
             case R.string.print_select_printer: {
-                PrinterId printerId = (PrinterId) item.getIntent().getParcelableExtra(
-                        EXTRA_PRINTER_ID);
-                Activity activity = getActivity();
-                if (activity instanceof OnPrinterSelectedListener) {
-                    ((OnPrinterSelectedListener) activity).onPrinterSelected(printerId);
-                } else {
-                    throw new IllegalStateException("the host activity must implement"
-                            + " OnPrinterSelectedListener");
-                }
+                PrinterId printerId = item.getIntent().getParcelableExtra(EXTRA_PRINTER_ID);
+                onPrinterSelected(printerId);
             } return true;
 
             case R.string.print_forget_printer: {
-                PrinterId printerId = (PrinterId) item.getIntent().getParcelableExtra(
-                        EXTRA_PRINTER_ID);
-                FusedPrintersProvider provider = (FusedPrintersProvider) (Loader<?>)
-                        getLoaderManager().getLoader(LOADER_ID_PRINTERS_LOADER);
-                provider.forgetFavoritePrinter(printerId);
+                PrinterId printerId = item.getIntent().getParcelableExtra(EXTRA_PRINTER_ID);
+                mPrinterRegistry.forgetFavoritePrinter(printerId);
             } return true;
         }
         return false;
@@ -252,9 +228,9 @@
 
     @Override
     public void onResume() {
-        updateAddPrintersAdapter();
-        getActivity().invalidateOptionsMenu();
         super.onResume();
+        updateServicesWithAddPrinterActivity();
+        invalidateOptionsMenu();
     }
 
     @Override
@@ -274,12 +250,18 @@
         return super.onOptionsItemSelected(item);
     }
 
-    private void updateAddPrintersAdapter() {
+    private void onPrinterSelected(PrinterId printerId) {
+        Intent intent = new Intent();
+        intent.putExtra(INTENT_EXTRA_PRINTER_ID, printerId);
+        setResult(RESULT_OK, intent);
+        finish();
+    }
+
+    private void updateServicesWithAddPrinterActivity() {
         mAddPrinterServices.clear();
 
         // Get all enabled print services.
-        PrintManager printManager = (PrintManager) getActivity()
-                .getSystemService(Context.PRINT_SERVICE);
+        PrintManager printManager = (PrintManager) getSystemService(Context.PRINT_SERVICE);
         List<PrintServiceInfo> enabledServices = printManager.getEnabledPrintServices();
 
         // No enabled print services - done.
@@ -292,7 +274,7 @@
         for (int i = 0; i < enabledServiceCount; i++) {
             PrintServiceInfo enabledService = enabledServices.get(i);
 
-            // No add printers activity declared - done.
+            // No add printers activity declared - next.
             if (TextUtils.isEmpty(enabledService.getAddPrintersActivityName())) {
                 continue;
             }
@@ -304,15 +286,14 @@
                 .setComponent(addPrintersComponentName);
 
             // The add printers activity is valid - add it.
-            PackageManager pm = getActivity().getPackageManager();
+            PackageManager pm = getPackageManager();
             List<ResolveInfo> resolvedActivities = pm.queryIntentActivities(addPritnersIntent, 0);
             if (!resolvedActivities.isEmpty()) {
                 // The activity is a component name, therefore it is one or none.
                 ActivityInfo activityInfo = resolvedActivities.get(0).activityInfo;
                 if (activityInfo.exported
                         && (activityInfo.permission == null
-                                || pm.checkPermission(activityInfo.permission,
-                                        getActivity().getPackageName())
+                                || pm.checkPermission(activityInfo.permission, getPackageName())
                                         == PackageManager.PERMISSION_GRANTED)) {
                     mAddPrinterServices.add(enabledService);
                 }
@@ -323,26 +304,26 @@
     private void showAddPrinterSelectionDialog() {
         FragmentTransaction transaction = getFragmentManager().beginTransaction();
         Fragment oldFragment = getFragmentManager().findFragmentByTag(
-                FRAGMRNT_TAG_ADD_PRINTER_DIALOG);
+                FRAGMENT_TAG_ADD_PRINTER_DIALOG);
         if (oldFragment != null) {
             transaction.remove(oldFragment);
         }
         AddPrinterAlertDialogFragment newFragment = new AddPrinterAlertDialogFragment();
         Bundle arguments = new Bundle();
-        arguments.putParcelableArrayList(FRAGMRNT_ARGUMENT_PRINT_SERVICE_INFOS,
+        arguments.putParcelableArrayList(FRAGMENT_ARGUMENT_PRINT_SERVICE_INFOS,
                 mAddPrinterServices);
         newFragment.setArguments(arguments);
-        transaction.add(newFragment, FRAGMRNT_TAG_ADD_PRINTER_DIALOG);
+        transaction.add(newFragment, FRAGMENT_TAG_ADD_PRINTER_DIALOG);
         transaction.commit();
     }
 
     public void updateEmptyView(DestinationAdapter adapter) {
         if (mListView.getEmptyView() == null) {
-            View emptyView = getActivity().findViewById(R.id.empty_print_state);
+            View emptyView = findViewById(R.id.empty_print_state);
             mListView.setEmptyView(emptyView);
         }
-        TextView titleView = (TextView) getActivity().findViewById(R.id.title);
-        View progressBar = getActivity().findViewById(R.id.progress_bar);
+        TextView titleView = (TextView) findViewById(R.id.title);
+        View progressBar = findViewById(R.id.progress_bar);
         if (adapter.getUnfilteredCount() <= 0) {
             titleView.setText(R.string.print_searching_for_printers);
             progressBar.setVisibility(View.VISIBLE);
@@ -353,7 +334,7 @@
     }
 
     private void announceSearchResultIfNeeded() {
-        if (AccessibilityManager.getInstance(getActivity()).isEnabled()) {
+        if (AccessibilityManager.getInstance(this).isEnabled()) {
             if (mAnnounceFilterResult == null) {
                 mAnnounceFilterResult = new AnnounceFilterResult();
             }
@@ -372,9 +353,9 @@
                     .setTitle(R.string.choose_print_service);
 
             final List<PrintServiceInfo> printServices = (List<PrintServiceInfo>) (List<?>)
-                    getArguments().getParcelableArrayList(FRAGMRNT_ARGUMENT_PRINT_SERVICE_INFOS);
+                    getArguments().getParcelableArrayList(FRAGMENT_ARGUMENT_PRINT_SERVICE_INFOS);
 
-            final ArrayAdapter<String> adapter = new ArrayAdapter<String>(
+            final ArrayAdapter<String> adapter = new ArrayAdapter<>(
                     getActivity(), android.R.layout.simple_list_item_1);
             final int printServiceCount = printServices.size();
             for (int i = 0; i < printServiceCount; i++) {
@@ -382,32 +363,33 @@
                 adapter.add(printService.getResolveInfo().loadLabel(
                         getActivity().getPackageManager()).toString());
             }
+
             final String searchUri = Settings.Secure.getString(getActivity().getContentResolver(),
                     Settings.Secure.PRINT_SERVICE_SEARCH_URI);
-            final Intent marketIntent;
+            final Intent viewIntent;
             if (!TextUtils.isEmpty(searchUri)) {
                 Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(searchUri));
                 if (getActivity().getPackageManager().resolveActivity(intent, 0) != null) {
-                    marketIntent = intent;
+                    viewIntent = intent;
                     mAddPrintServiceItem = getString(R.string.add_print_service_label);
                     adapter.add(mAddPrintServiceItem);
                 } else {
-                    marketIntent = null;
+                    viewIntent = null;
                 }
             } else {
-                marketIntent = null;
+                viewIntent = null;
             }
 
             builder.setAdapter(adapter, new DialogInterface.OnClickListener() {
                 @Override
                 public void onClick(DialogInterface dialog, int which) {
                     String item = adapter.getItem(which);
-                    if (item == mAddPrintServiceItem) {
+                    if (item.equals(mAddPrintServiceItem)) {
                         try {
-                          startActivity(marketIntent);
-                      } catch (ActivityNotFoundException anfe) {
-                          Log.w(LOG_TAG, "Couldn't start add printer activity", anfe);
-                      }
+                            startActivity(viewIntent);
+                        } catch (ActivityNotFoundException anfe) {
+                            Log.w(LOG_TAG, "Couldn't start add printer activity", anfe);
+                        }
                     } else {
                         PrintServiceInfo printService = printServices.get(which);
                         ComponentName componentName = new ComponentName(
@@ -418,7 +400,7 @@
                         try {
                             startActivity(intent);
                         } catch (ActivityNotFoundException anfe) {
-                            Log.w(LOG_TAG, "Couldn't start settings activity", anfe);
+                            Log.w(LOG_TAG, "Couldn't start add printer activity", anfe);
                         }
                     }
                 }
@@ -428,19 +410,41 @@
         }
     }
 
-    private final class DestinationAdapter extends BaseAdapter
-            implements LoaderManager.LoaderCallbacks<List<PrinterInfo>>, Filterable {
+    private final class DestinationAdapter extends BaseAdapter implements Filterable {
 
         private final Object mLock = new Object();
 
-        private final List<PrinterInfo> mPrinters = new ArrayList<PrinterInfo>();
+        private final List<PrinterInfo> mPrinters = new ArrayList<>();
 
-        private final List<PrinterInfo> mFilteredPrinters = new ArrayList<PrinterInfo>();
+        private final List<PrinterInfo> mFilteredPrinters = new ArrayList<>();
 
         private CharSequence mLastSearchString;
 
         public DestinationAdapter() {
-            getLoaderManager().initLoader(LOADER_ID_PRINTERS_LOADER, null, this);
+            mPrinterRegistry.setOnPrintersChangeListener(new PrinterRegistry.OnPrintersChangeListener() {
+                @Override
+                public void onPrintersChanged(List<PrinterInfo> printers) {
+                    synchronized (mLock) {
+                        mPrinters.clear();
+                        mPrinters.addAll(printers);
+                        mFilteredPrinters.clear();
+                        mFilteredPrinters.addAll(printers);
+                        if (!TextUtils.isEmpty(mLastSearchString)) {
+                            getFilter().filter(mLastSearchString);
+                        }
+                    }
+                    notifyDataSetChanged();
+                }
+
+                @Override
+                public void onPrintersInvalid() {
+                    synchronized (mLock) {
+                        mPrinters.clear();
+                        mFilteredPrinters.clear();
+                    }
+                    notifyDataSetInvalidated();
+                }
+            });
         }
 
         @Override
@@ -453,7 +457,7 @@
                             return null;
                         }
                         FilterResults results = new FilterResults();
-                        List<PrinterInfo> filteredPrinters = new ArrayList<PrinterInfo>();
+                        List<PrinterInfo> filteredPrinters = new ArrayList<>();
                         String constraintLowerCase = constraint.toString().toLowerCase();
                         final int printerCount = mPrinters.size();
                         for (int i = 0; i < printerCount; i++) {
@@ -518,28 +522,27 @@
         }
 
         @Override
-        public View getDropDownView(int position, View convertView,
-                ViewGroup parent) {
+        public View getDropDownView(int position, View convertView, ViewGroup parent) {
             return getView(position, convertView, parent);
         }
 
         @Override
         public View getView(int position, View convertView, ViewGroup parent) {
             if (convertView == null) {
-                convertView = getActivity().getLayoutInflater().inflate(
+                convertView = getLayoutInflater().inflate(
                         R.layout.printer_list_item, parent, false);
             }
 
             convertView.setEnabled(isActionable(position));
 
-            CharSequence title = null;
+            PrinterInfo printer = (PrinterInfo) getItem(position);
+
+            CharSequence title = printer.getName();
             CharSequence subtitle = null;
             Drawable icon = null;
 
-            PrinterInfo printer = (PrinterInfo) getItem(position);
-            title = printer.getName();
             try {
-                PackageManager pm = getActivity().getPackageManager();
+                PackageManager pm = getPackageManager();
                 PackageInfo packageInfo = pm.getPackageInfo(printer.getId()
                         .getServiceName().getPackageName(), 0);
                 subtitle = packageInfo.applicationInfo.loadLabel(pm);
@@ -576,38 +579,6 @@
             PrinterInfo printer =  (PrinterInfo) getItem(position);
             return printer.getStatus() != PrinterInfo.STATUS_UNAVAILABLE;
         }
-
-        @Override
-        public Loader<List<PrinterInfo>> onCreateLoader(int id, Bundle args) {
-            if (id == LOADER_ID_PRINTERS_LOADER) {
-                return new FusedPrintersProvider(getActivity());
-            }
-            return null;
-        }
-
-        @Override
-        public void onLoadFinished(Loader<List<PrinterInfo>> loader,
-                List<PrinterInfo> printers) {
-            synchronized (mLock) {
-                mPrinters.clear();
-                mPrinters.addAll(printers);
-                mFilteredPrinters.clear();
-                mFilteredPrinters.addAll(printers);
-                if (!TextUtils.isEmpty(mLastSearchString)) {
-                    getFilter().filter(mLastSearchString);
-                }
-            }
-            notifyDataSetChanged();
-        }
-
-        @Override
-        public void onLoaderReset(Loader<List<PrinterInfo>> loader) {
-            synchronized (mLock) {
-                mPrinters.clear();
-                mFilteredPrinters.clear();
-            }
-            notifyDataSetInvalidated();
-        }
     }
 
     private final class AnnounceFilterResult implements Runnable {
@@ -629,7 +600,7 @@
             if (count <= 0) {
                 text = getString(R.string.print_no_printers);
             } else {
-                text = getActivity().getResources().getQuantityString(
+                text = getResources().getQuantityString(
                     R.plurals.print_search_result_count_utterance, count, count);
             }
             mListView.announceForAccessibility(text);
diff --git a/packages/PrintSpooler/src/com/android/printspooler/MediaSizeUtils.java b/packages/PrintSpooler/src/com/android/printspooler/util/MediaSizeUtils.java
similarity index 95%
rename from packages/PrintSpooler/src/com/android/printspooler/MediaSizeUtils.java
rename to packages/PrintSpooler/src/com/android/printspooler/util/MediaSizeUtils.java
index ac27562..912ee1d 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/MediaSizeUtils.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/util/MediaSizeUtils.java
@@ -14,22 +14,28 @@
  * limitations under the License.
  */
 
-package com.android.printspooler;
+package com.android.printspooler.util;
 
 import android.content.Context;
 import android.print.PrintAttributes.MediaSize;
 import android.util.ArrayMap;
 
+import com.android.printspooler.R;
+
 import java.util.Comparator;
 import java.util.Map;
 
 /**
  * Utility functions and classes for dealing with media sizes.
  */
-public class MediaSizeUtils {
+public final class MediaSizeUtils {
 
     private static Map<MediaSize, String> sMediaSizeToStandardMap;
 
+    private MediaSizeUtils() {
+        /* do nothing - hide constructor */
+    }
+
     /**
      * Gets the default media size for the current locale.
      *
diff --git a/packages/PrintSpooler/src/com/android/printspooler/util/PageRangeUtils.java b/packages/PrintSpooler/src/com/android/printspooler/util/PageRangeUtils.java
new file mode 100644
index 0000000..33b294f
--- /dev/null
+++ b/packages/PrintSpooler/src/com/android/printspooler/util/PageRangeUtils.java
@@ -0,0 +1,159 @@
+/*
+ * 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.printspooler.util;
+
+import android.print.PageRange;
+
+import java.util.Arrays;
+import java.util.Comparator;
+
+/**
+ * This class contains utility functions for working with page ranges.
+ */
+public final class PageRangeUtils {
+
+    private static final PageRange[] ALL_PAGES_RANGE = new PageRange[] {PageRange.ALL_PAGES};
+
+    private static final Comparator<PageRange> sComparator = new Comparator<PageRange>() {
+        @Override
+        public int compare(PageRange lhs, PageRange rhs) {
+            return lhs.getStart() - rhs.getStart();
+        }
+    };
+
+    private PageRangeUtils() {
+        /* do nothing - hide constructor */
+    }
+
+    /**
+     * Checks whether one page range array contains another one.
+     *
+     * @param ourRanges The container page ranges.
+     * @param otherRanges The contained page ranges.
+     * @return Whether the container page ranges contains the contained ones.
+     */
+    public static boolean contains(PageRange[] ourRanges, PageRange[] otherRanges) {
+        if (ourRanges == null || otherRanges == null) {
+            return false;
+        }
+
+        if (Arrays.equals(ourRanges, ALL_PAGES_RANGE)) {
+            return true;
+        }
+
+        ourRanges = normalize(ourRanges);
+        otherRanges = normalize(otherRanges);
+
+        // Note that the code below relies on the ranges being normalized
+        // which is they contain monotonically increasing non-intersecting
+        // sub-ranges whose start is less that or equal to the end.
+        int otherRangeIdx = 0;
+        final int ourRangeCount = ourRanges.length;
+        final int otherRangeCount = otherRanges.length;
+        for (int ourRangeIdx = 0; ourRangeIdx < ourRangeCount; ourRangeIdx++) {
+            PageRange ourRange = ourRanges[ourRangeIdx];
+            for (; otherRangeIdx < otherRangeCount; otherRangeIdx++) {
+                PageRange otherRange = otherRanges[otherRangeIdx];
+                if (otherRange.getStart() > ourRange.getEnd()) {
+                    break;
+                }
+                if (otherRange.getStart() < ourRange.getStart()
+                        || otherRange.getEnd() > ourRange.getEnd()) {
+                    return false;
+                }
+            }
+        }
+        if (otherRangeIdx < otherRangeCount) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Normalizes a page range, which is the resulting page ranges are
+     * non-overlapping with the start lesser than or equal to the end
+     * and ordered in an ascending order.
+     *
+     * @param pageRanges The page ranges to normalize.
+     * @return The normalized page ranges.
+     */
+    public static PageRange[] normalize(PageRange[] pageRanges) {
+        if (pageRanges == null) {
+            return null;
+        }
+        final int oldRangeCount = pageRanges.length;
+        if (oldRangeCount <= 1) {
+            return pageRanges;
+        }
+        Arrays.sort(pageRanges, sComparator);
+        int newRangeCount = 1;
+        for (int i = 0; i < oldRangeCount - 1; i++) {
+            newRangeCount++;
+            PageRange currentRange = pageRanges[i];
+            PageRange nextRange = pageRanges[i + 1];
+            if (currentRange.getEnd() + 1 >= nextRange.getStart()) {
+                newRangeCount--;
+                pageRanges[i] = null;
+                pageRanges[i + 1] = new PageRange(currentRange.getStart(),
+                        Math.max(currentRange.getEnd(), nextRange.getEnd()));
+            }
+        }
+        if (newRangeCount == oldRangeCount) {
+            return pageRanges;
+        }
+        return Arrays.copyOfRange(pageRanges, oldRangeCount - newRangeCount,
+                oldRangeCount);
+    }
+
+    /**
+     * Offsets a the start and end of page ranges with the given value.
+     *
+     * @param pageRanges The page ranges to offset.
+     * @param offset The offset value.
+     */
+    public static void offset(PageRange[] pageRanges, int offset) {
+        if (offset == 0) {
+            return;
+        }
+        final int pageRangeCount = pageRanges.length;
+        for (int i = 0; i < pageRangeCount; i++) {
+            final int start = pageRanges[i].getStart() + offset;
+            final int end = pageRanges[i].getEnd() + offset;
+            pageRanges[i] = new PageRange(start, end);
+        }
+    }
+
+    /**
+     * Gets the number of pages in a normalized range array.
+     *
+     * @param pageRanges Normalized page ranges.
+     * @param layoutPageCount Page count after reported after layout pass.
+     * @return The page count in the ranges.
+     */
+    public static int getNormalizedPageCount(PageRange[] pageRanges, int layoutPageCount) {
+        int pageCount = 0;
+        final int pageRangeCount = pageRanges.length;
+        for (int i = 0; i < pageRangeCount; i++) {
+            PageRange pageRange = pageRanges[i];
+            if (PageRange.ALL_PAGES.equals(pageRange)) {
+                return layoutPageCount;
+            }
+            pageCount += pageRange.getEnd() - pageRange.getStart() + 1;
+        }
+        return pageCount;
+    }
+}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/util/PrintOptionUtils.java b/packages/PrintSpooler/src/com/android/printspooler/util/PrintOptionUtils.java
new file mode 100644
index 0000000..446952d
--- /dev/null
+++ b/packages/PrintSpooler/src/com/android/printspooler/util/PrintOptionUtils.java
@@ -0,0 +1,56 @@
+/*
+ * 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.printspooler.util;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.ServiceInfo;
+import android.print.PrintManager;
+import android.printservice.PrintServiceInfo;
+
+import java.util.List;
+
+public class PrintOptionUtils {
+
+    private PrintOptionUtils() {
+        /* ignore - hide constructor */
+    }
+
+    /**
+     * Gets the advanced options activity name for a print service.
+     *
+     * @param context Context for accessing system resources.
+     * @param serviceName The print service name.
+     * @return The advanced options activity name or null.
+     */
+    public static String getAdvancedOptionsActivityName(Context context,
+            ComponentName serviceName) {
+        PrintManager printManager = (PrintManager) context.getSystemService(
+                Context.PRINT_SERVICE);
+        List<PrintServiceInfo> printServices = printManager.getEnabledPrintServices();
+        final int printServiceCount = printServices.size();
+        for (int i = 0; i < printServiceCount; i ++) {
+            PrintServiceInfo printServiceInfo = printServices.get(i);
+            ServiceInfo serviceInfo = printServiceInfo.getResolveInfo().serviceInfo;
+            if (serviceInfo.name.equals(serviceName.getClassName())
+                    && serviceInfo.packageName.equals(serviceName.getPackageName())) {
+                return printServiceInfo.getAdvancedOptionsActivityName();
+            }
+        }
+        return null;
+    }
+}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/widget/ContentView.java b/packages/PrintSpooler/src/com/android/printspooler/widget/ContentView.java
new file mode 100644
index 0000000..77ca541
--- /dev/null
+++ b/packages/PrintSpooler/src/com/android/printspooler/widget/ContentView.java
@@ -0,0 +1,338 @@
+/*
+ * 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.printspooler.widget;
+
+import android.content.Context;
+import android.support.v4.widget.ViewDragHelper;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import com.android.printspooler.R;
+
+/**
+ * This class is a layout manager for the print screen. It has a sliding
+ * area that contains the print options. If the sliding area is open the
+ * print options are visible and if it is closed a summary of the print
+ * job is shown. Under the sliding area there is a place for putting
+ * arbitrary content such as preview, error message, progress indicator,
+ * etc. The sliding area is covering the content holder under it when
+ * the former is opened.
+ */
+@SuppressWarnings("unused")
+public final class ContentView extends ViewGroup implements View.OnClickListener {
+    private static final int FIRST_POINTER_ID = 0;
+
+    private final ViewDragHelper mDragger;
+
+    private View mStaticContent;
+    private ViewGroup mSummaryContent;
+    private View mDynamicContent;
+
+    private View mDraggableContent;
+    private ViewGroup mMoreOptionsContainer;
+    private ViewGroup mOptionsContainer;
+
+    private View mEmbeddedContentContainer;
+
+    private View mExpandCollapseHandle;
+    private View mExpandCollapseIcon;
+
+    private int mClosedOptionsOffsetY;
+    private int mCurrentOptionsOffsetY;
+
+    private OptionsStateChangeListener mOptionsStateChangeListener;
+
+    private int mOldDraggableHeight;
+
+    public interface OptionsStateChangeListener {
+        public void onOptionsOpened();
+        public void onOptionsClosed();
+    }
+
+    public ContentView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        mDragger = ViewDragHelper.create(this, new DragCallbacks());
+
+        // The options view is sliding under the static header but appears
+        // after it in the layout, so we will draw in opposite order.
+        setChildrenDrawingOrderEnabled(true);
+    }
+
+    public void setOptionsStateChangeListener(OptionsStateChangeListener listener) {
+        mOptionsStateChangeListener = listener;
+    }
+
+    private boolean isOptionsOpened() {
+        return mCurrentOptionsOffsetY == 0;
+    }
+
+    private boolean isOptionsClosed() {
+        return mCurrentOptionsOffsetY == mClosedOptionsOffsetY;
+    }
+
+    private void openOptions() {
+        if (isOptionsOpened()) {
+            return;
+        }
+        mDragger.smoothSlideViewTo(mDynamicContent, mDynamicContent.getLeft(),
+                getOpenedOptionsY());
+        invalidate();
+    }
+
+    private void closeOptions() {
+        if (isOptionsClosed()) {
+            return;
+        }
+        mDragger.smoothSlideViewTo(mDynamicContent, mDynamicContent.getLeft(),
+                getClosedOptionsY());
+        invalidate();
+    }
+
+    @Override
+    protected int getChildDrawingOrder(int childCount, int i) {
+        return childCount - i - 1;
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        mStaticContent = findViewById(R.id.static_content);
+        mSummaryContent = (ViewGroup) findViewById(R.id.summary_content);
+        mDynamicContent = findViewById(R.id.dynamic_content);
+        mDraggableContent = findViewById(R.id.draggable_content);
+        mMoreOptionsContainer = (ViewGroup) findViewById(R.id.more_options_container);
+        mOptionsContainer = (ViewGroup) findViewById(R.id.options_container);
+        mEmbeddedContentContainer = findViewById(R.id.embedded_content_container);
+        mExpandCollapseIcon = findViewById(R.id.expand_collapse_icon);
+        mExpandCollapseHandle = findViewById(R.id.expand_collapse_handle);
+
+        mExpandCollapseIcon.setOnClickListener(this);
+        mExpandCollapseHandle.setOnClickListener(this);
+
+        // Make sure we start in a closed options state.
+        onDragProgress(1.0f);
+    }
+
+    @Override
+    public void onClick(View view) {
+        if (view == mExpandCollapseHandle || view == mExpandCollapseIcon) {
+            if (isOptionsClosed()) {
+                openOptions();
+            } else if (isOptionsOpened()) {
+                closeOptions();
+            } // else in open/close progress do nothing.
+        }
+    }
+
+    @Override
+    public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
+        /* do nothing */
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        mDragger.processTouchEvent(event);
+        return true;
+    }
+
+    @Override
+    public boolean onInterceptTouchEvent(MotionEvent event) {
+        return mDragger.shouldInterceptTouchEvent(event)
+                || super.onInterceptTouchEvent(event);
+    }
+
+    @Override
+    public void computeScroll() {
+        if (mDragger.continueSettling(true)) {
+            postInvalidateOnAnimation();
+        }
+    }
+
+    private int getOpenedOptionsY() {
+        return mStaticContent.getBottom();
+    }
+
+    private int getClosedOptionsY() {
+        return getOpenedOptionsY() + mClosedOptionsOffsetY;
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        measureChild(mStaticContent, widthMeasureSpec, heightMeasureSpec);
+
+        if (mSummaryContent.getVisibility() != View.GONE) {
+            measureChild(mSummaryContent, widthMeasureSpec, heightMeasureSpec);
+        }
+
+        measureChild(mDynamicContent, widthMeasureSpec, heightMeasureSpec);
+
+        final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
+
+//        // The height of the draggable content may change and if that happens
+//        // we have to adjust the current offset to ensure the sliding area is
+//        // at the same position.
+//        mCurrentOptionsOffsetY -= mDraggableContent.getMeasuredHeight()
+//                - oldDraggableHeight;
+
+        if (mOldDraggableHeight != mDraggableContent.getMeasuredHeight()) {
+            mCurrentOptionsOffsetY -= mDraggableContent.getMeasuredHeight()
+                    - mOldDraggableHeight;
+            mOldDraggableHeight = mDraggableContent.getMeasuredHeight();
+        }
+
+        // The height of the draggable content may change and if that happens
+        // we have to adjust the sliding area closed state offset.
+        mClosedOptionsOffsetY = mSummaryContent.getMeasuredHeight()
+                - mDraggableContent.getMeasuredHeight();
+
+        // The content host must be maximally large size that fits entirely
+        // on the screen when the options are collapsed.
+        ViewGroup.LayoutParams params = mEmbeddedContentContainer.getLayoutParams();
+        if (params.height == 0) {
+            params.height = heightSize - mStaticContent.getMeasuredHeight()
+                    - mSummaryContent.getMeasuredHeight() - mDynamicContent.getMeasuredHeight()
+                    + mDraggableContent.getMeasuredHeight();
+
+            mCurrentOptionsOffsetY = mClosedOptionsOffsetY;
+        }
+
+        // The content host can grow vertically as much as needed - we will be covering it.
+        final int hostHeightMeasureSpec = MeasureSpec.makeMeasureSpec(MeasureSpec.UNSPECIFIED, 0);
+        measureChild(mEmbeddedContentContainer, widthMeasureSpec, hostHeightMeasureSpec);
+
+        setMeasuredDimension(resolveSize(MeasureSpec.getSize(widthMeasureSpec), widthMeasureSpec),
+                resolveSize(heightSize, heightMeasureSpec));
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        mStaticContent.layout(left, top, right, mStaticContent.getMeasuredHeight());
+
+        if (mSummaryContent.getVisibility() != View.GONE) {
+            mSummaryContent.layout(left, mStaticContent.getMeasuredHeight(), right,
+                    mStaticContent.getMeasuredHeight() + mSummaryContent.getMeasuredHeight());
+        }
+
+        final int dynContentTop = mStaticContent.getMeasuredHeight() + mCurrentOptionsOffsetY;
+        final int dynContentBottom = dynContentTop + mDynamicContent.getMeasuredHeight();
+
+        mDynamicContent.layout(left, dynContentTop, right, dynContentBottom);
+
+        final int embContentTop = mStaticContent.getMeasuredHeight() + mClosedOptionsOffsetY
+                + mDynamicContent.getMeasuredHeight();
+        final int embContentBottom = embContentTop + mEmbeddedContentContainer.getMeasuredHeight();
+
+        mEmbeddedContentContainer.layout(left, embContentTop, right, embContentBottom);
+    }
+
+    private void onDragProgress(float progress) {
+        final int summaryCount = mSummaryContent.getChildCount();
+        for (int i = 0; i < summaryCount; i++) {
+            View child = mSummaryContent.getChildAt(i);
+            child.setAlpha(progress);
+        }
+
+        if (progress == 0) {
+            if (mOptionsStateChangeListener != null) {
+                mOptionsStateChangeListener.onOptionsOpened();
+            }
+            mSummaryContent.setVisibility(View.GONE);
+            mExpandCollapseIcon.setBackgroundResource(R.drawable.ic_expand_less);
+        } else {
+            mSummaryContent.setVisibility(View.VISIBLE);
+        }
+
+        final float inverseAlpha = 1.0f - progress;
+
+        final int optionCount = mOptionsContainer.getChildCount();
+        for (int i = 0; i < optionCount; i++) {
+            View child = mOptionsContainer.getChildAt(i);
+            child.setAlpha(inverseAlpha);
+        }
+
+        if (mMoreOptionsContainer.getVisibility() != View.GONE) {
+            final int moreOptionCount = mMoreOptionsContainer.getChildCount();
+            for (int i = 0; i < moreOptionCount; i++) {
+                View child = mMoreOptionsContainer.getChildAt(i);
+                child.setAlpha(inverseAlpha);
+            }
+        }
+
+        if (inverseAlpha == 0) {
+            if (mOptionsStateChangeListener != null) {
+                mOptionsStateChangeListener.onOptionsClosed();
+            }
+            if (mMoreOptionsContainer.getVisibility() != View.GONE) {
+                mMoreOptionsContainer.setVisibility(View.INVISIBLE);
+            }
+            mDraggableContent.setVisibility(View.INVISIBLE);
+            mExpandCollapseIcon.setBackgroundResource(R.drawable.ic_expand_more);
+        } else {
+            if (mMoreOptionsContainer.getVisibility() != View.GONE) {
+                mMoreOptionsContainer.setVisibility(View.VISIBLE);
+            }
+            mDraggableContent.setVisibility(View.VISIBLE);
+        }
+    }
+
+    private final class DragCallbacks extends ViewDragHelper.Callback {
+        @Override
+        public boolean tryCaptureView(View child, int pointerId) {
+            return child == mDynamicContent && pointerId == FIRST_POINTER_ID;
+        }
+
+        @Override
+        public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
+            mCurrentOptionsOffsetY += dy;
+            final float progress = ((float) top - getOpenedOptionsY())
+                    / (getClosedOptionsY() - getOpenedOptionsY());
+
+            mDraggableContent.notifySubtreeAccessibilityStateChangedIfNeeded();
+
+            onDragProgress(progress);
+        }
+
+        public void onViewReleased(View child, float velocityX, float velocityY) {
+            final int childTop = child.getTop();
+
+            final int openedOptionsY = getOpenedOptionsY();
+            final int closedOptionsY = getClosedOptionsY();
+
+            if (childTop == openedOptionsY || childTop == closedOptionsY) {
+                return;
+            }
+
+            final int halfRange = closedOptionsY + (openedOptionsY - closedOptionsY) / 2;
+            if (childTop < halfRange) {
+                mDragger.smoothSlideViewTo(child, child.getLeft(), closedOptionsY);
+            } else {
+                mDragger.smoothSlideViewTo(child, child.getLeft(), openedOptionsY);
+            }
+
+            invalidate();
+        }
+
+        public int getViewVerticalDragRange(View child) {
+            return mDraggableContent.getHeight();
+        }
+
+        public int clampViewPositionVertical(View child, int top, int dy) {
+            final int staticOptionBottom = mStaticContent.getBottom();
+            return Math.max(Math.min(top, getOpenedOptionsY()), getClosedOptionsY());
+        }
+    }
+}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/widget/FirstFocusableEditText.java b/packages/PrintSpooler/src/com/android/printspooler/widget/FirstFocusableEditText.java
new file mode 100644
index 0000000..d6bb7c8
--- /dev/null
+++ b/packages/PrintSpooler/src/com/android/printspooler/widget/FirstFocusableEditText.java
@@ -0,0 +1,69 @@
+/*
+ * 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.printspooler.widget;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.widget.EditText;
+
+/**
+ * An instance of this class class is intended to be the first focusable
+ * in a layout to which the system automatically gives focus. It performs
+ * some voodoo to avoid the first tap on it to start an edit mode, rather
+ * to bring up the IME, i.e. to get the behavior as if the view was not
+ * focused.
+ */
+public final class FirstFocusableEditText extends EditText {
+    private boolean mClickedBeforeFocus;
+    private CharSequence mError;
+
+    public FirstFocusableEditText(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    public boolean performClick() {
+        super.performClick();
+        if (isFocused() && !mClickedBeforeFocus) {
+            clearFocus();
+            requestFocus();
+        }
+        mClickedBeforeFocus = true;
+        return true;
+    }
+
+    @Override
+    public CharSequence getError() {
+        return mError;
+    }
+
+    @Override
+    public void setError(CharSequence error, Drawable icon) {
+        setCompoundDrawables(null, null, icon, null);
+        mError = error;
+    }
+
+    protected void onFocusChanged(boolean gainFocus, int direction,
+            Rect previouslyFocusedRect) {
+        if (!gainFocus) {
+            mClickedBeforeFocus = false;
+        }
+        super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
+    }
+}
\ No newline at end of file
diff --git a/packages/PrintSpooler/src/com/android/printspooler/widget/PrintOptionsLayout.java b/packages/PrintSpooler/src/com/android/printspooler/widget/PrintOptionsLayout.java
new file mode 100644
index 0000000..23c8d08
--- /dev/null
+++ b/packages/PrintSpooler/src/com/android/printspooler/widget/PrintOptionsLayout.java
@@ -0,0 +1,166 @@
+/*
+ * 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.printspooler.widget;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+import com.android.printspooler.R;
+
+/**
+ * This class is a layout manager for the print options. The options are
+ * arranged in a configurable number of columns and enough rows to fit all
+ * the options given the column count.
+ */
+@SuppressWarnings("unused")
+public final class PrintOptionsLayout extends ViewGroup {
+
+    private final int mColumnCount;
+
+    public PrintOptionsLayout(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+        TypedArray typedArray = context.obtainStyledAttributes(attrs,
+                R.styleable.PrintOptionsLayout);
+        mColumnCount = typedArray.getInteger(R.styleable.PrintOptionsLayout_columnCount, 0);
+        typedArray.recycle();
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
+        final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
+
+        final int columnWidth = (widthSize != 0)
+                ? (widthSize - mPaddingLeft - mPaddingRight) / mColumnCount : 0;
+
+        int width = 0;
+        int height = 0;
+        int childState = 0;
+
+        final int childCount = getChildCount();
+        final int rowCount = childCount / mColumnCount + childCount % mColumnCount;
+
+        for (int row = 0; row < rowCount; row++) {
+            int rowWidth = 0;
+            int rowHeight = 0;
+
+            for (int col = 0; col < mColumnCount; col++) {
+                final int childIndex = row * mColumnCount + col;
+
+                if (childIndex >= childCount) {
+                    break;
+                }
+
+                View child = getChildAt(childIndex);
+
+                if (child.getVisibility() == GONE) {
+                    continue;
+                }
+
+                MarginLayoutParams childParams = (MarginLayoutParams) child.getLayoutParams();
+
+                final int childWidthMeasureSpec;
+                if (columnWidth > 0) {
+                    childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
+                            columnWidth - childParams.getMarginStart() - childParams.getMarginEnd(),
+                            MeasureSpec.EXACTLY);
+                } else {
+                    childWidthMeasureSpec = getChildMeasureSpec(heightMeasureSpec,
+                            getPaddingStart() + getPaddingEnd() + width, childParams.width);
+                }
+
+                final int childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec,
+                        getPaddingTop() + getPaddingBottom() + height, childParams.height);
+
+                child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+
+                childState = combineMeasuredStates(childState, child.getMeasuredState());
+
+                rowWidth += child.getMeasuredWidth() + childParams.getMarginStart()
+                        + childParams.getMarginEnd();
+
+                rowHeight = Math.max(rowHeight, child.getMeasuredHeight() + childParams.topMargin
+                        + childParams.bottomMargin);
+            }
+
+            width = Math.max(width, rowWidth);
+            height += rowHeight;
+        }
+
+        width += getPaddingStart() + getPaddingEnd();
+        width = Math.max(width, getMinimumWidth());
+
+        height += getPaddingTop() + getPaddingBottom();
+        height = Math.max(height, getMinimumHeight());
+
+        setMeasuredDimension(resolveSizeAndState(width, widthMeasureSpec, childState),
+                resolveSizeAndState(height, heightMeasureSpec,
+                        childState << MEASURED_HEIGHT_STATE_SHIFT));
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int l, int t, int r, int b) {
+        final int childCount = getChildCount();
+        final int rowCount = childCount / mColumnCount + childCount % mColumnCount;
+
+        int cellStart = getPaddingStart();
+        int cellTop = getPaddingTop();
+
+        for (int row = 0; row < rowCount; row++) {
+            int rowHeight = 0;
+
+            for (int col = 0; col < mColumnCount; col++) {
+                final int childIndex = row * mColumnCount + col;
+
+                if (childIndex >= childCount) {
+                    break;
+                }
+
+                View child = getChildAt(childIndex);
+
+                if (child.getVisibility() == GONE) {
+                    continue;
+                }
+
+                MarginLayoutParams childParams = (MarginLayoutParams) child.getLayoutParams();
+
+                final int childLeft = cellStart + childParams.getMarginStart();
+                final int childTop = cellTop + childParams.topMargin;
+                final int childRight = childLeft + child.getMeasuredWidth();
+                final int childBottom = childTop + child.getMeasuredHeight();
+
+                child.layout(childLeft, childTop, childRight, childBottom);
+
+                cellStart = childRight + childParams.getMarginEnd();
+
+                rowHeight = Math.max(rowHeight, child.getMeasuredHeight()
+                        + childParams.topMargin + childParams.bottomMargin);
+            }
+
+            cellStart = getPaddingStart();
+            cellTop += cellTop + rowHeight;
+        }
+    }
+
+    @Override
+    public LayoutParams generateLayoutParams(AttributeSet attrs) {
+        return new ViewGroup.MarginLayoutParams(getContext(), attrs);
+    }
+}
diff --git a/packages/SystemUI/res/drawable-hdpi/recents_nav_bar_background.9.png b/packages/SystemUI/res/drawable-hdpi/recents_nav_bar_background.9.png
new file mode 100644
index 0000000..6cd1176
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/recents_nav_bar_background.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_bluetooth.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_bluetooth.png
deleted file mode 100644
index 7ed4c78..0000000
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_bluetooth.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_bluetooth_connected.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_bluetooth_connected.png
deleted file mode 100644
index 08c07b2..0000000
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_bluetooth_connected.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/recents_nav_bar_background.9.png b/packages/SystemUI/res/drawable-mdpi/recents_nav_bar_background.9.png
new file mode 100644
index 0000000..7237f09
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/recents_nav_bar_background.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_bluetooth.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_bluetooth.png
deleted file mode 100644
index bd4e1ae..0000000
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_bluetooth.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_bluetooth_connected.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_bluetooth_connected.png
deleted file mode 100644
index e82c6e4..0000000
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_bluetooth_connected.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/recents_nav_bar_background.9.png b/packages/SystemUI/res/drawable-xhdpi/recents_nav_bar_background.9.png
new file mode 100644
index 0000000..8d56a1d
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/recents_nav_bar_background.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_bluetooth.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_bluetooth.png
deleted file mode 100644
index 757dbf3..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_bluetooth.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_bluetooth_connected.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_bluetooth_connected.png
deleted file mode 100644
index d431dc2..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_bluetooth_connected.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/recents_nav_bar_background.9.png b/packages/SystemUI/res/drawable-xxhdpi/recents_nav_bar_background.9.png
new file mode 100644
index 0000000..aed300b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/recents_nav_bar_background.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_bluetooth.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_bluetooth.png
deleted file mode 100644
index 17ffdb9..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_bluetooth.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_bluetooth_connected.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_bluetooth_connected.png
deleted file mode 100644
index 6ec234e..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_bluetooth_connected.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_06.xml b/packages/SystemUI/res/drawable/ic_qs_location_06.xml
index 25c9ae5..5642a8a2 100644
--- a/packages/SystemUI/res/drawable/ic_qs_location_06.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_location_06.xml
@@ -27,7 +27,5 @@
         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:strokeWidth=".35"
-        android:fill="#00000000"
-        android:stroke="#CCCCCC"/>
+        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
index a69c3a2..1ad2ebc 100644
--- a/packages/SystemUI/res/drawable/ic_qs_location_07.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_location_07.xml
@@ -24,7 +24,5 @@
 
     <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:strokeWidth="0.65"
-        android:fill="#00000000"
-        android:stroke="#CCCCCC"/>
+        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
index c89c047..179bc66 100644
--- a/packages/SystemUI/res/drawable/ic_qs_location_08.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_location_08.xml
@@ -24,7 +24,5 @@
 
     <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:strokeWidth="0.8"
-        android:fill="#00000000"
-        android:stroke="#CCCCCC"/>
+        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
index 96bb6ce..6169af5 100644
--- a/packages/SystemUI/res/drawable/ic_qs_location_09.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_location_09.xml
@@ -24,7 +24,5 @@
 
     <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:strokeWidth="0.9"
-        android:fill="#00000000"
-        android:stroke="#CCCCCC"/>
+        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
index aced4bd..93e2eb4 100644
--- a/packages/SystemUI/res/drawable/ic_qs_location_10.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_location_10.xml
@@ -24,7 +24,5 @@
 
     <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:strokeWidth="0.95"
-        android:fill="#00000000"
-        android:stroke="#CCCCCC"/>
+        android:fill="#4DFFFFFF"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_11.xml b/packages/SystemUI/res/drawable/ic_qs_location_11.xml
index 578308e..09a3e63 100644
--- a/packages/SystemUI/res/drawable/ic_qs_location_11.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_location_11.xml
@@ -24,7 +24,5 @@
 
     <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="#00000000"
-        android:stroke="#CCCCCC"
-        android:strokeWidth="1.0"/>
+        android:fill="#4DFFFFFF"/>
 </vector>
diff --git a/core/res/res/layout/notification_quantum_media_action.xml b/packages/SystemUI/res/drawable/keyguard_overflow_number_background.xml
similarity index 67%
copy from core/res/res/layout/notification_quantum_media_action.xml
copy to packages/SystemUI/res/drawable/keyguard_overflow_number_background.xml
index 17f0848..b812d43 100644
--- a/core/res/res/layout/notification_quantum_media_action.xml
+++ b/packages/SystemUI/res/drawable/keyguard_overflow_number_background.xml
@@ -15,11 +15,7 @@
   ~ limitations under the License
   -->
 
-<ImageButton xmlns:android="http://schemas.android.com/apk/res/android"
-    style="@android:style/Widget.Quantum.Light.Button.Borderless.Small"
-    android:id="@+id/action0"
-    android:layout_width="60dp"
-    android:layout_height="match_parent"
-    android:layout_weight="1"
-    android:gravity="center"
-    />
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="oval">
+    <solid android:color="#1a000000" />
+</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/qs_panel_background.xml b/packages/SystemUI/res/drawable/qs_panel_background.xml
index a1a5362..74876f7 100644
--- a/packages/SystemUI/res/drawable/qs_panel_background.xml
+++ b/packages/SystemUI/res/drawable/qs_panel_background.xml
@@ -16,5 +16,5 @@
 <shape xmlns:android="http://schemas.android.com/apk/res/android">
     <solid android:color="@color/system_primary_color" />
     <corners
-        android:radius="@*android:dimen/notification_quantum_rounded_rect_radius"/>
+        android:radius="@*android:dimen/notification_material_rounded_rect_radius"/>
 </shape>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth.xml
new file mode 100644
index 0000000..e28490b
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth.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="18dp"
+        android:height="18dp"/>
+
+    <viewport
+        android:viewportWidth="48.0"
+        android:viewportHeight="48.0"/>
+
+    <path
+        android:fill="#FFFFFFFF"
+        android:pathData="M35.4,15.4L24.0,4.0l-2.0,0.0l0.0,15.2L12.8,10.0L10.0,12.8L21.2,24.0L10.0,35.2l2.8,2.8l9.2,-9.2L22.0,44.0l2.0,0.0l11.4,-11.4L26.8,24.0L35.4,15.4zM26.0,11.7l3.8,3.8L26.0,19.2L26.0,11.7zM29.8,32.6L26.0,36.3l0.0,-7.5L29.8,32.6z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected.xml
new file mode 100644
index 0000000..c012d14
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected.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="18dp"
+        android:height="18dp"/>
+
+    <viewport
+        android:viewportWidth="48.0"
+        android:viewportHeight="48.0"/>
+
+    <path
+        android:fill="#FFFFFFFF"
+        android:pathData="M14.0,24.0l-4.0,-4.0l-4.0,4.0l4.0,4.0L14.0,24.0zM35.4,15.4L24.0,4.0l-2.0,0.0l0.0,15.2L12.8,10.0L10.0,12.8L21.2,24.0L10.0,35.2l2.8,2.8l9.2,-9.2L22.0,44.0l2.0,0.0l11.4,-11.4L26.8,24.0L35.4,15.4zM26.0,11.7l3.8,3.8L26.0,19.2L26.0,11.7zM29.8,32.6L26.0,36.3l0.0,-7.5L29.8,32.6zM38.0,20.0l-4.0,4.0l4.0,4.0l4.0,-4.0L38.0,20.0z"/>
+</vector>
diff --git a/core/res/res/color/btn_default_quantum_dark.xml b/packages/SystemUI/res/layout/recents_nav_bar_scrim.xml
similarity index 68%
copy from core/res/res/color/btn_default_quantum_dark.xml
copy to packages/SystemUI/res/layout/recents_nav_bar_scrim.xml
index ec0f140..463fee8 100644
--- a/core/res/res/color/btn_default_quantum_dark.xml
+++ b/packages/SystemUI/res/layout/recents_nav_bar_scrim.xml
@@ -14,7 +14,10 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_enabled="false" android:alpha="0.5" android:color="@color/button_quantum_dark"/>
-    <item android:color="@color/button_quantum_dark"/>
-</selector>
+<ImageView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:layout_gravity="center_horizontal|bottom"
+    android:scaleType="fitXY"
+    android:src="@drawable/recents_nav_bar_background" />
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/status_bar_expanded_header.xml b/packages/SystemUI/res/layout/status_bar_expanded_header.xml
index 7f34041..693d8c3 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded_header.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded_header.xml
@@ -75,7 +75,7 @@
         />
 
     <ImageButton android:id="@+id/settings_button"
-        style="@android:style/Widget.Quantum.Button.Borderless"
+        style="@android:style/Widget.Material.Button.Borderless"
         android:layout_toStartOf="@id/multi_user_switch"
         android:layout_width="56dp"
         android:layout_height="@dimen/status_bar_header_height"
diff --git a/packages/SystemUI/res/layout/status_bar_notification_keyguard_overflow.xml b/packages/SystemUI/res/layout/status_bar_notification_keyguard_overflow.xml
index f867068..c442f79 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_keyguard_overflow.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_keyguard_overflow.xml
@@ -32,20 +32,20 @@
         />
     <TextView
         android:id="@+id/more_text"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
+        android:layout_width="32dp"
+        android:layout_height="32dp"
+        android:layout_marginStart="20dp"
         android:layout_gravity="center_vertical"
-        android:gravity="center_horizontal"
-        android:textColor="@color/keyguard_overflow_content_color"
-        android:textAllCaps="true"
-        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:background="@drawable/keyguard_overflow_number_background"
+        android:gravity="center"
+        android:textColor="#ff686868"
+        android:textStyle="bold"
+        android:textSize="14dp"
         />
     <com.android.systemui.statusbar.NotificationOverflowIconsView
         android:id="@+id/overflow_icons_view"
-        android:layout_gravity="end|center_vertical"
-        android:gravity="end"
-        android:paddingLeft="8dp"
-        android:paddingRight="8dp"
+        android:layout_gravity="center_vertical"
+        android:layout_marginStart="68dp"
         android:layout_width="120dp"
         android:layout_height="wrap_content"
         />
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 ff8800c..84d64b9 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_speed_bump.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_speed_bump.xml
@@ -28,7 +28,7 @@
             android:layout_height="@dimen/speed_bump_height_collapsed"
             android:layout_gravity="top"
             android:orientation="horizontal">
-        <View
+        <com.android.systemui.statusbar.AlphaOptimizedView
             android:id="@+id/speedbump_line_left"
             android:layout_width="0dp"
             android:layout_height="1dp"
@@ -42,7 +42,7 @@
                 android:layout_marginEnd="8dp"
                 android:layout_height="match_parent"
                 android:layout_weight="0"/>
-        <View
+        <com.android.systemui.statusbar.AlphaOptimizedView
             android:id="@+id/speedbump_line_right"
             android:layout_width="0dp"
             android:layout_height="1dp"
diff --git a/packages/SystemUI/res/layout/status_bar_toggle_slider.xml b/packages/SystemUI/res/layout/status_bar_toggle_slider.xml
index 7671c354a..1928506 100644
--- a/packages/SystemUI/res/layout/status_bar_toggle_slider.xml
+++ b/packages/SystemUI/res/layout/status_bar_toggle_slider.xml
@@ -28,7 +28,7 @@
         android:layout_alignParentTop="true"
         android:layout_alignParentBottom="true"
         android:button="@null"
-        android:background="@*android:drawable/switch_track_quantum"
+        android:background="@*android:drawable/switch_track_material"
         android:visibility="gone"
         />
     <com.android.systemui.settings.ToggleSeekBar
diff --git a/packages/SystemUI/res/layout/volume_panel_item.xml b/packages/SystemUI/res/layout/volume_panel_item.xml
index 4a2a0c0..6e5ab47 100644
--- a/packages/SystemUI/res/layout/volume_panel_item.xml
+++ b/packages/SystemUI/res/layout/volume_panel_item.xml
@@ -35,7 +35,6 @@
             android:layout_height="wrap_content"
             android:layout_weight="1">
         <SeekBar
-                style="?android:attr/seekBarStyle"
                 android:id="@+id/seekbar"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 757d4ad..bcd37bd 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -46,7 +46,7 @@
     <drawable name="notification_item_background_color_pressed">#ff454545</drawable>
 
     <!-- Tint color for the content on the notification overflow card. -->
-    <color name="keyguard_overflow_content_color">#ff666666</color>
+    <color name="keyguard_overflow_content_color">#ff686868</color>
 
     <!-- The color of the red speed bump dot -->
     <color name="speed_bump_dot_red">#ffd50000</color>
@@ -77,7 +77,7 @@
 
     <color name="keyguard_affordance">#ffffffff</color>
 
-    <!-- Our quantum color palette (deep teal) -->
+    <!-- Our material color palette (deep teal) -->
     <color name="primary_color">#ff7fcac3</color>
     <color name="background_color_1">#ff384248</color>
     <color name="background_color_1_press">#ff54656e</color>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 0184df2..79a1df4 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -113,17 +113,20 @@
     <!-- The min animation duration for animating views that are newly visible. -->
     <integer name="recents_filter_animate_new_views_min_duration">125</integer>
     <!-- The min animation duration for animating the task bar in. -->
-    <integer name="recents_animate_task_bar_enter_duration">300</integer>
+    <integer name="recents_animate_task_bar_enter_duration">250</integer>
+    <!-- The animation delay for animating the first task in. This should roughly be the animation
+     duration of the transition in to recents. -->
+    <integer name="recents_animate_task_bar_enter_delay">225</integer>
     <!-- The min animation duration for animating the task bar out. -->
-    <integer name="recents_animate_task_bar_exit_duration">150</integer>
-    <!-- The animation duration for animating in the info pane. -->
-    <integer name="recents_animate_task_view_info_pane_duration">150</integer>
+    <integer name="recents_animate_task_bar_exit_duration">125</integer>
+    <!-- The min animation duration for animating the nav bar scrim in. -->
+    <integer name="recents_nav_bar_scrim_enter_duration">400</integer>
     <!-- The animation duration for animating the removal of a task view. -->
     <integer name="recents_animate_task_view_remove_duration">250</integer>
     <!-- The minimum alpha for the dim applied to cards that go deeper into the stack. -->
     <integer name="recents_max_task_stack_view_dim">96</integer>
-    <!-- Transposes the search bar layout in landscape -->
-    <bool name="recents_transpose_search_layout_with_orientation">true</bool>
+    <!-- Transposes the recents layout in landscape. -->
+    <bool name="recents_transpose_layout_with_orientation">true</bool>
 
     <!-- Whether to enable KeyguardService or not -->
     <bool name="config_enableKeyguardService">true</bool>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 60a5643..35bc7e3 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -83,7 +83,7 @@
     <dimen name="notification_mid_height">128dp</dimen>
 
     <!-- Height of a the summary ("more card") notification on keyguard. -->
-    <dimen name="notification_summary_height">40dp</dimen>
+    <dimen name="notification_summary_height">44dp</dimen>
 
     <!-- size at which Notification icons will be drawn in the status bar -->
     <dimen name="status_bar_icon_drawing_size">18dip</dimen>
@@ -272,6 +272,9 @@
     <!-- The padding between the individual notification cards. -->
     <dimen name="notification_padding">4dp</dimen>
 
+    <!-- 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>
 
@@ -322,6 +325,17 @@
     <!-- Distance between notifications and header when they are considered to be colliding. -->
     <dimen name="header_notifications_collide_distance">24dp</dimen>
 
-    <!-- Move distance for the hint animations on the lockscreen (unlock, phone, camera)-->
+    <!-- Distance the user needs to drag vertically such that a swipe is accepted to unlock the
+         device. -->
+    <dimen name="unlock_move_distance">75dp</dimen>
+
+    <!-- Move distance for the unlock hint animation on the lockscreen -->
     <dimen name="hint_move_distance">75dp</dimen>
+
+    <!-- Move distance for the other hint animations on the lockscreen (phone, camera)-->
+    <dimen name="hint_move_distance_sideways">60dp</dimen>
+
+    <!-- The width of the region on the left/right edge of the screen for performing the camera/
+         phone hints. -->
+    <dimen name="edge_tap_area_width">48dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values/internal.xml b/packages/SystemUI/res/values/internal.xml
index ddaab942..7b93d31 100644
--- a/packages/SystemUI/res/values/internal.xml
+++ b/packages/SystemUI/res/values/internal.xml
@@ -17,6 +17,6 @@
 <resources>
     <dimen name="status_bar_height">@*android:dimen/status_bar_height</dimen>
     <dimen name="navigation_bar_height">@*android:dimen/navigation_bar_height</dimen>
-    <drawable name="notification_quantum_bg">@*android:drawable/notification_quantum_bg</drawable>
+    <drawable name="notification_material_bg">@*android:drawable/notification_material_bg</drawable>
 </resources>
 
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 373f11f..de297e5 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -471,13 +471,13 @@
     <!-- QuickSettings: Brightness [CHAR LIMIT=NONE] -->
     <string name="quick_settings_brightness_label">Brightness</string>
     <!-- QuickSettings: Rotation Unlocked [CHAR LIMIT=NONE] -->
-    <string name="quick_settings_rotation_unlocked_label">Auto Rotate</string>
+    <string name="quick_settings_rotation_unlocked_label">Auto-rotate</string>
     <!-- QuickSettings: Rotation Locked [CHAR LIMIT=NONE] -->
-    <string name="quick_settings_rotation_locked_label">Rotation Locked</string>
+    <string name="quick_settings_rotation_locked_label">Rotation locked</string>
     <!-- QuickSettings: Locked to Portrait [CHAR LIMIT=NONE] -->
-    <string name="quick_settings_rotation_locked_portrait_label">Locked to Portrait</string>
+    <string name="quick_settings_rotation_locked_portrait_label">Portrait</string>
     <!-- QuickSettings: Locked to Landscape [CHAR LIMIT=NONE] -->
-    <string name="quick_settings_rotation_locked_landscape_label">Locked to Landscape</string>
+    <string name="quick_settings_rotation_locked_landscape_label">Landscape</string>
     <!-- QuickSettings: IME [CHAR LIMIT=NONE] -->
     <string name="quick_settings_ime_label">Input Method</string>
     <!-- QuickSettings: Location [CHAR LIMIT=NONE] -->
@@ -505,7 +505,7 @@
     <!-- QuickSettings: Wifi (Off) [CHAR LIMIT=NONE] -->
     <string name="quick_settings_wifi_off_label">Wi-Fi Off</string>
     <!-- QuickSettings: Remote display [CHAR LIMIT=NONE] -->
-    <string name="quick_settings_remote_display_no_connection_label">Cast Screen</string>
+    <string name="quick_settings_remote_display_no_connection_label">Cast screen</string>
     <!-- QuickSettings: Brightness dialog title [CHAR LIMIT=NONE] -->
     <string name="quick_settings_brightness_dialog_title">Brightness</string>
     <!-- QuickSettings: Brightness dialog auto brightness button [CHAR LIMIT=NONE] -->
@@ -558,10 +558,8 @@
     <!-- Zen mode: Short title. [CHAR LIMIT=40] -->
     <string name="zen_mode_title">Do not disturb</string>
 
-    <!-- Text for overflow card on Keyguard when there is not enough space for all notifications on Keyguard. [CHAR LIMIT=12] -->
-    <plurals name="keyguard_more_overflow_text">
-        <item quantity="other">%d more</item>
-    </plurals>
+    <!-- Text for overflow card on Keyguard when there is not enough space for all notifications on Keyguard. [CHAR LIMIT=1] -->
+    <string name="keyguard_more_overflow_text">+<xliff:g id="number_of_notifications" example="5">%d</xliff:g></string>
 
     <!-- An explanation for the visual speed bump in the notifications, which will appear when you click on it. [CHAR LIMIT=50] -->
     <string name="speed_bump_explanation">Less urgent notifications below</string>
@@ -572,11 +570,20 @@
     <!-- Shows when people have pressed the unlock icon to explain how to unlock. [CHAR LIMIT=60] -->
     <string name="keyguard_unlock">Swipe up to unlock</string>
 
+    <!-- Shows when people have clicked at the left edge of the screen to explain how to open the phone. In right-to-left languages, this is the opposite direction. [CHAR LIMIT=60] -->
+    <string name="phone_hint">Swipe right for phone</string>
+
+    <!-- Shows when people have clicked at the right edge of the screen to explain how to open the phone. In right-to-left languages, this is the opposite direction. [CHAR LIMIT=60] -->
+    <string name="camera_hint">Swipe left for camera</string>
+
     <string name="bugreport_tile_extended" translatable="false">%s\n%s (%s)</string>
 
     <!-- Zen mode condition: no exit criteria. [CHAR LIMIT=NONE] -->
     <string name="zen_mode_forever">Until you turn this off</string>
 
+    <!-- Indication on the keyguard that is shown when the device is charging. [CHAR LIMIT=40]-->
+    <string name="keyguard_indication_charging_time">Charging (<xliff:g id="charging_time_left" example="4 hours and 2 minutes">%s</xliff:g> until full)</string>
+
     <!-- Zen mode condition: time duration in minutes. [CHAR LIMIT=NONE] -->
     <plurals name="zen_mode_duration_minutes">
         <item quantity="one">For one minute</item>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 6a12232..b0b018d 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -197,6 +197,7 @@
 
     <style name="systemui_theme" parent="@android:style/Theme.DeviceDefault">
         <item name="android:colorPrimary">@color/primary_color</item>
+        <item name="android:colorControlActivated">@color/system_accent_color</item>
     </style>
 
     <style name="NotificationsQuickSettings">
@@ -213,12 +214,7 @@
         <item name="android:colorControlActivated">#ffffffff</item>
     </style>
 
-    <style name="QSAccentTheme" parent="@android:style/Theme.DeviceDefault">
-        <item name="android:colorControlNormal">@color/system_accent_color</item>
-        <item name="android:colorControlActivated">@color/system_accent_color</item>
-    </style>
-
-    <style name="BorderlessButton" parent="@android:style/Widget.Quantum.Button.Borderless" />
+    <style name="BorderlessButton" parent="@android:style/Widget.Material.Button.Borderless" />
 
     <style name="BorderlessButton.Tiny">
         <item name="android:minHeight">12dip</item>
diff --git a/packages/SystemUI/src/com/android/systemui/DessertCaseView.java b/packages/SystemUI/src/com/android/systemui/DessertCaseView.java
index 4147155..14392b4 100644
--- a/packages/SystemUI/src/com/android/systemui/DessertCaseView.java
+++ b/packages/SystemUI/src/com/android/systemui/DessertCaseView.java
@@ -507,7 +507,6 @@
                     | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                     | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                     | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
-                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                     | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
             );
         }
diff --git a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
index 4d6d815c..006619b 100644
--- a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
@@ -42,6 +42,7 @@
         boolean canChildBeExpanded(View v);
         void setUserExpandedChild(View v, boolean userExpanded);
         void setUserLockedChild(View v, boolean userLocked);
+        void expansionStateChanged(boolean isExpanding);
     }
 
     private static final String TAG = "ExpandHelper";
@@ -77,7 +78,6 @@
     private boolean mWatchingForPull;
     private boolean mHasPopped;
     private View mEventSource;
-    private View mCurrView;
     private float mOldHeight;
     private float mNaturalHeight;
     private float mInitialTouchFocusY;
@@ -86,8 +86,7 @@
     private float mLastFocusY;
     private float mLastSpanY;
     private int mTouchSlop;
-    private int mLastMotionY;
-    private float mPopLimit;
+    private float mLastMotionY;
     private int mPopDuration;
     private float mPullGestureMinXSpan;
     private Callback mCallback;
@@ -95,10 +94,14 @@
     private ViewScaler mScaler;
     private ObjectAnimator mScaleAnimation;
     private Vibrator mVibrator;
+    private boolean mEnabled = true;
+    private ExpandableView mResizedView;
+    private float mCurrentHeight;
 
     private int mSmallSize;
     private int mLargeSize;
     private float mMaximumStretch;
+    private boolean mOnlyMovements;
 
     private int mGravity;
 
@@ -109,17 +112,14 @@
         @Override
         public boolean onScaleBegin(ScaleGestureDetector detector) {
             if (DEBUG_SCALE) Log.v(TAG, "onscalebegin()");
-            float focusX = detector.getFocusX();
-            float focusY = detector.getFocusY();
 
-            final ExpandableView underFocus = findView(focusX, focusY);
-            startExpanding(underFocus, STRETCH);
+            startExpanding(mResizedView, STRETCH);
             return mExpanding;
         }
 
         @Override
         public boolean onScale(ScaleGestureDetector detector) {
-            if (DEBUG_SCALE) Log.v(TAG, "onscale() on " + mCurrView);
+            if (DEBUG_SCALE) Log.v(TAG, "onscale() on " + mResizedView);
             return true;
         }
 
@@ -138,6 +138,7 @@
         public void setHeight(float h) {
             if (DEBUG_SCALE) Log.v(TAG, "SetHeight: setting to " + h);
             mView.setActualHeight((int) h);
+            mCurrentHeight = h;
         }
         public float getHeight() {
             return mView.getActualHeight();
@@ -165,7 +166,6 @@
         mGravity = Gravity.TOP;
         mScaleAnimation = ObjectAnimator.ofFloat(mScaler, "height", 0f);
         mScaleAnimation.setDuration(EXPAND_DURATION);
-        mPopLimit = mContext.getResources().getDimension(R.dimen.blinds_pop_threshold);
         mPopDuration = mContext.getResources().getInteger(R.integer.blinds_pop_duration_ms);
         mPullGestureMinXSpan = mContext.getResources().getDimension(R.dimen.pull_span_min);
 
@@ -188,7 +188,6 @@
         float target = hand + mOldHeight;
         float newHeight = clamp(target);
         mScaler.setHeight(newHeight);
-
         mLastFocusY = mSGD.getFocusY();
         mLastSpanY = mSGD.getCurrentSpan();
     }
@@ -252,6 +251,9 @@
 
     @Override
     public boolean onInterceptTouchEvent(MotionEvent ev) {
+        if (!isEnabled()) {
+            return false;
+        }
         final int action = ev.getAction();
         if (DEBUG_SCALE) Log.d(TAG, "intercept: act=" + MotionEvent.actionToString(action) +
                          " expanding=" + mExpanding +
@@ -270,38 +272,34 @@
         if (DEBUG_SCALE) Log.d(TAG, "set initial span: " + mInitialTouchSpan);
 
         if (mExpanding) {
+            mLastMotionY = ev.getRawY();
             return true;
         } else {
             if ((action == MotionEvent.ACTION_MOVE) && 0 != (mExpansionStyle & BLINDS)) {
                 // we've begun Venetian blinds style expansion
                 return true;
             }
-            final float xspan = mSGD.getCurrentSpanX();
-            if ((action == MotionEvent.ACTION_MOVE &&
-                    xspan > mPullGestureMinXSpan &&
-                    xspan > mSGD.getCurrentSpanY())) {
-                // detect a vertical pulling gesture with fingers somewhat separated
-                if (DEBUG_SCALE) Log.v(TAG, "got pull gesture (xspan=" + xspan + "px)");
-
-                final ExpandableView underFocus = findView(x, y);
-                startExpanding(underFocus, PULL);
-                return true;
-            }
-            if (mScrollAdapter != null && !mScrollAdapter.isScrolledToTop()) {
-                return false;
-            }
-            // Now look for other gestures
             switch (action & MotionEvent.ACTION_MASK) {
             case MotionEvent.ACTION_MOVE: {
+                final float xspan = mSGD.getCurrentSpanX();
+                if (xspan > mPullGestureMinXSpan &&
+                        xspan > mSGD.getCurrentSpanY() && !mExpanding) {
+                    // detect a vertical pulling gesture with fingers somewhat separated
+                    if (DEBUG_SCALE) Log.v(TAG, "got pull gesture (xspan=" + xspan + "px)");
+                    startExpanding(mResizedView, PULL);
+                    mWatchingForPull = false;
+                }
                 if (mWatchingForPull) {
-                    final int yDiff = y - mLastMotionY;
+                    final float yDiff = ev.getRawY() - mInitialTouchY;
                     if (yDiff > mTouchSlop) {
                         if (DEBUG) Log.v(TAG, "got venetian gesture (dy=" + yDiff + "px)");
-                        mLastMotionY = y;
-                        final ExpandableView underFocus = findView(x, y);
-                        if (startExpanding(underFocus, BLINDS)) {
-                            mInitialTouchY = mLastMotionY;
-                            mHasPopped = false;
+                        mWatchingForPull = false;
+                        if (mResizedView != null && !isFullyExpanded(mResizedView)) {
+                            if (startExpanding(mResizedView, BLINDS)) {
+                                mLastMotionY = ev.getRawY();
+                                mInitialTouchY = ev.getRawY();
+                                mHasPopped = false;
+                            }
                         }
                     }
                 }
@@ -310,8 +308,10 @@
 
             case MotionEvent.ACTION_DOWN:
                 mWatchingForPull = mScrollAdapter != null &&
-                        isInside(mScrollAdapter.getHostView(), x, y);
-                mLastMotionY = y;
+                        isInside(mScrollAdapter.getHostView(), x, y)
+                        && mScrollAdapter.isScrolledToTop();
+                mResizedView = findView(x, y);
+                mInitialTouchY = ev.getY();
                 break;
 
             case MotionEvent.ACTION_CANCEL:
@@ -321,12 +321,28 @@
                 clearView();
                 break;
             }
+            mLastMotionY = ev.getRawY();
             return mExpanding;
         }
     }
 
+    public void setEnabled(boolean enable) {
+        mEnabled = enable;
+    }
+
+    private boolean isEnabled() {
+        return mEnabled;
+    }
+
+    private boolean isFullyExpanded(ExpandableView underFocus) {
+        return underFocus.getIntrinsicHeight() == underFocus.getMaxHeight();
+    }
+
     @Override
     public boolean onTouchEvent(MotionEvent ev) {
+        if (!isEnabled()) {
+            return false;
+        }
         final int action = ev.getActionMasked();
         if (DEBUG_SCALE) Log.d(TAG, "touch: act=" + MotionEvent.actionToString(action) +
                 " expanding=" + mExpanding +
@@ -335,47 +351,71 @@
                 (0 != (mExpansionStyle & STRETCH) ? " (stretch)" : ""));
 
         mSGD.onTouchEvent(ev);
+        final int x = (int) mSGD.getFocusX();
+        final int y = (int) mSGD.getFocusY();
 
+        if (mOnlyMovements) {
+            mLastMotionY = ev.getRawY();
+            return false;
+        }
         switch (action) {
+            case MotionEvent.ACTION_DOWN:
+                mWatchingForPull = mScrollAdapter != null &&
+                        isInside(mScrollAdapter.getHostView(), x, y);
+                mResizedView = findView(x, y);
+                mInitialTouchY = ev.getY();
+                break;
             case MotionEvent.ACTION_MOVE: {
-                if (0 != (mExpansionStyle & BLINDS)) {
-                    final float rawHeight = ev.getY() - mInitialTouchY + mOldHeight;
+                if (mWatchingForPull) {
+                    final float yDiff = ev.getRawY() - mInitialTouchY;
+                    if (yDiff > mTouchSlop) {
+                        if (DEBUG) Log.v(TAG, "got venetian gesture (dy=" + yDiff + "px)");
+                        mWatchingForPull = false;
+                        if (mResizedView != null && !isFullyExpanded(mResizedView)) {
+                            if (startExpanding(mResizedView, BLINDS)) {
+                                mInitialTouchY = ev.getRawY();
+                                mLastMotionY = ev.getRawY();
+                                mHasPopped = false;
+                            }
+                        }
+                    }
+                }
+                if (mExpanding && 0 != (mExpansionStyle & BLINDS)) {
+                    final float rawHeight = ev.getRawY() - mLastMotionY + mCurrentHeight;
                     final float newHeight = clamp(rawHeight);
-                    final boolean wasClosed = (mOldHeight == mSmallSize);
                     boolean isFinished = false;
+                    boolean expanded = false;
                     if (rawHeight > mNaturalHeight) {
                         isFinished = true;
+                        expanded = true;
                     }
                     if (rawHeight < mSmallSize) {
                         isFinished = true;
+                        expanded = false;
                     }
 
-                    final float pull = Math.abs(ev.getY() - mInitialTouchY);
-                    if (mHasPopped || pull > mPopLimit) {
-                        if (!mHasPopped) {
-                            vibrate(mPopDuration);
-                            mHasPopped = true;
-                        }
+                    if (!mHasPopped) {
+                        vibrate(mPopDuration);
+                        mHasPopped = true;
                     }
 
-                    if (mHasPopped) {
-                        mScaler.setHeight(newHeight);
-                    }
-
-                    final int x = (int) mSGD.getFocusX();
-                    final int y = (int) mSGD.getFocusY();
-                    ExpandableView underFocus = findView(x, y);
-                    if (isFinished && underFocus != null && underFocus != mCurrView) {
-                        finishExpanding(false); // @@@ needed?
-                        startExpanding(underFocus, BLINDS);
-                        mInitialTouchY = y;
-                        mHasPopped = false;
+                    mScaler.setHeight(newHeight);
+                    mLastMotionY = ev.getRawY();
+                    if (isFinished) {
+                        mCallback.setUserExpandedChild(mResizedView, expanded);
+                        mCallback.expansionStateChanged(false);
+                        return false;
+                    } else {
+                        mCallback.expansionStateChanged(true);
                     }
                     return true;
                 }
 
                 if (mExpanding) {
+
+                    // Gestural expansion is running
                     updateExpansion();
+                    mLastMotionY = ev.getRawY();
                     return true;
                 }
 
@@ -396,7 +436,8 @@
                 clearView();
                 break;
         }
-        return true;
+        mLastMotionY = ev.getRawY();
+        return mResizedView != null;
     }
 
     /**
@@ -407,15 +448,16 @@
             return false;
         }
         mExpansionStyle = expandType;
-        if (mExpanding && v == mCurrView) {
+        if (mExpanding && v == mResizedView) {
             return true;
         }
         mExpanding = true;
+        mCallback.expansionStateChanged(true);
         if (DEBUG) Log.d(TAG, "scale type " + expandType + " beginning on view: " + v);
         mCallback.setUserLockedChild(v, true);
-        setView(v);
-        mScaler.setView((ExpandableView) v);
+        mScaler.setView(v);
         mOldHeight = mScaler.getHeight();
+        mCurrentHeight = mOldHeight;
         if (mCallback.canChildBeExpanded(v)) {
             if (DEBUG) Log.d(TAG, "working on an expandable child");
             mNaturalHeight = mScaler.getNaturalHeight(mLargeSize);
@@ -425,14 +467,13 @@
         }
         if (DEBUG) Log.d(TAG, "got mOldHeight: " + mOldHeight +
                     " mNaturalHeight: " + mNaturalHeight);
-        v.getParent().requestDisallowInterceptTouchEvent(true);
         return true;
     }
 
     private void finishExpanding(boolean force) {
         if (!mExpanding) return;
 
-        if (DEBUG) Log.d(TAG, "scale in finishing on view: " + mCurrView);
+        if (DEBUG) Log.d(TAG, "scale in finishing on view: " + mResizedView);
 
         float currentHeight = mScaler.getHeight();
         float targetHeight = mSmallSize;
@@ -446,11 +487,12 @@
         if (mScaleAnimation.isRunning()) {
             mScaleAnimation.cancel();
         }
-        mCallback.setUserExpandedChild(mCurrView, targetHeight == mNaturalHeight);
+        mCallback.setUserExpandedChild(mResizedView, targetHeight == mNaturalHeight);
+        mCallback.expansionStateChanged(false);
         if (targetHeight != currentHeight) {
             mScaleAnimation.setFloatValues(targetHeight);
             mScaleAnimation.setupStartValues();
-            final View scaledView = mCurrView;
+            final View scaledView = mResizedView;
             mScaleAnimation.addListener(new AnimatorListenerAdapter() {
                 @Override
                 public void onAnimationEnd(Animator animation) {
@@ -460,7 +502,7 @@
             });
             mScaleAnimation.start();
         } else {
-            mCallback.setUserLockedChild(mCurrView, false);
+            mCallback.setUserLockedChild(mResizedView, false);
         }
 
         mExpanding = false;
@@ -470,16 +512,11 @@
         if (DEBUG) Log.d(TAG, "currentHeight is: " + currentHeight);
         if (DEBUG) Log.d(TAG, "mSmallSize is: " + mSmallSize);
         if (DEBUG) Log.d(TAG, "targetHeight is: " + targetHeight);
-        if (DEBUG) Log.d(TAG, "scale was finished on view: " + mCurrView);
+        if (DEBUG) Log.d(TAG, "scale was finished on view: " + mResizedView);
     }
 
     private void clearView() {
-        mCurrView = null;
-
-    }
-
-    private void setView(View v) {
-        mCurrView = v;
+        mResizedView = null;
     }
 
     /**
@@ -494,6 +531,18 @@
     }
 
     /**
+     * Change the expansion mode to only observe movements and don't perform any resizing.
+     * This is needed when the expanding is finished and the scroller kicks in,
+     * performing an overscroll motion. We only want to shrink it again when we are not
+     * overscrolled.
+     *
+     * @param onlyMovements Should only movements be observed?
+     */
+    public void onlyObserveMovements(boolean onlyMovements) {
+        mOnlyMovements = onlyMovements;
+    }
+
+    /**
      * Triggers haptic feedback.
      */
     private synchronized void vibrate(long duration) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 4837a53..ffd76a7 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -878,6 +878,7 @@
         if (mLockPatternUtils.checkVoldPassword()) {
             if (DEBUG) Log.d(TAG, "Not showing lock screen since just decrypted");
             // Without this, settings is not enabled until the lock screen first appears
+            mShowing = false;
             hideLocked();
             return;
         }
@@ -1191,9 +1192,17 @@
             if (DEBUG) Log.d(TAG, "handleHide");
             try {
 
-                // Don't actually hide the Keyguard at the moment, wait for window manager until
-                // it tells us it's safe to do so with startKeyguardExitAnimation.
-                mWM.keyguardGoingAway();
+                if (mShowing) {
+
+                    // Don't actually hide the Keyguard at the moment, wait for window manager until
+                    // it tells us it's safe to do so with startKeyguardExitAnimation.
+                    mWM.keyguardGoingAway();
+                } else {
+
+                    // Don't try to rely on WindowManager - if Keyguard wasn't showing, window
+                    // manager won't start the exit animation.
+                    handleStartKeyguardExitAnimation(0, 0);
+                }
             } catch (RemoteException e) {
                 Log.e(TAG, "Error while calling WindowManager", e);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 2bf369a..07ffd66 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -156,12 +156,14 @@
         AnimatorListener listener = null;
         if (show) {
             if (mDetailRecord != null) return;
-            final View detail = r.tile.createDetailView(mContext, mDetail);
-            if (detail == null) return;
+            if (r.detailView == null) {
+                r.detailView = r.tile.createDetailView(mContext, mDetail);
+            }
+            if (r.detailView == null) return;
             mDetailRecord = r;
             mDetail.removeAllViews();
             mDetail.bringToFront();
-            mDetail.addView(detail);
+            mDetail.addView(r.detailView);
         } else {
             if (mDetailRecord == null) return;
             listener = mTeardownDetailWhenDone;
@@ -273,6 +275,7 @@
     private static final class TileRecord {
         QSTile<?> tile;
         QSTileView tileView;
+        View detailView;
         int row;
         int col;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
index 2edd8d5..5388994 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
@@ -135,7 +135,7 @@
     }
 
     private Drawable getTileBackground() {
-        final int[] attrs = new int[] { android.R.attr.selectableItemBackground};
+        final int[] attrs = new int[] { android.R.attr.selectableItemBackgroundBorderless };
         final TypedArray ta = mContext.obtainStyledAttributes(attrs);
         final Drawable d = ta.getDrawable(0);
         ta.recycle();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java b/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
index 7b6c544..901cc10 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
@@ -18,6 +18,8 @@
 
 import android.animation.ValueAnimator;
 import android.content.Context;
+import android.graphics.ColorFilter;
+import android.graphics.LightingColorFilter;
 import android.view.View;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
@@ -29,6 +31,7 @@
 public final class SignalTileView extends QSTileView {
     private static final long DEFAULT_DURATION = new ValueAnimator().getDuration();
     private static final long SHORT_DURATION = DEFAULT_DURATION / 3;
+    private static final ColorFilter FILTER = new LightingColorFilter(0xffffffff, 0xff283034);
 
     private FrameLayout mIconFrame;
     private ImageView mSignal;
@@ -41,10 +44,12 @@
 
         mIn = new ImageView(context);
         mIn.setImageResource(R.drawable.ic_qs_signal_in);
+        mIn.setColorFilter(FILTER);
         addView(mIn);
 
         mOut = new ImageView(context);
         mOut.setImageResource(R.drawable.ic_qs_signal_out);
+        mOut.setColorFilter(FILTER);
         addView(mOut);
     }
 
@@ -88,10 +93,12 @@
         final SignalState s = (SignalState) state;
         mSignal.setImageDrawable(null);  // force refresh
         mSignal.setImageResource(s.iconId);
+        mSignal.setColorFilter(FILTER);
         if (s.overlayIconId > 0) {
             mOverlay.setVisibility(VISIBLE);
             mOverlay.setImageDrawable(null);  // force refresh
             mOverlay.setImageResource(s.overlayIconId);
+            mOverlay.setColorFilter(FILTER);
         } else {
             mOverlay.setVisibility(GONE);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
index d220e1a..7431e69 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -84,7 +84,7 @@
             } else if (connecting) {
                 state.iconId = R.drawable.ic_qs_bluetooth_connecting;
                 stateContentDescription = mContext.getString(R.string.accessibility_desc_connecting);
-                state.label = mController.getLastDeviceName();
+                state.label = mContext.getString(R.string.quick_settings_bluetooth_label);
             } else {
                 state.iconId = R.drawable.ic_qs_bluetooth_on;
                 stateContentDescription = mContext.getString(R.string.accessibility_desc_on);
@@ -94,7 +94,7 @@
             }
         } else {
             state.iconId = R.drawable.ic_qs_bluetooth_off;
-            state.label = mContext.getString(R.string.quick_settings_bluetooth_off_label);
+            state.label = mContext.getString(R.string.quick_settings_bluetooth_label);
             stateContentDescription = mContext.getString(R.string.accessibility_desc_off);
         }
         state.contentDescription = mContext.getString(
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 e496468..db9b054 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
@@ -85,7 +85,7 @@
                     mContext.getString(R.string.accessibility_desc_on));
         } else {
             if (state.icon == null) state.iconId = R.drawable.ic_qs_location_11;
-            state.label = mContext.getString(R.string.quick_settings_location_off_label);
+            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_off));
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NotificationsTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NotificationsTile.java
index 20bbf8b..b981ed6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NotificationsTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NotificationsTile.java
@@ -22,7 +22,6 @@
 import android.content.IntentFilter;
 import android.media.AudioManager;
 import android.util.Log;
-import android.view.ContextThemeWrapper;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.View.OnAttachStateChangeListener;
@@ -49,8 +48,7 @@
 
     @Override
     public View createDetailView(Context context, ViewGroup root) {
-        final Context themedContext = new ContextThemeWrapper(mContext, R.style.QSAccentTheme);
-        final View v = LayoutInflater.from(themedContext).inflate(R.layout.qs_detail, root, false);
+        final View v = LayoutInflater.from(context).inflate(R.layout.qs_detail, root, false);
         final TextView title = (TextView) v.findViewById(android.R.id.title);
         title.setText(R.string.quick_settings_notifications_label);
         final View close = v.findViewById(android.R.id.button1);
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 a1e70b9..6b73002 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -99,7 +99,7 @@
             signalContentDescription = r.getString(R.string.accessibility_no_wifi);
         } else {
             state.iconId = R.drawable.ic_qs_wifi_no_network;
-            state.label = r.getString(R.string.quick_settings_wifi_off_label);
+            state.label = r.getString(R.string.quick_settings_wifi_label);
             signalContentDescription = r.getString(R.string.accessibility_wifi_off);
         }
         state.contentDescription = mContext.getString(
diff --git a/packages/SystemUI/src/com/android/systemui/recent/Recents.java b/packages/SystemUI/src/com/android/systemui/recent/Recents.java
index 0cc09c8..116d755d 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/Recents.java
@@ -61,6 +61,11 @@
 
     @Override
     protected void onBootCompleted() {
+        if (mUseAlternateRecents) {
+            if (mAlternateRecents != null) {
+                mAlternateRecents.onBootCompleted();
+            }
+        }
         mBootCompleted = true;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
index ca9bb94..2f6d58f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
@@ -152,6 +152,8 @@
     // Recents service binding
     Messenger mService = null;
     Messenger mMessenger;
+    RecentsMessageHandler mHandler;
+    boolean mBootCompleted = false;
     boolean mServiceIsBound = false;
     boolean mToggleRecentsUponServiceBound;
     RecentsServiceConnection mConnection = new RecentsServiceConnection();
@@ -168,7 +170,8 @@
     public AlternateRecentsComponent(Context context) {
         mContext = context;
         mSystemServicesProxy = new SystemServicesProxy(context);
-        mMessenger = new Messenger(new RecentsMessageHandler());
+        mHandler = new RecentsMessageHandler();
+        mMessenger = new Messenger(mHandler);
     }
 
     public void onStart() {
@@ -180,6 +183,10 @@
         bindToRecentsService(false);
     }
 
+    public void onBootCompleted() {
+        mBootCompleted = true;
+    }
+
     /** Shows the recents */
     public void onShowRecents(boolean triggeredFromAltTab, View statusBarView) {
         if (Console.Enabled) {
@@ -206,7 +213,7 @@
         if (Console.Enabled) {
             Console.log(Constants.Log.App.RecentsComponent, "[RecentsComponent|hideRecents]");
         }
-        if (mServiceIsBound) {
+        if (mServiceIsBound && mBootCompleted) {
             // Notify recents to close it
             try {
                 Bundle data = new Bundle();
@@ -276,7 +283,7 @@
 
     /** Updates each of the task animation rects. */
     void updateAnimationRects() {
-        if (mServiceIsBound) {
+        if (mServiceIsBound && mBootCompleted) {
             Resources res = mContext.getResources();
             int statusBarHeight = res.getDimensionPixelSize(
                     com.android.internal.R.dimen.status_bar_height);
@@ -507,7 +514,7 @@
         if (!useThumbnailTransition) {
             ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext,
                     R.anim.recents_from_launcher_enter,
-                    R.anim.recents_from_launcher_exit);
+                    R.anim.recents_from_launcher_exit, mHandler, this);
             startAlternateRecentsActivity(opts, false);
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index df387c1..8680786 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -26,11 +26,14 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.res.Configuration;
 import android.os.Bundle;
 import android.util.Pair;
+import android.view.Gravity;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.WindowManager;
 import android.widget.FrameLayout;
 import com.android.systemui.R;
@@ -67,6 +70,7 @@
     FrameLayout mContainerView;
     RecentsView mRecentsView;
     View mEmptyView;
+    View mNavBarScrimView;
 
     AppWidgetHost mAppWidgetHost;
     AppWidgetProviderInfo mSearchAppWidgetInfo;
@@ -99,7 +103,7 @@
                     dismissRecentsIfVisible();
                 }
             } else if (action.equals(RecentsService.ACTION_START_ENTER_ANIMATION)) {
-                // Try and start the enter animation
+                // Try and start the enter animation (or restart it on configuration changed)
                 mRecentsView.startOnEnterAnimation();
             }
         }
@@ -129,6 +133,9 @@
             mRecentsView.setBSP(root);
         }
 
+        // Hide the scrim by default when we enter recents
+        mNavBarScrimView.setVisibility(View.INVISIBLE);
+
         // Add the default no-recents layout
         if (stacks.size() == 1 && stacks.get(0).getTaskCount() == 0) {
             mEmptyView.setVisibility(View.VISIBLE);
@@ -269,10 +276,12 @@
         // Create the empty view
         LayoutInflater inflater = LayoutInflater.from(this);
         mEmptyView = inflater.inflate(R.layout.recents_empty, mContainerView, false);
+        mNavBarScrimView = inflater.inflate(R.layout.recents_nav_bar_scrim, mContainerView, false);
 
         mContainerView = new FrameLayout(this);
         mContainerView.addView(mRecentsView);
         mContainerView.addView(mEmptyView);
+        mContainerView.addView(mNavBarScrimView);
         setContentView(mContainerView);
 
         // Update the recent tasks
@@ -282,6 +291,16 @@
         bindSearchBarAppWidget();
         // Add the search bar layout
         addSearchBarAppWidgetView();
+
+        // Update if we are getting a configuration change
+        if (savedInstanceState != null) {
+            onConfigurationChange();
+        }
+    }
+
+    void onConfigurationChange() {
+        // Try and start the enter animation (or restart it on configuration changed)
+        mRecentsView.startOnEnterAnimation();
     }
 
     @Override
@@ -433,17 +452,44 @@
 
     @Override
     public void onBackPressed() {
-        boolean interceptedByInfoPanelClose = false;
-
         // Unfilter any stacks
         if (!mRecentsView.unfilterFilteredStacks()) {
-            super.onBackPressed();
+            if (!mRecentsView.launchFirstTask()) {
+                super.onBackPressed();
+            }
         }
     }
 
     @Override
-    public void onTaskLaunching() {
+    public void onEnterAnimationTriggered() {
+        // Fade in the scrim
+        RecentsConfiguration config = RecentsConfiguration.getInstance();
+        if (config.hasNavBarScrim()) {
+            mNavBarScrimView.setVisibility(View.VISIBLE);
+            mNavBarScrimView.setAlpha(0f);
+            mNavBarScrimView.animate().alpha(1f)
+                    .setStartDelay(config.taskBarEnterAnimDelay)
+                    .setDuration(config.navBarScrimEnterDuration)
+                    .setInterpolator(config.fastOutSlowInInterpolator)
+                    .withLayer()
+                    .start();
+        }
+    }
+
+    @Override
+    public void onTaskLaunching(boolean isTaskInStackBounds) {
         mTaskLaunched = true;
+
+        // Fade out the scrim
+        RecentsConfiguration config = RecentsConfiguration.getInstance();
+        if (!isTaskInStackBounds && config.hasNavBarScrim()) {
+            mNavBarScrimView.animate().alpha(0f)
+                    .setStartDelay(0)
+                    .setDuration(config.taskBarExitAnimDuration)
+                    .setInterpolator(config.fastOutSlowInInterpolator)
+                    .withLayer()
+                    .start();
+        }
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
index 6391685..0cf6ee6 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
@@ -41,7 +41,7 @@
     public Rect displayRect = new Rect();
 
     boolean isLandscape;
-    boolean transposeSearchLayoutWithOrientation;
+    boolean transposeRecentsLayoutWithOrientation;
     int searchBarAppWidgetId = -1;
 
     public float animationPxMovementPerSecond;
@@ -58,7 +58,6 @@
     public float taskStackWidthPaddingPct;
     public int taskStackTopPaddingPx;
 
-    public int taskViewInfoPaneAnimDuration;
     public int taskViewRemoveAnimDuration;
     public int taskViewRemoveAnimTranslationXPx;
     public int taskViewTranslationZMinPx;
@@ -76,8 +75,11 @@
     public int taskBarViewHighlightColor;
 
     public int taskBarEnterAnimDuration;
+    public int taskBarEnterAnimDelay;
     public int taskBarExitAnimDuration;
 
+    public int navBarScrimEnterDuration;
+
     public boolean launchedFromAltTab;
     public boolean launchedWithThumbnailAnimation;
 
@@ -108,8 +110,8 @@
 
         isLandscape = res.getConfiguration().orientation ==
                 Configuration.ORIENTATION_LANDSCAPE;
-        transposeSearchLayoutWithOrientation =
-                res.getBoolean(R.bool.recents_transpose_search_layout_with_orientation);
+        transposeRecentsLayoutWithOrientation =
+                res.getBoolean(R.bool.recents_transpose_layout_with_orientation);
         if (Console.Enabled) {
             Console.log(Constants.Log.UI.MeasureAndLayout,
                     "[RecentsConfiguration|orientation]", isLandscape ? "Landscape" : "Portrait",
@@ -133,8 +135,6 @@
         taskStackWidthPaddingPct = widthPaddingPctValue.getFloat();
         taskStackTopPaddingPx = res.getDimensionPixelSize(R.dimen.recents_stack_top_padding);
 
-        taskViewInfoPaneAnimDuration =
-                res.getInteger(R.integer.recents_animate_task_view_info_pane_duration);
         taskViewRemoveAnimDuration =
                 res.getInteger(R.integer.recents_animate_task_view_remove_duration);
         taskViewRemoveAnimTranslationXPx =
@@ -163,9 +163,14 @@
 
         taskBarEnterAnimDuration =
                 res.getInteger(R.integer.recents_animate_task_bar_enter_duration);
+        taskBarEnterAnimDelay =
+                res.getInteger(R.integer.recents_animate_task_bar_enter_delay);
         taskBarExitAnimDuration =
                 res.getInteger(R.integer.recents_animate_task_bar_exit_duration);
 
+        navBarScrimEnterDuration =
+                res.getInteger(R.integer.recents_nav_bar_scrim_enter_duration);
+
         fastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
                         com.android.internal.R.interpolator.fast_out_slow_in);
         fastOutLinearInInterpolator = AnimationUtils.loadInterpolator(context,
@@ -203,11 +208,16 @@
         launchedWithThumbnailAnimation = false;
     }
 
-    /** Returns whether the search bar app widget exists */
+    /** Returns whether the search bar app widget exists. */
     public boolean hasSearchBarAppWidget() {
         return searchBarAppWidgetId >= 0;
     }
 
+    /** Returns whether the nav bar scrim should be visible. */
+    public boolean hasNavBarScrim() {
+        return !transposeRecentsLayoutWithOrientation || !isLandscape;
+    }
+
     /**
      * Returns the task stack bounds in the current orientation. These bounds do not account for
      * the system insets.
@@ -216,7 +226,7 @@
         if (hasSearchBarAppWidget()) {
             Rect searchBarBounds = new Rect();
             getSearchBarBounds(width, height, searchBarBounds);
-            if (isLandscape && transposeSearchLayoutWithOrientation) {
+            if (isLandscape && transposeRecentsLayoutWithOrientation) {
                 // In landscape, the search bar appears on the left, so shift the task rect right
                 taskStackBounds.set(searchBarBounds.width(), 0, width, height);
             } else {
@@ -239,7 +249,7 @@
             return;
         }
 
-        if (isLandscape && transposeSearchLayoutWithOrientation) {
+        if (isLandscape && transposeRecentsLayoutWithOrientation) {
             // In landscape, the search bar appears on the left
             searchBarSpaceBounds.set(0, 0, searchBarSpaceHeightPx, height);
         } else {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsPackageMonitor.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsPackageMonitor.java
index 4e620b6..8bcc7f5 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsPackageMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsPackageMonitor.java
@@ -38,6 +38,7 @@
     PackageCallbacks mCb;
     List<ActivityManager.RecentTaskInfo> mTasks;
     SystemServicesProxy mSsp;
+    boolean mRegistered;
 
     public RecentsPackageMonitor(Context context) {
         mSsp = new SystemServicesProxy(context);
@@ -46,13 +47,19 @@
     /** Registers the broadcast receivers with the specified callbacks. */
     public void register(Context context, PackageCallbacks cb) {
         mCb = cb;
-        register(context, Looper.getMainLooper(), false);
+        if (!mRegistered) {
+            register(context, Looper.getMainLooper(), false);
+            mRegistered = true;
+        }
     }
 
     /** Unregisters the broadcast receivers. */
     @Override
     public void unregister() {
-        super.unregister();
+        if (mRegistered) {
+            super.unregister();
+            mRegistered = false;
+        }
         mTasks.clear();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index 6005275..db398b1 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -54,7 +54,8 @@
 
     /** The RecentsView callbacks */
     public interface RecentsViewCallbacks {
-        public void onTaskLaunching();
+        public void onTaskLaunching(boolean isTaskInStackBounds);
+        public void onEnterAnimationTriggered();
     }
 
     // The space partitioning root of this container
@@ -160,6 +161,9 @@
 
     /** Requests all task stacks to start their enter-recents animation */
     public void startOnEnterAnimation() {
+        // Notify callbacks that we are starting the enter animation
+        mCb.onEnterAnimationTriggered();
+
         int childCount = getChildCount();
         for (int i = 0; i < childCount; i++) {
             View child = getChildAt(i);
@@ -351,7 +355,11 @@
                                final TaskStack stack, final Task task) {
         // Notify any callbacks of the launching of a new task
         if (mCb != null) {
-            mCb.onTaskLaunching();
+            boolean isTaskInStackBounds = false;
+            if (stackView != null && tv != null) {
+                isTaskInStackBounds = stackView.isTaskInStackBounds(tv);
+            }
+            mCb.onTaskLaunching(isTaskInStackBounds);
         }
 
         final Runnable launchRunnable = new Runnable() {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
index 053f122..5830e37 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -430,6 +430,13 @@
         return getScrollAmountOutOfBounds(getStackScroll()) != 0;
     }
 
+    /** Returns whether the task view is in the stack bounds or not */
+    boolean isTaskInStackBounds(TaskView tv) {
+        Rect r = new Rect();
+        tv.getHitRect(r);
+        return r.bottom <= mRect.bottom;
+    }
+
     /** Updates the min and max virtual scroll bounds */
     void updateMinMaxScroll(boolean boundScrollToNewMinMax) {
         // Compute the min and max scroll values
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
index ffa181d..632c816 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -234,7 +234,7 @@
         mBarView.setTranslationY(-mBarView.getMeasuredHeight());
         mBarView.animate()
                 .translationY(0)
-                .setStartDelay(200)
+                .setStartDelay(config.taskBarEnterAnimDelay)
                 .setInterpolator(config.fastOutSlowInInterpolator)
                 .setDuration(config.taskBarEnterAnimDuration)
                 .withLayer()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
index dcd187c..b91e129 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
@@ -33,11 +33,13 @@
 import android.util.AttributeSet;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.ViewAnimationUtils;
 import android.view.ViewConfiguration;
 import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
 import android.view.animation.LinearInterpolator;
 import android.view.animation.PathInterpolator;
+
 import com.android.systemui.R;
 import com.android.systemui.statusbar.stack.StackStateAnimator;
 
@@ -88,8 +90,8 @@
 
     private boolean mDimmed;
 
-    private int mBgResId = com.android.internal.R.drawable.notification_quantum_bg;
-    private int mDimmedBgResId = com.android.internal.R.drawable.notification_quantum_bg_dim;
+    private int mBgResId = com.android.internal.R.drawable.notification_material_bg;
+    private int mDimmedBgResId = com.android.internal.R.drawable.notification_material_bg_dim;
 
     private int mBgTint = 0;
     private int mDimmedBgTint = 0;
@@ -141,7 +143,7 @@
         setClipToPadding(false);
         mAppearAnimationFilter = new PorterDuffColorFilter(0, PorterDuff.Mode.SRC_ATOP);
         mRoundedRectCornerRadius = getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.notification_quantum_rounded_rect_radius);
+                com.android.internal.R.dimen.notification_material_rounded_rect_radius);
     }
 
     @Override
@@ -219,7 +221,8 @@
         int heightHalf = mBackgroundNormal.getActualHeight()/2;
         float radius = (float) Math.sqrt(widthHalf*widthHalf + heightHalf*heightHalf);
         ValueAnimator animator =
-                mBackgroundNormal.createRevealAnimator(widthHalf, heightHalf, 0, radius);
+                ViewAnimationUtils.createCircularReveal(mBackgroundNormal,
+                        widthHalf, heightHalf, 0, radius);
         mBackgroundNormal.setVisibility(View.VISIBLE);
         Interpolator interpolator;
         Interpolator alphaInterpolator;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/AlphaOptimizedView.java b/packages/SystemUI/src/com/android/systemui/statusbar/AlphaOptimizedView.java
new file mode 100644
index 0000000..d2fe858
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/AlphaOptimizedView.java
@@ -0,0 +1,50 @@
+/*
+ * 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.util.AttributeSet;
+import android.view.View;
+
+/**
+ * A View which does not have overlapping renderings commands and therefore does not need a
+ * layer when alpha is changed.
+ */
+public class AlphaOptimizedView extends View
+{
+    public AlphaOptimizedView(Context context) {
+        super(context);
+    }
+
+    public AlphaOptimizedView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public AlphaOptimizedView(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    public AlphaOptimizedView(Context context, AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    @Override
+    public boolean hasOverlappingRendering() {
+        return false;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 06cc476..a7af998 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -557,9 +557,9 @@
             final int color = sbn.getNotification().color;
             if (isMediaNotification(entry)) {
                 entry.row.setBackgroundResourceIds(
-                        com.android.internal.R.drawable.notification_quantum_bg,
+                        com.android.internal.R.drawable.notification_material_bg,
                         color,
-                        com.android.internal.R.drawable.notification_quantum_bg_dim,
+                        com.android.internal.R.drawable.notification_material_bg_dim,
                         color);
             }
         }
@@ -981,7 +981,7 @@
         if (publicViewLocal == null) {
             // Add a basic notification template
             publicViewLocal = LayoutInflater.from(mContext).inflate(
-                    com.android.internal.R.layout.notification_template_quantum_base,
+                    com.android.internal.R.layout.notification_template_material_base,
                     expandedPublic, true);
 
             final TextView title = (TextView) publicViewLocal.findViewById(com.android.internal.R.id.title);
@@ -992,7 +992,10 @@
                 title.setText(entry.notification.getPackageName());
             }
 
-            final ImageView icon = (ImageView) publicViewLocal.findViewById(com.android.internal.R.id.icon);
+            final ImageView icon = (ImageView) publicViewLocal.findViewById(
+                    com.android.internal.R.id.icon);
+            final ImageView profileIcon = (ImageView) publicViewLocal.findViewById(
+                    com.android.internal.R.id.profile_icon);
 
             final StatusBarIcon ic = new StatusBarIcon(entry.notification.getPackageName(),
                     entry.notification.getUser(),
@@ -1008,7 +1011,19 @@
                         com.android.internal.R.drawable.notification_icon_legacy_bg_inset);
             }
 
-            final TextView text = (TextView) publicViewLocal.findViewById(com.android.internal.R.id.text);
+            if (profileIcon != null) {
+                Drawable profileDrawable
+                        = mUserManager.getBadgeForUser(entry.notification.getUser());
+                if (profileDrawable != null) {
+                    profileIcon.setImageDrawable(profileDrawable);
+                    profileIcon.setVisibility(View.VISIBLE);
+                } else {
+                    profileIcon.setVisibility(View.GONE);
+                }
+            }
+
+            final TextView text = (TextView) publicViewLocal.findViewById(
+                    com.android.internal.R.id.text);
             text.setText("Unlock your device to see this notification.");
 
             // TODO: fill out "time" as well
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java
index 5b2ea0b..517a4e8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java
@@ -25,7 +25,6 @@
 import android.view.ViewConfiguration;
 import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
-
 import com.android.systemui.ExpandHelper;
 import com.android.systemui.Gefingerpoken;
 import com.android.systemui.R;
@@ -87,6 +86,7 @@
                     captureStartingChild(mInitialTouchX, mInitialTouchY);
                     mInitialTouchY = y;
                     mInitialTouchX = x;
+                    mOnDragDownListener.onTouchSlopExceeded();
                     return true;
                 }
                 break;
@@ -202,5 +202,6 @@
         void onDraggedDown(View startingChild);
         void onDragDownReset();
         void onThresholdReached();
+        void onTouchSlopExceeded();
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
index 088f076..ac2537c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
@@ -69,7 +69,9 @@
                         ? MeasureSpec.makeMeasureSpec(ownMaxHeight, MeasureSpec.EXACTLY)
                         : MeasureSpec.makeMeasureSpec(layoutParams.height, MeasureSpec.EXACTLY);
                 }
-                child.measure(widthMeasureSpec, childHeightSpec);
+                child.measure(
+                        getChildMeasureSpec(widthMeasureSpec, 0 /* padding */, layoutParams.width),
+                        childHeightSpec);
                 int childHeight = child.getMeasuredHeight();
                 maxChildHeight = Math.max(maxChildHeight, childHeight);
             } else {
@@ -79,7 +81,9 @@
         int ownHeight = hasFixedHeight ? ownMaxHeight : maxChildHeight;
         newHeightSpec = MeasureSpec.makeMeasureSpec(ownHeight, MeasureSpec.EXACTLY);
         for (View child : mMatchParentViews) {
-            child.measure(widthMeasureSpec, newHeightSpec);
+            child.measure(getChildMeasureSpec(
+                    widthMeasureSpec, 0 /* padding */, child.getLayoutParams().width),
+                    newHeightSpec);
         }
         mMatchParentViews.clear();
         int width = MeasureSpec.getSize(widthMeasureSpec);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java b/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java
index de27119f..4233ab8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java
@@ -52,7 +52,7 @@
         for (int i = 0; i < n; i++) {
             final StatusBarNotification sbn = mIntercepted.valueAt(i);
             mReleased.add(sbn.getKey());
-            mBar.addNotificationInternal(sbn, null);
+            mBar.displayNotification(sbn, null);
         }
         mIntercepted.clear();
         updateSyntheticNotification();
@@ -71,16 +71,17 @@
     public void retryIntercepts(Ranking ranking) {
         if (ranking == null) return;
 
-        boolean changed = false;
         final int N = mIntercepted.size();
+        final ArraySet<String> removed = new ArraySet<String>(N);
         for (int i = 0; i < N; i++) {
             final StatusBarNotification sbn = mIntercepted.valueAt(i);
             if (!tryIntercept(sbn, ranking)) {
-                changed = true;
-                mBar.addNotificationInternal(sbn, ranking);
+                removed.add(sbn.getKey());
+                mBar.displayNotification(sbn, ranking);
             }
         }
-        if (changed) {
+        if (!removed.isEmpty()) {
+            mIntercepted.removeAll(removed);
             updateSyntheticNotification();
         }
     }
@@ -96,12 +97,6 @@
         return ent.key.equals(mSynKey);
     }
 
-    public void update(StatusBarNotification notification) {
-        if (mIntercepted.containsKey(notification.getKey())) {
-            mIntercepted.put(notification.getKey(), notification);
-        }
-    }
-
     private boolean shouldDisplayIntercepted() {
         return Settings.Secure.getInt(mContext.getContentResolver(),
                 Settings.Secure.DISPLAY_INTERCEPTED_NOTIFICATIONS, 0) != 0;
@@ -129,7 +124,7 @@
                 mBar.getCurrentUserHandle());
         if (mSynKey == null) {
             mSynKey = sbn.getKey();
-            mBar.addNotificationInternal(sbn, null);
+            mBar.displayNotification(sbn, null);
         } else {
            mBar.updateNotificationInternal(sbn, null);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
new file mode 100644
index 0000000..ce35e4b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -0,0 +1,190 @@
+/*
+ * 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 com.android.internal.app.IBatteryStats;
+import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.keyguard.KeyguardUpdateMonitorCallback;
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.BatteryManager;
+import android.os.BatteryStats;
+import android.os.Handler;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.text.TextUtils;
+import android.text.format.Formatter;
+import android.util.Log;
+import android.view.View;
+
+/**
+ * Controls the little text indicator on the keyguard.
+ */
+public class KeyguardIndicationController {
+
+    private static final String TAG = "KeyguardIndicationController";
+
+    private static final int MSG_HIDE_TRANSIENT = 1;
+
+    private final Context mContext;
+    private final KeyguardIndicationTextView mTextView;
+    private final IBatteryStats mBatteryInfo;
+
+    private String mRestingIndication;
+    private String mTransientIndication;
+    private boolean mVisible;
+
+    private boolean mPowerPluggedIn;
+    private boolean mPowerCharged;
+
+    public KeyguardIndicationController(Context context, KeyguardIndicationTextView textView) {
+        mContext = context;
+        mTextView = textView;
+
+        mBatteryInfo = IBatteryStats.Stub.asInterface(
+                ServiceManager.getService(BatteryStats.SERVICE_NAME));
+        KeyguardUpdateMonitor.getInstance(context).registerCallback(mUpdateMonitor);
+        context.registerReceiverAsUser(
+                mReceiver, UserHandle.OWNER, new IntentFilter(Intent.ACTION_TIME_TICK), null, null);
+    }
+
+    public void setVisible(boolean visible) {
+        mVisible = visible;
+        mTextView.setVisibility(visible ? View.VISIBLE : View.GONE);
+        if (visible) {
+            hideTransientIndication();
+            updateIndication();
+        }
+    }
+
+    /**
+     * Sets the indication that is shown if nothing else is showing.
+     */
+    public void setRestingIndication(String restingIndication) {
+        mRestingIndication = restingIndication;
+        updateIndication();
+    }
+
+    /**
+     * Hides transient indication in {@param delayMs}.
+     */
+    public void hideTransientIndicationDelayed(long delayMs) {
+        mHandler.sendMessageDelayed(
+                mHandler.obtainMessage(MSG_HIDE_TRANSIENT), delayMs);
+    }
+
+    /**
+     * Shows {@param transientIndication} until it is hidden by {@link #hideTransientIndication}.
+     */
+    public void showTransientIndication(int transientIndication) {
+        showTransientIndication(mContext.getResources().getString(transientIndication));
+    }
+
+    /**
+     * Shows {@param transientIndication} until it is hidden by {@link #hideTransientIndication}.
+     */
+    public void showTransientIndication(String transientIndication) {
+        mTransientIndication = transientIndication;
+        mHandler.removeMessages(MSG_HIDE_TRANSIENT);
+        updateIndication();
+    }
+
+    /**
+     * Hides transient indication.
+     */
+    public void hideTransientIndication() {
+        if (mTransientIndication != null) {
+            mTransientIndication = null;
+            mHandler.removeMessages(MSG_HIDE_TRANSIENT);
+            updateIndication();
+        }
+    }
+
+    private void updateIndication() {
+        if (mVisible) {
+            mTextView.switchIndication(computeIndication());
+        }
+    }
+
+    private String computeIndication() {
+        if (!TextUtils.isEmpty(mTransientIndication)) {
+            return mTransientIndication;
+        }
+        if (mPowerPluggedIn) {
+            return computePowerIndication();
+        }
+        return mRestingIndication;
+    }
+
+    private String computePowerIndication() {
+        if (mPowerCharged) {
+            return mContext.getResources().getString(R.string.keyguard_charged);
+        }
+
+        // Try fetching charging time from battery stats.
+        try {
+            long chargingTimeRemaining = mBatteryInfo.computeChargeTimeRemaining();
+            if (chargingTimeRemaining > 0) {
+                String chargingTimeFormatted =
+                        Formatter.formatShortElapsedTime(mContext, chargingTimeRemaining);
+                return mContext.getResources().getString(
+                        R.string.keyguard_indication_charging_time, chargingTimeFormatted);
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error calling IBatteryStats: ", e);
+        }
+
+        // Fall back to simple charging label.
+        return mContext.getResources().getString(R.string.keyguard_plugged_in);
+    }
+
+    KeyguardUpdateMonitorCallback mUpdateMonitor = new KeyguardUpdateMonitorCallback() {
+        @Override
+        public void onRefreshBatteryInfo(KeyguardUpdateMonitor.BatteryStatus status) {
+            mPowerPluggedIn = status.status == BatteryManager.BATTERY_STATUS_CHARGING
+                    || status.status == BatteryManager.BATTERY_STATUS_FULL;
+            mPowerCharged = status.isCharged();
+            updateIndication();
+        }
+    };
+
+    BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (mVisible) {
+                updateIndication();
+            }
+        }
+    };
+
+    private final Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            if (msg.what == MSG_HIDE_TRANSIENT && mTransientIndication != null) {
+                mTransientIndication = null;
+                updateIndication();
+            }
+        }
+    };
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationOverflowIconsView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationOverflowIconsView.java
index ce31894..6819d9b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationOverflowIconsView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationOverflowIconsView.java
@@ -18,15 +18,13 @@
 
 import android.app.Notification;
 import android.content.Context;
-import android.graphics.Color;
+import android.content.res.Configuration;
 import android.graphics.PorterDuff;
 import android.util.AttributeSet;
-import android.view.View;
 import android.widget.ImageView;
-import android.widget.LinearLayout;
 import android.widget.TextView;
 
-import com.android.internal.statusbar.StatusBarIcon;
+import com.android.internal.util.NotificationColorUtil;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.phone.IconMerger;
 
@@ -37,6 +35,8 @@
 
     private TextView mMoreText;
     private int mTintColor;
+    private int mIconSize;
+    private NotificationColorUtil mNotificationColorUtil = new NotificationColorUtil();
 
     public NotificationOverflowIconsView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -46,6 +46,8 @@
     protected void onFinishInflate() {
         super.onFinishInflate();
         mTintColor = getResources().getColor(R.color.keyguard_overflow_content_color);
+        mIconSize = getResources().getDimensionPixelSize(
+                com.android.internal.R.dimen.status_bar_icon_size);
     }
 
     public void setMoreText(TextView moreText) {
@@ -56,14 +58,24 @@
         StatusBarIconView v = new StatusBarIconView(getContext(), "",
                 notification.notification.getNotification());
         v.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
-        v.setColorFilter(mTintColor, PorterDuff.Mode.MULTIPLY);
-        addView(v);
+        addView(v, mIconSize, mIconSize);
         v.set(notification.icon.getStatusBarIcon());
+        applyColor(notification.notification.getNotification(), v);
         updateMoreText();
     }
 
+    private void applyColor(Notification notification, StatusBarIconView view) {
+        if (notification.color != Notification.COLOR_DEFAULT) {
+            if (mNotificationColorUtil.isGrayscale(view.getDrawable())) {
+                view.setColorFilter(mTintColor, PorterDuff.Mode.MULTIPLY);
+            }
+        } else {
+            view.setColorFilter(notification.color, PorterDuff.Mode.SRC_ATOP);
+        }
+    }
+
     private void updateMoreText() {
-        mMoreText.setText(getResources().getQuantityString(
-                R.plurals.keyguard_more_overflow_text, getChildCount(), getChildCount()));
+        mMoreText.setText(
+                getResources().getString(R.string.keyguard_more_overflow_text, getChildCount()));
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotView.java
index 3ca021a..1503072 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotView.java
@@ -41,6 +41,11 @@
         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/SpeedBumpDotsState.java b/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotsState.java
index 06a7f95..4febab1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotsState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotsState.java
@@ -70,23 +70,12 @@
         for (int i = 0; i < childCount; i++) {
             View child = mHostView.getChildAt(i);
             ViewState viewState = mStateMap.get(child);
-            float translationX = child.getTranslationX();
-            float translationY = child.getTranslationY();
-            float scale = child.getScaleX();
-            float alpha = child.getAlpha();
-            if (translationX != viewState.xTranslation) {
-                child.setTranslationX(viewState.xTranslation);
-            }
-            if (translationY != viewState.yTranslation) {
-                child.setTranslationY(viewState.yTranslation);
-            }
-            if (scale != viewState.scale) {
-                child.setScaleX(viewState.scale);
-                child.setScaleY(viewState.scale);
-            }
-            if (alpha != viewState.alpha) {
-                child.setAlpha(viewState.alpha);
-            }
+
+            child.setTranslationX(viewState.xTranslation);
+            child.setTranslationY(viewState.yTranslation);
+            child.setScaleX(viewState.scale);
+            child.setScaleY(viewState.scale);
+            child.setAlpha(viewState.alpha);
         }
     }
 
@@ -115,7 +104,7 @@
             ViewState viewState = mStateMap.get(child);
             child.animate().setInterpolator(mFastOutSlowInInterpolator)
                     .setStartDelay(startDelay)
-                    .alpha(viewState.alpha).withLayer()
+                    .alpha(viewState.alpha)
                     .translationX(viewState.xTranslation)
                     .translationY(viewState.yTranslation)
                     .scaleX(viewState.scale).scaleY(viewState.scale);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpView.java
index a84daef..689d0e9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpView.java
@@ -37,8 +37,8 @@
     private final int mDotsHeight;
     private final int mTextPaddingInset;
     private SpeedBumpDotsLayout mDots;
-    private View mLineLeft;
-    private View mLineRight;
+    private AlphaOptimizedView mLineLeft;
+    private AlphaOptimizedView mLineRight;
     private boolean mIsExpanded;
     private boolean mDividerVisible = true;
     private ValueAnimator mCurrentAnimator;
@@ -89,8 +89,8 @@
     protected void onFinishInflate() {
         super.onFinishInflate();
         mDots = (SpeedBumpDotsLayout) findViewById(R.id.speed_bump_dots_layout);
-        mLineLeft = findViewById(R.id.speedbump_line_left);
-        mLineRight = findViewById(R.id.speedbump_line_right);
+        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();
 
@@ -176,8 +176,7 @@
                     .scaleX(scale)
                     .scaleY(scale)
                     .translationY(translationY)
-                    .setListener(needsHideListener ? mHideExplanationListener : null)
-                    .withLayer();
+                    .setListener(needsHideListener ? mHideExplanationListener : null);
             mExplanationTextVisible = visible;
         }
     }
@@ -211,7 +210,6 @@
             float endTranslationXRight = nowVisible ? 0.0f : mCenterX - mLineRight.getLeft();
             mLineLeft.animate()
                     .alpha(endValue)
-                    .withLayer()
                     .scaleX(endValue)
                     .scaleY(endValue)
                     .translationX(endTranslationXLeft)
@@ -219,7 +217,6 @@
                     .withEndAction(onFinishedRunnable);
             mLineRight.animate()
                     .alpha(endValue)
-                    .withLayer()
                     .scaleX(endValue)
                     .scaleY(endValue)
                     .translationX(endTranslationXRight)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BounceInterpolator.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BounceInterpolator.java
index 367d326..0fdc185 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BounceInterpolator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BounceInterpolator.java
@@ -27,6 +27,7 @@
 
     @Override
     public float getInterpolation(float t) {
+        t *= 11f / 10f;
         if (t < 4f / 11f) {
             return SCALE_FACTOR * t * t;
         } else if (t < 8f / 11f) {
@@ -36,8 +37,7 @@
             float t2 = t - 9f / 11f;
             return SCALE_FACTOR * t2 * t2 + 15f / 16f;
         } else {
-            float t2 = t - 21f / 22f;
-            return SCALE_FACTOR * t2 * t2 + 63f / 64f;
+            return 1;
         }
     }
 }
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 b4f4865..086a266 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardPageSwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardPageSwipeHelper.java
@@ -28,6 +28,7 @@
 import android.view.ViewPropertyAnimator;
 import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
+
 import com.android.systemui.R;
 import com.android.systemui.statusbar.FlingAnimationUtils;
 
@@ -39,7 +40,10 @@
 public class KeyguardPageSwipeHelper {
 
     private static final float SWIPE_MAX_ICON_SCALE_AMOUNT = 2.0f;
-    private static final float SWIPE_RESTING_ALPHA_AMOUNT = 0.7f;
+    public static final float SWIPE_RESTING_ALPHA_AMOUNT = 0.5f;
+    public static final long HINT_PHASE1_DURATION = 250;
+    private static final long HINT_PHASE2_DURATION = 450;
+
     private final Context mContext;
 
     private FlingAnimationUtils mFlingAnimationUtils;
@@ -54,11 +58,13 @@
     private int mTouchSlop;
     private int mMinTranslationAmount;
     private int mMinFlingVelocity;
+    private int mHintDistance;
     private PowerManager mPowerManager;
     private final View mLeftIcon;
     private final View mCenterIcon;
     private final View mRightIcon;
     private Interpolator mFastOutSlowIn;
+    private Interpolator mBounceInterpolator;
     private Animator mSwipeAnimator;
     private boolean mCallbackCalled;
 
@@ -81,9 +87,12 @@
         mMinFlingVelocity = configuration.getScaledMinimumFlingVelocity();
         mMinTranslationAmount = mContext.getResources().getDimensionPixelSize(
                 R.dimen.keyguard_min_swipe_amount);
+        mHintDistance =
+                mContext.getResources().getDimensionPixelSize(R.dimen.hint_move_distance_sideways);
         mFlingAnimationUtils = new FlingAnimationUtils(mContext, 0.4f);
         mFastOutSlowIn = AnimationUtils.loadInterpolator(mContext,
                 android.R.interpolator.fast_out_slow_in);
+        mBounceInterpolator = new BounceInterpolator();
     }
 
     public boolean onTouchEvent(MotionEvent event) {
@@ -168,6 +177,83 @@
         return false;
     }
 
+    public void startHintAnimation(boolean right, Runnable onFinishedListener) {
+        startHintAnimationPhase1(right, onFinishedListener);
+    }
+
+    /**
+     * Phase 1: Move everything sidewards.
+     */
+    private void startHintAnimationPhase1(boolean right, final Runnable onFinishedListener) {
+        float target = right ? -mHintDistance : mHintDistance;
+        startHintTranslationAnimations(target, HINT_PHASE1_DURATION, mFastOutSlowIn);
+        ValueAnimator animator = ValueAnimator.ofFloat(mTranslation, target);
+        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+            @Override
+            public void onAnimationUpdate(ValueAnimator animation) {
+                mTranslation = (float) animation.getAnimatedValue();
+            }
+        });
+        animator.addListener(new AnimatorListenerAdapter() {
+            private boolean mCancelled;
+
+            @Override
+            public void onAnimationCancel(Animator animation) {
+                mCancelled = true;
+            }
+
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                if (mCancelled) {
+                    mSwipeAnimator = null;
+                    onFinishedListener.run();
+                } else {
+                    startUnlockHintAnimationPhase2(onFinishedListener);
+                }
+            }
+        });
+        animator.setInterpolator(mFastOutSlowIn);
+        animator.setDuration(HINT_PHASE1_DURATION);
+        animator.start();
+        mSwipeAnimator = animator;
+    }
+
+    /**
+     * Phase 2: Move back.
+     */
+    private void startUnlockHintAnimationPhase2(final Runnable onFinishedListener) {
+        startHintTranslationAnimations(0f /* target */, HINT_PHASE2_DURATION, mBounceInterpolator);
+        ValueAnimator animator = ValueAnimator.ofFloat(mTranslation, 0f);
+        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+            @Override
+            public void onAnimationUpdate(ValueAnimator animation) {
+                mTranslation = (float) animation.getAnimatedValue();
+            }
+        });
+        animator.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                mSwipeAnimator = null;
+                onFinishedListener.run();
+            }
+        });
+        animator.setInterpolator(mBounceInterpolator);
+        animator.setDuration(HINT_PHASE2_DURATION);
+        animator.start();
+        mSwipeAnimator = animator;
+    }
+
+    private void startHintTranslationAnimations(float target, long duration,
+            Interpolator interpolator) {
+        ArrayList<View> targetViews = mCallback.getTranslationViews();
+        for (View targetView : targetViews) {
+            targetView.animate()
+                    .setDuration(duration)
+                    .setInterpolator(interpolator)
+                    .translationX(target);
+        }
+    }
+
     private void onUserActivity(long when) {
         mPowerManager.userActivity(when, false);
     }
@@ -180,7 +266,6 @@
         View targetView = mTranslation > 0 ? mLeftIcon : mRightIcon;
         targetView.animate().cancel();
         if (mSwipeAnimator != null) {
-            mSwipeAnimator.removeAllListeners();
             mSwipeAnimator.cancel();
             hideInactiveIcons(true);
         }
@@ -218,11 +303,18 @@
             }
         });
         animator.addListener(new AnimatorListenerAdapter() {
+            private boolean mCancelled;
+
+            @Override
+            public void onAnimationCancel(Animator animation) {
+                mCancelled = true;
+            }
+
             @Override
             public void onAnimationEnd(Animator animation) {
                 mSwipeAnimator = null;
                 mSwipingInProgress = false;
-                if (!snapBack && !mCallbackCalled) {
+                if (!snapBack && !mCallbackCalled && !mCancelled) {
 
                     // ensure that the callback is called eventually
                     mCallback.onAnimationToSideStarted(mTranslation < 0);
@@ -281,7 +373,7 @@
     private void setTranslation(float translation, boolean isReset) {
         translation = rightSwipePossible() ? translation : Math.max(0, translation);
         translation = leftSwipePossible() ? translation : Math.min(0, translation);
-        if (translation != mTranslation) {
+        if (translation != mTranslation || isReset) {
             ArrayList<View> translatedViews = mCallback.getTranslationViews();
             for (View view : translatedViews) {
                 view.setTranslationX(translation);
@@ -307,7 +399,7 @@
         }
     }
 
-    private void showAllIcons(boolean animate) {
+    public void showAllIcons(boolean animate) {
         float scale = 1.0f;
         float alpha = SWIPE_RESTING_ALPHA_AMOUNT;
         updateIcon(mRightIcon, scale, alpha, animate);
@@ -315,6 +407,11 @@
         updateIcon(mLeftIcon, scale, alpha, animate);
     }
 
+    public void animateHideLeftRightIcon() {
+        updateIcon(mRightIcon, 0f, 0f, true);
+        updateIcon(mLeftIcon, 0f, 0f, true);
+    }
+
     private void hideInactiveIcons(boolean animate){
         View otherView = mTranslation < 0 ? mLeftIcon : mRightIcon;
         updateIcon(otherView, 0, 0, animate);
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 ee6d369..34179cb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -23,7 +23,6 @@
 import android.content.Context;
 import android.content.res.Configuration;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
 import android.view.View;
@@ -49,7 +48,7 @@
         View.OnClickListener, NotificationStackScrollLayout.OnOverscrollTopChangedListener,
         KeyguardPageSwipeHelper.Callback {
 
-    private static float EXPANSION_RUBBER_BAND_EXTRA_FACTOR = 0.6f;
+    private static final float LOCK_ICON_ACTIVE_SCALE = 1.2f;
 
     private KeyguardPageSwipeHelper mPageSwiper;
     private StatusBarHeaderView mHeader;
@@ -83,17 +82,16 @@
     private float mQsExpansionHeight;
     private int mQsMinExpansionHeight;
     private int mQsMaxExpansionHeight;
-    private int mMinStackHeight;
     private int mQsPeekHeight;
-    private float mNotificationTranslation;
-    private int mStackScrollerIntrinsicPadding;
     private boolean mStackScrollerOverscrolling;
     private boolean mQsExpansionEnabled = true;
     private ValueAnimator mQsExpansionAnimator;
     private FlingAnimationUtils mFlingAnimationUtils;
     private int mStatusBarMinHeight;
     private boolean mHeaderHidden;
+    private boolean mUnlockIconActive;
     private int mNotificationsHeaderCollideDistance;
+    private int mUnlockMoveDistance;
 
     private Interpolator mFastOutSlowInInterpolator;
     private Interpolator mFastOutLinearInterpolator;
@@ -163,13 +161,13 @@
         super.loadDimens();
         mNotificationTopPadding = getResources().getDimensionPixelSize(
                 R.dimen.notifications_top_padding);
-        mMinStackHeight = getResources().getDimensionPixelSize(R.dimen.collapsed_stack_height);
         mFlingAnimationUtils = new FlingAnimationUtils(getContext(), 0.4f);
         mStatusBarMinHeight = getResources().getDimensionPixelSize(
                 com.android.internal.R.dimen.status_bar_height);
         mQsPeekHeight = getResources().getDimensionPixelSize(R.dimen.qs_peek_height);
         mNotificationsHeaderCollideDistance =
                 getResources().getDimensionPixelSize(R.dimen.header_notifications_collide_distance);
+        mUnlockMoveDistance = getResources().getDimensionPixelOffset(R.dimen.unlock_move_distance);
         mClockPositionAlgorithm.loadDimens(getResources());
     }
 
@@ -182,7 +180,8 @@
         mQsMaxExpansionHeight = mHeader.getExpandedHeight() + mQsContainer.getHeight();
         if (mQsExpanded) {
             if (mQsFullyExpanded) {
-                setQsStackScrollerPadding(mQsMaxExpansionHeight);
+                mQsExpansionHeight = mQsMaxExpansionHeight;
+                requestScrollerTopPaddingUpdate(false /* animate */);
             }
         } else {
             if (!mStackScrollerOverscrolling) {
@@ -199,11 +198,12 @@
      */
     private void positionClockAndNotifications() {
         boolean animateClock = mNotificationStackScroller.isAddOrRemoveAnimationPending();
+        int stackScrollerPadding;
         if (mStatusBar.getBarState() != StatusBarState.KEYGUARD) {
             int bottom = mStackScrollerOverscrolling
                     ? mHeader.getCollapsedHeight()
                     : mHeader.getBottom();
-            mStackScrollerIntrinsicPadding = bottom + mQsPeekHeight
+            stackScrollerPadding = bottom + mQsPeekHeight
                     + mNotificationTopPadding;
             mTopPaddingAdjustment = 0;
         } else {
@@ -221,12 +221,11 @@
                 mKeyguardStatusView.setY(mClockPositionResult.clockY);
             }
             applyClockAlpha(mClockPositionResult.clockAlpha);
-            mStackScrollerIntrinsicPadding = mClockPositionResult.stackScrollerPadding;
+            stackScrollerPadding = mClockPositionResult.stackScrollerPadding;
             mTopPaddingAdjustment = mClockPositionResult.stackScrollerPaddingAdjustment;
         }
-        mNotificationStackScroller.setTopPadding(mStackScrollerIntrinsicPadding,
-                mAnimateNextTopPaddingChange || animateClock);
-        mAnimateNextTopPaddingChange = false;
+        mNotificationStackScroller.setIntrinsicPadding(stackScrollerPadding);
+        requestScrollerTopPaddingUpdate(animateClock);
     }
 
     private void startClockAnimation(int y) {
@@ -242,8 +241,8 @@
                     mClockAnimator.removeAllListeners();
                     mClockAnimator.cancel();
                 }
-                mClockAnimator =
-                        ObjectAnimator.ofFloat(mKeyguardStatusView, View.Y, mClockAnimationTarget);
+                mClockAnimator = ObjectAnimator
+                        .ofFloat(mKeyguardStatusView, View.Y, mClockAnimationTarget);
                 mClockAnimator.setInterpolator(mFastOutSlowInInterpolator);
                 mClockAnimator.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
                 mClockAnimator.addListener(new AnimatorListenerAdapter() {
@@ -288,6 +287,7 @@
     @Override
     public void resetViews() {
         mBlockTouches = false;
+        mUnlockIconActive = false;
         mPageSwiper.reset();
         closeQs();
     }
@@ -380,6 +380,7 @@
                     mInitialTouchX = x;
                     mQsTracking = true;
                     mIntercepting = false;
+                    mNotificationStackScroller.removeLongPressCallback();
                     return true;
                 }
                 break;
@@ -422,7 +423,9 @@
         }
         // TODO: Handle doublefinger swipe to notifications again. Look at history for a reference
         // implementation.
-        if (!mIsExpanding && !mQsExpanded && mStatusBar.getBarState() != StatusBarState.SHADE) {
+        if ((!mIsExpanding || mHintAnimationRunning)
+                && !mQsExpanded
+                && mStatusBar.getBarState() != StatusBarState.SHADE) {
             mPageSwiper.onTouchEvent(event);
             if (mPageSwiper.isSwipingInProgress()) {
                 return true;
@@ -517,6 +520,13 @@
         updateQsState();
     }
 
+    @Override
+    public void flingTopOverscroll(float velocity, boolean open) {
+        mStackScrollerOverscrolling = false;
+        setQsExpansion(mQsExpansionHeight);
+        flingSettings(velocity, open);
+    }
+
     private void onQsExpansionStarted() {
         onQsExpansionStarted(0);
     }
@@ -548,10 +558,11 @@
         mHeader.setExpanded(expandVisually, mStackScrollerOverscrolling);
         mNotificationStackScroller.setEnabled(!mQsExpanded);
         mQsPanel.setVisibility(expandVisually ? View.VISIBLE : View.INVISIBLE);
-        mQsContainer.setVisibility(mKeyguardShowing && !mQsExpanded
+        mQsContainer.setVisibility(mKeyguardShowing && !expandVisually
                 ? View.INVISIBLE
                 : View.VISIBLE);
         mScrollView.setTouchEnabled(mQsExpanded);
+        mNotificationStackScroller.setTouchEnabled(!mQsExpanded);
     }
 
     private void setQsExpansion(float height) {
@@ -565,9 +576,7 @@
         mQsExpansionHeight = height;
         mHeader.setExpansion(height - mQsPeekHeight);
         setQsTranslation(height);
-        if (!mStackScrollerOverscrolling) {
-            setQsStackScrollerPadding(height);
-        }
+        requestScrollerTopPaddingUpdate(false /* animate */);
         mStatusBar.userActivity();
     }
 
@@ -575,24 +584,12 @@
         mQsContainer.setY(height - mQsContainer.getHeight());
     }
 
-    private void setQsStackScrollerPadding(float height) {
-        float start = height - mScrollView.getScrollY() + mNotificationTopPadding;
-        float stackHeight = mNotificationStackScroller.getHeight() - start;
-        if (stackHeight <= mMinStackHeight) {
-            float overflow = mMinStackHeight - stackHeight;
-            stackHeight = mMinStackHeight;
-            start = mNotificationStackScroller.getHeight() - stackHeight;
-            mNotificationStackScroller.setTranslationY(overflow);
-            mNotificationTranslation = overflow + mScrollView.getScrollY();
-        } else {
-            mNotificationStackScroller.setTranslationY(0);
-            mNotificationTranslation = mScrollView.getScrollY();
-        }
-        mNotificationStackScroller.setTopPadding(clampQsStackScrollerPadding((int) start), false);
-    }
 
-    private int clampQsStackScrollerPadding(int desiredPadding) {
-        return Math.max(desiredPadding, mStackScrollerIntrinsicPadding);
+    private void requestScrollerTopPaddingUpdate(boolean animate) {
+        mNotificationStackScroller.updateTopPadding(mQsExpansionHeight,
+                mScrollView.getScrollY(),
+                mAnimateNextTopPaddingChange || animate);
+        mAnimateNextTopPaddingChange = false;
     }
 
     private void trackMovement(MotionEvent event) {
@@ -700,11 +697,9 @@
     @Override
     protected int getMaxPanelHeight() {
         // TODO: Figure out transition for collapsing when QS is open, adjust height here.
-        int maxPanelHeight = super.getMaxPanelHeight();
-        int emptyBottomMargin = mStackScrollerContainer.getHeight()
-                - mNotificationStackScroller.getHeight()
-                + mNotificationStackScroller.getEmptyBottomMargin();
-        int maxHeight = maxPanelHeight - emptyBottomMargin - mTopPaddingAdjustment;
+        int emptyBottomMargin = mNotificationStackScroller.getEmptyBottomMargin();
+        int maxHeight = mNotificationStackScroller.getHeight() - emptyBottomMargin
+                - mTopPaddingAdjustment;
         maxHeight = Math.max(maxHeight, mStatusBarMinHeight);
         return maxHeight;
     }
@@ -720,6 +715,40 @@
         }
         mNotificationStackScroller.setStackHeight(expandedHeight);
         updateKeyguardHeaderVisibility();
+        updateUnlockIcon();
+    }
+
+    @Override
+    protected float getOverExpansionAmount() {
+        return mNotificationStackScroller.getCurrentOverScrollAmount(true /* top */);
+    }
+
+    @Override
+    protected float getOverExpansionPixels() {
+        return mNotificationStackScroller.getCurrentOverScrolledPixels(true /* top */);
+    }
+
+    private void updateUnlockIcon() {
+        if (mStatusBar.getBarState() == StatusBarState.KEYGUARD
+                || mStatusBar.getBarState() == StatusBarState.SHADE_LOCKED) {
+            boolean active = getMaxPanelHeight() - getExpandedHeight() > mUnlockMoveDistance;
+            if (active && !mUnlockIconActive && mTracking) {
+                mKeyguardBottomArea.getLockIcon().animate()
+                        .alpha(1f)
+                        .scaleY(LOCK_ICON_ACTIVE_SCALE)
+                        .scaleX(LOCK_ICON_ACTIVE_SCALE)
+                        .setInterpolator(mFastOutLinearInterpolator)
+                        .setDuration(150);
+            } else if (!active && mUnlockIconActive && mTracking) {
+                mKeyguardBottomArea.getLockIcon().animate()
+                        .alpha(KeyguardPageSwipeHelper.SWIPE_RESTING_ALPHA_AMOUNT)
+                        .scaleY(1f)
+                        .scaleX(1f)
+                        .setInterpolator(mFastOutLinearInterpolator)
+                        .setDuration(150);
+            }
+            mUnlockIconActive = active;
+        }
     }
 
     /**
@@ -728,8 +757,20 @@
     private void updateKeyguardHeaderVisibility() {
         if (mStatusBar.getBarState() == StatusBarState.KEYGUARD
                 || mStatusBar.getBarState() == StatusBarState.SHADE_LOCKED) {
-            boolean hidden = mNotificationStackScroller.getNotificationsTopY()
-                    <= mHeader.getBottom() + mNotificationsHeaderCollideDistance;
+            boolean hidden;
+            if (mStatusBar.getBarState() == StatusBarState.KEYGUARD) {
+                
+                // When on Keyguard, we hide the header as soon as the top card of the notification
+                // stack scroller is close enough (collision distance) to the bottom of the header.
+                hidden = mNotificationStackScroller.getNotificationsTopY()
+                        <= mHeader.getBottom() + mNotificationsHeaderCollideDistance;
+            } else {
+
+                // In SHADE_LOCKED, the top card is already really close to the header. Hide it as
+                // soon as we start translating the stack.
+                hidden = mNotificationStackScroller.getTranslationY() < 0;
+            }
+
             if (hidden && !mHeaderHidden) {
                 mHeader.animate()
                         .alpha(0f)
@@ -773,25 +814,51 @@
     }
 
     @Override
-    protected void onOverExpansionChanged(float overExpansion) {
-        float currentOverScroll = mNotificationStackScroller.getCurrentOverScrolledPixels(true);
-        float expansionChange = overExpansion - mOverExpansion;
-        expansionChange *= EXPANSION_RUBBER_BAND_EXTRA_FACTOR;
-        mNotificationStackScroller.setOverScrolledPixels(currentOverScroll + expansionChange,
-                true /* onTop */,
-                false /* animate */);
-        super.onOverExpansionChanged(overExpansion);
+    protected void setOverExpansion(float overExpansion, boolean isPixels) {
+        if (mStatusBar.getBarState() != StatusBarState.KEYGUARD) {
+            mNotificationStackScroller.setOnHeightChangedListener(null);
+            if (isPixels) {
+                mNotificationStackScroller.setOverScrolledPixels(
+                        overExpansion, true /* onTop */, false /* animate */);
+            } else {
+                mNotificationStackScroller.setOverScrollAmount(
+                        overExpansion, true /* onTop */, false /* animate */);
+            }
+            mNotificationStackScroller.setOnHeightChangedListener(this);
+        }
+    }
+
+    @Override
+    protected void onTrackingStarted() {
+        super.onTrackingStarted();
+        if (mStatusBar.getBarState() == StatusBarState.KEYGUARD
+                || mStatusBar.getBarState() == StatusBarState.SHADE_LOCKED) {
+            mPageSwiper.animateHideLeftRightIcon();
+        }
     }
 
     @Override
     protected void onTrackingStopped(boolean expand) {
         super.onTrackingStopped(expand);
-        mOverExpansion = 0.0f;
-        mNotificationStackScroller.setOverScrolledPixels(0.0f, true /* onTop */,
-                true /* animate */);
+        if (expand) {
+            mNotificationStackScroller.setOverScrolledPixels(
+                    0.0f, true /* onTop */, true /* animate */);
+        }
+        if (expand && (mStatusBar.getBarState() == StatusBarState.KEYGUARD
+                || mStatusBar.getBarState() == StatusBarState.SHADE_LOCKED)) {
+            mPageSwiper.showAllIcons(true);
+        }
+        if (!expand && (mStatusBar.getBarState() == StatusBarState.KEYGUARD
+                || mStatusBar.getBarState() == StatusBarState.SHADE_LOCKED)) {
+            mKeyguardBottomArea.getLockIcon().animate()
+                    .alpha(0f)
+                    .scaleX(2f)
+                    .scaleY(2f)
+                    .setInterpolator(mFastOutLinearInterpolator)
+                    .setDuration(100);
+        }
     }
 
-
     @Override
     public void onHeightChanged(ExpandableView view) {
         requestPanelHeightUpdate();
@@ -800,8 +867,7 @@
     @Override
     public void onScrollChanged() {
         if (mQsExpanded) {
-            mNotificationStackScroller.setTranslationY(
-                    mNotificationTranslation - mScrollView.getScrollY());
+            requestScrollerTopPaddingUpdate(false /* animate */);
         }
     }
 
@@ -825,14 +891,61 @@
 
     @Override
     public void onAnimationToSideStarted(boolean rightPage) {
-        if (rightPage) {
-            mKeyguardBottomArea.launchCamera();
-        } else {
+        boolean start = getLayoutDirection() == LAYOUT_DIRECTION_RTL ? rightPage : !rightPage;
+        if (start) {
             mKeyguardBottomArea.launchPhone();
+        } else {
+            mKeyguardBottomArea.launchCamera();
         }
         mBlockTouches = true;
     }
 
+    @Override
+    protected void onEdgeClicked(boolean right) {
+        if ((right && getRightIcon().getVisibility() != View.VISIBLE)
+                || (!right && getLeftIcon().getVisibility() != View.VISIBLE)) {
+            return;
+        }
+        mHintAnimationRunning = true;
+        mPageSwiper.startHintAnimation(right, new Runnable() {
+            @Override
+            public void run() {
+                mHintAnimationRunning = false;
+                mStatusBar.onHintFinished();
+            }
+        });
+        startHighlightIconAnimation(right ? getRightIcon() : getLeftIcon());
+        boolean start = getLayoutDirection() == LAYOUT_DIRECTION_RTL ? right : !right;
+        if (start) {
+            mStatusBar.onPhoneHintStarted();
+        } else {
+            mStatusBar.onCameraHintStarted();
+        }
+    }
+
+    @Override
+    protected void startUnlockHintAnimation() {
+        super.startUnlockHintAnimation();
+        startHighlightIconAnimation(getCenterIcon());
+    }
+
+    /**
+     * Starts the highlight (making it fully opaque) animation on an icon.
+     */
+    private void startHighlightIconAnimation(final View icon) {
+        icon.animate()
+                .alpha(1.0f)
+                .setDuration(KeyguardPageSwipeHelper.HINT_PHASE1_DURATION)
+                .setInterpolator(mFastOutSlowInInterpolator)
+                .withEndAction(new Runnable() {
+                    @Override
+                    public void run() {
+                        icon.animate().alpha(KeyguardPageSwipeHelper.SWIPE_RESTING_ALPHA_AMOUNT)
+                                .setDuration(KeyguardPageSwipeHelper.HINT_PHASE1_DURATION)
+                                .setInterpolator(mFastOutSlowInInterpolator);
+                    }
+                });
+    }
 
     @Override
     public float getPageWidth() {
@@ -846,7 +959,9 @@
 
     @Override
     public View getLeftIcon() {
-        return mKeyguardBottomArea.getPhoneImageView();
+        return getLayoutDirection() == LAYOUT_DIRECTION_RTL
+                ? mKeyguardBottomArea.getCameraImageView()
+                : mKeyguardBottomArea.getPhoneImageView();
     }
 
     @Override
@@ -856,6 +971,8 @@
 
     @Override
     public View getRightIcon() {
-        return mKeyguardBottomArea.getCameraImageView();
+        return getLayoutDirection() == LAYOUT_DIRECTION_RTL
+                ? mKeyguardBottomArea.getPhoneImageView()
+                : mKeyguardBottomArea.getCameraImageView();
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index 4686933..772d0e7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -41,7 +41,6 @@
 public abstract class PanelView extends FrameLayout {
     public static final boolean DEBUG = PanelBar.DEBUG;
     public static final String TAG = PanelView.class.getSimpleName();
-    protected float mOverExpansion;
 
     private final void logf(String fmt, Object... args) {
         Log.v(TAG, (mViewName != null ? (mViewName + ": ") : "") + String.format(fmt, args));
@@ -50,15 +49,18 @@
     protected PhoneStatusBar mStatusBar;
     private float mPeekHeight;
     private float mHintDistance;
+    private int mEdgeTapAreaWidth;
     private float mInitialOffsetOnTouch;
     private float mExpandedFraction = 0;
-    private float mExpandedHeight = 0;
+    protected float mExpandedHeight = 0;
     private boolean mJustPeeked;
     private boolean mClosing;
-    private boolean mTracking;
+    protected boolean mTracking;
     private boolean mTouchSlopExceeded;
     private int mTrackingPointer;
     protected int mTouchSlop;
+    protected boolean mHintAnimationRunning;
+    private boolean mOverExpandedBeforeFling;
 
     private ValueAnimator mHeightAnimator;
     private ObjectAnimator mPeekAnimator;
@@ -111,6 +113,7 @@
         final ViewConfiguration configuration = ViewConfiguration.get(getContext());
         mTouchSlop = configuration.getScaledTouchSlop();
         mHintDistance = res.getDimension(R.dimen.hint_move_distance);
+        mEdgeTapAreaWidth = res.getDimensionPixelSize(R.dimen.edge_tap_area_width);
     }
 
     private void trackMovement(MotionEvent event) {
@@ -147,7 +150,6 @@
 
         switch (event.getActionMasked()) {
             case MotionEvent.ACTION_DOWN:
-
                 mInitialTouchY = y;
                 mInitialTouchX = x;
                 mInitialOffsetOnTouch = mExpandedHeight;
@@ -156,10 +158,11 @@
                     initVelocityTracker();
                 }
                 trackMovement(event);
-                if (!waitForTouchSlop || mHeightAnimator != null) {
+                if (!waitForTouchSlop || (mHeightAnimator != null && !mHintAnimationRunning)) {
                     if (mHeightAnimator != null) {
                         mHeightAnimator.cancel(); // end any outstanding animations
                     }
+                    mTouchSlopExceeded = (mHeightAnimator != null && !mHintAnimationRunning);
                     onTrackingStarted();
                 }
                 if (mExpandedHeight == 0) {
@@ -216,13 +219,14 @@
             case MotionEvent.ACTION_CANCEL:
                 mTrackingPointer = -1;
                 trackMovement(event);
-                if (mTracking && mTouchSlopExceeded) {
+                if ((mTracking && mTouchSlopExceeded)
+                        || event.getActionMasked() == MotionEvent.ACTION_CANCEL) {
                     float vel = getCurrentVelocity();
                     boolean expand = flingExpands(vel);
                     onTrackingStopped(expand);
                     fling(vel, expand);
                 } else {
-                    boolean expands = onEmptySpaceClick();
+                    boolean expands = onEmptySpaceClick(mInitialTouchX);
                     onTrackingStopped(expands);
                 }
                 if (mVelocityTracker != null) {
@@ -279,8 +283,9 @@
 
         switch (event.getActionMasked()) {
             case MotionEvent.ACTION_DOWN:
-                if (mHeightAnimator != null) {
+                if (mHeightAnimator != null && !mHintAnimationRunning) {
                     mHeightAnimator.cancel(); // end any outstanding animations
+                    mTouchSlopExceeded = true;
                     return true;
                 }
                 mInitialTouchY = y;
@@ -305,6 +310,9 @@
                 trackMovement(event);
                 if (scrolledToBottom) {
                     if (h < -mTouchSlop && h < -Math.abs(x - mInitialTouchX)) {
+                        if (mHeightAnimator != null) {
+                            mHeightAnimator.cancel();
+                        }
                         mInitialOffsetOnTouch = mExpandedHeight;
                         mInitialTouchY = y;
                         mInitialTouchX = x;
@@ -362,11 +370,12 @@
     protected void fling(float vel, boolean expand) {
         cancelPeek();
         float target = expand ? getMaxPanelHeight() : 0.0f;
-        if (target == mExpandedHeight) {
+        if (target == mExpandedHeight || getOverExpansionAmount() > 0f && expand) {
             onExpandingFinished();
             mBar.panelExpansionChanged(this, mExpandedFraction);
             return;
         }
+        mOverExpandedBeforeFling = getOverExpansionAmount() > 0f;
         ValueAnimator animator = createHeightAnimator(target);
         if (expand) {
             mFlingAnimationUtils.apply(animator, mExpandedHeight, target, vel, getHeight());
@@ -386,8 +395,8 @@
                 onExpandingFinished();
             }
         });
-        animator.start();
         mHeightAnimator = animator;
+        animator.start();
     }
 
     @Override
@@ -423,7 +432,7 @@
 
     public void setExpandedHeight(float height) {
         if (DEBUG) logf("setExpandedHeight(%.1f)", height);
-        setExpandedHeightInternal(height);
+        setExpandedHeightInternal(height + getOverExpansionPixels());
         mBar.panelExpansionChanged(PanelView.this, mExpandedFraction);
     }
 
@@ -441,33 +450,39 @@
         // If the user isn't actively poking us, let's update the height
         if (!mTracking && mHeightAnimator == null
                 && mExpandedHeight > 0 && currentMaxPanelHeight != mExpandedHeight) {
-            setExpandedHeightInternal(currentMaxPanelHeight);
+            setExpandedHeight(currentMaxPanelHeight);
         }
     }
 
     public void setExpandedHeightInternal(float h) {
-        float fh = getMaxPanelHeight();
-        mExpandedHeight = Math.max(0, Math.min(fh, h));
-        float overExpansion = h - fh;
-        overExpansion = Math.max(0, overExpansion);
-        if (overExpansion != mOverExpansion) {
-            onOverExpansionChanged(overExpansion);
-        }
-
-        if (DEBUG) {
-            logf("setExpansion: height=%.1f fh=%.1f tracking=%s", h, fh, mTracking ? "T" : "f");
+        float fhWithoutOverExpansion = getMaxPanelHeight() - getOverExpansionAmount();
+        if (mHeightAnimator == null) {
+            float overExpansionPixels = Math.max(0, h - fhWithoutOverExpansion);
+            if (getOverExpansionPixels() != overExpansionPixels && mTracking) {
+                setOverExpansion(overExpansionPixels, true /* isPixels */);
+            }
+            mExpandedHeight = Math.min(h, fhWithoutOverExpansion) + getOverExpansionAmount();
+        } else {
+            mExpandedHeight = h;
+            if (mOverExpandedBeforeFling) {
+                setOverExpansion(Math.max(0, h - fhWithoutOverExpansion), false /* isPixels */);
+            }
         }
 
         onHeightUpdated(mExpandedHeight);
-        mExpandedFraction = Math.min(1f, (fh == 0) ? 0 : mExpandedHeight / fh);
+        mExpandedFraction = Math.min(1f, fhWithoutOverExpansion == 0
+                ? 0
+                : mExpandedHeight / fhWithoutOverExpansion);
     }
 
-    protected void onOverExpansionChanged(float overExpansion) {
-        mOverExpansion = overExpansion;
-    }
+    protected abstract void setOverExpansion(float overExpansion, boolean isPixels);
 
     protected abstract void onHeightUpdated(float expandedHeight);
 
+    protected abstract float getOverExpansionAmount();
+
+    protected abstract float getOverExpansionPixels();
+
     /**
      * This returns the maximum height of the panel. Children should override this if their
      * desired height is not the full height.
@@ -550,14 +565,22 @@
         }
         cancelPeek();
         onExpandingStarted();
-        startUnlockHintAnimationPhase1();
+        startUnlockHintAnimationPhase1(new Runnable() {
+            @Override
+            public void run() {
+                onExpandingFinished();
+                mStatusBar.onHintFinished();
+                mHintAnimationRunning = false;
+            }
+        });
         mStatusBar.onUnlockHintStarted();
+        mHintAnimationRunning = true;
     }
 
     /**
      * Phase 1: Move everything upwards.
      */
-    private void startUnlockHintAnimationPhase1() {
+    private void startUnlockHintAnimationPhase1(final Runnable onAnimationFinished) {
         float target = Math.max(0, getMaxPanelHeight() - mHintDistance);
         ValueAnimator animator = createHeightAnimator(target);
         animator.setDuration(250);
@@ -574,10 +597,9 @@
             public void onAnimationEnd(Animator animation) {
                 if (mCancelled) {
                     mHeightAnimator = null;
-                    onExpandingFinished();
-                    mStatusBar.onUnlockHintFinished();
+                    onAnimationFinished.run();
                 } else {
-                    startUnlockHintAnimationPhase2();
+                    startUnlockHintAnimationPhase2(onAnimationFinished);
                 }
             }
         });
@@ -588,7 +610,7 @@
     /**
      * Phase 2: Bounce down.
      */
-    private void startUnlockHintAnimationPhase2() {
+    private void startUnlockHintAnimationPhase2(final Runnable onAnimationFinished) {
         ValueAnimator animator = createHeightAnimator(getMaxPanelHeight());
         animator.setDuration(450);
         animator.setInterpolator(mBounceInterpolator);
@@ -596,8 +618,7 @@
             @Override
             public void onAnimationEnd(Animator animation) {
                 mHeightAnimator = null;
-                onExpandingFinished();
-                mStatusBar.onUnlockHintFinished();
+                onAnimationFinished.run();
             }
         });
         animator.start();
@@ -609,7 +630,8 @@
         animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
             @Override
             public void onAnimationUpdate(ValueAnimator animation) {
-                setExpandedHeight((Float) animation.getAnimatedValue());
+                setExpandedHeightInternal((Float) animation.getAnimatedValue());
+                mBar.panelExpansionChanged(PanelView.this, mExpandedFraction);
             }
         });
         return animator;
@@ -620,13 +642,30 @@
      *
      * @return whether the panel will be expanded after the action performed by this method
      */
-    private boolean onEmptySpaceClick() {
+    private boolean onEmptySpaceClick(float x) {
+        if (mHintAnimationRunning) {
+            return true;
+        }
+        if (x < mEdgeTapAreaWidth
+                && mStatusBar.getBarState() == StatusBarState.KEYGUARD) {
+            onEdgeClicked(false /* right */);
+            return true;
+        } else if (x > getWidth() - mEdgeTapAreaWidth
+                && mStatusBar.getBarState() == StatusBarState.KEYGUARD) {
+            onEdgeClicked(true /* right */);
+            return true;
+        } else {
+            return onMiddleClicked();
+        }
+    }
+
+    private boolean onMiddleClicked() {
         switch (mStatusBar.getBarState()) {
             case StatusBarState.KEYGUARD:
                 startUnlockHintAnimation();
                 return true;
             case StatusBarState.SHADE_LOCKED:
-                // TODO: Go to Keyguard again.
+                mStatusBar.goToKeyguard();
                 return true;
             case StatusBarState.SHADE:
                 collapse();
@@ -636,6 +675,8 @@
         }
     }
 
+    protected abstract void onEdgeClicked(boolean right);
+
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println(String.format("[PanelView(%s): expandedHeight=%f maxPanelHeight=%d closing=%s"
                 + " tracking=%s justPeeked=%s peekAnim=%s%s timeAnim=%s%s"
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 b1216e69..ac9866c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -77,6 +77,7 @@
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
 import android.view.View;
+import android.view.ViewAnimationUtils;
 import android.view.ViewGroup;
 import android.view.ViewGroup.LayoutParams;
 import android.view.ViewPropertyAnimator;
@@ -86,6 +87,8 @@
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
 import android.view.animation.DecelerateInterpolator;
+import android.view.animation.Interpolator;
+import android.view.animation.PathInterpolator;
 import android.widget.FrameLayout;
 import android.widget.LinearLayout;
 import android.widget.TextView;
@@ -105,6 +108,7 @@
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.GestureRecorder;
 import com.android.systemui.statusbar.InterceptedNotifications;
+import com.android.systemui.statusbar.KeyguardIndicationController;
 import com.android.systemui.statusbar.NotificationData;
 import com.android.systemui.statusbar.NotificationData.Entry;
 import com.android.systemui.statusbar.NotificationOverflowContainer;
@@ -122,7 +126,6 @@
 import com.android.systemui.statusbar.policy.NetworkControllerImpl;
 import com.android.systemui.statusbar.policy.RotationLockControllerImpl;
 import com.android.systemui.statusbar.policy.ZenModeController;
-import com.android.systemui.statusbar.policy.ZenModeControllerImpl;
 import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.stack.NotificationStackScrollLayout.OnChildLocationsChangedListener;
 import com.android.systemui.statusbar.stack.StackScrollState.ViewState;
@@ -174,6 +177,11 @@
     /** The minimum delay in ms between reports of notification visibility. */
     private static final int VISIBILITY_REPORT_MIN_DELAY_MS = 500;
 
+    /**
+     * The delay to reset the hint text when the hint animation is finished running.
+     */
+    private static final int HINT_RESET_DELAY_MS = 1200;
+
     // fling gesture tuning parameters, scaled to display density
     private float mSelfExpandVelocityPx; // classic value: 2000px/s
     private float mSelfCollapseVelocityPx; // classic value: 2000px/s (will be negated to collapse "up")
@@ -248,10 +256,8 @@
     View mKeyguardStatusView;
     KeyguardBottomAreaView mKeyguardBottomArea;
     boolean mLeaveOpenOnKeyguardHide;
-    KeyguardIndicationTextView mKeyguardIndicationTextView;
+    KeyguardIndicationController mKeyguardIndicationController;
 
-    // TODO: Fetch phrase from search/hotword provider.
-    String mKeyguardHotwordPhrase = "";
     int mKeyguardMaxNotificationCount;
     View mDateTimeView;
 
@@ -396,6 +402,9 @@
     private boolean mSettingsClosing;
     private boolean mVisible;
 
+    private Interpolator mAlphaOut = new PathInterpolator(0f, 0.4f, 1f, 1f);
+    private Interpolator mAlphaIn = new PathInterpolator(0f, 0f, 0.8f, 1f);
+
     private final OnChildLocationsChangedListener mOnChildLocationsChangedListener =
             new OnChildLocationsChangedListener() {
         @Override
@@ -404,6 +413,8 @@
         }
     };
 
+    private int mDisabledUnmodified;
+
     public void setOnFlipRunnable(Runnable onFlipRunnable) {
         mOnFlipRunnable = onFlipRunnable;
     }
@@ -662,8 +673,9 @@
         mKeyguardBottomArea =
                 (KeyguardBottomAreaView) mStatusBarWindow.findViewById(R.id.keyguard_bottom_area);
         mKeyguardBottomArea.setActivityStarter(this);
-        mKeyguardIndicationTextView = (KeyguardIndicationTextView) mStatusBarWindow.findViewById(
-                R.id.keyguard_indication_text);
+        mKeyguardIndicationController = new KeyguardIndicationController(mContext,
+                (KeyguardIndicationTextView) mStatusBarWindow.findViewById(
+                        R.id.keyguard_indication_text));
         mDateView = (DateView)mStatusBarWindow.findViewById(R.id.date);
 
         mDateTimeView = mHeader.findViewById(R.id.datetime);
@@ -672,10 +684,6 @@
             mDateTimeView.setEnabled(true);
         }
 
-        mNotificationPanel.setSystemUiVisibility(
-                View.STATUS_BAR_DISABLE_NOTIFICATION_ICONS |
-                View.STATUS_BAR_DISABLE_CLOCK);
-
         mTicker = new MyTicker(context, mStatusBarView);
 
         TickerView tickerView = (TickerView)mStatusBarView.findViewById(R.id.tickerText);
@@ -753,7 +761,8 @@
                 @Override
                 public ValueAnimator createRevealAnimator(View v, int centerX, int centerY,
                         float startRadius, float endRadius) {
-                    return v.createRevealAnimator(centerX, centerY, startRadius, endRadius);
+                    return ViewAnimationUtils.createCircularReveal(v, centerX, centerY,
+                            startRadius, endRadius);
                 }
             });
             final QSTileHost qsh = new QSTileHost(mContext, this,
@@ -1047,16 +1056,22 @@
 
     @Override
     public void addNotificationInternal(StatusBarNotification notification, Ranking ranking) {
-        if (DEBUG) Log.d(TAG, "addNotification score=" + notification.getScore());
-        Entry shadeEntry = createNotificationViews(notification);
-        if (shadeEntry == null) {
-            return;
-        }
+        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.
             mNotificationData.updateRanking(ranking);
             return;
         }
+        mIntercepted.remove(notification.getKey());
+        displayNotification(notification, ranking);
+    }
+
+    public void displayNotification(StatusBarNotification notification,
+            Ranking ranking) {
+        Entry shadeEntry = createNotificationViews(notification);
+        if (shadeEntry == null) {
+            return;
+        }
         if (mUseHeadsUp && shouldInterrupt(notification)) {
             if (DEBUG) Log.d(TAG, "launching notification in heads up mode");
             Entry interruptionCandidate = new Entry(notification, null);
@@ -1112,7 +1127,8 @@
     @Override
     public void updateNotificationInternal(StatusBarNotification notification, Ranking ranking) {
         super.updateNotificationInternal(notification, ranking);
-        mIntercepted.update(notification);
+        // if we're here, then the notification is already in the shade
+        mIntercepted.remove(notification.getKey());
     }
 
     @Override
@@ -1174,7 +1190,6 @@
             Entry ent = mNotificationData.get(i);
             if (!(provisioned || showNotificationEvenIfUnprovisioned(ent.notification))) continue;
 
-            // TODO How do we want to badge notifcations from profiles.
             if (!notificationIsForCurrentProfiles(ent.notification)) continue;
 
             final int vis = ent.notification.getNotification().visibility;
@@ -1403,10 +1418,20 @@
         }
     }
 
+    private int adjustDisableFlags(int state) {
+        if (mExpandedVisible) {
+            state |= StatusBarManager.DISABLE_NOTIFICATION_ICONS;
+            state |= StatusBarManager.DISABLE_SYSTEM_INFO;
+        }
+        return state;
+    }
+
     /**
      * State is one or more of the DISABLE constants from StatusBarManager.
      */
     public void disable(int state) {
+        mDisabledUnmodified = state;
+        state = adjustDisableFlags(state);
         final int old = mDisabled;
         final int diff = state ^ old;
         mDisabled = state;
@@ -1444,20 +1469,17 @@
             if ((state & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
                 mSystemIconArea.animate()
                     .alpha(0f)
-                    .translationY(mNaturalBarHeight*0.5f)
-                    .setDuration(175)
-                    .setInterpolator(new DecelerateInterpolator(1.5f))
-                    .setListener(mMakeIconsInvisible)
-                    .start();
+                    .withLayer()
+                    .setDuration(160)
+                    .setInterpolator(mAlphaIn)
+                    .setListener(mMakeIconsInvisible);
             } else {
                 mSystemIconArea.setVisibility(View.VISIBLE);
                 mSystemIconArea.animate()
                     .alpha(1f)
-                    .translationY(0)
-                    .setStartDelay(0)
-                    .setInterpolator(new DecelerateInterpolator(1.5f))
-                    .setDuration(175)
-                    .start();
+                    .withLayer()
+                    .setInterpolator(mAlphaOut)
+                    .setDuration(320);
             }
         }
 
@@ -1493,20 +1515,18 @@
 
                 mNotificationIcons.animate()
                     .alpha(0f)
-                    .translationY(mNaturalBarHeight*0.5f)
-                    .setDuration(175)
-                    .setInterpolator(new DecelerateInterpolator(1.5f))
+                    .withLayer()
+                    .setDuration(160)
+                    .setInterpolator(mAlphaIn)
                     .setListener(mMakeIconsInvisible)
                     .start();
             } else {
                 mNotificationIcons.setVisibility(View.VISIBLE);
                 mNotificationIcons.animate()
                     .alpha(1f)
-                    .translationY(0)
-                    .setStartDelay(0)
-                    .setInterpolator(new DecelerateInterpolator(1.5f))
-                    .setDuration(175)
-                    .start();
+                    .withLayer()
+                    .setInterpolator(mAlphaOut)
+                    .setDuration(320);
             }
         }
     }
@@ -1606,7 +1626,7 @@
         mStatusBarWindowManager.setStatusBarExpanded(true);
 
         visibilityChanged(true);
-
+        disable(mDisabledUnmodified);
         setInteracting(StatusBarManager.WINDOW_STATUS_BAR, true);
     }
 
@@ -1757,10 +1777,6 @@
         mStatusBarView.collapseAllPanels(true);
     }
 
-    void makeExpandedInvisibleSoon() {
-        mHandler.postDelayed(new Runnable() { public void run() { makeExpandedInvisible(); }}, 50);
-    }
-
     void makeExpandedInvisible() {
         if (SPEW) Log.d(TAG, "makeExpandedInvisible: mExpandedVisible=" + mExpandedVisible
                 + " mExpandedVisible=" + mExpandedVisible);
@@ -1804,7 +1820,7 @@
         }
 
         setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
-
+        disable(mDisabledUnmodified);
         showBouncer();
     }
 
@@ -2840,19 +2856,20 @@
     }
 
     private void updatePublicMode() {
-        setLockscreenPublicMode(mState == StatusBarState.KEYGUARD
+        setLockscreenPublicMode(
+                (mStatusBarKeyguardViewManager.isShowing() || 
+                    mStatusBarKeyguardViewManager.isOccluded())
                 && mStatusBarKeyguardViewManager.isSecure());
     }
 
     private void updateKeyguardState() {
         if (mState == StatusBarState.KEYGUARD) {
             mKeyguardStatusView.setVisibility(View.VISIBLE);
-            mKeyguardIndicationTextView.setVisibility(View.VISIBLE);
-            mKeyguardIndicationTextView.switchIndication(mKeyguardHotwordPhrase);
+            mKeyguardIndicationController.setVisible(true);
             mNotificationPanel.resetViews();
         } else {
             mKeyguardStatusView.setVisibility(View.GONE);
-            mKeyguardIndicationTextView.setVisibility(View.GONE);
+            mKeyguardIndicationController.setVisible(false);
         }
         if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
             mKeyguardBottomArea.setVisibility(View.VISIBLE);
@@ -2875,9 +2892,12 @@
 
     public void updateStackScrollerState() {
         if (mStackScroller == null) return;
-        mStackScroller.setDimmed(mState == StatusBarState.KEYGUARD, false /* animate */);
-        mStackScroller.setVisibility(!mShowLockscreenNotifications && mState == StatusBarState.KEYGUARD
+        boolean onKeyguard = mState == StatusBarState.KEYGUARD;
+        mStackScroller.setDimmed(onKeyguard, false /* animate */);
+        mStackScroller.setVisibility(!mShowLockscreenNotifications && onKeyguard
                 ? View.INVISIBLE : View.VISIBLE);
+        mStackScroller.setScrollingEnabled(!onKeyguard);
+        mStackScroller.setExpandingEnabled(!onKeyguard);
     }
 
     public void userActivity() {
@@ -2936,7 +2956,7 @@
     @Override
     public void onActivated(View view) {
         userActivity();
-        mKeyguardIndicationTextView.switchIndication(R.string.notification_tap_again);
+        mKeyguardIndicationController.showTransientIndication(R.string.notification_tap_again);
         mStackScroller.setActivatedChild(view);
     }
 
@@ -2951,7 +2971,7 @@
     @Override
     public void onActivationReset(View view) {
         if (view == mStackScroller.getActivatedChild()) {
-            mKeyguardIndicationTextView.switchIndication(mKeyguardHotwordPhrase);
+            mKeyguardIndicationController.hideTransientIndication();
             mStackScroller.setActivatedChild(null);
         }
     }
@@ -2960,11 +2980,20 @@
     }
 
     public void onUnlockHintStarted() {
-        mKeyguardIndicationTextView.switchIndication(R.string.keyguard_unlock);
+        mKeyguardIndicationController.showTransientIndication(R.string.keyguard_unlock);
     }
 
-    public void onUnlockHintFinished() {
-        mKeyguardIndicationTextView.switchIndication(mKeyguardHotwordPhrase);
+    public void onHintFinished() {
+        // Delay the reset a bit so the user can read the text.
+        mKeyguardIndicationController.hideTransientIndicationDelayed(HINT_RESET_DELAY_MS);
+    }
+
+    public void onCameraHintStarted() {
+        mKeyguardIndicationController.showTransientIndication(R.string.camera_hint);
+    }
+
+    public void onPhoneHintStarted() {
+        mKeyguardIndicationController.showTransientIndication(R.string.phone_hint);
     }
 
     public void onTrackingStopped(boolean expand) {
@@ -3000,6 +3029,11 @@
         mStackScroller.setDimmed(false /* dimmed */, true /* animate */);
     }
 
+    @Override
+    public void onTouchSlopExceeded() {
+        mStackScroller.removeLongPressCallback();
+    }
+
     /**
      * If secure with redaction: Show bouncer, go to unlocked shade.
      *
@@ -3023,6 +3057,16 @@
     }
 
     /**
+     * Goes back to the keyguard after hanging around in {@link StatusBarState#SHADE_LOCKED}.
+     */
+    public void goToKeyguard() {
+        if (mState == StatusBarState.SHADE_LOCKED) {
+            setBarState(StatusBarState.KEYGUARD);
+            updateKeyguardState();
+        }
+    }
+
+    /**
      * @return a ViewGroup that spans the entire panel which contains the quick settings
      */
     public ViewGroup getQuickSettingsOverlayParent() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
index 910d88c..3a17177 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -111,8 +111,7 @@
     @Override
     public void onAllPanelsCollapsed() {
         super.onAllPanelsCollapsed();
-        // give animations time to settle
-        mBar.makeExpandedInvisibleSoon();
+        mBar.makeExpandedInvisible();
         mLastFullyOpenedPanel = null;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index e3145a6..09e4d94 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -181,6 +181,10 @@
         reset();
     }
 
+    public boolean isOccluded() {
+        return mOccluded;
+    }
+
     /**
      * Hides the keyguard view
      */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index b51626d..d5e8e8c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -40,7 +40,6 @@
     public static final String TAG = "StatusBarWindowView";
     public static final boolean DEBUG = BaseStatusBar.DEBUG;
 
-    private ExpandHelper mExpandHelper;
     private DragDownHelper mDragDownHelper;
     private NotificationStackScrollLayout mStackScrollLayout;
     private NotificationPanelView mNotificationPanel;
@@ -73,12 +72,6 @@
         mStackScrollLayout = (NotificationStackScrollLayout) findViewById(
                 R.id.notification_stack_scroller);
         mNotificationPanel = (NotificationPanelView) findViewById(R.id.notification_panel);
-        int minHeight = getResources().getDimensionPixelSize(R.dimen.notification_min_height);
-        int maxHeight = getResources().getDimensionPixelSize(R.dimen.notification_max_height);
-        mExpandHelper = new ExpandHelper(getContext(), mStackScrollLayout,
-                minHeight, maxHeight);
-        mExpandHelper.setEventSource(this);
-        mExpandHelper.setScrollAdapter(mStackScrollLayout);
         mDragDownHelper = new DragDownHelper(getContext(), this, mStackScrollLayout, mService);
 
         // We really need to be able to animate while window animations are going on
@@ -114,12 +107,6 @@
         boolean intercept = false;
         if (mNotificationPanel.isFullyExpanded()
                 && mStackScrollLayout.getVisibility() == View.VISIBLE
-                && (mService.getBarState() == StatusBarState.SHADE
-                        || (mService.getBarState() == StatusBarState.SHADE_LOCKED
-                                && !mService.isBouncerShowing()))) {
-            intercept = mExpandHelper.onInterceptTouchEvent(ev);
-        } else if (mNotificationPanel.isFullyExpanded()
-                && mStackScrollLayout.getVisibility() == View.VISIBLE
                 && mService.getBarState() == StatusBarState.KEYGUARD
                 && !mService.isBouncerShowing()) {
             intercept = mDragDownHelper.onInterceptTouchEvent(ev);
@@ -139,10 +126,7 @@
     @Override
     public boolean onTouchEvent(MotionEvent ev) {
         boolean handled = false;
-        if (mNotificationPanel.isFullyExpanded()
-                && mService.getBarState() != StatusBarState.KEYGUARD) {
-            handled = mExpandHelper.onTouchEvent(ev);
-        } else if (mService.getBarState() == StatusBarState.KEYGUARD) {
+        if (mService.getBarState() == StatusBarState.KEYGUARD) {
             handled = mDragDownHelper.onTouchEvent(ev);
         }
         if (!handled) {
@@ -168,8 +152,8 @@
     }
 
     public void cancelExpandHelper() {
-        if (mExpandHelper != null) {
-            mExpandHelper.cancel();
+        if (mStackScrollLayout != null) {
+            mStackScrollLayout.cancelExpandHelper();
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
index 117bf61..379b509 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
@@ -45,6 +45,7 @@
         filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
         filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
         filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
+        filter.addAction(BluetoothDevice.ACTION_ALIAS_CHANGED);
         context.registerReceiver(this, filter);
 
         final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
@@ -104,8 +105,8 @@
 
     @Override
     public String getLastDeviceName() {
-        return mLastDevice != null ? mLastDevice.getName()
-                : mBondedDevices.size() == 1 ? mBondedDevices.iterator().next().getName()
+        return mLastDevice != null ? mLastDevice.getAliasName()
+                : mBondedDevices.size() == 1 ? mBondedDevices.iterator().next().getAliasName()
                 : null;
     }
 
@@ -122,6 +123,9 @@
                     == BluetoothAdapter.STATE_CONNECTING;
             mLastDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
         }
+        if (action.equals(BluetoothDevice.ACTION_ALIAS_CHANGED)) {
+            mLastDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+        }
         fireCallbacks();
         updateBondedBluetoothDevices();
     }
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 ac26da2..df01c12 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
@@ -225,6 +225,11 @@
         }
     }
 
+    @Override
+    public void expansionStateChanged(boolean isExpanding) {
+
+    }
+
     // SwipeHelper.Callback methods
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeController.java
index 6225c12..4cf72a2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeController.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.policy;
 
+import android.net.Uri;
 import android.service.notification.Condition;
 
 public interface ZenModeController {
@@ -24,10 +25,12 @@
     void setZen(boolean zen);
     boolean isZen();
     void requestConditions(boolean request);
-    void select(Condition condition);
+    void setExitConditionId(Uri exitConditionId);
+    Uri getExitConditionId();
 
     public static class Callback {
         public void onZenChanged(boolean zen) {}
+        public void onExitConditionChanged(Uri exitConditionId) {}
         public void onConditionsChanged(Condition[] conditions) {}
     }
 }
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
index adf2935..da8fd32 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
@@ -25,6 +25,7 @@
 import android.provider.Settings.Global;
 import android.service.notification.Condition;
 import android.service.notification.IConditionListener;
+import android.service.notification.ZenModeConfig;
 import android.util.Slog;
 
 import com.android.systemui.qs.GlobalSetting;
@@ -35,10 +36,12 @@
 /** Platform implementation of the zen mode controller. **/
 public class ZenModeControllerImpl implements ZenModeController {
     private static final String TAG = "ZenModeControllerImpl";
+    private static final boolean DEBUG = false;
 
     private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>();
     private final Context mContext;
-    private final GlobalSetting mSetting;
+    private final GlobalSetting mModeSetting;
+    private final GlobalSetting mConfigSetting;
     private final INotificationManager mNoMan;
     private final LinkedHashMap<Uri, Condition> mConditions = new LinkedHashMap<Uri, Condition>();
 
@@ -46,13 +49,20 @@
 
     public ZenModeControllerImpl(Context context, Handler handler) {
         mContext = context;
-        mSetting = new GlobalSetting(mContext, handler, Global.ZEN_MODE) {
+        mModeSetting = new GlobalSetting(mContext, handler, Global.ZEN_MODE) {
             @Override
             protected void handleValueChanged(int value) {
                 fireZenChanged(value != 0);
             }
         };
-        mSetting.setListening(true);
+        mConfigSetting = new GlobalSetting(mContext, handler, Global.ZEN_MODE_CONFIG_ETAG) {
+            @Override
+            protected void handleValueChanged(int value) {
+                fireExitConditionChanged();
+            }
+        };
+        mModeSetting.setListening(true);
+        mConfigSetting.setListening(true);
         mNoMan = INotificationManager.Stub.asInterface(
                 ServiceManager.getService(Context.NOTIFICATION_SERVICE));
     }
@@ -69,12 +79,12 @@
 
     @Override
     public boolean isZen() {
-        return mSetting.getValue() != 0;
+        return mModeSetting.getValue() != 0;
     }
 
     @Override
     public void setZen(boolean zen) {
-        mSetting.setValue(zen ? 1 : 0);
+        mModeSetting.setValue(zen ? 1 : 0);
     }
 
     @Override
@@ -91,14 +101,27 @@
     }
 
     @Override
-    public void select(Condition condition) {
+    public void setExitConditionId(Uri exitConditionId) {
         try {
-            mNoMan.setZenModeCondition(condition == null ? null : condition.id);
+            mNoMan.setZenModeCondition(exitConditionId);
         } catch (RemoteException e) {
             // noop
         }
     }
 
+    @Override
+    public Uri getExitConditionId() {
+        try {
+            final ZenModeConfig config = mNoMan.getZenModeConfig();
+            if (config != null) {
+                return config.exitConditionId;
+            }
+        } catch (RemoteException e) {
+            // noop
+        }
+        return null;
+    }
+
     private void fireZenChanged(boolean zen) {
         for (Callback cb : mCallbacks) {
             cb.onZenChanged(zen);
@@ -111,6 +134,14 @@
         }
     }
 
+    private void fireExitConditionChanged() {
+        final Uri exitConditionId = getExitConditionId();
+        if (DEBUG) Slog.d(TAG, "exitConditionId changed: " + exitConditionId);
+        for (Callback cb : mCallbacks) {
+            cb.onExitConditionChanged(exitConditionId);
+        }
+    }
+
     private void updateConditions(Condition[] conditions) {
         if (conditions == null || conditions.length == 0) return;
         for (Condition c : conditions) {
@@ -124,8 +155,8 @@
     private final IConditionListener mListener = new IConditionListener.Stub() {
         @Override
         public void onConditionsReceived(Condition[] conditions) {
-            Slog.d(TAG, "onConditionsReceived " + (conditions == null ? 0 : conditions.length)
-                    + " mRequesting=" + mRequesting); 
+            if (DEBUG) Slog.d(TAG, "onConditionsReceived "
+                    + (conditions == null ? 0 : conditions.length) + " mRequesting=" + mRequesting);
             if (!mRequesting) return;
             updateConditions(conditions);
         }
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 5c98d51..20caed8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -30,7 +30,6 @@
 import android.view.ViewTreeObserver;
 import android.view.animation.AnimationUtils;
 import android.widget.OverScroller;
-
 import com.android.systemui.ExpandHelper;
 import com.android.systemui.R;
 import com.android.systemui.SwipeHelper;
@@ -51,13 +50,16 @@
 
     private static final String TAG = "NotificationStackScrollLayout";
     private static final boolean DEBUG = false;
-    private static final float RUBBER_BAND_FACTOR = 0.35f;
+    private static final float RUBBER_BAND_FACTOR_NORMAL = 0.35f;
+    private static final float RUBBER_BAND_FACTOR_AFTER_EXPAND = 0.15f;
+    private static final float RUBBER_BAND_FACTOR_ON_PANEL_EXPAND = 0.21f;
 
     /**
      * Sentinel value for no current active pointer. Used by {@link #mActivePointerId}.
      */
     private static final int INVALID_POINTER = -1;
 
+    private ExpandHelper mExpandHelper;
     private SwipeHelper mSwipeHelper;
     private boolean mSwipingInProgress;
     private int mCurrentStackHeight = Integer.MAX_VALUE;
@@ -73,6 +75,7 @@
     private float mMaxOverScroll;
     private boolean mIsBeingDragged;
     private int mLastMotionY;
+    private int mDownX;
     private int mActivePointerId;
 
     private int mSidePaddings;
@@ -106,6 +109,7 @@
     private ArrayList<View> mSwipedOutViews = new ArrayList<View>();
     private final StackStateAnimator mStateAnimator = new StackStateAnimator(this);
     private boolean mAnimationsEnabled;
+    private boolean mChangePositionInProgress;
 
     /**
      * The raw amount of the overScroll on the top, which is not rubber-banded.
@@ -128,6 +132,39 @@
     private boolean mChildrenUpdateRequested;
     private SpeedBumpView mSpeedBumpView;
     private boolean mIsExpansionChanging;
+    private boolean mExpandingNotification;
+    private boolean mExpandedInThisMotion;
+    private boolean mScrollingEnabled;
+
+    /**
+     * Was the scroller scrolled to the top when the down motion was observed?
+     */
+    private boolean mScrolledToTopOnFirstDown;
+
+    /**
+     * The minimal amount of over scroll which is needed in order to switch to the quick settings
+     * when over scrolling on a expanded card.
+     */
+    private float mMinTopOverScrollToEscape;
+    private int mIntrinsicPadding;
+    private int mNotificationTopPadding;
+    private int mMinStackHeight;
+    private boolean mDontReportNextOverScroll;
+
+    /**
+     * The maximum scrollPosition which we are allowed to reach when a notification was expanded.
+     * This is needed to avoid scrolling too far after the notification was collapsed in the same
+     * motion.
+     */
+    private int mMaxScrollAfterExpand;
+    private OnLongClickListener mLongClickListener;
+
+    /**
+     * Should in this touch motion only be scrolling allowed? It's true when the scroller was
+     * animating.
+     */
+    private boolean mOnlyScrollingInThisMotion;
+    private boolean mTouchEnabled = true;
     private ViewTreeObserver.OnPreDrawListener mChildrenUpdater
             = new ViewTreeObserver.OnPreDrawListener() {
         @Override
@@ -194,6 +231,7 @@
         float densityScale = getResources().getDisplayMetrics().density;
         float pagingTouchSlop = ViewConfiguration.get(getContext()).getScaledPagingTouchSlop();
         mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, densityScale, pagingTouchSlop);
+        mSwipeHelper.setLongPressListener(mLongClickListener);
 
         mSidePaddings = context.getResources()
                 .getDimensionPixelSize(R.dimen.notification_side_padding);
@@ -207,6 +245,17 @@
         mPaddingBetweenElementsNormal = context.getResources()
                 .getDimensionPixelSize(R.dimen.notification_padding);
         updatePadding(false);
+        int minHeight = getResources().getDimensionPixelSize(R.dimen.notification_min_height);
+        int maxHeight = getResources().getDimensionPixelSize(R.dimen.notification_max_height);
+        mExpandHelper = new ExpandHelper(getContext(), this,
+                minHeight, maxHeight);
+        mExpandHelper.setEventSource(this);
+        mExpandHelper.setScrollAdapter(this);
+        mMinTopOverScrollToEscape = getResources().getDimensionPixelSize(
+                R.dimen.min_top_overscroll_to_qs);
+        mNotificationTopPadding = getResources().getDimensionPixelSize(
+                R.dimen.notifications_top_padding);
+        mMinStackHeight = getResources().getDimensionPixelSize(R.dimen.collapsed_stack_height);
     }
 
     private void updatePadding(boolean dimmed) {
@@ -215,6 +264,13 @@
                 : mPaddingBetweenElementsNormal;
         mBottomStackSlowDownHeight = mStackScrollAlgorithm.getBottomStackSlowDownLength();
         updateContentHeight();
+        notifyHeightChangeListener(null);
+    }
+
+    private void notifyHeightChangeListener(ExpandableView view) {
+        if (mOnHeightChangedListener != null) {
+            mOnHeightChangedListener.onHeightChanged(view);
+        }
     }
 
     @Override
@@ -343,7 +399,7 @@
         return mTopPadding;
     }
 
-    public void setTopPadding(int topPadding, boolean animate) {
+    private void setTopPadding(int topPadding, boolean animate) {
         if (mTopPadding != topPadding) {
             mTopPadding = topPadding;
             updateAlgorithmHeightAndPadding();
@@ -353,9 +409,7 @@
                 mNeedsAnimation =  true;
             }
             requestChildrenUpdate();
-            if (mOnHeightChangedListener != null) {
-                mOnHeightChangedListener.onHeightChanged(null);
-            }
+            notifyHeightChangeListener(null);
         }
     }
 
@@ -414,6 +468,7 @@
 
     public void setLongPressListener(View.OnLongClickListener listener) {
         mSwipeHelper.setLongPressListener(listener);
+        mLongClickListener = listener;
     }
 
     public void onChildDismissed(View v) {
@@ -511,6 +566,29 @@
         if (v instanceof ExpandableNotificationRow) {
             ((ExpandableNotificationRow) v).setUserLocked(userLocked);
         }
+        removeLongPressCallback();
+        requestDisallowInterceptTouchEvent(true);
+    }
+
+    @Override
+    public void expansionStateChanged(boolean isExpanding) {
+        mExpandingNotification = isExpanding;
+        if (!mExpandedInThisMotion) {
+            mMaxScrollAfterExpand = mOwnScrollY;
+            mExpandedInThisMotion = true;
+        }
+    }
+
+    public void setScrollingEnabled(boolean enable) {
+        mScrollingEnabled = enable;
+    }
+
+    public void setExpandingEnabled(boolean enable) {
+        mExpandHelper.setEnabled(enable);
+    }
+
+    private boolean isScrollingEnabled() {
+        return mScrollingEnabled;
     }
 
     public View getChildContentView(View v) {
@@ -548,18 +626,44 @@
         if (!isEnabled()) {
             return false;
         }
+        boolean isCancelOrUp = ev.getActionMasked() == MotionEvent.ACTION_CANCEL
+                || ev.getActionMasked()== MotionEvent.ACTION_UP;
+        boolean expandWantsIt = false;
+        if (!mSwipingInProgress && !mOnlyScrollingInThisMotion) {
+            if (isCancelOrUp) {
+                mExpandHelper.onlyObserveMovements(false);
+            }
+            boolean wasExpandingBefore = mExpandingNotification;
+            expandWantsIt = mExpandHelper.onTouchEvent(ev);
+            if (mExpandedInThisMotion && !mExpandingNotification && wasExpandingBefore) {
+                dispatchDownEventToScroller(ev);
+            }
+        }
         boolean scrollerWantsIt = false;
-        if (!mSwipingInProgress) {
+        if (!mSwipingInProgress && !mExpandingNotification) {
             scrollerWantsIt = onScrollTouch(ev);
         }
         boolean horizontalSwipeWantsIt = false;
-        if (!mIsBeingDragged) {
+        if (!mIsBeingDragged
+                && !mExpandingNotification
+                && !mExpandedInThisMotion
+                && !mOnlyScrollingInThisMotion) {
             horizontalSwipeWantsIt = mSwipeHelper.onTouchEvent(ev);
         }
-        return horizontalSwipeWantsIt || scrollerWantsIt || super.onTouchEvent(ev);
+        return horizontalSwipeWantsIt || scrollerWantsIt || expandWantsIt || super.onTouchEvent(ev);
+    }
+
+    private void dispatchDownEventToScroller(MotionEvent ev) {
+        MotionEvent downEvent = MotionEvent.obtain(ev);
+        downEvent.setAction(MotionEvent.ACTION_DOWN);
+        onScrollTouch(downEvent);
+        downEvent.recycle();
     }
 
     private boolean onScrollTouch(MotionEvent ev) {
+        if (!isScrollingEnabled()) {
+            return false;
+        }
         initVelocityTrackerIfNotExists();
         mVelocityTracker.addMovement(ev);
 
@@ -583,6 +687,7 @@
 
                 // Remember where the motion event started
                 mLastMotionY = (int) ev.getY();
+                mDownX = (int) ev.getX();
                 mActivePointerId = ev.getPointerId(0);
                 break;
             }
@@ -594,8 +699,11 @@
                 }
 
                 final int y = (int) ev.getY(activePointerIndex);
+                final int x = (int) ev.getX(activePointerIndex);
                 int deltaY = mLastMotionY - y;
-                if (!mIsBeingDragged && Math.abs(deltaY) > mTouchSlop) {
+                final int xDiff = Math.abs(x - mDownX);
+                final int yDiff = Math.abs(deltaY);
+                if (!mIsBeingDragged && yDiff > mTouchSlop && yDiff > xDiff) {
                     setIsBeingDragged(true);
                     if (deltaY > 0) {
                         deltaY -= mTouchSlop;
@@ -606,7 +714,10 @@
                 if (mIsBeingDragged) {
                     // Scroll to follow the motion event
                     mLastMotionY = y;
-                    final int range = getScrollRange();
+                    int range = getScrollRange();
+                    if (mExpandedInThisMotion) {
+                        range = Math.min(range, mMaxScrollAfterExpand);
+                    }
 
                     float scrollAmount;
                     if (deltaY < 0) {
@@ -631,19 +742,28 @@
                     velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
                     int initialVelocity = (int) velocityTracker.getYVelocity(mActivePointerId);
 
-                    if (getChildCount() > 0) {
-                        if ((Math.abs(initialVelocity) > mMinimumVelocity)) {
-                            fling(-initialVelocity);
-                        } else {
-                            if (mScroller.springBack(mScrollX, mOwnScrollY, 0, 0, 0,
-                                    getScrollRange())) {
-                                postInvalidateOnAnimation();
+                    if (shouldOverScrollFling(initialVelocity)) {
+                        onOverScrollFling(true, initialVelocity);
+                    } else {
+                        if (getChildCount() > 0) {
+                            if ((Math.abs(initialVelocity) > mMinimumVelocity)) {
+                                float currentOverScrollTop = getCurrentOverScrollAmount(true);
+                                if (currentOverScrollTop == 0.0f || initialVelocity > 0) {
+                                    fling(-initialVelocity);
+                                } else {
+                                    onOverScrollFling(false, initialVelocity);
+                                }
+                            } else {
+                                if (mScroller.springBack(mScrollX, mOwnScrollY, 0, 0, 0,
+                                        getScrollRange())) {
+                                    postInvalidateOnAnimation();
+                                }
                             }
                         }
-                    }
 
-                    mActivePointerId = INVALID_POINTER;
-                    endDrag();
+                        mActivePointerId = INVALID_POINTER;
+                        endDrag();
+                    }
                 }
                 break;
             case MotionEvent.ACTION_CANCEL:
@@ -658,17 +778,27 @@
             case MotionEvent.ACTION_POINTER_DOWN: {
                 final int index = ev.getActionIndex();
                 mLastMotionY = (int) ev.getY(index);
+                mDownX = (int) ev.getX(index);
                 mActivePointerId = ev.getPointerId(index);
                 break;
             }
             case MotionEvent.ACTION_POINTER_UP:
                 onSecondaryPointerUp(ev);
                 mLastMotionY = (int) ev.getY(ev.findPointerIndex(mActivePointerId));
+                mDownX = (int) ev.getX(ev.findPointerIndex(mActivePointerId));
                 break;
         }
         return true;
     }
 
+    private void onOverScrollFling(boolean open, int initialVelocity) {
+        if (mOverscrollTopChangedListener != null) {
+            mOverscrollTopChangedListener.flingTopOverscroll(initialVelocity, open);
+        }
+        mDontReportNextOverScroll = true;
+        setOverScrollAmount(0.0f, true, false);
+    }
+
     /**
      * Perform a scroll upwards and adapt the overscroll amounts accordingly
      *
@@ -689,11 +819,13 @@
         float scrollAmount = newTopAmount < 0 ? -newTopAmount : 0.0f;
         float newScrollY = mOwnScrollY + scrollAmount;
         if (newScrollY > range) {
-            float currentBottomPixels = getCurrentOverScrolledPixels(false);
-            // We overScroll on the top
-            setOverScrolledPixels(currentBottomPixels + newScrollY - range,
-                    false /* onTop */,
-                    false /* animate */);
+            if (!mExpandedInThisMotion) {
+                float currentBottomPixels = getCurrentOverScrolledPixels(false);
+                // We overScroll on the top
+                setOverScrolledPixels(currentBottomPixels + newScrollY - range,
+                        false /* onTop */,
+                        false /* animate */);
+            }
             mOwnScrollY = range;
             scrollAmount = 0.0f;
         }
@@ -834,7 +966,7 @@
      * @param animate Should an animation be performed.
      */
     public void setOverScrolledPixels(float numPixels, boolean onTop, boolean animate) {
-        setOverScrollAmount(numPixels * RUBBER_BAND_FACTOR, onTop, animate, true);
+        setOverScrollAmount(numPixels * getRubberBandFactor(), onTop, animate, true);
     }
 
     /**
@@ -870,17 +1002,21 @@
         if (animate) {
             mStateAnimator.animateOverScrollToAmount(amount, onTop);
         } else {
-            setOverScrolledPixels(amount / RUBBER_BAND_FACTOR, onTop);
+            setOverScrolledPixels(amount / getRubberBandFactor(), onTop);
             mAmbientState.setOverScrollAmount(amount, onTop);
-            requestChildrenUpdate();
             if (onTop) {
-                float scrollAmount = mOwnScrollY < 0 ? -mOwnScrollY : 0;
-                notifyOverscrollTopListener(scrollAmount + amount);
+                notifyOverscrollTopListener(amount);
             }
+            requestChildrenUpdate();
         }
     }
 
     private void notifyOverscrollTopListener(float amount) {
+        mExpandHelper.onlyObserveMovements(amount > 1.0f);
+        if (mDontReportNextOverScroll) {
+            mDontReportNextOverScroll = false;
+            return;
+        }
         if (mOverscrollTopChangedListener != null) {
             mOverscrollTopChangedListener.onOverscrollTopChanged(amount);
         }
@@ -928,7 +1064,7 @@
                 updateChildren();
                 float overScrollTop = getCurrentOverScrollAmount(true);
                 if (mOwnScrollY < 0) {
-                    notifyOverscrollTopListener(-mOwnScrollY + overScrollTop);
+                    notifyOverscrollTopListener(-mOwnScrollY);
                 } else {
                     notifyOverscrollTopListener(overScrollTop);
                 }
@@ -950,6 +1086,7 @@
                 onTop = true;
                 newAmount = -mOwnScrollY;
                 mOwnScrollY = 0;
+                mDontReportNextOverScroll = true;
             } else {
                 onTop = false;
                 newAmount = mOwnScrollY - scrollRange;
@@ -1085,13 +1222,14 @@
             float bottomAmount = getCurrentOverScrollAmount(false);
             if (velocityY < 0 && topAmount > 0) {
                 mOwnScrollY -= (int) topAmount;
+                mDontReportNextOverScroll = true;
                 setOverScrollAmount(0, true, false);
-                mMaxOverScroll = Math.abs(velocityY) / 1000f * RUBBER_BAND_FACTOR
+                mMaxOverScroll = Math.abs(velocityY) / 1000f * getRubberBandFactor()
                         * mOverflingDistance + topAmount;
             } else if (velocityY > 0 && bottomAmount > 0) {
                 mOwnScrollY += bottomAmount;
                 setOverScrollAmount(0, false, false);
-                mMaxOverScroll = Math.abs(velocityY) / 1000f * RUBBER_BAND_FACTOR
+                mMaxOverScroll = Math.abs(velocityY) / 1000f * getRubberBandFactor()
                         * mOverflingDistance + bottomAmount;
             } else {
                 // it will be set once we reach the boundary
@@ -1104,6 +1242,47 @@
         }
     }
 
+    /**
+     * @return Whether a fling performed on the top overscroll edge lead to the expanded
+     * overScroll view (i.e QS).
+     */
+    private boolean shouldOverScrollFling(int initialVelocity) {
+        float topOverScroll = getCurrentOverScrollAmount(true);
+        return mScrolledToTopOnFirstDown
+                && !mExpandedInThisMotion
+                && topOverScroll > mMinTopOverScrollToEscape
+                && initialVelocity > 0;
+    }
+
+    public void updateTopPadding(float qsHeight, int scrollY, boolean animate) {
+        float start = qsHeight - scrollY + mNotificationTopPadding;
+        float stackHeight = getHeight() - start;
+        if (stackHeight <= mMinStackHeight) {
+            float overflow = mMinStackHeight - stackHeight;
+            stackHeight = mMinStackHeight;
+            start = getHeight() - stackHeight;
+            setTranslationY(overflow);
+        } else {
+            setTranslationY(0);
+        }
+        setTopPadding(clampPadding((int) start), animate);
+    }
+
+    private int clampPadding(int desiredPadding) {
+        return Math.max(desiredPadding, mIntrinsicPadding);
+    }
+
+    private float getRubberBandFactor() {
+        if (mExpandedInThisMotion) {
+            return RUBBER_BAND_FACTOR_AFTER_EXPAND;
+        } else if (mIsExpansionChanging) {
+            return RUBBER_BAND_FACTOR_ON_PANEL_EXPAND;
+        } else if (mScrolledToTopOnFirstDown) {
+            return 1.0f;
+        }
+        return RUBBER_BAND_FACTOR_NORMAL;
+    }
+
     private void endDrag() {
         setIsBeingDragged(false);
 
@@ -1119,23 +1298,37 @@
 
     @Override
     public boolean onInterceptTouchEvent(MotionEvent ev) {
+        initDownStates(ev);
+        boolean expandWantsIt = false;
+        if (!mSwipingInProgress && !mOnlyScrollingInThisMotion) {
+            expandWantsIt = mExpandHelper.onInterceptTouchEvent(ev);
+        }
         boolean scrollWantsIt = false;
-        if (!mSwipingInProgress) {
+        if (!mSwipingInProgress && !mExpandingNotification) {
             scrollWantsIt = onInterceptTouchEventScroll(ev);
         }
         boolean swipeWantsIt = false;
-        if (!mIsBeingDragged) {
+        if (!mIsBeingDragged
+                && !mExpandingNotification
+                && !mExpandedInThisMotion
+                && !mOnlyScrollingInThisMotion) {
             swipeWantsIt = mSwipeHelper.onInterceptTouchEvent(ev);
         }
-        return swipeWantsIt || scrollWantsIt ||
-                super.onInterceptTouchEvent(ev);
+        return swipeWantsIt || scrollWantsIt || expandWantsIt || super.onInterceptTouchEvent(ev);
+    }
+
+    private void initDownStates(MotionEvent ev) {
+        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+            mExpandedInThisMotion = false;
+            mOnlyScrollingInThisMotion = !mScroller.isFinished();
+        }
     }
 
     @Override
     protected void onViewRemoved(View child) {
         super.onViewRemoved(child);
         mStackScrollAlgorithm.notifyChildrenChanged(this);
-        if (mChildrenChangingPositions.contains(child)) {
+        if (mChangePositionInProgress) {
             // This is only a position change, don't do anything special
             return;
         }
@@ -1230,7 +1423,7 @@
      * @param child The view to be added.
      */
     public void generateAddAnimation(View child) {
-        if (mIsExpanded && mAnimationsEnabled && !mChildrenChangingPositions.contains(child)) {
+        if (mIsExpanded && mAnimationsEnabled && !mChangePositionInProgress) {
             // Generate Animations
             mChildrenToAddAnimated.add(child);
             mNeedsAnimation = true;
@@ -1245,10 +1438,14 @@
      */
     public void changeViewPosition(View child, int newIndex) {
         if (child != null && child.getParent() == this) {
-            mChildrenChangingPositions.add(child);
+            mChangePositionInProgress = true;
             removeView(child);
             addView(child, newIndex);
-            mNeedsAnimation = true;
+            mChangePositionInProgress = false;
+            if (mIsExpanded && mAnimationsEnabled) {
+                mChildrenChangingPositions.add(child);
+                mNeedsAnimation = true;
+            }
         }
     }
 
@@ -1350,6 +1547,9 @@
     }
 
     private boolean onInterceptTouchEventScroll(MotionEvent ev) {
+        if (!isScrollingEnabled()) {
+            return false;
+        }
         /*
          * This method JUST determines whether we want to intercept the motion.
          * If we return true, onMotionEvent will be called and we do the actual
@@ -1366,13 +1566,6 @@
             return true;
         }
 
-        /*
-         * Don't try to intercept touch if we can't scroll anyway.
-         */
-        if (mOwnScrollY == 0 && getScrollRange() == 0) {
-            return false;
-        }
-
         switch (action & MotionEvent.ACTION_MASK) {
             case MotionEvent.ACTION_MOVE: {
                 /*
@@ -1398,10 +1591,13 @@
                 }
 
                 final int y = (int) ev.getY(pointerIndex);
+                final int x = (int) ev.getX(pointerIndex);
                 final int yDiff = Math.abs(y - mLastMotionY);
-                if (yDiff > mTouchSlop) {
+                final int xDiff = Math.abs(x - mDownX);
+                if (yDiff > mTouchSlop && yDiff > xDiff) {
                     setIsBeingDragged(true);
                     mLastMotionY = y;
+                    mDownX = x;
                     initVelocityTrackerIfNotExists();
                     mVelocityTracker.addMovement(ev);
                 }
@@ -1421,7 +1617,9 @@
                  * ACTION_DOWN always refers to pointer index 0.
                  */
                 mLastMotionY = y;
+                mDownX = (int) ev.getX();
                 mActivePointerId = ev.getPointerId(0);
+                mScrolledToTopOnFirstDown = isScrolledToTop();
 
                 initOrResetVelocityTracker();
                 mVelocityTracker.addMovement(ev);
@@ -1468,7 +1666,7 @@
         mIsBeingDragged = isDragged;
         if (isDragged) {
             requestDisallowInterceptTouchEvent(true);
-            mSwipeHelper.removeLongPressCallback();
+            removeLongPressCallback();
         }
     }
 
@@ -1476,10 +1674,14 @@
     public void onWindowFocusChanged(boolean hasWindowFocus) {
         super.onWindowFocusChanged(hasWindowFocus);
         if (!hasWindowFocus) {
-            mSwipeHelper.removeLongPressCallback();
+            removeLongPressCallback();
         }
     }
 
+    public void removeLongPressCallback() {
+        mSwipeHelper.removeLongPressCallback();
+    }
+
     @Override
     public boolean isScrolledToTop() {
         return mOwnScrollY == 0;
@@ -1528,9 +1730,7 @@
     public void onHeightChanged(ExpandableView view) {
         updateContentHeight();
         updateScrollPositionIfNecessary();
-        if (mOnHeightChangedListener != null) {
-            mOnHeightChangedListener.onHeightChanged(view);
-        }
+        notifyHeightChangeListener(view);
         requestChildrenUpdate();
     }
 
@@ -1608,6 +1808,14 @@
         updateSpeedBump(true);
     }
 
+    public void cancelExpandHelper() {
+        mExpandHelper.cancel();
+    }
+
+    public void setIntrinsicPadding(int intrinsicPadding) {
+        mIntrinsicPadding = intrinsicPadding;
+    }
+
     /**
      * @return the y position of the first notification
      */
@@ -1615,6 +1823,18 @@
         return mTopPadding + getTranslationY();
     }
 
+    public void setTouchEnabled(boolean touchEnabled) {
+        mTouchEnabled = touchEnabled;
+    }
+
+    @Override
+    public boolean dispatchTouchEvent(MotionEvent ev) {
+        if (!mTouchEnabled) {
+            return false;
+        }
+        return super.dispatchTouchEvent(ev);
+    }
+
     /**
      * A listener that is notified when some child locations might have changed.
      */
@@ -1627,6 +1847,15 @@
      */
     public interface OnOverscrollTopChangedListener {
         public void onOverscrollTopChanged(float amount);
+
+        /**
+         * Notify a listener that the scroller wants to escape from the scrolling motion and
+         * start a fling animation to the expanded or collapsed overscroll view (e.g expand the QS)
+         *
+         * @param velocity The velocity that the Scroller had when over flinging
+         * @param open Should the fling open or close the overscroll view.
+         */
+        public void flingTopOverscroll(float velocity, boolean open);
     }
 
     static class AnimationEvent {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
index 2b52c7e..426220a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -113,7 +113,7 @@
         mBottomStackSlowDownLength = context.getResources()
                 .getDimensionPixelSize(R.dimen.bottom_stack_slow_down_length);
         mRoundedRectCornerRadius = context.getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.notification_quantum_rounded_rect_radius);
+                com.android.internal.R.dimen.notification_material_rounded_rect_radius);
     }
 
 
@@ -131,10 +131,14 @@
         algorithmState.scrolledPixelsTop = 0;
         algorithmState.itemsInBottomStack = 0.0f;
         algorithmState.partialInBottom = 0.0f;
-        float topOverScroll = ambientState.getOverScrollAmount(true /* onTop */);
         float bottomOverScroll = ambientState.getOverScrollAmount(false /* onTop */);
-        algorithmState.scrollY = (int) (ambientState.getScrollY() + mCollapsedSize
-                + bottomOverScroll - topOverScroll);
+
+        int scrollY = ambientState.getScrollY();
+
+        // Due to the overScroller, the stackscroller can have negative scroll state. This is
+        // already accounted for by the top padding and doesn't need an additional adaption
+        scrollY = Math.max(0, scrollY);
+        algorithmState.scrollY = (int) (scrollY + mCollapsedSize + bottomOverScroll);
 
         updateVisibleChildren(resultState, algorithmState);
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
index 2edd7d1..225398a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
@@ -726,11 +726,21 @@
             @Override
             public void onAnimationUpdate(ValueAnimator animation) {
                 float currentOverScroll = (float) animation.getAnimatedValue();
-                mHostLayout.setOverScrollAmount(currentOverScroll, onTop, false /* animate */,
-                        false /* cancelAnimators */);
+                mHostLayout.setOverScrollAmount(
+                        currentOverScroll, onTop, false /* animate */, false /* cancelAnimators */);
             }
         });
         overScrollAnimator.setInterpolator(mFastOutSlowInInterpolator);
+        overScrollAnimator.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                if (onTop) {
+                    mTopOverScrollAnimator = null;
+                } else {
+                    mBottomOverScrollAnimator = null;
+                }
+            }
+        });
         overScrollAnimator.start();
         if (onTop) {
             mTopOverScrollAnimator = overScrollAnimator;
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java b/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
index 898b46e..1cab7ea 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
@@ -333,6 +333,7 @@
                 public void onDismiss(DialogInterface dialog) {
                     mActiveStreamType = -1;
                     mAudioManager.forceVolumeControlStream(mActiveStreamType);
+                    collapse();
                 }
             });
 
@@ -602,7 +603,7 @@
         if (LOGD) Log.d(mTag, "expand mZenPanel=" + mZenPanel);
         if (mZenPanel == null) {
             mZenPanel = (ZenModePanel) mZenPanelStub.inflate();
-            mZenPanel.init(mZenController);
+            mZenPanel.init(mZenController, mDialog != null ? 'D' : 'E');
             mZenPanel.setCallback(new ZenModePanel.Callback() {
                 @Override
                 public void onMoreSettings() {
@@ -651,6 +652,9 @@
             mExpandDivider.setVisibility(show ? View.VISIBLE : View.GONE);
             mExpandButton.setImageResource(zen ? com.android.systemui.R.drawable.ic_vol_zen_on
                     : com.android.systemui.R.drawable.ic_vol_zen_off);
+            if (show && !zen) {
+                collapse();
+            }
         } else {
             mExpandButton.setVisibility(View.GONE);
             mExpandDivider.setVisibility(View.GONE);
@@ -882,10 +886,6 @@
             // when the stream is for remote playback, use -1 to reset the stream type evaluation
             mAudioManager.forceVolumeControlStream(stream);
 
-            // Showing dialog - use collapsed state
-            if (mZenModeCapable) {
-                collapse();
-            }
             if (mDialog != null) {
                 mDialog.show();
             }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
index c338563..798e7fa 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
@@ -18,16 +18,21 @@
 
 import android.content.Context;
 import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
 import android.net.Uri;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
 import android.provider.Settings;
 import android.service.notification.Condition;
+import android.service.notification.ZenModeConfig;
 import android.util.AttributeSet;
+import android.util.Log;
 import android.view.ContextThemeWrapper;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.view.ViewGroup;
 import android.widget.CompoundButton;
 import android.widget.CompoundButton.OnCheckedChangeListener;
 import android.widget.ImageView;
@@ -39,26 +44,47 @@
 import com.android.systemui.statusbar.policy.ZenModeController;
 
 import java.util.Arrays;
-import java.util.HashSet;
+import java.util.Objects;
 
 public class ZenModePanel extends LinearLayout {
-    private static final int[] MINUTES = new int[] { 15, 30, 45, 60, 120, 180, 240, 480 };
+    private static final boolean DEBUG = false;
+
+    private static final int[] MINUTE_BUCKETS = new int[] { 15, 30, 45, 60, 120, 180, 240, 480 };
+    private static final int MIN_BUCKET_MINUTES = MINUTE_BUCKETS[0];
+    private static final int MAX_BUCKET_MINUTES = MINUTE_BUCKETS[MINUTE_BUCKETS.length - 1];
+    private static final int DEFAULT_BUCKET_INDEX = Arrays.binarySearch(MINUTE_BUCKETS, 60);
+
+    private static final int SECONDS_MS = 1000;
+    private static final int MINUTES_MS = 60 * SECONDS_MS;
+
     public static final Intent ZEN_SETTINGS = new Intent(Settings.ACTION_ZEN_MODE_SETTINGS);
 
     private final Context mContext;
     private final LayoutInflater mInflater;
-    private final HashSet<RadioButton> mRadioButtons = new HashSet<RadioButton>();
     private final H mHandler = new H();
+    private final Favorites mFavorites;
+
+    private char mLogTag = '?';
+    private String mTag;
     private LinearLayout mConditions;
-    private int mMinutesIndex = Arrays.binarySearch(MINUTES, 60);  // default to one hour
     private Callback mCallback;
     private ZenModeController mController;
     private boolean mRequestingConditions;
+    private Uri mExitConditionId;
+    private int mBucketIndex = -1;
+    private boolean mShowing;
 
     public ZenModePanel(Context context, AttributeSet attrs) {
         super(context, attrs);
         mContext = context;
+        mFavorites = new Favorites();
         mInflater = LayoutInflater.from(new ContextThemeWrapper(context, R.style.QSWhiteTheme));
+        updateTag();
+        if (DEBUG) Log.d(mTag, "new ZenModePanel");
+    }
+
+    private void updateTag() {
+        mTag = "ZenModePanel/" + mLogTag + "/" + Integer.toHexString(System.identityHashCode(this));
     }
 
     @Override
@@ -74,44 +100,97 @@
     }
 
     @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        if (DEBUG) Log.d(mTag, "onAttachedToWindow");
+        final ViewGroup p = (ViewGroup) getParent();
+        updateShowing(p != null && p.getVisibility() == VISIBLE);
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        if (DEBUG) Log.d(mTag, "onDetachedFromWindow");
+        updateShowing(false);
+    }
+
+    @Override
     public void setVisibility(int visibility) {
         super.setVisibility(visibility);
-        setRequestingConditions(visibility == VISIBLE);
+        final boolean vis = visibility == VISIBLE;
+        updateShowing(isAttachedToWindow() && vis);
+    }
+
+    private void updateShowing(boolean showing) {
+        if (showing == mShowing) return;
+        mShowing = showing;
+        if (DEBUG) Log.d(mTag, "mShowing=" + mShowing);
+        if (mController != null) {
+            setRequestingConditions(mShowing);
+        }
     }
 
     /** Start or stop requesting relevant zen mode exit conditions */
     private void setRequestingConditions(boolean requesting) {
         if (mRequestingConditions == requesting) return;
+        if (DEBUG) Log.d(mTag, "setRequestingConditions " + requesting);
         mRequestingConditions = requesting;
-        if (mRequestingConditions) {
-            mController.addCallback(mZenCallback);
-        } else {
-            mController.removeCallback(mZenCallback);
+        if (mController != null) {
+            mController.requestConditions(mRequestingConditions);
         }
-        mController.requestConditions(mRequestingConditions);
+        if (mRequestingConditions) {
+            Condition timeCondition = parseExistingTimeCondition(mExitConditionId);
+            if (timeCondition != null) {
+                mBucketIndex = -1;
+            } else {
+                mBucketIndex = DEFAULT_BUCKET_INDEX;
+                timeCondition = newTimeCondition(MINUTE_BUCKETS[mBucketIndex]);
+            }
+            if (DEBUG) Log.d(mTag, "Initial bucket index: " + mBucketIndex);
+            bind(timeCondition, mConditions.getChildAt(0));
+            handleUpdateConditions(new Condition[0]);
+        } else {
+            mConditions.removeAllViews();
+        }
     }
 
-    public void init(ZenModeController controller) {
+    public void init(ZenModeController controller, char logTag) {
         mController = controller;
+        mLogTag = logTag;
+        updateTag();
+        mExitConditionId = mController.getExitConditionId();
+        if (DEBUG) Log.d(mTag, "init mExitConditionId=" + mExitConditionId);
         mConditions.removeAllViews();
-        bind(updateTimeCondition(), mConditions.getChildAt(0));
-        handleUpdateConditions(new Condition[0]);
+        mController.addCallback(mZenCallback);
+        if (mShowing) {
+            setRequestingConditions(true);
+        }
     }
 
     public void setCallback(Callback callback) {
         mCallback = callback;
     }
 
-    private Condition updateTimeCondition() {
-        final int minutes = MINUTES[mMinutesIndex];
-        final long millis = System.currentTimeMillis() + minutes * 60 * 1000;
-        final Uri id = new Uri.Builder().scheme(Condition.SCHEME).authority("android")
-                .appendPath("countdown").appendPath(Long.toString(millis)).build();
-        final int num = minutes < 60 ? minutes : minutes / 60;
+    private Condition parseExistingTimeCondition(Uri conditionId) {
+        final long time = ZenModeConfig.tryParseCountdownConditionId(conditionId);
+        if (time == 0) return null;
+        final long span = time - System.currentTimeMillis();
+        if (span <= 0 || span > MAX_BUCKET_MINUTES * MINUTES_MS) return null;
+        return timeCondition(time, Math.round(span / (float)MINUTES_MS));
+    }
+
+    private Condition newTimeCondition(int minutesFromNow) {
+        final long now = System.currentTimeMillis();
+        return timeCondition(now + minutesFromNow * MINUTES_MS, minutesFromNow);
+    }
+
+    private Condition timeCondition(long time, int minutes) {
+        final int num = minutes < 60 ? minutes : Math.round(minutes / 60f);
         final int resId = minutes < 60
                 ? R.plurals.zen_mode_duration_minutes
                 : R.plurals.zen_mode_duration_hours;
         final String caption = mContext.getResources().getQuantityString(resId, num, num);
+        final Uri id = ZenModeConfig.toCountdownConditionId(time);
         return new Condition(id, caption, "", "", 0, Condition.STATE_TRUE,
                 Condition.FLAG_RELEVANT_NOW);
     }
@@ -125,14 +204,40 @@
             bind(conditions[i], mConditions.getChildAt(i + 1));
         }
         bind(null, mConditions.getChildAt(newCount + 1));
+        checkForDefault();
     }
 
-    private void editTimeCondition(int delta) {
-        final int i = mMinutesIndex + delta;
-        if (i < 0 || i >= MINUTES.length) return;
-        mMinutesIndex = i;
-        final Condition c = updateTimeCondition();
-        bind(c, mConditions.getChildAt(0));
+    private ConditionTag getConditionTagAt(int index) {
+        return (ConditionTag) mConditions.getChildAt(index).getTag();
+    }
+
+    private void checkForDefault() {
+        // are we left without anything selected?  if so, set a default
+        for (int i = 0; i < mConditions.getChildCount(); i++) {
+            if (getConditionTagAt(i).rb.isChecked()) {
+                return;
+            }
+        }
+        if (DEBUG) Log.d(mTag, "Selecting a default");
+        final int favoriteIndex = mFavorites.getMinuteIndex();
+        if (favoriteIndex == -1) {
+            getConditionTagAt(mConditions.getChildCount() - 1).rb.setChecked(true);
+        } else {
+            final Condition c = newTimeCondition(MINUTE_BUCKETS[favoriteIndex]);
+            mBucketIndex = favoriteIndex;
+            bind(c, mConditions.getChildAt(0));
+            getConditionTagAt(0).rb.setChecked(true);
+        }
+    }
+
+    private void handleExitConditionChanged(Uri exitCondition) {
+        mExitConditionId = exitCondition;
+        if (DEBUG) Log.d(mTag, "handleExitConditionChanged " + mExitConditionId);
+        final int N = mConditions.getChildCount();
+        for (int i = 0; i < N; i++) {
+            final ConditionTag tag = getConditionTagAt(i);
+            tag.rb.setChecked(Objects.equals(tag.conditionId, exitCondition));
+        }
     }
 
     private void bind(final Condition condition, View convertView) {
@@ -140,23 +245,31 @@
         final View row;
         if (convertView == null) {
             row = mInflater.inflate(R.layout.zen_mode_condition, this, false);
+            if (DEBUG) Log.d(mTag, "Adding new condition view for: " + condition);
             mConditions.addView(row);
         } else {
             row = convertView;
         }
-        final int position = mConditions.indexOfChild(row);
-        final RadioButton rb = (RadioButton) row.findViewById(android.R.id.checkbox);
-        mRadioButtons.add(rb);
-        rb.setEnabled(enabled);
-        rb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
+        final ConditionTag tag =
+                row.getTag() != null ? (ConditionTag) row.getTag() : new ConditionTag();
+        row.setTag(tag);
+        if (tag.rb == null) {
+            tag.rb = (RadioButton) row.findViewById(android.R.id.checkbox);
+        }
+        tag.conditionId = condition != null ? condition.id : null;
+        tag.rb.setEnabled(enabled);
+        tag.rb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
             @Override
             public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
-                if (isChecked) {
-                    for (RadioButton otherButton : mRadioButtons) {
-                        if (otherButton == rb) continue;
-                        otherButton.setChecked(false);
+                if (mShowing && isChecked) {
+                    if (DEBUG) Log.d(mTag, "onCheckedChanged " + tag.conditionId);
+                    final int N = mConditions.getChildCount();
+                    for (int i = 0; i < N; i++) {
+                        ConditionTag childTag = getConditionTagAt(i);
+                        if (childTag == tag) continue;
+                        childTag.rb.setChecked(false);
                     }
-                    mController.select(condition);
+                    select(tag.conditionId);
                     fireInteraction();
                 }
             }
@@ -173,9 +286,7 @@
         button1.setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View v) {
-                rb.setChecked(true);
-                editTimeCondition(-1);
-                fireInteraction();
+                onClickTimeButton(row, tag, false /*down*/);
             }
         });
 
@@ -183,29 +294,79 @@
         button2.setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View v) {
-                rb.setChecked(true);
-                editTimeCondition(1);
-                fireInteraction();
+                onClickTimeButton(row, tag, true /*up*/);
             }
         });
         title.setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View v) {
-                rb.setChecked(true);
+                tag.rb.setChecked(true);
                 fireInteraction();
             }
         });
-        if (position == 0) {
-            button1.setEnabled(mMinutesIndex > 0);
-            button2.setEnabled(mMinutesIndex < MINUTES.length - 1);
-            button1.setImageAlpha(button1.isEnabled() ? 0xff : 0x7f);
-            button2.setImageAlpha(button2.isEnabled() ? 0xff : 0x7f);
+
+        final long time = ZenModeConfig.tryParseCountdownConditionId(tag.conditionId);
+        if (time > 0) {
+            if (mBucketIndex > -1) {
+                button1.setEnabled(mBucketIndex > 0);
+                button2.setEnabled(mBucketIndex < MINUTE_BUCKETS.length - 1);
+            } else {
+                final long span = time - System.currentTimeMillis();
+                button1.setEnabled(span > MIN_BUCKET_MINUTES * MINUTES_MS);
+                final Condition maxCondition = newTimeCondition(MAX_BUCKET_MINUTES);
+                button2.setEnabled(!Objects.equals(condition.summary, maxCondition.summary));
+            }
+
+            button1.setAlpha(button1.isEnabled() ? 1f : .5f);
+            button2.setAlpha(button2.isEnabled() ? 1f : .5f);
         } else {
             button1.setVisibility(View.GONE);
             button2.setVisibility(View.GONE);
         }
-        if (position == 0 &&  mConditions.getChildCount() == 1) {
-            rb.setChecked(true);
+    }
+
+    private void onClickTimeButton(View row, ConditionTag tag, boolean up) {
+        Condition newCondition = null;
+        final int N = MINUTE_BUCKETS.length;
+        if (mBucketIndex == -1) {
+            // not on a known index, search for the next or prev bucket by time
+            final long time = ZenModeConfig.tryParseCountdownConditionId(tag.conditionId);
+            final long now = System.currentTimeMillis();
+            for (int i = 0; i < N; i++) {
+                int j = up ? i : N - 1 - i;
+                final int bucketMinutes = MINUTE_BUCKETS[j];
+                final long bucketTime = now + bucketMinutes * MINUTES_MS;
+                if (up && bucketTime > time || !up && bucketTime < time) {
+                    mBucketIndex = j;
+                    newCondition = timeCondition(bucketTime, bucketMinutes);
+                    break;
+                }
+            }
+            if (newCondition == null) {
+                mBucketIndex = DEFAULT_BUCKET_INDEX;
+                newCondition = newTimeCondition(MINUTE_BUCKETS[mBucketIndex]);
+            }
+        } else {
+            // on a known index, simply increment or decrement
+            mBucketIndex = Math.max(0, Math.min(N - 1, mBucketIndex + (up ? 1 : -1)));
+            newCondition = newTimeCondition(MINUTE_BUCKETS[mBucketIndex]);
+        }
+        bind(newCondition, row);
+        tag.rb.setChecked(true);
+        select(newCondition.id);
+        fireInteraction();
+    }
+
+    private void select(Uri conditionId) {
+        if (DEBUG) Log.d(mTag, "select " + conditionId);
+        if (mController != null) {
+            mController.setExitConditionId(conditionId);
+        }
+        mExitConditionId = conditionId;
+        if (conditionId == null) {
+            mFavorites.setMinuteIndex(-1);
+        } else if (ZenModeConfig.isValidCountdownConditionId(conditionId) && mBucketIndex != -1) {
+            mFavorites.setMinuteIndex(mBucketIndex);
         }
     }
 
@@ -226,10 +387,16 @@
         public void onConditionsChanged(Condition[] conditions) {
             mHandler.obtainMessage(H.UPDATE_CONDITIONS, conditions).sendToTarget();
         }
+
+        @Override
+        public void onExitConditionChanged(Uri exitConditionId) {
+            mHandler.obtainMessage(H.EXIT_CONDITION_CHANGED, exitConditionId).sendToTarget();
+        }
     };
 
     private final class H extends Handler {
         private static final int UPDATE_CONDITIONS = 1;
+        private static final int EXIT_CONDITION_CHANGED = 2;
 
         private H() {
             super(Looper.getMainLooper());
@@ -239,6 +406,8 @@
         public void handleMessage(Message msg) {
             if (msg.what == UPDATE_CONDITIONS) {
                 handleUpdateConditions((Condition[])msg.obj);
+            } else if (msg.what == EXIT_CONDITION_CHANGED) {
+                handleExitConditionChanged((Uri)msg.obj);
             }
         }
     }
@@ -247,4 +416,51 @@
         void onMoreSettings();
         void onInteraction();
     }
+
+    // used as the view tag on condition rows
+    private static class ConditionTag {
+        RadioButton rb;
+        Uri conditionId;
+    }
+
+    private final class Favorites implements OnSharedPreferenceChangeListener {
+        private static final String KEY_MINUTE_INDEX = "minuteIndex";
+
+        private int mMinuteIndex;
+
+        private Favorites() {
+            prefs().registerOnSharedPreferenceChangeListener(this);
+            updateMinuteIndex();
+        }
+
+        public int getMinuteIndex() {
+            return mMinuteIndex;
+        }
+
+        public void setMinuteIndex(int minuteIndex) {
+            minuteIndex = clamp(minuteIndex);
+            if (minuteIndex == mMinuteIndex) return;
+            mMinuteIndex = clamp(minuteIndex);
+            if (DEBUG) Log.d(mTag, "Setting favorite minute index: " + mMinuteIndex);
+            prefs().edit().putInt(KEY_MINUTE_INDEX, mMinuteIndex).apply();
+        }
+
+        @Override
+        public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
+            updateMinuteIndex();
+        }
+
+        private SharedPreferences prefs() {
+            return mContext.getSharedPreferences(ZenModePanel.class.getSimpleName(), 0);
+        }
+
+        private void updateMinuteIndex() {
+            mMinuteIndex = clamp(prefs().getInt(KEY_MINUTE_INDEX, DEFAULT_BUCKET_INDEX));
+            if (DEBUG) Log.d(mTag, "Favorite minute index: " + mMinuteIndex);
+        }
+
+        private int clamp(int index) {
+            return Math.max(-1, Math.min(MINUTE_BUCKETS.length - 1, index));
+        }
+    }
 }
diff --git a/packages/WallpaperCropper/src/com/android/photos/BitmapRegionTileSource.java b/packages/WallpaperCropper/src/com/android/photos/BitmapRegionTileSource.java
index 764156d..66ece4f 100644
--- a/packages/WallpaperCropper/src/com/android/photos/BitmapRegionTileSource.java
+++ b/packages/WallpaperCropper/src/com/android/photos/BitmapRegionTileSource.java
@@ -283,9 +283,6 @@
             } catch (FileNotFoundException e) {
                 Log.e("BitmapRegionTileSource", "Failed to load URI " + mUri, e);
                 return null;
-            } catch (IOException e) {
-                Log.e("BitmapRegionTileSource", "Failure while reading URI " + mUri, e);
-                return null;
             }
         }
         @Override
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 2eee853..a8645bc 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -46,6 +46,7 @@
 import android.content.pm.PackageManager;
 import android.content.res.Configuration;
 import android.content.res.Resources;
+import android.content.res.Resources.Theme;
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
 import android.graphics.Color;
@@ -213,7 +214,7 @@
     private int mTitleColor = 0;
 
     private boolean mAlwaysReadCloseOnTouchAttr = false;
-    
+
     private ContextMenuBuilder mContextMenu;
     private MenuDialogHelper mContextMenuHelper;
     private boolean mClosingActionMenu;
@@ -475,7 +476,7 @@
         if (st.isPrepared) {
             return true;
         }
-        
+
         if ((mPreparedPanel != null) && (mPreparedPanel != st)) {
             // Another Panel is prepared and possibly open, so close it
             closePanel(mPreparedPanel, false);
@@ -528,7 +529,7 @@
 
                     return false;
                 }
-                
+
                 st.refreshMenuContent = false;
             }
 
@@ -620,7 +621,7 @@
 
         // Causes the decor view to be recreated
         st.refreshDecorView = true;
-        
+
         st.clearMenuPresenters();
     }
 
@@ -872,7 +873,7 @@
         }
         st.refreshMenuContent = true;
         st.refreshDecorView = true;
-        
+
         // Prepare the options panel if we have an action bar
         if ((featureId == FEATURE_ACTION_BAR || featureId == FEATURE_OPTIONS_PANEL)
                 && mDecorContentParent != null) {
@@ -883,7 +884,7 @@
             }
         }
     }
-    
+
     /**
      * Called when the panel key is pushed down.
      * @param featureId The feature ID of the relevant panel (defaults to FEATURE_OPTIONS_PANEL}.
@@ -892,7 +893,7 @@
      */
     public final boolean onKeyDownPanel(int featureId, KeyEvent event) {
         final int keyCode = event.getKeyCode();
-        
+
         if (event.getRepeatCount() == 0) {
             // The panel key was pushed, so set the chording key
             mPanelChordingKey = keyCode;
@@ -919,7 +920,7 @@
             if (event.isCanceled() || (mDecor != null && mDecor.mActionMode != null)) {
                 return;
             }
-            
+
             boolean playSoundEffect = false;
             final PanelFeatureState st = getPanelState(featureId, true);
             if (featureId == FEATURE_OPTIONS_PANEL && mDecorContentParent != null &&
@@ -1159,22 +1160,40 @@
     protected boolean initializePanelMenu(final PanelFeatureState st) {
         Context context = getContext();
 
-        // If we have an action bar, initialize the menu with a context themed for it.
+        // If we have an action bar, initialize the menu with the right theme.
         if ((st.featureId == FEATURE_OPTIONS_PANEL || st.featureId == FEATURE_ACTION_BAR) &&
                 mDecorContentParent != null) {
-            TypedValue outValue = new TypedValue();
-            Resources.Theme currentTheme = context.getTheme();
-            currentTheme.resolveAttribute(com.android.internal.R.attr.actionBarWidgetTheme,
-                    outValue, true);
-            final int targetThemeRes = outValue.resourceId;
+            final TypedValue outValue = new TypedValue();
+            final Theme baseTheme = context.getTheme();
+            baseTheme.resolveAttribute(com.android.internal.R.attr.actionBarTheme, outValue, true);
 
-            if (targetThemeRes != 0 && context.getThemeResId() != targetThemeRes) {
-                context = new ContextThemeWrapper(context, targetThemeRes);
+            Theme widgetTheme = null;
+            if (outValue.resourceId != 0) {
+                widgetTheme = context.getResources().newTheme();
+                widgetTheme.setTo(baseTheme);
+                widgetTheme.applyStyle(outValue.resourceId, true);
+                widgetTheme.resolveAttribute(
+                        com.android.internal.R.attr.actionBarWidgetTheme, outValue, true);
+            } else {
+                baseTheme.resolveAttribute(
+                        com.android.internal.R.attr.actionBarWidgetTheme, outValue, true);
+            }
+
+            if (outValue.resourceId != 0) {
+                if (widgetTheme == null) {
+                    widgetTheme = context.getResources().newTheme();
+                    widgetTheme.setTo(baseTheme);
+                }
+                widgetTheme.applyStyle(outValue.resourceId, true);
+            }
+
+            if (widgetTheme != null) {
+                context = new ContextThemeWrapper(context, 0);
+                context.getTheme().setTo(widgetTheme);
             }
         }
 
         final MenuBuilder menu = new MenuBuilder(context);
-
         menu.setCallback(this);
         st.setMenu(menu);
 
@@ -1665,7 +1684,7 @@
                 mDecor != null ? mDecor.getKeyDispatcherState() : null;
         //Log.i(TAG, "Key down: repeat=" + event.getRepeatCount()
         //        + " flags=0x" + Integer.toHexString(event.getFlags()));
-        
+
         switch (keyCode) {
             case KeyEvent.KEYCODE_VOLUME_UP:
             case KeyEvent.KEYCODE_VOLUME_DOWN:
@@ -1727,7 +1746,7 @@
         }
         //Log.i(TAG, "Key up: repeat=" + event.getRepeatCount()
         //        + " flags=0x" + Integer.toHexString(event.getFlags()));
-        
+
         switch (keyCode) {
             case KeyEvent.KEYCODE_VOLUME_UP:
             case KeyEvent.KEYCODE_VOLUME_DOWN:
@@ -2278,7 +2297,7 @@
             if (!AccessibilityManager.getInstance(mContext).isEnabled()) {
                 return;
             }
- 
+
             // if we are showing a feature that should be announced and one child
             // make this child the event source since this is the feature itself
             // otherwise the callback will take over and announce its client
@@ -2829,13 +2848,13 @@
             hackTurnOffWindowResizeAnim(bg == null || bg.getOpacity()
                     != PixelFormat.OPAQUE);
         }
-        
+
         @Override
         protected void onAttachedToWindow() {
             super.onAttachedToWindow();
-            
+
             updateWindowResizeState();
-            
+
             final Callback cb = getCallback();
             if (cb != null && !isDestroyed() && mFeatureId < 0) {
                 cb.onAttachedToWindow();
@@ -2856,7 +2875,7 @@
         @Override
         protected void onDetachedFromWindow() {
             super.onDetachedFromWindow();
-            
+
             final Callback cb = getCallback();
             if (cb != null && mFeatureId < 0) {
                 cb.onDetachedFromWindow();
@@ -2890,19 +2909,19 @@
         public android.view.SurfaceHolder.Callback2 willYouTakeTheSurface() {
             return mFeatureId < 0 ? mTakeSurfaceCallback : null;
         }
-        
+
         public InputQueue.Callback willYouTakeTheInputQueue() {
             return mFeatureId < 0 ? mTakeInputQueueCallback : null;
         }
-        
+
         public void setSurfaceType(int type) {
             PhoneWindow.this.setType(type);
         }
-        
+
         public void setSurfaceFormat(int format) {
             PhoneWindow.this.setFormat(format);
         }
-        
+
         public void setSurfaceKeepScreenOn(boolean keepOn) {
             if (keepOn) PhoneWindow.this.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
             else PhoneWindow.this.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
@@ -3119,7 +3138,7 @@
                 setCloseOnTouchOutsideIfNotSet(true);
             }
         }
-        
+
         WindowManager.LayoutParams params = getAttributes();
 
         if (!hasSoftInputMode()) {
@@ -3897,11 +3916,11 @@
         boolean refreshDecorView;
 
         boolean refreshMenuContent;
-        
+
         boolean wasLastOpen;
-        
+
         boolean wasLastExpanded;
-        
+
         /**
          * Contains the state of the menu when told to freeze.
          */
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 0d39586..03d29c0 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -91,6 +91,7 @@
 import android.view.Window;
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
+import android.view.WindowManagerInternal;
 import android.view.WindowManagerPolicy;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
@@ -102,14 +103,17 @@
 import com.android.internal.policy.IKeyguardServiceConstants;
 import com.android.internal.policy.PolicyManager;
 import com.android.internal.policy.impl.keyguard.KeyguardServiceDelegate;
+import com.android.internal.policy.impl.keyguard.KeyguardServiceDelegate.ShowListener;
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.telephony.ITelephony;
 import com.android.internal.widget.PointerLocationView;
+import com.android.server.LocalServices;
 
 import java.io.File;
 import java.io.FileReader;
 import java.io.IOException;
 import java.io.PrintWriter;
+import java.util.ArrayList;
 import java.util.HashSet;
 
 import static android.view.WindowManager.LayoutParams.*;
@@ -131,6 +135,7 @@
     static final boolean DEBUG_LAYOUT = false;
     static final boolean DEBUG_INPUT = false;
     static final boolean DEBUG_STARTING_WINDOW = false;
+    static final boolean DEBUG_WAKEUP = false;
     static final boolean SHOW_STARTING_ANIMATIONS = true;
     static final boolean SHOW_PROCESSES_ON_ALT_MENU = false;
 
@@ -223,6 +228,7 @@
     Context mContext;
     IWindowManager mWindowManager;
     WindowManagerFuncs mWindowManagerFuncs;
+    WindowManagerInternal mWindowManagerInternal;
     PowerManager mPowerManager;
     IStatusBarService mStatusBarService;
     boolean mPreloadedRecentApps;
@@ -264,6 +270,25 @@
     int[] mNavigationBarWidthForRotation = new int[4];
 
     KeyguardServiceDelegate mKeyguardDelegate;
+    // The following are only accessed on the mHandler thread.
+    boolean mKeyguardDrawComplete;
+    boolean mWindowManagerDrawComplete;
+    ArrayList<ScreenOnListener> mScreenOnListeners = new ArrayList<ScreenOnListener>();
+    final IRemoteCallback mWindowManagerDrawCallback = new IRemoteCallback.Stub() {
+        @Override
+        public void sendResult(Bundle data) {
+            if (DEBUG_WAKEUP) Slog.i(TAG, "All windows ready for display!");
+            mHandler.sendEmptyMessage(MSG_WINDOW_MANAGER_DRAWN_COMPLETE);
+        }
+    };
+    final ShowListener mKeyguardDelegateCallback = new ShowListener() {
+        @Override
+        public void onShown(IBinder windowToken) {
+            if (DEBUG_WAKEUP) Slog.d(TAG, "mKeyguardDelegate.ShowListener.onShown.");
+            mHandler.sendEmptyMessage(MSG_KEYGUARD_DRAWN_COMPLETE);
+        }
+    };
+
     GlobalActions mGlobalActions;
     volatile boolean mPowerKeyHandled; // accessed from input reader and handler thread
     boolean mPendingPowerKeyUpCanceled;
@@ -421,6 +446,7 @@
     boolean mSearchKeyShortcutPending;
     boolean mConsumeSearchKeyUp;
     boolean mAssistKeyLongPressed;
+    boolean mPendingMetaAction;
 
     // support for activating the lock screen while the screen is on
     boolean mAllowLockscreenWhenOn;
@@ -486,6 +512,10 @@
     private static final int MSG_DISABLE_POINTER_LOCATION = 2;
     private static final int MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK = 3;
     private static final int MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK = 4;
+    private static final int MSG_KEYGUARD_DRAWN_COMPLETE = 5;
+    private static final int MSG_KEYGUARD_DRAWN_TIMEOUT = 6;
+    private static final int MSG_WINDOW_MANAGER_DRAWN_COMPLETE = 7;
+    private static final int MSG_WAKING_UP = 8;
 
     private class PolicyHandler extends Handler {
         @Override
@@ -503,6 +533,25 @@
                 case MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK:
                     dispatchMediaKeyRepeatWithWakeLock((KeyEvent)msg.obj);
                     break;
+                case MSG_KEYGUARD_DRAWN_COMPLETE:
+                    if (DEBUG_WAKEUP) Slog.w(TAG, "Setting mKeyguardDrawComplete");
+                    mKeyguardDrawComplete = true;
+                    finishScreenTurningOn();
+                    break;
+                case MSG_KEYGUARD_DRAWN_TIMEOUT:
+                    Slog.w(TAG, "Keyguard drawn timeout. Setting mKeyguardDrawComplete");
+                    mKeyguardDrawComplete = true;
+                    finishScreenTurningOn();
+                    break;
+                case MSG_WINDOW_MANAGER_DRAWN_COMPLETE:
+                    if (DEBUG_WAKEUP) Slog.w(TAG, "Setting mWindowManagerDrawComplete");
+                    mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT);
+                    mWindowManagerDrawComplete = true;
+                    finishScreenTurningOn();
+                    break;
+                case MSG_WAKING_UP:
+                    handleWakingUp((ScreenOnListener) msg.obj);
+                    break;
             }
         }
     }
@@ -876,6 +925,8 @@
         mContext = context;
         mWindowManager = windowManager;
         mWindowManagerFuncs = windowManagerFuncs;
+        mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
+
         mHandler = new PolicyHandler();
         mWakeGestureListener = new MyWakeGestureListener(mContext, mHandler);
         mOrientationListener = new MyOrientationListener(mContext, mHandler);
@@ -2038,6 +2089,12 @@
             }
         }
 
+        // Cancel any pending meta actions if we see any other keys being pressed between the down
+        // of the meta key and its corresponding up.
+        if (mPendingMetaAction && keyCode != KeyEvent.KEYCODE_META_LEFT) {
+            mPendingMetaAction = false;
+        }
+
         // First we always handle the home key here, so applications
         // can never break it, although if keyguard is on, we do let
         // it handle it, because that gives us the correct 5 second
@@ -2232,6 +2289,14 @@
                 mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT_OR_SELF);
             }
             return -1;
+        } else if (keyCode == KeyEvent.KEYCODE_META_LEFT) {
+            if (down) {
+                mPendingMetaAction = true;
+            } else if (mPendingMetaAction) {
+                mPendingMetaAction = false;
+                launchAssistAction();
+            }
+            return -1;
         }
 
         // Shortcuts are invoked through Search+key, so intercept those here
@@ -2341,6 +2406,11 @@
             return -1;
         }
 
+        // Reserve all the META modifier combos for system behavior
+        if ((metaState & KeyEvent.META_META_LEFT_ON) != 0) {
+            return -1;
+        }
+
         // Let the application handle the key.
         return 0;
     }
@@ -3045,7 +3115,7 @@
     public void layoutWindowLw(WindowState win, WindowManager.LayoutParams attrs,
             WindowState attached) {
         // we've already done the status bar
-        if (win == mStatusBar || win == mNavigationBar) {
+        if ((win == mStatusBar && !doesForceHide(attrs)) || win == mNavigationBar) {
             return;
         }
         final boolean isDefaultDisplay = win.isDefaultDisplay();
@@ -3323,7 +3393,8 @@
                             = mOverscanScreenTop + mOverscanScreenHeight;
                 } else if (canHideNavigationBar()
                         && (sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0
-                        && (attrs.type == TYPE_TOAST
+                        && (attrs.type == TYPE_STATUS_BAR
+                            || attrs.type == TYPE_TOAST
                             || (attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW
                             && attrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW))) {
                     // Asking for layout as if the nav bar is hidden, lets the
@@ -4464,10 +4535,15 @@
     @Override
     public void wakingUp(final ScreenOnListener screenOnListener) {
         EventLog.writeEvent(70000, 1);
-        if (false) {
-            RuntimeException here = new RuntimeException("here");
-            here.fillInStackTrace();
-            Slog.i(TAG, "Screen turning on...", here);
+        if (DEBUG_WAKEUP) Slog.i(TAG, "Screen turning on...",
+                new RuntimeException("here").fillInStackTrace());
+        mHandler.obtainMessage(MSG_WAKING_UP, screenOnListener).sendToTarget();
+    }
+
+    // Called on the mHandler thread.
+    private void handleWakingUp(final ScreenOnListener screenOnListener) {
+        if (screenOnListener != null) {
+            mScreenOnListeners.add(screenOnListener);
         }
 
         synchronized (mLock) {
@@ -4477,51 +4553,28 @@
             updateLockScreenTimeout();
         }
 
-        waitForKeyguard(screenOnListener);
-    }
-
-    private void waitForKeyguard(final ScreenOnListener screenOnListener) {
+        mKeyguardDrawComplete = false;
+        mWindowManagerDrawComplete = false;
         if (mKeyguardDelegate != null) {
-            mKeyguardDelegate.onScreenTurnedOn(new KeyguardServiceDelegate.ShowListener() {
-                @Override
-                public void onShown(IBinder windowToken) {
-                    waitForKeyguardWindowDrawn(windowToken, screenOnListener);
-                }
-            });
+            mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT);
+            mHandler.sendEmptyMessageDelayed(MSG_KEYGUARD_DRAWN_TIMEOUT, 1000);
+            mKeyguardDelegate.onScreenTurnedOn(mKeyguardDelegateCallback);
         } else {
-            Slog.i(TAG, "No keyguard interface!");
-            finishScreenTurningOn(screenOnListener);
+            if (DEBUG_WAKEUP) Slog.d(TAG, "null mKeyguardDelegate: setting mKeyguardDrawComplete.");
+            mKeyguardDrawComplete = true;
         }
+        mWindowManagerInternal.waitForAllWindowsDrawn(mWindowManagerDrawCallback, 500);
     }
 
-    private void waitForKeyguardWindowDrawn(IBinder windowToken,
-            final ScreenOnListener screenOnListener) {
-        if (windowToken != null && !mHideLockScreen) {
-            try {
-                if (mWindowManager.waitForWindowDrawn(
-                        windowToken, new IRemoteCallback.Stub() {
-                    @Override
-                    public void sendResult(Bundle data) {
-                        Slog.i(TAG, "Lock screen displayed!");
-                        finishScreenTurningOn(screenOnListener);
-                        setKeyguardDrawn();
-                    }
-                })) {
-                    return;
-                }
-                Slog.i(TAG, "No lock screen! waitForWindowDrawn false");
-
-            } catch (RemoteException ex) {
-                // Can't happen in system process.
-            }
+    // Called on the mHandler thread.
+    private void finishScreenTurningOn() {
+        if (DEBUG_WAKEUP) Slog.d(TAG,
+                "finishScreenTurningOn: mKeyguardDrawComplete=" + mKeyguardDrawComplete
+                        + " mWindowManagerDrawComplete=" + mWindowManagerDrawComplete);
+        if (!mKeyguardDrawComplete || !mWindowManagerDrawComplete) {
+            return;
         }
 
-        Slog.i(TAG, "No lock screen! windowToken=" + windowToken);
-        finishScreenTurningOn(screenOnListener);
-        setKeyguardDrawn();
-    }
-
-    private void finishScreenTurningOn(ScreenOnListener screenOnListener) {
         synchronized (mLock) {
             mScreenOnFully = true;
         }
@@ -4531,9 +4584,11 @@
         } catch (RemoteException unhandled) {
         }
 
-        if (screenOnListener != null) {
-            screenOnListener.onScreenOn();
+        for (int i = mScreenOnListeners.size() - 1; i >=0; --i) {
+            mScreenOnListeners.remove(i).onScreenOn();
         }
+
+        setKeyguardDrawn();
     }
 
     @Override
@@ -4906,7 +4961,7 @@
         synchronized (mLock) {
             mSystemBooted = true;
         }
-        waitForKeyguard(null);
+        wakingUp(null);
     }
 
     ProgressDialog mBootMsgDialog = null;
diff --git a/rs/java/android/renderscript/RenderScript.java b/rs/java/android/renderscript/RenderScript.java
index 8cac22d..44de480 100644
--- a/rs/java/android/renderscript/RenderScript.java
+++ b/rs/java/android/renderscript/RenderScript.java
@@ -64,23 +64,23 @@
     static Method registerNativeFree;
 
     /*
-     * Context creation flag which specifies a normal context.
+     * Context creation flag that specifies a normal context.
     */
-    public static final long CREATE_FLAG_NONE = 0x0000;
+    public static final int CREATE_FLAG_NONE = 0x0000;
 
     /*
      * Context creation flag which specifies a context optimized for low
      * latency over peak performance. This is a hint and may have no effect
      * on some implementations.
     */
-    public static final long CREATE_FLAG_LOW_LATENCY = 0x0002;
+    public static final int CREATE_FLAG_LOW_LATENCY = 0x0002;
 
     /*
      * Context creation flag which specifies a context optimized for long
      * battery life over peak performance. This is a hint and may have no effect
      * on some implementations.
     */
-    public static final long CREATE_FLAG_LOW_POWER = 0x0004;
+    public static final int CREATE_FLAG_LOW_POWER = 0x0004;
 
     /*
      * Detect the bitness of the VM to allow FieldPacker to do the right thing.
@@ -1181,7 +1181,7 @@
      * @param ctx The context.
      * @return RenderScript
      */
-    public static RenderScript create(Context ctx, int sdkVersion, ContextType ct, long flags) {
+    public static RenderScript create(Context ctx, int sdkVersion, ContextType ct, int flags) {
         if (!sInitialized) {
             Log.e(LOG_TAG, "RenderScript.create() called when disabled; someone is likely to crash");
             return null;
@@ -1194,7 +1194,7 @@
         RenderScript rs = new RenderScript(ctx);
 
         rs.mDev = rs.nDeviceCreate();
-        rs.mContext = rs.nContextCreate(rs.mDev, (int)flags, sdkVersion, ct.mID);
+        rs.mContext = rs.nContextCreate(rs.mDev, flags, sdkVersion, ct.mID);
         rs.mContextType = ct;
         if (rs.mContext == 0) {
             throw new RSDriverException("Failed to create RS context.");
@@ -1236,7 +1236,7 @@
      * @param flags The OR of the CREATE_FLAG_* options desired
      * @return RenderScript
      */
-    public static RenderScript create(Context ctx, ContextType ct, long flags) {
+    public static RenderScript create(Context ctx, ContextType ct, int flags) {
         int v = ctx.getApplicationInfo().targetSdkVersion;
         return create(ctx, v, ct, flags);
     }
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index cb5946a..fe5c2ef 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -128,6 +128,8 @@
     private int mPlugType;
     private int mLastPlugType = -1; // Extra state so we can detect first run
 
+    private boolean mBatteryLevelLow;
+
     private long mDischargeStartTime;
     private int mDischargeStartLevel;
 
@@ -222,14 +224,30 @@
     }
 
     /**
-     * Returns true if battery level is below the first warning threshold.
+     * Returns whether we currently consider the battery level to be low.
      */
-    public boolean isBatteryLow() {
+    public boolean getBatteryLevelLow() {
         synchronized (mLock) {
-            return mBatteryProps.batteryPresent && mBatteryProps.batteryLevel <= mLowBatteryWarningLevel;
+            return mBatteryLevelLow;
         }
     }
 
+    public boolean isBatteryLowLocked() {
+        final boolean plugged = mPlugType != BATTERY_PLUGGED_NONE;
+        final boolean oldPlugged = mLastPlugType != BATTERY_PLUGGED_NONE;
+
+        /* The ACTION_BATTERY_LOW broadcast is sent in these situations:
+         * - is just un-plugged (previously was plugged) and battery level is
+         *   less than or equal to WARNING, or
+         * - is not plugged and battery level falls to WARNING boundary
+         *   (becomes <= mLowBatteryWarningLevel).
+         */
+        return !plugged
+                && mBatteryProps.batteryStatus != BatteryManager.BATTERY_STATUS_UNKNOWN
+                && mBatteryProps.batteryLevel <= mLowBatteryWarningLevel
+                && (oldPlugged || mLastBatteryLevel > mLowBatteryWarningLevel);
+    }
+
     /**
      * Returns a non-zero value if an  unsupported charger is attached.
      */
@@ -382,19 +400,7 @@
                 logOutlier = true;
             }
 
-            final boolean plugged = mPlugType != BATTERY_PLUGGED_NONE;
-            final boolean oldPlugged = mLastPlugType != BATTERY_PLUGGED_NONE;
-
-            /* The ACTION_BATTERY_LOW broadcast is sent in these situations:
-             * - is just un-plugged (previously was plugged) and battery level is
-             *   less than or equal to WARNING, or
-             * - is not plugged and battery level falls to WARNING boundary
-             *   (becomes <= mLowBatteryWarningLevel).
-             */
-            final boolean sendBatteryLow = !plugged
-                    && mBatteryProps.batteryStatus != BatteryManager.BATTERY_STATUS_UNKNOWN
-                    && mBatteryProps.batteryLevel <= mLowBatteryWarningLevel
-                    && (oldPlugged || mLastBatteryLevel > mLowBatteryWarningLevel);
+            mBatteryLevelLow = isBatteryLowLocked();
 
             sendIntentLocked();
 
@@ -422,7 +428,7 @@
                 });
             }
 
-            if (sendBatteryLow) {
+            if (mBatteryLevelLow) {
                 mSentLowBatteryBroadcast = true;
                 mHandler.post(new Runnable() {
                     @Override
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index b2b4217..bd45761 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -1754,31 +1754,34 @@
             if (DBG) log("requestRouteToHostAddress on invalid network: " + networkType);
             return false;
         }
-        NetworkStateTracker tracker = mNetTrackers[networkType];
-        DetailedState netState = DetailedState.DISCONNECTED;
-        if (tracker != null) {
-            netState = tracker.getNetworkInfo().getDetailedState();
+
+        NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
+        if (nai == null) {
+            if (mLegacyTypeTracker.isTypeSupported(networkType) == false) {
+                if (DBG) log("requestRouteToHostAddress on unsupported network: " + networkType);
+            } else {
+                if (DBG) log("requestRouteToHostAddress on down network: " + networkType);
+            }
+            return false;
         }
 
+        DetailedState netState = nai.networkInfo.getDetailedState();
+
         if ((netState != DetailedState.CONNECTED &&
-                netState != DetailedState.CAPTIVE_PORTAL_CHECK) ||
-                tracker.isTeardownRequested()) {
+                netState != DetailedState.CAPTIVE_PORTAL_CHECK)) {
             if (VDBG) {
                 log("requestRouteToHostAddress on down network "
                         + "(" + networkType + ") - dropped"
-                        + " tracker=" + tracker
-                        + " netState=" + netState
-                        + " isTeardownRequested="
-                            + ((tracker != null) ? tracker.isTeardownRequested() : "tracker:null"));
+                        + " netState=" + netState);
             }
             return false;
         }
         final int uid = Binder.getCallingUid();
         final long token = Binder.clearCallingIdentity();
         try {
-            LinkProperties lp = tracker.getLinkProperties();
+            LinkProperties lp = nai.linkProperties;
             boolean ok = modifyRouteToAddress(lp, addr, ADD, TO_DEFAULT_TABLE, exempt,
-                    tracker.getNetwork().netId, uid);
+                    nai.network.netId, uid);
             if (DBG) log("requestRouteToHostAddress ok=" + ok);
             return ok;
         } finally {
@@ -3100,7 +3103,7 @@
                         break;
                     }
                     Integer score = (Integer) msg.obj;
-                    updateNetworkScore(nai, score);
+                    if (score != null) updateNetworkScore(nai, score.intValue());
                     break;
                 }
                 case NetworkMonitor.EVENT_NETWORK_VALIDATED: {
@@ -3316,6 +3319,7 @@
         if (bestNetwork != null) {
             if (VDBG) log("using " + bestNetwork.name());
             bestNetwork.addRequest(nri.request);
+            mNetworkForRequestId.put(nri.request.requestId, bestNetwork);
             int legacyType = nri.request.legacyType;
             if (legacyType != TYPE_NONE) {
                 mLegacyTypeTracker.add(legacyType, bestNetwork);
@@ -5911,9 +5915,30 @@
         }
     }
 
-    private void updateNetworkScore(NetworkAgentInfo nai, Integer scoreInteger) {
-        int score = scoreInteger.intValue();
-        // TODO
+    private void updateNetworkScore(NetworkAgentInfo nai, int score) {
+        if (DBG) log("updateNetworkScore for " + nai.name() + " to " + score);
+
+        nai.currentScore = score;
+
+        // TODO - This will not do the right thing if this network is lowering
+        // its score and has requests that can be served by other
+        // currently-active networks, or if the network is increasing its
+        // score and other networks have requests that can be better served
+        // by this network.
+        //
+        // Really we want to see if any of our requests migrate to other
+        // active/lingered networks and if any other requests migrate to us (depending
+        // on increasing/decreasing currentScore.  That's a bit of work and probably our
+        // score checking/network allocation code needs to be modularized so we can understand
+        // (see handleConnectionValided for an example).
+        //
+        // As a first order approx, lets just advertise the new score to factories.  If
+        // somebody can beat it they will nominate a network and our normal net replacement
+        // code will fire.
+        for (int i = 0; i < nai.networkRequests.size(); i++) {
+            NetworkRequest nr = nai.networkRequests.valueAt(i);
+            sendUpdatedScoreToFactories(nr, score);
+        }
     }
 
     // notify only this one new request of the current state
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index 11d6a55..251247c 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -2310,14 +2310,14 @@
     }
 
     @Override
-    public void notifyTextCommitted() {
+    public void notifyUserAction() {
         if (DEBUG) {
-            Slog.d(TAG, "Got the notification of commitText");
+            Slog.d(TAG, "Got the notification of a user action");
         }
         synchronized (mMethodMap) {
             final InputMethodInfo imi = mMethodMap.get(mCurMethodId);
             if (imi != null) {
-                mSwitchingController.onCommitTextLocked(imi, mCurrentSubtype);
+                mSwitchingController.onUserActionLocked(imi, mCurrentSubtype);
             }
         }
     }
diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index 06dd3ed..fdaf55e 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -28,6 +28,7 @@
 import android.os.Handler;
 import android.os.IVibratorService;
 import android.os.PowerManager;
+import android.os.PowerManagerInternal;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.IBinder;
@@ -64,6 +65,7 @@
     private final PowerManager.WakeLock mWakeLock;
     private final IAppOpsService mAppOpsService;
     private final IBatteryStats mBatteryStatsService;
+    private PowerManagerInternal mPowerManagerInternal;
     private InputManager mIm;
 
     volatile VibrateThread mThread;
@@ -169,14 +171,19 @@
         mIm = (InputManager)mContext.getSystemService(Context.INPUT_SERVICE);
         mSettingObserver = new SettingsObserver(mH);
 
+        mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
+        mPowerManagerInternal.registerLowPowerModeObserver(
+                new PowerManagerInternal.LowPowerModeListener() {
+            @Override
+            public void onLowPowerModeChanged(boolean enabled) {
+                updateInputDeviceVibrators();
+            }
+        });
+
         mContext.getContentResolver().registerContentObserver(
                 Settings.System.getUriFor(Settings.System.VIBRATE_INPUT_DEVICES),
                 true, mSettingObserver, UserHandle.USER_ALL);
 
-        mContext.getContentResolver().registerContentObserver(
-                Settings.Global.getUriFor(Settings.Global.LOW_POWER_MODE), false,
-                mSettingObserver, UserHandle.USER_ALL);
-
         mContext.registerReceiver(new BroadcastReceiver() {
             @Override
             public void onReceive(Context context, Intent intent) {
@@ -448,8 +455,7 @@
                 } catch (SettingNotFoundException snfe) {
                 }
 
-                mLowPowerMode = Settings.Global.getInt(mContext.getContentResolver(),
-                         Settings.Global.LOW_POWER_MODE, 0) != 0;
+                mLowPowerMode = mPowerManagerInternal.getLowPowerModeEnabled();
 
                 if (mVibrateInputDevicesSetting) {
                     if (!mInputDeviceListenerRegistered) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index aede797..fa26d56 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -2883,16 +2883,17 @@
                 }
 
                 /*
-                 * Add shared application GID so applications can share some
-                 * resources like shared libraries
+                 * Add shared application and profile GIDs so applications can share some
+                 * resources like shared libraries and access user-wide resources
                  */
                 if (permGids == null) {
-                    gids = new int[1];
+                    gids = new int[2];
                 } else {
-                    gids = new int[permGids.length + 1];
-                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
+                    gids = new int[permGids.length + 2];
+                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
                 }
                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
+                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
             }
             if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
                 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index ba12374..e6b465d 100755
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -3801,6 +3801,7 @@
                 mStacks.remove(this);
                 mStacks.add(0, this);
             }
+            mActivityContainer.onTaskListEmpty();
         }
     }
 
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index dc4ad48..35ac9c9 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -134,6 +134,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;
+    static final int CONTAINER_CALLBACK_TASK_LIST_EMPTY = FIRST_SUPERVISOR_STACK_MSG + 11;
 
     private final static String VIRTUAL_DISPLAY_BASE_NAME = "ActivityViewVirtualDisplay";
 
@@ -3074,12 +3075,14 @@
                 } break;
                 case CONTAINER_CALLBACK_VISIBILITY: {
                     final ActivityContainer container = (ActivityContainer) msg.obj;
-                    try {
-                        // We only send this message if mCallback is non-null.
-                        container.mCallback.setVisible(container.asBinder(), msg.arg1 == 1);
-                    } catch (RemoteException e) {
+                    final IActivityContainerCallback callback = container.mCallback;
+                    if (callback != null) {
+                        try {
+                            callback.setVisible(container.asBinder(), msg.arg1 == 1);
+                        } catch (RemoteException e) {
+                        }
                     }
-                }
+                } break;
                 case LOCK_TASK_START_MSG: {
                     // When lock task starts, we disable the status bars.
                     try {
@@ -3091,8 +3094,7 @@
                     } catch (RemoteException ex) {
                         throw new RuntimeException(ex);
                     }
-                    break;
-                }
+                } break;
                 case LOCK_TASK_END_MSG: {
                     // When lock task ends, we enable the status bars.
                     try {
@@ -3104,8 +3106,17 @@
                     } catch (RemoteException ex) {
                         throw new RuntimeException(ex);
                     }
-                    break;
-                }
+                } break;
+                case CONTAINER_CALLBACK_TASK_LIST_EMPTY: {
+                    final ActivityContainer container = (ActivityContainer) msg.obj;
+                    final IActivityContainerCallback callback = container.mCallback;
+                    if (callback != null) {
+                        try {
+                            callback.onAllActivitiesComplete(container.asBinder());
+                        } catch (RemoteException e) {
+                        }
+                    }
+                } break;
             }
         }
     }
@@ -3310,6 +3321,10 @@
             return true;
         }
 
+        void onTaskListEmpty() {
+            mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget();
+        }
+
         @Override
         public String toString() {
             return mIdString + (mActivityDisplay == null ? "N" : "A");
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index b492edd..eb253eb 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -669,6 +669,7 @@
         int flags = 0;
         boolean isCheckin = false;
         boolean noOutput = false;
+        boolean writeData = false;
         long historyStart = -1;
         int reqUid = -1;
         if (args != null) {
@@ -687,6 +688,7 @@
                         return;
                     }
                     historyStart = Long.parseLong(args[i]);
+                    writeData = true;
                 } else if ("-c".equals(arg)) {
                     isCheckin = true;
                     flags |= BatteryStats.DUMP_INCLUDE_HISTORY;
@@ -749,10 +751,16 @@
             List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications(0);
             synchronized (mStats) {
                 mStats.dumpCheckinLocked(mContext, pw, apps, flags, historyStart);
+                if (writeData) {
+                    mStats.writeAsyncLocked();
+                }
             }
         } else {
             synchronized (mStats) {
                 mStats.dumpLocked(mContext, pw, flags, reqUid, historyStart);
+                if (writeData) {
+                    mStats.writeAsyncLocked();
+                }
             }
         }
     }
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index 8fd55e7..3b55bfc 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -365,15 +365,8 @@
                         Manifest.permission.WRITE_SYNC_SETTINGS,
                         "no permission to write the sync settings");
                 SyncStorageEngine.EndPoint info;
-                if (!request.hasAuthority()) {
-                    // Extra permissions checking for sync service.
-                    verifySignatureForPackage(callerUid,
-                            request.getService().getPackageName(), "sync");
-                    info = new SyncStorageEngine.EndPoint(request.getService(), userId);
-                } else {
-                    info = new SyncStorageEngine.EndPoint(
-                            request.getAccount(), request.getProvider(), userId);
-                }
+                info = new SyncStorageEngine.EndPoint(
+                        request.getAccount(), request.getProvider(), userId);
                 if (runAtTime < 60) {
                     Slog.w(TAG, "Requested poll frequency of " + runAtTime
                             + " seconds being rounded up to 60 seconds.");
@@ -385,17 +378,10 @@
             } else {
                 long beforeRuntimeMillis = (flextime) * 1000;
                 long runtimeMillis = runAtTime * 1000;
-                if (request.hasAuthority()) {
                 syncManager.scheduleSync(
                         request.getAccount(), userId, callerUid, request.getProvider(), extras,
                         beforeRuntimeMillis, runtimeMillis,
                         false /* onlyThoseWithUnknownSyncableState */);
-                } else {
-                    syncManager.scheduleSync(
-                            request.getService(), userId, callerUid, extras,
-                            beforeRuntimeMillis,
-                            runtimeMillis); // Empty function.
-                }
             }
         } finally {
             restoreCallingIdentity(identityToken);
@@ -442,22 +428,14 @@
         SyncManager syncManager = getSyncManager();
         if (syncManager == null) return;
         int userId = UserHandle.getCallingUserId();
-        int callerUid = Binder.getCallingUid();
 
         long identityToken = clearCallingIdentity();
         try {
             SyncStorageEngine.EndPoint info;
             Bundle extras = new Bundle(request.getBundle());
-            if (request.hasAuthority()) {
-                Account account = request.getAccount();
-                String provider = request.getProvider();
-                info = new SyncStorageEngine.EndPoint(account, provider, userId);
-            } else {
-                // Only allowed to manipulate syncs for a service which you own.
-                ComponentName service = request.getService();
-                verifySignatureForPackage(callerUid, service.getPackageName(), "cancel");
-                info = new SyncStorageEngine.EndPoint(service, userId);
-            }
+            Account account = request.getAccount();
+            String provider = request.getProvider();
+            info = new SyncStorageEngine.EndPoint(account, provider, userId);
             if (request.isPeriodic()) {
                 // Remove periodic sync.
                 mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS,
@@ -599,20 +577,11 @@
         mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS,
                 "no permission to read the sync settings");
 
-        int callerUid = Binder.getCallingUid();
         int userId = UserHandle.getCallingUserId();
         long identityToken = clearCallingIdentity();
         try {
-            if (cname == null) {
-                return getSyncManager().getSyncStorageEngine().getPeriodicSyncs(
-                        new SyncStorageEngine.EndPoint(account, providerName, userId));
-            } else if (account == null && providerName == null) {
-                verifySignatureForPackage(callerUid, cname.getPackageName(), "getPeriodicSyncs");
-                return getSyncManager().getSyncStorageEngine().getPeriodicSyncs(
-                        new SyncStorageEngine.EndPoint(cname, userId));
-            } else {
-                throw new IllegalArgumentException("Invalid authority specified");
-            }
+            return getSyncManager().getSyncStorageEngine().getPeriodicSyncs(
+                    new SyncStorageEngine.EndPoint(account, providerName, userId));
         } finally {
             restoreCallingIdentity(identityToken);
         }
@@ -656,45 +625,6 @@
         }
     }
 
-    public void setServiceActive(ComponentName cname, boolean active) {
-        mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS,
-                "no permission to write the sync settings");
-        verifySignatureForPackage(Binder.getCallingUid(), cname.getPackageName(),
-                "setServiceActive");
-
-        int userId = UserHandle.getCallingUserId();
-        long identityToken = clearCallingIdentity();
-        try {
-            SyncManager syncManager = getSyncManager();
-            if (syncManager != null) {
-                syncManager.getSyncStorageEngine().setIsTargetServiceActive(
-                        cname, userId, active);
-            }
-        } finally {
-            restoreCallingIdentity(identityToken);
-        }
-    }
-
-    public boolean isServiceActive(ComponentName cname) {
-        mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS,
-                "no permission to read the sync settings");
-        verifySignatureForPackage(Binder.getCallingUid(), cname.getPackageName(),
-                "isServiceActive");
-
-        int userId = UserHandle.getCallingUserId();
-        long identityToken = clearCallingIdentity();
-        try {
-            SyncManager syncManager = getSyncManager();
-            if (syncManager != null) {
-                return syncManager.getSyncStorageEngine()
-                        .getIsTargetServiceActive(cname, userId);
-            }
-        } finally {
-            restoreCallingIdentity(identityToken);
-        }
-        return false;
-    }
-
     @Override
     public boolean getMasterSyncAutomatically() {
         mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS,
@@ -741,18 +671,11 @@
             if (syncManager == null) {
                 return false;
             }
-            if (cname == null) {
-                return syncManager.getSyncStorageEngine().isSyncActive(
-                        new SyncStorageEngine.EndPoint(account, authority, userId));
-            } else if (account == null && authority == null) {
-                verifySignatureForPackage(callingUid, cname.getPackageName(), "isSyncActive");
-                return syncManager.getSyncStorageEngine().isSyncActive(
-                        new SyncStorageEngine.EndPoint(cname, userId));
-            }
+            return syncManager.getSyncStorageEngine().isSyncActive(
+                    new SyncStorageEngine.EndPoint(account, authority, userId));
         } finally {
             restoreCallingIdentity(identityToken);
         }
-        return false;
     }
 
     public List<SyncInfo> getCurrentSyncs() {
@@ -784,11 +707,8 @@
                 return null;
             }
             SyncStorageEngine.EndPoint info;
-            if (cname == null) {
+            if (!(account == null || authority == null)) {
                 info = new SyncStorageEngine.EndPoint(account, authority, userId);
-            } else if (account == null && authority == null) {
-                verifySignatureForPackage(callerUid, cname.getPackageName(), "getSyncStatus");
-                info = new SyncStorageEngine.EndPoint(cname, userId);
             } else {
                 throw new IllegalArgumentException("Must call sync status with valid authority");
             }
@@ -810,11 +730,8 @@
 
         try {
             SyncStorageEngine.EndPoint info;
-            if (cname == null) {
+            if (!(account == null || authority == null)) {
                 info = new SyncStorageEngine.EndPoint(account, authority, userId);
-            } else if (account == null && authority == null) {
-                verifySignatureForPackage(callerUid, cname.getPackageName(), "isSyncPending");
-                info = new SyncStorageEngine.EndPoint(cname, userId);
             } else {
                 throw new IllegalArgumentException("Invalid authority specified");
             }
@@ -855,30 +772,6 @@
     }
 
     /**
-     * Helper to verify that the provided package name shares the same cert as the caller.
-     * @param callerUid uid of the calling process.
-     * @param packageName package to verify against package of calling application.
-     * @param tag a tag to use when throwing an exception if the signatures don't
-     * match. Cannot be null.
-     * @return true if the calling application and the provided package are signed with the same
-     * certificate.
-     */
-    private boolean verifySignatureForPackage(int callerUid, String packageName, String tag) {
-        PackageManager pm = mContext.getPackageManager();
-        try {
-            int serviceUid = pm.getApplicationInfo(packageName, 0).uid;
-            if (pm.checkSignatures(callerUid, serviceUid) == PackageManager.SIGNATURE_MATCH) {
-                return true;
-            } else {
-                throw new SecurityException(tag + ": Caller certificate does not match that for - "
-                        + packageName);
-            }
-        } catch (PackageManager.NameNotFoundException e) {
-            throw new IllegalArgumentException(tag + ": " + packageName + " package not found.");
-        }
-    }
-
-    /**
      * Hide this class since it is not part of api,
      * but current unittest framework requires it to be public
      * @hide
diff --git a/services/core/java/com/android/server/content/SyncStorageEngine.java b/services/core/java/com/android/server/content/SyncStorageEngine.java
index 35c494d..9499370 100644
--- a/services/core/java/com/android/server/content/SyncStorageEngine.java
+++ b/services/core/java/com/android/server/content/SyncStorageEngine.java
@@ -925,10 +925,7 @@
                             period,
                             flextime);
                 } else {
-                    toUpdate = new PeriodicSync(info.service,
-                            extras,
-                            period,
-                            flextime);
+                    return;
                 }
                 AuthorityInfo authority =
                         getOrCreateAuthorityLocked(info, -1, false);
@@ -1246,7 +1243,6 @@
                     authorityInfo.ident,
                     authorityInfo.target.account,
                     authorityInfo.target.provider,
-                    authorityInfo.target.service,
                     activeSyncContext.mStartTime);
             getCurrentSyncs(authorityInfo.target.userId).add(syncInfo);
         }
@@ -1262,8 +1258,7 @@
             if (Log.isLoggable(TAG, Log.VERBOSE)) {
                 Log.v(TAG, "removeActiveSync: account=" + syncInfo.account
                         + " user=" + userId
-                        + " auth=" + syncInfo.authority
-                        + " service=" + syncInfo.service);
+                        + " auth=" + syncInfo.authority);
             }
             getCurrentSyncs(userId).remove(syncInfo);
         }
@@ -2109,12 +2104,8 @@
                         extras,
                         period, flextime);
         } else {
-            periodicSync =
-                    new PeriodicSync(
-                            authorityInfo.target.service,
-                            extras,
-                            period,
-                            flextime);
+            Log.e(TAG, "Unknown target.");
+            return null;
         }
         authorityInfo.periodicSyncs.add(periodicSync);
         return periodicSync;
@@ -2700,7 +2691,10 @@
             if (authorityInfo.target.target_provider) {
                 req.setSyncAdapter(authorityInfo.target.account, authorityInfo.target.provider);
             } else {
-                req.setSyncAdapter(authorityInfo.target.service);
+                if (Log.isLoggable(TAG, Log.DEBUG)) {
+                    Log.d(TAG, "Unknown target, skipping sync request.");
+                }
+                return;
             }
             ContentResolver.requestSync(req.build());
         }
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index a98c340..654b574 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -555,8 +555,14 @@
                 // Turn the screen on.  The contents of the screen may not yet
                 // be visible if the electron beam has not been dismissed because
                 // its last frame of animation is solid black.
-                setScreenState(mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DOZE
-                        ? Display.STATE_DOZING : Display.STATE_ON);
+
+                if (mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DOZE) {
+                    if (!mScreenBrightnessRampAnimator.isAnimating()) {
+                        setScreenState(Display.STATE_DOZING);
+                    }
+                } else {
+                    setScreenState(Display.STATE_ON);
+                }
 
                 if (mPowerRequest.blockScreenOn
                         && mPowerState.getElectronBeamLevel() == 0.0f) {
diff --git a/services/core/java/com/android/server/hdmi/DeviceDiscoveryAction.java b/services/core/java/com/android/server/hdmi/DeviceDiscoveryAction.java
index 579f89f..e8862c9 100644
--- a/services/core/java/com/android/server/hdmi/DeviceDiscoveryAction.java
+++ b/services/core/java/com/android/server/hdmi/DeviceDiscoveryAction.java
@@ -124,7 +124,7 @@
                 allocateDevices(ackedAddress);
                 startPhysicalAddressStage();
             }
-        }, DEVICE_POLLING_RETRY);
+        }, HdmiControlService.POLL_STRATEGY_REMOTES_DEVICES, DEVICE_POLLING_RETRY);
         return true;
     }
 
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecController.java b/services/core/java/com/android/server/hdmi/HdmiCecController.java
index 5141d16..5c420d7 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecController.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecController.java
@@ -25,6 +25,7 @@
 import android.util.Slog;
 import android.util.SparseArray;
 
+import com.android.internal.util.Predicate;
 import com.android.server.hdmi.HdmiControlService.DevicePollingCallback;
 
 import libcore.util.EmptyArray;
@@ -47,6 +48,21 @@
 final class HdmiCecController {
     private static final String TAG = "HdmiCecController";
 
+    /**
+     * Interface to report allocated logical address.
+     */
+    interface AllocateAddressCallback {
+        /**
+         * Called when a new logical address is allocated.
+         *
+         * @param deviceType requested device type to allocate logical address
+         * @param logicalAddress allocated logical address. If it is
+         *                       {@link HdmiCec#ADDR_UNREGISTERED}, it means that
+         *                       it failed to allocate logical address for the given device type
+         */
+        void onAllocated(int deviceType, int logicalAddress);
+    }
+
     private static final byte[] EMPTY_BODY = EmptyArray.BYTE;
 
     // A message to pass cec send command to IO looper.
@@ -63,6 +79,22 @@
 
     private static final int RETRY_COUNT_FOR_LOGICAL_ADDRESS_ALLOCATION = 3;
 
+    // Predicate for whether the given logical address is remote device's one or not.
+    private final Predicate<Integer> mRemoteDeviceAddressPredicate = new Predicate<Integer>() {
+        @Override
+        public boolean apply(Integer address) {
+            return !isAllocatedLocalDeviceAddress(address);
+        }
+    };
+
+    // Predicate whether the given logical address is system audio's one or not
+    private final Predicate<Integer> mSystemAudioAddressPredicate = new Predicate<Integer>() {
+        @Override
+        public boolean apply(Integer address) {
+            return HdmiCec.getTypeFromAddress(address) == HdmiCec.ADDR_AUDIO_SYSTEM;
+        }
+    };
+
     // Handler instance to process synchronous I/O (mainly send) message.
     private Handler mIoHandler;
 
@@ -116,45 +148,13 @@
         mNativePtr = nativePtr;
     }
 
-    /**
-     * Perform initialization for each hosted device.
-     *
-     * @param deviceTypes array of device types
-     */
-    void initializeLocalDevices(int[] deviceTypes,
-            HdmiCecLocalDevice.AddressAllocationCallback callback) {
-        assertRunOnServiceThread();
-        for (int type : deviceTypes) {
-            HdmiCecLocalDevice device = HdmiCecLocalDevice.create(this, type, callback);
-            if (device == null) {
-                continue;
-            }
-            // TODO: Consider restoring the local device addresses from persistent storage
-            //       to allocate the same addresses again if possible.
-            device.setPreferredAddress(HdmiCec.ADDR_UNREGISTERED);
-            mLocalDevices.put(type, device);
-            device.init();
-        }
-    }
-
-    /**
-     * Interface to report allocated logical address.
-     */
-    interface AllocateLogicalAddressCallback {
-        /**
-         * Called when a new logical address is allocated.
-         *
-         * @param deviceType requested device type to allocate logical address
-         * @param logicalAddress allocated logical address. If it is
-         *                       {@link HdmiCec#ADDR_UNREGISTERED}, it means that
-         *                       it failed to allocate logical address for the given device type
-         */
-        void onAllocated(int deviceType, int logicalAddress);
+    void addLocalDevice(int deviceType, HdmiCecLocalDevice device) {
+        mLocalDevices.put(deviceType, device);
     }
 
     /**
      * Allocate a new logical address of the given device type. Allocated
-     * address will be reported through {@link AllocateLogicalAddressCallback}.
+     * address will be reported through {@link AllocateAddressCallback}.
      *
      * <p> Declared as package-private, accessed by {@link HdmiControlService} only.
      *
@@ -166,7 +166,7 @@
      * @param callback callback interface to report allocated logical address to caller
      */
     void allocateLogicalAddress(final int deviceType, final int preferredAddress,
-            final AllocateLogicalAddressCallback callback) {
+            final AllocateAddressCallback callback) {
         assertRunOnServiceThread();
 
         runOnIoThread(new Runnable() {
@@ -178,7 +178,7 @@
     }
 
     private void handleAllocateLogicalAddress(final int deviceType, int preferredAddress,
-            final AllocateLogicalAddressCallback callback) {
+            final AllocateAddressCallback callback) {
         assertRunOnIoThread();
         int startAddress = preferredAddress;
         // If preferred address is "unregistered", start address will be the smallest
@@ -275,10 +275,23 @@
      * Return a list of all {@link HdmiCecDeviceInfo}.
      *
      * <p>Declared as package-private. accessed by {@link HdmiControlService} only.
+     *
+     * @param includeLocalDevice whether to add local device or not
      */
-    List<HdmiCecDeviceInfo> getDeviceInfoList() {
+    List<HdmiCecDeviceInfo> getDeviceInfoList(boolean includeLocalDevice) {
         assertRunOnServiceThread();
-        return sparseArrayToList(mDeviceInfos);
+        if (includeLocalDevice) {
+            return sparseArrayToList(mDeviceInfos);
+        } else {
+            ArrayList<HdmiCecDeviceInfo> infoList = new ArrayList<>();
+            for (int i = 0; i < mDeviceInfos.size(); ++i) {
+                HdmiCecDeviceInfo info = mDeviceInfos.valueAt(i);
+                if (mRemoteDeviceAddressPredicate.apply(info.getLogicalAddress())) {
+                    infoList.add(info);
+                }
+            }
+            return infoList;
+        }
     }
 
     /**
@@ -380,18 +393,14 @@
      * <p>Declared as package-private. accessed by {@link HdmiControlService} only.
      *
      * @param callback an interface used to get a list of all remote devices' address
+     * @param pickStrategy strategy how to pick polling candidates
      * @param retryCount the number of retry used to send polling message to remote devices
      */
-    void pollDevices(DevicePollingCallback callback, int retryCount) {
+    void pollDevices(DevicePollingCallback callback, int pickStrategy, int retryCount) {
         assertRunOnServiceThread();
-        // Extract polling candidates. No need to poll against local devices.
-        ArrayList<Integer> pollingCandidates = new ArrayList<>();
-        for (int i = HdmiCec.ADDR_SPECIFIC_USE; i >= HdmiCec.ADDR_TV; --i) {
-            if (!isAllocatedLocalDeviceAddress(i)) {
-                pollingCandidates.add(i);
-            }
-        }
 
+        // Extract polling candidates. No need to poll against local devices.
+        List<Integer> pollingCandidates = pickPollCandidates(pickStrategy);
         runDevicePolling(pollingCandidates, retryCount, callback);
     }
 
@@ -405,6 +414,41 @@
         return sparseArrayToList(mLocalDevices);
     }
 
+    private List<Integer> pickPollCandidates(int pickStrategy) {
+        int strategy = pickStrategy & HdmiControlService.POLL_STRATEGY_MASK;
+        Predicate<Integer> pickPredicate = null;
+        switch (strategy) {
+            case HdmiControlService.POLL_STRATEGY_SYSTEM_AUDIO:
+                pickPredicate = mSystemAudioAddressPredicate;
+                break;
+            case HdmiControlService.POLL_STRATEGY_REMOTES_DEVICES:
+            default:  // The default is POLL_STRATEGY_REMOTES_DEVICES.
+                pickPredicate = mRemoteDeviceAddressPredicate;
+                break;
+        }
+
+        int iterationStrategy = pickStrategy & HdmiControlService.POLL_ITERATION_STRATEGY_MASK;
+        ArrayList<Integer> pollingCandidates = new ArrayList<>();
+        switch (iterationStrategy) {
+            case HdmiControlService.POLL_ITERATION_IN_ORDER:
+                for (int i = HdmiCec.ADDR_TV; i <= HdmiCec.ADDR_SPECIFIC_USE; ++i) {
+                    if (pickPredicate.apply(i)) {
+                        pollingCandidates.add(i);
+                    }
+                }
+                break;
+            case HdmiControlService.POLL_ITERATION_REVERSE_ORDER:
+            default:  // The default is reverse order.
+                for (int i = HdmiCec.ADDR_SPECIFIC_USE; i >= HdmiCec.ADDR_TV; --i) {
+                    if (pickPredicate.apply(i)) {
+                        pollingCandidates.add(i);
+                    }
+                }
+                break;
+        }
+        return pollingCandidates;
+    }
+
     private static <T> List<T> sparseArrayToList(SparseArray<T> array) {
         ArrayList<T> list = new ArrayList<>();
         for (int i = 0; i < array.size(); ++i) {
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
index aac2a15..23454ad 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
@@ -16,8 +16,6 @@
 
 package com.android.server.hdmi;
 
-import com.android.server.hdmi.HdmiCecController.AllocateLogicalAddressCallback;
-
 import android.hardware.hdmi.HdmiCec;
 import android.hardware.hdmi.HdmiCecDeviceInfo;
 
@@ -27,84 +25,43 @@
  */
 abstract class HdmiCecLocalDevice {
 
-    protected final HdmiCecController mController;
+    protected final HdmiControlService mService;
     protected final int mDeviceType;
-    protected final AddressAllocationCallback mAllocationCallback;
     protected int mAddress;
     protected int mPreferredAddress;
     protected HdmiCecDeviceInfo mDeviceInfo;
 
-    /**
-     * Callback interface to notify newly allocated logical address of the given
-     * local device.
-     */
-    interface AddressAllocationCallback {
-        /**
-         * Called when a logical address of the given device is allocated.
-         *
-         * @param deviceType original device type
-         * @param logicalAddress newly allocated logical address
-         */
-        void onAddressAllocated(int deviceType, int logicalAddress);
-    }
-
-    protected HdmiCecLocalDevice(HdmiCecController controller, int deviceType,
-            AddressAllocationCallback callback) {
-        mController = controller;
+    protected HdmiCecLocalDevice(HdmiControlService service, int deviceType) {
+        mService = service;
         mDeviceType = deviceType;
-        mAllocationCallback = callback;
         mAddress = HdmiCec.ADDR_UNREGISTERED;
     }
 
     // Factory method that returns HdmiCecLocalDevice of corresponding type.
-    static HdmiCecLocalDevice create(HdmiCecController controller, int deviceType,
-            AddressAllocationCallback callback) {
+    static HdmiCecLocalDevice create(HdmiControlService service, int deviceType) {
         switch (deviceType) {
         case HdmiCec.DEVICE_TV:
-            return new HdmiCecLocalDeviceTv(controller, callback);
+            return new HdmiCecLocalDeviceTv(service);
         case HdmiCec.DEVICE_PLAYBACK:
-            return new HdmiCecLocalDevicePlayback(controller, callback);
+            return new HdmiCecLocalDevicePlayback(service);
         default:
             return null;
         }
     }
 
-    abstract void init();
+    void init() {
+        mPreferredAddress = HdmiCec.ADDR_UNREGISTERED;
+        // TODO: load preferred address from permanent storage.
+    }
 
     /**
-     * Called when a logical address of the local device is allocated.
-     * Note that internal variables are updated before it's called.
+     * Called once a logical address of the local device is allocated.
      */
     protected abstract void onAddressAllocated(int logicalAddress);
 
-    protected void allocateAddress(int type) {
-        mController.allocateLogicalAddress(type, mPreferredAddress,
-                new AllocateLogicalAddressCallback() {
-            @Override
-            public void onAllocated(int deviceType, int logicalAddress) {
-                mAddress = mPreferredAddress = logicalAddress;
-
-                // Create and set device info.
-                HdmiCecDeviceInfo deviceInfo = createDeviceInfo(mAddress, deviceType);
-                setDeviceInfo(deviceInfo);
-                mController.addDeviceInfo(deviceInfo);
-
-                mController.addLogicalAddress(logicalAddress);
-                onAddressAllocated(logicalAddress);
-                if (mAllocationCallback != null) {
-                    mAllocationCallback.onAddressAllocated(deviceType, logicalAddress);
-                }
-            }
-        });
-    }
-
-    private final HdmiCecDeviceInfo createDeviceInfo(int logicalAddress, int deviceType) {
-        int vendorId = mController.getVendorId();
-        int physicalAddress = mController.getPhysicalAddress();
-        // TODO: get device name read from system configuration.
-        String displayName = HdmiCec.getDefaultDeviceName(logicalAddress);
-        return new HdmiCecDeviceInfo(logicalAddress,
-                physicalAddress, deviceType, vendorId, displayName);
+    final void handleAddressAllocated(int logicalAddress) {
+        mAddress = mPreferredAddress = logicalAddress;
+        onAddressAllocated(logicalAddress);
     }
 
     HdmiCecDeviceInfo getDeviceInfo() {
@@ -128,4 +85,8 @@
     void setPreferredAddress(int addr) {
         mPreferredAddress = addr;
     }
+
+    int getPreferredAddress() {
+        return mPreferredAddress;
+    }
 }
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
index 3347725..d79e283 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
@@ -23,18 +23,13 @@
  */
 final class HdmiCecLocalDevicePlayback extends HdmiCecLocalDevice {
 
-    HdmiCecLocalDevicePlayback(HdmiCecController controller, AddressAllocationCallback callback) {
-        super(controller, HdmiCec.DEVICE_PLAYBACK, callback);
-    }
-
-    @Override
-    void init() {
-        allocateAddress(mDeviceType);
+    HdmiCecLocalDevicePlayback(HdmiControlService service) {
+        super(service, HdmiCec.DEVICE_PLAYBACK);
     }
 
     @Override
     protected void onAddressAllocated(int logicalAddress) {
-        mController.sendCommand(HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
-                mAddress, mController.getPhysicalAddress(), mDeviceType));
+        mService.sendCecCommand(HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
+                mAddress, mService.getPhysicalAddress(), mDeviceType));
     }
 }
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index 93761ab..72d7f2d 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -23,24 +23,20 @@
  */
 final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
 
-    HdmiCecLocalDeviceTv(HdmiCecController controller, AddressAllocationCallback callback) {
-        super(controller, HdmiCec.DEVICE_TV, callback);
-    }
-
-    @Override
-    void init() {
-        allocateAddress(mDeviceType);
+    HdmiCecLocalDeviceTv(HdmiControlService service) {
+        super(service, HdmiCec.DEVICE_TV);
     }
 
     @Override
     protected void onAddressAllocated(int logicalAddress) {
         // TODO: vendor-specific initialization here.
 
-        mController.sendCommand(HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
-                mAddress, mController.getPhysicalAddress(), mDeviceType));
-        mController.sendCommand(HdmiCecMessageBuilder.buildDeviceVendorIdCommand(
-                mAddress, mController.getVendorId()));
+        mService.sendCecCommand(HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
+                mAddress, mService.getPhysicalAddress(), mDeviceType));
+        mService.sendCecCommand(HdmiCecMessageBuilder.buildDeviceVendorIdCommand(
+                mAddress, mService.getVendorId()));
 
+        mService.launchDeviceDiscovery(mAddress);
         // TODO: Start routing control action, device discovery action.
     }
 }
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 0f3fc21..4b78591 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -30,12 +30,13 @@
 import android.os.Looper;
 import android.os.RemoteException;
 import android.util.Slog;
+import android.util.SparseArray;
 import android.util.SparseIntArray;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.server.SystemService;
 import com.android.server.hdmi.DeviceDiscoveryAction.DeviceDiscoveryCallback;
-import com.android.server.hdmi.HdmiCecLocalDevice.AddressAllocationCallback;
+import com.android.server.hdmi.HdmiCecController.AllocateAddressCallback;
 
 import java.util.ArrayList;
 import java.util.Iterator;
@@ -57,6 +58,14 @@
     static final int SEND_RESULT_NAK = -1;
     static final int SEND_RESULT_FAILURE = -2;
 
+    static final int POLL_STRATEGY_MASK = 0x3;  // first and second bit.
+    static final int POLL_STRATEGY_REMOTES_DEVICES = 0x1;
+    static final int POLL_STRATEGY_SYSTEM_AUDIO = 0x2;
+
+    static final int POLL_ITERATION_STRATEGY_MASK = 0x30000;  // first and second bit.
+    static final int POLL_ITERATION_IN_ORDER = 0x10000;
+    static final int POLL_ITERATION_REVERSE_ORDER = 0x20000;
+
     /**
      * Interface to report send result.
      */
@@ -114,10 +123,12 @@
     @Nullable
     private HdmiMhlController mMhlController;
 
+    @GuardedBy("mLock")
     // Whether ARC is "enabled" or not.
     // TODO: it may need to hold lock if it's accessed from others.
     private boolean mArcStatusEnabled = false;
 
+    @GuardedBy("mLock")
     // Whether SystemAudioMode is "On" or not.
     private boolean mSystemAudioMode;
 
@@ -134,23 +145,9 @@
     public void onStart() {
         mIoThread.start();
         mCecController = HdmiCecController.create(this);
+
         if (mCecController != null) {
-            mCecController.initializeLocalDevices(mLocalDevices, new AddressAllocationCallback() {
-                private final SparseIntArray mAllocated = new SparseIntArray();
-
-                @Override
-                public void onAddressAllocated(int deviceType, int logicalAddress) {
-                    mAllocated.append(deviceType, logicalAddress);
-                    // TODO: get HdmiLCecLocalDevice and call onAddressAllocated here.
-
-                    // Once all logical allocation is done, launch device discovery
-                    // action if one of local device is TV.
-                    int tvAddress = mAllocated.get(HdmiCec.DEVICE_TV, -1);
-                    if (mLocalDevices.length == mAllocated.size() && tvAddress != -1) {
-                        launchDeviceDiscovery(tvAddress);
-                    }
-                }
-            });
+            initializeLocalDevices(mLocalDevices);
         } else {
             Slog.i(TAG, "Device does not support HDMI-CEC.");
         }
@@ -166,6 +163,46 @@
         // start to monitor the preference value and invoke SystemAudioActionFromTv if needed.
     }
 
+    private void initializeLocalDevices(final int[] deviceTypes) {
+        // A container for [Logical Address, Local device info].
+        final SparseArray<HdmiCecLocalDevice> devices = new SparseArray<>();
+        final SparseIntArray finished = new SparseIntArray();
+        for (int type : deviceTypes) {
+            final HdmiCecLocalDevice localDevice = HdmiCecLocalDevice.create(this, type);
+            localDevice.init();
+            mCecController.allocateLogicalAddress(type,
+                    localDevice.getPreferredAddress(), new AllocateAddressCallback() {
+                @Override
+                public void onAllocated(int deviceType, int logicalAddress) {
+                    if (logicalAddress == HdmiCec.ADDR_UNREGISTERED) {
+                        Slog.e(TAG, "Failed to allocate address:[device_type:" + deviceType + "]");
+                    } else {
+                        HdmiCecDeviceInfo deviceInfo = createDeviceInfo(logicalAddress, deviceType);
+                        localDevice.setDeviceInfo(deviceInfo);
+                        mCecController.addLocalDevice(deviceType, localDevice);
+                        mCecController.addLogicalAddress(logicalAddress);
+                        devices.append(logicalAddress, localDevice);
+                    }
+                    finished.append(deviceType, logicalAddress);
+
+                    // Once finish address allocation for all devices, notify
+                    // it to each device.
+                    if (deviceTypes.length == finished.size()) {
+                        notifyAddressAllocated(devices);
+                    }
+                }
+            });
+        }
+    }
+
+    private void notifyAddressAllocated(SparseArray<HdmiCecLocalDevice> devices) {
+        for (int i = 0; i < devices.size(); ++i) {
+            int address = devices.keyAt(i);
+            HdmiCecLocalDevice device = devices.valueAt(i);
+            device.onAddressAllocated(address);
+        }
+    }
+
     /**
      * Returns {@link Looper} for IO operation.
      *
@@ -186,6 +223,30 @@
     }
 
     /**
+     * Returns physical address of the device.
+     */
+    int getPhysicalAddress() {
+        return mCecController.getPhysicalAddress();
+    }
+
+    /**
+     * Returns vendor id of CEC service.
+     */
+    int getVendorId() {
+        return mCecController.getVendorId();
+    }
+
+    /**
+     * Returns a list of {@link HdmiCecDeviceInfo}.
+     *
+     * @param includeLocalDevice whether to include local devices
+     */
+    List<HdmiCecDeviceInfo> getDeviceInfoList(boolean includeLocalDevice) {
+        assertRunOnServiceThread();
+        return mCecController.getDeviceInfoList(includeLocalDevice);
+    }
+
+    /**
      * Add and start a new {@link FeatureAction} to the action queue.
      *
      * @param action {@link FeatureAction} to add and start
@@ -201,6 +262,18 @@
         });
     }
 
+    void setSystemAudioMode(boolean on) {
+        synchronized (mLock) {
+            mSystemAudioMode = on;
+        }
+    }
+
+    boolean getSystemAudioMode() {
+        synchronized (mLock) {
+            return mSystemAudioMode;
+        }
+    }
+
     // See if we have an action of a given type in progress.
     private <T extends FeatureAction> boolean hasAction(final Class<T> clazz) {
         for (FeatureAction action : mActions) {
@@ -260,13 +333,15 @@
      * @return {@code true} if ARC was in "Enabled" status
      */
     boolean setArcStatus(boolean enabled) {
-        boolean oldStatus = mArcStatusEnabled;
-        // 1. Enable/disable ARC circuit.
-        // TODO: call set_audio_return_channel of hal interface.
+        synchronized (mLock) {
+            boolean oldStatus = mArcStatusEnabled;
+            // 1. Enable/disable ARC circuit.
+            // TODO: call set_audio_return_channel of hal interface.
 
-        // 2. Update arc status;
-        mArcStatusEnabled = enabled;
-        return oldStatus;
+            // 2. Update arc status;
+            mArcStatusEnabled = enabled;
+            return oldStatus;
+        }
     }
 
     /**
@@ -346,10 +421,63 @@
      * devices.
      *
      * @param callback an interface used to get a list of all remote devices' address
+     * @param pickStrategy strategy how to pick polling candidates
      * @param retryCount the number of retry used to send polling message to remote devices
+     * @throw IllegalArgumentException if {@code pickStrategy} is invalid value
      */
-    void pollDevices(DevicePollingCallback callback, int retryCount) {
-        mCecController.pollDevices(callback, retryCount);
+    void pollDevices(DevicePollingCallback callback, int pickStrategy, int retryCount) {
+        mCecController.pollDevices(callback, checkPollStrategy(pickStrategy), retryCount);
+    }
+
+    private int checkPollStrategy(int pickStrategy) {
+        int strategy = pickStrategy & POLL_STRATEGY_MASK;
+        if (strategy == 0) {
+            throw new IllegalArgumentException("Invalid poll strategy:" + pickStrategy);
+        }
+        int iterationStrategy = pickStrategy & POLL_ITERATION_STRATEGY_MASK;
+        if (iterationStrategy == 0) {
+            throw new IllegalArgumentException("Invalid iteration strategy:" + pickStrategy);
+        }
+        return strategy | iterationStrategy;
+    }
+
+
+    /**
+     * Launch device discovery sequence. It starts with clearing the existing device info list.
+     * Note that it assumes that logical address of all local devices is already allocated.
+     *
+     * @param sourceAddress a logical address of tv
+     */
+    void launchDeviceDiscovery(final int sourceAddress) {
+        // At first, clear all existing device infos.
+        mCecController.clearDeviceInfoList();
+
+        // TODO: check whether TV is one of local devices.
+        DeviceDiscoveryAction action = new DeviceDiscoveryAction(this, sourceAddress,
+                new DeviceDiscoveryCallback() {
+                    @Override
+                    public void onDeviceDiscoveryDone(List<HdmiCecDeviceInfo> deviceInfos) {
+                        for (HdmiCecDeviceInfo info : deviceInfos) {
+                            mCecController.addDeviceInfo(info);
+                        }
+
+                        // Add device info of all local devices.
+                        for (HdmiCecLocalDevice device : mCecController.getLocalDeviceList()) {
+                            mCecController.addDeviceInfo(device.getDeviceInfo());
+                        }
+
+                        addAndStartAction(new HotplugDetectionAction(HdmiControlService.this,
+                                sourceAddress));
+                    }
+                });
+        addAndStartAction(action);
+    }
+
+    private HdmiCecDeviceInfo createDeviceInfo(int logicalAddress, int deviceType) {
+        // TODO: get device name read from system configuration.
+        String displayName = HdmiCec.getDefaultDeviceName(logicalAddress);
+        return new HdmiCecDeviceInfo(logicalAddress,
+                getPhysicalAddress(), deviceType, getVendorId(), displayName);
     }
 
     private void handleReportPhysicalAddress(HdmiCecMessage message) {
@@ -358,7 +486,7 @@
             return;
         }
 
-        // Ignore if [Device Discovery Action] is on going ignore message.
+        // Ignore if [Device Discovery Action] is going on.
         if (hasAction(DeviceDiscoveryAction.class)) {
             Slog.i(TAG, "Ignore unrecognizable <Report Physical Address> "
                     + "because Device Discovery Action is on-going:" + message);
@@ -505,34 +633,6 @@
         mCecController.addDeviceInfo(info);
     }
 
-    // Launch device discovery sequence.
-    // It starts with clearing the existing device info list.
-    // Note that it assumes that logical address of all local devices is already allocated.
-    private void launchDeviceDiscovery(int sourceAddress) {
-        // At first, clear all existing device infos.
-        mCecController.clearDeviceInfoList();
-
-        // TODO: check whether TV is one of local devices.
-        DeviceDiscoveryAction action = new DeviceDiscoveryAction(this, sourceAddress,
-                new DeviceDiscoveryCallback() {
-                    @Override
-                    public void onDeviceDiscoveryDone(List<HdmiCecDeviceInfo> deviceInfos) {
-                        for (HdmiCecDeviceInfo info : deviceInfos) {
-                            mCecController.addDeviceInfo(info);
-                        }
-
-                        // Add device info of all local devices.
-                        for (HdmiCecLocalDevice device : mCecController.getLocalDeviceList()) {
-                            mCecController.addDeviceInfo(device.getDeviceInfo());
-                        }
-
-                        // TODO: start hot-plug detection sequence here.
-                        // addAndStartAction(new HotplugDetectionAction());
-                    }
-                });
-        addAndStartAction(action);
-    }
-
     private void enforceAccessPermission() {
         getContext().enforceCallingOrSelfPermission(PERMISSION, TAG);
     }
@@ -677,21 +777,6 @@
         return mCecController.getDeviceInfo(HdmiCec.ADDR_AUDIO_SYSTEM);
     }
 
-    void setSystemAudioMode(boolean newMode) {
-        assertRunOnServiceThread();
-        if (newMode != mSystemAudioMode) {
-            // TODO: Need to set the preference for SystemAudioMode.
-            // TODO: Need to handle the notification of changing the mode and
-            // to identify the notification should be handled in the service or TvSettings.
-            mSystemAudioMode = newMode;
-        }
-    }
-
-    boolean getSystemAudioMode() {
-        assertRunOnServiceThread();
-        return mSystemAudioMode;
-    }
-
     void setAudioStatus(boolean mute, int volume) {
         // TODO: Hook up with AudioManager.
     }
diff --git a/services/core/java/com/android/server/hdmi/HotplugDetectionAction.java b/services/core/java/com/android/server/hdmi/HotplugDetectionAction.java
new file mode 100644
index 0000000..c905c76
--- /dev/null
+++ b/services/core/java/com/android/server/hdmi/HotplugDetectionAction.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.hdmi;
+
+import android.hardware.hdmi.HdmiCec;
+import android.hardware.hdmi.HdmiCecDeviceInfo;
+import android.hardware.hdmi.HdmiCecMessage;
+import android.util.Slog;
+
+import com.android.server.hdmi.HdmiControlService.DevicePollingCallback;
+
+import java.util.BitSet;
+import java.util.List;
+
+/**
+ * Feature action that handles hot-plug detection mechanism.
+ * Hot-plug event is initiated by timer after device discovery action.
+ *
+ * <p>Check all devices every 15 secs except for system audio.
+ * If system audio is on, check hot-plug for audio system every 5 secs.
+ * For other devices, keep 15 secs period.
+ */
+final class HotplugDetectionAction extends FeatureAction {
+    private static final String TAG = "HotPlugDetectionAction";
+
+    private static final int POLLING_INTERVAL_MS = 5000;
+    private static final int TIMEOUT_COUNT = 3;
+    private static final int POLL_RETRY_COUNT = 2;
+
+    // State in which waits for next polling
+    private static final int STATE_WAIT_FOR_NEXT_POLLING = 1;
+
+    // All addresses except for broadcast (unregistered address).
+    private static final int NUM_OF_ADDRESS = HdmiCec.ADDR_SPECIFIC_USE - HdmiCec.ADDR_TV + 1;
+
+    private int mTimeoutCount = 0;
+
+    /**
+     * Constructor
+     *
+     * @param service instance of {@link HdmiControlService}
+     * @param sourceAddress logical address of a device that initiate this action
+     */
+    HotplugDetectionAction(HdmiControlService service, int sourceAddress) {
+        super(service, sourceAddress);
+    }
+
+    @Override
+    boolean start() {
+        Slog.v(TAG, "Hot-plug dection started.");
+
+        mState = STATE_WAIT_FOR_NEXT_POLLING;
+        mTimeoutCount = 0;
+
+        // Start timer without polling.
+        // The first check for all devices will be initiated 15 seconds later.
+        addTimer(mState, POLLING_INTERVAL_MS);
+        return true;
+    }
+
+    @Override
+    boolean processCommand(HdmiCecMessage cmd) {
+        // No-op
+        return false;
+    }
+
+    @Override
+    void handleTimerEvent(int state) {
+        if (mState != state) {
+            return;
+        }
+
+        if (mState == STATE_WAIT_FOR_NEXT_POLLING) {
+            mTimeoutCount = (mTimeoutCount + 1) % TIMEOUT_COUNT;
+            pollDevices();
+        }
+    }
+
+    // This method is called every 5 seconds.
+    private void pollDevices() {
+        // All device check called every 15 seconds.
+        if (mTimeoutCount == 0) {
+            pollAllDevices();
+        } else {
+            if (mService.getSystemAudioMode()) {
+                pollAudioSystem();
+            }
+        }
+
+        addTimer(mState, POLLING_INTERVAL_MS);
+    }
+
+    private void pollAllDevices() {
+        Slog.v(TAG, "Poll all devices.");
+
+        mService.pollDevices(new DevicePollingCallback() {
+            @Override
+            public void onPollingFinished(List<Integer> ackedAddress) {
+                checkHotplug(ackedAddress, false);
+            }
+        }, HdmiControlService.POLL_ITERATION_IN_ORDER
+                | HdmiControlService.POLL_STRATEGY_REMOTES_DEVICES, POLL_RETRY_COUNT);
+    }
+
+    private void pollAudioSystem() {
+        Slog.v(TAG, "Poll audio system.");
+
+        mService.pollDevices(new DevicePollingCallback() {
+            @Override
+            public void onPollingFinished(List<Integer> ackedAddress) {
+                checkHotplug(ackedAddress, false);
+            }
+        }, HdmiControlService.POLL_ITERATION_IN_ORDER
+                | HdmiControlService.POLL_STRATEGY_SYSTEM_AUDIO, POLL_RETRY_COUNT);
+    }
+
+    private void checkHotplug(List<Integer> ackedAddress, boolean audioOnly) {
+        BitSet currentInfos = infoListToBitSet(mService.getDeviceInfoList(false), audioOnly);
+        BitSet polledResult = addressListToBitSet(ackedAddress);
+
+        // At first, check removed devices.
+        BitSet removed = complement(currentInfos, polledResult);
+        int index = -1;
+        while ((index = removed.nextSetBit(index + 1)) != -1) {
+            Slog.v(TAG, "Remove device by hot-plug detection:" + index);
+            removeDevice(index);
+        }
+
+        // Next, check added devices.
+        BitSet added = complement(polledResult, currentInfos);
+        index = -1;
+        while ((index = added.nextSetBit(index + 1)) != -1) {
+            Slog.v(TAG, "Add device by hot-plug detection:" + index);
+            addDevice(index);
+        }
+    }
+
+    private static BitSet infoListToBitSet(List<HdmiCecDeviceInfo> infoList, boolean audioOnly) {
+        BitSet set = new BitSet(NUM_OF_ADDRESS);
+        for (HdmiCecDeviceInfo info : infoList) {
+            if (audioOnly) {
+                if (info.getDeviceType() == HdmiCec.DEVICE_AUDIO_SYSTEM) {
+                    set.set(info.getLogicalAddress());
+                }
+            } else {
+                set.set(info.getLogicalAddress());
+            }
+        }
+        return set;
+    }
+
+    private static BitSet addressListToBitSet(List<Integer> list) {
+        BitSet set = new BitSet(NUM_OF_ADDRESS);
+        for (Integer value : list) {
+            set.set(value);
+        }
+        return set;
+    }
+
+    // A - B = A & ~B
+    private static BitSet complement(BitSet first, BitSet second) {
+        // Need to clone it so that it doesn't touch original set.
+        BitSet clone = (BitSet) first.clone();
+        clone.andNot(second);
+        return clone;
+    }
+
+    private void addDevice(int addedAddress) {
+        // TODO: implement this.
+    }
+
+    private void removeDevice(int removedAddress) {
+        // TODO: implements following steps.
+        // 1. Launch routing control sequence
+        // 2. Stop one touch play sequence if removed device is the device to be selected.
+        // 3. If audio system, start system audio off and arc off
+        // 4. Inform device remove to others
+    }
+}
diff --git a/services/core/java/com/android/server/notification/ConditionProviders.java b/services/core/java/com/android/server/notification/ConditionProviders.java
index dbfb1cf..15f0ebf 100644
--- a/services/core/java/com/android/server/notification/ConditionProviders.java
+++ b/services/core/java/com/android/server/notification/ConditionProviders.java
@@ -16,18 +16,14 @@
 
 package com.android.server.notification;
 
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
 import android.net.Uri;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.IInterface;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.provider.Settings;
 import android.provider.Settings.Global;
 import android.service.notification.Condition;
@@ -35,7 +31,6 @@
 import android.service.notification.IConditionListener;
 import android.service.notification.IConditionProvider;
 import android.service.notification.ZenModeConfig;
-import android.text.format.DateUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Slog;
@@ -45,7 +40,7 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Date;
+import java.util.Objects;
 
 public class ConditionProviders extends ManagedServices {
     private static final Condition[] NO_CONDITIONS = new Condition[0];
@@ -54,7 +49,9 @@
     private final ArrayMap<IBinder, IConditionListener> mListeners
             = new ArrayMap<IBinder, IConditionListener>();
     private final ArrayList<ConditionRecord> mRecords = new ArrayList<ConditionRecord>();
-    private final CountdownConditionHelper mCountdownHelper = new CountdownConditionHelper();
+    private final CountdownConditionProvider mCountdown = new CountdownConditionProvider();
+
+    private Uri mExitConditionId;
 
     public ConditionProviders(Context context, Handler handler,
             UserProfiles userProfiles, ZenModeHelper zenModeHelper) {
@@ -86,10 +83,13 @@
             }
             pw.print("    mRecords("); pw.print(mRecords.size()); pw.println("):");
             for (int i = 0; i < mRecords.size(); i++) {
-                pw.print("      "); pw.println(mRecords.get(i));
+                final ConditionRecord r = mRecords.get(i);
+                pw.print("      "); pw.println(r);
+                final String countdownDesc =  CountdownConditionProvider.tryParseDescription(r.id);
+                if (countdownDesc != null) {
+                    pw.print("        ("); pw.print(countdownDesc); pw.println(")");
+                }
             }
-            pw.print("    mCountdownHelper: ");
-            pw.println(mCountdownHelper.getCurrentConditionDescription());
         }
     }
 
@@ -99,6 +99,14 @@
     }
 
     @Override
+    public void onBootPhaseAppsCanStart() {
+        super.onBootPhaseAppsCanStart();
+        mCountdown.attachBase(mContext);
+        registerService(mCountdown.asInterface(), CountdownConditionProvider.COMPONENT,
+                UserHandle.USER_OWNER);
+    }
+
+    @Override
     protected void onServiceAdded(ManagedServiceInfo info) {
         Slog.d(TAG, "onServiceAdded " + info);
         final IConditionProvider provider = provider(info);
@@ -262,6 +270,15 @@
     public void setZenModeCondition(Uri conditionId) {
         if (DEBUG) Slog.d(TAG, "setZenModeCondition " + conditionId);
         synchronized(mMutex) {
+            if (ZenModeConfig.isValidCountdownConditionId(conditionId)) {
+                // constructed by the client, make sure the record exists...
+                final ConditionRecord r = getRecordLocked(conditionId,
+                        CountdownConditionProvider.COMPONENT);
+                if (r.info == null) {
+                    // ... and is associated with the in-process service
+                    r.info = checkServiceTokenLocked(mCountdown.asInterface());
+                }
+            }
             final int N = mRecords.size();
             for (int i = 0; i < N; i++) {
                 final ConditionRecord r = mRecords.get(i);
@@ -276,8 +293,11 @@
                     r.isManual = true;
                 }
             }
+            if (!Objects.equals(mExitConditionId, conditionId)) {
+                mExitConditionId = conditionId;
+                saveZenConfigLocked();
+            }
         }
-        mCountdownHelper.setZenModeCondition(conditionId);
     }
 
     private void subscribeLocked(ConditionRecord r) {
@@ -395,6 +415,7 @@
             return;
         }
         synchronized (mMutex) {
+            mExitConditionId = config.exitConditionId;
             if (config.conditionComponents == null || config.conditionIds == null
                     || config.conditionComponents.length != config.conditionIds.length) {
                 if (DEBUG) Slog.d(TAG, "loadZenConfig: no conditions");
@@ -441,82 +462,11 @@
                 config.conditionIds[i] = r.id;
             }
         }
+        config.exitConditionId = mExitConditionId;
         if (DEBUG) Slog.d(TAG, "Setting zen config to: " + config);
         mZenModeHelper.setConfig(config);
     }
 
-    private final class CountdownConditionHelper extends BroadcastReceiver {
-        private static final String ACTION = "CountdownConditionHelper";
-        private static final int REQUEST_CODE = 100;
-        private static final String EXTRA_TIME = "time";
-
-        private long mCurrent;
-
-        public CountdownConditionHelper() {
-            mContext.registerReceiver(this, new IntentFilter(ACTION));
-        }
-
-        public void setZenModeCondition(Uri conditionId) {
-            final long time = tryParseCondition(conditionId);
-            final AlarmManager alarms = (AlarmManager)
-                    mContext.getSystemService(Context.ALARM_SERVICE);
-            final Intent intent = new Intent(ACTION).putExtra(EXTRA_TIME, time)
-                    .setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
-            final PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, REQUEST_CODE,
-                    intent, PendingIntent.FLAG_UPDATE_CURRENT);
-            alarms.cancel(pendingIntent);
-            mCurrent = time;
-            if (time > 0) {
-                final long now = System.currentTimeMillis();
-                final CharSequence span =
-                        DateUtils.getRelativeTimeSpanString(time, now, DateUtils.MINUTE_IN_MILLIS);
-                Slog.d(TAG, String.format("Scheduling %s for %s, %s in the future (%s), now=%s",
-                        ACTION, ts(time), time - now, span, ts(now)));
-                alarms.setExact(AlarmManager.RTC_WAKEUP, time, pendingIntent);
-            }
-        }
-
-        public String getCurrentConditionDescription() {
-            if (mCurrent == 0) return null;
-            final long time = mCurrent;
-            final long now = System.currentTimeMillis();
-            final CharSequence span =
-                    DateUtils.getRelativeTimeSpanString(time, now, DateUtils.MINUTE_IN_MILLIS);
-            return String.format("Scheduled for %s, %s in the future (%s), now=%s",
-                    ts(time), time - now, span, ts(now));
-        }
-
-        private String ts(long time) {
-            return new Date(time) + " (" + time + ")";
-        }
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (ACTION.equals(intent.getAction())) {
-                final long time = intent.getLongExtra(EXTRA_TIME, 0);
-                Slog.d(TAG, "Countdown condition fired. time=" + time + " mCurrent=" + mCurrent);
-                if (time > 0 && time == mCurrent) {
-                    // countdown condition is still the manual condition, leave zen
-                    mZenModeHelper.setZenMode(Global.ZEN_MODE_OFF);
-                    ConditionProviders.this.setZenModeCondition(null);
-                }
-            }
-        }
-
-        private long tryParseCondition(Uri conditionId) {
-            // condition://android/countdown/1399917958951
-            if (!Condition.isValidId(conditionId, "android")) return 0;
-            if (conditionId.getPathSegments().size() != 2
-                    || !"countdown".equals(conditionId.getPathSegments().get(0))) return 0;
-            try {
-                return Long.parseLong(conditionId.getPathSegments().get(1));
-            } catch (RuntimeException e) {
-                Slog.w(TAG, "Error parsing countdown condition: " + conditionId, e);
-                return 0;
-            }
-        }
-    }
-
     private class ZenModeHelperCallback extends ZenModeHelper.Callback {
         @Override
         void onConfigChanged() {
diff --git a/services/core/java/com/android/server/notification/CountdownConditionProvider.java b/services/core/java/com/android/server/notification/CountdownConditionProvider.java
new file mode 100644
index 0000000..0884f76
--- /dev/null
+++ b/services/core/java/com/android/server/notification/CountdownConditionProvider.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.notification;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.Uri;
+import android.service.notification.Condition;
+import android.service.notification.ConditionProviderService;
+import android.service.notification.IConditionProvider;
+import android.service.notification.ZenModeConfig;
+import android.text.format.DateUtils;
+import android.util.Slog;
+
+import java.util.Date;
+
+/** Built-in zen condition provider for simple time-based conditions */
+public class CountdownConditionProvider extends ConditionProviderService {
+    private static final String TAG = "CountdownConditionProvider";
+    private static final boolean DEBUG = false;
+
+    public static final ComponentName COMPONENT =
+            new ComponentName("android", CountdownConditionProvider.class.getName());
+
+    private static final String ACTION = CountdownConditionProvider.class.getName();
+    private static final int REQUEST_CODE = 100;
+    private static final String EXTRA_CONDITION_ID = "condition_id";
+
+    private final Context mContext = this;
+    private final Receiver mReceiver = new Receiver();
+
+    private boolean mConnected;
+
+    public CountdownConditionProvider() {
+        if (DEBUG) Slog.d(TAG, "new CountdownConditionProvider()");
+    }
+
+    @Override
+    public void onConnected() {
+        if (DEBUG) Slog.d(TAG, "onConnected");
+        mContext.registerReceiver(mReceiver, new IntentFilter(ACTION));
+        mConnected = true;
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        if (DEBUG) Slog.d(TAG, "onDestroy");
+        if (mConnected) {
+            mContext.unregisterReceiver(mReceiver);
+        }
+        mConnected = false;
+    }
+
+    @Override
+    public void onRequestConditions(int relevance) {
+        // by convention
+    }
+
+    @Override
+    public void onSubscribe(Uri conditionId) {
+        if (DEBUG) Slog.d(TAG, "onSubscribe " + conditionId);
+        final long time = ZenModeConfig.tryParseCountdownConditionId(conditionId);
+        final AlarmManager alarms = (AlarmManager)
+                mContext.getSystemService(Context.ALARM_SERVICE);
+        final Intent intent = new Intent(ACTION).putExtra(EXTRA_CONDITION_ID, conditionId)
+                .setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+        final PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, REQUEST_CODE,
+                intent, PendingIntent.FLAG_UPDATE_CURRENT);
+        alarms.cancel(pendingIntent);
+        if (time > 0) {
+            final long now = System.currentTimeMillis();
+            final CharSequence span =
+                    DateUtils.getRelativeTimeSpanString(time, now, DateUtils.MINUTE_IN_MILLIS);
+            if (DEBUG) Slog.d(TAG, String.format(
+                    "Scheduling %s for %s, %s in the future (%s), now=%s",
+                    ACTION, ts(time), time - now, span, ts(now)));
+            alarms.setExact(AlarmManager.RTC_WAKEUP, time, pendingIntent);
+        }
+    }
+
+    @Override
+    public void onUnsubscribe(Uri conditionId) {
+        // noop
+    }
+
+    private final class Receiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (ACTION.equals(intent.getAction())) {
+                final Uri conditionId = intent.getParcelableExtra(EXTRA_CONDITION_ID);
+                final long time = ZenModeConfig.tryParseCountdownConditionId(conditionId);
+                if (DEBUG) Slog.d(TAG, "Countdown condition fired: " + conditionId);
+                if (time > 0) {
+                    notifyCondition(newCondition(time, Condition.STATE_FALSE));
+                }
+            }
+        }
+    }
+
+    private static final Condition newCondition(long time, int state) {
+        return new Condition(ZenModeConfig.toCountdownConditionId(time),
+                "", "", "", 0, state,Condition.FLAG_RELEVANT_NOW);
+    }
+
+    public static String tryParseDescription(Uri conditionUri) {
+        final long time = ZenModeConfig.tryParseCountdownConditionId(conditionUri);
+        if (time == 0) return null;
+        final long now = System.currentTimeMillis();
+        final CharSequence span =
+                DateUtils.getRelativeTimeSpanString(time, now, DateUtils.MINUTE_IN_MILLIS);
+        return String.format("Scheduled for %s, %s in the future (%s), now=%s",
+                ts(time), time - now, span, ts(now));
+    }
+
+    private static String ts(long time) {
+        return new Date(time) + " (" + time + ")";
+    }
+
+    public void attachBase(Context base) {
+        attachBaseContext(base);
+    }
+
+    public IConditionProvider asInterface() {
+        return (IConditionProvider) onBind(null);
+    }
+}
diff --git a/services/core/java/com/android/server/notification/NotificationComparator.java b/services/core/java/com/android/server/notification/NotificationComparator.java
index b30baea..6cd4019 100644
--- a/services/core/java/com/android/server/notification/NotificationComparator.java
+++ b/services/core/java/com/android/server/notification/NotificationComparator.java
@@ -41,6 +41,6 @@
             return -1 * Float.compare(leftPeple, rightPeople);
         }
         // then break ties by time, most recent first
-        return -1 * Long.compare(lhs.sbn.getPostTime(), rhs.sbn.getPostTime());
+        return -1 * Long.compare(lhs.getRankingTimeMs(), rhs.getRankingTimeMs());
     }
 }
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index cb78a45..386402b 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -163,6 +163,7 @@
     private long[] mDefaultVibrationPattern;
 
     private long[] mFallbackVibrationPattern;
+    private boolean mUseAttentionLight;
     boolean mSystemReady;
 
     private boolean mDisableNotificationAlerts;
@@ -182,7 +183,7 @@
             new ArrayMap<String, NotificationRecord>();
     final ArrayList<ToastRecord> mToastQueue = new ArrayList<ToastRecord>();
 
-    ArrayList<NotificationRecord> mLights = new ArrayList<NotificationRecord>();
+    ArrayList<String> mLights = new ArrayList<String>();
     NotificationRecord mLedNotification;
 
     private AppOpsManager mAppOps;
@@ -797,6 +798,8 @@
                 VIBRATE_PATTERN_MAXLEN,
                 DEFAULT_VIBRATE_PATTERN);
 
+        mUseAttentionLight = resources.getBoolean(R.bool.config_useAttentionLight);
+
         // Don't start allowing notifications until the setup wizard has run once.
         // After that, including subsequent boots, init with notifications turned on.
         // This works on the first boot because the setup wizard will toggle this
@@ -1238,7 +1241,7 @@
 
         @Override
         public ZenModeConfig getZenModeConfig() {
-            checkCallerIsSystem();
+            enforceSystemOrSystemUI("INotificationManager.getZenModeConfig");
             return mZenModeHelper.getConfig();
         }
 
@@ -1478,14 +1481,19 @@
                     }
                 }
 
-                // 1. initial score: buckets of 10, around the app
-                int score = notification.priority * NOTIFICATION_PRIORITY_MULTIPLIER; //[-20..20]
+                // 1. initial score: buckets of 10, around the app [-20..20]
+                final int score = notification.priority * NOTIFICATION_PRIORITY_MULTIPLIER;
 
                 // 2. extract ranking signals from the notification data
                 final StatusBarNotification n = new StatusBarNotification(
                         pkg, opPkg, id, tag, callingUid, callingPid, score, notification,
                         user);
-                NotificationRecord r = new NotificationRecord(n);
+                NotificationRecord r = new NotificationRecord(n, score);
+                NotificationRecord old = mNotificationsByKey.get(n.getKey());
+                if (old != null) {
+                    // Retain ranking information from previous record
+                    r.copyRankingInformation(old);
+                }
                 if (!mSignalExtractors.isEmpty()) {
                     for (NotificationSignalExtractor extractor : mSignalExtractors) {
                         try {
@@ -1502,27 +1510,18 @@
                 // blocked apps
                 if (ENABLE_BLOCKED_NOTIFICATIONS && !noteNotificationOp(pkg, callingUid)) {
                     if (!isSystemNotification) {
-                        score = JUNK_SCORE;
+                        r.score = JUNK_SCORE;
                         Slog.e(TAG, "Suppressing notification from package " + pkg
                                 + " by user request.");
                     }
                 }
 
-                if (score < SCORE_DISPLAY_THRESHOLD) {
+                if (r.score < SCORE_DISPLAY_THRESHOLD) {
                     // Notification will be blocked because the score is too low.
                     return;
                 }
 
                 synchronized (mNotificationList) {
-                    applyZenModeLocked(r);
-
-                    // Should this notification make noise, vibe, or use the LED?
-                    final boolean canInterrupt = (score >= SCORE_INTERRUPTION_THRESHOLD) &&
-                            !r.isIntercepted();
-                    if (DBG || r.isIntercepted()) Slog.v(TAG,
-                            "pkg=" + pkg + " canInterrupt=" + canInterrupt +
-                                    " intercept=" + r.isIntercepted());
-                    NotificationRecord old = null;
                     int index = indexOfNotificationLocked(n.getKey());
                     if (index < 0) {
                         mNotificationList.add(r);
@@ -1533,21 +1532,15 @@
                         mUsageStats.registerUpdatedByApp(r, old);
                         // Make sure we don't lose the foreground service state.
                         notification.flags |=
-                            old.getNotification().flags & Notification.FLAG_FOREGROUND_SERVICE;
-                        // Retain ranking information from previous record
-                        r.copyRankingInformation(old);
+                                old.getNotification().flags & Notification.FLAG_FOREGROUND_SERVICE;
                         mNotificationsByKey.remove(old.sbn.getKey());
+                        r.isUpdate = true;
                     }
                     mNotificationsByKey.put(n.getKey(), r);
 
-                    Collections.sort(mNotificationList, mRankingComparator);
+                    applyZenModeLocked(r);
 
-                    // Ensure if this is a foreground service that the proper additional
-                    // flags are set.
-                    if ((notification.flags&Notification.FLAG_FOREGROUND_SERVICE) != 0) {
-                        notification.flags |= Notification.FLAG_ONGOING_EVENT
-                                | Notification.FLAG_NO_CLEAR;
-                    }
+                    Collections.sort(mNotificationList, mRankingComparator);
 
                     final int currentUser;
                     final long token = Binder.clearCallingIdentity();
@@ -1569,20 +1562,11 @@
                             final long identity = Binder.clearCallingIdentity();
                             try {
                                 mStatusBar.addNotification(n);
-                                if ((n.getNotification().flags & Notification.FLAG_SHOW_LIGHTS) != 0
-                                        && canInterrupt) {
-                                    mAttentionLight.pulse();
-                                }
                             } finally {
                                 Binder.restoreCallingIdentity(identity);
                             }
                         }
-                        // Send accessibility events only for the current user.
-                        if (currentUser == userId) {
-                            sendAccessibilityEvent(notification, pkg);
-                        }
-
-                        mListeners.notifyPostedLocked(r.sbn);
+                        mListeners.notifyPostedLocked(n);
                     } else {
                         Slog.e(TAG, "Not posting notification with icon==0: " + notification);
                         if (old != null && !old.isCanceled) {
@@ -1593,7 +1577,7 @@
                                 Binder.restoreCallingIdentity(identity);
                             }
 
-                            mListeners.notifyRemovedLocked(r.sbn);
+                            mListeners.notifyRemovedLocked(n);
                         }
                         // ATTENTION: in a future release we will bail out here
                         // so that we do not play sounds, show lights, etc. for invalid
@@ -1602,136 +1586,14 @@
                                 + n.getPackageName());
                     }
 
-                    // If we're not supposed to beep, vibrate, etc. then don't.
-                    if (!mDisableNotificationAlerts
-                            && (!(old != null
-                                && (notification.flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0 ))
-                            && (r.getUserId() == UserHandle.USER_ALL ||
-                                (r.getUserId() == userId && r.getUserId() == currentUser) ||
-                                mUserProfiles.isCurrentProfile(r.getUserId()))
-                            && canInterrupt
-                            && mSystemReady
-                            && mAudioManager != null) {
-                        if (DBG) Slog.v(TAG, "Interrupting!");
-                        // sound
-
-                        // should we use the default notification sound? (indicated either by
-                        // DEFAULT_SOUND or because notification.sound is pointing at
-                        // Settings.System.NOTIFICATION_SOUND)
-                        final boolean useDefaultSound =
-                               (notification.defaults & Notification.DEFAULT_SOUND) != 0 ||
-                                       Settings.System.DEFAULT_NOTIFICATION_URI
-                                               .equals(notification.sound);
-
-                        Uri soundUri = null;
-                        boolean hasValidSound = false;
-
-                        if (useDefaultSound) {
-                            soundUri = Settings.System.DEFAULT_NOTIFICATION_URI;
-
-                            // check to see if the default notification sound is silent
-                            ContentResolver resolver = getContext().getContentResolver();
-                            hasValidSound = Settings.System.getString(resolver,
-                                   Settings.System.NOTIFICATION_SOUND) != null;
-                        } else if (notification.sound != null) {
-                            soundUri = notification.sound;
-                            hasValidSound = (soundUri != null);
-                        }
-
-                        if (hasValidSound) {
-                            boolean looping =
-                                    (notification.flags & Notification.FLAG_INSISTENT) != 0;
-                            int audioStreamType;
-                            if (notification.audioStreamType >= 0) {
-                                audioStreamType = notification.audioStreamType;
-                            } else {
-                                audioStreamType = DEFAULT_STREAM_TYPE;
-                            }
-                            mSoundNotification = r;
-                            // do not play notifications if stream volume is 0 (typically because
-                            // ringer mode is silent) or if there is a user of exclusive audio focus
-                            if ((mAudioManager.getStreamVolume(audioStreamType) != 0)
-                                    && !mAudioManager.isAudioFocusExclusive()) {
-                                final long identity = Binder.clearCallingIdentity();
-                                try {
-                                    final IRingtonePlayer player =
-                                            mAudioManager.getRingtonePlayer();
-                                    if (player != null) {
-                                        if (DBG) Slog.v(TAG, "Playing sound " + soundUri
-                                                + " on stream " + audioStreamType);
-                                        player.playAsync(soundUri, user, looping, audioStreamType);
-                                    }
-                                } catch (RemoteException e) {
-                                } finally {
-                                    Binder.restoreCallingIdentity(identity);
-                                }
-                            }
-                        }
-
-                        // vibrate
-                        // Does the notification want to specify its own vibration?
-                        final boolean hasCustomVibrate = notification.vibrate != null;
-
-                        // new in 4.2: if there was supposed to be a sound and we're in vibrate
-                        // mode, and no other vibration is specified, we fall back to vibration
-                        final boolean convertSoundToVibration =
-                                   !hasCustomVibrate
-                                && hasValidSound
-                                && (mAudioManager.getRingerMode()
-                                           == AudioManager.RINGER_MODE_VIBRATE);
-
-                        // The DEFAULT_VIBRATE flag trumps any custom vibration AND the fallback.
-                        final boolean useDefaultVibrate =
-                                (notification.defaults & Notification.DEFAULT_VIBRATE) != 0;
-
-                        if ((useDefaultVibrate || convertSoundToVibration || hasCustomVibrate)
-                                && !(mAudioManager.getRingerMode()
-                                        == AudioManager.RINGER_MODE_SILENT)) {
-                            mVibrateNotification = r;
-
-                            if (useDefaultVibrate || convertSoundToVibration) {
-                                // Escalate privileges so we can use the vibrator even if the
-                                // notifying app does not have the VIBRATE permission.
-                                long identity = Binder.clearCallingIdentity();
-                                try {
-                                    mVibrator.vibrate(r.sbn.getUid(), r.sbn.getOpPkg(),
-                                        useDefaultVibrate ? mDefaultVibrationPattern
-                                            : mFallbackVibrationPattern,
-                                        ((notification.flags & Notification.FLAG_INSISTENT) != 0)
-                                                ? 0: -1, notification.audioStreamType);
-                                } finally {
-                                    Binder.restoreCallingIdentity(identity);
-                                }
-                            } else if (notification.vibrate.length > 1) {
-                                // If you want your own vibration pattern, you need the VIBRATE
-                                // permission
-                                mVibrator.vibrate(r.sbn.getUid(), r.sbn.getOpPkg(),
-                                        notification.vibrate,
-                                    ((notification.flags & Notification.FLAG_INSISTENT) != 0)
-                                            ? 0: -1, notification.audioStreamType);
-                            }
-                        }
+                    // Ensure if this is a foreground service that the proper additional
+                    // flags are set.
+                    if ((notification.flags & Notification.FLAG_FOREGROUND_SERVICE) != 0) {
+                        notification.flags |= Notification.FLAG_ONGOING_EVENT
+                                | Notification.FLAG_NO_CLEAR;
                     }
 
-                    // light
-                    // the most recent thing gets the light
-                    mLights.remove(old);
-                    if (mLedNotification == old) {
-                        mLedNotification = null;
-                    }
-                    //Slog.i(TAG, "notification.lights="
-                    //        + ((old.notification.lights.flags & Notification.FLAG_SHOW_LIGHTS)
-                    //                  != 0));
-                    if ((notification.flags & Notification.FLAG_SHOW_LIGHTS) != 0
-                            && canInterrupt) {
-                        mLights.add(r);
-                        updateLightsLocked();
-                    } else {
-                        if (old != null
-                                && ((old.getFlags() & Notification.FLAG_SHOW_LIGHTS) != 0)) {
-                            updateLightsLocked();
-                        }
-                    }
+                    buzzBeepBlinkLocked(r);
                 }
             }
         });
@@ -1739,6 +1601,158 @@
         idOut[0] = id;
     }
 
+    private void buzzBeepBlinkLocked(NotificationRecord record) {
+        final Notification notification = record.sbn.getNotification();
+
+        // Should this notification make noise, vibe, or use the LED?
+        final boolean canInterrupt = (record.score >= SCORE_INTERRUPTION_THRESHOLD) &&
+                !record.isIntercepted();
+        if (DBG || record.isIntercepted())
+            Slog.v(TAG,
+                    "pkg=" + record.sbn.getPackageName() + " canInterrupt=" + canInterrupt +
+                            " intercept=" + record.isIntercepted()
+            );
+
+        final int currentUser;
+        final long token = Binder.clearCallingIdentity();
+        try {
+            currentUser = ActivityManager.getCurrentUser();
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+
+        // If we're not supposed to beep, vibrate, etc. then don't.
+        if (!mDisableNotificationAlerts
+                && (!(record.isUpdate
+                    && (notification.flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0 ))
+                && (record.getUserId() == UserHandle.USER_ALL ||
+                    record.getUserId() == currentUser ||
+                    mUserProfiles.isCurrentProfile(record.getUserId()))
+                && canInterrupt
+                && mSystemReady
+                && mAudioManager != null) {
+            if (DBG) Slog.v(TAG, "Interrupting!");
+
+            sendAccessibilityEvent(notification, record.sbn.getPackageName());
+
+            // sound
+
+            // should we use the default notification sound? (indicated either by
+            // DEFAULT_SOUND or because notification.sound is pointing at
+            // Settings.System.NOTIFICATION_SOUND)
+            final boolean useDefaultSound =
+                   (notification.defaults & Notification.DEFAULT_SOUND) != 0 ||
+                           Settings.System.DEFAULT_NOTIFICATION_URI
+                                   .equals(notification.sound);
+
+            Uri soundUri = null;
+            boolean hasValidSound = false;
+
+            if (useDefaultSound) {
+                soundUri = Settings.System.DEFAULT_NOTIFICATION_URI;
+
+                // check to see if the default notification sound is silent
+                ContentResolver resolver = getContext().getContentResolver();
+                hasValidSound = Settings.System.getString(resolver,
+                       Settings.System.NOTIFICATION_SOUND) != null;
+            } else if (notification.sound != null) {
+                soundUri = notification.sound;
+                hasValidSound = (soundUri != null);
+            }
+
+            if (hasValidSound) {
+                boolean looping =
+                        (notification.flags & Notification.FLAG_INSISTENT) != 0;
+                int audioStreamType;
+                if (notification.audioStreamType >= 0) {
+                    audioStreamType = notification.audioStreamType;
+                } else {
+                    audioStreamType = DEFAULT_STREAM_TYPE;
+                }
+                mSoundNotification = record;
+                // do not play notifications if stream volume is 0 (typically because
+                // ringer mode is silent) or if there is a user of exclusive audio focus
+                if ((mAudioManager.getStreamVolume(audioStreamType) != 0)
+                        && !mAudioManager.isAudioFocusExclusive()) {
+                    final long identity = Binder.clearCallingIdentity();
+                    try {
+                        final IRingtonePlayer player =
+                                mAudioManager.getRingtonePlayer();
+                        if (player != null) {
+                            if (DBG) Slog.v(TAG, "Playing sound " + soundUri
+                                    + " on stream " + audioStreamType);
+                            player.playAsync(soundUri, record.sbn.getUser(), looping,
+                                    audioStreamType);
+                        }
+                    } catch (RemoteException e) {
+                    } finally {
+                        Binder.restoreCallingIdentity(identity);
+                    }
+                }
+            }
+
+            // vibrate
+            // Does the notification want to specify its own vibration?
+            final boolean hasCustomVibrate = notification.vibrate != null;
+
+            // new in 4.2: if there was supposed to be a sound and we're in vibrate
+            // mode, and no other vibration is specified, we fall back to vibration
+            final boolean convertSoundToVibration =
+                       !hasCustomVibrate
+                    && hasValidSound
+                    && (mAudioManager.getRingerMode()
+                               == AudioManager.RINGER_MODE_VIBRATE);
+
+            // The DEFAULT_VIBRATE flag trumps any custom vibration AND the fallback.
+            final boolean useDefaultVibrate =
+                    (notification.defaults & Notification.DEFAULT_VIBRATE) != 0;
+
+            if ((useDefaultVibrate || convertSoundToVibration || hasCustomVibrate)
+                    && !(mAudioManager.getRingerMode()
+                            == AudioManager.RINGER_MODE_SILENT)) {
+                mVibrateNotification = record;
+
+                if (useDefaultVibrate || convertSoundToVibration) {
+                    // Escalate privileges so we can use the vibrator even if the
+                    // notifying app does not have the VIBRATE permission.
+                    long identity = Binder.clearCallingIdentity();
+                    try {
+                        mVibrator.vibrate(record.sbn.getUid(), record.sbn.getOpPkg(),
+                            useDefaultVibrate ? mDefaultVibrationPattern
+                                : mFallbackVibrationPattern,
+                            ((notification.flags & Notification.FLAG_INSISTENT) != 0)
+                                    ? 0: -1, notification.audioStreamType);
+                    } finally {
+                        Binder.restoreCallingIdentity(identity);
+                    }
+                } else if (notification.vibrate.length > 1) {
+                    // If you want your own vibration pattern, you need the VIBRATE
+                    // permission
+                    mVibrator.vibrate(record.sbn.getUid(), record.sbn.getOpPkg(),
+                            notification.vibrate,
+                        ((notification.flags & Notification.FLAG_INSISTENT) != 0)
+                                ? 0: -1, notification.audioStreamType);
+                }
+            }
+        }
+
+        // light
+        // release the light
+        boolean wasShowLights = mLights.remove(record.getKey());
+        if (mLedNotification != null && record.getKey().equals(mLedNotification.getKey())) {
+            mLedNotification = null;
+        }
+        if ((notification.flags & Notification.FLAG_SHOW_LIGHTS) != 0 && canInterrupt) {
+            mLights.add(record.getKey());
+            updateLightsLocked();
+            if (mUseAttentionLight) {
+                mAttentionLight.pulse();
+            }
+        } else if (wasShowLights) {
+            updateLightsLocked();
+        }
+    }
+
     void showNextToastLocked() {
         ToastRecord record = mToastQueue.get(0);
         while (record != null) {
@@ -1864,6 +1878,9 @@
             int indexAfter = findNotificationRecordIndexLocked(record);
             boolean interceptAfter = record.isIntercepted();
             changed = indexBefore != indexAfter || interceptBefore != interceptAfter;
+            if (interceptBefore && !interceptAfter) {
+                buzzBeepBlinkLocked(record);
+            }
         }
         if (changed) {
             scheduleSendRankingUpdate();
@@ -2009,7 +2026,7 @@
         }
 
         // light
-        mLights.remove(r);
+        mLights.remove(r.getKey());
         if (mLedNotification == r) {
             mLedNotification = null;
         }
@@ -2194,7 +2211,7 @@
             // get next notification, if any
             int n = mLights.size();
             if (n > 0) {
-                mLedNotification = mLights.get(n-1);
+                mLedNotification = mNotificationsByKey.get(mLights.get(n-1));
             }
         }
 
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index 08f8eb4..13fb986 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -42,6 +42,7 @@
     final StatusBarNotification sbn;
     NotificationUsageStats.SingleNotificationStats stats;
     boolean isCanceled;
+    int score;
 
     // These members are used by NotificationSignalExtractors
     // to communicate with the ranking module.
@@ -53,9 +54,17 @@
     // InterceptedNotifications needs to know if this has been previously evaluated.
     private boolean mTouchedByZen;
 
-    NotificationRecord(StatusBarNotification sbn)
+    // The timestamp used for ranking.
+    private long mRankingTimeMs;
+
+    // Is this record an update of an old record?
+    public boolean isUpdate;
+
+    NotificationRecord(StatusBarNotification sbn, int score)
     {
         this.sbn = sbn;
+        this.score = score;
+        mRankingTimeMs = calculateRankingTimeMs(0L);
     }
 
     // copy any notes that the ranking system may have made before the update
@@ -64,6 +73,7 @@
         mRecentlyIntrusive = previous.mRecentlyIntrusive;
         mTouchedByZen = previous.mTouchedByZen;
         mIntercept = previous.mIntercept;
+        mRankingTimeMs = calculateRankingTimeMs(previous.getRankingTimeMs());
     }
 
     public Notification getNotification() { return sbn.getNotification(); }
@@ -134,6 +144,7 @@
         pw.println(prefix + "  mContactAffinity=" + mContactAffinity);
         pw.println(prefix + "  mRecentlyIntrusive=" + mRecentlyIntrusive);
         pw.println(prefix + "  mIntercept=" + mIntercept);
+        pw.println(prefix + "  mRankingTimeMs=" + mRankingTimeMs);
     }
 
 
@@ -201,4 +212,29 @@
         mTouchedByZen = true;
     }
 
+    /**
+     * Returns the timestamp to use for time-based sorting in the ranker.
+     */
+    public long getRankingTimeMs() {
+        return mRankingTimeMs;
+    }
+
+    /**
+     * @param previousRankingTimeMs for updated notifications, {@link #getRankingTimeMs()}
+     *     of the previous notification record, 0 otherwise
+     */
+    private long calculateRankingTimeMs(long previousRankingTimeMs) {
+        Notification n = getNotification();
+        // Take developer provided 'when', unless it's in the future.
+        if (n.when != 0 && n.when <= sbn.getPostTime()) {
+            return n.when;
+        }
+        // If we've ranked a previous instance with a timestamp, inherit it. This case is
+        // important in order to have ranking stability for updating notifications.
+        if (previousRankingTimeMs > 0) {
+            return previousRankingTimeMs;
+        }
+        return sbn.getPostTime();
+    }
+
 }
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index bb93663..8585b4e 100755
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -7829,13 +7829,9 @@
     @Override
     public boolean getApplicationBlockedSettingAsUser(String packageName, int userId) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
+        enforceCrossUserPermission(Binder.getCallingUid(), userId, true,
+                "getApplicationBlocked for user " + userId);
         PackageSetting pkgSetting;
-        final int uid = Binder.getCallingUid();
-        if (UserHandle.getUserId(uid) != userId) {
-            mContext.enforceCallingPermission(
-                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
-                    "getApplicationBlocked for user " + userId);
-        }
         long callingId = Binder.clearCallingIdentity();
         try {
             // writer
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index aca17bf..d8671d9 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -406,6 +406,12 @@
     // If true, the device is in low power mode.
     private boolean mLowPowerModeEnabled;
 
+    // Current state of the low power mode setting.
+    private boolean mLowPowerModeSetting;
+
+    // True if the battery level is currently considered low.
+    private boolean mBatteryLevelLow;
+
     private final ArrayList<PowerManagerInternal.LowPowerModeListener> mLowPowerModeListeners
             = new ArrayList<PowerManagerInternal.LowPowerModeListener>();
 
@@ -502,6 +508,7 @@
             // Register for broadcasts from other components of the system.
             IntentFilter filter = new IntentFilter();
             filter.addAction(Intent.ACTION_BATTERY_CHANGED);
+            filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
             mContext.registerReceiver(new BatteryReceiver(), filter, null, mHandler);
 
             filter = new IntentFilter();
@@ -638,7 +645,18 @@
 
         final boolean lowPowerModeEnabled = Settings.Global.getInt(resolver,
                 Settings.Global.LOW_POWER_MODE, 0) != 0;
-        if (lowPowerModeEnabled != mLowPowerModeEnabled) {
+        if (lowPowerModeEnabled != mLowPowerModeSetting) {
+            mLowPowerModeSetting = lowPowerModeEnabled;
+            updateLowPowerModeLocked();
+        }
+
+        mDirty |= DIRTY_SETTINGS;
+    }
+
+    void updateLowPowerModeLocked() {
+        final boolean lowPowerModeEnabled = mLowPowerModeSetting || mBatteryLevelLow;
+        if (mLowPowerModeEnabled != lowPowerModeEnabled) {
+            mLowPowerModeEnabled = lowPowerModeEnabled;
             powerHintInternal(POWER_HINT_LOW_POWER_MODE, lowPowerModeEnabled ? 1 : 0);
             mLowPowerModeEnabled = lowPowerModeEnabled;
             BackgroundThread.getHandler().post(new Runnable() {
@@ -652,11 +670,12 @@
                     for (int i=0; i<listeners.size(); i++) {
                         listeners.get(i).onLowPowerModeChanged(lowPowerModeEnabled);
                     }
+                    Intent intent = new Intent(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
+                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+                    mContext.sendBroadcast(intent);
                 }
             });
         }
-
-        mDirty |= DIRTY_SETTINGS;
     }
 
     private void handleSettingsChangedLocked() {
@@ -1137,9 +1156,11 @@
         if ((dirty & DIRTY_BATTERY_STATE) != 0) {
             final boolean wasPowered = mIsPowered;
             final int oldPlugType = mPlugType;
+            final boolean oldLevelLow = mBatteryLevelLow;
             mIsPowered = mBatteryService.isPowered(BatteryManager.BATTERY_PLUGGED_ANY);
             mPlugType = mBatteryService.getPlugType();
             mBatteryLevel = mBatteryService.getBatteryLevel();
+            mBatteryLevelLow = mBatteryService.getBatteryLevelLow();
 
             if (DEBUG_SPEW) {
                 Slog.d(TAG, "updateIsPoweredLocked: wasPowered=" + wasPowered
@@ -1175,6 +1196,10 @@
                     mNotifier.onWirelessChargingStarted();
                 }
             }
+
+            if (oldLevelLow != mBatteryLevelLow) {
+                updateLowPowerModeLocked();
+            }
         }
     }
 
@@ -1896,6 +1921,12 @@
         }
     }
 
+    private boolean isLowPowerModeInternal() {
+        synchronized (mLock) {
+            return mLowPowerModeEnabled;
+        }
+    }
+
     private void handleBatteryStateChangedLocked() {
         mDirty |= DIRTY_BATTERY_STATE;
         updatePowerStateLocked();
@@ -2764,6 +2795,16 @@
             }
         }
 
+        @Override // Binder call
+        public boolean isPowerSaveMode() {
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                return isLowPowerModeInternal();
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
         /**
          * Reboots the device.
          *
diff --git a/services/core/java/com/android/server/task/TaskManagerService.java b/services/core/java/com/android/server/task/TaskManagerService.java
index d5b70e6..a5f865f 100644
--- a/services/core/java/com/android/server/task/TaskManagerService.java
+++ b/services/core/java/com/android/server/task/TaskManagerService.java
@@ -36,6 +36,7 @@
 import android.util.Slog;
 import android.util.SparseArray;
 
+import com.android.server.task.controllers.BatteryController;
 import com.android.server.task.controllers.ConnectivityController;
 import com.android.server.task.controllers.IdleController;
 import com.android.server.task.controllers.StateController;
@@ -48,12 +49,19 @@
  * Responsible for taking tasks representing work to be performed by a client app, and determining
  * based on the criteria specified when that task should be run against the client application's
  * endpoint.
+ * Implements logic for scheduling, and rescheduling tasks. The TaskManagerService knows nothing
+ * about constraints, or the state of active tasks. It receives callbacks from the various
+ * controllers and completed tasks and operates accordingly.
+ *
+ * Note on locking: Any operations that manipulate {@link #mTasks} need to lock on that object, and
+ * similarly for {@link #mActiveServices}. If both locks need to be held take mTasksSet first and then
+ * mActiveService afterwards.
  * @hide
  */
 public class TaskManagerService extends com.android.server.SystemService
-        implements StateChangedListener, TaskCompletedListener {
+        implements StateChangedListener, TaskCompletedListener, TaskMapReadFinishedListener {
     // TODO: Switch this off for final version.
-    private static final boolean DEBUG = true;
+    static final boolean DEBUG = true;
     /** The number of concurrent tasks we run at one time. */
     private static final int MAX_TASK_CONTEXTS_COUNT = 3;
     static final String TAG = "TaskManager";
@@ -113,8 +121,8 @@
      */
     public int schedule(Task task, int uId, boolean canPersistTask) {
         TaskStatus taskStatus = new TaskStatus(task, uId, canPersistTask);
-        return startTrackingTask(taskStatus) ?
-                TaskManager.RESULT_SUCCESS : TaskManager.RESULT_FAILURE;
+        startTrackingTask(taskStatus);
+        return TaskManager.RESULT_SUCCESS;
     }
 
     public List<Task> getPendingTasks(int uid) {
@@ -210,7 +218,7 @@
      */
     public TaskManagerService(Context context) {
         super(context);
-        mTasks = new TaskStore(context);
+        mTasks = TaskStore.initAndGet(this);
         mHandler = new TaskHandler(context.getMainLooper());
         mTaskManagerStub = new TaskManagerStub();
         // Create the "runners".
@@ -218,12 +226,12 @@
             mActiveServices.add(
                     new TaskServiceContext(this, context.getMainLooper()));
         }
-
+        // Create the controllers.
         mControllers = new LinkedList<StateController>();
         mControllers.add(ConnectivityController.get(this));
         mControllers.add(TimeController.get(this));
         mControllers.add(IdleController.get(this));
-        // TODO: Add BatteryStateController when implemented.
+        mControllers.add(BatteryController.get(this));
     }
 
     @Override
@@ -236,17 +244,14 @@
      * {@link com.android.server.task.TaskStore}, and make sure all the relevant controllers know
      * about.
      */
-    private boolean startTrackingTask(TaskStatus taskStatus) {
-        boolean added = false;
+    private void startTrackingTask(TaskStatus taskStatus) {
         synchronized (mTasks) {
-            added = mTasks.add(taskStatus);
+            mTasks.add(taskStatus);
         }
-        if (added) {
-            for (StateController controller : mControllers) {
-                controller.maybeStartTrackingTask(taskStatus);
-            }
+        for (StateController controller : mControllers) {
+            controller.maybeStartTrackingTask(taskStatus);
+
         }
-        return added;
     }
 
     /**
@@ -404,6 +409,27 @@
         mHandler.obtainMessage(MSG_TASK_EXPIRED, taskStatus);
     }
 
+    /**
+     * Disk I/O is finished, take the list of tasks we read from disk and add them to our
+     * {@link TaskStore}.
+     * This is run on the {@link com.android.server.IoThread} instance, which is a separate thread,
+     * and is called once at boot.
+     */
+    @Override
+    public void onTaskMapReadFinished(List<TaskStatus> tasks) {
+        synchronized (mTasks) {
+            for (TaskStatus ts : tasks) {
+                if (mTasks.contains(ts)) {
+                    // An app with BOOT_COMPLETED *might* have decided to reschedule their task, in
+                    // the same amount of time it took us to read it from disk. If this is the case
+                    // we leave it be.
+                    continue;
+                }
+                startTrackingTask(ts);
+            }
+        }
+    }
+
     private class TaskHandler extends Handler {
 
         public TaskHandler(Looper looper) {
diff --git a/services/core/java/com/android/server/task/TaskMapReadFinishedListener.java b/services/core/java/com/android/server/task/TaskMapReadFinishedListener.java
new file mode 100644
index 0000000..c68d8db
--- /dev/null
+++ b/services/core/java/com/android/server/task/TaskMapReadFinishedListener.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.task;
+
+import java.util.List;
+
+import com.android.server.task.controllers.TaskStatus;
+
+/**
+ * Callback definition for I/O thread to let the TaskManagerService know when
+ * I/O read has completed. Done this way so we don't stall the main thread on
+ * boot.
+ */
+public interface TaskMapReadFinishedListener {
+
+    /**
+     * Called by the {@link TaskStore} at boot, when the disk read is finished.
+     */
+    public void onTaskMapReadFinished(List<TaskStatus> tasks);
+}
diff --git a/services/core/java/com/android/server/task/TaskStore.java b/services/core/java/com/android/server/task/TaskStore.java
index f72ab22..6bb00b1 100644
--- a/services/core/java/com/android/server/task/TaskStore.java
+++ b/services/core/java/com/android/server/task/TaskStore.java
@@ -16,17 +16,37 @@
 
 package com.android.server.task;
 
+import android.content.ComponentName;
 import android.app.task.Task;
 import android.content.Context;
+import android.os.Environment;
+import android.os.Handler;
+import android.os.PersistableBundle;
+import android.os.SystemClock;
+import android.util.AtomicFile;
 import android.util.ArraySet;
+import android.util.Pair;
 import android.util.Slog;
-import android.util.SparseArray;
+import android.util.Xml;
 
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.FastXmlSerializer;
+import com.android.server.IoThread;
 import com.android.server.task.controllers.TaskStatus;
 
-import java.util.HashSet;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Iterator;
-import java.util.Set;
+import java.util.List;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
 
 /**
  * Maintain a list of classes, and accessor methods/logic for these tasks.
@@ -38,57 +58,108 @@
  *     - Handles rescheduling of tasks.
  *       - When a periodic task is executed and must be re-added.
  *       - When a task fails and the client requests that it be retried with backoff.
- *       - This class is <strong>not</strong> thread-safe.
+ *       - This class <strong>is not</strong> thread-safe.
+ *
+ * Note on locking:
+ *      All callers to this class must <strong>lock on the class object they are calling</strong>.
+ *      This is important b/c {@link com.android.server.task.TaskStore.WriteTasksMapToDiskRunnable}
+ *      and {@link com.android.server.task.TaskStore.ReadTaskMapFromDiskRunnable} lock on that
+ *      object.
  */
 public class TaskStore {
     private static final String TAG = "TaskManagerStore";
+    private static final boolean DEBUG = TaskManagerService.DEBUG;
+
     /** Threshold to adjust how often we want to write to the db. */
     private static final int MAX_OPS_BEFORE_WRITE = 1;
-    final ArraySet<TaskStatus> mTasks;
+    final ArraySet<TaskStatus> mTasksSet;
     final Context mContext;
 
     private int mDirtyOperations;
 
-    TaskStore(Context context) {
-        mTasks = intialiseTasksFromDisk();
+    private static final Object sSingletonLock = new Object();
+    private final AtomicFile mTasksFile;
+    /** Handler backed by IoThread for writing to disk. */
+    private final Handler mIoHandler = IoThread.getHandler();
+    private static TaskStore sSingleton;
+
+    /** Used by the {@Link TaskManagerService} to instantiate the TaskStore. */
+    static TaskStore initAndGet(TaskManagerService taskManagerService) {
+        synchronized (sSingletonLock) {
+            if (sSingleton == null) {
+                sSingleton = new TaskStore(taskManagerService.getContext(),
+                        Environment.getDataDirectory(), taskManagerService);
+            }
+            return sSingleton;
+        }
+    }
+
+    @VisibleForTesting
+    public static TaskStore initAndGetForTesting(Context context, File dataDir,
+                                          TaskMapReadFinishedListener callback) {
+        return new TaskStore(context, dataDir, callback);
+    }
+
+    private TaskStore(Context context, File dataDir, TaskMapReadFinishedListener callback) {
         mContext = context;
         mDirtyOperations = 0;
+
+        File systemDir = new File(dataDir, "system");
+        File taskDir = new File(systemDir, "task");
+        taskDir.mkdirs();
+        mTasksFile = new AtomicFile(new File(taskDir, "tasks.xml"));
+
+        mTasksSet = new ArraySet<TaskStatus>();
+
+        readTaskMapFromDiskAsync(callback);
     }
 
     /**
      * Add a task to the master list, persisting it if necessary. If the TaskStatus already exists,
      * it will be replaced.
      * @param taskStatus Task to add.
-     * @return true if the operation succeeded.
+     * @return Whether or not an equivalent TaskStatus was replaced by this operation.
      */
     public boolean add(TaskStatus taskStatus) {
+        boolean replaced = mTasksSet.remove(taskStatus);
+        mTasksSet.add(taskStatus);
         if (taskStatus.isPersisted()) {
-            if (!maybeWriteStatusToDisk()) {
-                return false;
-            }
+            maybeWriteStatusToDiskAsync();
         }
-        mTasks.remove(taskStatus);
-        mTasks.add(taskStatus);
-        return true;
+        return replaced;
+    }
+
+    /**
+     * Whether this taskStatus object already exists in the TaskStore.
+     */
+    public boolean contains(TaskStatus taskStatus) {
+        return mTasksSet.contains(taskStatus);
     }
 
     public int size() {
-        return mTasks.size();
+        return mTasksSet.size();
     }
 
     /**
      * Remove the provided task. Will also delete the task if it was persisted.
-     * @return The TaskStatus that was removed, or null if an invalid token was provided.
+     * @return Whether or not the task existed to be removed.
      */
     public boolean remove(TaskStatus taskStatus) {
-        boolean removed = mTasks.remove(taskStatus);
+        boolean removed = mTasksSet.remove(taskStatus);
         if (!removed) {
-            Slog.e(TAG, "Error removing task: " + taskStatus);
+            if (DEBUG) {
+                Slog.d(TAG, "Couldn't remove task: didn't exist: " + taskStatus);
+            }
             return false;
-        } else {
-            maybeWriteStatusToDisk();
         }
-        return true;
+        maybeWriteStatusToDiskAsync();
+        return removed;
+    }
+
+    @VisibleForTesting
+    public void clear() {
+        mTasksSet.clear();
+        maybeWriteStatusToDiskAsync();
     }
 
     /**
@@ -100,19 +171,16 @@
      * was found.
      */
     public boolean removeAllByUid(int uid) {
-        Iterator<TaskStatus> it = mTasks.iterator();
-        boolean removed = false;
+        Iterator<TaskStatus> it = mTasksSet.iterator();
         while (it.hasNext()) {
             TaskStatus ts = it.next();
             if (ts.getUid() == uid) {
                 it.remove();
-                removed = true;
+                maybeWriteStatusToDiskAsync();
+                return true;
             }
         }
-        if (removed) {
-            maybeWriteStatusToDisk();
-        }
-        return removed;
+        return false;
     }
 
     /**
@@ -124,48 +192,464 @@
      * @return true if a removal occurred, false if the provided parameters didn't match anything.
      */
     public boolean remove(int uid, int taskId) {
-        Iterator<TaskStatus> it = mTasks.iterator();
+        boolean changed = false;
+        Iterator<TaskStatus> it = mTasksSet.iterator();
         while (it.hasNext()) {
             TaskStatus ts = it.next();
             if (ts.getUid() == uid && ts.getTaskId() == taskId) {
                 it.remove();
-                maybeWriteStatusToDisk();
-                return true;
+                changed = true;
             }
         }
-        return false;
+        if (changed) {
+            maybeWriteStatusToDiskAsync();
+        }
+        return changed;
     }
 
     /**
      * @return The live array of TaskStatus objects.
      */
-    public Set<TaskStatus> getTasks() {
-        return mTasks;
+    public ArraySet<TaskStatus> getTasks() {
+        return mTasksSet;
     }
 
+    /** Version of the db schema. */
+    private static final int TASKS_FILE_VERSION = 0;
+    /** Tag corresponds to constraints this task needs. */
+    private static final String XML_TAG_PARAMS_CONSTRAINTS = "constraints";
+    /** Tag corresponds to execution parameters. */
+    private static final String XML_TAG_PERIODIC = "periodic";
+    private static final String XML_TAG_ONEOFF = "one-off";
+    private static final String XML_TAG_EXTRAS = "extras";
+
     /**
      * Every time the state changes we write all the tasks in one swathe, instead of trying to
      * track incremental changes.
      * @return Whether the operation was successful. This will only fail for e.g. if the system is
      * low on storage. If this happens, we continue as normal
      */
-    private boolean maybeWriteStatusToDisk() {
+    private void maybeWriteStatusToDiskAsync() {
         mDirtyOperations++;
-        if (mDirtyOperations > MAX_OPS_BEFORE_WRITE) {
-            for (TaskStatus ts : mTasks) {
-                //
+        if (mDirtyOperations >= MAX_OPS_BEFORE_WRITE) {
+            if (DEBUG) {
+                Slog.v(TAG, "Writing tasks to disk.");
             }
-            mDirtyOperations = 0;
+            mIoHandler.post(new WriteTasksMapToDiskRunnable());
         }
-        return true;
+    }
+
+    private void readTaskMapFromDiskAsync(TaskMapReadFinishedListener callback) {
+        mIoHandler.post(new ReadTaskMapFromDiskRunnable(callback));
+    }
+
+    public void readTaskMapFromDisk(TaskMapReadFinishedListener callback) {
+        new ReadTaskMapFromDiskRunnable(callback).run();
     }
 
     /**
-     *
-     * @return
+     * Runnable that writes {@link #mTasksSet} out to xml.
+     * NOTE: This Runnable locks on TaskStore.this
      */
-    // TODO: Implement this.
-    private ArraySet<TaskStatus> intialiseTasksFromDisk() {
-        return new ArraySet<TaskStatus>();
+    private class WriteTasksMapToDiskRunnable implements Runnable {
+        @Override
+        public void run() {
+            final long startElapsed = SystemClock.elapsedRealtime();
+            synchronized (TaskStore.this) {
+                writeTasksMapImpl();
+            }
+            if (TaskManagerService.DEBUG) {
+                Slog.v(TAG, "Finished writing, took " + (SystemClock.elapsedRealtime()
+                        - startElapsed) + "ms");
+            }
+        }
+
+        private void writeTasksMapImpl() {
+            try {
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                XmlSerializer out = new FastXmlSerializer();
+                out.setOutput(baos, "utf-8");
+                out.startDocument(null, true);
+                out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
+
+                out.startTag(null, "task-info");
+                out.attribute(null, "version", Integer.toString(TASKS_FILE_VERSION));
+                for (int i = 0; i < mTasksSet.size(); i++) {
+                    final TaskStatus taskStatus = mTasksSet.valueAt(i);
+                    if (DEBUG) {
+                        Slog.d(TAG, "Saving task " + taskStatus.getTaskId());
+                    }
+                    out.startTag(null, "task");
+                    addIdentifierAttributesToTaskTag(out, taskStatus);
+                    writeConstraintsToXml(out, taskStatus);
+                    writeExecutionCriteriaToXml(out, taskStatus);
+                    writeBundleToXml(taskStatus.getExtras(), out);
+                    out.endTag(null, "task");
+                }
+                out.endTag(null, "task-info");
+                out.endDocument();
+
+                // Write out to disk in one fell sweep.
+                FileOutputStream fos = mTasksFile.startWrite();
+                fos.write(baos.toByteArray());
+                mTasksFile.finishWrite(fos);
+                mDirtyOperations = 0;
+            } catch (IOException e) {
+                if (DEBUG) {
+                    Slog.v(TAG, "Error writing out task data.", e);
+                }
+            } catch (XmlPullParserException e) {
+                if (DEBUG) {
+                    Slog.d(TAG, "Error persisting bundle.", e);
+                }
+            }
+        }
+
+        /** Write out a tag with data comprising the required fields of this task and its client. */
+        private void addIdentifierAttributesToTaskTag(XmlSerializer out, TaskStatus taskStatus)
+                throws IOException {
+            out.attribute(null, "taskid", Integer.toString(taskStatus.getTaskId()));
+            out.attribute(null, "package", taskStatus.getServiceComponent().getPackageName());
+            out.attribute(null, "class", taskStatus.getServiceComponent().getClassName());
+            out.attribute(null, "uid", Integer.toString(taskStatus.getUid()));
+        }
+
+        private void writeBundleToXml(PersistableBundle extras, XmlSerializer out)
+                throws IOException, XmlPullParserException {
+            out.startTag(null, XML_TAG_EXTRAS);
+            extras.saveToXml(out);
+            out.endTag(null, XML_TAG_EXTRAS);
+        }
+        /**
+         * Write out a tag with data identifying this tasks constraints. If the constraint isn't here
+         * it doesn't apply.
+         */
+        private void writeConstraintsToXml(XmlSerializer out, TaskStatus taskStatus) throws IOException {
+            out.startTag(null, XML_TAG_PARAMS_CONSTRAINTS);
+            if (taskStatus.hasMeteredConstraint()) {
+                out.attribute(null, "unmetered", Boolean.toString(true));
+            }
+            if (taskStatus.hasConnectivityConstraint()) {
+                out.attribute(null, "connectivity", Boolean.toString(true));
+            }
+            if (taskStatus.hasIdleConstraint()) {
+                out.attribute(null, "idle", Boolean.toString(true));
+            }
+            if (taskStatus.hasChargingConstraint()) {
+                out.attribute(null, "charging", Boolean.toString(true));
+            }
+            out.endTag(null, XML_TAG_PARAMS_CONSTRAINTS);
+        }
+
+        private void writeExecutionCriteriaToXml(XmlSerializer out, TaskStatus taskStatus)
+                throws IOException {
+            final Task task = taskStatus.getTask();
+            if (taskStatus.getTask().isPeriodic()) {
+                out.startTag(null, XML_TAG_PERIODIC);
+                out.attribute(null, "period", Long.toString(task.getIntervalMillis()));
+            } else {
+                out.startTag(null, XML_TAG_ONEOFF);
+            }
+
+            if (taskStatus.hasDeadlineConstraint()) {
+                // Wall clock deadline.
+                final long deadlineWallclock =  System.currentTimeMillis() +
+                        (taskStatus.getLatestRunTimeElapsed() - SystemClock.elapsedRealtime());
+                out.attribute(null, "deadline", Long.toString(deadlineWallclock));
+            }
+            if (taskStatus.hasTimingDelayConstraint()) {
+                final long delayWallclock = System.currentTimeMillis() +
+                        (taskStatus.getEarliestRunTime() - SystemClock.elapsedRealtime());
+                out.attribute(null, "delay", Long.toString(delayWallclock));
+            }
+
+            // Only write out back-off policy if it differs from the default.
+            // This also helps the case where the task is idle -> these aren't allowed to specify
+            // back-off.
+            if (taskStatus.getTask().getInitialBackoffMillis() != Task.DEFAULT_INITIAL_BACKOFF_MILLIS
+                    || taskStatus.getTask().getBackoffPolicy() != Task.DEFAULT_BACKOFF_POLICY) {
+                out.attribute(null, "backoff-policy", Integer.toString(task.getBackoffPolicy()));
+                out.attribute(null, "initial-backoff", Long.toString(task.getInitialBackoffMillis()));
+            }
+            if (task.isPeriodic()) {
+                out.endTag(null, XML_TAG_PERIODIC);
+            } else {
+                out.endTag(null, XML_TAG_ONEOFF);
+            }
+        }
+    }
+
+    /**
+     * Runnable that reads list of persisted task from xml.
+     * NOTE: This Runnable locks on TaskStore.this
+     */
+    private class ReadTaskMapFromDiskRunnable implements Runnable {
+        private TaskMapReadFinishedListener mCallback;
+        public ReadTaskMapFromDiskRunnable(TaskMapReadFinishedListener callback) {
+            mCallback = callback;
+        }
+
+        @Override
+        public void run() {
+            try {
+                List<TaskStatus> tasks;
+                synchronized (TaskStore.this) {
+                    tasks = readTaskMapImpl();
+                }
+                if (tasks != null) {
+                    mCallback.onTaskMapReadFinished(tasks);
+                }
+            } catch (FileNotFoundException e) {
+                if (TaskManagerService.DEBUG) {
+                    Slog.d(TAG, "Could not find tasks file, probably there was nothing to load.");
+                }
+            } catch (XmlPullParserException e) {
+                if (TaskManagerService.DEBUG) {
+                    Slog.d(TAG, "Error parsing xml.", e);
+                }
+            } catch (IOException e) {
+                if (TaskManagerService.DEBUG) {
+                    Slog.d(TAG, "Error parsing xml.", e);
+                }
+            }
+        }
+
+        private List<TaskStatus> readTaskMapImpl() throws XmlPullParserException, IOException {
+            FileInputStream fis = mTasksFile.openRead();
+            XmlPullParser parser = Xml.newPullParser();
+            parser.setInput(fis, null);
+
+            int eventType = parser.getEventType();
+            while (eventType != XmlPullParser.START_TAG &&
+                    eventType != XmlPullParser.END_DOCUMENT) {
+                eventType = parser.next();
+                Slog.d(TAG, parser.getName());
+            }
+            if (eventType == XmlPullParser.END_DOCUMENT) {
+                if (DEBUG) {
+                    Slog.d(TAG, "No persisted tasks.");
+                }
+                return null;
+            }
+
+            String tagName = parser.getName();
+            if ("task-info".equals(tagName)) {
+                final List<TaskStatus> tasks = new ArrayList<TaskStatus>();
+                // Read in version info.
+                try {
+                    int version = Integer.valueOf(parser.getAttributeValue(null, "version"));
+                    if (version != TASKS_FILE_VERSION) {
+                        Slog.d(TAG, "Invalid version number, aborting tasks file read.");
+                        return null;
+                    }
+                } catch (NumberFormatException e) {
+                    Slog.e(TAG, "Invalid version number, aborting tasks file read.");
+                    return null;
+                }
+                eventType = parser.next();
+                do {
+                    // Read each <task/>
+                    if (eventType == XmlPullParser.START_TAG) {
+                        tagName = parser.getName();
+                        // Start reading task.
+                        if ("task".equals(tagName)) {
+                            TaskStatus persistedTask = restoreTaskFromXml(parser);
+                            if (persistedTask != null) {
+                                if (DEBUG) {
+                                    Slog.d(TAG, "Read out " + persistedTask);
+                                }
+                                tasks.add(persistedTask);
+                            } else {
+                                Slog.d(TAG, "Error reading task from file.");
+                            }
+                        }
+                    }
+                    eventType = parser.next();
+                } while (eventType != XmlPullParser.END_DOCUMENT);
+                return tasks;
+            }
+            return null;
+        }
+
+        /**
+         * @param parser Xml parser at the beginning of a "<task/>" tag. The next "parser.next()" call
+         *               will take the parser into the body of the task tag.
+         * @return Newly instantiated task holding all the information we just read out of the xml tag.
+         */
+        private TaskStatus restoreTaskFromXml(XmlPullParser parser) throws XmlPullParserException,
+                IOException {
+            Task.Builder taskBuilder;
+            int uid;
+
+            // Read out task identifier attributes.
+            try {
+                taskBuilder = buildBuilderFromXml(parser);
+                uid = Integer.valueOf(parser.getAttributeValue(null, "uid"));
+            } catch (NumberFormatException e) {
+                Slog.e(TAG, "Error parsing task's required fields, skipping");
+                return null;
+            }
+
+            int eventType;
+            // Read out constraints tag.
+            do {
+                eventType = parser.next();
+            } while (eventType == XmlPullParser.TEXT);  // Push through to next START_TAG.
+
+            if (!(eventType == XmlPullParser.START_TAG &&
+                    XML_TAG_PARAMS_CONSTRAINTS.equals(parser.getName()))) {
+                // Expecting a <constraints> start tag.
+                return null;
+            }
+            try {
+                buildConstraintsFromXml(taskBuilder, parser);
+            } catch (NumberFormatException e) {
+                Slog.d(TAG, "Error reading constraints, skipping.");
+                return null;
+            }
+            parser.next(); // Consume </constraints>
+
+            // Read out execution parameters tag.
+            do {
+                eventType = parser.next();
+            } while (eventType == XmlPullParser.TEXT);
+            if (eventType != XmlPullParser.START_TAG) {
+                return null;
+            }
+
+            Pair<Long, Long> runtimes;
+            try {
+                runtimes = buildExecutionTimesFromXml(parser);
+            } catch (NumberFormatException e) {
+                if (DEBUG) {
+                    Slog.d(TAG, "Error parsing execution time parameters, skipping.");
+                }
+                return null;
+            }
+
+            if (XML_TAG_PERIODIC.equals(parser.getName())) {
+                try {
+                    String val = parser.getAttributeValue(null, "period");
+                    taskBuilder.setPeriodic(Long.valueOf(val));
+                } catch (NumberFormatException e) {
+                    Slog.d(TAG, "Error reading periodic execution criteria, skipping.");
+                    return null;
+                }
+            } else if (XML_TAG_ONEOFF.equals(parser.getName())) {
+                try {
+                    if (runtimes.first != TaskStatus.DEFAULT_EARLIEST_RUNTIME) {
+                        taskBuilder.setMinimumLatency(runtimes.first - SystemClock.elapsedRealtime());
+                    }
+                    if (runtimes.second != TaskStatus.DEFAULT_LATEST_RUNTIME) {
+                        taskBuilder.setOverrideDeadline(
+                                runtimes.second - SystemClock.elapsedRealtime());
+                    }
+                } catch (NumberFormatException e) {
+                    Slog.d(TAG, "Error reading task execution criteria, skipping.");
+                    return null;
+                }
+            } else {
+                if (DEBUG) {
+                    Slog.d(TAG, "Invalid parameter tag, skipping - " + parser.getName());
+                }
+                // Expecting a parameters start tag.
+                return null;
+            }
+            maybeBuildBackoffPolicyFromXml(taskBuilder, parser);
+
+            parser.nextTag(); // Consume parameters end tag.
+
+            // Read out extras Bundle.
+            do {
+                eventType = parser.next();
+            } while (eventType == XmlPullParser.TEXT);
+            if (!(eventType == XmlPullParser.START_TAG && XML_TAG_EXTRAS.equals(parser.getName()))) {
+                if (DEBUG) {
+                    Slog.d(TAG, "Error reading extras, skipping.");
+                }
+                return null;
+            }
+
+            PersistableBundle extras = PersistableBundle.restoreFromXml(parser);
+            taskBuilder.setExtras(extras);
+            parser.nextTag(); // Consume </extras>
+
+            return new TaskStatus(taskBuilder.build(), uid, runtimes.first, runtimes.second);
+        }
+
+        private Task.Builder buildBuilderFromXml(XmlPullParser parser) throws NumberFormatException {
+            // Pull out required fields from <task> attributes.
+            int taskId = Integer.valueOf(parser.getAttributeValue(null, "taskid"));
+            String packageName = parser.getAttributeValue(null, "package");
+            String className = parser.getAttributeValue(null, "class");
+            ComponentName cname = new ComponentName(packageName, className);
+
+            return new Task.Builder(taskId, cname);
+        }
+
+        private void buildConstraintsFromXml(Task.Builder taskBuilder, XmlPullParser parser) {
+            String val = parser.getAttributeValue(null, "unmetered");
+            if (val != null) {
+                taskBuilder.setRequiredNetworkCapabilities(Task.NetworkType.UNMETERED);
+            }
+            val = parser.getAttributeValue(null, "connectivity");
+            if (val != null) {
+                taskBuilder.setRequiredNetworkCapabilities(Task.NetworkType.ANY);
+            }
+            val = parser.getAttributeValue(null, "idle");
+            if (val != null) {
+                taskBuilder.setRequiresDeviceIdle(true);
+            }
+            val = parser.getAttributeValue(null, "charging");
+            if (val != null) {
+                taskBuilder.setRequiresCharging(true);
+            }
+        }
+
+        /**
+         * Builds the back-off policy out of the params tag. These attributes may not exist, depending
+         * on whether the back-off was set when the task was first scheduled.
+         */
+        private void maybeBuildBackoffPolicyFromXml(Task.Builder taskBuilder, XmlPullParser parser) {
+            String val = parser.getAttributeValue(null, "initial-backoff");
+            if (val != null) {
+                long initialBackoff = Long.valueOf(val);
+                val = parser.getAttributeValue(null, "backoff-policy");
+                int backoffPolicy = Integer.valueOf(val);  // Will throw NFE which we catch higher up.
+                taskBuilder.setBackoffCriteria(initialBackoff, backoffPolicy);
+            }
+        }
+
+        /**
+         * Convenience function to read out and convert deadline and delay from xml into elapsed real
+         * time.
+         * @return A {@link android.util.Pair}, where the first value is the earliest elapsed runtime
+         * and the second is the latest elapsed runtime.
+         */
+        private Pair<Long, Long> buildExecutionTimesFromXml(XmlPullParser parser)
+                throws NumberFormatException {
+            // Pull out execution time data.
+            final long nowWallclock = System.currentTimeMillis();
+            final long nowElapsed = SystemClock.elapsedRealtime();
+
+            long earliestRunTimeElapsed = TaskStatus.DEFAULT_EARLIEST_RUNTIME;
+            long latestRunTimeElapsed = TaskStatus.DEFAULT_LATEST_RUNTIME;
+            String val = parser.getAttributeValue(null, "deadline");
+            if (val != null) {
+                long latestRuntimeWallclock = Long.valueOf(val);
+                long maxDelayElapsed =
+                        Math.max(latestRuntimeWallclock - nowWallclock, 0);
+                latestRunTimeElapsed = nowElapsed + maxDelayElapsed;
+            }
+            val = parser.getAttributeValue(null, "delay");
+            if (val != null) {
+                long earliestRuntimeWallclock = Long.valueOf(val);
+                long minDelayElapsed =
+                        Math.max(earliestRuntimeWallclock - nowWallclock, 0);
+                earliestRunTimeElapsed = nowElapsed + minDelayElapsed;
+
+            }
+            return Pair.create(earliestRunTimeElapsed, latestRunTimeElapsed);
+        }
     }
 }
diff --git a/services/core/java/com/android/server/task/controllers/BatteryController.java b/services/core/java/com/android/server/task/controllers/BatteryController.java
new file mode 100644
index 0000000..4727e9a
--- /dev/null
+++ b/services/core/java/com/android/server/task/controllers/BatteryController.java
@@ -0,0 +1,213 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.task.controllers;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.BatteryManager;
+import android.os.BatteryProperty;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.BatteryService;
+import com.android.server.task.StateChangedListener;
+import com.android.server.task.TaskManagerService;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Simple controller that tracks whether the phone is charging or not. The phone is considered to
+ * be charging when it's been plugged in for more than two minutes, and the system has broadcast
+ * ACTION_BATTERY_OK.
+ */
+public class BatteryController extends StateController {
+    private static final String TAG = "BatteryController";
+
+    private static final Object sCreationLock = new Object();
+    private static volatile BatteryController sController;
+    private static final String ACTION_CHARGING_STABLE =
+            "com.android.server.task.controllers.BatteryController.ACTION_CHARGING_STABLE";
+    /** Wait this long after phone is plugged in before doing any work. */
+    private static final long STABLE_CHARGING_THRESHOLD_MILLIS = 2 * 60 * 1000; // 2 minutes.
+
+    private List<TaskStatus> mTrackedTasks = new ArrayList<TaskStatus>();
+    private ChargingTracker mChargeTracker;
+
+    public static BatteryController get(TaskManagerService taskManagerService) {
+        synchronized (sCreationLock) {
+            if (sController == null) {
+                sController = new BatteryController(taskManagerService,
+                        taskManagerService.getContext());
+            }
+        }
+        return sController;
+    }
+
+    @VisibleForTesting
+    public ChargingTracker getTracker() {
+        return mChargeTracker;
+    }
+
+    @VisibleForTesting
+    public static BatteryController getForTesting(StateChangedListener stateChangedListener,
+                                           Context context) {
+        return new BatteryController(stateChangedListener, context);
+    }
+
+    private BatteryController(StateChangedListener stateChangedListener, Context context) {
+        super(stateChangedListener, context);
+        mChargeTracker = new ChargingTracker();
+        mChargeTracker.startTracking();
+    }
+
+    @Override
+    public void maybeStartTrackingTask(TaskStatus taskStatus) {
+        if (taskStatus.hasChargingConstraint()) {
+            synchronized (mTrackedTasks) {
+                mTrackedTasks.add(taskStatus);
+                taskStatus.chargingConstraintSatisfied.set(mChargeTracker.isOnStablePower());
+            }
+        }
+
+    }
+
+    @Override
+    public void maybeStopTrackingTask(TaskStatus taskStatus) {
+        if (taskStatus.hasChargingConstraint()) {
+            synchronized (mTrackedTasks) {
+                mTrackedTasks.remove(taskStatus);
+            }
+        }
+    }
+
+    private void maybeReportNewChargingState() {
+        final boolean stablePower = mChargeTracker.isOnStablePower();
+        boolean reportChange = false;
+        synchronized (mTrackedTasks) {
+            for (TaskStatus ts : mTrackedTasks) {
+                boolean previous = ts.chargingConstraintSatisfied.getAndSet(stablePower);
+                if (previous != stablePower) {
+                    reportChange = true;
+                }
+            }
+        }
+        if (reportChange) {
+            mStateChangedListener.onControllerStateChanged();
+        }
+    }
+
+    public class ChargingTracker extends BroadcastReceiver {
+        private final AlarmManager mAlarm;
+        private final PendingIntent mStableChargingTriggerIntent;
+        /**
+         * Track whether we're "charging", where charging means that we're ready to commit to
+         * doing work.
+         */
+        private boolean mCharging;
+        /** Keep track of whether the battery is charged enough that we want to do work. */
+        private boolean mBatteryHealthy;
+
+        public ChargingTracker() {
+            mAlarm = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
+            Intent intent = new Intent(ACTION_CHARGING_STABLE)
+                    .setComponent(new ComponentName(mContext, this.getClass()));
+            mStableChargingTriggerIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
+        }
+
+        public void startTracking() {
+            IntentFilter filter = new IntentFilter();
+
+            // Battery health.
+            filter.addAction(Intent.ACTION_BATTERY_LOW);
+            filter.addAction(Intent.ACTION_BATTERY_OKAY);
+            // Charging/not charging.
+            filter.addAction(Intent.ACTION_POWER_CONNECTED);
+            filter.addAction(Intent.ACTION_POWER_DISCONNECTED);
+            mContext.registerReceiver(this, filter);
+
+            // Initialise tracker state.
+            BatteryService batteryService = (BatteryService) ServiceManager.getService("battery");
+            if (batteryService != null) {
+                mBatteryHealthy = !batteryService.getBatteryLevelLow();
+                mCharging = batteryService.isPowered(BatteryManager.BATTERY_PLUGGED_ANY);
+            } else {
+                // Unavailable for some reason, we default to false and let ACTION_BATTERY_[OK,LOW]
+                // sort it out.
+            }
+        }
+
+        boolean isOnStablePower() {
+            return mCharging && mBatteryHealthy;
+        }
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            onReceiveInternal(intent);
+        }
+
+        @VisibleForTesting
+        public void onReceiveInternal(Intent intent) {
+            final String action = intent.getAction();
+            if (Intent.ACTION_BATTERY_LOW.equals(action)) {
+                if (DEBUG) {
+                    Slog.d(TAG, "Battery life too low to do work. @ "
+                            + SystemClock.elapsedRealtime());
+                }
+                // If we get this action, the battery is discharging => it isn't plugged in so
+                // there's no work to cancel. We track this variable for the case where it is
+                // charging, but hasn't been for long enough to be healthy.
+                mBatteryHealthy = false;
+            } else if (Intent.ACTION_BATTERY_OKAY.equals(action)) {
+                if (DEBUG) {
+                    Slog.d(TAG, "Battery life healthy enough to do work. @ "
+                            + SystemClock.elapsedRealtime());
+                }
+                mBatteryHealthy = true;
+                maybeReportNewChargingState();
+            } else if (Intent.ACTION_POWER_CONNECTED.equals(action)) {
+                // Set up an alarm for ACTION_CHARGING_STABLE - we don't want to kick off tasks
+                // here if the user unplugs the phone immediately.
+                mAlarm.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+                        SystemClock.elapsedRealtime() + STABLE_CHARGING_THRESHOLD_MILLIS,
+                        mStableChargingTriggerIntent);
+                mCharging = true;
+            } else if (Intent.ACTION_POWER_DISCONNECTED.equals(action)) {
+                // If an alarm is set, breathe a sigh of relief and cancel it - crisis averted.
+                mAlarm.cancel(mStableChargingTriggerIntent);
+                mCharging = false;
+                maybeReportNewChargingState();
+            }else if (ACTION_CHARGING_STABLE.equals(action)) {
+                // Here's where we actually do the notify for a task being ready.
+                if (DEBUG) {
+                    Slog.d(TAG, "Battery connected fired @ " + SystemClock.elapsedRealtime());
+                }
+                if (mCharging) {  // Should never receive this intent if mCharging is false.
+                    maybeReportNewChargingState();
+                }
+            }
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/task/controllers/ConnectivityController.java b/services/core/java/com/android/server/task/controllers/ConnectivityController.java
index 474af8f..4819460 100644
--- a/services/core/java/com/android/server/task/controllers/ConnectivityController.java
+++ b/services/core/java/com/android/server/task/controllers/ConnectivityController.java
@@ -27,6 +27,7 @@
 import android.util.Log;
 import android.util.Slog;
 
+import com.android.server.task.StateChangedListener;
 import com.android.server.task.TaskManagerService;
 
 import java.util.LinkedList;
@@ -39,7 +40,6 @@
  */
 public class ConnectivityController extends StateController {
     private static final String TAG = "TaskManager.Connectivity";
-    private static final boolean DEBUG = true;
 
     private final List<TaskStatus> mTrackedTasks = new LinkedList<TaskStatus>();
     private final BroadcastReceiver mConnectivityChangedReceiver =
@@ -54,13 +54,13 @@
 
     public static synchronized ConnectivityController get(TaskManagerService taskManager) {
         if (mSingleton == null) {
-            mSingleton = new ConnectivityController(taskManager);
+            mSingleton = new ConnectivityController(taskManager, taskManager.getContext());
         }
         return mSingleton;
     }
 
-    private ConnectivityController(TaskManagerService service) {
-        super(service);
+    private ConnectivityController(StateChangedListener stateChangedListener, Context context) {
+        super(stateChangedListener, context);
         // Register connectivity changed BR.
         IntentFilter intentFilter = new IntentFilter();
         intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
diff --git a/services/core/java/com/android/server/task/controllers/IdleController.java b/services/core/java/com/android/server/task/controllers/IdleController.java
index 9489644..c47faca 100644
--- a/services/core/java/com/android/server/task/controllers/IdleController.java
+++ b/services/core/java/com/android/server/task/controllers/IdleController.java
@@ -28,11 +28,11 @@
 import android.os.SystemClock;
 import android.util.Slog;
 
+import com.android.server.task.StateChangedListener;
 import com.android.server.task.TaskManagerService;
 
 public class IdleController extends StateController {
     private static final String TAG = "IdleController";
-    private static final boolean DEBUG = false;
 
     // Policy: we decide that we're "idle" if the device has been unused /
     // screen off or dreaming for at least this long
@@ -52,14 +52,14 @@
     public static IdleController get(TaskManagerService service) {
         synchronized (sCreationLock) {
             if (sController == null) {
-                sController = new IdleController(service);
+                sController = new IdleController(service, service.getContext());
             }
             return sController;
         }
     }
 
-    private IdleController(TaskManagerService service) {
-        super(service);
+    private IdleController(StateChangedListener stateChangedListener, Context context) {
+        super(stateChangedListener, context);
         initIdleStateTracking();
     }
 
diff --git a/services/core/java/com/android/server/task/controllers/StateController.java b/services/core/java/com/android/server/task/controllers/StateController.java
index ed31eac..cbe6ff8 100644
--- a/services/core/java/com/android/server/task/controllers/StateController.java
+++ b/services/core/java/com/android/server/task/controllers/StateController.java
@@ -27,13 +27,13 @@
  * are ready to run, or whether they must be stopped.
  */
 public abstract class StateController {
-
+    protected static final boolean DEBUG = true;
     protected Context mContext;
     protected StateChangedListener mStateChangedListener;
 
-    public StateController(TaskManagerService service) {
-        mStateChangedListener = service;
-        mContext = service.getContext();
+    public StateController(StateChangedListener stateChangedListener, Context context) {
+        mStateChangedListener = stateChangedListener;
+        mContext = context;
     }
 
     /**
diff --git a/services/core/java/com/android/server/task/controllers/TaskStatus.java b/services/core/java/com/android/server/task/controllers/TaskStatus.java
index b7f84ec..33670a1 100644
--- a/services/core/java/com/android/server/task/controllers/TaskStatus.java
+++ b/services/core/java/com/android/server/task/controllers/TaskStatus.java
@@ -18,7 +18,7 @@
 
 import android.app.task.Task;
 import android.content.ComponentName;
-import android.os.Bundle;
+import android.os.PersistableBundle;
 import android.os.SystemClock;
 import android.os.UserHandle;
 
@@ -37,6 +37,9 @@
  * @hide
  */
 public class TaskStatus {
+    public static final long DEFAULT_LATEST_RUNTIME = Long.MAX_VALUE;
+    public static final long DEFAULT_EARLIEST_RUNTIME = 0L;
+
     final Task task;
     final int uId;
 
@@ -61,7 +64,7 @@
      * indicates there is no deadline constraint. See {@link #hasDeadlineConstraint()}.
      */
     private long latestRunTimeElapsedMillis;
-
+    /** How many times this task has failed, used to compute back-off. */
     private final int numFailures;
 
     /** Provide a handle to the service that this task will be run on. */
@@ -69,36 +72,52 @@
         return uId;
     }
 
-    /** Create a newly scheduled task. */
-    public TaskStatus(Task task, int uId, boolean persisted) {
+    private TaskStatus(Task task, int uId, boolean persisted, int numFailures) {
         this.task = task;
         this.uId = uId;
-        this.numFailures = 0;
+        this.numFailures = numFailures;
         this.persisted = persisted;
+    }
+
+    /** Create a newly scheduled task. */
+    public TaskStatus(Task task, int uId, boolean persisted) {
+        this(task, uId, persisted, 0);
 
         final long elapsedNow = SystemClock.elapsedRealtime();
-        // Timing constraints
+
         if (task.isPeriodic()) {
             earliestRunTimeElapsedMillis = elapsedNow;
             latestRunTimeElapsedMillis = elapsedNow + task.getIntervalMillis();
         } else {
             earliestRunTimeElapsedMillis = task.hasEarlyConstraint() ?
-                    elapsedNow + task.getMinLatencyMillis() : 0L;
+                    elapsedNow + task.getMinLatencyMillis() : DEFAULT_EARLIEST_RUNTIME;
             latestRunTimeElapsedMillis = task.hasLateConstraint() ?
-                    elapsedNow + task.getMaxExecutionDelayMillis() : Long.MAX_VALUE;
+                    elapsedNow + task.getMaxExecutionDelayMillis() : DEFAULT_LATEST_RUNTIME;
         }
     }
 
-    public TaskStatus(TaskStatus rescheduling, long newEarliestRuntimeElapsed,
-                      long newLatestRuntimeElapsed, int backoffAttempt) {
-        this.task = rescheduling.task;
+    /**
+     * Create a new TaskStatus that was loaded from disk. We ignore the provided
+     * {@link android.app.task.Task} time criteria because we can load a persisted periodic task
+     * from the {@link com.android.server.task.TaskStore} and still want to respect its
+     * wallclock runtime rather than resetting it on every boot.
+     * We consider a freshly loaded task to no longer be in back-off.
+     */
+    public TaskStatus(Task task, int uId, long earliestRunTimeElapsedMillis,
+                      long latestRunTimeElapsedMillis) {
+        this(task, uId, true, 0);
 
-        this.uId = rescheduling.getUid();
-        this.persisted = rescheduling.isPersisted();
-        this.numFailures = backoffAttempt;
+        this.earliestRunTimeElapsedMillis = earliestRunTimeElapsedMillis;
+        this.latestRunTimeElapsedMillis = latestRunTimeElapsedMillis;
+    }
 
-        earliestRunTimeElapsedMillis = newEarliestRuntimeElapsed;
-        latestRunTimeElapsedMillis = newLatestRuntimeElapsed;
+    /** Create a new task to be rescheduled with the provided parameters. */
+    public TaskStatus(TaskStatus rescheduling, long newEarliestRuntimeElapsedMillis,
+                      long newLatestRuntimeElapsedMillis, int backoffAttempt) {
+        this(rescheduling.task, rescheduling.getUid(), rescheduling.isPersisted(), backoffAttempt);
+
+        earliestRunTimeElapsedMillis = newEarliestRuntimeElapsedMillis;
+        latestRunTimeElapsedMillis = newLatestRuntimeElapsedMillis;
     }
 
     public Task getTask() {
@@ -125,7 +144,7 @@
         return uId;
     }
 
-    public Bundle getExtras() {
+    public PersistableBundle getExtras() {
         return task.getExtras();
     }
 
@@ -142,11 +161,11 @@
     }
 
     public boolean hasTimingDelayConstraint() {
-        return earliestRunTimeElapsedMillis != 0L;
+        return earliestRunTimeElapsedMillis != DEFAULT_EARLIEST_RUNTIME;
     }
 
     public boolean hasDeadlineConstraint() {
-        return latestRunTimeElapsedMillis != Long.MAX_VALUE;
+        return latestRunTimeElapsedMillis != DEFAULT_LATEST_RUNTIME;
     }
 
     public boolean hasIdleConstraint() {
diff --git a/services/core/java/com/android/server/task/controllers/TimeController.java b/services/core/java/com/android/server/task/controllers/TimeController.java
index 72f312c..8c6dd27 100644
--- a/services/core/java/com/android/server/task/controllers/TimeController.java
+++ b/services/core/java/com/android/server/task/controllers/TimeController.java
@@ -24,6 +24,7 @@
 import android.content.IntentFilter;
 import android.os.SystemClock;
 
+import com.android.server.task.StateChangedListener;
 import com.android.server.task.TaskManagerService;
 
 import java.util.Iterator;
@@ -58,13 +59,13 @@
 
     public static synchronized TimeController get(TaskManagerService taskManager) {
         if (mSingleton == null) {
-            mSingleton = new TimeController(taskManager);
+            mSingleton = new TimeController(taskManager, taskManager.getContext());
         }
         return mSingleton;
     }
 
-    private TimeController(TaskManagerService service) {
-        super(service);
+    private TimeController(StateChangedListener stateChangedListener, Context context) {
+        super(stateChangedListener, context);
         mTaskExpiredAlarmIntent =
                 PendingIntent.getBroadcast(mContext, 0 /* ignored */,
                         new Intent(ACTION_TASK_EXPIRED), 0);
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 1629a614..32546df 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -50,6 +50,7 @@
 import android.service.trust.TrustAgentService;
 import android.util.ArraySet;
 import android.util.AttributeSet;
+import android.util.Log;
 import android.util.Slog;
 import android.util.SparseBooleanArray;
 import android.util.Xml;
@@ -81,6 +82,7 @@
 
     private static final Intent TRUST_AGENT_INTENT =
             new Intent(TrustAgentService.SERVICE_INTERFACE);
+    private static final String PERMISSION_PROVIDE_AGENT = Manifest.permission.PROVIDE_TRUST_AGENT;
 
     private static final int MSG_REGISTER_LISTENER = 1;
     private static final int MSG_UNREGISTER_LISTENER = 2;
@@ -182,6 +184,15 @@
                     PackageManager.GET_META_DATA, userInfo.id);
             for (ResolveInfo resolveInfo : resolveInfos) {
                 if (resolveInfo.serviceInfo == null) continue;
+
+                String packageName = resolveInfo.serviceInfo.packageName;
+                if (pm.checkPermission(PERMISSION_PROVIDE_AGENT, packageName)
+                        != PackageManager.PERMISSION_GRANTED) {
+                    Log.w(TAG, "Skipping agent because package " + packageName
+                            + " does not have permission " + PERMISSION_PROVIDE_AGENT + ".");
+                    continue;
+                }
+
                 ComponentName name = getComponentName(resolveInfo);
                 if (!enabledAgents.contains(name)) continue;
 
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index 5eb3305..1c277a8 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -372,18 +372,54 @@
             }
 
             @Override
-            public void onVideoSizeChanged(int width, int height) throws RemoteException {
+            public void onVideoStreamChanged(int width, int height, boolean interlaced) {
                 synchronized (mLock) {
                     if (DEBUG) {
-                        Slog.d(TAG, "onVideoSizeChanged(" + width + ", " + height + ")");
+                        Slog.d(TAG, "onVideoStreamChanged(" + width + ", " + height + ")");
                     }
                     if (sessionState.mSession == null || sessionState.mClient == null) {
                         return;
                     }
                     try {
-                        sessionState.mClient.onVideoSizeChanged(width, height, sessionState.mSeq);
+                        sessionState.mClient.onVideoStreamChanged(width, height, interlaced,
+                                sessionState.mSeq);
                     } catch (RemoteException e) {
-                        Slog.e(TAG, "error in onSessionEvent");
+                        Slog.e(TAG, "error in onVideoStreamChanged");
+                    }
+                }
+            }
+
+            @Override
+            public void onAudioStreamChanged(int channelCount) {
+                synchronized (mLock) {
+                    if (DEBUG) {
+                        Slog.d(TAG, "onAudioStreamChanged(" + channelCount + ")");
+                    }
+                    if (sessionState.mSession == null || sessionState.mClient == null) {
+                        return;
+                    }
+                    try {
+                        sessionState.mClient.onAudioStreamChanged(channelCount, sessionState.mSeq);
+                    } catch (RemoteException e) {
+                        Slog.e(TAG, "error in onAudioStreamChanged");
+                    }
+                }
+            }
+
+            @Override
+            public void onClosedCaptionStreamChanged(boolean hasClosedCaption) {
+                synchronized (mLock) {
+                    if (DEBUG) {
+                        Slog.d(TAG, "onClosedCaptionStreamChanged(" + hasClosedCaption + ")");
+                    }
+                    if (sessionState.mSession == null || sessionState.mClient == null) {
+                        return;
+                    }
+                    try {
+                        sessionState.mClient.onClosedCaptionStreamChanged(hasClosedCaption,
+                                sessionState.mSeq);
+                    } catch (RemoteException e) {
+                        Slog.e(TAG, "error in onClosedCaptionStreamChanged");
                     }
                 }
             }
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index 35b7f99..cfd09e5 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -541,7 +541,7 @@
                 if (isMagnifyingLocked()) {
                     setMagnifiedRegionBorderShownLocked(false, false);
                     final long delay = (long) (mLongAnimationDuration
-                            * mWindowManagerService.mWindowAnimationScale);
+                            * mWindowManagerService.getWindowAnimationScaleLocked());
                     Message message = mHandler.obtainMessage(
                             MyHandler.MESSAGE_SHOW_MAGNIFIED_REGION_BOUNDS_IF_NEEDED);
                     mHandler.sendMessageDelayed(message, delay);
diff --git a/services/core/java/com/android/server/wm/AppWindowAnimator.java b/services/core/java/com/android/server/wm/AppWindowAnimator.java
index 7fe895b..63ae98e 100644
--- a/services/core/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/core/java/com/android/server/wm/AppWindowAnimator.java
@@ -87,7 +87,7 @@
             anim.initialize(width, height, width, height);
         }
         anim.restrictDuration(WindowManagerService.MAX_ANIMATION_DURATION);
-        anim.scaleCurrentDuration(mService.mTransitionAnimationScale);
+        anim.scaleCurrentDuration(mService.getTransitionAnimationScaleLocked());
         int zorder = anim.getZAdjustment();
         int adj = 0;
         if (zorder == Animation.ZORDER_TOP) {
@@ -227,7 +227,8 @@
                 if (!animating) {
                     if (WindowManagerService.DEBUG_ANIM) Slog.v(
                         TAG, "Starting animation in " + mAppToken +
-                        " @ " + currentTime + " scale=" + mService.mTransitionAnimationScale
+                        " @ " + currentTime + " scale="
+                        + mService.getTransitionAnimationScaleLocked()
                         + " allDrawn=" + mAppToken.allDrawn + " animating=" + animating);
                     animation.setStartTime(currentTime);
                     animating = true;
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index ca9076f..3200b54 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -17,6 +17,7 @@
 package com.android.server.wm;
 
 import android.view.IWindowId;
+import android.view.IWindowSessionCallback;
 import com.android.internal.view.IInputContext;
 import com.android.internal.view.IInputMethodClient;
 import com.android.internal.view.IInputMethodManager;
@@ -54,6 +55,7 @@
 final class Session extends IWindowSession.Stub
         implements IBinder.DeathRecipient {
     final WindowManagerService mService;
+    final IWindowSessionCallback mCallback;
     final IInputMethodClient mClient;
     final IInputContext mInputContext;
     final int mUid;
@@ -62,14 +64,17 @@
     SurfaceSession mSurfaceSession;
     int mNumWindow = 0;
     boolean mClientDead = false;
+    float mLastReportedAnimatorScale;
 
-    public Session(WindowManagerService service, IInputMethodClient client,
-            IInputContext inputContext) {
+    public Session(WindowManagerService service, IWindowSessionCallback callback,
+            IInputMethodClient client, IInputContext inputContext) {
         mService = service;
+        mCallback = callback;
         mClient = client;
         mInputContext = inputContext;
         mUid = Binder.getCallingUid();
         mPid = Binder.getCallingPid();
+        mLastReportedAnimatorScale = service.getCurrentAnimatorScale();
         StringBuilder sb = new StringBuilder();
         sb.append("Session{");
         sb.append(Integer.toHexString(System.identityHashCode(this)));
@@ -464,6 +469,9 @@
             if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(
                     WindowManagerService.TAG, "  NEW SURFACE SESSION " + mSurfaceSession);
             mService.mSessions.add(this);
+            if (mLastReportedAnimatorScale != mService.getCurrentAnimatorScale()) {
+                mService.dispatchNewAnimatorScaleLocked(this);
+            }
         }
         mNumWindow++;
     }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 05502cf..2d15dab 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -24,6 +24,7 @@
 import android.util.TimeUtils;
 import android.view.IWindowId;
 
+import android.view.IWindowSessionCallback;
 import android.view.WindowContentFrameStats;
 import com.android.internal.app.IBatteryStats;
 import com.android.internal.policy.PolicyManager;
@@ -339,7 +340,7 @@
     /**
      * All currently active sessions with clients.
      */
-    final HashSet<Session> mSessions = new HashSet<Session>();
+    final ArraySet<Session> mSessions = new ArraySet<Session>();
 
     /**
      * Mapping from an IWindow IBinder to the server's Window object.
@@ -407,8 +408,11 @@
     /**
      * Windows that clients are waiting to have drawn.
      */
-    ArrayList<Pair<WindowState, IRemoteCallback>> mWaitingForDrawn
-            = new ArrayList<Pair<WindowState, IRemoteCallback>>();
+    ArrayList<WindowState> mWaitingForDrawn = new ArrayList<WindowState>();
+    /**
+     * And the callback to make when they've all been drawn.
+     */
+    IRemoteCallback mWaitingForDrawnCallback;
 
     /**
      * Windows that have called relayout() while we were running animations,
@@ -559,9 +563,10 @@
     PowerManager mPowerManager;
     PowerManagerInternal mPowerManagerInternal;
 
-    float mWindowAnimationScale = 1.0f;
-    float mTransitionAnimationScale = 1.0f;
-    float mAnimatorDurationScale = 1.0f;
+    float mWindowAnimationScaleSetting = 1.0f;
+    float mTransitionAnimationScaleSetting = 1.0f;
+    float mAnimatorDurationScaleSetting = 1.0f;
+    boolean mAnimationsDisabled = false;
 
     final InputManagerService mInputManager;
     final DisplayManagerInternal mDisplayManagerInternal;
@@ -777,6 +782,19 @@
         mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
         mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
         mPowerManagerInternal.setPolicy(mPolicy); // TODO: register as local service instead
+        mPowerManagerInternal.registerLowPowerModeObserver(
+                new PowerManagerInternal.LowPowerModeListener() {
+            @Override
+            public void onLowPowerModeChanged(boolean enabled) {
+                synchronized (mWindowMap) {
+                    if (mAnimationsDisabled != enabled) {
+                        mAnimationsDisabled = enabled;
+                        dispatchNewAnimatorScaleLocked(null);
+                    }
+                }
+            }
+        });
+        mAnimationsDisabled = mPowerManagerInternal.getLowPowerModeEnabled();
         mScreenFrozenLock = mPowerManager.newWakeLock(
                 PowerManager.PARTIAL_WAKE_LOCK, "SCREEN_FROZEN");
         mScreenFrozenLock.setReferenceCounted(false);
@@ -796,12 +814,12 @@
         );
 
         // Get persisted window scale setting
-        mWindowAnimationScale = Settings.Global.getFloat(context.getContentResolver(),
-                Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
-        mTransitionAnimationScale = Settings.Global.getFloat(context.getContentResolver(),
-                Settings.Global.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
+        mWindowAnimationScaleSetting = Settings.Global.getFloat(context.getContentResolver(),
+                Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScaleSetting);
+        mTransitionAnimationScaleSetting = Settings.Global.getFloat(context.getContentResolver(),
+                Settings.Global.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScaleSetting);
         setAnimatorDurationScale(Settings.Global.getFloat(context.getContentResolver(),
-                Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScale));
+                Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScaleSetting));
 
         // Track changes to DevicePolicyManager state so we can enable/disable keyguard.
         IntentFilter filter = new IntentFilter();
@@ -814,6 +832,7 @@
 
         mAnimator = new WindowAnimator(this);
 
+        LocalServices.addService(WindowManagerInternal.class, new LocalService());
         initPolicy();
 
         // Add ourself to the Watchdog monitors.
@@ -828,7 +847,6 @@
             SurfaceControl.closeTransaction();
         }
 
-        LocalServices.addService(WindowManagerInternal.class, new LocalService());
         showCircularDisplayMaskIfNeeded();
     }
 
@@ -5185,9 +5203,9 @@
 
         scale = fixScale(scale);
         switch (which) {
-            case 0: mWindowAnimationScale = scale; break;
-            case 1: mTransitionAnimationScale = scale; break;
-            case 2: mAnimatorDurationScale = scale; break;
+            case 0: mWindowAnimationScaleSetting = scale; break;
+            case 1: mTransitionAnimationScaleSetting = scale; break;
+            case 2: mAnimatorDurationScaleSetting = scale; break;
         }
 
         // Persist setting
@@ -5203,13 +5221,14 @@
 
         if (scales != null) {
             if (scales.length >= 1) {
-                mWindowAnimationScale = fixScale(scales[0]);
+                mWindowAnimationScaleSetting = fixScale(scales[0]);
             }
             if (scales.length >= 2) {
-                mTransitionAnimationScale = fixScale(scales[1]);
+                mTransitionAnimationScaleSetting = fixScale(scales[1]);
             }
             if (scales.length >= 3) {
-                setAnimatorDurationScale(fixScale(scales[2]));
+                mAnimatorDurationScaleSetting = fixScale(scales[2]);
+                dispatchNewAnimatorScaleLocked(null);
             }
         }
 
@@ -5218,24 +5237,43 @@
     }
 
     private void setAnimatorDurationScale(float scale) {
-        mAnimatorDurationScale = scale;
+        mAnimatorDurationScaleSetting = scale;
         ValueAnimator.setDurationScale(scale);
     }
 
+    public float getWindowAnimationScaleLocked() {
+        return mAnimationsDisabled ? 0 : mWindowAnimationScaleSetting;
+    }
+
+    public float getTransitionAnimationScaleLocked() {
+        return mAnimationsDisabled ? 0 : mTransitionAnimationScaleSetting;
+    }
+
     @Override
     public float getAnimationScale(int which) {
         switch (which) {
-            case 0: return mWindowAnimationScale;
-            case 1: return mTransitionAnimationScale;
-            case 2: return mAnimatorDurationScale;
+            case 0: return mWindowAnimationScaleSetting;
+            case 1: return mTransitionAnimationScaleSetting;
+            case 2: return mAnimatorDurationScaleSetting;
         }
         return 0;
     }
 
     @Override
     public float[] getAnimationScales() {
-        return new float[] { mWindowAnimationScale, mTransitionAnimationScale,
-                mAnimatorDurationScale };
+        return new float[] { mWindowAnimationScaleSetting, mTransitionAnimationScaleSetting,
+                mAnimatorDurationScaleSetting };
+    }
+
+    @Override
+    public float getCurrentAnimatorScale() {
+        synchronized(mWindowMap) {
+            return mAnimationsDisabled ? 0 : mAnimatorDurationScaleSetting;
+        }
+    }
+
+    void dispatchNewAnimatorScaleLocked(Session session) {
+        mH.obtainMessage(H.NEW_ANIMATOR_SCALE, session).sendToTarget();
     }
 
     @Override
@@ -6093,7 +6131,7 @@
                     && screenRotationAnimation.hasScreenshot()) {
                 if (screenRotationAnimation.setRotationInTransaction(
                         rotation, mFxSession,
-                        MAX_ANIMATION_DURATION, mTransitionAnimationScale,
+                        MAX_ANIMATION_DURATION, getTransitionAnimationScaleLocked(),
                         displayInfo.logicalWidth, displayInfo.logicalHeight)) {
                     scheduleAnimationLocked();
                 }
@@ -7176,6 +7214,9 @@
         public static final int NOTIFY_ACTIVITY_DRAWN = 32;
 
         public static final int SHOW_DISPLAY_MASK = 33;
+        public static final int ALL_WINDOWS_DRAWN = 34;
+
+        public static final int NEW_ANIMATOR_SCALE = 35;
 
         @Override
         public void handleMessage(Message msg) {
@@ -7427,11 +7468,12 @@
 
                 case PERSIST_ANIMATION_SCALE: {
                     Settings.Global.putFloat(mContext.getContentResolver(),
-                            Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
+                            Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScaleSetting);
                     Settings.Global.putFloat(mContext.getContentResolver(),
-                            Settings.Global.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
+                            Settings.Global.TRANSITION_ANIMATION_SCALE,
+                            mTransitionAnimationScaleSetting);
                     Settings.Global.putFloat(mContext.getContentResolver(),
-                            Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScale);
+                            Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScaleSetting);
                     break;
                 }
 
@@ -7552,17 +7594,18 @@
                 }
 
                 case WAITING_FOR_DRAWN_TIMEOUT: {
-                    Pair<WindowState, IRemoteCallback> pair;
+                    IRemoteCallback callback = null;
                     synchronized (mWindowMap) {
-                        pair = (Pair<WindowState, IRemoteCallback>)msg.obj;
-                        Slog.w(TAG, "Timeout waiting for drawn: " + pair.first);
-                        if (!mWaitingForDrawn.remove(pair)) {
-                            return;
-                        }
+                        Slog.w(TAG, "Timeout waiting for drawn: undrawn=" + mWaitingForDrawn);
+                        mWaitingForDrawn.clear();
+                        callback = mWaitingForDrawnCallback;
+                        mWaitingForDrawnCallback = null;
                     }
-                    try {
-                        pair.second.sendResult(null);
-                    } catch (RemoteException e) {
+                    if (callback != null) {
+                        try {
+                            callback.sendResult(null);
+                        } catch (RemoteException e) {
+                        }
                     }
                     break;
                 }
@@ -7620,6 +7663,46 @@
                     } catch (RemoteException e) {
                     }
                     break;
+                case ALL_WINDOWS_DRAWN: {
+                    IRemoteCallback callback;
+                    synchronized (mWindowMap) {
+                        callback = mWaitingForDrawnCallback;
+                        mWaitingForDrawnCallback = null;
+                    }
+                    if (callback != null) {
+                        try {
+                            callback.sendResult(null);
+                        } catch (RemoteException e) {
+                        }
+                    }
+                }
+                case NEW_ANIMATOR_SCALE: {
+                    float scale = getCurrentAnimatorScale();
+                    ValueAnimator.setDurationScale(scale);
+                    Session session = (Session)msg.obj;
+                    if (session != null) {
+                        try {
+                            session.mCallback.onAnimatorScaleChanged(scale);
+                        } catch (RemoteException e) {
+                        }
+                    } else {
+                        ArrayList<IWindowSessionCallback> callbacks
+                                = new ArrayList<IWindowSessionCallback>();
+                        synchronized (mWindowMap) {
+                            for (int i=0; i<mSessions.size(); i++) {
+                                callbacks.add(mSessions.valueAt(i).mCallback);
+                            }
+
+                        }
+                        for (int i=0; i<callbacks.size(); i++) {
+                            try {
+                                callbacks.get(i).onAnimatorScaleChanged(scale);
+                            } catch (RemoteException e) {
+                            }
+                        }
+                    }
+                }
+                break;
             }
             if (DEBUG_WINDOW_TRACE) {
                 Slog.v(TAG, "handleMessage: exit");
@@ -7632,11 +7715,11 @@
     // -------------------------------------------------------------
 
     @Override
-    public IWindowSession openSession(IInputMethodClient client,
+    public IWindowSession openSession(IWindowSessionCallback callback, IInputMethodClient client,
             IInputContext inputContext) {
         if (client == null) throw new IllegalArgumentException("null client");
         if (inputContext == null) throw new IllegalArgumentException("null inputContext");
-        Session session = new Session(this, client, inputContext);
+        Session session = new Session(this, callback, client, inputContext);
         return session;
     }
 
@@ -8746,7 +8829,7 @@
                             displayInfo.appWidth, displayInfo.appHeight, transit);
                     appAnimator.thumbnailAnimation = anim;
                     anim.restrictDuration(MAX_ANIMATION_DURATION);
-                    anim.scaleCurrentDuration(mTransitionAnimationScale);
+                    anim.scaleCurrentDuration(getTransitionAnimationScaleLocked());
                     Point p = new Point();
                     mAppTransition.getStartingPoint(p);
                     appAnimator.thumbnailX = p.x;
@@ -9558,53 +9641,30 @@
     }
 
     void checkDrawnWindowsLocked() {
-        if (mWaitingForDrawn.size() > 0) {
-            for (int j=mWaitingForDrawn.size()-1; j>=0; j--) {
-                Pair<WindowState, IRemoteCallback> pair = mWaitingForDrawn.get(j);
-                WindowState win = pair.first;
-                //Slog.i(TAG, "Waiting for drawn " + win + ": removed="
-                //        + win.mRemoved + " visible=" + win.isVisibleLw()
-                //        + " shown=" + win.mSurfaceShown);
-                if (win.mRemoved) {
-                    // Window has been removed; no draw will now happen, so stop waiting.
-                    Slog.w(TAG, "Aborted waiting for drawn: " + pair.first);
-                    try {
-                        pair.second.sendResult(null);
-                    } catch (RemoteException e) {
-                    }
-                    mWaitingForDrawn.remove(pair);
-                    mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
-                } else if (win.mWinAnimator.mSurfaceShown) {
-                    // Window is now drawn (and shown).
-                    try {
-                        pair.second.sendResult(null);
-                    } catch (RemoteException e) {
-                    }
-                    mWaitingForDrawn.remove(pair);
-                    mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
-                }
+        if (mWaitingForDrawn.isEmpty() || mWaitingForDrawnCallback == null) {
+            return;
+        }
+        for (int j = mWaitingForDrawn.size() - 1; j >= 0; j--) {
+            WindowState win = mWaitingForDrawn.get(j);
+            if (DEBUG_SCREEN_ON) Slog.i(TAG, "Waiting for drawn " + win +
+                    ": removed=" + win.mRemoved + " visible=" + win.isVisibleLw() +
+                    " mHasSurface=" + win.mHasSurface +
+                    " drawState=" + win.mWinAnimator.mDrawState);
+            if (win.mRemoved || !win.mHasSurface) {
+                // Window has been removed; no draw will now happen, so stop waiting.
+                if (DEBUG_SCREEN_ON) Slog.w(TAG, "Aborted waiting for drawn: " + win);
+                mWaitingForDrawn.remove(win);
+            } else if (win.hasDrawnLw()) {
+                // Window is now drawn (and shown).
+                if (DEBUG_SCREEN_ON) Slog.d(TAG, "Window drawn win=" + win);
+                mWaitingForDrawn.remove(win);
             }
         }
-    }
-
-    @Override
-    public boolean waitForWindowDrawn(IBinder token, IRemoteCallback callback) {
-        if (token != null && callback != null) {
-            synchronized (mWindowMap) {
-                WindowState win = windowForClientLocked(null, token, true);
-                if (win != null) {
-                    Pair<WindowState, IRemoteCallback> pair =
-                            new Pair<WindowState, IRemoteCallback>(win, callback);
-                    Message m = mH.obtainMessage(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
-                    mH.sendMessageDelayed(m, 2000);
-                    mWaitingForDrawn.add(pair);
-                    checkDrawnWindowsLocked();
-                    return true;
-                }
-                Slog.i(TAG, "waitForWindowDrawn: win null");
-            }
+        if (mWaitingForDrawn.isEmpty()) {
+            if (DEBUG_SCREEN_ON) Slog.d(TAG, "All windows drawn!");
+            mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT);
+            mH.sendEmptyMessage(H.ALL_WINDOWS_DRAWN);
         }
-        return false;
     }
 
     void setHoldScreenLocked(final Session newHoldScreen) {
@@ -10077,7 +10137,7 @@
                 mExitAnimId = mEnterAnimId = 0;
             }
             if (screenRotationAnimation.dismiss(mFxSession, MAX_ANIMATION_DURATION,
-                    mTransitionAnimationScale, displayInfo.logicalWidth,
+                    getTransitionAnimationScaleLocked(), displayInfo.logicalWidth,
                         displayInfo.logicalHeight, mExitAnimId, mEnterAnimId)) {
                 scheduleAnimationLocked();
             } else {
@@ -10412,13 +10472,10 @@
 
     void dumpSessionsLocked(PrintWriter pw, boolean dumpAll) {
         pw.println("WINDOW MANAGER SESSIONS (dumpsys window sessions)");
-        if (mSessions.size() > 0) {
-            Iterator<Session> it = mSessions.iterator();
-            while (it.hasNext()) {
-                Session s = it.next();
-                pw.print("  Session "); pw.print(s); pw.println(':');
-                s.dump(pw, "    ");
-            }
+        for (int i=0; i<mSessions.size(); i++) {
+            Session s = mSessions.valueAt(i);
+            pw.print("  Session "); pw.print(s); pw.println(':');
+            s.dump(pw, "    ");
         }
     }
 
@@ -10552,9 +10609,8 @@
             pw.println();
             pw.println("  Clients waiting for these windows to be drawn:");
             for (int i=mWaitingForDrawn.size()-1; i>=0; i--) {
-                Pair<WindowState, IRemoteCallback> pair = mWaitingForDrawn.get(i);
-                pw.print("  Waiting #"); pw.print(i); pw.print(' '); pw.print(pair.first);
-                        pw.print(": "); pw.println(pair.second);
+                WindowState win = mWaitingForDrawn.get(i);
+                pw.print("  Waiting #"); pw.print(i); pw.print(' '); pw.print(win);
             }
         }
         pw.println();
@@ -10623,9 +10679,10 @@
             pw.print("  mLastWindowForcedOrientation="); pw.print(mLastWindowForcedOrientation);
                     pw.print(" mForcedAppOrientation="); pw.println(mForcedAppOrientation);
             pw.print("  mDeferredRotationPauseCount="); pw.println(mDeferredRotationPauseCount);
-            pw.print("  mWindowAnimationScale="); pw.print(mWindowAnimationScale);
-                    pw.print(" mTransitionWindowAnimationScale="); pw.print(mTransitionAnimationScale);
-                    pw.print(" mAnimatorDurationScale="); pw.println(mAnimatorDurationScale);
+            pw.print("  Animation settings: disabled="); pw.print(mAnimationsDisabled);
+                    pw.print(" window="); pw.print(mWindowAnimationScaleSetting);
+                    pw.print(" transition="); pw.print(mTransitionAnimationScaleSetting);
+                    pw.print(" animator="); pw.println(mAnimatorDurationScaleSetting);
             pw.print("  mTraversalScheduled="); pw.println(mTraversalScheduled);
             pw.print("  mStartingIconInTransition="); pw.print(mStartingIconInTransition);
                     pw.print(" mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
@@ -11064,7 +11121,7 @@
                 }
                 mAccessibilityController.setMagnificationCallbacksLocked(callbacks);
                 if (!mAccessibilityController.hasCallbacksLocked()) {
-                     mAccessibilityController = null;
+                    mAccessibilityController = null;
                 }
             }
         }
@@ -11078,7 +11135,7 @@
                 }
                 mAccessibilityController.setWindowsForAccessibilityCallback(callback);
                 if (!mAccessibilityController.hasCallbacksLocked()) {
-                     mAccessibilityController = null;
+                    mAccessibilityController = null;
                 }
             }
         }
@@ -11115,5 +11172,25 @@
                 }
             }
         }
+
+        public void waitForAllWindowsDrawn(IRemoteCallback callback, long timeout) {
+            synchronized (mWindowMap) {
+                mWaitingForDrawnCallback = callback;
+                final WindowList windows = getDefaultWindowListLocked();
+                for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
+                    final WindowState win = windows.get(winNdx);
+                    if (win.mHasSurface) {
+                        win.mWinAnimator.mDrawState = WindowStateAnimator.DRAW_PENDING;
+                        // Force add to mResizingWindows.
+                        win.mLastContentInsets.set(-1, -1, -1, -1);
+                        mWaitingForDrawn.add(win);
+                    }
+                }
+                requestTraversalLocked();
+                mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT);
+                mH.sendEmptyMessageDelayed(H.WAITING_FOR_DRAWN_TIMEOUT, timeout);
+            }
+            checkDrawnWindowsLocked();
+        }
     }
 }
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index e257ebc..bda10de 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -207,7 +207,7 @@
         mLocalAnimating = false;
         mAnimation = anim;
         mAnimation.restrictDuration(WindowManagerService.MAX_ANIMATION_DURATION);
-        mAnimation.scaleCurrentDuration(mService.mWindowAnimationScale);
+        mAnimation.scaleCurrentDuration(mService.getWindowAnimationScaleLocked());
         // Start out animation gone if window is gone, or visible if window is visible.
         mTransformation.clear();
         mTransformation.setAlpha(mLastHidden ? 0 : 1);
@@ -283,7 +283,7 @@
                         " @ " + currentTime + ": ww=" + mWin.mFrame.width() +
                         " wh=" + mWin.mFrame.height() +
                         " dw=" + mAnimDw + " dh=" + mAnimDh +
-                        " scale=" + mService.mWindowAnimationScale);
+                        " scale=" + mService.getWindowAnimationScaleLocked());
                     mAnimation.initialize(mWin.mFrame.width(), mWin.mFrame.height(),
                             mAnimDw, mAnimDh);
                     final DisplayInfo displayInfo = displayContent.getDisplayInfo();
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 043fab4..8ca437f 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -51,6 +51,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.pm.UserInfo;
+import android.net.ConnectivityManager;
 import android.net.ProxyInfo;
 import android.os.Binder;
 import android.os.Bundle;
@@ -840,7 +841,7 @@
             mContext.sendOrderedBroadcastAsUser(intent, admin.getUserHandle(),
                     null, result, mHandler, Activity.RESULT_OK, null, null);
         } else {
-            mContext.sendBroadcastAsUser(intent, UserHandle.OWNER);
+            mContext.sendBroadcastAsUser(intent, admin.getUserHandle());
         }
     }
 
@@ -1227,6 +1228,7 @@
             loadSettingsLocked(getUserData(UserHandle.USER_OWNER), UserHandle.USER_OWNER);
             loadDeviceOwner();
         }
+        cleanUpOldUsers();
         mAppOpsService = IAppOpsService.Stub.asInterface(
                 ServiceManager.getService(Context.APP_OPS_SERVICE));
         if (mDeviceOwner != null) {
@@ -1247,6 +1249,32 @@
         }
     }
 
+    private void cleanUpOldUsers() {
+        // This is needed in case the broadcast {@link Intent.ACTION_USER_REMOVED} was not handled
+        // before reboot
+        Set<Integer> usersWithProfileOwners;
+        Set<Integer> usersWithData;
+        synchronized(this) {
+            usersWithProfileOwners = mDeviceOwner != null
+                    ? mDeviceOwner.getProfileOwnerKeys() : new HashSet<Integer>();
+            usersWithData = new HashSet<Integer>();
+            for (int i = 0; i < mUserData.size(); i++) {
+                usersWithData.add(mUserData.keyAt(i));
+            }
+        }
+        List<UserInfo> allUsers = mUserManager.getUsers();
+
+        Set<Integer> deletedUsers = new HashSet<Integer>();
+        deletedUsers.addAll(usersWithProfileOwners);
+        deletedUsers.addAll(usersWithData);
+        for (UserInfo userInfo : allUsers) {
+            deletedUsers.remove(userInfo.id);
+        }
+        for (Integer userId : deletedUsers) {
+            removeUserData(userId);
+        }
+    }
+
     private void handlePasswordExpirationNotification(int userHandle) {
         synchronized (this) {
             final long now = System.currentTimeMillis();
@@ -2695,6 +2723,20 @@
         return null;
     }
 
+    public void setRecommendedGlobalProxy(ComponentName who, ProxyInfo proxyInfo) {
+        synchronized (this) {
+            getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
+        }
+        long token = Binder.clearCallingIdentity();
+        try {
+            ConnectivityManager connectivityManager = (ConnectivityManager)
+                    mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+            connectivityManager.setGlobalProxy(proxyInfo);
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
     private void resetGlobalProxyLocked(DevicePolicyData policy) {
         final int N = policy.mAdminList.size();
         for (int i = 0; i < N; i++) {
@@ -3123,6 +3165,7 @@
                 intent.putExtra(Intent.EXTRA_USER, new UserHandle(UserHandle.getCallingUserId()));
                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY |
                         Intent.FLAG_RECEIVER_FOREGROUND);
+                // TODO This should send to parent of profile (which is always owner at the moment).
                 mContext.sendBroadcastAsUser(intent, UserHandle.OWNER);
             } finally {
                 restoreCallingIdentity(id);
diff --git a/services/print/java/com/android/server/print/RemotePrintService.java b/services/print/java/com/android/server/print/RemotePrintService.java
index 1bb61d2..a8c739c 100644
--- a/services/print/java/com/android/server/print/RemotePrintService.java
+++ b/services/print/java/com/android/server/print/RemotePrintService.java
@@ -121,15 +121,7 @@
         throwIfDestroyed();
 
         // Stop tracking printers.
-        if (mTrackedPrinterList != null) {
-            final int trackedPrinterCount = mTrackedPrinterList.size();
-            for (int i = 0; i < trackedPrinterCount; i++) {
-                PrinterId printerId = mTrackedPrinterList.get(i);
-                if (printerId.getServiceName().equals(mComponentName)) {
-                    handleStopPrinterStateTracking(printerId);
-                }
-            }
-        }
+        stopTrackingAllPrinters();
 
         // Stop printer discovery.
         if (mDiscoveryPriorityList != null) {
@@ -270,7 +262,7 @@
             try {
                 mPrintService.createPrinterDiscoverySession();
             } catch (RemoteException re) {
-                Slog.e(LOG_TAG, "Error creating printer dicovery session.", re);
+                Slog.e(LOG_TAG, "Error creating printer discovery session.", re);
             }
         }
     }
@@ -365,10 +357,14 @@
             if (DEBUG) {
                 Slog.i(LOG_TAG, "[user: " + mUserId + "] stopPrinterDiscovery()");
             }
+
+            // Stop tracking printers.
+            stopTrackingAllPrinters();
+
             try {
                 mPrintService.stopPrinterDiscovery();
             } catch (RemoteException re) {
-                Slog.e(LOG_TAG, "Error stopping printer dicovery.", re);
+                Slog.e(LOG_TAG, "Error stopping printer discovery.", re);
             }
         }
     }
@@ -466,6 +462,19 @@
         }
     }
 
+    private void stopTrackingAllPrinters() {
+        if (mTrackedPrinterList == null) {
+            return;
+        }
+        final int trackedPrinterCount = mTrackedPrinterList.size();
+        for (int i = trackedPrinterCount - 1; i >= 0; i--) {
+            PrinterId printerId = mTrackedPrinterList.get(i);
+            if (printerId.getServiceName().equals(mComponentName)) {
+                handleStopPrinterStateTracking(printerId);
+            }
+        }
+    }
+
     public void dump(PrintWriter pw, String prefix) {
         String tab = "  ";
         pw.append(prefix).append("service:").println();
diff --git a/services/print/java/com/android/server/print/RemotePrintSpooler.java b/services/print/java/com/android/server/print/RemotePrintSpooler.java
index ffe9806..9496cae 100644
--- a/services/print/java/com/android/server/print/RemotePrintSpooler.java
+++ b/services/print/java/com/android/server/print/RemotePrintSpooler.java
@@ -44,7 +44,7 @@
 
 /**
  * This represents the remote print spooler as a local object to the
- * PrintManagerSerivce. It is responsible to connecting to the remote
+ * PrintManagerService. It is responsible to connecting to the remote
  * spooler if needed, to make the timed remote calls, to handle
  * remote exceptions, and to bind/unbind to the remote instance as
  * needed.
@@ -99,7 +99,7 @@
         mClient = new PrintSpoolerClient(this);
         mIntent = new Intent();
         mIntent.setComponent(new ComponentName("com.android.printspooler",
-                "com.android.printspooler.PrintSpoolerService"));
+                "com.android.printspooler.model.PrintSpoolerService"));
     }
 
     public final List<PrintJobInfo> getPrintJobInfos(ComponentName componentName, int state,
diff --git a/services/tests/servicestests/src/com/android/server/task/TaskStoreTest.java b/services/tests/servicestests/src/com/android/server/task/TaskStoreTest.java
new file mode 100644
index 0000000..e7f9ca0
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/task/TaskStoreTest.java
@@ -0,0 +1,199 @@
+package com.android.server.task;
+
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.app.task.Task;
+import android.app.task.Task.Builder;
+import android.os.PersistableBundle;
+import android.test.AndroidTestCase;
+import android.test.RenamingDelegatingContext;
+import android.util.Log;
+
+import com.android.server.task.controllers.TaskStatus;
+
+import java.util.List;
+
+import static com.android.server.task.TaskStore.initAndGet;
+/**
+ * Test reading and writing correctly from file.
+ */
+public class TaskStoreTest extends AndroidTestCase {
+    private static final String TAG = "TaskStoreTest";
+    private static final String TEST_PREFIX = "_test_";
+    // private static final int USER_NON_0 = 3;
+    private static final int SOME_UID = 34234;
+    private ComponentName mComponent;
+    private static final long IO_WAIT = 600L;
+
+    TaskStore mTaskStoreUnderTest;
+    Context mTestContext;
+    TaskMapReadFinishedListener mTaskMapReadFinishedListenerStub =
+            new TaskMapReadFinishedListener() {
+        @Override
+        public void onTaskMapReadFinished(List<TaskStatus> tasks) {
+            // do nothing.
+        }
+    };
+
+    @Override
+    public void setUp() throws Exception {
+        mTestContext = new RenamingDelegatingContext(getContext(), TEST_PREFIX);
+        Log.d(TAG, "Saving tasks to '" + mTestContext.getFilesDir() + "'");
+        mTaskStoreUnderTest = TaskStore.initAndGetForTesting(mTestContext,
+                mTestContext.getFilesDir(), mTaskMapReadFinishedListenerStub);
+        mComponent = new ComponentName(getContext().getPackageName(), StubClass.class.getName());
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        mTaskStoreUnderTest.clear();
+    }
+
+    public void testMaybeWriteStatusToDisk() throws Exception {
+        int taskId = 5;
+        long runByMillis = 20000L; // 20s
+        long runFromMillis = 2000L; // 2s
+        long initialBackoff = 10000L; // 10s
+
+        final Task task = new Builder(taskId, mComponent)
+                .setRequiresCharging(true)
+                .setRequiredNetworkCapabilities(Task.NetworkType.ANY)
+                .setBackoffCriteria(initialBackoff, Task.BackoffPolicy.EXPONENTIAL)
+                .setOverrideDeadline(runByMillis)
+                .setMinimumLatency(runFromMillis)
+                .build();
+        final TaskStatus ts = new TaskStatus(task, SOME_UID, true /* persisted */);
+        mTaskStoreUnderTest.add(ts);
+        Thread.sleep(IO_WAIT);
+        // Manually load tasks from xml file.
+        mTaskStoreUnderTest.readTaskMapFromDisk(new TaskMapReadFinishedListener() {
+            @Override
+            public void onTaskMapReadFinished(List<TaskStatus> tasks) {
+                assertEquals("Didn't get expected number of persisted tasks.", 1, tasks.size());
+                TaskStatus loadedTaskStatus = tasks.get(0);
+                assertTasksEqual(task, loadedTaskStatus.getTask());
+                assertEquals("Different uids.", SOME_UID, tasks.get(0).getUid());
+                compareTimestampsSubjectToIoLatency("Early run-times not the same after read.",
+                        ts.getEarliestRunTime(), loadedTaskStatus.getEarliestRunTime());
+                compareTimestampsSubjectToIoLatency("Late run-times not the same after read.",
+                        ts.getLatestRunTimeElapsed(), loadedTaskStatus.getLatestRunTimeElapsed());
+            }
+        });
+
+    }
+
+    public void testWritingTwoFilesToDisk() throws Exception {
+        final Task task1 = new Builder(8, mComponent)
+                .setRequiresDeviceIdle(true)
+                .setPeriodic(10000L)
+                .setRequiresCharging(true)
+                .build();
+        final Task task2 = new Builder(12, mComponent)
+                .setMinimumLatency(5000L)
+                .setBackoffCriteria(15000L, Task.BackoffPolicy.LINEAR)
+                .setOverrideDeadline(30000L)
+                .setRequiredNetworkCapabilities(Task.NetworkType.UNMETERED)
+                .build();
+        final TaskStatus taskStatus1 = new TaskStatus(task1, SOME_UID, true /* persisted */);
+        final TaskStatus taskStatus2 = new TaskStatus(task2, SOME_UID, true /* persisted */);
+        mTaskStoreUnderTest.add(taskStatus1);
+        mTaskStoreUnderTest.add(taskStatus2);
+        Thread.sleep(IO_WAIT);
+        mTaskStoreUnderTest.readTaskMapFromDisk(new TaskMapReadFinishedListener() {
+            @Override
+            public void onTaskMapReadFinished(List<TaskStatus> tasks) {
+                assertEquals("Incorrect # of persisted tasks.", 2, tasks.size());
+                TaskStatus loaded1 = tasks.get(0);
+                TaskStatus loaded2 = tasks.get(1);
+                assertTasksEqual(task1, loaded1.getTask());
+                assertTasksEqual(task2, loaded2.getTask());
+
+                // Check that the loaded task has the correct runtimes.
+                compareTimestampsSubjectToIoLatency("Early run-times not the same after read.",
+                        taskStatus1.getEarliestRunTime(), loaded1.getEarliestRunTime());
+                compareTimestampsSubjectToIoLatency("Late run-times not the same after read.",
+                        taskStatus1.getLatestRunTimeElapsed(), loaded1.getLatestRunTimeElapsed());
+                compareTimestampsSubjectToIoLatency("Early run-times not the same after read.",
+                        taskStatus2.getEarliestRunTime(), loaded2.getEarliestRunTime());
+                compareTimestampsSubjectToIoLatency("Late run-times not the same after read.",
+                        taskStatus2.getLatestRunTimeElapsed(), loaded2.getLatestRunTimeElapsed());
+            }
+        });
+
+    }
+
+    public void testWritingTaskWithExtras() throws Exception {
+        Task.Builder b = new Builder(8, mComponent)
+                .setRequiresDeviceIdle(true)
+                .setPeriodic(10000L)
+                .setRequiresCharging(true);
+
+        PersistableBundle extras = new PersistableBundle();
+        extras.putDouble("hello", 3.2);
+        extras.putString("hi", "there");
+        extras.putInt("into", 3);
+        b.setExtras(extras);
+        final Task task = b.build();
+        TaskStatus taskStatus = new TaskStatus(task, SOME_UID, true /* persisted */);
+
+        mTaskStoreUnderTest.add(taskStatus);
+        Thread.sleep(IO_WAIT);
+        mTaskStoreUnderTest.readTaskMapFromDisk(new TaskMapReadFinishedListener() {
+            @Override
+            public void onTaskMapReadFinished(List<TaskStatus> tasks) {
+                assertEquals("Incorrect # of persisted tasks.", 1, tasks.size());
+                TaskStatus loaded = tasks.get(0);
+                assertTasksEqual(task, loaded.getTask());
+            }
+        });
+
+    }
+
+    /**
+     * Helper function to throw an error if the provided task and TaskStatus objects are not equal.
+     */
+    private void assertTasksEqual(Task first, Task second) {
+        assertEquals("Different task ids.", first.getId(), second.getId());
+        assertEquals("Different components.", first.getService(), second.getService());
+        assertEquals("Different periodic status.", first.isPeriodic(), second.isPeriodic());
+        assertEquals("Different period.", first.getIntervalMillis(), second.getIntervalMillis());
+        assertEquals("Different inital backoff.", first.getInitialBackoffMillis(),
+                second.getInitialBackoffMillis());
+        assertEquals("Different backoff policy.", first.getBackoffPolicy(),
+                second.getBackoffPolicy());
+
+        assertEquals("Invalid charging constraint.", first.isRequireCharging(),
+                second.isRequireCharging());
+        assertEquals("Invalid idle constraint.", first.isRequireDeviceIdle(),
+                second.isRequireDeviceIdle());
+        assertEquals("Invalid unmetered constraint.",
+                first.getNetworkCapabilities() == Task.NetworkType.UNMETERED,
+                second.getNetworkCapabilities() == Task.NetworkType.UNMETERED);
+        assertEquals("Invalid connectivity constraint.",
+                first.getNetworkCapabilities() == Task.NetworkType.ANY,
+                second.getNetworkCapabilities() == Task.NetworkType.ANY);
+        assertEquals("Invalid deadline constraint.",
+                first.hasLateConstraint(),
+                second.hasLateConstraint());
+        assertEquals("Invalid delay constraint.",
+                first.hasEarlyConstraint(),
+                second.hasEarlyConstraint());
+        assertEquals("Extras don't match",
+                first.getExtras().toString(), second.getExtras().toString());
+    }
+
+    /**
+     * When comparing timestamps before and after DB read/writes (to make sure we're saving/loading
+     * the correct values), there is some latency involved that terrorises a naive assertEquals().
+     * We define a <code>DELTA_MILLIS</code> as a function variable here to make this comparision
+     * more reasonable.
+     */
+    private void compareTimestampsSubjectToIoLatency(String error, long ts1, long ts2) {
+        final long DELTA_MILLIS = 700L;  // We allow up to 700ms of latency for IO read/writes.
+        assertTrue(error, Math.abs(ts1 - ts2) < DELTA_MILLIS + IO_WAIT);
+    }
+
+    private static class StubClass {}
+
+}
\ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/task/controllers/BatteryControllerTest.java b/services/tests/servicestests/src/com/android/server/task/controllers/BatteryControllerTest.java
new file mode 100644
index 0000000..e617caf
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/task/controllers/BatteryControllerTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.task.controllers;
+
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.test.AndroidTestCase;
+
+import com.android.server.task.StateChangedListener;
+
+import static com.android.server.task.controllers.BatteryController.getForTesting;
+
+import static org.mockito.Mockito.*;
+
+/**
+ *
+ */
+public class BatteryControllerTest extends AndroidTestCase {
+    BatteryController mBatteryControllerUnderTest;
+
+    StateChangedListener mStateChangedListenerStub = new StateChangedListener() {
+        @Override
+        public void onControllerStateChanged() {
+
+        }
+
+        @Override
+        public void onTaskDeadlineExpired(TaskStatus taskStatus) {
+
+        }
+    };
+    BatteryController.ChargingTracker mTrackerUnderTest;
+
+    public void setUp() throws Exception {
+        mBatteryControllerUnderTest = getForTesting(mStateChangedListenerStub, getTestContext());
+        mTrackerUnderTest = mBatteryControllerUnderTest.getTracker();
+    }
+
+    public void testSendBatteryChargingIntent() throws Exception {
+        Intent batteryConnectedIntent = new Intent(Intent.ACTION_POWER_CONNECTED)
+                .setComponent(new ComponentName(getContext(), mTrackerUnderTest.getClass()));
+        Intent batteryHealthyIntent = new Intent(Intent.ACTION_BATTERY_OKAY)
+                .setComponent(new ComponentName(getContext(), mTrackerUnderTest.getClass()));
+
+        mTrackerUnderTest.onReceiveInternal(batteryConnectedIntent);
+        mTrackerUnderTest.onReceiveInternal(batteryHealthyIntent);
+
+        assertTrue(mTrackerUnderTest.isOnStablePower());
+    }
+
+}
diff --git a/services/usb/java/com/android/server/usb/UsbDebuggingManager.java b/services/usb/java/com/android/server/usb/UsbDebuggingManager.java
index 0946c5a..cc5d004 100644
--- a/services/usb/java/com/android/server/usb/UsbDebuggingManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDebuggingManager.java
@@ -84,7 +84,6 @@
             while (true) {
                 int count = inputStream.read(buffer);
                 if (count < 0) {
-                    Slog.e(TAG, "got " + count + " reading");
                     break;
                 }
 
@@ -100,9 +99,6 @@
                     break;
                 }
             }
-        } catch (IOException ex) {
-            Slog.e(TAG, "Communication error: ", ex);
-            throw ex;
         } finally {
             closeSocket();
         }
diff --git a/telecomm/java/android/telecomm/CallService.java b/telecomm/java/android/telecomm/CallService.java
index d452172..a254459 100644
--- a/telecomm/java/android/telecomm/CallService.java
+++ b/telecomm/java/android/telecomm/CallService.java
@@ -63,6 +63,7 @@
     private static final int MSG_STOP_DTMF_TONE = 13;
     private static final int MSG_ADD_TO_CONFERENCE = 14;
     private static final int MSG_SPLIT_FROM_CONFERENCE = 15;
+    private static final int MSG_ON_POST_DIAL_CONTINUE = 16;
 
     /**
      * Default Handler used to consolidate binder method calls onto a single thread.
@@ -150,6 +151,17 @@
                     }
                     break;
                 }
+                case MSG_ON_POST_DIAL_CONTINUE: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        String callId = (String) args.arg1;
+                        boolean proceed = (args.argi1 == 1);
+                        onPostDialContinue(callId, proceed);
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
                 default:
                     break;
             }
@@ -247,6 +259,14 @@
             args.arg2 = callId;
             mMessageHandler.obtainMessage(MSG_SPLIT_FROM_CONFERENCE, args).sendToTarget();
         }
+
+        @Override
+        public void onPostDialContinue(String callId, boolean proceed) {
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = callId;
+            args.argi1 = proceed ? 1 : 0;
+            mMessageHandler.obtainMessage(MSG_ON_POST_DIAL_CONTINUE, args).sendToTarget();
+        }
     }
 
     /**
@@ -422,4 +442,7 @@
      * @hide
      */
     public abstract void splitFromConference(String conferenceCallId, String callId);
+
+    public void onPostDialContinue(String callId, boolean proceed) {}
+    public void onPostDialWait(Connection conn, String remaining) {}
 }
diff --git a/telecomm/java/android/telecomm/CallServiceAdapter.java b/telecomm/java/android/telecomm/CallServiceAdapter.java
index 7396808..fb5c871 100644
--- a/telecomm/java/android/telecomm/CallServiceAdapter.java
+++ b/telecomm/java/android/telecomm/CallServiceAdapter.java
@@ -84,12 +84,16 @@
     /**
      * Tells Telecomm that an attempt to place the specified outgoing call failed.
      *
-     * @param callId The ID of the outgoing call.
-     * @param errorMessage The error associated with the failed call attempt.
+     * @param request The originating request for a connection.
+     * @param errorCode The error code associated with the failed call attempt.
+     * @param errorMsg The error message associated with the failed call attempt.
      */
-    public void handleFailedOutgoingCall(String callId, String errorMessage) {
+    public void handleFailedOutgoingCall(
+            ConnectionRequest request,
+            int errorCode,
+            String errorMsg) {
         try {
-            mAdapter.handleFailedOutgoingCall(callId, errorMessage);
+            mAdapter.handleFailedOutgoingCall(request, errorCode, errorMsg);
         } catch (RemoteException e) {
         }
     }
@@ -213,4 +217,11 @@
         } catch (RemoteException ignored) {
         }
     }
+
+    public void onPostDialWait(String callId, String remaining) {
+        try {
+            mAdapter.onPostDialWait(callId, remaining);
+        } catch (RemoteException ignored) {
+        }
+    }
 }
diff --git a/telecomm/java/android/telecomm/Connection.java b/telecomm/java/android/telecomm/Connection.java
index 8cce8e6..344814f 100644
--- a/telecomm/java/android/telecomm/Connection.java
+++ b/telecomm/java/android/telecomm/Connection.java
@@ -444,6 +444,11 @@
      */
     protected void onReject() {}
 
+    /**
+     * Notifies this Connection whether the user wishes to proceed with the post-dial DTMF codes.
+     */
+    protected void onPostDialContinue(boolean proceed) {}
+
     private void setState(int state) {
         Log.d(this, "setState: %s", stateToString(state));
         onSetState(state);
diff --git a/telecomm/java/android/telecomm/ConnectionRequest.aidl b/telecomm/java/android/telecomm/ConnectionRequest.aidl
new file mode 100644
index 0000000..72e5c8c
--- /dev/null
+++ b/telecomm/java/android/telecomm/ConnectionRequest.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 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.telecomm;
+
+parcelable ConnectionRequest;
diff --git a/telecomm/java/android/telecomm/ConnectionRequest.java b/telecomm/java/android/telecomm/ConnectionRequest.java
index c1f1871..bf5727b 100644
--- a/telecomm/java/android/telecomm/ConnectionRequest.java
+++ b/telecomm/java/android/telecomm/ConnectionRequest.java
@@ -18,23 +18,37 @@
 
 import android.os.Bundle;
 import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
 
 /**
  * Simple data container encapsulating a request to some entity to
  * create a new {@link Connection}.
  */
-public final class ConnectionRequest {
+public final class ConnectionRequest implements Parcelable {
 
     // TODO: Token to limit recursive invocations
     // TODO: Consider upgrading "mHandle" to ordered list of handles, indicating a set of phone
     //         numbers that would satisfy the client's needs, in order of preference
+    private final String mCallId;
     private final Uri mHandle;
     private final Bundle mExtras;
 
     public ConnectionRequest(Uri handle, Bundle extras) {
-        mHandle = handle; mExtras = extras;
+        this(null, handle, extras);
     }
 
+    public ConnectionRequest(String callId, Uri handle, Bundle extras) {
+        mCallId = callId;
+        mHandle = handle;
+        mExtras = extras;
+    }
+
+    /**
+     * An identifier for this call.
+     */
+    public String getCallId() { return mCallId; }
+
     /**
      * The handle (e.g., phone number) to which the {@link Connection} is to connect.
      */
@@ -54,4 +68,40 @@
                         : ConnectionService.toLogSafePhoneNumber(mHandle.toString()),
                 mExtras == null ? "" : mExtras);
     }
-}
+
+    /**
+     * Responsible for creating CallInfo objects for deserialized Parcels.
+     */
+    public static final Parcelable.Creator<ConnectionRequest> CREATOR =
+            new Parcelable.Creator<ConnectionRequest> () {
+                @Override
+                public ConnectionRequest createFromParcel(Parcel source) {
+                    String callId = source.readString();
+                    Uri handle = (Uri) source.readParcelable(getClass().getClassLoader());
+                    Bundle extras = (Bundle) source.readParcelable(getClass().getClassLoader());
+                    return new ConnectionRequest(callId, handle, extras);
+                }
+
+                @Override
+                public ConnectionRequest[] newArray(int size) {
+                    return new ConnectionRequest[size];
+                }
+            };
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /**
+     * Writes CallInfo object into a serializeable Parcel.
+     */
+    @Override
+    public void writeToParcel(Parcel destination, int flags) {
+        destination.writeString(mCallId);
+        destination.writeParcelable(mHandle, 0);
+        destination.writeParcelable(mExtras, 0);
+    }}
diff --git a/telecomm/java/android/telecomm/ConnectionService.java b/telecomm/java/android/telecomm/ConnectionService.java
index aeb1c33..59e977d 100644
--- a/telecomm/java/android/telecomm/ConnectionService.java
+++ b/telecomm/java/android/telecomm/ConnectionService.java
@@ -18,6 +18,7 @@
 
 import android.net.Uri;
 import android.os.Bundle;
+import android.telephony.DisconnectCause;
 
 import java.util.HashMap;
 import java.util.LinkedList;
@@ -115,9 +116,8 @@
                     }
 
                     @Override
-                    public void onError(Uri handle, String reason) {
-                        Log.w(this, "Error in onFindSubscriptions " + callInfo.getHandle()
-                                + " error: " + reason);
+                    public void onError(Uri handle, int code, String msg) {
+                        Log.w(this, "Error in onFindSubscriptions %s %d %s", handle, code, msg);
                         getAdapter().setIsCompatibleWith(callInfo.getId(), false);
                     }
                 }
@@ -129,6 +129,7 @@
         Log.d(this, "call %s", callInfo);
         onCreateConnections(
                 new ConnectionRequest(
+                        callInfo.getId(),
                         callInfo.getHandle(),
                         callInfo.getExtras()),
                 new Response<ConnectionRequest, Connection>() {
@@ -137,21 +138,23 @@
                         if (result.length != 1) {
                             Log.d(this, "adapter handleFailedOutgoingCall %s", callInfo);
                             getAdapter().handleFailedOutgoingCall(
-                                    callInfo.getId(),
+                                    request,
+                                    DisconnectCause.ERROR_UNSPECIFIED,
                                     "Created " + result.length + " Connections, expected 1");
                             for (Connection c : result) {
                                 c.abort();
                             }
                         } else {
                             addConnection(callInfo.getId(), result[0]);
-                            Log.d(this, "adapter handleSuccessfulOutgoingCall %s", callInfo.getId());
+                            Log.d(this, "adapter handleSuccessfulOutgoingCall %s",
+                                    callInfo.getId());
                             getAdapter().handleSuccessfulOutgoingCall(callInfo.getId());
                         }
                     }
 
                     @Override
-                    public void onError(ConnectionRequest request, String reason) {
-                        getAdapter().handleFailedOutgoingCall(callInfo.getId(), reason);
+                    public void onError(ConnectionRequest request, int code, String msg) {
+                        getAdapter().handleFailedOutgoingCall(request, code, msg);
                     }
                 }
         );
@@ -168,6 +171,7 @@
         Log.d(this, "setIncomingCallId %s %s", callId, extras);
         onCreateIncomingConnection(
                 new ConnectionRequest(
+                        callId,
                         null,  // TODO: Can we obtain this from "extras"?
                         extras),
                 new Response<ConnectionRequest, Connection>() {
@@ -176,7 +180,8 @@
                         if (result.length != 1) {
                             Log.d(this, "adapter handleFailedOutgoingCall %s", callId);
                             getAdapter().handleFailedOutgoingCall(
-                                    callId,
+                                    request,
+                                    DisconnectCause.ERROR_UNSPECIFIED,
                                     "Created " + result.length + " Connections, expected 1");
                             for (Connection c : result) {
                                 c.abort();
@@ -195,8 +200,9 @@
                     }
 
                     @Override
-                    public void onError(ConnectionRequest request, String reason) {
-                        Log.d(this, "adapter failed setIncomingCallId %s %s", request, reason);
+                    public void onError(ConnectionRequest request, int code, String msg) {
+                        Log.d(this, "adapter failed setIncomingCallId %s %d %s",
+                                request, code, msg);
                     }
                 }
         );
@@ -283,6 +289,25 @@
         // TODO(santoscordon): Find existing conference call and invoke split(connection).
     }
 
+    @Override
+    public final void onPostDialContinue(String callId, boolean proceed) {
+        Log.d(this, "onPostDialContinue(%s)", callId);
+
+        Connection connection = findConnectionForAction(callId, "onPostDialContinue");
+        if (connection == NULL_CONNECTION) {
+            Log.w(this, "Connection missing in post-dial request %s.", callId);
+            return;
+        }
+        connection.onPostDialContinue(proceed);
+    }
+
+    @Override
+    public final void onPostDialWait(Connection conn, String remaining) {
+        Log.d(this, "onPostDialWait(%s, %s)", conn, remaining);
+
+        getAdapter().onPostDialWait(mIdByConnection.get(conn), remaining);
+    }
+
     /**
      * Find a set of Subscriptions matching a given handle (e.g. phone number).
      *
diff --git a/telecomm/java/android/telecomm/InCallAdapter.java b/telecomm/java/android/telecomm/InCallAdapter.java
index 6838ede..0bef419 100644
--- a/telecomm/java/android/telecomm/InCallAdapter.java
+++ b/telecomm/java/android/telecomm/InCallAdapter.java
@@ -174,13 +174,14 @@
      * will pause playing the tones and notify the {@link InCallService} that the call is in the
      * {@link InCallService#setPostDialWait(String,String)} state. When the user decides to continue
      * the postdial sequence, the {@link InCallService} should invoke the
-     * {@link #postDialContinue(String)} method.
+     * {@link #postDialContinue(String,boolean)} method.
      *
      * @param callId The unique ID of the call for which postdial string playing should continue.
+     * @param proceed Whether or not to continue with the post-dial sequence.
      */
-    public void postDialContinue(String callId) {
+    public void postDialContinue(String callId, boolean proceed) {
         try {
-            mAdapter.postDialContinue(callId);
+            mAdapter.postDialContinue(callId, proceed);
         } catch (RemoteException e) {
         }
     }
diff --git a/telecomm/java/android/telecomm/InCallCall.java b/telecomm/java/android/telecomm/InCallCall.java
index 346d207..b531ccd 100644
--- a/telecomm/java/android/telecomm/InCallCall.java
+++ b/telecomm/java/android/telecomm/InCallCall.java
@@ -31,7 +31,8 @@
 public final class InCallCall implements Parcelable {
     private final String mId;
     private final CallState mState;
-    private final int mDisconnectCause;
+    private final int mDisconnectCauseCode;
+    private final String mDisconnectCauseMsg;
     private final int mCapabilities;
     private final long mConnectTimeMillis;
     private final Uri mHandle;
@@ -47,15 +48,16 @@
     public InCallCall(
             String id,
             CallState state,
-            int disconnectCause,
+            int disconnectCauseCode,
+            String disconnectCauseMsg,
             int capabilities,
             long connectTimeMillis,
             Uri handle,
             GatewayInfo gatewayInfo,
             CallServiceDescriptor descriptor,
             CallServiceDescriptor handoffDescriptor) {
-        this(id, state, disconnectCause, capabilities, connectTimeMillis, handle, gatewayInfo,
-                descriptor, handoffDescriptor, Collections.EMPTY_LIST, null,
+        this(id, state, disconnectCauseCode, disconnectCauseMsg, capabilities, connectTimeMillis,
+                handle, gatewayInfo, descriptor, handoffDescriptor, Collections.EMPTY_LIST, null,
                 Collections.EMPTY_LIST);
     }
 
@@ -63,7 +65,8 @@
     public InCallCall(
             String id,
             CallState state,
-            int disconnectCause,
+            int disconnectCauseCode,
+            String disconnectCauseMsg,
             int capabilities,
             long connectTimeMillis,
             Uri handle,
@@ -75,7 +78,8 @@
             List<String> childCallIds) {
         mId = id;
         mState = state;
-        mDisconnectCause = disconnectCause;
+        mDisconnectCauseCode = disconnectCauseCode;
+        mDisconnectCauseMsg = disconnectCauseMsg;
         mCapabilities = capabilities;
         mConnectTimeMillis = connectTimeMillis;
         mHandle = handle;
@@ -101,8 +105,16 @@
      * Reason for disconnection, values are defined in {@link DisconnectCause}. Valid when call
      * state is {@link CallState#DISCONNECTED}.
      */
-    public int getDisconnectCause() {
-        return mDisconnectCause;
+    public int getDisconnectCauseCode() {
+        return mDisconnectCauseCode;
+    }
+
+    /**
+     * Further optional textual information about the reason for disconnection. Valid when call
+     * state is {@link CallState#DISCONNECTED}.
+     */
+    public String getDisconnectCauseMsg() {
+        return mDisconnectCauseMsg;
     }
 
     // Bit mask of actions a call supports, values are defined in {@link CallCapabilities}.
@@ -170,7 +182,8 @@
         public InCallCall createFromParcel(Parcel source) {
             String id = source.readString();
             CallState state = CallState.valueOf(source.readString());
-            int disconnectCause = source.readInt();
+            int disconnectCauseCode = source.readInt();
+            String disconnectCauseMsg = source.readString();
             int capabilities = source.readInt();
             long connectTimeMillis = source.readLong();
             ClassLoader classLoader = InCallCall.class.getClassLoader();
@@ -183,9 +196,9 @@
             String parentCallId = source.readString();
             List<String> childCallIds = new ArrayList<>();
             source.readList(childCallIds, classLoader);
-            return new InCallCall(id, state, disconnectCause, capabilities, connectTimeMillis,
-                    handle, gatewayInfo, descriptor, handoffDescriptor, conferenceCapableCallIds,
-                    parentCallId, childCallIds);
+            return new InCallCall(id, state, disconnectCauseCode, disconnectCauseMsg, capabilities,
+                    connectTimeMillis, handle, gatewayInfo, descriptor, handoffDescriptor,
+                    conferenceCapableCallIds, parentCallId, childCallIds);
         }
 
         @Override
@@ -205,7 +218,8 @@
     public void writeToParcel(Parcel destination, int flags) {
         destination.writeString(mId);
         destination.writeString(mState.name());
-        destination.writeInt(mDisconnectCause);
+        destination.writeInt(mDisconnectCauseCode);
+        destination.writeString(mDisconnectCauseMsg);
         destination.writeInt(mCapabilities);
         destination.writeLong(mConnectTimeMillis);
         destination.writeParcelable(mHandle, 0);
diff --git a/telecomm/java/android/telecomm/InCallService.java b/telecomm/java/android/telecomm/InCallService.java
index 3a63077..c7dd23a 100644
--- a/telecomm/java/android/telecomm/InCallService.java
+++ b/telecomm/java/android/telecomm/InCallService.java
@@ -203,7 +203,7 @@
      * {@link #setPostDial(String,String)} state but is now waiting for user confirmation before the
      * remaining digits can be sent. Normal transitions are to {@link #setPostDial(String,String)}
      * when the user asks Telecomm to proceed with the post-dial sequence and the in-call app
-     * informs Telecomm of this by invoking {@link InCallAdapter#postDialContinue(String)}.
+     * informs Telecomm of this by invoking {@link InCallAdapter#postDialContinue(String,boolean)}.
      *
      * @param callId The identifier of the call changing state.
      * @param remaining The remaining postdial string to be dialed.
diff --git a/telecomm/java/android/telecomm/Response.java b/telecomm/java/android/telecomm/Response.java
index 14f8340..13c0702 100644
--- a/telecomm/java/android/telecomm/Response.java
+++ b/telecomm/java/android/telecomm/Response.java
@@ -33,7 +33,8 @@
      * Indicates the inability to provide results.
      *
      * @param request The original request.
-     * @param reason The reason for the failure.
+     * @param code An integer code indicating the reason for failure.
+     * @param msg A message explaining the reason for failure.
      */
-    void onError(IN request, String reason);
+    void onError(IN request, int code, String msg);
 }
diff --git a/telecomm/java/com/android/internal/telecomm/ICallService.aidl b/telecomm/java/com/android/internal/telecomm/ICallService.aidl
index 771a3ae..9139aa6 100644
--- a/telecomm/java/com/android/internal/telecomm/ICallService.aidl
+++ b/telecomm/java/com/android/internal/telecomm/ICallService.aidl
@@ -59,4 +59,6 @@
     void addToConference(String conferenceCallId, in List<String> callIds);
 
     void splitFromConference(String conferenceCallId, String callId);
+
+    void onPostDialContinue(String callId, boolean proceed);
 }
diff --git a/telecomm/java/com/android/internal/telecomm/ICallServiceAdapter.aidl b/telecomm/java/com/android/internal/telecomm/ICallServiceAdapter.aidl
index a92b176..17e0487 100644
--- a/telecomm/java/com/android/internal/telecomm/ICallServiceAdapter.aidl
+++ b/telecomm/java/com/android/internal/telecomm/ICallServiceAdapter.aidl
@@ -17,6 +17,7 @@
 package com.android.internal.telecomm;
 
 import android.telecomm.CallInfo;
+import android.telecomm.ConnectionRequest;
 
 /**
  * Internal remote callback interface for call services.
@@ -32,7 +33,7 @@
 
     void handleSuccessfulOutgoingCall(String callId);
 
-    void handleFailedOutgoingCall(String callId, String errorMessage);
+    void handleFailedOutgoingCall(in ConnectionRequest request, int errorCode, String errorMessage);
 
     void setActive(String callId);
 
@@ -51,4 +52,6 @@
     void setIsConferenced(String conferenceCallId, String callId, boolean isConferenced);
 
     void removeCall(String callId);
+
+    void onPostDialWait(String callId, String remaining);
 }
diff --git a/telecomm/java/com/android/internal/telecomm/IInCallAdapter.aidl b/telecomm/java/com/android/internal/telecomm/IInCallAdapter.aidl
index 6a27217..f144043 100644
--- a/telecomm/java/com/android/internal/telecomm/IInCallAdapter.aidl
+++ b/telecomm/java/com/android/internal/telecomm/IInCallAdapter.aidl
@@ -44,7 +44,7 @@
 
     void stopDtmfTone(String callId);
 
-    void postDialContinue(String callId);
+    void postDialContinue(String callId, boolean proceed);
 
     void handoffCall(String callId);
 
diff --git a/telephony/java/android/telephony/DisconnectCause.java b/telephony/java/android/telephony/DisconnectCause.java
index 8681344..d2044be 100644
--- a/telephony/java/android/telephony/DisconnectCause.java
+++ b/telephony/java/android/telephony/DisconnectCause.java
@@ -97,11 +97,62 @@
     public static final int CDMA_ACCESS_BLOCKED            = 35;
     /** Unknown error or not specified */
     public static final int ERROR_UNSPECIFIED              = 36;
+    /**
+     * Only emergency numbers are allowed, but we tried to dial
+     * a non-emergency number.
+     */
+    // TODO: This should be the same as NOT_EMERGENCY
+    public static final int EMERGENCY_ONLY                 = 37;
+    /**
+     * The supplied CALL Intent didn't contain a valid phone number.
+     */
+    public static final int NO_PHONE_NUMBER_SUPPLIED       = 38;
+    /**
+     * Our initial phone number was actually an MMI sequence.
+     */
+    public static final int DIALED_MMI                     = 39;
+    /**
+     * We tried to call a voicemail: URI but the device has no
+     * voicemail number configured.
+     */
+    public static final int VOICEMAIL_NUMBER_MISSING       = 40;
+    /**
+     * This status indicates that InCallScreen should display the
+     * CDMA-specific "call lost" dialog.  (If an outgoing call fails,
+     * and the CDMA "auto-retry" feature is enabled, *and* the retried
+     * call fails too, we display this specific dialog.)
+     *
+     * TODO: this is currently unused, since the "call lost" dialog
+     * needs to be triggered by a *disconnect* event, rather than when
+     * the InCallScreen first comes to the foreground.  For now we use
+     * the needToShowCallLostDialog field for this (see below.)
+     */
+    public static final int CDMA_CALL_LOST                 = 41;
+    /**
+     * This status indicates that the call was placed successfully,
+     * but additionally, the InCallScreen needs to display the
+     * "Exiting ECM" dialog.
+     *
+     * (Details: "Emergency callback mode" is a CDMA-specific concept
+     * where the phone disallows data connections over the cell
+     * network for some period of time after you make an emergency
+     * call.  If the phone is in ECM and you dial a non-emergency
+     * number, that automatically *cancels* ECM, but we additionally
+     * need to warn the user that ECM has been canceled (see bug
+     * 4207607.))
+     *
+     * TODO: Rethink where the best place to put this is. It is not a notification
+     * of a failure of the connection -- it is an additional message that accompanies
+     * a successful connection giving the user important information about what happened.
+     *
+     * {@hide}
+     */
+    public static final int EXITED_ECM                     = 42;
 
     /** Smallest valid value for call disconnect codes. */
     public static final int MINIMUM_VALID_VALUE = NOT_DISCONNECTED;
     /** Largest valid value for call disconnect codes. */
-    public static final int MAXIMUM_VALID_VALUE = ERROR_UNSPECIFIED;
+    public static final int MAXIMUM_VALID_VALUE = EXITED_ECM;
 
     /** Private constructor to avoid class instantiation. */
     private DisconnectCause() {
@@ -181,6 +232,18 @@
             return "CDMA_NOT_EMERGENCY";
         case CDMA_ACCESS_BLOCKED:
             return "CDMA_ACCESS_BLOCKED";
+        case EMERGENCY_ONLY:
+            return "EMERGENCY_ONLY";
+        case NO_PHONE_NUMBER_SUPPLIED:
+            return "NO_PHONE_NUMBER_SUPPLIED";
+        case DIALED_MMI:
+            return "DIALED_MMI";
+        case VOICEMAIL_NUMBER_MISSING:
+            return "VOICEMAIL_NUMBER_MISSING";
+        case CDMA_CALL_LOST:
+            return "CDMA_CALL_LOST";
+        case EXITED_ECM:
+            return "EXITED_ECM";
         case ERROR_UNSPECIFIED:
             return "ERROR_UNSPECIFIED";
         default:
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index 9da032a..ed7f6b8 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -1742,15 +1742,15 @@
 
     /**
      * Checks if a given number is an emergency number for the country that the user is in.
-     *
-     * @param number the number to look up.
      * @param context the specific context which the number should be checked against
+     * @param number the number to look up.
+     *
      * @return true if the specified number is an emergency number for the country the user
      * is currently in.
      */
-    public static boolean isLocalEmergencyNumber(String number, Context context) {
-        return isLocalEmergencyNumberInternal(number,
-                                              context,
+    public static boolean isLocalEmergencyNumber(Context context, String number) {
+        return isLocalEmergencyNumberInternal(context,
+                                              number,
                                               true /* useExactMatch */);
     }
 
@@ -1767,27 +1767,26 @@
      * This method is intended for internal use by the phone app when
      * deciding whether to allow ACTION_CALL intents from 3rd party apps
      * (where we're required to *not* allow emergency calls to be placed.)
-     *
-     * @param number the number to look up.
      * @param context the specific context which the number should be checked against
+     * @param number the number to look up.
+     *
      * @return true if the specified number is an emergency number for a local country, based on the
      *              CountryDetector.
      *
      * @see android.location.CountryDetector
      * @hide
      */
-    public static boolean isPotentialLocalEmergencyNumber(String number, Context context) {
-        return isLocalEmergencyNumberInternal(number,
-                                              context,
+    public static boolean isPotentialLocalEmergencyNumber(Context context, String number) {
+        return isLocalEmergencyNumberInternal(context,
+                                              number,
                                               false /* useExactMatch */);
     }
 
     /**
      * Helper function for isLocalEmergencyNumber() and
      * isPotentialLocalEmergencyNumber().
-     *
-     * @param number the number to look up.
      * @param context the specific context which the number should be checked against
+     * @param number the number to look up.
      * @param useExactMatch if true, consider a number to be an emergency
      *           number only if it *exactly* matches a number listed in
      *           the RIL / SIM.  If false, a number is considered to be an
@@ -1799,8 +1798,8 @@
      *
      * @see android.location.CountryDetector
      */
-    private static boolean isLocalEmergencyNumberInternal(String number,
-                                                          Context context,
+    private static boolean isLocalEmergencyNumberInternal(Context context,
+                                                          String number,
                                                           boolean useExactMatch) {
         String countryIso;
         CountryDetector detector = (CountryDetector) context.getSystemService(
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index ffa9a4e..3f65bca 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -16,7 +16,7 @@
 
 package android.telephony;
 
-import android.annotation.PrivateApi;
+import android.annotation.SystemApi;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.content.ComponentName;
@@ -1961,11 +1961,11 @@
     }
 
     /**
-     * Expose the rest of ITelephony to @PrivateApi
+     * Expose the rest of ITelephony to @SystemApi
      */
 
     /** @hide */
-    @PrivateApi
+    @SystemApi
     public void dial(String number) {
         try {
             getITelephony().dial(number);
@@ -1975,7 +1975,7 @@
     }
 
     /** @hide */
-    @PrivateApi
+    @SystemApi
     public void call(String callingPackage, String number) {
         try {
             getITelephony().call(callingPackage, number);
@@ -1985,7 +1985,7 @@
     }
 
     /** @hide */
-    @PrivateApi
+    @SystemApi
     public boolean showCallScreen() {
         try {
             getTelecommService().showCallScreen(false);
@@ -1997,7 +1997,7 @@
     }
 
     /** @hide */
-    @PrivateApi
+    @SystemApi
     public boolean showCallScreenWithDialpad(boolean showDialpad) {
         try {
             getTelecommService().showCallScreen(showDialpad);
@@ -2009,7 +2009,7 @@
     }
 
     /** @hide */
-    @PrivateApi
+    @SystemApi
     public boolean endCall() {
         try {
             return getITelephony().endCall();
@@ -2020,7 +2020,7 @@
     }
 
     /** @hide */
-    @PrivateApi
+    @SystemApi
     public void answerRingingCall() {
         try {
             getITelephony().answerRingingCall();
@@ -2030,7 +2030,7 @@
     }
 
     /** @hide */
-    @PrivateApi
+    @SystemApi
     public void silenceRinger() {
         try {
             getTelecommService().silenceRinger();
@@ -2040,7 +2040,7 @@
     }
 
     /** @hide */
-    @PrivateApi
+    @SystemApi
     public boolean isOffhook() {
         try {
             return getITelephony().isOffhook();
@@ -2051,7 +2051,7 @@
     }
 
     /** @hide */
-    @PrivateApi
+    @SystemApi
     public boolean isRinging() {
         try {
             return getITelephony().isRinging();
@@ -2062,7 +2062,7 @@
     }
 
     /** @hide */
-    @PrivateApi
+    @SystemApi
     public boolean isIdle() {
         try {
             return getITelephony().isIdle();
@@ -2073,7 +2073,7 @@
     }
 
     /** @hide */
-    @PrivateApi
+    @SystemApi
     public boolean isRadioOn() {
         try {
             return getITelephony().isRadioOn();
@@ -2084,7 +2084,7 @@
     }
 
     /** @hide */
-    @PrivateApi
+    @SystemApi
     public boolean isSimPinEnabled() {
         try {
             return getITelephony().isSimPinEnabled();
@@ -2095,7 +2095,7 @@
     }
 
     /** @hide */
-    @PrivateApi
+    @SystemApi
     public void cancelMissedCallsNotification() {
         try {
             getITelephony().cancelMissedCallsNotification();
@@ -2105,7 +2105,7 @@
     }
 
     /** @hide */
-    @PrivateApi
+    @SystemApi
     public boolean supplyPin(String pin) {
         try {
             return getITelephony().supplyPin(pin);
@@ -2116,7 +2116,7 @@
     }
 
     /** @hide */
-    @PrivateApi
+    @SystemApi
     public boolean supplyPuk(String puk, String pin) {
         try {
             return getITelephony().supplyPuk(puk, pin);
@@ -2127,7 +2127,7 @@
     }
 
     /** @hide */
-    @PrivateApi
+    @SystemApi
     public int[] supplyPinReportResult(String pin) {
         try {
             return getITelephony().supplyPinReportResult(pin);
@@ -2138,7 +2138,7 @@
     }
 
     /** @hide */
-    @PrivateApi
+    @SystemApi
     public int[] supplyPukReportResult(String puk, String pin) {
         try {
             return getITelephony().supplyPukReportResult(puk, pin);
@@ -2149,7 +2149,7 @@
     }
 
     /** @hide */
-    @PrivateApi
+    @SystemApi
     public boolean handlePinMmi(String dialString) {
         try {
             return getITelephony().handlePinMmi(dialString);
@@ -2160,7 +2160,7 @@
     }
 
     /** @hide */
-    @PrivateApi
+    @SystemApi
     public void toggleRadioOnOff() {
         try {
             getITelephony().toggleRadioOnOff();
@@ -2170,7 +2170,7 @@
     }
 
     /** @hide */
-    @PrivateApi
+    @SystemApi
     public boolean setRadio(boolean turnOn) {
         try {
             return getITelephony().setRadio(turnOn);
@@ -2181,7 +2181,7 @@
     }
 
     /** @hide */
-    @PrivateApi
+    @SystemApi
     public boolean setRadioPower(boolean turnOn) {
         try {
             return getITelephony().setRadioPower(turnOn);
@@ -2192,7 +2192,7 @@
     }
 
     /** @hide */
-    @PrivateApi
+    @SystemApi
     public void updateServiceLocation() {
         try {
             getITelephony().updateServiceLocation();
@@ -2202,7 +2202,7 @@
     }
 
     /** @hide */
-    @PrivateApi
+    @SystemApi
     public int enableApnType(String type) {
         try {
             return getITelephony().enableApnType(type);
@@ -2213,7 +2213,7 @@
     }
 
     /** @hide */
-    @PrivateApi
+    @SystemApi
     public int disableApnType(String type) {
         try {
             return getITelephony().disableApnType(type);
@@ -2224,7 +2224,7 @@
     }
 
     /** @hide */
-    @PrivateApi
+    @SystemApi
     public boolean enableDataConnectivity() {
         try {
             return getITelephony().enableDataConnectivity();
@@ -2235,7 +2235,7 @@
     }
 
     /** @hide */
-    @PrivateApi
+    @SystemApi
     public boolean disableDataConnectivity() {
         try {
             return getITelephony().disableDataConnectivity();
@@ -2246,7 +2246,7 @@
     }
 
     /** @hide */
-    @PrivateApi
+    @SystemApi
     public boolean isDataConnectivityPossible() {
         try {
             return getITelephony().isDataConnectivityPossible();
@@ -2257,7 +2257,7 @@
     }
 
     /** @hide */
-    @PrivateApi
+    @SystemApi
     public boolean needsOtaServiceProvisioning() {
         try {
             return getITelephony().needsOtaServiceProvisioning();
@@ -2268,7 +2268,7 @@
     }
 
     /** @hide */
-    @PrivateApi
+    @SystemApi
     public void setDataEnabled(boolean enable) {
         try {
             getITelephony().setDataEnabled(enable);
@@ -2278,7 +2278,7 @@
     }
 
     /** @hide */
-    @PrivateApi
+    @SystemApi
     public boolean getDataEnabled() {
         try {
             return getITelephony().getDataEnabled();
diff --git a/telephony/java/com/android/internal/telephony/CallerInfo.java b/telephony/java/com/android/internal/telephony/CallerInfo.java
index f6143ed..f8dd7cf 100644
--- a/telephony/java/com/android/internal/telephony/CallerInfo.java
+++ b/telephony/java/com/android/internal/telephony/CallerInfo.java
@@ -276,7 +276,7 @@
         // Change the callerInfo number ONLY if it is an emergency number
         // or if it is the voicemail number.  If it is either, take a
         // shortcut and skip the query.
-        if (PhoneNumberUtils.isLocalEmergencyNumber(number, context)) {
+        if (PhoneNumberUtils.isLocalEmergencyNumber(context, number)) {
             return new CallerInfo().markAsEmergency(context);
         } else if (PhoneNumberUtils.isVoiceMailNumber(number)) {
             return new CallerInfo().markAsVoiceMail();
diff --git a/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java b/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
index 74f73b5..34fed5e 100644
--- a/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
+++ b/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
@@ -399,7 +399,7 @@
         cw.number = number;
 
         // check to see if these are recognized numbers, and use shortcuts if we can.
-        if (PhoneNumberUtils.isLocalEmergencyNumber(number, context)) {
+        if (PhoneNumberUtils.isLocalEmergencyNumber(context, number)) {
             cw.event = EVENT_EMERGENCY_NUMBER;
         } else if (PhoneNumberUtils.isVoiceMailNumber(number)) {
             cw.event = EVENT_VOICEMAIL_NUMBER;
diff --git a/tests/VoiceInteraction/AndroidManifest.xml b/tests/VoiceInteraction/AndroidManifest.xml
index e1a5854..33f000d 100644
--- a/tests/VoiceInteraction/AndroidManifest.xml
+++ b/tests/VoiceInteraction/AndroidManifest.xml
@@ -3,7 +3,7 @@
 
     <application>
         <activity android:name="VoiceInteractionMain" android:label="Voice Interaction"
-                android:theme="@android:style/Theme.Quantum">
+                android:theme="@android:style/Theme.Material">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.DEFAULT" />
@@ -24,7 +24,7 @@
                 android:process=":session">
         </service>
         <activity android:name="TestInteractionActivity" android:label="Voice Interaction Target"
-                  android:theme="@android:style/Theme.Quantum.Light.Voice">
+                  android:theme="@android:style/Theme.Material.Light.Voice">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.DEFAULT" />
diff --git a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
index e35bc06..cd199dc 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
@@ -977,7 +977,7 @@
     /*package*/ static void native_drawText(long nativeCanvas,
             final char[] text, final int index, final int count,
             final float startX, final float startY, final int flags, long paint,
-            long typeface) {
+            final long typeface) {
 
         draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
                 new GcSnapshot.Drawable() {
@@ -985,6 +985,11 @@
             public void draw(Graphics2D graphics, Paint_Delegate paintDelegate) {
                 // WARNING: the logic in this method is similar to Paint_Delegate.measureText.
                 // Any change to this method should be reflected in Paint.measureText
+
+                // assert that the typeface passed is actually the one stored in paint.
+                assert (typeface == paintDelegate.mNativeTypeface);
+
+
                 // Paint.TextAlign indicates how the text is positioned relative to X.
                 // LEFT is the default and there's nothing to do.
                 float x = startX;
diff --git a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
index 9ea4538..d73adab 100644
--- a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
@@ -21,6 +21,8 @@
 import com.android.layoutlib.bridge.impl.DelegateManager;
 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
 
+import android.content.res.AssetManager;
+
 import java.awt.Font;
 import java.io.File;
 import java.util.ArrayList;
@@ -47,7 +49,6 @@
     private static final String FONT_SUFFIX_BOLDITALIC = "BoldItalic.ttf";
     private static final String FONT_SUFFIX_BOLD = "Bold.ttf";
     private static final String FONT_SUFFIX_ITALIC = "Italic.ttf";
-    private static final String FONT_SUBSTRING_COMPACT = "UI";
 
     /**
      * A class associating {@link Font} with its metadata.
@@ -56,11 +57,6 @@
         Font mFont;
         /** Regular, Bold, Italic, or BoldItalic. */
         int mStyle;
-        /**
-         * The variant of the Font - compact or elegant.
-         * @see Paint#setElegantTextHeight(boolean)
-         */
-        boolean mIsCompact;
     }
 
     // ---- delegate manager ----
@@ -75,6 +71,14 @@
 
     // ---- delegate data ----
     private List<FontInfo> mFonts = new ArrayList<FontInfo>();
+    /**
+     * The variant of the Font Family - compact or elegant.
+     * 0 is unspecified, 1 is compact and 2 is elegant. This needs to be kept in sync with values in
+     * android.graphics.FontFamily
+     *
+     * @see Paint#setElegantTextHeight(boolean)
+     */
+    private FontVariant mVariant;
     // Path of fonts that haven't been created since sFontLoader hasn't been initialized.
     private List<String> mPath = new ArrayList<String>();
 
@@ -93,37 +97,22 @@
         sPostInitDelegate.clear();
     }
 
-    public Font getFont(int style, boolean isCompact) {
+    public Font getFont(int style) {
         FontInfo plainFont = null;
-        FontInfo styledFont = null;  // Font matching the style but not isCompact
         for (FontInfo font : mFonts) {
             if (font.mStyle == style) {
-                if (font.mIsCompact == isCompact) {
-                    return font.mFont;
-                }
-                styledFont = font;
+                return font.mFont;
             }
-            if (font.mStyle == Font.PLAIN) {
-                if (plainFont == null) {
-                    plainFont = font;
-                    continue;
-                }
-                if (font.mIsCompact == isCompact) {
-                    // Override the previous selection of plain font since we've found a better one.
-                    plainFont = font;
-                }
+            if (font.mStyle == Font.PLAIN && plainFont == null) {
+                plainFont = font;
             }
         }
-        if (styledFont != null) {
-            return styledFont.mFont;
-        }
 
         // No font with the mentioned style is found. Try to derive one.
         if (plainFont != null && style > 0 && style < 4) {
-            styledFont = new FontInfo();
+            FontInfo styledFont = new FontInfo();
             styledFont.mFont = plainFont.mFont.deriveFont(style);
             styledFont.mStyle = style;
-            styledFont.mIsCompact = plainFont.mIsCompact;
             // Add the font to the list of fonts so that we don't have to derive it the next time.
             mFonts.add(styledFont);
             return styledFont.mFont;
@@ -131,11 +120,20 @@
         return null;
     }
 
+    public FontVariant getVariant() {
+        return mVariant;
+    }
+
+
     // ---- native methods ----
 
     @LayoutlibDelegate
-    /*package*/ static long nCreateFamily() {
+    /*package*/ static long nCreateFamily(String lang, int variant) {
+        // TODO: support lang. This is required for japanese locale.
         FontFamily_Delegate delegate = new FontFamily_Delegate();
+        // variant can be 0, 1 or 2.
+        assert variant < 3;
+        delegate.mVariant = FontVariant.values()[variant];
         if (sFontLocation != null) {
             delegate.init();
         } else {
@@ -164,6 +162,13 @@
         return false;
     }
 
+    @LayoutlibDelegate
+    /*package*/ static boolean nAddFontFromAsset(long nativeFamily, AssetManager mgr, String path) {
+        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+                "FontFamily.addFontFromAsset is not supported.", null /*throwable*/, null /*data*/);
+        return false;
+    }
+
     private void init() {
         for (String path : mPath) {
             addFont(path);
@@ -195,13 +200,6 @@
             style = Font.ITALIC;
         }
         fontInfo.mStyle = style;
-
-        // Names of compact fonts end with UI-<style>.ttf. For example, NotoNakshUI-Regular.ttf.
-        // This should go away when this info is passed on by nAddFont().
-        int hyphenIndex = fontName.lastIndexOf('-');
-        fontInfo.mIsCompact = hyphenIndex > 0 &&
-                fontName.substring(0, hyphenIndex).endsWith(FONT_SUBSTRING_COMPACT);
-
     }
 
     private static Font loadFont(String path) {
@@ -214,7 +212,7 @@
             } catch (Exception e) {
                 Bridge.getLog().fidelityWarning(LayoutLog.TAG_BROKEN,
                         String.format("Unable to load font %1$s", relativePath),
-                        null /*throwable*/, null /*data*/);
+                        e /*throwable*/, null /*data*/);
             }
         } else {
             Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
@@ -224,4 +222,12 @@
 
         return null;
     }
+
+
+    // ---- Public helper class ----
+
+    public enum FontVariant {
+        // The order needs to be kept in sync with android.graphics.FontFamily.
+        NONE, COMPACT, ELEGANT
+    }
 }
diff --git a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
index 911f4e7..6ee307e 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
@@ -21,6 +21,7 @@
 import com.android.layoutlib.bridge.impl.DelegateManager;
 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
 
+import android.graphics.FontFamily_Delegate.FontVariant;
 import android.graphics.Paint.FontMetrics;
 import android.graphics.Paint.FontMetricsInt;
 import android.text.TextUtils;
@@ -30,7 +31,6 @@
 import java.awt.Shape;
 import java.awt.Stroke;
 import java.awt.Toolkit;
-import java.awt.font.FontRenderContext;
 import java.awt.geom.AffineTransform;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -81,7 +81,8 @@
     private float mTextScaleX;
     private float mTextSkewX;
     private int mHintingMode = Paint.HINTING_ON;
-    private boolean mIsCompact = true;
+    // Variant of the font.
+    private FontVariant mFontVariant = FontVariant.NONE;
 
     private Xfermode_Delegate mXfermode;
     private ColorFilter_Delegate mColorFilter;
@@ -92,6 +93,8 @@
 
     private Locale mLocale = Locale.getDefault();
 
+    // Used only to assert invariants.
+    public long mNativeTypeface;
 
     // ---- Public Helper methods ----
 
@@ -437,7 +440,7 @@
     /*package*/ static boolean isElegantTextHeight(Paint thisPaint) {
         // get the delegate from the native int.
         Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
-        return delegate != null && !delegate.mIsCompact;
+        return delegate != null && delegate.mFontVariant == FontVariant.ELEGANT;
     }
 
     @LayoutlibDelegate
@@ -448,7 +451,7 @@
             return;
         }
 
-        delegate.mIsCompact = !elegant;
+        delegate.mFontVariant = elegant ? FontVariant.ELEGANT : FontVariant.COMPACT;
     }
 
     @LayoutlibDelegate
@@ -887,6 +890,7 @@
         }
 
         delegate.mTypeface = Typeface_Delegate.getDelegate(typeface);
+        delegate.mNativeTypeface = typeface;
         delegate.updateFontObject();
         return typeface;
     }
@@ -965,15 +969,10 @@
     }
 
     @LayoutlibDelegate
-    /*package*/ static float native_getTextRunAdvances(long native_object,
-            long native_typeface /*ignored*/,
+    /*package*/ static float native_getTextRunAdvances(long native_object, long native_typeface,
             char[] text, int index, int count, int contextIndex, int contextCount,
             int flags, float[] advances, int advancesIndex) {
 
-        // native_typeface is passed here since Framework's old implementation did not have the
-        // typeface object associated with the Paint. Since, we follow the new framework way,
-        // we store the typeface with the paint and use it directly.
-
         if (advances != null)
             for (int i = advancesIndex; i< advancesIndex+count; i++)
                 advances[i]=0;
@@ -982,6 +981,12 @@
         if (delegate == null) {
             return 0.f;
         }
+
+        // native_typeface is passed here since Framework's old implementation did not have the
+        // typeface object associated with the Paint. Since, we follow the new framework way,
+        // we store the typeface with the paint and use it directly.
+        assert (native_typeface == delegate.mNativeTypeface);
+
         boolean isRtl = isRtl(flags);
 
         int limit = index + count;
@@ -1022,37 +1027,41 @@
     }
 
     @LayoutlibDelegate
-    /*package*/ static void native_getTextPath(long native_object, int bidiFlags,
-                char[] text, int index, int count, float x, float y, long path) {
+    /*package*/ static void native_getTextPath(long native_object, long native_typeface,
+            int bidiFlags, char[] text, int index, int count, float x, float y, long path) {
         // FIXME
         Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
                 "Paint.getTextPath is not supported.", null, null /*data*/);
     }
 
     @LayoutlibDelegate
-    /*package*/ static void native_getTextPath(long native_object, int bidiFlags,
-            String text, int start, int end, float x, float y, long path) {
+    /*package*/ static void native_getTextPath(long native_object, long native_typeface,
+            int bidiFlags, String text, int start, int end, float x, float y, long path) {
         // FIXME
         Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
                 "Paint.getTextPath is not supported.", null, null /*data*/);
     }
 
     @LayoutlibDelegate
-    /*package*/ static void nativeGetStringBounds(long nativePaint, String text, int start,
-            int end, int bidiFlags, Rect bounds) {
-        nativeGetCharArrayBounds(nativePaint, text.toCharArray(), start, end - start, bidiFlags,
-                bounds);
+    /*package*/ static void nativeGetStringBounds(long nativePaint, long native_typeface,
+            String text, int start, int end, int bidiFlags, Rect bounds) {
+        nativeGetCharArrayBounds(nativePaint, native_typeface, text.toCharArray(), start,
+                end - start, bidiFlags, bounds);
     }
 
     @LayoutlibDelegate
-    /*package*/ static void nativeGetCharArrayBounds(long nativePaint, char[] text, int index,
-            int count, int bidiFlags, Rect bounds) {
+    /*package*/ static void nativeGetCharArrayBounds(long nativePaint, long native_typeface,
+            char[] text, int index, int count, int bidiFlags, Rect bounds) {
 
         // get the delegate from the native int.
         Paint_Delegate delegate = sManager.getDelegate(nativePaint);
         if (delegate == null) {
             return;
         }
+
+        // assert that the typeface passed is actually the one that we had stored.
+        assert (native_typeface == delegate.mNativeTypeface);
+
         delegate.measureText(text, index, count, isRtl(bidiFlags)).roundOut(bounds);
     }
 
@@ -1079,6 +1088,7 @@
         mJoin = paint.mJoin;
         mTextAlign = paint.mTextAlign;
         mTypeface = paint.mTypeface;
+        mNativeTypeface = paint.mNativeTypeface;
         mStrokeWidth = paint.mStrokeWidth;
         mStrokeMiter = paint.mStrokeMiter;
         mTextSize = paint.mTextSize;
@@ -1102,6 +1112,7 @@
         mJoin = Paint.Join.MITER.nativeInt;
         mTextAlign = 0;
         mTypeface = Typeface_Delegate.getDelegate(Typeface.sDefaults[0].native_instance);
+        mNativeTypeface = 0;
         mStrokeWidth = 1.f;
         mStrokeMiter = 4.f;
         mTextSize = 20.f;
@@ -1124,7 +1135,7 @@
     private void updateFontObject() {
         if (mTypeface != null) {
             // Get the fonts from the TypeFace object.
-            List<Font> fonts = mTypeface.getFonts(mIsCompact);
+            List<Font> fonts = mTypeface.getFonts(mFontVariant);
 
             // create new font objects as well as FontMetrics, based on the current text size
             // and skew info.
diff --git a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
index 9746b48..908bb64 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
@@ -22,6 +22,7 @@
 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
 
 import android.content.res.AssetManager;
+import android.graphics.FontFamily_Delegate.FontVariant;
 
 import java.awt.Font;
 import java.io.File;
@@ -69,17 +70,28 @@
         return sManager.getDelegate(nativeTypeface);
     }
 
-    public List<Font> getFonts(boolean compact) {
+    public List<Font> getFonts(FontVariant variant) {
         List<Font> fonts = new ArrayList<Font>(mFontFamilies.length);
+        // If we are unable to find fonts matching the variant, we return the fonts from the
+        // other variant since we always want to draw something, rather than nothing.
+        // TODO: check this behaviour with platform.
+        List<Font> otherVariantFonts = new ArrayList<Font>();
         for (FontFamily_Delegate ffd : mFontFamilies) {
             if (ffd != null) {
-                Font font = ffd.getFont(mStyle, compact);
+                Font font = ffd.getFont(mStyle);
                 if (font != null) {
-                    fonts.add(font);
+                    if (ffd.getVariant() == variant || ffd.getVariant() == FontVariant.NONE) {
+                        fonts.add(font);
+                    } else {
+                        otherVariantFonts.add(font);
+                    }
                 }
             }
         }
-        return fonts;
+        if (fonts.size() > 0) {
+            return fonts;
+        }
+        return otherVariantFonts;
     }
 
     // ---- native methods ----
diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
index 3bf2b20..2f40003 100644
--- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
+++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
@@ -195,8 +195,8 @@
     }
 
     @Override
-    public IWindowSession openSession(IInputMethodClient arg0, IInputContext arg1)
-            throws RemoteException {
+    public IWindowSession openSession(IWindowSessionCallback argn1, IInputMethodClient arg0,
+            IInputContext arg1) throws RemoteException {
         // TODO Auto-generated method stub
         return null;
     }
@@ -276,6 +276,11 @@
     }
 
     @Override
+    public float getCurrentAnimatorScale() throws RemoteException {
+        return 0;
+    }
+
+    @Override
     public void setAppGroupId(IBinder arg0, int arg1) throws RemoteException {
         // TODO Auto-generated method stub
 
@@ -419,11 +424,6 @@
     }
 
     @Override
-    public boolean waitForWindowDrawn(IBinder token, IRemoteCallback callback) {
-        return false;
-    }
-
-    @Override
     public IBinder asBinder() {
         // TODO Auto-generated method stub
         return null;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
index ffab4de..cc69af2 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
@@ -214,7 +214,8 @@
                 Capability.EXTENDED_VIEWINFO,
                 Capability.FIXED_SCALABLE_NINE_PATCH,
                 Capability.RTL,
-                Capability.ACTION_BAR);
+                Capability.ACTION_BAR,
+                Capability.SIMULATE_PLATFORM);
 
 
         BridgeAssetManager.initSystem();
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java
index 0bb7fc2..66268f2 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java
@@ -135,7 +135,6 @@
     @Override
     public void setImeWindowStatus(IBinder arg0, int arg1, int arg2) throws RemoteException {
         // TODO Auto-generated method stub
-
     }
 
     @Override
@@ -197,25 +196,25 @@
     }
 
     @Override
-        public boolean switchToNextInputMethod(IBinder arg0, boolean arg1) throws RemoteException {
+    public boolean switchToNextInputMethod(IBinder arg0, boolean arg1) throws RemoteException {
         // TODO Auto-generated method stub
         return false;
     }
 
     @Override
-        public boolean shouldOfferSwitchingToNextInputMethod(IBinder arg0) throws RemoteException {
+    public boolean shouldOfferSwitchingToNextInputMethod(IBinder arg0) throws RemoteException {
         // TODO Auto-generated method stub
         return false;
     }
 
     @Override
-        public int getInputMethodWindowVisibleHeight() throws RemoteException {
+     public int getInputMethodWindowVisibleHeight() throws RemoteException {
         // TODO Auto-generated method stub
         return 0;
     }
 
     @Override
-        public void notifyTextCommitted() throws RemoteException {
+    public void notifyUserAction() throws RemoteException {
         // TODO Auto-generated method stub
     }
 
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
index 00c0f93..17d990b 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
@@ -33,6 +33,11 @@
     }
 
     @Override
+    public boolean isPowerSaveMode() throws RemoteException {
+        return false;
+    }
+
+    @Override
     public IBinder asBinder() {
         // pass for now.
         return null;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/ActionBarLayout.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/ActionBarLayout.java
index e59ccd7..d95c815 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/ActionBarLayout.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/ActionBarLayout.java
@@ -23,10 +23,8 @@
 import com.android.ide.common.rendering.api.RenderResources;
 import com.android.ide.common.rendering.api.ResourceValue;
 import com.android.ide.common.rendering.api.SessionParams;
-import com.android.ide.common.rendering.api.SystemViewCookie;
 import com.android.internal.R;
 import com.android.internal.app.WindowDecorActionBar;
-import com.android.internal.util.Predicate;
 import com.android.internal.view.menu.MenuBuilder;
 import com.android.internal.view.menu.MenuItemImpl;
 import com.android.internal.widget.ActionBarAccessor;
@@ -50,7 +48,6 @@
 import android.view.MenuInflater;
 import android.view.View;
 import android.view.ViewGroup;
-import android.widget.ActionMenuView;
 import android.widget.FrameLayout;
 import android.widget.LinearLayout;
 import android.widget.ListAdapter;
@@ -59,8 +56,6 @@
 
 import java.util.ArrayList;
 
-import static com.android.ide.common.rendering.api.SystemViewCookie.ACTION_BAR_OVERFLOW;
-
 /**
  * A layout representing the action bar.
  */
@@ -174,29 +169,6 @@
             mActionBarView.setSplitToolbar(mSplit);
 
             inflateMenus();
-
-            // Find if the Overflow Menu Button (the three dots) exists. If yes,
-            // add the view cookie.
-            Predicate<View> overflowMenuButtonTest = new Predicate<View>() {
-                @Override
-                public boolean apply(View view) {
-                    ViewGroup.LayoutParams lp = view.getLayoutParams();
-                    return lp instanceof ActionMenuView.LayoutParams &&
-                            ((ActionMenuView.LayoutParams) lp).isOverflowButton;
-                }
-            };
-            View overflowMenu = null;
-            if (mSplit) {
-                if (splitView != null) {
-                    overflowMenu = splitView.findViewByPredicate(overflowMenuButtonTest);
-                }
-            }
-            else {
-                overflowMenu = mActionBarView.findViewByPredicate(overflowMenuButtonTest);
-            }
-            if (overflowMenu != null) {
-                mBridgeContext.addViewKey(overflowMenu, new SystemViewCookie(ACTION_BAR_OVERFLOW));
-            }
         }
     }
 
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java
index 1498044..2421f29 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java
@@ -16,6 +16,7 @@
 
 package com.android.layoutlib.bridge.bars;
 
+import com.android.layoutlib.bridge.impl.Config;
 import com.android.resources.Density;
 import com.android.resources.ResourceType;
 
@@ -30,14 +31,14 @@
 
 public class StatusBar extends CustomBar {
 
-    public StatusBar(Context context, Density density, int direction, boolean RtlEnabled)
-            throws XmlPullParserException {
+    public StatusBar(Context context, Density density, int direction, boolean RtlEnabled,
+            int simulatedPlatformVersion) throws XmlPullParserException {
         // FIXME: if direction is RTL but it's not enabled in application manifest, mirror this bar.
         super(context, density, LinearLayout.HORIZONTAL, "/bars/status_bar.xml", "status_bar.xml");
 
         // FIXME: use FILL_H?
         setGravity(Gravity.START | Gravity.TOP | Gravity.RIGHT);
-        setBackgroundColor(0xFF000000);
+        setBackgroundColor(Config.getStatusBarColor(simulatedPlatformVersion));
 
         // Cannot access the inside items through id because no R.id values have been
         // created for them.
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Config.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Config.java
new file mode 100644
index 0000000..e8bc292
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Config.java
@@ -0,0 +1,33 @@
+/*
+ * 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.layoutlib.bridge.impl;
+
+/**
+ * Various helper methods to simulate older versions of platform.
+ */
+public class Config {
+
+    public static boolean showOnScreenNavBar(int platformVersion) {
+        // return true if ICS or later.
+        return platformVersion >= 14 || platformVersion == 0;
+    }
+
+    public static int getStatusBarColor(int platformVersion) {
+        // return white for froyo and earlier; black otherwise.
+        return platformVersion >= 9 || platformVersion == 0 ? 0xFF000000 : 0xFFFFFFFF;
+    }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
index 4af73cf..c715003 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
@@ -37,6 +37,7 @@
 import com.android.ide.common.rendering.api.SessionParams;
 import com.android.ide.common.rendering.api.SessionParams.RenderingMode;
 import com.android.ide.common.rendering.api.ViewInfo;
+import com.android.ide.common.rendering.api.ViewType;
 import com.android.internal.util.XmlUtils;
 import com.android.internal.view.menu.ActionMenuItemView;
 import com.android.internal.view.menu.BridgeMenuItemImpl;
@@ -83,9 +84,12 @@
 import android.view.ViewGroup;
 import android.view.ViewGroup.LayoutParams;
 import android.view.ViewGroup.MarginLayoutParams;
+import android.view.ViewParent;
 import android.view.WindowManagerGlobal_Delegate;
+import android.view.ViewParent;
 import android.widget.AbsListView;
 import android.widget.AbsSpinner;
+import android.widget.ActionMenuView;
 import android.widget.AdapterView;
 import android.widget.ExpandableListView;
 import android.widget.FrameLayout;
@@ -267,12 +271,13 @@
                     mViewRoot = topLayout;
                     topLayout.setOrientation(LinearLayout.HORIZONTAL);
 
-                    try {
-                        NavigationBar navigationBar = createNavigationBar(context,
-                                hardwareConfig.getDensity(), isRtl, params.isRtlSupported());
-                        topLayout.addView(navigationBar);
-                    } catch (XmlPullParserException ignored) {
-
+                    if (Config.showOnScreenNavBar(params.getSimulatedPlatformVersion())) {
+                        try {
+                            NavigationBar navigationBar = createNavigationBar(context,
+                                    hardwareConfig.getDensity(), isRtl, params.isRtlSupported());
+                            topLayout.addView(navigationBar);
+                        } catch (XmlPullParserException ignored) {
+                        }
                     }
                 }
 
@@ -325,7 +330,8 @@
                     // system bar
                     try {
                         StatusBar statusBar = createStatusBar(context, hardwareConfig.getDensity(),
-                                layoutDirection, params.isRtlSupported());
+                                layoutDirection, params.isRtlSupported(),
+                                params.getSimulatedPlatformVersion());
                         topLayout.addView(statusBar);
                     } catch (XmlPullParserException ignored) {
 
@@ -368,7 +374,8 @@
                     backgroundLayout.addView(mContentRoot);
                 }
 
-                if (mNavigationBarOrientation == LinearLayout.HORIZONTAL &&
+                if (Config.showOnScreenNavBar(params.getSimulatedPlatformVersion()) &&
+                        mNavigationBarOrientation == LinearLayout.HORIZONTAL &&
                         mNavigationBarSize > 0) {
                     // system bar
                     try {
@@ -1473,16 +1480,49 @@
 
         ViewInfo result;
         if (isContentFrame) {
+            // The view is part of the layout added by the user. Hence,
+            // the ViewCookie may be obtained only through the Context.
             result = new ViewInfo(view.getClass().getName(),
-                    getViewKey(view),
+                    getContext().getViewKey(view),
                     view.getLeft(), view.getTop() + offset, view.getRight(),
                     view.getBottom() + offset, view, view.getLayoutParams());
-
         } else {
-            result = new SystemViewInfo(view.getClass().getName(),
+            // We are part of the system decor.
+            SystemViewInfo r = new SystemViewInfo(view.getClass().getName(),
                     getViewKey(view),
                     view.getLeft(), view.getTop(), view.getRight(),
                     view.getBottom(), view, view.getLayoutParams());
+            result = r;
+            // We currently mark three kinds of views:
+            // 1. Menus in the Action Bar
+            // 2. Menus in the Overflow popup.
+            // 3. The overflow popup button.
+            if (view instanceof ListMenuItemView) {
+                // Mark 2.
+                // All menus in the popup are of type ListMenuItemView.
+                r.setViewType(ViewType.ACTION_BAR_OVERFLOW_MENU);
+            } else {
+                // Mark 3.
+                ViewGroup.LayoutParams lp = view.getLayoutParams();
+                if (lp instanceof ActionMenuView.LayoutParams &&
+                        ((ActionMenuView.LayoutParams) lp).isOverflowButton) {
+                    r.setViewType(ViewType.ACTION_BAR_OVERFLOW);
+                } else {
+                    // Mark 1.
+                    // A view is a menu in the Action Bar is it is not the overflow button and of
+                    // its parent is of type ActionMenuView. We can also check if the view is
+                    // instanceof ActionMenuItemView but that will fail for menus using
+                    // actionProviderClass.
+                    ViewParent parent = view.getParent();
+                    while (parent != mViewRoot && parent instanceof ViewGroup) {
+                        if (parent instanceof ActionMenuView) {
+                            r.setViewType(ViewType.ACTION_BAR_MENU);
+                            break;
+                        }
+                        parent = parent.getParent();
+                    }
+                }
+            }
         }
 
         if (setExtendedInfo) {
@@ -1501,7 +1541,7 @@
         return result;
     }
 
-    /**
+    /* (non-Javadoc)
      * The cookie for menu items are stored in menu item and not in the map from View stored in
      * BridgeContext.
      */
@@ -1535,9 +1575,9 @@
      * Creates the status bar with wifi and battery icons.
      */
     private StatusBar createStatusBar(BridgeContext context, Density density, int direction,
-            boolean isRtlSupported) throws XmlPullParserException {
+            boolean isRtlSupported, int platformVersion) throws XmlPullParserException {
         StatusBar statusBar = new StatusBar(context, density,
-                direction, isRtlSupported);
+                direction, isRtlSupported, platformVersion);
         statusBar.setLayoutParams(
                 new LinearLayout.LayoutParams(
                         LayoutParams.MATCH_PARENT, mStatusBarSize));
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/SystemViewInfo.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/SystemViewInfo.java
index 5c267df..9fea167 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/SystemViewInfo.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/SystemViewInfo.java
@@ -17,9 +17,15 @@
 package com.android.layoutlib.bridge.impl;
 
 import com.android.ide.common.rendering.api.ViewInfo;
+import com.android.ide.common.rendering.api.ViewType;
 
+/**
+ * ViewInfo for views added by the platform.
+ */
 public class SystemViewInfo extends ViewInfo {
 
+    private ViewType mViewType;
+
     public SystemViewInfo(String name, Object cookie, int left, int top,
             int right, int bottom) {
         super(name, cookie, left, top, right, bottom);
@@ -32,7 +38,14 @@
     }
 
     @Override
-    public boolean isSystemView() {
-        return true;
+    public ViewType getViewType() {
+        if (mViewType != null) {
+            return mViewType;
+        }
+        return ViewType.SYSTEM_UNKNOWN;
+    }
+
+    public void setViewType(ViewType type) {
+        mViewType = type;
     }
 }