Added compatibility support for decorated custom views

This adds compatibility for both decorated custom views
and decorated media custom view styles.

Change-Id: If3d73564626748e4f24a2ad9b2055dc1ded7dc9a
Fixes: 27698612
diff --git a/api/current.txt b/api/current.txt
index f3c219d..a628df5 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -7934,6 +7934,14 @@
     ctor public NotificationCompat.Builder(android.content.Context);
   }
 
+  public static class NotificationCompat.DecoratedCustomViewStyle extends android.support.v4.app.NotificationCompat.Style {
+    ctor public NotificationCompat.DecoratedCustomViewStyle();
+  }
+
+  public static class NotificationCompat.DecoratedMediaCustomViewStyle extends android.support.v7.app.NotificationCompat.MediaStyle {
+    ctor public NotificationCompat.DecoratedMediaCustomViewStyle();
+  }
+
   public static class NotificationCompat.MediaStyle extends android.support.v4.app.NotificationCompat.Style {
     ctor public NotificationCompat.MediaStyle();
     ctor public NotificationCompat.MediaStyle(android.support.v4.app.NotificationCompat.Builder);
diff --git a/compat/java/android/support/v4/app/NotificationCompat.java b/compat/java/android/support/v4/app/NotificationCompat.java
index 62c1a7b..009b864 100644
--- a/compat/java/android/support/v4/app/NotificationCompat.java
+++ b/compat/java/android/support/v4/app/NotificationCompat.java
@@ -512,7 +512,11 @@
      */
     protected static class BuilderExtender {
         public Notification build(Builder b, NotificationBuilderWithBuilderAccessor builder) {
-            return builder.build();
+            Notification n = builder.build();
+            if (b.mContentView != null) {
+                n.contentView = b.mContentView;
+            }
+            return n;
         }
     }
 
@@ -617,11 +621,7 @@
                             b.mContext, b.mNotification, b.mContentTitle, b.mContentText, b.mContentInfo,
                             b.mTickerView, b.mNumber, b.mContentIntent, b.mFullScreenIntent, b.mLargeIcon,
                             b.mProgressMax, b.mProgress, b.mProgressIndeterminate);
-            Notification notification = extender.build(b, builder);
-            if (b.mContentView != null) {
-                notification.contentView = b.mContentView;
-            }
-            return notification;
+            return extender.build(b, builder);
         }
     }
 
@@ -1740,6 +1740,54 @@
             }
             return cs;
         }
