Merge "Override performClick method to eliminate redundant click" into qt-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 202335e..8e4d6a4 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1588,6 +1588,10 @@
             android:exported="false"
             android:screenOrientation="portrait"/>
 
+        <activity android:name=".biometrics.face.FaceEnrollEducation"
+            android:exported="false"
+            android:screenOrientation="portrait"/>
+
         <activity android:name=".biometrics.face.FaceEnrollEnrolling"
             android:exported="false"
             android:screenOrientation="portrait"/>
diff --git a/res/drawable/ic_arrow_back.xml b/res/drawable/ic_arrow_back.xml
index 374f16b..b6a80cf 100644
--- a/res/drawable/ic_arrow_back.xml
+++ b/res/drawable/ic_arrow_back.xml
@@ -18,6 +18,7 @@
     android:height="24dp"
     android:viewportWidth="24"
     android:viewportHeight="24"
+    android:autoMirrored="true"
     android:tint="?android:attr/colorControlNormal">
     <path
         android:fillColor="@android:color/white"
diff --git a/res/drawable/ic_face_enroll_introduction_people.xml b/res/drawable/ic_face_enroll_introduction_people.xml
new file mode 100644
index 0000000..b452efe
--- /dev/null
+++ b/res/drawable/ic_face_enroll_introduction_people.xml
@@ -0,0 +1,42 @@
+<!--
+  ~ Copyright (C) 2019 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+                 xmlns:aapt="http://schemas.android.com/aapt">
+    <aapt:attr name="android:drawable">
+        <vector android:height="24dp" android:width="24dp" android:viewportHeight="24"
+                android:viewportWidth="24"
+                android:tint="?android:attr/colorControlNormal">
+            <group android:name="_R_G">
+                <group android:name="_R_G_L_0_G">
+                    <path android:name="_R_G_L_0_G_D_0_P_0" android:fillColor="#000000"
+                          android:fillAlpha="1" android:fillType="nonZero"
+                          android:pathData=" M15 8 C15,6.58 14.5,5.27 13.67,4.24 C14.09,4.1 14.53,4 15,4 C17.21,4 19,5.79 19,8 C19,10.21 17.21,12 15,12 C14.57,12 14.16,11.91 13.77,11.79 C13.74,11.78 13.71,11.77 13.67,11.76 C14.5,10.73 15,9.42 15,8c  M16.66 13.13 C18.03,14.06 19,15.32 19,17 C19,17 19,20 19,20 C19,20 23,20 23,20 C23,20 23,17 23,17 C23,14.82 19.42,13.53 16.66,13.13c  M9 6 C7.9,6 7,6.9 7,8 C7,9.1 7.9,10 9,10 C10.1,10 11,9.1 11,8 C11,6.9 10.1,6 9,6c  M9 15 C6.3,15 3.2,16.29 3,17.01 C3,17.01 3,18 3,18 C3,18 15,18 15,18 C15,18 15,17 15,17 C14.8,16.29 11.7,15 9,15c  M9 4 C11.21,4 13,5.79 13,8 C13,10.21 11.21,12 9,12 C6.79,12 5,10.21 5,8 C5,5.79 6.79,4 9,4c  M9 13 C11.67,13 17,14.34 17,17 C17,17 17,20 17,20 C17,20 1,20 1,20 C1,20 1,17 1,17 C1,14.34 6.33,13 9,13c "/>
+                </group>
+            </group>
+            <group android:name="time_group"/>
+        </vector>
+    </aapt:attr>
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:propertyName="translateX" android:duration="2000"
+                                android:startOffset="0" android:valueFrom="0" android:valueTo="1"
+                                android:valueType="floatType"/>
+            </set>
+        </aapt:attr>
+    </target>
+</animated-vector>
\ No newline at end of file
diff --git a/res/drawable/ic_face_enroll_introduction_shield.xml b/res/drawable/ic_face_enroll_introduction_shield.xml
new file mode 100644
index 0000000..09d3909
--- /dev/null
+++ b/res/drawable/ic_face_enroll_introduction_shield.xml
@@ -0,0 +1,45 @@
+<!--
+  ~ Copyright (C) 2019 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+                 xmlns:aapt="http://schemas.android.com/aapt">
+    <aapt:attr name="android:drawable">
+        <vector android:height="24dp" android:width="24dp" android:viewportHeight="24"
+                android:viewportWidth="24"
+                android:tint="?android:attr/colorControlNormal">
+            <group android:name="_R_G">
+                <group android:name="_R_G_L_0_G">
+                    <path android:name="_R_G_L_0_G_D_0_P_0" android:fillColor="#000000"
+                          android:fillAlpha="1" android:fillType="nonZero"
+                          android:pathData=" M12 2 C12,2 3.82,5.64 3.82,5.64 C3.82,5.64 3.82,11.09 3.82,11.09 C3.82,16.14 7.31,20.85 12,22 C16.69,20.85 20.18,16.14 20.18,11.09 C20.18,11.09 20.18,5.64 20.18,5.64 C20.18,5.64 12,2 12,2c  M18.18 11.09 C18.18,12.64 17.77,14.14 17.08,15.47 C15.77,14.5 13.4,14 12,14 C10.6,14 8.23,14.5 6.92,15.47 C6.23,14.14 5.82,12.64 5.82,11.09 C5.82,11.09 5.82,6.94 5.82,6.94 C5.82,6.94 12,4.19 12,4.19 C12,4.19 18.18,6.94 18.18,6.94 C18.18,6.94 18.18,11.09 18.18,11.09c "/>
+                    <path android:name="_R_G_L_0_G_D_1_P_0" android:fillColor="#000000"
+                          android:fillAlpha="1" android:fillType="nonZero"
+                          android:pathData=" M12 7.5 C13.66,7.5 15,8.84 15,10.5 C15,12.16 13.66,13.5 12,13.5 C10.34,13.5 9,12.16 9,10.5 C9,8.84 10.34,7.5 12,7.5c "/>
+                </group>
+            </group>
+            <group android:name="time_group"/>
+        </vector>
+    </aapt:attr>
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:propertyName="translateX" android:duration="2000"
+                                android:startOffset="0" android:valueFrom="0" android:valueTo="1"
+                                android:valueType="floatType"/>
+            </set>
+        </aapt:attr>
+    </target>
+</animated-vector>
\ No newline at end of file
diff --git a/res/drawable/ic_face_enroll_introduction_visibility.xml b/res/drawable/ic_face_enroll_introduction_visibility.xml
new file mode 100644
index 0000000..04ff21f
--- /dev/null
+++ b/res/drawable/ic_face_enroll_introduction_visibility.xml
@@ -0,0 +1,45 @@
+<!--
+  ~ Copyright (C) 2019 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+                 xmlns:aapt="http://schemas.android.com/aapt">
+    <aapt:attr name="android:drawable">
+        <vector android:height="24dp" android:width="24dp" android:viewportHeight="24"
+                android:viewportWidth="24"
+                android:tint="?android:attr/colorControlNormal">
+            <group android:name="_R_G">
+                <group android:name="_R_G_L_0_G">
+                    <path android:name="_R_G_L_0_G_D_0_P_0" android:fillColor="#000000"
+                          android:fillAlpha="1" android:fillType="nonZero"
+                          android:pathData=" M12 7 C9.52,7 7.5,9.02 7.5,11.5 C7.5,13.98 9.52,16 12,16 C14.48,16 16.5,13.98 16.5,11.5 C16.5,9.02 14.48,7 12,7c  M12 14.2 C10.51,14.2 9.3,12.99 9.3,11.5 C9.3,10.01 10.51,8.8 12,8.8 C13.49,8.8 14.7,10.01 14.7,11.5 C14.7,12.99 13.49,14.2 12,14.2c "/>
+                    <path android:name="_R_G_L_0_G_D_1_P_0" android:fillColor="#000000"
+                          android:fillAlpha="1" android:fillType="nonZero"
+                          android:pathData=" M12 4 C7,4 2.73,7.11 1,11.5 C2.73,15.89 7,19 12,19 C17,19 21.27,15.89 23,11.5 C21.27,7.11 17,4 12,4c  M12 17 C8.21,17 4.83,14.87 3.18,11.5 C4.83,8.13 8.21,6 12,6 C15.79,6 19.17,8.13 20.82,11.5 C19.17,14.87 15.79,17 12,17c "/>
+                </group>
+            </group>
+            <group android:name="time_group"/>
+        </vector>
+    </aapt:attr>
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:propertyName="translateX" android:duration="2000"
+                                android:startOffset="0" android:valueFrom="0" android:valueTo="1"
+                                android:valueType="floatType"/>
+            </set>
+        </aapt:attr>
+    </target>
+</animated-vector>
\ No newline at end of file
diff --git a/res/drawable/ic_pan_tool_18dp.xml b/res/drawable/ic_pan_tool_18dp.xml
new file mode 100644
index 0000000..3ebfc9c
--- /dev/null
+++ b/res/drawable/ic_pan_tool_18dp.xml
@@ -0,0 +1,12 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="18dp"
+    android:height="18dp"
+    android:viewportWidth="48"
+    android:viewportHeight="48">
+  <group>
+    <clip-path android:pathData="M0,0h48v48H0z M 0,0"/>
+    <path
+        android:pathData="M46,11v29c0,4.4 -3.6,8 -8,8H23.4c-2.16,0 -4.2,-0.86 -5.7,-2.38L2,29.66s2.52,-2.46 2.6,-2.5c0.44,-0.38 0.98,-0.58 1.58,-0.58 0.44,0 0.84,0.12 1.2,0.32 0.08,0.02 8.62,4.92 8.62,4.92V8c0,-1.66 1.34,-3 3,-3s3,1.34 3,3v14h2V3c0,-1.66 1.34,-3 3,-3s3,1.34 3,3v19h2V5c0,-1.66 1.34,-3 3,-3s3,1.34 3,3v17h2V11c0,-1.66 1.34,-3 3,-3s3,1.34 3,3z"
+        android:fillColor="#757575"/>
+  </group>
+</vector>
diff --git a/res/drawable/ic_visibility_18dp.xml b/res/drawable/ic_visibility_18dp.xml
new file mode 100644
index 0000000..9e27815c
--- /dev/null
+++ b/res/drawable/ic_visibility_18dp.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="18dp"
+    android:height="18dp"
+    android:viewportWidth="48"
+    android:viewportHeight="48">
+  <path
+      android:pathData="M24,9C14,9 5.46,15.22 2,24c3.46,8.78 12,15 22,15 10.01,0 18.54,-6.22 22,-15 -3.46,-8.78 -11.99,-15 -22,-15zM24,34c-5.52,0 -10,-4.48 -10,-10s4.48,-10 10,-10 10,4.48 10,10 -4.48,10 -10,10zM24,18c-3.31,0 -6,2.69 -6,6s2.69,6 6,6 6,-2.69 6,-6 -2.69,-6 -6,-6z"
+      android:fillColor="#757575"/>
+</vector>
diff --git a/res/layout-land/wifi_dpp_qrcode_scanner_fragment.xml b/res/layout-land/wifi_dpp_qrcode_scanner_fragment.xml
index 887d0fb..51c8c96 100644
--- a/res/layout-land/wifi_dpp_qrcode_scanner_fragment.xml
+++ b/res/layout-land/wifi_dpp_qrcode_scanner_fragment.xml
@@ -61,6 +61,8 @@
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_marginTop="16dp"
+                android:layout_marginStart="24dp"
+                android:layout_marginEnd="24dp"
                 android:textAlignment="center"
                 android:textColor="?android:attr/colorError"
                 android:visibility="invisible"/>
diff --git a/res/layout/contextual_slice_full_tile.xml b/res/layout/contextual_slice_full_tile.xml
index 8b1ac58..b67b777 100644
--- a/res/layout/contextual_slice_full_tile.xml
+++ b/res/layout/contextual_slice_full_tile.xml
@@ -29,7 +29,7 @@
 
         <androidx.slice.widget.SliceView
             android:id="@+id/slice_view"
-            style="@style/SliceViewStyle"
+            style="@style/ContextualCardSliceViewStyle"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_gravity="center_vertical"
diff --git a/res/layout/disable_accessibility_service_dialog_content.xml b/res/layout/disable_accessibility_service_dialog_content.xml
new file mode 100644
index 0000000..e365484
--- /dev/null
+++ b/res/layout/disable_accessibility_service_dialog_content.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2019 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<ScrollView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:textDirection="locale"
+    android:scrollbarStyle="outsideOverlay"
+    android:gravity="top">
+
+    <LinearLayout
+        android:theme="@style/Theme.AlertDialog"
+        style="@style/AccessibilityDialog">
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="vertical"
+            android:gravity="center_horizontal"
+            android:paddingTop="32dp"
+            android:paddingLeft="24dp"
+            android:paddingRight="24dp">
+
+            <TextView
+                android:id="@+id/permissionDialog_disable_title"
+                style="@style/AccessibilityDialogTitle" />
+
+            <TextView
+                android:id="@+id/permissionDialog_disable_message"
+                android:gravity="center"
+                android:text="@string/accessibility_service_warning_description"
+                style="@style/AccessibilityDialogDescription" />
+
+        </LinearLayout>
+            <!-- Buttons on bottom of dialog -->
+            <LinearLayout
+                style="@style/AccessibilityDialogButtonList">
+
+                <Space
+                    style="@style/AccessibilityDialogButtonBarSpace"/>
+
+                <Button
+                    android:id="@+id/permission_disable_stop_button"
+                    android:text="@string/accessibility_dialog_button_stop"
+                    style="@style/AccessibilityDialogButtonAllow" />
+
+                <Button
+                    android:id="@+id/permission_disable_cancel_button"
+                    android:text="@string/accessibility_dialog_button_cancel"
+                    style="@style/AccessibilityDialogButtonDeny" />
+
+            </LinearLayout>
+
+    </LinearLayout>
+
+</ScrollView>
diff --git a/res/layout/dismissal_swipe_background.xml b/res/layout/dismissal_swipe_background.xml
index 49f6266..7268922 100644
--- a/res/layout/dismissal_swipe_background.xml
+++ b/res/layout/dismissal_swipe_background.xml
@@ -20,7 +20,8 @@
     android:id="@+id/dismissal_swipe_background"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:background="@color/contextual_card_dismissal_background">
+    android:background="@color/contextual_card_dismissal_background"
+    android:visibility="gone">
 
     <ImageView
         android:id="@+id/dismissal_icon_start"
diff --git a/res/layout/enable_accessibility_service_dialog_content.xml b/res/layout/enable_accessibility_service_dialog_content.xml
index e16dc65..066c339 100644
--- a/res/layout/enable_accessibility_service_dialog_content.xml
+++ b/res/layout/enable_accessibility_service_dialog_content.xml
@@ -23,28 +23,118 @@
     android:gravity="top">
 
     <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="vertical"
-        android:paddingStart="16dip"
-        android:paddingEnd="16dip">
+        android:theme="@style/Theme.AlertDialog"
+        style="@style/AccessibilityDialog">
 
-        <TextView
-            android:id="@+id/encryption_warning"
-            android:layout_width="fill_parent"
+        <LinearLayout
+            android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:padding="10dip"
-            android:textAlignment="viewStart"
-            android:textAppearance="?android:attr/textAppearanceMedium"/>
+            android:orientation="vertical"
+            android:gravity="center_horizontal"
+            android:paddingLeft="24dp"
+            android:paddingRight="24dp">
 
-        <TextView
-            android:id="@+id/accessibility_service_warning"
-            android:layout_width="fill_parent"
-            android:layout_height="wrap_content"
-            android:padding="10dip"
-            android:textAlignment="viewStart"
-            android:textAppearance="?android:attr/textAppearanceMedium"/>
+            <ImageView
+                android:id="@+id/permissionDialog_icon"
+                style="@style/AccessibilityDialogServiceIcon" />
 
+            <TextView
+                android:id="@+id/permissionDialog_title"
+                style="@style/AccessibilityDialogTitle" />
+
+            <TextView
+                android:id="@+id/encryption_warning"
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:padding="10dip"
+                android:textAlignment="viewStart"
+                android:textAppearance="?android:attr/textAppearanceMedium"/>
+
+            <TextView
+                android:id="@+id/permissionDialog_description"
+                android:text="@string/accessibility_service_warning_description"
+                style="@style/AccessibilityDialogDescription" />
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal"
+                android:layout_marginBottom="24dp" >
+
+                <ImageView
+                    android:id="@+id/controlScreen_icon"
+                    android:src="@drawable/ic_visibility_18dp"
+                    style="@style/AccessibilityDialogIcon" />
+
+                <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:orientation="vertical" >
+
+                    <TextView
+                        android:id="@+id/controlScreen_title"
+                        android:text="@string/accessibility_service_screen_control_title"
+                        style="@style/AccessibilityDialogPermissionTitle" />
+
+                    <TextView
+                        android:id="@+id/controlScreen_description"
+                        android:text="@string/accessibility_service_screen_control_description"
+                        style="@style/AccessibilityDialogPermissionDescription" />
+
+                </LinearLayout>
+
+            </LinearLayout>
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal"
+                android:layout_marginBottom="24dp" >
+
+                <ImageView
+                    android:id="@+id/performAction_icon"
+                    android:src="@drawable/ic_pan_tool_18dp"
+                    style="@style/AccessibilityDialogIcon" />
+
+                <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:orientation="vertical" >
+
+                    <TextView
+                        android:id="@+id/performAction_title"
+                        android:text="@string/accessibility_service_action_perform_title"
+                        style="@style/AccessibilityDialogPermissionTitle" />
+
+                    <TextView
+                        android:id="@+id/performAction_description"
+                        android:text="@string/accessibility_service_action_perform_description"
+                        style="@style/AccessibilityDialogPermissionDescription" />
+
+                </LinearLayout>
+
+            </LinearLayout>
+
+        </LinearLayout>
+
+        <!-- Buttons on bottom of dialog -->
+        <LinearLayout
+            style="@style/AccessibilityDialogButtonList">
+
+            <Space
+                style="@style/AccessibilityDialogButtonBarSpace"/>
+
+            <Button
+                android:id="@+id/permission_enable_allow_button"
+                android:text="@string/accessibility_dialog_button_allow"
+                style="@style/AccessibilityDialogButtonAllow" />
+
+            <Button
+                android:id="@+id/permission_enable_deny_button"
+                android:text="@string/accessibility_dialog_button_deny"
+                style="@style/AccessibilityDialogButtonDeny" />
+
+        </LinearLayout>
     </LinearLayout>
 
 </ScrollView>
diff --git a/res/layout/face_enroll_education.xml b/res/layout/face_enroll_education.xml
new file mode 100644
index 0000000..c41c724
--- /dev/null
+++ b/res/layout/face_enroll_education.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2018 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<com.google.android.setupdesign.GlifLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:FaceEnrollAccessibilitySwitch="http://schemas.android.com/apk/res/com.android.settings"
+    style="?attr/face_layout_theme"
+    android:id="@+id/setup_wizard_layout"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <LinearLayout
+        style="@style/SudContentFrame"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:clipChildren="false"
+        android:clipToPadding="false"
+        android:orientation="vertical">
+
+        <com.google.android.setupdesign.view.RichTextView
+            android:id="@+id/sud_layout_description"
+            style="@style/SudDescription.Glif"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:textAlignment="center"
+            android:text="@string/security_settings_face_enroll_education_message"/>
+
+        <com.google.android.setupdesign.view.RichTextView
+            android:id="@+id/error_text"
+            style="@style/SudDescription.Glif"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"/>
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginVertical="48dp">
+
+            <com.google.android.setupdesign.view.IllustrationVideoView
+                android:id="@+id/illustration_normal"
+                style="@style/SudContentIllustration"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                app:sudVideo="@raw/face_education"/>
+
+            <ImageView
+                android:id="@+id/illustration_accessibility"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center"
+                android:visibility="invisible"
+                android:background="@drawable/face_enroll_introduction"/>
+
+        </FrameLayout>
+
+        <!-- Contains the buttons and extra information text at the bottom -->
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="vertical"
+            android:layout_gravity="center_horizontal|bottom">
+
+            <FrameLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content">
+
+                <Button
+                    android:id="@+id/accessibility_button"
+                    style="@style/SudGlifButton.Secondary"
+                    android:layout_gravity="center"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/security_settings_face_enroll_introduction_accessibility"/>
+
+                <com.android.settings.biometrics.face.FaceEnrollAccessibilityToggle
+                    android:id="@+id/toggle_diversity"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:visibility="gone"
+                    FaceEnrollAccessibilitySwitch:messageText="@string/security_settings_face_enroll_introduction_accessibility_diversity"/>
+
+            </FrameLayout>
+
+        </LinearLayout>
+
+    </LinearLayout>
+
+</com.google.android.setupdesign.GlifLayout>
diff --git a/res/layout/face_enroll_introduction.xml b/res/layout/face_enroll_introduction.xml
index 3115bb4..535a531 100644
--- a/res/layout/face_enroll_introduction.xml
+++ b/res/layout/face_enroll_introduction.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2018 The Android Open Source Project
+  ~ Copyright (C) 2019 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.
@@ -37,13 +37,13 @@
             style="@style/SudDescription.Glif"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:text="@string/security_settings_face_enroll_introduction_message" />
+            android:text="@string/security_settings_face_enroll_introduction_message"/>
 
         <com.google.android.setupdesign.view.RichTextView
             android:id="@+id/error_text"
             style="@style/SudDescription.Glif"
             android:layout_width="match_parent"
-            android:layout_height="wrap_content" />
+            android:layout_height="wrap_content"/>
 
         <FrameLayout
             android:layout_width="match_parent"
@@ -52,18 +52,10 @@
 
             <com.google.android.setupdesign.view.IllustrationVideoView
                 android:id="@+id/illustration_normal"
-                style="@style/SudContentIllustration"
-                android:layout_width="240dp"
-                android:layout_height="240dp"
-                app:sudVideo="@raw/face_enroll_introduction_animation" />
-
-            <ImageView
-                android:id="@+id/illustration_accessibility"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_gravity="center"
-                android:visibility="invisible"
-                android:background="@drawable/face_enroll_introduction" />
+                style="@style/SudContentIllustration"
+                app:sudVideo="@raw/face_enroll_introduction_animation"/>
 
         </FrameLayout>
 
@@ -74,29 +66,7 @@
             android:orientation="vertical"
             android:layout_gravity="center_horizontal|bottom">
 
-            <FrameLayout
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content">
-
-                <Button
-                    android:id="@+id/accessibility_button"
-                    style="@style/SudGlifButton.Secondary"
-                    android:layout_gravity="center"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="@string/security_settings_face_enroll_introduction_accessibility" />
-
-                <com.android.settings.biometrics.face.FaceEnrollAccessibilityToggle
-                    android:id="@+id/toggle_diversity"
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:visibility="gone"
-                    FaceEnrollAccessibilitySwitch:messageText="@string/security_settings_face_enroll_introduction_accessibility_diversity"/>
-
-            </FrameLayout>
-
             <LinearLayout
-                android:id="@+id/footer_layout"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:orientation="horizontal"
@@ -107,15 +77,61 @@
                 <ImageView
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
-                    android:background="@drawable/ic_face_enroll_introduction_detail">
+                    android:background="@drawable/ic_face_enroll_introduction_shield">
                 </ImageView>
                 <Space
                     android:layout_width="8dp"
-                    android:layout_height="wrap_content" />
+                    android:layout_height="wrap_content"/>
                 <TextView
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
-                    android:text="@string/security_settings_face_enroll_introduction_footer_message"/>
+                    android:text="@string/security_settings_face_enroll_introduction_footer_part_1"/>
+
+            </LinearLayout>
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal"
+                android:paddingStart="16dp"
+                android:paddingEnd="16dp"
+                android:paddingTop="24dp">
+
+                <ImageView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:background="@drawable/ic_face_enroll_introduction_visibility">
+                </ImageView>
+                <Space
+                    android:layout_width="8dp"
+                    android:layout_height="wrap_content"/>
+                <TextView
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:text="@string/security_settings_face_enroll_introduction_footer_part_2"/>
+
+            </LinearLayout>
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal"
+                android:paddingStart="16dp"
+                android:paddingEnd="16dp"
+                android:paddingTop="24dp">
+
+                <ImageView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:background="@drawable/ic_face_enroll_introduction_people">
+                </ImageView>
+                <Space
+                    android:layout_width="8dp"
+                    android:layout_height="wrap_content"/>
+                <TextView
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:text="@string/security_settings_face_enroll_introduction_footer_part_3"/>
             </LinearLayout>
 
         </LinearLayout>
diff --git a/res/layout/manage_applications_apps_unsupported.xml b/res/layout/manage_applications_apps_unsupported.xml
index d7c6726..0c3a0a2 100644
--- a/res/layout/manage_applications_apps_unsupported.xml
+++ b/res/layout/manage_applications_apps_unsupported.xml
@@ -29,6 +29,7 @@
 
         <TextView
             android:id="@+id/empty_header"
