Merge "Refactor the DataUsageBase"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index fc5b830..9740019 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -36,6 +36,7 @@
     <uses-permission android:name="com.android.certinstaller.INSTALL_AS_USER" />
     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
     <uses-permission android:name="android.permission.TETHER_PRIVILEGED" />
+    <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
     <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.CLEAR_APP_USER_DATA" />
     <uses-permission android:name="android.permission.READ_PHONE_STATE" />
@@ -157,7 +158,7 @@
         <activity android:name=".Settings$NetworkDashboardActivity"
             android:taskAffinity="com.android.settings"
             android:label="@string/network_dashboard_title"
-            android:icon="@drawable/ic_settings_wireless"
+            android:icon="@drawable/ic_homepage_network"
             android:parentActivityName="Settings">
             <intent-filter android:priority="1">
                 <action android:name="android.settings.WIRELESS_SETTINGS" />
@@ -183,7 +184,7 @@
         <activity android:name=".Settings$ConnectedDeviceDashboardActivity"
             android:taskAffinity="com.android.settings"
             android:label="@string/connected_devices_dashboard_title"
-            android:icon="@drawable/ic_devices_other"
+            android:icon="@drawable/ic_homepage_connected_device"
             android:parentActivityName="Settings">
             <intent-filter android:priority="1">
                 <action android:name="android.settings.NFC_SETTINGS" />
@@ -209,7 +210,7 @@
                   android:enabled="false"
                   android:taskAffinity="com.android.settings"
                   android:label="@string/connected_devices_dashboard_title"
-                  android:icon="@drawable/ic_devices_other"
+                  android:icon="@drawable/ic_homepage_connected_device"
                   android:parentActivityName="Settings">
             <intent-filter android:priority="1">
                 <action android:name="android.settings.NFC_SETTINGS" />
@@ -902,7 +903,7 @@
 
         <activity android:name="Settings$DisplaySettingsActivity"
                 android:label="@string/display_settings"
-                android:icon="@drawable/ic_settings_display"
+                android:icon="@drawable/ic_homepage_display"
                 android:taskAffinity="">
             <intent-filter android:priority="1">
                 <action android:name="com.android.settings.DISPLAY_SETTINGS" />
@@ -1085,9 +1086,6 @@
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="com.android.settings.SHORTCUT" />
             </intent-filter>
-            <intent-filter android:priority="3">
-                <action android:name="com.android.settings.action.SETTINGS" />
-            </intent-filter>
             <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
                 android:value="com.android.settings.applications.ProcessStatsSummary" />
         </activity>
@@ -1283,7 +1281,7 @@
 
         <activity android:name="Settings$SecuritySettingsActivity"
                 android:label="@string/security_settings_title"
-                android:icon="@drawable/ic_settings_security"
+                android:icon="@drawable/ic_homepage_security"
                 android:configChanges="orientation|keyboardHidden|screenSize"
                 android:taskAffinity=""
                 android:parentActivityName="Settings">
@@ -1311,7 +1309,7 @@
         <!-- TODO(32953042) Merge with Settings$SecuritySettingsActivity -->
         <activity android:name="Settings$SecuritySettingsActivityV2"
                   android:label="@string/security_settings_title"
-                  android:icon="@drawable/ic_settings_security"
+                  android:icon="@drawable/ic_homepage_security"
                   android:enabled="false"
                   android:configChanges="orientation|keyboardHidden|screenSize"
                   android:taskAffinity=""
@@ -1474,7 +1472,7 @@
 
         <activity android:name="Settings$AccessibilitySettingsActivity"
                 android:label="@string/accessibility_settings"
-                android:icon="@drawable/ic_settings_accessibility"
+                android:icon="@drawable/ic_homepage_accessibility"
                 android:configChanges="orientation|keyboardHidden|screenSize"
                 android:taskAffinity="">
             <intent-filter android:priority="1">
@@ -1804,7 +1802,7 @@
 
         <activity android:name=".Settings$StorageDashboardActivity"
                 android:label="@string/storage_settings"
-                android:icon="@drawable/ic_settings_storage"
+                android:icon="@drawable/ic_homepage_storage"
                 android:taskAffinity="com.android.settings"
                 android:parentActivityName="Settings">
             <intent-filter android:priority="1">
@@ -2226,7 +2224,7 @@
 
         <activity android:name="Settings$PowerUsageSummaryActivity"
                 android:label="@string/power_usage_summary_title"
-                android:icon="@drawable/ic_settings_battery"
+                android:icon="@drawable/ic_homepage_battery"
                 android:enabled="false">
             <intent-filter android:priority="1">
                 <action android:name="android.intent.action.POWER_USAGE_SUMMARY" />
@@ -2257,7 +2255,7 @@
 
         <activity android:name=".Settings$PowerUsageSummaryLegacyActivity"
                   android:label="@string/power_usage_summary_title"
-                  android:icon="@drawable/ic_settings_battery">
+                  android:icon="@drawable/ic_homepage_battery">
             <intent-filter>
                 <action android:name="android.intent.action.POWER_USAGE_SUMMARY" />
                 <category android:name="android.intent.category.DEFAULT" />
@@ -2642,7 +2640,7 @@
         <!-- Keep compatibility with old shortcuts. -->
         <activity android:name="Settings$SoundSettingsActivity"
                 android:label="@string/sound_settings"
-                android:icon="@drawable/ic_settings_sound"
+                android:icon="@drawable/ic_homepage_sound"
                 android:taskAffinity=""
                 android:exported="true">
             <intent-filter android:priority="1">
@@ -2688,8 +2686,6 @@
             <intent-filter android:priority="150">
                 <action android:name="com.android.settings.action.SETTINGS" />
             </intent-filter>
-            <meta-data android:name="com.android.settings.category"
-                       android:value="com.android.settings.category.ia.notifications" />
             <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
                 android:value="com.android.settings.applications.NotificationApps" />
         </activity>
@@ -3060,9 +3056,6 @@
                 <category android:name="android.intent.category.DEFAULT" />
                 <category android:name="android.intent.category.VOICE_LAUNCH" />
             </intent-filter>
-            <intent-filter android:priority="60">
-                <action android:name="com.android.settings.action.SETTINGS" />
-            </intent-filter>
             <meta-data android:name="com.android.settings.summary"
                        android:resource="@string/summary_empty"/>
             <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
@@ -3085,7 +3078,7 @@
         <!-- Alias for battery settings in new IA. Remove and merge metadata into TargetActivity -->
         <activity android:name=".Settings$AppAndNotificationDashboardActivity"
                   android:label="@string/app_and_notification_dashboard_title"
-                  android:icon="@drawable/ic_apps">
+                  android:icon="@drawable/ic_homepage_apps">
             <intent-filter android:priority="9">
                 <action android:name="com.android.settings.action.SETTINGS"/>
             </intent-filter>
@@ -3099,7 +3092,7 @@
 
         <activity android:name=".Settings$UserAndAccountDashboardActivity"
                   android:label="@string/account_dashboard_title"
-                  android:icon="@drawable/ic_settings_accounts">
+                  android:icon="@drawable/ic_homepage_accounts">
             <intent-filter android:priority="3">
                 <action android:name="com.android.settings.action.SETTINGS"/>
             </intent-filter>
@@ -3117,7 +3110,7 @@
 
         <activity android:name=".Settings$SystemDashboardActivity"
                   android:label="@string/header_category_system"
-                  android:icon="@drawable/ic_settings_about">
+                  android:icon="@drawable/ic_homepage_system_dashboard">
             <intent-filter android:priority="-1">
                 <action android:name="com.android.settings.action.SETTINGS"/>
             </intent-filter>
@@ -3131,7 +3124,7 @@
 
         <activity android:name=".support.SupportDashboardActivity"
                   android:label="@string/page_tab_title_support"
-                  android:icon="@drawable/ic_help"
+                  android:icon="@drawable/ic_homepage_support"
                   android:theme="@android:style/Theme.DeviceDefault.Light.Panel"
                   android:enabled="@bool/config_support_enabled">
             <intent-filter android:priority="-2">
diff --git a/color-check-baseline.xml b/color-check-baseline.xml
index 506770c..066dab9 100644
--- a/color-check-baseline.xml
+++ b/color-check-baseline.xml
@@ -93,7 +93,7 @@
         errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/layout-land/choose_lock_pattern.xml"
-            line="160"
+            line="170"
             column="17"/>
     </issue>
 
@@ -1081,6 +1081,214 @@
         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_network_background&quot;>#2196F3&lt;/color>"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/values/colors.xml"
+            line="123"
+            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;homepage_connected_device_background&quot;>#71A234&lt;/color>"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/values/colors.xml"
+            line="124"
+            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;homepage_app_and_notification_background&quot;>#FF7E0F&lt;/color>"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/values/colors.xml"
+            line="125"
+            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;homepage_battery_background&quot;>#258982&lt;/color>"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/values/colors.xml"
+            line="126"
+            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;homepage_display_background&quot;>#FFB600&lt;/color>"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/values/colors.xml"
+            line="127"
+            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;homepage_sound_background&quot;>#01B1AF&lt;/color>"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/values/colors.xml"
+            line="128"
+            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;homepage_storage_background&quot;>#C14CE6&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;homepage_security_background&quot;>#0F9D58&lt;/color>"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/values/colors.xml"
+            line="130"
+            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;homepage_accounts_background&quot;>#F15B8D&lt;/color>"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/values/colors.xml"
+            line="131"
+            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;homepage_accessibility_background&quot;>#5011C1&lt;/color>"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/values/colors.xml"
+            line="132"
+            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;homepage_system_background&quot;>#757575&lt;/color>"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/values/colors.xml"
+            line="133"
+            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;homepage_support_background&quot;>#26459C&lt;/color>"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/values/colors.xml"
+            line="134"
+            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;homepage_generic_icon_background&quot;>#1A73E8&lt;/color>"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/values/colors.xml"
+            line="135"
+            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="    android:background=&quot;@color/condition_card_background&quot;"
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
@@ -1449,6 +1657,198 @@
         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
+            file="res/drawable/ic_homepage_accessibility.xml"
+            line="24"
+            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_accounts_background&quot; />"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/drawable/ic_homepage_accounts.xml"
+            line="24"
+            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_app_and_notification_background&quot; />"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/drawable/ic_homepage_apps.xml"
+            line="24"
+            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_battery_background&quot; />"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/drawable/ic_homepage_battery.xml"
+            line="24"
+            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_connected_device_background&quot; />"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/drawable/ic_homepage_connected_device.xml"
+            line="24"
+            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_display_background&quot; />"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/drawable/ic_homepage_display.xml"
+            line="24"
+            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_network_background&quot; />"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/drawable/ic_homepage_network.xml"
+            line="24"
+            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_security_background&quot; />"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/drawable/ic_homepage_security.xml"
+            line="24"
+            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_sound_background&quot; />"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/drawable/ic_homepage_sound.xml"
+            line="24"
+            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_storage_background&quot; />"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/drawable/ic_homepage_storage.xml"
+            line="24"
+            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_support_background&quot; />"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/drawable/ic_homepage_support.xml"
+            line="24"
+            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_system_background&quot; />"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/drawable/ic_homepage_system_dashboard.xml"
+            line="24"
+            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:tint=&quot;#db4437&quot;"
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~">
         <location
@@ -2073,22 +2473,6 @@
         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;string name=&quot;sync_plug&quot; msgid=&quot;3905078969081888738&quot;>&quot;‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‎‏‏‎‎‎‏‏‎‎‎‏‏‎‏‎‎‎‎‎‏‎‏‎‎‎‎‏‏‏‏‎‎‎‏‏‏‏‏‏‏‎‎‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‎‏‎‎‏‏‎&quot;&lt;font fgcolor=&quot;#ffffffff&quot;>&quot;‎‏‎‎‏‏‏‎Welcome to Google sync!‎‏‎‎‏‏‎&quot;&lt;/font>&quot;‎‏‎‎‏‏‏‎ ‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎A Google approach to syncing data to allow access to your contacts, appointments, and more from wherever you are.‎‏‎‎‏‎&quot;&lt;/string>"
-        errorLine2="                                                                                                                                                                       ~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="res/values-en-rXC/strings.xml"
-            line="2353"
-            column="168"/>
-    </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;string name=&quot;sync_plug&quot; msgid=&quot;3905078969081888738&quot;>&lt;font fgcolor=&quot;#ffffffff&quot;>&quot;Welcome to Google sync!&quot;&lt;/font>&quot; \nA Google approach to syncing data to allow access to your contacts, appointments and more from wherever you are.&quot;&lt;/string>"
         errorLine2="                                                               ~~~~~~~~~~~~~~~~~~~">
         <location
@@ -2153,11 +2537,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;string name=&quot;sync_plug&quot; msgid=&quot;3905078969081888738&quot;>&quot;‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‎‏‏‎‎‎‏‏‎‎‎‏‏‎‏‎‎‎‎‎‏‎‏‎‎‎‎‏‏‏‏‎‎‎‏‏‏‏‏‏‏‎‎‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‎‏‎‎‏‏‎&quot;&lt;font fgcolor=&quot;#ffffffff&quot;>&quot;‎‏‎‎‏‏‏‎Welcome to Google sync!‎‏‎‎‏‏‎&quot;&lt;/font>&quot;‎‏‎‎‏‏‏‎ ‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎A Google approach to syncing data to allow access to your contacts, appointments, and more from wherever you are.‎‏‎‎‏‎&quot;&lt;/string>"
+        errorLine2="                                                                                                                                                                       ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/values-en-rXC/strings.xml"
+            line="2396"
+            column="168"/>
+    </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;string name=&quot;sync_plug&quot;>&lt;font fgcolor=&quot;#ffffffff&quot;>Welcome to Google sync!&lt;/font>"
         errorLine2="                                   ~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/strings.xml"
-            line="5539"
+            line="5637"
             column="36"/>
     </issue>
 
@@ -2189,7 +2589,7 @@
         errorLine2="                                           ^">
         <location
             file="res/values/styles.xml"
-            line="442"
+            line="437"
             column="44"/>
     </issue>
 
@@ -2205,7 +2605,7 @@
         errorLine2="                                           ^">
         <location
             file="res/values/styles.xml"
-            line="448"
+            line="443"
             column="44"/>
     </issue>
 
@@ -2221,7 +2621,7 @@
         errorLine2="                                           ^">
         <location
             file="res/values/styles.xml"
-            line="449"
+            line="444"
             column="44"/>
     </issue>
 
@@ -2237,7 +2637,7 @@
         errorLine2="                                        ^">
         <location
             file="res/values/styles.xml"
-            line="472"
+            line="467"
             column="41"/>
     </issue>
 
@@ -2445,7 +2845,7 @@
         errorLine2="                                            ^">
         <location
             file="res/values/themes.xml"
-            line="316"
+            line="308"
             column="45"/>
     </issue>
 
@@ -2461,7 +2861,7 @@
         errorLine2="                                                ^">
         <location
             file="res/values/themes.xml"
-            line="317"
+            line="309"
             column="49"/>
     </issue>
 
@@ -2477,7 +2877,7 @@
         errorLine2="                                            ^">
         <location
             file="res/values/themes.xml"
-            line="325"
+            line="317"
             column="45"/>
     </issue>
 
@@ -2493,7 +2893,7 @@
         errorLine2="                                                ^">
         <location
             file="res/values/themes.xml"
-            line="326"
+            line="318"
             column="49"/>
     </issue>
 
diff --git a/res/drawable/ic_apps.xml b/res/drawable/ic_apps.xml
index 9f00141..841c25a 100644
--- a/res/drawable/ic_apps.xml
+++ b/res/drawable/ic_apps.xml
@@ -17,8 +17,7 @@
         android:width="24dp"
         android:height="24dp"
         android:viewportWidth="24.0"
-        android:viewportHeight="24.0"
-        android:tint="?android:attr/colorControlNormal">
+        android:viewportHeight="24.0">
     <path
         android:pathData="M6 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm6 12c1.1 0 2-.9 2-2s-.9-2-2-2-2
 .9-2 2 .9 2 2 2zm-6 0c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0-6c1.1 0 2-.9
diff --git a/res/drawable/ic_devices_other.xml b/res/drawable/ic_devices_other.xml
index b22e483..b40aceb 100644
--- a/res/drawable/ic_devices_other.xml
+++ b/res/drawable/ic_devices_other.xml
@@ -17,8 +17,7 @@
         android:width="24dp"
         android:height="24dp"
         android:viewportWidth="24.0"
-        android:viewportHeight="24.0"
-        android:tint="?android:attr/colorControlNormal">
+        android:viewportHeight="24.0">
     <path
         android:fillColor="#FFFFFFFF"
         android:pathData="M3,6h17c0.55,0,1-0.45,1-1v0c0-0.55-0.45-1-1-1H3C1.9,4,1,4.9,1,6v12c0,1.1,0.9,2,2,2h3c0.55,0,1-0.45,1-1v0
diff --git a/res/drawable/ic_help.xml b/res/drawable/ic_help.xml
index 6add484..841de58 100644
--- a/res/drawable/ic_help.xml
+++ b/res/drawable/ic_help.xml
@@ -17,8 +17,7 @@
         android:width="24dp"
         android:height="24dp"
         android:viewportWidth="24.0"
-        android:viewportHeight="24.0"
-        android:tint="?android:attr/colorControlNormal">
+        android:viewportHeight="24.0">
     <path
         android:pathData="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 16.81c-.72
 0-1.3-.58-1.3-1.3s.58-1.3 1.3-1.3 1.3 .58 1.3 1.3-.58 1.3-1.3
diff --git a/res/drawable/ic_help_24dp.xml b/res/drawable/ic_help_24dp.xml
deleted file mode 100644
index d80b717..0000000
--- a/res/drawable/ic_help_24dp.xml
+++ /dev/null
@@ -1,31 +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.
--->
-
-<vector
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24.0"
-    android:viewportHeight="24.0"
-    android:tint="?android:attr/colorAccent">
-    <path
-        android:fillColor="#FF000000"
-        android:pathData="M20,19.59V8l-6,-6H6c-1.1,0 -1.99,0.9 -1.99,2L4,20c0,1.1 0.89,2
-        1.99,2H18c0.45,0 0.85,-0.15 1.19,-0.4l-4.43,-4.43c-0.8,0.52 -1.74,0.83 -2.76,0.83 -2.76,0
-         -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5c0,1.02 -0.31,1.96 -0.83,2.75L20,19.59zM9,13c0,1.66
-          1.34,3 3,3s3,-1.34 3,-3 -1.34,-3 -3,-3 -3,1.34 -3,3z"/>
-</vector>
\ No newline at end of file
diff --git a/res/drawable/ic_homepage_accessibility.xml b/res/drawable/ic_homepage_accessibility.xml
new file mode 100644
index 0000000..6cfb124
--- /dev/null
+++ b/res/drawable/ic_homepage_accessibility.xml
@@ -0,0 +1,37 @@
+<?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 xmlns:android="http://schemas.android.com/apk/res/android"
+               android:shape="oval">
+            <solid
+                android:color="@color/homepage_accessibility_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_settings_accessibility" />
+</layer-list>
diff --git a/res/drawable/ic_homepage_accounts.xml b/res/drawable/ic_homepage_accounts.xml
new file mode 100644
index 0000000..4cfccc2
--- /dev/null
+++ b/res/drawable/ic_homepage_accounts.xml
@@ -0,0 +1,37 @@
+<?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 xmlns:android="http://schemas.android.com/apk/res/android"
+               android:shape="oval">
+            <solid
+                android:color="@color/homepage_accounts_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_settings_accounts" />
+</layer-list>
diff --git a/res/drawable/ic_homepage_apps.xml b/res/drawable/ic_homepage_apps.xml
new file mode 100644
index 0000000..d494799
--- /dev/null
+++ b/res/drawable/ic_homepage_apps.xml
@@ -0,0 +1,37 @@
+<?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 xmlns:android="http://schemas.android.com/apk/res/android"
+               android:shape="oval">
+            <solid
+                android:color="@color/homepage_app_and_notification_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_apps" />
+</layer-list>
diff --git a/res/drawable/ic_homepage_battery.xml b/res/drawable/ic_homepage_battery.xml
new file mode 100644
index 0000000..d9ad3d3
--- /dev/null
+++ b/res/drawable/ic_homepage_battery.xml
@@ -0,0 +1,37 @@
+<?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 xmlns:android="http://schemas.android.com/apk/res/android"
+               android:shape="oval">
+            <solid
+                android:color="@color/homepage_battery_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_settings_battery_white" />
+</layer-list>
diff --git a/res/drawable/ic_homepage_connected_device.xml b/res/drawable/ic_homepage_connected_device.xml
new file mode 100644
index 0000000..20707fb
--- /dev/null
+++ b/res/drawable/ic_homepage_connected_device.xml
@@ -0,0 +1,37 @@
+<?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 xmlns:android="http://schemas.android.com/apk/res/android"
+               android:shape="oval">
+            <solid
+                android:color="@color/homepage_connected_device_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_devices_other" />
+</layer-list>
diff --git a/res/drawable/ic_homepage_display.xml b/res/drawable/ic_homepage_display.xml
new file mode 100644
index 0000000..ec5e54f
--- /dev/null
+++ b/res/drawable/ic_homepage_display.xml
@@ -0,0 +1,37 @@
+<?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 xmlns:android="http://schemas.android.com/apk/res/android"
+               android:shape="oval">
+            <solid
+                android:color="@color/homepage_display_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_settings_display_white" />
+</layer-list>
diff --git a/res/drawable/ic_homepage_network.xml b/res/drawable/ic_homepage_network.xml
new file mode 100644
index 0000000..c72e152
--- /dev/null
+++ b/res/drawable/ic_homepage_network.xml
@@ -0,0 +1,37 @@
+<?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 xmlns:android="http://schemas.android.com/apk/res/android"
+               android:shape="oval">
+            <solid
+                android:color="@color/homepage_network_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_settings_wireless_white" />
+</layer-list>
diff --git a/res/drawable/ic_homepage_security.xml b/res/drawable/ic_homepage_security.xml
new file mode 100644
index 0000000..52dedfb
--- /dev/null
+++ b/res/drawable/ic_homepage_security.xml
@@ -0,0 +1,37 @@
+<?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 xmlns:android="http://schemas.android.com/apk/res/android"
+               android:shape="oval">
+            <solid
+                android:color="@color/homepage_security_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_settings_security_white" />
+</layer-list>
diff --git a/res/drawable/ic_homepage_sound.xml b/res/drawable/ic_homepage_sound.xml
new file mode 100644
index 0000000..7210889
--- /dev/null
+++ b/res/drawable/ic_homepage_sound.xml
@@ -0,0 +1,37 @@
+<?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 xmlns:android="http://schemas.android.com/apk/res/android"
+               android:shape="oval">
+            <solid
+                android:color="@color/homepage_sound_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_settings_sound_white" />
+</layer-list>
diff --git a/res/drawable/ic_homepage_storage.xml b/res/drawable/ic_homepage_storage.xml
new file mode 100644
index 0000000..e7f5819
--- /dev/null
+++ b/res/drawable/ic_homepage_storage.xml
@@ -0,0 +1,37 @@
+<?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 xmlns:android="http://schemas.android.com/apk/res/android"
+               android:shape="oval">
+            <solid
+                android:color="@color/homepage_storage_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_settings_storage_white" />
+</layer-list>
diff --git a/res/drawable/ic_homepage_support.xml b/res/drawable/ic_homepage_support.xml
new file mode 100644
index 0000000..31d51bf
--- /dev/null
+++ b/res/drawable/ic_homepage_support.xml
@@ -0,0 +1,37 @@
+<?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 xmlns:android="http://schemas.android.com/apk/res/android"
+               android:shape="oval">
+            <solid
+                android:color="@color/homepage_support_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_help" />
+</layer-list>
diff --git a/res/drawable/ic_homepage_system_dashboard.xml b/res/drawable/ic_homepage_system_dashboard.xml
new file mode 100644
index 0000000..bf3d0eb
--- /dev/null
+++ b/res/drawable/ic_homepage_system_dashboard.xml
@@ -0,0 +1,37 @@
+<?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 xmlns:android="http://schemas.android.com/apk/res/android"
+               android:shape="oval">
+            <solid
+                android:color="@color/homepage_system_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_settings_system_dashboard_white" />
+</layer-list>
diff --git a/res/drawable/ic_settings_accessibility.xml b/res/drawable/ic_settings_accessibility.xml
index 4cf5182..67b6c9a 100644
--- a/res/drawable/ic_settings_accessibility.xml
+++ b/res/drawable/ic_settings_accessibility.xml
@@ -17,8 +17,7 @@
         android:width="24.0dp"
         android:height="24.0dp"
         android:viewportWidth="24.0"
-        android:viewportHeight="24.0"
-        android:tint="?android:attr/colorControlNormal">
+        android:viewportHeight="24.0">
     <path
         android:fillColor="#FFFFFFFF"
         android:pathData="M20.75,6.99c-0.14,-0.55 -0.69,-0.87 -1.24,-0.75C17.13,6.77 14.48,7 12,7S6.87,6.77 4.49,6.24c-0.55,-0.12 -1.1,0.2 -1.24,0.75l0,0C3.11,7.55 3.45,8.12 4,8.25C5.61,8.61 7.35,8.86 9,9v12c0,0.55 0.45,1 1,1h0c0.55,0 1,-0.45 1,-1v-5h2v5c0,0.55 0.45,1 1,1h0c0.55,0 1,-0.45 1,-1V9c1.65,-0.14 3.39,-0.39 5,-0.75C20.55,8.12 20.89,7.55 20.75,6.99L20.75,6.99zM12,6c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2s-2,0.9 -2,2S10.9,6 12,6z"/>
diff --git a/res/drawable/ic_settings_accounts.xml b/res/drawable/ic_settings_accounts.xml
index 154c09c..d152b14 100644
--- a/res/drawable/ic_settings_accounts.xml
+++ b/res/drawable/ic_settings_accounts.xml
@@ -17,8 +17,7 @@
         android:width="24.0dp"
         android:height="24.0dp"
         android:viewportWidth="24.0"
-        android:viewportHeight="24.0"
-        android:tint="?android:attr/colorControlNormal">
+        android:viewportHeight="24.0">
     <path
         android:fillColor="#FFFFFFFF"
         android:pathData="M3.0,5.0
diff --git a/res/drawable/ic_settings_battery_white.xml b/res/drawable/ic_settings_battery_white.xml
new file mode 100644
index 0000000..255b75e
--- /dev/null
+++ b/res/drawable/ic_settings_battery_white.xml
@@ -0,0 +1,24 @@
+<!--
+  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.
+  -->
+<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="#FFFFFF"
+        android:pathData="M15.67,4H14V2h-4v2H8.33C7.6,4 7,4.6 7,5.33v15.33C7,21.4 7.6,22 8.33,22h7.33c0.74,0 1.34,-0.6 1.34,-1.33V5.33C17,4.6 16.4,4 15.67,4z"/>
+</vector>
diff --git a/res/drawable/ic_settings_display_white.xml b/res/drawable/ic_settings_display_white.xml
new file mode 100644
index 0000000..4a41691
--- /dev/null
+++ b/res/drawable/ic_settings_display_white.xml
@@ -0,0 +1,27 @@
+<!--
+  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.
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M20,15.31l2.6-2.6c0.39-0.39,0.39-1.02,0-1.41L20,8.69V5c0-0.55-0.45-1-1-1h-3.69l-2.6-2.6c-0.39-0.39-1.02-0.39-1.41,0
+L8.69,4H5C4.45,4,4,4.45,4,5v3.69l-2.6,2.6c-0.39,0.39-0.39,1.02,0,1.41l2.6,2.6V19c0,0.55,0.45,1,1,1h3.69l2.6,2.6
+c0.39,0.39,1.02,0.39,1.41,0l2.6-2.6H19c0.55,0,1-0.45,1-1V15.31z
+M12,18V6c3.31,0,6,2.69,6,6S15.31,18,12,18z"/>
+</vector>
diff --git a/res/drawable/ic_settings_security_white.xml b/res/drawable/ic_settings_security_white.xml
new file mode 100644
index 0000000..d6c5b64
--- /dev/null
+++ b/res/drawable/ic_settings_security_white.xml
@@ -0,0 +1,24 @@
+<!--
+  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.
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M18.0,8.0l-1.0,0.0L17.0,6.0c0.0,-2.76 -2.24,-5.0 -5.0,-5.0S7.0,3.24 7.0,6.0l0.0,2.0L6.0,8.0c-1.1,0.0 -2.0,0.9 -2.0,2.0l0.0,10.0c0.0,1.0 0.9,2.0 2.0,2.0l12.0,0.0c1.1,0.0 2.0,-0.9 2.0,-2.0L20.0,10.0c0.0,-1.1 -0.9,-2.0 -2.0,-2.0zm-6.0,9.0c-1.1,0.0 -2.0,-0.9 -2.0,-2.0s0.9,-2.0 2.0,-2.0 2.0,0.9 2.0,2.0 -0.9,2.0 -2.0,2.0zm3.1,-9.0L8.9,8.0L8.9,6.0c0.0,-1.71 1.39,-3.1 3.1,-3.1 1.71,0.0 3.1,1.39 3.1,3.1l0.0,2.0z"/>
+</vector>
diff --git a/res/drawable/ic_settings_sound_white.xml b/res/drawable/ic_settings_sound_white.xml
new file mode 100644
index 0000000..4737349
--- /dev/null
+++ b/res/drawable/ic_settings_sound_white.xml
@@ -0,0 +1,29 @@
+<!--
+  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.
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M3 10v4c0 .55 .45 1 1 1h3l3.29 3.29c.63 .63 1.71 .18
+1.71-.71V6.41c0-.89-1.08-1.34-1.71-.71L7 9H4c-.55 0-1 .45-1 1zm13.5 2A4.5 4.5 0
+0 0 14 7.97v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 4.46v.19c0 .38 .25 .71 .61
+.85C17.18 6.54 19 9.06 19 12s-1.82 5.46-4.39 6.5c-.36 .14 -.61 .47 -.61 .85
+v.19c0 .63 .63 1.08 1.22 .86 a8.995 8.995 0 0 0 0-16.8c-.59-.23-1.22 .23 -1.22
+.86 z"/>
+</vector>
diff --git a/res/drawable/ic_settings_storage_white.xml b/res/drawable/ic_settings_storage_white.xml
new file mode 100644
index 0000000..8f662f3
--- /dev/null
+++ b/res/drawable/ic_settings_storage_white.xml
@@ -0,0 +1,24 @@
+<!--
+  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.
+  -->
+<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="#FFFFFF"
+        android:pathData="M20,16L4,16c-1.1,0 -2,0.9 -2,2s0.9,2 2,2h16c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2zM5,19.1c-0.61,0 -1.1,-0.49 -1.1,-1.1 0,-0.61 0.49,-1.1 1.1,-1.1s1.1,0.49 1.1,1.1c0,0.61 -0.49,1.1 -1.1,1.1zM4,8h16c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2L4,4c-1.1,0 -2,0.9 -2,2s0.9,2 2,2zM5,4.9c0.61,0 1.1,0.49 1.1,1.1 0,0.61 -0.49,1.1 -1.1,1.1S3.9,6.61 3.9,6c0,-0.61 0.49,-1.1 1.1,-1.1zM20,10L4,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2h16c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2zM5,13.1c-0.61,0 -1.1,-0.49 -1.1,-1.1 0,-0.61 0.49,-1.1 1.1,-1.1s1.1,0.49 1.1,1.1c0,0.61 -0.49,1.1 -1.1,1.1z"/>
+</vector>
diff --git a/res/drawable/ic_settings_system_dashboard_white.xml b/res/drawable/ic_settings_system_dashboard_white.xml
new file mode 100644
index 0000000..5308cb0
--- /dev/null
+++ b/res/drawable/ic_settings_system_dashboard_white.xml
@@ -0,0 +1,30 @@
+<!--
+  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.
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FFFFFF"
+        android:pathData="M12,17L12,17c0.55,0 1,-0.45 1,-1v-4c0,-0.55 -0.45,-1 -1,-1l0,0c-0.55,0 -1,0.45 -1,1v4C11,16.55 11.45,17 12,17z"/>
+    <path
+        android:fillColor="#FFFFFF"
+        android:pathData="M12,2c-5.52,0 -10,4.48 -10,10s4.48,10 10,10s10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8s8,3.59 8,8S16.41,20 12,20z"/>
+    <path
+        android:fillColor="#FFFFFF"
+        android:pathData="M12,9.1L12,9.1c0.61,0 1.1,-0.49 1.1,-1.1l0,0c0,-0.61 -0.49,-1.1 -1.1,-1.1l0,0c-0.61,0 -1.1,0.49 -1.1,1.1l0,0C10.9,8.61 11.39,9.1 12,9.1z"/>
+</vector>
diff --git a/res/drawable/ic_settings_wireless_white.xml b/res/drawable/ic_settings_wireless_white.xml
new file mode 100644
index 0000000..8dedb0d
--- /dev/null
+++ b/res/drawable/ic_settings_wireless_white.xml
@@ -0,0 +1,24 @@
+<!--
+  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.
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M23.66,8.11c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3 6.44,3 2.33,5.36 0.56,6.57c-0.51,0.35 -0.61,1.06 -0.23,1.54L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L23.66,8.11z"/>
+</vector>
diff --git a/res/layout/condition_header_icon.xml b/res/layout/condition_header_icon.xml
index 4f93f54..e5cbdc9 100644
--- a/res/layout/condition_header_icon.xml
+++ b/res/layout/condition_header_icon.xml
@@ -17,8 +17,8 @@
 
 <ImageView xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@android:id/icon"
-    android:layout_width="@dimen/dashboard_tile_image_size"
-    android:layout_height="@dimen/dashboard_tile_image_size"
+    android:layout_width="@dimen/suggestion_card_icon_size"
+    android:layout_height="@dimen/suggestion_card_icon_size"
     android:layout_marginStart="0dp"
     android:layout_marginEnd="24dp"
     android:tint="?android:attr/colorAccent"
diff --git a/res/layout/condition_tile.xml b/res/layout/condition_tile.xml
index 3e2f9b4..7d1db40 100644
--- a/res/layout/condition_tile.xml
+++ b/res/layout/condition_tile.xml
@@ -30,8 +30,8 @@
 
         <ImageView
             android:id="@android:id/icon"
-            android:layout_width="@dimen/dashboard_tile_image_size"
-            android:layout_height="@dimen/dashboard_tile_image_size"
+            android:layout_width="@dimen/suggestion_card_icon_size"
+            android:layout_height="@dimen/suggestion_card_icon_size"
             android:layout_marginTop="12dp"
             android:layout_marginStart="14dp"
             android:layout_marginEnd="24dp"
diff --git a/res/layout/suggestion_container.xml b/res/layout/suggestion_container.xml
index e01a590..9110c58 100644
--- a/res/layout/suggestion_container.xml
+++ b/res/layout/suggestion_container.xml
@@ -20,7 +20,7 @@
     style="@style/SuggestionConditionStyle"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:paddingTop="20dp"
+    android:paddingTop="12dp"
     android:orientation="vertical">
 
     <LinearLayout
@@ -55,7 +55,7 @@
         android:id="@+id/suggestion_list"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:paddingTop="20dp"
+        android:paddingTop="18dp"
         android:paddingBottom="16dp"
         android:scrollbars="none"/>
 
diff --git a/res/layout/suggestion_tile.xml b/res/layout/suggestion_tile.xml
index 2adfab3..b947452 100644
--- a/res/layout/suggestion_tile.xml
+++ b/res/layout/suggestion_tile.xml
@@ -30,8 +30,8 @@
 
         <ImageView
             android:id="@android:id/icon"
-            android:layout_width="@dimen/dashboard_tile_image_size"
-            android:layout_height="@dimen/dashboard_tile_image_size"
+            android:layout_width="@dimen/suggestion_card_icon_size"
+            android:layout_height="@dimen/suggestion_card_icon_size"
             android:layout_marginStart="14dp"
             android:layout_marginEnd="24dp" />
 
diff --git a/res/layout/suggestion_tile_v2.xml b/res/layout/suggestion_tile_v2.xml
index 27b3c34..e04febb 100644
--- a/res/layout/suggestion_tile_v2.xml
+++ b/res/layout/suggestion_tile_v2.xml
@@ -20,6 +20,7 @@
     android:id="@+id/suggestion_card"
     android:layout_width="328dp"
     android:layout_height="wrap_content"
+    app:cardPreventCornerOverlap="false"
     app:cardUseCompatPadding="true"
     app:cardElevation="2dp"
     app:cardCornerRadius="@dimen/suggestion_card_corner_radius">
@@ -37,16 +38,17 @@
 
             <ImageView
                 android:id="@android:id/icon"
-                android:layout_width="@dimen/dashboard_tile_image_size"
-                android:layout_height="@dimen/dashboard_tile_image_size"
+                android:layout_width="@dimen/suggestion_card_icon_size"
+                android:layout_height="@dimen/suggestion_card_icon_size"
                 style="@style/SuggestionCardIcon"
                 android:layout_marginTop="16dp"
                 android:layout_marginBottom="8dp" />
 
             <ImageView
                 android:id="@+id/close_button"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
