Merge "Add dev option to force desktop mode"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index efa57de..eb3be0e 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -911,7 +911,7 @@
 
         <activity android:name=".Settings$MyDeviceInfoActivity"
                   android:label="@string/about_settings"
-                  android:icon="@drawable/ic_settings_about"
+                  android:icon="@drawable/ic_homepage_about"
                   android:parentActivityName="Settings">
             <intent-filter android:priority="1">
                 <action android:name="android.settings.DEVICE_INFO_SETTINGS" />
@@ -922,14 +922,6 @@
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="com.android.settings.SHORTCUT" />
             </intent-filter>
-            <intent-filter>
-                <action android:name="com.android.settings.action.SETTINGS" />
-            </intent-filter>
-            <meta-data android:name="com.android.settings.order" android:value="-270"/>
-            <meta-data android:name="com.android.settings.category"
-                       android:value="com.android.settings.category.ia.system" />
-            <meta-data android:name="com.android.settings.title"
-                       android:resource="@string/about_settings" />
             <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
                        android:value="com.android.settings.deviceinfo.aboutphone.MyDeviceInfoFragment" />
             <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
@@ -2962,16 +2954,6 @@
                        android:value="true" />
         </activity>
 
-        <activity android:name="Settings$DirectoryAccessSettingsActivity"
-                android:label="@string/directory_access">
-            <intent-filter>
-                <action android:name="android.settings.STORAGE_VOLUME_ACCESS_SETTINGS" />
-                <category android:name="android.intent.category.DEFAULT" />
-            </intent-filter>
-            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
-                android:value="com.android.settings.applications.manageapplications.ManageApplications" />
-        </activity>
-
         <provider android:name=".slices.SettingsSliceProvider"
                   android:authorities="com.android.settings.slices;android.settings.slices"
                   android:exported="true"
diff --git a/color-check-baseline.xml b/color-check-baseline.xml
index d28f2d1..3672e2d 100644
--- a/color-check-baseline.xml
+++ b/color-check-baseline.xml
@@ -1029,7 +1029,7 @@
         priority="4"
         summary="Using hardcoded color"
         explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.&#xA;This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
-        errorLine1="    &lt;color name=&quot;homepage_connected_device_background&quot;>#71A234&lt;/color>"
+        errorLine1="    &lt;color name=&quot;homepage_connected_device_background&quot;>#72B70F&lt;/color>"
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
@@ -1077,7 +1077,7 @@
         priority="4"
         summary="Using hardcoded color"
         explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.&#xA;This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
-        errorLine1="    &lt;color name=&quot;homepage_display_background&quot;>#FFB600&lt;/color>"
+        errorLine1="    &lt;color name=&quot;homepage_display_background&quot;>#FFA727&lt;/color>"
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
@@ -1173,7 +1173,7 @@
         priority="4"
         summary="Using hardcoded color"
         explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.&#xA;This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
-        errorLine1="    &lt;color name=&quot;homepage_system_background&quot;>#757575&lt;/color>"
+        errorLine1="    &lt;color name=&quot;homepage_system_background&quot;>#9E9E9E&lt;/color>"
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
@@ -1237,11 +1237,27 @@
         priority="4"
         summary="Using hardcoded color"
         explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.&#xA;This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
+        errorLine1="    &lt;color name=&quot;homepage_about_background&quot;>#9FA8DA&lt;/color>"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/values/colors.xml"
+            line="129"
+            column="5"/>
+    </issue>
+
+    <issue
+        id="HardCodedColor"
+        severity="Error"
+        message="Avoid using hardcoded color"
+        category="Correctness"
+        priority="4"
+        summary="Using hardcoded color"
+        explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.&#xA;This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
         errorLine1="    &lt;color name=&quot;battery_good_color_light&quot;>#43a047&lt;/color> &lt;!-- Material Green 600 -->"
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="133"
+            line="134"
             column="5"/>
     </issue>
 
@@ -1257,7 +1273,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="134"
+            line="135"
             column="5"/>
     </issue>
 
@@ -1273,7 +1289,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="135"
+            line="136"
             column="5"/>
     </issue>
 
@@ -1289,7 +1305,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="136"
+            line="137"
             column="5"/>
     </issue>
 
@@ -1305,7 +1321,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="137"
+            line="138"
             column="5"/>
     </issue>
 
@@ -1321,7 +1337,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="138"
+            line="139"
             column="5"/>
     </issue>
 
@@ -1337,7 +1353,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="141"
+            line="142"
             column="5"/>
     </issue>
 
@@ -1353,7 +1369,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="142"
+            line="143"
             column="5"/>
     </issue>
 
@@ -1369,7 +1385,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="143"
+            line="144"
             column="5"/>
     </issue>
 
@@ -1385,7 +1401,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="144"
+            line="145"
             column="5"/>
     </issue>
 
@@ -1401,7 +1417,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="145"
+            line="146"
             column="5"/>
     </issue>
 
@@ -1701,6 +1717,22 @@
         priority="4"
         summary="Using hardcoded color"
         explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.&#xA;This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
+        errorLine1="                android:color=&quot;@color/homepage_about_background&quot; />"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/drawable/ic_homepage_about.xml"
+            line="23"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="HardCodedColor"
+        severity="Error"
+        message="Avoid using hardcoded color"
+        category="Correctness"
+        priority="4"
+        summary="Using hardcoded color"
+        explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.&#xA;This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
         errorLine1="                android:color=&quot;@color/homepage_accessibility_background&quot; />"
         errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
diff --git a/res/drawable/ic_homepage_about.xml b/res/drawable/ic_homepage_about.xml
new file mode 100644
index 0000000..d47a740
--- /dev/null
+++ b/res/drawable/ic_homepage_about.xml
@@ -0,0 +1,36 @@
+<?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.
+  -->
+
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item>
+        <shape android:shape="oval">
+            <solid
+                android:color="@color/homepage_about_background" />
+            <size
+                android:width="@dimen/dashboard_tile_image_size"
+                android:height="@dimen/dashboard_tile_image_size" />
+        </shape>
+    </item>
+
+    <item
+        android:width="@dimen/dashboard_tile_foreground_image_size"
+        android:height="@dimen/dashboard_tile_foreground_image_size"
+        android:start="@dimen/dashboard_tile_foreground_image_inset"
+        android:top="@dimen/dashboard_tile_foreground_image_inset"
+        android:drawable="@drawable/ic_phone_info" />
+</layer-list>
diff --git a/res/drawable/ic_phone_info.xml b/res/drawable/ic_phone_info.xml
new file mode 100644
index 0000000..7aee3e8
--- /dev/null
+++ b/res/drawable/ic_phone_info.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M17,1.01L7,1C5.9,1 5,1.9 5,3v18c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2V3C19,1.9 18.1,1.01 17,1.01zM17,21H7v-1h10V21zM17,18H7V6h10V18zM7,4V3h10v1H7zM11,7h2v2h-2V7zM11,11h2v6h-2V11z"/>
+</vector>
diff --git a/res/layout-sw320dp/settings_entity_header.xml b/res/layout-sw320dp/settings_entity_header.xml
deleted file mode 100644
index 9a46adf..0000000
--- a/res/layout-sw320dp/settings_entity_header.xml
+++ /dev/null
@@ -1,113 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2016 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-
-<!-- Entity header -->
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/entity_header"
-    style="@style/EntityHeader"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:paddingTop="24dp"
-    android:paddingBottom="24dp">
-
-    <LinearLayout
-        android:id="@+id/entity_header_content"
-        android:layout_width="0dp"
-        android:layout_height="wrap_content"
-        android:layout_weight="1"
-        android:background="?android:attr/selectableItemBackground"
-        android:orientation="horizontal"
-        android:paddingStart="56dp">
-
-        <ImageView
-            android:id="@+id/entity_header_icon"
-            android:layout_width="48dp"
-            android:layout_height="48dp"
-            android:scaleType="fitCenter"
-            android:layout_gravity="center_horizontal"
-            android:antialias="true" />
-
-        <LinearLayout
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center_vertical"
-            android:paddingStart="16dp"
-            android:paddingEnd="16dp"
-            android:orientation="vertical">
-
-            <TextView
-                android:id="@+id/entity_header_title"
-                style="@style/TextAppearance.EntityHeaderTitle"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:singleLine="false"
-                android:ellipsize="marquee"
-                android:gravity="start"
-                android:textDirection="locale" />
-
-            <TextView
-                android:id="@+id/install_type"
-                style="@style/TextAppearance.EntityHeaderSummary"
-                android:visibility="gone"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"/>
-
-            <TextView
-                android:id="@+id/entity_header_summary"
-                style="@style/TextAppearance.EntityHeaderSummary"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content" />
-
-            <TextView
-                android:id="@+id/entity_header_second_summary"
-                style="@style/TextAppearance.EntityHeaderSummary"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content" />
-
-        </LinearLayout>
-    </LinearLayout>
-
-    <LinearLayout
-        android:id="@+id/entity_header_links"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:orientation="vertical">
-
-        <ImageButton
-            android:id="@android:id/button1"
-            style="?android:attr/actionOverflowButtonStyle"
-            android:layout_width="wrap_content"
-            android:layout_weight="1"
-            android:layout_height="0dp"
-            android:minWidth="@dimen/min_tap_target_size"
-            android:src="@null"
-            android:tint="?android:attr/colorAccent" />
-
-        <ImageButton
-            android:id="@android:id/button2"
-            style="?android:attr/actionOverflowButtonStyle"
-            android:layout_width="wrap_content"
-            android:layout_weight="1"
-            android:layout_height="0dp"
-            android:minWidth="@dimen/min_tap_target_size"
-            android:src="@null"
-            android:tint="?android:attr/colorAccent" />
-
-    </LinearLayout>
-
-</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/admin_support_details_dialog.xml b/res/layout/admin_support_details_dialog.xml
index 8c33b1a..922451f 100644
--- a/res/layout/admin_support_details_dialog.xml
+++ b/res/layout/admin_support_details_dialog.xml
@@ -27,8 +27,6 @@
         <ImageView android:id="@+id/admin_support_icon"
                 android:layout_width="@dimen/admin_details_dialog_icon_size"
                 android:layout_height="@dimen/admin_details_dialog_icon_size"
-                android:tint="?android:attr/colorAccent"
-                android:src="@*android:drawable/ic_info"
                 android:scaleType="fitCenter"
                 android:contentDescription="@null" />
         <TextView android:id="@+id/admin_support_dialog_title"
diff --git a/res/layout/homepage_condition_full_tile.xml b/res/layout/homepage_condition_full_tile.xml
index f00132b..415defc 100644
--- a/res/layout/homepage_condition_full_tile.xml
+++ b/res/layout/homepage_condition_full_tile.xml
@@ -24,16 +24,18 @@
     <LinearLayout
         android:id="@+id/content"
         android:layout_width="match_parent"
-        android:layout_height="@dimen/homepage_condition_full_card_height"
+        android:layout_height="wrap_content"
         android:paddingStart="@dimen/homepage_card_padding_start"
         android:paddingEnd="@dimen/homepage_card_padding_end"
+        android:paddingTop="@dimen/homepage_condition_full_card_padding_top"
+        android:paddingBottom="@dimen/homepage_condition_full_card_padding_bottom"
         android:orientation="horizontal"
         android:gravity="center_vertical">
 
         <ImageView
             android:id="@android:id/icon"
-            android:layout_width="@dimen/suggestion_card_icon_size"
-            android:layout_height="@dimen/suggestion_card_icon_size"
+            android:layout_width="@dimen/homepage_card_icon_size"
+            android:layout_height="@dimen/homepage_card_icon_size"
             android:tint="?android:attr/colorAccent"/>
 
         <LinearLayout
@@ -59,13 +61,7 @@
 
         </LinearLayout>
 
-        <View
-            android:id="@+id/divider"
-            android:layout_width="@dimen/homepage_condition_full_card_divider_width"
-            android:layout_height="match_parent"
-            android:layout_marginTop="@dimen/homepage_condition_full_card_divider_padding_top"
-            android:layout_marginBottom="@dimen/homepage_condition_full_card_divider_padding_bottom"
-            android:background="?android:attr/dividerVertical" />
+        <include layout="@layout/vertical_divider"/>
 
         <Button
             android:id="@+id/first_action"
diff --git a/res/layout/homepage_condition_half_tile.xml b/res/layout/homepage_condition_half_tile.xml
index 9cde951..0b7eec7 100644
--- a/res/layout/homepage_condition_half_tile.xml
+++ b/res/layout/homepage_condition_half_tile.xml
@@ -32,14 +32,16 @@
 
         <ImageView
             android:id="@android:id/icon"
-            android:layout_width="@dimen/suggestion_card_icon_size"
-            android:layout_height="@dimen/suggestion_card_icon_size"
+            android:layout_width="@dimen/homepage_card_icon_size"
+            android:layout_height="@dimen/homepage_card_icon_size"
             android:tint="?android:attr/colorAccent"/>
 
         <TextView
             android:id="@android:id/title"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
+            android:maxLines="1"
+            android:ellipsize="end"
             android:layout_marginTop="@dimen/homepage_condition_half_card_title_margin_top"
             android:layout_marginBottom="@dimen/homepage_condition_card_title_margin_bottom"
             style="@style/TextAppearance.ConditionCardTitle"/>
@@ -48,6 +50,9 @@
             android:id="@android:id/summary"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
+            android:maxLines="1"
+            android:ellipsize="end"
+            android:layout_marginBottom="@dimen/homepage_condition_half_card_summary_margin_bottom"
             style="@style/TextAppearance.ConditionCardSummary"/>
 
         <include layout="@layout/horizontal_divider"/>
diff --git a/res/layout/homepage_suggestion_tile.xml b/res/layout/homepage_suggestion_tile.xml
new file mode 100644
index 0000000..36ad45c
--- /dev/null
+++ b/res/layout/homepage_suggestion_tile.xml
@@ -0,0 +1,70 @@
+<?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.
+  -->
+
+<androidx.cardview.widget.CardView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/suggestion_card"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    style="@style/ContextualCardStyle">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:minHeight="112dp"
+        android:paddingBottom="8dp"
+        android:orientation="vertical">
+
+        <RelativeLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal">
+
+            <ImageView
+                android:id="@android:id/icon"
+                android:layout_width="@dimen/homepage_card_icon_size"
+                android:layout_height="@dimen/homepage_card_icon_size"
+                style="@style/SuggestionCardIcon"
+                android:layout_marginTop="16dp"
+                android:layout_marginBottom="6dp"/>
+
+        </RelativeLayout>
+
+        <TextView
+            android:id="@android:id/title"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            style="@style/SuggestionCardText"
+            android:layout_marginStart="12dp"
+            android:layout_marginEnd="12dp"
+            android:singleLine="true"
+            android:textAppearance="@style/TextAppearance.SuggestionTitle"
+            android:fadingEdge="horizontal"/>
+
+        <TextView
+            android:id="@android:id/summary"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            style="@style/SuggestionCardText"
+            android:layout_marginStart="12dp"
+            android:layout_marginEnd="12dp"
+            android:singleLine="true"
+            android:textAppearance="@style/TextAppearance.SuggestionSummary"/>
+
+    </LinearLayout>
+
+</androidx.cardview.widget.CardView>
\ No newline at end of file
diff --git a/res/layout/settings_entity_header.xml b/res/layout/settings_entity_header.xml
index 6698f3f..5f5fe00 100644
--- a/res/layout/settings_entity_header.xml
+++ b/res/layout/settings_entity_header.xml
@@ -16,60 +16,58 @@
   -->
 
 <!-- Entity header -->
-<LinearLayout
+<RelativeLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/entity_header"
     style="@style/EntityHeader"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:paddingStart="@dimen/preference_no_icon_padding_start"
-    android:paddingTop="24dp"
-    android:paddingBottom="32dp"
     android:orientation="horizontal">
 
     <LinearLayout
         android:id="@+id/entity_header_content"
-        android:layout_width="0dp"
+        android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_weight="1"
-        android:background="?android:attr/selectableItemBackground"
+        android:layout_centerHorizontal="true"
+        android:gravity="center_horizontal"
         android:orientation="vertical">
 
         <ImageView
             android:id="@+id/entity_header_icon"
             android:layout_width="48dp"
             android:layout_height="48dp"
-            android:layout_marginBottom="16dp"
             android:scaleType="fitXY"
-            android:antialias="true" />
+            android:antialias="true"/>
 
         <TextView
             android:id="@+id/entity_header_title"
             style="@style/TextAppearance.EntityHeaderTitle"
-            android:layout_width="match_parent"
+            android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:singleLine="false"
             android:ellipsize="marquee"
-            android:gravity="start"
-            android:textDirection="locale" />
+            android:textDirection="locale"
+            android:layout_marginTop="8dp"/>
 
         <TextView
             android:id="@+id/install_type"
             style="@style/TextAppearance.EntityHeaderSummary"
             android:visibility="gone"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content" />
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="2dp"/>
 
         <TextView
             android:id="@+id/entity_header_summary"
             style="@style/TextAppearance.EntityHeaderSummary"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content" />
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="2dp"/>
 
         <TextView
             android:id="@+id/entity_header_second_summary"
             style="@style/TextAppearance.EntityHeaderSummary"
-            android:layout_width="match_parent"
+            android:layout_width="wrap_content"
             android:layout_height="wrap_content" />
 
     </LinearLayout>
@@ -78,6 +76,8 @@
         android:id="@+id/entity_header_links"
         android:layout_width="wrap_content"
         android:layout_height="match_parent"
+        android:layout_centerVertical="true"
+        android:layout_alignParentEnd="true"
         android:orientation="vertical">
 
         <ImageButton
@@ -102,4 +102,4 @@
 
     </LinearLayout>
 
-</LinearLayout>
+</RelativeLayout>
diff --git a/res/xml/directory_access_details.xml b/res/layout/vertical_divider.xml
similarity index 65%
rename from res/xml/directory_access_details.xml
rename to res/layout/vertical_divider.xml
index 4448ba6..4f1cc43 100644
--- a/res/xml/directory_access_details.xml
+++ b/res/layout/vertical_divider.xml
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 The Android Open Source Project
+<!--
+     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.
@@ -14,7 +15,9 @@
      limitations under the License.
 -->
 
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
-        xmlns:settings="http://schemas.android.com/apk/res-auto"
-        android:key="directory_access_details"
-        android:title="@string/directory_access"/>
+<View
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/divider"
+    android:layout_width="@dimen/vertical_divider_width"
+    android:layout_height="match_parent"
+    android:background="?android:attr/dividerVertical"/>
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index 94d915c..c3faaba 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -215,10 +215,12 @@
     <string-array name="wifi_security">
         <!-- The Wi-Fi network does not have any security. -->
         <item>@string/wifi_security_none</item>
+        <item translatable="false">@string/wifi_security_owe</item>
         <item translatable="false">@string/wifi_security_wep</item>
         <item translatable="false">@string/wifi_security_psk_generic</item>
+        <item translatable="false">@string/wifi_security_sae</item>
         <item translatable="false">@string/wifi_security_eap</item>