+
+        /**
+         * @hide
+         */
+        public RemoteViews getContentView() {
+            return mContentView;
+        }
+
+        /**
+         * @hide
+         */
+        public RemoteViews getBigContentView() {
+            return mBigContentView;
+        }
+
+        /**
+         * @hide
+         */
+        public RemoteViews getHeadsUpContentView() {
+            return mHeadsUpContentView;
+        }
+
+        /**
+         * return when if it is showing or 0 otherwise
+         *
+         * @hide
+         */
+        public long getWhenIfShowing() {
+            return mShowWhen ? mNotification.when : 0;
+        }
+
+        /**
+         * @return the priority set on the notification
+         *
+         * @hide
+         */
+        public int getPriority() {
+            return mPriority;
+        }
+
+        /**
+         * @return the color of the notification
+         *
+         * @hide
+         */
+        public int getColor() {
+            return mColor;
+        }
     }
 
     /**
diff --git a/v7/appcompat/res/drawable-hdpi/notification_bg_low_normal.9.png b/v7/appcompat/res/drawable-hdpi/notification_bg_low_normal.9.png
new file mode 100644
index 0000000..af91f5e
--- /dev/null
+++ b/v7/appcompat/res/drawable-hdpi/notification_bg_low_normal.9.png
Binary files differ
diff --git a/v7/appcompat/res/drawable-hdpi/notification_bg_low_pressed.9.png b/v7/appcompat/res/drawable-hdpi/notification_bg_low_pressed.9.png
new file mode 100644
index 0000000..1602ab8
--- /dev/null
+++ b/v7/appcompat/res/drawable-hdpi/notification_bg_low_pressed.9.png
Binary files differ
diff --git a/v7/appcompat/res/drawable-hdpi/notification_bg_normal.9.png b/v7/appcompat/res/drawable-hdpi/notification_bg_normal.9.png
new file mode 100644
index 0000000..6ebed8b
--- /dev/null
+++ b/v7/appcompat/res/drawable-hdpi/notification_bg_normal.9.png
Binary files differ
diff --git a/v7/appcompat/res/drawable-hdpi/notification_bg_normal_pressed.9.png b/v7/appcompat/res/drawable-hdpi/notification_bg_normal_pressed.9.png
new file mode 100644
index 0000000..6193822
--- /dev/null
+++ b/v7/appcompat/res/drawable-hdpi/notification_bg_normal_pressed.9.png
Binary files differ
diff --git a/v7/appcompat/res/drawable-hdpi/notify_panel_notification_icon_bg.png b/v7/appcompat/res/drawable-hdpi/notify_panel_notification_icon_bg.png
new file mode 100644
index 0000000..6f37a22
--- /dev/null
+++ b/v7/appcompat/res/drawable-hdpi/notify_panel_notification_icon_bg.png
Binary files differ
diff --git a/v7/appcompat/res/drawable-mdpi/notification_bg_low_normal.9.png b/v7/appcompat/res/drawable-mdpi/notification_bg_low_normal.9.png
new file mode 100644
index 0000000..62de9d7
--- /dev/null
+++ b/v7/appcompat/res/drawable-mdpi/notification_bg_low_normal.9.png
Binary files differ
diff --git a/v7/appcompat/res/drawable-mdpi/notification_bg_low_pressed.9.png b/v7/appcompat/res/drawable-mdpi/notification_bg_low_pressed.9.png
new file mode 100644
index 0000000..eaabd93
--- /dev/null
+++ b/v7/appcompat/res/drawable-mdpi/notification_bg_low_pressed.9.png
Binary files differ
diff --git a/v7/appcompat/res/drawable-mdpi/notification_bg_normal.9.png b/v7/appcompat/res/drawable-mdpi/notification_bg_normal.9.png
new file mode 100644
index 0000000..aa239b3
--- /dev/null
+++ b/v7/appcompat/res/drawable-mdpi/notification_bg_normal.9.png
Binary files differ
diff --git a/v7/appcompat/res/drawable-mdpi/notification_bg_normal_pressed.9.png b/v7/appcompat/res/drawable-mdpi/notification_bg_normal_pressed.9.png
new file mode 100644
index 0000000..62d8622
--- /dev/null
+++ b/v7/appcompat/res/drawable-mdpi/notification_bg_normal_pressed.9.png
Binary files differ
diff --git a/v7/appcompat/res/drawable-mdpi/notify_panel_notification_icon_bg.png b/v7/appcompat/res/drawable-mdpi/notify_panel_notification_icon_bg.png
new file mode 100644
index 0000000..c286875
--- /dev/null
+++ b/v7/appcompat/res/drawable-mdpi/notify_panel_notification_icon_bg.png
Binary files differ
diff --git a/v7/appcompat/res/drawable-v21/notification_action_background.xml b/v7/appcompat/res/drawable-v21/notification_action_background.xml
new file mode 100644
index 0000000..852c3f0
--- /dev/null
+++ b/v7/appcompat/res/drawable-v21/notification_action_background.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2016 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
+  -->
+
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+    android:color="@color/ripple_material_light">
+    <item android:id="@android:id/mask"
+        android:drawable="@drawable/abc_btn_default_mtrl_shape" />
+</ripple>
\ No newline at end of file
diff --git a/v7/appcompat/res/drawable-xhdpi/notification_bg_low_normal.9.png b/v7/appcompat/res/drawable-xhdpi/notification_bg_low_normal.9.png
new file mode 100644
index 0000000..8c884de
--- /dev/null
+++ b/v7/appcompat/res/drawable-xhdpi/notification_bg_low_normal.9.png
Binary files differ
diff --git a/v7/appcompat/res/drawable-xhdpi/notification_bg_low_pressed.9.png b/v7/appcompat/res/drawable-xhdpi/notification_bg_low_pressed.9.png
new file mode 100644
index 0000000..32e00be
--- /dev/null
+++ b/v7/appcompat/res/drawable-xhdpi/notification_bg_low_pressed.9.png
Binary files differ
diff --git a/v7/appcompat/res/drawable-xhdpi/notification_bg_normal.9.png b/v7/appcompat/res/drawable-xhdpi/notification_bg_normal.9.png
new file mode 100644
index 0000000..bdf477b
--- /dev/null
+++ b/v7/appcompat/res/drawable-xhdpi/notification_bg_normal.9.png
Binary files differ
diff --git a/v7/appcompat/res/drawable-xhdpi/notification_bg_normal_pressed.9.png b/v7/appcompat/res/drawable-xhdpi/notification_bg_normal_pressed.9.png
new file mode 100644
index 0000000..5c4da74
--- /dev/null
+++ b/v7/appcompat/res/drawable-xhdpi/notification_bg_normal_pressed.9.png
Binary files differ
diff --git a/v7/appcompat/res/drawable-xhdpi/notify_panel_notification_icon_bg.png b/v7/appcompat/res/drawable-xhdpi/notify_panel_notification_icon_bg.png
new file mode 100644
index 0000000..9128e62
--- /dev/null
+++ b/v7/appcompat/res/drawable-xhdpi/notify_panel_notification_icon_bg.png
Binary files differ
diff --git a/v7/appcompat/res/drawable/notification_bg.xml b/v7/appcompat/res/drawable/notification_bg.xml
new file mode 100644
index 0000000..1232b4c
--- /dev/null
+++ b/v7/appcompat/res/drawable/notification_bg.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2016 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:exitFadeDuration="@android:integer/config_mediumAnimTime">
+
+    <item android:state_pressed="true"
+        android:drawable="@drawable/notification_bg_normal_pressed" />
+    <item android:state_pressed="false" android:drawable="@drawable/notification_bg_normal" />
+</selector>
\ No newline at end of file
diff --git a/v7/appcompat/res/drawable/notification_bg_low.xml b/v7/appcompat/res/drawable/notification_bg_low.xml
new file mode 100644
index 0000000..72e58ae
--- /dev/null
+++ b/v7/appcompat/res/drawable/notification_bg_low.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2016 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:exitFadeDuration="@android:integer/config_mediumAnimTime">
+
+    <item android:state_pressed="true"  android:drawable="@drawable/notification_bg_low_pressed" />
+    <item android:state_pressed="false" android:drawable="@drawable/notification_bg_low_normal" />
+</selector>
\ No newline at end of file
diff --git a/v7/appcompat/res/drawable/notification_icon_background.xml b/v7/appcompat/res/drawable/notification_icon_background.xml
new file mode 100644
index 0000000..490a797
--- /dev/null
+++ b/v7/appcompat/res/drawable/notification_icon_background.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2016 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
+  -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="oval">
+    <solid
+        android:color="@color/notification_icon_bg_color"/>
+</shape>
\ No newline at end of file
diff --git a/v7/appcompat/res/drawable/notification_tile_bg.xml b/v7/appcompat/res/drawable/notification_tile_bg.xml
new file mode 100644
index 0000000..8eee7ef
--- /dev/null
+++ b/v7/appcompat/res/drawable/notification_tile_bg.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2016 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:tileMode="repeat"
+    android:src="@drawable/notify_panel_notification_icon_bg"
+/>
\ No newline at end of file
diff --git a/v7/appcompat/res/layout-v16/notification_template_custom_big.xml b/v7/appcompat/res/layout-v16/notification_template_custom_big.xml
new file mode 100644
index 0000000..24c3323
--- /dev/null
+++ b/v7/appcompat/res/layout-v16/notification_template_custom_big.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2016 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
+  -->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/notification_background"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content" >
+    <ImageView android:id="@+id/icon"
+        android:layout_width="@dimen/notification_large_icon_width"
+        android:layout_height="@dimen/notification_large_icon_height"
+        android:scaleType="center"
+    />
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="top"
+        android:orientation="vertical" >
+        <LinearLayout
+            android:id="@+id/notification_main_column_container"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="@dimen/notification_large_icon_width"
+            android:layout_marginStart="@dimen/notification_large_icon_width"
+            android:paddingTop="@dimen/notification_main_column_padding_top"
+            android:minHeight="@dimen/notification_large_icon_height"
+            android:orientation="horizontal">
+            <FrameLayout
+                android:id="@+id/notification_main_column"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:layout_marginLeft="@dimen/notification_content_margin_start"
+                android:layout_marginStart="@dimen/notification_content_margin_start"
+                android:layout_marginBottom="8dp"
+                android:layout_marginRight="8dp"
+                android:layout_marginEnd="8dp" />
+            <FrameLayout
+                android:id="@+id/right_side"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginRight="8dp"
+                android:layout_marginEnd="8dp"
+                android:paddingTop="@dimen/notification_right_side_padding_top">
+                <ViewStub android:id="@+id/time"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="end|top"
+                    android:visibility="gone"
+                    android:layout="@layout/notification_template_part_time" />
+                <ViewStub android:id="@+id/chronometer"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="end|top"
+                    android:visibility="gone"
+                    android:layout="@layout/notification_template_part_chronometer" />
+                <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:orientation="horizontal"
+                    android:layout_gravity="end|bottom"
+                    android:layout_marginTop="20dp">
+                    <TextView android:id="@+id/info"
+                        android:textAppearance="@style/TextAppearance.AppCompat.Notification.Info"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:singleLine="true"
+                    />
+                    <ImageView android:id="@+id/right_icon"
+                        android:layout_width="16dp"
+                        android:layout_height="16dp"
+                        android:layout_gravity="center"
+                        android:layout_marginLeft="8dp"
+                        android:layout_marginStart="8dp"
+                        android:scaleType="centerInside"
+                        android:visibility="gone"
+                        android:alpha="0.6"
+                    />
+                </LinearLayout>
+            </FrameLayout>
+        </LinearLayout>
+        <ImageView
+            android:layout_width="match_parent"
+            android:layout_height="1px"
+            android:id="@+id/action_divider"
+            android:visibility="gone"
+            android:layout_marginLeft="@dimen/notification_large_icon_width"
+            android:layout_marginStart="@dimen/notification_large_icon_width"
+            android:background="?android:attr/dividerHorizontal" />
+        <LinearLayout
+            android:id="@+id/actions"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal"
+            android:visibility="gone"
+            android:showDividers="middle"
+            android:divider="?android:attr/listDivider"
+            android:dividerPadding="12dp"
+            android:layout_marginLeft="@dimen/notification_large_icon_width"
+            android:layout_marginStart="@dimen/notification_large_icon_width" >
+            <!-- actions will be added here -->
+        </LinearLayout>
+    </LinearLayout>
+</FrameLayout>
\ No newline at end of file
diff --git a/v7/appcompat/res/layout-v21/notification_action.xml b/v7/appcompat/res/layout-v21/notification_action.xml
new file mode 100644
index 0000000..c60bf7d
--- /dev/null
+++ b/v7/appcompat/res/layout-v21/notification_action.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2016 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"
+    style="@style/Widget.AppCompat.NotificationActionContainer"
+    android:id="@+id/action_container"
+    android:layout_width="0dp"
+    android:layout_weight="1"
+    android:layout_height="48dp"
+    android:paddingStart="4dp"
+    android:orientation="horizontal">
+    <ImageView
+        android:id="@+id/action_image"
+        android:layout_width="@dimen/notification_action_icon_size"
+        android:layout_height="@dimen/notification_action_icon_size"
+        android:layout_gravity="center|start"
+        android:scaleType="centerInside"/>
+    <TextView
+        style="@style/Widget.AppCompat.NotificationActionText"
+        android:id="@+id/action_text"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center|start"
+        android:paddingStart="4dp"
+        android:singleLine="true"
+        android:ellipsize="end"
+        android:clickable="false"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/v7/appcompat/res/layout-v21/notification_action_tombstone.xml b/v7/appcompat/res/layout-v21/notification_action_tombstone.xml
new file mode 100644
index 0000000..1637c6f
--- /dev/null
+++ b/v7/appcompat/res/layout-v21/notification_action_tombstone.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2016 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"
+    style="@style/Widget.AppCompat.NotificationActionContainer"
+    android:id="@+id/action_container"
+    android:layout_width="0dp"
+    android:layout_weight="1"
+    android:layout_height="48dp"
+    android:paddingStart="4dp"
+    android:orientation="horizontal"
+    android:enabled="false"
+    android:background="@null">
+    <ImageView
+        android:id="@+id/action_image"
+        android:layout_width="@dimen/notification_action_icon_size"
+        android:layout_height="@dimen/notification_action_icon_size"
+        android:layout_gravity="center|start"
+        android:scaleType="centerInside"
+        android:enabled="false"
+        android:alpha="0.5"/>
+    <TextView
+        style="@style/Widget.AppCompat.NotificationActionText"
+        android:id="@+id/action_text"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center|start"
+        android:paddingStart="4dp"
+        android:singleLine="true"
+        android:ellipsize="end"
+        android:clickable="false"
+        android:enabled="false"
+        android:alpha="0.5"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/v7/appcompat/res/layout-v21/notification_template_custom_big.xml b/v7/appcompat/res/layout-v21/notification_template_custom_big.xml
new file mode 100644
index 0000000..38332bd
--- /dev/null
+++ b/v7/appcompat/res/layout-v21/notification_template_custom_big.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2016 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
+  -->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/notification_background"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content" >
+    <include layout="@layout/notification_template_icon_group"
+        android:layout_width="@dimen/notification_large_icon_width"
+        android:layout_height="@dimen/notification_large_icon_height"
+    />
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="top"
+        android:layout_marginStart="@dimen/notification_large_icon_width"
+        android:orientation="vertical" >
+        <LinearLayout
+            android:id="@+id/notification_main_column_container"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:minHeight="@dimen/notification_large_icon_height"
+            android:orientation="horizontal">
+            <FrameLayout
+                android:id="@+id/notification_main_column"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:layout_marginEnd="8dp"
+                android:layout_marginBottom="8dp"/>
+            <FrameLayout
+                android:id="@+id/right_side"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginEnd="8dp"
+                android:paddingTop="@dimen/notification_right_side_padding_top">
+                <ViewStub android:id="@+id/time"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="end|top"
+                    android:visibility="gone"
+                    android:layout="@layout/notification_template_part_time" />
+                <ViewStub android:id="@+id/chronometer"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="end|top"
+                    android:visibility="gone"
+                    android:layout="@layout/notification_template_part_chronometer" />
+                <TextView android:id="@+id/info"
+                    android:textAppearance="@style/TextAppearance.AppCompat.Notification.Info"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="20dp"
+                    android:layout_gravity="end|bottom"
+                    android:singleLine="true"
+                />
+            </FrameLayout>
+        </LinearLayout>
+        <ImageView
+            android:layout_width="match_parent"
+            android:layout_height="1dp"
+            android:id="@+id/action_divider"
+            android:visibility="gone"
+            android:background="#29000000" />
+        <LinearLayout
+            android:id="@+id/actions"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="-8dp"
+            android:orientation="horizontal"
+            android:visibility="gone"
+        >
+            <!-- actions will be added here -->
+        </LinearLayout>
+    </LinearLayout>
+</FrameLayout>
\ No newline at end of file
diff --git a/v7/appcompat/res/layout-v21/notification_template_icon_group.xml b/v7/appcompat/res/layout-v21/notification_template_icon_group.xml
new file mode 100644
index 0000000..6c19022
--- /dev/null
+++ b/v7/appcompat/res/layout-v21/notification_template_icon_group.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2016 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
+  -->
+
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="@dimen/notification_large_icon_width"
+    android:layout_height="@dimen/notification_large_icon_height"
+    android:id="@+id/icon_group"
+>
+    <ImageView android:id="@+id/icon"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_marginTop="@dimen/notification_big_circle_margin"
+        android:layout_marginBottom="@dimen/notification_big_circle_margin"
+        android:layout_marginStart="@dimen/notification_big_circle_margin"
+        android:layout_marginEnd="@dimen/notification_big_circle_margin"
+        android:scaleType="centerInside"
+    />
+    <ImageView android:id="@+id/right_icon"
+        android:layout_width="@dimen/notification_right_icon_size"
+        android:layout_height="@dimen/notification_right_icon_size"
+        android:layout_gravity="end|bottom"
+        android:scaleType="centerInside"
+        android:visibility="gone"
+        android:layout_marginEnd="8dp"
+        android:layout_marginBottom="8dp"
+    />
+</FrameLayout>
+
diff --git a/v7/appcompat/res/layout/notification_action.xml b/v7/appcompat/res/layout/notification_action.xml
new file mode 100644
index 0000000..82e95a5
--- /dev/null
+++ b/v7/appcompat/res/layout/notification_action.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2016 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"
+    style="@style/Widget.AppCompat.NotificationActionContainer"
+    android:id="@+id/action_container"
+    android:layout_width="0dp"
+    android:layout_weight="1"
+    android:layout_height="48dp"
+    android:paddingLeft="4dp"
+    android:paddingStart="4dp"
+    android:orientation="horizontal">
+    <ImageView
+        android:id="@+id/action_image"
+        android:layout_width="@dimen/notification_action_icon_size"
+        android:layout_height="@dimen/notification_action_icon_size"
+        android:layout_gravity="center|start"
+        android:scaleType="centerInside"/>
+    <TextView
+        style="@style/Widget.AppCompat.NotificationActionText"
+        android:id="@+id/action_text"
+        android:textColor="#ccc"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center|start"
+        android:paddingLeft="4dp"
+        android:paddingStart="4dp"
+        android:singleLine="true"
+        android:ellipsize="end"
+        android:clickable="false"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/v7/appcompat/res/layout/notification_action_tombstone.xml b/v7/appcompat/res/layout/notification_action_tombstone.xml
new file mode 100644
index 0000000..d491c78
--- /dev/null
+++ b/v7/appcompat/res/layout/notification_action_tombstone.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2016 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"
+    style="@style/Widget.AppCompat.NotificationActionContainer"
+    android:id="@+id/action_container"
+    android:layout_width="0dp"
+    android:layout_weight="1"
+    android:layout_height="48dp"
+    android:paddingLeft="4dp"
+    android:paddingStart="4dp"
+    android:orientation="horizontal"
+    android:enabled="false"
+    android:background="@null">
+    <ImageView
+        android:id="@+id/action_image"
+        android:layout_width="@dimen/notification_action_icon_size"
+        android:layout_height="@dimen/notification_action_icon_size"
+        android:layout_gravity="center|start"
+        android:scaleType="centerInside"
+        android:enabled="false"
+        android:alpha="0.5"/>
+    <TextView
+        style="@style/Widget.AppCompat.NotificationActionText"
+        android:id="@+id/action_text"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center|start"
+        android:textColor="#ccc"
+        android:paddingLeft="4dp"
+        android:paddingStart="4dp"
+        android:singleLine="true"
+        android:ellipsize="end"
+        android:clickable="false"
+        android:enabled="false"
+        android:alpha="0.5"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/v7/appcompat/res/layout/notification_template_big_media.xml b/v7/appcompat/res/layout/notification_template_big_media.xml
index 2e40b69..b72fd97 100644
--- a/v7/appcompat/res/layout/notification_template_big_media.xml
+++ b/v7/appcompat/res/layout/notification_template_big_media.xml
@@ -20,18 +20,18 @@
     android:layout_width="match_parent"
     android:layout_height="128dp"
     >
-    <ImageView android:id="@+id/icon"
+    <include layout="@layout/notification_template_icon_group"
         android:layout_width="@dimen/notification_large_icon_width"
         android:layout_height="@dimen/notification_large_icon_height"
-        android:scaleType="centerCrop"
-        />
+    />
     <include layout="@layout/notification_media_cancel_action"
         android:layout_width="48dp"
         android:layout_height="48dp"
         android:layout_marginLeft="2dp"
         android:layout_marginRight="2dp"
-        android:layout_alignParentRight="true"/>
-    <include layout="@layout/notification_template_lines"
+        android:layout_alignParentRight="true"
+        android:layout_alignParentEnd="true" />
+    <include layout="@layout/notification_template_lines_media"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:layout_gravity="fill_vertical"
diff --git a/v7/appcompat/res/layout/notification_template_big_media_custom.xml b/v7/appcompat/res/layout/notification_template_big_media_custom.xml
new file mode 100644
index 0000000..c88d799
--- /dev/null
+++ b/v7/appcompat/res/layout/notification_template_big_media_custom.xml
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2016 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
+  -->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/status_bar_latest_event_content"
+    android:layout_width="match_parent"
+    android:layout_height="128dp"
+    >
+    <include layout="@layout/notification_template_icon_group"
+        android:layout_width="@dimen/notification_large_icon_width"
+        android:layout_height="@dimen/notification_large_icon_height"
+    />
+    <include layout="@layout/notification_media_cancel_action"
+        android:layout_width="48dp"
+        android:layout_height="48dp"
+        android:layout_marginLeft="2dp"
+        android:layout_marginRight="2dp"
+        android:layout_alignParentRight="true"
+        android:layout_alignParentEnd="true"/>
+    <LinearLayout
+        android:id="@+id/notification_main_column_container"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="@dimen/notification_large_icon_height"
+        android:layout_marginStart="@dimen/notification_large_icon_height"
+        android:minHeight="@dimen/notification_large_icon_height"
+        android:paddingTop="@dimen/notification_main_column_padding_top"
+        android:orientation="horizontal"
+        android:layout_toLeftOf="@id/cancel_action"
+        android:layout_toStartOf="@id/cancel_action">
+        <FrameLayout
+            android:id="@+id/notification_main_column"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:layout_marginLeft="@dimen/notification_content_margin_start"
+            android:layout_marginStart="@dimen/notification_content_margin_start"
+            android:layout_marginRight="8dp"
+            android:layout_marginEnd="8dp"
+            android:layout_marginBottom="8dp"
+        />
+        <FrameLayout
+            android:id="@+id/right_side"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginRight="8dp"
+            android:layout_marginEnd="8dp"
+            android:paddingTop="@dimen/notification_right_side_padding_top">
+            <DateTimeView android:id="@+id/time"
+                android:textAppearance="@style/TextAppearance.AppCompat.Notification.Time.Media"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:singleLine="true"
+                android:layout_gravity="end|top"
+                android:visibility="gone"
+            />
+            <Chronometer android:id="@+id/chronometer"
+                android:textAppearance="@style/TextAppearance.AppCompat.Notification.Time.Media"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:singleLine="true"
+                android:layout_gravity="end|top"
+                android:visibility="gone"
+            />
+            <TextView android:id="@+id/info"
+                android:textAppearance="@style/TextAppearance.AppCompat.Notification.Info.Media"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="20dp"
+                android:layout_gravity="end|bottom"
+                android:singleLine="true"
+            />
+        </FrameLayout>
+    </LinearLayout>
+    <LinearLayout
+        android:id="@+id/media_actions"
+        android:layout_width="match_parent"
+        android:layout_height="48dp"
+        android:layout_alignParentBottom="true"
+        android:layout_marginLeft="12dp"
+        android:layout_marginRight="12dp"
+        android:orientation="horizontal"
+        android:layoutDirection="ltr"
+        >
+        <!-- media buttons will be added here -->
+    </LinearLayout>
+    <ImageView
+        android:layout_width="match_parent"
+        android:layout_height="1dp"
+        android:layout_above="@id/media_actions"
+        android:id="@+id/action_divider"
+        android:background="?android:attr/dividerHorizontal" />
+</RelativeLayout>
diff --git a/v7/appcompat/res/layout/notification_template_big_media_narrow.xml b/v7/appcompat/res/layout/notification_template_big_media_narrow.xml
index cf64061..979c8f4 100644
--- a/v7/appcompat/res/layout/notification_template_big_media_narrow.xml
+++ b/v7/appcompat/res/layout/notification_template_big_media_narrow.xml
@@ -35,7 +35,7 @@
         android:layout_alignParentRight="true"
         android:layout_alignParentEnd="true"/>
 
-    <include layout="@layout/notification_template_lines"
+    <include layout="@layout/notification_template_lines_media"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:layout_marginLeft="128dp"
diff --git a/v7/appcompat/res/layout/notification_template_big_media_narrow_custom.xml b/v7/appcompat/res/layout/notification_template_big_media_narrow_custom.xml
new file mode 100644
index 0000000..b7fbff7
--- /dev/null
+++ b/v7/appcompat/res/layout/notification_template_big_media_narrow_custom.xml
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2016 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
+  -->
+
+<!-- Layout to be used with only max 3 actions. It has a much larger picture at the left side-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/status_bar_latest_event_content"
+    android:layout_width="match_parent"
+    android:layout_height="128dp"
+    >
+    <ImageView android:id="@+id/icon"
+        android:layout_width="128dp"
+        android:layout_height="128dp"
+        android:scaleType="centerCrop"
+        />
+
+    <include layout="@layout/notification_media_cancel_action"
+        android:layout_width="48dp"
+        android:layout_height="48dp"
+        android:layout_marginLeft="2dp"
+        android:layout_marginRight="2dp"
+        android:layout_alignParentRight="true"
+        android:layout_alignParentEnd="true"/>
+
+    <LinearLayout
+        android:id="@+id/notification_main_column_container"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="128dp"
+        android:layout_marginStart="128dp"
+        android:minHeight="@dimen/notification_large_icon_height"
+        android:paddingTop="@dimen/notification_main_column_padding_top"
+        android:orientation="horizontal"
+        android:layout_toLeftOf="@id/cancel_action"
+        android:layout_toStartOf="@id/cancel_action">
+        <FrameLayout
+            android:id="@+id/notification_main_column"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:layout_marginLeft="@dimen/notification_media_narrow_margin"
+            android:layout_marginStart="@dimen/notification_media_narrow_margin"
+            android:layout_marginRight="8dp"
+            android:layout_marginEnd="8dp"
+            android:layout_marginBottom="8dp"/>
+        <FrameLayout
+            android:id="@+id/right_side"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginRight="8dp"
+            android:layout_marginEnd="8dp"
+            android:paddingTop="@dimen/notification_right_side_padding_top">
+            <DateTimeView android:id="@+id/time"
+                android:textAppearance="@style/TextAppearance.AppCompat.Notification.Time.Media"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:singleLine="true"
+                android:layout_gravity="end|top"
+                android:visibility="gone"
+            />
+            <Chronometer android:id="@+id/chronometer"
+                android:textAppearance="@style/TextAppearance.AppCompat.Notification.Time.Media"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:singleLine="true"
+                android:layout_gravity="end|top"
+                android:visibility="gone"
+            />
+            <TextView android:id="@+id/info"
+                android:textAppearance="@style/TextAppearance.AppCompat.Notification.Info.Media"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="20dp"
+                android:layout_gravity="end|bottom"
+                android:singleLine="true"
+            />
+        </FrameLayout>
+    </LinearLayout>
+
+    <LinearLayout
+        android:id="@+id/media_actions"
+        android:layout_width="match_parent"
+        android:layout_height="48dp"
+        android:layout_toRightOf="@id/icon"
+        android:layout_toEndOf="@id/icon"
+        android:layout_alignParentBottom="true"
+        android:layout_marginLeft="12dp"
+        android:layout_marginRight="12dp"
+        android:orientation="horizontal"
+        android:layoutDirection="ltr"
+        >
+        <!-- media buttons will be added here -->
+    </LinearLayout>
+    <ImageView
+        android:layout_width="match_parent"
+        android:layout_height="1dp"
+        android:layout_toRightOf="@id/icon"
+        android:layout_toEndOf="@id/icon"
+        android:layout_above="@id/media_actions"
+        android:id="@+id/action_divider"
+        android:background="?android:attr/dividerHorizontal" />
+</RelativeLayout>
diff --git a/v7/appcompat/res/layout/notification_template_custom_big.xml b/v7/appcompat/res/layout/notification_template_custom_big.xml
new file mode 100644
index 0000000..c922629
--- /dev/null
+++ b/v7/appcompat/res/layout/notification_template_custom_big.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2016 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 android:id="@+id/notification_main_column_container"
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:minHeight="@dimen/notification_large_icon_height"
+    android:orientation="horizontal"
+    android:paddingRight="12dp"
+    android:paddingEnd="12dp">
+    <ImageView android:id="@+id/icon"
+        android:layout_width="@dimen/notification_large_icon_width"
+        android:layout_height="@dimen/notification_large_icon_height"
+        android:background="@drawable/notification_tile_bg"
+        android:scaleType="center"
+    />
+    <FrameLayout
+        android:id="@+id/notification_main_column"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingLeft="12dp"
+        android:paddingStart="12dp"
+        android:paddingTop="@dimen/notification_main_column_padding_top"
+        android:layout_weight="1"/>
+    <FrameLayout
+        android:id="@+id/right_side"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:paddingTop="12dp"
+        android:paddingLeft="12dp">
+        <include
+            layout="@layout/notification_template_part_time"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="end|top"
+            android:visibility="gone"/>
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="end|bottom"
+            android:layout_marginTop="18dp"
+            android:orientation="horizontal">
+            <TextView android:id="@+id/info"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center"
+                android:singleLine="true"
+                android:textAppearance="@style/TextAppearance.AppCompat.Notification.Info"
+            />
+            <ImageView android:id="@+id/right_icon"
+                android:layout_width="24dp"
+                android:layout_height="24dp"
+                android:layout_gravity="center"
+                android:layout_marginLeft="8dp"
+                android:alpha="0.7"
+                android:scaleType="center"
+                android:visibility="gone"
+            />
+        </LinearLayout>
+    </FrameLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/v7/appcompat/res/layout/notification_template_icon_group.xml b/v7/appcompat/res/layout/notification_template_icon_group.xml
new file mode 100644
index 0000000..dd564f8
--- /dev/null
+++ b/v7/appcompat/res/layout/notification_template_icon_group.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2016 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
+  -->
+
+<ImageView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/icon"
+    android:layout_width="@dimen/notification_large_icon_width"
+    android:layout_height="@dimen/notification_large_icon_height"
+    android:scaleType="centerCrop"
+/>
+
diff --git a/v7/appcompat/res/layout/notification_template_lines.xml b/v7/appcompat/res/layout/notification_template_lines_media.xml
similarity index 70%
rename from v7/appcompat/res/layout/notification_template_lines.xml
rename to v7/appcompat/res/layout/notification_template_lines_media.xml
index 42ba776..9a7b788 100644
--- a/v7/appcompat/res/layout/notification_template_lines.xml
+++ b/v7/appcompat/res/layout/notification_template_lines_media.xml
@@ -29,12 +29,12 @@
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:paddingTop="6dp"
-        android:layout_marginLeft="8dp"
-        android:layout_marginStart="8dp"
+        android:layout_marginLeft="@dimen/notification_content_margin_start"
+        android:layout_marginStart="@dimen/notification_content_margin_start"
         android:orientation="horizontal"
         >
         <TextView android:id="@+id/title"
-            android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Title"
+            android:textAppearance="@style/TextAppearance.AppCompat.Notification.Title.Media"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:singleLine="true"
@@ -42,33 +42,37 @@
             android:fadingEdge="horizontal"
             android:layout_weight="1"
             />
-        <include
-            layout="@layout/notification_template_part_time"
-            android:id="@+id/time"
+        <DateTimeView android:id="@+id/time"
+            android:textAppearance="@style/TextAppearance.AppCompat.Notification.Time.Media"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            android:singleLine="true"
             android:layout_gravity="center"
             android:layout_weight="0"
             android:visibility="gone"
-            />
-        <include
-            layout="@layout/notification_template_part_chronometer"
-            android:id="@+id/chronometer"
+            android:paddingLeft="8dp"
+            android:paddingStart="8dp"
+        />
+        <Chronometer android:id="@+id/chronometer"
+            android:textAppearance="@style/TextAppearance.AppCompat.Notification.Time.Media"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            android:singleLine="true"
             android:layout_gravity="center"
             android:layout_weight="0"
             android:visibility="gone"
-            />
+            android:paddingLeft="8dp"
+            android:paddingStart="8dp"
+        />
     </LinearLayout>
     <TextView android:id="@+id/text2"
-        android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Line2"
+        android:textAppearance="@style/TextAppearance.AppCompat.Notification.Line2.Media"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:layout_marginTop="-2dp"
         android:layout_marginBottom="-2dp"
-        android:layout_marginLeft="8dp"
-        android:layout_marginStart="8dp"
+        android:layout_marginLeft="@dimen/notification_content_margin_start"
+        android:layout_marginStart="@dimen/notification_content_margin_start"
         android:singleLine="true"
         android:fadingEdge="horizontal"
         android:ellipsize="marquee"
@@ -80,11 +84,11 @@
         android:layout_height="wrap_content"
         android:orientation="horizontal"
         android:gravity="center_vertical"
-        android:layout_marginLeft="8dp"
-        android:layout_marginStart="8dp"
+        android:layout_marginLeft="@dimen/notification_content_margin_start"
+        android:layout_marginStart="@dimen/notification_content_margin_start"
         >
         <TextView android:id="@+id/text"
-            android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
+            android:textAppearance="@style/TextAppearance.AppCompat.Notification.Media"
             android:layout_width="0dp"
             android:layout_height="wrap_content"
             android:layout_weight="1"
@@ -94,7 +98,7 @@
             android:fadingEdge="horizontal"
             />
         <TextView android:id="@+id/info"
-            android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info"
+            android:textAppearance="@style/TextAppearance.AppCompat.Notification.Info.Media"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_gravity="center"
diff --git a/v7/appcompat/res/layout/notification_template_media.xml b/v7/appcompat/res/layout/notification_template_media.xml
index 90daa88..6eac23b7 100644
--- a/v7/appcompat/res/layout/notification_template_media.xml
+++ b/v7/appcompat/res/layout/notification_template_media.xml
@@ -21,12 +21,11 @@
     android:layout_height="64dp"
     android:orientation="horizontal"
     >
-    <ImageView android:id="@+id/icon"
+    <include layout="@layout/notification_template_icon_group"
         android:layout_width="@dimen/notification_large_icon_width"
-        android:layout_height="@dimen/notification_large_icon_width"
-        android:scaleType="centerCrop"
-        />
-    <include layout="@layout/notification_template_lines"
+        android:layout_height="@dimen/notification_large_icon_height"
+    />
+    <include layout="@layout/notification_template_lines_media"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
         android:layout_weight="1"/>
diff --git a/v7/appcompat/res/layout/notification_template_media_custom.xml b/v7/appcompat/res/layout/notification_template_media_custom.xml
new file mode 100644
index 0000000..62e07d4
--- /dev/null
+++ b/v7/appcompat/res/layout/notification_template_media_custom.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2015 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/status_bar_latest_event_content"
+    android:layout_width="match_parent"
+    android:layout_height="64dp"
+    android:orientation="horizontal"
+    >
+    <include layout="@layout/notification_template_icon_group"
+        android:layout_width="@dimen/notification_large_icon_width"
+        android:layout_height="@dimen/notification_large_icon_height"
+    />
+    <LinearLayout
+        android:id="@+id/notification_main_column_container"
+        android:layout_width="0dp"
+        android:layout_weight="1"
+        android:layout_height="wrap_content"
+        android:paddingTop="@dimen/notification_main_column_padding_top"
+        android:minHeight="@dimen/notification_large_icon_height"
+        android:orientation="horizontal"
+        android:layout_toLeftOf="@id/cancel_action"
+        android:layout_toStartOf="@id/cancel_action">
+        <FrameLayout
+            android:id="@+id/notification_main_column"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:layout_marginLeft="@dimen/notification_content_margin_start"
+            android:layout_marginStart="@dimen/notification_content_margin_start"
+            android:layout_marginRight="8dp"
+            android:layout_marginEnd="8dp"
+            android:layout_marginBottom="8dp"/>
+        <FrameLayout
+            android:id="@+id/right_side"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginRight="8dp"
+            android:layout_marginEnd="8dp"
+            android:paddingTop="@dimen/notification_right_side_padding_top">
+            <DateTimeView android:id="@+id/time"
+                android:textAppearance="@style/TextAppearance.AppCompat.Notification.Time.Media"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:singleLine="true"
+                android:layout_gravity="end|top"
+                android:visibility="gone"
+            />
+            <Chronometer android:id="@+id/chronometer"
+                android:textAppearance="@style/TextAppearance.AppCompat.Notification.Time.Media"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:singleLine="true"
+                android:layout_gravity="end|top"
+                android:visibility="gone"
+            />
+            <TextView android:id="@+id/info"
+                android:textAppearance="@style/TextAppearance.AppCompat.Notification.Info.Media"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="20dp"
+                android:layout_gravity="end|bottom"
+                android:singleLine="true"
+            />
+        </FrameLayout>
+    </LinearLayout>
+    <LinearLayout
+        android:id="@+id/media_actions"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:layout_gravity="center_vertical|end"
+        android:orientation="horizontal"
+        android:layoutDirection="ltr"
+        >
+        <!-- media buttons will be added here -->
+    </LinearLayout>
+    <include layout="@layout/notification_media_cancel_action"
+        android:layout_width="48dp"
+        android:layout_height="match_parent"
+        android:layout_marginRight="6dp"
+        android:layout_marginEnd="6dp"/>
+    <ImageView android:id="@+id/end_padder"
+        android:layout_width="6dp"
+        android:layout_height="match_parent"
+        />
+</LinearLayout>
diff --git a/v7/appcompat/res/layout/notification_template_part_chronometer.xml b/v7/appcompat/res/layout/notification_template_part_chronometer.xml
index 6f5f3ac..9e58a38 100644
--- a/v7/appcompat/res/layout/notification_template_part_chronometer.xml
+++ b/v7/appcompat/res/layout/notification_template_part_chronometer.xml
@@ -16,13 +16,8 @@
   -->
 
 <Chronometer android:id="@+id/chronometer" xmlns:android="http://schemas.android.com/apk/res/android"
-    android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Time"
+    android:textAppearance="@style/TextAppearance.AppCompat.Notification.Time"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
-    android:layout_gravity="center"
-    android:layout_weight="0"
     android:singleLine="true"
-    android:gravity="center"
-    android:paddingLeft="8dp"
-    android:paddingStart="8dp"
     />
diff --git a/v7/appcompat/res/layout/notification_template_part_time.xml b/v7/appcompat/res/layout/notification_template_part_time.xml
index 72d216e..810d1e3 100644
--- a/v7/appcompat/res/layout/notification_template_part_time.xml
+++ b/v7/appcompat/res/layout/notification_template_part_time.xml
@@ -16,13 +16,8 @@
   -->
 
 <DateTimeView android:id="@+id/time" xmlns:android="http://schemas.android.com/apk/res/android"
-    android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Time"
+    android:textAppearance="@style/TextAppearance.AppCompat.Notification.Time"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
-    android:layout_gravity="center"
-    android:layout_weight="0"
     android:singleLine="true"
-    android:gravity="center"
-    android:paddingLeft="8dp"
-    android:paddingStart="8dp"
     />
diff --git a/v7/appcompat/res/values-v14/styles.xml b/v7/appcompat/res/values-v14/styles.xml
index f54796d..39419d2 100644
--- a/v7/appcompat/res/values-v14/styles.xml
+++ b/v7/appcompat/res/values-v14/styles.xml
@@ -30,4 +30,9 @@
     <style name="TextAppearance.StatusBar.EventContent.Info"/>
     <style name="TextAppearance.StatusBar.EventContent.Time"/>
 
+    <style name="TextAppearance.AppCompat.Notification.Title"
+        parent="@android:style/TextAppearance.StatusBar.EventContent.Title"/>
+
+    <style name="TextAppearance.AppCompat.Notification"
+        parent="@android:style/TextAppearance.StatusBar.EventContent"/>
 </resources>
\ No newline at end of file
diff --git a/v7/appcompat/res/values-v16/dimens.xml b/v7/appcompat/res/values-v16/dimens.xml
new file mode 100644
index 0000000..3280f7b
--- /dev/null
+++ b/v7/appcompat/res/values-v16/dimens.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2016 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>
+    <!-- the paddingtop on the right side of the notification (for time etc.) -->
+    <dimen name="notification_right_side_padding_top">4dp</dimen>
+</resources>
diff --git a/v7/appcompat/res/values-v21/colors.xml b/v7/appcompat/res/values-v21/colors.xml
new file mode 100644
index 0000000..4a1b209
--- /dev/null
+++ b/v7/appcompat/res/values-v21/colors.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2016 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>
+    <color name="notification_action_color_filter">@color/secondary_text_default_material_light</color>
+</resources>
\ No newline at end of file
diff --git a/v7/appcompat/res/values-v21/dimens.xml b/v7/appcompat/res/values-v21/dimens.xml
new file mode 100644
index 0000000..de665a6
--- /dev/null
+++ b/v7/appcompat/res/values-v21/dimens.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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>
+    <!-- the margin at the beginning of the notification content -->
+    <dimen name="notification_content_margin_start">0dp</dimen>
+    <!-- image margin on the large icon in the narrow media template -->
+    <dimen name="notification_media_narrow_margin">12dp</dimen>
+    <!-- the top padding of the notification content -->
+    <dimen name="notification_main_column_padding_top">0dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/v7/appcompat/res/values-v21/styles.xml b/v7/appcompat/res/values-v21/styles.xml
new file mode 100644
index 0000000..1c435ae
--- /dev/null
+++ b/v7/appcompat/res/values-v21/styles.xml
@@ -0,0 +1,58 @@
+<!--
+  ~ Copyright (C) 2016 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>
+
+    <!-- Use platform styles -->
+    <style name="TextAppearance.AppCompat.Notification.Info"
+        parent="@android:style/TextAppearance.Material.Notification.Info"/>
+
+    <style name="TextAppearance.AppCompat.Notification.Time"
+        parent="@android:style/TextAppearance.Material.Notification.Time"/>
+
+    <style name="TextAppearance.AppCompat.Notification.Title"
+        parent="@android:style/TextAppearance.Material.Notification.Title"/>
+
+    <style name="TextAppearance.AppCompat.Notification"
+        parent="@android:style/TextAppearance.Material.Notification"/>
+
+    <style name="TextAppearance.AppCompat.Notification.Media" >
+        <item name="android:textColor">@color/secondary_text_default_material_dark</item>
+    </style>
+
+    <style name="TextAppearance.AppCompat.Notification.Title.Media" >
+        <item name="android:textColor">@color/primary_text_default_material_dark</item>
+    </style>
+
+    <style name="TextAppearance.AppCompat.Notification.Info.Media">
+        <item name="android:textColor">@color/secondary_text_default_material_dark</item>
+    </style>
+
+    <style name="TextAppearance.AppCompat.Notification.Time.Media">
+        <item name="android:textColor">@color/secondary_text_default_material_dark</item>
+    </style>
+
+    <style name="Widget.AppCompat.NotificationActionText" parent="">
+        <item name="android:textAppearance">?android:attr/textAppearanceButton</item>
+        <item name="android:textColor">@color/secondary_text_default_material_light</item>
+        <item name="android:textSize">@dimen/notification_action_text_size</item>
+    </style>
+
+    <style name="Widget.AppCompat.NotificationActionContainer" parent="">
+        <item name="android:background">@drawable/notification_action_background</item>
+    </style>
+
+</resources>
\ No newline at end of file
diff --git a/v7/appcompat/res/values-v24/styles.xml b/v7/appcompat/res/values-v24/styles.xml
new file mode 100644
index 0000000..52bb3d4
--- /dev/null
+++ b/v7/appcompat/res/values-v24/styles.xml
@@ -0,0 +1,28 @@
+<!--
+  ~ Copyright (C) 2016 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>
+
+    <!-- Use platform styles, Media is dark again -->
+    <style name="TextAppearance.AppCompat.Notification.Media" />
+
+    <style name="TextAppearance.AppCompat.Notification.Info.Media" />
+
+    <style name="TextAppearance.AppCompat.Notification.Time.Media" />
+
+    <style name="TextAppearance.AppCompat.Notification.Title.Media" />
+
+</resources>
\ No newline at end of file
diff --git a/v7/appcompat/res/values/colors.xml b/v7/appcompat/res/values/colors.xml
index 0ce01d2..92c91fd 100644
--- a/v7/appcompat/res/values/colors.xml
+++ b/v7/appcompat/res/values/colors.xml
@@ -21,4 +21,11 @@
     <color name="abc_input_method_navigation_guard">@android:color/black</color>
 
     <drawable name="notification_template_icon_bg">#3333B5E5</drawable>
+    <drawable name="notification_template_icon_low_bg">#0cffffff</drawable>
+    <color name="notification_action_color_filter">#ffffffff</color>
+    <color name="notification_icon_bg_color">#ff9e9e9e</color>
+
+    <!-- The color of the material notification background for media notifications when no custom
+     color is specified -->
+    <color name="notification_material_background_media_default_color">#ff424242</color>
 </resources>
\ No newline at end of file
diff --git a/v7/appcompat/res/values/dimens.xml b/v7/appcompat/res/values/dimens.xml
index 69928ae..7467beb 100644
--- a/v7/appcompat/res/values/dimens.xml
+++ b/v7/appcompat/res/values/dimens.xml
@@ -103,5 +103,41 @@
 
     <!-- Size of smaller notification text (see TextAppearance.StatusBar.EventContent.Line2, Info,
          Time) -->
-    <dimen name="notification_subtext_size">12dp</dimen>
+    <dimen name="notification_subtext_size">13sp</dimen>
+
+    <!-- Size of notification action text -->
+    <dimen name="notification_action_text_size">13sp</dimen>
+
+    <!-- Top padding for notifications in the standard layout. -->
+    <dimen name="notification_top_pad">10dp</dimen>
+
+    <!-- Top padding for notification when text is large -->
+    <dimen name="notification_top_pad_large_text">5dp</dimen>
+
+    <!-- The size of the action icons -->
+    <dimen name="notification_action_icon_size">32dp</dimen>
+
+    <!-- the size of the small icon on the right of the largeIcon -->
+    <dimen name="notification_right_icon_size">16dp</dimen>
+
+    <!-- the padding of the small icon to the circle -->
+    <dimen name="notification_small_icon_background_padding">3dp</dimen>
+
+    <!-- the side margin of the big notification circle -->
+    <dimen name="notification_big_circle_margin">12dp</dimen>
+
+    <!-- small icon size when placed as large icon -->
+    <dimen name="notification_small_icon_size_as_large">24dp</dimen>
+
+    <!-- the margin at the beginning of the notification content -->
+    <dimen name="notification_content_margin_start">8dp</dimen>
+
+    <!-- image margin on the large icon in the narrow media template -->
+    <dimen name="notification_media_narrow_margin">@dimen/notification_content_margin_start</dimen>
+
+    <!-- the top padding of the notification content -->
+    <dimen name="notification_main_column_padding_top">10dp</dimen>
+
+    <!-- the paddingtop on the right side of the notification (for time etc.) -->
+    <dimen name="notification_right_side_padding_top">2dp</dimen>
 </resources>
diff --git a/v7/appcompat/res/values/styles.xml b/v7/appcompat/res/values/styles.xml
index ad86cbd..ec8bbe1 100644
--- a/v7/appcompat/res/values/styles.xml
+++ b/v7/appcompat/res/values/styles.xml
@@ -329,4 +329,35 @@
     <style name="TextAppearance.StatusBar.EventContent.Line2" parent=""/>
     <style name="TextAppearance.StatusBar.EventContent.Info" parent=""/>
     <style name="TextAppearance.StatusBar.EventContent.Time" parent=""/>
+
+    <style name="TextAppearance.AppCompat.Notification">
+        <item name="android:textSize">14sp</item>
+        <item name="android:textColor">?android:attr/textColorSecondary</item>
+    </style>
+    <style name="TextAppearance.AppCompat.Notification.Title">
+        <item name="android:textSize">16sp</item>
+        <item name="android:textColor">?android:attr/textColorPrimary</item>
+    </style>
+    <style name="TextAppearance.AppCompat.Notification.Info">
+        <item name="android:textSize">12sp</item>
+        <item name="android:textColor">?android:attr/textColorSecondary</item>
+    </style>
+    <style name="TextAppearance.AppCompat.Notification.Time">
+        <item name="android:textSize">12sp</item>
+        <item name="android:textColor">?android:attr/textColorSecondary</item>
+    </style>
+    <style name="TextAppearance.AppCompat.Notification.Line2" parent="TextAppearance.AppCompat.Notification.Info" />
+
+    <style name="TextAppearance.AppCompat.Notification.Title.Media" />
+
+    <style name="TextAppearance.AppCompat.Notification.Media" />
+
+    <style name="TextAppearance.AppCompat.Notification.Info.Media"/>
+
+    <style name="TextAppearance.AppCompat.Notification.Time.Media"/>
+
+    <style name="TextAppearance.AppCompat.Notification.Line2.Media" parent="TextAppearance.AppCompat.Notification.Info.Media"/>
+
+    <style name="Widget.AppCompat.NotificationActionText" parent=""/>
+    <style name="Widget.AppCompat.NotificationActionContainer" parent=""/>
 </resources>
diff --git a/v7/appcompat/src/android/support/v7/app/NotificationCompat.java b/v7/appcompat/src/android/support/v7/app/NotificationCompat.java
index cf4ef60..6215d46 100644
--- a/v7/appcompat/src/android/support/v7/app/NotificationCompat.java
+++ b/v7/appcompat/src/android/support/v7/app/NotificationCompat.java
@@ -22,46 +22,205 @@
 import android.os.Build;
 import android.support.v4.app.NotificationBuilderWithBuilderAccessor;
 import android.support.v4.media.session.MediaSessionCompat;
+import android.support.v7.appcompat.R;
+import android.widget.RemoteViews;
 
 /**
  * An extension of {@link android.support.v4.app.NotificationCompat} which supports
- * {@link android.support.v7.app.NotificationCompat.MediaStyle}. You should start using this variant
- * if you need support for media styled notifications.
+ * {@link android.support.v7.app.NotificationCompat.MediaStyle},
+ * {@link android.support.v7.app.NotificationCompat.DecoratedCustomViewStyle},
+ * and {@link android.support.v7.app.NotificationCompat.DecoratedMediaCustomViewStyle}.
+ * You should start using this variant if you need support any of these styles.
  */
 public class NotificationCompat extends android.support.v4.app.NotificationCompat {
 
-    private static void addMediaStyleToBuilderLollipop(
-            NotificationBuilderWithBuilderAccessor builder, android.support.v4.app.NotificationCompat.Style style) {
-        if (style instanceof MediaStyle) {
-            MediaStyle mediaStyle = (MediaStyle) style;
+    private static void addStyleToBuilderApi24(NotificationBuilderWithBuilderAccessor builder,
+            android.support.v4.app.NotificationCompat.Builder b) {
+        if (b.mStyle instanceof DecoratedCustomViewStyle) {
+            NotificationCompatImpl24.addDecoratedCustomViewStyle(builder);
+        } else if (b.mStyle instanceof DecoratedMediaCustomViewStyle) {
+            NotificationCompatImpl24.addDecoratedMediaCustomViewStyle(builder);
+        } else {
+            addStyleGetContentViewLollipop(builder, b);
+        }
+    }
+
+    private static RemoteViews addStyleGetContentViewLollipop(
+            NotificationBuilderWithBuilderAccessor builder,
+            android.support.v4.app.NotificationCompat.Builder b) {
+        if (b.mStyle instanceof MediaStyle) {
+            MediaStyle mediaStyle = (MediaStyle) b.mStyle;
             NotificationCompatImpl21.addMediaStyle(builder,
                     mediaStyle.mActionsToShowInCompact,
                     mediaStyle.mToken != null ? mediaStyle.mToken.getToken() : null);
+
+            boolean hasContentView = b.getContentView() != null;
+            // If we are on L/M the media notification will only be colored if the expanded version
+            // is of media style, so we have to create a custom view for the collapsed version as
+            // well in that case.
+            boolean isMorL = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP
+                    && Build.VERSION.SDK_INT <= Build.VERSION_CODES.M;
+            boolean createCustomContent = hasContentView
+                    || (isMorL && b.getBigContentView() != null);
+            if (b.mStyle instanceof DecoratedMediaCustomViewStyle && createCustomContent) {
+                RemoteViews contentViewMedia = NotificationCompatImplBase.overrideContentViewMedia(
+                        builder, b.mContext, b.mContentTitle, b.mContentText, b.mContentInfo,
+                        b.mNumber, b.mLargeIcon, b.mSubText, b.mUseChronometer,
+                        b.getWhenIfShowing(), b.getPriority(), b.mActions,
+                        mediaStyle.mActionsToShowInCompact, false /* no cancel button on L */,
+                        null /* cancelButtonIntent */, hasContentView /* isDecoratedCustomView */);
+                if (hasContentView) {
+                    NotificationCompatImplBase.buildIntoRemoteViews(b.mContext, contentViewMedia,
+                            b.getContentView());
+                }
+                setBackgroundColor(b.mContext, contentViewMedia, b.getColor());
+                return contentViewMedia;
+            }
+        } else if (b.mStyle instanceof DecoratedCustomViewStyle) {
+            return getDecoratedContentView(b);
         }
+        return null;
     }
 
-    private static void addMediaStyleToBuilderIcs(NotificationBuilderWithBuilderAccessor builder,
+    private static RemoteViews addStyleGetContentViewIcs(
+            NotificationBuilderWithBuilderAccessor builder,
             android.support.v4.app.NotificationCompat.Builder b) {
         if (b.mStyle instanceof MediaStyle) {
             MediaStyle mediaStyle = (MediaStyle) b.mStyle;
-            NotificationCompatImplBase.overrideContentView(builder, b.mContext,
-                    b.mContentTitle,
-                    b.mContentText, b.mContentInfo, b.mNumber, b.mLargeIcon, b.mSubText,
-                    b.mUseChronometer, b.mNotification.when, b.mActions,
-                    mediaStyle.mActionsToShowInCompact, mediaStyle.mShowCancelButton,
-                    mediaStyle.mCancelButtonIntent);
+            boolean isDecorated = b.mStyle instanceof DecoratedMediaCustomViewStyle
+                    && b.getContentView() != null;
+            RemoteViews contentViewMedia = NotificationCompatImplBase.overrideContentViewMedia(
+                    builder, b.mContext, b.mContentTitle, b.mContentText, b.mContentInfo, b.mNumber,
+                    b.mLargeIcon, b.mSubText, b.mUseChronometer, b.getWhenIfShowing(),
+                    b.getPriority(), b.mActions, mediaStyle.mActionsToShowInCompact,
+                    mediaStyle.mShowCancelButton, mediaStyle.mCancelButtonIntent, isDecorated);
+            if (isDecorated) {
+                NotificationCompatImplBase.buildIntoRemoteViews(b.mContext, contentViewMedia,
+                        b.getContentView());
+                return contentViewMedia;
+            }
+        } else if (b.mStyle instanceof DecoratedCustomViewStyle) {
+            return getDecoratedContentView(b);
         }
+        return null;
     }
 
-    private static void addBigMediaStyleToBuilderJellybean(Notification n,
+    private static void addBigStyleToBuilderJellybean(Notification n,
             android.support.v4.app.NotificationCompat.Builder b) {
         if (b.mStyle instanceof MediaStyle) {
             MediaStyle mediaStyle = (MediaStyle) b.mStyle;
-            NotificationCompatImplBase.overrideBigContentView(n, b.mContext,
-                    b.mContentTitle,
-                    b.mContentText, b.mContentInfo, b.mNumber, b.mLargeIcon, b.mSubText,
-                    b.mUseChronometer, b.mNotification.when, b.mActions,
-                    mediaStyle.mShowCancelButton, mediaStyle.mCancelButtonIntent);
+            RemoteViews innerView = b.getBigContentView() != null
+                    ? b.getBigContentView()
+                    : b.getContentView();
+            boolean isDecorated = b.mStyle instanceof DecoratedMediaCustomViewStyle
+                    && innerView != null;
+            NotificationCompatImplBase.overrideMediaBigContentView(n, b.mContext,
+                    b.mContentTitle, b.mContentText, b.mContentInfo, b.mNumber, b.mLargeIcon,
+                    b.mSubText, b.mUseChronometer, b.getWhenIfShowing(), b.getPriority(), 0,
+                    b.mActions, mediaStyle.mShowCancelButton, mediaStyle.mCancelButtonIntent,
+                    isDecorated);
+            if (isDecorated) {
+                NotificationCompatImplBase.buildIntoRemoteViews(b.mContext, n.bigContentView,
+                        innerView);
+            }
+        } else if (b.mStyle instanceof DecoratedCustomViewStyle) {
+            addDecoratedBigStyleToBuilder(n, b);
+        }
+    }
+
+    private static RemoteViews getDecoratedContentView(
+            android.support.v4.app.NotificationCompat.Builder b) {
+        if (b.getContentView() == null) {
+            // No special content view
+            return null;
+        }
+        RemoteViews remoteViews = NotificationCompatImplBase.applyStandardTemplateWithActions(
+                b.mContext, b.mContentTitle, b.mContentText, b.mContentInfo, b.mNumber,
+                b.mNotification.icon, b.mLargeIcon, b.mSubText, b.mUseChronometer,
+                b.getWhenIfShowing(), b.getPriority(), b.getColor(),
+                R.layout.notification_template_custom_big, false /* fitIn1U */, null /* actions */);
+        NotificationCompatImplBase.buildIntoRemoteViews(b.mContext, remoteViews,
+                b.getContentView());
+        return remoteViews;
+    }
+
+    private static void addDecoratedBigStyleToBuilder(Notification n,
+            android.support.v4.app.NotificationCompat.Builder b) {
+        RemoteViews bigContentView = b.getBigContentView();
+        RemoteViews innerView = bigContentView != null ? bigContentView : b.getContentView();
+        if (innerView == null) {
+            // No expandable notification
+            return;
+        }
+        RemoteViews remoteViews = NotificationCompatImplBase.applyStandardTemplateWithActions(
+                b.mContext, b.mContentTitle, b.mContentText, b.mContentInfo, b.mNumber,
+                n.icon ,b.mLargeIcon, b.mSubText, b.mUseChronometer, b.getWhenIfShowing(),
+                b.getPriority(), b.getColor(), R.layout.notification_template_custom_big,
+                false /* fitIn1U */, b.mActions);
+        NotificationCompatImplBase.buildIntoRemoteViews(b.mContext, remoteViews, innerView);
+        n.bigContentView = remoteViews;
+    }
+
+    private static void addDecoratedHeadsUpToBuilder(Notification n,
+            android.support.v4.app.NotificationCompat.Builder b) {
+        RemoteViews headsUp = b.getHeadsUpContentView();
+        RemoteViews innerView = headsUp != null ? headsUp : b.getContentView();
+        if (headsUp == null) {
+            // No expandable notification
+            return;
+        }
+        RemoteViews remoteViews = NotificationCompatImplBase.applyStandardTemplateWithActions(
+                b.mContext, b.mContentTitle, b.mContentText, b.mContentInfo, b.mNumber, n.icon,
+                b.mLargeIcon, b.mSubText, b.mUseChronometer, b.getWhenIfShowing(), b.getPriority(),
+                b.getColor(), R.layout.notification_template_custom_big, false /* fitIn1U */,
+                b.mActions);
+        NotificationCompatImplBase.buildIntoRemoteViews(b.mContext, remoteViews, innerView);
+        n.headsUpContentView = remoteViews;
+    }
+
+    private static void addBigStyleToBuilderLollipop(Notification n,
+            android.support.v4.app.NotificationCompat.Builder b) {
+        RemoteViews innerView = b.getBigContentView() != null
+                ? b.getBigContentView()
+                : b.getContentView();
+        if (b.mStyle instanceof DecoratedMediaCustomViewStyle && innerView != null) {
+            NotificationCompatImplBase.overrideMediaBigContentView(n, b.mContext,
+                    b.mContentTitle, b.mContentText, b.mContentInfo, b.mNumber, b.mLargeIcon,
+                    b.mSubText, b.mUseChronometer, b.getWhenIfShowing(), b.getPriority(), 0,
+                    b.mActions, false /* showCancelButton */, null /* cancelButtonIntent */,
+                    true /* decoratedCustomView */);
+                    NotificationCompatImplBase.buildIntoRemoteViews(b.mContext, n.bigContentView,
+                            innerView);
+            setBackgroundColor(b.mContext, n.bigContentView, b.getColor());
+        } else if (b.mStyle instanceof DecoratedCustomViewStyle) {
+            addDecoratedBigStyleToBuilder(n, b);
+        }
+    }
+
+    private static void setBackgroundColor(Context context, RemoteViews views, int color) {
+        if (color == COLOR_DEFAULT) {
+            color = context.getResources().getColor(
+                    R.color.notification_material_background_media_default_color);
+        }
+        views.setInt(R.id.status_bar_latest_event_content, "setBackgroundColor", color);
+    }
+
+    private static void addHeadsUpToBuilderLollipop(Notification n,
+            android.support.v4.app.NotificationCompat.Builder b) {
+        RemoteViews innerView = b.getHeadsUpContentView() != null
+                ? b.getHeadsUpContentView()
+                : b.getContentView();
+        if (b.mStyle instanceof DecoratedMediaCustomViewStyle && innerView != null) {
+            n.headsUpContentView = NotificationCompatImplBase.generateMediaBigView(b.mContext,
+                    b.mContentTitle, b.mContentText, b.mContentInfo, b.mNumber,
+                    b.mLargeIcon, b.mSubText, b.mUseChronometer, b.getWhenIfShowing(),
+                    b.getPriority(), 0, b.mActions, false /* showCancelButton */,
+                    null /* cancelButtonIntent */, true /* decoratedCustomView */);
+            NotificationCompatImplBase.buildIntoRemoteViews(b.mContext, n.headsUpContentView,
+                    innerView);
+            setBackgroundColor(b.mContext, n.headsUpContentView, b.getColor());
+        } else if (b.mStyle instanceof DecoratedCustomViewStyle) {
+            addDecoratedHeadsUpToBuilder(n, b);
         }
     }
 
@@ -83,7 +242,9 @@
          */
         @Override
         protected BuilderExtender getExtender() {
-            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+                return new Api24Extender();
+            } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                 return new LollipopExtender();
             } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                 return new JellybeanExtender();
@@ -100,8 +261,16 @@
         @Override
         public Notification build(android.support.v4.app.NotificationCompat.Builder b,
                 NotificationBuilderWithBuilderAccessor builder) {
-            addMediaStyleToBuilderIcs(builder, b);
-            return builder.build();
+            RemoteViews contentView = addStyleGetContentViewIcs(builder, b);
+            Notification n = builder.build();
+            // The above call might override decorated content views again, let's make sure it
+            // sticks.
+            if (contentView != null) {
+                n.contentView = contentView;
+            } else if (b.getContentView() != null) {
+                n.contentView = b.getContentView();
+            }
+            return n;
         }
     }
 
@@ -110,9 +279,14 @@
         @Override
         public Notification build(android.support.v4.app.NotificationCompat.Builder b,
                 NotificationBuilderWithBuilderAccessor builder) {
-            addMediaStyleToBuilderIcs(builder, b);
+            RemoteViews contentView = addStyleGetContentViewIcs(builder, b);
             Notification n = builder.build();
-            addBigMediaStyleToBuilderJellybean(n, b);
+            // The above call might override decorated content views again, let's make sure it
+            // sticks.
+            if (contentView != null) {
+                n.contentView = contentView;
+            }
+            addBigStyleToBuilderJellybean(n, b);
             return n;
         }
     }
@@ -122,7 +296,25 @@
         @Override
         public Notification build(android.support.v4.app.NotificationCompat.Builder b,
                 NotificationBuilderWithBuilderAccessor builder) {
-            addMediaStyleToBuilderLollipop(builder, b.mStyle);
+            RemoteViews contentView = addStyleGetContentViewLollipop(builder, b);
+            Notification n = builder.build();
+            // The above call might override decorated content views again, let's make sure it
+            // sticks.
+            if (contentView != null) {
+                n.contentView = contentView;
+            }
+            addBigStyleToBuilderLollipop(n, b);
+            addHeadsUpToBuilderLollipop(n, b);
+            return n;
+        }
+    }
+
+    private static class Api24Extender extends BuilderExtender {
+
+        @Override
+        public Notification build(android.support.v4.app.NotificationCompat.Builder b,
+                NotificationBuilderWithBuilderAccessor builder) {
+            addStyleToBuilderApi24(builder, b);
             return builder.build();
         }
     }
@@ -240,4 +432,78 @@
             return this;
         }
     }