+            android:gravity="center"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:text="@string/disabled_feature"
@@ -36,6 +37,7 @@
 
         <TextView
             android:id="@+id/empty_body"
+            android:gravity="center"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:text="@string/disabled_feature_reason_slow_down_phone"
diff --git a/res/layout/settings_homepage_container.xml b/res/layout/settings_homepage_container.xml
index 856bd80..d6c4aef 100644
--- a/res/layout/settings_homepage_container.xml
+++ b/res/layout/settings_homepage_container.xml
@@ -18,6 +18,8 @@
 <androidx.coordinatorlayout.widget.CoordinatorLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/settings_homepage_container"
+    android:fitsSystemWindows="true"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
@@ -54,13 +56,6 @@
     <com.google.android.material.appbar.AppBarLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content">
-
-        <Space
-            android:layout_width="match_parent"
-            android:layout_height="@*android:dimen/status_bar_height"
-            android:background="@android:color/transparent"
-            app:layout_scrollFlags="scroll|enterAlways"/>
-
         <include layout="@layout/search_bar"/>
     </com.google.android.material.appbar.AppBarLayout>
 </androidx.coordinatorlayout.widget.CoordinatorLayout>
diff --git a/res/layout/wifi_dpp_qrcode_scanner_fragment.xml b/res/layout/wifi_dpp_qrcode_scanner_fragment.xml
index 68ba277..9364071 100644
--- a/res/layout/wifi_dpp_qrcode_scanner_fragment.xml
+++ b/res/layout/wifi_dpp_qrcode_scanner_fragment.xml
@@ -64,6 +64,8 @@
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_marginTop="16dp"
+                android:layout_marginStart="24dp"
+                android:layout_marginEnd="24dp"
                 android:textAlignment="center"
                 android:textColor="?android:attr/colorError"
                 android:visibility="invisible"/>
diff --git a/res/raw/face_education.mp4 b/res/raw/face_education.mp4
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/res/raw/face_education.mp4
diff --git a/res/raw/gesture_global_actions_panel.mp4 b/res/raw/gesture_global_actions_panel.mp4
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/res/raw/gesture_global_actions_panel.mp4
diff --git a/res/values-night/colors.xml b/res/values-night/colors.xml
index 4c43257..f761217 100644
--- a/res/values-night/colors.xml
+++ b/res/values-night/colors.xml
@@ -15,19 +15,17 @@
 -->
 
 <resources>
-  <color name="switchbar_switch_track_tint">#82000000</color>
-  <color name="switchbar_switch_thumb_tint">@android:color/black</color>
-  <color name="homepage_accessibility_background">#783BE5</color>
-  <color name="homepage_support_background">#3F5FBD</color>
-  <!-- 80% black for status bar of homepage -->
-  <color name="homepage_status_bar_color">#cc000000</color>
-  <color name="homepage_card_dismissal_background">@*android:color/material_grey_900</color>
-  <color name="contextual_card_background">@*android:color/material_grey_900</color>
-  <color name="search_bar_background">@*android:color/material_grey_800</color>
-  <!-- Dialog background color -->
-  <color name="dialog_background">@*android:color/material_grey_800</color>
-  <color name="notification_importance_selection_bg">@*android:color/material_grey_800</color>
-  <color name="notification_importance_button_selected">#AECBFA</color> <!-- material blue 200 -->
-  <color name="notification_importance_button_unselected">#5F6368</color>
+    <color name="switchbar_switch_track_tint">#82000000</color>
+    <color name="switchbar_switch_thumb_tint">@android:color/black</color>
+    <color name="homepage_accessibility_background">#783BE5</color>
+    <color name="homepage_support_background">#3F5FBD</color>
+    <color name="homepage_card_dismissal_background">@*android:color/material_grey_900</color>
+    <color name="contextual_card_background">@*android:color/material_grey_900</color>
+    <color name="search_bar_background">@*android:color/material_grey_800</color>
+    <!-- Dialog background color -->
+    <color name="dialog_background">@*android:color/material_grey_800</color>
+    <color name="notification_importance_selection_bg">@*android:color/material_grey_800</color>
+    <color name="notification_importance_button_selected">#AECBFA</color> <!-- material blue 200 -->
+    <color name="notification_importance_button_unselected">#5F6368</color>
 </resources>
 
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 42fa3f9..4a4c896 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -23,7 +23,9 @@
 
     <color name="divider_color">#20ffffff</color>
     <color name="title_color">@android:color/holo_blue_light</color>
-    <color name="setup_lock_pattern_view_regular_color_light">@color/lock_pattern_view_regular_color</color>
+    <color name="setup_lock_pattern_view_regular_color_light">
+        @color/lock_pattern_view_regular_color
+    </color>
     <color name="setup_lock_pattern_view_success_color_dark">#ff84ffff</color>
     <color name="setup_lock_pattern_view_success_color_light">@color/sud_color_accent_light</color>
     <color name="setup_lock_pattern_view_error_color_dark">#fff44336</color>
@@ -133,9 +135,6 @@
     <!-- launcher icon color -->
     <color name="icon_launcher_setting_color">@*android:color/accent_device_default_light</color>
 
-    <!-- 80% white for status bar of homepage -->
-    <color name="homepage_status_bar_color">#ccFFFFFF</color>
-
     <!-- QR code scanner colors -->
     <color name="qr_corner_line_color">#ffdadce0</color>
     <color name="qr_focused_corner_line_color">#ff1a73e8</color>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index a348f8a..09ab682 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -409,5 +409,5 @@
     <dimen name="two_target_min_width">80dp</dimen>
 
     <!-- Maximum height for SliceView, override on slices/view/src/main/res/values/dimens.xml -->
-    <dimen name="abc_slice_large_height">360dp</dimen>
+    <dimen name="abc_slice_large_height">480dp</dimen>
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index a31de98..1b24912 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -888,6 +888,12 @@
     <string name="security_settings_face_preference_summary_none">Tap to set up face authentication</string>
     <!-- Title shown for menu item that launches face settings or enrollment. [CHAR LIMIT=32] -->
     <string name="security_settings_face_preference_title">Face authentication</string>
+    <!-- Introduction title shown in face enrollment education screen [CHAR LIMIT=40] -->
+    <string name="security_settings_face_enroll_education_title">How to set up Face unlock</string>
+    <!-- Introduction title shown in face enrollment education screen to show the face authentication feature, when face unlock is disabled by device admin [CHAR LIMIT=40] -->
+    <string name="security_settings_face_enroll_education_title_unlock_disabled">Use your face to authenticate</string>
+    <!-- Introduction detail message shown in face education [CHAR LIMIT=NONE] -->
+    <string name="security_settings_face_enroll_education_message"></string>
     <!-- Button shown which shows accessibility toggles for face enrollment when clicked. [CHAR LIMIT=32] -->
     <string name="security_settings_face_enroll_introduction_accessibility">Use accessibility setup</string>
     <!-- Additional details shown when the accessibility toggle is expanded. [CHAR LIMIT=NONE]-->
@@ -908,8 +914,12 @@
     <string name="security_settings_face_enroll_introduction_message_unlock_disabled">Use your face to unlock your phone or approve purchases.\n\nNote: You can\u2019t use your face to unlock this device. For more information, contact your organization\u2019s admin.</string>
     <!-- Introduction detail message shown in face enrollment screen in setup wizard. [CHAR LIMIT=NONE] -->
     <string name="security_settings_face_enroll_introduction_message_setup">Use your face to unlock your phone, authorize purchases, or sign in to apps</string>
-    <!-- Introduction detail message shown in face enrollment that provides extra detais. [CHAR LIMIT=NONE] -->
-    <string name="security_settings_face_enroll_introduction_footer_message"></string>
+    <!-- Introduction message shown in face enrollment that provides extra detail. [CHAR LIMIT=NONE] -->
+    <string name="security_settings_face_enroll_introduction_footer_part_1"></string>
+    <!-- Introduction message shown in face enrollment that provides extra detail. [CHAR LIMIT=NONE] -->
+    <string name="security_settings_face_enroll_introduction_footer_part_2"></string>
+    <!-- Introduction message shown in face enrollment that provides extra detail. [CHAR LIMIT=NONE] -->
+    <string name="security_settings_face_enroll_introduction_footer_part_3"></string>
     <!-- Title shown in face enrollment dialog [CHAR LIMIT=40] -->
     <string name="security_settings_face_enroll_repeat_title">Center your face in the circle</string>
     <!-- Button text to skip enrollment of face [CHAR LIMIT=40] -->
@@ -2895,7 +2905,7 @@
     <string name="wallpaper_settings_fragment_title">Choose wallpaper from</string>
     <!-- Styles and Wallpaper settings title [CHAR_LIMIT=46] -->
     <string name="style_suggestion_title">Customize your Pixel</string>
-    <!-- Styles and Wallpapers summary [CHAR_LIMIT=55] -->
+    <!-- Styles and Wallpapers summary [CHAR_LIMIT=70] -->
     <string name="style_suggestion_summary">Try different styles, wallpapers, clocks, and more</string>
     <!-- Display settings screen, trigger for screen saver options -->
     <string name="screensaver_settings_title">Screen saver</string>
@@ -5070,8 +5080,9 @@
 
     <!-- Title for a warning about security implications of enabling an accessibility
          service. [CHAR LIMIT=NONE] -->
-    <string name="enable_service_title">Use
-         <xliff:g id="service" example="TalkBack">%1$s</xliff:g>?</string>
+    <string name="enable_service_title">Allow
+         <xliff:g id="service" example="TalkBack">%1$s</xliff:g> to have full contol of your
+        device?</string>
     <!-- Title for the list of capabilities of an accessibility service. -->
     <string name="capabilities_list_title"><xliff:g id="service" example="TalkBack">%1$s</xliff:g>
         needs to:</string>
@@ -5112,11 +5123,43 @@
         This level of control is not appropriate for most apps.
     </string>
 
+    <!-- Warning description that explains that it's appropriate for accessibility
+         services to have full control to help users with accessibility needs. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_service_warning_description">Full control is appropriate for apps
+        that help you with accessibility needs, but not for most apps.
+    </string>
+
+    <!-- Title for the screen control in accessibility dialog. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_service_screen_control_title">View and control screen</string>
+
+    <!-- Description for the screen control in accessibility dialog. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_service_screen_control_description">It can read all content on the
+        screen and display content over other apps.
+    </string>
+
+    <!-- Title for the action perform in accessibility dialog. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_service_action_perform_title">View and platform actions</string>
+
+    <!-- Description for the action perform in accessibility dialog. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_service_action_perform_description">It can track your interactions
+        with an app or a hardware sensor, and interact with apps on your behalf.
+    </string>
+
+    <!-- String for the allow button in accessibility permission dialog. [CHAR LIMIT=10] -->
+    <string name="accessibility_dialog_button_allow">Allow</string>
+    <!-- String for the deny button in accessibility permission dialog. [CHAR LIMIT=10] -->
+    <string name="accessibility_dialog_button_deny">Deny</string>
+
+    <!-- String for the allow button in accessibility permission dialog. [CHAR LIMIT=10] -->
+    <string name="accessibility_dialog_button_stop">Stop</string>
+    <!-- String for the deny button in accessibility permission dialog. [CHAR LIMIT=10] -->
+    <string name="accessibility_dialog_button_cancel">Cancel</string>
+
     <!-- Title for a warning about disabling an accessibility service. [CHAR LIMIT=NONE] -->
     <string name="disable_service_title">Stop <xliff:g id="service" example="TalkBack">%1$s</xliff:g>?</string>
     <!-- Message for a warning about disabling accessibility service. [CHAR LIMIT=NONE] -->
-    <string name="disable_service_message">Tapping OK will
-        stop <xliff:g id="service" example="TalkBack">%1$s</xliff:g>.</string>
+    <string name="disable_service_message">Tapping <xliff:g id="stop" example="Stop">%1$s</xliff:g> will
+        stop <xliff:g id="service" example="TalkBack">%2$s</xliff:g>.</string>
 
     <!-- Title for the prompt shown as a placeholder if no accessibility services are installed. [CHAR LIMIT=50] -->
     <string name="accessibility_no_services_installed">No services installed</string>
@@ -7264,6 +7307,8 @@
     <string name="keywords_profile_challenge">work challenge, work, profile</string>
     <string name="keywords_unification">work profile, managed profile, unify, unification, work, profile</string>
     <string name="keywords_gesture">gestures</string>
+    <!-- Search keywords for Global Actions Panel. [DO NOT TRANSLATE] -->
+    <string name="keywords_global_actions_panel" translatable="false">global actions</string>
     <string name="keywords_payment_settings">pay, tap, payments</string>
     <string name="keywords_backup">backup, back up</string>
     <string name="keywords_assist_gesture_launch">gesture</string>
@@ -10148,6 +10193,15 @@
     <!-- Summary text for ambient display tap [CHAR LIMIT=NONE]-->
     <string name="ambient_display_tap_screen_summary">To check time, notifications, and other info, tap your screen.</string>
 
+    <!-- Summary text for global actions panel [CHAR LIMIT=NONE] [DO NOT TRANSLATE]-->
+    <string name="global_actions_panel_summary" translatable="false">To show the global actions panel, press &amp; hold Power button</string>
+    <!-- Preference and settings suggestion title text for global actions panel [CHAR LIMIT=60] [DO NOT TRANSLATE]-->
+    <string name="global_actions_panel_title" translatable="false">Show global actions</string>
+    <!-- Short title text for global actions panel [CHAR LIMIT=40] [DO NOT TRANSLATE]-->
+    <string name="global_actions_panel_short_title" translatable="false">Global actions</string>
+    <!-- Footer text for global actions panel [CHAR LIMIT=NONE] [DO NOT TRANSLATE]-->
+    <string name="global_actions_panel_footer" translatable="false">The global actions panel can be accessed even when the device is locked.</string>
+
     <!-- Title text for swiping downwards on fingerprint sensor for notifications [CHAR LIMIT=80]-->
     <string name="fingerprint_swipe_for_notifications_title">Swipe fingerprint for notifications</string>
     <!-- Title text for fingerprint gesture preference screen [CHAR LIMIT=25] -->
@@ -10489,9 +10543,9 @@
     <!-- Note displayed when certain features are not available on low ram devices. [CHAR LIMIT=NONE] -->
     <string name="disabled_low_ram_device">This feature is not available on this device</string>
     <!-- Note displayed when certain features are not available. [CHAR LIMIT=NONE] -->
-    <string name="disabled_feature">This feature is not available</string>
+    <string name="disabled_feature">Feature not available</string>
     <!-- Note displayed to explain that a feature is not available because it will slow down the phone. [CHAR LIMIT=NONE] -->
-    <string name="disabled_feature_reason_slow_down_phone">It will slow down this phone</string>
+    <string name="disabled_feature_reason_slow_down_phone">This feature has been turned off because it slows down your phone</string>
 
     <!-- UI debug setting: preference title - enforce full raw GNSS satellite measurements [CHAR LIMIT=60] -->
     <string name="enable_gnss_raw_meas_full_tracking">Force full GNSS measurements</string>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 8678e6e..d3d3199 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -493,6 +493,10 @@
         <item name="android:paddingEnd">8dp</item>
 
         <item name="rowStyle">@style/SliceRowStyle</item>
+        <item name="android:background">?android:attr/colorBackgroundFloating</item>
+    </style>
+
+    <style name="ContextualCardSliceViewStyle" parent="SliceViewStyle">
         <item name="android:background">@color/contextual_card_background</item>
     </style>
 
@@ -562,4 +566,94 @@
         <item name="android:textColor">?android:attr/textColorPrimary</item>
     </style>
 
+    <style name="AccessibilityDialog">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:orientation">vertical</item>
+        <item name="android:divider">@*android:drawable/list_divider_material</item>
+        <item name="android:showDividers">middle</item>
+    </style>
+
+    <style name="AccessibilityDialogServiceIcon">
+        <item name="android:layout_width">36dp</item>
+        <item name="android:layout_height">36dp</item>
+        <item name="android:layout_marginTop">16dp</item>
+        <item name="android:layout_marginBottom">16dp</item>
+        <item name="android:scaleType">fitCenter</item>
+    </style>
+
+    <style name="AccessibilityDialogIcon">
+        <item name="android:layout_width">18dp</item>
+        <item name="android:layout_height">18dp</item>
+        <item name="android:layout_marginRight">12dp</item>
+        <item name="android:scaleType">fitCenter</item>
+    </style>
+
+    <style name="AccessibilityDialogTitle"
+           parent="@android:style/TextAppearance.DeviceDefault">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:gravity">center</item>
+        <item name="android:textSize">20sp</item>
+        <item name="android:textColor">?android:attr/textColorPrimary</item>
+        <item name="android:fontFamily">google-sans-medium</item>
+    </style>
+
+    <style name="AccessibilityDialogDescription"
+           parent="@android:style/TextAppearance.DeviceDefault">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_marginTop">16dp</item>
+        <item name="android:layout_marginBottom">32dp</item>
+        <item name="android:textSize">16sp</item>
+        <item name="android:textColor">?android:attr/textColorPrimary</item>
+        <item name="android:fontFamily">sans-serif</item>
+    </style>
+
+    <style name="AccessibilityDialogPermissionTitle"
+           parent="@android:style/TextAppearance.DeviceDefault">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:textSize">16sp</item>
+        <item name="android:textColor">?android:attr/textColorPrimary</item>
+        <item name="android:fontFamily">sans-serif</item>
+    </style>
+
+    <style name="AccessibilityDialogPermissionDescription"
+           parent="@android:style/TextAppearance.DeviceDefault">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:textSize">14sp</item>
+        <item name="android:textColor">?android:attr/textColorSecondary</item>
+        <item name="android:fontFamily">sans-serif</item>
+    </style>
+
+    <style name="AccessibilityDialogButtonBarSpace">
+        <item name="android:layout_width">0dp</item>
+        <item name="android:layout_height">0dp</item>
+        <item name="android:visibility">gone</item>
+    </style>
+
+    <style name="AccessibilityDialogButtonList">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:orientation">vertical</item>
+        <item name="android:divider">@*android:drawable/list_divider_material</item>
+        <item name="android:showDividers">middle</item>
+    </style>
+
+    <style name="AccessibilityDialogButton"
+           parent="@*android:style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">56dp</item>
+        <item name="android:paddingLeft">8dp</item>
+        <item name="android:paddingRight">8dp</item>
+        <item name="android:background">?android:attr/selectableItemBackground</item>
+    </style>
+
+    <style name="AccessibilityDialogButtonAllow"
+           parent="@style/AccessibilityDialogButton"></style>
+    <style name="AccessibilityDialogButtonDeny"
+           parent="@style/AccessibilityDialogButton"></style>
+
 </resources>
diff --git a/res/values/themes.xml b/res/values/themes.xml
index 951bb04..4edd943 100644
--- a/res/values/themes.xml
+++ b/res/values/themes.xml
@@ -197,9 +197,8 @@
         <item name="colorPrimaryDark">@*android:color/primary_dark_device_default_settings_light</item>
         <item name="android:windowLightStatusBar">true</item>
         <item name="android:navigationBarDividerColor">@*android:color/ripple_material_light</item>
-        <item name="android:navigationBarColor">@android:color/white</item>
+        <item name="android:navigationBarColor">@android:color/transparent</item>
         <item name="android:windowBackground">@android:color/white</item>
-        <item name="android:windowLightNavigationBar">true</item>
     </style>
 
     <!-- Note that Dialog themes do not set list dividers -->
diff --git a/res/xml/gentle_notification_settings.xml b/res/xml/gentle_notification_settings.xml
index 80061ba..56c3c40 100644
--- a/res/xml/gentle_notification_settings.xml
+++ b/res/xml/gentle_notification_settings.xml
@@ -24,6 +24,7 @@
             android:title="@string/summary_placeholder"
             android:layout="@layout/drawable_layout"
             settings:controller="com.android.settings.notification.GentleDrawablePreferenceController"
+            android:selectable="false"
             android:order="1"
             settings:allowDividerBelow="true"
             android:persistent="false" />
diff --git a/res/xml/gestures.xml b/res/xml/gestures.xml
index 8515bd7..5dcb1b0 100644
--- a/res/xml/gestures.xml
+++ b/res/xml/gestures.xml
@@ -75,4 +75,10 @@
         android:fragment="com.android.settings.gestures.PreventRingingGestureSettings"
         settings:controller="com.android.settings.gestures.PreventRingingParentPreferenceController" />
 
+    <Preference
+        android:key="gesture_global_actions_panel_summary"
+        android:title="@string/global_actions_panel_short_title"
+        android:fragment="com.android.settings.gestures.GlobalActionsPanelSettings"
+        settings:controller="com.android.settings.gestures.GlobalActionsPanelPreferenceController" />
+
 </PreferenceScreen>
diff --git a/res/xml/global_actions_panel_settings.xml b/res/xml/global_actions_panel_settings.xml
new file mode 100644
index 0000000..af155bc
--- /dev/null
+++ b/res/xml/global_actions_panel_settings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2019 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.
+  -->
+
+<PreferenceScreen
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:key="gesture_global_actions_panel"
+    android:title="@string/global_actions_panel_title">
+
+    <com.android.settings.widget.VideoPreference
+        android:key="global_actions_panel_video"
+        app:animation="@raw/gesture_global_actions_panel" />
+
+    <SwitchPreference
+        android:key="gesture_global_actions_panel_switch"
+        android:title="@string/global_actions_panel_title"
+        android:summary="@string/global_actions_panel_summary"
+        app:keywords="@string/keywords_global_actions_panel"
+        app:controller="com.android.settings.gestures.GlobalActionsPanelPreferenceController"
+        app:allowDividerAbove="true" />
+
+    <com.android.settingslib.widget.FooterPreference
+        android:key="footer_preference"
+        android:title="@string/global_actions_panel_footer" />
+
+</PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/privacy_settings.xml b/res/xml/privacy_settings.xml
index 57c3d5e..2e09dbd 100644
--- a/res/xml/privacy_settings.xml
+++ b/res/xml/privacy_settings.xml
@@ -50,7 +50,7 @@
 
     <Preference
         android:key="backup_inactive"
-        android:title="@string/backup_inactive_title"
+        android:title="@string/disabled_by_administrator_summary"
         android:enabled="false"
         android:selectable="false"
         settings:controller="com.android.settings.backup.BackupInactivePreferenceController" />
diff --git a/src/com/android/settings/accessibility/AccessibilityServiceWarning.java b/src/com/android/settings/accessibility/AccessibilityServiceWarning.java
index dec734c..40ac641 100644
--- a/src/com/android/settings/accessibility/AccessibilityServiceWarning.java
+++ b/src/com/android/settings/accessibility/AccessibilityServiceWarning.java
@@ -22,7 +22,7 @@
 import android.app.Activity;
 import android.app.Dialog;
 import android.content.Context;
-import android.content.DialogInterface;
+import android.graphics.drawable.Drawable;
 import android.os.storage.StorageManager;
 import android.text.BidiFormatter;
 import android.view.LayoutInflater;
@@ -30,10 +30,13 @@
 import android.view.View;
 import android.view.Window;
 import android.view.WindowManager;
+import android.widget.Button;
+import android.widget.ImageView;
 import android.widget.TextView;
 import android.widget.Toast;
 
 import androidx.appcompat.app.AlertDialog;
+import androidx.core.content.ContextCompat;
 
 import com.android.settings.R;
 