-
+        <item translatable="false">@string/wifi_security_eap_suiteb</item>
     </string-array>
 
     <!-- Match this with the constants in AccessPoint. --> <skip />
@@ -228,6 +230,7 @@
         <item>@string/wifi_security_none</item>
         <item translatable="false">@string/wifi_security_wep</item>
         <item translatable="false">@string/wifi_security_psk_generic</item>
+        <item translatable="false">@string/wifi_security_sae</item>
     </string-array>
 
     <!-- Security types for wireless tether -->
diff --git a/res/values/colors.xml b/res/values/colors.xml
index a00fd8a..11c1aaf 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -113,19 +113,20 @@
 
     <!-- Dashboard/homepage icon background colors -->
     <color name="homepage_network_background">#2196F3</color>
-    <color name="homepage_connected_device_background">#71A234</color>
+    <color name="homepage_connected_device_background">#72B70F</color>
     <color name="homepage_app_and_notification_background">#FF7E0F</color>
     <color name="homepage_battery_background">#258982</color>
-    <color name="homepage_display_background">#FFB600</color>
+    <color name="homepage_display_background">#FFA727</color>
     <color name="homepage_sound_background">#01B1AF</color>
     <color name="homepage_storage_background">#C14CE6</color>
     <color name="homepage_security_background">#0F9D58</color>
     <color name="homepage_accounts_background">#F15B8D</color>
     <color name="homepage_accessibility_background">#5011C1</color>
-    <color name="homepage_system_background">#757575</color>
+    <color name="homepage_system_background">#9E9E9E</color>
     <color name="homepage_support_background">#26459C</color>
     <color name="homepage_generic_icon_background">#1A73E8</color>
     <color name="homepage_location_background">#2EC7DC</color>
+    <color name="homepage_about_background">#9FA8DA</color>
     <!-- End of dashboard/homepage icon background colors -->
 
     <color name="glif_error_color">@*android:color/material_red_A700</color>
diff --git a/res/values/config.xml b/res/values/config.xml
index b496080..a9fe35d 100755
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -134,14 +134,15 @@
          have distinct intensity levels -->
     <bool name="config_vibration_supports_multiple_intensities">false</bool>
 
+    <!--
+        Whether or not the homepage should be powered by legacy suggestion (versus contextual cards)
+        Default to true as not all devices support contextual cards.
+    -->
+    <bool name="config_use_legacy_suggestion">true</bool>
+
+    <!-- Whether or not homepage should display user's account avatar -->
+    <bool name="config_show_avatar_in_homepage">false</bool>
+
     <!-- Whether or not TopLevelSettings should force rounded icon for injected tiles -->
     <bool name="config_force_rounded_icon_TopLevelSettings">true</bool>
-
-    <!-- TODO(b/115429501): move those 3 configs to framework-->
-    <!-- Show enabled lte option for lte device -->
-    <bool name="config_enabled_lte" translatable="false">false</bool>
-    <!-- Show enabled tdscdma option for device -->
-    <bool name="config_support_tdscdma" translatable="false">false</bool>
-    <!-- Show enabled tdscdma option for device when connect roaming network -->
-    <string-array name="config_support_tdscdma_roaming_on_networks" translatable="false"></string-array>
 </resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index c91ffb5..caaea90 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -303,17 +303,6 @@
     <dimen name="suggestion_condition_header_padding_expanded">5dp</dimen>
     <dimen name="condition_header_height">36dp</dimen>
 
-    <!-- Suggestion cards size and padding -->
-    <dimen name="suggestion_card_icon_size">24dp</dimen>
-    <dimen name="suggestion_card_outer_margin">14dp</dimen>
-    <dimen name="suggestion_card_inner_margin">12dp</dimen>
-    <dimen name="suggestion_card_padding_bottom_one_card">16dp</dimen>
-    <dimen name="suggestion_card_corner_radius">2dp</dimen>
-    <dimen name="suggestion_card_icon_side_margin">12dp</dimen>
-    <dimen name="suggestion_card_button_side_margin">8dp</dimen>
-    <dimen name="suggestion_card_button_top_margin">16dp</dimen>
-    <dimen name="suggestion_card_button_bottom_margin">18dp</dimen>
-
     <!-- Condition cards size and padding -->
     <dimen name="condition_card_elevation">2dp</dimen>
 
@@ -331,6 +320,7 @@
     <dimen name="homepage_bottombar_fab_cradle">68dp</dimen>
 
     <!-- Homepage cards size and padding -->
+    <dimen name="homepage_card_icon_size">24dp</dimen>
     <dimen name="homepage_card_corner_radius">8dp</dimen>
     <dimen name="homepage_card_elevation">2dp</dimen>
     <dimen name="homepage_card_vertical_margin">4dp</dimen>
@@ -343,6 +333,9 @@
     <dimen name="horizontal_divider_margin_bottom">8dp</dimen>
     <dimen name="horizontal_divider_height">.75dp</dimen>
 
+    <!-- Vertical divider size -->
+    <dimen name="vertical_divider_width">.75dp</dimen>
+
     <!-- Signal icon in NetworkSelectSetting -->
     <dimen name="signal_strength_icon_size">24dp</dimen>
 
@@ -351,11 +344,10 @@
     <dimen name="homepage_condition_half_card_height">150dp</dimen>
     <dimen name="homepage_condition_half_card_padding_top">12dp</dimen>
     <dimen name="homepage_condition_half_card_title_margin_top">12dp</dimen>
-    <dimen name="homepage_condition_full_card_height">72dp</dimen>
+    <dimen name="homepage_condition_half_card_summary_margin_bottom">12dp</dimen>
     <dimen name="homepage_condition_full_card_padding_start">24dp</dimen>
     <dimen name="homepage_condition_full_card_padding_end">24dp</dimen>
-    <dimen name="homepage_condition_full_card_divider_width">.75dp</dimen>
-    <dimen name="homepage_condition_full_card_divider_padding_top">12dp</dimen>
-    <dimen name="homepage_condition_full_card_divider_padding_bottom">12dp</dimen>
+    <dimen name="homepage_condition_full_card_padding_top">12dp</dimen>
+    <dimen name="homepage_condition_full_card_padding_bottom">12dp</dimen>
 
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index aa66d28..e93e56d 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -9964,15 +9964,6 @@
     <!-- UI debug setting: ANGLE enabled app has been set [CHAR LIMIT=NONE] -->
     <string name="angle_enabled_app_set">ANGLE enabled application: <xliff:g id="app_name" example="com.company.app">%1$s</xliff:g></string>
 
-    <!-- Title for Directory Access settings -->
-    <string name="directory_access">Directory access</string>
-    <!-- Keywords for Directory Access settings -->
-    <string name="keywords_directory_access">directory access</string>
-
-    <!-- String used to describe the name of a directory in a volume; it must
-         show both names, with the directory name wrapped in parenthesis -->
-    <string name="directory_on_volume"><xliff:g id="volume" example="SD Card">%1$s</xliff:g> (<xliff:g id="directory" example="Movies">%2$s</xliff:g>)</string>
-
     <!-- Slices Strings -->
 
     <!-- Summary text on a card explaining that a setting does not exist / is not supported on the device [CHAR_LIMIT=NONE]-->
@@ -10010,11 +10001,6 @@
     <!-- Title for preference showing the name of the device. [CHAR LIMIT=60]-->
     <string name="my_device_info_device_name_preference_title">Device name</string>
 
-    <!-- Settings item title for automatic Bluetooth on while driving preference [CHAR LIMIT=35] -->
-    <string name="bluetooth_on_while_driving_pref">Use Bluetooth when driving</string>
-    <!-- Settings item summary for automatic Bluetooth on while driving preference [CHAR LIMIT=100] -->
-    <string name="bluetooth_on_while_driving_summary">Turn on Bluetooth automatically when driving</string>
-
     <!-- Title for Wifi Access settings [CHAR LIMIT=35] -->
     <string name="change_wifi_state_title">Wi-Fi control</string>
 
@@ -10187,9 +10173,6 @@
     <!-- Text for Network global [CHAR LIMIT=NONE] -->
     <string name="network_global">Global</string>
 
-    <!-- Configuration setting for world mode Format is <true;GID if any to be checked> [CHAR LIMIT=NONE] -->
-    <string translatable="false" name="config_world_mode"/>
-
     <!-- Available networks screen title/heading [CHAR LIMIT=NONE] -->
     <string name="label_available">Available networks</string>
     <!-- Mobile network settings screen, toast when searching for available networks [CHAR LIMIT=NONE] -->
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 70d8a93..a954c5e 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -320,8 +320,9 @@
 
     <style name="TextAppearance.EntityHeaderTitle"
            parent="@android:style/TextAppearance.Material.Subhead">
+        <item name="android:fontFamily">@*android:string/config_headlineFontFamilyMedium</item>
         <item name="android:textColor">?android:attr/textColorPrimary</item>
-        <item name="android:textSize">16sp</item>
+        <item name="android:textSize">20sp</item>
     </style>
 
     <style name="TextAppearance.EntityHeaderSummary"
@@ -331,6 +332,7 @@
         <item name="android:gravity">start</item>
         <item name="android:singleLine">true</item>
         <item name="android:ellipsize">marquee</item>
+        <item name="android:textSize">14sp</item>
     </style>
 
     <style name="TextAppearance.ZenOnboardingButton">
@@ -350,16 +352,8 @@
     <style name="SuggestionCardIcon">
         <item name="android:layout_centerHorizontal">false</item>
         <item name="android:layout_alignParentStart">true</item>
-        <item name="android:layout_marginStart">@dimen/suggestion_card_icon_side_margin</item>
-        <item name="android:layout_marginEnd">@dimen/suggestion_card_icon_side_margin</item>
-    </style>
-
-    <style name="SuggestionCardButton">
-        <item name="android:layout_gravity">start</item>
-        <item name="android:layout_marginStart">@dimen/suggestion_card_button_side_margin</item>
-        <item name="android:layout_marginEnd">@dimen/suggestion_card_button_side_margin</item>
-        <item name="android:layout_marginTop">@dimen/suggestion_card_button_top_margin</item>
-        <item name="android:layout_marginBottom">@dimen/suggestion_card_button_bottom_margin</item>
+        <item name="android:layout_marginStart">12dp</item>
+        <item name="android:layout_marginEnd">12dp</item>
     </style>
 
     <style name="FingerprintLayoutTheme">
@@ -405,12 +399,10 @@
     </style>
 
     <style name="EntityHeader">
-        <item name="android:background">?android:attr/colorPrimary</item>
-        <item name="android:gravity">center_horizontal</item>
-        <item name="android:paddingTop">16dp</item>
-        <item name="android:paddingStart">16dp</item>
+        <item name="android:background">?android:attr/colorPrimaryDark</item>
+        <item name="android:paddingTop">24dp</item>
+        <item name="android:paddingBottom">16dp</item>
         <item name="android:paddingEnd">16dp</item>
-        <item name="android:paddingBottom">8dp</item>
     </style>
 
     <style name="ActionPrimaryButton" parent="android:Widget.DeviceDefault.Button.Colored"/>
diff --git a/res/xml/connected_devices_advanced.xml b/res/xml/connected_devices_advanced.xml
index a959d02..b5d2a99 100644
--- a/res/xml/connected_devices_advanced.xml
+++ b/res/xml/connected_devices_advanced.xml
@@ -44,14 +44,6 @@
         android:icon="@drawable/ic_android"
         android:order="-6"/>
 
-    <SwitchPreference
-        android:key="bluetooth_on_while_driving"
-        android:title="@string/bluetooth_on_while_driving_pref"
-        android:icon="@drawable/ic_settings_bluetooth"
-        android:summary="@string/bluetooth_on_while_driving_summary"
-        settings:controller="com.android.settings.connecteddevice.BluetoothOnWhileDrivingPreferenceController"
-        android:order="-4"/>
-
     <com.android.settingslib.RestrictedPreference
         android:key="connected_device_printing"
         android:title="@string/print_settings"
diff --git a/res/xml/print_job_settings.xml b/res/xml/print_job_settings.xml
index 32a80a7..877cd62 100644
--- a/res/xml/print_job_settings.xml
+++ b/res/xml/print_job_settings.xml
@@ -19,13 +19,16 @@
         android:title="@string/print_print_job">
 
     <Preference
-            android:key="print_job_preference">
+            android:key="print_job_preference"
+            android:title="@string/print_print_job"
+            settings:controller="com.android.settings.print.PrintJobPreferenceController">
     </Preference>
 
     <Preference
             android:key="print_job_message_preference"
             android:layout="@layout/print_job_summary"
-            android:selectable="false">
+            android:selectable="false"
+            settings:controller="com.android.settings.print.PrintJobMessagePreferenceController">
     </Preference>
 
 </PreferenceScreen>
diff --git a/res/xml/special_access.xml b/res/xml/special_access.xml
index a6c2159..57e673f 100644
--- a/res/xml/special_access.xml
+++ b/res/xml/special_access.xml
@@ -121,16 +121,6 @@
     </Preference>
 
     <Preference
-        android:key="special_app_directory_access"
-        android:title="@string/directory_access"
-        android:fragment="com.android.settings.applications.manageapplications.ManageApplications"
-        settings:keywords="@string/keywords_directory_access">
-        <extra
-            android:name="classname"
-            android:value="com.android.settings.Settings$DirectoryAccessSettingsActivity" />
-    </Preference>
-
-    <Preference
         android:key="change_wifi_state"
         android:title="@string/change_wifi_state_title"
         android:fragment="com.android.settings.applications.manageapplications.ManageApplications"
diff --git a/res/xml/top_level_settings.xml b/res/xml/top_level_settings.xml
index b5930e4..69c4bb8 100644
--- a/res/xml/top_level_settings.xml
+++ b/res/xml/top_level_settings.xml
@@ -125,6 +125,15 @@
         android:fragment="com.android.settings.system.SystemDashboardFragment"/>
 
     <Preference
+        android:key="top_level_about_device"
+        android:title="@string/about_settings"
+        android:summary="@string/summary_placeholder"
+        android:icon="@drawable/ic_homepage_about"
+        android:order="20"
+        android:fragment="com.android.settings.deviceinfo.aboutphone.MyDeviceInfoFragment"
+        settings:controller="com.android.settings.deviceinfo.aboutphone.TopLevelAboutDevicePreferenceController"/>
+
+    <Preference
         android:key="top_level_support"
         android:summary="@string/support_summary"
         android:title="@string/page_tab_title_support"
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 952c519..8cff5f1 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -120,7 +120,6 @@
     public static class PhotosStorageActivity extends SettingsActivity {
         /* empty */
     }
-    public static class DirectoryAccessSettingsActivity extends SettingsActivity { /* empty */ }
 
     public static class ApnSettingsActivity extends SettingsActivity { /* empty */ }
     public static class WifiCallingSettingsActivity extends SettingsActivity { /* empty */ }
diff --git a/src/com/android/settings/accounts/AvatarViewMixin.java b/src/com/android/settings/accounts/AvatarViewMixin.java
index d7f6f8a..6dcf312 100644
--- a/src/com/android/settings/accounts/AvatarViewMixin.java
+++ b/src/com/android/settings/accounts/AvatarViewMixin.java
@@ -18,6 +18,7 @@
 
 import android.accounts.Account;
 import android.content.Context;
+import android.util.Log;
 import android.widget.ImageView;
 
 import androidx.annotation.VisibleForTesting;