+
+
+    /**
+     * Notification style for custom views that are decorated by the system.
+     *
+     * <p>Instead of providing a notification that is completely custom, a developer can set this
+     * style and still obtain system decorations like the notification header with the expand
+     * affordance and actions.
+     *
+     * <p>Use {@link android.app.Notification.Builder#setCustomContentView(RemoteViews)},
+     * {@link android.app.Notification.Builder#setCustomBigContentView(RemoteViews)} and
+     * {@link android.app.Notification.Builder#setCustomHeadsUpContentView(RemoteViews)} to set the
+     * corresponding custom views to display.
+     *
+     * <p>To use this style with your Notification, feed it to
+     * {@link NotificationCompat.Builder#setStyle(Style)} like so:
+     * <pre class="prettyprint">
+     * Notification noti = new NotificationCompat.Builder()
+     *     .setSmallIcon(R.drawable.ic_stat_player)
+     *     .setLargeIcon(albumArtBitmap))
+     *     .setCustomContentView(contentView);
+     *     .setStyle(<b>new NotificationCompat.DecoratedCustomViewStyle()</b>)
+     *     .build();
+     * </pre>
+     *
+     * <p>If you are using this style, consider using the corresponding styles like
+     * {@link android.support.v7.appcompat.R.style#TextAppearance_AppCompat_Notification} or
+     * {@link android.support.v7.appcompat.R.style#TextAppearance_AppCompat_Notification_Title} in
+     * your custom views in order to get the correct styling on each platform version.
+     */
+    public static class DecoratedCustomViewStyle extends Style {
+
+        public DecoratedCustomViewStyle() {
+        }
+    }
+
+    /**
+     * Notification style for media custom views that are decorated by the system.
+     *
+     * <p>Instead of providing a media notification that is completely custom, a developer can set
+     * this style and still obtain system decorations like the notification header with the expand
+     * affordance and actions.
+     *
+     * <p>Use {@link android.app.Notification.Builder#setCustomContentView(RemoteViews)},
+     * {@link android.app.Notification.Builder#setCustomBigContentView(RemoteViews)} and
+     * {@link android.app.Notification.Builder#setCustomHeadsUpContentView(RemoteViews)} to set the
+     * corresponding custom views to display.
+     *
+     * <p>To use this style with your Notification, feed it to
+     * {@link NotificationCompat.Builder#setStyle(Style)} like so:
+     * <pre class="prettyprint">
+     * Notification noti = new Notification.Builder()
+     *     .setSmallIcon(R.drawable.ic_stat_player)
+     *     .setLargeIcon(albumArtBitmap))
+     *     .setCustomContentView(contentView);
+     *     .setStyle(<b>new NotificationCompat.DecoratedMediaCustomViewStyle()</b>
+     *          .setMediaSession(mySession))
+     *     .build();
+     * </pre>
+     *
+     * <p>If you are using this style, consider using the corresponding styles like
+     * {@link android.support.v7.appcompat.R.style#TextAppearance_AppCompat_Notification_Media} or
+     * {@link
+     * android.support.v7.appcompat.R.style#TextAppearance_AppCompat_Notification_Title_Media} in
+     * your custom views in order to get the correct styling on each platform version.
+     *
+     * @see DecoratedCustomViewStyle
+     * @see MediaStyle
+     */
+    public static class DecoratedMediaCustomViewStyle extends MediaStyle {
+
+        public DecoratedMediaCustomViewStyle() {
+        }
+    }
 }