+                android:layout_width="18dp"
+                android:layout_height="18dp"
+                android:alpha="0.54"
                 android:layout_alignParentEnd="true"
                 android:layout_marginTop="8dp"
                 android:layout_marginEnd="8dp"
@@ -62,7 +64,7 @@
             android:layout_marginStart="12dp"
             android:layout_marginEnd="12dp"
             android:singleLine="true"
-            android:textAppearance="@style/TextAppearance.TileTitle"
+            android:textAppearance="@style/TextAppearance.SuggestionTitleV2"
             android:ellipsize="marquee"
             android:fadingEdge="horizontal" />
 
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 72f2d91..e10b4cb 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -118,4 +118,22 @@
     <!-- Suggestion/condition colors -->
     <color name="suggestion_condition_background">#f2f2f2</color>
     <color name="condition_card_background">#f8f8f8</color>
+
+    <!-- Dashboard/homepage icon background colors -->
+    <color name="homepage_network_background">#2196F3</color>
+    <color name="homepage_connected_device_background">#71A234</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_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_support_background">#26459C</color>
+    <color name="homepage_generic_icon_background">#1A73E8</color>
+    <!-- End of dashboard/homepage icon background colors -->
+
 </resources>
+
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 16ac128..332deea 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -101,7 +101,13 @@
     <dimen name="dashboard_tile_minimum_height">72dp</dimen>
 
     <!-- Dashboard image tile size -->
-    <dimen name="dashboard_tile_image_size">24dp</dimen>
+    <dimen name="dashboard_tile_image_size">36dp</dimen>
+
+    <!-- Dashboard foreground image size -->
+    <dimen name="dashboard_tile_foreground_image_size">24dp</dimen>
+
+    <!-- Dashboard foreground image inset (from background edge to foreground edge) -->
+    <dimen name="dashboard_tile_foreground_image_inset">6dp</dimen>
 
     <!-- Dashboard tile image margin start / end -->
     <dimen name="dashboard_tile_image_margin">24dp</dimen>
@@ -297,6 +303,7 @@
     <dimen name="suggestion_condition_header_padding_expanded">5dp</dimen>
 
     <!-- Suggestion cards size and padding -->
+    <dimen name="suggestion_card_icon_size">24dp</dimen>
     <dimen name="suggestion_card_width_one_card">328dp</dimen>
     <dimen name="suggestion_card_width_two_cards">158dp</dimen>
     <dimen name="suggestion_card_width_multiple_cards">152dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 800113e..9fc6452 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -3228,7 +3228,7 @@
     <!-- SD card & phone storage settings screen, title for the checkbox to let user decide whether erase eSIM data together [CHAR LIMIT=NONE] -->
     <string name="reset_esim_title">Also reset eSIMs</string>
     <!-- SD card & phone storage settings screen, message for the checkbox to let user decide whether erase eSIM data together [CHAR LIMIT=NONE] -->
-    <string name="reset_esim_desc">Erase all eSIMs on the phone. You\u2019ll have to contract your carrier to redownload your eSIMs. This will not cancel your mobile service plan.</string>
+    <string name="reset_esim_desc">Erase all eSIMs on the phone. You\u2019ll have to contact your carrier to redownload your eSIMs. This will not cancel your mobile service plan.</string>
     <!-- SD card & phone storage settings screen, button on screen after user selects Reset network settings -->
     <string name="reset_network_button_text">Reset settings</string>
     <!-- SD card & phone storage settings screen, message on screen after user selects Reset settings button -->
@@ -3391,16 +3391,6 @@
     <string name="location_title">My Location</string>
     <!-- [CHAR LIMIT=30] Title for managed profile location switch  -->
     <string name="managed_profile_location_switch_title">Location for work profile</string>
-    <!-- [CHAR LIMIT=30] Location settings screen, setting preference screen box label for location mode -->
-    <string name="location_mode_title">Mode</string>
-    <!-- [CHAR LIMIT=30] Location settings screen, high accuracy location mode -->
-    <string name="location_mode_high_accuracy_title">High accuracy</string>
-    <!-- [CHAR LIMIT=30] Location settings screen, battery saving location mode -->
-    <string name="location_mode_battery_saving_title">Battery saving</string>
-    <!-- [CHAR LIMIT=30] Location settings screen, device only location mode -->
-    <string name="location_mode_sensors_only_title">Device only</string>
-    <!-- [CHAR LIMIT=30] Location settings screen, location off mode -->
-    <string name="location_mode_location_off_title">Location off</string>
     <!-- [CHAR LIMIT=30] Location settings screen. It's a link that directs the user to a page that
       shows the location permission setting for each installed app -->
     <string name="location_app_level_permissions">App-level permissions</string>
@@ -3414,14 +3404,6 @@
     <string name="location_high_battery_use">High battery use</string>
     <!-- [CHAR LIMIT=30] Location settings screen, recent location requests low battery use-->
     <string name="location_low_battery_use">Low battery use</string>
-    <!-- [CHAR LIMIT=30] Location mode screen, screen title -->
-    <string name="location_mode_screen_title">Location mode</string>
-    <!-- [CHAR LIMIT=130] Location mode screen, description for high accuracy mode -->
-    <string name="location_mode_high_accuracy_description">Use GPS, Wi\u2011Fi, Bluetooth, or mobile networks to determine location </string>
-    <!-- [CHAR LIMIT=130] Location mode screen, description for battery saving mode -->
-    <string name="location_mode_battery_saving_description">Use Wi\u2011Fi, Bluetooth, or mobile networks to determine location</string>
-    <!-- [CHAR LIMIT=130] Location mode screen, description for sensors only mode -->
-    <string name="location_mode_sensors_only_description">Use GPS and device sensors to determine location</string>
     <!-- [CHAR LIMIT=30] Wireless background scanning settings screen, screen title -->
     <string name="location_scanning_screen_title">Scanning</string>
     <!-- [CHAR LIMIT=130] Preference title for Wi-Fi always scanning -->
@@ -6709,7 +6691,6 @@
     <string name="keywords_sounds_and_notifications_interruptions">dont don\u2019t disturb, interrupt, interruption, break</string>
     <string name="keywords_app">RAM</string>
     <string name="keywords_location">nearby, location, history, reporting</string>
-    <string name="keywords_location_mode">accuracy</string>
     <string name="keywords_accounts">account</string>
     <string name="keywords_users">restriction, restrict, restricted</string>
     <string name="keywords_keyboard_and_ime">text correction, correct, sound, vibrate, auto, language, gesture, suggest, suggestion, theme, offensive, word, type, emoji, international</string>
@@ -8346,8 +8327,8 @@
     <!-- Summary of payment screen [CHAR LIMIT=NONE] -->
     <string name="payment_summary"><xliff:g id="app_name" example="Payment App">%1$s</xliff:g> is default</string>
 
-    <!-- Summary of location screen [CHAR LIMIT=NONE] -->
-    <string name="location_on_summary">ON / <xliff:g id="location_mode" example="High accuracy">%1$s</xliff:g></string>
+    <!-- Summary of location on screen [CHAR LIMIT=NONE] -->
+    <string name="location_on_summary">ON</string>
 
     <!-- Location off [CHAR LIMIT=NONE] -->
     <string name="location_off_summary">OFF</string>
@@ -9230,12 +9211,20 @@
     <!-- 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>
+
     <!-- Account type associated with the backup account. Empty for AOSP. [DO NOT TRANSLATE] -->
-    <string name="account_type"></string>
+    <string name="account_type" translatable="false"></string>
     <!-- Package to target for Account credential confirmation. This will allow users to
          remind/rediscover their backup account password prior to a reset. Empty for AOSP.
          [DO NOT TRANSLATE] -->
-    <string name="account_confirmation_package"></string>
+    <string name="account_confirmation_package" translatable="false"></string>
+    <!-- Class to target for Account credential confirmation. This will allow users to
+         remind/rediscover their backup account password prior to a reset. Empty for AOSP.
+         [DO NOT TRANSLATE] -->
+    <string name="account_confirmation_class" translatable="false"></string>
 
     <!-- Title for the new About Phone screen [CHAR LIMIT=40] -->
     <string name="my_device_info_title" product="default">My Phone</string>
@@ -9248,4 +9237,9 @@
     <!-- 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>
+
 </resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 7764e74..b672247 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -318,7 +318,7 @@
 
     <style name="TextAppearance.SuggestionHeader"
            parent="@android:style/TextAppearance.Material.Subhead">
-        <item name="android:fontFamily">sans-serif-medium</item>
+        <item name="android:fontFamily">@config/config_headlineFontFamilyMedium</item>
         <item name="android:textSize">14sp</item>
         <item name="android:textColor">?android:attr/colorAccent</item>
     </style>
@@ -337,6 +337,11 @@
         <item name="android:fontFamily">sans-serif-medium</item>
     </style>
 
+    <style name="TextAppearance.SuggestionTitleV2"
+           parent="@android:style/TextAppearance.Material.Subhead">
+        <item name="android:fontFamily">@config/config_headlineFontFamily</item>
+    </style>
+
     <style name="TextAppearance.SuggestionSummary" parent="TextAppearance.Small">
         <item name="android:textColor">?android:attr/textColorSecondary</item>
     </style>
@@ -469,6 +474,7 @@
 
     <style name="TextAppearance.SearchBar" parent="@android:style/TextAppearance.Material.Widget.Toolbar.Subtitle">
         <item name="android:textSize">@dimen/search_bar_text_size</item>
+        <item name="android:fontFamily">@config/config_headlineFontFamily</item>
     </style>
 
     <style name="device_info_dialog_label">
diff --git a/res/xml/channel_notification_settings.xml b/res/xml/channel_notification_settings.xml
index c799c8b..6d20571 100644
--- a/res/xml/channel_notification_settings.xml
+++ b/res/xml/channel_notification_settings.xml
@@ -53,7 +53,7 @@
         settings:useAdditionalSummary="true" />
 
     <!-- Visibility Override -->
-    <com.android.settings.notification.RestrictedDropDownPreference
+    <com.android.settings.RestrictedListPreference
         android:key="visibility_override"
         android:title="@string/app_notification_visibility_override_title"/>
 
diff --git a/res/xml/configure_notification_settings.xml b/res/xml/configure_notification_settings.xml
index 520ebaa..e080be4 100644
--- a/res/xml/configure_notification_settings.xml
+++ b/res/xml/configure_notification_settings.xml
@@ -15,39 +15,27 @@
 -->
 
 <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+                  xmlns:settings="http://schemas.android.com/apk/res-auto"
                   android:title="@string/configure_notification_settings"
                   android:key="configure_notification_settings">
 
-    <PreferenceCategory
-        android:key="recent_notifications_category"
-        android:title="@string/recent_notifications"
-        android:order="-200">
-        <!-- Placeholder for a list of recent apps -->
-
-        <!-- See all apps button -->
-        <Preference
-            android:title="@string/notifications_title"
-            android:key="all_notifications"
-            android:order="20">
-            <intent
-                android:action="android.intent.action.MAIN"
-                android:targetPackage="com.android.settings"
-                android:targetClass="com.android.settings.Settings$NotificationAppListActivity">
-            </intent>
-        </Preference>
-    </PreferenceCategory>
-
-    <!-- Empty category to draw divider -->
-    <PreferenceCategory
-        android:key="all_notifications_divider"
-        android:order="-190"/>
-
     <!-- When device is locked -->
-    <com.android.settings.notification.RestrictedDropDownPreference
+    <com.android.settings.RestrictedListPreference
         android:key="lock_screen_notifications"
         android:title="@string/lock_screen_notifications_title"
         android:summary="@string/summary_placeholder"/>
 
+    <PreferenceCategory
+        android:key="lock_screen_notifications_profile_header"
+        android:title="@string/profile_section_header">
+
+        <com.android.settings.RestrictedListPreference
+            android:key="lock_screen_notifications_profile"
+            android:title="@string/lock_screen_notifications_title"
+            android:summary="@string/summary_placeholder"/>
+
+    </PreferenceCategory>
+
     <!-- Notification badging -->
     <SwitchPreference
         android:key="notification_badging"
@@ -71,14 +59,30 @@
         android:title="@string/fingerprint_swipe_for_notifications_title"
         android:fragment="com.android.settings.gestures.SwipeToNotificationSettings" />
 
+    <!-- Empty category to draw divider -->
     <PreferenceCategory
-        android:key="lock_screen_notifications_profile_header"
-        android:title="@string/profile_section_header">
+        android:key="all_notifications_divider"
+        android:order="20"/>
 
-        <com.android.settings.notification.RestrictedDropDownPreference
-            android:key="lock_screen_notifications_profile"
-            android:title="@string/lock_screen_notifications_title"
-            android:summary="@string/summary_placeholder"/>
+    <PreferenceCategory
+        android:key="recent_notifications_category"
+        android:title="@string/recent_notifications"
+        settings:allowDividerAbove="false"
+        android:order="21">
+        <!-- Placeholder for a list of recent apps -->
 
+        <!-- See all apps button -->
+        <Preference
+            android:title="@string/notifications_title"
+            android:key="all_notifications"
+            android:order="22">
+            <intent
+                android:action="android.intent.action.MAIN"
+                android:targetPackage="com.android.settings"
+                android:targetClass="com.android.settings.Settings$NotificationAppListActivity">
+            </intent>
+        </Preference>
     </PreferenceCategory>
+
+
 </PreferenceScreen>
diff --git a/res/xml/connected_devices_advanced.xml b/res/xml/connected_devices_advanced.xml
index dfe23df..8ca6b81 100644
--- a/res/xml/connected_devices_advanced.xml
+++ b/res/xml/connected_devices_advanced.xml
@@ -16,6 +16,7 @@
 
 <PreferenceScreen
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:settings="http://schemas.android.com/apk/res-auto"
     android:key="connected_devices_screen"
     android:title="@string/connected_device_connections_title">
 
@@ -24,6 +25,7 @@
       android:title="@string/bluetooth_settings_title"
       android:icon="@drawable/ic_settings_bluetooth"
       android:summary="@string/bluetooth_pref_summary"
+      settings:controller="com.android.settings.bluetooth.BluetoothSwitchPreferenceController"
       android:order="-7"/>
 
     <SwitchPreference
@@ -47,11 +49,18 @@
         android:summary="@string/summary_placeholder"
         android:order="-3"/>
 
+    <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"
+        android:order="-2"/>
+
     <Preference
         android:key="usb_mode"
         android:title="@string/usb_pref"
         android:icon="@drawable/ic_usb"
-        android:order="-2">
+        android:order="-1">
         <intent android:action="android.intent.action.MAIN"
                 android:targetPackage="com.android.settings"
                 android:targetClass="com.android.settings.deviceinfo.UsbModeChooserActivity"/>
diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml
index 04644f5..42e5c54 100644
--- a/res/xml/development_settings.xml
+++ b/res/xml/development_settings.xml
@@ -15,109 +15,116 @@
 -->
 
 <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
-        xmlns:settings="http://schemas.android.com/apk/res-auto"
-        android:key="development_prefs_screen"
-        android:title="@string/development_settings_title">
+                  xmlns:settings="http://schemas.android.com/apk/res-auto"
+                  android:key="development_prefs_screen"
+                  android:title="@string/development_settings_title">
 
-    <Preference
-        android:key="memory"
-        android:icon="@drawable/ic_settings_memory"
-        android:title="@string/memory_settings_title"
-        android:summary="@string/summary_placeholder"
-        android:fragment="com.android.settings.applications.ProcessStatsSummary" />
+    <PreferenceCategory
+        android:key="debug_misc_category"
+        android:order="100">
 
-    <com.android.settings.BugreportPreference
+        <Preference
+            android:key="memory"
+            android:icon="@drawable/ic_settings_memory"
+            android:title="@string/memory_settings_title"
+            android:summary="@string/summary_placeholder"
+            android:fragment="com.android.settings.applications.ProcessStatsSummary" />
+
+        <com.android.settings.BugreportPreference
             android:key="bugreport"
             android:title="@*android:string/bugreport_title"
             android:dialogTitle="@*android:string/bugreport_title" />
 
-    <Preference
+        <Preference
             android:key="local_backup_password"
             android:title="@string/local_backup_password_title"
             android:summary="@string/local_backup_password_summary_none"
-            android:persistent="false" >
-        <intent
+            android:persistent="false">
+            <intent
                 android:action="android.settings.privacy.SET_FULL_BACKUP_PASSWORD"
                 android:targetPackage="com.android.settings"
                 android:targetClass="com.android.settings.SetFullBackupPassword" />
-    </Preference>
+        </Preference>
 
-    <com.android.settingslib.RestrictedSwitchPreference
-        android:key="keep_screen_on"
-        android:title="@string/keep_screen_on"
-        android:summary="@string/keep_screen_on_summary"
-        settings:useAdditionalSummary="true" />
+        <com.android.settingslib.RestrictedSwitchPreference
+            android:key="keep_screen_on"
+            android:title="@string/keep_screen_on"
+            android:summary="@string/keep_screen_on_summary"
+            settings:useAdditionalSummary="true" />
 
-    <ListPreference
-        android:key="hdcp_checking"
-        android:title="@string/hdcp_checking_title"
-        android:dialogTitle="@string/hdcp_checking_dialog_title"
-        android:entries="@array/hdcp_checking_titles"
-        android:entryValues="@array/hdcp_checking_values" />
+        <ListPreference
+            android:key="hdcp_checking"
+            android:title="@string/hdcp_checking_title"
+            android:dialogTitle="@string/hdcp_checking_dialog_title"
+            android:entries="@array/hdcp_checking_titles"
+            android:entryValues="@array/hdcp_checking_values" />
 
-    <SwitchPreference
-        android:key="bt_hci_snoop_log"
-        android:title="@string/bt_hci_snoop_log"
-        android:summary="@string/bt_hci_snoop_log_summary"/>
+        <SwitchPreference
+            android:key="bt_hci_snoop_log"
+            android:title="@string/bt_hci_snoop_log"
+            android:summary="@string/bt_hci_snoop_log_summary" />
 
-    <com.android.settingslib.RestrictedSwitchPreference
-        android:key="oem_unlock_enable"
-        android:title="@string/oem_unlock_enable"
-        android:summary="@string/oem_unlock_enable_summary"
-        settings:useAdditionalSummary="true"/>
+        <com.android.settingslib.RestrictedSwitchPreference
+            android:key="oem_unlock_enable"
+            android:title="@string/oem_unlock_enable"
+            android:summary="@string/oem_unlock_enable_summary"
+            settings:useAdditionalSummary="true" />
 
-    <Preference
-        android:key="running_apps"
-        android:title="@string/runningservices_settings_title"
-        android:summary="@string/runningservices_settings_summary"
-        android:fragment="com.android.settings.applications.RunningServices" />
+        <Preference
+            android:key="running_apps"
+            android:title="@string/runningservices_settings_title"
+            android:summary="@string/runningservices_settings_summary"
+            android:fragment="com.android.settings.applications.RunningServices" />
 
-    <Preference
-        android:key="convert_to_file_encryption"
-        android:title="@string/convert_to_file_encryption"
-        android:summary="@string/convert_to_file_encryption_enabled"
-        android:fragment="com.android.settings.applications.ConvertToFbe" />
+        <Preference
+            android:key="convert_to_file_encryption"
+            android:title="@string/convert_to_file_encryption"
+            android:summary="@string/convert_to_file_encryption_enabled"
+            android:fragment="com.android.settings.applications.ConvertToFbe" />
 
-    <com.android.settings.development.ColorModePreference
-        android:key="picture_color_mode"
-        android:title="@string/picture_color_mode"
-        android:summary="@string/picture_color_mode_desc" />
+        <com.android.settings.development.ColorModePreference
+            android:key="picture_color_mode"
+            android:title="@string/picture_color_mode"
+            android:summary="@string/picture_color_mode_desc" />
 
-    <Preference android:key="select_webview_provider"
-        android:title="@string/select_webview_provider_title"
-        android:dialogTitle="@string/select_webview_provider_dialog_title"
-        android:fragment="com.android.settings.webview.WebViewAppPicker" />
+        <Preference android:key="select_webview_provider"
+                    android:title="@string/select_webview_provider_title"
+                    android:dialogTitle="@string/select_webview_provider_dialog_title"
+                    android:fragment="com.android.settings.webview.WebViewAppPicker" />
 
-    <SwitchPreference
-        android:key="color_temperature"
-        android:title="@string/color_temperature"
-        android:summary="@string/color_temperature_desc" />
+        <SwitchPreference
+            android:key="color_temperature"
+            android:title="@string/color_temperature"
+            android:summary="@string/color_temperature_desc" />
 
-    <SwitchPreference
-        android:key="ota_disable_automatic_update"
-        android:title="@string/ota_disable_automatic_update" />
+        <SwitchPreference
+            android:key="ota_disable_automatic_update"
+            android:title="@string/ota_disable_automatic_update" />
 
-    <Preference
-        android:key="demo_mode"
-        android:title="@string/demo_mode">
-        <intent android:action="com.android.settings.action.DEMO_MODE" />
-    </Preference>
+        <Preference
+            android:key="demo_mode"
+            android:title="@string/demo_mode">
+            <intent android:action="com.android.settings.action.DEMO_MODE" />
+        </Preference>
 
-    <Preference
-        android:key="quick_settings_tiles"
-        android:title="@string/quick_settings_developer_tiles"
-        android:fragment="com.android.settings.development.qstile.DevelopmentTileConfigFragment" />
+        <Preference
+            android:key="quick_settings_tiles"
+            android:title="@string/quick_settings_developer_tiles"
+            android:fragment="com.android.settings.development.qstile.DevelopmentTileConfigFragment" />
+    </PreferenceCategory>
 
-    <PreferenceCategory android:key="debug_debugging_category"
-            android:title="@string/debug_debugging_category">
+    <PreferenceCategory
+        android:key="debug_debugging_category"
+        android:title="@string/debug_debugging_category"
+        android:order="200">
 
         <SwitchPreference
             android:key="enable_adb"
             android:title="@string/enable_adb"
-            android:summary="@string/enable_adb_summary"/>
+            android:summary="@string/enable_adb_summary" />
 
         <Preference android:key="clear_adb_keys"
-                android:title="@string/clear_adb_keys" />
+                    android:title="@string/clear_adb_keys" />
 
         <SwitchPreference
             android:key="enable_terminal"
@@ -127,32 +134,32 @@
         <SwitchPreference
             android:key="bugreport_in_power"
             android:title="@string/bugreport_in_power"
-            android:summary="@string/bugreport_in_power_summary"/>
+            android:summary="@string/bugreport_in_power_summary" />
 
         <Preference android:key="mock_location_app"
-            android:title="@string/mock_location_app" />
+                    android:title="@string/mock_location_app" />
 
         <SwitchPreference
             android:key="enable_gnss_raw_meas_full_tracking"
             android:title="@string/enable_gnss_raw_meas_full_tracking"
-            android:summary="@string/enable_gnss_raw_meas_full_tracking_summary"/>
+            android:summary="@string/enable_gnss_raw_meas_full_tracking_summary" />
 
         <SwitchPreference
-                android:key="debug_view_attributes"
-                android:title="@string/debug_view_attributes" />
+            android:key="debug_view_attributes"
+            android:title="@string/debug_view_attributes" />
 
         <Preference android:key="debug_app"
-                android:title="@string/debug_app" />
+                    android:title="@string/debug_app" />
 
         <SwitchPreference
             android:key="wait_for_debugger"
             android:title="@string/wait_for_debugger"
-            android:summary="@string/wait_for_debugger_summary"/>
+            android:summary="@string/wait_for_debugger_summary" />
 
         <com.android.settingslib.RestrictedSwitchPreference
             android:key="verify_apps_over_usb"
             android:title="@string/verify_apps_over_usb_title"
-            android:summary="@string/verify_apps_over_usb_summary"/>
+            android:summary="@string/verify_apps_over_usb_summary" />
 
         <ListPreference
             android:key="select_logd_size"
@@ -171,7 +178,7 @@
         <SwitchPreference
             android:key="connectivity_monitor_switch"
             android:title="@string/connectivity_monitor_switch"
-            android:summary="@string/connectivity_monitor_switch_summary"/>
+            android:summary="@string/connectivity_monitor_switch_summary" />
 
         <SwitchPreference
             android:key="camera_laser_sensor_switch"
@@ -180,42 +187,48 @@
         <Preference
             android:key="feature_flags_dashboard"
             android:title="@string/feature_flags_dashboard_title"
-            android:fragment="com.android.settings.development.featureflags.FeatureFlagsDashboard"/>
+            android:fragment="com.android.settings.development.featureflags.FeatureFlagsDashboard" />
 
         <SwitchPreference
             android:key="enable_gpu_debug_layers"
             android:title="@string/enable_gpu_debug_layers"
-            android:summary="@string/enable_gpu_debug_layers_summary"/>
+            android:summary="@string/enable_gpu_debug_layers_summary" />
 
     </PreferenceCategory>
 
-    <PreferenceCategory android:key="debug_networking_category"
-            android:title="@string/debug_networking_category">
+    <PreferenceCategory
+        android:key="dashboard_tile_placeholder"
+        android:order="300" />
+
+    <PreferenceCategory
+        android:key="debug_networking_category"
+        android:title="@string/debug_networking_category"
+        android:order="400">
 
         <SwitchPreference
             android:key="wifi_display_certification"
             android:title="@string/wifi_display_certification"
-            android:summary="@string/wifi_display_certification_summary"/>
+            android:summary="@string/wifi_display_certification_summary" />
 
         <SwitchPreference
             android:key="wifi_verbose_logging"
             android:title="@string/wifi_verbose_logging"
-            android:summary="@string/wifi_verbose_logging_summary"/>
+            android:summary="@string/wifi_verbose_logging_summary" />
 
         <SwitchPreference
             android:key="wifi_connected_mac_randomization"
             android:title="@string/wifi_connected_mac_randomization"
-            android:summary="@string/wifi_connected_mac_randomization_summary"/>
+            android:summary="@string/wifi_connected_mac_randomization_summary" />
 
         <SwitchPreference
             android:key="mobile_data_always_on"
             android:title="@string/mobile_data_always_on"
-            android:summary="@string/mobile_data_always_on_summary"/>
+            android:summary="@string/mobile_data_always_on_summary" />
 
         <SwitchPreference
             android:key="tethering_hardware_offload"
             android:title="@string/tethering_hardware_offload"
-            android:summary="@string/tethering_hardware_offload_summary"/>
+            android:summary="@string/tethering_hardware_offload_summary" />
 
         <ListPreference
             android:key="select_usb_configuration"
@@ -227,17 +240,17 @@
         <SwitchPreference
             android:key="bluetooth_show_devices_without_names"
             android:title="@string/bluetooth_show_devices_without_names"
-            android:summary="@string/bluetooth_show_devices_without_names_summary"/>
+            android:summary="@string/bluetooth_show_devices_without_names_summary" />
 
         <SwitchPreference
             android:key="bluetooth_disable_absolute_volume"
             android:title="@string/bluetooth_disable_absolute_volume"
-            android:summary="@string/bluetooth_disable_absolute_volume_summary"/>
+            android:summary="@string/bluetooth_disable_absolute_volume_summary" />
 
         <SwitchPreference
             android:key="bluetooth_disable_inband_ringing"
             android:title="@string/bluetooth_disable_inband_ringing"
-            android:summary="@string/bluetooth_disable_inband_ringing_summary"/>
+            android:summary="@string/bluetooth_disable_inband_ringing_summary" />
 
         <ListPreference
             android:key="bluetooth_select_avrcp_version"
@@ -282,46 +295,50 @@
             android:entryValues="@array/bluetooth_a2dp_codec_ldac_playback_quality_values" />
 
         <ListPreference
-                android:key="bluetooth_max_connected_audio_devices"
-                android:title="@string/bluetooth_max_connected_audio_devices_string"
-                android:dialogTitle="@string/bluetooth_max_connected_audio_devices_dialog_title"
-                android:entries="@array/bluetooth_max_connected_audio_devices"
-                android:entryValues="@array/bluetooth_max_connected_audio_devices_values" />
+            android:key="bluetooth_max_connected_audio_devices"
+            android:title="@string/bluetooth_max_connected_audio_devices_string"
+            android:dialogTitle="@string/bluetooth_max_connected_audio_devices_dialog_title"
+            android:entries="@array/bluetooth_max_connected_audio_devices"
+            android:entryValues="@array/bluetooth_max_connected_audio_devices_values" />
 
     </PreferenceCategory>
 
-    <PreferenceCategory android:key="debug_input_category"
-            android:title="@string/debug_input_category">
+    <PreferenceCategory
+        android:key="debug_input_category"
+        android:title="@string/debug_input_category"
+        android:order="500">
 
         <SwitchPreference
             android:key="show_touches"
             android:title="@string/show_touches"
-            android:summary="@string/show_touches_summary"/>
+            android:summary="@string/show_touches_summary" />
 
         <SwitchPreference
             android:key="pointer_location"
             android:title="@string/pointer_location"
-            android:summary="@string/pointer_location_summary"/>
+            android:summary="@string/pointer_location_summary" />
 
     </PreferenceCategory>
 
-    <PreferenceCategory android:key="debug_drawing_category"
-            android:title="@string/debug_drawing_category">
+    <PreferenceCategory
+        android:key="debug_drawing_category"
+        android:title="@string/debug_drawing_category"
+        android:order="600">
 
         <SwitchPreference
             android:key="show_screen_updates"
             android:title="@string/show_screen_updates"
-            android:summary="@string/show_screen_updates_summary"/>
+            android:summary="@string/show_screen_updates_summary" />
 
         <SwitchPreference
             android:key="debug_layout"
             android:title="@string/debug_layout"
-            android:summary="@string/debug_layout_summary"/>
+            android:summary="@string/debug_layout_summary" />
 
         <SwitchPreference
             android:key="force_rtl_layout_all_locales"
             android:title="@string/force_rtl_layout_all_locales"
-            android:summary="@string/force_rtl_layout_all_locales_summary"/>
+            android:summary="@string/force_rtl_layout_all_locales_summary" />
 
         <ListPreference
             android:key="window_animation_scale"
@@ -357,78 +374,84 @@
 
     </PreferenceCategory>
 
-    <PreferenceCategory android:key="debug_hw_drawing_category"
-            android:title="@string/debug_hw_drawing_category">
+    <PreferenceCategory
+        android:key="debug_hw_drawing_category"
+        android:title="@string/debug_hw_drawing_category"
+        android:order="700">
 
         <SwitchPreference
-                android:key="force_hw_ui"
-                android:title="@string/force_hw_ui"
-                android:summary="@string/force_hw_ui_summary"/>
+            android:key="force_hw_ui"
+            android:title="@string/force_hw_ui"
+            android:summary="@string/force_hw_ui_summary" />
 
         <SwitchPreference
-                android:key="show_hw_screen_updates"
-                android:title="@string/show_hw_screen_updates"
-                android:summary="@string/show_hw_screen_updates_summary"/>
+            android:key="show_hw_screen_updates"
+            android:title="@string/show_hw_screen_updates"
+            android:summary="@string/show_hw_screen_updates_summary" />
 
         <SwitchPreference
-                android:key="show_hw_layers_updates"
-                android:title="@string/show_hw_layers_updates"
-                android:summary="@string/show_hw_layers_updates_summary"/>
+            android:key="show_hw_layers_updates"
+            android:title="@string/show_hw_layers_updates"
+            android:summary="@string/show_hw_layers_updates_summary" />
 
         <ListPreference
-                android:key="debug_hw_overdraw"
-                android:title="@string/debug_hw_overdraw"
-                android:entries="@array/debug_hw_overdraw_entries"
-                android:entryValues="@array/debug_hw_overdraw_values" />
+            android:key="debug_hw_overdraw"
+            android:title="@string/debug_hw_overdraw"
+            android:entries="@array/debug_hw_overdraw_entries"
+            android:entryValues="@array/debug_hw_overdraw_values" />
 
         <ListPreference
-                android:key="show_non_rect_clip"
-                android:title="@string/show_non_rect_clip"
-                android:entries="@array/show_non_rect_clip_entries"
-                android:entryValues="@array/show_non_rect_clip_values" />
+            android:key="show_non_rect_clip"
+            android:title="@string/show_non_rect_clip"
+            android:entries="@array/show_non_rect_clip_entries"
+            android:entryValues="@array/show_non_rect_clip_values" />
 
         <SwitchPreference
-                android:key="force_msaa"
-                android:title="@string/force_msaa"
-                android:summary="@string/force_msaa_summary"/>
+            android:key="force_msaa"
+            android:title="@string/force_msaa"
+            android:summary="@string/force_msaa_summary" />
 
         <SwitchPreference
-                android:key="disable_overlays"
-                android:title="@string/disable_overlays"
-                android:summary="@string/disable_overlays_summary"/>
+            android:key="disable_overlays"
+            android:title="@string/disable_overlays"
+            android:summary="@string/disable_overlays_summary" />
 
         <ListPreference
-                android:entries="@array/simulate_color_space_entries"
-                android:entryValues="@array/simulate_color_space_values"
-                android:key="simulate_color_space"
-                android:summary="%s"
-                android:title="@string/simulate_color_space" />
+            android:entries="@array/simulate_color_space_entries"
+            android:entryValues="@array/simulate_color_space_values"
+            android:key="simulate_color_space"
+            android:summary="%s"
+            android:title="@string/simulate_color_space" />
 
         <ListPreference
-                android:key="debug_hw_renderer"
-                android:title="@string/debug_hw_renderer"
-                android:entries="@array/debug_hw_renderer_entries"
-                android:entryValues="@array/debug_hw_renderer_values" />
+            android:key="debug_hw_renderer"
+            android:title="@string/debug_hw_renderer"
+            android:entries="@array/debug_hw_renderer_entries"
+            android:entryValues="@array/debug_hw_renderer_values" />
 
     </PreferenceCategory>
 
-    <PreferenceCategory android:key="media_category"
-            android:title="@string/media_category">
+    <PreferenceCategory
+        android:key="media_category"
+        android:title="@string/media_category"
+        android:order="800">
 
         <SwitchPreference
-                android:key="usb_audio"
-                android:title="@string/usb_audio_disable_routing"
-                android:summary="@string/usb_audio_disable_routing_summary" />
+            android:key="usb_audio"
+            android:title="@string/usb_audio_disable_routing"
+            android:summary="@string/usb_audio_disable_routing_summary" />
 
     </PreferenceCategory>
 
-    <PreferenceCategory android:key="debug_monitoring_category"
-            android:title="@string/debug_monitoring_category">
+    <PreferenceCategory
+        android:key="debug_monitoring_category"
+        android:title="@string/debug_monitoring_category"
+        android:order="900">
 
         <SwitchPreference
             android:key="strict_mode"
             android:title="@string/strict_mode"
-            android:summary="@string/strict_mode_summary"/>
+            android:summary="@string/strict_mode_summary" />
 
         <ListPreference
             android:key="track_frame_time"
@@ -438,13 +461,15 @@
 
     </PreferenceCategory>
 
-    <PreferenceCategory android:key="debug_applications_category"
-            android:title="@string/debug_applications_category">
+    <PreferenceCategory
+        android:key="debug_applications_category"
+        android:title="@string/debug_applications_category"
+        android:order="1000">
 
         <SwitchPreference
             android:key="immediately_destroy_activities"
             android:title="@string/immediately_destroy_activities"
-            android:summary="@string/immediately_destroy_activities_summary"/>
+            android:summary="@string/immediately_destroy_activities_summary" />
 
         <ListPreference
             android:key="app_process_limit"
@@ -454,52 +479,48 @@
 
 
         <Preference
-                android:key="background_check"
-                android:fragment="com.android.settings.applications.appops.BackgroundCheckSummary"
-                android:title="@string/background_check_pref" />
+            android:key="background_check"
+            android:fragment="com.android.settings.applications.appops.BackgroundCheckSummary"
+            android:title="@string/background_check_pref" />
 
         <SwitchPreference
             android:key="show_first_crash_dialog"
             android:title="@string/show_first_crash_dialog"
-            android:summary="@string/show_first_crash_dialog_summary"/>
+            android:summary="@string/show_first_crash_dialog_summary" />
 
         <SwitchPreference
             android:key="show_all_anrs"
             android:title="@string/show_all_anrs"
-            android:summary="@string/show_all_anrs_summary"/>
+            android:summary="@string/show_all_anrs_summary" />
 
         <SwitchPreference
             android:key="show_notification_channel_warnings"
             android:title="@string/show_notification_channel_warnings"
-            android:summary="@string/show_notification_channel_warnings_summary"/>
+            android:summary="@string/show_notification_channel_warnings_summary" />
 
         <Preference
-                android:key="inactive_apps"
-                android:title="@string/inactive_apps_title"
-                android:fragment="com.android.settings.fuelgauge.InactiveApps"/>
+            android:key="inactive_apps"
+            android:title="@string/inactive_apps_title"
+            android:fragment="com.android.settings.fuelgauge.InactiveApps" />
 
         <SwitchPreference
             android:key="force_allow_on_external"
             android:title="@string/force_allow_on_external"
-            android:summary="@string/force_allow_on_external_summary"/>
+            android:summary="@string/force_allow_on_external_summary" />
 
         <SwitchPreference
             android:key="force_resizable_activities"
             android:title="@string/force_resizable_activities"