@@ -44,40 +47,45 @@
  * accessibility service to access user data before the service is enabled
  */
 public class AccessibilityServiceWarning {
-    public static Dialog createCapabilitiesDialog(Activity parentActivity,
-            AccessibilityServiceInfo info, DialogInterface.OnClickListener listener) {
-        final AlertDialog ad = new AlertDialog.Builder(parentActivity)
-                .setTitle(parentActivity.getString(R.string.enable_service_title,
-                        getServiceName(parentActivity, info)))
-                .setView(createEnableDialogContentView(parentActivity, info))
-                .setPositiveButton(android.R.string.ok, listener)
-                .setNegativeButton(android.R.string.cancel, listener)
-                .create();
-
-        final View.OnTouchListener filterTouchListener = (View v, MotionEvent event) -> {
-            // Filter obscured touches by consuming them.
-            if (((event.getFlags() & MotionEvent.FLAG_WINDOW_IS_OBSCURED) != 0)
-                    || ((event.getFlags() & MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED) != 0)) {
-                if (event.getAction() == MotionEvent.ACTION_UP) {
-                    Toast.makeText(v.getContext(), R.string.touch_filtered_warning,
-                            Toast.LENGTH_SHORT).show();
-                }
-                return true;
+    private static final View.OnTouchListener filterTouchListener = (View v, MotionEvent event) -> {
+        // Filter obscured touches by consuming them.
+        if (((event.getFlags() & MotionEvent.FLAG_WINDOW_IS_OBSCURED) != 0)
+                || ((event.getFlags() & MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED) != 0)) {
+            if (event.getAction() == MotionEvent.ACTION_UP) {
+                Toast.makeText(v.getContext(), R.string.touch_filtered_warning,
+                        Toast.LENGTH_SHORT).show();
             }
-            return false;
-        };
+            return true;
+        }
+        return false;
+    };
+
+    public static Dialog createCapabilitiesDialog(Activity parentActivity,
+            AccessibilityServiceInfo info, View.OnClickListener listener) {
+        final AlertDialog ad = new AlertDialog.Builder(parentActivity)
+                .setView(createEnableDialogContentView(parentActivity, info, listener))
+                .create();
 
         Window window = ad.getWindow();
         WindowManager.LayoutParams params = window.getAttributes();
         params.privateFlags |= SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
         window.setAttributes(params);
         ad.create();
-        ad.getButton(AlertDialog.BUTTON_POSITIVE).setOnTouchListener(filterTouchListener);
         ad.setCanceledOnTouchOutside(true);
 
         return ad;
     }
 
+    public static Dialog createDisableDialog(Activity parentActivity,
+            AccessibilityServiceInfo info, View.OnClickListener listener) {
+        final AlertDialog ad = new AlertDialog.Builder(parentActivity)
+                .setView(createDisableDialogContentView(parentActivity, info, listener))
+                .setCancelable(true)
+                .create();
+
+        return ad;
+    }
+
     /**
      * Return whether the device is encrypted with legacy full disk encryption. Newer devices
      * should be using File Based Encryption.
@@ -96,7 +104,7 @@
      * @return A content view suitable for viewing
      */
     private static View createEnableDialogContentView(Context context,
-            AccessibilityServiceInfo info) {
+            AccessibilityServiceInfo info, View.OnClickListener listener) {
         LayoutInflater inflater = (LayoutInflater) context.getSystemService(
                 Context.LAYOUT_INFLATER_SERVICE);
 
@@ -114,9 +122,55 @@
             encryptionWarningView.setVisibility(View.GONE);
         }
 
-        TextView serviceWarningTextView = content.findViewById(R.id.accessibility_service_warning);
-        serviceWarningTextView.setText(context.getString(R.string.accessibility_service_warning,
-            getServiceName(context, info)));
+        final Drawable icon;
+        if (info.getResolveInfo().getIconResource() == 0) {
+            icon = ContextCompat.getDrawable(context, R.drawable.ic_accessibility_generic);
+        } else {
+            icon = info.getResolveInfo().loadIcon(context.getPackageManager());
+        }
+
+        ImageView permissionDialogIcon = content.findViewById(
+                R.id.permissionDialog_icon);
+        permissionDialogIcon.setImageDrawable(icon);
+
+        TextView permissionDialogTitle = content.findViewById(R.id.permissionDialog_title);
+        permissionDialogTitle.setText(context.getString(R.string.enable_service_title,
+                getServiceName(context, info)));
+
+        Button permissionAllowButton = content.findViewById(
+                R.id.permission_enable_allow_button);
+        Button permissionDenyButton = content.findViewById(
+                R.id.permission_enable_deny_button);
+        permissionAllowButton.setOnClickListener(listener);
+        permissionAllowButton.setOnTouchListener(filterTouchListener);
+        permissionDenyButton.setOnClickListener(listener);
+
+        return content;
+    }
+
+    private static View createDisableDialogContentView(Context context,
+            AccessibilityServiceInfo info, View.OnClickListener listener) {
+        LayoutInflater inflater = (LayoutInflater) context.getSystemService(
+                Context.LAYOUT_INFLATER_SERVICE);
+
+        View content = inflater.inflate(R.layout.disable_accessibility_service_dialog_content,
+                null);
+
+        TextView permissionDialogTitle = content.findViewById(R.id.permissionDialog_disable_title);
+        permissionDialogTitle.setText(context.getString(R.string.disable_service_title,
+                getServiceName(context, info)));
+        TextView permissionDialogMessage = content
+                .findViewById(R.id.permissionDialog_disable_message);
+        permissionDialogMessage.setText(context.getString(R.string.disable_service_message,
+                context.getString(R.string.accessibility_dialog_button_stop),
+                getServiceName(context, info)));
+
+        Button permissionAllowButton = content.findViewById(
+                R.id.permission_disable_stop_button);
+        Button permissionDenyButton = content.findViewById(
+                R.id.permission_disable_cancel_button);
+        permissionAllowButton.setOnClickListener(listener);
+        permissionDenyButton.setOnClickListener(listener);
 
         return content;
     }
diff --git a/src/com/android/settings/accessibility/ShortcutServicePickerFragment.java b/src/com/android/settings/accessibility/ShortcutServicePickerFragment.java
index 2da4f7a..bb26283 100644
--- a/src/com/android/settings/accessibility/ShortcutServicePickerFragment.java
+++ b/src/com/android/settings/accessibility/ShortcutServicePickerFragment.java
@@ -37,6 +37,7 @@
 import android.provider.Settings;
 import android.text.TextUtils;
 import android.view.accessibility.AccessibilityManager;
+import android.view.View;
 
 import androidx.fragment.app.Fragment;
 import androidx.fragment.app.FragmentActivity;
@@ -148,7 +149,7 @@
     }
 
     public static class ConfirmationDialogFragment extends InstrumentedDialogFragment
-            implements DialogInterface.OnClickListener {
+            implements View.OnClickListener {
         private static final String EXTRA_KEY = "extra_key";
         private static final String TAG = "ConfirmationDialogFragment";
         private IBinder mToken;
@@ -182,9 +183,10 @@
         }
 
         @Override
-        public void onClick(DialogInterface dialog, int which) {
+        public void onClick(View view) {
             final Fragment fragment = getTargetFragment();
-            if ((which == BUTTON_POSITIVE) && (fragment instanceof ShortcutServicePickerFragment)) {
+            if ((view.getId() == R.id.permission_enable_allow_button)
+                && (fragment instanceof ShortcutServicePickerFragment)) {
                 final Bundle bundle = getArguments();
                 ((ShortcutServicePickerFragment) fragment).onServiceConfirmed(
                         bundle.getString(EXTRA_KEY));
diff --git a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
index d935d92..b28d8b5 100644
--- a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
@@ -22,7 +22,6 @@
 import android.app.admin.DevicePolicyManager;
 import android.app.settings.SettingsEnums;
 import android.content.ComponentName;
-import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.pm.ResolveInfo;
 import android.net.Uri;
@@ -34,10 +33,9 @@
 import android.text.TextUtils;
 import android.view.Menu;
 import android.view.MenuInflater;
+import android.view.View;
 import android.view.accessibility.AccessibilityManager;
 
-import androidx.appcompat.app.AlertDialog;
-
 import com.android.internal.widget.LockPatternUtils;
 import com.android.settings.R;
 import com.android.settings.password.ConfirmDeviceCredentialActivity;
@@ -48,7 +46,7 @@
 import java.util.List;
 
 public class ToggleAccessibilityServicePreferenceFragment
-        extends ToggleFeaturePreferenceFragment implements DialogInterface.OnClickListener {
+        extends ToggleFeaturePreferenceFragment implements View.OnClickListener {
 
     private static final int DIALOG_ID_ENABLE_WARNING = 1;
     private static final int DIALOG_ID_DISABLE_WARNING = 2;
@@ -67,7 +65,7 @@
 
     private ComponentName mComponentName;
 
-    private int mShownDialogId;
+    private Dialog mDialog;
 
     @Override
     public int getMetricsCategory() {
@@ -129,35 +127,28 @@
     public Dialog onCreateDialog(int dialogId) {
         switch (dialogId) {
             case DIALOG_ID_ENABLE_WARNING: {
-                mShownDialogId = DIALOG_ID_ENABLE_WARNING;
                 final AccessibilityServiceInfo info = getAccessibilityServiceInfo();
                 if (info == null) {
                     return null;
                 }
-
-                return AccessibilityServiceWarning
+                mDialog = AccessibilityServiceWarning
                         .createCapabilitiesDialog(getActivity(), info, this);
+                break;
             }
             case DIALOG_ID_DISABLE_WARNING: {
-                mShownDialogId = DIALOG_ID_DISABLE_WARNING;
                 AccessibilityServiceInfo info = getAccessibilityServiceInfo();
                 if (info == null) {
                     return null;
                 }
-                return new AlertDialog.Builder(getActivity())
-                        .setTitle(getString(R.string.disable_service_title,
-                                info.getResolveInfo().loadLabel(getPackageManager())))
-                        .setMessage(getString(R.string.disable_service_message,
-                                info.getResolveInfo().loadLabel(getPackageManager())))
-                        .setCancelable(true)
-                        .setPositiveButton(android.R.string.ok, this)
-                        .setNegativeButton(android.R.string.cancel, this)
-                        .create();
+                mDialog = AccessibilityServiceWarning
+                        .createDisableDialog(getActivity(), info, this);
+                break;
             }
             default: {
                 throw new IllegalArgumentException();
             }
         }
+        return mDialog;
     }
 
     @Override
@@ -205,30 +196,31 @@
     }
 
     @Override
-    public void onClick(DialogInterface dialog, int which) {
-        final boolean checked;
-        switch (which) {
-            case DialogInterface.BUTTON_POSITIVE:
-                if (mShownDialogId == DIALOG_ID_ENABLE_WARNING) {
-                    if (isFullDiskEncrypted()) {
-                        String title = createConfirmCredentialReasonMessage();
-                        Intent intent = ConfirmDeviceCredentialActivity.createIntent(title, null);
-                        startActivityForResult(intent,
-                                ACTIVITY_REQUEST_CONFIRM_CREDENTIAL_FOR_WEAKER_ENCRYPTION);
-                    } else {
-                        handleConfirmServiceEnabled(true);
-                    }
+    public void onClick(View view) {
+        switch (view.getId()) {
+            case R.id.permission_enable_allow_button:
+                if (isFullDiskEncrypted()) {
+                    String title = createConfirmCredentialReasonMessage();
+                    Intent intent = ConfirmDeviceCredentialActivity.createIntent(title, null);
+                    startActivityForResult(intent,
+                            ACTIVITY_REQUEST_CONFIRM_CREDENTIAL_FOR_WEAKER_ENCRYPTION);
                 } else {
-                    handleConfirmServiceEnabled(false);
+                    handleConfirmServiceEnabled(true);
                 }
                 break;
-            case DialogInterface.BUTTON_NEGATIVE:
-                checked = (mShownDialogId == DIALOG_ID_DISABLE_WARNING);
-                handleConfirmServiceEnabled(checked);
+            case R.id.permission_enable_deny_button:
+                handleConfirmServiceEnabled(false);
+                break;
+            case R.id.permission_disable_stop_button:
+                handleConfirmServiceEnabled(false);
+                break;
+            case R.id.permission_disable_cancel_button:
+                handleConfirmServiceEnabled(true);
                 break;
             default:
                 throw new IllegalArgumentException();
         }
+        mDialog.dismiss();
     }
 
     private void handleConfirmServiceEnabled(boolean confirmed) {
diff --git a/src/com/android/settings/applications/ApplicationFeatureProvider.java b/src/com/android/settings/applications/ApplicationFeatureProvider.java
index 3ffacb0..e9f877e 100644
--- a/src/com/android/settings/applications/ApplicationFeatureProvider.java
+++ b/src/com/android/settings/applications/ApplicationFeatureProvider.java
@@ -82,6 +82,14 @@
     Set<String> getKeepEnabledPackages();
 
     /**
+     * Returns a user readable text explaining how much time user has spent in an app at a
+     * pre-specified duration.
+     */
+    default CharSequence getTimeSpentInApp(String packageName) {
+        return null;
+    }
+
+    /**
      * Callback that receives the number of packages installed on the device.
      */
     interface NumberOfAppsCallback {
diff --git a/src/com/android/settings/applications/ApplicationFeatureProviderImpl.java b/src/com/android/settings/applications/ApplicationFeatureProviderImpl.java
index 7027239..1fd7997 100644
--- a/src/com/android/settings/applications/ApplicationFeatureProviderImpl.java
+++ b/src/com/android/settings/applications/ApplicationFeatureProviderImpl.java
@@ -41,7 +41,7 @@
 
 public class ApplicationFeatureProviderImpl implements ApplicationFeatureProvider {
 
-    private final Context mContext;
+    protected final Context mContext;
     private final PackageManager mPm;
     private final IPackageManager mPms;
     private final DevicePolicyManager mDpm;
diff --git a/src/com/android/settings/applications/appinfo/TimeSpentInAppPreferenceController.java b/src/com/android/settings/applications/appinfo/TimeSpentInAppPreferenceController.java
index 70ffcb3..b1bbd06 100644
--- a/src/com/android/settings/applications/appinfo/TimeSpentInAppPreferenceController.java
+++ b/src/com/android/settings/applications/appinfo/TimeSpentInAppPreferenceController.java
@@ -28,7 +28,9 @@
 import androidx.preference.Preference;
 import androidx.preference.PreferenceScreen;
 
+import com.android.settings.applications.ApplicationFeatureProvider;
 import com.android.settings.core.BasePreferenceController;
+import com.android.settings.overlay.FeatureFactory;
 
 import java.util.List;
 
@@ -38,13 +40,15 @@
     static final Intent SEE_TIME_IN_APP_TEMPLATE = new Intent(Settings.ACTION_APP_USAGE_SETTINGS);
 
     private final PackageManager mPackageManager;
-
+    private final ApplicationFeatureProvider mAppFeatureProvider;
     private Intent mIntent;
     private String mPackageName;
 
     public TimeSpentInAppPreferenceController(Context context, String preferenceKey) {
         super(context, preferenceKey);
         mPackageManager = context.getPackageManager();
+        mAppFeatureProvider = FeatureFactory.getFactory(context)
+                .getApplicationFeatureProvider(context);
     }
 
     public void setPackageName(String packageName) {
@@ -80,6 +84,11 @@
         }
     }
 
+    @Override
+    public CharSequence getSummary() {
+        return mAppFeatureProvider.getTimeSpentInApp(mPackageName);
+    }
+
     private boolean isSystemApp(ResolveInfo info) {
         return info != null
                 && info.activityInfo != null
diff --git a/src/com/android/settings/applications/manageapplications/ManageApplications.java b/src/com/android/settings/applications/manageapplications/ManageApplications.java
index ba5e73f..d2b21b0 100644
--- a/src/com/android/settings/applications/manageapplications/ManageApplications.java
+++ b/src/com/android/settings/applications/manageapplications/ManageApplications.java
@@ -373,6 +373,7 @@
                                 UserHandle.of(userId)));
             }
             mRecyclerView = mListContainer.findViewById(R.id.apps_list);
+            mRecyclerView.setItemAnimator(null);
             mRecyclerView.setLayoutManager(new LinearLayoutManager(
                     getContext(), RecyclerView.VERTICAL, false /* reverseLayout */));
             mRecyclerView.setAdapter(mApplications);
diff --git a/src/com/android/settings/biometrics/face/FaceEnrollEducation.java b/src/com/android/settings/biometrics/face/FaceEnrollEducation.java
new file mode 100644
index 0000000..9660f3b
--- /dev/null
+++ b/src/com/android/settings/biometrics/face/FaceEnrollEducation.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2018 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.biometrics.face;
+
+import static android.provider.Settings.Secure.FACE_UNLOCK_EDUCATION_INFO_DISPLAYED;
+import static android.security.KeyStore.getApplicationContext;
+
+import android.app.settings.SettingsEnums;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.hardware.face.FaceManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.view.View;
+import android.widget.Button;
+import android.widget.CompoundButton;
+
+import com.android.settings.R;
+import com.android.settings.Utils;
+import com.android.settings.biometrics.BiometricEnrollBase;
+import com.android.settings.password.ChooseLockSettingsHelper;
+
+import com.google.android.setupcompat.template.FooterBarMixin;
+import com.google.android.setupcompat.template.FooterButton;
+import com.google.android.setupcompat.util.WizardManagerHelper;
+import com.google.android.setupdesign.view.IllustrationVideoView;
+
+public class FaceEnrollEducation extends BiometricEnrollBase {
+
+    private static final String TAG = "FaceEducation";
+    private static final int ON = 1;
+    private static final int OFF = 0;
+    // 10 seconds.
+    private static final long FACE_ENROLL_EDUCATION_DELAY = 16000;
+
+    private FaceManager mFaceManager;
+    private FaceEnrollAccessibilityToggle mSwitchDiversity;
+
+    private IllustrationVideoView mIllustrationNormal;
+    private View mIllustrationAccessibility;
+    private Handler mHandler;
+
+    private CompoundButton.OnCheckedChangeListener mSwitchDiversityListener =
+            new CompoundButton.OnCheckedChangeListener() {
+                @Override
+                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+                    if (isChecked) {
+                        mIllustrationNormal.stop();
+                        mIllustrationNormal.setVisibility(View.INVISIBLE);
+                        mIllustrationAccessibility.setVisibility(View.VISIBLE);
+                    } else {
+                        mIllustrationNormal.setVisibility(View.VISIBLE);
+                        mIllustrationNormal.start();
+                        mIllustrationAccessibility.setVisibility(View.INVISIBLE);
+                    }
+                }
+            };
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.face_enroll_education);
+        getLayout().setHeaderText(R.string.security_settings_face_enroll_education_title);
+        setTitle(R.string.security_settings_face_enroll_education_title);
+        mHandler = new Handler();
+
+        mFaceManager = Utils.getFaceManagerOrNull(this);
+        final Button accessibilityButton = findViewById(R.id.accessibility_button);
+        accessibilityButton.setOnClickListener(view -> {
+            mSwitchDiversity.setChecked(true);
+            accessibilityButton.setVisibility(View.GONE);
+            mSwitchDiversity.setVisibility(View.VISIBLE);
+        });
+
+        mSwitchDiversity = findViewById(R.id.toggle_diversity);
+        mSwitchDiversity.setListener(mSwitchDiversityListener);
+
+        mIllustrationNormal = findViewById(R.id.illustration_normal);
+        mIllustrationAccessibility = findViewById(R.id.illustration_accessibility);
+
+        mFooterBarMixin = getLayout().getMixin(FooterBarMixin.class);
+        mFooterBarMixin.setSecondaryButton(
+                new FooterButton.Builder(this)
+                        .setText(R.string.security_settings_face_enroll_enrolling_skip)
+                        .setListener(this::onSkipButtonClick)
+                        .setButtonType(FooterButton.ButtonType.SKIP)
+                        .setTheme(R.style.SudGlifButton_Secondary)
+                        .build()
+        );
+
+        final FooterButton footerButton = new FooterButton.Builder(this)
+                .setText(R.string.wizard_next)
+                .setListener(this::onNextButtonClick)
+                .setButtonType(FooterButton.ButtonType.NEXT)
+                .setTheme(R.style.SudGlifButton_Primary)
+                .build();
+
+        mFooterBarMixin.setPrimaryButton(footerButton);
+        final Context context = getApplicationContext();
+        final boolean didDisplayEdu = Settings.Secure.getIntForUser(context.getContentResolver(),
+                FACE_UNLOCK_EDUCATION_INFO_DISPLAYED, OFF, mUserId) == ON;
+        if (!didDisplayEdu) {
+            Settings.Secure.putIntForUser(context.getContentResolver(),
+                    FACE_UNLOCK_EDUCATION_INFO_DISPLAYED, ON, mUserId);
+            footerButton.setEnabled(false);
+            mHandler.postDelayed(() -> {
+                footerButton.setEnabled(true);
+            }, FACE_ENROLL_EDUCATION_DELAY);
+        }
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        mSwitchDiversityListener.onCheckedChanged(mSwitchDiversity.getSwitch(),
+                mSwitchDiversity.isChecked());
+    }
+
+    @Override
+    protected void onNextButtonClick(View view) {
+        final Intent intent = new Intent();
+        if (mToken != null) {
+            intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, mToken);
+        }
+        if (mUserId != UserHandle.USER_NULL) {
+            intent.putExtra(Intent.EXTRA_USER_ID, mUserId);
+        }
+        final String flattenedString = getString(R.string.config_face_enroll);
+        if (!TextUtils.isEmpty(flattenedString)) {
+            ComponentName componentName = ComponentName.unflattenFromString(flattenedString);
+            intent.setComponent(componentName);
+        } else {
+            intent.setClass(this, FaceEnrollEnrolling.class);
+        }
+        intent.putExtra(EXTRA_KEY_REQUIRE_DIVERSITY, !mSwitchDiversity.isChecked());
+        WizardManagerHelper.copyWizardManagerExtras(getIntent(), intent);
+        startActivityForResult(intent, BIOMETRIC_FIND_SENSOR_REQUEST);
+    }
+
+    protected void onSkipButtonClick(View view) {
+        setResult(RESULT_SKIP);
+        finish();
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (requestCode == BIOMETRIC_FIND_SENSOR_REQUEST) {
+            setResult(resultCode);
+            finish();
+        }
+    }
+
+    @Override
+    public int getMetricsCategory() {
+        return SettingsEnums.FACE_ENROLL_INTRO;
+    }
+}
diff --git a/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java b/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java
index 6887d51..525c1a3 100644
--- a/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java
+++ b/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java
@@ -18,14 +18,9 @@
 
 import android.app.admin.DevicePolicyManager;
 import android.app.settings.SettingsEnums;
-import android.content.ComponentName;
 import android.content.Intent;
 import android.hardware.face.FaceManager;
 import android.os.Bundle;
-import android.text.TextUtils;
-import android.view.View;
-import android.widget.Button;
-import android.widget.CompoundButton;
 import android.widget.TextView;
 
 import com.android.settings.R;
@@ -38,51 +33,18 @@
 import com.google.android.setupcompat.template.FooterButton;
 import com.google.android.setupcompat.util.WizardManagerHelper;
 import com.google.android.setupdesign.span.LinkSpan;
-import com.google.android.setupdesign.view.IllustrationVideoView;
 
 public class FaceEnrollIntroduction extends BiometricEnrollIntroduction {
 
     private static final String TAG = "FaceIntro";
 
     private FaceManager mFaceManager;
-    private FaceEnrollAccessibilityToggle mSwitchDiversity;
-
-    private IllustrationVideoView mIllustrationNormal;
-    private View mIllustrationAccessibility;
-
-    private CompoundButton.OnCheckedChangeListener mSwitchDiversityListener =
-            new CompoundButton.OnCheckedChangeListener() {
-        @Override
-        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
-            if (isChecked) {
-                mIllustrationNormal.stop();
-                mIllustrationNormal.setVisibility(View.INVISIBLE);
-                mIllustrationAccessibility.setVisibility(View.VISIBLE);
-            } else {
-                mIllustrationNormal.setVisibility(View.VISIBLE);
-                mIllustrationNormal.start();
-                mIllustrationAccessibility.setVisibility(View.INVISIBLE);
-            }
-        }
-    };
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
         mFaceManager = Utils.getFaceManagerOrNull(this);
-        final Button accessibilityButton = findViewById(R.id.accessibility_button);
-        accessibilityButton.setOnClickListener(view -> {
-            mSwitchDiversity.setChecked(true);
-            accessibilityButton.setVisibility(View.GONE);
-            mSwitchDiversity.setVisibility(View.VISIBLE);
-        });
-
-        mSwitchDiversity = findViewById(R.id.toggle_diversity);
-        mSwitchDiversity.setListener(mSwitchDiversityListener);
-
-        mIllustrationNormal = findViewById(R.id.illustration_normal);
-        mIllustrationAccessibility = findViewById(R.id.illustration_accessibility);
 
         mFooterBarMixin = getLayout().getMixin(FooterBarMixin.class);
         if (WizardManagerHelper.isAnySetupWizard(getIntent())) {
@@ -116,13 +78,6 @@
     }
 
     @Override
-    protected void onResume() {
-        super.onResume();
-        mSwitchDiversityListener.onCheckedChanged(mSwitchDiversity.getSwitch(),
-                mSwitchDiversity.isChecked());
-     }
-
-    @Override
     protected boolean isDisabledByAdmin() {
         return RestrictedLockUtilsInternal.checkIfKeyguardFeaturesDisabled(
                 this, DevicePolicyManager.KEYGUARD_DISABLE_FACE, mUserId) != null;
@@ -200,16 +155,7 @@
 
     @Override
     protected Intent getEnrollingIntent() {
-        final String flattenedString = getString(R.string.config_face_enroll);
-        final Intent intent = new Intent();
-        if (!TextUtils.isEmpty(flattenedString)) {
-            ComponentName componentName = ComponentName.unflattenFromString(flattenedString);
-            intent.setComponent(componentName);
-
-        } else {
-            intent.setClass(this, FaceEnrollEnrolling.class);
-        }
-        intent.putExtra(EXTRA_KEY_REQUIRE_DIVERSITY, !mSwitchDiversity.isChecked());
+        Intent intent = new Intent(this, FaceEnrollEducation.class);
         WizardManagerHelper.copyWizardManagerExtras(getIntent(), intent);
         return intent;
     }
diff --git a/src/com/android/settings/core/SettingsUIDeviceConfig.java b/src/com/android/settings/core/SettingsUIDeviceConfig.java
index b7aa281..8c85c82 100644
--- a/src/com/android/settings/core/SettingsUIDeviceConfig.java
+++ b/src/com/android/settings/core/SettingsUIDeviceConfig.java
@@ -33,4 +33,9 @@
      * {@code true} if near by device suggestion is enabled in connected device page
      */
     public static final String BT_NEAR_BY_SUGGESTION_ENABLED = "bt_near_by_suggestion_enabled";
+
+    /**
+     * {@code true} whether or not event_log for generic actions is enabled. Default is true.
+     */
+    public static final String GENERIC_EVENT_LOGGING_ENABLED = "event_logging_enabled";
 }
diff --git a/src/com/android/settings/core/instrumentation/SettingsEventLogWriter.java b/src/com/android/settings/core/instrumentation/SettingsEventLogWriter.java
new file mode 100644
index 0000000..a58555f
--- /dev/null
+++ b/src/com/android/settings/core/instrumentation/SettingsEventLogWriter.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2019 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.core.instrumentation;
+
+import android.content.Context;
+import android.provider.DeviceConfig;
+
+import com.android.settings.core.SettingsUIDeviceConfig;
+import com.android.settingslib.core.instrumentation.EventLogWriter;
+
+public class SettingsEventLogWriter extends EventLogWriter {
+
+    @Override
+    public void visible(Context context, int source, int category) {
+        if (shouldDisableGenericEventLogging()) {
+            return;
+        }
+        super.visible(context, source, category);
+    }
+
+    @Override
+    public void hidden(Context context, int category) {
+        if (shouldDisableGenericEventLogging()) {
+            return;
+        }
+        super.hidden(context, category);
+    }
+
+    @Override
+    public void action(Context context, int category, String pkg) {
+        if (shouldDisableGenericEventLogging()) {
+            return;
+        }
+        super.action(context, category, pkg);
+    }
+
+    @Override
+    public void action(Context context, int category, int value) {
+        if (shouldDisableGenericEventLogging()) {
+            return;
+        }
+        super.action(context, category, value);
+    }
+
+    @Override
+    public void action(Context context, int category, boolean value) {
+        if (shouldDisableGenericEventLogging()) {
+            return;
+        }
+        super.action(context, category, value);
+    }
+
+    private static boolean shouldDisableGenericEventLogging() {
+        return !DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SETTINGS_UI,
+                SettingsUIDeviceConfig.GENERIC_EVENT_LOGGING_ENABLED, true /* default */);
+    }
+}
diff --git a/src/com/android/settings/core/instrumentation/SettingsMetricsFeatureProvider.java b/src/com/android/settings/core/instrumentation/SettingsMetricsFeatureProvider.java
index ec05757..01927fd 100644
--- a/src/com/android/settings/core/instrumentation/SettingsMetricsFeatureProvider.java
+++ b/src/com/android/settings/core/instrumentation/SettingsMetricsFeatureProvider.java
@@ -17,14 +17,29 @@
 package com.android.settings.core.instrumentation;
 
 import android.content.Context;
+import android.util.Log;
+import android.util.Pair;
 
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 public class SettingsMetricsFeatureProvider extends MetricsFeatureProvider {
+    private static final String TAG = "SettingsMetricsFeature";
+
     @Override
     protected void installLogWriters() {
-        super.installLogWriters();
         mLoggerWriters.add(new StatsLogWriter());
+        mLoggerWriters.add(new SettingsEventLogWriter());
         mLoggerWriters.add(new SettingsIntelligenceLogWriter());
     }
+
+    /**
+     * @deprecated Use {@link #action(int, int, int, String, int)} instead.
+     */
+    @Deprecated
+    @Override
+    public void action(Context context, int category, Pair<Integer, Object>... taggedData) {
+        Log.w(TAG, "action(Pair<Integer, Object>... taggedData) is deprecated, "
+                + "Use action(int, int, int, String, int) instead.");
+        super.action(context, category, taggedData);
+    }
 }
diff --git a/src/com/android/settings/datausage/DataUsageUtils.java b/src/com/android/settings/datausage/DataUsageUtils.java
index 283c84f..68657a4 100644
--- a/src/com/android/settings/datausage/DataUsageUtils.java
+++ b/src/com/android/settings/datausage/DataUsageUtils.java
@@ -178,9 +178,10 @@
      * Returns the default network template based on the availability of mobile data, Wifi. Returns
      * ethernet template if both mobile data and Wifi are not available.
      */
-    static NetworkTemplate getDefaultTemplate(Context context, int defaultSubId) {
+    public static NetworkTemplate getDefaultTemplate(Context context, int defaultSubId) {
         if (hasMobileData(context) && defaultSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
-            TelephonyManager telephonyManager = TelephonyManager.from(context);
+            TelephonyManager telephonyManager = TelephonyManager.from(context)
+                    .createForSubscriptionId(defaultSubId);
             NetworkTemplate mobileAll = NetworkTemplate.buildTemplateMobileAll(
                     telephonyManager.getSubscriberId(defaultSubId));
             return NetworkTemplate.normalize(mobileAll,
diff --git a/src/com/android/settings/deviceinfo/StorageWizardBase.java b/src/com/android/settings/deviceinfo/StorageWizardBase.java
index 3873389..92afa56 100644
--- a/src/com/android/settings/deviceinfo/StorageWizardBase.java
+++ b/src/com/android/settings/deviceinfo/StorageWizardBase.java
@@ -187,6 +187,14 @@
         mNext.setVisibility(View.VISIBLE);
     }
 
+    protected void setBackButtonVisibility(int visible) {
+        mBack.setVisibility(visible);
+    }
+
+    protected void setNextButtonVisibility(int visible) {
+        mNext.setVisibility(visible);
+    }
+
     protected void setIcon(int resId) {
         final GlifLayout layout = getGlifLayout();
         final Drawable icon = getDrawable(resId).mutate();
diff --git a/src/com/android/settings/deviceinfo/StorageWizardFormatProgress.java b/src/com/android/settings/deviceinfo/StorageWizardFormatProgress.java
index 1e8c169..88968b3 100644
--- a/src/com/android/settings/deviceinfo/StorageWizardFormatProgress.java
+++ b/src/com/android/settings/deviceinfo/StorageWizardFormatProgress.java
@@ -30,6 +30,7 @@
 import android.os.storage.StorageManager;
 import android.os.storage.VolumeInfo;
 import android.util.Log;
+import android.view.View;
 import android.widget.Toast;
 
 import com.android.settings.R;
@@ -59,7 +60,8 @@
 
         setHeaderText(R.string.storage_wizard_format_progress_title, getDiskShortDescription());
         setBodyText(R.string.storage_wizard_format_progress_body, getDiskDescription());
-
+        setBackButtonVisibility(View.INVISIBLE);
+        setNextButtonVisibility(View.INVISIBLE);
         mTask = (PartitionTask) getLastCustomNonConfigurationInstance();
         if (mTask == null) {
             mTask = new PartitionTask();
diff --git a/src/com/android/settings/deviceinfo/StorageWizardInit.java b/src/com/android/settings/deviceinfo/StorageWizardInit.java
index 4f9c5e7..426395c 100644
--- a/src/com/android/settings/deviceinfo/StorageWizardInit.java
+++ b/src/com/android/settings/deviceinfo/StorageWizardInit.java
@@ -51,7 +51,7 @@
         mInternal = requireViewById(R.id.storage_wizard_init_internal);
 
         setBackButtonText(R.string.storage_wizard_init_v2_later);
-
+        setNextButtonVisibility(View.INVISIBLE);
         if (!mDisk.isAdoptable()) {
             // If not adoptable, we only have one choice
             mInternal.setEnabled(false);
diff --git a/src/com/android/settings/deviceinfo/StorageWizardMigrateProgress.java b/src/com/android/settings/deviceinfo/StorageWizardMigrateProgress.java
index 60f3cb5..b6f2a8d 100644
--- a/src/com/android/settings/deviceinfo/StorageWizardMigrateProgress.java
+++ b/src/com/android/settings/deviceinfo/StorageWizardMigrateProgress.java
@@ -28,6 +28,7 @@
 import android.os.Handler;
 import android.os.storage.DiskInfo;
 import android.util.Log;
+import android.view.View;
 import android.widget.Toast;
 
 import com.android.settings.R;
@@ -51,7 +52,8 @@
         setIcon(R.drawable.ic_swap_horiz);
         setHeaderText(R.string.storage_wizard_migrate_progress_v2_title);
         setAuxChecklist();
-
+        setBackButtonVisibility(View.INVISIBLE);
+        setNextButtonVisibility(View.INVISIBLE);
         // Register for updates and push through current status
         getPackageManager().registerMoveCallback(mCallback, new Handler());
         mCallback.onStatusChanged(mMoveId, getPackageManager().getMoveStatus(mMoveId), -1);
diff --git a/src/com/android/settings/deviceinfo/StorageWizardMoveConfirm.java b/src/com/android/settings/deviceinfo/StorageWizardMoveConfirm.java
index 10b78af..8dc878e 100644
--- a/src/com/android/settings/deviceinfo/StorageWizardMoveConfirm.java
+++ b/src/com/android/settings/deviceinfo/StorageWizardMoveConfirm.java
@@ -73,6 +73,7 @@
         setBodyText(R.string.storage_wizard_move_confirm_body, appName, volumeName);
 
         setNextButtonText(R.string.move_app);
+        setBackButtonVisibility(View.INVISIBLE);
     }
 
     @Override
diff --git a/src/com/android/settings/deviceinfo/StorageWizardMoveProgress.java b/src/com/android/settings/deviceinfo/StorageWizardMoveProgress.java
index 27fa9be..1966c95 100644
--- a/src/com/android/settings/deviceinfo/StorageWizardMoveProgress.java
+++ b/src/com/android/settings/deviceinfo/StorageWizardMoveProgress.java
@@ -26,6 +26,7 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.util.Log;
+import android.view.View;
 import android.widget.Toast;
 
 import com.android.settings.R;
@@ -49,7 +50,8 @@
         setIcon(R.drawable.ic_swap_horiz);
         setHeaderText(R.string.storage_wizard_move_progress_title, appName);
         setBodyText(R.string.storage_wizard_move_progress_body, volumeName, appName);
-
+        setBackButtonVisibility(View.INVISIBLE);
+        setNextButtonVisibility(View.INVISIBLE);
         // Register for updates and push through current status
         getPackageManager().registerMoveCallback(mCallback, new Handler());
         mCallback.onStatusChanged(mMoveId, getPackageManager().getMoveStatus(mMoveId), -1);
diff --git a/src/com/android/settings/deviceinfo/StorageWizardReady.java b/src/com/android/settings/deviceinfo/StorageWizardReady.java
index fdb8d8a..813bcc6 100644
--- a/src/com/android/settings/deviceinfo/StorageWizardReady.java
+++ b/src/com/android/settings/deviceinfo/StorageWizardReady.java
@@ -50,6 +50,7 @@
         }
 
         setNextButtonText(R.string.done);
+        setBackButtonVisibility(View.INVISIBLE);
     }
 
     @Override
diff --git a/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java b/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java
index 95f913e..c18ec78 100644
--- a/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java
+++ b/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java
@@ -19,6 +19,7 @@
 import static android.content.Context.CARRIER_CONFIG_SERVICE;
 import static android.content.Context.EUICC_SERVICE;
 import static android.content.Context.TELEPHONY_SERVICE;
+import static android.content.Context.TELEPHONY_SUBSCRIPTION_SERVICE;
 
 import android.Manifest;
 import android.content.BroadcastReceiver;
@@ -36,6 +37,7 @@
 import android.telephony.SignalStrength;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
+import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
 import android.telephony.TelephonyManager;
 import android.telephony.euicc.EuiccManager;
 import android.text.BidiFormatter;
@@ -53,8 +55,6 @@
 import com.android.settingslib.core.lifecycle.events.OnPause;
 import com.android.settingslib.core.lifecycle.events.OnResume;
 
-import java.util.List;
-
 public class SimStatusDialogController implements LifecycleObserver, OnResume, OnPause {
 
     private final static String TAG = "SimStatusDialogCtrl";
@@ -98,9 +98,21 @@
             "com.android.cellbroadcastreceiver.GET_LATEST_CB_AREA_INFO";
     private final static String CELL_BROADCAST_RECEIVER_APP = "com.android.cellbroadcastreceiver";
 
+    private final OnSubscriptionsChangedListener mOnSubscriptionsChangedListener =
+            new OnSubscriptionsChangedListener() {
+                @Override
+                public void onSubscriptionsChanged() {
+                    mSubscriptionInfo = mSubscriptionManager.getActiveSubscriptionInfo(
+                            mSubscriptionInfo.getSubscriptionId());
+                    updateNetworkProvider();
+                }
+            };
+
+    private SubscriptionInfo mSubscriptionInfo;
+
     private final SimStatusDialogFragment mDialog;
-    private final SubscriptionInfo mSubscriptionInfo;
     private final TelephonyManager mTelephonyManager;
+    private final SubscriptionManager mSubscriptionManager;
     private final CarrierConfigManager mCarrierConfigManager;
     private final EuiccManager mEuiccManager;
     private final Resources mRes;
@@ -134,11 +146,10 @@
         mDialog = dialog;
         mContext = dialog.getContext();
         mSubscriptionInfo = getPhoneSubscriptionInfo(slotId);
-        mTelephonyManager = (TelephonyManager) mContext.getSystemService(
-                TELEPHONY_SERVICE);
-        mCarrierConfigManager = (CarrierConfigManager) mContext.getSystemService(
-                CARRIER_CONFIG_SERVICE);
-        mEuiccManager = (EuiccManager) mContext.getSystemService(EUICC_SERVICE);
+        mTelephonyManager =  mContext.getSystemService(TelephonyManager.class);
+        mCarrierConfigManager =  mContext.getSystemService(CarrierConfigManager.class);
+        mEuiccManager =  mContext.getSystemService(EuiccManager.class);
+        mSubscriptionManager = mContext.getSystemService(SubscriptionManager.class);
 
         mRes = mContext.getResources();
 
@@ -155,9 +166,9 @@
         }
 
         mPhoneStateListener = getPhoneStateListener();
+        updateNetworkProvider();
 
         final ServiceState serviceState = getCurrentServiceState();
-        updateNetworkProvider(serviceState);
         updatePhoneNumber();
         updateLatestAreaInfo();
         updateServiceState(serviceState);
@@ -179,6 +190,7 @@
                 PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
                         | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
                         | PhoneStateListener.LISTEN_SERVICE_STATE);
+        mSubscriptionManager.addOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
 
         if (mShowLatestAreaInfo) {
             mContext.registerReceiver(mAreaInfoReceiver,
@@ -198,6 +210,7 @@
             return;
         }
 
+        mSubscriptionManager.removeOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
         mTelephonyManager.createForSubscriptionId(mSubscriptionInfo.getSubscriptionId())
                 .listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
 
@@ -206,8 +219,10 @@
         }
     }
 
-    private void updateNetworkProvider(ServiceState serviceState) {
-        mDialog.setText(NETWORK_PROVIDER_VALUE_ID, serviceState.getOperatorAlphaLong());
+    private void updateNetworkProvider() {
+        final CharSequence carrierName =
+                mSubscriptionInfo != null ? mSubscriptionInfo.getCarrierName() : null;
+        mDialog.setText(NETWORK_PROVIDER_VALUE_ID, carrierName);
     }
 
     private void updatePhoneNumber() {
@@ -441,7 +456,7 @@
 
             @Override
             public void onServiceStateChanged(ServiceState serviceState) {
-                updateNetworkProvider(serviceState);
+                updateNetworkProvider();
                 updateServiceState(serviceState);
                 updateRoamingStatus(serviceState);
             }
diff --git a/src/com/android/settings/display/AdaptiveSleepPreferenceController.java b/src/com/android/settings/display/AdaptiveSleepPreferenceController.java
index 6aa7187..fab3efa 100644
--- a/src/com/android/settings/display/AdaptiveSleepPreferenceController.java
+++ b/src/com/android/settings/display/AdaptiveSleepPreferenceController.java
@@ -20,9 +20,6 @@
 import android.content.pm.PackageManager;
 import android.provider.Settings;
 
-import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
-
 import com.android.settings.R;
 import com.android.settings.core.TogglePreferenceController;
 
@@ -60,10 +57,12 @@
     @Override
     @AvailabilityStatus
     public int getAvailabilityStatus() {
-        return mContext.getResources().getBoolean(
-                com.android.internal.R.bool.config_adaptive_sleep_available)
-                ? AVAILABLE
-                : UNSUPPORTED_ON_DEVICE;
+        final boolean supportedOnDevice =  mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_adaptive_sleep_available);
+        if (!supportedOnDevice) {
+            return UNSUPPORTED_ON_DEVICE;
+        }
+        return hasSufficientPermissions ? AVAILABLE : DISABLED_DEPENDENT_SETTING;
     }
 
     @Override
@@ -77,15 +76,4 @@
                 ? R.string.adaptive_sleep_summary_on
                 : R.string.adaptive_sleep_summary_off);
     }
-
-    @Override
-    public void displayPreference(PreferenceScreen screen) {
-        super.displayPreference(screen);
-        final Preference preference = screen.findPreference(SYSTEM_KEY);
-
-        if (preference != null) {
-            preference.setEnabled(hasSufficientPermissions);
-        }
-
-    }
 }
diff --git a/src/com/android/settings/display/DisplayWhiteBalancePreferenceController.java b/src/com/android/settings/display/DisplayWhiteBalancePreferenceController.java
index dc569aa..6fc0b0e 100644
--- a/src/com/android/settings/display/DisplayWhiteBalancePreferenceController.java
+++ b/src/com/android/settings/display/DisplayWhiteBalancePreferenceController.java
@@ -13,17 +13,34 @@
  */
 package com.android.settings.display;
 
+import android.app.ActivityManager;
+import android.content.ContentResolver;
 import android.content.Context;
+import android.database.ContentObserver;
 import android.hardware.display.ColorDisplayManager;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Looper;
 import android.os.UserHandle;
 import android.provider.Settings.Secure;
+import android.provider.Settings.System;
 import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.OnStart;
+import com.android.settingslib.core.lifecycle.events.OnStop;
 
 import com.android.settings.core.TogglePreferenceController;
 
-public class DisplayWhiteBalancePreferenceController extends TogglePreferenceController {
+public class DisplayWhiteBalancePreferenceController extends TogglePreferenceController
+    implements LifecycleObserver, OnStart, OnStop {
 
     private ColorDisplayManager mColorDisplayManager;
+    @VisibleForTesting
+    ContentObserver mContentObserver;
+    private Preference mPreference;
 
     public DisplayWhiteBalancePreferenceController(Context context, String key) {
         super(context, key);
@@ -31,12 +48,8 @@
 
     @Override
     public int getAvailabilityStatus() {
-        // Display white balance is only valid in linear light space. COLOR_MODE_SATURATED implies
-        // unmanaged color mode, and hence unknown color processing conditions.
-        return ColorDisplayManager.isDisplayWhiteBalanceAvailable(mContext) &&
-                getColorDisplayManager().getColorMode() !=
-                        ColorDisplayManager.COLOR_MODE_SATURATED ?
-                AVAILABLE : DISABLED_FOR_USER;
+        return getColorDisplayManager().isDisplayWhiteBalanceAvailable(mContext) ?
+            AVAILABLE : DISABLED_FOR_USER;
     }
 
     @Override
@@ -49,6 +62,50 @@
         return getColorDisplayManager().setDisplayWhiteBalanceEnabled(isChecked);
     }
 
+    @Override
+    public void onStart() {
+        if (!isAvailable()) {
+            return;
+        }
+
+        final ContentResolver cr = mContext.getContentResolver();
+        mContentObserver = new ContentObserver(new Handler(Looper.getMainLooper())) {
+            @Override
+            public void onChange(boolean selfChange, Uri uri) {
+                super.onChange(selfChange, uri);
+                updateVisibility();
+            }
+        };
+        cr.registerContentObserver(
+                Secure.getUriFor(Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED),
+                false /* notifyForDescendants */, mContentObserver,
+                ActivityManager.getCurrentUser());
+        cr.registerContentObserver(
+                Secure.getUriFor(Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED),
+                false /* notifyForDescendants */, mContentObserver,
+                ActivityManager.getCurrentUser());
+        cr.registerContentObserver(
+                System.getUriFor(System.DISPLAY_COLOR_MODE),
+                false /* notifyForDescendants */, mContentObserver,
+                ActivityManager.getCurrentUser());
+
+        updateVisibility();
+    }
+
+    @Override
+    public void onStop() {
+        if (mContentObserver != null) {
+            mContext.getContentResolver().unregisterContentObserver(mContentObserver);
+            mContentObserver = null;
+        }
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        mPreference = screen.findPreference(getPreferenceKey());
+    }
+
     @VisibleForTesting
     ColorDisplayManager getColorDisplayManager() {
         if (mColorDisplayManager == null) {
@@ -56,4 +113,17 @@
         }
         return mColorDisplayManager;
     }
+
+    @VisibleForTesting
+    void updateVisibility() {
+        if (mPreference != null) {
+            ColorDisplayManager cdm = getColorDisplayManager();
+
+            // Display white balance is only valid in linear light space. COLOR_MODE_SATURATED
+            // implies unmanaged color mode, and hence unknown color processing conditions.
+            // We also disallow display white balance when color accessibility features are enabled.
+            mPreference.setVisible(cdm.getColorMode() != ColorDisplayManager.COLOR_MODE_SATURATED &&
+                    !cdm.areAccessibilityTransformsEnabled(mContext));
+        }
+    }
 }
diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
index 85a0879..880255b 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
@@ -378,6 +378,9 @@
 
     @VisibleForTesting
     void restartBatteryInfoLoader() {
+        if (getContext() == null) {
+            return;
+        }
         getLoaderManager().restartLoader(BATTERY_INFO_LOADER, Bundle.EMPTY,
                 mBatteryInfoLoaderCallbacks);
         if (mPowerFeatureProvider.isEstimateDebugEnabled()) {
diff --git a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSeekBarController.java b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSeekBarController.java
index a936e99..5442e7d 100644
--- a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSeekBarController.java
+++ b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSeekBarController.java
@@ -99,10 +99,15 @@
         }
     }
 
+    /**
+     * Adds the seekbar to the end of the provided preference screen
+     *
+     * @param screen The preference screen to add the seekbar to
+     */
     public void addToScreen(PreferenceScreen screen) {
         // makes sure it gets added after the preferences if called due to first time battery
         // saver message
-        mSeekBarPreference.setOrder(5);
+        mSeekBarPreference.setOrder(100);
         screen.addPreference(mSeekBarPreference);
     }
 }
diff --git a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSettings.java b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSettings.java
index 6553c60..31ee278 100644
--- a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSettings.java
+++ b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSettings.java
@@ -64,6 +64,7 @@
     final ContentObserver mSettingsObserver = new ContentObserver(new Handler()) {
         @Override
         public void onChange(boolean selfChange, Uri uri) {
+            getPreferenceScreen().removeAll();
             updateCandidates();
         }
     };
diff --git a/src/com/android/settings/gestures/GlobalActionsPanelPreferenceController.java b/src/com/android/settings/gestures/GlobalActionsPanelPreferenceController.java
new file mode 100644
index 0000000..b980499
--- /dev/null
+++ b/src/com/android/settings/gestures/GlobalActionsPanelPreferenceController.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2019 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.gestures;
+
+import android.content.Context;
+import android.provider.Settings;
+import android.text.TextUtils;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+public class GlobalActionsPanelPreferenceController extends GesturePreferenceController {
+    private static final String PREF_KEY_VIDEO = "global_actions_panel_video";
+
+    @VisibleForTesting
+    protected static final String ENABLED_SETTING = Settings.Secure.GLOBAL_ACTIONS_PANEL_ENABLED;
+    @VisibleForTesting
+    protected static final String AVAILABLE_SETTING =
+            Settings.Secure.GLOBAL_ACTIONS_PANEL_AVAILABLE;
+
+    @VisibleForTesting
+    protected static final String TOGGLE_KEY = "gesture_global_actions_panel_switch";
+
+    public GlobalActionsPanelPreferenceController(Context context, String key) {
+        super(context, key);
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        int enabled = Settings.Secure.getInt(mContext.getContentResolver(), AVAILABLE_SETTING, 0);
+        return enabled == 1 ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
+    }
+
+    @Override
+    public boolean setChecked(boolean isChecked) {
+        return Settings.Secure.putInt(mContext.getContentResolver(), ENABLED_SETTING,
+                isChecked ? 1 : 0);
+    }
+
+    @Override
+    protected String getVideoPrefKey() {
+        return PREF_KEY_VIDEO;
+    }
+
+    @Override
+    public boolean isSliceable() {
+        return TextUtils.equals(getPreferenceKey(), TOGGLE_KEY);
+    }
+
+    @Override
+    public boolean isChecked() {
+        int enabled = Settings.Secure.getInt(mContext.getContentResolver(), ENABLED_SETTING, 0);
+        return enabled == 1;
+    }
+}
diff --git a/src/com/android/settings/gestures/GlobalActionsPanelSettings.java b/src/com/android/settings/gestures/GlobalActionsPanelSettings.java
new file mode 100644
index 0000000..fe9a9e8
--- /dev/null
+++ b/src/com/android/settings/gestures/GlobalActionsPanelSettings.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2019 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.gestures;
+
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+import android.provider.SearchIndexableResource;
+
+import com.android.settings.R;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settingslib.search.SearchIndexable;
+
+import java.util.Arrays;
+import java.util.List;
+
+@SearchIndexable
+public class GlobalActionsPanelSettings extends DashboardFragment {
+
+    private static final String TAG = "GlobalActionsPanelSettings";
+
+    @Override
+    public int getMetricsCategory() {
+        return SettingsEnums.GLOBAL_ACTIONS_PANEL_SETTINGS;
+    }
+
+    @Override
+    protected String getLogTag() {
+        return TAG;
+    }
+
+    @Override
+    protected int getPreferenceScreenResId() {
+        return R.xml.global_actions_panel_settings;
+    }
+
+    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+        new BaseSearchIndexProvider() {
+            @Override
+            public List<SearchIndexableResource> getXmlResourcesToIndex(
+                    Context context, boolean enabled) {
+                final SearchIndexableResource sir = new SearchIndexableResource(context);
+                sir.xmlResId = R.xml.global_actions_panel_settings;
+                return Arrays.asList(sir);
+            }
+        };
+}
diff --git a/src/com/android/settings/gestures/SystemNavigationEdgeToEdgePreferenceController.java b/src/com/android/settings/gestures/SystemNavigationEdgeToEdgePreferenceController.java
index 337ad2e..0c5adc4 100644
--- a/src/com/android/settings/gestures/SystemNavigationEdgeToEdgePreferenceController.java
+++ b/src/com/android/settings/gestures/SystemNavigationEdgeToEdgePreferenceController.java
@@ -39,7 +39,7 @@
     @VisibleForTesting
     public SystemNavigationEdgeToEdgePreferenceController(Context context,
             IOverlayManager overlayManager, String key) {
-        super(context, overlayManager, key);
+        super(context, overlayManager, key, NAV_BAR_MODE_GESTURAL_OVERLAY);
     }
 
     @Override
diff --git a/src/com/android/settings/gestures/SystemNavigationLegacyPreferenceController.java b/src/com/android/settings/gestures/SystemNavigationLegacyPreferenceController.java
index 728c5df..7ac9a03 100644
--- a/src/com/android/settings/gestures/SystemNavigationLegacyPreferenceController.java
+++ b/src/com/android/settings/gestures/SystemNavigationLegacyPreferenceController.java
@@ -39,7 +39,7 @@
     @VisibleForTesting
     public SystemNavigationLegacyPreferenceController(Context context,
             IOverlayManager overlayManager, String key) {
-        super(context, overlayManager, key);
+        super(context, overlayManager, key, NAV_BAR_MODE_3BUTTON_OVERLAY);
     }
 
     @Override
diff --git a/src/com/android/settings/gestures/SystemNavigationPreferenceController.java b/src/com/android/settings/gestures/SystemNavigationPreferenceController.java
index f2c8252..664e7bb 100644
--- a/src/com/android/settings/gestures/SystemNavigationPreferenceController.java
+++ b/src/com/android/settings/gestures/SystemNavigationPreferenceController.java
@@ -52,16 +52,18 @@
 
     protected final IOverlayManager mOverlayManager;
     protected PreferenceScreen mPreferenceScreen;
+    private final String mOverlayPackage;
 
     public SystemNavigationPreferenceController(Context context, IOverlayManager overlayManager,
-            String key) {
+            String key, String overlayPackage) {
         super(context, key);
         mOverlayManager = overlayManager;
+        mOverlayPackage = overlayPackage;
     }
 
     @Override
     public int getAvailabilityStatus() {
-        return isGestureAvailable(mContext) ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
+        return isGestureAvailable(mContext, mOverlayPackage) ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
     }
 
     @Override
@@ -105,23 +107,43 @@
         return PREF_KEY_VIDEO;
     }
 
+
     static boolean isGestureAvailable(Context context) {
+        return isGestureAvailable(context, null /* overlayPackage */);
+    }
+
+    static boolean isGestureAvailable(Context context, String overlayPackage) {
+        // Skip if the swipe up settings are not available
         if (!context.getResources().getBoolean(
                 com.android.internal.R.bool.config_swipe_up_gesture_setting_available)) {
             return false;
         }
 
+        // Skip if the recents component is not defined
         final ComponentName recentsComponentName = ComponentName.unflattenFromString(
                 context.getString(com.android.internal.R.string.config_recentsComponentName));
         if (recentsComponentName == null) {
             return false;
         }
+
+        // Skip if the overview proxy service exists
+        final PackageManager pm = context.getPackageManager();
         final Intent quickStepIntent = new Intent(ACTION_QUICKSTEP)
                 .setPackage(recentsComponentName.getPackageName());
-        if (context.getPackageManager().resolveService(quickStepIntent,
-                PackageManager.MATCH_SYSTEM_ONLY) == null) {
+        if (pm.resolveService(quickStepIntent, PackageManager.MATCH_SYSTEM_ONLY) == null) {
             return false;
         }
+
+        // Skip if the required overlay package is defined but doesn't exist
+        if (overlayPackage != null) {
+            try {
+                return pm.getPackageInfo(overlayPackage, 0 /* flags */) != null;
+            } catch (PackageManager.NameNotFoundException e) {
+                // Not found, just return unavailable
+                return false;
+            }
+        }
+
         return true;
     }
 
diff --git a/src/com/android/settings/gestures/SystemNavigationSwipeUpPreferenceController.java b/src/com/android/settings/gestures/SystemNavigationSwipeUpPreferenceController.java
index cf2886f..592b231 100644
--- a/src/com/android/settings/gestures/SystemNavigationSwipeUpPreferenceController.java
+++ b/src/com/android/settings/gestures/SystemNavigationSwipeUpPreferenceController.java
@@ -39,7 +39,7 @@
     @VisibleForTesting
     public SystemNavigationSwipeUpPreferenceController(Context context,
             IOverlayManager overlayManager, String key) {
-        super(context, overlayManager, key);
+        super(context, overlayManager, key, NAV_BAR_MODE_2BUTTON_OVERLAY);
     }
 
     @Override
diff --git a/src/com/android/settings/homepage/SettingsHomepageActivity.java b/src/com/android/settings/homepage/SettingsHomepageActivity.java
index 6d16d7f..e767664 100644
--- a/src/com/android/settings/homepage/SettingsHomepageActivity.java
+++ b/src/com/android/settings/homepage/SettingsHomepageActivity.java
@@ -42,8 +42,11 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        updateWindowProperties();
         setContentView(R.layout.settings_homepage_container);
+        final View root = findViewById(R.id.settings_homepage_container);
+        root.setSystemUiVisibility(
+                View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
+
         setHomepageContainerPaddingTop();
 
         final Toolbar toolbar = findViewById(R.id.search_action_bar);
@@ -76,29 +79,15 @@
         fragmentTransaction.commit();
     }
 
-    private void updateWindowProperties() {
-        final View decorView = getWindow().getDecorView();
-        decorView.setSystemUiVisibility(
-                decorView.getSystemUiVisibility() |
-                        View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
-                        View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
-        );
-
-        getWindow().setStatusBarColor(getColor(R.color.homepage_status_bar_color));
-    }
-
     @VisibleForTesting
     void setHomepageContainerPaddingTop() {
         final View view = this.findViewById(R.id.homepage_container);
 
-        final int statusBarHeight = getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.status_bar_height);
         final int searchBarHeight = getResources().getDimensionPixelSize(R.dimen.search_bar_height);
         final int searchBarMargin = getResources().getDimensionPixelSize(R.dimen.search_bar_margin);
 
-        // The top padding is the height of status bar + height of action bar(48dp) + top/bottom
-        // margins(16dp)
-        final int paddingTop = statusBarHeight + searchBarHeight + searchBarMargin * 2;
+        // The top padding is the height of action bar(48dp) + top/bottom margins(16dp)
+        final int paddingTop = searchBarHeight + searchBarMargin * 2;
         view.setPadding(0 /* left */, paddingTop, 0 /* right */, 0 /* bottom */);
     }
 }
\ No newline at end of file
diff --git a/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java b/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java
index 9898834..b83a712 100644
--- a/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java
+++ b/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java
@@ -110,7 +110,12 @@
             mSliceLiveDataMap.put(uri, sliceLiveData);
         }
 
+        final View swipeBackground = holder.itemView.findViewById(R.id.dismissal_swipe_background);
         sliceLiveData.removeObservers(mLifecycleOwner);
+        // set the background to GONE in case the holder is reused.
+        if (swipeBackground != null) {
+            swipeBackground.setVisibility(View.GONE);
+        }
         sliceLiveData.observe(mLifecycleOwner, slice -> {
             if (slice == null) {
                 Log.w(TAG, "Slice is null");
@@ -137,6 +142,9 @@
                 default:
                     mFullCardHelper.bindView(holder, card, slice);
             }
+            if (swipeBackground != null) {
+                swipeBackground.setVisibility(View.VISIBLE);
+            }
         });
 
         switch (holder.getItemViewType()) {
diff --git a/src/com/android/settings/media/MediaOutputSlice.java b/src/com/android/settings/media/MediaOutputSlice.java
index dee5d62..96f8bc3 100644
--- a/src/com/android/settings/media/MediaOutputSlice.java
+++ b/src/com/android/settings/media/MediaOutputSlice.java
@@ -90,10 +90,13 @@
         final List<MediaDevice> devices = getMediaDevices();
 
         final MediaDevice connectedDevice = getWorker().getCurrentConnectedMediaDevice();
-        listBuilder.addRow(getActiveDeviceHeaderRow(connectedDevice));
+        if (connectedDevice != null) {
+            listBuilder.addRow(getActiveDeviceHeaderRow(connectedDevice));
+        }
 
         for (MediaDevice device : devices) {
-            if (!TextUtils.equals(connectedDevice.getId(), device.getId())) {
+            if (connectedDevice == null
+                    || !TextUtils.equals(connectedDevice.getId(), device.getId())) {
                 listBuilder.addRow(getMediaDeviceRow(device));
             }
         }
diff --git a/src/com/android/settings/network/MobileDataEnabledListener.java b/src/com/android/settings/network/MobileDataEnabledListener.java
new file mode 100644
index 0000000..8344f88
--- /dev/null
+++ b/src/com/android/settings/network/MobileDataEnabledListener.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2019 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.network;
+
+import android.content.Context;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.provider.Settings;
+import android.telephony.SubscriptionManager;
+
+/** Helper class to listen for changes in the enabled state of mobile data. */
+public class MobileDataEnabledListener extends ContentObserver {
+    private Context mContext;
+    private Client mClient;
+    private int mSubId;
+
+    public interface Client {
+        void onMobileDataEnabledChange();
+    }
+
+    public MobileDataEnabledListener(Context context, Client client) {
+        super(new Handler());
+        mContext = context;
+        mClient = client;
+        mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+    }
+
+    /** Starts listening to changes in the enabled state for data on the given subscription id. */
+    public void start(int subId) {
+        mSubId = subId;
+        Uri uri;
+        if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+            uri = Settings.Global.getUriFor(Settings.Global.MOBILE_DATA);
+        }  else {
+            uri = Settings.Global.getUriFor(Settings.Global.MOBILE_DATA + mSubId);
+        }
+        mContext.getContentResolver().registerContentObserver(uri, true /*notifyForDescendants*/,
+                this);
+    }
+
+    public int getSubId() {
+        return mSubId;
+    }
+
+    public MobileDataEnabledListener stop() {
+        mContext.getContentResolver().unregisterContentObserver(this);
+        return this;
+    }
+
+    @Override
+    public void onChange(boolean selfChange) {
+        mClient.onMobileDataEnabledChange();
+    }
+}
diff --git a/src/com/android/settings/network/SubscriptionsPreferenceController.java b/src/com/android/settings/network/SubscriptionsPreferenceController.java
index 88ff5cf..ae31b56 100644
--- a/src/com/android/settings/network/SubscriptionsPreferenceController.java
+++ b/src/com/android/settings/network/SubscriptionsPreferenceController.java
@@ -21,6 +21,9 @@
 
 import android.content.Context;
 import android.content.Intent;
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkCapabilities;
 import android.provider.Settings;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
@@ -35,6 +38,7 @@
 import androidx.preference.PreferenceScreen;
 
 import com.android.settings.R;
+import com.android.settings.network.telephony.DataConnectivityListener;
 import com.android.settings.network.telephony.MobileNetworkActivity;
 import com.android.settingslib.core.AbstractPreferenceController;
 
@@ -46,14 +50,18 @@
  * available if there are 2 or more subscriptions.
  */
 public class SubscriptionsPreferenceController extends AbstractPreferenceController implements
-        LifecycleObserver, SubscriptionsChangeListener.SubscriptionsChangeListenerClient {
+        LifecycleObserver, SubscriptionsChangeListener.SubscriptionsChangeListenerClient,
+        MobileDataEnabledListener.Client, DataConnectivityListener.Client {
     private static final String TAG = "SubscriptionsPrefCntrlr";
 
     private UpdateListener mUpdateListener;
     private String mPreferenceGroupKey;
     private PreferenceGroup mPreferenceGroup;
     private SubscriptionManager mManager;
+    private ConnectivityManager mConnectivityManager;
     private SubscriptionsChangeListener mSubscriptionsListener;
+    private MobileDataEnabledListener mDataEnabledListener;
+    private DataConnectivityListener mConnectivityListener;
 
     // Map of subscription id to Preference
     private Map<Integer, Preference> mSubscriptionPreferences;
@@ -89,20 +97,27 @@
         mPreferenceGroupKey = preferenceGroupKey;
         mStartOrder = startOrder;
         mManager = context.getSystemService(SubscriptionManager.class);
+        mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
         mSubscriptionPreferences = new ArrayMap<>();
         mSubscriptionsListener = new SubscriptionsChangeListener(context, this);
+        mDataEnabledListener = new MobileDataEnabledListener(context, this);
+        mConnectivityListener = new DataConnectivityListener(context, this);
         lifecycle.addObserver(this);
     }
 
     @OnLifecycleEvent(ON_RESUME)
     public void onResume() {
         mSubscriptionsListener.start();
+        mDataEnabledListener.start(SubscriptionManager.getDefaultDataSubscriptionId());
+        mConnectivityListener.start();
         update();
     }
 
     @OnLifecycleEvent(ON_PAUSE)
     public void onPause() {
         mSubscriptionsListener.stop();
+        mDataEnabledListener.stop();
+        mConnectivityListener.stop();
     }
 
     @Override
@@ -158,6 +173,19 @@
         mUpdateListener.onChildrenUpdated();
     }
 
+    private boolean activeNetworkIsCellular() {
+        final Network activeNetwork = mConnectivityManager.getActiveNetwork();
+        if (activeNetwork == null) {
+            return false;
+        }
+        final NetworkCapabilities networkCapabilities = mConnectivityManager.getNetworkCapabilities(
+                activeNetwork);
+        if (networkCapabilities == null) {
+            return false;
+        }
+        return networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR);
+    }
+
     /**
      * The summary can have either 1 or 2 lines depending on which services (calls, SMS, data) this
      * subscription is the default for.
@@ -187,10 +215,10 @@
         if (subId == dataDefaultSubId) {
             final TelephonyManager telMgrForSub = mContext.getSystemService(
                     TelephonyManager.class).createForSubscriptionId(subId);
-            final int dataState = telMgrForSub.getDataState();
-            if (dataState == TelephonyManager.DATA_CONNECTED) {
+            boolean dataEnabled = telMgrForSub.isDataEnabled();
+            if (dataEnabled && activeNetworkIsCellular()) {
                 line2 = mContext.getString(R.string.mobile_data_active);
-            } else if (!telMgrForSub.isDataEnabled()) {
+            } else if (!dataEnabled) {
                 line2 = mContext.getString(R.string.mobile_data_off);
             } else {
                 line2 = mContext.getString(R.string.default_for_mobile_data);
@@ -231,6 +259,22 @@
 
     @Override
     public void onSubscriptionsChanged() {
+        // See if we need to change which sub id we're using to listen for enabled/disabled changes.
+        int defaultDataSubId = SubscriptionManager.getDefaultDataSubscriptionId();
+        if (defaultDataSubId != mDataEnabledListener.getSubId()) {
+            mDataEnabledListener.stop();
+            mDataEnabledListener.start(defaultDataSubId);
+        }
+        update();
+    }
+
+    @Override
+    public void onMobileDataEnabledChange() {
+        update();
+    }
+
+    @Override
+    public void onDataConnectivityChange() {
         update();
     }
 }
diff --git a/src/com/android/settings/network/telephony/DataConnectivityListener.java b/src/com/android/settings/network/telephony/DataConnectivityListener.java
new file mode 100644
index 0000000..adb39c6
--- /dev/null
+++ b/src/com/android/settings/network/telephony/DataConnectivityListener.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2019 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.network.telephony;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkRequest;
+
+/** A helper class to listen to a few different kinds of connectivity changes that could be relevant
+ *  to changes in which network is active, and whether the active network has internet data
+ *  connectivity. */
+public class DataConnectivityListener extends ConnectivityManager.NetworkCallback {
+    private Context mContext;
+    private ConnectivityManager mConnectivityManager;
+    private final NetworkRequest mNetworkRequest;
+    private Client mClient;
+
+    public interface Client {
+        void onDataConnectivityChange();
+    }
+
+    public DataConnectivityListener(Context context, Client client) {
+        mContext = context;
+        mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
+        mClient = client;
+        mNetworkRequest = new NetworkRequest.Builder()
+                .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
+                .build();
+    }
+
+    public void start() {
+        mConnectivityManager.registerNetworkCallback(mNetworkRequest, this,
+                mContext.getMainThreadHandler());
+    }
+
+    public void stop() {
+        mConnectivityManager.unregisterNetworkCallback(this);
+    }
+
+    @Override
+    public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {
+        final Network activeNetwork = mConnectivityManager.getActiveNetwork();
+        if (activeNetwork != null && activeNetwork.equals(network)) {
+            mClient.onDataConnectivityChange();
+        }
+    }
+
+    @Override
+    public void onLosing(Network network, int maxMsToLive) {
+        mClient.onDataConnectivityChange();
+    }
+
+    @Override
+    public void onLost(Network network) {
+        mClient.onDataConnectivityChange();
+    }
+}
diff --git a/src/com/android/settings/network/telephony/DataUsagePreferenceController.java b/src/com/android/settings/network/telephony/DataUsagePreferenceController.java
index 3f55003..b8a31fe 100644
--- a/src/com/android/settings/network/telephony/DataUsagePreferenceController.java
+++ b/src/com/android/settings/network/telephony/DataUsagePreferenceController.java
@@ -21,9 +21,7 @@
 import android.net.NetworkTemplate;
 import android.provider.Settings;
 import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
 import android.text.TextUtils;
-import android.text.format.Formatter;
 
 import androidx.preference.Preference;
 
@@ -87,9 +85,10 @@
         mSubId = subId;
 
         if (mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
-            mTemplate = getNetworkTemplate(mContext, subId);
+            mTemplate = DataUsageUtils.getDefaultTemplate(mContext, mSubId);
 
             final DataUsageController controller = new DataUsageController(mContext);
+            controller.setSubscriptionId(mSubId);
             mDataUsageInfo = controller.getDataUsageInfo(mTemplate);
 
             mIntent = new Intent(Settings.ACTION_MOBILE_DATA_USAGE);
@@ -97,12 +96,4 @@
             mIntent.putExtra(Settings.EXTRA_SUB_ID, mSubId);
         }
     }
-
-    private NetworkTemplate getNetworkTemplate(Context context, int subId) {
-        final TelephonyManager tm = TelephonyManager.from(context).createForSubscriptionId(subId);
-        NetworkTemplate mobileAll = NetworkTemplate.buildTemplateMobileAll(tm.getSubscriberId());
-
-        return NetworkTemplate.normalize(mobileAll, tm.getMergedSubscriberIds());
-    }
-
 }