@@ -34,8 +35,10 @@
  * in {@link SettingsHomepageActivity}.
  */
 public class AvatarViewMixin implements LifecycleObserver {
-    private Context mContext;
-    private ImageView mAvatarView;
+    private static final String TAG = "AvatarViewMixin";
+
+    private final Context mContext;
+    private final ImageView mAvatarView;
 
     public AvatarViewMixin(Context context, ImageView avatarView) {
         mContext = context.getApplicationContext();
@@ -44,6 +47,10 @@
 
     @OnLifecycleEvent(Lifecycle.Event.ON_START)
     public void onStart() {
+        if (!mContext.getResources().getBoolean(R.bool.config_show_avatar_in_homepage)) {
+            Log.d(TAG, "Feature disabled. Skipping");
+            return;
+        }
         if (hasAccount()) {
             //TODO(b/117509285): To migrate account icon on search bar
         } else {
diff --git a/src/com/android/settings/applications/AppStateDirectoryAccessBridge.java b/src/com/android/settings/applications/AppStateDirectoryAccessBridge.java
deleted file mode 100644
index 1c2a0af..0000000
--- a/src/com/android/settings/applications/AppStateDirectoryAccessBridge.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * 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.applications;
-
-import static android.os.storage.StorageVolume.ScopedAccessProviderContract.AUTHORITY;
-import static android.os.storage.StorageVolume.ScopedAccessProviderContract.TABLE_PACKAGES;
-import static android.os.storage.StorageVolume.ScopedAccessProviderContract.TABLE_PACKAGES_COLUMNS;
-import static android.os.storage.StorageVolume.ScopedAccessProviderContract.TABLE_PACKAGES_COL_PACKAGE;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.database.Cursor;
-import android.net.Uri;
-import android.util.ArraySet;
-import android.util.Log;
-
-import com.android.settingslib.applications.ApplicationsState;
-import com.android.settingslib.applications.ApplicationsState.AppEntry;
-import com.android.settingslib.applications.ApplicationsState.AppFilter;
-
-import java.util.Set;
-
-// TODO(b/72055774): add unit tests
-public class AppStateDirectoryAccessBridge extends AppStateBaseBridge {
-
-    private static final String TAG = "DirectoryAccessBridge";
-
-    // TODO(b/72055774): set to false once feature is ready (or use Log.isLoggable)
-    static final boolean DEBUG = true;
-    static final boolean VERBOSE = true;
-
-    public AppStateDirectoryAccessBridge(ApplicationsState appState, Callback callback) {
-        super(appState, callback);
-    }
-
-    @Override
-    protected void loadAllExtraInfo() { }
-
-    @Override
-    protected void updateExtraInfo(AppEntry app, String pkg, int uid) { }
-
-    public static final AppFilter FILTER_APP_HAS_DIRECTORY_ACCESS = new AppFilter() {
-
-        private Set<String> mPackages;
-
-        @Override
-        public void init() {
-            throw new UnsupportedOperationException("Need to call constructor that takes context");
-        }
-
-        @Override
-        public void init(Context context) {
-            mPackages = null;
-            final Uri providerUri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
-                    .authority(AUTHORITY).appendPath(TABLE_PACKAGES).appendPath("*")
-                    .build();
-            try (Cursor cursor = context.getContentResolver().query(providerUri,
-                    TABLE_PACKAGES_COLUMNS, null, null)) {
-                if (cursor == null) {
-                    Log.w(TAG, "Didn't get cursor for " + providerUri);
-                    return;
-                }
-                final int count = cursor.getCount();
-                if (count == 0) {
-                    if (DEBUG) {
-                        Log.d(TAG, "No packages anymore (was " + mPackages + ")");
-                    }
-                    return;
-                }
-                mPackages = new ArraySet<>(count);
-                while (cursor.moveToNext()) {
-                    mPackages.add(cursor.getString(TABLE_PACKAGES_COL_PACKAGE));
-                }
-                if (DEBUG) {
-                    Log.d(TAG, "init(): " + mPackages);
-                }
-            }
-        }
-
-
-        @Override
-        public boolean filterApp(AppEntry info) {
-            return mPackages != null && mPackages.contains(info.info.packageName);
-        }
-    };
-}
diff --git a/src/com/android/settings/applications/AppStorageSettings.java b/src/com/android/settings/applications/AppStorageSettings.java
index e24a210..c926da3 100644
--- a/src/com/android/settings/applications/AppStorageSettings.java
+++ b/src/com/android/settings/applications/AppStorageSettings.java
@@ -18,13 +18,10 @@
 
 import static android.content.pm.ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA;
 import static android.content.pm.ApplicationInfo.FLAG_SYSTEM;
-import static android.os.storage.StorageVolume.ScopedAccessProviderContract.AUTHORITY;
-import static android.os.storage.StorageVolume.ScopedAccessProviderContract.TABLE_PERMISSIONS;
 
 import android.app.ActivityManager;
 import android.app.AppGlobals;
 import android.app.GrantedUriPermission;
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
@@ -32,7 +29,6 @@
 import android.content.pm.IPackageDataObserver;
 import android.content.pm.PackageManager;
 import android.content.pm.ProviderInfo;
-import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
@@ -461,17 +457,6 @@
                 Context.ACTIVITY_SERVICE);
         am.clearGrantedUriPermissions(packageName);
 
-
-        // Also update the Scoped Directory Access UI permissions
-        final Uri providerUri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
-                .authority(AUTHORITY).appendPath(TABLE_PERMISSIONS).appendPath("*")
-                .build();
-        Log.v(TAG, "Asking " + providerUri + " to delete permissions for " + packageName);
-        final int deleted = context.getContentResolver().delete(providerUri, null, new String[] {
-                packageName
-        });
-        Log.d(TAG, "Deleted " + deleted + " entries for package " + packageName);
-
         // Update UI
         refreshGrantedUriPermissions();
     }
diff --git a/src/com/android/settings/applications/DirectoryAccessDetails.java b/src/com/android/settings/applications/DirectoryAccessDetails.java
deleted file mode 100644
index f158d81..0000000
--- a/src/com/android/settings/applications/DirectoryAccessDetails.java
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
- * 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.applications;
-
-import static android.os.storage.StorageVolume.ScopedAccessProviderContract.AUTHORITY;
-import static android.os.storage.StorageVolume.ScopedAccessProviderContract.COL_GRANTED;
-import static android.os.storage.StorageVolume.ScopedAccessProviderContract.TABLE_PERMISSIONS;
-import static android.os.storage.StorageVolume.ScopedAccessProviderContract
-        .TABLE_PERMISSIONS_COLUMNS;
-import static android.os.storage.StorageVolume.ScopedAccessProviderContract
-        .TABLE_PERMISSIONS_COL_DIRECTORY;
-import static android.os.storage.StorageVolume.ScopedAccessProviderContract
-        .TABLE_PERMISSIONS_COL_GRANTED;
-import static android.os.storage.StorageVolume.ScopedAccessProviderContract
-        .TABLE_PERMISSIONS_COL_PACKAGE;
-import static android.os.storage.StorageVolume.ScopedAccessProviderContract
-        .TABLE_PERMISSIONS_COL_VOLUME_UUID;
-
-import static com.android.settings.applications.AppStateDirectoryAccessBridge.DEBUG;
-import static com.android.settings.applications.AppStateDirectoryAccessBridge.VERBOSE;
-
-import android.annotation.Nullable;
-import android.app.Activity;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.storage.StorageManager;
-import android.os.storage.VolumeInfo;
-import android.util.IconDrawableFactory;
-import android.util.Log;
-import android.util.Pair;
-
-import androidx.appcompat.app.AlertDialog;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceCategory;
-import androidx.preference.PreferenceScreen;
-import androidx.preference.SwitchPreference;
-
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settings.R;
-import com.android.settings.widget.EntityHeaderController;
-import com.android.settings.widget.EntityHeaderController.ActionType;
-import com.android.settingslib.applications.AppUtils;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Detailed settings for an app's directory access permissions (A.K.A Scoped Directory Access).
- *
- * <p>Currently, it shows the entry for which the user denied access with the "Do not ask again"
- * flag checked on: the user than can use the settings toggle to reset that deniel.
- *
- * <p>This fragments dynamically lists all such permissions, starting with one preference per
- * directory in the primary storage, then adding additional entries for the external volumes (one
- * entry for the whole volume).
- */
-// TODO(b/72055774): add unit tests
-public class DirectoryAccessDetails extends AppInfoBase {
-
-    @SuppressWarnings("hiding")
-    private static final String TAG = "DirectoryAccessDetails";
-
-    private boolean mCreated;
-
-    @Override
-    public void onActivityCreated(Bundle savedInstanceState) {
-        super.onActivityCreated(savedInstanceState);
-
-        if (mCreated) {
-            Log.w(TAG, "onActivityCreated(): ignoring duplicate call");
-            return;
-        }
-        mCreated = true;
-        if (mPackageInfo == null) {
-            Log.w(TAG, "onActivityCreated(): no package info");
-            return;
-        }
-        final Activity activity = getActivity();
-        final Preference pref = EntityHeaderController
-                .newInstance(activity, this, /* header= */ null )
-                .setRecyclerView(getListView(), getSettingsLifecycle())
-                .setIcon(IconDrawableFactory.newInstance(getPrefContext())
-                        .getBadgedIcon(mPackageInfo.applicationInfo))
-                .setLabel(mPackageInfo.applicationInfo.loadLabel(mPm))
-                .setIsInstantApp(AppUtils.isInstant(mPackageInfo.applicationInfo))
-                .setPackageName(mPackageName)
-                .setUid(mPackageInfo.applicationInfo.uid)
-                .setHasAppInfoLink(false)
-                .setButtonActions(ActionType.ACTION_NONE, ActionType.ACTION_NONE)
-                .done(activity, getPrefContext());
-        getPreferenceScreen().addPreference(pref);
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        addPreferencesFromResource(R.xml.directory_access_details);
-
-    }
-
-    @Override
-    protected boolean refreshUi() {
-        final Context context = getPrefContext();
-        final PreferenceScreen prefsGroup = getPreferenceScreen();
-        prefsGroup.removeAll();
-
-        final Map<String, ExternalVolume> externalVolumes = new HashMap<>();
-
-        final Uri providerUri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
-                .authority(AUTHORITY).appendPath(TABLE_PERMISSIONS).appendPath("*")
-                .build();
-        // Query provider for entries.
-        try (Cursor cursor = context.getContentResolver().query(providerUri,
-                TABLE_PERMISSIONS_COLUMNS, null, new String[] { mPackageName }, null)) {
-            if (cursor == null) {
-                Log.w(TAG, "Didn't get cursor for " + mPackageName);
-                return true;
-            }
-            final int count = cursor.getCount();
-            if (count == 0) {
-                // This setting screen should not be reached if there was no permission, so just
-                // ignore it
-                Log.w(TAG, "No permissions for " + mPackageName);
-                return true;
-            }
-
-            while (cursor.moveToNext()) {
-                final String pkg = cursor.getString(TABLE_PERMISSIONS_COL_PACKAGE);
-                final String uuid = cursor.getString(TABLE_PERMISSIONS_COL_VOLUME_UUID);
-                final String dir = cursor.getString(TABLE_PERMISSIONS_COL_DIRECTORY);
-                final boolean granted = cursor.getInt(TABLE_PERMISSIONS_COL_GRANTED) == 1;
-                if (VERBOSE) {
-                    Log.v(TAG, "Pkg:"  + pkg + " uuid: " + uuid + " dir: " + dir
-                            + " granted:" + granted);
-                }
-
-                if (!mPackageName.equals(pkg)) {
-                    // Sanity check, shouldn't happen
-                    Log.w(TAG, "Ignoring " + uuid + "/" + dir + " due to package mismatch: "
-                            + "expected " + mPackageName + ", got " + pkg);
-                    continue;
-                }
-
-                if (uuid == null) {
-                    if (dir == null) {
-                        // Sanity check, shouldn't happen
-                        Log.wtf(TAG, "Ignoring permission on primary storage root");
-                    } else {
-                        // Primary storage entry: add right away
-                        prefsGroup.addPreference(newPreference(context, dir, providerUri,
-                                /* uuid= */ null, dir, granted, /* children= */ null));
-                    }
-                } else {
-                    // External volume entry: save it for later.
-                    ExternalVolume externalVolume = externalVolumes.get(uuid);
-                    if (externalVolume == null) {
-                        externalVolume = new ExternalVolume(uuid);
-                        externalVolumes.put(uuid, externalVolume);
-                    }
-                    if (dir == null) {
-                        // Whole volume
-                        externalVolume.granted = granted;
-                    } else {
-                        // Directory only
-                        externalVolume.children.add(new Pair<>(dir, granted));
-                    }
-                }
-            }
-        }
-
-        if (VERBOSE) {
-            Log.v(TAG, "external volumes: " + externalVolumes);
-        }
-
-        if (externalVolumes.isEmpty()) {
-            // We're done!
-            return true;
-        }
-
-        // Add entries from external volumes
-
-        // Query StorageManager to get the user-friendly volume names.
-        final StorageManager sm = context.getSystemService(StorageManager.class);
-        final List<VolumeInfo> volumes = sm.getVolumes();
-        if (volumes.isEmpty()) {
-            Log.w(TAG, "StorageManager returned no secondary volumes");
-            return true;
-        }
-        final Map<String, String> volumeNames = new HashMap<>(volumes.size());
-        for (VolumeInfo volume : volumes) {
-            final String uuid = volume.getFsUuid();
-            if (uuid == null) continue; // Primary storage; not used.
-
-            String name = sm.getBestVolumeDescription(volume);
-            if (name == null) {
-                Log.w(TAG, "No description for " + volume + "; using uuid instead: " + uuid);
-                name = uuid;
-            }
-            volumeNames.put(uuid, name);
-        }
-        if (VERBOSE) {
-            Log.v(TAG, "UUID -> name mapping: " + volumeNames);
-        }
-
-        for (ExternalVolume volume : externalVolumes.values()) {
-            final String volumeName = volumeNames.get(volume.uuid);
-            if (volumeName == null) {
-                Log.w(TAG, "Ignoring entry for invalid UUID: " + volume.uuid);
-                continue;
-            }
-            // First add the pref for the whole volume...
-            final PreferenceCategory category = new PreferenceCategory(context);
-            prefsGroup.addPreference(category);
-            final Set<SwitchPreference> children = new HashSet<>(volume.children.size());
-            category.addPreference(newPreference(context, volumeName, providerUri, volume.uuid,
-                    /* dir= */ null, volume.granted, children));
-
-            // ... then the children prefs
-            volume.children.forEach((pair) -> {
-                final String dir = pair.first;
-                final String name = context.getResources()
-                        .getString(R.string.directory_on_volume, volumeName, dir);
-                final SwitchPreference childPref =
-                        newPreference(context, name, providerUri, volume.uuid, dir, pair.second,
-                                /* children= */ null);
-                category.addPreference(childPref);
-                children.add(childPref);
-            });
-        }
-        return true;
-    }
-
-    private SwitchPreference newPreference(Context context, String title, Uri providerUri,
-            String uuid, String dir, boolean granted, @Nullable Set<SwitchPreference> children) {
-        final SwitchPreference pref = new SwitchPreference(context);
-        pref.setKey(String.format("%s:%s", uuid, dir));
-        pref.setTitle(title);
-        pref.setChecked(granted);
-        pref.setOnPreferenceChangeListener((unused, value) -> {
-            if (!Boolean.class.isInstance(value)) {
-                // Sanity check
-                Log.wtf(TAG, "Invalid value from switch: " + value);
-                return true;
-            }
-            final boolean newValue = ((Boolean) value).booleanValue();
-
-            resetDoNotAskAgain(context, newValue, providerUri, uuid, dir);
-            if (children != null) {
-                // When parent is granted, children should be hidden; and vice versa
-                final boolean newChildValue = !newValue;
-                for (SwitchPreference child : children) {
-                    child.setVisible(newChildValue);
-                }
-            }
-            return true;
-        });
-        return pref;
-    }
-
-    private void resetDoNotAskAgain(Context context, boolean newValue, Uri providerUri,
-            @Nullable String uuid, @Nullable String directory) {
-        if (DEBUG) {
-            Log.d(TAG, "Asking " + providerUri  + " to update " + uuid + "/" + directory + " to "
-                    + newValue);
-        }
-        final ContentValues values = new ContentValues(1);
-        values.put(COL_GRANTED, newValue);
-        final int updated = context.getContentResolver().update(providerUri, values,
-                null, new String[] { mPackageName, uuid, directory });
-        if (DEBUG) {
-            Log.d(TAG, "Updated " + updated + " entries for " + uuid + "/" + directory);
-        }
-    }
-
-    @Override
-    protected AlertDialog createDialog(int id, int errorCode) {
-        return null;
-    }
-
-    @Override
-    public int getMetricsCategory() {
-        return MetricsEvent.APPLICATIONS_DIRECTORY_ACCESS_DETAIL;
-    }
-
-    private static class ExternalVolume {
-        final String uuid;
-        final List<Pair<String, Boolean>> children = new ArrayList<>();
-        boolean granted;
-
-        ExternalVolume(String uuid) {
-            this.uuid = uuid;
-        }
-
-        @Override
-        public String toString() {
-            return "ExternalVolume: [uuid=" + uuid + ", granted=" + granted +
-                    ", children=" + children + "]";
-        }
-    }
-}
diff --git a/src/com/android/settings/applications/appinfo/AppHeaderViewPreferenceController.java b/src/com/android/settings/applications/appinfo/AppHeaderViewPreferenceController.java
index c861175..5f41ae0 100644
--- a/src/com/android/settings/applications/appinfo/AppHeaderViewPreferenceController.java
+++ b/src/com/android/settings/applications/appinfo/AppHeaderViewPreferenceController.java
@@ -90,12 +90,9 @@
     private void setAppLabelAndIcon(PackageInfo pkgInfo, AppEntry appEntry) {
         final Activity activity = mParent.getActivity();
         final boolean isInstantApp = AppUtils.isInstant(pkgInfo.applicationInfo);
-        final CharSequence summary = isInstantApp
-                ? null : mContext.getString(Utils.getInstallationStatus(appEntry.info));
         mEntityHeaderController
                 .setLabel(appEntry)
                 .setIcon(appEntry)
-                .setSummary(summary)
                 .setIsInstantApp(isInstantApp)
                 .done(activity, false /* rebindActions */);
     }
diff --git a/src/com/android/settings/applications/manageapplications/AppFilterRegistry.java b/src/com/android/settings/applications/manageapplications/AppFilterRegistry.java
index 7d1e159..0d2bcab 100644
--- a/src/com/android/settings/applications/manageapplications/AppFilterRegistry.java
+++ b/src/com/android/settings/applications/manageapplications/AppFilterRegistry.java
@@ -19,7 +19,6 @@
 import androidx.annotation.IntDef;
 
 import com.android.settings.R;
-import com.android.settings.applications.AppStateDirectoryAccessBridge;
 import com.android.settings.applications.AppStateInstallAppsBridge;
 import com.android.settings.applications.AppStateNotificationBridge;
 import com.android.settings.applications.AppStateOverlayBridge;
@@ -70,7 +69,6 @@
     public static final int FILTER_APPS_WITH_OVERLAY = 11;
     public static final int FILTER_APPS_WRITE_SETTINGS = 12;
     public static final int FILTER_APPS_INSTALL_SOURCES = 13;
-    public static final int FILTER_APP_HAS_DIRECTORY_ACCESS = 14;
     public static final int FILTER_APP_CAN_CHANGE_WIFI_STATE = 15;
     public static final int FILTER_APPS_BLOCKED = 16;
     // Next id: 17
@@ -170,12 +168,6 @@
                 FILTER_APPS_INSTALL_SOURCES,
                 R.string.filter_install_sources_apps);
 
-        // Apps that interacted with directory access permissions (A.K.A. Scoped Directory Access)
-        mFilters[FILTER_APP_HAS_DIRECTORY_ACCESS] = new AppFilterItem(
-                AppStateDirectoryAccessBridge.FILTER_APP_HAS_DIRECTORY_ACCESS,
-                FILTER_APP_HAS_DIRECTORY_ACCESS,
-                R.string.filter_install_sources_apps);
-
         mFilters[FILTER_APP_CAN_CHANGE_WIFI_STATE] = new AppFilterItem(
                 AppStateChangeWifiStateBridge.FILTER_CHANGE_WIFI_STATE,
                 FILTER_APP_CAN_CHANGE_WIFI_STATE,
@@ -208,8 +200,6 @@
                 return FILTER_APPS_WRITE_SETTINGS;
             case ManageApplications.LIST_TYPE_MANAGE_SOURCES:
                 return FILTER_APPS_INSTALL_SOURCES;
-            case ManageApplications.LIST_TYPE_DIRECTORY_ACCESS:
-                return FILTER_APP_HAS_DIRECTORY_ACCESS;
             case ManageApplications.LIST_TYPE_WIFI_ACCESS:
                 return FILTER_APP_CAN_CHANGE_WIFI_STATE;
             case ManageApplications.LIST_TYPE_NOTIFICATION:
diff --git a/src/com/android/settings/applications/manageapplications/ManageApplications.java b/src/com/android/settings/applications/manageapplications/ManageApplications.java
index 44ea575..6b2fb91 100644
--- a/src/com/android/settings/applications/manageapplications/ManageApplications.java
+++ b/src/com/android/settings/applications/manageapplications/ManageApplications.java
@@ -90,7 +90,6 @@
 import com.android.settings.applications.AppInfoBase;
 import com.android.settings.applications.AppStateAppOpsBridge.PermissionState;
 import com.android.settings.applications.AppStateBaseBridge;
-import com.android.settings.applications.AppStateDirectoryAccessBridge;
 import com.android.settings.applications.AppStateInstallAppsBridge;
 import com.android.settings.applications.AppStateNotificationBridge;
 import com.android.settings.applications.AppStateNotificationBridge.NotificationsSentState;
@@ -101,7 +100,6 @@
 import com.android.settings.applications.AppStateWriteSettingsBridge;
 import com.android.settings.applications.AppStorageSettings;
 import com.android.settings.applications.DefaultAppSettings;
-import com.android.settings.applications.DirectoryAccessDetails;
 import com.android.settings.applications.InstalledAppCounter;
 import com.android.settings.applications.UsageAccessDetails;
 import com.android.settings.applications.appinfo.AppInfoDashboardFragment;
@@ -218,7 +216,6 @@
     public static final int LIST_TYPE_GAMES = 9;
     public static final int LIST_TYPE_MOVIES = 10;
     public static final int LIST_TYPE_PHOTOGRAPHY = 11;
-    public static final int LIST_TYPE_DIRECTORY_ACCESS = 12;
     public static final int LIST_TYPE_WIFI_ACCESS = 13;
 
     // List types that should show instant apps.
@@ -293,9 +290,6 @@
             mListType = LIST_TYPE_PHOTOGRAPHY;
             mSortOrder = R.id.sort_order_size;
             mStorageType = args.getInt(EXTRA_STORAGE_TYPE, STORAGE_TYPE_DEFAULT);
-        } else if (className.equals(Settings.DirectoryAccessSettingsActivity.class.getName())) {
-            mListType = LIST_TYPE_DIRECTORY_ACCESS;
-            screenTitle = R.string.directory_access;
         } else if (className.equals(Settings.ChangeWifiStateActivity.class.getName())) {
             mListType = LIST_TYPE_WIFI_ACCESS;
             screenTitle = R.string.change_wifi_state_title;
@@ -479,8 +473,6 @@
                 return MetricsEvent.SYSTEM_ALERT_WINDOW_APPS;
             case LIST_TYPE_MANAGE_SOURCES:
                 return MetricsEvent.MANAGE_EXTERNAL_SOURCES;
-            case LIST_TYPE_DIRECTORY_ACCESS:
-                return MetricsEvent.DIRECTORY_ACCESS;
             case LIST_TYPE_WIFI_ACCESS:
                 return MetricsEvent.CONFIGURE_WIFI;
             default:
@@ -578,9 +570,6 @@
             case LIST_TYPE_PHOTOGRAPHY:
                 startAppInfoFragment(AppStorageSettings.class, R.string.storage_photos_videos);
                 break;
-            case LIST_TYPE_DIRECTORY_ACCESS:
-                startAppInfoFragment(DirectoryAccessDetails.class, R.string.directory_access);
-                break;
             case LIST_TYPE_WIFI_ACCESS:
                 startAppInfoFragment(ChangeWifiStateDetails.class,
                         R.string.change_wifi_state_title);
@@ -916,8 +905,6 @@
                 mExtraInfoBridge = new AppStateWriteSettingsBridge(mContext, mState, this);
             } else if (mManageApplications.mListType == LIST_TYPE_MANAGE_SOURCES) {
                 mExtraInfoBridge = new AppStateInstallAppsBridge(mContext, mState, this);
-            } else if (mManageApplications.mListType == LIST_TYPE_DIRECTORY_ACCESS) {
-                mExtraInfoBridge = new AppStateDirectoryAccessBridge(mState, this);
             } else if (mManageApplications.mListType == LIST_TYPE_WIFI_ACCESS) {
                 mExtraInfoBridge = new AppStateChangeWifiStateBridge(mContext, mState, this);
             } else {
@@ -1360,9 +1347,6 @@
                 case LIST_TYPE_MANAGE_SOURCES:
                     holder.setSummary(ExternalSourcesDetails.getPreferenceSummary(mContext, entry));
                     break;
-                case LIST_TYPE_DIRECTORY_ACCESS:
-                    holder.setSummary(null);
-                    break;
                 case LIST_TYPE_WIFI_ACCESS:
                     holder.setSummary(ChangeWifiStateDetails.getSummary(mContext, entry));
                     break;
diff --git a/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragment.java b/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragment.java
index 5c678a9..54842f7 100644
--- a/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragment.java
+++ b/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragment.java
@@ -74,7 +74,6 @@
         final List<AbstractPreferenceController> controllers = new ArrayList<>();
 
         controllers.add(new BluetoothFilesPreferenceController(context));
-        controllers.add(new BluetoothOnWhileDrivingPreferenceController(context));
 
         final PrintSettingPreferenceController printerController =
                 new PrintSettingPreferenceController(context);
diff --git a/src/com/android/settings/connecteddevice/BluetoothOnWhileDrivingPreferenceController.java b/src/com/android/settings/connecteddevice/BluetoothOnWhileDrivingPreferenceController.java
deleted file mode 100644
index 6d4e8b8..0000000
--- a/src/com/android/settings/connecteddevice/BluetoothOnWhileDrivingPreferenceController.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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.connecteddevice;
-
-import android.content.Context;
-import android.provider.Settings;
-import android.util.FeatureFlagUtils;
-
-import com.android.settings.core.FeatureFlags;
-import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settings.core.TogglePreferenceController;
-
-/** Handles a toggle for a setting to turn on Bluetooth while driving. * */
-public class BluetoothOnWhileDrivingPreferenceController extends TogglePreferenceController
-        implements PreferenceControllerMixin {
-    static final String KEY_BLUETOOTH_ON_DRIVING = "bluetooth_on_while_driving";
-
-    public BluetoothOnWhileDrivingPreferenceController(Context context) {
-        super(context, KEY_BLUETOOTH_ON_DRIVING);
-    }
-
-    @Override
-    public int getAvailabilityStatus() {
-        if (FeatureFlagUtils.isEnabled(mContext, FeatureFlags.BLUETOOTH_WHILE_DRIVING)) {
-            return AVAILABLE;
-        }
-        return CONDITIONALLY_UNAVAILABLE;
-    }
-
-    @Override
-    public boolean isChecked() {
-        return Settings.Secure.getInt(
-                        mContext.getContentResolver(),
-                        Settings.Secure.BLUETOOTH_ON_WHILE_DRIVING,
-                        0)
-                != 0;
-    }
-
-    @Override
-    public boolean setChecked(boolean isChecked) {
-        final int value = isChecked ? 1 : 0;
-        return Settings.Secure.putInt(
-                mContext.getContentResolver(), Settings.Secure.BLUETOOTH_ON_WHILE_DRIVING, value);
-    }
-}
diff --git a/src/com/android/settings/core/FeatureFlags.java b/src/com/android/settings/core/FeatureFlags.java
index 811f7ad..0a26b79 100644
--- a/src/com/android/settings/core/FeatureFlags.java
+++ b/src/com/android/settings/core/FeatureFlags.java
@@ -20,7 +20,6 @@
  * This class keeps track of all feature flags in Settings.
  */
 public class FeatureFlags {
-    public static final String BLUETOOTH_WHILE_DRIVING = "settings_bluetooth_while_driving";
     public static final String AUDIO_SWITCHER_SETTINGS = "settings_audio_switcher";
     public static final String DYNAMIC_HOMEPAGE = "settings_dynamic_homepage";
     public static final String HEARING_AID_SETTINGS = "settings_bluetooth_hearing_aid";
diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java
index 4346973..f61cb0c 100644
--- a/src/com/android/settings/core/gateway/SettingsGateway.java
+++ b/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -34,7 +34,6 @@
 import com.android.settings.accounts.ManagedProfileSettings;
 import com.android.settings.applications.AppAndNotificationDashboardFragment;
 import com.android.settings.applications.DefaultAppSettings;
-import com.android.settings.applications.DirectoryAccessDetails;
 import com.android.settings.applications.ProcessStatsSummary;
 import com.android.settings.applications.ProcessStatsUi;
 import com.android.settings.applications.UsageAccessDetails;
@@ -258,7 +257,6 @@
             LockscreenDashboardFragment.class.getName(),
             BluetoothDeviceDetailsFragment.class.getName(),
             DataUsageList.class.getName(),
-            DirectoryAccessDetails.class.getName(),
             ToggleBackupSettingFragment.class.getName(),
             PreviouslyConnectedDeviceDashboardFragment.class.getName(),
     };
diff --git a/src/com/android/settings/deviceinfo/DeviceModelPreferenceController.java b/src/com/android/settings/deviceinfo/DeviceModelPreferenceController.java
index 25090dc..a9d0e3f 100644
--- a/src/com/android/settings/deviceinfo/DeviceModelPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/DeviceModelPreferenceController.java
@@ -79,12 +79,7 @@
     }
 
     public static String getDeviceModel() {
-        FutureTask<String> msvSuffixTask = new FutureTask<String>(new Callable<String>() {
-            @Override
-            public String call() {
-                return DeviceInfoUtils.getMsvSuffix();
-            }
-        });
+        FutureTask<String> msvSuffixTask = new FutureTask<>(() -> DeviceInfoUtils.getMsvSuffix());
 
         msvSuffixTask.run();
         try {
diff --git a/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java b/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java
index 37f80b7..8c6c5ae 100644
--- a/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java
+++ b/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java
@@ -181,25 +181,6 @@
         controller.updateDeviceName(confirm);
     }
 
-    private static class SummaryProvider implements SummaryLoader.SummaryProvider {
-
-        private final SummaryLoader mSummaryLoader;
-
-        public SummaryProvider(SummaryLoader summaryLoader) {
-            mSummaryLoader = summaryLoader;
-        }
-
-        @Override
-        public void setListening(boolean listening) {
-            if (listening) {
-                mSummaryLoader.setSummary(this, DeviceModelPreferenceController.getDeviceModel());
-            }
-        }
-    }
-
-    public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY
-            = (activity, summaryLoader) -> new SummaryProvider(summaryLoader);
-
     /**
      * For Search.
      */
diff --git a/src/com/android/settings/deviceinfo/aboutphone/TopLevelAboutDevicePreferenceController.java b/src/com/android/settings/deviceinfo/aboutphone/TopLevelAboutDevicePreferenceController.java
new file mode 100644
index 0000000..ba28f3a
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/aboutphone/TopLevelAboutDevicePreferenceController.java
@@ -0,0 +1,39 @@
+/*
+ * 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.deviceinfo.aboutphone;
+
+import android.content.Context;
+
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.deviceinfo.DeviceModelPreferenceController;
+
+public class TopLevelAboutDevicePreferenceController extends BasePreferenceController {
+
+    public TopLevelAboutDevicePreferenceController(Context context, String preferenceKey) {
+        super(context, preferenceKey);
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return AVAILABLE;
+    }
+
+    @Override
+    public CharSequence getSummary() {
+        return DeviceModelPreferenceController.getDeviceModel();
+    }
+}
diff --git a/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelper.java b/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelper.java
index 5ca8fea..5bdf587 100644
--- a/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelper.java
+++ b/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelper.java
@@ -23,6 +23,8 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.res.ColorStateList;
+import android.content.res.TypedArray;
 import android.graphics.drawable.Drawable;
 import android.os.Process;
 import android.os.UserHandle;
@@ -109,16 +111,24 @@
         if (admin == null) {
             return;
         }
+        ImageView supportIconView = root.requireViewById(R.id.admin_support_icon);
         if (!RestrictedLockUtilsInternal.isAdminInCurrentUserOrProfile(mActivity, admin)
                 || !RestrictedLockUtils.isCurrentUserOrProfile(mActivity, userId)) {
             admin = null;
+
+            supportIconView.setImageDrawable(
+                    mActivity.getDrawable(com.android.internal.R.drawable.ic_info));
+
+            TypedArray ta = mActivity.obtainStyledAttributes(new int[]{android.R.attr.colorAccent});
+            supportIconView.setImageTintList(ColorStateList.valueOf(ta.getColor(0, 0)));
+            ta.recycle();
         } else {
             final Drawable badgedIcon = Utils.getBadgedIcon(
                     IconDrawableFactory.newInstance(mActivity),
                     mActivity.getPackageManager(),
                     admin.getPackageName(),
                     userId);
-            ((ImageView) root.findViewById(R.id.admin_support_icon)).setImageDrawable(badgedIcon);
+            supportIconView.setImageDrawable(badgedIcon);
         }
 
         setAdminSupportTitle(root, restriction);
diff --git a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
index e34e622..ce9cabc 100644
--- a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
+++ b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
@@ -235,10 +235,7 @@
             controller.setLabel(mAppEntry);
             controller.setIcon(mAppEntry);
             boolean isInstantApp = AppUtils.isInstant(mAppEntry.info);
-            CharSequence summary = isInstantApp
-                    ? null : getString(Utils.getInstallationStatus(mAppEntry.info));
             controller.setIsInstantApp(AppUtils.isInstant(mAppEntry.info));
-            controller.setSummary(summary);
         }
 
         controller.done(context, true /* rebindActions */);
diff --git a/src/com/android/settings/homepage/contextualcards/CardDatabaseHelper.java b/src/com/android/settings/homepage/contextualcards/CardDatabaseHelper.java
index 0065f5c..b5cdf87 100644
--- a/src/com/android/settings/homepage/contextualcards/CardDatabaseHelper.java
+++ b/src/com/android/settings/homepage/contextualcards/CardDatabaseHelper.java
@@ -201,7 +201,7 @@
         final String selection = CardColumns.CARD_DISMISSED + "=0";
         Cursor cursor = db.query(CARD_TABLE, null /* columns */, selection,
                 null /* selectionArgs */, null /* groupBy */, null /* having */,
-                null /* orderBy */);
+                CardColumns.SCORE + " DESC" /* orderBy */);
         return cursor;
     }
 
diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCard.java b/src/com/android/settings/homepage/contextualcards/ContextualCard.java
index b0dfad8..8d43914 100644
--- a/src/com/android/settings/homepage/contextualcards/ContextualCard.java
+++ b/src/com/android/settings/homepage/contextualcards/ContextualCard.java
@@ -33,12 +33,12 @@
     /**
      * Flags indicating the type of the ContextualCard.
      */
-    @IntDef({CardType.DEFAULT, CardType.SLICE, CardType.SUGGESTION, CardType.CONDITIONAL})
+    @IntDef({CardType.DEFAULT, CardType.SLICE, CardType.LEGACY_SUGGESTION, CardType.CONDITIONAL})
     @Retention(RetentionPolicy.SOURCE)
     public @interface CardType {
         int DEFAULT = 0;
         int SLICE = 1;
-        int SUGGESTION = 2;
+        int LEGACY_SUGGESTION = 2;
         int CONDITIONAL = 3;
     }
 
diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardLookupTable.java b/src/com/android/settings/homepage/contextualcards/ContextualCardLookupTable.java
index 2253a2f..dabc88c 100644
--- a/src/com/android/settings/homepage/contextualcards/ContextualCardLookupTable.java
+++ b/src/com/android/settings/homepage/contextualcards/ContextualCardLookupTable.java
@@ -18,11 +18,16 @@
 
 import android.util.Log;
 
+import androidx.annotation.LayoutRes;
 import androidx.annotation.VisibleForTesting;
 
 import com.android.settings.homepage.contextualcards.ContextualCard.CardType;
 import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardController;
 import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardRenderer;
+import com.android.settings.homepage.contextualcards.legacysuggestion
+        .LegacySuggestionContextualCardController;
+import com.android.settings.homepage.contextualcards.legacysuggestion
+        .LegacySuggestionContextualCardRenderer;
 import com.android.settings.homepage.contextualcards.slices.SliceContextualCardController;
 import com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer;
 