-            android:summary="@string/force_resizable_activities_summary"/>
+            android:summary="@string/force_resizable_activities_summary" />
 
         <SwitchPreference
-                android:key="enable_freeform_support"
-                android:title="@string/enable_freeform_support"
-                android:summary="@string/enable_freeform_support_summary"/>
+            android:key="enable_freeform_support"
+            android:title="@string/enable_freeform_support"
+            android:summary="@string/enable_freeform_support_summary" />
 
         <Preference
             android:key="reset_shortcut_manager_throttling"
             android:title="@string/reset_shortcut_manager_throttling" />
-     </PreferenceCategory>
-
-    <PreferenceCategory
-      android:key="dashboard_tile_placeholder"
-      android:order="200"/>
+    </PreferenceCategory>
 
 </PreferenceScreen>
diff --git a/res/xml/location_mode.xml b/res/xml/location_mode.xml
deleted file mode 100644
index ac8e584..0000000
--- a/res/xml/location_mode.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<PreferenceScreen
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:key="location_mode_settings"
-    android:title="@string/location_mode_screen_title">
-
-    <com.android.settings.widget.RadioButtonPreference
-        android:key="high_accuracy"
-        android:title="@string/location_mode_high_accuracy_title"
-        android:summary="@string/location_mode_high_accuracy_description" />
-    <com.android.settings.widget.RadioButtonPreference
-        android:key="battery_saving"
-        android:title="@string/location_mode_battery_saving_title"
-        android:summary="@string/location_mode_battery_saving_description" />
-    <com.android.settings.widget.RadioButtonPreference
-        android:key="sensors_only"
-        android:title="@string/location_mode_sensors_only_title"
-        android:summary="@string/location_mode_sensors_only_description" />
-
-</PreferenceScreen>
diff --git a/res/xml/location_settings.xml b/res/xml/location_settings.xml
index 0414f20..267fce9 100644
--- a/res/xml/location_settings.xml
+++ b/res/xml/location_settings.xml
@@ -50,10 +50,4 @@
         <PreferenceCategory
             android:key="location_services"
             android:title="@string/location_category_location_services" />
-
-        <Preference
-            android:key="location_mode"
-            android:title="@string/location_mode_title"
-            settings:keywords="@string/keywords_location_mode"
-            android:summary="@string/summary_placeholder" />
 </PreferenceScreen>
diff --git a/res/xml/my_device_info.xml b/res/xml/my_device_info.xml
index 673b2a5..4988b16 100644
--- a/res/xml/my_device_info.xml
+++ b/res/xml/my_device_info.xml
@@ -30,7 +30,7 @@
 
     <!-- Account name -->
     <Preference
-        android:key="account"
+        android:key="branded_account"
         android:order="1"
         android:title="@string/my_device_info_account_preference_title"
         android:summary="@string/summary_placeholder"/>
@@ -43,7 +43,7 @@
         android:summary="@string/summary_placeholder"/>
 
     <!-- Device name -->
-    <Preference
+    <com.android.settings.widget.ValidatedEditTextPreference
         android:key="device_name"
         android:order="3"
         android:title="@string/my_device_info_device_name_preference_title"
diff --git a/res/xml/security_lockscreen_settings.xml b/res/xml/security_lockscreen_settings.xml
index 6faedd7..1da1de5 100644
--- a/res/xml/security_lockscreen_settings.xml
+++ b/res/xml/security_lockscreen_settings.xml
@@ -19,7 +19,7 @@
     android:key="security_lockscreen_settings_screen"
     android:title="@string/lockscreen_settings_title">
 
-    <com.android.settings.notification.RestrictedDropDownPreference
+    <com.android.settings.RestrictedListPreference
         android:key="security_setting_lock_screen_notif"
         android:title="@string/lock_screen_notifications_title"
         android:summary="@string/summary_placeholder" />
@@ -42,7 +42,7 @@
         android:key="security_setting_lock_screen_notif_work_header"
         android:title="@string/profile_section_header">
 
-        <com.android.settings.notification.RestrictedDropDownPreference
+        <com.android.settings.RestrictedListPreference
             android:key="security_setting_lock_screen_notif_work"
             android:title="@string/lock_screen_notifications_title"
             android:summary="@string/summary_placeholder" />
diff --git a/src/com/android/settings/AirplaneModeEnabler.java b/src/com/android/settings/AirplaneModeEnabler.java
index 4fc205d..5f93589 100644
--- a/src/com/android/settings/AirplaneModeEnabler.java
+++ b/src/com/android/settings/AirplaneModeEnabler.java
@@ -30,8 +30,8 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.telephony.PhoneStateIntentReceiver;
 import com.android.internal.telephony.TelephonyProperties;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.WirelessUtils;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 public class AirplaneModeEnabler implements Preference.OnPreferenceChangeListener {
 
diff --git a/src/com/android/settings/DeviceAdminSettings.java b/src/com/android/settings/DeviceAdminSettings.java
index 9391439..bb53018 100644
--- a/src/com/android/settings/DeviceAdminSettings.java
+++ b/src/com/android/settings/DeviceAdminSettings.java
@@ -49,8 +49,9 @@
 import android.widget.TextView;
 
 import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.core.instrumentation.Instrumentable;
-import com.android.settings.core.instrumentation.VisibilityLoggerMixin;
+import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.core.instrumentation.Instrumentable;
+import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
 
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -63,8 +64,7 @@
 public class DeviceAdminSettings extends ListFragment implements Instrumentable {
     static final String TAG = "DeviceAdminSettings";
 
-    private final VisibilityLoggerMixin mVisibilityLoggerMixin =
-            new VisibilityLoggerMixin(getMetricsCategory());
+    private VisibilityLoggerMixin mVisibilityLoggerMixin;
     private DevicePolicyManager mDPM;
     private UserManager mUm;
 
@@ -85,12 +85,6 @@
         }
     }
 
-    @Override
-    public void onAttach(Context context) {
-        super.onAttach(context);
-        mVisibilityLoggerMixin.onAttach(context);
-    }
-
     /**
      * Internal collection of device admin info objects for all profiles associated with the current
      * user.
@@ -121,6 +115,8 @@
     @Override
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
+        mVisibilityLoggerMixin = new VisibilityLoggerMixin(getMetricsCategory(),
+                FeatureFactory.getFactory(getContext()).getMetricsFeatureProvider());
     }
 
     @Override
diff --git a/src/com/android/settings/MasterClear.java b/src/com/android/settings/MasterClear.java
index b7fb694..687e645 100644
--- a/src/com/android/settings/MasterClear.java
+++ b/src/com/android/settings/MasterClear.java
@@ -123,17 +123,21 @@
         return !((requestCode != KEYGUARD_REQUEST) && (requestCode != CREDENTIAL_CONFIRM_REQUEST));
     }
 
+    @VisibleForTesting
+    boolean isShowFinalConfirmation(int requestCode, int resultCode) {
+        return (resultCode == Activity.RESULT_OK) || (requestCode == CREDENTIAL_CONFIRM_REQUEST);
+    }
+
     @Override
     public void onActivityResult(int requestCode, int resultCode, Intent data) {
         super.onActivityResult(requestCode, resultCode, data);
-
         if (!isValidRequestCode(requestCode)) {
             return;
         }
 
         // If the user entered a valid keyguard trace, present the final
         // confirmation prompt; otherwise, go back to the initial state.
-        if (resultCode == Activity.RESULT_OK) {
+        if (isShowFinalConfirmation(requestCode, resultCode)) {
             showFinalConfirmation();
         } else {
             establishInitialState();
@@ -155,7 +159,10 @@
         final Context context = getActivity();
         final String accountType = context.getString(R.string.account_type);
         final String packageName = context.getString(R.string.account_confirmation_package);
-        if (TextUtils.isEmpty(accountType) || TextUtils.isEmpty(packageName)) {
+        final String className = context.getString(R.string.account_confirmation_class);
+        if (TextUtils.isEmpty(accountType)
+                || TextUtils.isEmpty(packageName)
+                || TextUtils.isEmpty(className)) {
             return false;
         }
         final AccountManager am = AccountManager.get(context);
@@ -163,7 +170,7 @@
         if (accounts != null && accounts.length > 0) {
             final Intent requestAccountConfirmation = new Intent()
                 .setPackage(packageName)
-                .setAction("android.accounts.action.PRE_FACTORY_RESET");
+                .setComponent(new ComponentName(packageName, className));
             // Check to make sure that the intent is supported.
             final PackageManager pm = context.getPackageManager();
             final ResolveInfo resolution = pm.resolveActivity(requestAccountConfirmation, 0);
@@ -172,7 +179,7 @@
                     && packageName.equals(resolution.activityInfo.packageName)) {
                 // Note that we need to check the packagename to make sure that an Activity resolver
                 // wasn't returned.
-                getActivity().startActivityForResult(
+                startActivityForResult(
                     requestAccountConfirmation, CREDENTIAL_CONFIRM_REQUEST);
                 return true;
             }
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index 3ac268a..cc90619 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -56,13 +56,13 @@
 import com.android.settings.applications.manageapplications.ManageApplications;
 import com.android.settings.backup.BackupSettingsActivity;
 import com.android.settings.core.gateway.SettingsGateway;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
-import com.android.settings.core.instrumentation.SharedPreferencesLogger;
 import com.android.settings.dashboard.DashboardFeatureProvider;
 import com.android.settings.dashboard.DashboardSummary;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.wfd.WifiDisplaySettings;
 import com.android.settings.widget.SwitchBar;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
+import com.android.settingslib.core.instrumentation.SharedPreferencesLogger;
 import com.android.settingslib.development.DevelopmentSettingsEnabler;
 import com.android.settingslib.drawer.DashboardCategory;
 import com.android.settingslib.drawer.SettingsDrawerActivity;
@@ -93,11 +93,6 @@
     public static final String EXTRA_SHOW_FRAGMENT = ":settings:show_fragment";
 
     /**
-     * The metrics category constant for logging source when a setting fragment is opened.
-     */
-    public static final String EXTRA_SOURCE_METRICS_CATEGORY = ":settings:source_metrics";
-
-    /**
      * When starting this activity and using {@link #EXTRA_SHOW_FRAGMENT},
      * this extra can also be specified to supply a Bundle of arguments to pass
      * to that fragment when it is instantiated during the initial creation
@@ -220,7 +215,8 @@
     @Override
     public SharedPreferences getSharedPreferences(String name, int mode) {
         if (name.equals(getPackageName() + "_preferences")) {
-            return new SharedPreferencesLogger(this, getMetricsTag());
+            return new SharedPreferencesLogger(this, getMetricsTag(),
+                    FeatureFactory.getFactory(this).getMetricsFeatureProvider());
         }
         return super.getSharedPreferences(name, mode);
     }
diff --git a/src/com/android/settings/SettingsPreferenceFragment.java b/src/com/android/settings/SettingsPreferenceFragment.java
index d9e264b..c5d477a 100644
--- a/src/com/android/settings/SettingsPreferenceFragment.java
+++ b/src/com/android/settings/SettingsPreferenceFragment.java
@@ -45,7 +45,6 @@
 
 import com.android.settings.applications.LayoutPreference;
 import com.android.settings.core.InstrumentedPreferenceFragment;
-import com.android.settings.core.instrumentation.Instrumentable;
 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
 import com.android.settings.search.actionbar.SearchMenuController;
 import com.android.settings.support.actionbar.HelpMenuController;
@@ -53,6 +52,7 @@
 import com.android.settings.widget.LoadingViewController;
 import com.android.settingslib.CustomDialogPreference;
 import com.android.settingslib.CustomEditTextPreference;
+import com.android.settingslib.core.instrumentation.Instrumentable;
 import com.android.settingslib.widget.FooterPreferenceMixin;
 
 import java.util.UUID;
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index ae10ffe..f45ac5e 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -110,6 +110,7 @@
 import com.android.settings.password.ChooseLockSettingsHelper;
 import com.android.settings.wrapper.DevicePolicyManagerWrapper;
 import com.android.settings.wrapper.FingerprintManagerWrapper;
+import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
 
 import java.net.InetAddress;
 import java.util.ArrayList;
@@ -577,7 +578,7 @@
         intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_TITLE_RESID, titleResId);
         intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_TITLE, title);
         intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_AS_SHORTCUT, isShortcut);
-        intent.putExtra(SettingsActivity.EXTRA_SOURCE_METRICS_CATEGORY, sourceMetricsCategory);
+        intent.putExtra(VisibilityLoggerMixin.EXTRA_SOURCE_METRICS_CATEGORY, sourceMetricsCategory);
         return intent;
     }
 
diff --git a/src/com/android/settings/accounts/AccountPreferenceController.java b/src/com/android/settings/accounts/AccountPreferenceController.java
index c0bf7d2..6127ab9 100644
--- a/src/com/android/settings/accounts/AccountPreferenceController.java
+++ b/src/com/android/settings/accounts/AccountPreferenceController.java
@@ -51,12 +51,12 @@
 import com.android.settings.SettingsPreferenceFragment;
 import com.android.settings.Utils;
 import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.search.SearchIndexableRaw;
 import com.android.settingslib.RestrictedPreference;
 import com.android.settingslib.accounts.AuthenticatorHelper;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnPause;
 import com.android.settingslib.core.lifecycle.events.OnResume;
diff --git a/src/com/android/settings/applications/AppStorageSettings.java b/src/com/android/settings/applications/AppStorageSettings.java
index 78a5050..ff036bb 100644
--- a/src/com/android/settings/applications/AppStorageSettings.java
+++ b/src/com/android/settings/applications/AppStorageSettings.java
@@ -22,6 +22,7 @@
 import android.app.ActivityManager;
 import android.app.AlertDialog;
 import android.app.AppGlobals;
+import android.app.GrantedUriPermission;
 import android.app.LoaderManager;
 import android.content.Context;
 import android.content.DialogInterface;
@@ -399,7 +400,7 @@
         // Gets all URI permissions from am.
         ActivityManager am = (ActivityManager) getActivity().getSystemService(
                 Context.ACTIVITY_SERVICE);
-        List<UriPermission> perms =
+        List<GrantedUriPermission> perms =
                 am.getGrantedUriPermissions(mAppEntry.info.packageName).getList();
 
         if (perms.isEmpty()) {
@@ -411,8 +412,8 @@
 
         // Group number of URIs by app.
         Map<CharSequence, MutableInt> uriCounters = new TreeMap<>();
-        for (UriPermission perm : perms) {
-            String authority = perm.getUri().getAuthority();
+        for (GrantedUriPermission perm : perms) {
+            String authority = perm.uri.getAuthority();
             ProviderInfo provider = pm.resolveContentProvider(authority, 0);
             CharSequence app = provider.applicationInfo.loadLabel(pm);
             MutableInt count = uriCounters.get(app);
diff --git a/src/com/android/settings/applications/DirectoryAccessDetails.java b/src/com/android/settings/applications/DirectoryAccessDetails.java
index 43422d0..3e9bf47 100644
--- a/src/com/android/settings/applications/DirectoryAccessDetails.java
+++ b/src/com/android/settings/applications/DirectoryAccessDetails.java
@@ -24,6 +24,7 @@
 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;
 
@@ -120,8 +121,7 @@
         addPreferencesFromResource(R.xml.directory_access_details);
         final PreferenceScreen prefsGroup = getPreferenceScreen();
 
-        // Set external directory UUIDs.
-        ArraySet<String> externalDirectoryUuids = null;
+        final Map<String, ExternalVolume> externalVolumes = new HashMap<>();
 
         final Uri providerUri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
                 .authority(AUTHORITY).appendPath(TABLE_PERMISSIONS).appendPath("*")
@@ -146,8 +146,10 @@
                 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);
+                    Log.v(TAG, "Pkg:"  + pkg + " uuid: " + uuid + " dir: " + dir
+                            + " granted:" + granted);
                 }
 
                 if (!mPackageName.equals(pkg)) {
@@ -159,64 +161,92 @@
 
                 if (uuid == null) {
                     // Primary storage entry: add right away
-                    prefsGroup.addPreference(
-                            newPreference(context, dir, providerUri, /* uuid= */ null, dir));
+                    prefsGroup.addPreference(newPreference(context, dir, providerUri,
+                            /* uuid= */ null, dir, granted));
                 } else {
                     // External volume entry: save it for later.
-                    if (externalDirectoryUuids == null) {
-                        externalDirectoryUuids = new ArraySet<>(1);
+                    ExternalVolume externalVolume = externalVolumes.get(uuid);
+                    if (externalVolume == null) {
+                        externalVolume = new ExternalVolume(uuid);
+                        externalVolumes.put(uuid, externalVolume);
                     }
-                    externalDirectoryUuids.add(uuid);
+                    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;
+        }
+
         // Add entries from external volumes
-        if (externalDirectoryUuids != null) {
-            if (VERBOSE) {
-                Log.v(TAG, "adding external directories: " + externalDirectoryUuids);
-            }
 
-            // 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;
-            }
-            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.
+        // 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;
+        }
+        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);
+            String name = sm.getBestVolumeDescription(volume);
+            if (name == null) {
+                Log.w(TAG, "No description for " + volume + "; using uuid instead: " + uuid);
+                name = uuid;
             }
-            if (VERBOSE) {
-                Log.v(TAG, "UUID -> name mapping: " + volumeNames);
-            }
+            volumeNames.put(uuid, name);
+        }
+        if (VERBOSE) {
+            Log.v(TAG, "UUID -> name mapping: " + volumeNames);
+        }
 
-            externalDirectoryUuids.forEach((uuid) ->{
-                final String name = volumeNames.get(uuid);
-                // TODO(b/72055774): add separator
-                prefsGroup.addPreference(
-                        newPreference(context, name, providerUri, uuid, /* dir= */ null));
+        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...
+            // TODO(b/72055774): add separator
+            prefsGroup.addPreference(newPreference(context, volumeName, providerUri, volume.uuid,
+                    /* dir= */ null, volume.granted));
+            // TODO(b/72055774): make sure children are gone when parent is toggled on - should be
+            // handled automatically if we're refreshing the activity on change, otherwise we'll
+            // need to explicitly remove them
+
+            // ... 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);
+                prefsGroup
+                        .addPreference(newPreference(context, name, providerUri, volume.uuid,
+                                dir, pair.second));
             });
         }
-        return;
     }
 