diff --git a/src/com/android/settings/network/telephony/MobileDataPreferenceController.java b/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
index 2df16f5..c06b78b 100644
--- a/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
+++ b/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
@@ -30,6 +30,7 @@
 import androidx.preference.PreferenceScreen;
 import androidx.preference.SwitchPreference;
 
+import com.android.settings.R;
 import com.android.settings.network.MobileDataContentObserver;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnStart;
@@ -120,7 +121,13 @@
     @Override
     public void updateState(Preference preference) {
         super.updateState(preference);
-        preference.setEnabled(!isOpportunistic());
+        if (isOpportunistic()) {
+            preference.setEnabled(false);
+            preference.setSummary(R.string.mobile_data_settings_summary_auto_switch);
+        } else {
+            preference.setEnabled(true);
+            preference.setSummary(R.string.mobile_data_settings_summary);
+        }
     }
 
     private boolean isOpportunistic() {
diff --git a/src/com/android/settings/network/telephony/RoamingPreferenceController.java b/src/com/android/settings/network/telephony/RoamingPreferenceController.java
index 4140d5d..dd5fd0e 100644
--- a/src/com/android/settings/network/telephony/RoamingPreferenceController.java
+++ b/src/com/android/settings/network/telephony/RoamingPreferenceController.java
@@ -33,7 +33,6 @@
 import androidx.preference.Preference;
 import androidx.preference.PreferenceScreen;
 
-import com.android.settings.core.TogglePreferenceController;
 import com.android.settingslib.RestrictedSwitchPreference;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnStart;
@@ -114,8 +113,10 @@
     public void updateState(Preference preference) {
         super.updateState(preference);
         final RestrictedSwitchPreference switchPreference = (RestrictedSwitchPreference) preference;
-        switchPreference.setEnabled(mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-        switchPreference.setChecked(isChecked());
+        if (!switchPreference.isDisabledByAdmin()) {
+            switchPreference.setEnabled(mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+            switchPreference.setChecked(isChecked());
+        }
     }
 
     @VisibleForTesting
diff --git a/src/com/android/settings/privacy/EnableContentCaptureWithServiceSettingsPreferenceController.java b/src/com/android/settings/privacy/EnableContentCaptureWithServiceSettingsPreferenceController.java
index 1456c2d..809bfbd 100644
--- a/src/com/android/settings/privacy/EnableContentCaptureWithServiceSettingsPreferenceController.java
+++ b/src/com/android/settings/privacy/EnableContentCaptureWithServiceSettingsPreferenceController.java
@@ -19,23 +19,36 @@
 import android.annotation.NonNull;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.DialogInterface;
 import android.content.Intent;
+import android.content.pm.UserInfo;
+import android.os.UserHandle;
+import android.os.UserManager;
 import android.util.Log;
 
+import androidx.appcompat.app.AlertDialog;
 import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
 
 import com.android.settings.core.TogglePreferenceController;
+import com.android.settings.dashboard.profileselector.UserAdapter;
 import com.android.settings.utils.ContentCaptureUtils;
-import com.android.settings.widget.MasterSwitchPreference;
+
+import java.util.ArrayList;
+import java.util.List;
 
 public final class EnableContentCaptureWithServiceSettingsPreferenceController
         extends TogglePreferenceController {
 
     private static final String TAG = "ContentCaptureController";
 
+    private final UserManager mUserManager;
+
     public EnableContentCaptureWithServiceSettingsPreferenceController(@NonNull Context context,
             @NonNull String key) {
         super(context, key);
+
+        mUserManager = UserManager.get(context);
     }
 
     @Override
@@ -61,6 +74,11 @@
             Log.w(TAG, "No component name for custom service settings");
             preference.setSelectable(false);
         }
+
+        preference.setOnPreferenceClickListener((pref) -> {
+            ProfileSelectDialog.show(mContext, pref);
+            return true;
+        });
     }
 
     @Override
@@ -69,4 +87,28 @@
                 && ContentCaptureUtils.getServiceSettingsComponentName() != null;
         return available ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
     }
+
+    private static final class ProfileSelectDialog {
+        public static void show(Context context, Preference pref) {
+            final UserManager userManager = UserManager.get(context);
+            final List<UserInfo> userInfos = userManager.getUsers();
+            final ArrayList<UserHandle> userHandles = new ArrayList<>(userInfos.size());
+            for (UserInfo info: userInfos) {
+                userHandles.add(info.getUserHandle());
+            }
+
+            AlertDialog.Builder builder = new AlertDialog.Builder(context);
+            UserAdapter adapter = UserAdapter.createUserAdapter(userManager, context, userHandles);
+            builder.setTitle(com.android.settingslib.R.string.choose_profile)
+                    .setAdapter(adapter, (DialogInterface dialog, int which) -> {
+                        final UserHandle user = userHandles.get(which);
+                        // Show menu on top level items.
+                        final Intent intent = pref.getIntent();
+                        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+                        context.startActivityAsUser(intent, user);
+                    })
+                    .show();
+        }
+    }
+
 }