diff --git a/v7/appcompat/src/android/support/v7/app/NotificationCompatImpl24.java b/v7/appcompat/src/android/support/v7/app/NotificationCompatImpl24.java
new file mode 100644
index 0000000..0547ad4
--- /dev/null
+++ b/v7/appcompat/src/android/support/v7/app/NotificationCompatImpl24.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2016 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.support.v7.app;
+
+import android.app.Notification;
+import android.support.v4.app.NotificationBuilderWithBuilderAccessor;
+
+class NotificationCompatImpl24 {
+
+    public static void addDecoratedCustomViewStyle(NotificationBuilderWithBuilderAccessor b) {
+        Notification.Builder builder = b.getBuilder();
+        builder.setStyle(new Notification.DecoratedCustomViewStyle());
+    }
+
+    public static void addDecoratedMediaCustomViewStyle(NotificationBuilderWithBuilderAccessor b) {
+        Notification.Builder builder = b.getBuilder();
+        builder.setStyle(new Notification.DecoratedMediaCustomViewStyle());
+    }
+}
diff --git a/v7/appcompat/src/android/support/v7/app/NotificationCompatImplBase.java b/v7/appcompat/src/android/support/v7/app/NotificationCompatImplBase.java
index 2bd772c..a37c921 100644
--- a/v7/appcompat/src/android/support/v7/app/NotificationCompatImplBase.java
+++ b/v7/appcompat/src/android/support/v7/app/NotificationCompatImplBase.java
@@ -21,9 +21,15 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
+import android.graphics.drawable.Drawable;
 import android.os.Build;
 import android.os.SystemClock;
 import android.support.v4.app.NotificationBuilderWithBuilderAccessor;
