Merge "Only try disabling quiet mode" into nyc-dev
diff --git a/res/layout-h360dp/font_size_activity.xml b/res/layout-h360dp/font_size_activity.xml
new file mode 100644
index 0000000..aa3930c
--- /dev/null
+++ b/res/layout-h360dp/font_size_activity.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.
+-->
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:fillViewport="true">
+
+    <LinearLayout
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content" >
+
+        <include layout="@layout/preview_seek_bar_view_pager" />
+
+        <LinearLayout
+            android:orientation="vertical"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingTop="16dp"
+            android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+            android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
+
+            <com.android.settings.widget.DotsPageIndicator
+                android:id="@+id/page_indicator"
+                style="@style/PreviewPagerPageIndicator"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_horizontal"
+                android:padding="6dp" />
+
+            <TextView
+                android:id="@+id/current_label"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_horizontal"
+                android:padding="6dp"
+                android:textAppearance="@android:style/TextAppearance.Material.Widget.TextView"
+                android:elevation="2dp" />
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:gravity="center_vertical"
+                android:paddingTop="8dp">
+
+                <ImageView
+                    android:id="@+id/smaller"
+                    android:layout_width="48dp"
+                    android:layout_height="48dp"
+                    android:background="?android:attr/selectableItemBackgroundBorderless"
+                    android:src="@drawable/ic_font_size_16dp"
+                    android:tint="?android:attr/textColorPrimary"
+                    android:tintMode="src_in"
+                    android:scaleType="center"
+                    android:focusable="true"
+                    android:contentDescription="@string/font_size_make_smaller_desc" />
+
+                <com.android.settings.widget.LabeledSeekBar
+                    android:id="@+id/seek_bar"
+                    android:layout_width="0dp"
+                    android:layout_height="48dp"
+                    android:layout_weight="1"
+                    style="@android:style/Widget.Material.SeekBar.Discrete"/>
+
+                <ImageView
+                    android:id="@+id/larger"
+                    android:layout_width="48dp"
+                    android:layout_height="48dp"
+                    android:background="?android:attr/selectableItemBackgroundBorderless"
+                    android:src="@drawable/ic_font_size_24dp"
+                    android:tint="?android:attr/textColorPrimary"
+                    android:tintMode="src_in"
+                    android:scaleType="center"
+                    android:focusable="true"
+                    android:contentDescription="@string/font_size_make_larger_desc" />
+            </LinearLayout>
+
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/font_size_summary"
+                android:layout_marginBottom="16dp"
+                android:textAppearance="@android:style/TextAppearance.Material.Subhead" />
+        </LinearLayout>
+    </LinearLayout>
+</ScrollView>
diff --git a/res/layout-h360dp/screen_zoom_activity.xml b/res/layout-h360dp/screen_zoom_activity.xml
new file mode 100644
index 0000000..0141019
--- /dev/null
+++ b/res/layout-h360dp/screen_zoom_activity.xml
@@ -0,0 +1,99 @@
+<?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.
+-->
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:fillViewport="true">
+
+    <LinearLayout
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content" >
+
+        <include layout="@layout/preview_seek_bar_view_pager" />
+
+        <LinearLayout
+            android:orientation="vertical"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingTop="16dp"
+            android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+            android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
+
+            <com.android.settings.widget.DotsPageIndicator
+                android:id="@+id/page_indicator"
+                style="@style/PreviewPagerPageIndicator"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_horizontal"
+                android:padding="6dp" />
+
+            <TextView
+                android:id="@+id/current_label"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_horizontal"
+                android:padding="6dp"
+                android:textAppearance="@android:style/TextAppearance.Material.Widget.TextView"
+                android:elevation="2dp" />
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:gravity="center_vertical">
+
+                <ImageView
+                    android:id="@+id/smaller"
+                    android:layout_width="48dp"
+                    android:layout_height="48dp"
+                    android:background="?android:attr/selectableItemBackgroundBorderless"
+                    android:src="@drawable/ic_remove_24dp"
+                    android:tint="?android:attr/textColorPrimary"
+                    android:tintMode="src_in"
+                    android:scaleType="center"
+                    android:focusable="true"
+                    android:contentDescription="@string/screen_zoom_make_smaller_desc" />
+
+                <com.android.settings.widget.LabeledSeekBar
+                    android:id="@+id/seek_bar"
+                    android:layout_width="0dp"
+                    android:layout_height="48dp"
+                    android:layout_weight="1"
+                    style="@android:style/Widget.Material.SeekBar.Discrete"/>
+
+                <ImageView
+                    android:id="@+id/larger"
+                    android:layout_width="48dp"
+                    android:layout_height="48dp"
+                    android:background="?android:attr/selectableItemBackgroundBorderless"
+                    android:src="@drawable/ic_add_24dp"
+                    android:tint="?android:attr/textColorPrimary"
+                    android:tintMode="src_in"
+                    android:scaleType="center"
+                    android:focusable="true"
+                    android:contentDescription="@string/screen_zoom_make_larger_desc" />
+            </LinearLayout>
+
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/screen_zoom_summary"
+                android:layout_marginBottom="16dp"
+                android:textAppearance="@android:style/TextAppearance.Material.Subhead" />
+        </LinearLayout>
+    </LinearLayout>
+</ScrollView>
diff --git a/res/layout/dashboard_category.xml b/res/layout/dashboard_category.xml
index b3500b2..7019a9c 100644
--- a/res/layout/dashboard_category.xml
+++ b/res/layout/dashboard_category.xml
@@ -21,7 +21,8 @@
     android:orientation="vertical"
     android:paddingBottom="8dip"
     android:background="@color/card_background"
-    android:importantForAccessibility="noHideDescendants">
+    android:importantForAccessibility="noHideDescendants"
+    android:elevation="@dimen/dashboard_category_elevation" >
 
     <TextView android:id="@android:id/title"
         android:layout_width="match_parent"
diff --git a/res/layout/dashboard_tile.xml b/res/layout/dashboard_tile.xml
index 983e6ea..2f87909 100644
--- a/res/layout/dashboard_tile.xml
+++ b/res/layout/dashboard_tile.xml
@@ -21,7 +21,8 @@
     android:gravity="center_vertical"
     android:minHeight="@dimen/dashboard_tile_minimum_height"
     android:clickable="true"
-    android:background="@drawable/selectable_card" >
+    android:background="@drawable/selectable_card"
+    android:elevation="@dimen/dashboard_category_elevation" >
 
     <ImageView
         android:id="@android:id/icon"
diff --git a/res/layout/edit_user_photo_popup_item.xml b/res/layout/edit_user_photo_popup_item.xml
deleted file mode 100644
index 11fdfbc..0000000
--- a/res/layout/edit_user_photo_popup_item.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2013, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<TextView xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@android:id/text1"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:minHeight="?android:attr/listPreferredItemHeightSmall"
-    android:textAppearance="?android:attr/textAppearanceListItemSmall"
-    android:textColor="?android:attr/textColorAlertDialogListItem"
-    android:gravity="center_vertical"
-    android:paddingStart="16dip"
-    android:paddingEnd="16dip"
-    android:ellipsize="marquee"
-/>
diff --git a/res/layout/font_size_activity.xml b/res/layout/font_size_activity.xml
index 5a4aba6..4825f24 100644
--- a/res/layout/font_size_activity.xml
+++ b/res/layout/font_size_activity.xml
@@ -22,79 +22,63 @@
     <LinearLayout
         android:orientation="vertical"
         android:layout_width="match_parent"
-        android:layout_height="wrap_content" >
+        android:layout_height="wrap_content"
+        android:paddingTop="16dp"
+        android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+        android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
 
-        <include layout="@layout/preview_seek_bar_view_pager" />
+        <TextView
+            android:id="@+id/current_label"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:padding="6dp"
+            android:textAppearance="@android:style/TextAppearance.Material.Widget.TextView"
+            android:elevation="2dp" />
 
         <LinearLayout
-            android:orientation="vertical"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:paddingTop="16dp"
-            android:paddingStart="?android:attr/listPreferredItemPaddingStart"
-            android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
+            android:gravity="center_vertical"
+            android:paddingTop="8dp">
 
-            <com.android.settings.widget.DotsPageIndicator
-                android:id="@+id/page_indicator"
-                style="@style/PreviewPagerPageIndicator"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_gravity="center_horizontal"
-                android:padding="6dp" />
+            <ImageView
+                android:id="@+id/smaller"
+                android:layout_width="48dp"
+                android:layout_height="48dp"
+                android:background="?android:attr/selectableItemBackgroundBorderless"
+                android:src="@drawable/ic_font_size_16dp"
+                android:tint="?android:attr/textColorPrimary"
+                android:tintMode="src_in"
+                android:scaleType="center"
+                android:focusable="true"
+                android:contentDescription="@string/font_size_make_smaller_desc" />
 
-            <TextView
-                android:id="@+id/current_label"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_gravity="center_horizontal"
-                android:padding="6dp"
-                android:textAppearance="@android:style/TextAppearance.Material.Widget.TextView"
-                android:elevation="2dp" />
+            <com.android.settings.widget.LabeledSeekBar
+                android:id="@+id/seek_bar"
+                android:layout_width="0dp"
+                android:layout_height="48dp"
+                android:layout_weight="1"
+                style="@android:style/Widget.Material.SeekBar.Discrete"/>
 
-            <LinearLayout
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:gravity="center_vertical"
-                android:paddingTop="8dp">
-
-                <ImageView
-                    android:id="@+id/smaller"
-                    android:layout_width="48dp"
-                    android:layout_height="48dp"
-                    android:background="?android:attr/selectableItemBackgroundBorderless"
-                    android:src="@drawable/ic_font_size_16dp"
-                    android:tint="?android:attr/colorControlNormal"
-                    android:tintMode="src_in"
-                    android:scaleType="center"
-                    android:focusable="true"
-                    android:contentDescription="@string/font_size_make_smaller_desc" />
-
-                <com.android.settings.widget.LabeledSeekBar
-                    android:id="@+id/seek_bar"
-                    android:layout_width="0dp"
-                    android:layout_height="48dp"
-                    android:layout_weight="1"
-                    style="@android:style/Widget.Material.SeekBar.Discrete"/>
-
-                <ImageView
-                    android:id="@+id/larger"
-                    android:layout_width="48dp"
-                    android:layout_height="48dp"
-                    android:background="?android:attr/selectableItemBackgroundBorderless"
-                    android:src="@drawable/ic_font_size_24dp"
-                    android:tint="?android:attr/colorControlNormal"
-                    android:tintMode="src_in"
-                    android:scaleType="center"
-                    android:focusable="true"
-                    android:contentDescription="@string/font_size_make_larger_desc" />
-            </LinearLayout>
-
-            <TextView
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:text="@string/font_size_summary"
-                android:layout_marginBottom="16dp"
-                android:textAppearance="@android:style/TextAppearance.Material.Subhead" />
+            <ImageView
+                android:id="@+id/larger"
+                android:layout_width="48dp"
+                android:layout_height="48dp"
+                android:background="?android:attr/selectableItemBackgroundBorderless"
+                android:src="@drawable/ic_font_size_24dp"
+                android:tint="?android:attr/textColorPrimary"
+                android:tintMode="src_in"
+                android:scaleType="center"
+                android:focusable="true"
+                android:contentDescription="@string/font_size_make_larger_desc" />
         </LinearLayout>
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/font_size_summary"
+            android:layout_marginBottom="16dp"
+            android:textAppearance="@android:style/TextAppearance.Material.Subhead" />
     </LinearLayout>
 </ScrollView>
diff --git a/res/layout/restricted_popup_menu_item.xml b/res/layout/restricted_popup_menu_item.xml
new file mode 100644
index 0000000..78a09ef
--- /dev/null
+++ b/res/layout/restricted_popup_menu_item.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:minHeight="?android:attr/listPreferredItemHeightSmall"
+    android:gravity="center_vertical"
+    android:paddingStart="16dip"
+    android:paddingEnd="16dip">
+    <TextView
+        android:id="@+id/text"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textColor="?android:attr/textColorAlertDialogListItem"
+        android:textAppearance="?android:attr/textAppearanceListItemSmall"
+        android:ellipsize="marquee"
+        android:layout_alignParentLeft="true" />
+    <ImageView
+        android:id="@+id/restricted_icon"
+        android:layout_width="@dimen/restricted_icon_size"
+        android:layout_height="@dimen/restricted_icon_size"
+        android:scaleType="centerInside"
+        android:src="@drawable/ic_info"
+        android:layout_alignParentRight="true"
+        android:visibility="gone" />
+</RelativeLayout>
\ No newline at end of file
diff --git a/res/layout/screen_zoom_activity.xml b/res/layout/screen_zoom_activity.xml
index 4d3ab39..36dd9fa 100644
--- a/res/layout/screen_zoom_activity.xml
+++ b/res/layout/screen_zoom_activity.xml
@@ -22,78 +22,62 @@
     <LinearLayout
         android:orientation="vertical"
         android:layout_width="match_parent"
-        android:layout_height="wrap_content" >
+        android:layout_height="wrap_content"
+        android:paddingTop="16dp"
+        android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+        android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
 
-        <include layout="@layout/preview_seek_bar_view_pager" />
+        <TextView
+            android:id="@+id/current_label"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:padding="6dp"
+            android:textAppearance="@android:style/TextAppearance.Material.Widget.TextView"
+            android:elevation="2dp" />
 
         <LinearLayout
-            android:orientation="vertical"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:paddingTop="16dp"
-            android:paddingStart="?android:attr/listPreferredItemPaddingStart"
-            android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
+            android:gravity="center_vertical">
 