@@ -34,6 +39,7 @@
 
 public class ContextualCardLookupTable {
     private static final String TAG = "ContextualCardLookup";
+
     static class ControllerRendererMapping implements Comparable<ControllerRendererMapping> {
         @CardType
         final int mCardType;
@@ -41,7 +47,7 @@
         final Class<? extends ContextualCardController> mControllerClass;
         final Class<? extends ContextualCardRenderer> mRendererClass;
 
-        ControllerRendererMapping(@CardType int cardType, int viewType,
+        ControllerRendererMapping(@CardType int cardType, @LayoutRes int viewType,
                 Class<? extends ContextualCardController> controllerClass,
                 Class<? extends ContextualCardRenderer> rendererClass) {
             mCardType = cardType;
@@ -69,6 +75,10 @@
                         ConditionContextualCardRenderer.FULL_WIDTH_VIEW_TYPE,
                         ConditionContextualCardController.class,
                         ConditionContextualCardRenderer.class));
+                add(new ControllerRendererMapping(CardType.LEGACY_SUGGESTION,
+                        LegacySuggestionContextualCardRenderer.VIEW_TYPE,
+                        LegacySuggestionContextualCardController.class,
+                        LegacySuggestionContextualCardRenderer.class));
                 add(new ControllerRendererMapping(CardType.SLICE,
                         SliceContextualCardRenderer.VIEW_TYPE,
                         SliceContextualCardController.class,
diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardManager.java b/src/com/android/settings/homepage/contextualcards/ContextualCardManager.java
index 9bd08c8..39ceff3 100644
--- a/src/com/android/settings/homepage/contextualcards/ContextualCardManager.java
+++ b/src/com/android/settings/homepage/contextualcards/ContextualCardManager.java
@@ -16,7 +16,8 @@
 
 package com.android.settings.homepage.contextualcards;
 
-import static com.android.settings.homepage.contextualcards.ContextualCardLoader.CARD_CONTENT_LOADER_ID;
+import static com.android.settings.homepage.contextualcards.ContextualCardLoader
+        .CARD_CONTENT_LOADER_ID;
 
 import static java.util.stream.Collectors.groupingBy;
 
@@ -57,8 +58,8 @@
 
     private static final String TAG = "ContextualCardManager";
     //The list for Settings Custom Card
-    @ContextualCard.CardType
-    private static final int[] SETTINGS_CARDS = {ContextualCard.CardType.CONDITIONAL};
+    private static final int[] SETTINGS_CARDS =
+            {ContextualCard.CardType.CONDITIONAL, ContextualCard.CardType.LEGACY_SUGGESTION};
 
     private final Context mContext;
     private final ControllerRendererPool mControllerRendererPool;
@@ -68,14 +69,14 @@
 
     private ContextualCardUpdateListener mListener;
 
-    public ContextualCardManager(Context context, @NonNull Lifecycle lifecycle) {
+    public ContextualCardManager(Context context, Lifecycle lifecycle) {
         mContext = context;
         mLifecycle = lifecycle;
         mContextualCards = new ArrayList<>();
         mLifecycleObservers = new ArrayList<>();
         mControllerRendererPool = new ControllerRendererPool();
         //for data provided by Settings
-        for (int cardType : SETTINGS_CARDS) {
+        for (@ContextualCard.CardType int cardType : SETTINGS_CARDS) {
             setupController(cardType);
         }
     }
@@ -94,7 +95,7 @@
         }
     }
 
-    private void setupController(int cardType) {
+    private void setupController(@ContextualCard.CardType int cardType) {
         final ContextualCardController controller = mControllerRendererPool.getController(mContext,
                 cardType);
         if (controller == null) {
diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardRenderer.java b/src/com/android/settings/homepage/contextualcards/ContextualCardRenderer.java
index bb85bd2..283a079 100644
--- a/src/com/android/settings/homepage/contextualcards/ContextualCardRenderer.java
+++ b/src/com/android/settings/homepage/contextualcards/ContextualCardRenderer.java
@@ -18,6 +18,7 @@
 
 import android.view.View;
 
+import androidx.annotation.LayoutRes;
 import androidx.recyclerview.widget.RecyclerView;
 
 /**
@@ -28,6 +29,7 @@
     /**
      * The layout type of the renderer.
      */
+    @LayoutRes
     int getViewType(boolean isHalfWidth);
 
     /**
diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardUpdateListener.java b/src/com/android/settings/homepage/contextualcards/ContextualCardUpdateListener.java
index 725f6da..9b90d41 100644
--- a/src/com/android/settings/homepage/contextualcards/ContextualCardUpdateListener.java
+++ b/src/com/android/settings/homepage/contextualcards/ContextualCardUpdateListener.java
@@ -16,6 +16,8 @@
 
 package com.android.settings.homepage.contextualcards;
 
+import androidx.annotation.MainThread;
+
 import java.util.List;
 import java.util.Map;
 
@@ -31,5 +33,6 @@
      *              null, which means all cards from corresponding {@link
      *              ContextualCard.CardType} are removed.
      */
+    @MainThread
     void onContextualCardUpdated(Map<Integer, List<ContextualCard>> cards);
 }
\ No newline at end of file
diff --git a/src/com/android/settings/homepage/contextualcards/ControllerRendererPool.java b/src/com/android/settings/homepage/contextualcards/ControllerRendererPool.java
index 8e59f46..7d9d5a8 100644
--- a/src/com/android/settings/homepage/contextualcards/ControllerRendererPool.java
+++ b/src/com/android/settings/homepage/contextualcards/ControllerRendererPool.java
@@ -26,6 +26,10 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardController;
 import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardRenderer;
+import com.android.settings.homepage.contextualcards.legacysuggestion
+        .LegacySuggestionContextualCardController;
+import com.android.settings.homepage.contextualcards.legacysuggestion
+        .LegacySuggestionContextualCardRenderer;
 import com.android.settings.homepage.contextualcards.slices.SliceContextualCardController;
 import com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer;
 
@@ -111,6 +115,8 @@
             return new ConditionContextualCardController(context);
         } else if (SliceContextualCardController.class == clz) {
             return new SliceContextualCardController();
+        } else if (LegacySuggestionContextualCardController.class == clz) {
+            return new LegacySuggestionContextualCardController(context);
         }
         return null;
     }
@@ -118,9 +124,12 @@
     private ContextualCardRenderer createCardRenderer(Context context,
             LifecycleOwner lifecycleOwner, Class<?> clz) {
         if (ConditionContextualCardRenderer.class == clz) {
-            return new ConditionContextualCardRenderer(context, this /*controllerRendererPool*/);
+            return new ConditionContextualCardRenderer(context, this /* controllerRendererPool */);
         } else if (SliceContextualCardRenderer.class == clz) {
             return new SliceContextualCardRenderer(context, lifecycleOwner);
+        } else if (LegacySuggestionContextualCardRenderer.class == clz) {
+            return new LegacySuggestionContextualCardRenderer(context,
+                    this /* controllerRendererPool */);
         }
         return null;
     }
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardRenderer.java b/src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardRenderer.java
index 41c540c..5e4e749 100644
--- a/src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardRenderer.java
+++ b/src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardRenderer.java
@@ -23,6 +23,7 @@
 import android.widget.ImageView;
 import android.widget.TextView;
 
+import androidx.annotation.LayoutRes;
 import androidx.recyclerview.widget.RecyclerView;
 
 import com.android.internal.logging.nano.MetricsProto;
@@ -37,7 +38,9 @@
  * Card renderer for {@link ConditionalContextualCard}.
  */
 public class ConditionContextualCardRenderer implements ContextualCardRenderer {
+    @LayoutRes
     public static final int HALF_WIDTH_VIEW_TYPE = R.layout.homepage_condition_half_tile;
+    @LayoutRes
     public static final int FULL_WIDTH_VIEW_TYPE = R.layout.homepage_condition_full_tile;
 
     private final Context mContext;
diff --git a/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCard.java b/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCard.java
new file mode 100644
index 0000000..d11f771
--- /dev/null
+++ b/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCard.java
@@ -0,0 +1,61 @@
+/*
+ * 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.homepage.contextualcards.legacysuggestion;
+
+import android.app.PendingIntent;
+
+import com.android.settings.homepage.contextualcards.ContextualCard;
+
+public class LegacySuggestionContextualCard extends ContextualCard {
+
+    private final PendingIntent mPendingIntent;
+
+    public LegacySuggestionContextualCard(Builder builder) {
+        super(builder);
+        mPendingIntent = builder.mPendingIntent;
+    }
+
+    @Override
+    public int getCardType() {
+        return CardType.LEGACY_SUGGESTION;
+    }
+
+    public PendingIntent getPendingIntent() {
+        return mPendingIntent;
+    }
+
+    public static class Builder extends ContextualCard.Builder {
+
+        private PendingIntent mPendingIntent;
+
+        public Builder setPendingIntent(PendingIntent pendingIntent) {
+            mPendingIntent = pendingIntent;
+            return this;
+        }
+
+        @Override
+        public Builder setCardType(int cardType) {
+            throw new IllegalArgumentException(
+                    "Cannot change card type for " + getClass().getName());
+        }
+
+        public LegacySuggestionContextualCard build() {
+            return new LegacySuggestionContextualCard(this);
+        }
+    }
+
+}
diff --git a/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardController.java b/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardController.java
new file mode 100644
index 0000000..550f845
--- /dev/null
+++ b/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardController.java
@@ -0,0 +1,156 @@
+/*
+ * 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.homepage.contextualcards.legacysuggestion;
+
+import android.app.PendingIntent;
+import android.content.ComponentName;
+import android.content.Context;
+import android.service.settings.suggestions.Suggestion;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import androidx.annotation.VisibleForTesting;
+
+import com.android.settings.R;
+import com.android.settings.homepage.contextualcards.ContextualCard;
+import com.android.settings.homepage.contextualcards.ContextualCardController;
+import com.android.settings.homepage.contextualcards.ContextualCardUpdateListener;
+import com.android.settings.overlay.FeatureFactory;
+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.settingslib.suggestions.SuggestionController;
+import com.android.settingslib.suggestions.SuggestionController.ServiceConnectionListener;
+import com.android.settingslib.utils.ThreadUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class LegacySuggestionContextualCardController implements ContextualCardController,
+        LifecycleObserver, OnStart, OnStop, ServiceConnectionListener {
+
+    private static final String TAG = "LegacySuggestCardCtrl";
+
+    @VisibleForTesting
+    SuggestionController mSuggestionController;
+
+    private ContextualCardUpdateListener mCardUpdateListener;
+    private final Context mContext;
+
+
+    public LegacySuggestionContextualCardController(Context context) {
+        mContext = context;
+        if (!mContext.getResources().getBoolean(R.bool.config_use_legacy_suggestion)) {
+            Log.w(TAG, "Legacy suggestion contextual card disabled, skipping.");
+            return;
+        }
+        final ComponentName suggestionServiceComponent =
+                FeatureFactory.getFactory(mContext).getSuggestionFeatureProvider(mContext)
+                        .getSuggestionServiceComponent();
+        mSuggestionController = new SuggestionController(
+                mContext, suggestionServiceComponent, this /* listener */);
+
+    }
+
+    @Override
+    public int getCardType() {
+        return ContextualCard.CardType.LEGACY_SUGGESTION;
+    }
+
+    @Override
+    public void onPrimaryClick(ContextualCard card) {
+        try {
+            ((LegacySuggestionContextualCard) card).getPendingIntent().send();
+        } catch (PendingIntent.CanceledException e) {
+            Log.w(TAG, "Failed to start suggestion " + card.getTitleText());
+        }
+    }
+
+    @Override
+    public void onActionClick(ContextualCard card) {
+
+    }
+
+    @Override
+    public void setCardUpdateListener(ContextualCardUpdateListener listener) {
+        mCardUpdateListener = listener;
+    }
+
+    @Override
+    public void onStart() {
+        if (mSuggestionController == null) {
+            return;
+        }
+        mSuggestionController.start();
+    }
+
+    @Override
+    public void onStop() {
+        if (mSuggestionController == null) {
+            return;
+        }
+        mSuggestionController.stop();
+    }
+
+    @Override
+    public void onServiceConnected() {
+        loadSuggestions();
+    }
+
+    @Override
+    public void onServiceDisconnected() {
+
+    }
+
+    private void loadSuggestions() {
+        ThreadUtils.postOnBackgroundThread(() -> {
+            if (mSuggestionController == null || mCardUpdateListener == null) {
+                return;
+            }
+            final List<Suggestion> suggestions = mSuggestionController.getSuggestions();
+            Log.d(TAG, "Loaded suggests: "
+                    + suggestions == null ? "null" : String.valueOf(suggestions.size()));
+
+            final List<ContextualCard> cards = new ArrayList<>();
+            if (suggestions != null) {
+                // Convert suggestion to ContextualCard
+                for (Suggestion suggestion : suggestions) {
+                    final LegacySuggestionContextualCard.Builder cardBuilder =
+                            new LegacySuggestionContextualCard.Builder();
+                    if (suggestion.getIcon() != null) {
+                        cardBuilder.setIconDrawable(suggestion.getIcon().loadDrawable(mContext));
+                    }
+                    cardBuilder
+                            .setPendingIntent(suggestion.getPendingIntent())
+                            .setName(suggestion.getId())
+                            .setTitleText(suggestion.getTitle().toString())
+                            .setSummaryText(suggestion.getSummary().toString());
+
+                    cards.add(cardBuilder.build());
+                }
+            }
+
+            // Update adapter
+            final Map<Integer, List<ContextualCard>> suggestionCards = new ArrayMap<>();
+            suggestionCards.put(ContextualCard.CardType.LEGACY_SUGGESTION, cards);
+            ThreadUtils.postOnMainThread(
+                    () -> mCardUpdateListener.onContextualCardUpdated(suggestionCards));
+
+        });
+    }
+}
diff --git a/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRenderer.java b/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRenderer.java
new file mode 100644
index 0000000..3ce1883
--- /dev/null
+++ b/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRenderer.java
@@ -0,0 +1,81 @@
+/*
+ * 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.homepage.contextualcards.legacysuggestion;
+
+import android.content.Context;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import androidx.annotation.LayoutRes;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.settings.R;
+import com.android.settings.homepage.contextualcards.ContextualCard;
+import com.android.settings.homepage.contextualcards.ContextualCardRenderer;
+import com.android.settings.homepage.contextualcards.ControllerRendererPool;
+
+public class LegacySuggestionContextualCardRenderer implements ContextualCardRenderer {
+
+    @LayoutRes
+    public static final int VIEW_TYPE = R.layout.homepage_suggestion_tile;
+
+    private final Context mContext;
+    private final ControllerRendererPool mControllerRendererPool;
+
+    public LegacySuggestionContextualCardRenderer(Context context,
+            ControllerRendererPool controllerRendererPool) {
+        mContext = context;
+        mControllerRendererPool = controllerRendererPool;
+    }
+
+    @Override
+    public int getViewType(boolean isHalfWidth) {
+        return VIEW_TYPE;
+    }
+
+    @Override
+    public RecyclerView.ViewHolder createViewHolder(View view) {
+        return new LegacySuggestionViewHolder(view);
+    }
+
+    @Override
+    public void bindView(RecyclerView.ViewHolder holder, ContextualCard card) {
+        final LegacySuggestionViewHolder vh = (LegacySuggestionViewHolder) holder;
+        vh.icon.setImageDrawable(card.getIconDrawable());
+        vh.title.setText(card.getTitleText());
+        vh.summary.setText(card.getSummaryText());
+        vh.itemView.setOnClickListener(v ->
+                mControllerRendererPool.getController(mContext,
+                        card.getCardType()).onPrimaryClick(card));
+    }
+
+    private static class LegacySuggestionViewHolder extends RecyclerView.ViewHolder {
+
+        public final ImageView icon;
+        public final TextView title;
+        public final TextView summary;
+
+        public LegacySuggestionViewHolder(View itemView) {
+            super(itemView);
+            icon = itemView.findViewById(android.R.id.icon);
+            title = itemView.findViewById(android.R.id.title);
+            summary = itemView.findViewById(android.R.id.summary);
+        }
+    }
+}
+
diff --git a/src/com/android/settings/network/ApnPreference.java b/src/com/android/settings/network/ApnPreference.java
index 412259b..a7fbb6e 100755
--- a/src/com/android/settings/network/ApnPreference.java
+++ b/src/com/android/settings/network/ApnPreference.java
@@ -25,18 +25,15 @@
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.View;
-import android.view.View.OnClickListener;
 import android.widget.CompoundButton;
 import android.widget.RadioButton;
-import android.widget.RelativeLayout;
 
 import androidx.preference.Preference;
 import androidx.preference.PreferenceViewHolder;
 
 import com.android.settings.R;
 
-public class ApnPreference extends Preference implements
-        CompoundButton.OnCheckedChangeListener, OnClickListener {
+public class ApnPreference extends Preference implements CompoundButton.OnCheckedChangeListener {
     final static String TAG = "ApnPreference";
 
     private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
@@ -82,11 +79,6 @@
                 rb.setVisibility(View.GONE);
             }
         }
-
-        View textLayout = view.findViewById(R.id.text_layout);
-        if ((textLayout != null) && textLayout instanceof RelativeLayout) {
-            textLayout.setOnClickListener(this);
-        }
     }
 
     public boolean isChecked() {
@@ -116,16 +108,16 @@
         }
     }
 
-    public void onClick(android.view.View v) {
-        if ((v != null) && (R.id.text_layout == v.getId())) {
-            Context context = getContext();
-            if (context != null) {
-                int pos = Integer.parseInt(getKey());
-                Uri url = ContentUris.withAppendedId(Telephony.Carriers.CONTENT_URI, pos);
-                Intent editIntent = new Intent(Intent.ACTION_EDIT, url);
-                editIntent.putExtra(ApnSettings.SUB_ID, mSubId);
-                context.startActivity(editIntent);
-            }
+    @Override
+    protected void onClick() {
+        super.onClick();
+        Context context = getContext();
+        if (context != null) {
+            int pos = Integer.parseInt(getKey());
+            Uri url = ContentUris.withAppendedId(Telephony.Carriers.CONTENT_URI, pos);
+            Intent editIntent = new Intent(Intent.ACTION_EDIT, url);
+            editIntent.putExtra(ApnSettings.SUB_ID, mSubId);
+            context.startActivity(editIntent);
         }
     }
 
diff --git a/src/com/android/settings/network/ApnSettings.java b/src/com/android/settings/network/ApnSettings.java
index beeaab3..a71dfaa 100755
--- a/src/com/android/settings/network/ApnSettings.java
+++ b/src/com/android/settings/network/ApnSettings.java
@@ -21,7 +21,6 @@
 import android.app.ProgressDialog;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
-import android.content.ContentUris;
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
@@ -65,8 +64,7 @@
 
 import java.util.ArrayList;
 
-public class ApnSettings extends RestrictedSettingsFragment implements
-        Preference.OnPreferenceChangeListener {
+public class ApnSettings extends RestrictedSettingsFragment {
     static final String TAG = "ApnSettings";
 
     public static final String EXTRA_POSITION = "position";
@@ -313,7 +311,6 @@
                 pref.setTitle(name);
                 pref.setSummary(apn);
                 pref.setPersistent(false);
-                pref.setOnPreferenceChangeListener(this);
                 pref.setSubId(subId);
 
                 boolean selectable = ((type == null) || !type.equals("mms"));
@@ -405,14 +402,6 @@
         startActivity(intent);
     }
 
-    @Override
-    public boolean onPreferenceTreeClick(Preference preference) {
-        int pos = Integer.parseInt(preference.getKey());
-        Uri url = ContentUris.withAppendedId(Telephony.Carriers.CONTENT_URI, pos);
-        startActivity(new Intent(Intent.ACTION_EDIT, url));
-        return true;
-    }
-
     public boolean onPreferenceChange(Preference preference, Object newValue) {
         Log.d(TAG, "onPreferenceChange(): Preference - " + preference
                 + ", newValue - " + newValue + ", newValue type - "
diff --git a/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java b/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java
index b077dd5..b323f91 100644
--- a/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java
+++ b/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java
@@ -180,7 +180,7 @@
                 preference.setEntryValues(
                         R.array.enabled_networks_tdscdma_values);
             } else if (!carrierConfig.getBoolean(CarrierConfigManager.KEY_PREFER_2G_BOOL)
-                    && !resources.getBoolean(R.bool.config_enabled_lte)) {
+                    && !carrierConfig.getBoolean(CarrierConfigManager.KEY_LTE_ENABLED_BOOL)) {
                 preference.setEntries(R.array.enabled_networks_except_gsm_lte_choices);
                 preference.setEntryValues(R.array.enabled_networks_except_gsm_lte_values);
             } else if (!carrierConfig.getBoolean(CarrierConfigManager.KEY_PREFER_2G_BOOL)) {
@@ -190,7 +190,7 @@
                 preference.setEntries(select);
                 preference.setEntryValues(
                         R.array.enabled_networks_except_gsm_values);
-            } else if (!resources.getBoolean(R.bool.config_enabled_lte)) {
+            } else if (!carrierConfig.getBoolean(CarrierConfigManager.KEY_LTE_ENABLED_BOOL)) {
                 preference.setEntries(
                         R.array.enabled_networks_except_lte_choices);
                 preference.setEntryValues(
diff --git a/src/com/android/settings/network/telephony/MobileNetworkUtils.java b/src/com/android/settings/network/telephony/MobileNetworkUtils.java
index 689799e..dc184d3 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkUtils.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkUtils.java
@@ -27,6 +27,7 @@
 import android.os.PersistableBundle;
 import android.os.SystemProperties;
 import android.provider.Settings;
+import android.service.carrier.CarrierMessagingService;
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
 import android.telephony.CarrierConfigManager;
@@ -329,28 +330,11 @@
      * settings
      */
     public static boolean isWorldMode(Context context, int subId) {
-        final TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class)
-                .createForSubscriptionId(subId);
-        boolean worldModeOn = false;
-        final String configString = context.getString(R.string.config_world_mode);
-
-        if (!TextUtils.isEmpty(configString)) {
-            String[] configArray = configString.split(";");
-            // Check if we have World mode configuration set to True only or config is set to True
-            // and SIM GID value is also set and matches to the current SIM GID.
-            if (configArray != null &&
-                    ((configArray.length == 1 && configArray[0].equalsIgnoreCase("true"))
-                            || (configArray.length == 2 && !TextUtils.isEmpty(configArray[1])
-                            && telephonyManager != null
-                            && configArray[1].equalsIgnoreCase(
-                            telephonyManager.getGroupIdLevel1())))) {
-                worldModeOn = true;
-            }
-        }
-
-        Log.d(TAG, "isWorldMode=" + worldModeOn);
-
-        return worldModeOn;
+        final PersistableBundle carrierConfig = context.getSystemService(
+                CarrierConfigManager.class).getConfigForSubId(subId);
+        return carrierConfig == null
+                ? false
+                : carrierConfig.getBoolean(CarrierConfigManager.KEY_WORLD_MODE_ENABLED_BOOL);
     }
 
     /**
@@ -396,14 +380,21 @@
 
     //TODO(b/117651939): move it to telephony
     private static boolean isTdscdmaSupported(Context context, TelephonyManager telephonyManager) {
-        if (context.getResources().getBoolean(R.bool.config_support_tdscdma)) {
+        final PersistableBundle carrierConfig = context.getSystemService(
+                CarrierConfigManager.class).getConfig();
+
+        if (carrierConfig == null) {
+            return false;
+        }
+
+        if (carrierConfig.getBoolean(CarrierConfigManager.KEY_SUPPORT_TDSCDMA_BOOL)) {
             return true;
         }
 
         String operatorNumeric = telephonyManager.getServiceState().getOperatorNumeric();
-        String[] numericArray = context.getResources().getStringArray(
-                R.array.config_support_tdscdma_roaming_on_networks);
-        if (numericArray.length == 0 || operatorNumeric == null) {
+        String[] numericArray = carrierConfig.getStringArray(
+                CarrierConfigManager.KEY_SUPPORT_TDSCDMA_ROAMING_NETWORKS_STRING_ARRAY);
+        if (numericArray == null || operatorNumeric == null) {
             return false;
         }
         for (String numeric : numericArray) {
@@ -413,4 +404,4 @@
         }
         return false;
     }
-}
\ No newline at end of file
+}
diff --git a/src/com/android/settings/print/PrintJobMessagePreferenceController.java b/src/com/android/settings/print/PrintJobMessagePreferenceController.java
new file mode 100644
index 0000000..9573e5d
--- /dev/null
+++ b/src/com/android/settings/print/PrintJobMessagePreferenceController.java
@@ -0,0 +1,47 @@
+/*
+ * 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.print;
+
+import android.content.Context;
+import android.print.PrintJob;
+import android.print.PrintJobInfo;
+import android.text.TextUtils;
+
+public class PrintJobMessagePreferenceController extends PrintJobPreferenceControllerBase {
+
+    public PrintJobMessagePreferenceController(Context context, String key) {
+        super(context, key);
+    }
+
+    @Override
+    protected void updateUi() {
+        final PrintJob printJob = getPrintJob();
+
+        if (printJob == null) {
+            mFragment.finish();
+            return;
+        }
+
+        if (printJob.isCancelled() || printJob.isCompleted()) {
+            mFragment.finish();
+            return;
+        }
+
+        final PrintJobInfo info = printJob.getInfo();
+        final CharSequence status = info.getStatus(mContext.getPackageManager());
+        mPreference.setVisible(!TextUtils.isEmpty(status));
+        mPreference.setSummary(status);
+    }
+}
diff --git a/src/com/android/settings/print/PrintJobPreferenceController.java b/src/com/android/settings/print/PrintJobPreferenceController.java
new file mode 100644
index 0000000..0eff0d6
--- /dev/null
+++ b/src/com/android/settings/print/PrintJobPreferenceController.java
@@ -0,0 +1,115 @@
+/*
+ * 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.print;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
+import android.print.PrintJob;
+import android.print.PrintJobInfo;
+import android.text.format.DateUtils;
+
+import com.android.settings.R;
+
+import java.text.DateFormat;
+
+public class PrintJobPreferenceController extends PrintJobPreferenceControllerBase {
+
+    public PrintJobPreferenceController(Context context, String key) {
+        super(context, key);
+    }
+
+    @Override
+    protected void updateUi() {
+        final PrintJob printJob = getPrintJob();
+
+        if (printJob == null) {
+            mFragment.finish();
+            return;
+        }
+
+        if (printJob.isCancelled() || printJob.isCompleted()) {
+            mFragment.finish();
+            return;
+        }
+
+        PrintJobInfo info = printJob.getInfo();
+
+        switch (info.getState()) {
+            case PrintJobInfo.STATE_CREATED: {
+                mPreference.setTitle(mContext.getString(
+                        R.string.print_configuring_state_title_template, info.getLabel()));
+            }
+            break;
+            case PrintJobInfo.STATE_QUEUED:
+            case PrintJobInfo.STATE_STARTED: {
+                if (!printJob.getInfo().isCancelling()) {
+                    mPreference.setTitle(mContext.getString(
+                            R.string.print_printing_state_title_template, info.getLabel()));
+                } else {
+                    mPreference.setTitle(mContext.getString(
+                            R.string.print_cancelling_state_title_template, info.getLabel()));
+                }
+            }
+            break;
+
+            case PrintJobInfo.STATE_FAILED: {
+                mPreference.setTitle(mContext.getString(
+                        R.string.print_failed_state_title_template, info.getLabel()));
+            }
+            break;
+
+            case PrintJobInfo.STATE_BLOCKED: {
+                if (!printJob.getInfo().isCancelling()) {
+                    mPreference.setTitle(mContext.getString(
+                            R.string.print_blocked_state_title_template, info.getLabel()));
+                } else {
+                    mPreference.setTitle(mContext.getString(
+                            R.string.print_cancelling_state_title_template, info.getLabel()));
+                }
+            }
+            break;
+        }
+
+        mPreference.setSummary(mContext.getString(R.string.print_job_summary,
+                info.getPrinterName(), DateUtils.formatSameDayTime(
+                        info.getCreationTime(), info.getCreationTime(), DateFormat.SHORT,
+                        DateFormat.SHORT)));
+
+        TypedArray a = mContext.obtainStyledAttributes(new int[]{
+                android.R.attr.colorControlNormal});
+        int tintColor = a.getColor(0, 0);
+        a.recycle();
+
+        switch (info.getState()) {
+            case PrintJobInfo.STATE_QUEUED:
+            case PrintJobInfo.STATE_STARTED: {
+                Drawable icon = mContext.getDrawable(com.android.internal.R.drawable.ic_print);
+                icon.setTint(tintColor);
+                mPreference.setIcon(icon);
+                break;
+            }
+
+            case PrintJobInfo.STATE_FAILED:
+            case PrintJobInfo.STATE_BLOCKED: {
+                Drawable icon = mContext.getDrawable(
+                        com.android.internal.R.drawable.ic_print_error);
+                icon.setTint(tintColor);
+                mPreference.setIcon(icon);
+                break;
+            }
+        }
+    }
+}
diff --git a/src/com/android/settings/print/PrintJobPreferenceControllerBase.java b/src/com/android/settings/print/PrintJobPreferenceControllerBase.java
new file mode 100644
index 0000000..0726a19
--- /dev/null
+++ b/src/com/android/settings/print/PrintJobPreferenceControllerBase.java
@@ -0,0 +1,99 @@
+/*
+ * 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.print;
+
+import android.content.Context;
+import android.print.PrintJob;
+import android.print.PrintJobId;
+import android.print.PrintManager;
+import android.util.Log;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.core.BasePreferenceController;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.OnStart;
+import com.android.settingslib.core.lifecycle.events.OnStop;
+
+public abstract class PrintJobPreferenceControllerBase extends BasePreferenceController implements
+        LifecycleObserver, OnStart, OnStop, PrintManager.PrintJobStateChangeListener {
+    private static final String TAG = "PrintJobPrefCtrlBase";
+
+    private static final String EXTRA_PRINT_JOB_ID = "EXTRA_PRINT_JOB_ID";
+
+    private final PrintManager mPrintManager;
+    protected Preference mPreference;
+    protected PrintJobSettingsFragment mFragment;
+    protected PrintJobId mPrintJobId;
+
+    public PrintJobPreferenceControllerBase(Context context, String key) {
+        super(context, key);
+        mPrintManager = ((PrintManager) mContext.getSystemService(
+                Context.PRINT_SERVICE)).getGlobalPrintManagerForUser(mContext.getUserId());
+    }
+
+    @Override
+    public void onStart() {
+        mPrintManager.addPrintJobStateChangeListener(this);
+        updateUi();
+    }
+
+    @Override
+    public void onStop() {
+        mPrintManager.removePrintJobStateChangeListener(this);
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return AVAILABLE;
+    }
+
+    @Override
+    public void onPrintJobStateChanged(PrintJobId printJobId) {
+        updateUi();
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        mPreference = screen.findPreference(getPreferenceKey());
+    }
+
+    public void init(PrintJobSettingsFragment fragment) {
+        mFragment = fragment;
+        processArguments();
+    }
+
+    protected PrintJob getPrintJob() {
+        return mPrintManager.getPrintJob(mPrintJobId);
+    }
+
+    protected abstract void updateUi();
+
+    private void processArguments() {
+        String printJobId = mFragment.getArguments().getString(EXTRA_PRINT_JOB_ID);
+        if (printJobId == null) {
+            printJobId = mFragment.getActivity().getIntent().getStringExtra(EXTRA_PRINT_JOB_ID);
+
+            if (printJobId == null) {
+                Log.w(TAG, EXTRA_PRINT_JOB_ID + " not set");
+                mFragment.finish();
+                return;
+            }
+        }
+        mPrintJobId = PrintJobId.unflattenFromString(printJobId);
+    }
+}
diff --git a/src/com/android/settings/print/PrintJobSettingsFragment.java b/src/com/android/settings/print/PrintJobSettingsFragment.java
index ba0172b..1d6ff5a 100644
--- a/src/com/android/settings/print/PrintJobSettingsFragment.java
+++ b/src/com/android/settings/print/PrintJobSettingsFragment.java
@@ -17,60 +17,42 @@
 package com.android.settings.print;
 
 import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.print.PrintJob;
-import android.print.PrintJobId;
-import android.print.PrintJobInfo;
-import android.print.PrintManager;
-import android.print.PrintManager.PrintJobStateChangeListener;
-import android.text.TextUtils;
-import android.text.format.DateUtils;
-import android.util.Log;
-import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.preference.Preference;
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-
-import java.text.DateFormat;
+import com.android.settings.dashboard.DashboardFragment;
 
 /**
  * Fragment for management of a print job.
  */
-public class PrintJobSettingsFragment extends SettingsPreferenceFragment {
-    private static final String LOG_TAG = PrintJobSettingsFragment.class.getSimpleName();
+public class PrintJobSettingsFragment extends DashboardFragment {
+    private static final String TAG = "PrintJobSettingsFragment";
 
     private static final int MENU_ITEM_ID_CANCEL = 1;
     private static final int MENU_ITEM_ID_RESTART = 2;
 
-    private static final String EXTRA_PRINT_JOB_ID = "EXTRA_PRINT_JOB_ID";
+    @Override
+    protected int getPreferenceScreenResId() {
+        return R.xml.print_job_settings;
+    }
 
-    private static final String PRINT_JOB_PREFERENCE = "print_job_preference";
-    private static final String PRINT_JOB_MESSAGE_PREFERENCE = "print_job_message_preference";
+    @Override
+    protected String getLogTag() {
+        return TAG;
+    }
 
-    private final PrintJobStateChangeListener mPrintJobStateChangeListener =
-            new PrintJobStateChangeListener() {
-        @Override
-        public void onPrintJobStateChanged(PrintJobId printJobId) {
-            updateUi();
-        }
-    };
-
-    private PrintManager mPrintManager;
-
-    private Preference mPrintJobPreference;
-    private Preference mMessagePreference;
-
-    private PrintJobId mPrintJobId;
+    @Override
+    public void onAttach(Context context) {
+        super.onAttach(context);
+        use(PrintJobPreferenceController.class).init(this);
+        use(PrintJobMessagePreferenceController.class).init(this);
+    }
 
     @Override
     public int getMetricsCategory() {
@@ -78,53 +60,16 @@
     }
 
     @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container,
-            Bundle savedInstanceState) {
-        View view = super.onCreateView(inflater, container, savedInstanceState);
-
-        addPreferencesFromResource(R.xml.print_job_settings);
-        mPrintJobPreference = findPreference(PRINT_JOB_PREFERENCE);
-        mMessagePreference = findPreference(PRINT_JOB_MESSAGE_PREFERENCE);
-
-        mPrintManager = ((PrintManager) getActivity().getSystemService(
-                Context.PRINT_SERVICE)).getGlobalPrintManagerForUser(
-                        getActivity().getUserId());
-
-        getActivity().getActionBar().setTitle(R.string.print_print_job);
-
-        processArguments();
-
-        setHasOptionsMenu(true);
-
-        return  view;
-    }
-
-    @Override
     public void onViewCreated(View view, Bundle savedInstanceState) {
         super.onViewCreated(view, savedInstanceState);
         getListView().setEnabled(false);
     }
 
     @Override
-    public void onStart() {
-        super.onStart();
-        mPrintManager.addPrintJobStateChangeListener(
-                mPrintJobStateChangeListener);
-        updateUi();
-    }
-
-    @Override
-    public void onStop() {
-        super.onStop();
-        mPrintManager.removePrintJobStateChangeListener(
-                mPrintJobStateChangeListener);
-    }
-
-    @Override
     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
         super.onCreateOptionsMenu(menu, inflater);
 
-        PrintJob printJob = getPrintJob();
+        final PrintJob printJob = use(PrintJobPreferenceController.class).getPrintJob();
         if (printJob == null) {
             return;
         }
@@ -144,7 +89,7 @@
 
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
-        PrintJob printJob = getPrintJob();
+        final PrintJob printJob = use(PrintJobPreferenceController.class).getPrintJob();
 
         if (printJob != null) {
             switch (item.getItemId()) {
@@ -164,113 +109,4 @@
 
         return super.onOptionsItemSelected(item);
     }
-
-    private void processArguments() {
-        String printJobId = getArguments().getString(EXTRA_PRINT_JOB_ID);
-        if (printJobId == null) {
-            printJobId = getIntent().getStringExtra(EXTRA_PRINT_JOB_ID);
-
-            if (printJobId == null) {
-                Log.w(LOG_TAG, EXTRA_PRINT_JOB_ID + " not set");
-                finish();
-                return;
-            }
-        }
-
-
-        mPrintJobId = PrintJobId.unflattenFromString(printJobId);
-    }
-
-    private PrintJob getPrintJob() {
-        return mPrintManager.getPrintJob(mPrintJobId);
-    }
-
-    private void updateUi() {
-        PrintJob printJob = getPrintJob();
-
-        if (printJob == null) {
-            finish();
-            return;
-        }
-
-        if (printJob.isCancelled() || printJob.isCompleted()) {
-            finish();
-            return;
-        }
-
-        PrintJobInfo info = printJob.getInfo();
-
-        switch (info.getState()) {
-            case PrintJobInfo.STATE_CREATED: {
-                mPrintJobPreference.setTitle(getString(
-                        R.string.print_configuring_state_title_template, info.getLabel()));
-            } break;
-            case PrintJobInfo.STATE_QUEUED:
-            case PrintJobInfo.STATE_STARTED: {
-                if (!printJob.getInfo().isCancelling()) {
-                    mPrintJobPreference.setTitle(getString(
-                            R.string.print_printing_state_title_template, info.getLabel()));
-                } else {
-                    mPrintJobPreference.setTitle(getString(
-                            R.string.print_cancelling_state_title_template, info.getLabel()));
-                }
-            } break;
-
-            case PrintJobInfo.STATE_FAILED: {
-                mPrintJobPreference.setTitle(getString(
-                        R.string.print_failed_state_title_template, info.getLabel()));
-            } break;
-
-            case PrintJobInfo.STATE_BLOCKED: {
-                if (!printJob.getInfo().isCancelling()) {
-                    mPrintJobPreference.setTitle(getString(
-                            R.string.print_blocked_state_title_template, info.getLabel()));
-                } else {
-                    mPrintJobPreference.setTitle(getString(
-                            R.string.print_cancelling_state_title_template, info.getLabel()));
-                }
-            } break;
-        }
-
-        mPrintJobPreference.setSummary(getString(R.string.print_job_summary,
-                info.getPrinterName(), DateUtils.formatSameDayTime(
-                        info.getCreationTime(), info.getCreationTime(), DateFormat.SHORT,
-                        DateFormat.SHORT)));
-
-        TypedArray a = getActivity().obtainStyledAttributes(new int[]{
-                android.R.attr.colorControlNormal});
-        int tintColor = a.getColor(0, 0);
-        a.recycle();
-
-        switch (info.getState()) {
-            case PrintJobInfo.STATE_QUEUED:
-            case PrintJobInfo.STATE_STARTED: {
-                Drawable icon = getActivity().getDrawable(com.android.internal.R.drawable.ic_print);
-                icon.setTint(tintColor);
-                mPrintJobPreference.setIcon(icon);
-                break;
-            }
-
-            case PrintJobInfo.STATE_FAILED:
-            case PrintJobInfo.STATE_BLOCKED: {
-                Drawable icon = getActivity().getDrawable(
-                        com.android.internal.R.drawable.ic_print_error);
-                icon.setTint(tintColor);
-                mPrintJobPreference.setIcon(icon);
-                break;
-            }
-        }
-
-        CharSequence status = info.getStatus(getPackageManager());
-        if (!TextUtils.isEmpty(status)) {
-            if (getPreferenceScreen().findPreference(PRINT_JOB_MESSAGE_PREFERENCE) == null) {
-                getPreferenceScreen().addPreference(mMessagePreference);
-            }
-            mMessagePreference.setSummary(status);
-        } else {
-            getPreferenceScreen().removePreference(mMessagePreference);
-        }
-
-        getActivity().invalidateOptionsMenu();
-    }
 }
diff --git a/src/com/android/settings/wifi/WifiConfigController.java b/src/com/android/settings/wifi/WifiConfigController.java
index 4b93fc1..70837a6 100644
--- a/src/com/android/settings/wifi/WifiConfigController.java
+++ b/src/com/android/settings/wifi/WifiConfigController.java
@@ -454,6 +454,13 @@
         return false;
     }
 
+    boolean isValidSaePassword(String password) {
+        if (password.length() >= 1 && password.length() <= 63) {
+            return true;
+        }
+        return false;
+    }
+
     boolean isSubmittable() {
         boolean enabled = false;
         boolean passwordInvalid = false;
@@ -461,7 +468,9 @@
                 && ((mAccessPointSecurity == AccessPoint.SECURITY_WEP
                         && mPasswordView.length() == 0)
                     || (mAccessPointSecurity == AccessPoint.SECURITY_PSK
-                           && !isValidPsk(mPasswordView.getText().toString())))) {
+                           && !isValidPsk(mPasswordView.getText().toString()))
+                    || (mAccessPointSecurity == AccessPoint.SECURITY_SAE
+                        && !isValidSaePassword(mPasswordView.getText().toString())))) {
             passwordInvalid = true;
         }
         if ((mSsidView != null && mSsidView.length() == 0)
@@ -475,7 +484,9 @@
         } else {
             enabled = ipAndProxyFieldsAreValid();
         }