+import android.support.v4.app.NotificationCompat;
 import android.support.v4.app.NotificationCompatBase;
 import android.support.v7.appcompat.R;
 import android.util.TypedValue;
@@ -31,6 +37,7 @@
 import android.widget.RemoteViews;
 
 import java.text.NumberFormat;
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -41,30 +48,38 @@
 
     static final int MAX_MEDIA_BUTTONS_IN_COMPACT = 3;
     static final int MAX_MEDIA_BUTTONS = 5;
+    private static final int MAX_ACTION_BUTTONS = 3;
 
-    public static <T extends NotificationCompatBase.Action> void overrideContentView(
+    public static <T extends NotificationCompatBase.Action> RemoteViews overrideContentViewMedia(
             NotificationBuilderWithBuilderAccessor builder,
             Context context, CharSequence contentTitle, CharSequence contentText,
             CharSequence contentInfo, int number, Bitmap largeIcon, CharSequence subText,
-            boolean useChronometer, long when, List<T> actions, int[] actionsToShowInCompact,
-            boolean showCancelButton, PendingIntent cancelButtonIntent) {
-        RemoteViews views = generateContentView(context, contentTitle, contentText, contentInfo,
-                number, largeIcon, subText, useChronometer, when, actions, actionsToShowInCompact,
-                showCancelButton, cancelButtonIntent);
+            boolean useChronometer, long when, int priority, List<T> actions,
+            int[] actionsToShowInCompact, boolean showCancelButton,
+            PendingIntent cancelButtonIntent, boolean isDecoratedCustomView) {
+        RemoteViews views = generateContentViewMedia(context, contentTitle, contentText, contentInfo,
+                number, largeIcon, subText, useChronometer, when, priority, actions,
+                actionsToShowInCompact, showCancelButton, cancelButtonIntent,
+                isDecoratedCustomView);
         builder.getBuilder().setContent(views);
         if (showCancelButton) {
             builder.getBuilder().setOngoing(true);
         }
+        return views;
     }
 
-    private static <T extends NotificationCompatBase.Action> RemoteViews generateContentView(
+    private static <T extends NotificationCompatBase.Action> RemoteViews generateContentViewMedia(
             Context context, CharSequence contentTitle, CharSequence contentText,
             CharSequence contentInfo, int number, Bitmap largeIcon, CharSequence subText,
-            boolean useChronometer, long when, List<T> actions, int[] actionsToShowInCompact,
-            boolean showCancelButton, PendingIntent cancelButtonIntent) {
+            boolean useChronometer, long when, int priority, List<T> actions,
+            int[] actionsToShowInCompact, boolean showCancelButton,
+            PendingIntent cancelButtonIntent, boolean isDecoratedCustomView) {
         RemoteViews view = applyStandardTemplate(context, contentTitle, contentText, contentInfo,
-                number, largeIcon, subText, useChronometer, when,
-                R.layout.notification_template_media, true /* fitIn1U */);
+                number, 0 /* smallIcon */, largeIcon, subText, useChronometer, when, priority,
+                0 /* color is unused on media */,
+                isDecoratedCustomView ? R.layout.notification_template_media_custom
+                        : R.layout.notification_template_media,
+                true /* fitIn1U */);
 
         final int numActions = actions.size();
         final int N = actionsToShowInCompact == null
@@ -97,28 +112,31 @@
         return view;
     }
 
-    public static <T extends NotificationCompatBase.Action> void overrideBigContentView(
+    public static <T extends NotificationCompatBase.Action> void overrideMediaBigContentView(
             Notification n, Context context, CharSequence contentTitle, CharSequence contentText,
             CharSequence contentInfo, int number, Bitmap largeIcon, CharSequence subText,
-            boolean useChronometer, long when, List<T> actions, boolean showCancelButton,
-            PendingIntent cancelButtonIntent) {
-        n.bigContentView = generateBigContentView(context, contentTitle, contentText, contentInfo,
-                number, largeIcon, subText, useChronometer, when, actions, showCancelButton,
-                cancelButtonIntent);
+            boolean useChronometer, long when, int priority, int color, List<T> actions,
+            boolean showCancelButton, PendingIntent cancelButtonIntent,
+            boolean decoratedCustomView) {
+        n.bigContentView = generateMediaBigView(context, contentTitle, contentText, contentInfo,
+                number, largeIcon, subText, useChronometer, when, priority, color,
+                actions, showCancelButton, cancelButtonIntent, decoratedCustomView);
         if (showCancelButton) {
             n.flags |= Notification.FLAG_ONGOING_EVENT;
         }
     }
 
-    private static <T extends NotificationCompatBase.Action> RemoteViews generateBigContentView(
+    public static <T extends NotificationCompatBase.Action> RemoteViews generateMediaBigView(
             Context context, CharSequence contentTitle, CharSequence contentText,
             CharSequence contentInfo, int number, Bitmap largeIcon, CharSequence subText,
-            boolean useChronometer, long when, List<T> actions, boolean showCancelButton,
-            PendingIntent cancelButtonIntent) {
+            boolean useChronometer, long when, int priority, int color, List<T> actions,
+            boolean showCancelButton, PendingIntent cancelButtonIntent,
+            boolean decoratedCustomView) {
         final int actionCount = Math.min(actions.size(), MAX_MEDIA_BUTTONS);
         RemoteViews big = applyStandardTemplate(context, contentTitle, contentText, contentInfo,
-                number, largeIcon, subText, useChronometer, when,
-                getBigLayoutResource(actionCount), false /* fitIn1U */);
+                number, 0 /* smallIcon */, largeIcon, subText, useChronometer, when, priority,
+                color,  /* fitIn1U */getBigMediaLayoutResource(decoratedCustomView, actionCount),
+                false);
 
         big.removeAllViews(R.id.media_actions);
         if (actionCount > 0) {
@@ -153,29 +171,162 @@
         return button;
     }
 
-    private static int getBigLayoutResource(int actionCount) {
+    private static int getBigMediaLayoutResource(boolean decoratedCustomView, int actionCount) {
         if (actionCount <= 3) {
-            return R.layout.notification_template_big_media_narrow;
+            return decoratedCustomView
+                    ? R.layout.notification_template_big_media_narrow_custom
+                    : R.layout.notification_template_big_media_narrow;
         } else {
-            return R.layout.notification_template_big_media;
+            return decoratedCustomView
+                    ? R.layout.notification_template_big_media_custom
+                    : R.layout.notification_template_big_media;
         }
     }
 
-    private static RemoteViews applyStandardTemplate(Context context,
+    public static RemoteViews applyStandardTemplateWithActions(Context context,
             CharSequence contentTitle, CharSequence contentText, CharSequence contentInfo,
-            int number, Bitmap largeIcon, CharSequence subText, boolean useChronometer, long when,
-            int resId, boolean fitIn1U) {
+            int number, int smallIcon, Bitmap largeIcon, CharSequence subText,
+            boolean useChronometer, long when, int priority, int color, int resId, boolean fitIn1U,
+            ArrayList<NotificationCompat.Action> actions) {
+        RemoteViews remoteViews = applyStandardTemplate(context, contentTitle, contentText,
+                contentInfo, number, smallIcon, largeIcon, subText, useChronometer, when, priority,
+                color, resId, fitIn1U);
+        remoteViews.removeAllViews(R.id.actions);
+        boolean actionsVisible = false;
+        if (actions != null) {
+            int N = actions.size();
+            if (N > 0) {
+                actionsVisible = true;
+                if (N > MAX_ACTION_BUTTONS) N = MAX_ACTION_BUTTONS;
+                for (int i = 0; i < N; i++) {
+                    final RemoteViews button = generateActionButton(context, actions.get(i));
+                    remoteViews.addView(R.id.actions, button);
+                }
+            }
+        }
+        int actionVisibility = actionsVisible ? View.VISIBLE : View.GONE;
+        remoteViews.setViewVisibility(R.id.actions, actionVisibility);
+        remoteViews.setViewVisibility(R.id.action_divider, actionVisibility);
+        return remoteViews;
+    }
+
+    private static RemoteViews generateActionButton(Context context,
+            NotificationCompat.Action action) {
+        final boolean tombstone = (action.actionIntent == null);
+        RemoteViews button =  new RemoteViews(context.getPackageName(),
+                tombstone ? getActionTombstoneLayoutResource()
+                        : getActionLayoutResource());
+        button.setImageViewBitmap(R.id.action_image,
+                createColoredBitmap(context, action.getIcon(),
+                        context.getResources().getColor(R.color.notification_action_color_filter)));
+        button.setTextViewText(R.id.action_text, action.title);
+        if (!tombstone) {
+            button.setOnClickPendingIntent(R.id.action_container, action.actionIntent);
+        }
+        button.setContentDescription(R.id.action_container, action.title);
+        return button;
+    }
+
+    private static Bitmap createColoredBitmap(Context context, int iconId, int color) {
+        return createColoredBitmap(context, iconId, color, 0);
+    }
+
+    private static Bitmap createColoredBitmap(Context context, int iconId, int color, int size) {
+        Drawable drawable = context.getResources().getDrawable(iconId);
+        int width = size == 0 ? drawable.getIntrinsicWidth() : size;
+        int height = size == 0 ? drawable.getIntrinsicHeight() : size;
+        Bitmap resultBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+        drawable.setBounds(0, 0, width, height);
+        if (color != 0) {
+            drawable.mutate().setColorFilter(
+                    new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN));
+        }
+        Canvas canvas = new Canvas(resultBitmap);
+        drawable.draw(canvas);
+        return resultBitmap;
+    }
+
+    private static int getActionLayoutResource() {
+        return R.layout.notification_action;
+    }
+
+    private static int getActionTombstoneLayoutResource() {
+        return R.layout.notification_action_tombstone;
+    }
+
+    public static RemoteViews applyStandardTemplate(Context context,
+            CharSequence contentTitle, CharSequence contentText, CharSequence contentInfo,
+            int number, int smallIcon, Bitmap largeIcon, CharSequence subText,
+            boolean useChronometer, long when, int priority, int color, int resId,
+            boolean fitIn1U) {
+        Resources res = context.getResources();
         RemoteViews contentView = new RemoteViews(context.getPackageName(), resId);
         boolean showLine3 = false;
         boolean showLine2 = false;
 
-        // On versions before Jellybean, the large icon was shown by SystemUI, so we need to hide
-        // it here.
-        if (largeIcon != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+        boolean minPriority = priority < NotificationCompat.PRIORITY_LOW;
+        boolean afterJellyBean = Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN;
+        boolean afterLollipop = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
+        if (afterJellyBean && !afterLollipop) {
+            // lets color the backgrounds
+            if (minPriority) {
+                contentView.setInt(R.id.notification_background,
+                        "setBackgroundResource", R.drawable.notification_bg_low);
+                contentView.setInt(R.id.icon,
+                        "setBackgroundResource", R.drawable.notification_template_icon_low_bg);
+            } else {
+                contentView.setInt(R.id.notification_background,
+                        "setBackgroundResource", R.drawable.notification_bg);
+                contentView.setInt(R.id.icon,
+                        "setBackgroundResource", R.drawable.notification_template_icon_bg);
+            }
+        }
+
+        if (largeIcon != null) {
+            // On versions before Jellybean, the large icon was shown by SystemUI, so we need to hide
+            // it here.
+            if (afterJellyBean) {
+                contentView.setViewVisibility(R.id.icon, View.VISIBLE);
+                contentView.setImageViewBitmap(R.id.icon, largeIcon);
+            } else {
+                contentView.setViewVisibility(R.id.icon, View.GONE);
+            }
+            if (smallIcon != 0) {
+                int backgroundSize = res.getDimensionPixelSize(
+                        R.dimen.notification_right_icon_size);
+                int iconSize = backgroundSize - res.getDimensionPixelSize(
+                        R.dimen.notification_small_icon_background_padding) * 2;
+                if (afterLollipop) {
+                    Bitmap smallBit = createIconWithBackground(context,
+                            smallIcon,
+                            backgroundSize,
+                            iconSize,
+                            color);
+                    contentView.setImageViewBitmap(R.id.right_icon, smallBit);
+                } else {
+                    contentView.setImageViewBitmap(R.id.right_icon,
+                            createColoredBitmap(context, smallIcon, Color.WHITE));
+                }
+                contentView.setViewVisibility(R.id.right_icon, View.VISIBLE);
+            }
+        } else if (smallIcon != 0) { // small icon at left
             contentView.setViewVisibility(R.id.icon, View.VISIBLE);
-            contentView.setImageViewBitmap(R.id.icon, largeIcon);
-        } else {
-            contentView.setViewVisibility(R.id.icon, View.GONE);
+            if (afterLollipop) {
+                int backgroundSize = res.getDimensionPixelSize(
+                        R.dimen.notification_large_icon_width)
+                        - res.getDimensionPixelSize(R.dimen.notification_big_circle_margin);
+                int iconSize = res.getDimensionPixelSize(
+                        R.dimen.notification_small_icon_size_as_large);
+                Bitmap smallBit = createIconWithBackground(context,
+                        smallIcon,
+                        backgroundSize,
+                        iconSize,
+                        color);
+                contentView.setImageViewBitmap(R.id.icon, smallBit);
+            } else {
+                contentView.setImageViewBitmap(R.id.icon,
+                        createColoredBitmap(context, smallIcon, Color.WHITE));
+            }
         }
         if (contentTitle != null) {
             contentView.setTextViewText(R.id.title, contentTitle);
@@ -184,15 +335,18 @@
             contentView.setTextViewText(R.id.text, contentText);
             showLine3 = true;
         }
+        // If there is a large icon we have a right side
+        boolean hasRightSide = !afterLollipop && largeIcon != null;
         if (contentInfo != null) {
             contentView.setTextViewText(R.id.info, contentInfo);
             contentView.setViewVisibility(R.id.info, View.VISIBLE);
             showLine3 = true;
+            hasRightSide = true;
         } else if (number > 0) {
-            final int tooBig = context.getResources().getInteger(
+            final int tooBig = res.getInteger(
                     R.integer.status_bar_notification_info_maxnum);
             if (number > tooBig) {
-                contentView.setTextViewText(R.id.info, context.getResources().getString(
+                contentView.setTextViewText(R.id.info, ((Resources) res).getString(
                         R.string.status_bar_notification_info_overflow));
             } else {
                 NumberFormat f = NumberFormat.getIntegerInstance();
@@ -200,12 +354,13 @@
             }
             contentView.setViewVisibility(R.id.info, View.VISIBLE);
             showLine3 = true;
+            hasRightSide = true;
         } else {
             contentView.setViewVisibility(R.id.info, View.GONE);
         }
 
         // Need to show three lines? Only allow on Jellybean+
-        if (subText != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+        if (subText != null && afterJellyBean) {
             contentView.setTextViewText(R.id.text, subText);
             if (contentText != null) {
                 contentView.setTextViewText(R.id.text2, contentText);
@@ -217,10 +372,9 @@
         }
 
         // RemoteViews.setViewPadding and RemoteViews.setTextViewTextSize is not available on ICS-
-        if (showLine2 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+        if (showLine2 && afterJellyBean) {
             if (fitIn1U) {
                 // need to shrink all the type to make sure everything fits
-                final Resources res = context.getResources();
                 final float subTextSize = res.getDimensionPixelSize(
                         R.dimen.notification_subtext_size);
                 contentView.setTextViewTextSize(R.id.text, TypedValue.COMPLEX_UNIT_PX, subTextSize);
@@ -230,7 +384,7 @@
         }
 
         if (when != 0) {
-            if (useChronometer) {
+            if (useChronometer && afterJellyBean) {
                 contentView.setViewVisibility(R.id.chronometer, View.VISIBLE);
                 contentView.setLong(R.id.chronometer, "setBase",
                         when + (SystemClock.elapsedRealtime() - System.currentTimeMillis()));
@@ -239,8 +393,61 @@
                 contentView.setViewVisibility(R.id.time, View.VISIBLE);
                 contentView.setLong(R.id.time, "setTime", when);
             }
+            hasRightSide = true;
         }
+        contentView.setViewVisibility(R.id.right_side, hasRightSide ? View.VISIBLE : View.GONE);
         contentView.setViewVisibility(R.id.line3, showLine3 ? View.VISIBLE : View.GONE);
         return contentView;
     }
+
+    public static Bitmap createIconWithBackground(Context ctx, int iconId, int size, int iconSize,
+            int color) {
+        Bitmap coloredBitmap = createColoredBitmap(ctx, R.drawable.notification_icon_background,
+                        color == NotificationCompat.COLOR_DEFAULT ? 0 : color, size);
+        Canvas canvas = new Canvas(coloredBitmap);
+        Drawable icon = ctx.getResources().getDrawable(iconId).mutate();
+        icon.setFilterBitmap(true);
+        int inset = (size - iconSize) / 2;
+        icon.setBounds(inset, inset, iconSize + inset, iconSize + inset);
+        icon.setColorFilter(new PorterDuffColorFilter(Color.WHITE, PorterDuff.Mode.SRC_ATOP));
+        icon.draw(canvas);
+        return coloredBitmap;
+    }
+
+    public static void buildIntoRemoteViews(Context ctx, RemoteViews outerView,
+            RemoteViews innerView) {
+        // this needs to be done fore the other calls, since otherwise we might hide the wrong
+        // things if our ids collide.
+        hideNormalContent(outerView);
+        outerView.removeAllViews(R.id.notification_main_column);
+        outerView.addView(R.id.notification_main_column, innerView.clone());
+        outerView.setViewVisibility(R.id.notification_main_column, View.VISIBLE);
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+            // Adjust padding depending on font size.
+            outerView.setViewPadding(R.id.notification_main_column_container,
+                    0, calculateTopPadding(ctx), 0, 0);
+        }
+    }
+
+    private static void hideNormalContent(RemoteViews outerView) {
+        outerView.setViewVisibility(R.id.title, View.GONE);
+        outerView.setViewVisibility(R.id.text2, View.GONE);
+        outerView.setViewVisibility(R.id.text, View.GONE);
+    }
+
+    public static int calculateTopPadding(Context ctx) {
+        int padding = ctx.getResources().getDimensionPixelSize(R.dimen.notification_top_pad);
+        int largePadding = ctx.getResources().getDimensionPixelSize(
+                R.dimen.notification_top_pad_large_text);
+        float fontScale = ctx.getResources().getConfiguration().fontScale;
+        float largeFactor = (constrain(fontScale, 1.0f, 1.3f) - 1f) / (1.3f - 1f);
+
+        // Linearly interpolate the padding between large and normal with the font scale ranging
+        // from 1f to LARGE_TEXT_SCALE
+        return Math.round((1 - largeFactor) * padding + largeFactor * largePadding);
+    }
+
+    public static float constrain(float amount, float low, float high) {
+        return amount < low ? low : (amount > high ? high : amount);
+    }
 }