Merge "Set user icon to default when updating profile without photo" 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/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 aa3930c..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/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" />
+            <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 0141019..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/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" />
+            <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/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 ce0a4a6..2675e15 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -6031,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>
@@ -6877,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>
 
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/PreviewSeekBarPreferenceFragment.java b/src/com/android/settings/PreviewSeekBarPreferenceFragment.java
index aa663cf..a7763f7 100644
--- a/src/com/android/settings/PreviewSeekBarPreferenceFragment.java
+++ b/src/com/android/settings/PreviewSeekBarPreferenceFragment.java
@@ -151,51 +151,21 @@
             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, mPreviewSampleResIds,
+                    configurations);
+            mPreviewPager.setAdapter(mPreviewPagerAdapter);
+            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 +177,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 +201,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/Utils.java b/src/com/android/settings/Utils.java
index 9693ed9..46a3d9b 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -1114,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/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/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..c342ba0 100644
--- a/src/com/android/settings/notification/ConfigureNotificationSettings.java
+++ b/src/com/android/settings/notification/ConfigureNotificationSettings.java
@@ -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..cd3e30c 100644
--- a/src/com/android/settings/notification/NotificationLockscreenPreference.java
+++ b/src/com/android/settings/notification/NotificationLockscreenPreference.java
@@ -37,11 +37,16 @@
     private int mInitialIndex;
     private Listener mListener;
     private boolean mShowRemoteInput;
+    private boolean mRemoteInputCheckBoxEnabled = true;
 
     public NotificationLockscreenPreference(Context context, AttributeSet attrs) {
         super(context, attrs);
     }
 
+    public void setRemoteInputCheckBoxEnabled(boolean enabled) {
+        mRemoteInputCheckBoxEnabled = enabled;
+    }
+
     @Override
     protected void onPrepareDialogBuilder(AlertDialog.Builder builder,
             DialogInterface.OnClickListener innerListener) {
@@ -85,8 +90,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/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/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) {