-            <com.android.settings.widget.DotsPageIndicator
-                android:id="@+id/page_indicator"
-                style="@style/PreviewPagerPageIndicator"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_gravity="center_horizontal"
-                android:padding="6dp" />
+            <ImageView
+                android:id="@+id/smaller"
+                android:layout_width="48dp"
+                android:layout_height="48dp"
+                android:background="?android:attr/selectableItemBackgroundBorderless"
+                android:src="@drawable/ic_remove_24dp"
+                android:tint="?android:attr/textColorPrimary"
+                android:tintMode="src_in"
+                android:scaleType="center"
+                android:focusable="true"
+                android:contentDescription="@string/screen_zoom_make_smaller_desc" />
 
-            <TextView
-                android:id="@+id/current_label"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_gravity="center_horizontal"
-                android:padding="6dp"
-                android:textAppearance="@android:style/TextAppearance.Material.Widget.TextView"
-                android:elevation="2dp" />
+            <com.android.settings.widget.LabeledSeekBar
+                android:id="@+id/seek_bar"
+                android:layout_width="0dp"
+                android:layout_height="48dp"
+                android:layout_weight="1"
+                style="@android:style/Widget.Material.SeekBar.Discrete"/>
 
-            <LinearLayout
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:gravity="center_vertical">
-
-                <ImageView
-                    android:id="@+id/smaller"
-                    android:layout_width="48dp"
-                    android:layout_height="48dp"
-                    android:background="?android:attr/selectableItemBackgroundBorderless"
-                    android:src="@drawable/ic_remove_24dp"
-                    android:tint="?android:attr/colorControlNormal"
-                    android:tintMode="src_in"
-                    android:scaleType="center"
-                    android:focusable="true"
-                    android:contentDescription="@string/screen_zoom_make_smaller_desc" />
-
-                <com.android.settings.widget.LabeledSeekBar
-                    android:id="@+id/seek_bar"
-                    android:layout_width="0dp"
-                    android:layout_height="48dp"
-                    android:layout_weight="1"
-                    style="@android:style/Widget.Material.SeekBar.Discrete"/>
-
-                <ImageView
-                    android:id="@+id/larger"
-                    android:layout_width="48dp"
-                    android:layout_height="48dp"
-                    android:background="?android:attr/selectableItemBackgroundBorderless"
-                    android:src="@drawable/ic_add_24dp"
-                    android:tint="?android:attr/colorControlNormal"
-                    android:tintMode="src_in"
-                    android:scaleType="center"
-                    android:focusable="true"
-                    android:contentDescription="@string/screen_zoom_make_larger_desc" />
-            </LinearLayout>
-
-            <TextView
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:text="@string/screen_zoom_summary"
-                android:layout_marginBottom="16dp"
-                android:textAppearance="@android:style/TextAppearance.Material.Subhead" />
+            <ImageView
+                android:id="@+id/larger"
+                android:layout_width="48dp"
+                android:layout_height="48dp"
+                android:background="?android:attr/selectableItemBackgroundBorderless"
+                android:src="@drawable/ic_add_24dp"
+                android:tint="?android:attr/textColorPrimary"
+                android:tintMode="src_in"
+                android:scaleType="center"
+                android:focusable="true"
+                android:contentDescription="@string/screen_zoom_make_larger_desc" />
         </LinearLayout>
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/screen_zoom_summary"
+            android:layout_marginBottom="16dp"
+            android:textAppearance="@android:style/TextAppearance.Material.Subhead" />
     </LinearLayout>
 </ScrollView>
diff --git a/res/layout/video_preference.xml b/res/layout/video_preference.xml
index a6fde76..5f7116d 100644
--- a/res/layout/video_preference.xml
+++ b/res/layout/video_preference.xml
@@ -15,13 +15,22 @@
 -->
 <RelativeLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/video_background"
     android:layout_width="match_parent"
     android:layout_height="wrap_content">
 
+    <ImageView
+        android:id="@+id/video_background"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:src="@drawable/accessibility_screen_magnification_background"
+        android:scaleType="fitXY"
+        android:adjustViewBounds="true" />
+
     <VideoView
         android:id="@+id/video"
         android:layout_width="wrap_content"
-        android:layout_height="wrap_content" />
+        android:layout_height="wrap_content"
+        android:layout_alignTop="@id/video_background"
+        android:layout_centerHorizontal="true" />
 
 </RelativeLayout>
\ No newline at end of file
diff --git a/res/layout/vpn_dialog.xml b/res/layout/vpn_dialog.xml
index 620b43f..6822e95 100644
--- a/res/layout/vpn_dialog.xml
+++ b/res/layout/vpn_dialog.xml
@@ -119,8 +119,7 @@
         <LinearLayout android:id="@+id/login"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:orientation="vertical"
-                android:visibility="gone">
+                android:orientation="vertical">
 
             <TextView style="@style/vpn_label" android:text="@string/vpn_username"/>
             <EditText style="@style/vpn_value" android:id="@+id/username"/>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 9d739c0..0ddb5d8 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -295,7 +295,7 @@
 
     <!-- Display Size and Font Size preview screen -->
     <dimen name="preview_pager_padding">8dp</dimen>
-    <dimen name="preview_pager_min_height">200dp</dimen>
+    <dimen name="preview_pager_min_height">240dp</dimen>
 
     <!-- Padding between the radio buttons/checkbox and text on the redaction interstitial -->
     <dimen name="redaction_padding_start">16dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index c11ea33..2675e15 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -3441,6 +3441,13 @@
         If you turn off notifications for this app, you may miss important alerts and updates.
     </string>
 
+    <!-- Manage applications, individual application info screen, section heading for information about the app installer [CHAR_LIMIT=25] -->
+    <string name="app_install_details_group_title">Store</string>
+    <!-- Manage applications, individual application info screen, title for the option which will trigger application info in it's installer [CHAR_LIMIT=25] -->
+    <string name="app_install_details_title">App details</string>
+    <!-- Manage applications, individual application info screen, summary for the option which will trigger application info in it's installer [CHAR_LIMIT=50] -->
+    <string name="app_install_details_summary">App installed from <xliff:g id="app_store">%1$s</xliff:g></string>
+
     <!-- App Ops Settings --> <skip />
     <!-- [CHAR LIMIT=NONE] App ops settings title, on main settings screen. If clicked, the user is taken to a settings screen for app operations -->
     <string name="app_ops_settings">App ops</string>
@@ -6024,7 +6031,13 @@
         <xliff:g id="notification_listener_name">%1$s</xliff:g> will be able to read all notifications,
         including personal information such as contact names and the text of messages you receive.
         It will also be able to dismiss notifications or trigger action buttons they contain.
+        \n\nThis will also give the app the ability to turn Do Not Disturb on or off and change related settings.
     </string>
+    <string name="notification_listener_disable_warning_summary">
+        If you turn off notification access for <xliff:g id="notification_listener_name">%1$s</xliff:g>, Do Not Disturb access may also be turned off.
+    </string>
+    <string name="notification_listener_disable_warning_confirm">Turn off</string>
+    <string name="notification_listener_disable_warning_cancel">Cancel</string>
 
     <!-- Title for managing VR (virtual reality) helper services. [CHAR LIMIT=50] -->
     <string name="vr_listeners_title">VR helper services</string>
@@ -6870,6 +6883,8 @@
     <!-- Zen mode access settings - summary for warning dialog when enabling access [CHAR LIMIT=NONE] -->
     <string name="zen_access_warning_dialog_summary">The app will be able to turn on/off Do Not Disturb and make changes to related settings.</string>
 
+    <string name="zen_access_disabled_package_warning">Must stay turned on because notification access is on</string>
+
     <!-- Zen mode access settings - title for warning dialog when revoking access [CHAR LIMIT=NONE] -->
     <string name="zen_access_revoke_warning_dialog_title">Revoke access to Do Not Disturb for <xliff:g id="app" example="Tasker">%1$s</xliff:g>?</string>
 
@@ -7187,7 +7202,7 @@
     <string name="network_restrictions">Network restrictions</string>
 
     <!-- A summary shown on data usage screens to indicate inaccuracy of data tracking [CHAR LIMIT=NONE] -->
-    <string name="operator_warning">Operator data accounting may differ from your device.</string>
+    <string name="operator_warning">Carrier data accounting may differ from device accounting</string>
 
     <!-- Format string describing how much data has been used [CHAR LIMIT=20] -->
     <string name="data_used_template"><xliff:g name="amount" example="1 GB">%1$s</xliff:g> used</string>
@@ -7211,22 +7226,22 @@
          the code to do that -->
     <string name="data_usage_other_apps" translatable="false">Other apps included in usage</string>
 
-    <!-- Description of number of apps allowed to ignore data saver [CHAR LIMIT=NONE] -->
+    <!-- Description of number of apps allowed to ignore Data Saver [CHAR LIMIT=NONE] -->
     <plurals name="data_saver_unrestricted_summary">
         <item quantity="one">1 app allowed to use unrestricted data when Data Saver is on</item>
         <item quantity="other"><xliff:g id="count" example="10">%1$d</xliff:g> apps allowed to use unrestricted data when Data Saver is on</item>
     </plurals>
 
     <!-- Name of Data Saver screens [CHAR LIMIT=30] -->
-    <string name="data_saver_title">Data Saver</string>
+    <string name="data_saver_title">Data saver</string>
 
     <!-- Button that leads to list of apps with unrestricted data access [CHAR LIMIT=60] -->
     <string name="unrestricted_data_saver">Unrestricted data access</string>
 
-    <!-- Summary for the data saver feature being on [CHAR LIMIT=NONE] -->
+    <!-- Summary for the Data Saver feature being on [CHAR LIMIT=NONE] -->
     <string name="data_saver_on">On</string>
 
-    <!-- Summary for the data saver feature being off [CHAR LIMIT=NONE] -->
+    <!-- Summary for the Data Saver feature being off [CHAR LIMIT=NONE] -->
     <string name="data_saver_off">Off</string>
 
     <!-- Title for switch to allow app unrestricted data usage [CHAR LIMIT=30] -->
diff --git a/res/xml/data_saver.xml b/res/xml/data_saver.xml
index 5b69cbb..20ce5c8 100644
--- a/res/xml/data_saver.xml
+++ b/res/xml/data_saver.xml
@@ -15,11 +15,20 @@
 -->
 
 <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
-    android:title="@string/data_saver_title">
+        xmlns:settings="http://schemas.android.com/apk/res-auto"
+        android:title="@string/data_saver_title">
 
     <Preference
         android:key="unrestricted_access"
         android:title="@string/unrestricted_data_saver"
         android:fragment="com.android.settings.datausage.UnrestrictedDataAccess" />
 
+    <!-- Feature description text -->
+    <com.android.settings.fuelgauge.WallOfTextPreference
+            android:key="description"
+            android:summary="@*android:string/data_saver_description"
+            android:persistent="false"
+            android:selectable="false"
+            settings:allowDividerAbove="true" />
+
 </PreferenceScreen>
diff --git a/res/xml/security_settings_misc.xml b/res/xml/security_settings_misc.xml
index 2577b6c..0ba10c0 100644
--- a/res/xml/security_settings_misc.xml
+++ b/res/xml/security_settings_misc.xml
@@ -15,7 +15,8 @@
 -->
 
 <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
-                  android:title="@string/security_settings_title">
+        xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
+        android:title="@string/security_settings_title">
 
     <PreferenceCategory android:key="sim_lock"
             android:title="@string/sim_lock_settings_title"
@@ -54,7 +55,8 @@
         <com.android.settingslib.RestrictedSwitchPreference android:key="toggle_install_applications"
                 android:title="@string/install_applications"
                 android:summaryOff="@string/install_unknown_applications"
-                android:summaryOn="@string/install_unknown_applications" />
+                android:summaryOn="@string/install_unknown_applications"
+                settings:useAdditionalSummary="true" />
 
     </PreferenceCategory>
 
diff --git a/res/xml/user_settings.xml b/res/xml/user_settings.xml
index b89f766..cd0103d 100644
--- a/res/xml/user_settings.xml
+++ b/res/xml/user_settings.xml
@@ -34,7 +34,8 @@
         <com.android.settingslib.RestrictedSwitchPreference
                 android:key="add_users_when_locked"
                 android:title="@string/user_add_on_lockscreen_menu"
-                android:summary="@string/user_add_on_lockscreen_menu_summary" />
+                android:summary="@string/user_add_on_lockscreen_menu_summary"
+                settings:useAdditionalSummary="true" />
     </PreferenceCategory>
     <Preference
         android:key="emergency_info"
diff --git a/src/com/android/settings/ConfirmDeviceCredentialActivity.java b/src/com/android/settings/ConfirmDeviceCredentialActivity.java
index 16d0685..d71ba9b 100644
--- a/src/com/android/settings/ConfirmDeviceCredentialActivity.java
+++ b/src/com/android/settings/ConfirmDeviceCredentialActivity.java
@@ -95,6 +95,8 @@
     private String getTitleFromOrganizationName(int userId) {
         DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(
                 Context.DEVICE_POLICY_SERVICE);
-        return (dpm != null) ? dpm.getOrganizationNameForUser(userId) : null;
+        CharSequence organizationNameForUser = (dpm != null)
+                ? dpm.getOrganizationNameForUser(userId) : null;
+        return organizationNameForUser != null ? organizationNameForUser.toString() : null;
     }
 }
diff --git a/src/com/android/settings/ConfirmLockPassword.java b/src/com/android/settings/ConfirmLockPassword.java
index ca4be6c..a1bc3dd 100644
--- a/src/com/android/settings/ConfirmLockPassword.java
+++ b/src/com/android/settings/ConfirmLockPassword.java
@@ -267,6 +267,11 @@
                 handleAttemptLockout(deadline);
             } else {
                 resetState();
+                mErrorTextView.setText("");
+                if (isProfileChallenge()) {
+                    updateErrorMessage(mLockPatternUtils.getCurrentFailedPasswordAttempts(
+                            mEffectiveUserId));
+                }
             }
             mCredentialCheckResultTracker.setListener(this);
         }