diff --git a/src/com/android/settings/security/ScreenPinningSettings.java b/src/com/android/settings/security/ScreenPinningSettings.java
index 22223fd..c60fd47 100644
--- a/src/com/android/settings/security/ScreenPinningSettings.java
+++ b/src/com/android/settings/security/ScreenPinningSettings.java
@@ -117,9 +117,13 @@
     }
 
     private boolean isScreenLockUsed() {
-        int def = getCurrentSecurityTitle() != R.string.screen_pinning_unlock_none ? 1 : 0;
-        return Settings.Secure.getInt(getContentResolver(),
-                Settings.Secure.LOCK_TO_APP_EXIT_LOCKED, def) != 0;
+        // This functionality should be kept consistent with
+        // com.android.server.wm.LockTaskController (see b/127605586)
+        int defaultValueIfSettingNull = mLockPatternUtils.isSecure(UserHandle.myUserId()) ? 1 : 0;
+        return Settings.Secure.getInt(
+                getContentResolver(),
+                Settings.Secure.LOCK_TO_APP_EXIT_LOCKED,
+                defaultValueIfSettingNull) != 0;
     }
 
     private boolean setScreenLockUsed(boolean isEnabled) {
diff --git a/src/com/android/settings/slices/SliceDataConverter.java b/src/com/android/settings/slices/SliceDataConverter.java
index 14abd1b..7a8ab83 100644
--- a/src/com/android/settings/slices/SliceDataConverter.java
+++ b/src/com/android/settings/slices/SliceDataConverter.java
@@ -25,6 +25,7 @@
 import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_UNAVAILABLE_SLICE_SUBTITLE;
 
 import android.accessibilityservice.AccessibilityServiceInfo;
+import android.app.settings.SettingsEnums;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.PackageManager;
@@ -52,6 +53,7 @@
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.search.DatabaseIndexingUtils;
 import com.android.settings.search.Indexable.SearchIndexProvider;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -76,10 +78,12 @@
 
     private static final String NODE_NAME_PREFERENCE_SCREEN = "PreferenceScreen";
 
+    private final MetricsFeatureProvider mMetricsFeatureProvider;
     private Context mContext;
 
     public SliceDataConverter(Context context) {
         mContext = context;
+        mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
     }
 
     /**
@@ -151,6 +155,7 @@
         XmlResourceParser parser = null;
 
         final List<SliceData> xmlSliceData = new ArrayList<>();
+        String controllerClassName = "";
 
         try {
             parser = mContext.getResources().getXml(xmlResId);
@@ -188,7 +193,7 @@
             for (Bundle bundle : metadata) {
                 // TODO (b/67996923) Non-controller Slices should become intent-only slices.
                 // Note that without a controller, dynamic summaries are impossible.
-                final String controllerClassName = bundle.getString(METADATA_CONTROLLER);
+                controllerClassName = bundle.getString(METADATA_CONTROLLER);
                 if (TextUtils.isEmpty(controllerClassName)) {
                     continue;
                 }
@@ -226,12 +231,25 @@
             }
         } catch (SliceData.InvalidSliceDataException e) {
             Log.w(TAG, "Invalid data when building SliceData for " + fragmentName, e);
-        } catch (XmlPullParserException e) {
-            Log.w(TAG, "XML Error parsing PreferenceScreen: ", e);
-        } catch (IOException e) {
-            Log.w(TAG, "IO Error parsing PreferenceScreen: ", e);
-        } catch (Resources.NotFoundException e) {
-            Log.w(TAG, "Resource not found error parsing PreferenceScreen: ", e);
+            mMetricsFeatureProvider.action(SettingsEnums.PAGE_UNKNOWN,
+                    SettingsEnums.ACTION_VERIFY_SLICE_ERROR_INVALID_DATA,
+                    SettingsEnums.PAGE_UNKNOWN,
+                    controllerClassName,
+                    1);
+        } catch (XmlPullParserException | IOException | Resources.NotFoundException e) {
+            Log.w(TAG, "Error parsing PreferenceScreen: ", e);
+            mMetricsFeatureProvider.action(SettingsEnums.PAGE_UNKNOWN,
+                    SettingsEnums.ACTION_VERIFY_SLICE_PARSING_ERROR,
+                    SettingsEnums.PAGE_UNKNOWN,
+                    fragmentName,
+                    1);
+        } catch (Exception e) {
+            Log.w(TAG, "Get slice data from XML failed ", e);
+            mMetricsFeatureProvider.action(SettingsEnums.PAGE_UNKNOWN,
+                    SettingsEnums.ACTION_VERIFY_SLICE_OTHER_EXCEPTION,
+                    SettingsEnums.PAGE_UNKNOWN,
+                    fragmentName + "_" + controllerClassName,
+                    1);
         } finally {
             if (parser != null) parser.close();
         }
diff --git a/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java b/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java
index 7308741..5dfcc25 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java
@@ -323,15 +323,10 @@
 
     @Override
     public boolean onNavigateUp() {
-        Fragment fragment = mFragmentManager.findFragmentById(R.id.fragment_container);
-        if (fragment instanceof WifiDppQrCodeGeneratorFragment) {
+        if (!mFragmentManager.popBackStackImmediate()) {
             finish();
-            return true;
-        } else if (fragment instanceof WifiDppQrCodeScannerFragment) {
-            mFragmentManager.popBackStackImmediate();
         }
-
-        return false;
+        return true;
     }
 
     @Override
diff --git a/src/com/android/settings/wifi/p2p/WifiP2pSettings.java b/src/com/android/settings/wifi/p2p/WifiP2pSettings.java
index 1c1da38..f1ac6cd 100644
--- a/src/com/android/settings/wifi/p2p/WifiP2pSettings.java
+++ b/src/com/android/settings/wifi/p2p/WifiP2pSettings.java
@@ -34,6 +34,7 @@
 import android.net.wifi.p2p.WifiP2pGroupList;
 import android.net.wifi.p2p.WifiP2pInfo;
 import android.net.wifi.p2p.WifiP2pManager;
+import android.net.wifi.p2p.WifiP2pManager.DeviceInfoListener;
 import android.net.wifi.p2p.WifiP2pManager.PeerListListener;
 import android.net.wifi.p2p.WifiP2pManager.PersistentGroupInfoListener;
 import android.os.Bundle;
@@ -62,7 +63,7 @@
  * Displays Wi-fi p2p settings UI
  */
 public class WifiP2pSettings extends DashboardFragment
-        implements PersistentGroupInfoListener, PeerListListener {
+        implements PersistentGroupInfoListener, PeerListListener, DeviceInfoListener {
 
     private static final String TAG = "WifiP2pSettings";
     private static final boolean DBG = false;
@@ -134,10 +135,12 @@
                 mLastGroupFormed = wifip2pinfo.groupFormed;
                 mIsIgnoreInitConnectionInfoCallback = true;
             } else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {
-                mThisDevice = (WifiP2pDevice) intent.getParcelableExtra(
-                        WifiP2pManager.EXTRA_WIFI_P2P_DEVICE);
-                if (DBG) Log.d(TAG, "Update device info: " + mThisDevice);
-                mThisDevicePreferenceController.updateDeviceName(mThisDevice);
+                // Do not use WifiP2pManager.EXTRA_WIFI_P2P_DEVICE from the extras, as the system
+                // broadcast does not contain the device's MAC.
+                // Requesting our own device info as an app holding the NETWORK_SETTINGS permission
+                // ensures that the MAC address will be available in the result.
+                if (DBG) Log.d(TAG, "This device changed. Requesting device info.");
+                mWifiP2pManager.requestDeviceInfo(mChannel, WifiP2pSettings.this);
             } else if (WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION.equals(action)) {
                 int discoveryState = intent.getIntExtra(WifiP2pManager.EXTRA_DISCOVERY_STATE,
                     WifiP2pManager.WIFI_P2P_DISCOVERY_STOPPED);
@@ -340,13 +343,7 @@
         getActivity().registerReceiver(mReceiver, mIntentFilter);
         if (mWifiP2pManager != null) {
             mWifiP2pManager.requestPeers(mChannel, WifiP2pSettings.this);
-            mWifiP2pManager.requestDeviceInfo(mChannel, wifiP2pDevice -> {
-                if (DBG) {
-                    Log.d(TAG, "Get device info: " + wifiP2pDevice);
-                }
-                mThisDevice = wifiP2pDevice;
-                mThisDevicePreferenceController.updateDeviceName(wifiP2pDevice);
-            });
+            mWifiP2pManager.requestDeviceInfo(mChannel, WifiP2pSettings.this);
             mIsIgnoreInitConnectionInfoCallback = false;
             mWifiP2pManager.requestNetworkInfo(mChannel, networkInfo -> {
                 mWifiP2pManager.requestConnectionInfo(mChannel, wifip2pinfo -> {
@@ -599,6 +596,13 @@
         handlePeersChanged();
     }
 
+    @Override
+    public void onDeviceInfoAvailable(WifiP2pDevice wifiP2pDevice) {
+        mThisDevice = wifiP2pDevice;
+        if (DBG) Log.d(TAG, "Update device info: " + mThisDevice);
+        mThisDevicePreferenceController.updateDeviceName(mThisDevice);
+    }
+
     private void handleP2pStateChanged() {
         updateSearchMenu(false);
         mThisDevicePreferenceController.setEnabled(mWifiP2pEnabled);
diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/TimeSpentInAppPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/TimeSpentInAppPreferenceControllerTest.java
index 94d1228..e1da707 100644
--- a/tests/robotests/src/com/android/settings/applications/appinfo/TimeSpentInAppPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/appinfo/TimeSpentInAppPreferenceControllerTest.java
@@ -20,6 +20,8 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.ArgumentMatchers.nullable;
+import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
@@ -32,6 +34,7 @@
 import androidx.preference.PreferenceScreen;
 
 import com.android.settings.core.BasePreferenceController;
+import com.android.settings.testutils.FakeFeatureFactory;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -58,10 +61,12 @@
     private ShadowPackageManager mPackageManager;
     private TimeSpentInAppPreferenceController mController;
     private Preference mPreference;
+    private FakeFeatureFactory mFeatureFactory;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
+        mFeatureFactory = FakeFeatureFactory.setupForTest();
         mContext = RuntimeEnvironment.application;
         mPackageManager = Shadows.shadowOf(mContext.getPackageManager());
         mController = new TimeSpentInAppPreferenceController(mContext, TEST_KEY);
@@ -112,4 +117,12 @@
         assertThat(intent.getStringExtra(EXTRA_PACKAGE_NAME))
                 .isEqualTo(TEST_INTENT.getStringExtra(EXTRA_PACKAGE_NAME));
     }
+
+    @Test
+    public void getSummary_shouldQueryAppFeatureProvider() {
+        mController.getSummary();
+
+        verify(mFeatureFactory.applicationFeatureProvider).getTimeSpentInApp(
+                nullable(String.class));
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/core/instrumentation/SettingsEventLogWriterTest.java b/tests/robotests/src/com/android/settings/core/instrumentation/SettingsEventLogWriterTest.java
new file mode 100644
index 0000000..ba2553d
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/core/instrumentation/SettingsEventLogWriterTest.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2019 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.core.instrumentation;
+
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+import android.metrics.LogMaker;
+import android.provider.DeviceConfig;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.settings.core.SettingsUIDeviceConfig;
+import com.android.settings.testutils.shadow.ShadowDeviceConfig;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.Resetter;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(shadows = {ShadowDeviceConfig.class, SettingsEventLogWriterTest.ShadowMetricsLogger.class})
+public class SettingsEventLogWriterTest {
+
+    private SettingsEventLogWriter mWriter;
+
+    @Before
+    public void setUp() {
+        mWriter = new SettingsEventLogWriter();
+    }
+
+    @After
+    public void tearDown() {
+        ShadowDeviceConfig.reset();
+        ShadowMetricsLogger.reset();
+    }
+
+    @Test
+    public void visible_eventLogEnabled_shouldLog() {
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SETTINGS_UI,
+                SettingsUIDeviceConfig.GENERIC_EVENT_LOGGING_ENABLED, "true", true);
+
+        mWriter.visible(RuntimeEnvironment.application, SettingsEnums.PAGE_UNKNOWN,
+                SettingsEnums.SETTINGS_HOMEPAGE);
+
+        assertThat(ShadowMetricsLogger.sActionLoggedCount).isEqualTo(1);
+    }
+
+    @Test
+    public void hidden_eventLogEnabled_shouldLog() {
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SETTINGS_UI,
+                SettingsUIDeviceConfig.GENERIC_EVENT_LOGGING_ENABLED, "true", true);
+
+        mWriter.hidden(RuntimeEnvironment.application, SettingsEnums.SETTINGS_HOMEPAGE);
+
+        assertThat(ShadowMetricsLogger.sActionLoggedCount).isEqualTo(1);
+    }
+
+    @Test
+    public void visible_eventLogDisabled_shouldNotLog() {
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SETTINGS_UI,
+                SettingsUIDeviceConfig.GENERIC_EVENT_LOGGING_ENABLED, "false", true);
+
+        mWriter.visible(RuntimeEnvironment.application, SettingsEnums.PAGE_UNKNOWN,
+                SettingsEnums.SETTINGS_HOMEPAGE);
+
+        assertThat(ShadowMetricsLogger.sActionLoggedCount).isEqualTo(0);
+    }
+
+    @Test
+    public void hidden_eventLogDisabled_shouldNotLog() {
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SETTINGS_UI,
+                SettingsUIDeviceConfig.GENERIC_EVENT_LOGGING_ENABLED, "false", true);
+
+        mWriter.hidden(RuntimeEnvironment.application, SettingsEnums.SETTINGS_HOMEPAGE);
+
+        assertThat(ShadowMetricsLogger.sActionLoggedCount).isEqualTo(0);
+    }
+
+    @Implements(MetricsLogger.class)
+    public static class ShadowMetricsLogger {
+
+        public static int sActionLoggedCount = 0;
+
+        @Resetter
+        public static void reset() {
+            sActionLoggedCount = 0;
+        }
+
+        @Implementation
+        protected static void action(LogMaker content) {
+            sActionLoggedCount++;
+        }
+
+        @Implementation
+        public static void hidden(Context context, int category) throws IllegalArgumentException {
+            sActionLoggedCount++;
+        }
+    }
+
+}
diff --git a/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java b/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java
index 79c3ad1..b9bfcc1 100644
--- a/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java
+++ b/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java
@@ -27,11 +27,13 @@
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 import android.app.usage.NetworkStatsManager;
 import android.content.Context;
 import android.net.NetworkPolicyManager;
 import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
 
 import androidx.fragment.app.FragmentActivity;
 
@@ -44,6 +46,7 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Answers;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.Robolectric;
@@ -68,6 +71,8 @@
     private NetworkPolicyManager mNetworkPolicyManager;
     @Mock
     private NetworkStatsManager mNetworkStatsManager;
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+    private TelephonyManager mTelephonyManager;
     private Context mContext;
     private FragmentActivity mActivity;
     private SummaryLoader.SummaryProvider mSummaryProvider;
@@ -84,7 +89,9 @@
         ShadowUserManager.getShadow().setIsAdminUser(true);
         shadowContext.setSystemService(Context.NETWORK_POLICY_SERVICE, mNetworkPolicyManager);
 
-        mContext = RuntimeEnvironment.application;
+        mContext = spy(RuntimeEnvironment.application);
+        when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
+        when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mTelephonyManager);
         mActivity = spy(Robolectric.buildActivity(FragmentActivity.class).get());
         doReturn(mNetworkStatsManager).when(mActivity).getSystemService(NetworkStatsManager.class);
 
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogControllerTest.java
index 5a4a809..76c444e 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogControllerTest.java
@@ -63,6 +63,7 @@
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
 import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.telephony.euicc.EuiccManager;
 
@@ -103,6 +104,8 @@
     private PersistableBundle mPersistableBundle;
     @Mock
     private EuiccManager mEuiccManager;
+    @Mock
+    private SubscriptionManager mSubscriptionManager;
 
     private SimStatusDialogController mController;
     private Context mContext;
@@ -123,6 +126,7 @@
         doReturn(mPhoneStateListener).when(mController).getPhoneStateListener();
         doReturn("").when(mController).getPhoneNumber();
         doReturn(mSignalStrength).when(mController).getSignalStrength();
+        doReturn(mSubscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(anyInt());
 
         when(mEuiccManager.isEnabled()).thenReturn(true);
         when(mEuiccManager.getEid()).thenReturn("");
@@ -130,6 +134,7 @@
         ReflectionHelpers.setField(mController, "mCarrierConfigManager", mCarrierConfigManager);
         ReflectionHelpers.setField(mController, "mSubscriptionInfo", mSubscriptionInfo);
         ReflectionHelpers.setField(mController, "mEuiccManager", mEuiccManager);
+        ReflectionHelpers.setField(mController, "mSubscriptionManager", mSubscriptionManager);
         when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(mPersistableBundle);
 
         final ShadowPackageManager shadowPackageManager =
@@ -141,8 +146,8 @@
 
     @Test
     public void initialize_updateNetworkProviderWithFoobarCarrier_shouldUpdateCarrierWithFoobar() {
-        final String carrierName = "foobar";
-        when(mServiceState.getOperatorAlphaLong()).thenReturn(carrierName);
+        final CharSequence carrierName = "foobar";
+        doReturn(carrierName).when(mSubscriptionInfo).getCarrierName();
 
         mController.initialize();
 
diff --git a/tests/robotests/src/com/android/settings/display/AdaptiveSleepPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/AdaptiveSleepPreferenceControllerTest.java
index 8938873..295eac5 100644
--- a/tests/robotests/src/com/android/settings/display/AdaptiveSleepPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/AdaptiveSleepPreferenceControllerTest.java
@@ -21,6 +21,8 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
 
 import android.content.ContentResolver;
@@ -28,11 +30,12 @@
 import android.content.pm.PackageManager;
 import android.provider.Settings;
 
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
 import com.android.settings.R;
-import com.android.settingslib.RestrictedPreference;
 
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -41,7 +44,6 @@
 import org.robolectric.RuntimeEnvironment;
 
 @RunWith(RobolectricTestRunner.class)
-@Ignore("b/130897305")
 public class AdaptiveSleepPreferenceControllerTest {
 
     private static final String PREFERENCE_KEY = "adaptive_sleep";
@@ -52,18 +54,25 @@
 
     @Mock
     private PackageManager mPackageManager;
+    @Mock
+    private PreferenceScreen mScreen;
+    @Mock
+    private Preference mPreference;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
 
-        mContext = RuntimeEnvironment.application;
+        mContext = spy(RuntimeEnvironment.application);
         mContentResolver = mContext.getContentResolver();
-        mController = new AdaptiveSleepPreferenceController(mContext, PREFERENCE_KEY);
 
-
+        doReturn(mPackageManager).when(mContext).getPackageManager();
+        when(mPackageManager.getAttentionServicePackageName()).thenReturn("some.package");
         when(mPackageManager.checkPermission(any(), any())).thenReturn(
                 PackageManager.PERMISSION_GRANTED);
+
+        mController = new AdaptiveSleepPreferenceController(mContext, PREFERENCE_KEY);
+        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
     }
 
     @Test
@@ -134,9 +143,11 @@
     public void isChecked_returnsFalseWhenNotSufficientPermissions() {
         when(mPackageManager.checkPermission(any(), any())).thenReturn(
                 PackageManager.PERMISSION_DENIED);
+        final AdaptiveSleepPreferenceController controller = new AdaptiveSleepPreferenceController(
+                mContext, PREFERENCE_KEY);
 
-        mController.setChecked(true);
-        assertThat(mController.isChecked()).isFalse();
+        controller.setChecked(true);
+        assertThat(controller.isChecked()).isFalse();
     }
 
     @Test
@@ -145,8 +156,7 @@
                 PackageManager.PERMISSION_DENIED);
 
         mController.setChecked(true);
-        final RestrictedPreference mPreference = new RestrictedPreference(mContext);
-        mController.updateState(mPreference);
+        mController.displayPreference(mScreen);
         assertThat(mPreference.isEnabled()).isFalse();
     }
 }
diff --git a/tests/robotests/src/com/android/settings/display/DisplayWhiteBalancePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/DisplayWhiteBalancePreferenceControllerTest.java
index d0dbc0b..dfc13de 100644
--- a/tests/robotests/src/com/android/settings/display/DisplayWhiteBalancePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/DisplayWhiteBalancePreferenceControllerTest.java
@@ -1,16 +1,27 @@
 package com.android.settings.display;
 
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 import static com.google.common.truth.Truth.assertThat;
 
+
+import android.content.ContentResolver;
+import android.content.Context;
 import android.hardware.display.ColorDisplayManager;
+import android.provider.Settings;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
 import com.android.settings.testutils.shadow.SettingsShadowResources;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Answers;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
@@ -27,6 +38,15 @@
 
   @Mock
   private ColorDisplayManager mColorDisplayManager;
+  private ContentResolver mContentResolver;
+  @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+  private Context mContext;
+  @Mock
+  private PreferenceScreen mScreen;
+  @Mock
+  private Preference mPreference;
+
+  private final String PREFERENCE_KEY = "display_white_balance";
 
   @After
   public void tearDown() {
@@ -36,17 +56,21 @@
   @Before
   public void setUp() {
     MockitoAnnotations.initMocks(this);
-    mController = spy(new DisplayWhiteBalancePreferenceController(RuntimeEnvironment.application,
-        "display_white_balance"));
+
+    mContentResolver = RuntimeEnvironment.application.getContentResolver();
+    when(mContext.getContentResolver()).thenReturn(mContentResolver);
+    when(mContext.getResources()).thenReturn(RuntimeEnvironment.application.getResources());
+    when(mScreen.findPreference(PREFERENCE_KEY)).thenReturn(mPreference);
+
+    mController = spy(new DisplayWhiteBalancePreferenceController(mContext, PREFERENCE_KEY));
     doReturn(mColorDisplayManager).when(mController).getColorDisplayManager();
   }
 
   @Test
-  public void isAvailable_configuredAvailable() {
+  public void isAvailable() {
     SettingsShadowResources.overrideResource(
         com.android.internal.R.bool.config_displayWhiteBalanceAvailable, true);
-    when(mColorDisplayManager.getColorMode())
-        .thenReturn(ColorDisplayManager.COLOR_MODE_NATURAL);
+
     assertThat(mController.isAvailable()).isTrue();
   }
 
@@ -54,20 +78,7 @@
   public void isAvailable_configuredUnavailable() {
     SettingsShadowResources.overrideResource(
         com.android.internal.R.bool.config_displayWhiteBalanceAvailable, false);
-    when(mColorDisplayManager.getColorMode())
-        .thenReturn(ColorDisplayManager.COLOR_MODE_SATURATED);
-    assertThat(mController.isAvailable()).isFalse();
 
-    SettingsShadowResources.overrideResource(
-        com.android.internal.R.bool.config_displayWhiteBalanceAvailable, false);
-    when(mColorDisplayManager.getColorMode())
-        .thenReturn(ColorDisplayManager.COLOR_MODE_NATURAL);
-    assertThat(mController.isAvailable()).isFalse();
-
-    SettingsShadowResources.overrideResource(
-        com.android.internal.R.bool.config_displayWhiteBalanceAvailable, true);
-    when(mColorDisplayManager.getColorMode())
-        .thenReturn(ColorDisplayManager.COLOR_MODE_SATURATED);
     assertThat(mController.isAvailable()).isFalse();
   }
 
@@ -94,4 +105,101 @@
     when(mColorDisplayManager.isDisplayWhiteBalanceEnabled()).thenReturn(false);
     assertThat(mController.isChecked()).isFalse();
   }
+
+  @Test
+  public void onStart_configuredUnavailable() {
+    SettingsShadowResources.overrideResource(
+        com.android.internal.R.bool.config_displayWhiteBalanceAvailable, false);
+    mController.displayPreference(mScreen);
+    mController.onStart();
+    assertThat(mController.mContentObserver).isNull();
+  }
+
+  @Test
+  public void onStart_configuredAvailable() {
+    SettingsShadowResources.overrideResource(
+        com.android.internal.R.bool.config_displayWhiteBalanceAvailable, true);
+    when(mColorDisplayManager.getColorMode())
+        .thenReturn(ColorDisplayManager.COLOR_MODE_NATURAL);
+    toggleAccessibilityInversion(false);
+    toggleAccessibilityDaltonizer(false);
+
+    mController.displayPreference(mScreen);
+    mController.onStart();
+    assertThat(mController.mContentObserver).isNotNull();
+  }
+
+  @Test
+  public void visibility_configuredAvailableAccessibilityToggled() {
+    SettingsShadowResources.overrideResource(
+        com.android.internal.R.bool.config_displayWhiteBalanceAvailable, true);
+    mController.displayPreference(mScreen);
+
+    // Accessibility features disabled
+    toggleAccessibilityInversion(false);
+    reset(mPreference);
+    mController.updateVisibility();
+    verify(mPreference).setVisible(true);
+
+    toggleAccessibilityDaltonizer(false);
+    reset(mPreference);
+    mController.updateVisibility();
+    verify(mPreference).setVisible(true);
+
+    // Accessibility features enabled one by one
+    toggleAccessibilityInversion(true);
+    mController.updateVisibility();
+    verify(mPreference).setVisible(false);
+
+    toggleAccessibilityDaltonizer(true);
+    reset(mPreference);
+    mController.updateVisibility();
+    verify(mPreference).setVisible(false);
+
+    // Accessibility features disabled one by one
+    toggleAccessibilityInversion(false);
+    reset(mPreference);
+    mController.updateVisibility();
+    // Daltonizer is still enabled, so we expect the preference to still be invisible
+    verify(mPreference).setVisible(false);
+
+    // Now both a11y features are disabled, so we expect the preference to become visible
+    toggleAccessibilityDaltonizer(false);
+    mController.updateVisibility();
+    verify(mPreference).setVisible(true);
+  }
+
+  @Test
+  public void visibility_configuredAvailableColorModeChanged() {
+    SettingsShadowResources.overrideResource(
+            com.android.internal.R.bool.config_displayWhiteBalanceAvailable, true);
+    mController.displayPreference(mScreen);
+
+    // Non-Saturated color mode selected
+    when(mColorDisplayManager.getColorMode()).thenReturn(ColorDisplayManager.COLOR_MODE_NATURAL);
+    reset(mPreference);
+    mController.updateVisibility();
+    verify(mPreference).setVisible(true);
+
+    // Saturated color mode selected
+    when(mColorDisplayManager.getColorMode()).thenReturn(ColorDisplayManager.COLOR_MODE_SATURATED);
+    mController.updateVisibility();
+    verify(mPreference).setVisible(false);
+
+    // Switch back to non-Saturated color mode
+    when(mColorDisplayManager.getColorMode()).thenReturn(ColorDisplayManager.COLOR_MODE_NATURAL);
+    reset(mPreference);
+    mController.updateVisibility();
+    verify(mPreference).setVisible(true);
+  }
+
+  private void toggleAccessibilityInversion(boolean enable) {
+    Settings.Secure.putInt(mContentResolver,
+        Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, enable ? 1 : 0);
+  }
+
+  private void toggleAccessibilityDaltonizer(boolean enable) {
+    Settings.Secure.putInt(mContentResolver,
+        Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, enable ? 1 : 0);
+  }
 }
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java
index 2dd0d9b..4d77bdd 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java
@@ -15,6 +15,7 @@
  */
 package com.android.settings.fuelgauge;
 
+import static com.android.settings.fuelgauge.PowerUsageSummary.BATTERY_INFO_LOADER;
 import static com.android.settings.fuelgauge.PowerUsageSummary.MENU_ADVANCED_BATTERY;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -373,6 +374,17 @@
                 mFragment.mSettingsObserver);
     }
 