-        if (mAccessPointSecurity == AccessPoint.SECURITY_EAP && mEapCaCertSpinner != null
+        if ((mAccessPointSecurity == AccessPoint.SECURITY_EAP ||
+                mAccessPointSecurity == AccessPoint.SECURITY_EAP_SUITE_B)
+                && mEapCaCertSpinner != null
                 && mView.findViewById(R.id.l_ca_cert).getVisibility() != View.GONE) {
             String caCertSelection = (String) mEapCaCertSpinner.getSelectedItem();
             if (caCertSelection.equals(mUnspecifiedCertString)) {
@@ -492,7 +503,9 @@
                 enabled = false;
             }
         }
-        if (mAccessPointSecurity == AccessPoint.SECURITY_EAP && mEapUserCertSpinner != null
+        if ((mAccessPointSecurity == AccessPoint.SECURITY_EAP ||
+                mAccessPointSecurity == AccessPoint.SECURITY_EAP_SUITE_B)
+                && mEapUserCertSpinner != null
                 && mView.findViewById(R.id.l_user_cert).getVisibility() != View.GONE
                 && mEapUserCertSpinner.getSelectedItem().equals(mUnspecifiedCertString)) {
             // Disallow submit if the user has not selected a user certificate for an EAP network
@@ -590,8 +603,18 @@
                 break;
 
             case AccessPoint.SECURITY_EAP:
+            case AccessPoint.SECURITY_EAP_SUITE_B:
                 config.allowedKeyManagement.set(KeyMgmt.WPA_EAP);
                 config.allowedKeyManagement.set(KeyMgmt.IEEE8021X);
+                if (mAccessPointSecurity == AccessPoint.SECURITY_EAP_SUITE_B) {
+                    config.allowedKeyManagement.set(KeyMgmt.SUITE_B_192);
+                    config.requirePMF = true;
+                    config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.GCMP_256);
+                    config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256);
+                    config.allowedGroupMgmtCiphers.set(WifiConfiguration.GroupMgmtCipher
+                            .BIP_GMAC_256);
+                    config.allowedSuiteBCiphers.set(WifiConfiguration.SuiteBCipher.ECDHE_RSA);
+                }
                 config.enterpriseConfig = new WifiEnterpriseConfig();
                 int eapMethod = mEapMethodSpinner.getSelectedItemPosition();
                 int phase2Method = mPhase2Spinner.getSelectedItemPosition();
@@ -700,6 +723,20 @@
                     config.enterpriseConfig.setPassword(mPasswordView.getText().toString());
                 }
                 break;