-
     private SwitchPreference newPreference(Context context, String title, Uri providerUri,
-            String uuid, String dir) {
+            String uuid, String dir, boolean granted) {
         final SwitchPreference pref = new SwitchPreference(context);
         pref.setKey(String.format("%s:%s", uuid, dir));
         pref.setTitle(title);
-        pref.setChecked(false);
+        pref.setChecked(granted);
         pref.setOnPreferenceChangeListener((unused, value) -> {
             resetDoNotAskAgain(context, value, providerUri, uuid, dir);
             return true;
@@ -259,4 +289,20 @@
     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/RecentAppsPreferenceController.java b/src/com/android/settings/applications/RecentAppsPreferenceController.java
index 20c5581..3859081 100644
--- a/src/com/android/settings/applications/RecentAppsPreferenceController.java
+++ b/src/com/android/settings/applications/RecentAppsPreferenceController.java
@@ -325,7 +325,7 @@
             // Not visible on launcher -> likely not a user visible app, skip if non-instant.
             final ApplicationsState.AppEntry appEntry =
                     mApplicationsState.getEntry(pkgName, mUserId);
-            if (!AppUtils.isInstant(appEntry.info)) {
+            if (appEntry == null || appEntry.info == null || !AppUtils.isInstant(appEntry.info)) {
                 Log.d(TAG, "Not a user visible or instant app, skipping " + pkgName);
                 return false;
             }
diff --git a/src/com/android/settings/applications/UsageAccessDetails.java b/src/com/android/settings/applications/UsageAccessDetails.java
index c10fb55..c172137 100644
--- a/src/com/android/settings/applications/UsageAccessDetails.java
+++ b/src/com/android/settings/applications/UsageAccessDetails.java
@@ -37,8 +37,8 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
 import com.android.settings.applications.AppStateUsageBridge.UsageState;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 public class UsageAccessDetails extends AppInfoWithHeader implements OnPreferenceChangeListener,
         OnPreferenceClickListener {
diff --git a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
index a0ce733..3fd7ced 100644
--- a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
+++ b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
@@ -33,10 +33,10 @@
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.widget.GearPreference;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import static android.os.UserManager.DISALLOW_CONFIG_BLUETOOTH;
 
diff --git a/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceController.java b/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceController.java
index a12d1a8..cea0147 100644
--- a/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceController.java
@@ -23,9 +23,9 @@
 import android.text.TextUtils;
 
 import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 
 public class BluetoothDeviceRenamePreferenceController extends
diff --git a/src/com/android/settings/bluetooth/BluetoothEnabler.java b/src/com/android/settings/bluetooth/BluetoothEnabler.java
index 87fa43d..0f294bd 100644
--- a/src/com/android/settings/bluetooth/BluetoothEnabler.java
+++ b/src/com/android/settings/bluetooth/BluetoothEnabler.java
@@ -27,12 +27,12 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.settings.R;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.widget.SwitchWidgetController;
 import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
 import com.android.settingslib.WirelessUtils;
 import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 /**
  * BluetoothEnabler is a helper to manage the Bluetooth on/off checkbox
diff --git a/src/com/android/settings/bluetooth/BluetoothFilesPreferenceController.java b/src/com/android/settings/bluetooth/BluetoothFilesPreferenceController.java
index 450c7b2..1ecfed4 100644
--- a/src/com/android/settings/bluetooth/BluetoothFilesPreferenceController.java
+++ b/src/com/android/settings/bluetooth/BluetoothFilesPreferenceController.java
@@ -23,9 +23,9 @@
 
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 /**
  * Controller that shows received files
diff --git a/src/com/android/settings/bluetooth/BluetoothLengthDeviceNameFilter.java b/src/com/android/settings/bluetooth/BluetoothLengthDeviceNameFilter.java
new file mode 100644
index 0000000..cdf5310
--- /dev/null
+++ b/src/com/android/settings/bluetooth/BluetoothLengthDeviceNameFilter.java
@@ -0,0 +1,28 @@
+/*
+ * 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.bluetooth;
+
+/**
+ * Filter to max the length of a Bluetotoh device name to 248 bytes, as defined by the spec.
+ */
+public class BluetoothLengthDeviceNameFilter extends Utf8ByteLengthFilter {
+    private static final int BLUETOOTH_NAME_MAX_LENGTH_BYTES = 248;
+
+    public BluetoothLengthDeviceNameFilter() {
+        super(BLUETOOTH_NAME_MAX_LENGTH_BYTES);
+    }
+}
diff --git a/src/com/android/settings/bluetooth/BluetoothNameDialogFragment.java b/src/com/android/settings/bluetooth/BluetoothNameDialogFragment.java
index 576e656..134bb97 100644
--- a/src/com/android/settings/bluetooth/BluetoothNameDialogFragment.java
+++ b/src/com/android/settings/bluetooth/BluetoothNameDialogFragment.java
@@ -43,8 +43,6 @@
  */
 abstract class BluetoothNameDialogFragment extends InstrumentedDialogFragment
         implements TextWatcher {
-    private static final int BLUETOOTH_NAME_MAX_LENGTH_BYTES = 248;
-
     private AlertDialog mAlertDialog;
     private Button mOkButton;
 
@@ -109,7 +107,7 @@
         View view = layoutInflater.inflate(R.layout.dialog_edittext, null);
         mDeviceNameView = (EditText) view.findViewById(R.id.edittext);
         mDeviceNameView.setFilters(new InputFilter[] {
-                new Utf8ByteLengthFilter(BLUETOOTH_NAME_MAX_LENGTH_BYTES)
+                new BluetoothLengthDeviceNameFilter()
         });
         mDeviceNameView.setText(deviceName);    // set initial value before adding listener
         if (!TextUtils.isEmpty(deviceName)) {
diff --git a/src/com/android/settings/bluetooth/Utf8ByteLengthFilter.java b/src/com/android/settings/bluetooth/Utf8ByteLengthFilter.java
index bae6e56..ab49818 100644
--- a/src/com/android/settings/bluetooth/Utf8ByteLengthFilter.java
+++ b/src/com/android/settings/bluetooth/Utf8ByteLengthFilter.java
@@ -37,7 +37,7 @@
  * pairs are encoded as 4 bytes, with the caveat that the maximum
  * length will be constrained more conservatively than necessary.
  */
-class Utf8ByteLengthFilter implements InputFilter {
+public class Utf8ByteLengthFilter implements InputFilter {
     private final int mMaxBytes;
 
     Utf8ByteLengthFilter(int maxBytes) {
diff --git a/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragment.java b/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragment.java
index 02b1012..2a136bc 100644
--- a/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragment.java
+++ b/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragment.java
@@ -21,11 +21,9 @@
 
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.R;
-import com.android.settings.SettingsActivity;
 import com.android.settings.bluetooth.BluetoothFilesPreferenceController;
 import com.android.settings.bluetooth.BluetoothMasterSwitchPreferenceController;
 import com.android.settings.bluetooth.BluetoothSwitchPreferenceController;
-import com.android.settings.bluetooth.Utils;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.deviceinfo.UsbBackend;
 import com.android.settings.nfc.NfcPreferenceController;
@@ -33,7 +31,6 @@
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.core.lifecycle.Lifecycle;
-import com.android.settingslib.drawer.CategoryKey;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -89,6 +86,7 @@
                 smsMirroringFeatureProvider.getController(context);
         controllers.add(smsMirroringController);
         controllers.add(new BluetoothFilesPreferenceController(context));
+        controllers.add(new BluetoothOnWhileDrivingPreferenceController(context));
         return controllers;
     }
 
diff --git a/src/com/android/settings/connecteddevice/BluetoothOnWhileDrivingPreferenceController.java b/src/com/android/settings/connecteddevice/BluetoothOnWhileDrivingPreferenceController.java
new file mode 100644
index 0000000..072de75
--- /dev/null
+++ b/src/com/android/settings/connecteddevice/BluetoothOnWhileDrivingPreferenceController.java
@@ -0,0 +1,59 @@
+/*
+ * 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 DISABLED_UNSUPPORTED;
+    }
+
+    @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 4b8ccd1..e1636b4 100644
--- a/src/com/android/settings/core/FeatureFlags.java
+++ b/src/com/android/settings/core/FeatureFlags.java
@@ -28,4 +28,5 @@
     public static final String ZONE_PICKER_V2 = "settings_zone_picker_v2";
     public static final String SUGGESTION_UI_V2 = "settings_suggestion_ui_v2";
     public static final String ABOUT_PHONE_V2 = "settings_about_phone_v2";
+    public static final String BLUETOOTH_WHILE_DRIVING = "settings_bluetooth_while_driving";
 }
diff --git a/src/com/android/settings/core/InstrumentedActivity.java b/src/com/android/settings/core/InstrumentedActivity.java
index 9b24756..5ec8505 100644
--- a/src/com/android/settings/core/InstrumentedActivity.java
+++ b/src/com/android/settings/core/InstrumentedActivity.java
@@ -16,8 +16,11 @@
 
 package com.android.settings.core;
 
-import com.android.settings.core.instrumentation.Instrumentable;
-import com.android.settings.core.instrumentation.VisibilityLoggerMixin;
+import android.os.Bundle;
+
+import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.core.instrumentation.Instrumentable;
+import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
 import com.android.settingslib.core.lifecycle.ObservableActivity;
 
 /**
@@ -25,9 +28,11 @@
  */
 public abstract class InstrumentedActivity extends ObservableActivity implements Instrumentable {
 
-    public InstrumentedActivity() {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
         // Mixin that logs visibility change for activity.
-        getLifecycle().addObserver(new VisibilityLoggerMixin(getMetricsCategory()));
+        getLifecycle().addObserver(new VisibilityLoggerMixin(getMetricsCategory(),
+                FeatureFactory.getFactory(this).getMetricsFeatureProvider()));
     }
-
 }
diff --git a/src/com/android/settings/core/InstrumentedFragment.java b/src/com/android/settings/core/InstrumentedFragment.java
index 45db836..b1215b9 100644
--- a/src/com/android/settings/core/InstrumentedFragment.java
+++ b/src/com/android/settings/core/InstrumentedFragment.java
@@ -18,30 +18,28 @@
 
 import android.content.Context;
 
-import com.android.settings.core.instrumentation.Instrumentable;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
-import com.android.settings.core.instrumentation.VisibilityLoggerMixin;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.survey.SurveyMixin;
+import com.android.settingslib.core.instrumentation.Instrumentable;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
+import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
 import com.android.settingslib.core.lifecycle.ObservableFragment;
 
 public abstract class InstrumentedFragment extends ObservableFragment implements Instrumentable {
 
     protected MetricsFeatureProvider mMetricsFeatureProvider;
 
-    private final VisibilityLoggerMixin mVisibilityLoggerMixin;
-
-    public InstrumentedFragment() {
-        // Mixin that logs visibility change for activity.
-        mVisibilityLoggerMixin = new VisibilityLoggerMixin(getMetricsCategory());
-        getLifecycle().addObserver(mVisibilityLoggerMixin);
-        getLifecycle().addObserver(new SurveyMixin(this, getClass().getSimpleName()));
-    }
+    private VisibilityLoggerMixin mVisibilityLoggerMixin;
 
     @Override
     public void onAttach(Context context) {
-        super.onAttach(context);
         mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
+        mVisibilityLoggerMixin = new VisibilityLoggerMixin(getMetricsCategory(),
+                mMetricsFeatureProvider);
+        // Mixin that logs visibility change for activity.
+        getLifecycle().addObserver(mVisibilityLoggerMixin);
+        getLifecycle().addObserver(new SurveyMixin(this, getClass().getSimpleName()));
+        super.onAttach(context);
     }
 
     @Override
diff --git a/src/com/android/settings/core/InstrumentedPreferenceFragment.java b/src/com/android/settings/core/InstrumentedPreferenceFragment.java
index 7e37115..278676c 100644
--- a/src/com/android/settings/core/InstrumentedPreferenceFragment.java
+++ b/src/com/android/settings/core/InstrumentedPreferenceFragment.java
@@ -23,11 +23,11 @@
 import android.text.TextUtils;
 import android.util.Log;
 
-import com.android.settings.core.instrumentation.Instrumentable;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
-import com.android.settings.core.instrumentation.VisibilityLoggerMixin;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.survey.SurveyMixin;
+import com.android.settingslib.core.instrumentation.Instrumentable;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
+import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
 import com.android.settingslib.core.lifecycle.ObservablePreferenceFragment;
 
 /**
@@ -44,19 +44,17 @@
     // metrics placeholder value. Only use this for development.
     protected final int PLACEHOLDER_METRIC = 10000;
 
-    private final VisibilityLoggerMixin mVisibilityLoggerMixin;
-
-    public InstrumentedPreferenceFragment() {
-        // Mixin that logs visibility change for activity.
-        mVisibilityLoggerMixin = new VisibilityLoggerMixin(getMetricsCategory());
-        getLifecycle().addObserver(mVisibilityLoggerMixin);
-        getLifecycle().addObserver(new SurveyMixin(this, getClass().getSimpleName()));
-    }
+    private VisibilityLoggerMixin mVisibilityLoggerMixin;
 
     @Override
     public void onAttach(Context context) {
-        super.onAttach(context);
         mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
+        // Mixin that logs visibility change for activity.
+        mVisibilityLoggerMixin = new VisibilityLoggerMixin(getMetricsCategory(),
+                mMetricsFeatureProvider);
+        getLifecycle().addObserver(mVisibilityLoggerMixin);
+        getLifecycle().addObserver(new SurveyMixin(this, getClass().getSimpleName()));
+        super.onAttach(context);
     }
 
     @Override
diff --git a/src/com/android/settings/core/instrumentation/EventLogWriter.java b/src/com/android/settings/core/instrumentation/EventLogWriter.java
deleted file mode 100644
index 3196f76..0000000
--- a/src/com/android/settings/core/instrumentation/EventLogWriter.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.core.instrumentation;
-
-import android.content.Context;
-import android.metrics.LogMaker;
-import android.util.Log;
-import android.util.Pair;
-
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto;
-
-/**
- * {@link LogWriter} that writes data to eventlog.
- */
-public class EventLogWriter implements LogWriter {
-
-    private final MetricsLogger mMetricsLogger = new MetricsLogger();
-
-    public void visible(Context context, int source, int category) {
-        final LogMaker logMaker = new LogMaker(category)
-                .setType(MetricsProto.MetricsEvent.TYPE_OPEN)
-                .addTaggedData(MetricsProto.MetricsEvent.FIELD_CONTEXT, source);
-        MetricsLogger.action(logMaker);
-    }
-
-    public void hidden(Context context, int category) {
-        MetricsLogger.hidden(context, category);
-    }
-
-    public void action(int category, int value, Pair<Integer, Object>... taggedData) {
-        if (taggedData == null || taggedData.length == 0) {
-            mMetricsLogger.action(category, value);
-        } else {
-            final LogMaker logMaker = new LogMaker(category)
-                    .setType(MetricsProto.MetricsEvent.TYPE_ACTION)
-                    .setSubtype(value);
-            for (Pair<Integer, Object> pair : taggedData) {
-                logMaker.addTaggedData(pair.first, pair.second);
-            }
-            mMetricsLogger.write(logMaker);
-        }
-    }
-
-    public void action(int category, boolean value, Pair<Integer, Object>... taggedData) {
-        action(category, value ? 1 : 0, taggedData);
-    }
-
-    public void action(Context context, int category, Pair<Integer, Object>... taggedData) {
-        action(context, category, "", taggedData);
-    }
-
-    public void actionWithSource(Context context, int source, int category) {
-        final LogMaker logMaker = new LogMaker(category)
-                .setType(MetricsProto.MetricsEvent.TYPE_ACTION);
-        if (source != MetricsProto.MetricsEvent.VIEW_UNKNOWN) {
-            logMaker.addTaggedData(MetricsProto.MetricsEvent.FIELD_CONTEXT, source);
-        }
-        MetricsLogger.action(logMaker);
-    }
-
-    /** @deprecated use {@link #action(int, int, Pair[])} */
-    @Deprecated
-    public void action(Context context, int category, int value) {
-        MetricsLogger.action(context, category, value);
-    }
-
-    /** @deprecated use {@link #action(int, boolean, Pair[])} */
-    @Deprecated
-    public void action(Context context, int category, boolean value) {
-        MetricsLogger.action(context, category, value);
-    }
-
-    public void action(Context context, int category, String pkg,
-            Pair<Integer, Object>... taggedData) {
-        if (taggedData == null || taggedData.length == 0) {
-            MetricsLogger.action(context, category, pkg);
-        } else {
-            final LogMaker logMaker = new LogMaker(category)
-                    .setType(MetricsProto.MetricsEvent.TYPE_ACTION)
-                    .setPackageName(pkg);
-            for (Pair<Integer, Object> pair : taggedData) {
-                logMaker.addTaggedData(pair.first, pair.second);
-            }
-            MetricsLogger.action(logMaker);
-        }
-    }
-
-    public void count(Context context, String name, int value) {
-        MetricsLogger.count(context, name, value);
-    }
-
-    public void histogram(Context context, String name, int bucket) {
-        MetricsLogger.histogram(context, name, bucket);
-    }
-}
diff --git a/src/com/android/settings/core/instrumentation/Instrumentable.java b/src/com/android/settings/core/instrumentation/Instrumentable.java
deleted file mode 100644
index f58e140..0000000
--- a/src/com/android/settings/core/instrumentation/Instrumentable.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.core.instrumentation;
-
-public interface Instrumentable {
-
-    int METRICS_CATEGORY_UNKNOWN = 0;
-
-    /**
-     * Instrumented name for a view as defined in
-     * {@link com.android.internal.logging.nano.MetricsProto.MetricsEvent}.
-     */
-    int getMetricsCategory();
-}
diff --git a/src/com/android/settings/core/instrumentation/InstrumentedDialogFragment.java b/src/com/android/settings/core/instrumentation/InstrumentedDialogFragment.java
index 5a9ab56..0a214f1 100644
--- a/src/com/android/settings/core/instrumentation/InstrumentedDialogFragment.java
+++ b/src/com/android/settings/core/instrumentation/InstrumentedDialogFragment.java
@@ -19,6 +19,9 @@
 
 import com.android.settings.DialogCreatable;
 import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.core.instrumentation.Instrumentable;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
+import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
 import com.android.settingslib.core.lifecycle.ObservableDialogFragment;
 
 public abstract class InstrumentedDialogFragment extends ObservableDialogFragment
@@ -38,13 +41,15 @@
     public InstrumentedDialogFragment(DialogCreatable dialogCreatable, int dialogId) {
         mDialogCreatable = dialogCreatable;
         mDialogId = dialogId;
-        mLifecycle.addObserver(new VisibilityLoggerMixin(getMetricsCategory()));
     }
 
-
     @Override
     public void onAttach(Context context) {
         super.onAttach(context);
-        mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
+        mMetricsFeatureProvider = FeatureFactory.getFactory(context)
+                .getMetricsFeatureProvider();
+        mLifecycle.addObserver(new VisibilityLoggerMixin(getMetricsCategory(),
+                mMetricsFeatureProvider));
+        mLifecycle.onAttach(context);
     }
 }
diff --git a/src/com/android/settings/core/instrumentation/LogWriter.java b/src/com/android/settings/core/instrumentation/LogWriter.java
deleted file mode 100644
index 062d46f..0000000
--- a/src/com/android/settings/core/instrumentation/LogWriter.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.settings.core.instrumentation;
-
-import android.content.Context;
-import android.util.Pair;
-
-/**
- * Generic log writer interface.
- */
-public interface LogWriter {
-
-    /**
-     * Logs a visibility event when view becomes visible.
-     */
-    void visible(Context context, int source, int category);
-
-    /**
-     * Logs a visibility event when view becomes hidden.
-     */
-    void hidden(Context context, int category);
-
-    /**
-     * Logs a user action.
-     */
-    void action(int category, int value, Pair<Integer, Object>... taggedData);
-
-    /**
-     * Logs a user action.
-     */
-    void action(int category, boolean value, Pair<Integer, Object>... taggedData);
-
-    /**
-     * Logs an user action.
-     */
-    void action(Context context, int category, Pair<Integer, Object>... taggedData);
-
-    /**
-     * Logs an user action.
-     */
-    void actionWithSource(Context context, int source, int category);
-
-    /**
-     * Logs an user action.
-     * @deprecated use {@link #action(int, int, Pair[])}
-     */
-    @Deprecated
-    void action(Context context, int category, int value);
-
-    /**
-     * Logs an user action.
-     * @deprecated use {@link #action(int, boolean, Pair[])}
-     */
-    @Deprecated
-    void action(Context context, int category, boolean value);
-
-    /**
-     * Logs an user action.
-     */
-    void action(Context context, int category, String pkg, Pair<Integer, Object>... taggedData);
-
-    /**
-     * Logs a count.
-     */
-    void count(Context context, String name, int value);
-
-    /**
-     * Logs a histogram event.
-     */
-    void histogram(Context context, String name, int bucket);
-}
diff --git a/src/com/android/settings/core/instrumentation/MetricsFeatureProvider.java b/src/com/android/settings/core/instrumentation/MetricsFeatureProvider.java
deleted file mode 100644
index 166cbb8..0000000
--- a/src/com/android/settings/core/instrumentation/MetricsFeatureProvider.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.settings.core.instrumentation;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.text.TextUtils;
-import android.util.Pair;
-
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * FeatureProvider for metrics.
- */
-public class MetricsFeatureProvider {
-    private List<LogWriter> mLoggerWriters;
-
-    public MetricsFeatureProvider() {
-        mLoggerWriters = new ArrayList<>();
-        installLogWriters();
-    }
-
-    protected void installLogWriters() {
-        mLoggerWriters.add(new EventLogWriter());
-    }
-
-    public void visible(Context context, int source, int category) {
-        for (LogWriter writer : mLoggerWriters) {
-            writer.visible(context, source, category);
-        }
-    }
-
-    public void hidden(Context context, int category) {
-        for (LogWriter writer : mLoggerWriters) {
-            writer.hidden(context, category);
-        }
-    }
-
-    public void actionWithSource(Context context, int source, int category) {
-        for (LogWriter writer : mLoggerWriters) {
-            writer.actionWithSource(context, source, category);
-        }
-    }
-
-    /**
-     * Logs a user action. Includes the elapsed time since the containing
-     * fragment has been visible.
-     */
-    public void action(VisibilityLoggerMixin visibilityLogger, int category, int value) {
-        for (LogWriter writer : mLoggerWriters) {
-            writer.action(category, value,
-                    sinceVisibleTaggedData(visibilityLogger.elapsedTimeSinceVisible()));
-        }
-    }
-
-    /**
-     * Logs a user action. Includes the elapsed time since the containing
-     * fragment has been visible.
-     */
-    public void action(VisibilityLoggerMixin visibilityLogger, int category, boolean value) {
-        for (LogWriter writer : mLoggerWriters) {
-            writer.action(category, value,
-                    sinceVisibleTaggedData(visibilityLogger.elapsedTimeSinceVisible()));
-        }
-    }
-
-    public void action(Context context, int category, Pair<Integer, Object>... taggedData) {
-        for (LogWriter writer : mLoggerWriters) {
-            writer.action(context, category, taggedData);
-        }
-    }
-
-    /** @deprecated use {@link #action(VisibilityLoggerMixin, int, int)} */
-    @Deprecated
-    public void action(Context context, int category, int value) {
-        for (LogWriter writer : mLoggerWriters) {
-            writer.action(context, category, value);
-        }
-    }
-
-    /** @deprecated use {@link #action(VisibilityLoggerMixin, int, boolean)} */
-    @Deprecated
-    public void action(Context context, int category, boolean value) {
-        for (LogWriter writer : mLoggerWriters) {
-            writer.action(context, category, value);
-        }
-    }
-
-    public void action(Context context, int category, String pkg,
-            Pair<Integer, Object>... taggedData) {
-        for (LogWriter writer : mLoggerWriters) {
-            writer.action(context, category, pkg, taggedData);
-        }
-    }
-
-    public void count(Context context, String name, int value) {
-        for (LogWriter writer : mLoggerWriters) {
-            writer.count(context, name, value);
-        }
-    }
-
-    public void histogram(Context context, String name, int bucket) {
-        for (LogWriter writer : mLoggerWriters) {
-            writer.histogram(context, name, bucket);
-        }
-    }
-
-    public int getMetricsCategory(Object object) {
-        if (object == null || !(object instanceof Instrumentable)) {
-            return MetricsEvent.VIEW_UNKNOWN;
-        }
-        return ((Instrumentable) object).getMetricsCategory();
-    }
-
-    public void logDashboardStartIntent(Context context, Intent intent,
-            int sourceMetricsCategory) {
-        if (intent == null) {
-            return;
-        }
-        final ComponentName cn = intent.getComponent();
-        if (cn == null) {
-            final String action = intent.getAction();
-            if (TextUtils.isEmpty(action)) {
-                // Not loggable
-                return;
-            }
-            action(context, MetricsEvent.ACTION_SETTINGS_TILE_CLICK, action,
-                    Pair.create(MetricsEvent.FIELD_CONTEXT, sourceMetricsCategory));
-            return;
-        } else if (TextUtils.equals(cn.getPackageName(), context.getPackageName())) {
-            // Going to a Setting internal page, skip click logging in favor of page's own
-            // visibility logging.
-            return;
-        }
-        action(context, MetricsEvent.ACTION_SETTINGS_TILE_CLICK, cn.flattenToString(),
-                Pair.create(MetricsEvent.FIELD_CONTEXT, sourceMetricsCategory));
-    }
-
-    private Pair<Integer, Object> sinceVisibleTaggedData(long timestamp) {
-        return Pair.create(MetricsEvent.NOTIFICATION_SINCE_VISIBLE_MILLIS, timestamp);
-    }
-}
diff --git a/src/com/android/settings/core/instrumentation/SharedPreferencesLogger.java b/src/com/android/settings/core/instrumentation/SharedPreferencesLogger.java
deleted file mode 100644
index dee40c0..0000000
--- a/src/com/android/settings/core/instrumentation/SharedPreferencesLogger.java
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.settings.core.instrumentation;
-
-import android.annotation.Nullable;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.pm.PackageManager;
-import android.os.AsyncTask;
-import android.support.annotation.VisibleForTesting;
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.Pair;
-
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settings.overlay.FeatureFactory;
-
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentSkipListSet;
-
-public class SharedPreferencesLogger implements SharedPreferences {
-
-    private static final String LOG_TAG = "SharedPreferencesLogger";
-
-    private final String mTag;
-    private final Context mContext;
-    private final MetricsFeatureProvider mMetricsFeature;
-    private final Set<String> mPreferenceKeySet;
-
-    public SharedPreferencesLogger(Context context, String tag) {
-        mContext = context;
-        mTag = tag;
-        mMetricsFeature = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
-        mPreferenceKeySet = new ConcurrentSkipListSet<>();
-    }
-
-    @Override
-    public Map<String, ?> getAll() {
-        return null;
-    }
-
-    @Override
-    public String getString(String key, @Nullable String defValue) {
-        return defValue;
-    }
-
-    @Override
-    public Set<String> getStringSet(String key, @Nullable Set<String> defValues) {
-        return defValues;
-    }
-
-    @Override
-    public int getInt(String key, int defValue) {
-        return defValue;
-    }
-
-    @Override
-    public long getLong(String key, long defValue) {
-        return defValue;
-    }
-
-    @Override
-    public float getFloat(String key, float defValue) {
-        return defValue;
-    }
-
-    @Override
-    public boolean getBoolean(String key, boolean defValue) {
-        return defValue;
-    }
-
-    @Override
-    public boolean contains(String key) {
-        return false;
-    }
-
-    @Override
-    public Editor edit() {
-        return new EditorLogger();
-    }
-
-    @Override
-    public void registerOnSharedPreferenceChangeListener(
-            OnSharedPreferenceChangeListener listener) {
-    }
-
-    @Override
-    public void unregisterOnSharedPreferenceChangeListener(
-            OnSharedPreferenceChangeListener listener) {
-    }
-
-    private void logValue(String key, Object value) {
-        logValue(key, value, false /* forceLog */);
-    }
-
-    private void logValue(String key, Object value, boolean forceLog) {
-        final String prefKey = buildPrefKey(mTag, key);
-        if (!forceLog && !mPreferenceKeySet.contains(prefKey)) {
-            // Pref key doesn't exist in set, this is initial display so we skip metrics but
-            // keeps track of this key.
-            mPreferenceKeySet.add(prefKey);
-            return;
-        }
-        // TODO: Remove count logging to save some resource.
-        mMetricsFeature.count(mContext, buildCountName(prefKey, value), 1);
-
-        final Pair<Integer, Object> valueData;
-        if (value instanceof Long) {
-            final Long longVal = (Long) value;
-            final int intVal;
-            if (longVal > Integer.MAX_VALUE) {
-                intVal = Integer.MAX_VALUE;
-            } else if (longVal < Integer.MIN_VALUE) {
-                intVal = Integer.MIN_VALUE;
-            } else {
-                intVal = longVal.intValue();
-            }
-            valueData = Pair.create(MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE,
-                    intVal);
-        } else if (value instanceof Integer) {
-            valueData = Pair.create(MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE,
-                    value);
-        } else if (value instanceof Boolean) {
-            valueData = Pair.create(MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE,
-                    (Boolean) value ? 1 : 0);
-        } else if (value instanceof Float) {
-            valueData = Pair.create(MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_FLOAT_VALUE,
-                    value);
-        } else if (value instanceof String) {
-            Log.d(LOG_TAG, "Tried to log string preference " + prefKey + " = " + value);
-            valueData = null;
-        } else {
-            Log.w(LOG_TAG, "Tried to log unloggable object" + value);
-            valueData = null;
-        }
-        if (valueData != null) {
-            // Pref key exists in set, log it's change in metrics.
-            mMetricsFeature.action(mContext, MetricsEvent.ACTION_SETTINGS_PREFERENCE_CHANGE,
-                    Pair.create(MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_NAME, prefKey),
-                    valueData);
-        }
-    }
-
-    @VisibleForTesting
-    void logPackageName(String key, String value) {
-        final String prefKey = mTag + "/" + key;
-        mMetricsFeature.action(mContext, MetricsEvent.ACTION_SETTINGS_PREFERENCE_CHANGE, value,
-                Pair.create(MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_NAME, prefKey));
-    }
-
-    private void safeLogValue(String key, String value) {
-        new AsyncPackageCheck().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, key, value);
-    }
-
-    public static String buildCountName(String prefKey, Object value) {
-        return prefKey + "|" + value;
-    }
-
-    public static String buildPrefKey(String tag, String key) {
-        return tag + "/" + key;
-    }
-
-    private class AsyncPackageCheck extends AsyncTask<String, Void, Void> {
-        @Override
-        protected Void doInBackground(String... params) {
-            String key = params[0];
-            String value = params[1];
-            PackageManager pm = mContext.getPackageManager();
-            try {
-                // Check if this might be a component.
-                ComponentName name = ComponentName.unflattenFromString(value);
-                if (value != null) {
-                    value = name.getPackageName();
-                }
-            } catch (Exception e) {
-            }
-            try {
-                pm.getPackageInfo(value, PackageManager.MATCH_ANY_USER);
-                logPackageName(key, value);
-            } catch (PackageManager.NameNotFoundException e) {
-                // Clearly not a package, and it's unlikely this preference is in prefSet, so
-                // lets force log it.
-                logValue(key, value, true /* forceLog */);
-            }
-            return null;
-        }
-    }
-
-    public class EditorLogger implements Editor {
-        @Override
-        public Editor putString(String key, @Nullable String value) {
-            safeLogValue(key, value);
-            return this;
-        }
-
-        @Override
-        public Editor putStringSet(String key, @Nullable Set<String> values) {
-            safeLogValue(key, TextUtils.join(",", values));
-            return this;
-        }
-
-        @Override
-        public Editor putInt(String key, int value) {
-            logValue(key, value);
-            return this;
-        }
-
-        @Override
-        public Editor putLong(String key, long value) {
-            logValue(key, value);
-            return this;
-        }
-
-        @Override
-        public Editor putFloat(String key, float value) {
-            logValue(key, value);
-            return this;
-        }
-
-        @Override
-        public Editor putBoolean(String key, boolean value) {
-            logValue(key, value);
-            return this;
-        }
-
-        @Override
-        public Editor remove(String key) {
-            return this;
-        }
-
-        @Override
-        public Editor clear() {
-            return this;
-        }
-
-        @Override
-        public boolean commit() {
-            return true;
-        }
-
-        @Override
-        public void apply() {
-        }
-    }
-}
diff --git a/src/com/android/settings/core/instrumentation/VisibilityLoggerMixin.java b/src/com/android/settings/core/instrumentation/VisibilityLoggerMixin.java
deleted file mode 100644
index 2fe2a3b..0000000
--- a/src/com/android/settings/core/instrumentation/VisibilityLoggerMixin.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.core.instrumentation;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-
-import android.os.SystemClock;
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.SettingsActivity;
-import com.android.settings.overlay.FeatureFactory;
-import com.android.settingslib.core.lifecycle.LifecycleObserver;
-import com.android.settingslib.core.lifecycle.events.OnAttach;
-import com.android.settingslib.core.lifecycle.events.OnPause;
-import com.android.settingslib.core.lifecycle.events.OnResume;
-
-import static com.android.settings.core.instrumentation.Instrumentable.METRICS_CATEGORY_UNKNOWN;
-
-/**
- * Logs visibility change of a fragment.
- */
-public class VisibilityLoggerMixin implements LifecycleObserver, OnResume, OnPause, OnAttach {
-
-    private static final String TAG = "VisibilityLoggerMixin";
-
-    private final int mMetricsCategory;
-
-    private MetricsFeatureProvider mMetricsFeature;
-    private int mSourceMetricsCategory = MetricsProto.MetricsEvent.VIEW_UNKNOWN;
-    private long mVisibleTimestamp;
-
-    public VisibilityLoggerMixin(int metricsCategory) {
-        // MetricsFeature will be set during onAttach.
-        this(metricsCategory, null /* metricsFeature */);
-    }
-
-    public VisibilityLoggerMixin(int metricsCategory, MetricsFeatureProvider metricsFeature) {
-        mMetricsCategory = metricsCategory;
-        mMetricsFeature = metricsFeature;
-    }
-
-    @Override
-    public void onAttach(Context context) {
-        mMetricsFeature = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
-    }
-
-    @Override
-    public void onResume() {
-        mVisibleTimestamp = SystemClock.elapsedRealtime();
-        if (mMetricsFeature != null && mMetricsCategory != METRICS_CATEGORY_UNKNOWN) {
-            mMetricsFeature.visible(null /* context */, mSourceMetricsCategory, mMetricsCategory);
-        }
-    }
-
-    @Override
-    public void onPause() {
-        mVisibleTimestamp = 0;
-        if (mMetricsFeature != null && mMetricsCategory != METRICS_CATEGORY_UNKNOWN) {
-            mMetricsFeature.hidden(null /* context */, mMetricsCategory);
-        }
-    }
-
-    /**
-     * Sets source metrics category for this logger. Source is the caller that opened this UI.
-     */
-    public void setSourceMetricsCategory(Activity activity) {
-        if (mSourceMetricsCategory != MetricsProto.MetricsEvent.VIEW_UNKNOWN || activity == null) {
-            return;
-        }
-        final Intent intent = activity.getIntent();
-        if (intent == null) {
-            return;
-        }
-        mSourceMetricsCategory = intent.getIntExtra(SettingsActivity.EXTRA_SOURCE_METRICS_CATEGORY,
-                MetricsProto.MetricsEvent.VIEW_UNKNOWN);
-    }
-
-    /** Returns elapsed time since onResume() */
-    public long elapsedTimeSinceVisible() {
-        if (mVisibleTimestamp == 0) {
-            return 0;
-        }
-        return SystemClock.elapsedRealtime() - mVisibleTimestamp;
-    }
-}
diff --git a/src/com/android/settings/dashboard/DashboardAdapter.java b/src/com/android/settings/dashboard/DashboardAdapter.java
index 97eef13..2d35ea7 100644
--- a/src/com/android/settings/dashboard/DashboardAdapter.java
+++ b/src/com/android/settings/dashboard/DashboardAdapter.java
@@ -41,7 +41,6 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
 import com.android.settings.R.id;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.dashboard.DashboardData.SuggestionConditionHeaderData;
 import com.android.settings.dashboard.conditional.Condition;
 import com.android.settings.dashboard.conditional.ConditionAdapter;
@@ -50,6 +49,7 @@
 import com.android.settings.dashboard.suggestions.SuggestionDismissController;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.Utils;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.drawer.DashboardCategory;
 import com.android.settingslib.drawer.Tile;
 
diff --git a/src/com/android/settings/dashboard/DashboardAdapterV2.java b/src/com/android/settings/dashboard/DashboardAdapterV2.java
index a422ae4..ad93e4c 100644
--- a/src/com/android/settings/dashboard/DashboardAdapterV2.java
+++ b/src/com/android/settings/dashboard/DashboardAdapterV2.java
@@ -39,13 +39,13 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
 import com.android.settings.R.id;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.dashboard.DashboardDataV2.ConditionHeaderData;
 import com.android.settings.dashboard.conditional.Condition;
 import com.android.settings.dashboard.conditional.ConditionAdapterV2;
 import com.android.settings.dashboard.suggestions.SuggestionAdapterV2;
 import com.android.settings.dashboard.suggestions.SuggestionControllerMixin;
 import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState;
diff --git a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
index a06fee9..a14d9e9 100644
--- a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
+++ b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
@@ -41,8 +41,9 @@
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
 import com.android.settings.core.FeatureFlags;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
+import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
 import com.android.settingslib.drawer.CategoryManager;
 import com.android.settingslib.drawer.DashboardCategory;
 import com.android.settingslib.drawer.ProfileSelectDialog;
@@ -159,7 +160,8 @@
             pref.setFragment(clsName);
         } else if (tile.intent != null) {
             final Intent intent = new Intent(tile.intent);
-            intent.putExtra(SettingsActivity.EXTRA_SOURCE_METRICS_CATEGORY, sourceMetricsCategory);
+            intent.putExtra(VisibilityLoggerMixin.EXTRA_SOURCE_METRICS_CATEGORY,
+                    sourceMetricsCategory);
             if (action != null) {
                 intent.setAction(action);
             }
@@ -208,7 +210,7 @@
             return;
         }
         final Intent intent = new Intent(tile.intent)
-                .putExtra(SettingsActivity.EXTRA_SOURCE_METRICS_CATEGORY,
+                .putExtra(VisibilityLoggerMixin.EXTRA_SOURCE_METRICS_CATEGORY,
                         MetricsEvent.DASHBOARD_SUMMARY)
                 .putExtra(SettingsDrawerActivity.EXTRA_SHOW_MENU, true)
                 .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
diff --git a/src/com/android/settings/dashboard/conditional/AirplaneModeCondition.java b/src/com/android/settings/dashboard/conditional/AirplaneModeCondition.java
index 7fd9af8..c6002bd 100644
--- a/src/com/android/settings/dashboard/conditional/AirplaneModeCondition.java
+++ b/src/com/android/settings/dashboard/conditional/AirplaneModeCondition.java
@@ -21,10 +21,11 @@
 import android.content.IntentFilter;
 import android.graphics.drawable.Icon;
 import android.net.ConnectivityManager;
+import android.provider.Settings;
 import android.util.Log;
+
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
-import com.android.settings.Settings;
 import com.android.settingslib.WirelessUtils;
 
 public class AirplaneModeCondition extends Condition {
@@ -33,7 +34,7 @@
     private final Receiver mReceiver;
 
     private static final IntentFilter AIRPLANE_MODE_FILTER =
-        new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED);
+            new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED);
 
     public AirplaneModeCondition(ConditionManager conditionManager) {
         super(conditionManager);
@@ -79,13 +80,14 @@
 
     @Override
     public CharSequence[] getActions() {
-        return new CharSequence[] { mManager.getContext().getString(R.string.condition_turn_off) };
+        return new CharSequence[] {mManager.getContext().getString(R.string.condition_turn_off)};
     }
 
     @Override
     public void onPrimaryClick() {
-        mManager.getContext().startActivity(new Intent(mManager.getContext(),
-                Settings.NetworkDashboardActivity.class));
+        mManager.getContext().startActivity(
+                new Intent(Settings.ACTION_WIRELESS_SETTINGS)
+                        .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
     }
 
     @Override
diff --git a/src/com/android/settings/dashboard/conditional/BackgroundDataCondition.java b/src/com/android/settings/dashboard/conditional/BackgroundDataCondition.java
index 2bc71b2..cbac86f 100644
--- a/src/com/android/settings/dashboard/conditional/BackgroundDataCondition.java
+++ b/src/com/android/settings/dashboard/conditional/BackgroundDataCondition.java
@@ -56,7 +56,7 @@
     @Override
     public void onPrimaryClick() {
         mManager.getContext().startActivity(new Intent(mManager.getContext(),
-                Settings.DataUsageSummaryActivity.class));
+                Settings.DataUsageSummaryActivity.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
     }
 
     @Override
diff --git a/src/com/android/settings/dashboard/conditional/CellularDataCondition.java b/src/com/android/settings/dashboard/conditional/CellularDataCondition.java
index 64d263f..112248c 100644
--- a/src/com/android/settings/dashboard/conditional/CellularDataCondition.java
+++ b/src/com/android/settings/dashboard/conditional/CellularDataCondition.java
@@ -80,7 +80,7 @@
     @Override
     public void onPrimaryClick() {
         mManager.getContext().startActivity(new Intent(mManager.getContext(),
-                Settings.DataUsageSummaryActivity.class));
+                Settings.DataUsageSummaryActivity.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
     }
 
     @Override
diff --git a/src/com/android/settings/dashboard/conditional/Condition.java b/src/com/android/settings/dashboard/conditional/Condition.java
index 05783bd..d66440e 100644
--- a/src/com/android/settings/dashboard/conditional/Condition.java
+++ b/src/com/android/settings/dashboard/conditional/Condition.java
@@ -24,8 +24,8 @@
 
 import android.support.annotation.VisibleForTesting;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 public abstract class Condition {
 
diff --git a/src/com/android/settings/dashboard/conditional/ConditionAdapter.java b/src/com/android/settings/dashboard/conditional/ConditionAdapter.java
index eb768e5..d84aa7c 100644
--- a/src/com/android/settings/dashboard/conditional/ConditionAdapter.java
+++ b/src/com/android/settings/dashboard/conditional/ConditionAdapter.java
@@ -27,13 +27,13 @@
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.dashboard.DashboardAdapter;
 import com.android.settings.dashboard.DashboardAdapter.DashboardItemHolder;
 import com.android.settings.dashboard.DashboardData;
 import com.android.settings.dashboard.DashboardData.HeaderMode;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.WirelessUtils;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import java.util.List;
 import java.util.Objects;
diff --git a/src/com/android/settings/dashboard/conditional/ConditionAdapterV2.java b/src/com/android/settings/dashboard/conditional/ConditionAdapterV2.java
index 3f3e5c9..8db57f7 100644
--- a/src/com/android/settings/dashboard/conditional/ConditionAdapterV2.java
+++ b/src/com/android/settings/dashboard/conditional/ConditionAdapterV2.java
@@ -27,10 +27,10 @@
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.dashboard.DashboardAdapterV2.DashboardItemHolder;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.WirelessUtils;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import java.util.List;
 import java.util.Objects;
diff --git a/src/com/android/settings/dashboard/conditional/WorkModeCondition.java b/src/com/android/settings/dashboard/conditional/WorkModeCondition.java
index b637137..5add32f 100644
--- a/src/com/android/settings/dashboard/conditional/WorkModeCondition.java
+++ b/src/com/android/settings/dashboard/conditional/WorkModeCondition.java
@@ -22,6 +22,7 @@
 import android.graphics.drawable.Icon;
 import android.os.UserHandle;
 import android.os.UserManager;
+
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
 import com.android.settings.Settings;
@@ -84,7 +85,8 @@
     @Override
     public void onPrimaryClick() {
         mManager.getContext().startActivity(new Intent(mManager.getContext(),
-                Settings.UserAndAccountDashboardActivity.class));
+                Settings.UserAndAccountDashboardActivity.class)
+                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
     }
 
     @Override
diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java b/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java
index fc11029..2b79a9b 100644
--- a/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java
+++ b/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java
@@ -27,10 +27,10 @@
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.dashboard.DashboardAdapter.DashboardItemHolder;
 import com.android.settings.dashboard.DashboardAdapter.IconCache;
 import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import java.util.List;
 import java.util.Objects;
diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionAdapterV2.java b/src/com/android/settings/dashboard/suggestions/SuggestionAdapterV2.java
index afd0e08..e04ae93 100644
--- a/src/com/android/settings/dashboard/suggestions/SuggestionAdapterV2.java
+++ b/src/com/android/settings/dashboard/suggestions/SuggestionAdapterV2.java
@@ -31,10 +31,10 @@
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.dashboard.DashboardAdapterV2.DashboardItemHolder;
 import com.android.settings.dashboard.DashboardAdapterV2.IconCache;
 import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState;
diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java
index 05c1eff..60b20e0 100644
--- a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java
+++ b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java
@@ -31,7 +31,6 @@
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.Settings.NightDisplaySuggestionActivity;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.fingerprint.FingerprintEnrollSuggestionActivity;
 import com.android.settings.fingerprint.FingerprintSuggestionActivity;
 import com.android.settings.overlay.FeatureFactory;
@@ -39,6 +38,7 @@
 import com.android.settings.support.NewDeviceIntroSuggestionActivity;
 import com.android.settings.wallpaper.WallpaperSuggestionActivity;
 import com.android.settings.wifi.WifiCallingSuggestionActivity;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.drawer.Tile;
 
 import java.util.List;
diff --git a/src/com/android/settings/datausage/DataSaverBackend.java b/src/com/android/settings/datausage/DataSaverBackend.java
index ff568c7..b59da9d 100644
--- a/src/com/android/settings/datausage/DataSaverBackend.java
+++ b/src/com/android/settings/datausage/DataSaverBackend.java
@@ -25,8 +25,8 @@
 import android.util.SparseIntArray;
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.utils.ThreadUtils;
 
 import java.util.ArrayList;
diff --git a/src/com/android/settings/datetime/ZonePicker.java b/src/com/android/settings/datetime/ZonePicker.java
index 57c340c..dc69127 100644
--- a/src/com/android/settings/datetime/ZonePicker.java
+++ b/src/com/android/settings/datetime/ZonePicker.java
@@ -35,8 +35,9 @@
 
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.R;
-import com.android.settings.core.instrumentation.Instrumentable;
-import com.android.settings.core.instrumentation.VisibilityLoggerMixin;
+import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.core.instrumentation.Instrumentable;
+import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
 import com.android.settingslib.datetime.ZoneGetter;
 
 import java.text.Collator;
@@ -57,8 +58,7 @@
 
     private static final int MENU_TIMEZONE = Menu.FIRST+1;
     private static final int MENU_ALPHABETICAL = Menu.FIRST;
-    private final VisibilityLoggerMixin mVisibilityLoggerMixin =
-            new VisibilityLoggerMixin(getMetricsCategory());
+    private VisibilityLoggerMixin mVisibilityLoggerMixin;
 
     private boolean mSortedByTimezone;
 
@@ -145,12 +145,6 @@
     }
 
     @Override
-    public void onAttach(Context context) {
-        super.onAttach(context);
-        mVisibilityLoggerMixin.onAttach(context);
-    }
-
-    @Override
     public int getMetricsCategory() {
         return MetricsProto.MetricsEvent.ZONE_PICKER;
     }
@@ -170,6 +164,13 @@
     }
 
     @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mVisibilityLoggerMixin = new VisibilityLoggerMixin(getMetricsCategory(),
+            FeatureFactory.getFactory(getContext()).getMetricsFeatureProvider());
+    }
+
+    @Override
     public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
             Bundle savedInstanceState) {
         final View view = super.onCreateView(inflater, container, savedInstanceState);
diff --git a/src/com/android/settings/deletionhelper/AutomaticStorageManagerSwitchBarController.java b/src/com/android/settings/deletionhelper/AutomaticStorageManagerSwitchBarController.java
index 8ab1a07..a20afa1 100644
--- a/src/com/android/settings/deletionhelper/AutomaticStorageManagerSwitchBarController.java
+++ b/src/com/android/settings/deletionhelper/AutomaticStorageManagerSwitchBarController.java
@@ -23,10 +23,10 @@
 import android.support.v7.preference.Preference;
 import android.widget.Switch;
 
-import com.android.internal.util.Preconditions;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
-import com.android.settings.widget.SwitchBar;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.util.Preconditions;
+import com.android.settings.widget.SwitchBar;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 /** Handles the logic for flipping the storage management toggle on a {@link SwitchBar}. */
 public class AutomaticStorageManagerSwitchBarController
diff --git a/src/com/android/settings/development/AbstractBluetoothA2dpPreferenceController.java b/src/com/android/settings/development/AbstractBluetoothA2dpPreferenceController.java
index e4e6493..171dd6a 100644
--- a/src/com/android/settings/development/AbstractBluetoothA2dpPreferenceController.java
+++ b/src/com/android/settings/development/AbstractBluetoothA2dpPreferenceController.java
@@ -18,6 +18,8 @@
 
 import android.bluetooth.BluetoothA2dp;
 import android.bluetooth.BluetoothCodecConfig;
+import android.bluetooth.BluetoothCodecStatus;
+import android.bluetooth.BluetoothDevice;
 import android.content.Context;
 import android.support.annotation.VisibleForTesting;
 import android.support.v7.preference.ListPreference;
@@ -80,7 +82,7 @@
         final BluetoothCodecConfig codecConfig = mBluetoothA2dpConfigStore.createCodecConfig();
         synchronized (mBluetoothA2dpConfigStore) {
             if (mBluetoothA2dp != null) {
-                setCodecConfigPreference(codecConfig);
+                setCodecConfigPreference(null, codecConfig);    // Use current active device
             }
         }
         // Because the setting is not persisted into permanent storage, we cannot call update state
@@ -99,13 +101,13 @@
 
     @Override
     public void updateState(Preference preference) {
-        if (getCodecConfig() == null || mPreference == null) {
+        if (getCodecConfig(null) == null || mPreference == null) { // Use current active device
             return;
         }
 
         BluetoothCodecConfig codecConfig;
         synchronized (mBluetoothA2dpConfigStore) {
-            codecConfig = getCodecConfig();
+            codecConfig = getCodecConfig(null);         // Use current active device
         }
 
         final int index = getCurrentA2dpSettingIndex(codecConfig);
@@ -183,16 +185,19 @@
     protected abstract int getDefaultIndex();
 
     @VisibleForTesting
-    void setCodecConfigPreference(BluetoothCodecConfig config) {
-        mBluetoothA2dp.setCodecConfigPreference(config);
+    void setCodecConfigPreference(BluetoothDevice device,
+                                  BluetoothCodecConfig config) {
+        mBluetoothA2dp.setCodecConfigPreference(device, config);
     }
 
     @VisibleForTesting
-    BluetoothCodecConfig getCodecConfig() {
-        if (mBluetoothA2dp == null || mBluetoothA2dp.getCodecStatus() == null) {
-            return null;
+    BluetoothCodecConfig getCodecConfig(BluetoothDevice device) {
+        if (mBluetoothA2dp != null) {
+            BluetoothCodecStatus codecStatus = mBluetoothA2dp.getCodecStatus(device);
+            if (codecStatus != null) {
+                return codecStatus.getCodecConfig();
+            }
         }
-
-        return mBluetoothA2dp.getCodecStatus().getCodecConfig();
+        return null;
     }
 }
diff --git a/src/com/android/settings/development/BluetoothAudioCodecPreferenceController.java b/src/com/android/settings/development/BluetoothAudioCodecPreferenceController.java
index 2163a70..b5c40a3 100644
--- a/src/com/android/settings/development/BluetoothAudioCodecPreferenceController.java
+++ b/src/com/android/settings/development/BluetoothAudioCodecPreferenceController.java
@@ -109,14 +109,14 @@
             case 6:
                 synchronized (mBluetoothA2dpConfigStore) {
                     if (mBluetoothA2dp != null) {
-                        mBluetoothA2dp.enableOptionalCodecs();
+                        mBluetoothA2dp.enableOptionalCodecs(null); // Use current active device
                     }
                 }
                 return;
             case 7:
                 synchronized (mBluetoothA2dpConfigStore) {
                     if (mBluetoothA2dp != null) {
-                        mBluetoothA2dp.disableOptionalCodecs();
+                        mBluetoothA2dp.disableOptionalCodecs(null); // Use current active device
                     }
                 }
                 return;
diff --git a/src/com/android/settings/deviceinfo/BrandedAccountPreferenceController.java b/src/com/android/settings/deviceinfo/BrandedAccountPreferenceController.java
index 5565e3d..c968d25 100644
--- a/src/com/android/settings/deviceinfo/BrandedAccountPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/BrandedAccountPreferenceController.java
@@ -31,7 +31,7 @@
 import com.android.settings.overlay.FeatureFactory;
 
 public class BrandedAccountPreferenceController extends BasePreferenceController {
-    private static final String KEY_PREFERENCE_TITLE = "account";
+    private static final String KEY_PREFERENCE_TITLE = "branded_account";
     private final Account[] mAccounts;
 
     public BrandedAccountPreferenceController(Context context) {
diff --git a/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java b/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java
index 2641f5d..0f3bfb8 100644
--- a/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java
@@ -34,11 +34,11 @@
 import com.android.settings.R;
 import com.android.settings.Utils;
 import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.password.ChooseLockSettingsHelper;
 import com.android.settingslib.RestrictedLockUtils;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnResume;
diff --git a/src/com/android/settings/deviceinfo/DeviceNamePreferenceController.java b/src/com/android/settings/deviceinfo/DeviceNamePreferenceController.java
new file mode 100644
index 0000000..0f1dea1
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/DeviceNamePreferenceController.java
@@ -0,0 +1,151 @@
+/*
+ * 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;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiManager;
+import android.os.Build;
+import android.provider.Settings;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+import android.text.SpannedString;
+
+import com.android.settings.bluetooth.BluetoothLengthDeviceNameFilter;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.widget.ValidatedEditTextPreference;
+import com.android.settings.wifi.tether.WifiDeviceNameTextValidator;
+import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+
+public class DeviceNamePreferenceController extends BasePreferenceController
+        implements ValidatedEditTextPreference.Validator, Preference.OnPreferenceChangeListener {
+    private static final String PREF_KEY = "device_name";
+    private String mDeviceName;
+    protected WifiManager mWifiManager;
+    private final WifiDeviceNameTextValidator mWifiDeviceNameTextValidator;
+    private ValidatedEditTextPreference mPreference;
+    @Nullable
+    private LocalBluetoothManager mBluetoothManager;
+
+    public DeviceNamePreferenceController(Context context) {
+        super(context, PREF_KEY);
+        mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
+        mWifiDeviceNameTextValidator = new WifiDeviceNameTextValidator();
+        initializeDeviceName();
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        mPreference = (ValidatedEditTextPreference) screen.findPreference(PREF_KEY);
+        mPreference.setSummary(getSummary());
+        mPreference.setValidator(this);
+    }
+
+    private void initializeDeviceName() {
+        mDeviceName = Settings.Global.getString(mContext.getContentResolver(),
+                Settings.Global.DEVICE_NAME);
+        if (mDeviceName == null) {
+            mDeviceName = Build.MODEL;
+        }
+    }
+
+    @Override
+    public String getSummary() {
+        return mDeviceName;
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return AVAILABLE;
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return PREF_KEY;
+    }
+
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        mDeviceName = (String) newValue;
+        setDeviceName(mDeviceName);
+        preference.setSummary(getSummary());
+        return true;
+    }
+
+    @Override
+    public boolean isTextValid(String deviceName) {
+        // BluetoothNameDialogFragment describes BT name filter as a 248 bytes long cap.
+        // Given the restrictions presented by the SSID name filter (32 char), I don't believe it is
+        // possible to construct an SSID that is not a valid Bluetooth name.
+        return mWifiDeviceNameTextValidator.isTextValid(deviceName);
+    }
+
+    public void setLocalBluetoothManager(LocalBluetoothManager localBluetoothManager) {
+        mBluetoothManager = localBluetoothManager;
+    }
+
+    /**
+     * This method presumes that security/validity checks have already been passed.
+     */
+    private void setDeviceName(String deviceName) {
+        setSettingsGlobalDeviceName(deviceName);
+        setBluetoothDeviceName(deviceName);
+        setTetherSsidName(deviceName);
+    }
+
+    private void setSettingsGlobalDeviceName(String deviceName) {
+        Settings.Global.putString(mContext.getContentResolver(), Settings.Global.DEVICE_NAME,
+                deviceName);
+    }
+
+    private void setBluetoothDeviceName(String deviceName) {
+        // Bluetooth manager doesn't exist for certain devices.
+        if (mBluetoothManager == null) {
+            return;
+        }
+
+        final LocalBluetoothAdapter localBluetoothAdapter = mBluetoothManager.getBluetoothAdapter();
+        if (localBluetoothAdapter != null) {
+            localBluetoothAdapter.setName(getFilteredBluetoothString(deviceName));
+        }
+    }
+
+    /**
+     * Using a UTF8ByteLengthFilter, we can filter a string to be compliant with the Bluetooth spec.
+     * For more information, see {@link com.android.settings.bluetooth.BluetoothNameDialogFragment}.
+     */
+    private static final String getFilteredBluetoothString(final String deviceName) {
+        CharSequence filteredSequence = new BluetoothLengthDeviceNameFilter().filter(deviceName, 0, deviceName.length(),
+                new SpannedString(""),
+                0, 0);
+        // null -> use the original
+        if (filteredSequence == null) {
+            return deviceName;
+        }
+        return filteredSequence.toString();
+    }
+
+    private void setTetherSsidName(String deviceName) {
+        final WifiConfiguration config = mWifiManager.getWifiApConfiguration();
+        config.SSID = deviceName;
+        // TODO: If tether is running, turn off the AP and restart it after setting config.
+        mWifiManager.setWifiApConfiguration(config);
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java b/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java
index a301807..04e7fde 100644
--- a/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java
+++ b/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java
@@ -16,6 +16,8 @@
 
 package com.android.settings.deviceinfo.aboutphone;
 
+import static com.android.settings.bluetooth.Utils.getLocalBtManager;
+
 import android.app.Activity;
 import android.app.Fragment;
 import android.content.Context;
@@ -54,6 +56,7 @@
 import com.android.settings.widget.EntityHeaderController;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settings.deviceinfo.DeviceNamePreferenceController;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -102,6 +105,10 @@
         final List<AbstractPreferenceController> controllers = new ArrayList<>();
         controllers.add(new PhoneNumberPreferenceController(context));
         controllers.add(new BrandedAccountPreferenceController(context));
+        DeviceNamePreferenceController deviceNamePreferenceController =
+                new DeviceNamePreferenceController(context);
+        deviceNamePreferenceController.setLocalBluetoothManager(getLocalBtManager(context));
+        controllers.add(deviceNamePreferenceController);
         controllers.add(new SimStatusPreferenceController(context, fragment));
         controllers.add(new DeviceModelPreferenceController(context, fragment));
         controllers.add(new ImeiInfoPreferenceController(context, fragment));
@@ -117,7 +124,6 @@
         controllers.add(new FccEquipmentIdPreferenceController(context));
         controllers.add(
                 new BuildNumberPreferenceController(context, activity, fragment, lifecycle));
-        // TODO: Add preference controller for getting the device name.
         return controllers;
     }
 
diff --git a/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceController.java b/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceController.java
index 717d765..8ab21b3 100644
--- a/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceController.java
@@ -25,12 +25,12 @@
 import android.support.v7.preference.PreferenceScreen;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.deletionhelper.ActivationWarningFragment;
 import com.android.settings.widget.MasterSwitchController;
 import com.android.settings.widget.MasterSwitchPreference;
 import com.android.settings.widget.SwitchWidgetController;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnResume;
 
diff --git a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
index 1149b99..3623298 100644
--- a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
@@ -38,11 +38,11 @@
 import com.android.settings.Utils;
 import com.android.settings.applications.manageapplications.ManageApplications;
 import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.deviceinfo.PrivateVolumeSettings.SystemInfoFragment;
 import com.android.settings.deviceinfo.StorageItemPreference;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.deviceinfo.StorageMeasurement;
 import com.android.settingslib.deviceinfo.StorageVolumeProvider;
 
diff --git a/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceController.java b/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceController.java
index 68a21ce..f3d17d5 100644
--- a/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceController.java
+++ b/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceController.java
@@ -27,11 +27,11 @@
 import com.android.internal.hardware.AmbientDisplayConfiguration;
 import com.android.settings.R;
 import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.search.DatabaseIndexingUtils;
 import com.android.settings.search.InlineSwitchPayload;
 import com.android.settings.search.ResultPayload;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 public class AmbientDisplayNotificationsPreferenceController extends
         AbstractPreferenceController implements PreferenceControllerMixin,
diff --git a/src/com/android/settings/display/AmbientDisplaySettings.java b/src/com/android/settings/display/AmbientDisplaySettings.java
index 24aede0..187325c 100644
--- a/src/com/android/settings/display/AmbientDisplaySettings.java
+++ b/src/com/android/settings/display/AmbientDisplaySettings.java
@@ -23,13 +23,13 @@
 import com.android.internal.hardware.AmbientDisplayConfiguration;
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.R;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.gestures.DoubleTapScreenPreferenceController;
 import com.android.settings.gestures.PickupGesturePreferenceController;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.search.Indexable;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 
 import java.util.ArrayList;
diff --git a/src/com/android/settings/display/AutoRotatePreferenceController.java b/src/com/android/settings/display/AutoRotatePreferenceController.java
index c7f6af1..2134b88 100644
--- a/src/com/android/settings/display/AutoRotatePreferenceController.java
+++ b/src/com/android/settings/display/AutoRotatePreferenceController.java
@@ -20,9 +20,9 @@
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.internal.view.RotationPolicy;
 import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnPause;
diff --git a/src/com/android/settings/display/ThemePreferenceController.java b/src/com/android/settings/display/ThemePreferenceController.java
index d1341dd74..9c1314e 100644
--- a/src/com/android/settings/display/ThemePreferenceController.java
+++ b/src/com/android/settings/display/ThemePreferenceController.java
@@ -29,9 +29,9 @@
 
 import com.android.settings.R;
 import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import libcore.util.Objects;
 
diff --git a/src/com/android/settings/fuelgauge/AppButtonsPreferenceController.java b/src/com/android/settings/fuelgauge/AppButtonsPreferenceController.java
index c034746..a52433b 100644
--- a/src/com/android/settings/fuelgauge/AppButtonsPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/AppButtonsPreferenceController.java
@@ -48,7 +48,6 @@
 import com.android.settings.SettingsActivity;
 import com.android.settings.Utils;
 import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.widget.ActionButtonPreference;
 import com.android.settings.wrapper.DevicePolicyManagerWrapper;
@@ -56,6 +55,7 @@
 import com.android.settingslib.applications.AppUtils;
 import com.android.settingslib.applications.ApplicationsState;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnDestroy;
diff --git a/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java b/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java
index 5d95dd2..91f35e2 100644
--- a/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java
@@ -49,10 +49,10 @@
 import com.android.settings.core.FeatureFlags;
 import com.android.settings.core.PreferenceControllerMixin;
 import com.android.settings.Utils;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.fuelgauge.anomaly.Anomaly;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnDestroy;
diff --git a/src/com/android/settings/fuelgauge/BatteryInfo.java b/src/com/android/settings/fuelgauge/BatteryInfo.java
index c4c795b..6384130 100644
--- a/src/com/android/settings/fuelgauge/BatteryInfo.java
+++ b/src/com/android/settings/fuelgauge/BatteryInfo.java
@@ -171,18 +171,20 @@
                 if (discharging && provider != null
                         && provider.isEnhancedBatteryPredictionEnabled(context)) {
                     Estimate estimate = provider.getEnhancedBatteryPrediction(context);
-                    BatteryUtils.logRuntime(LOG_TAG, "time for enhanced BatteryInfo", startTime);
-                    return BatteryInfo.getBatteryInfo(context, batteryBroadcast, stats,
-                            elapsedRealtimeUs, shortString,
-                            BatteryUtils.convertMsToUs(estimate.estimateMillis),
-                            estimate.isBasedOnUsage);
-                } else {
-                    long prediction = discharging
-                            ? stats.computeBatteryTimeRemaining(elapsedRealtimeUs) : 0;
-                    BatteryUtils.logRuntime(LOG_TAG, "time for regular BatteryInfo", startTime);
-                    return BatteryInfo.getBatteryInfo(context, batteryBroadcast, stats,
-                            elapsedRealtimeUs, shortString, prediction, false);
+                    if(estimate != null) {
+                        BatteryUtils
+                                .logRuntime(LOG_TAG, "time for enhanced BatteryInfo", startTime);
+                        return BatteryInfo.getBatteryInfo(context, batteryBroadcast, stats,
+                                elapsedRealtimeUs, shortString,
+                                BatteryUtils.convertMsToUs(estimate.estimateMillis),
+                                estimate.isBasedOnUsage);
+                    }
                 }
+                long prediction = discharging
+                        ? stats.computeBatteryTimeRemaining(elapsedRealtimeUs) : 0;
+                BatteryUtils.logRuntime(LOG_TAG, "time for regular BatteryInfo", startTime);
+                return BatteryInfo.getBatteryInfo(context, batteryBroadcast, stats,
+                        elapsedRealtimeUs, shortString, prediction, false);
             }
 
             @Override
diff --git a/src/com/android/settings/fuelgauge/DebugEstimatesLoader.java b/src/com/android/settings/fuelgauge/DebugEstimatesLoader.java
index a080e2b..e58ccd3 100644
--- a/src/com/android/settings/fuelgauge/DebugEstimatesLoader.java
+++ b/src/com/android/settings/fuelgauge/DebugEstimatesLoader.java
@@ -55,6 +55,9 @@
                 stats, elapsedRealtimeUs, false);
 
         Estimate estimate = powerUsageFeatureProvider.getEnhancedBatteryPrediction(context);
+        if (estimate == null) {
+            estimate = new Estimate(0, false);
+        }
         BatteryInfo newInfo = BatteryInfo.getBatteryInfo(getContext(), batteryBroadcast, stats,
                 elapsedRealtimeUs, false,
                 BatteryUtils.convertMsToUs(estimate.estimateMillis),
diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
index ec54291..e0954e5 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
@@ -47,7 +47,6 @@
 import com.android.settings.Utils;
 import com.android.settings.applications.LayoutPreference;
 import com.android.settings.applications.manageapplications.ManageApplications;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.dashboard.SummaryLoader;
 import com.android.settings.display.AmbientDisplayPreferenceController;
 import com.android.settings.display.AutoBrightnessPreferenceController;
@@ -61,6 +60,7 @@
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 
 import java.util.ArrayList;
diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummaryLegacy.java b/src/com/android/settings/fuelgauge/PowerUsageSummaryLegacy.java
index c50d580..605591d 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageSummaryLegacy.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageSummaryLegacy.java
@@ -54,7 +54,6 @@
 import com.android.settings.Utils;
 import com.android.settings.applications.LayoutPreference;
 import com.android.settings.applications.manageapplications.ManageApplications;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.dashboard.SummaryLoader;
 import com.android.settings.display.AmbientDisplayPreferenceController;
 import com.android.settings.display.AutoBrightnessPreferenceController;
@@ -67,6 +66,7 @@
 import com.android.settings.fuelgauge.anomaly.AnomalySummaryPreferenceController;
 import com.android.settings.fuelgauge.anomaly.AnomalyUtils;
 import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.AbstractPreferenceController;
 
 import java.util.ArrayList;
diff --git a/src/com/android/settings/fuelgauge/anomaly/AnomalyUtils.java b/src/com/android/settings/fuelgauge/anomaly/AnomalyUtils.java
index 39d51dc0..3dde95e 100644
--- a/src/com/android/settings/fuelgauge/anomaly/AnomalyUtils.java
+++ b/src/com/android/settings/fuelgauge/anomaly/AnomalyUtils.java
@@ -24,7 +24,6 @@
 
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.internal.os.BatteryStatsHelper;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.fuelgauge.anomaly.action.AnomalyAction;
 import com.android.settings.fuelgauge.anomaly.action.ForceStopAction;
 import com.android.settings.fuelgauge.anomaly.action.LocationCheckAction;
@@ -33,6 +32,7 @@
 import com.android.settings.fuelgauge.anomaly.checker.BluetoothScanAnomalyDetector;
 import com.android.settings.fuelgauge.anomaly.checker.WakeLockAnomalyDetector;
 import com.android.settings.fuelgauge.anomaly.checker.WakeupAlarmAnomalyDetector;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import java.util.ArrayList;
 import java.util.List;
diff --git a/src/com/android/settings/fuelgauge/anomaly/action/AnomalyAction.java b/src/com/android/settings/fuelgauge/anomaly/action/AnomalyAction.java
index 3ee89d1..d7de5a7 100644
--- a/src/com/android/settings/fuelgauge/anomaly/action/AnomalyAction.java
+++ b/src/com/android/settings/fuelgauge/anomaly/action/AnomalyAction.java
@@ -20,9 +20,9 @@
 import android.util.Pair;
 
 import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.fuelgauge.anomaly.Anomaly;
 import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 /**
  * Abstract class for anomaly action, which is triggered if we need to handle the anomaly
diff --git a/src/com/android/settings/fuelgauge/batterytip/actions/BatteryTipAction.java b/src/com/android/settings/fuelgauge/batterytip/actions/BatteryTipAction.java
index 9fa69fd..1bf08b7 100644
--- a/src/com/android/settings/fuelgauge/batterytip/actions/BatteryTipAction.java
+++ b/src/com/android/settings/fuelgauge/batterytip/actions/BatteryTipAction.java
@@ -18,7 +18,7 @@
 
 import android.content.Context;
 
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 /**
  * Abstract class for battery tip action, which is triggered if we need to handle the battery tip
diff --git a/src/com/android/settings/fuelgauge/batterytip/actions/SmartBatteryAction.java b/src/com/android/settings/fuelgauge/batterytip/actions/SmartBatteryAction.java
index a19471e..cbd1581 100644
--- a/src/com/android/settings/fuelgauge/batterytip/actions/SmartBatteryAction.java
+++ b/src/com/android/settings/fuelgauge/batterytip/actions/SmartBatteryAction.java
@@ -22,8 +22,8 @@
 
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.fuelgauge.SmartBatterySettings;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 public class SmartBatteryAction extends BatteryTipAction {
     private SettingsActivity mSettingsActivity;
diff --git a/src/com/android/settings/inputmethod/UserDictionarySettings.java b/src/com/android/settings/inputmethod/UserDictionarySettings.java
index 9680af1..3bbc581 100644
--- a/src/com/android/settings/inputmethod/UserDictionarySettings.java
+++ b/src/com/android/settings/inputmethod/UserDictionarySettings.java
@@ -42,10 +42,11 @@
 import android.widget.TextView;
 
 import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
-import com.android.settings.core.instrumentation.Instrumentable;
-import com.android.settings.core.instrumentation.VisibilityLoggerMixin;
+import com.android.settingslib.core.instrumentation.Instrumentable;
+import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
 
 public class UserDictionarySettings extends ListFragment implements Instrumentable,
         LoaderManager.LoaderCallbacks<Cursor> {
@@ -59,8 +60,7 @@
     private static final int OPTIONS_MENU_ADD = Menu.FIRST;
     private static final int LOADER_ID = 1;
 
-    private final VisibilityLoggerMixin mVisibilityLoggerMixin =
-            new VisibilityLoggerMixin(getMetricsCategory());
+    private VisibilityLoggerMixin mVisibilityLoggerMixin;
 
     private Cursor mCursor;
     private String mLocale;
@@ -71,15 +71,12 @@
     }
 
     @Override
-    public void onAttach(Context context) {
-        super.onAttach(context);
-        mVisibilityLoggerMixin.onAttach(context);
-    }
-
-    @Override
     public void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
+        mVisibilityLoggerMixin = new VisibilityLoggerMixin(getMetricsCategory(),
+                FeatureFactory.getFactory(getContext()).getMetricsFeatureProvider());
+
         final Intent intent = getActivity().getIntent();
         final String localeFromIntent =
                 null == intent ? null : intent.getStringExtra("locale");
diff --git a/src/com/android/settings/location/LocationEnabler.java b/src/com/android/settings/location/LocationEnabler.java
index 28ee213..30ecf2e 100644
--- a/src/com/android/settings/location/LocationEnabler.java
+++ b/src/com/android/settings/location/LocationEnabler.java
@@ -123,7 +123,8 @@
             }
             return;
         }
-        updateLocationEnabled(mContext, enabled, UserHandle.myUserId());
+        updateLocationEnabled(mContext, enabled, UserHandle.myUserId(),
+                Settings.Secure.LOCATION_CHANGER_SYSTEM_SETTINGS);
         refreshLocationMode();
     }
 
@@ -142,7 +143,8 @@
             return;
         }
 
-        updateLocationMode(mContext, currentMode, mode, ActivityManager.getCurrentUser());
+        updateLocationMode(mContext, currentMode, mode, ActivityManager.getCurrentUser(),
+                Settings.Secure.LOCATION_CHANGER_SYSTEM_SETTINGS);
         refreshLocationMode();
     }
 
diff --git a/src/com/android/settings/location/LocationMode.java b/src/com/android/settings/location/LocationMode.java
deleted file mode 100644
index 5931f9e..0000000
--- a/src/com/android/settings/location/LocationMode.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.location;
-
-import android.content.Context;
-import android.provider.SearchIndexableResource;
-
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settings.R;
-import com.android.settings.dashboard.DashboardFragment;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
-import com.android.settingslib.core.AbstractPreferenceController;
-import com.android.settingslib.core.lifecycle.Lifecycle;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * A page with 3 radio buttons to choose the location mode.
- *
- * There are 3 location modes when location access is enabled:
- *
- * High accuracy: use both GPS and network location.
- *
- * Battery saving: use network location only to reduce the power consumption.
- *
- * Sensors only: use GPS location only.
- */
-public class LocationMode extends DashboardFragment {
-
-    private static final String TAG = "LocationMode";
-
-    @Override
-    public int getMetricsCategory() {
-        return MetricsEvent.LOCATION_MODE;
-    }
-
-    @Override
-    protected int getPreferenceScreenResId() {
-        return R.xml.location_mode;
-    }
-
-    @Override
-    protected String getLogTag() {
-        return TAG;
-    }
-
-    @Override
-    protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
-        return buildPreferenceControllers(context, getLifecycle());
-    }
-
-    @Override
-    public int getHelpResource() {
-        return R.string.help_url_location_access;
-    }
-
-    private static List<AbstractPreferenceController> buildPreferenceControllers(
-            Context context, Lifecycle lifecycle) {
-        final List<AbstractPreferenceController> controllers = new ArrayList<>();
-        controllers.add(new LocationModeHighAccuracyPreferenceController(context, lifecycle));
-        controllers.add(
-                new LocationModeBatterySavingPreferenceController(context, lifecycle));
-        controllers.add(new LocationModeSensorsOnlyPreferenceController(context, lifecycle));
-        return controllers;
-    }
-
-    /**
-     * For Search.
-     */
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new BaseSearchIndexProvider() {
-                @Override
-                public List<SearchIndexableResource> getXmlResourcesToIndex(
-                        Context context, boolean enabled) {
-                    final SearchIndexableResource sir = new SearchIndexableResource(context);
-                    sir.xmlResId = R.xml.location_mode;
-                    return Arrays.asList(sir);
-                }
-
-                @Override
-                protected boolean isPageSearchEnabled(Context context) {
-                    return context.getResources().getBoolean(R.bool.config_location_mode_available);
-                }
-
-                @Override
-                public List<AbstractPreferenceController> getPreferenceControllers(Context
-                        context) {
-                    return buildPreferenceControllers(context, null /* lifecycle */);
-                }
-            };
-}
diff --git a/src/com/android/settings/location/LocationModeBatterySavingPreferenceController.java b/src/com/android/settings/location/LocationModeBatterySavingPreferenceController.java
deleted file mode 100644
index 70c7013..0000000
--- a/src/com/android/settings/location/LocationModeBatterySavingPreferenceController.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2017 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.location;
-
-import android.content.Context;
-import android.provider.Settings;
-
-import com.android.settingslib.core.lifecycle.Lifecycle;
-
-public class LocationModeBatterySavingPreferenceController
-        extends LocationModeRadioButtonPreferenceController {
-
-    private static final String KEY_BATTERY_SAVING = "battery_saving";
-
-    public LocationModeBatterySavingPreferenceController(Context context,
-            Lifecycle lifecycle) {
-        super(context, lifecycle);
-    }
-
-    @Override
-    public String getPreferenceKey() {
-        return KEY_BATTERY_SAVING;
-    }
-
-    @Override
-    protected int getLocationMode() {
-        return Settings.Secure.LOCATION_MODE_BATTERY_SAVING;
-    }
-}
diff --git a/src/com/android/settings/location/LocationModeHighAccuracyPreferenceController.java b/src/com/android/settings/location/LocationModeHighAccuracyPreferenceController.java
deleted file mode 100644
index bd2d07e..0000000
--- a/src/com/android/settings/location/LocationModeHighAccuracyPreferenceController.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2017 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.location;
-
-import android.content.Context;
-import android.provider.Settings;
-
-import com.android.settingslib.core.lifecycle.Lifecycle;
-
-public class LocationModeHighAccuracyPreferenceController
-        extends LocationModeRadioButtonPreferenceController {
-
-    private static final String KEY_HIGH_ACCURACY = "high_accuracy";
-
-    public LocationModeHighAccuracyPreferenceController(Context context,
-            Lifecycle lifecycle) {
-        super(context, lifecycle);
-    }
-
-    @Override
-    public String getPreferenceKey() {
-        return KEY_HIGH_ACCURACY;
-    }
-
-    @Override
-    protected int getLocationMode() {
-        return Settings.Secure.LOCATION_MODE_HIGH_ACCURACY;
-    }
-}
diff --git a/src/com/android/settings/location/LocationModePreferenceController.java b/src/com/android/settings/location/LocationModePreferenceController.java
deleted file mode 100644
index 265a9df..0000000
--- a/src/com/android/settings/location/LocationModePreferenceController.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2017 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.location;
-
-import android.content.Context;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceScreen;
-
-import com.android.settings.R;
-import com.android.settings.SettingsActivity;
-import com.android.settingslib.core.lifecycle.Lifecycle;
-
-public class LocationModePreferenceController extends LocationBasePreferenceController {
-
-    /** Key for preference screen "Mode" */
-    private static final String KEY_LOCATION_MODE = "location_mode";
-
-    private final LocationSettings mParentFragment;
-    private Preference mPreference;
-
-    public LocationModePreferenceController(Context context, LocationSettings parent,
-            Lifecycle lifecycle) {
-        super(context, lifecycle);
-        mParentFragment = parent;
-    }
-
-    @Override
-    public String getPreferenceKey() {
-        return KEY_LOCATION_MODE;
-    }
-
-    @Override
-    public boolean isAvailable() {
-        return mContext.getResources().getBoolean(R.bool.config_location_mode_available);
-    }
-
-    @Override
-    public void displayPreference(PreferenceScreen screen) {
-        super.displayPreference(screen);
-        mPreference = screen.findPreference(KEY_LOCATION_MODE);
-    }
-
-    @Override
-    public boolean handlePreferenceTreeClick(Preference preference) {
-        if (KEY_LOCATION_MODE.equals(preference.getKey())) {
-            final SettingsActivity activity = (SettingsActivity) mParentFragment.getActivity();
-            activity.startPreferencePanel(mParentFragment, LocationMode.class.getName(), null,
-                    R.string.location_mode_screen_title, null, mParentFragment, 0);
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public void onLocationModeChanged(int mode, boolean restricted) {
-        final int modeDescription = LocationPreferenceController.getLocationString(mode);
-        if (modeDescription != 0) {
-            mPreference.setSummary(modeDescription);
-        }
-        // Restricted user can't change the location mode, so disable the master switch. But in some
-        // corner cases, the location might still be enabled. In such case the master switch should
-        // be disabled but checked.
-        mPreference.setEnabled(mLocationEnabler.isEnabled(mode));
-    }
-}
diff --git a/src/com/android/settings/location/LocationModeRadioButtonPreferenceController.java b/src/com/android/settings/location/LocationModeRadioButtonPreferenceController.java
deleted file mode 100644
index bdf7c8f..0000000
--- a/src/com/android/settings/location/LocationModeRadioButtonPreferenceController.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2017 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.location;
-
-import android.content.Context;
-import android.support.v7.preference.PreferenceScreen;
-
-import com.android.settings.widget.RadioButtonPreference;
-import com.android.settingslib.core.lifecycle.Lifecycle;
-
-public abstract class LocationModeRadioButtonPreferenceController
-        extends LocationBasePreferenceController
-        implements RadioButtonPreference.OnClickListener {
-
-    protected RadioButtonPreference mPreference;
-
-    public LocationModeRadioButtonPreferenceController(Context context, Lifecycle lifecycle) {
-        super(context, lifecycle);
-    }
-
-    @Override
-    public void displayPreference(PreferenceScreen screen) {
-        super.displayPreference(screen);
-        mPreference = (RadioButtonPreference) screen.findPreference(getPreferenceKey());
-        mPreference.setOnClickListener(this);
-    }
-
-    @Override
-    public void onRadioButtonClicked(RadioButtonPreference emiter) {
-        mLocationEnabler.setLocationMode(getLocationMode());
-    }
-
-    @Override
-    public void onLocationModeChanged(int mode, boolean restricted) {
-        mPreference.setChecked(mode == getLocationMode());
-        mPreference.setEnabled(mLocationEnabler.isEnabled(mode));
-    }
-
-    /** Gets the location mode that this controller monitors. */
-    protected abstract int getLocationMode();
-
-}
diff --git a/src/com/android/settings/location/LocationModeSensorsOnlyPreferenceController.java b/src/com/android/settings/location/LocationModeSensorsOnlyPreferenceController.java
deleted file mode 100644
index b79dbf2..0000000
--- a/src/com/android/settings/location/LocationModeSensorsOnlyPreferenceController.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2017 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.location;
-
-import android.content.Context;
-import android.provider.Settings;
-
-import com.android.settingslib.core.lifecycle.Lifecycle;
-
-public class LocationModeSensorsOnlyPreferenceController
-        extends LocationModeRadioButtonPreferenceController {
-
-    private static final String KEY_SENSORS_ONLY = "sensors_only";
-
-    public LocationModeSensorsOnlyPreferenceController(Context context,
-            Lifecycle lifecycle) {
-        super(context, lifecycle);
-    }
-
-    @Override
-    public String getPreferenceKey() {
-        return KEY_SENSORS_ONLY;
-    }
-
-    @Override
-    protected int getLocationMode() {
-        return Settings.Secure.LOCATION_MODE_SENSORS_ONLY;
-    }
-}
diff --git a/src/com/android/settings/location/LocationPreferenceController.java b/src/com/android/settings/location/LocationPreferenceController.java
index 9b68848..5760ab7 100644
--- a/src/com/android/settings/location/LocationPreferenceController.java
+++ b/src/com/android/settings/location/LocationPreferenceController.java
@@ -105,26 +105,11 @@
         int mode = Secure.getInt(context.getContentResolver(),
                 Secure.LOCATION_MODE, Secure.LOCATION_MODE_OFF);
         if (mode != Secure.LOCATION_MODE_OFF) {
-            return context.getString(R.string.location_on_summary,
-                    context.getString(getLocationString(mode)));
+            return context.getString(R.string.location_on_summary);
         }
         return context.getString(R.string.location_off_summary);
     }
 
-    public static int getLocationString(int mode) {
-        switch (mode) {
-            case Secure.LOCATION_MODE_OFF:
-                return R.string.location_mode_location_off_title;
-            case Secure.LOCATION_MODE_SENSORS_ONLY:
-                return R.string.location_mode_sensors_only_title;
-            case Secure.LOCATION_MODE_BATTERY_SAVING:
-                return R.string.location_mode_battery_saving_title;
-            case Secure.LOCATION_MODE_HIGH_ACCURACY:
-                return R.string.location_mode_high_accuracy_title;
-        }
-        return 0;
-    }
-
     @Override
     public ResultPayload getResultPayload() {
         final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(mContext,
diff --git a/src/com/android/settings/location/LocationSettings.java b/src/com/android/settings/location/LocationSettings.java
index 85c049d..3cc5b84 100644
--- a/src/com/android/settings/location/LocationSettings.java
+++ b/src/com/android/settings/location/LocationSettings.java
@@ -127,7 +127,6 @@
     private static List<AbstractPreferenceController> buildPreferenceControllers(
             Context context, LocationSettings fragment, Lifecycle lifecycle) {
         final List<AbstractPreferenceController> controllers = new ArrayList<>();
-        controllers.add(new LocationModePreferenceController(context, fragment, lifecycle));
         controllers.add(new AppLocationPermissionPreferenceController(context));
         controllers.add(new LocationForWorkPreferenceController(context, lifecycle));
         controllers.add(
diff --git a/src/com/android/settings/network/AirplaneModePreferenceController.java b/src/com/android/settings/network/AirplaneModePreferenceController.java
index 17cf211..0b77179 100644
--- a/src/com/android/settings/network/AirplaneModePreferenceController.java
+++ b/src/com/android/settings/network/AirplaneModePreferenceController.java
@@ -28,10 +28,10 @@
 import com.android.internal.telephony.TelephonyProperties;
 import com.android.settings.AirplaneModeEnabler;
 import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.R;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnPause;
 import com.android.settingslib.core.lifecycle.events.OnResume;
diff --git a/src/com/android/settings/network/NetworkDashboardFragment.java b/src/com/android/settings/network/NetworkDashboardFragment.java
index 4b1da31..74c1910 100644
--- a/src/com/android/settings/network/NetworkDashboardFragment.java
+++ b/src/com/android/settings/network/NetworkDashboardFragment.java
@@ -31,13 +31,13 @@
 
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.R;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.dashboard.SummaryLoader;
 import com.android.settings.network.MobilePlanPreferenceController.MobilePlanPreferenceHost;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.wifi.WifiMasterSwitchPreferenceController;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 
 import java.util.ArrayList;
diff --git a/src/com/android/settings/notification/AbstractZenModePreferenceController.java b/src/com/android/settings/notification/AbstractZenModePreferenceController.java
index 81ceca1..9180791 100644
--- a/src/com/android/settings/notification/AbstractZenModePreferenceController.java
+++ b/src/com/android/settings/notification/AbstractZenModePreferenceController.java
@@ -34,9 +34,9 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnPause;
diff --git a/src/com/android/settings/notification/LockScreenNotificationPreferenceController.java b/src/com/android/settings/notification/LockScreenNotificationPreferenceController.java
index d56febb..bf821db 100644
--- a/src/com/android/settings/notification/LockScreenNotificationPreferenceController.java
+++ b/src/com/android/settings/notification/LockScreenNotificationPreferenceController.java
@@ -34,6 +34,7 @@
 
 import com.android.internal.widget.LockPatternUtils;
 import com.android.settings.R;
+import com.android.settings.RestrictedListPreference;
 import com.android.settings.Utils;
 import com.android.settings.core.PreferenceControllerMixin;
 import com.android.settings.overlay.FeatureFactory;
@@ -55,8 +56,8 @@
     private final String mWorkSettingCategoryKey;
     private final String mWorkSettingKey;
 
-    private RestrictedDropDownPreference mLockscreen;
-    private RestrictedDropDownPreference mLockscreenProfile;
+    private RestrictedListPreference mLockscreen;
+    private RestrictedListPreference mLockscreenProfile;
 
     private final int mProfileChallengeUserId;
     private final boolean mSecure;
@@ -92,13 +93,13 @@
     public void displayPreference(PreferenceScreen screen) {
         super.displayPreference(screen);
         mLockscreen =
-                (RestrictedDropDownPreference) screen.findPreference(mSettingKey);
+                (RestrictedListPreference) screen.findPreference(mSettingKey);
         if (mLockscreen == null) {
             Log.i(TAG, "Preference not found: " + mSettingKey);
             return;
         }
         if (mProfileChallengeUserId != UserHandle.USER_NULL) {
-            mLockscreenProfile = (RestrictedDropDownPreference) screen.findPreference(
+            mLockscreenProfile = (RestrictedListPreference) screen.findPreference(
                     mWorkSettingKey);
         } else {
             setVisible(screen, mWorkSettingKey, false /* visible */);
@@ -180,11 +181,6 @@
         entries.add(mContext.getString(R.string.lock_screen_notifications_summary_disable_profile));
         values.add(Integer.toString(R.string.lock_screen_notifications_summary_disable_profile));
 
-        mLockscreenProfile.setOnPreClickListener(
-                (Preference p) -> Utils.startQuietModeDialogIfNecessary(mContext,
-                        UserManager.get(mContext), mProfileChallengeUserId)
-        );
-
         mLockscreenProfile.setEntries(entries.toArray(new CharSequence[entries.size()]));
         mLockscreenProfile.setEntryValues(values.toArray(new CharSequence[values.size()]));
         updateLockscreenNotificationsForProfile();
@@ -224,36 +220,40 @@
     public boolean onPreferenceChange(Preference preference, Object newValue) {
         final String key = preference.getKey();
         if (TextUtils.equals(mWorkSettingKey, key)) {
-                final int val = Integer.parseInt((String) newValue);
-                if (val == mLockscreenSelectedValueProfile) {
-                    return false;
-                }
-                final boolean enabled =
-                        val != R.string.lock_screen_notifications_summary_disable_profile;
-                final boolean show =
-                        val == R.string.lock_screen_notifications_summary_show_profile;
-                Settings.Secure.putIntForUser(mContext.getContentResolver(),
-                        Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
-                        show ? 1 : 0, mProfileChallengeUserId);
-                Settings.Secure.putIntForUser(mContext.getContentResolver(),
-                        Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
-                        enabled ? 1 : 0, mProfileChallengeUserId);
-                mLockscreenSelectedValueProfile = val;
-                return true;
+            if (Utils.startQuietModeDialogIfNecessary(mContext, UserManager.get(mContext),
+                    mProfileChallengeUserId)) {
+                return false;
+            }
+            final int val = Integer.parseInt((String) newValue);
+            if (val == mLockscreenSelectedValueProfile) {
+                return false;
+            }
+            final boolean enabled =
+                    val != R.string.lock_screen_notifications_summary_disable_profile;
+            final boolean show =
+                    val == R.string.lock_screen_notifications_summary_show_profile;
+            Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                    Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
+                    show ? 1 : 0, mProfileChallengeUserId);
+            Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                    Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
+                    enabled ? 1 : 0, mProfileChallengeUserId);
+            mLockscreenSelectedValueProfile = val;
+            return true;
         } else if (TextUtils.equals(mSettingKey, key)) {
-                final int val = Integer.parseInt((String) newValue);
-                if (val == mLockscreenSelectedValue) {
-                    return false;
-                }
-                final boolean enabled =
-                        val != R.string.lock_screen_notifications_summary_disable;
-                final boolean show = val == R.string.lock_screen_notifications_summary_show;
-                Settings.Secure.putInt(mContext.getContentResolver(),
-                        Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, show ? 1 : 0);
-                Settings.Secure.putInt(mContext.getContentResolver(),
-                        Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, enabled ? 1 : 0);
-                mLockscreenSelectedValue = val;
-                return true;
+            final int val = Integer.parseInt((String) newValue);
+            if (val == mLockscreenSelectedValue) {
+                return false;
+            }
+            final boolean enabled =
+                    val != R.string.lock_screen_notifications_summary_disable;
+            final boolean show = val == R.string.lock_screen_notifications_summary_show;
+            Settings.Secure.putInt(mContext.getContentResolver(),
+                    Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, show ? 1 : 0);
+            Settings.Secure.putInt(mContext.getContentResolver(),
+                    Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, enabled ? 1 : 0);
+            mLockscreenSelectedValue = val;
+            return true;
         }
         return false;
     }
@@ -264,8 +264,8 @@
                 RestrictedLockUtils.checkIfKeyguardFeaturesDisabled(
                         mContext, keyguardNotificationFeatures, UserHandle.myUserId());
         if (admin != null && mLockscreen != null) {
-            RestrictedDropDownPreference.RestrictedItem item =
-                    new RestrictedDropDownPreference.RestrictedItem(entry, entryValue, admin);
+            RestrictedListPreference.RestrictedItem item =
+                    new RestrictedListPreference.RestrictedItem(entry, entryValue, admin);
             mLockscreen.addRestrictedItem(item);
         }
         if (mProfileChallengeUserId != UserHandle.USER_NULL) {
@@ -273,8 +273,8 @@
                     RestrictedLockUtils.checkIfKeyguardFeaturesDisabled(
                             mContext, keyguardNotificationFeatures, mProfileChallengeUserId);
             if (profileAdmin != null && mLockscreenProfile != null) {
-                RestrictedDropDownPreference.RestrictedItem item =
-                        new RestrictedDropDownPreference.RestrictedItem(
+                RestrictedListPreference.RestrictedItem item =
+                        new RestrictedListPreference.RestrictedItem(
                                 entry, entryValue, profileAdmin);
                 mLockscreenProfile.addRestrictedItem(item);
             }
diff --git a/src/com/android/settings/notification/RecentNotifyingAppsPreferenceController.java b/src/com/android/settings/notification/RecentNotifyingAppsPreferenceController.java
index ef34a9b..dbffc55 100644
--- a/src/com/android/settings/notification/RecentNotifyingAppsPreferenceController.java
+++ b/src/com/android/settings/notification/RecentNotifyingAppsPreferenceController.java
@@ -283,7 +283,7 @@
             // Not visible on launcher -> likely not a user visible app, skip if non-instant.
             final ApplicationsState.AppEntry appEntry =
                     mApplicationsState.getEntry(pkgName, mUserId);
-            if (!AppUtils.isInstant(appEntry.info)) {
+            if (appEntry == null || appEntry.info == null || !AppUtils.isInstant(appEntry.info)) {
                 Log.d(TAG, "Not a user visible or instant app, skipping " + pkgName);
                 return false;
             }
diff --git a/src/com/android/settings/notification/RestrictedDropDownPreference.java b/src/com/android/settings/notification/RestrictedDropDownPreference.java
deleted file mode 100644
index d19cf8d..0000000
--- a/src/com/android/settings/notification/RestrictedDropDownPreference.java
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.notification;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.support.v7.preference.DropDownPreference;
-import android.support.v7.preference.PreferenceViewHolder;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemSelectedListener;
-import android.widget.ArrayAdapter;
-import android.widget.Spinner;
-import android.widget.TextView;
-
-import com.android.settings.R;
-import com.android.settingslib.RestrictedLockUtils;
-import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
-import com.android.settingslib.RestrictedPreferenceHelper;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class RestrictedDropDownPreference extends DropDownPreference {
-    private final RestrictedPreferenceHelper mHelper;
-    private ReselectionSpinner mSpinner;
-    private List<RestrictedItem> mRestrictedItems = new ArrayList<>();
-    private boolean mUserClicked = false;
-    private OnPreferenceClickListener mPreClickListener;
-
-    public RestrictedDropDownPreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        setLayoutResource(R.layout.restricted_preference_dropdown);
-        setWidgetLayoutResource(R.layout.restricted_icon);
-        mHelper = new RestrictedPreferenceHelper(context, this, attrs);
-    }
-
-    @Override
-    protected ArrayAdapter createAdapter() {
-        return new RestrictedArrayItemAdapter(getContext());
-    }
-
-    @Override
-    public void setValue(String value) {
-        if (getRestrictedItemForEntryValue(value) != null) {
-            return;
-        }
-        super.setValue(value);
-    }
-
-    @Override
-    public void onBindViewHolder(PreferenceViewHolder view) {
-        mSpinner = (ReselectionSpinner) view.itemView.findViewById(R.id.spinner);
-        mSpinner.setPreference(this);
-        super.onBindViewHolder(view);
-        mHelper.onBindViewHolder(view);
-        mSpinner.setOnItemSelectedListener(mItemSelectedListener);
-        final View restrictedIcon = view.findViewById(R.id.restricted_icon);
-        if (restrictedIcon != null) {
-            restrictedIcon.setVisibility(isDisabledByAdmin() ? View.VISIBLE : View.GONE);
-        }
-    }
-
-    private boolean isRestrictedForEntry(CharSequence entry) {
-        if (entry == null) {
-            return false;
-        }
-        for (RestrictedItem item : mRestrictedItems) {
-            if (entry.equals(item.entry)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private RestrictedItem getRestrictedItemForEntryValue(CharSequence entryValue) {
-        if (entryValue == null) {
-            return null;
-        }
-        for (RestrictedItem item : mRestrictedItems) {
-            if (entryValue.equals(item.entryValue)) {
-                return item;
-            }
-        }
-        return null;
-    }
-
-    private RestrictedItem getRestrictedItemForPosition(int position) {
-        if (position < 0 || position >= getEntryValues().length) {
-            return null;
-        }
-        CharSequence entryValue = getEntryValues()[position];
-        return getRestrictedItemForEntryValue(entryValue);
-    }
-
-    public void addRestrictedItem(RestrictedItem item) {
-        mRestrictedItems.add(item);
-    }
-
-    public void clearRestrictedItems() {
-        mRestrictedItems.clear();
-    }
-
-    @Override
-    public void performClick() {
-        if (mPreClickListener != null && mPreClickListener.onPreferenceClick(this)) {
-            return;
-        }
-        if (!mHelper.performClick()) {
-            mUserClicked = true;
-            super.performClick();
-        }
-    }
-
-    @Override
-    public void setEnabled(boolean enabled) {
-        if (enabled && isDisabledByAdmin()) {
-            mHelper.setDisabledByAdmin(null);
-            return;
-        }
-        super.setEnabled(enabled);
-    }
-
-    public void setDisabledByAdmin(EnforcedAdmin admin) {
-        if (mHelper.setDisabledByAdmin(admin)) {
-            notifyChanged();
-        }
-    }
-
-    /**
-     * Similar to {@link #setOnPreferenceClickListener(OnPreferenceClickListener)}, but can
-     * preempt {@link #onClick()}.
-     */
-    public void setOnPreClickListener(OnPreferenceClickListener l) {
-        mPreClickListener = l;
-    }
-
-    public boolean isDisabledByAdmin() {
-        return mHelper.isDisabledByAdmin();
-    }
-
-    private void setUserClicked(boolean userClicked) {
-        mUserClicked = userClicked;
-    }
-
-    private boolean isUserClicked() {
-        return mUserClicked;
-    }
-
-    private final OnItemSelectedListener mItemSelectedListener = new OnItemSelectedListener() {
-        @Override
-        public void onItemSelected(AdapterView<?> parent, View v, int position, long id) {
-            if (mUserClicked) {
-                mUserClicked = false;
-            } else {
-                return;
-            }
-            if (position >= 0 && position < getEntryValues().length) {
-                String value = getEntryValues()[position].toString();
-                RestrictedItem item = getRestrictedItemForEntryValue(value);
-                if (item != null) {
-                    RestrictedLockUtils.sendShowAdminSupportDetailsIntent(getContext(),
-                            item.enforcedAdmin);
-                    mSpinner.setSelection(findIndexOfValue(getValue()));
-                } else if (!value.equals(getValue()) && callChangeListener(value)) {
-                    setValue(value);
-                }
-            }
-        }
-
-        @Override
-        public void onNothingSelected(AdapterView<?> parent) {
-            // noop
-        }
-    };
-
-    /**
-     * Extension of {@link ArrayAdapter} which updates the state of the dropdown item
-     * depending on whether it is restricted by the admin.
-     */
-    private class RestrictedArrayItemAdapter extends ArrayAdapter<String> {
-        private static final int TEXT_RES_ID = android.R.id.text1;
-        public RestrictedArrayItemAdapter(Context context) {
-            super(context, R.layout.spinner_dropdown_restricted_item, TEXT_RES_ID);
-        }
-
-        @Override
-        public View getDropDownView(int position, View convertView, ViewGroup parent) {
-            View rootView = super.getView(position, convertView, parent);
-            CharSequence entry = getItem(position);
-            boolean isEntryRestricted = isRestrictedForEntry(entry);
-            TextView text = (TextView) rootView.findViewById(TEXT_RES_ID);
-            if (text != null) {
-                text.setEnabled(!isEntryRestricted);
-            }
-            View restrictedIcon = rootView.findViewById(R.id.restricted_icon);
-            if (restrictedIcon != null) {
-                restrictedIcon.setVisibility(isEntryRestricted ? View.VISIBLE : View.GONE);
-            }
-            return rootView;
-        }
-    }
-
-    /**
-     * Extension of {@link Spinner} which triggers the admin support dialog on user clicking a
-     * restricted item even if was already selected.
-     */
-    public static class ReselectionSpinner extends Spinner {
-        private RestrictedDropDownPreference pref;
-
-        public ReselectionSpinner(Context context, AttributeSet attrs) {
-            super(context, attrs);
-        }
-
-        public void setPreference(RestrictedDropDownPreference pref) {
-            this.pref = pref;
-        }
-
-        @Override
-        public void setSelection(int position) {
-            int previousSelectedPosition = getSelectedItemPosition();
-            super.setSelection(position);
-            if (position == previousSelectedPosition && pref.isUserClicked()) {
-                pref.setUserClicked(false);
-                RestrictedItem item = pref.getRestrictedItemForPosition(position);
-                if (item != null) {
-                    RestrictedLockUtils.sendShowAdminSupportDetailsIntent(getContext(),
-                            item.enforcedAdmin);
-                }
-            }
-        }
-    }
-
-    public static class RestrictedItem {
-        public final CharSequence entry;
-        public final CharSequence entryValue;
-        public final EnforcedAdmin enforcedAdmin;
-
-        public RestrictedItem(CharSequence entry, CharSequence entryValue,
-                EnforcedAdmin enforcedAdmin) {
-            this.entry = entry;
-            this.entryValue = entryValue;
-            this.enforcedAdmin = enforcedAdmin;
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/settings/notification/VisibilityPreferenceController.java b/src/com/android/settings/notification/VisibilityPreferenceController.java
index 76caac0..62ca183 100644
--- a/src/com/android/settings/notification/VisibilityPreferenceController.java
+++ b/src/com/android/settings/notification/VisibilityPreferenceController.java
@@ -29,6 +29,7 @@
 
 import com.android.internal.widget.LockPatternUtils;
 import com.android.settings.R;
+import com.android.settings.RestrictedListPreference;
 import com.android.settings.core.PreferenceControllerMixin;
 import com.android.settingslib.RestrictedLockUtils;
 
@@ -65,7 +66,7 @@
 
     public void updateState(Preference preference) {
         if (mChannel != null && mAppRow != null) {
-            RestrictedDropDownPreference pref = (RestrictedDropDownPreference) preference;
+            RestrictedListPreference pref = (RestrictedListPreference) preference;
             ArrayList<CharSequence> entries = new ArrayList<>();
             ArrayList<CharSequence> values = new ArrayList<>();
 
@@ -120,14 +121,14 @@
         return true;
     }
 
-    private void setRestrictedIfNotificationFeaturesDisabled(RestrictedDropDownPreference pref,
+    private void setRestrictedIfNotificationFeaturesDisabled(RestrictedListPreference pref,
             CharSequence entry, CharSequence entryValue, int keyguardNotificationFeatures) {
         RestrictedLockUtils.EnforcedAdmin admin =
                 RestrictedLockUtils.checkIfKeyguardFeaturesDisabled(
                         mContext, keyguardNotificationFeatures, mAppRow.userId);
         if (admin != null) {
-            RestrictedDropDownPreference.RestrictedItem item =
-                    new RestrictedDropDownPreference.RestrictedItem(entry, entryValue, admin);
+            RestrictedListPreference.RestrictedItem item =
+                    new RestrictedListPreference.RestrictedItem(entry, entryValue, admin);
             pref.addRestrictedItem(item);
         }
     }
diff --git a/src/com/android/settings/notification/ZenRulePreference.java b/src/com/android/settings/notification/ZenRulePreference.java
index 7193873..fee390f 100644
--- a/src/com/android/settings/notification/ZenRulePreference.java
+++ b/src/com/android/settings/notification/ZenRulePreference.java
@@ -30,10 +30,10 @@
 
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.R;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.utils.ManagedServiceSettings;
 import com.android.settings.utils.ZenServiceListing;
 import com.android.settingslib.TwoTargetPreference;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import java.util.Map;
 
@@ -145,4 +145,4 @@
                 ? mContext.getResources().getString(R.string.switch_off_text)
                 : mContext.getResources().getString(R.string.switch_on_text);
     }
-}
\ No newline at end of file
+}
diff --git a/src/com/android/settings/overlay/FeatureFactory.java b/src/com/android/settings/overlay/FeatureFactory.java
index 71fbaa4..80d435f 100644
--- a/src/com/android/settings/overlay/FeatureFactory.java
+++ b/src/com/android/settings/overlay/FeatureFactory.java
@@ -25,7 +25,6 @@
 import com.android.settings.applications.ApplicationFeatureProvider;
 import com.android.settings.bluetooth.BluetoothFeatureProvider;
 import com.android.settings.connecteddevice.SmsMirroringFeatureProvider;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.dashboard.DashboardFeatureProvider;
 import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
 import com.android.settings.datausage.DataPlanFeatureProvider;
@@ -37,6 +36,7 @@
 import com.android.settings.search.SearchFeatureProvider;
 import com.android.settings.slices.SlicesFeatureProvider;
 import com.android.settings.users.UserFeatureProvider;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 /**
  * Abstract class for creating feature controllers. Allows OEM implementations to define their own
diff --git a/src/com/android/settings/overlay/FeatureFactoryImpl.java b/src/com/android/settings/overlay/FeatureFactoryImpl.java
index 45dc238..55f408d 100644
--- a/src/com/android/settings/overlay/FeatureFactoryImpl.java
+++ b/src/com/android/settings/overlay/FeatureFactoryImpl.java
@@ -31,7 +31,6 @@
 import com.android.settings.bluetooth.BluetoothFeatureProviderImpl;
 import com.android.settings.connecteddevice.SmsMirroringFeatureProvider;
 import com.android.settings.connecteddevice.SmsMirroringFeatureProviderImpl;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.dashboard.DashboardFeatureProvider;
 import com.android.settings.dashboard.DashboardFeatureProviderImpl;
 import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
@@ -57,6 +56,7 @@
 import com.android.settings.wrapper.ConnectivityManagerWrapper;
 import com.android.settings.wrapper.DevicePolicyManagerWrapper;
 import com.android.settings.wrapper.IPackageManagerWrapper;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.wrapper.PackageManagerWrapper;
 
 /**
diff --git a/src/com/android/settings/search/SearchIndexableResourcesImpl.java b/src/com/android/settings/search/SearchIndexableResourcesImpl.java
index 034cbd0..75f64d3 100644
--- a/src/com/android/settings/search/SearchIndexableResourcesImpl.java
+++ b/src/com/android/settings/search/SearchIndexableResourcesImpl.java
@@ -62,7 +62,6 @@
 import com.android.settings.inputmethod.PhysicalKeyboardFragment;
 import com.android.settings.inputmethod.VirtualKeyboardFragment;
 import com.android.settings.language.LanguageAndInputSettings;
-import com.android.settings.location.LocationMode;
 import com.android.settings.location.LocationSettings;
 import com.android.settings.location.ScanningSettings;
 import com.android.settings.network.NetworkDashboardFragment;
@@ -132,7 +131,6 @@
         addIndex(GestureSettings.class);
         addIndex(LanguageAndInputSettings.class);
         addIndex(LocationSettings.class);
-        addIndex(LocationMode.class);
         addIndex(ScanningSettings.class);
         addIndex(SecuritySettingsV2.class);
         addIndex(ScreenLockSettings.class);
diff --git a/src/com/android/settings/slices/SettingsSliceProvider.java b/src/com/android/settings/slices/SettingsSliceProvider.java
index e068b2f..433bdf3 100644
--- a/src/com/android/settings/slices/SettingsSliceProvider.java
+++ b/src/com/android/settings/slices/SettingsSliceProvider.java
@@ -30,7 +30,6 @@
 import com.android.settings.R;
 import com.android.settingslib.utils.ThreadUtils;
 
-import java.util.HashMap;
 import java.util.Map;
 import java.util.WeakHashMap;
 
diff --git a/src/com/android/settings/slices/SliceBuilderUtils.java b/src/com/android/settings/slices/SliceBuilderUtils.java
index e9152ba..11ff1c1 100644
--- a/src/com/android/settings/slices/SliceBuilderUtils.java
+++ b/src/com/android/settings/slices/SliceBuilderUtils.java
@@ -23,6 +23,7 @@
 import android.content.Intent;
 import android.graphics.drawable.Icon;
 import android.text.TextUtils;
+import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.settings.R;
@@ -85,17 +86,46 @@
      */
     public static BasePreferenceController getPreferenceController(Context context,
             SliceData sliceData) {
-        // TODO check for context-only controller first.
+        try {
+            return getController(context, sliceData, true /* isContextOnly */);
+        } catch (IllegalStateException e) {
+            // Do nothing
+            Log.d(TAG, "Could not find Context-only controller for preference controller: "
+                    + sliceData.getKey());
+        }
+
+        return getController(context, sliceData, false /* isContextOnly */);
+    }
+
+    /**
+     * Attempts to build a {@link BasePreferenceController} from {@param SliceData}.
+     *
+     * @param sliceData     Backing data for the Slice.
+     * @param contextOnlyCtor {@code true} when the constructor for the
+     *                      {@link BasePreferenceController}
+     *                      only takes a {@link Context}. Else the constructor will be ({@link
+     *                      Context}, {@code String}.
+     */
+    private static BasePreferenceController getController(Context context, SliceData sliceData,
+            boolean contextOnlyCtor) {
         try {
             Class<?> clazz = Class.forName(sliceData.getPreferenceController());
-            Constructor<?> preferenceConstructor = clazz.getConstructor(Context.class,
-                    String.class);
-            return (BasePreferenceController) preferenceConstructor.newInstance(
-                    new Object[]{context, sliceData.getKey()});
+            Constructor<?> preferenceConstructor;
+            Object[] params;
+
+            if (contextOnlyCtor) {
+                preferenceConstructor = clazz.getConstructor(Context.class);
+                params = new Object[]{context};
+            } else {
+                preferenceConstructor = clazz.getConstructor(Context.class, String.class);
+                params = new Object[]{context, sliceData.getKey()};
+            }
+
+            return (BasePreferenceController) preferenceConstructor.newInstance(params);
         } catch (ClassNotFoundException | NoSuchMethodException | InstantiationException |
                 IllegalArgumentException | InvocationTargetException | IllegalAccessException e) {
             throw new IllegalStateException(
-                    "Invalid preference controller: " + sliceData.getPreferenceController());
+                    "Invalid preference controller: " + sliceData.getPreferenceController(), e);
         }
     }
 
diff --git a/src/com/android/settings/support/SupportDashboardActivity.java b/src/com/android/settings/support/SupportDashboardActivity.java
index 3b5d623..e829577 100644
--- a/src/com/android/settings/support/SupportDashboardActivity.java
+++ b/src/com/android/settings/support/SupportDashboardActivity.java
@@ -66,7 +66,7 @@
                     data.title = context.getString(R.string.page_tab_title_support);
                     data.screenTitle = context.getString(R.string.settings_label);
                     data.summaryOn = context.getString(R.string.support_summary);
-                    data.iconResId = R.drawable.ic_help;
+                    data.iconResId = R.drawable.ic_homepage_support;
                     data.intentTargetPackage = context.getPackageName();
                     data.intentTargetClass = SupportDashboardActivity.class.getName();
                     data.intentAction = Intent.ACTION_MAIN;
diff --git a/src/com/android/settings/wfd/WifiDisplaySettings.java b/src/com/android/settings/wfd/WifiDisplaySettings.java
index 7a9fc39..8f42389 100755
--- a/src/com/android/settings/wfd/WifiDisplaySettings.java
+++ b/src/com/android/settings/wfd/WifiDisplaySettings.java
@@ -22,6 +22,7 @@
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.PackageManager;
 import android.database.ContentObserver;
 import android.hardware.display.DisplayManager;
 import android.hardware.display.WifiDisplay;
@@ -218,13 +219,9 @@
     }
 
     public static boolean isAvailable(Context context) {
-        try {
-            return context.getSystemService(Context.DISPLAY_SERVICE) != null
-                    && context.getSystemService(Context.WIFI_P2P_SERVICE) != null;
-        } catch (Exception e) {
-            // Service is not registered, so this is definitely not available.
-            return false;
-        }
+        return context.getSystemService(Context.DISPLAY_SERVICE) != null
+                && context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT)
+                && context.getSystemService(Context.WIFI_P2P_SERVICE) != null;
     }
 
     private void scheduleUpdate(int changes) {
diff --git a/src/com/android/settings/widget/SettingsAppWidgetProvider.java b/src/com/android/settings/widget/SettingsAppWidgetProvider.java
index 5ccfc1b..adc386a 100644
--- a/src/com/android/settings/widget/SettingsAppWidgetProvider.java
+++ b/src/com/android/settings/widget/SettingsAppWidgetProvider.java
@@ -26,6 +26,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.database.ContentObserver;
+import android.hardware.display.DisplayManager;
 import android.location.LocationManager;
 import android.net.ConnectivityManager;
 import android.net.Uri;
@@ -736,7 +737,7 @@
                     R.drawable.appwidget_settings_ind_on_r_holo);
         } else {
             final int brightness = getBrightness(context);
-            final PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
+            final PowerManager pm = context.getSystemService(PowerManager.class);
             // Set the icon
             final int full = (int)(pm.getMaximumScreenBrightnessSetting()
                     * FULL_BRIGHTNESS_THRESHOLD);
@@ -872,53 +873,48 @@
      */
     private void toggleBrightness(Context context) {
         try {
-            IPowerManager power = IPowerManager.Stub.asInterface(
-                    ServiceManager.getService("power"));
-            if (power != null) {
-                PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
+            DisplayManager dm = context.getSystemService(DisplayManager.class);
+            PowerManager pm = context.getSystemService(PowerManager.class);
 
-                ContentResolver cr = context.getContentResolver();
-                int brightness = Settings.System.getInt(cr,
-                        Settings.System.SCREEN_BRIGHTNESS);
-                int brightnessMode = Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL;
-                //Only get brightness setting if available
-                if (context.getResources().getBoolean(
-                        com.android.internal.R.bool.config_automatic_brightness_available)) {
-                    brightnessMode = Settings.System.getInt(cr,
-                            Settings.System.SCREEN_BRIGHTNESS_MODE);
-                }
-
-                // Rotate AUTO -> MINIMUM -> DEFAULT -> MAXIMUM
-                // Technically, not a toggle...
-                if (brightnessMode == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC) {
-                    brightness = pm.getMinimumScreenBrightnessSetting();
-                    brightnessMode = Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL;
-                } else if (brightness < pm.getDefaultScreenBrightnessSetting()) {
-                    brightness = pm.getDefaultScreenBrightnessSetting();
-                } else if (brightness < pm.getMaximumScreenBrightnessSetting()) {
-                    brightness = pm.getMaximumScreenBrightnessSetting();
-                } else {
-                    brightnessMode = Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;
-                    brightness = pm.getMinimumScreenBrightnessSetting();
-                }
-
-                if (context.getResources().getBoolean(
-                        com.android.internal.R.bool.config_automatic_brightness_available)) {
-                    // Set screen brightness mode (automatic or manual)
-                    Settings.System.putInt(context.getContentResolver(),
-                            Settings.System.SCREEN_BRIGHTNESS_MODE,
-                            brightnessMode);
-                } else {
-                    // Make sure we set the brightness if automatic mode isn't available
-                    brightnessMode = Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL;
-                }
-                if (brightnessMode == Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL) {
-                    power.setTemporaryScreenBrightnessSettingOverride(brightness);
-                    Settings.System.putInt(cr, Settings.System.SCREEN_BRIGHTNESS, brightness);
-                }
+            ContentResolver cr = context.getContentResolver();
+            int brightness = Settings.System.getInt(cr,
+                    Settings.System.SCREEN_BRIGHTNESS);
+            int brightnessMode = Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL;
+            //Only get brightness setting if available
+            if (context.getResources().getBoolean(
+                    com.android.internal.R.bool.config_automatic_brightness_available)) {
+                brightnessMode = Settings.System.getInt(cr,
+                        Settings.System.SCREEN_BRIGHTNESS_MODE);
             }
-        } catch (RemoteException e) {
-            Log.d(TAG, "toggleBrightness: " + e);
+
+            // Rotate AUTO -> MINIMUM -> DEFAULT -> MAXIMUM
+            // Technically, not a toggle...
+            if (brightnessMode == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC) {
+                brightness = pm.getMinimumScreenBrightnessSetting();
+                brightnessMode = Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL;
+            } else if (brightness < pm.getDefaultScreenBrightnessSetting()) {
+                brightness = pm.getDefaultScreenBrightnessSetting();
+            } else if (brightness < pm.getMaximumScreenBrightnessSetting()) {
+                brightness = pm.getMaximumScreenBrightnessSetting();
+            } else {
+                brightnessMode = Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;
+                brightness = pm.getMinimumScreenBrightnessSetting();
+            }
+
+            if (context.getResources().getBoolean(
+                    com.android.internal.R.bool.config_automatic_brightness_available)) {
+                // Set screen brightness mode (automatic or manual)
+                Settings.System.putInt(context.getContentResolver(),
+                        Settings.System.SCREEN_BRIGHTNESS_MODE,
+                        brightnessMode);
+            } else {
+                // Make sure we set the brightness if automatic mode isn't available
+                brightnessMode = Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL;
+            }
+            if (brightnessMode == Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL) {
+                dm.setTemporaryBrightness(brightness);
+                Settings.System.putInt(cr, Settings.System.SCREEN_BRIGHTNESS, brightness);
+            }
         } catch (Settings.SettingNotFoundException e) {
             Log.d(TAG, "toggleBrightness: " + e);
         }
diff --git a/src/com/android/settings/widget/SwitchBar.java b/src/com/android/settings/widget/SwitchBar.java
index 749ec0a..3be5eca 100644
--- a/src/com/android/settings/widget/SwitchBar.java
+++ b/src/com/android/settings/widget/SwitchBar.java
@@ -39,9 +39,9 @@
 import android.widget.TextView;
 
 import com.android.settings.R;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import java.util.ArrayList;
 import java.util.List;
diff --git a/src/com/android/settings/wifi/WifiEnabler.java b/src/com/android/settings/wifi/WifiEnabler.java
index 9c43142..c5e79b2 100644
--- a/src/com/android/settings/wifi/WifiEnabler.java
+++ b/src/com/android/settings/wifi/WifiEnabler.java
@@ -33,9 +33,9 @@
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.widget.SwitchWidgetController;
 import com.android.settings.wrapper.ConnectivityManagerWrapper;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.RestrictedLockUtils;
 import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
 import com.android.settingslib.WirelessUtils;
diff --git a/src/com/android/settings/wifi/WifiMasterSwitchPreferenceController.java b/src/com/android/settings/wifi/WifiMasterSwitchPreferenceController.java
index de1b030..8843d93 100644
--- a/src/com/android/settings/wifi/WifiMasterSwitchPreferenceController.java
+++ b/src/com/android/settings/wifi/WifiMasterSwitchPreferenceController.java
@@ -19,12 +19,12 @@
 import android.support.v7.preference.PreferenceScreen;
 
 import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.R;
 import com.android.settings.widget.SummaryUpdater;
 import com.android.settings.widget.MasterSwitchPreference;
 import com.android.settings.widget.MasterSwitchController;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnPause;
 import com.android.settingslib.core.lifecycle.events.OnResume;
diff --git a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
index 82ffc38..4d9ad27 100644
--- a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
+++ b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
@@ -54,7 +54,6 @@
 import com.android.settings.Utils;
 import com.android.settings.applications.LayoutPreference;
 import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.widget.ActionButtonPreference;
 import com.android.settings.widget.EntityHeaderController;
 import com.android.settings.wifi.WifiDetailPreference;
@@ -63,6 +62,7 @@
 import com.android.settings.wifi.WifiUtils;
 import com.android.settings.wrapper.ConnectivityManagerWrapper;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnPause;
diff --git a/src/com/android/settings/wifi/tether/WifiDeviceNameTextValidator.java b/src/com/android/settings/wifi/tether/WifiDeviceNameTextValidator.java
new file mode 100644
index 0000000..e766e32
--- /dev/null
+++ b/src/com/android/settings/wifi/tether/WifiDeviceNameTextValidator.java
@@ -0,0 +1,30 @@
+/*
+ * 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.wifi.tether;
+
+import com.android.settings.widget.ValidatedEditTextPreference;
+import com.android.settings.wifi.WifiUtils;
+
+/**
+ * Validates a text field for a valid Wi-Fi SSID name.
+ */
+public class WifiDeviceNameTextValidator implements ValidatedEditTextPreference.Validator {
+    @Override
+    public boolean isTextValid(String value) {
+        return !WifiUtils.isSSIDTooLong(value) && !WifiUtils.isSSIDTooShort(value);
+    }
+}
diff --git a/src/com/android/settings/wifi/tether/WifiTetherSSIDPreferenceController.java b/src/com/android/settings/wifi/tether/WifiTetherSSIDPreferenceController.java
index b563e53..d7cb441 100644
--- a/src/com/android/settings/wifi/tether/WifiTetherSSIDPreferenceController.java
+++ b/src/com/android/settings/wifi/tether/WifiTetherSSIDPreferenceController.java
@@ -35,10 +35,12 @@
     static final String DEFAULT_SSID = "AndroidAP";
 
     private String mSSID;
+    private WifiDeviceNameTextValidator mWifiDeviceNameTextValidator;
 
     public WifiTetherSSIDPreferenceController(Context context,
             OnTetherConfigUpdateListener listener) {
         super(context, listener);
+        mWifiDeviceNameTextValidator = new WifiDeviceNameTextValidator();
     }
 
     @Override
@@ -70,7 +72,7 @@
 
     @Override
     public boolean isTextValid(String value) {
-        return !WifiUtils.isSSIDTooLong(value) && !WifiUtils.isSSIDTooShort(value);
+        return mWifiDeviceNameTextValidator.isTextValid(value);
     }
 
     public String getSSID() {
diff --git a/tests/robotests/src/com/android/settings/MasterClearTest.java b/tests/robotests/src/com/android/settings/MasterClearTest.java
index 9bf3310..776025f 100644
--- a/tests/robotests/src/com/android/settings/MasterClearTest.java
+++ b/tests/robotests/src/com/android/settings/MasterClearTest.java
@@ -66,7 +66,8 @@
 )
 public class MasterClearTest {
     private static final String TEST_ACCOUNT_TYPE = "android.test.account.type";
-    private static final String TEST_CONFIRMATION_PACKAGE = "android.test.confirmation.pkg";
+    private static final String TEST_CONFIRMATION_PACKAGE = "android.test.conf.pkg";
+    private static final String TEST_CONFIRMATION_CLASS = "android.test.conf.pkg.ConfActivity";
     private static final String TEST_ACCOUNT_NAME = "test@example.com";
 
     @Mock
@@ -223,6 +224,7 @@
         when(mMasterClear.getActivity()).thenReturn(mMockActivity);
         when(mMockActivity.getString(R.string.account_type)).thenReturn(TEST_ACCOUNT_TYPE);
         when(mMockActivity.getString(R.string.account_confirmation_package)).thenReturn(TEST_CONFIRMATION_PACKAGE);
+        when(mMockActivity.getString(R.string.account_confirmation_class)).thenReturn(TEST_CONFIRMATION_CLASS);
 
         Account[] accounts = new Account[0];
         when(mMockActivity.getSystemService(Context.ACCOUNT_SERVICE)).thenReturn(mAccountManager);
@@ -235,6 +237,7 @@
         when(mMasterClear.getActivity()).thenReturn(mMockActivity);
         when(mMockActivity.getString(R.string.account_type)).thenReturn(TEST_ACCOUNT_TYPE);
         when(mMockActivity.getString(R.string.account_confirmation_package)).thenReturn(TEST_CONFIRMATION_PACKAGE);
+        when(mMockActivity.getString(R.string.account_confirmation_class)).thenReturn(TEST_CONFIRMATION_CLASS);
         Account[] accounts = new Account[] { new Account(TEST_ACCOUNT_NAME, TEST_ACCOUNT_TYPE) };
         when(mMockActivity.getSystemService(Context.ACCOUNT_SERVICE)).thenReturn(mAccountManager);
         when(mAccountManager.getAccountsByType(TEST_ACCOUNT_TYPE)).thenReturn(accounts);
@@ -250,6 +253,7 @@
         // Only try to show account confirmation if the appropriate resource overlays are available.
         when(mMockActivity.getString(R.string.account_type)).thenReturn(TEST_ACCOUNT_TYPE);
         when(mMockActivity.getString(R.string.account_confirmation_package)).thenReturn(TEST_CONFIRMATION_PACKAGE);
+        when(mMockActivity.getString(R.string.account_confirmation_class)).thenReturn(TEST_CONFIRMATION_CLASS);
         // Add accounts to trigger the search for a resolving intent.
         Account[] accounts = new Account[] { new Account(TEST_ACCOUNT_NAME, TEST_ACCOUNT_TYPE) };
         when(mMockActivity.getSystemService(Context.ACCOUNT_SERVICE)).thenReturn(mAccountManager);
@@ -265,7 +269,7 @@
         when(mPackageManager.resolveActivity(any(), eq(0))).thenReturn(resolveInfo);
 
         // Finally mock out the startActivityForResultCall
-        doNothing().when(mMockActivity).startActivityForResult(any(), eq(MasterClear.CREDENTIAL_CONFIRM_REQUEST));
+        doNothing().when(mMasterClear).startActivityForResult(any(), eq(MasterClear.CREDENTIAL_CONFIRM_REQUEST));
 
         assertThat(mMasterClear.tryShowAccountConfirmation()).isTrue();
     }
diff --git a/tests/robotests/src/com/android/settings/SettingsDialogFragmentTest.java b/tests/robotests/src/com/android/settings/SettingsDialogFragmentTest.java
index 942634a..3a7d094 100644
--- a/tests/robotests/src/com/android/settings/SettingsDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/SettingsDialogFragmentTest.java
@@ -17,6 +17,7 @@
 
 import android.app.Dialog;
 import android.app.Fragment;
+import android.content.Context;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -39,6 +40,8 @@
     private static final int DIALOG_ID = 15;
 
     @Mock
+    private Context mContext;
+    @Mock
     private DialogCreatableFragment mDialogCreatable;
     private SettingsPreferenceFragment.SettingsDialogFragment mDialogFragment;
 
@@ -53,9 +56,10 @@
 
         mDialogFragment =
                 new SettingsPreferenceFragment.SettingsDialogFragment(mDialogCreatable, DIALOG_ID);
+        mDialogFragment.onAttach(mContext);
         mDialogFragment.getMetricsCategory();
 
-        // getDialogMetricsCategory called in constructor, and explicitly in test.
+        // getDialogMetricsCategory called in onAttach, and explicitly in test.
         verify(mDialogCreatable, times(2)).getDialogMetricsCategory(DIALOG_ID);
     }
 
@@ -66,6 +70,7 @@
         try {
             mDialogFragment = new SettingsPreferenceFragment.SettingsDialogFragment(
                     mDialogCreatable, DIALOG_ID);
+            mDialogFragment.onAttach(mContext);
         } catch (IllegalStateException e) {
             // getDialogMetricsCategory called in constructor
             verify(mDialogCreatable).getDialogMetricsCategory(DIALOG_ID);
diff --git a/tests/robotests/src/com/android/settings/applications/RecentAppsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/RecentAppsPreferenceControllerTest.java
index bd57211..ed97fe7 100644
--- a/tests/robotests/src/com/android/settings/applications/RecentAppsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/RecentAppsPreferenceControllerTest.java
@@ -248,6 +248,33 @@
     }
 
     @Test
+    public void display_showRecentsWithNullAppEntryOrInfo() {
+        final List<UsageStats> stats = new ArrayList<>();
+        final UsageStats stat1 = new UsageStats();
+        final UsageStats stat2 = new UsageStats();
+        stat1.mLastTimeUsed = System.currentTimeMillis();
+        stat1.mPackageName = "pkg.class";
+        stats.add(stat1);
+
+        stat2.mLastTimeUsed = System.currentTimeMillis();
+        stat2.mPackageName = "pkg.class2";
+        stats.add(stat2);
+
+        // app1 has AppEntry with null info, app2 has null AppEntry.
+        mAppEntry.info = null;
+        when(mAppState.getEntry(stat1.mPackageName, UserHandle.myUserId()))
+                .thenReturn(mAppEntry);
+        when(mAppState.getEntry(stat2.mPackageName, UserHandle.myUserId()))
+                .thenReturn(null);
+
+        when(mUsageStatsManager.queryUsageStats(anyInt(), anyLong(), anyLong()))
+                .thenReturn(stats);
+
+        // We should not crash here.
+        mController.displayPreference(mScreen);
+    }
+
+    @Test
     public void display_hasRecentButNoneDisplayable_showAppInfo() {
         final List<UsageStats> stats = new ArrayList<>();
         final UsageStats stat1 = new UsageStats();
diff --git a/tests/robotests/src/com/android/settings/applications/instantapps/InstantAppButtonsControllerTest.java b/tests/robotests/src/com/android/settings/applications/instantapps/InstantAppButtonsControllerTest.java
index 5c0badc..f85d43a 100644
--- a/tests/robotests/src/com/android/settings/applications/instantapps/InstantAppButtonsControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/instantapps/InstantAppButtonsControllerTest.java
@@ -42,9 +42,9 @@
 
 import com.android.settings.R;
 import com.android.settings.TestConfig;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.wrapper.PackageManagerWrapper;
 
 import org.junit.Before;
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDevicePreferenceTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDevicePreferenceTest.java
index e9d37f6..71020be 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDevicePreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDevicePreferenceTest.java
@@ -32,11 +32,11 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
 import com.android.settings.TestConfig;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.SettingsShadowResources;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothEnablerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothEnablerTest.java
index b973edb..828b5a1 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothEnablerTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothEnablerTest.java
@@ -29,13 +29,13 @@
 import com.android.settings.R;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.testutils.shadow.SettingsShadowResources;
 import com.android.settings.widget.MasterSwitchController;
 import com.android.settings.widget.MasterSwitchPreference;
 import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
 import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import org.junit.Before;
 import org.junit.BeforeClass;
diff --git a/tests/robotests/src/com/android/settings/bluetooth/UtilsTest.java b/tests/robotests/src/com/android/settings/bluetooth/UtilsTest.java
index 8666ce3..c3b22b3 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/UtilsTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/UtilsTest.java
@@ -26,11 +26,11 @@
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.TestConfig;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.SettingsShadowResources;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/BluetoothOnWhileDrivingPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/BluetoothOnWhileDrivingPreferenceControllerTest.java
new file mode 100644
index 0000000..3e60ca6
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/connecteddevice/BluetoothOnWhileDrivingPreferenceControllerTest.java
@@ -0,0 +1,83 @@
+/*
+ * 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.util.FeatureFlagUtils;
+
+import com.android.settings.TestConfig;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.core.FeatureFlags;
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.SettingsShadowSystemProperties;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION, shadows =
+        SettingsShadowSystemProperties.class)
+public class BluetoothOnWhileDrivingPreferenceControllerTest {
+    private BluetoothOnWhileDrivingPreferenceController mController;
+    private Context mContext;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = RuntimeEnvironment.application;
+        mController = new BluetoothOnWhileDrivingPreferenceController(mContext);
+    }
+
+    @After
+    public void teardown() {
+        SettingsShadowSystemProperties.clear();
+    }
+
+    @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.DISABLED_UNSUPPORTED);
+    }
+
+    @Test
+    public void setChecked_togglesSettingSecure() {
+        mController.setChecked(true);
+
+        assertThat(
+                Settings.Secure.getInt(
+                        mContext.getContentResolver(),
+                        Settings.Secure.BLUETOOTH_ON_WHILE_DRIVING,
+                        0))
+                .isEqualTo(1);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/core/InstrumentedActivityTest.java b/tests/robotests/src/com/android/settings/core/InstrumentedActivityTest.java
new file mode 100644
index 0000000..ecd756a
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/core/InstrumentedActivityTest.java
@@ -0,0 +1,49 @@
+/*
+ * 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.core;
+
+import android.content.res.Resources;
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.Robolectric;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class InstrumentedActivityTest {
+
+    /**
+     * Verifies that the {@link InstrumentedActivity} class can be instantiated successfully.
+     * Code added to the activity constructor had resulted in an NPE if resources are accessed
+     * before onCreate().
+     */
+    @Test
+    public void canInstantiate() {
+        Robolectric.buildActivity(InstrumentedActivityTestable.class).setup().get();
+    }
+
+    public static class InstrumentedActivityTestable extends InstrumentedActivity {
+
+        @Override
+        public int getMetricsCategory() {
+            return 0;
+        }
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/core/XmlControllerAttributeTest.java b/tests/robotests/src/com/android/settings/core/XmlControllerAttributeTest.java
index 8ded9d6..e6ca59b 100644
--- a/tests/robotests/src/com/android/settings/core/XmlControllerAttributeTest.java
+++ b/tests/robotests/src/com/android/settings/core/XmlControllerAttributeTest.java
@@ -80,11 +80,6 @@
     private static final String BAD_CLASSNAME_ERROR =
             "The following controllers set in the XML did not have valid class names:\n";
 
-    private static final String BAD_CONSTRUCTOR_ERROR =
-            "The constructor provided by the following classes were insufficient to instantiate "
-                    + "the object. It could be due to being an interface, abstract, or an "
-                    + "IllegalAccessException. Please fix the following classes:\n";
-
     Context mContext;
     SearchFeatureProvider mSearchProvider;
     private FakeFeatureFactory mFakeFeatureFactory;
@@ -112,7 +107,6 @@
         Set<String> invalidConstructors = new HashSet<>();
         Set<String> invalidClassHierarchy = new HashSet<>();
         Set<String> badClassNameControllers = new HashSet<>();
-        Set<String> badConstructorControllers = new HashSet<>();
 
         for (int resId : xmlSet) {
             xmlControllers.addAll(getXmlControllers(resId));
@@ -133,13 +127,7 @@
                 continue;
             }
 
-            Object controller = getObjectFromConstructor(constructor);
-            if (controller == null) {
-                badConstructorControllers.add(controllerClassName);
-                continue;
-            }
-
-            if (!(controller instanceof BasePreferenceController)) {
+            if (!isBasePreferenceController(clazz)) {
                 invalidClassHierarchy.add(controllerClassName);
             }
         }
@@ -150,13 +138,10 @@
                 invalidClassHierarchy);
         final String badClassNameError = buildErrorMessage(BAD_CLASSNAME_ERROR,
                 badClassNameControllers);
-        final String badConstructorError = buildErrorMessage(BAD_CONSTRUCTOR_ERROR,
-                badConstructorControllers);
 
         assertWithMessage(invalidConstructorError).that(invalidConstructors).isEmpty();
         assertWithMessage(invalidClassHierarchyError).that(invalidClassHierarchy).isEmpty();
         assertWithMessage(badClassNameError).that(badClassNameControllers).isEmpty();
-        assertWithMessage(badConstructorError).that(badConstructorControllers).isEmpty();
     }
 
     private Set<Integer> getIndexableXml() {
@@ -260,25 +245,16 @@
         return constructor;
     }
 
-    private Object getObjectFromConstructor(Constructor<?> constructor) {
-        Object controller = null;
-
-        try {
-            controller = constructor.newInstance(mContext);
-        } catch (InstantiationException | IllegalAccessException | InvocationTargetException |
-                IllegalArgumentException e) {
+    /**
+     * Make sure that {@link BasePreferenceController} is in the class hierarchy.
+     */
+    private boolean isBasePreferenceController(Class<?> clazz) {
+        while (clazz != null) {
+            clazz = clazz.getSuperclass();
+            if (BasePreferenceController.class.equals(clazz)) {
+                return true;
+            }
         }
-
-        if (controller != null) {
-            return controller;
-        }
-
-        try {
-            controller = constructor.newInstance(mContext, "key");
-        } catch (InstantiationException | IllegalAccessException | InvocationTargetException |
-                IllegalArgumentException e) {
-        }
-
-        return controller;
+        return false;
     }
-}
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/core/instrumentation/InstrumentableFragmentCodeInspector.java b/tests/robotests/src/com/android/settings/core/instrumentation/InstrumentableFragmentCodeInspector.java
index 4455549..867b5df 100644
--- a/tests/robotests/src/com/android/settings/core/instrumentation/InstrumentableFragmentCodeInspector.java
+++ b/tests/robotests/src/com/android/settings/core/instrumentation/InstrumentableFragmentCodeInspector.java
@@ -20,6 +20,7 @@
 import android.util.ArraySet;
 
 import com.android.settings.core.codeinspection.CodeInspector;
+import com.android.settingslib.core.instrumentation.Instrumentable;
 
 import java.util.ArrayList;
 import java.util.List;
diff --git a/tests/robotests/src/com/android/settings/core/instrumentation/InstrumentedDialogFragmentTest.java b/tests/robotests/src/com/android/settings/core/instrumentation/InstrumentedDialogFragmentTest.java
index 9e37896..8ad2d69 100644
--- a/tests/robotests/src/com/android/settings/core/instrumentation/InstrumentedDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/core/instrumentation/InstrumentedDialogFragmentTest.java
@@ -21,6 +21,7 @@
 
 import com.android.settings.TestConfig;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
diff --git a/tests/robotests/src/com/android/settings/core/instrumentation/MetricsFeatureProviderTest.java b/tests/robotests/src/com/android/settings/core/instrumentation/MetricsFeatureProviderTest.java
index da48f15..2950c07 100644
--- a/tests/robotests/src/com/android/settings/core/instrumentation/MetricsFeatureProviderTest.java
+++ b/tests/robotests/src/com/android/settings/core/instrumentation/MetricsFeatureProviderTest.java
@@ -31,6 +31,9 @@
 import com.android.settings.TestConfig;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.core.instrumentation.LogWriter;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
+import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -58,7 +61,6 @@
     @Mock private VisibilityLoggerMixin mockVisibilityLogger;
 
     private Context mContext;
-    private MetricsFeatureProvider mProvider;
 
     @Captor
     private ArgumentCaptor<Pair> mPairCaptor;
@@ -67,12 +69,6 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mContext = RuntimeEnvironment.application;
-        mProvider = new MetricsFeatureProvider();
-        List<LogWriter> writers = new ArrayList<>();
-        writers.add(mockLogWriter);
-        ReflectionHelpers.setField(mProvider, "mLoggerWriters", writers);
-
-        when(mockVisibilityLogger.elapsedTimeSinceVisible()).thenReturn(ELAPSED_TIME);
     }
 
     @Test
@@ -84,60 +80,4 @@
 
         assertThat(feature1 == feature2).isTrue();
     }
-
-    @Test
-    public void logDashboardStartIntent_intentEmpty_shouldNotLog() {
-        mProvider.logDashboardStartIntent(mContext, null /* intent */,
-                MetricsEvent.SETTINGS_GESTURES);
-
-        verifyNoMoreInteractions(mockLogWriter);
-    }
-
-    @Test
-    public void logDashboardStartIntent_intentHasNoComponent_shouldLog() {
-        final Intent intent = new Intent(Intent.ACTION_ASSIST);
-
-        mProvider.logDashboardStartIntent(mContext, intent, MetricsEvent.SETTINGS_GESTURES);
-
-        verify(mockLogWriter).action(
-                eq(mContext),
-                eq(MetricsEvent.ACTION_SETTINGS_TILE_CLICK),
-                anyString(),
-                eq(Pair.create(MetricsEvent.FIELD_CONTEXT, MetricsEvent.SETTINGS_GESTURES)));
-    }
-
-    @Test
-    public void logDashboardStartIntent_intentIsExternal_shouldLog() {
-        final Intent intent = new Intent().setComponent(new ComponentName("pkg", "cls"));
-
-        mProvider.logDashboardStartIntent(mContext, intent, MetricsEvent.SETTINGS_GESTURES);
-
-        verify(mockLogWriter).action(
-                eq(mContext),
-                eq(MetricsEvent.ACTION_SETTINGS_TILE_CLICK),
-                anyString(),
-                eq(Pair.create(MetricsEvent.FIELD_CONTEXT, MetricsEvent.SETTINGS_GESTURES)));
-    }
-
-    @Test
-    public void action_BooleanLogsElapsedTime() {
-        mProvider.action(mockVisibilityLogger, CATEGORY, SUBTYPE_BOOLEAN);
-        verify(mockLogWriter).action(eq(CATEGORY), eq(SUBTYPE_BOOLEAN), mPairCaptor.capture());
-
-        Pair value = mPairCaptor.getValue();
-        assertThat(value.first instanceof Integer).isTrue();
-        assertThat((int) value.first).isEqualTo(MetricsEvent.NOTIFICATION_SINCE_VISIBLE_MILLIS);
-        assertThat(value.second).isEqualTo(ELAPSED_TIME);
-    }
-
-    @Test
-    public void action_IntegerLogsElapsedTime() {
-        mProvider.action(mockVisibilityLogger, CATEGORY, SUBTYPE_INTEGER);
-        verify(mockLogWriter).action(eq(CATEGORY), eq(SUBTYPE_INTEGER), mPairCaptor.capture());
-
-        Pair value = mPairCaptor.getValue();
-        assertThat(value.first instanceof Integer).isTrue();
-        assertThat((int) value.first).isEqualTo(MetricsEvent.NOTIFICATION_SINCE_VISIBLE_MILLIS);
-        assertThat(value.second).isEqualTo(ELAPSED_TIME);
-    }
 }
diff --git a/tests/robotests/src/com/android/settings/core/instrumentation/SharedPreferenceLoggerTest.java b/tests/robotests/src/com/android/settings/core/instrumentation/SharedPreferenceLoggerTest.java
deleted file mode 100644
index c80e3a8..0000000
--- a/tests/robotests/src/com/android/settings/core/instrumentation/SharedPreferenceLoggerTest.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.settings.core.instrumentation;
-
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_SETTINGS_PREFERENCE_CHANGE;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_FLOAT_VALUE;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_NAME;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.util.Pair;
-
-import com.android.settings.TestConfig;
-import com.android.settings.testutils.FakeFeatureFactory;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
-
-import com.google.common.truth.Platform;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Answers;
-import org.mockito.ArgumentMatcher;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.annotation.Config;
-
-@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
-public class SharedPreferenceLoggerTest {
-
-    private static final String TEST_TAG = "tag";
-    private static final String TEST_KEY = "key";
-
-    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
-    private Context mContext;
-
-    private ArgumentMatcher<Pair<Integer, Object>> mNamePairMatcher;
-    private FakeFeatureFactory mFactory;
-    private MetricsFeatureProvider mMetricsFeature;
-    private SharedPreferencesLogger mSharedPrefLogger;
-
-    @Before
-    public void init() {
-        MockitoAnnotations.initMocks(this);
-        mFactory = FakeFeatureFactory.setupForTest();
-        mMetricsFeature = mFactory.metricsFeatureProvider;
-
-        mSharedPrefLogger = new SharedPreferencesLogger(mContext, TEST_TAG);
-        mNamePairMatcher = pairMatches(FIELD_SETTINGS_PREFERENCE_CHANGE_NAME, String.class);
-    }
-
-    @Test
-    public void putInt_shouldNotLogInitialPut() {
-        final SharedPreferences.Editor editor = mSharedPrefLogger.edit();
-        editor.putInt(TEST_KEY, 1);
-        editor.putInt(TEST_KEY, 1);
-        editor.putInt(TEST_KEY, 1);
-        editor.putInt(TEST_KEY, 2);
-        editor.putInt(TEST_KEY, 2);
-        editor.putInt(TEST_KEY, 2);
-        editor.putInt(TEST_KEY, 2);
-
-        verify(mMetricsFeature, times(6)).action(any(Context.class), anyInt(),
-                argThat(mNamePairMatcher),
-                argThat(pairMatches(FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE, Integer.class)));
-    }
-
-    @Test
-    public void putBoolean_shouldNotLogInitialPut() {
-        final SharedPreferences.Editor editor = mSharedPrefLogger.edit();
-        editor.putBoolean(TEST_KEY, true);
-        editor.putBoolean(TEST_KEY, true);
-        editor.putBoolean(TEST_KEY, false);
-        editor.putBoolean(TEST_KEY, false);
-        editor.putBoolean(TEST_KEY, false);
-
-
-        verify(mMetricsFeature).action(any(Context.class), anyInt(),
-                argThat(mNamePairMatcher),
-                argThat(pairMatches(FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE, true)));
-        verify(mMetricsFeature, times(3)).action(any(Context.class), anyInt(),
-                argThat(mNamePairMatcher),
-                argThat(pairMatches(FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE, false)));
-    }
-
-    @Test
-    public void putLong_shouldNotLogInitialPut() {
-        final SharedPreferences.Editor editor = mSharedPrefLogger.edit();
-        editor.putLong(TEST_KEY, 1);
-        editor.putLong(TEST_KEY, 1);
-        editor.putLong(TEST_KEY, 1);
-        editor.putLong(TEST_KEY, 1);
-        editor.putLong(TEST_KEY, 2);
-
-        verify(mMetricsFeature, times(4)).action(any(Context.class), anyInt(),
-                argThat(mNamePairMatcher),
-                argThat(pairMatches(FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE, Integer.class)));
-    }
-
-    @Test
-    public void putLong_biggerThanIntMax_shouldLogIntMax() {
-        final SharedPreferences.Editor editor = mSharedPrefLogger.edit();
-        final long veryBigNumber = 500L + Integer.MAX_VALUE;
-        editor.putLong(TEST_KEY, 1);
-        editor.putLong(TEST_KEY, veryBigNumber);
-
-        verify(mMetricsFeature).action(any(Context.class), anyInt(),
-                argThat(mNamePairMatcher),
-                argThat(pairMatches(
-                        FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE, Integer.MAX_VALUE)));
-    }
-
-    @Test
-    public void putLong_smallerThanIntMin_shouldLogIntMin() {
-        final SharedPreferences.Editor editor = mSharedPrefLogger.edit();
-        final long veryNegativeNumber = -500L + Integer.MIN_VALUE;
-        editor.putLong(TEST_KEY, 1);
-        editor.putLong(TEST_KEY, veryNegativeNumber);
-
-        verify(mMetricsFeature).action(any(Context.class), anyInt(),
-                argThat(mNamePairMatcher),
-                argThat(pairMatches(
-                        FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE, Integer.MIN_VALUE)));
-    }
-
-    @Test
-    public void putFloat_shouldNotLogInitialPut() {
-        final SharedPreferences.Editor editor = mSharedPrefLogger.edit();
-        editor.putFloat(TEST_KEY, 1);
-        editor.putFloat(TEST_KEY, 1);
-        editor.putFloat(TEST_KEY, 1);
-        editor.putFloat(TEST_KEY, 1);
-        editor.putFloat(TEST_KEY, 2);
-
-        verify(mMetricsFeature, times(4)).action(any(Context.class), anyInt(),
-                argThat(mNamePairMatcher),
-                argThat(pairMatches(FIELD_SETTINGS_PREFERENCE_CHANGE_FLOAT_VALUE, Float.class)));
-    }
-
-    @Test
-    public void logPackage_shouldUseLogPackageApi() {
-        mSharedPrefLogger.logPackageName("key", "com.android.settings");
-        verify(mMetricsFeature).action(any(Context.class),
-                eq(ACTION_SETTINGS_PREFERENCE_CHANGE),
-                eq("com.android.settings"),
-                any(Pair.class));
-    }
-
-    private ArgumentMatcher<Pair<Integer, Object>> pairMatches(int tag, Class clazz) {
-        return pair -> pair.first == tag && Platform.isInstanceOfType(pair.second, clazz);
-    }
-
-    private ArgumentMatcher<Pair<Integer, Object>> pairMatches(int tag, boolean bool) {
-        return pair -> pair.first == tag
-                && Platform.isInstanceOfType(pair.second, Integer.class)
-                && pair.second.equals((bool ? 1 : 0));
-    }
-
-    private ArgumentMatcher<Pair<Integer, Object>> pairMatches(int tag, int val) {
-        return pair -> pair.first == tag
-                && Platform.isInstanceOfType(pair.second, Integer.class)
-                && pair.second.equals(val);
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/core/instrumentation/VisibilityLoggerMixinTest.java b/tests/robotests/src/com/android/settings/core/instrumentation/VisibilityLoggerMixinTest.java
deleted file mode 100644
index 1a47a66..0000000
--- a/tests/robotests/src/com/android/settings/core/instrumentation/VisibilityLoggerMixinTest.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.settings.core.instrumentation;
-
-import static com.android.settings.core.instrumentation.Instrumentable.METRICS_CATEGORY_UNKNOWN;
-
-import static org.mockito.ArgumentMatchers.nullable;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.SettingsActivity;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settings.TestConfig;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.annotation.Config;
-
-
-@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
-public class VisibilityLoggerMixinTest {
-
-    @Mock
-    private MetricsFeatureProvider mMetricsFeature;
-
-    private VisibilityLoggerMixin mMixin;
-
-    @Before
-    public void init() {
-        MockitoAnnotations.initMocks(this);
-        mMixin = new VisibilityLoggerMixin(TestInstrumentable.TEST_METRIC, mMetricsFeature);
-    }
-
-    @Test
-    public void shouldLogVisibleOnResume() {
-        mMixin.onResume();
-
-        verify(mMetricsFeature, times(1))
-                .visible(nullable(Context.class), eq(MetricsProto.MetricsEvent.VIEW_UNKNOWN),
-                        eq(TestInstrumentable.TEST_METRIC));
-    }
-
-    @Test
-    public void shouldLogVisibleWithSource() {
-        final Intent sourceIntent = new Intent()
-                .putExtra(SettingsActivity.EXTRA_SOURCE_METRICS_CATEGORY,
-                        MetricsProto.MetricsEvent.SETTINGS_GESTURES);
-        final Activity activity = mock(Activity.class);
-        when(activity.getIntent()).thenReturn(sourceIntent);
-        mMixin.setSourceMetricsCategory(activity);
-        mMixin.onResume();
-
-        verify(mMetricsFeature, times(1))
-                .visible(nullable(Context.class), eq(MetricsProto.MetricsEvent.SETTINGS_GESTURES),
-                        eq(TestInstrumentable.TEST_METRIC));
-    }
-
-    @Test
-    public void shouldLogHideOnPause() {
-        mMixin.onPause();
-
-        verify(mMetricsFeature, times(1))
-                .hidden(nullable(Context.class), eq(TestInstrumentable.TEST_METRIC));
-    }
-
-    @Test
-    public void shouldNotLogIfMetricsFeatureIsNull() {
-        mMixin = new VisibilityLoggerMixin(TestInstrumentable.TEST_METRIC);
-        mMixin.onResume();
-        mMixin.onPause();
-
-        verify(mMetricsFeature, never())
-                .hidden(nullable(Context.class), anyInt());
-    }
-
-    @Test
-    public void shouldNotLogIfMetricsCategoryIsUnknown() {
-        mMixin = new VisibilityLoggerMixin(METRICS_CATEGORY_UNKNOWN, mMetricsFeature);
-
-        mMixin.onResume();
-        mMixin.onPause();
-
-        verify(mMetricsFeature, never())
-                .hidden(nullable(Context.class), anyInt());
-    }
-
-    private final class TestInstrumentable implements Instrumentable {
-
-        public static final int TEST_METRIC = 12345;
-
-        @Override
-        public int getMetricsCategory() {
-            return TEST_METRIC;
-        }
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java
index 741f2bc..afa914c 100644
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java
@@ -51,6 +51,7 @@
 import com.android.settings.testutils.shadow.ShadowThreadUtils;
 import com.android.settings.testutils.shadow.ShadowTileUtils;
 import com.android.settings.testutils.shadow.ShadowUserManager;
+import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
 import com.android.settingslib.drawer.CategoryKey;
 import com.android.settingslib.drawer.CategoryManager;
 import com.android.settingslib.drawer.DashboardCategory;
@@ -372,7 +373,7 @@
         final Intent launchIntent = shadowActivity.getNextStartedActivityForResult().intent;
         assertThat(launchIntent.getAction())
                 .isEqualTo("TestAction");
-        assertThat(launchIntent.getIntExtra(SettingsActivity.EXTRA_SOURCE_METRICS_CATEGORY, 0))
+        assertThat(launchIntent.getIntExtra(VisibilityLoggerMixin.EXTRA_SOURCE_METRICS_CATEGORY, 0))
                 .isEqualTo(MetricsProto.MetricsEvent.SETTINGS_GESTURES);
     }
 
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java
index 6c663ab..40e590a 100644
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java
@@ -33,10 +33,10 @@
 
 import com.android.settings.TestConfig;
 import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settings.core.instrumentation.VisibilityLoggerMixin;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
 import com.android.settingslib.drawer.DashboardCategory;
 import com.android.settingslib.drawer.Tile;
 import com.android.settingslib.drawer.TileUtils;
diff --git a/tests/robotests/src/com/android/settings/dashboard/conditional/ConditionTest.java b/tests/robotests/src/com/android/settings/dashboard/conditional/ConditionTest.java
index d077e6f..1a3fa5e 100644
--- a/tests/robotests/src/com/android/settings/dashboard/conditional/ConditionTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/conditional/ConditionTest.java
@@ -22,7 +22,7 @@
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
diff --git a/tests/robotests/src/com/android/settings/datausage/DataUsageListTest.java b/tests/robotests/src/com/android/settings/datausage/DataUsageListTest.java
index 9ab88d3..8b3c770 100644
--- a/tests/robotests/src/com/android/settings/datausage/DataUsageListTest.java
+++ b/tests/robotests/src/com/android/settings/datausage/DataUsageListTest.java
@@ -60,6 +60,7 @@
 
     @Test
     public void resumePause_shouldListenUnlistenDataStateChange() {
+        mDataUsageList.onAttach(mContext);
         mDataUsageList.onResume();
 
         verify(mListener).setListener(true, 0, mContext);
diff --git a/tests/robotests/src/com/android/settings/datetime/ZonePickerTest.java b/tests/robotests/src/com/android/settings/datetime/ZonePickerTest.java
index 92807e9..9f6d0ef 100644
--- a/tests/robotests/src/com/android/settings/datetime/ZonePickerTest.java
+++ b/tests/robotests/src/com/android/settings/datetime/ZonePickerTest.java
@@ -28,8 +28,8 @@
 
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
-import com.android.settings.core.instrumentation.VisibilityLoggerMixin;
 import com.android.settings.testutils.shadow.ShadowZoneGetter;
+import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/tests/robotests/src/com/android/settings/deletionhelper/AutomaticStorageManagerSwitchBarControllerTest.java b/tests/robotests/src/com/android/settings/deletionhelper/AutomaticStorageManagerSwitchBarControllerTest.java
index 66ccc6e..ab32fa2 100644
--- a/tests/robotests/src/com/android/settings/deletionhelper/AutomaticStorageManagerSwitchBarControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deletionhelper/AutomaticStorageManagerSwitchBarControllerTest.java
@@ -31,11 +31,11 @@
 
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.TestConfig;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.SettingsShadowSystemProperties;
 import com.android.settings.widget.SwitchBar;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/tests/robotests/src/com/android/settings/development/AbstractBluetoothA2dpPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/AbstractBluetoothA2dpPreferenceControllerTest.java
index a7ae938..15df916 100644
--- a/tests/robotests/src/com/android/settings/development/AbstractBluetoothA2dpPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/AbstractBluetoothA2dpPreferenceControllerTest.java
@@ -74,8 +74,8 @@
         mLifecycle = new Lifecycle(mLifecycleOwner);
         mController = spy(new AbstractBluetoothA2dpPreferenceControllerImpl(mContext, mLifecycle,
                 mBluetoothA2dpConfigStore));
-        doReturn(mBluetoothCodecConfig).when(mController).getCodecConfig();
-        doNothing().when(mController).setCodecConfigPreference(any());
+        doReturn(mBluetoothCodecConfig).when(mController).getCodecConfig(null);
+        doNothing().when(mController).setCodecConfigPreference(any(), any());
         when(mBluetoothA2dpConfigStore.createCodecConfig()).thenReturn(mBluetoothCodecConfig);
         when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
         mController.displayPreference(mScreen);
@@ -87,7 +87,7 @@
 
         mController.onPreferenceChange(mPreference, "" /* new value */);
 
-        verify(mController).setCodecConfigPreference(any());
+        verify(mController).setCodecConfigPreference(any(), any());
     }
 
     @Test
@@ -96,7 +96,7 @@
 
         mController.onPreferenceChange(mPreference, "" /* new value */);
 
-        verify(mController, never()).setCodecConfigPreference(any());
+        verify(mController, never()).setCodecConfigPreference(any(), any());
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/DeviceNamePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/DeviceNamePreferenceControllerTest.java
new file mode 100644
index 0000000..4ff79ca
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/deviceinfo/DeviceNamePreferenceControllerTest.java
@@ -0,0 +1,132 @@
+/*
+ * 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;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiManager;
+import android.os.Build;
+import android.provider.Settings;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.widget.ValidatedEditTextPreference;
+import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class DeviceNamePreferenceControllerTest {
+    private static final String TESTING_STRING = "Testing";
+
+    @Mock
+    private LocalBluetoothAdapter mBluetoothAdapter;
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+    private LocalBluetoothManager mBluetoothManager;
+    @Mock
+    private WifiManager mWifiManager;
+    @Mock
+    private PreferenceScreen mScreen;
+    private ValidatedEditTextPreference mPreference;
+    private DeviceNamePreferenceController mController;
+    private Context mContext;
+
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        ShadowApplication shadowApplication = ShadowApplication.getInstance();
+        shadowApplication.setSystemService(Context.WIFI_SERVICE, mWifiManager);
+        mContext = shadowApplication.getApplicationContext();
+        mPreference = new ValidatedEditTextPreference(mContext);
+        when(mBluetoothManager.getBluetoothAdapter()).thenReturn(mBluetoothAdapter);
+        when(mScreen.findPreference(anyString())).thenReturn(mPreference);
+        final WifiConfiguration configuration = new WifiConfiguration();
+        configuration.SSID = "test-ap";
+        when(mWifiManager.getWifiApConfiguration()).thenReturn(configuration);
+
+        mController = new DeviceNamePreferenceController(mContext);
+        mController.setLocalBluetoothManager(mBluetoothManager);
+    }
+
+    @Test
+    public void constructor_defaultDeviceNameIsModelName() {
+        assertThat(mController.getSummary()).isEqualTo(Build.MODEL);
+    }
+
+    @Test
+    public void constructor_deviceNameLoadedIfSet() {
+        Settings.Global.putString(mContext.getContentResolver(), Settings.Global.DEVICE_NAME,
+                "Test");
+        mController = new DeviceNamePreferenceController(mContext);
+        mController.setLocalBluetoothManager(mBluetoothManager);
+        assertThat(mController.getSummary()).isEqualTo("Test");
+    }
+
+    @Test
+    public void isTextValid_nameUnder33CharactersIsValid() {
+        assertThat(mController.isTextValid("12345678901234567890123456789012")).isTrue();
+    }
+
+    @Test
+    public void isTextValid_nameTooLongIsInvalid() {
+        assertThat(mController.isTextValid("123456789012345678901234567890123")).isFalse();
+    }
+
+    @Test
+    public void setDeviceName_preferenceUpdatedWhenDeviceNameUpdated() {
+        mController.onPreferenceChange(mPreference, TESTING_STRING);
+
+        assertThat(mPreference.getSummary()).isEqualTo(TESTING_STRING);
+    }
+
+    @Test
+    public void setDeviceName_bluetoothNameUpdatedWhenDeviceNameUpdated() {
+        mController.onPreferenceChange(mPreference, TESTING_STRING);
+
+        verify(mBluetoothAdapter).setName(eq(TESTING_STRING));
+    }
+
+    @Test
+    public void setDeviceName_wifiTetherNameUpdatedWhenDeviceNameUpdated() {
+        mController.onPreferenceChange(mPreference, TESTING_STRING);
+
+        ArgumentCaptor<WifiConfiguration> captor = ArgumentCaptor.forClass(WifiConfiguration.class);
+        verify(mWifiManager).setWifiApConfiguration(captor.capture());
+        assertThat(captor.getValue().SSID).isEqualTo(TESTING_STRING);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceControllerTest.java
index 90ce395..9c56611 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceControllerTest.java
@@ -37,13 +37,13 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.os.RoSystemProperties;
 import com.android.settings.TestConfig;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.deletionhelper.ActivationWarningFragment;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.SettingsShadowSystemProperties;
 import com.android.settings.widget.MasterSwitchPreference;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import org.junit.After;
 import org.junit.Before;
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java
index 1a3139d..2da756f 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java
@@ -50,13 +50,13 @@
 import com.android.settings.SubSettings;
 import com.android.settings.TestConfig;
 import com.android.settings.applications.manageapplications.ManageApplications;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.deviceinfo.PrivateVolumeSettings;
 import com.android.settings.deviceinfo.StorageItemPreference;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.SettingsShadowResources;
 import com.android.settingslib.applications.StorageStatsSource;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.deviceinfo.StorageVolumeProvider;
 
 import org.junit.After;
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceControllerTest.java
index 6ad37ce..e251be0 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceControllerTest.java
@@ -38,10 +38,10 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
 import com.android.settings.TestConfig;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.SettingsShadowResources;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.deviceinfo.StorageVolumeProvider;
 
 import org.junit.After;
diff --git a/tests/robotests/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceControllerTest.java
index e1ce694..c003f17 100644
--- a/tests/robotests/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceControllerTest.java
@@ -32,11 +32,11 @@
 
 import com.android.internal.hardware.AmbientDisplayConfiguration;
 import com.android.settings.TestConfig;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.search.InlinePayload;
 import com.android.settings.search.InlineSwitchPayload;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.ShadowSecureSettings;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/tests/robotests/src/com/android/settings/fingerprint/FingerprintEnrollEnrollingTest.java b/tests/robotests/src/com/android/settings/fingerprint/FingerprintEnrollEnrollingTest.java
index c590fd3..5418ead 100644
--- a/tests/robotests/src/com/android/settings/fingerprint/FingerprintEnrollEnrollingTest.java
+++ b/tests/robotests/src/com/android/settings/fingerprint/FingerprintEnrollEnrollingTest.java
@@ -36,6 +36,7 @@
 import com.android.settings.R;
 import com.android.settings.TestConfig;
 import com.android.settings.password.ChooseLockSettingsHelper;
+import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.ShadowUtils;
 import com.android.settings.testutils.shadow.ShadowVibrator;
@@ -69,12 +70,15 @@
 
     private FingerprintEnrollEnrolling mActivity;
 
+    private FakeFeatureFactory mFactory;
+
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         ShadowUtils.setFingerprintManager(mFingerprintManager);
         ShadowVibrator.addToServiceMap();
 
+        mFactory = FakeFeatureFactory.setupForTest();
         mActivity = Robolectric.buildActivity(
                 FingerprintEnrollEnrolling.class,
                 new Intent()
diff --git a/tests/robotests/src/com/android/settings/fingerprint/FingerprintEnrollFindSensorTest.java b/tests/robotests/src/com/android/settings/fingerprint/FingerprintEnrollFindSensorTest.java
index d495b74..be53aa5 100644
--- a/tests/robotests/src/com/android/settings/fingerprint/FingerprintEnrollFindSensorTest.java
+++ b/tests/robotests/src/com/android/settings/fingerprint/FingerprintEnrollFindSensorTest.java
@@ -33,6 +33,7 @@
 import com.android.settings.R;
 import com.android.settings.TestConfig;
 import com.android.settings.password.ChooseLockSettingsHelper;
+import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.SettingsShadowResources;
 import com.android.settings.testutils.shadow.ShadowEventLogWriter;
@@ -69,10 +70,13 @@
 
     private FingerprintEnrollFindSensor mActivity;
 
+    private FakeFeatureFactory mFactory;
+
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         ShadowUtils.setFingerprintManager(mFingerprintManager);
+        mFactory = FakeFeatureFactory.setupForTest();
 
         mActivity = Robolectric.buildActivity(
                 FingerprintEnrollFindSensor.class,
diff --git a/tests/robotests/src/com/android/settings/fingerprint/FingerprintSuggestionActivityTest.java b/tests/robotests/src/com/android/settings/fingerprint/FingerprintSuggestionActivityTest.java
index 0254bcb..f52f437 100644
--- a/tests/robotests/src/com/android/settings/fingerprint/FingerprintSuggestionActivityTest.java
+++ b/tests/robotests/src/com/android/settings/fingerprint/FingerprintSuggestionActivityTest.java
@@ -30,6 +30,7 @@
 
 import com.android.settings.R;
 import com.android.settings.TestConfig;
+import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.ShadowEventLogWriter;
 import com.android.settings.testutils.shadow.ShadowLockPatternUtils;
@@ -63,9 +64,12 @@
 
     private ActivityController<FingerprintSuggestionActivity> mController;
 
+    private FakeFeatureFactory mFactory;
+
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
+        mFactory = FakeFeatureFactory.setupForTest();
 
         final Intent intent = new Intent();
         mController = Robolectric.buildActivity(FingerprintSuggestionActivity.class, intent);
diff --git a/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollFindSensorTest.java b/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollFindSensorTest.java
index c3899e9..c786608 100644
--- a/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollFindSensorTest.java
+++ b/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollFindSensorTest.java
@@ -27,6 +27,7 @@
 import com.android.settings.R;
 import com.android.settings.TestConfig;
 import com.android.settings.password.ChooseLockSettingsHelper;
+import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.SettingsShadowResources;
 import com.android.settings.testutils.shadow.ShadowEventLogWriter;
@@ -61,10 +62,13 @@
 
     private SetupFingerprintEnrollFindSensor mActivity;
 
+    private FakeFeatureFactory mFactory;
+
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         ShadowUtils.setFingerprintManager(mFingerprintManager);
+        mFactory = FakeFeatureFactory.setupForTest();
     }
 
     private void createActivity(Intent intent) {
diff --git a/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroductionTest.java b/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroductionTest.java
index 2d98bf4..f5b0c8a 100644
--- a/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroductionTest.java
+++ b/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroductionTest.java
@@ -35,6 +35,7 @@
 import com.android.settings.password.SetupChooseLockGeneric.SetupChooseLockGenericFragment;
 import com.android.settings.password.SetupSkipDialog;
 import com.android.settings.password.StorageManagerWrapper;
+import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.ShadowEventLogWriter;
 import com.android.settings.testutils.shadow.ShadowFingerprintManager;
@@ -72,6 +73,7 @@
 
     @Mock
     private UserInfo mUserInfo;
+    private FakeFeatureFactory mFactory;
 
     private ActivityController<SetupFingerprintEnrollIntroduction> mController;
 
@@ -83,6 +85,8 @@
                 .setSystemFeature(PackageManager.FEATURE_FINGERPRINT, true);
         ShadowFingerprintManager.addToServiceMap();
 
+        mFactory = FakeFeatureFactory.setupForTest();
+
         final Intent intent = new Intent();
         mController = Robolectric.buildActivity(SetupFingerprintEnrollIntroduction.class, intent);
 
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyUtilsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyUtilsTest.java
index 38391c9..3e33823 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyUtilsTest.java
@@ -24,7 +24,6 @@
 import android.util.Pair;
 
 import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.fuelgauge.anomaly.action.StopAndBackgroundCheckAction;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
@@ -32,6 +31,7 @@
 import com.android.settings.fuelgauge.anomaly.checker.WakeLockAnomalyDetector;
 import com.android.settings.testutils.shadow.ShadowKeyValueListParserWrapperImpl;
 import com.android.settings.fuelgauge.anomaly.checker.WakeupAlarmAnomalyDetector;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/tests/robotests/src/com/android/settings/localepicker/LocaleListEditorTest.java b/tests/robotests/src/com/android/settings/localepicker/LocaleListEditorTest.java
index 1ee52ca..737c16d 100644
--- a/tests/robotests/src/com/android/settings/localepicker/LocaleListEditorTest.java
+++ b/tests/robotests/src/com/android/settings/localepicker/LocaleListEditorTest.java
@@ -20,6 +20,7 @@
 import android.view.View;
 import android.widget.TextView;
 import com.android.settings.TestConfig;
+import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.ShadowSettingsPreferenceFragment;
 
@@ -27,6 +28,7 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
 import org.robolectric.util.ReflectionHelpers;
@@ -39,6 +41,11 @@
 
     private LocaleListEditor mLocaleListEditor;
 
+    @Mock
+    private Context mContext;
+
+    private FakeFeatureFactory mFactory;
+
     @Before
     public void setUp() {
         mLocaleListEditor = new LocaleListEditor();
@@ -48,11 +55,13 @@
                 RuntimeEnvironment.application.getSystemService(Context.RESTRICTIONS_SERVICE));
         ReflectionHelpers.setField(mLocaleListEditor, "mUserManager",
                 RuntimeEnvironment.application.getSystemService(Context.USER_SERVICE));
+        mFactory = FakeFeatureFactory.setupForTest();
     }
 
     @Test
     public void testDisallowConfigLocale_unrestrict() {
         ReflectionHelpers.setField(mLocaleListEditor, "mIsUiRestricted", true);
+        mLocaleListEditor.onAttach(mContext);
         mLocaleListEditor.onResume();
         Assert.assertEquals(View.GONE, mLocaleListEditor.getEmptyTextView().getVisibility());
     }
@@ -60,6 +69,7 @@
     @Test
     public void testDisallowConfigLocale_restrict() {
         ReflectionHelpers.setField(mLocaleListEditor, "mIsUiRestricted", false);
+        mLocaleListEditor.onAttach(mContext);
         mLocaleListEditor.onResume();
         Assert.assertEquals(View.VISIBLE, mLocaleListEditor.getEmptyTextView().getVisibility());
     }
diff --git a/tests/robotests/src/com/android/settings/location/LocationEnablerTest.java b/tests/robotests/src/com/android/settings/location/LocationEnablerTest.java
index 8cc92cd..1bae729 100644
--- a/tests/robotests/src/com/android/settings/location/LocationEnablerTest.java
+++ b/tests/robotests/src/com/android/settings/location/LocationEnablerTest.java
@@ -179,7 +179,7 @@
     }
 
     @Test
-    public void setLocationMode_notRestricted_shouldBroadcastUpdate() {
+    public void setLocationMode_notRestricted_shouldBroadcastUpdateAndSetChanger() {
         when(mUserManager.hasUserRestriction(anyString())).thenReturn(false);
         Settings.Secure.putInt(mContext.getContentResolver(),
                 Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_BATTERY_SAVING);
@@ -189,6 +189,9 @@
                 argThat(actionMatches(LocationManager.MODE_CHANGING_ACTION)),
                 eq(UserHandle.of(ActivityManager.getCurrentUser())),
                 eq(WRITE_SECURE_SETTINGS));
+        assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.LOCATION_CHANGER, Settings.Secure.LOCATION_CHANGER_UNKNOWN))
+                .isEqualTo(Settings.Secure.LOCATION_CHANGER_SYSTEM_SETTINGS);
     }
 
     @Test
@@ -202,7 +205,7 @@
     }
 
     @Test
-    public void setLocationEnabled_notRestricted_shouldBroadcastUpdate() {
+    public void setLocationEnabled_notRestricted_shouldBroadcastUpdateAndSetChanger() {
         when(mUserManager.hasUserRestriction(anyString())).thenReturn(false);
         Settings.Secure.putInt(mContext.getContentResolver(),
             Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF);
@@ -212,6 +215,9 @@
             argThat(actionMatches(LocationManager.MODE_CHANGING_ACTION)),
             eq(UserHandle.of(ActivityManager.getCurrentUser())),
             eq(WRITE_SECURE_SETTINGS));
+        assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.LOCATION_CHANGER, Settings.Secure.LOCATION_CHANGER_UNKNOWN))
+                .isEqualTo(Settings.Secure.LOCATION_CHANGER_SYSTEM_SETTINGS);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/location/LocationModeBatterySavingPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/LocationModeBatterySavingPreferenceControllerTest.java
deleted file mode 100644
index 41e9f1e..0000000
--- a/tests/robotests/src/com/android/settings/location/LocationModeBatterySavingPreferenceControllerTest.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2017 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.location;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.mock;
-
-import android.arch.lifecycle.LifecycleOwner;
-import android.content.Context;
-import android.provider.Settings;
-
-import com.android.settings.TestConfig;
-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.robolectric.annotation.Config;
-
-@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
-public class LocationModeBatterySavingPreferenceControllerTest {
-
-    private LifecycleOwner mLifecycleOwner;
-    private Lifecycle mLifecycle;
-
-    @Before
-    public void setUp() {
-        mLifecycleOwner = () -> mLifecycle;
-        mLifecycle = new Lifecycle(mLifecycleOwner);
-    }
-
-    @Test
-    public void getLocationMode_shouldReturnModeBatterySaving() {
-        final LocationModeBatterySavingPreferenceController controller =
-                new LocationModeBatterySavingPreferenceController(mock(Context.class), mLifecycle);
-
-        assertThat(controller.getLocationMode())
-                .isEqualTo(Settings.Secure.LOCATION_MODE_BATTERY_SAVING);
-    }
-
-}
diff --git a/tests/robotests/src/com/android/settings/location/LocationModeHighAccuracyPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/LocationModeHighAccuracyPreferenceControllerTest.java
deleted file mode 100644
index 9c8bac6..0000000
--- a/tests/robotests/src/com/android/settings/location/LocationModeHighAccuracyPreferenceControllerTest.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2017 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.location;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.mock;
-
-import android.arch.lifecycle.LifecycleOwner;
-import android.content.Context;
-import android.provider.Settings;
-
-import com.android.settings.TestConfig;
-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.robolectric.annotation.Config;
-
-@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
-public class LocationModeHighAccuracyPreferenceControllerTest {
-
-    private LifecycleOwner mLifecycleOwner;
-    private Lifecycle mLifecycle;
-
-    @Before
-    public void setUp() {
-        mLifecycleOwner = () -> mLifecycle;
-        mLifecycle = new Lifecycle(mLifecycleOwner);
-    }
-
-    @Test
-    public void getLocationMode_shouldReturnModeHighAccuracy() {
-        final LocationModeHighAccuracyPreferenceController controller =
-                new LocationModeHighAccuracyPreferenceController(mock(Context.class), mLifecycle);
-
-        assertThat(controller.getLocationMode())
-                .isEqualTo(Settings.Secure.LOCATION_MODE_HIGH_ACCURACY);
-    }
-
-}
diff --git a/tests/robotests/src/com/android/settings/location/LocationModePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/LocationModePreferenceControllerTest.java
deleted file mode 100644
index a28cb20..0000000
--- a/tests/robotests/src/com/android/settings/location/LocationModePreferenceControllerTest.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (C) 2017 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.location;
-
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.arch.lifecycle.LifecycleOwner;
-import android.content.Context;
-import android.os.UserManager;
-import android.provider.Settings;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceScreen;
-
-import com.android.settings.R;
-import com.android.settings.SettingsActivity;
-import com.android.settings.TestConfig;
-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;
-import org.robolectric.annotation.Config;
-
-@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
-public class LocationModePreferenceControllerTest {
-
-    @Mock
-    private LocationSettings mFragment;
-    @Mock
-    private SettingsActivity mActivity;
-    @Mock
-    private Preference mPreference;
-    @Mock
-    private PreferenceScreen mScreen;
-    @Mock
-    private UserManager mUserManager;
-
-    private Context mContext;
-    private LocationModePreferenceController mController;
-    private LifecycleOwner mLifecycleOwner;
-    private Lifecycle mLifecycle;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mContext = spy(RuntimeEnvironment.application);
-        when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
-        mLifecycleOwner = () -> mLifecycle;
-        mLifecycle = new Lifecycle(mLifecycleOwner);
-        mController = new LocationModePreferenceController(mContext, mFragment, mLifecycle);
-        when(mFragment.getActivity()).thenReturn(mActivity);
-        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
-    }
-
-    @Test
-    @Config(qualifiers = "mcc999")
-    public void locationModePreference_ifXmlSetToFalse_shouldNotBeAvailable() {
-        assertFalse(mController.isAvailable());
-    }
-
-    @Test
-    public void locationModePreference_ifXmlSetToTrue_shouldBeAvailable() {
-        assertTrue(mController.isAvailable());
-    }
-
-    @Test
-    public void onLocationModeChanged_locationOff_shouldDisablePreference() {
-        when(mUserManager.hasUserRestriction(any())).thenReturn(false);
-        mController.displayPreference(mScreen);
-
-        mController.onLocationModeChanged(Settings.Secure.LOCATION_MODE_OFF, false);
-
-        verify(mPreference).setEnabled(false);
-    }
-
-    @Test
-    public void onLocationModeChanged_restricted_shouldDisablePreference() {
-        when(mUserManager.hasUserRestriction(any())).thenReturn(true);
-        mController.displayPreference(mScreen);
-
-        mController.onLocationModeChanged(Settings.Secure.LOCATION_MODE_BATTERY_SAVING, false);
-
-        verify(mPreference).setEnabled(false);
-    }
-
-    @Test
-    public void onLocationModeChanged_locationOnNotRestricted_shouldEnablePreference() {
-        when(mUserManager.hasUserRestriction(any())).thenReturn(false);
-        mController.displayPreference(mScreen);
-
-        mController.onLocationModeChanged(Settings.Secure.LOCATION_MODE_BATTERY_SAVING, false);
-
-        verify(mPreference).setEnabled(true);
-    }
-
-    @Test
-    public void onLocationModeChanged_shouldUpdateSummary() {
-        mController.displayPreference(mScreen);
-
-        mController.onLocationModeChanged(Settings.Secure.LOCATION_MODE_BATTERY_SAVING, false);
-
-        verify(mPreference).setSummary(anyInt());
-    }
-
-    @Test
-    public void handlePreferenceTreeClick_shouldStartLocationModeFragment() {
-        final Preference preference = new Preference(mContext);
-        preference.setKey(mController.getPreferenceKey());
-
-        mController.handlePreferenceTreeClick(preference);
-
-        verify(mActivity).startPreferencePanel(any(), eq(LocationMode.class.getName()), any(),
-                eq(R.string.location_mode_screen_title), any(), any(), anyInt());
-    }
-
-}
diff --git a/tests/robotests/src/com/android/settings/location/LocationModeRadioButtonPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/LocationModeRadioButtonPreferenceControllerTest.java
deleted file mode 100644
index 2766788..0000000
--- a/tests/robotests/src/com/android/settings/location/LocationModeRadioButtonPreferenceControllerTest.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2017 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.location;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.arch.lifecycle.LifecycleOwner;
-import android.content.Context;
-import android.provider.Settings;
-import android.support.v7.preference.PreferenceScreen;
-import com.android.settings.TestConfig;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settings.testutils.shadow.ShadowSecureSettings;
-import com.android.settings.widget.RadioButtonPreference;
-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;
-import org.robolectric.annotation.Config;
-
-@RunWith(SettingsRobolectricTestRunner.class)
-@Config(
-        manifest = TestConfig.MANIFEST_PATH,
-        sdk = TestConfig.SDK_VERSION,
-        shadows = {ShadowSecureSettings.class})
-public class LocationModeRadioButtonPreferenceControllerTest {
-
-    @Mock
-    private RadioButtonPreference mPreference;
-    @Mock
-    private PreferenceScreen mScreen;
-
-    private Context mContext;
-    private LocationModeRadioButtonPreferenceController mController;
-    private LifecycleOwner mLifecycleOwner;
-    private Lifecycle mLifecycle;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mContext = RuntimeEnvironment.application;
-        mLifecycleOwner = () -> mLifecycle;
-        mLifecycle = new Lifecycle(mLifecycleOwner);
-        mController = new LocationModeRadioButtonPreferenceControllerTestable(mContext, mLifecycle);
-        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
-    }
-
-    @Test
-    public void displayPreference_shouldAddClickListener() {
-        mController.displayPreference(mScreen);
-
-        verify(mPreference).setOnClickListener(mController);
-    }
-
-    @Test
-    public void onRadioButtonClicked_shouldSetLocationModeToOwnMode() {
-        mController.displayPreference(mScreen);
-        Settings.Secure.putInt(mContext.getContentResolver(),
-                Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF);
-
-        mController.onRadioButtonClicked(mPreference);
-
-        assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
-                Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF))
-                .isEqualTo(mController.getLocationMode());
-    }
-
-    @Test
-    public void onLocationModeChanged_otherModeSelected_shouldUncheckPreference() {
-        mController.displayPreference(mScreen);
-
-        mController.onLocationModeChanged(Settings.Secure.LOCATION_MODE_BATTERY_SAVING, false);
-
-        verify(mPreference).setChecked(false);
-    }
-
-    @Test
-    public void onLocationModeChanged_ownModeSelected_shouldCheckPreference() {
-        mController.displayPreference(mScreen);
-
-        mController.onLocationModeChanged(mController.getLocationMode(), false);
-
-        verify(mPreference).setChecked(true);
-    }
-
-    @Test
-    public void onLocationModeChanged_locationOff_shouldDisablePreference() {
-        mController.displayPreference(mScreen);
-
-        mController.onLocationModeChanged(Settings.Secure.LOCATION_MODE_OFF, false);
-
-        verify(mPreference).setEnabled(false);
-    }
-
-    @Test
-    public void onLocationModeChanged_locationOn_shouldDisablePreference() {
-        mController.displayPreference(mScreen);
-
-        mController.onLocationModeChanged(Settings.Secure.LOCATION_MODE_BATTERY_SAVING, false);
-
-        verify(mPreference).setEnabled(true);
-    }
-
-    private class LocationModeRadioButtonPreferenceControllerTestable
-            extends LocationModeRadioButtonPreferenceController {
-
-        public LocationModeRadioButtonPreferenceControllerTestable(Context context,
-                Lifecycle lifecycle) {
-            super(context, lifecycle);
-        }
-
-        @Override
-        public String getPreferenceKey() {
-            return "test";
-        }
-
-        @Override
-        protected int getLocationMode() {
-            return Settings.Secure.LOCATION_MODE_HIGH_ACCURACY;
-        }
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/location/LocationModeSensorsOnlyPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/LocationModeSensorsOnlyPreferenceControllerTest.java
deleted file mode 100644
index 4ed75d2..0000000
--- a/tests/robotests/src/com/android/settings/location/LocationModeSensorsOnlyPreferenceControllerTest.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2017 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.location;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.mock;
-
-import android.arch.lifecycle.LifecycleOwner;
-import android.content.Context;
-import android.provider.Settings;
-
-import com.android.settings.TestConfig;
-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.robolectric.annotation.Config;
-
-@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
-public class LocationModeSensorsOnlyPreferenceControllerTest {
-
-    private LifecycleOwner mLifecycleOwner;
-    private Lifecycle mLifecycle;
-
-    @Before
-    public void setUp() {
-        mLifecycleOwner = () -> mLifecycle;
-        mLifecycle = new Lifecycle(mLifecycleOwner);
-    }
-
-    @Test
-    public void getLocationMode_shouldReturnModeSensorsOnly() {
-        final LocationModeSensorsOnlyPreferenceController controller =
-                new LocationModeSensorsOnlyPreferenceController(mock(Context.class), mLifecycle);
-
-        assertThat(controller.getLocationMode())
-                .isEqualTo(Settings.Secure.LOCATION_MODE_SENSORS_ONLY);
-    }
-
-}
diff --git a/tests/robotests/src/com/android/settings/location/LocationModeTest.java b/tests/robotests/src/com/android/settings/location/LocationModeTest.java
deleted file mode 100644
index 0e7a9d7..0000000
--- a/tests/robotests/src/com/android/settings/location/LocationModeTest.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2017 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.location;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.spy;
-
-import android.content.Context;
-import android.provider.SearchIndexableResource;
-
-import com.android.settings.TestConfig;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settings.testutils.XmlTestUtils;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
-public class LocationModeTest {
-
-    private Context mContext;
-    private LocationMode mFragment;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mContext = spy(RuntimeEnvironment.application);
-        mFragment = new LocationMode();
-    }
-
-    @Test
-    public void testSearchIndexProvider_shouldIndexResource() {
-        final List<SearchIndexableResource> indexRes =
-                mFragment.SEARCH_INDEX_DATA_PROVIDER.getXmlResourcesToIndex(mContext,
-                        true /* enabled */);
-
-        assertThat(indexRes).isNotNull();
-        assertThat(indexRes.get(0).xmlResId).isEqualTo(mFragment.getPreferenceScreenResId());
-    }
-
-    @Test
-    @Config(qualifiers = "mcc999")
-    public void testSearchIndexProvider_ifPageDisabled_shouldNotIndexResource() {
-        final List<String> niks = LocationMode.SEARCH_INDEX_DATA_PROVIDER
-                .getNonIndexableKeys(mContext);
-        final int xmlId = mFragment.getPreferenceScreenResId();
-
-        final List<String> keys = XmlTestUtils.getKeysFromPreferenceXml(mContext, xmlId);
-        assertThat(niks).containsAllIn(keys);
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/location/LocationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/LocationPreferenceControllerTest.java
index 2c92b44..e4aa075 100644
--- a/tests/robotests/src/com/android/settings/location/LocationPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/location/LocationPreferenceControllerTest.java
@@ -109,45 +109,30 @@
     }
 
     @Test
-    public void getLocationSummary_sensorsOnly_shouldSetSummarySensorsOnly() {
+    public void getLocationSummary_sensorsOnly_shouldSetSummaryOn() {
         Secure.putInt(mContext.getContentResolver(),
                 Secure.LOCATION_MODE, Secure.LOCATION_MODE_SENSORS_ONLY);
 
         assertThat(mController.getLocationSummary(mContext)).isEqualTo(
-                mContext.getString(R.string.location_on_summary,
-                        mContext.getString(R.string.location_mode_sensors_only_title)));
+                mContext.getString(R.string.location_on_summary));
     }
 
     @Test
-    public void getLocationSummary_highAccuracy_shouldSetSummarHighAccuracy() {
+    public void getLocationSummary_highAccuracy_shouldSetSummaryOn() {
         Secure.putInt(mContext.getContentResolver(),
                 Secure.LOCATION_MODE, Secure.LOCATION_MODE_HIGH_ACCURACY);
 
         assertThat(mController.getLocationSummary(mContext)).isEqualTo(
-                mContext.getString(R.string.location_on_summary,
-                        mContext.getString(R.string.location_mode_high_accuracy_title)));
+            mContext.getString(R.string.location_on_summary));
     }
 
     @Test
-    public void getLocationSummary_batterySaving_shouldSetSummaryBatterySaving() {
+    public void getLocationSummary_batterySaving_shouldSetSummaryOn() {
         Secure.putInt(mContext.getContentResolver(),
                 Secure.LOCATION_MODE, Secure.LOCATION_MODE_BATTERY_SAVING);
 
         assertThat(mController.getLocationSummary(mContext)).isEqualTo(
-                mContext.getString(R.string.location_on_summary,
-                        mContext.getString(R.string.location_mode_battery_saving_title)));
-    }
-
-    @Test
-    public void getLocationString_shouldCorrectString() {
-        assertThat(mController.getLocationString(Secure.LOCATION_MODE_OFF)).isEqualTo(
-                R.string.location_mode_location_off_title);
-        assertThat(mController.getLocationString(Secure.LOCATION_MODE_SENSORS_ONLY)).isEqualTo(
-                R.string.location_mode_sensors_only_title);
-        assertThat(mController.getLocationString(Secure.LOCATION_MODE_BATTERY_SAVING)).isEqualTo(
-                R.string.location_mode_battery_saving_title);
-        assertThat(mController.getLocationString(Secure.LOCATION_MODE_HIGH_ACCURACY)).isEqualTo(
-                R.string.location_mode_high_accuracy_title);
+            mContext.getString(R.string.location_on_summary));
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/notification/VisibilityPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/VisibilityPreferenceControllerTest.java
index c18372c..25dba80 100644
--- a/tests/robotests/src/com/android/settings/notification/VisibilityPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/VisibilityPreferenceControllerTest.java
@@ -47,6 +47,7 @@
 import android.support.v7.preference.PreferenceScreen;
 
 import com.android.internal.widget.LockPatternUtils;
+import com.android.settings.RestrictedListPreference;
 import com.android.settings.TestConfig;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.ShadowRestrictionUtils;
@@ -115,8 +116,8 @@
     @Test
     public void testNoCrashIfNoOnResume() throws Exception {
         mController.isAvailable();
-        mController.updateState(mock(RestrictedDropDownPreference.class));
-        mController.onPreferenceChange(mock(RestrictedDropDownPreference.class), true);
+        mController.updateState(mock(RestrictedListPreference.class));
+        mController.onPreferenceChange(mock(RestrictedListPreference.class), true);
     }
 
     @Test
@@ -165,7 +166,7 @@
         mController.onResume(new NotificationBackend.AppRow(), channel, null, mock(
                 RestrictedLockUtils.EnforcedAdmin.class));
 
-        RestrictedDropDownPreference pref = mock(RestrictedDropDownPreference.class);
+        RestrictedListPreference pref = mock(RestrictedListPreference.class);
         mController.updateState(pref);
 
         verify(pref, times(2)).addRestrictedItem(any());
@@ -187,7 +188,7 @@
         mController.onResume(new NotificationBackend.AppRow(), channel, null, mock(
                 RestrictedLockUtils.EnforcedAdmin.class));
 
-        RestrictedDropDownPreference pref = mock(RestrictedDropDownPreference.class);
+        RestrictedListPreference pref = mock(RestrictedListPreference.class);
         mController.updateState(pref);
 
         verify(pref, times(1)).addRestrictedItem(any());
@@ -202,7 +203,7 @@
         NotificationChannel channel = mock(NotificationChannel.class);
         mController.onResume(appRow, channel, null, null);
 
-        RestrictedDropDownPreference pref = mock(RestrictedDropDownPreference.class);
+        RestrictedListPreference pref = mock(RestrictedListPreference.class);
         mController.updateState(pref);
 
         ArgumentCaptor<CharSequence[]> argumentCaptor =
@@ -221,7 +222,7 @@
         NotificationChannel channel = mock(NotificationChannel.class);
         mController.onResume(appRow, channel, null, null);
 
-        RestrictedDropDownPreference pref = mock(RestrictedDropDownPreference.class);
+        RestrictedListPreference pref = mock(RestrictedListPreference.class);
         mController.updateState(pref);
 
         ArgumentCaptor<CharSequence[]> argumentCaptor =
@@ -237,7 +238,7 @@
         NotificationChannel channel = mock(NotificationChannel.class);
         mController.onResume(appRow, channel, null, null);
 
-        RestrictedDropDownPreference pref = mock(RestrictedDropDownPreference.class);
+        RestrictedListPreference pref = mock(RestrictedListPreference.class);
         mController.updateState(pref);
 
         ArgumentCaptor<CharSequence[]> argumentCaptor =
@@ -268,7 +269,7 @@
         when(channel.getLockscreenVisibility()).thenReturn(VISIBILITY_NO_OVERRIDE);
         mController.onResume(appRow, channel, null, null);
 
-        RestrictedDropDownPreference pref = mock(RestrictedDropDownPreference.class);
+        RestrictedListPreference pref = mock(RestrictedListPreference.class);
         mController.updateState(pref);
 
         ArgumentCaptor<String> argumentCaptor = ArgumentCaptor.forClass(String.class);
@@ -287,7 +288,7 @@
         when(channel.getLockscreenVisibility()).thenReturn(Notification.VISIBILITY_SECRET);
         mController.onResume(appRow, channel, null, null);
 
-        RestrictedDropDownPreference pref = mock(RestrictedDropDownPreference.class);
+        RestrictedListPreference pref = mock(RestrictedListPreference.class);
         mController.updateState(pref);
 
         ArgumentCaptor<String> argumentCaptor = ArgumentCaptor.forClass(String.class);
@@ -306,7 +307,7 @@
         channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
         mController.onResume(appRow, channel, null, null);
 
-        RestrictedDropDownPreference pref = mock(RestrictedDropDownPreference.class);
+        RestrictedListPreference pref = mock(RestrictedListPreference.class);
         mController.updateState(pref);
 
         mController.onPreferenceChange(pref, String.valueOf(Notification.VISIBILITY_PRIVATE));
@@ -325,7 +326,7 @@
         channel.setLockscreenVisibility(VISIBILITY_NO_OVERRIDE);
         mController.onResume(appRow, channel, null, null);
 
-        RestrictedDropDownPreference pref = mock(RestrictedDropDownPreference.class);
+        RestrictedListPreference pref = mock(RestrictedListPreference.class);
         mController.updateState(pref);
 
         mController.onPreferenceChange(pref, String.valueOf(Notification.VISIBILITY_SECRET));
diff --git a/tests/robotests/src/com/android/settings/slices/FakeContextOnlyPreferenceController.java b/tests/robotests/src/com/android/settings/slices/FakeContextOnlyPreferenceController.java
new file mode 100644
index 0000000..214607b
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/slices/FakeContextOnlyPreferenceController.java
@@ -0,0 +1,19 @@
+package com.android.settings.slices;
+
+import android.content.Context;
+
+import com.android.settings.core.BasePreferenceController;
+
+public class FakeContextOnlyPreferenceController extends BasePreferenceController {
+
+    public static final String KEY = "fakeController2";
+
+    public FakeContextOnlyPreferenceController(Context context) {
+        super(context, KEY);
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return AVAILABLE;
+    }
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java b/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java
index 10e4b76..0923571 100644
--- a/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java
@@ -50,8 +50,8 @@
     private final String FRAGMENT_NAME = "fragment name";
     private final int ICON = 1234; // I declare a thumb war
     private final Uri URI = Uri.parse("content://com.android.settings.slices/test");
-    private final String PREF_CONTROLLER = FakeToggleController.class.getName();
-    ;
+    private final Class PREF_CONTROLLER = FakeToggleController.class;
+    private final Class PREF_CONTROLLER2 = FakeContextOnlyPreferenceController.class;
 
     private Context mContext;
 
@@ -76,6 +76,14 @@
     }
 
     @Test
+    public void testGetPreferenceController_contextOnly_buildsMatchingController() {
+        BasePreferenceController controller = SliceBuilderUtils.getPreferenceController(mContext,
+                getDummyData(PREF_CONTROLLER2));
+
+        assertThat(controller).isInstanceOf(FakeContextOnlyPreferenceController.class);
+    }
+
+    @Test
     public void testDynamicSummary_returnsSliceSummary() {
         SliceData data = getDummyData();
         FakePreferenceController controller = new FakePreferenceController(mContext, KEY);
@@ -87,7 +95,7 @@
 
     @Test
     public void testDynamicSummary_returnsFragmentSummary() {
-        SliceData data = getDummyData(null);
+        SliceData data = getDummyData((String) null);
         FakePreferenceController controller = spy(new FakePreferenceController(mContext, KEY));
         String controllerSummary = "new_Summary";
         doReturn(controllerSummary).when(controller).getSummary();
@@ -99,7 +107,7 @@
 
     @Test
     public void testDynamicSummary_returnsSliceScreenTitle() {
-        SliceData data = getDummyData(null);
+        SliceData data = getDummyData((String) null);
         FakePreferenceController controller = new FakePreferenceController(mContext, KEY);
 
         String summary = SliceBuilderUtils.getSubtitleText(mContext, controller, data);
@@ -129,10 +137,18 @@
     }
 
     private SliceData getDummyData() {
-        return getDummyData(SUMMARY);
+        return getDummyData(PREF_CONTROLLER, SUMMARY);
     }
 
     private SliceData getDummyData(String summary) {
+        return getDummyData(PREF_CONTROLLER, summary);
+    }
+
+    private SliceData getDummyData(Class prefController) {
+        return getDummyData(prefController, SUMMARY);
+    }
+
+    private SliceData getDummyData(Class prefController, String summary) {
         return new SliceData.Builder()
                 .setKey(KEY)
                 .setTitle(TITLE)
@@ -141,7 +157,7 @@
                 .setIcon(ICON)
                 .setFragmentName(FRAGMENT_NAME)
                 .setUri(URI)
-                .setPreferenceControllerClassName(PREF_CONTROLLER)
+                .setPreferenceControllerClassName(prefController.getName())
                 .build();
     }
 }
diff --git a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
index ad51f79..ad72e6b 100644
--- a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
+++ b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
@@ -25,7 +25,6 @@
 import com.android.settings.applications.ApplicationFeatureProvider;
 import com.android.settings.bluetooth.BluetoothFeatureProvider;
 import com.android.settings.connecteddevice.SmsMirroringFeatureProvider;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.dashboard.DashboardFeatureProvider;
 import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
 import com.android.settings.datausage.DataPlanFeatureProvider;
@@ -40,6 +39,7 @@
 import com.android.settings.security.SecurityFeatureProvider;
 import com.android.settings.slices.SlicesFeatureProvider;
 import com.android.settings.users.UserFeatureProvider;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import org.mockito.Answers;
 
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowEventLogWriter.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowEventLogWriter.java
index dcced4e..9caf09f 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowEventLogWriter.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowEventLogWriter.java
@@ -19,7 +19,7 @@
 
 import android.content.Context;
 
-import com.android.settings.core.instrumentation.EventLogWriter;
+import com.android.settingslib.core.instrumentation.EventLogWriter;
 
 import org.robolectric.annotation.Implementation;
 import org.robolectric.annotation.Implements;
diff --git a/tests/robotests/src/com/android/settings/webview/WebViewAppPickerTest.java b/tests/robotests/src/com/android/settings/webview/WebViewAppPickerTest.java
index e44be0e..59a08ae 100644
--- a/tests/robotests/src/com/android/settings/webview/WebViewAppPickerTest.java
+++ b/tests/robotests/src/com/android/settings/webview/WebViewAppPickerTest.java
@@ -44,10 +44,10 @@
 
 import com.android.settings.TestConfig;
 import com.android.settings.applications.defaultapps.DefaultAppInfo;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.widget.RadioButtonPreference;
 import com.android.settings.wrapper.UserPackageWrapper;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.wrapper.PackageManagerWrapper;
 
 import org.junit.Before;
diff --git a/tests/robotests/src/com/android/settings/wfd/WifiDisplaySettingsTest.java b/tests/robotests/src/com/android/settings/wfd/WifiDisplaySettingsTest.java
index 1cf85fb..fc634d2 100644
--- a/tests/robotests/src/com/android/settings/wfd/WifiDisplaySettingsTest.java
+++ b/tests/robotests/src/com/android/settings/wfd/WifiDisplaySettingsTest.java
@@ -24,6 +24,7 @@
 
 import android.app.Activity;
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.hardware.display.DisplayManager;
 import android.media.MediaRouter;
 import android.net.wifi.p2p.WifiP2pManager;
@@ -50,6 +51,8 @@
     private SummaryLoader mSummaryLoader;
     @Mock
     private MediaRouter mMediaRouter;
+    @Mock
+    private PackageManager mPackageManager;
 
     private SummaryLoader.SummaryProvider mSummaryProvider;
 
@@ -58,6 +61,8 @@
         MockitoAnnotations.initMocks(this);
         when(mActivity.getSystemService(Context.MEDIA_ROUTER_SERVICE))
                 .thenReturn(mMediaRouter);
+        when(mActivity.getPackageManager()).thenReturn(mPackageManager);
+        when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT)).thenReturn(true);
 
         mSummaryProvider = WifiDisplaySettings.SUMMARY_PROVIDER_FACTORY.createSummaryProvider(
                 mActivity, mSummaryLoader);
@@ -86,15 +91,15 @@
     }
 
     @Test
-    public void isAvailable_noService_shouldReturnFalse() {
+    public void isAvailable_nullService_shouldReturnFalse() {
         assertThat(WifiDisplaySettings.isAvailable(mActivity))
                 .isFalse();
     }
 
     @Test
-    public void isAvailable_throwException_shouldReturnFalse() {
-        when(mActivity.getSystemService(Context.WIFI_P2P_SERVICE))
-                .thenThrow(new IllegalStateException());
+    public void isAvailable_noWifiDirectFeature_shouldReturnFalse() {
+        when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT))
+                .thenReturn(false);
 
         assertThat(WifiDisplaySettings.isAvailable(mActivity))
                 .isFalse();
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiEnablerTest.java b/tests/robotests/src/com/android/settings/wifi/WifiEnablerTest.java
index 63f89e6..84549a6 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiEnablerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiEnablerTest.java
@@ -22,9 +22,9 @@
 
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.widget.SwitchWidgetController;
 import com.android.settings.wrapper.ConnectivityManagerWrapper;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiMasterSwitchPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/WifiMasterSwitchPreferenceControllerTest.java
index 1708e36..82569c7 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiMasterSwitchPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiMasterSwitchPreferenceControllerTest.java
@@ -30,10 +30,10 @@
 import android.support.v7.preference.PreferenceScreen;
 
 import com.android.settings.TestConfig;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.widget.MasterSwitchPreference;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
index 4f77435..ca2cac0 100644
--- a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
@@ -65,7 +65,6 @@
 import com.android.settings.R;
 import com.android.settings.TestConfig;
 import com.android.settings.applications.LayoutPreference;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.ShadowBidiFormatter;
 import com.android.settings.testutils.shadow.ShadowDevicePolicyManagerWrapper;
@@ -76,6 +75,7 @@
 import com.android.settings.widget.EntityHeaderController;
 import com.android.settings.wifi.WifiDetailPreference;
 import com.android.settings.wrapper.ConnectivityManagerWrapper;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.wifi.AccessPoint;
 
diff --git a/tests/unit/src/com/android/settings/applications/AppOpsSettingsTest.java b/tests/unit/src/com/android/settings/applications/AppOpsSettingsTest.java
index d89d4a3..17a1889 100644
--- a/tests/unit/src/com/android/settings/applications/AppOpsSettingsTest.java
+++ b/tests/unit/src/com/android/settings/applications/AppOpsSettingsTest.java
@@ -15,6 +15,9 @@
  */
 package com.android.settings.applications;
 
+import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+
 import android.app.AppOpsManager;
 import android.content.Context;
 import android.content.Intent;
@@ -95,7 +98,9 @@
      * Creates an intent for showing the permission settings for all apps.
      */
     private Intent createManageAllAppsIntent() {
-        return new Intent(mActivityAction);
+        final Intent intent = new Intent(mActivityAction);
+        intent.addFlags(FLAG_ACTIVITY_CLEAR_TASK | FLAG_ACTIVITY_NEW_TASK);
+        return intent;
     }
 
     /**
diff --git a/tests/unit/src/com/android/settings/core/UniquePreferenceTest.java b/tests/unit/src/com/android/settings/core/UniquePreferenceTest.java
index 8fe2358..3daecce 100644
--- a/tests/unit/src/com/android/settings/core/UniquePreferenceTest.java
+++ b/tests/unit/src/com/android/settings/core/UniquePreferenceTest.java
@@ -74,7 +74,24 @@
             "toggle_bluetooth",
             "toggle_nfc",
             "android_beam_settings",
-            "sms_mirroring"
+            "sms_mirroring",
+            // Dup keys from About Phone v2 experiment.
+            "ims_reg_state",
+            "bt_address",
+            "device_model",
+            "firmware_version",
+            "regulatory_info",
+            "manual",
+            "legal_container",
+            "device_feedback",
+            "fcc_equipment_id",
+            "sim_status",
+            "build_number",
+            "phone_number",
+            "imei_info",
+            "wifi_ip_address",
+            "wifi_mac_address",
+            "safety_info"
     );
 
     private Context mContext;