+    @Test
+    public void restartBatteryInfoLoader_contextNull_doNothing() {
+        when(mFragment.getContext()).thenReturn(null);
+        when(mFragment.getLoaderManager()).thenReturn(mLoaderManager);
+
+        mFragment.restartBatteryInfoLoader();
+
+        verify(mLoaderManager, never()).restartLoader(BATTERY_INFO_LOADER, Bundle.EMPTY,
+                mFragment.mBatteryInfoLoaderCallbacks);
+    }
+
     public static class TestFragment extends PowerUsageSummary {
         private Context mContext;
 
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSeekBarControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSeekBarControllerTest.java
index 03c9b0a..5022d4a 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSeekBarControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSeekBarControllerTest.java
@@ -7,9 +7,14 @@
 import android.os.PowerManager;
 import android.provider.Settings;
 import android.provider.Settings.Global;
+
+import androidx.preference.PreferenceScreen;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
 
@@ -19,9 +24,12 @@
     private Context mContext;
     private ContentResolver mResolver;
     private BatterySaverScheduleSeekBarController mController;
+    @Mock
+    private PreferenceScreen mScreen;
 
     @Before
     public void setUp() {
+        MockitoAnnotations.initMocks(this);
         mContext = RuntimeEnvironment.application;
         mController = new BatterySaverScheduleSeekBarController(mContext);
         mResolver = mContext.getContentResolver();
@@ -62,4 +70,14 @@
         mController.updateSeekBar();
         assertThat(mController.mSeekBarPreference.isVisible()).isFalse();
     }
+
+    @Test
+    public void addToScreen_addsToEnd() {
+        Settings.Global.putInt(mResolver, Global.AUTOMATIC_POWER_SAVE_MODE,
+                PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE);
+        Settings.Global.putInt(mResolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, 15);
+        mController.addToScreen(mScreen);
+        assertThat(mController.mSeekBarPreference.getOrder()).isEqualTo(100);
+    }
+
 }