+            case AccessPoint.SECURITY_SAE:
+                config.allowedKeyManagement.set(KeyMgmt.SAE);
+                config.requirePMF = true;
+                if (mPasswordView.length() != 0) {
+                    String password = mPasswordView.getText().toString();
+                    config.preSharedKey = '"' + password + '"';
+                }
+                break;
+
+            case AccessPoint.SECURITY_OWE:
+                config.allowedKeyManagement.set(KeyMgmt.OWE);
+                config.requirePMF = true;
+                break;
+
             default:
                 return null;
         }
@@ -851,7 +888,8 @@
     }
 
     private void showSecurityFields() {
-        if (mAccessPointSecurity == AccessPoint.SECURITY_NONE) {
+        if (mAccessPointSecurity == AccessPoint.SECURITY_NONE ||
+                  mAccessPointSecurity == AccessPoint.SECURITY_OWE) {
             mView.findViewById(R.id.security_fields).setVisibility(View.GONE);
             return;
         }
@@ -870,7 +908,8 @@
             }
         }
 
-        if (mAccessPointSecurity != AccessPoint.SECURITY_EAP) {
+        if (mAccessPointSecurity != AccessPoint.SECURITY_EAP &&
+                mAccessPointSecurity != AccessPoint.SECURITY_EAP_SUITE_B) {
             mView.findViewById(R.id.eap).setVisibility(View.GONE);
             return;
         }
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index f097d5b..1c9a5e1 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -488,7 +488,8 @@
                 menu.add(Menu.NONE, MENU_ID_MODIFY, 0, R.string.wifi_menu_modify);
                 NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(getActivity());
                 if (nfcAdapter != null && nfcAdapter.isEnabled() &&
-                        mSelectedAccessPoint.getSecurity() != AccessPoint.SECURITY_NONE) {
+                        (!(mSelectedAccessPoint.getSecurity() == AccessPoint.SECURITY_NONE) ||
+                                (mSelectedAccessPoint.getSecurity() == AccessPoint.SECURITY_OWE))) {
                     // Only allow writing of NFC tags for password-protected networks.
                     menu.add(Menu.NONE, MENU_ID_WRITE_NFC, 0, R.string.wifi_menu_write_to_nfc);
                 }
@@ -506,7 +507,8 @@
                 boolean isSavedNetwork = mSelectedAccessPoint.isSaved();
                 if (isSavedNetwork) {
                     connect(mSelectedAccessPoint.getConfig(), isSavedNetwork);
-                } else if (mSelectedAccessPoint.getSecurity() == AccessPoint.SECURITY_NONE) {
+                } else if ((mSelectedAccessPoint.getSecurity() == AccessPoint.SECURITY_NONE) ||
+                        (mSelectedAccessPoint.getSecurity() == AccessPoint.SECURITY_OWE)) {
                     /** Bypass dialog for unsecured networks */
                     mSelectedAccessPoint.generateOpenNetworkConfig();
                     connect(mSelectedAccessPoint.getConfig(), isSavedNetwork);
@@ -552,7 +554,8 @@
              * networks, or Passpoint provided networks.
              */
             WifiConfiguration config = mSelectedAccessPoint.getConfig();
-            if (mSelectedAccessPoint.getSecurity() == AccessPoint.SECURITY_NONE) {
+            if ((mSelectedAccessPoint.getSecurity() == AccessPoint.SECURITY_NONE) ||
+                    (mSelectedAccessPoint.getSecurity() == AccessPoint.SECURITY_OWE)) {
                 mSelectedAccessPoint.generateOpenNetworkConfig();
                 connect(mSelectedAccessPoint.getConfig(), mSelectedAccessPoint.isSaved());
             } else if (mSelectedAccessPoint.isSaved() && config != null
@@ -772,7 +775,8 @@
                 preference.setKey(key);
                 preference.setOrder(index);
                 if (mOpenSsid != null && mOpenSsid.equals(accessPoint.getSsidStr())
-                        && accessPoint.getSecurity() != AccessPoint.SECURITY_NONE) {
+                        && (accessPoint.getSecurity() != AccessPoint.SECURITY_NONE &&
+                        accessPoint.getSecurity() != AccessPoint.SECURITY_OWE)) {
                     if (!accessPoint.isSaved() || isDisabledByWrongPassword(accessPoint)) {
                         onPreferenceTreeClick(preference);
                         mOpenSsid = null;
diff --git a/src/com/android/settings/wifi/details/WifiPrivacyPreferenceController.java b/src/com/android/settings/wifi/details/WifiPrivacyPreferenceController.java
index 2afe35b..9f81431 100644
--- a/src/com/android/settings/wifi/details/WifiPrivacyPreferenceController.java
+++ b/src/com/android/settings/wifi/details/WifiPrivacyPreferenceController.java
@@ -67,7 +67,7 @@
     @Override
     public boolean onPreferenceChange(Preference preference, Object newValue) {
         if (mWifiConfiguration != null) {
-            //TODO(b/117957974): update MAC randomization level to WifiManager
+            mWifiConfiguration.macRandomizationSetting = Integer.parseInt((String) newValue);
             mWifiManager.updateNetwork(mWifiConfiguration);
         }
         updateSummary((DropDownPreference) preference, Integer.parseInt((String) newValue));
@@ -77,10 +77,9 @@
     @VisibleForTesting
     int getRandomizationValue() {
         if (mWifiConfiguration != null) {
-            //TODO(b/117957974): get real MAC randomization level from WifiManager
-            return 0;
+            return mWifiConfiguration.macRandomizationSetting;
         }
-        return 0;
+        return WifiConfiguration.RANDOMIZATION_PERSISTENT;
     }
 
     private void updateSummary(DropDownPreference preference, int macRandomized) {
diff --git a/tests/robotests/assets/grandfather_not_implementing_index_provider b/tests/robotests/assets/grandfather_not_implementing_index_provider
index 6f4deca..f9301a2 100644
--- a/tests/robotests/assets/grandfather_not_implementing_index_provider
+++ b/tests/robotests/assets/grandfather_not_implementing_index_provider
@@ -15,7 +15,6 @@
 com.android.settings.applications.AppLaunchSettings
 com.android.settings.applications.AppStorageSettings
 com.android.settings.applications.ConfirmConvertToFbe
-com.android.settings.applications.DirectoryAccessDetails
 com.android.settings.applications.ProcessStatsDetail
 com.android.settings.applications.ProcessStatsSummary
 com.android.settings.applications.ProcessStatsUi
diff --git a/tests/robotests/res/values-mcc999/config.xml b/tests/robotests/res/values-mcc999/config.xml
index 6347d79..73d2264 100644
--- a/tests/robotests/res/values-mcc999/config.xml
+++ b/tests/robotests/res/values-mcc999/config.xml
@@ -62,6 +62,8 @@
     <bool name="config_show_wifi_mac_address">false</bool>
     <bool name="config_disable_uninstall_update">true</bool>
     <bool name="config_show_device_name">false</bool>
+    <bool name="config_use_legacy_suggestion">false</bool>
+    <bool name="config_show_avatar_in_homepage">true</bool>
 
     <!-- Whether or not extra preview panels should be used for screen zoom setting. -->
     <bool name="config_enable_extra_screen_zoom_preview">false</bool>
diff --git a/tests/robotests/src/com/android/settings/accounts/AvatarViewMixinTest.java b/tests/robotests/src/com/android/settings/accounts/AvatarViewMixinTest.java
index c72561e..b3d929c 100644
--- a/tests/robotests/src/com/android/settings/accounts/AvatarViewMixinTest.java
+++ b/tests/robotests/src/com/android/settings/accounts/AvatarViewMixinTest.java
@@ -18,6 +18,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 
@@ -29,7 +30,6 @@
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 
 import org.junit.Before;
-import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.MockitoAnnotations;
@@ -69,6 +69,15 @@
     }
 
     @Test
+    public void onStart_configDisabled_doNothing() {
+        final AvatarViewMixin mixin = spy(new AvatarViewMixin(mContext, mImageView));
+        mixin.onStart();
+
+        verify(mixin, never()).hasAccount();
+    }
+
+    @Test
+    @Config(qualifiers = "mcc999")
     public void onStart_useMockAvatarViewMixin_shouldBeExecuted() {
         final AvatarViewMixin mockAvatar = spy(new AvatarViewMixin(mContext, mImageView));
 
@@ -79,7 +88,7 @@
         settingsHomepageActivity.getLifecycle().addObserver(mockAvatar);
         controller.start();
 
-        verify(mockAvatar).onStart();
+        verify(mockAvatar).hasAccount();
     }
 
     @Implements(AccountFeatureProviderImpl.class)
diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/AppHeaderViewPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/AppHeaderViewPreferenceControllerTest.java
index a342e10..d3e00c3 100644
--- a/tests/robotests/src/com/android/settings/applications/appinfo/AppHeaderViewPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/appinfo/AppHeaderViewPreferenceControllerTest.java
@@ -106,15 +106,12 @@
 
 
         final TextView title = mHeader.findViewById(R.id.entity_header_title);
-        final TextView summary = mHeader.findViewById(R.id.entity_header_summary);
 
         mController.displayPreference(mScreen);
         mController.refreshUi();
 
         assertThat(title).isNotNull();
         assertThat(title.getText()).isEqualTo(appLabel);
-        assertThat(summary).isNotNull();
-        assertThat(summary.getText()).isEqualTo(mContext.getString(R.string.installed));
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/BluetoothOnWhileDrivingPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/BluetoothOnWhileDrivingPreferenceControllerTest.java
deleted file mode 100644
index 83763bb..0000000
--- a/tests/robotests/src/com/android/settings/connecteddevice/BluetoothOnWhileDrivingPreferenceControllerTest.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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.connecteddevice;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.Context;
-import android.provider.Settings;
-import android.provider.Settings.Secure;
-import android.util.FeatureFlagUtils;
-
-import com.android.settings.core.BasePreferenceController;
-import com.android.settings.core.FeatureFlags;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RuntimeEnvironment;
-
-@RunWith(SettingsRobolectricTestRunner.class)
-public class BluetoothOnWhileDrivingPreferenceControllerTest {
-
-    private BluetoothOnWhileDrivingPreferenceController mController;
-    private Context mContext;
-
-    @Before
-    public void setUp() {
-        mContext = RuntimeEnvironment.application;
-        mController = new BluetoothOnWhileDrivingPreferenceController(mContext);
-    }
-
-    @Test
-    public void getAvailabilityStatus_onWhenEnabled() {
-        FeatureFlagUtils.setEnabled(mContext, FeatureFlags.BLUETOOTH_WHILE_DRIVING, true);
-
-        assertThat(mController.getAvailabilityStatus())
-            .isEqualTo(BasePreferenceController.AVAILABLE);
-    }
-
-    @Test
-    public void getAvailabilityStatus_offWhenDisabled() {
-        assertThat(mController.getAvailabilityStatus())
-            .isEqualTo(BasePreferenceController.CONDITIONALLY_UNAVAILABLE);
-    }
-
-    @Test
-    public void setChecked_togglesSettingSecure() {
-        mController.setChecked(true);
-
-        final String name = Secure.BLUETOOTH_ON_WHILE_DRIVING;
-        assertThat(Settings.Secure.getInt(mContext.getContentResolver(), name, 0)).isEqualTo(1);
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/deviceinfo/DeviceNameWarningDialogTest.java b/tests/robotests/src/com/android/settings/deviceinfo/aboutphone/DeviceNameWarningDialogTest.java
similarity index 72%
rename from tests/robotests/src/com/android/settings/deviceinfo/deviceinfo/DeviceNameWarningDialogTest.java
rename to tests/robotests/src/com/android/settings/deviceinfo/aboutphone/DeviceNameWarningDialogTest.java
index 0be0ac2..6ea36a0 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/deviceinfo/DeviceNameWarningDialogTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/aboutphone/DeviceNameWarningDialogTest.java
@@ -1,4 +1,20 @@
-package com.android.settings.deviceinfo.deviceinfo;
+/*
+ * 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.deviceinfo.aboutphone;
 
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
@@ -6,8 +22,6 @@
 
 import android.content.DialogInterface;
 
-import com.android.settings.deviceinfo.aboutphone.DeviceNameWarningDialog;
-import com.android.settings.deviceinfo.aboutphone.MyDeviceInfoFragment;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 
 import org.junit.Test;
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/MyDeviceInfoFragmentTest.java b/tests/robotests/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragmentTest.java
similarity index 97%
rename from tests/robotests/src/com/android/settings/deviceinfo/MyDeviceInfoFragmentTest.java
rename to tests/robotests/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragmentTest.java
index 4a741cf..e304a1e 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/MyDeviceInfoFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragmentTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.settings.deviceinfo;
+package com.android.settings.deviceinfo.aboutphone;
 
 import static com.android.settings.SettingsActivity.EXTRA_FRAGMENT_ARG_KEY;
 
@@ -35,7 +35,7 @@
 import androidx.fragment.app.FragmentActivity;
 import androidx.preference.PreferenceScreen;
 
-import com.android.settings.deviceinfo.aboutphone.MyDeviceInfoFragment;
+import com.android.settings.deviceinfo.BuildNumberPreferenceController;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.SettingsShadowResources;
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/aboutphone/TopLevelAboutDevicePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/aboutphone/TopLevelAboutDevicePreferenceControllerTest.java
new file mode 100644
index 0000000..ae3007c
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/deviceinfo/aboutphone/TopLevelAboutDevicePreferenceControllerTest.java
@@ -0,0 +1,55 @@
+/*
+ * 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.deviceinfo.aboutphone;
+
+
+import static com.android.settings.core.BasePreferenceController.AVAILABLE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.os.Build;
+
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class TopLevelAboutDevicePreferenceControllerTest {
+
+    private Context mContext;
+    private TopLevelAboutDevicePreferenceController mController;
+
+    @Before
+    public void setUp() {
+        mContext = RuntimeEnvironment.application;
+        mController = new TopLevelAboutDevicePreferenceController(mContext, "test_key");
+    }
+
+    @Test
+    public void getAvailabilityState_shouldBeAvailable() {
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
+    }
+
+    @Test
+    public void getSummary_shouldReturnDeviceModel() {
+        assertThat(mController.getSummary().toString()).isEqualTo(Build.MODEL);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
index b356c49..1a8d58d 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
@@ -258,7 +258,6 @@
         verify(mEntityHeaderController).setIcon(mAppEntry);
         verify(mEntityHeaderController).setLabel(mAppEntry);
         verify(mEntityHeaderController).setIsInstantApp(true);
-        verify(mEntityHeaderController).setSummary((CharSequence) null);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/CardDatabaseHelperTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/CardDatabaseHelperTest.java
index b25508b..ef60f85 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/CardDatabaseHelperTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/CardDatabaseHelperTest.java
@@ -18,10 +18,12 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import android.content.ContentValues;
 import android.content.Context;
 import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
 
+import com.android.settings.intelligence.ContextualCardProto;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 
 import org.junit.After;
@@ -30,6 +32,9 @@
 import org.junit.runner.RunWith;
 import org.robolectric.RuntimeEnvironment;
 
+import java.util.ArrayList;
+import java.util.List;
+
 @RunWith(SettingsRobolectricTestRunner.class)
 public class CardDatabaseHelperTest {
 
@@ -80,4 +85,38 @@
         assertThat(columnNames).isEqualTo(expectedNames);
         cursor.close();
     }
+
+    @Test
+    public void getContextualCards_shouldSortByScore() {
+        insertFakeCard(mDatabase, "card1", 1, "uri1");
+        insertFakeCard(mDatabase, "card2", 0, "uri2");
+        insertFakeCard(mDatabase, "card3", 10, "uri3");
+        // Should sort as 3,1,2
+        try (final Cursor cursor = CardDatabaseHelper.getInstance(mContext).getContextualCards()) {
+            assertThat(cursor.getCount()).isEqualTo(3);
+            final List<ContextualCard> cards = new ArrayList<>();
+            for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
+                cards.add(new ContextualCard(cursor));
+            }
+            assertThat(cards.get(0).getName()).isEqualTo("card3");
+            assertThat(cards.get(1).getName()).isEqualTo("card1");
+            assertThat(cards.get(2).getName()).isEqualTo("card2");
+        }
+    }
+
+    private static void insertFakeCard(SQLiteDatabase db, String name, double score, String uri) {
+        final ContentValues value = new ContentValues();
+        value.put(CardDatabaseHelper.CardColumns.NAME, name);
+        value.put(CardDatabaseHelper.CardColumns.SCORE, score);
+        value.put(CardDatabaseHelper.CardColumns.SLICE_URI, uri);
+
+        value.put(CardDatabaseHelper.CardColumns.TYPE, ContextualCard.CardType.SLICE);
+        value.put(CardDatabaseHelper.CardColumns.CATEGORY,
+                ContextualCardProto.ContextualCard.Category.DEFAULT.getNumber());
+        value.put(CardDatabaseHelper.CardColumns.PACKAGE_NAME,
+                RuntimeEnvironment.application.getPackageName());
+        value.put(CardDatabaseHelper.CardColumns.APP_VERSION, 1);
+
+        db.insert(CardDatabaseHelper.CARD_TABLE, null, value);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/ConditionalContextualCardTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/ConditionalContextualCardTest.java
index 2cff9f2..74e88d7 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/ConditionalContextualCardTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/ConditionalContextualCardTest.java
@@ -30,7 +30,7 @@
     @Test(expected = IllegalArgumentException.class)
     public void newInstance_changeCardType_shouldCrash() {
         new ConditionalContextualCard.Builder()
-                .setCardType(ContextualCard.CardType.SUGGESTION)
+                .setCardType(ContextualCard.CardType.LEGACY_SUGGESTION)
                 .build();
     }
 
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardControllerTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardControllerTest.java
new file mode 100644
index 0000000..9d9d84e
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardControllerTest.java
@@ -0,0 +1,94 @@
+/*
+ * 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.homepage.contextualcards.legacysuggestion;
+
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+
+import com.android.settings.homepage.contextualcards.ContextualCardUpdateListener;
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.ShadowThreadUtils;
+import com.android.settingslib.suggestions.SuggestionController;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(shadows = ShadowThreadUtils.class)
+public class LegacySuggestionContextualCardControllerTest {
+
+    @Mock
+    private SuggestionController mSuggestionController;
+    @Mock
+    private ContextualCardUpdateListener mCardUpdateListener;
+
+    private Context mContext;
+    private LegacySuggestionContextualCardController mController;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        FakeFeatureFactory.setupForTest();
+        mContext = RuntimeEnvironment.application;
+        mController = new LegacySuggestionContextualCardController(mContext);
+    }
+
+    @Test
+    public void init_configOn_shouldCreateSuggestionController() {
+        final LegacySuggestionContextualCardController controller =
+                new LegacySuggestionContextualCardController(mContext);
+        assertThat(controller.mSuggestionController).isNotNull();
+    }
+
+    @Test
+    @Config(qualifiers = "mcc999")
+    public void init_configOff_shouldNotCreateSuggestionController() {
+        final LegacySuggestionContextualCardController controller =
+                new LegacySuggestionContextualCardController(mContext);
+
+        assertThat(controller.mSuggestionController).isNull();
+    }
+
+    @Test
+    public void goThroughLifecycle_hasSuggestionController_shouldStartStopController() {
+        mController.mSuggestionController = mSuggestionController;
+        mController.onStart();
+        verify(mSuggestionController).start();
+
+        mController.onStop();
+        verify(mSuggestionController).stop();
+    }
+
+    @Test
+    public void onServiceConnected_shouldLoadSuggestion() {
+        mController.mSuggestionController = mSuggestionController;
+        mController.setCardUpdateListener(mCardUpdateListener);
+        mController.onServiceConnected();
+
+        verify(mSuggestionController).getSuggestions();
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRendererTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRendererTest.java
new file mode 100644
index 0000000..20f1b7b
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRendererTest.java
@@ -0,0 +1,105 @@
+/*
+ * 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.homepage.contextualcards.legacysuggestion;
+
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.settings.R;
+import com.android.settings.homepage.contextualcards.ContextualCard;
+import com.android.settings.homepage.contextualcards.ControllerRendererPool;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class LegacySuggestionContextualCardRendererTest {
+    @Mock
+    private ControllerRendererPool mControllerRendererPool;
+    @Mock
+    private LegacySuggestionContextualCardController mController;
+    private Context mContext;
+    private LegacySuggestionContextualCardRenderer mRenderer;
+
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = RuntimeEnvironment.application;
+        mRenderer = new LegacySuggestionContextualCardRenderer(mContext, mControllerRendererPool);
+    }
+
+    @Test
+    public void bindView_shouldSetListener() {
+        final int viewType = mRenderer.getViewType(true /* isHalfWidth */);
+        final RecyclerView recyclerView = new RecyclerView(mContext);
+        recyclerView.setLayoutManager(new LinearLayoutManager(mContext));
+        final View card = LayoutInflater.from(mContext).inflate(viewType, recyclerView, false);
+        final RecyclerView.ViewHolder viewHolder = mRenderer.createViewHolder(card);
+
+        when(mControllerRendererPool.getController(mContext,
+                ContextualCard.CardType.LEGACY_SUGGESTION)).thenReturn(mController);
+
+        mRenderer.bindView(viewHolder, buildContextualCard());
+
+        assertThat(card).isNotNull();
+        assertThat(card.hasOnClickListeners()).isTrue();
+    }
+
+    @Test
+    public void viewClick_shouldInvokeControllerPrimaryClick() {
+        final int viewType = mRenderer.getViewType(true /* isHalfWidth */);
+        final RecyclerView recyclerView = new RecyclerView(mContext);
+        recyclerView.setLayoutManager(new LinearLayoutManager(mContext));
+        final View card = LayoutInflater.from(mContext).inflate(viewType, recyclerView, false);
+        final RecyclerView.ViewHolder viewHolder = mRenderer.createViewHolder(card);
+        when(mControllerRendererPool.getController(mContext,
+                ContextualCard.CardType.LEGACY_SUGGESTION)).thenReturn(mController);
+
+        mRenderer.bindView(viewHolder, buildContextualCard());
+
+        assertThat(card).isNotNull();
+        card.performClick();
+
+        verify(mController).onPrimaryClick(any(ContextualCard.class));
+    }
+
+    private ContextualCard buildContextualCard() {
+        return new LegacySuggestionContextualCard.Builder()
+                .setName("test_name")
+                .setTitleText("test_title")
+                .setSummaryText("test_summary")
+                .setIconDrawable(mContext.getDrawable(R.drawable.ic_do_not_disturb_on_24dp))
+                .build();
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardTest.java
new file mode 100644
index 0000000..8b9a7a9
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardTest.java
@@ -0,0 +1,55 @@
+/*
+ * 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.homepage.contextualcards.legacysuggestion;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.mock;
+
+import android.app.PendingIntent;
+
+import com.android.settings.homepage.contextualcards.ContextualCard;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class LegacySuggestionContextualCardTest {
+
+    @Test(expected = IllegalArgumentException.class)
+    public void newInstance_changeCardType_shouldCrash() {
+        new LegacySuggestionContextualCard.Builder()
+                .setCardType(ContextualCard.CardType.CONDITIONAL)
+                .build();
+    }
+
+    @Test
+    public void getCardType_shouldAlwaysBeSuggestionType() {
+        assertThat(new LegacySuggestionContextualCard.Builder().build().getCardType())
+                .isEqualTo(ContextualCard.CardType.LEGACY_SUGGESTION);
+    }
+
+    @Test
+    public void build_shouldSetPendingIntent() {
+        assertThat(new LegacySuggestionContextualCard.Builder()
+                .setPendingIntent(mock(PendingIntent.class))
+                .build()
+                .getPendingIntent()).isNotNull();
+    }
+
+}
diff --git a/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkUtilsTest.java b/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkUtilsTest.java
index 676c9f4..8a57a0c 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkUtilsTest.java
@@ -165,7 +165,8 @@
     @Test
     public void isCdmaOptions_worldModeWithGsmWcdma_returnTrue() {
         when(mTelephonyManager.getPhoneType()).thenReturn(PhoneConstants.PHONE_TYPE_GSM);
-        when(mContext.getString(R.string.config_world_mode)).thenReturn("true");
+        mCarrierConfig.putBoolean(CarrierConfigManager.KEY_WORLD_MODE_ENABLED_BOOL, true);
+
         Settings.Global.putInt(mContext.getContentResolver(),
                 android.provider.Settings.Global.PREFERRED_NETWORK_MODE + SUB_ID_1,
                 TelephonyManager.NETWORK_MODE_LTE_GSM_WCDMA);
diff --git a/tests/robotests/src/com/android/settings/print/PrintJobMessagePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/print/PrintJobMessagePreferenceControllerTest.java
new file mode 100644
index 0000000..50dd38b
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/print/PrintJobMessagePreferenceControllerTest.java
@@ -0,0 +1,113 @@
+/*
+ * 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.print;
+
+import static androidx.lifecycle.Lifecycle.Event.ON_START;
+import static androidx.lifecycle.Lifecycle.Event.ON_STOP;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyObject;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.print.PrintJob;
+import android.print.PrintJobInfo;
+import android.print.PrintManager;
+
+import androidx.lifecycle.LifecycleOwner;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class PrintJobMessagePreferenceControllerTest {
+    private static final String PREF_KEY = "print_job_message_preference";
+
+    @Mock
+    private PrintManager mPrintManager;
+    @Mock
+    private PrintJob mPrintJob;
+    @Mock
+    private PrintJobInfo mPrintJobInfo;
+    @Mock
+    private PreferenceScreen mScreen;
+
+    private Context mContext;
+    private PrintJobMessagePreferenceController mController;
+    private Preference mPreference;
+    private LifecycleOwner mLifecycleOwner;
+    private Lifecycle mLifecycle;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = spy(RuntimeEnvironment.application);
+        mPreference = new Preference(mContext);
+        when(mContext.getSystemService(Context.PRINT_SERVICE)).thenReturn(mPrintManager);
+        when(mPrintManager.getGlobalPrintManagerForUser(anyInt())).thenReturn(mPrintManager);
+        when(mPrintManager.getPrintJob(anyObject())).thenReturn(mPrintJob);
+        when(mPrintJob.getInfo()).thenReturn(mPrintJobInfo);
+        mController = new PrintJobMessagePreferenceController(mContext, PREF_KEY);
+        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
+        mController.displayPreference(mScreen);
+        mLifecycleOwner = () -> mLifecycle;
+        mLifecycle = new Lifecycle(mLifecycleOwner);
+        mLifecycle.addObserver(mController);
+    }
+
+    @Test
+    public void onStartStop_shouldRegisterPrintStateListener() {
+        mLifecycle.handleLifecycleEvent(ON_START);
+        mLifecycle.handleLifecycleEvent(ON_STOP);
+
+        verify(mPrintManager).addPrintJobStateChangeListener(mController);
+        verify(mPrintManager).removePrintJobStateChangeListener(mController);
+    }
+
+    @Test
+    public void updateUi_visiblePreference() {
+        when(mPrintJobInfo.getStatus(anyObject())).thenReturn("TestPrint");
+        mLifecycle.handleLifecycleEvent(ON_START);
+
+        assertThat(mPreference.isVisible()).isTrue();
+
+        mLifecycle.handleLifecycleEvent(ON_STOP);
+    }
+
+    @Test
+    public void updateUi_invisiblePreference() {
+        when(mPrintJobInfo.getStatus(anyObject())).thenReturn(null);
+        mLifecycle.handleLifecycleEvent(ON_START);
+
+        assertThat(mPreference.isVisible()).isFalse();
+
+        mLifecycle.handleLifecycleEvent(ON_STOP);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/print/PrintJobPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/print/PrintJobPreferenceControllerTest.java
new file mode 100644
index 0000000..fc92eb3
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/print/PrintJobPreferenceControllerTest.java
@@ -0,0 +1,189 @@
+/*
+ * 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.print;
+
+import static androidx.lifecycle.Lifecycle.Event.ON_START;
+import static androidx.lifecycle.Lifecycle.Event.ON_STOP;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyObject;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.print.PrintJob;
+import android.print.PrintJobInfo;
+import android.print.PrintManager;
+
+import androidx.lifecycle.LifecycleOwner;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class PrintJobPreferenceControllerTest {
+    private static final String PREF_KEY = "print_job_preference";
+
+    @Mock
+    private PrintManager mPrintManager;
+    @Mock
+    private PrintJob mPrintJob;
+    @Mock
+    private PrintJobInfo mPrintJobInfo;
+    @Mock
+    private PreferenceScreen mScreen;
+
+    private Context mContext;
+    private LifecycleOwner mLifecycleOwner;
+    private Lifecycle mLifecycle;
+    private PrintJobPreferenceController mController;
+    private Preference mPreference;
+    private String mTestLabel;
+
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = spy(RuntimeEnvironment.application);
+        mPreference = new Preference(mContext);
+        mTestLabel = "PrintTest";
+        when(mContext.getSystemService(Context.PRINT_SERVICE)).thenReturn(mPrintManager);
+        when(mPrintManager.getGlobalPrintManagerForUser(anyInt())).thenReturn(mPrintManager);
+        when(mPrintManager.getPrintJob(anyObject())).thenReturn(mPrintJob);
+        when(mPrintJob.getInfo()).thenReturn(mPrintJobInfo);
+        mController = new PrintJobPreferenceController(mContext, PREF_KEY);
+        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
+        when(mPrintJobInfo.getLabel()).thenReturn(mTestLabel);
+        mController.displayPreference(mScreen);
+        mLifecycleOwner = () -> mLifecycle;
+        mLifecycle = new Lifecycle(mLifecycleOwner);
+        mLifecycle.addObserver(mController);
+    }
+
+    @Test
+    public void onStartStop_shouldRegisterPrintStateListener() {
+        mLifecycle.handleLifecycleEvent(ON_START);
+        mLifecycle.handleLifecycleEvent(ON_STOP);
+
+        verify(mPrintManager).addPrintJobStateChangeListener(mController);
+        verify(mPrintManager).removePrintJobStateChangeListener(mController);
+    }
+
+    @Test
+    public void updateUi_jobState_STATE_CREATED() {
+        when(mPrintJobInfo.getState()).thenReturn(PrintJobInfo.STATE_CREATED);
+
+        mController.onStart();
+        String title = mContext.getString(
+                R.string.print_configuring_state_title_template, mTestLabel);
+
+        assertThat(mPreference.getTitle()).isEqualTo(title);
+    }
+
+    @Test
+    public void updateUi_jobState_STATE_QUEUED() {
+        when(mPrintJobInfo.getState()).thenReturn(PrintJobInfo.STATE_QUEUED);
+
+        mController.onStart();
+        String title = mContext.getString(
+                R.string.print_printing_state_title_template, mTestLabel);
+
+        assertThat(mPreference.getTitle()).isEqualTo(title);
+    }
+
+    @Test
+    public void updateUi_jobState_STATE_STARTED() {
+        when(mPrintJobInfo.getState()).thenReturn(PrintJobInfo.STATE_STARTED);
+
+        mController.onStart();
+        String title = mContext.getString(
+                R.string.print_printing_state_title_template, mTestLabel);
+
+        assertThat(mPreference.getTitle()).isEqualTo(title);
+    }
+
+    @Test
+    public void updateUi_jobState_STATE_QUEUED_and_jobInfo_CANCELLING() {
+        when(mPrintJobInfo.getState()).thenReturn(PrintJobInfo.STATE_QUEUED);
+        when(mPrintJobInfo.isCancelling()).thenReturn(true);
+
+        mController.onStart();
+        String title = mContext.getString(
+                R.string.print_cancelling_state_title_template, mTestLabel);
+
+        assertThat(mPreference.getTitle()).isEqualTo(title);
+    }
+
+    @Test
+    public void updateUi_jobState_STATE_STARTED_and_jobInfo_CANCELLING() {
+        when(mPrintJobInfo.getState()).thenReturn(PrintJobInfo.STATE_STARTED);
+        when(mPrintJobInfo.isCancelling()).thenReturn(true);
+
+        mController.onStart();
+        String title = mContext.getString(
+                R.string.print_cancelling_state_title_template, mTestLabel);
+
+        assertThat(mPreference.getTitle()).isEqualTo(title);
+    }
+
+    @Test
+    public void updateUi_jobState_STATE_FAILED() {
+        when(mPrintJobInfo.getState()).thenReturn(PrintJobInfo.STATE_FAILED);
+
+        mController.onStart();
+        String title = mContext.getString(
+                R.string.print_failed_state_title_template, mTestLabel);
+
+        assertThat(mPreference.getTitle()).isEqualTo(title);
+    }
+
+    @Test
+    public void updateUi_jobState_STATE_BLOCKED() {
+        when(mPrintJobInfo.getState()).thenReturn(PrintJobInfo.STATE_BLOCKED);
+
+        mController.onStart();
+        String title = mContext.getString(
+                R.string.print_blocked_state_title_template, mTestLabel);
+
+        assertThat(mPreference.getTitle()).isEqualTo(title);
+    }
+
+    @Test
+    public void updateUi_jobState_STATE_BLOCKED_and_jobInfo_CANCELLING() {
+        when(mPrintJobInfo.getState()).thenReturn(PrintJobInfo.STATE_BLOCKED);
+        when(mPrintJobInfo.isCancelling()).thenReturn(true);
+
+        mController.onStart();
+        String title = mContext.getString(
+                R.string.print_cancelling_state_title_template, mTestLabel);
+
+        assertThat(mPreference.getTitle()).isEqualTo(title);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSecurityPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSecurityPreferenceControllerTest.java
index f813185..e8d13df 100644
--- a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSecurityPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSecurityPreferenceControllerTest.java
@@ -66,7 +66,7 @@
     public void onPreferenceChange_securityValueUpdated() {
         mController.onPreferenceChange(mPreference, WPA2_PSK);
         assertThat(mController.getSecurityType()).isEqualTo(WifiConfiguration.KeyMgmt.WPA2_PSK);
-        assertThat(mPreference.getSummary()).isEqualTo("WPA2 PSK");
+        assertThat(mPreference.getSummary()).isEqualTo("WPA2-Personal");
 
         mController.onPreferenceChange(mPreference, NONE);
         assertThat(mController.getSecurityType()).isEqualTo(WifiConfiguration.KeyMgmt.NONE);
@@ -75,11 +75,11 @@
 
     @Test
     public void updateDisplay_preferenceUpdated() {
-        // test defaulting to WPA2 PSK on new config
+        // test defaulting to WPA2-Personal on new config
         when(mWifiManager.getWifiApConfiguration()).thenReturn(null);
         mController.updateDisplay();
         assertThat(mController.getSecurityType()).isEqualTo(WifiConfiguration.KeyMgmt.WPA2_PSK);
-        assertThat(mPreference.getSummary()).isEqualTo("WPA2 PSK");
+        assertThat(mPreference.getSummary()).isEqualTo("WPA2-Personal");
 
         // test open tether network
         when(mWifiManager.getWifiApConfiguration()).thenReturn(mConfig);
@@ -89,11 +89,11 @@
         assertThat(mController.getSecurityType()).isEqualTo(WifiConfiguration.KeyMgmt.NONE);
         assertThat(mPreference.getSummary()).isEqualTo("None");
 
-        // test WPA2 PSK tether network
+        // test WPA2-Personal tether network
         mConfig.allowedKeyManagement.clear();
         mConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA2_PSK);
         mController.updateDisplay();
         assertThat(mController.getSecurityType()).isEqualTo(WifiConfiguration.KeyMgmt.WPA2_PSK);
-        assertThat(mPreference.getSummary()).isEqualTo("WPA2 PSK");
+        assertThat(mPreference.getSummary()).isEqualTo("WPA2-Personal");
     }
 }
diff --git a/tests/uitests/assets/search_results_list b/tests/uitests/assets/search_results_list
index 817164e..6f7c513 100644
--- a/tests/uitests/assets/search_results_list
+++ b/tests/uitests/assets/search_results_list
@@ -166,7 +166,6 @@
 Device security;security_category
 Device theme;theme
 Dial pad tones;dial_pad_tones
-Directory access;special_app_directory_access
 Disable Bluetooth A2DP hardware offload;bluetooth_disable_a2dp_hw_offload
 Disable HW overlays;disable_overlays
 Disable USB audio routing;usb_audio
@@ -621,4 +620,4 @@
  ;auto_brightness_video
  ;battery_header
  ;battery_tip
- ;feature_flag_category
\ No newline at end of file
+ ;feature_flag_category