diff --git a/src/com/android/settings/CryptKeeper.java b/src/com/android/settings/CryptKeeper.java
index 1b37066..594cd38 100644
--- a/src/com/android/settings/CryptKeeper.java
+++ b/src/com/android/settings/CryptKeeper.java
@@ -799,6 +799,8 @@
         // Asynchronously throw up the IME, since there are issues with requesting it to be shown
         // immediately.
         if (mLockPatternView == null && !mCooldown) {
+            getWindow().setSoftInputMode(
+                                WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
             mHandler.postDelayed(new Runnable() {
                 @Override public void run() {
                     imm.showSoftInputUnchecked(0, null);
diff --git a/src/com/android/settings/DeviceAdminAdd.java b/src/com/android/settings/DeviceAdminAdd.java
index 364700b..ddee6aa 100644
--- a/src/com/android/settings/DeviceAdminAdd.java
+++ b/src/com/android/settings/DeviceAdminAdd.java
@@ -82,6 +82,9 @@
     public static final String EXTRA_DEVICE_ADMIN_PACKAGE_NAME =
             "android.app.extra.DEVICE_ADMIN_PACKAGE_NAME";
 
+    public static final String EXTRA_CALLED_FROM_SUPPORT_DIALOG =
+            "android.app.extra.CALLED_FROM_SUPPORT_DIALOG";
+
     Handler mHandler;
 
     DevicePolicyManager mDPM;
@@ -113,6 +116,8 @@
     int mCurSysAppOpMode;
     int mCurToastAppOpMode;
 
+    boolean mIsCalledFromSupportDialog = false;
+
     @Override
     protected void onCreate(Bundle icicle) {
         super.onCreate(icicle);
@@ -129,6 +134,8 @@
             return;
         }
 
+        mIsCalledFromSupportDialog = getIntent().getBooleanExtra(
+                EXTRA_CALLED_FROM_SUPPORT_DIALOG, false);
 
         String action = getIntent().getAction();
         ComponentName who = (ComponentName)getIntent().getParcelableExtra(
@@ -459,6 +466,18 @@
     }
 
     @Override
+    protected void onUserLeaveHint() {
+        super.onUserLeaveHint();
+        // In case this is triggered from support dialog, finish this activity once the user leaves
+        // so that this won't appear as a background next time support dialog is triggered. This
+        // is because the support dialog activity and this belong to the same task and we can't
+        // start this in new activity since we need to know the calling package in this activity.
+        if (mIsCalledFromSupportDialog) {
+            finish();
+        }
+    }
+
+    @Override
     protected Dialog onCreateDialog(int id, Bundle args) {
         switch (id) {
             case DIALOG_WARNING: {
@@ -539,7 +558,7 @@
                     mActionButton.setText(R.string.remove_device_admin);
                 }
             }
-            String supportMessage = mDPM.getLongSupportMessageForUser(
+            CharSequence supportMessage = mDPM.getLongSupportMessageForUser(
                     mDeviceAdmin.getComponent(), UserHandle.myUserId());
             if (!TextUtils.isEmpty(supportMessage)) {
                 mSupportMessage.setText(supportMessage);
diff --git a/src/com/android/settings/PreviewPagerAdapter.java b/src/com/android/settings/PreviewPagerAdapter.java
index 20d1761..7e4ebf3 100644
--- a/src/com/android/settings/PreviewPagerAdapter.java
+++ b/src/com/android/settings/PreviewPagerAdapter.java
@@ -45,19 +45,23 @@
     /** Interpolator to use when cross-fading between previews. */
     private static final Interpolator FADE_OUT_INTERPOLATOR = new AccelerateInterpolator();
 
-    private final FrameLayout[] mPreviewFrames;
+    private FrameLayout[] mPreviewFrames;
+
+    private boolean mIsLayoutRtl;
 
     private Runnable mAnimationEndAction;
 
     private int mAnimationCounter;
 
-    public PreviewPagerAdapter(Context context, int[] previewSampleResIds,
-                               Configuration[] configurations) {
+    public PreviewPagerAdapter(Context context, boolean isLayoutRtl,
+            int[] previewSampleResIds, Configuration[] configurations) {
+        mIsLayoutRtl = isLayoutRtl;
         mPreviewFrames = new FrameLayout[previewSampleResIds.length];
 
         for (int i = 0; i < previewSampleResIds.length; ++i) {
-            mPreviewFrames[i] = new FrameLayout(context);
-            mPreviewFrames[i].setLayoutParams(new LinearLayout.LayoutParams(
+            int p = mIsLayoutRtl ? previewSampleResIds.length - 1 - i : i;
+            mPreviewFrames[p] = new FrameLayout(context);
+            mPreviewFrames[p].setLayoutParams(new LinearLayout.LayoutParams(
                     LinearLayout.LayoutParams.MATCH_PARENT,
                     LinearLayout.LayoutParams.MATCH_PARENT));
 
@@ -69,10 +73,10 @@
 
                 final LayoutInflater configInflater = LayoutInflater.from(configContext);
                 final View sampleView = configInflater.inflate(previewSampleResIds[i],
-                        mPreviewFrames[i], false);
+                        mPreviewFrames[p], false);
                 sampleView.setAlpha(0);
                 sampleView.setVisibility(View.INVISIBLE);
-                mPreviewFrames[i].addView(sampleView);
+                mPreviewFrames[p].addView(sampleView);
             }
         }
     }
diff --git a/src/com/android/settings/PreviewSeekBarPreferenceFragment.java b/src/com/android/settings/PreviewSeekBarPreferenceFragment.java
index aa663cf..ff9e035 100644
--- a/src/com/android/settings/PreviewSeekBarPreferenceFragment.java
+++ b/src/com/android/settings/PreviewSeekBarPreferenceFragment.java
@@ -21,6 +21,7 @@
 import android.os.Bundle;
 import android.support.v4.view.ViewPager;
 import android.support.v4.view.ViewPager.OnPageChangeListener;
+import android.text.TextUtils;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.View.OnClickListener;
@@ -29,9 +30,11 @@
 import android.widget.SeekBar;
 import android.widget.SeekBar.OnSeekBarChangeListener;
 import android.widget.TextView;
+
 import com.android.settings.widget.DotsPageIndicator;
 import com.android.settings.widget.LabeledSeekBar;
 
+import java.util.Locale;
 
 /**
  * Preference fragment shows a preview and a seek bar to adjust a specific settings.
@@ -146,56 +149,28 @@
 
         final Context context = getPrefContext();
         final Configuration origConfig = context.getResources().getConfiguration();
+        final boolean isLayoutRtl = origConfig.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
         Configuration[] configurations = new Configuration[mEntries.length];
         for (int i = 0; i < mEntries.length; ++i) {
             configurations[i] = createConfig(origConfig, i);
         }
 
-        mPreviewPagerAdapter = new PreviewPagerAdapter(context, mPreviewSampleResIds,
-                configurations);
         mPreviewPager = (ViewPager) content.findViewById(R.id.preview_pager);
-        mPreviewPager.setAdapter(mPreviewPagerAdapter);
-        mPreviewPager.addOnPageChangeListener(new OnPageChangeListener() {
-            @Override
-            public void onPageScrollStateChanged(int state) {
-                // Do nothing.
+        if (mPreviewPager != null) {
+            mPreviewPagerAdapter = new PreviewPagerAdapter(context, isLayoutRtl,
+                    mPreviewSampleResIds, configurations);
+            mPreviewPager.setAdapter(mPreviewPagerAdapter);
+            mPreviewPager.setCurrentItem(isLayoutRtl ? mPreviewSampleResIds.length - 1 : 0);
+            mPreviewPager.addOnPageChangeListener(mPreviewPageChangeListener);
+
+            mPageIndicator = (DotsPageIndicator) content.findViewById(R.id.page_indicator);
+            if (mPreviewSampleResIds.length > 1) {
+                mPageIndicator.setViewPager(mPreviewPager);
+                mPageIndicator.setVisibility(View.VISIBLE);
+                mPageIndicator.setOnPageChangeListener(mPageIndicatorPageChangeListener);
+            } else {
+                mPageIndicator.setVisibility(View.GONE);
             }
-
-            @Override
-            public void onPageScrolled(int position, float positionOffset,
-                    int positionOffsetPixels) {
-                // Do nothing.
-            }
-
-            @Override
-            public void onPageSelected(int position) {
-                mPreviewPager.sendAccessibilityEvent(AccessibilityEvent.TYPE_ANNOUNCEMENT);
-            }
-        });
-
-        mPageIndicator = (DotsPageIndicator) content.findViewById(R.id.page_indicator);
-        if (mPreviewSampleResIds.length > 1) {
-            mPageIndicator.setViewPager(mPreviewPager);
-            mPageIndicator.setVisibility(View.VISIBLE);
-            mPageIndicator.setOnPageChangeListener(new OnPageChangeListener() {
-                @Override
-                public void onPageScrollStateChanged(int state) {
-                    // Do nothing.
-                }
-
-                @Override
-                public void onPageScrolled(int position, float positionOffset,
-                        int positionOffsetPixels) {
-                    // Do nothing.
-                }
-
-                @Override
-                public void onPageSelected(int position) {
-                    setPagerIndicatorContentDescription(position);
-                }
-            });
-        } else {
-            mPageIndicator.setVisibility(View.GONE);
         }
 
         setPreviewLayer(mInitialIndex, false);
@@ -207,15 +182,21 @@
      */
     protected abstract Configuration createConfig(Configuration origConfig, int index);
 
+    /**
+     * Persists the selected value and sends a configuration change.
+     */
+    protected abstract void commit();
+
     private void setPreviewLayer(int index, boolean animate) {
         mLabel.setText(mEntries[index]);
         mSmaller.setEnabled(index > 0);
         mLarger.setEnabled(index < mEntries.length - 1);
+        if (mPreviewPager != null) {
+            setPagerIndicatorContentDescription(mPreviewPager.getCurrentItem());
+            mPreviewPagerAdapter.setPreviewLayer(index, mCurrentIndex,
+                    mPreviewPager.getCurrentItem(), animate);
+        }
 
-        setPagerIndicatorContentDescription(mPreviewPager.getCurrentItem());
-
-        mPreviewPagerAdapter.setPreviewLayer(index, mCurrentIndex, mPreviewPager.getCurrentItem(),
-                animate);
         mCurrentIndex = index;
     }
 
@@ -225,8 +206,39 @@
                         position + 1, mPreviewSampleResIds.length));
     }
 
-    /**
-     * Persists the selected value and sends a configuration change.
-     */
-    protected abstract void commit();
+    private OnPageChangeListener mPreviewPageChangeListener = new OnPageChangeListener() {
+        @Override
+        public void onPageScrollStateChanged(int state) {
+            // Do nothing.
+        }
+
+        @Override
+        public void onPageScrolled(int position, float positionOffset,
+                int positionOffsetPixels) {
+            // Do nothing.
+        }
+
+        @Override
+        public void onPageSelected(int position) {
+            mPreviewPager.sendAccessibilityEvent(AccessibilityEvent.TYPE_ANNOUNCEMENT);
+        }
+    };
+
+    private OnPageChangeListener mPageIndicatorPageChangeListener = new OnPageChangeListener() {
+        @Override
+        public void onPageScrollStateChanged(int state) {
+            // Do nothing.
+        }
+
+        @Override
+        public void onPageScrolled(int position, float positionOffset,
+                int positionOffsetPixels) {
+            // Do nothing.
+        }
+
+        @Override
+        public void onPageSelected(int position) {
+            setPagerIndicatorContentDescription(position);
+        }
+    };
 }
diff --git a/src/com/android/settings/SecuritySettings.java b/src/com/android/settings/SecuritySettings.java
index 049660e..b45a988 100644
--- a/src/com/android/settings/SecuritySettings.java
+++ b/src/com/android/settings/SecuritySettings.java
@@ -625,7 +625,7 @@
             startFragment(this, "com.android.settings.ChooseLockGeneric$ChooseLockGenericFragment",
                     R.string.lock_settings_picker_title, SET_OR_CHANGE_LOCK_METHOD_REQUEST, null);
         } else if (KEY_UNLOCK_SET_OR_CHANGE_PROFILE.equals(key)) {
-            if (Utils.startQuiteModeDialogIfNecessary(this.getActivity(), mUm,
+            if (Utils.startQuietModeDialogIfNecessary(this.getActivity(), mUm,
                     mProfileChallengeUserId)) {
                 return false;
             }
@@ -750,13 +750,13 @@
         final String key = preference.getKey();
         final LockPatternUtils lockPatternUtils = mChooseLockSettingsHelper.utils();
         if (KEY_VISIBLE_PATTERN_PROFILE.equals(key)) {
-            if (Utils.startQuiteModeDialogIfNecessary(this.getActivity(), mUm,
+            if (Utils.startQuietModeDialogIfNecessary(this.getActivity(), mUm,
                     mProfileChallengeUserId)) {
                 return false;
             }
             lockPatternUtils.setVisiblePatternEnabled((Boolean) value, mProfileChallengeUserId);
         } else if (KEY_UNIFICATION.equals(key)) {
-            if (Utils.startQuiteModeDialogIfNecessary(this.getActivity(), mUm,
+            if (Utils.startQuietModeDialogIfNecessary(this.getActivity(), mUm,
                     mProfileChallengeUserId)) {
                 return false;
             }
diff --git a/src/com/android/settings/ShowAdminSupportDetailsDialog.java b/src/com/android/settings/ShowAdminSupportDetailsDialog.java
index 2f2379a..fce669c 100644
--- a/src/com/android/settings/ShowAdminSupportDetailsDialog.java
+++ b/src/com/android/settings/ShowAdminSupportDetailsDialog.java
@@ -155,6 +155,7 @@
                             intent.setClass(activity, DeviceAdminAdd.class);
                             intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
                                     enforcedAdmin.component);
+                            intent.putExtra(DeviceAdminAdd.EXTRA_CALLED_FROM_SUPPORT_DIALOG, true);
                             // DeviceAdminAdd class may need to run as managed profile.
                             activity.startActivityAsUser(intent,
                                     new UserHandle(enforcedAdmin.userId));
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index 4dd203c..46a3d9b 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -336,24 +336,31 @@
     }
 
     /* Used by UserSettings as well. Call this on a non-ui thread. */
-    public static boolean copyMeProfilePhoto(Context context, UserInfo user) {
+    public static void copyMeProfilePhoto(Context context, UserInfo user) {
         Uri contactUri = Profile.CONTENT_URI;
 
+        int userId = user != null ? user.id : UserHandle.myUserId();
+
         InputStream avatarDataStream = Contacts.openContactPhotoInputStream(
                     context.getContentResolver(),
                     contactUri, true);
         // If there's no profile photo, assign a default avatar
         if (avatarDataStream == null) {
-            return false;
+            assignDefaultPhoto(context, userId);
+        } else {
+            UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
+            Bitmap icon = BitmapFactory.decodeStream(avatarDataStream);
+            um.setUserIcon(userId, icon);
         }
-        int userId = user != null ? user.id : UserHandle.myUserId();
-        UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
-        Bitmap icon = BitmapFactory.decodeStream(avatarDataStream);
-        um.setUserIcon(userId, icon);
         try {
             avatarDataStream.close();
         } catch (IOException ioe) { }
-        return true;
+    }
+
+    public static void assignDefaultPhoto(Context context, int userId) {
+        UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
+        Bitmap bitmap = getDefaultUserIconAsBitmap(userId);
+        um.setUserIcon(userId, bitmap);
     }
 
     public static String getMeProfileName(Context context, boolean full) {
@@ -1107,7 +1114,7 @@
                 Settings.Global.DEVICE_PROVISIONED, 0) != 0;
     }
 
-    public static boolean startQuiteModeDialogIfNecessary(Context context, UserManager um,
+    public static boolean startQuietModeDialogIfNecessary(Context context, UserManager um,
             int userId) {
         if (um.isQuietModeEnabled(UserHandle.of(userId))) {
             final Intent intent = UnlaunchableAppActivity.createInQuietModeDialogIntent(userId);
diff --git a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java
index 748dc15..e6a8c1e 100644
--- a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java
@@ -30,20 +30,24 @@
 import android.support.v7.preference.PreferenceScreen;
 import android.support.v7.preference.PreferenceViewHolder;
 import android.view.Display;
-import android.view.Gravity;
+import android.view.ViewTreeObserver;
+import android.view.ViewTreeObserver.OnGlobalLayoutListener;
 import android.view.WindowManager;
+import android.widget.ImageView;
 import android.widget.MediaController;
-import android.widget.RelativeLayout;
+import android.widget.RelativeLayout.LayoutParams;
 import android.widget.VideoView;
 import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.settings.R;
 import com.android.settings.widget.ToggleSwitch;
 import com.android.settings.widget.ToggleSwitch.OnBeforeCheckedChangeListener;
 
-public class ToggleScreenMagnificationPreferenceFragment
-        extends ToggleFeaturePreferenceFragment {
+public class ToggleScreenMagnificationPreferenceFragment extends ToggleFeaturePreferenceFragment {
 
     protected class VideoPreference extends Preference {
+        private ImageView mVideoBackgroundView;
+        private OnGlobalLayoutListener mLayoutListener;
+
         public VideoPreference(Context context) {
             super(context);
         }
@@ -51,40 +55,19 @@
         @Override
         public void onBindViewHolder(PreferenceViewHolder view) {
             super.onBindViewHolder(view);
+            Resources res = getPrefContext().getResources();
+            final int backgroundAssetWidth = res.getDimensionPixelSize(
+                    R.dimen.screen_magnification_video_background_width);
+            final int videoAssetWidth = res
+                    .getDimensionPixelSize(R.dimen.screen_magnification_video_width);
+            final int videoAssetHeight = res
+                    .getDimensionPixelSize(R.dimen.screen_magnification_video_height);
+            final int videoAssetMarginTop = res.getDimensionPixelSize(
+                    R.dimen.screen_magnification_video_margin_top);
             view.setDividerAllowedAbove(false);
             view.setDividerAllowedBelow(false);
-            final RelativeLayout background =
-                    (RelativeLayout) view.findViewById(R.id.video_background);
-            VideoView videoView = (VideoView) view.findViewById(R.id.video);
-
-            // Hacky adjustment for using VideoView in recycle view and positioning
-            // it on the background image
-            Resources res = getPrefContext().getResources();
-            final int backgroundWidth = res.getDimensionPixelSize(
-                    R.dimen.screen_magnification_video_background_width);
-            final int backgroundHeight = res.getDimensionPixelSize(
-                    R.dimen.screen_magnification_video_background_height);
-            final int videoWidth = res.getDimensionPixelSize(
-                    R.dimen.screen_magnification_video_width);
-            final int videoHeight = res.getDimensionPixelSize(
-                    R.dimen.screen_magnification_video_height);
-            final int videoMarginTop = res.getDimensionPixelSize(
-                    R.dimen.screen_magnification_video_margin_top);
-            final int screenWidth = getScreenWidth(getPrefContext());
-
-            RelativeLayout.LayoutParams videoLp = new RelativeLayout.LayoutParams(
-                    screenWidth * videoWidth / backgroundWidth,
-                    screenWidth * videoHeight / backgroundWidth);
-            videoLp.setMargins(0, screenWidth * videoMarginTop / backgroundWidth, 0, 0);
-            videoView.setLayoutParams(videoLp);
-
-            RelativeLayout.LayoutParams backgroundLp = new RelativeLayout.LayoutParams(
-                    screenWidth,
-                    screenWidth * backgroundHeight / backgroundWidth);
-            background.setLayoutParams(backgroundLp);
-            background.setBackgroundResource(
-                    R.drawable.accessibility_screen_magnification_background);
-            background.setGravity(Gravity.CENTER_HORIZONTAL);
+            mVideoBackgroundView = (ImageView) view.findViewById(R.id.video_background);
+            final VideoView videoView = (VideoView) view.findViewById(R.id.video);
 
             // Loop the video.
             videoView.setOnPreparedListener(new OnPreparedListener() {
@@ -100,7 +83,31 @@
                     R.raw.accessibility_screen_magnification)));
             // Make sure video controls (e.g. for pausing) are not displayed.
             videoView.setMediaController(null);
-            videoView.start();
+
+            // LayoutListener for adjusting the position of the VideoView on the background image.
+            mLayoutListener = new OnGlobalLayoutListener() {
+                @Override
+                public void onGlobalLayout() {
+                    final int backgroundViewWidth = mVideoBackgroundView.getWidth();
+
+                    LayoutParams videoLp = (LayoutParams) videoView.getLayoutParams();
+                    videoLp.width = videoAssetWidth * backgroundViewWidth / backgroundAssetWidth;
+                    videoLp.height = videoAssetHeight * backgroundViewWidth / backgroundAssetWidth;
+                    videoLp.setMargins(0,
+                            videoAssetMarginTop * backgroundViewWidth / backgroundAssetWidth, 0, 0);
+                    videoView.setLayoutParams(videoLp);
+                    videoView.invalidate();
+                    videoView.start();
+                }
+            };
+
+            mVideoBackgroundView.getViewTreeObserver().addOnGlobalLayoutListener(mLayoutListener);
+        }
+
+        @Override
+        protected void onPrepareForRemoval() {
+            mVideoBackgroundView.getViewTreeObserver()
+                    .removeOnGlobalLayoutListener(mLayoutListener);
         }
     }
 
diff --git a/src/com/android/settings/applications/InstalledAppDetails.java b/src/com/android/settings/applications/InstalledAppDetails.java
index f91f7bf..035b504 100755
--- a/src/com/android/settings/applications/InstalledAppDetails.java
+++ b/src/com/android/settings/applications/InstalledAppDetails.java
@@ -424,7 +424,7 @@
 
     private Intent resolveIntent(Intent i) {
         ResolveInfo result = getContext().getPackageManager().resolveActivity(i, 0);
-        return result != null ? new Intent(Intent.ACTION_APPLICATION_PREFERENCES)
+        return result != null ? new Intent(i.getAction())
                 .setClassName(result.activityInfo.packageName, result.activityInfo.name) : null;
     }
 
@@ -902,6 +902,26 @@
                 category.addPreference(pref);
             }
         }
+
+        final String installerPackageName =
+                getContext().getPackageManager().getInstallerPackageName(mPackageName);
+        if (installerPackageName != null) {
+            final Intent intent = new Intent(Intent.ACTION_SHOW_APP_INFO)
+                    .setPackage(installerPackageName);
+            final Intent result = resolveIntent(intent);
+            if (result != null) {
+                result.putExtra(Intent.EXTRA_PACKAGE_NAME, mPackageName);
+                PreferenceCategory category = new PreferenceCategory(getPrefContext());
+                category.setTitle(R.string.app_install_details_group_title);
+                screen.addPreference(category);
+                Preference pref = new Preference(getPrefContext());
+                pref.setTitle(R.string.app_install_details_title);
+                pref.setKey("app_info_store");
+                pref.setSummary(getString(R.string.app_install_details_summary, mAppEntry.label));
+                pref.setIntent(result);
+                category.addPreference(pref);
+            }
+        }
     }
 
     private boolean hasPermission(String permission) {
diff --git a/src/com/android/settings/dashboard/DashboardDecorator.java b/src/com/android/settings/dashboard/DashboardDecorator.java
index 2e7afaf..9bcf39d 100644
--- a/src/com/android/settings/dashboard/DashboardDecorator.java
+++ b/src/com/android/settings/dashboard/DashboardDecorator.java
@@ -21,7 +21,6 @@
 import android.support.v7.widget.RecyclerView;
 import android.support.v7.widget.RecyclerView.State;
 import android.support.v7.widget.RecyclerView.ViewHolder;
-import android.util.Log;
 import android.util.TypedValue;
 import android.view.View;
 import com.android.settings.R;
@@ -41,8 +40,6 @@
     @Override
     public void onDrawOver(Canvas c, RecyclerView parent, State state) {
         final int childCount = parent.getChildCount();
-        final int width = parent.getWidth();
-        final int bottom = parent.getBottom();
         for (int i = 1; i < childCount; i++) {
             final View child = parent.getChildAt(i);
             final ViewHolder holder = parent.getChildViewHolder(child);
@@ -56,7 +53,8 @@
             }
 
             int top = getChildTop(child);
-            mDivider.setBounds(0, top, width, top + mDivider.getIntrinsicHeight());
+            mDivider.setBounds(child.getLeft(), top, child.getRight(),
+                    top + mDivider.getIntrinsicHeight());
             mDivider.draw(c);
         }
     }
diff --git a/src/com/android/settings/dashboard/conditional/ConditionManager.java b/src/com/android/settings/dashboard/conditional/ConditionManager.java
index 24d5f09..0d02ae2 100644
--- a/src/com/android/settings/dashboard/conditional/ConditionManager.java
+++ b/src/com/android/settings/dashboard/conditional/ConditionManager.java
@@ -36,7 +36,7 @@
 
     private static final String TAG = "ConditionManager";
 
-    private static final boolean DEBUG = true;
+    private static final boolean DEBUG = false;
 
     private static final String PKG = "com.android.settings.dashboard.conditional.";
 
diff --git a/src/com/android/settings/datausage/AppDataUsage.java b/src/com/android/settings/datausage/AppDataUsage.java
index b3c8e03..701b8c4 100644
--- a/src/com/android/settings/datausage/AppDataUsage.java
+++ b/src/com/android/settings/datausage/AppDataUsage.java
@@ -236,7 +236,12 @@
             mRestrictBackground.setChecked(!getAppRestrictBackground());
         }
         if (mUnrestrictedData != null) {
-            mUnrestrictedData.setChecked(mDataSaverBackend.isWhitelisted(mAppItem.key));
+            if (getAppRestrictBackground()) {
+                mUnrestrictedData.setVisible(false);
+            } else {
+                mUnrestrictedData.setVisible(true);
+                mUnrestrictedData.setChecked(mDataSaverBackend.isWhitelisted(mAppItem.key));
+            }
         }
     }
 
@@ -250,18 +255,21 @@
     }
 
     private void bindData() {
+        final long backgroundBytes, foregroundBytes;
         if (mChartData == null || mStart == 0) {
-            return;
+            backgroundBytes = foregroundBytes = 0;
+            mCycle.setVisible(false);
+        } else {
+            mCycle.setVisible(true);
+            final long now = System.currentTimeMillis();
+            NetworkStatsHistory.Entry entry = null;
+            entry = mChartData.detailDefault.getValues(mStart, mEnd, now, entry);
+            backgroundBytes = entry.rxBytes + entry.txBytes;
+            entry = mChartData.detailForeground.getValues(mStart, mEnd, now, entry);
+            foregroundBytes = entry.rxBytes + entry.txBytes;
         }
-        final Context context = getContext();
-        final long now = System.currentTimeMillis();
-
-        NetworkStatsHistory.Entry entry = null;
-        entry = mChartData.detailDefault.getValues(mStart, mEnd, now, entry);
-        final long backgroundBytes = entry.rxBytes + entry.txBytes;
-        entry = mChartData.detailForeground.getValues(mStart, mEnd, now, entry);
-        final long foregroundBytes = entry.rxBytes + entry.txBytes;
         final long totalBytes = backgroundBytes + foregroundBytes;
+        final Context context = getContext();
 
         mTotalUsage.setSummary(Formatter.formatFileSize(context, totalBytes));
         mForegroundUsage.setSummary(Formatter.formatFileSize(context, foregroundBytes));
@@ -278,6 +286,7 @@
         final int uid = mAppItem.key;
         services.mPolicyManager.setUidPolicy(
                 uid, restrictBackground ? POLICY_REJECT_METERED_BACKGROUND : POLICY_NONE);
+        updatePrefs();        // TODO: should have been notified by NPMS instead
     }
 
     @Override
diff --git a/src/com/android/settings/datausage/DataSaverSummary.java b/src/com/android/settings/datausage/DataSaverSummary.java
index e12afbf..e8c8cdd 100644
--- a/src/com/android/settings/datausage/DataSaverSummary.java
+++ b/src/com/android/settings/datausage/DataSaverSummary.java
@@ -100,6 +100,9 @@
 
     @Override
     public void onExtraInfoUpdated() {
+        if (!isAdded()) {
+            return;
+        }
         int count = 0;
         final ArrayList<AppEntry> allApps = mSession.getAllApps();
         final int N = allApps.size();
diff --git a/src/com/android/settings/fingerprint/FingerprintSettings.java b/src/com/android/settings/fingerprint/FingerprintSettings.java
index 3b83e48..6fd2d14 100644
--- a/src/com/android/settings/fingerprint/FingerprintSettings.java
+++ b/src/com/android/settings/fingerprint/FingerprintSettings.java
@@ -837,7 +837,7 @@
             public boolean onPreferenceClick(Preference preference) {
                 final Context context = preference.getContext();
                 final UserManager userManager = UserManager.get(context);
-                if (Utils.startQuiteModeDialogIfNecessary(context, userManager,
+                if (Utils.startQuietModeDialogIfNecessary(context, userManager,
                         userId)) {
                     return false;
                 }
diff --git a/src/com/android/settings/inputmethod/PhysicalKeyboardFragment.java b/src/com/android/settings/inputmethod/PhysicalKeyboardFragment.java
index fb44a3d..cf8db7a 100644
--- a/src/com/android/settings/inputmethod/PhysicalKeyboardFragment.java
+++ b/src/com/android/settings/inputmethod/PhysicalKeyboardFragment.java
@@ -54,6 +54,7 @@
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.List;
 
 public final class PhysicalKeyboardFragment extends SettingsPreferenceFragment
         implements InputManager.InputDeviceListener {
@@ -65,7 +66,7 @@
     private static final String IM_SUBTYPE_MODE_KEYBOARD = "keyboard";
 
     @NonNull
-    private final ArrayList<HardKeyboardDeviceInfo> mLastHardKeyboards = new ArrayList<>();
+    private final List<HardKeyboardDeviceInfo> mLastHardKeyboards = new ArrayList<>();
 
     @NonNull
     private final HashSet<Integer> mLoaderIDs = new HashSet<>();
@@ -128,32 +129,42 @@
         unregisterShowVirtualKeyboardSettingsObserver();
     }
 
-    public void onLoadFinishedInternal(final int loaderId, @NonNull final Keyboards data,
-            @NonNull final PreferenceCategory preferenceCategory) {
+    public void onLoadFinishedInternal(
+            final int loaderId, @NonNull final List<Keyboards> keyboardsList) {
         if (!mLoaderIDs.remove(loaderId)) {
             // Already destroyed loader.  Ignore.
             return;
         }
 
-        final InputDeviceIdentifier deviceId = data.mInputDeviceIdentifier;
-        preferenceCategory.removeAll();
-        for (Keyboards.KeyboardInfo info : data.mKeyboardInfoList) {
-            Preference pref = new Preference(getPrefContext(), null);
-            final InputMethodInfo imi = info.mImi;
-            final InputMethodSubtype imSubtype = info.mImSubtype;
-            if (imi != null && imSubtype != null) {
-                pref.setTitle(getDisplayName(getContext(), imi, imSubtype));
-                KeyboardLayout layout = info.mLayout;
-                if (layout != null) {
-                    pref.setSummary(layout.getLabel());
+        final PreferenceScreen preferenceScreen = getPreferenceScreen();
+        preferenceScreen.removeAll();
+        for (Keyboards keyboards : keyboardsList) {
+            final PreferenceCategory category = new PreferenceCategory(getPrefContext(), null);
+            category.setTitle(keyboards.mDeviceInfo.mDeviceName);
+            category.setOrder(0);
+            preferenceScreen.addPreference(category);
+            for (Keyboards.KeyboardInfo info : keyboards.mKeyboardInfoList) {
+                Preference pref = new Preference(getPrefContext(), null);
+                final InputMethodInfo imi = info.mImi;
+                final InputMethodSubtype imSubtype = info.mImSubtype;
+                if (imi != null && imSubtype != null) {
+                    pref.setTitle(getDisplayName(getContext(), imi, imSubtype));
+                    KeyboardLayout layout = info.mLayout;
+                    if (layout != null) {
+                        pref.setSummary(layout.getLabel());
+                    }
+                    pref.setOnPreferenceClickListener(preference -> {
+                        showKeyboardLayoutScreen(
+                                keyboards.mDeviceInfo.mDeviceIdentifier, imi, imSubtype);
+                        return true;
+                    });
+                    category.addPreference(pref);
                 }
-                pref.setOnPreferenceClickListener(preference -> {
-                    showKeyboardLayoutScreen(deviceId, imi, imSubtype);
-                    return true;
-                });
-                preferenceCategory.addPreference(pref);
             }
         }
+        mKeyboardAssistanceCategory.setOrder(1);
+        preferenceScreen.addPreference(mKeyboardAssistanceCategory);
+        updateShowVirtualKeyboardSwitch();
     }
 
     @Override
@@ -193,27 +204,13 @@
         final ArrayList<HardKeyboardDeviceInfo> newHardKeyboards = getHardKeyboards();
         if (!Objects.equal(newHardKeyboards, mLastHardKeyboards)) {
             clearLoader();
-            final PreferenceScreen preferenceScreen = getPreferenceScreen();
-            preferenceScreen.removeAll();
             mLastHardKeyboards.clear();
             mLastHardKeyboards.addAll(newHardKeyboards);
-            final int N = newHardKeyboards.size();
-            for (int i = 0; i < N; ++i) {
-                final HardKeyboardDeviceInfo deviceInfo = newHardKeyboards.get(i);
-                final PreferenceCategory category = new PreferenceCategory(getPrefContext(), null);
-                category.setTitle(deviceInfo.mDeviceName);
-                category.setOrder(0);
-                getLoaderManager().initLoader(mNextLoaderId, null,
-                        new Callbacks(getContext(), this, deviceInfo.mDeviceIdentifier, category));
-                mLoaderIDs.add(mNextLoaderId);
-                ++mNextLoaderId;
-                preferenceScreen.addPreference(category);
-            }
-            mKeyboardAssistanceCategory.setOrder(1);
-            preferenceScreen.addPreference(mKeyboardAssistanceCategory);
-
+            getLoaderManager().initLoader(mNextLoaderId, null,
+                    new Callbacks(getContext(), this, mLastHardKeyboards));
+            mLoaderIDs.add(mNextLoaderId);
+            ++mNextLoaderId;
         }
-        updateShowVirtualKeyboardSwitch();
     }
 
     private void showKeyboardLayoutScreen(
@@ -285,56 +282,49 @@
                 context.getString(R.string.physical_device_title), imSubtypeName, imeName);
     }
 
-    private static final class Callbacks
-            implements LoaderManager.LoaderCallbacks<PhysicalKeyboardFragment.Keyboards> {
+    private static final class Callbacks implements LoaderManager.LoaderCallbacks<List<Keyboards>> {
         @NonNull
         final Context mContext;
         @NonNull
         final PhysicalKeyboardFragment mPhysicalKeyboardFragment;
         @NonNull
-        final InputDeviceIdentifier mInputDeviceIdentifier;
-        @NonNull
-        final PreferenceCategory mPreferenceCategory;
+        final List<HardKeyboardDeviceInfo> mHardKeyboards;
         public Callbacks(
                 @NonNull Context context,
                 @NonNull PhysicalKeyboardFragment physicalKeyboardFragment,
-                @NonNull InputDeviceIdentifier inputDeviceIdentifier,
-                @NonNull PreferenceCategory preferenceCategory) {
+                @NonNull List<HardKeyboardDeviceInfo> hardKeyboards) {
             mContext = context;
             mPhysicalKeyboardFragment = physicalKeyboardFragment;
-            mInputDeviceIdentifier = inputDeviceIdentifier;
-            mPreferenceCategory = preferenceCategory;
+            mHardKeyboards = hardKeyboards;
         }
 
         @Override
-        public Loader<Keyboards> onCreateLoader(int id, Bundle args) {
-            return new KeyboardLayoutLoader(mContext, mInputDeviceIdentifier);
+        public Loader<List<Keyboards>> onCreateLoader(int id, Bundle args) {
+            return new KeyboardLayoutLoader(mContext, mHardKeyboards);
         }
 
         @Override
-        public void onLoadFinished(Loader<Keyboards> loader, Keyboards data) {
-            mPhysicalKeyboardFragment.onLoadFinishedInternal(loader.getId(), data,
-                    mPreferenceCategory);
+        public void onLoadFinished(Loader<List<Keyboards>> loader, List<Keyboards> data) {
+            mPhysicalKeyboardFragment.onLoadFinishedInternal(loader.getId(), data);
         }
 
         @Override
-        public void onLoaderReset(Loader<Keyboards> loader) {
+        public void onLoaderReset(Loader<List<Keyboards>> loader) {
         }
     }
 
-    private static final class KeyboardLayoutLoader extends AsyncTaskLoader<Keyboards> {
+    private static final class KeyboardLayoutLoader extends AsyncTaskLoader<List<Keyboards>> {
         @NonNull
-        private final InputDeviceIdentifier mInputDeviceIdentifier;
+        private final List<HardKeyboardDeviceInfo> mHardKeyboards;
 
         public KeyboardLayoutLoader(
                 @NonNull Context context,
-                @NonNull InputDeviceIdentifier inputDeviceIdentifier) {
+                @NonNull List<HardKeyboardDeviceInfo> hardKeyboards) {
             super(context);
-            mInputDeviceIdentifier = Preconditions.checkNotNull(inputDeviceIdentifier);
+            mHardKeyboards = Preconditions.checkNotNull(hardKeyboards);
         }
 
-        @Override
-        public Keyboards loadInBackground() {
+        private Keyboards loadInBackground(HardKeyboardDeviceInfo deviceInfo) {
             final ArrayList<Keyboards.KeyboardInfo> keyboardInfoList = new ArrayList<>();
             final InputMethodManager imm = getContext().getSystemService(InputMethodManager.class);
             final InputManager im = getContext().getSystemService(InputManager.class);
@@ -346,12 +336,21 @@
                             continue;
                         }
                         final KeyboardLayout layout = im.getKeyboardLayoutForInputDevice(
-                                mInputDeviceIdentifier, imi, subtype);
+                                deviceInfo.mDeviceIdentifier, imi, subtype);
                         keyboardInfoList.add(new Keyboards.KeyboardInfo(imi, subtype, layout));
                     }
                 }
             }
-            return new Keyboards(mInputDeviceIdentifier, keyboardInfoList);
+            return new Keyboards(deviceInfo, keyboardInfoList);
+        }
+
+        @Override
+        public List<Keyboards> loadInBackground() {
+            List<Keyboards> keyboardsList = new ArrayList<>(mHardKeyboards.size());
+            for (HardKeyboardDeviceInfo deviceInfo : mHardKeyboards) {
+                keyboardsList.add(loadInBackground(deviceInfo));
+            }
+            return keyboardsList;
         }
 
         @Override
@@ -408,14 +407,14 @@
 
     public static final class Keyboards {
         @NonNull
-        public final InputDeviceIdentifier mInputDeviceIdentifier;
+        public final HardKeyboardDeviceInfo mDeviceInfo;
         @NonNull
         public final ArrayList<KeyboardInfo> mKeyboardInfoList;
 
         public Keyboards(
-                @NonNull final InputDeviceIdentifier inputDeviceIdentifier,
+                @NonNull final HardKeyboardDeviceInfo deviceInfo,
                 @NonNull final ArrayList<KeyboardInfo> keyboardInfoList) {
-            mInputDeviceIdentifier = inputDeviceIdentifier;
+            mDeviceInfo = deviceInfo;
             mKeyboardInfoList = keyboardInfoList;
         }
 
diff --git a/src/com/android/settings/notification/ConfigureNotificationSettings.java b/src/com/android/settings/notification/ConfigureNotificationSettings.java
index 4d50461..9acac06 100644
--- a/src/com/android/settings/notification/ConfigureNotificationSettings.java
+++ b/src/com/android/settings/notification/ConfigureNotificationSettings.java
@@ -213,7 +213,7 @@
             Log.i(TAG, "Preference not found: " + KEY_LOCK_SCREEN_PROFILE_NOTIFICATIONS);
             return;
         }
-
+        mLockscreenProfile.setUserId(mProfileChallengeUserId);
         ArrayList<CharSequence> entries = new ArrayList<>();
         ArrayList<CharSequence> values = new ArrayList<>();
         entries.add(getString(R.string.lock_screen_notifications_summary_disable_profile));
@@ -241,6 +241,8 @@
 
         mLockscreenProfile.setEntries(entries.toArray(new CharSequence[entries.size()]));
         mLockscreenProfile.setEntryValues(values.toArray(new CharSequence[values.size()]));
+        // Work profile does not support this settings as we do not have a policy to enforce it yet
+        mLockscreenProfile.setRemoteInputCheckBoxEnabled(false);
         updateLockscreenNotificationsForProfile();
         if (mLockscreenProfile.getEntries().length > 1) {
             mLockscreenProfile.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
diff --git a/src/com/android/settings/notification/NotificationAccessSettings.java b/src/com/android/settings/notification/NotificationAccessSettings.java
index 0111a38..d81bc0e 100644
--- a/src/com/android/settings/notification/NotificationAccessSettings.java
+++ b/src/com/android/settings/notification/NotificationAccessSettings.java
@@ -16,8 +16,16 @@
 
 package com.android.settings.notification;
 
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.NotificationManager;
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.DialogInterface;
 import android.content.pm.PackageManager;
+import android.os.AsyncTask;
+import android.os.Bundle;
 import android.provider.Settings;
 import android.service.notification.NotificationListenerService;
 
@@ -30,6 +38,14 @@
     private static final String TAG = NotificationAccessSettings.class.getSimpleName();
     private static final Config CONFIG = getNotificationListenerConfig();
 
+    private NotificationManager mNm;
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        mNm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+    }
+
     private static Config getNotificationListenerConfig() {
         final Config c = new Config();
         c.tag = TAG;
@@ -60,4 +76,74 @@
     public static int getEnabledListenersCount(Context context) {
         return ServiceListing.getEnabledServicesCount(CONFIG, context);
     }
+
+    protected boolean setEnabled(ComponentName service, String title, boolean enable) {
+        if (!enable) {
+            if (!mServiceListing.isEnabled(service)) {
+                return true; // already disabled
+            }
+            // show a friendly dialog
+            new FriendlyWarningDialogFragment()
+                    .setServiceInfo(service, title)
+                    .show(getFragmentManager(), "friendlydialog");
+            return false;
+        } else {
+            return super.setEnabled(service, title, enable);
+        }
+    }
+
+    private static void deleteRules(final Context context, final String pkg) {
+        AsyncTask.execute(new Runnable() {
+            @Override
+            public void run() {
+                final NotificationManager mgr = context.getSystemService(NotificationManager.class);
+                mgr.removeAutomaticZenRules(pkg);
+            }
+        });
+    }
+
+    public class FriendlyWarningDialogFragment extends DialogFragment {
+        static final String KEY_COMPONENT = "c";
+        static final String KEY_LABEL = "l";
+
+        public FriendlyWarningDialogFragment setServiceInfo(ComponentName cn, String label) {
+            Bundle args = new Bundle();
+            args.putString(KEY_COMPONENT, cn.flattenToString());
+            args.putString(KEY_LABEL, label);
+            setArguments(args);
+            return this;
+        }
+
+        @Override
+        public Dialog onCreateDialog(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            final Bundle args = getArguments();
+            final String label = args.getString(KEY_LABEL);
+            final ComponentName cn = ComponentName.unflattenFromString(args
+                    .getString(KEY_COMPONENT));
+
+            final String summary = getResources().getString(
+                    R.string.notification_listener_disable_warning_summary, label);
+            return new AlertDialog.Builder(mContext)
+                    .setMessage(summary)
+                    .setCancelable(true)
+                    .setPositiveButton(R.string.notification_listener_disable_warning_confirm,
+                            new DialogInterface.OnClickListener() {
+                                public void onClick(DialogInterface dialog, int id) {
+                                    mServiceListing.setEnabled(cn, false);
+                                    if (!mNm.isNotificationPolicyAccessGrantedForPackage(
+                                            cn.getPackageName())) {
+                                        deleteRules(mContext, cn.getPackageName());
+                                    }
+                                }
+                            })
+                    .setNegativeButton(R.string.notification_listener_disable_warning_cancel,
+                            new DialogInterface.OnClickListener() {
+                                public void onClick(DialogInterface dialog, int id) {
+                                    // pass
+                                }
+                            })
+                    .create();
+        }
+    }
 }
diff --git a/src/com/android/settings/notification/NotificationLockscreenPreference.java b/src/com/android/settings/notification/NotificationLockscreenPreference.java
index 39b9c5d..8c89968 100644
--- a/src/com/android/settings/notification/NotificationLockscreenPreference.java
+++ b/src/com/android/settings/notification/NotificationLockscreenPreference.java
@@ -18,11 +18,14 @@
 
 import com.android.settings.R;
 import com.android.settings.RestrictedListPreference;
+import com.android.settings.Utils;
 
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.content.Context;
 import android.content.DialogInterface;
+import android.os.UserHandle;
+import android.os.UserManager;
 import android.provider.Settings;
 import android.util.AttributeSet;
 import android.view.View;
@@ -37,11 +40,31 @@
     private int mInitialIndex;
     private Listener mListener;
     private boolean mShowRemoteInput;
+    private boolean mRemoteInputCheckBoxEnabled = true;
+    private int mUserId = UserHandle.myUserId();
 
     public NotificationLockscreenPreference(Context context, AttributeSet attrs) {
         super(context, attrs);
     }
 
+    public void setRemoteInputCheckBoxEnabled(boolean enabled) {
+        mRemoteInputCheckBoxEnabled = enabled;
+    }
+
+    @Override
+    protected void onClick() {
+        final Context context = getContext();
+        if (!Utils.startQuietModeDialogIfNecessary(context, UserManager.get(context), mUserId)) {
+            // Call super to create preference dialog only when work mode is on
+            // startQuietModeDialogIfNecessary will return false if mUserId is not a managed user
+            super.onClick();
+        }
+    }
+
+    public void setUserId(int userId) {
+        mUserId = userId;
+    }
+
     @Override
     protected void onPrepareDialogBuilder(AlertDialog.Builder builder,
             DialogInterface.OnClickListener innerListener) {
@@ -85,8 +108,10 @@
         return false;
     }
 
-    private static int checkboxVisibilityForSelectedIndex(int selected, boolean showRemoteAtAll) {
-        return selected == 1 && showRemoteAtAll ? View.VISIBLE : View.GONE;
+    private int checkboxVisibilityForSelectedIndex(int selected,
+            boolean showRemoteAtAll) {
+        return selected == 1 && showRemoteAtAll && mRemoteInputCheckBoxEnabled ? View.VISIBLE
+                : View.GONE;
     }
 
     private class Listener implements DialogInterface.OnClickListener,
diff --git a/src/com/android/settings/notification/RedactionInterstitial.java b/src/com/android/settings/notification/RedactionInterstitial.java
index abadb8b..35e4036 100644
--- a/src/com/android/settings/notification/RedactionInterstitial.java
+++ b/src/com/android/settings/notification/RedactionInterstitial.java
@@ -186,7 +186,10 @@
 
         private void updateRemoteInputCheckboxVisibility() {
             boolean visible = mRadioGroup.getCheckedRadioButtonId() == R.id.show_all;
-            mRemoteInputCheckbox.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
+            boolean isManagedProfile = Utils.isManagedProfile(UserManager.get(getPrefContext()),
+                    mUserId);
+            mRemoteInputCheckbox
+                    .setVisibility((visible && !isManagedProfile) ? View.VISIBLE : View.INVISIBLE);
         }
     }
 }
diff --git a/src/com/android/settings/notification/ZenAccessSettings.java b/src/com/android/settings/notification/ZenAccessSettings.java
index 9ff2fed..638972e 100644
--- a/src/com/android/settings/notification/ZenAccessSettings.java
+++ b/src/com/android/settings/notification/ZenAccessSettings.java
@@ -21,6 +21,7 @@
 import android.app.Dialog;
 import android.app.DialogFragment;
 import android.app.NotificationManager;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.pm.ApplicationInfo;
@@ -32,6 +33,7 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
+import android.provider.Settings;
 import android.provider.Settings.Secure;
 import android.support.v14.preference.SwitchPreference;
 import android.support.v7.preference.Preference;
@@ -40,6 +42,8 @@
 import android.text.TextUtils;
 import android.util.ArraySet;
 import android.view.View;
+import android.widget.Toast;
+
 import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.settings.R;
 
@@ -50,6 +54,7 @@
 public class ZenAccessSettings extends EmptyTextSettings {
 
     private final SettingObserver mObserver = new SettingObserver();
+    private static final String ENABLED_SERVICES_SEPARATOR = ":";
 
     private Context mContext;
     private PackageManager mPkgMan;
@@ -83,6 +88,9 @@
         getContentResolver().registerContentObserver(
                 Secure.getUriFor(Secure.ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES), false,
                 mObserver);
+        getContentResolver().registerContentObserver(
+                Secure.getUriFor(Secure.ENABLED_NOTIFICATION_LISTENERS), false,
+                mObserver);
     }
 
     @Override
@@ -96,7 +104,7 @@
         screen.removeAll();
         final ArrayList<ApplicationInfo> apps = new ArrayList<>();
         final ArraySet<String> requesting = mNoMan.getPackagesRequestingNotificationPolicyAccess();
-        if (requesting != null && !requesting.isEmpty()) {
+        if (!requesting.isEmpty()) {
             final List<ApplicationInfo> installed = mPkgMan.getInstalledApplications(0);
             if (installed != null) {
                 for (ApplicationInfo app : installed) {
@@ -106,6 +114,8 @@
                 }
             }
         }
+        ArraySet<String> autoApproved = getEnabledNotificationListeners();
+        requesting.addAll(autoApproved);
         Collections.sort(apps, new PackageItemInfo.DisplayNameComparator(mPkgMan));
         for (ApplicationInfo app : apps) {
             final String pkg = app.packageName;
@@ -115,6 +125,10 @@
             pref.setIcon(app.loadIcon(mPkgMan));
             pref.setTitle(label);
             pref.setChecked(hasAccess(pkg));
+            if (autoApproved.contains(pkg)) {
+                pref.setEnabled(false);
+                pref.setSummary(getString(R.string.zen_access_disabled_package_warning));
+            }
             pref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
                 @Override
                 public boolean onPreferenceChange(Preference preference, Object newValue) {
@@ -135,6 +149,22 @@
         }
     }
 
+    private ArraySet<String> getEnabledNotificationListeners() {
+        ArraySet<String> packages = new ArraySet<>();
+        String settingValue = Settings.Secure.getString(getContext().getContentResolver(),
+                Settings.Secure.ENABLED_NOTIFICATION_LISTENERS);
+        if (!TextUtils.isEmpty(settingValue)) {
+            String[] restored = settingValue.split(ENABLED_SERVICES_SEPARATOR);
+            for (int i = 0; i < restored.length; i++) {
+                ComponentName value = ComponentName.unflattenFromString(restored[i]);
+                if (null != value) {
+                    packages.add(value.getPackageName());
+                }
+            }
+        }
+        return packages;
+    }
+
     private boolean hasAccess(String pkg) {
         return mNoMan.isNotificationPolicyAccessGrantedForPackage(pkg);
     }
diff --git a/src/com/android/settings/notification/ZenModeAutomationSettings.java b/src/com/android/settings/notification/ZenModeAutomationSettings.java
index 3cf28e1..1fdba61 100644
--- a/src/com/android/settings/notification/ZenModeAutomationSettings.java
+++ b/src/com/android/settings/notification/ZenModeAutomationSettings.java
@@ -43,11 +43,10 @@
 import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.settings.R;
 import com.android.settings.utils.ManagedServiceSettings.Config;
-import com.android.settings.utils.ServiceListing;
+import com.android.settings.utils.ZenServiceListing;
 
 import java.lang.ref.WeakReference;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.Comparator;
 import java.util.Map;
 
@@ -56,14 +55,14 @@
     static final Config CONFIG = getConditionProviderConfig();
 
     private PackageManager mPm;
-    private ServiceListing mServiceListing;
+    private ZenServiceListing mServiceListing;
 
     @Override
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
         addPreferencesFromResource(R.xml.zen_mode_automation_settings);
         mPm = mContext.getPackageManager();
-        mServiceListing = new ServiceListing(mContext, CONFIG);
+        mServiceListing = new ZenServiceListing(mContext, CONFIG);
         mServiceListing.reloadApprovedServices();
     }
 
@@ -203,6 +202,7 @@
         final Config c = new Config();
         c.tag = TAG;
         c.setting = Settings.Secure.ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES;
+        c.secondarySetting = Settings.Secure.ENABLED_NOTIFICATION_LISTENERS;
         c.intentAction = ConditionProviderService.SERVICE_INTERFACE;
         c.permission = android.Manifest.permission.BIND_CONDITION_PROVIDER_SERVICE;
         c.noun = "condition provider";
@@ -308,7 +308,7 @@
 
             final String action = isSchedule ? ZenModeScheduleRuleSettings.ACTION
                     : isEvent ? ZenModeEventRuleSettings.ACTION : "";
-            ServiceInfo si = mServiceListing.findService(mContext, CONFIG, rule.getOwner());
+            ServiceInfo si = mServiceListing.findService(rule.getOwner());
             ComponentName settingsActivity = getSettingsActivity(si);
             setIntent(getRuleIntent(action, settingsActivity, mId));
             setSelectable(settingsActivity != null || isSystemRule);
diff --git a/src/com/android/settings/notification/ZenRuleInfo.java b/src/com/android/settings/notification/ZenRuleInfo.java
index 2a06a08..2d7abf8 100644
--- a/src/com/android/settings/notification/ZenRuleInfo.java
+++ b/src/com/android/settings/notification/ZenRuleInfo.java
@@ -4,6 +4,31 @@
 import android.net.Uri;
 
 public class ZenRuleInfo {
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        ZenRuleInfo that = (ZenRuleInfo) o;
+
+        if (isSystem != that.isSystem) return false;
+        if (ruleInstanceLimit != that.ruleInstanceLimit) return false;
+        if (packageName != null ? !packageName.equals(that.packageName) : that.packageName != null)
+            return false;
+        if (title != null ? !title.equals(that.title) : that.title != null) return false;
+        if (settingsAction != null ? !settingsAction.equals(
+                that.settingsAction) : that.settingsAction != null) return false;
+        if (configurationActivity != null ? !configurationActivity.equals(
+                that.configurationActivity) : that.configurationActivity != null) return false;
+        if (defaultConditionId != null ? !defaultConditionId.equals(
+                that.defaultConditionId) : that.defaultConditionId != null) return false;
+        if (serviceComponent != null ? !serviceComponent.equals(
+                that.serviceComponent) : that.serviceComponent != null) return false;
+        return packageLabel != null ? packageLabel.equals(
+                that.packageLabel) : that.packageLabel == null;
+
+    }
+
     public String packageName;
     public String title;
     public String settingsAction;
diff --git a/src/com/android/settings/notification/ZenRuleSelectionDialog.java b/src/com/android/settings/notification/ZenRuleSelectionDialog.java
index 05f42d8..9de9a60 100644
--- a/src/com/android/settings/notification/ZenRuleSelectionDialog.java
+++ b/src/com/android/settings/notification/ZenRuleSelectionDialog.java
@@ -27,6 +27,7 @@
 import android.graphics.drawable.Drawable;
 import android.os.AsyncTask;
 import android.service.notification.ZenModeConfig;
+import android.util.ArraySet;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -36,6 +37,7 @@
 
 import com.android.settings.R;
 import com.android.settings.utils.ServiceListing;
+import com.android.settings.utils.ZenServiceListing;
 
 import java.lang.ref.WeakReference;
 import java.text.Collator;
@@ -43,6 +45,8 @@
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
 
 public abstract class ZenRuleSelectionDialog {
     private static final String TAG = "ZenRuleSelectionDialog";
@@ -53,9 +57,9 @@
     private NotificationManager mNm;
     private final AlertDialog mDialog;
     private final LinearLayout mRuleContainer;
-    private final ServiceListing mServiceListing;
+    private final ZenServiceListing mServiceListing;
 
-    public ZenRuleSelectionDialog(Context context, ServiceListing serviceListing) {
+    public ZenRuleSelectionDialog(Context context, ZenServiceListing serviceListing) {
         mContext = context;
         mPm = context.getPackageManager();
         mNm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
@@ -67,7 +71,7 @@
         if (mServiceListing != null) {
             bindType(defaultNewEvent());
             bindType(defaultNewSchedule());
-            mServiceListing.addCallback(mServiceListingCallback);
+            mServiceListing.addZenCallback(mServiceListingCallback);
             mServiceListing.reloadApprovedServices();
         }
         mDialog = new AlertDialog.Builder(context)
@@ -77,7 +81,7 @@
                     @Override
                     public void onDismiss(DialogInterface dialog) {
                         if (mServiceListing != null) {
-                            mServiceListing.removeCallback(mServiceListingCallback);
+                            mServiceListing.removeZenCallback(mServiceListingCallback);
                         }
                     }
                 })
@@ -152,24 +156,24 @@
         return rt;
     }
 
-    private void bindExternalRules(List<ZenRuleInfo> externalRuleTypes) {
-        Collections.sort(externalRuleTypes, RULE_TYPE_COMPARATOR);
+    private void bindExternalRules(Set<ZenRuleInfo> externalRuleTypes) {
         for (ZenRuleInfo ri : externalRuleTypes) {
             bindType(ri);
         }
     }
 
-    private final ServiceListing.Callback mServiceListingCallback = new ServiceListing.Callback() {
+    private final ZenServiceListing.Callback mServiceListingCallback = new
+            ZenServiceListing.Callback() {
         @Override
-        public void onServicesReloaded(List<ServiceInfo> services) {
+        public void onServicesReloaded(Set<ServiceInfo> services) {
             if (DEBUG) Log.d(TAG, "Services reloaded: count=" + services.size());
-            List<ZenRuleInfo> externalRuleTypes = new ArrayList<>();
-            for (int i = 0; i < services.size(); i++) {
-                final ZenRuleInfo ri = ZenModeAutomationSettings.getRuleInfo(mPm, services.get(i));
+            Set<ZenRuleInfo> externalRuleTypes = new TreeSet<>(RULE_TYPE_COMPARATOR);
+            for (ServiceInfo serviceInfo : services) {
+                final ZenRuleInfo ri = ZenModeAutomationSettings.getRuleInfo(mPm, serviceInfo);
                 if (ri != null && ri.configurationActivity != null
                         && mNm.isNotificationPolicyAccessGrantedForPackage(ri.packageName)
                         && (ri.ruleInstanceLimit <= 0 || ri.ruleInstanceLimit
-                        >= (mNm.getRuleInstanceCount(services.get(i).getComponentName()) + 1))) {
+                        >= (mNm.getRuleInstanceCount(serviceInfo.getComponentName()) + 1))) {
                     externalRuleTypes.add(ri);
                 }
             }
diff --git a/src/com/android/settings/users/EditUserPhotoController.java b/src/com/android/settings/users/EditUserPhotoController.java
index 97a9937..5229da0 100644
--- a/src/com/android/settings/users/EditUserPhotoController.java
+++ b/src/com/android/settings/users/EditUserPhotoController.java
@@ -32,6 +32,7 @@
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.os.AsyncTask;
+import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.ContactsContract.DisplayPhoto;
 import android.provider.MediaStore;
@@ -40,13 +41,15 @@
 import android.view.Gravity;
 import android.view.View;
 import android.view.View.OnClickListener;
+import android.view.ViewGroup;
 import android.widget.AdapterView;
 import android.widget.ArrayAdapter;
 import android.widget.ImageView;
-import android.widget.ListAdapter;
 import android.widget.ListPopupWindow;
+import android.widget.TextView;
 
 import com.android.settings.R;
+import com.android.settingslib.RestrictedLockUtils;
 import com.android.settingslib.drawable.CircleFramedDrawable;
 
 import java.io.File;
@@ -61,9 +64,6 @@
 public class EditUserPhotoController {
     private static final String TAG = "EditUserPhotoController";
 
-    private static final int POPUP_LIST_ITEM_ID_CHOOSE_PHOTO = 1;
-    private static final int POPUP_LIST_ITEM_ID_TAKE_PHOTO = 2;
-
     // It seems that this class generates custom request codes and they may
     // collide with ours, these values are very unlikely to have a conflict.
     private static final int REQUEST_CODE_CHOOSE_PHOTO = 1001;
@@ -100,10 +100,6 @@
                 showUpdatePhotoPopup();
             }
         });
-        final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
-        if (um.hasUserRestriction(UserManager.DISALLOW_SET_USER_ICON)) {
-            mImageView.setEnabled(false);
-        }
         mNewUserPhotoBitmap = bitmap;
         mNewUserPhotoDrawable = drawable;
     }
@@ -142,19 +138,31 @@
             return;
         }
 
-        Context context = mImageView.getContext();
-        final List<EditUserPhotoController.AdapterItem> items = new ArrayList<EditUserPhotoController.AdapterItem>();
+        final Context context = mImageView.getContext();
+        final List<EditUserPhotoController.RestrictedMenuItem> items = new ArrayList<>();
 
-        if (canTakePhoto()) {
-            String title = mImageView.getContext().getString( R.string.user_image_take_photo);
-            EditUserPhotoController.AdapterItem item = new AdapterItem(title, POPUP_LIST_ITEM_ID_TAKE_PHOTO);
-            items.add(item);
+        if (canTakePhoto) {
+            final String title = context.getString(R.string.user_image_take_photo);
+            final Runnable action = new Runnable() {
+                @Override
+                public void run() {
+                    takePhoto();
+                }
+            };
+            items.add(new RestrictedMenuItem(context, title, UserManager.DISALLOW_SET_USER_ICON,
+                    action));
         }
 
         if (canChoosePhoto) {
-            String title = context.getString(R.string.user_image_choose_photo);
-            EditUserPhotoController.AdapterItem item = new AdapterItem(title, POPUP_LIST_ITEM_ID_CHOOSE_PHOTO);
-            items.add(item);
+            final String title = context.getString(R.string.user_image_choose_photo);
+            final Runnable action = new Runnable() {
+                @Override
+                public void run() {
+                    choosePhoto();
+                }
+            };
+            items.add(new RestrictedMenuItem(context, title, UserManager.DISALLOW_SET_USER_ICON,
+                    action));
         }
 
         final ListPopupWindow listPopupWindow = new ListPopupWindow(context);
@@ -162,10 +170,7 @@
         listPopupWindow.setAnchorView(mImageView);
         listPopupWindow.setModal(true);
         listPopupWindow.setInputMethodMode(ListPopupWindow.INPUT_METHOD_NOT_NEEDED);
-
-        ListAdapter adapter = new ArrayAdapter<EditUserPhotoController.AdapterItem>(context,
-                R.layout.edit_user_photo_popup_item, items);
-        listPopupWindow.setAdapter(adapter);
+        listPopupWindow.setAdapter(new RestrictedPopupMenuAdapter(context, items));
 
         final int width = Math.max(mImageView.getWidth(), context.getResources()
                 .getDimensionPixelSize(R.dimen.update_user_photo_popup_min_width));
@@ -175,17 +180,10 @@
         listPopupWindow.setOnItemClickListener(new AdapterView.OnItemClickListener() {
             @Override
             public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-                EditUserPhotoController.AdapterItem item = items.get(position);
-                switch (item.id) {
-                    case POPUP_LIST_ITEM_ID_CHOOSE_PHOTO: {
-                        choosePhoto();
-                        listPopupWindow.dismiss();
-                    } break;
-                    case POPUP_LIST_ITEM_ID_TAKE_PHOTO: {
-                        takePhoto();
-                        listPopupWindow.dismiss();
-                    } break;
-                }
+                listPopupWindow.dismiss();
+                final RestrictedMenuItem item =
+                        (RestrictedMenuItem) parent.getAdapter().getItem(position);
+                item.doAction();
             }
         });
 
@@ -363,18 +361,82 @@
         new File(mContext.getCacheDir(), NEW_USER_PHOTO_FILE_NAME).delete();
     }
 
-    private static final class AdapterItem {
-        final String title;
-        final int id;
+    private static final class RestrictedMenuItem {
+        private final Context mContext;
+        private final String mTitle;
+        private final Runnable mAction;
+        private final RestrictedLockUtils.EnforcedAdmin mAdmin;
+        // Restriction may be set by system or something else via UserManager.setUserRestriction().
+        private final boolean mIsRestrictedByBase;
 
-        public AdapterItem(String title, int id) {
-            this.title = title;
-            this.id = id;
+        /**
+         * The menu item, used for popup menu. Any element of such a menu can be disabled by admin.
+         * @param context A context.
+         * @param title The title of the menu item.
+         * @param restriction The restriction, that if is set, blocks the menu item.
+         * @param action The action on menu item click.
+         */
+        public RestrictedMenuItem(Context context, String title, String restriction,
+                Runnable action) {
+            mContext = context;
+            mTitle = title;
+            mAction = action;
+
+            final int myUserId = UserHandle.myUserId();
+            mAdmin = RestrictedLockUtils.checkIfRestrictionEnforced(context,
+                    restriction, myUserId);
+            mIsRestrictedByBase = RestrictedLockUtils.hasBaseUserRestriction(mContext,
+                    restriction, myUserId);
         }
 
         @Override
         public String toString() {
-            return title;
+            return mTitle;
+        }
+
+        final void doAction() {
+            if (isRestrictedByBase()) {
+                return;
+            }
+
+            if (isRestrictedByAdmin()) {
+                RestrictedLockUtils.sendShowAdminSupportDetailsIntent(mContext, mAdmin);
+                return;
+            }
+
+            mAction.run();
+        }
+
+        final boolean isRestrictedByAdmin() {
+            return mAdmin != null;
+        }
+
+        final boolean isRestrictedByBase() {
+            return mIsRestrictedByBase;
+        }
+    }
+
+    /**
+     * Provide this adapter to ListPopupWindow.setAdapter() to have a popup window menu, where
+     * any element can be restricted by admin (profile owner or device owner).
+     */
+    private static final class RestrictedPopupMenuAdapter extends ArrayAdapter<RestrictedMenuItem> {
+        public RestrictedPopupMenuAdapter(Context context, List<RestrictedMenuItem> items) {
+            super(context, R.layout.restricted_popup_menu_item, R.id.text, items);
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            final View view = super.getView(position, convertView, parent);
+            final RestrictedMenuItem item = getItem(position);
+            final TextView text = (TextView) view.findViewById(R.id.text);
+            final ImageView image = (ImageView) view.findViewById(R.id.restricted_icon);
+
+            text.setEnabled(!item.isRestrictedByAdmin() && !item.isRestrictedByBase());
+            image.setVisibility(item.isRestrictedByAdmin() && !item.isRestrictedByBase() ?
+                    ImageView.VISIBLE : ImageView.GONE);
+
+            return view;
         }
     }
 }
diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java
index eb74c4b..bf93cd3 100644
--- a/src/com/android/settings/users/UserSettings.java
+++ b/src/com/android/settings/users/UserSettings.java
@@ -331,7 +331,8 @@
             protected String doInBackground(Void... values) {
                 UserInfo user = mUserManager.getUserInfo(UserHandle.myUserId());
                 if (user.iconPath == null || user.iconPath.equals("")) {
-                    assignProfilePhoto(user);
+                    // Assign profile photo.
+                    Utils.copyMeProfilePhoto(getActivity(), user);
                 }
                 return user.name;
             }
@@ -404,14 +405,14 @@
 
     private UserInfo createRestrictedProfile() {
         UserInfo newUserInfo = mUserManager.createRestrictedProfile(mAddingUserName);
-        assignDefaultPhoto(newUserInfo);
+        Utils.assignDefaultPhoto(getActivity(), newUserInfo.id);
         return newUserInfo;
     }
 
     private UserInfo createTrustedUser() {
         UserInfo newUserInfo = mUserManager.createUser(mAddingUserName, 0);
         if (newUserInfo != null) {
-            assignDefaultPhoto(newUserInfo);
+            Utils.assignDefaultPhoto(getActivity(), newUserInfo.id);
         }
         return newUserInfo;
     }
@@ -898,17 +899,6 @@
         }.execute(missingIcons);
     }
 
-    private void assignProfilePhoto(final UserInfo user) {
-        if (!Utils.copyMeProfilePhoto(getActivity(), user)) {
-            assignDefaultPhoto(user);
-        }
-    }
-
-    private void assignDefaultPhoto(UserInfo user) {
-        Bitmap bitmap = Utils.getDefaultUserIconAsBitmap(user.id);
-        mUserManager.setUserIcon(user.id, bitmap);
-    }
-
     private Drawable getEncircledDefaultIcon() {
         if (mDefaultIconDrawable == null) {
             mDefaultIconDrawable = encircle(Utils.getDefaultUserIconAsBitmap(UserHandle.USER_NULL));
diff --git a/src/com/android/settings/utils/ManagedServiceSettings.java b/src/com/android/settings/utils/ManagedServiceSettings.java
index e198955..da4798e 100644
--- a/src/com/android/settings/utils/ManagedServiceSettings.java
+++ b/src/com/android/settings/utils/ManagedServiceSettings.java
@@ -42,9 +42,9 @@
 public abstract class ManagedServiceSettings extends EmptyTextSettings {
     private final Config mConfig;
 
-    private Context mContext;
+    protected Context mContext;
     private PackageManager mPM;
-    private ServiceListing mServiceListing;
+    protected ServiceListing mServiceListing;
     private TextView mEmpty;
 
     abstract protected Config getConfig();
@@ -111,7 +111,7 @@
         }
     }
 
-    private boolean setEnabled(ComponentName service, String title, boolean enable) {
+    protected boolean setEnabled(ComponentName service, String title, boolean enable) {
         if (!enable) {
             // the simple version: disabling
             mServiceListing.setEnabled(service, false);
@@ -173,6 +173,7 @@
     public static class Config {
         public String tag;
         public String setting;
+        public String secondarySetting;
         public String intentAction;
         public String permission;
         public String noun;
diff --git a/src/com/android/settings/utils/ServiceListing.java b/src/com/android/settings/utils/ServiceListing.java
index dfca5a3..6a5fa10 100644
--- a/src/com/android/settings/utils/ServiceListing.java
+++ b/src/com/android/settings/utils/ServiceListing.java
@@ -30,6 +30,7 @@
 import android.net.Uri;
 import android.os.Handler;
 import android.provider.Settings;
+import android.text.TextUtils;
 import android.util.Slog;
 
 import com.android.settings.utils.ManagedServiceSettings.Config;
@@ -46,7 +47,6 @@
     private final HashSet<ComponentName> mEnabledServices = new HashSet<ComponentName>();
     private final List<ServiceInfo> mServices = new ArrayList<ServiceInfo>();
     private final List<Callback> mCallbacks = new ArrayList<Callback>();
-    private final List<ServiceInfo> mApprovedServices = new ArrayList<ServiceInfo>();
 
     private boolean mListening;
 
@@ -95,18 +95,7 @@
         return getServices(c, null, pm);
     }
 
-    public ServiceInfo findService(Context context, Config config, final ComponentName cn) {
-        final ServiceListing listing = new ServiceListing(context, config);
-        for (ServiceInfo service : mApprovedServices) {
-            final ComponentName serviceCN = new ComponentName(service.packageName, service.name);
-            if (serviceCN.equals(cn)) {
-                return service;
-            }
-        }
-        return null;
-    }
-
-    private static int getServices(Config c, List<ServiceInfo> list, PackageManager pm) {
+    protected static int getServices(Config c, List<ServiceInfo> list, PackageManager pm) {
         int services = 0;
         if (list != null) {
             list.clear();
@@ -174,26 +163,6 @@
         return mServices;
     }
 
-    public void reloadApprovedServices() {
-        mApprovedServices.clear();
-        final String flat = Settings.Secure.getString(mContentResolver, mConfig.setting);
-        if (flat != null && !"".equals(flat)) {
-            final List<String> names = Arrays.asList(flat.split(":"));
-            List<ServiceInfo> services = new ArrayList<>();
-            getServices(mConfig, services, mContext.getPackageManager());
-            for (ServiceInfo service : services) {
-                final ComponentName componentName = service.getComponentName();
-                String flatCn = service.getComponentName().flattenToString();
-                if (names.contains(flatCn) || names.contains(componentName.getPackageName())) {
-                    mApprovedServices.add(service);
-                }
-            }
-            for (Callback callback : mCallbacks) {
-                callback.onServicesReloaded(mApprovedServices);
-            }
-        }
-    }
-
     public boolean isEnabled(ComponentName cn) {
         return mEnabledServices.contains(cn);
     }
diff --git a/src/com/android/settings/utils/ZenServiceListing.java b/src/com/android/settings/utils/ZenServiceListing.java
new file mode 100644
index 0000000..167b066
--- /dev/null
+++ b/src/com/android/settings/utils/ZenServiceListing.java
@@ -0,0 +1,148 @@
+/*
+ * 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 com.android.settings.utils;
+
+import android.app.ActivityManager;
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.ArraySet;
+import android.util.Slog;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+public class ZenServiceListing {
+
+    private final ContentResolver mContentResolver;
+    private final Context mContext;
+    private final ManagedServiceSettings.Config mConfig;
+    private final Set<ServiceInfo> mApprovedServices = new ArraySet<ServiceInfo>();
+    private final List<Callback> mZenCallbacks = new ArrayList<>();
+
+    public ZenServiceListing(Context context, ManagedServiceSettings.Config config) {
+        mContext = context;
+        mConfig = config;
+        mContentResolver = context.getContentResolver();
+    }
+
+    public ServiceInfo findService(final ComponentName cn) {
+        for (ServiceInfo service : mApprovedServices) {
+            final ComponentName serviceCN = new ComponentName(service.packageName, service.name);
+            if (serviceCN.equals(cn)) {
+                return service;
+            }
+        }
+        return null;
+    }
+
+    public void addZenCallback(Callback callback) {
+        mZenCallbacks.add(callback);
+    }
+
+    public void removeZenCallback(Callback callback) {
+        mZenCallbacks.remove(callback);
+    }
+
+    public void reloadApprovedServices() {
+        mApprovedServices.clear();
+        String[] settings = {mConfig.setting, mConfig.secondarySetting};
+
+        for (String setting : settings) {
+            if (!TextUtils.isEmpty(setting)) {
+                final String flat = Settings.Secure.getString(mContentResolver, setting);
+                if (!TextUtils.isEmpty(flat)) {
+                    final List<String> names = Arrays.asList(flat.split(":"));
+                    List<ServiceInfo> services = new ArrayList<>();
+                    getServices(mConfig, services, mContext.getPackageManager());
+                    for (ServiceInfo service : services) {
+                        if (matchesApprovedPackage(names, service.getComponentName())) {
+                            mApprovedServices.add(service);
+                        }
+                    }
+                }
+            }
+        }
+        if (!mApprovedServices.isEmpty()) {
+            for (Callback callback : mZenCallbacks) {
+                callback.onServicesReloaded(mApprovedServices);
+            }
+        }
+    }
+
+    // Setting could contain: the component name of the condition provider, the package name of
+    // the condition provider, the component name of the notification listener.
+    private boolean matchesApprovedPackage(List<String> approved, ComponentName serviceOwner) {
+        String flatCn = serviceOwner.flattenToString();
+        if (approved.contains(flatCn) || approved.contains(serviceOwner.getPackageName())) {
+            return true;
+        }
+        for (String entry : approved) {
+            if (!TextUtils.isEmpty(entry)) {
+                ComponentName approvedComponent = ComponentName.unflattenFromString(entry);
+                if (approvedComponent != null && approvedComponent.getPackageName().equals(
+                        serviceOwner.getPackageName())) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    private static int getServices(ManagedServiceSettings.Config c, List<ServiceInfo> list,
+            PackageManager pm) {
+        int services = 0;
+        if (list != null) {
+            list.clear();
+        }
+        final int user = ActivityManager.getCurrentUser();
+
+        List<ResolveInfo> installedServices = pm.queryIntentServicesAsUser(
+                new Intent(c.intentAction),
+                PackageManager.GET_SERVICES | PackageManager.GET_META_DATA,
+                user);
+
+        for (int i = 0, count = installedServices.size(); i < count; i++) {
+            ResolveInfo resolveInfo = installedServices.get(i);
+            ServiceInfo info = resolveInfo.serviceInfo;
+
+            if (!c.permission.equals(info.permission)) {
+                Slog.w(c.tag, "Skipping " + c.noun + " service "
+                        + info.packageName + "/" + info.name
+                        + ": it does not require the permission "
+                        + c.permission);
+                continue;
+            }
+            if (list != null) {
+                list.add(info);
+            }
+            services++;
+        }
+        return services;
+    }
+
+    public interface Callback {
+        void onServicesReloaded(Set<ServiceInfo> services);
+    }
+}
diff --git a/src/com/android/settings/vpn2/AppDialogFragment.java b/src/com/android/settings/vpn2/AppDialogFragment.java
index e70b412..004ad80 100644
--- a/src/com/android/settings/vpn2/AppDialogFragment.java
+++ b/src/com/android/settings/vpn2/AppDialogFragment.java
@@ -137,11 +137,8 @@
     private void onDisconnect(final DialogInterface dialog) {
         final int userId = UserHandle.getUserId(mPackageInfo.applicationInfo.uid);
         try {
-            final VpnConfig vpnConfig = mService.getVpnConfig(userId);
-            if (vpnConfig == null || vpnConfig.legacy) {
-                return;
-            }
-            if (mPackageInfo.packageName.equals(vpnConfig.user)) {
+            if (mPackageInfo.packageName.equals(getConnectedPackage(mService, userId))) {
+                mService.setAlwaysOnVpnPackage(userId, null);
                 mService.prepareVpn(mPackageInfo.packageName, VpnConfig.LEGACY_VPN, userId);
             }
         } catch (RemoteException e) {
@@ -149,4 +146,10 @@
                     " for user " + userId, e);
         }
     }
+
+    private static String getConnectedPackage(IConnectivityManager service, final int userId)
+            throws RemoteException {
+        final VpnConfig config = service.getVpnConfig(userId);
+        return config != null ? config.user : null;
+    }
 }
diff --git a/src/com/android/settings/vpn2/ConfigDialog.java b/src/com/android/settings/vpn2/ConfigDialog.java
index a13e29d..92050e9 100644
--- a/src/com/android/settings/vpn2/ConfigDialog.java
+++ b/src/com/android/settings/vpn2/ConfigDialog.java
@@ -170,6 +170,9 @@
             // Show type-specific fields.
             changeType(mProfile.type);
 
+            // Hide 'save login' when we are editing.
+            mSaveLogin.setVisibility(View.GONE);
+
             // Switch to advanced view immediately if any advanced options are on
             if (!mProfile.searchDomains.isEmpty() || !mProfile.dnsServers.isEmpty() ||
                     !mProfile.routes.isEmpty()) {
@@ -188,9 +191,6 @@
         } else {
             setTitle(context.getString(R.string.vpn_connect_to, mProfile.name));
 
-            // Not editing, just show username and password.
-            mView.findViewById(R.id.login).setVisibility(View.VISIBLE);
-
             // Create a button to connect the network.
             setButton(DialogInterface.BUTTON_POSITIVE,
                     context.getString(R.string.vpn_connect), mListener);
@@ -259,6 +259,7 @@
     public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
         if (compoundButton == mAlwaysOnVpn) {
             updateSaveLoginStatus();
+            getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(validate(mEditing));
         }
     }
 
@@ -318,6 +319,9 @@
         if (!editing) {
             return mUsername.getText().length() != 0 && mPassword.getText().length() != 0;
         }
+        if (mAlwaysOnVpn.isChecked() && !getProfile().isValidLockdownProfile()) {
+            return false;
+        }
         if (mName.getText().length() == 0 || mServer.getText().length() == 0 ||
                 !validateAddresses(mDnsServers.getText().toString(), false) ||
                 !validateAddresses(mRoutes.getText().toString(), true)) {
@@ -441,7 +445,8 @@
                 break;
         }
 
-        profile.saveLogin = mSaveLogin.isChecked();
+        final boolean hasLogin = !profile.username.isEmpty() || !profile.password.isEmpty();
+        profile.saveLogin = mSaveLogin.isChecked() || (mEditing && hasLogin);
         return profile;
     }
 }
diff --git a/src/com/android/settings/vpn2/ConfigDialogFragment.java b/src/com/android/settings/vpn2/ConfigDialogFragment.java
index fc49fd8..5e4a7d9 100644
--- a/src/com/android/settings/vpn2/ConfigDialogFragment.java
+++ b/src/com/android/settings/vpn2/ConfigDialogFragment.java
@@ -152,12 +152,9 @@
                 return;
             }
 
-            // Update only if lockdown vpn has been changed
-            if (!VpnUtils.isVpnLockdown(profile.key)) {
-                final ConnectivityManager conn = ConnectivityManager.from(getActivity());
-                conn.setAlwaysOnVpnPackageForUser(UserHandle.myUserId(), null);
-                VpnUtils.setLockdownVpn(getContext(), profile.key);
-            }
+            final ConnectivityManager conn = ConnectivityManager.from(getActivity());
+            conn.setAlwaysOnVpnPackageForUser(UserHandle.myUserId(), null);
+            VpnUtils.setLockdownVpn(getContext(), profile.key);
         } else {
             // update only if lockdown vpn has been changed
             if (VpnUtils.isVpnLockdown(profile.key)) {
diff --git a/src/com/android/settings/vpn2/VpnSettings.java b/src/com/android/settings/vpn2/VpnSettings.java
index f605896..6c47b43 100644
--- a/src/com/android/settings/vpn2/VpnSettings.java
+++ b/src/com/android/settings/vpn2/VpnSettings.java
@@ -299,11 +299,6 @@
             return true;
         } else if (preference instanceof AppPreference) {
             AppPreference pref = (AppPreference) preference;
-            if (pref.isAlwaysOn()) {
-                // User can't disconnect vpn when always-on is enabled
-                return true;
-            }
-
             boolean connected = (pref.getState() == AppPreference.STATE_CONNECTED);
 
             if (!connected) {