diff --git a/tests/robotests/src/com/android/settings/gestures/GlobalActionsPanelPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/GlobalActionsPanelPreferenceControllerTest.java
new file mode 100644
index 0000000..1fed7df
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/gestures/GlobalActionsPanelPreferenceControllerTest.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2019 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.gestures;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.provider.Settings;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class GlobalActionsPanelPreferenceControllerTest {
+
+    private Context mContext;
+    private GlobalActionsPanelPreferenceController mController;
+
+    private static final String KEY_GESTURE_PANEL = "gesture_global_actions_panel";
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = RuntimeEnvironment.application;
+        mController = new GlobalActionsPanelPreferenceController(mContext, KEY_GESTURE_PANEL);
+    }
+
+    @Test
+    public void testIsChecked_panelEnabled() {
+        Settings.Secure.putInt(
+                mContext.getContentResolver(), mController.ENABLED_SETTING, 1);
+        assertThat(mController.isChecked()).isTrue();
+    }
+
+    @Test
+    public void testIsChecked_panelDisabled() {
+        Settings.Secure.putInt(
+                mContext.getContentResolver(), mController.ENABLED_SETTING, 0);
+        assertThat(mController.isChecked()).isFalse();
+    }
+
+    @Test
+    public void getAvailabilityStatus_panelAvailable() {
+        Settings.Secure.putInt(
+                mContext.getContentResolver(), mController.AVAILABLE_SETTING, 1);
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(mController.AVAILABLE);
+    }
+
+    @Test
+    public void getAvailabilityStatus_panelUnavailable() {
+        Settings.Secure.putInt(
+                mContext.getContentResolver(), mController.AVAILABLE_SETTING, 0);
+        assertThat(mController.getAvailabilityStatus())
+                .isEqualTo(mController.CONDITIONALLY_UNAVAILABLE);
+    }
+
+    @Test
+    public void isSliceable_correctKey() {
+        final GlobalActionsPanelPreferenceController controller =
+                new GlobalActionsPanelPreferenceController(mContext, mController.TOGGLE_KEY);
+        assertThat(controller.isSliceable()).isTrue();
+    }
+
+    @Test
+    public void isSliceable_incorrectKey() {
+        final GlobalActionsPanelPreferenceController controller =
+                new GlobalActionsPanelPreferenceController(mContext, "bad_key");
+        assertThat(controller.isSliceable()).isFalse();
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/gestures/SystemNavigationEdgeToEdgePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/SystemNavigationEdgeToEdgePreferenceControllerTest.java
index a23f8da..5c02101 100644
--- a/tests/robotests/src/com/android/settings/gestures/SystemNavigationEdgeToEdgePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/SystemNavigationEdgeToEdgePreferenceControllerTest.java
@@ -131,6 +131,12 @@
     }
 
     @Test
+    public void testIsGestureAvailable_noOverlayPackage_shouldReturnFalse() {
+        assertThat(SystemNavigationEdgeToEdgePreferenceController.isGestureAvailable(mContext,
+                "com.package.fake")).isFalse();
+    }
+
+    @Test
     public void testIsChecked_defaultIsEdgeToEdge_shouldReturnTrue() {
         SettingsShadowResources.overrideResource(R.integer.config_navBarInteractionMode,
                 NAV_BAR_MODE_GESTURAL);
diff --git a/tests/robotests/src/com/android/settings/gestures/SystemNavigationLegacyPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/SystemNavigationLegacyPreferenceControllerTest.java
index dc9e3d9..ebb1eb0 100644
--- a/tests/robotests/src/com/android/settings/gestures/SystemNavigationLegacyPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/SystemNavigationLegacyPreferenceControllerTest.java
@@ -131,6 +131,12 @@
     }
 
     @Test
+    public void testIsGestureAvailable_noOverlayPackage_shouldReturnFalse() {
+        assertThat(SystemNavigationLegacyPreferenceController.isGestureAvailable(mContext,
+                "com.package.fake")).isFalse();
+    }
+
+    @Test
     public void testIsChecked_defaultIsLegacy_shouldReturnTrue() {
         SettingsShadowResources.overrideResource(R.integer.config_navBarInteractionMode,
                 NAV_BAR_MODE_3BUTTON);
diff --git a/tests/robotests/src/com/android/settings/gestures/SystemNavigationSwipeUpPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/SystemNavigationSwipeUpPreferenceControllerTest.java
index 955ea0c..f8a0b58 100644
--- a/tests/robotests/src/com/android/settings/gestures/SystemNavigationSwipeUpPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/SystemNavigationSwipeUpPreferenceControllerTest.java
@@ -131,6 +131,12 @@
     }
 
     @Test
+    public void testIsGestureAvailable_noOverlayPackage_shouldReturnFalse() {
+        assertThat(SystemNavigationSwipeUpPreferenceController.isGestureAvailable(mContext,
+                "com.package.fake")).isFalse();
+    }
+
+    @Test
     public void testIsChecked_defaultIsSwipeUp_shouldReturnTrue() {
         SettingsShadowResources.overrideResource(R.integer.config_navBarInteractionMode,
                 NAV_BAR_MODE_2BUTTON);
diff --git a/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java b/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java
index 50a798f..dcb32c4 100644
--- a/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java
@@ -35,8 +35,6 @@
     public void setHomepageContainerPaddingTop_shouldBeSetPaddingTop() {
         final SettingsHomepageActivity activity = Robolectric.buildActivity(
                 SettingsHomepageActivity.class).create().get();
-        final int statusBarHeight = activity.getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.status_bar_height);
         final int searchBarHeight = activity.getResources().getDimensionPixelSize(
                 R.dimen.search_bar_height);
         final int searchBarMargin = activity.getResources().getDimensionPixelSize(
@@ -46,8 +44,7 @@
         activity.setHomepageContainerPaddingTop();
 
         final int actualPaddingTop = view.getPaddingTop();
-        assertThat(actualPaddingTop).isEqualTo(
-                statusBarHeight + searchBarHeight + searchBarMargin * 2);
+        assertThat(actualPaddingTop).isEqualTo(searchBarHeight + searchBarMargin * 2);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRendererTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRendererTest.java
index fff1765..fb04dac 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRendererTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRendererTest.java
@@ -16,11 +16,13 @@
 
 package com.android.settings.homepage.contextualcards.slices;
 
+import static com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer.VIEW_TYPE_DEFERRED_SETUP;
 import static com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer.VIEW_TYPE_FULL_WIDTH;
 
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 
 import android.app.Activity;
@@ -137,6 +139,39 @@
     }
 
     @Test
+    public void bindView_beforeSuccessfulSliceBinding_shouldHideSwipeBackground() {
+        final RecyclerView.ViewHolder viewHolder = getSliceViewHolder();
+        final ContextualCard card = buildContextualCard(TEST_SLICE_URI);
+        final View swipeBg = viewHolder.itemView.findViewById(R.id.dismissal_swipe_background);
+
+        mRenderer.bindView(viewHolder, card);
+
+        assertThat(swipeBg.getVisibility()).isEqualTo(View.GONE);
+    }
+
+    @Test
+    public void bindView_reuseViewHolder_shouldHideSwipeBackgroundBeforeSliceBinding() {
+        final RecyclerView.ViewHolder viewHolder = getSliceViewHolder();
+        final ContextualCard card = buildContextualCard(TEST_SLICE_URI);
+        final View swipeBg = viewHolder.itemView.findViewById(R.id.dismissal_swipe_background);
+        swipeBg.setVisibility(View.VISIBLE);
+        mRenderer.mSliceLiveDataMap.put(TEST_SLICE_URI, mSliceLiveData);
+
+        mRenderer.bindView(viewHolder, card);
+
+        assertThat(swipeBg.getVisibility()).isEqualTo(View.GONE);
+    }
+
+    @Test
+    public void bindView_deferredSetupCard_shouldNotCrash() {
+        final RecyclerView.ViewHolder viewHolder = getDeferredSetupViewHolder();
+        final ContextualCard card = buildContextualCard(TEST_SLICE_URI);
+        mRenderer.mSliceLiveDataMap.put(TEST_SLICE_URI, mSliceLiveData);
+
+        mRenderer.bindView(viewHolder, card);
+    }
+
+    @Test
     public void viewClick_keepCard_shouldShowSlice() {
         final RecyclerView.ViewHolder viewHolder = getSliceViewHolder();
         final View sliceView = viewHolder.itemView.findViewById(R.id.slice_view);
@@ -222,6 +257,18 @@
         return mRenderer.createViewHolder(view, VIEW_TYPE_FULL_WIDTH);
     }
 
+    private RecyclerView.ViewHolder getDeferredSetupViewHolder() {
+        final RecyclerView recyclerView = new RecyclerView(mActivity);
+        recyclerView.setLayoutManager(new LinearLayoutManager(mActivity));
+        final View view = LayoutInflater.from(mActivity)
+                .inflate(VIEW_TYPE_DEFERRED_SETUP, recyclerView, false);
+        final RecyclerView.ViewHolder viewHolder = spy(
+                new SliceDeferredSetupCardRendererHelper.DeferredSetupCardViewHolder(view));
+        doReturn(VIEW_TYPE_DEFERRED_SETUP).when(viewHolder).getItemViewType();
+
+        return viewHolder;
+    }
+
     private ContextualCard buildContextualCard(Uri sliceUri) {
         return new ContextualCard.Builder()
                 .setName("test_name")
diff --git a/tests/robotests/src/com/android/settings/network/DataConnectivityListenerTest.java b/tests/robotests/src/com/android/settings/network/DataConnectivityListenerTest.java
new file mode 100644
index 0000000..b45e28c
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/network/DataConnectivityListenerTest.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2019 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.network;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkRequest;
+import android.os.Handler;
+
+import com.android.settings.network.telephony.DataConnectivityListener;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class DataConnectivityListenerTest {
+    @Mock
+    private DataConnectivityListener.Client mClient;
+    @Mock
+    private ConnectivityManager mConnectivityManager;
+    @Mock
+    private Network mActiveNetwork;
+
+    private Context mContext;
+    private DataConnectivityListener mListener;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = spy(RuntimeEnvironment.application);
+        when(mContext.getSystemService(ConnectivityManager.class)).thenReturn(mConnectivityManager);
+        when(mConnectivityManager.getActiveNetwork()).thenReturn(mActiveNetwork);
+        mListener = new DataConnectivityListener(mContext, mClient);
+    }
+
+    @Test
+    public void noStart_doesNotRegister() {
+        verify(mConnectivityManager, never()).registerNetworkCallback(any(NetworkRequest.class),
+                any(ConnectivityManager.NetworkCallback.class), any(Handler.class));
+    }
+
+    @Test
+    public void start_doesRegister() {
+        mListener.start();
+        verify(mConnectivityManager).registerNetworkCallback(any(NetworkRequest.class),
+                eq(mListener), any(Handler.class));
+    }
+
+    @Test
+    public void onCapabilitiesChanged_notActiveNetwork_noCallback() {
+        Network changedNetwork = mock(Network.class);
+        mListener.onCapabilitiesChanged(changedNetwork, mock(NetworkCapabilities.class));
+        verify(mClient, never()).onDataConnectivityChange();
+    }
+
+    @Test
+    public void onCapabilitiesChanged_activeNetwork_onDataConnectivityChangeFires() {
+        mListener.onCapabilitiesChanged(mActiveNetwork, mock(NetworkCapabilities.class));
+        verify(mClient).onDataConnectivityChange();
+    }
+
+    @Test
+    public void onLosing_notActiveNetwork_onDataConnectivityChangeFires() {
+        Network changedNetwork = mock(Network.class);
+        mListener.onLosing(changedNetwork, 500);
+        verify(mClient).onDataConnectivityChange();
+    }
+
+    @Test
+    public void onLosing_activeNetwork_onDataConnectivityChangeFires() {
+        mListener.onLosing(mActiveNetwork, 500);
+        verify(mClient).onDataConnectivityChange();
+    }
+
+    @Test
+    public void onLost_notActiveNetwork_onDataConnectivityChangeFires() {
+        Network changedNetwork = mock(Network.class);
+        mListener.onLost(changedNetwork);
+        verify(mClient).onDataConnectivityChange();
+    }
+
+    @Test
+    public void onLost_activeNetwork_onDataConnectivityChangeFires() {
+        mListener.onLost(mActiveNetwork);
+        verify(mClient).onDataConnectivityChange();
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/network/MobileDataEnabledListenerTest.java b/tests/robotests/src/com/android/settings/network/MobileDataEnabledListenerTest.java
new file mode 100644
index 0000000..0824680
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/network/MobileDataEnabledListenerTest.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2019 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.network;
+
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.net.Uri;
+import android.provider.Settings;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class MobileDataEnabledListenerTest {
+    private static final int SUB_ID_ONE = 111;
+    private static final int SUB_ID_TWO = 222;
+
+    @Mock
+    private MobileDataEnabledListener.Client mClient;
+
+    private Context mContext;
+    private MobileDataEnabledListener mListener;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = RuntimeEnvironment.application;
+        mListener = new MobileDataEnabledListener(mContext, mClient);
+    }
+
+    @Test
+    public void onMobileDataEnabledChange_firesCorrectly() {
+        mListener.start(SUB_ID_ONE);
+        final Uri uri = Settings.Global.getUriFor(Settings.Global.MOBILE_DATA + SUB_ID_ONE);
+        mContext.getContentResolver().notifyChange(uri, null);
+        verify(mClient).onMobileDataEnabledChange();
+    }
+
+    @Test
+    public void onMobileDataEnabledChange_doesNotFireAfterStop() {
+        mListener.start(SUB_ID_ONE);
+        mListener.stop();
+        final Uri uri = Settings.Global.getUriFor(Settings.Global.MOBILE_DATA + SUB_ID_ONE);
+        mContext.getContentResolver().notifyChange(uri, null);
+        verify(mClient, never()).onMobileDataEnabledChange();
+    }
+
+    @Test
+    public void onMobileDataEnabledChange_changedToDifferentId_firesCorrectly() {
+        mListener.start(SUB_ID_ONE);
+        mListener.stop();
+        mListener.start(SUB_ID_TWO);
+        final Uri uri = Settings.Global.getUriFor(Settings.Global.MOBILE_DATA + SUB_ID_TWO);
+        mContext.getContentResolver().notifyChange(uri, null);
+        verify(mClient).onMobileDataEnabledChange();
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/network/SubscriptionsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/SubscriptionsPreferenceControllerTest.java
index 26f26ff..d6edcc7 100644
--- a/tests/robotests/src/com/android/settings/network/SubscriptionsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/SubscriptionsPreferenceControllerTest.java
@@ -33,6 +33,9 @@
 import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkCapabilities;
 import android.provider.Settings;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
@@ -74,7 +77,13 @@
     @Mock
     private SubscriptionManager mSubscriptionManager;
     @Mock
+    private ConnectivityManager mConnectivityManager;
+    @Mock
     private TelephonyManager mTelephonyManager;
+    @Mock
+    private Network mActiveNetwork;
+    @Mock
+    private NetworkCapabilities mCapabilities;
 
     private Context mContext;
     private LifecycleOwner mLifecycleOwner;
@@ -90,7 +99,10 @@
         mLifecycleOwner = () -> mLifecycle;
         mLifecycle = new Lifecycle(mLifecycleOwner);
         when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(mSubscriptionManager);
+        when(mContext.getSystemService(ConnectivityManager.class)).thenReturn(mConnectivityManager);
         when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager);
+        when(mConnectivityManager.getActiveNetwork()).thenReturn(mActiveNetwork);
+        when(mConnectivityManager.getNetworkCapabilities(mActiveNetwork)).thenReturn(mCapabilities);
         when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mTelephonyManager);
         when(mScreen.findPreference(eq(KEY))).thenReturn(mPreferenceCategory);
         when(mPreferenceCategory.getContext()).thenReturn(mContext);
@@ -308,7 +320,8 @@
         ShadowSubscriptionManager.setDefaultDataSubscriptionId(11);
         ShadowSubscriptionManager.setDefaultSmsSubscriptionId(11);
         ShadowSubscriptionManager.setDefaultVoiceSubscriptionId(11);
-        when(mTelephonyManager.getDataState()).thenReturn(TelephonyManager.DATA_CONNECTED);
+        when(mTelephonyManager.isDataEnabled()).thenReturn(true);
+        when(mCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)).thenReturn(true);
 
         assertThat(mController.getSummary(11)).isEqualTo(
                 mContext.getString(R.string.default_for_calls_and_sms) + System.lineSeparator()
@@ -319,6 +332,27 @@
     }
 
     @Test
+    public void getSummary_twoSubsOneDefaultForEverythingDataNotActive() {
+        final SubscriptionInfo sub1 = mock(SubscriptionInfo.class);
+        final SubscriptionInfo sub2 = mock(SubscriptionInfo.class);
+        when(sub1.getSubscriptionId()).thenReturn(11);
+        when(sub2.getSubscriptionId()).thenReturn(22);
+        SubscriptionUtil.setActiveSubscriptionsForTesting(Arrays.asList(sub1, sub2));
+
+        ShadowSubscriptionManager.setDefaultDataSubscriptionId(11);
+        ShadowSubscriptionManager.setDefaultSmsSubscriptionId(11);
+        ShadowSubscriptionManager.setDefaultVoiceSubscriptionId(11);
+        when(mTelephonyManager.isDataEnabled()).thenReturn(true);
+
+        assertThat(mController.getSummary(11)).isEqualTo(
+                mContext.getString(R.string.default_for_calls_and_sms) + System.lineSeparator()
+                        + mContext.getString(R.string.default_for_mobile_data));
+
+        assertThat(mController.getSummary(22)).isEqualTo(
+                mContext.getString(R.string.subscription_available));
+    }
+
+    @Test
     public void getSummary_twoSubsOneDefaultForEverythingDataDisabled() {
         final SubscriptionInfo sub1 = mock(SubscriptionInfo.class);
         final SubscriptionInfo sub2 = mock(SubscriptionInfo.class);
@@ -329,7 +363,6 @@
         ShadowSubscriptionManager.setDefaultVoiceSubscriptionId(11);
         ShadowSubscriptionManager.setDefaultSmsSubscriptionId(11);
         ShadowSubscriptionManager.setDefaultDataSubscriptionId(11);
-        when(mTelephonyManager.getDataState()).thenReturn(TelephonyManager.DATA_DISCONNECTED);
         when(mTelephonyManager.isDataEnabled()).thenReturn(false);
 
         assertThat(mController.getSummary(11)).isEqualTo(
@@ -351,7 +384,6 @@
         ShadowSubscriptionManager.setDefaultDataSubscriptionId(11);
         ShadowSubscriptionManager.setDefaultSmsSubscriptionId(22);
         ShadowSubscriptionManager.setDefaultVoiceSubscriptionId(11);
-        when(mTelephonyManager.getDataState()).thenReturn(TelephonyManager.DATA_DISCONNECTED);
         when(mTelephonyManager.isDataEnabled()).thenReturn(true);
 
         assertThat(mController.getSummary(11)).isEqualTo(
diff --git a/tests/robotests/src/com/android/settings/network/telephony/MobileDataPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/MobileDataPreferenceControllerTest.java
index 30b5408..86f2355 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/MobileDataPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/MobileDataPreferenceControllerTest.java
@@ -33,6 +33,8 @@
 import androidx.fragment.app.FragmentTransaction;
 import androidx.preference.SwitchPreference;
 
+import com.android.settings.R;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -165,5 +167,19 @@
         mController.updateState(mPreference);
 
         assertThat(mPreference.isEnabled()).isFalse();
+        assertThat(mPreference.getSummary())
+                .isEqualTo(mContext.getString(R.string.mobile_data_settings_summary_auto_switch));
+    }
+
+    @Test
+    public void updateState_notOpportunistic_enabled() {
+        doReturn(mSubscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(SUB_ID);
+        mController.init(mFragmentManager, SUB_ID);
+        doReturn(false).when(mSubscriptionInfo).isOpportunistic();
+        mController.updateState(mPreference);
+
+        assertThat(mPreference.isEnabled()).isTrue();
+        assertThat(mPreference.getSummary())
+                .isEqualTo(mContext.getString(R.string.mobile_data_settings_summary));
     }
 }
diff --git a/tests/robotests/src/com/android/settings/network/telephony/RoamingPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/RoamingPreferenceControllerTest.java
index ce61a89..a883c51 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/RoamingPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/RoamingPreferenceControllerTest.java
@@ -18,9 +18,12 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 import android.content.Context;
 import android.os.PersistableBundle;
@@ -76,7 +79,7 @@
                 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
         doReturn(mFragmentTransaction).when(mFragmentManager).beginTransaction();
 
-        mPreference = new RestrictedSwitchPreference(mContext);
+        mPreference = spy(new RestrictedSwitchPreference(mContext));
         mController = new RoamingPreferenceController(mContext, "roaming");
         mController.init(mFragmentManager, SUB_ID);
         mPreference.setKey(mController.getPreferenceKey());
@@ -140,4 +143,22 @@
         assertThat(mPreference.isEnabled()).isTrue();
         assertThat(mPreference.isChecked()).isTrue();
     }
+
+    @Test
+    public void updateState_isNotDisabledByAdmin_shouldInvokeSetEnabled() {
+        when(mPreference.isDisabledByAdmin()).thenReturn(false);
+
+        mController.updateState(mPreference);
+
+        verify(mPreference).setEnabled(anyBoolean());
+    }
+
+    @Test
+    public void updateState_isDisabledByAdmin_shouldNotInvokeSetEnabled() {
+        when(mPreference.isDisabledByAdmin()).thenReturn(true);
+
+        mController.updateState(mPreference);
+
+        verify(mPreference, never()).setEnabled(anyBoolean());
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/webview/WebViewAppPickerTest.java b/tests/robotests/src/com/android/settings/webview/WebViewAppPickerTest.java
index 4bcc15f..10cf413 100644
--- a/tests/robotests/src/com/android/settings/webview/WebViewAppPickerTest.java
+++ b/tests/robotests/src/com/android/settings/webview/WebViewAppPickerTest.java
@@ -21,7 +21,6 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
@@ -36,11 +35,8 @@
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
-import android.content.pm.PackageItemInfo;
-import android.content.pm.PackageManager;
 import android.content.pm.UserInfo;
 import android.graphics.drawable.ColorDrawable;
-import android.os.UserManager;
 import android.webkit.UserPackage;
 
 import androidx.fragment.app.FragmentActivity;
@@ -49,17 +45,18 @@
 import com.android.settingslib.applications.DefaultAppInfo;
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
+import org.junit.After;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.Answers;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.Shadows;
+import org.robolectric.shadow.api.Shadow;
 import org.robolectric.shadows.ShadowPackageManager;
+import org.robolectric.shadows.ShadowUserManager;
 import org.robolectric.util.ReflectionHelpers;
 
 import java.util.Arrays;
@@ -68,34 +65,40 @@
 @RunWith(RobolectricTestRunner.class)
 public class WebViewAppPickerTest {
 
-    private final static String DEFAULT_PACKAGE_NAME = "DEFAULT_PACKAGE_NAME";
-
-    private Context mContext;
-
-    private UserInfo mFirstUser;
-    private UserInfo mSecondUser;
+    private final static String PACKAGE_NAME = "com.example.test";
+    private final static String PACKAGE_VERSION = "1.0.0";
 
     @Mock
     private FragmentActivity mActivity;
-    @Mock
-    private UserManager mUserManager;
-    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
-    private PackageManager mPackageManager;
 
+    private Context mContext;
+    private UserInfo mFirstUser;
+    private UserInfo mSecondUser;
+    private ShadowPackageManager mPackageManager;
     private WebViewAppPicker mPicker;
     private WebViewUpdateServiceWrapper mWvusWrapper;
-
-    private static ApplicationInfo createApplicationInfo(String packageName) {
-        ApplicationInfo ai = new ApplicationInfo();
-        ai.packageName = packageName;
-        return ai;
-    }
+    private ShadowUserManager mUserManager;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mContext = spy(RuntimeEnvironment.application);
-        doReturn(mUserManager).when(mContext).getSystemService(Context.USER_SERVICE);
+        mUserManager = Shadow.extract(mContext.getSystemService(Context.USER_SERVICE));
+        mPackageManager = Shadows.shadowOf(mContext.getPackageManager());
+
+        final ApplicationInfo applicationInfo = new ApplicationInfo();
+        applicationInfo.name = PACKAGE_NAME;
+        applicationInfo.uid = 0;
+        applicationInfo.flags = 0;
+        applicationInfo.packageName = PACKAGE_NAME;
+
+        final PackageInfo packageInfo = new PackageInfo();
+        packageInfo.packageName = PACKAGE_NAME;
+        packageInfo.applicationInfo = applicationInfo;
+        packageInfo.versionName = PACKAGE_VERSION;
+        mPackageManager.addPackage(packageInfo);
+        mPackageManager.setUnbadgedApplicationIcon(PACKAGE_NAME, new ColorDrawable());
+
         mFirstUser = new UserInfo(0, "FIRST_USER", 0);
         mSecondUser = new UserInfo(0, "SECOND_USER", 0);
         mPicker = new WebViewAppPicker();
@@ -104,13 +107,17 @@
         doNothing().when(mPicker).updateCheckedState(any());
         doReturn(mActivity).when(mPicker).getActivity();
 
-        ReflectionHelpers.setField(mPicker, "mPm", mPackageManager);
         ReflectionHelpers.setField(mPicker, "mMetricsFeatureProvider",
                 mock(MetricsFeatureProvider.class));
         mWvusWrapper = mock(WebViewUpdateServiceWrapper.class);
         mPicker.setWebViewUpdateServiceWrapper(mWvusWrapper);
     }
 
+    @After
+    public void tearDown() {
+        mPackageManager.removePackage(PACKAGE_NAME);
+    }
+
     @Test
     public void testClickingItemChangesProvider() {
         testSuccessfulClickChangesProvider();
@@ -134,105 +141,70 @@
         testFailingClick();
     }
 
-    private void useWebViewSettingIntent() {
-        Intent intent = new Intent(ACTION_WEBVIEW_SETTINGS);
-        when(mActivity.getIntent()).thenReturn(intent);
-    }
-
-    private void testSuccessfulClickChangesProvider() {
-        when(mWvusWrapper.getValidWebViewApplicationInfos(any()))
-                .thenReturn(Collections.singletonList(createApplicationInfo(DEFAULT_PACKAGE_NAME)));
-        when(mWvusWrapper.setWebViewProvider(eq(DEFAULT_PACKAGE_NAME))).thenReturn(true);
-
-        RadioButtonPreference defaultPackagePref = mock(RadioButtonPreference.class);
-        when(defaultPackagePref.getKey()).thenReturn(DEFAULT_PACKAGE_NAME);
-        mPicker.onRadioButtonClicked(defaultPackagePref);
-
-        verify(mWvusWrapper, times(1)).setWebViewProvider(eq(DEFAULT_PACKAGE_NAME));
-        verify(mPicker, times(1)).updateCheckedState(DEFAULT_PACKAGE_NAME);
-        verify(mWvusWrapper, never()).showInvalidChoiceToast(any());
-    }
-
-    private void testFailingClickUpdatesSetting() {
-        when(mWvusWrapper.getValidWebViewApplicationInfos(any()))
-                .thenReturn(Collections.singletonList(createApplicationInfo(DEFAULT_PACKAGE_NAME)));
-        when(mWvusWrapper.setWebViewProvider(eq(DEFAULT_PACKAGE_NAME))).thenReturn(false);
-
-        RadioButtonPreference defaultPackagePref = mock(RadioButtonPreference.class);
-        when(defaultPackagePref.getKey()).thenReturn(DEFAULT_PACKAGE_NAME);
-        mPicker.onRadioButtonClicked(defaultPackagePref);
-
-        verify(mWvusWrapper, times(1)).setWebViewProvider(eq(DEFAULT_PACKAGE_NAME));
-        // Ensure we update the list of packages when we click a non-valid package - the list must
-        // have changed, otherwise this click wouldn't fail.
-        verify(mPicker, times(1)).updateCandidates();
-        verify(mWvusWrapper, times(1)).showInvalidChoiceToast(any());
-    }
-
     @Test
-    @Ignore
     public void testDisabledPackageShownAsDisabled() {
-        DefaultAppInfo webviewAppInfo = mPicker.createDefaultAppInfo(mContext, mPackageManager,
-                createApplicationInfo(DEFAULT_PACKAGE_NAME), "disabled");
+        DefaultAppInfo webviewAppInfo = mPicker.createDefaultAppInfo(mContext,
+                mContext.getPackageManager(),
+                createApplicationInfo(PACKAGE_NAME), "disabled");
 
         RadioButtonPreference preference = mock(RadioButtonPreference.class);
-        mPicker.bindPreference(preference, DEFAULT_PACKAGE_NAME, webviewAppInfo, null);
-        mPicker.bindPreferenceExtra(preference, DEFAULT_PACKAGE_NAME, webviewAppInfo, null, null);
+        mPicker.bindPreference(preference, PACKAGE_NAME, webviewAppInfo, null);
+        mPicker.bindPreferenceExtra(preference, PACKAGE_NAME, webviewAppInfo, null, null);
         verify(preference, times(1)).setEnabled(eq(false));
         verify(preference, never()).setEnabled(eq(true));
     }
 
     @Test
-    @Ignore
     public void testEnabledPackageShownAsEnabled() {
         String disabledReason = "";
-        DefaultAppInfo webviewAppInfo = mPicker.createDefaultAppInfo(mContext, mPackageManager,
-                createApplicationInfo(DEFAULT_PACKAGE_NAME), disabledReason);
+        DefaultAppInfo webviewAppInfo = mPicker.createDefaultAppInfo(mContext,
+                mContext.getPackageManager(),
+                createApplicationInfo(PACKAGE_NAME), disabledReason);
 
         RadioButtonPreference preference = mock(RadioButtonPreference.class);
-        mPicker.bindPreference(preference, DEFAULT_PACKAGE_NAME, webviewAppInfo, null);
-        mPicker.bindPreferenceExtra(preference, DEFAULT_PACKAGE_NAME, webviewAppInfo, null, null);
+        mPicker.bindPreference(preference, PACKAGE_NAME, webviewAppInfo, null);
+        mPicker.bindPreferenceExtra(preference, PACKAGE_NAME, webviewAppInfo, null, null);
         verify(preference, times(1)).setEnabled(eq(true));
         verify(preference, never()).setEnabled(eq(false));
     }
 
     @Test
-    @Ignore
     public void testDisabledPackageShowsDisabledReasonSummary() {
         String disabledReason = "disabled";
-        DefaultAppInfo webviewAppInfo = mPicker.createDefaultAppInfo(mContext, mPackageManager,
-                createApplicationInfo(DEFAULT_PACKAGE_NAME), disabledReason);
+        DefaultAppInfo webviewAppInfo = mPicker.createDefaultAppInfo(mContext,
+                mContext.getPackageManager(),
+                createApplicationInfo(PACKAGE_NAME), disabledReason);
 
         RadioButtonPreference preference = mock(RadioButtonPreference.class);
-        mPicker.bindPreference(preference, DEFAULT_PACKAGE_NAME, webviewAppInfo, null);
-        mPicker.bindPreferenceExtra(preference, DEFAULT_PACKAGE_NAME, webviewAppInfo, null, null);
+        mPicker.bindPreference(preference, PACKAGE_NAME, webviewAppInfo, null);
+        mPicker.bindPreferenceExtra(preference, PACKAGE_NAME, webviewAppInfo, null, null);
         verify(preference, times(1)).setSummary(eq(disabledReason));
         // Ensure we haven't called setSummary several times.
         verify(preference, times(1)).setSummary(any());
     }
 
     @Test
-    @Ignore
     public void testEnabledPackageShowsEmptySummary() {
-        DefaultAppInfo webviewAppInfo = mPicker.createDefaultAppInfo(mContext, mPackageManager,
-                createApplicationInfo(DEFAULT_PACKAGE_NAME), null);
+        DefaultAppInfo webviewAppInfo = mPicker.createDefaultAppInfo(mContext,
+                mContext.getPackageManager(),
+                createApplicationInfo(PACKAGE_NAME), null);
 
         RadioButtonPreference preference = mock(RadioButtonPreference.class);
-        mPicker.bindPreference(preference, DEFAULT_PACKAGE_NAME, webviewAppInfo, null);
-        mPicker.bindPreferenceExtra(preference, DEFAULT_PACKAGE_NAME, webviewAppInfo, null, null);
+        mPicker.bindPreference(preference, PACKAGE_NAME, webviewAppInfo, null);
+        mPicker.bindPreferenceExtra(preference, PACKAGE_NAME, webviewAppInfo, null, null);
         verify(preference, never()).setSummary(any());
     }
 
     @Test
     public void testFinishIfNotAdmin() {
-        doReturn(false).when(mUserManager).isAdminUser();
+        mUserManager.setIsAdminUser(false);
         mPicker.onAttach(mContext);
         verify(mActivity, times(1)).finish();
     }
 
     @Test
     public void testNotFinishedIfAdmin() {
-        doReturn(true).when(mUserManager).isAdminUser();
+        mUserManager.setIsAdminUser(true);
         mPicker.onAttach(mContext);
         verify(mActivity, never()).finish();
     }
@@ -248,10 +220,10 @@
         when(packageForSecondUser.isInstalledPackage()).thenReturn(true);
 
         WebViewUpdateServiceWrapper wvusWrapper = mock(WebViewUpdateServiceWrapper.class);
-        when(wvusWrapper.getPackageInfosAllUsers(any(), eq(DEFAULT_PACKAGE_NAME)))
+        when(wvusWrapper.getPackageInfosAllUsers(any(), eq(PACKAGE_NAME)))
                 .thenReturn(Arrays.asList(packageForFirstUser, packageForSecondUser));
 
-        assertThat(mPicker.getDisabledReason(wvusWrapper, mContext, DEFAULT_PACKAGE_NAME)).isNull();
+        assertThat(mPicker.getDisabledReason(wvusWrapper, mContext, PACKAGE_NAME)).isNull();
     }
 
     @Test
@@ -262,11 +234,11 @@
         when(packageForFirstUser.getUserInfo()).thenReturn(mFirstUser);
 
         WebViewUpdateServiceWrapper wvusWrapper = mock(WebViewUpdateServiceWrapper.class);
-        when(wvusWrapper.getPackageInfosAllUsers(any(), eq(DEFAULT_PACKAGE_NAME)))
+        when(wvusWrapper.getPackageInfosAllUsers(any(), eq(PACKAGE_NAME)))
                 .thenReturn(Collections.singletonList(packageForFirstUser));
 
         final String expectedReason = String.format("(disabled for user %s)", mFirstUser.name);
-        assertThat(mPicker.getDisabledReason(wvusWrapper, mContext, DEFAULT_PACKAGE_NAME))
+        assertThat(mPicker.getDisabledReason(wvusWrapper, mContext, PACKAGE_NAME))
                 .isEqualTo(expectedReason);
     }
 
@@ -278,11 +250,11 @@
         when(packageForFirstUser.getUserInfo()).thenReturn(mFirstUser);
 
         WebViewUpdateServiceWrapper wvusWrapper = mock(WebViewUpdateServiceWrapper.class);
-        when(wvusWrapper.getPackageInfosAllUsers(any(), eq(DEFAULT_PACKAGE_NAME)))
+        when(wvusWrapper.getPackageInfosAllUsers(any(), eq(PACKAGE_NAME)))
                 .thenReturn(Collections.singletonList(packageForFirstUser));
 
         final String expectedReason = String.format("(uninstalled for user %s)", mFirstUser.name);
-        assertThat(mPicker.getDisabledReason(wvusWrapper, mContext, DEFAULT_PACKAGE_NAME))
+        assertThat(mPicker.getDisabledReason(wvusWrapper, mContext, PACKAGE_NAME))
                 .isEqualTo(expectedReason);
     }
 
@@ -299,11 +271,11 @@
         when(packageForSecondUser.getUserInfo()).thenReturn(mSecondUser);
 
         WebViewUpdateServiceWrapper wvusWrapper = mock(WebViewUpdateServiceWrapper.class);
-        when(wvusWrapper.getPackageInfosAllUsers(any(), eq(DEFAULT_PACKAGE_NAME)))
+        when(wvusWrapper.getPackageInfosAllUsers(any(), eq(PACKAGE_NAME)))
                 .thenReturn(Arrays.asList(packageForFirstUser, packageForSecondUser));
 
         final String expectedReason = String.format("(disabled for user %s)", mFirstUser.name);
-        assertThat(mPicker.getDisabledReason(wvusWrapper, mContext, DEFAULT_PACKAGE_NAME))
+        assertThat(mPicker.getDisabledReason(wvusWrapper, mContext, PACKAGE_NAME))
                 .isEqualTo(expectedReason);
     }
 
@@ -324,11 +296,11 @@
         when(packageForSecondUser.getUserInfo()).thenReturn(mSecondUser);
 
         WebViewUpdateServiceWrapper wvusWrapper = mock(WebViewUpdateServiceWrapper.class);
-        when(wvusWrapper.getPackageInfosAllUsers(any(), eq(DEFAULT_PACKAGE_NAME)))
+        when(wvusWrapper.getPackageInfosAllUsers(any(), eq(PACKAGE_NAME)))
                 .thenReturn(Arrays.asList(packageForFirstUser, packageForSecondUser));
 
         final String expectedReason = String.format("(uninstalled for user %s)", mFirstUser.name);
-        assertThat(mPicker.getDisabledReason(wvusWrapper, mContext, DEFAULT_PACKAGE_NAME))
+        assertThat(mPicker.getDisabledReason(wvusWrapper, mContext, PACKAGE_NAME))
                 .isEqualTo(expectedReason);
     }
 
@@ -337,29 +309,58 @@
      * preference title.
      */
     @Test
-    public void testWebViewVersionAddedAfterLabel() throws PackageManager.NameNotFoundException {
-        PackageItemInfo mockPackageItemInfo = mock(PackageItemInfo.class);
-        mockPackageItemInfo.packageName = DEFAULT_PACKAGE_NAME;
-        when(mockPackageItemInfo.loadLabel(any())).thenReturn("myPackage");
-        DefaultAppInfo webviewAppInfo = mPicker.createDefaultAppInfo(mContext, mPackageManager,
-                mockPackageItemInfo, "" /* disabledReason */);
+    public void testWebViewVersionAddedAfterLabel() {
+        final DefaultAppInfo webviewAppInfo = mPicker.createDefaultAppInfo(mContext,
+                mContext.getPackageManager(),
+                createApplicationInfo(PACKAGE_NAME), "" /* disabledReason */);
 
-        PackageInfo packageInfo = new PackageInfo();
-        packageInfo.versionName = "myVersionName";
-        when(mPackageManager.getPackageInfo(eq(DEFAULT_PACKAGE_NAME), anyInt())).thenReturn(
-                packageInfo);
+        final RadioButtonPreference mockPreference = mock(RadioButtonPreference.class);
+        mPicker.bindPreference(mockPreference, PACKAGE_NAME, webviewAppInfo, null);
+        mPicker.bindPreferenceExtra(
+                mockPreference, PACKAGE_NAME, webviewAppInfo, null, null);
 
-        // Subvert attempts to load an unbadged icon for the application.
-        PackageManager pm = RuntimeEnvironment.application.getPackageManager();
-        ShadowPackageManager spm = Shadows.shadowOf(pm);
-        spm.setUnbadgedApplicationIcon(DEFAULT_PACKAGE_NAME, new ColorDrawable());
+        verify(mockPreference).setTitle(eq(PACKAGE_NAME + " " + PACKAGE_VERSION));
+        verify(mockPreference).setTitle(any());
+    }
 
-        RadioButtonPreference mockPreference = mock(RadioButtonPreference.class);
-        mPicker.bindPreference(mockPreference, DEFAULT_PACKAGE_NAME, webviewAppInfo, null);
-        mPicker
-                .bindPreferenceExtra(mockPreference, DEFAULT_PACKAGE_NAME, webviewAppInfo, null,
-                        null);
-        verify(mockPreference, times(1)).setTitle(eq("myPackage myVersionName"));
-        verify(mockPreference, times(1)).setTitle(any());
+    private static ApplicationInfo createApplicationInfo(String packageName) {
+        ApplicationInfo ai = new ApplicationInfo();
+        ai.packageName = packageName;
+        return ai;
+    }
+
+    private void useWebViewSettingIntent() {
+        Intent intent = new Intent(ACTION_WEBVIEW_SETTINGS);
+        when(mActivity.getIntent()).thenReturn(intent);
+    }
+
+    private void testSuccessfulClickChangesProvider() {
+        when(mWvusWrapper.getValidWebViewApplicationInfos(any()))
+                .thenReturn(Collections.singletonList(createApplicationInfo(PACKAGE_NAME)));
+        when(mWvusWrapper.setWebViewProvider(eq(PACKAGE_NAME))).thenReturn(true);
+
+        RadioButtonPreference defaultPackagePref = mock(RadioButtonPreference.class);
+        when(defaultPackagePref.getKey()).thenReturn(PACKAGE_NAME);
+        mPicker.onRadioButtonClicked(defaultPackagePref);
+
+        verify(mWvusWrapper, times(1)).setWebViewProvider(eq(PACKAGE_NAME));
+        verify(mPicker, times(1)).updateCheckedState(PACKAGE_NAME);
+        verify(mWvusWrapper, never()).showInvalidChoiceToast(any());
+    }
+
+    private void testFailingClickUpdatesSetting() {
+        when(mWvusWrapper.getValidWebViewApplicationInfos(any()))
+                .thenReturn(Collections.singletonList(createApplicationInfo(PACKAGE_NAME)));
+        when(mWvusWrapper.setWebViewProvider(eq(PACKAGE_NAME))).thenReturn(false);
+
+        RadioButtonPreference defaultPackagePref = mock(RadioButtonPreference.class);
+        when(defaultPackagePref.getKey()).thenReturn(PACKAGE_NAME);
+        mPicker.onRadioButtonClicked(defaultPackagePref);
+
+        verify(mWvusWrapper, times(1)).setWebViewProvider(eq(PACKAGE_NAME));
+        // Ensure we update the list of packages when we click a non-valid package - the list must
+        // have changed, otherwise this click wouldn't fail.
+        verify(mPicker, times(1)).updateCandidates();
+        verify(mWvusWrapper, times(1)).showInvalidChoiceToast(any());
     }
 }
diff --git a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java
index 38211b3..de78828 100644
--- a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java
+++ b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java
@@ -175,4 +175,40 @@
         assertThat(restoredWifiNetworkConfig.getNetworkId()).isEqualTo(0);
         assertThat(restoredWifiNetworkConfig.isHotspot()).isTrue();
     }
+
+    @Test
+    public void launchScanner_onNavigateUp_shouldFinish() {
+        Intent intent = new Intent(WifiDppConfiguratorActivity.ACTION_CONFIGURATOR_QR_CODE_SCANNER);
+        intent.putExtra(WifiDppUtils.EXTRA_WIFI_SECURITY, "WEP");
+        intent.putExtra(WifiDppUtils.EXTRA_WIFI_SSID, "GoogleGuest");
+        intent.putExtra(WifiDppUtils.EXTRA_WIFI_PRE_SHARED_KEY, "password");
+        final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+
+        mActivityRule.launchActivity(intent);
+
+        instrumentation.runOnMainSync(() -> {
+            mActivityRule.getActivity().onNavigateUp();
+
+            assertThat(mActivityRule.getActivity().isFinishing()).isEqualTo(true);
+        });
+    }
+
+    @Test
+    public void launchGenerator_onNavigateUp_shouldFinish() {
+        Intent intent = new Intent(
+                WifiDppConfiguratorActivity.ACTION_CONFIGURATOR_QR_CODE_GENERATOR);
+        intent.putExtra(WifiDppUtils.EXTRA_WIFI_SECURITY, "WEP");
+        intent.putExtra(WifiDppUtils.EXTRA_WIFI_SSID, "GoogleGuest");
+        intent.putExtra(WifiDppUtils.EXTRA_WIFI_PRE_SHARED_KEY, "password");
+        final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+
+        mActivityRule.launchActivity(intent);
+
+        instrumentation.runOnMainSync(() -> {
+            mActivityRule.getActivity().onNavigateUp();
+
+            assertThat(mActivityRule.getActivity().isFinishing()).isEqualTo(true);
+        });
+    }
+
 }