Merge "Get rid of divider above ringtone selector" into pi-dev
diff --git a/res/layout/choose_lock_pattern_common.xml b/res/layout/choose_lock_pattern_common.xml
index c4a9381..77dd12d 100644
--- a/res/layout/choose_lock_pattern_common.xml
+++ b/res/layout/choose_lock_pattern_common.xml
@@ -50,6 +50,7 @@
             <TextView
                 android:id="@+id/suw_layout_title"
                 style="@style/SuwGlifHeaderTitle"
+                android:accessibilityLiveRegion="polite"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content" />
 
diff --git a/res/layout/radio_info.xml b/res/layout/radio_info.xml
index 502505c..0ec1f10 100644
--- a/res/layout/radio_info.xml
+++ b/res/layout/radio_info.xml
@@ -91,6 +91,30 @@
             <TextView android:id="@+id/roaming" style="@style/info_value" />
         </LinearLayout>
 
+        <!-- Link Bandwidth -->
+        <LinearLayout style="@style/entry_layout" android:orientation="horizontal">
+            <TextView android:text="@string/radio_info_dl_kbps" style="@style/info_label" />
+            <TextView android:id="@+id/dl_kbps" style="@style/info_value" />
+        </LinearLayout>
+
+        <!-- Link Bandwidth -->
+        <LinearLayout style="@style/entry_layout" android:orientation="horizontal">
+            <TextView android:text="@string/radio_info_ul_kbps" style="@style/info_label" />
+            <TextView android:id="@+id/ul_kbps" style="@style/info_value" />
+        </LinearLayout>
+
+        <!-- Physical Channel Config -->
+        <LinearLayout style="@style/entry_layout">
+            <TextView android:text="@string/radio_info_phy_chan_config" style="@style/info_label" />
+            <TextView android:id="@+id/phy_chan_config" style="@style/info_value" />
+        </LinearLayout>
+
+        <!-- Horizontal Rule -->
+        <View
+            android:layout_width="fill_parent"
+            android:layout_height="1dip"
+            android:background="#000000" />
+
         <!-- Preferred Network Type -->
         <TextView
                 android:layout_width="match_parent"
diff --git a/res/layout/storage_item.xml b/res/layout/storage_item.xml
index ba1c697..aa2b4f8 100644
--- a/res/layout/storage_item.xml
+++ b/res/layout/storage_item.xml
@@ -72,7 +72,7 @@
                 android:layout_height="wrap_content"
                 android:textAlignment="viewStart"
                 android:textAppearance="@android:style/TextAppearance.Material.Body1"
-                android:textColor="?android:attr/textColorSecondaryNoDisable"
+                android:textColor="?android:attr/textColorSecondary"
                 android:maxLines="10"
                 android:layout_alignParentEnd="true"/>
 
diff --git a/res/values/config.xml b/res/values/config.xml
index f8a7acc..e3ec74f 100755
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -131,7 +131,4 @@
     <!-- List of a11y components on the device allowed to be enabled by Settings Slices -->
     <string-array name="config_settings_slices_accessibility_components" translatable="false"/>
 
-    <!-- Whether or not swipe up gesture's opt-in setting is available on this device -->
-    <bool name="config_swipe_up_gesture_setting_available">false</bool>
-
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index fda46b7..f617df1 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -472,10 +472,16 @@
     <string name="proxy_url_title">"PAC URL: "</string>
 
     <!-- Radio Info screen. Label for a status item.  Used for diagnostic info screens, precise translation isn't needed -->
+    <string name="radio_info_dl_kbps">DL Bandwidth (kbps):</string>
+    <!-- Radio Info screen. Label for a status item.  Used for diagnostic info screens, precise translation isn't needed -->
+    <string name="radio_info_ul_kbps">UL Bandwidth (kbps):</string>
+    <!-- Radio Info screen. Label for a status item.  Used for diagnostic info screens, precise translation isn't needed -->
     <string name="radio_info_signal_location_label">Cell Location Info (deprecated):</string>
     <!-- Radio Info screen. Label for a status item.  Used for diagnostic info screens, precise translation isn't needed -->
     <string name="radio_info_neighboring_location_label">Neighbor Cell Info (deprecated):</string>
     <!-- Radio Info screen. Label for a status item.  Used for diagnostic info screens, precise translation isn't needed -->
+    <string name="radio_info_phy_chan_config">LTE Physical Channel Configuration:</string>
+    <!-- Radio Info screen. Label for a status item.  Used for diagnostic info screens, precise translation isn't needed -->
     <string name="radio_info_cell_info_refresh_rate">Cell Info Refresh Rate:</string>
     <!-- Radio Info screen. Label for a status item.  Used for diagnostic info screens, precise translation isn't needed -->
     <string name="radio_info_cellinfo_label">All Cell Measurement Info:</string>
@@ -9249,7 +9255,7 @@
     <!-- Informational text about update time only, without carrier. First argument intentionally skipped. [CHAR LIMIT=30] -->
     <string name="no_carrier_update_text">Updated <xliff:g name="time" example="3m">^2</xliff:g> ago</string>
 
-    <!-- Informational text about a recent carrier and update time [CHAR LIMIT=30] -->
+    <!-- Informational text about a recent carrier and update time [CHAR LIMIT=34] -->
     <string name="carrier_and_update_now_text">Updated by <xliff:g name="carrier" example="T-mobile">^1</xliff:g> just now</string>
 
     <!-- Informational text about recent update time only, without carrier [CHAR LIMIT=30] -->
diff --git a/res/xml/app_info_settings.xml b/res/xml/app_info_settings.xml
index 86b0df0..15afb5f 100644
--- a/res/xml/app_info_settings.xml
+++ b/res/xml/app_info_settings.xml
@@ -162,9 +162,16 @@
     </PreferenceCategory>
 
     <Preference
+        android:key="app_settings_link"
+        android:title="@string/app_settings_link"
+        settings:controller="com.android.settings.applications.appinfo.AppSettingPreferenceController"
+        settings:allowDividerAbove="true" />
+
+    <Preference
         android:key="app_version"
         android:selectable="false"
         android:order="9999"
-        settings:controller="com.android.settings.applications.appinfo.AppVersionPreferenceController" />
+        settings:controller="com.android.settings.applications.appinfo.AppVersionPreferenceController"
+        settings:allowDividerAbove="true" />
 
 </PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/bluetooth_pairing_detail.xml b/res/xml/bluetooth_pairing_detail.xml
index e654a3c..86fb9e4 100644
--- a/res/xml/bluetooth_pairing_detail.xml
+++ b/res/xml/bluetooth_pairing_detail.xml
@@ -16,12 +16,14 @@
 
 <PreferenceScreen
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:settings="http://schemas.android.com/apk/res-auto"
     android:title="@string/bluetooth_pairing_pref_title">
 
     <Preference
         android:key="bt_pair_rename_devices"
         android:title="@string/bluetooth_device_name"
-        android:summary="@string/summary_placeholder" />
+        android:summary="@string/summary_placeholder"
+        settings:controller="com.android.settings.bluetooth.BluetoothDeviceRenamePreferenceController"/>
 
     <com.android.settings.bluetooth.BluetoothProgressCategory
         android:key="available_devices"
diff --git a/res/xml/bluetooth_screen.xml b/res/xml/bluetooth_screen.xml
index 407feb6..5679cd4 100644
--- a/res/xml/bluetooth_screen.xml
+++ b/res/xml/bluetooth_screen.xml
@@ -19,9 +19,15 @@
     android:key="bluetooth_switchbar_screen"
     android:title="@string/bluetooth_settings_title">
 
+    <Preference
+        android:key="bluetooth_screen_bt_pair_rename_devices"
+        android:title="@string/bluetooth_device_name"
+        android:summary="@string/summary_placeholder"
+        settings:controller="com.android.settings.bluetooth.BluetoothDeviceRenamePreferenceController"/>
+
     <com.android.settingslib.RestrictedPreference
         android:key="bluetooth_screen_add_bt_devices"
-        android:title="@string/connected_device_add_device_title"
+        android:title="@string/bluetooth_pairing_pref_title"
         android:icon="@drawable/ic_menu_add"
         android:summary="@string/connected_device_add_device_summary"
         android:fragment="com.android.settings.bluetooth.BluetoothPairingDetail"
diff --git a/res/xml/connected_devices.xml b/res/xml/connected_devices.xml
index 6d25c58..75f9988 100644
--- a/res/xml/connected_devices.xml
+++ b/res/xml/connected_devices.xml
@@ -49,21 +49,6 @@
         settings:allowDividerAbove="true"/>
 
     <Preference
-        android:fragment="com.android.settings.connecteddevice.BluetoothDashboardFragment"
-        android:key="bluetooth_settings"
-        android:title="@string/bluetooth_settings_title"
-        android:icon="@drawable/ic_settings_bluetooth"/>
-
-    <PreferenceCategory
-        android:key="dashboard_tile_placeholder" />
-
-    <SwitchPreference
-        android:key="toggle_nfc"
-        android:title="@string/nfc_quick_toggle_title"
-        android:icon="@drawable/ic_nfc"
-        android:summary="@string/nfc_quick_toggle_summary"/>
-
-    <Preference
         android:key="connection_preferences"
         android:title="@string/connected_device_connections_title"
         android:fragment="com.android.settings.connecteddevice.AdvancedConnectedDeviceDashboardFragment"/>
diff --git a/res/xml/connected_devices_advanced.xml b/res/xml/connected_devices_advanced.xml
index 1917df1..f81fd79 100644
--- a/res/xml/connected_devices_advanced.xml
+++ b/res/xml/connected_devices_advanced.xml
@@ -20,12 +20,26 @@
     android:key="connected_devices_advanced_screen"
     android:title="@string/connected_device_connections_title">
 
+    <Preference
+        android:fragment="com.android.settings.connecteddevice.BluetoothDashboardFragment"
+        android:key="bluetooth_settings"
+        android:title="@string/bluetooth_settings_title"
+        android:icon="@drawable/ic_settings_bluetooth"
+        android:order="-9"/>
+
+    <SwitchPreference
+        android:key="toggle_nfc"
+        android:title="@string/nfc_quick_toggle_title"
+        android:icon="@drawable/ic_nfc"
+        android:summary="@string/nfc_quick_toggle_summary"
+        android:order="-7"/>
+
     <com.android.settingslib.RestrictedPreference
         android:fragment="com.android.settings.nfc.AndroidBeam"
         android:key="android_beam_settings"
         android:title="@string/android_beam_settings_title"
         android:icon="@drawable/ic_android"
-        android:order="-4"/>
+        android:order="-6"/>
 
     <SwitchPreference
         android:key="bluetooth_on_while_driving"
@@ -33,7 +47,7 @@
         android:icon="@drawable/ic_settings_bluetooth"
         android:summary="@string/bluetooth_on_while_driving_summary"
         settings:controller="com.android.settings.connecteddevice.BluetoothOnWhileDrivingPreferenceController"
-        android:order="-2"/>
+        android:order="-4"/>
 
     <com.android.settingslib.RestrictedPreference
         android:key="connected_device_printing"
@@ -41,7 +55,7 @@
         android:summary="@string/summary_placeholder"
         android:icon="@drawable/ic_settings_print"
         android:fragment="com.android.settings.print.PrintSettingsFragment"
-        android:order="-1"/>
+        android:order="-3"/>
 
     <Preference
         android:key="bt_received_files"
@@ -50,6 +64,6 @@
 
     <PreferenceCategory
         android:key="dashboard_tile_placeholder"
-        android:order="50"/>
+        android:order="-8"/>
 
 </PreferenceScreen>
diff --git a/res/xml/sound_settings.xml b/res/xml/sound_settings.xml
index 42dc588..353d1f1 100644
--- a/res/xml/sound_settings.xml
+++ b/res/xml/sound_settings.xml
@@ -62,12 +62,6 @@
         android:order="-160"
         settings:controller="com.android.settings.notification.RingVolumePreferenceController"/>
 
-    <!-- Also vibrate for calls -->
-    <SwitchPreference
-        android:key="vibrate_when_ringing"
-        android:title="@string/vibrate_when_ringing_title"
-        android:order="-155"/>
-
     <!-- Alarm volume -->
     <com.android.settings.notification.VolumeSeekBarPreference
         android:key="alarm_volume"
@@ -84,6 +78,13 @@
         android:order="-140"
         settings:controller="com.android.settings.notification.NotificationVolumePreferenceController"/>
 
+    <!-- Also vibrate for calls -->
+    <SwitchPreference
+        android:key="vibrate_when_ringing"
+        android:title="@string/vibrate_when_ringing_title"
+        settings:controller="com.android.settings.notification.VibrateWhenRingPreferenceController"
+        android:order="-130"/>
+
     <!-- Interruptions -->
     <com.android.settingslib.RestrictedPreference
         android:key="zen_mode"
diff --git a/src/com/android/settings/RadioInfo.java b/src/com/android/settings/RadioInfo.java
index b885483..170db16 100644
--- a/src/com/android/settings/RadioInfo.java
+++ b/src/com/android/settings/RadioInfo.java
@@ -16,6 +16,8 @@
 
 package com.android.settings;
 
+import static android.net.ConnectivityManager.NetworkCallback;
+
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.Dialog;
@@ -27,6 +29,10 @@
 import android.content.pm.ResolveInfo;
 import android.content.res.Resources;
 import android.graphics.Typeface;
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkRequest;
 import android.net.TrafficStats;
 import android.net.Uri;
 import android.os.AsyncResult;
@@ -52,12 +58,14 @@
 import android.telephony.NeighboringCellInfo;
 import android.telephony.PreciseCallState;
 import android.telephony.PhoneStateListener;
+import android.telephony.PhysicalChannelConfig;
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.telephony.cdma.CdmaCellLocation;
 import android.telephony.gsm.GsmCellLocation;
+import android.text.TextUtils;
 import android.util.Log;
 import android.view.Menu;
 import android.view.MenuItem;
@@ -193,7 +201,10 @@
     private TextView mPingHostnameV4;
     private TextView mPingHostnameV6;
     private TextView mHttpClientTest;
+    private TextView mPhyChanConfig;
     private TextView dnsCheckState;
+    private TextView mDownlinkKbps;
+    private TextView mUplinkKbps;
     private EditText smsc;
     private Switch radioPowerOnSwitch;
     private Button cellInfoRefreshRateButton;
@@ -211,6 +222,7 @@
     private Spinner preferredNetworkType;
     private Spinner cellInfoRefreshRateSpinner;
 
+    private ConnectivityManager mConnectivityManager;
     private TelephonyManager mTelephonyManager;
     private ImsManager mImsManager = null;
     private Phone phone = null;
@@ -228,6 +240,19 @@
     private int mPreferredNetworkTypeResult;
     private int mCellInfoRefreshRateIndex;
 
+    private final NetworkRequest mDefaultNetworkRequest = new NetworkRequest.Builder()
+            .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
+            .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
+            .build();
+
+    private final NetworkCallback mNetworkCallback = new NetworkCallback() {
+        public void onCapabilitiesChanged(Network n, NetworkCapabilities nc) {
+            int dlbw = nc.getLinkDownstreamBandwidthKbps();
+            int ulbw = nc.getLinkUpstreamBandwidthKbps();
+            updateBandwidths(dlbw, ulbw);
+        }
+    };
+
     private final PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
         @Override
         public void onDataConnectionStateChanged(int state) {
@@ -295,8 +320,29 @@
             updateNetworkType();
             updateImsProvisionedState();
         }
+
+        @Override
+        public void onPhysicalChannelConfigurationChanged(
+                List<PhysicalChannelConfig> configs) {
+            updatePhysicalChannelConfiguration(configs);
+        }
+
     };
 
+    private void updatePhysicalChannelConfiguration(List<PhysicalChannelConfig> configs) {
+            StringBuilder sb = new StringBuilder();
+            String div = "";
+            sb.append("{");
+            if (configs != null) {
+                for(PhysicalChannelConfig c : configs) {
+                    sb.append(div).append(c);
+                    div = ",";
+                }
+            }
+            sb.append("}");
+            mPhyChanConfig.setText(sb.toString());
+    }
+
     private void updatePreferredNetworkType(int type) {
         if (type >= mPreferredNetworkLabels.length || type < 0) {
             log("EVENT_QUERY_PREFERRED_TYPE_DONE: unknown " +
@@ -365,6 +411,7 @@
         log("Started onCreate");
 
         mTelephonyManager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
+        mConnectivityManager = (ConnectivityManager)getSystemService(CONNECTIVITY_SERVICE);
         phone = PhoneFactory.getDefaultPhone();
 
         //TODO: Need to update this if the default phoneId changes?
@@ -399,6 +446,8 @@
         mPingHostnameV6 = (TextView) findViewById(R.id.pingHostnameV6);
         mHttpClientTest = (TextView) findViewById(R.id.httpClientTest);
 
+        mPhyChanConfig = (TextView) findViewById(R.id.phy_chan_config);
+
         preferredNetworkType = (Spinner) findViewById(R.id.preferredNetworkType);
         ArrayAdapter<String> adapter = new ArrayAdapter<String> (this,
                 android.R.layout.simple_spinner_item, mPreferredNetworkLabels);
@@ -418,6 +467,10 @@
 
         radioPowerOnSwitch = (Switch) findViewById(R.id.radio_power);
 
+        mDownlinkKbps = (TextView) findViewById(R.id.dl_kbps);
+        mUplinkKbps = (TextView) findViewById(R.id.ul_kbps);
+        updateBandwidths(0, 0);
+
         pingTestButton = (Button) findViewById(R.id.ping_test);
         pingTestButton.setOnClickListener(mPingButtonHandler);
         updateSmscButton = (Button) findViewById(R.id.update_smsc);
@@ -501,7 +554,10 @@
                 | PhoneStateListener.LISTEN_CELL_INFO
                 | PhoneStateListener.LISTEN_SERVICE_STATE
                 | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
-                | PhoneStateListener.LISTEN_DATA_CONNECTION_REAL_TIME_INFO);
+                | PhoneStateListener.LISTEN_PHYSICAL_CHANNEL_CONFIGURATION);
+
+        mConnectivityManager.registerNetworkCallback(
+                mDefaultNetworkRequest, mNetworkCallback, mHandler);
 
         smsc.clearFocus();
     }
@@ -514,6 +570,8 @@
 
         mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
         mTelephonyManager.setCellInfoListRate(CELL_INFO_LIST_RATE_DISABLED);
+        mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
+
     }
 
     private void restoreFromBundle(Bundle b) {
@@ -593,6 +651,14 @@
                 "0.0.0.0 allowed" :"0.0.0.0 not allowed");
     }
 
+    private void updateBandwidths(int dlbw, int ulbw) {
+        dlbw = (dlbw < 0 || dlbw == Integer.MAX_VALUE) ? -1 : dlbw;
+        ulbw = (ulbw < 0 || ulbw == Integer.MAX_VALUE) ? -1 : ulbw;
+        mDownlinkKbps.setText(String.format("%-5d", dlbw));
+        mUplinkKbps.setText(String.format("%-5d", ulbw));
+    }
+
+
     private final void
     updateSignalStrength(SignalStrength signalStrength) {
         Resources r = getResources();
@@ -673,12 +739,34 @@
         return (i != Long.MAX_VALUE) ? Long.toString(i) : "";
     }
 
+    private final String getConnectionStatusString(CellInfo ci) {
+        String regStr = "";
+        String connStatStr = "";
+        String connector = "";
+
+        if (ci.isRegistered()) {
+            regStr = "R";
+        }
+        switch (ci.getCellConnectionStatus()) {
+            case CellInfo.CONNECTION_PRIMARY_SERVING: connStatStr = "P"; break;
+            case CellInfo.CONNECTION_SECONDARY_SERVING: connStatStr = "S"; break;
+            case CellInfo.CONNECTION_NONE: connStatStr = "N"; break;
+            case CellInfo.CONNECTION_UNKNOWN: /* Field is unsupported */ break;
+            default: break;
+        }
+        if (!TextUtils.isEmpty(regStr) && !TextUtils.isEmpty(connStatStr)) {
+            connector = "+";
+        }
+
+        return regStr + connector + connStatStr;
+    }
+
     private final String buildCdmaInfoString(CellInfoCdma ci) {
         CellIdentityCdma cidCdma = ci.getCellIdentity();
         CellSignalStrengthCdma ssCdma = ci.getCellSignalStrength();
 
         return String.format("%-3.3s %-5.5s %-5.5s %-5.5s %-6.6s %-6.6s %-6.6s %-6.6s %-5.5s",
-                ci.isRegistered() ? "S  " : "   ",
+                getConnectionStatusString(ci),
                 getCellInfoDisplayString(cidCdma.getSystemId()),
                 getCellInfoDisplayString(cidCdma.getNetworkId()),
                 getCellInfoDisplayString(cidCdma.getBasestationId()),
@@ -694,7 +782,7 @@
         CellSignalStrengthGsm ssGsm = ci.getCellSignalStrength();
 
         return String.format("%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-6.6s %-4.4s %-4.4s\n",
-                ci.isRegistered() ? "S  " : "   ",
+                getConnectionStatusString(ci),
                 getCellInfoDisplayString(cidGsm.getMcc()),
                 getCellInfoDisplayString(cidGsm.getMnc()),
                 getCellInfoDisplayString(cidGsm.getLac()),
@@ -709,14 +797,15 @@
         CellSignalStrengthLte ssLte = ci.getCellSignalStrength();
 
         return String.format(
-                "%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-3.3s %-6.6s %-4.4s %-4.4s %-2.2s\n",
-                ci.isRegistered() ? "S  " : "   ",
+                "%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-3.3s %-6.6s %-2.2s %-4.4s %-4.4s %-2.2s\n",
+                getConnectionStatusString(ci),
                 getCellInfoDisplayString(cidLte.getMcc()),
                 getCellInfoDisplayString(cidLte.getMnc()),
                 getCellInfoDisplayString(cidLte.getTac()),
                 getCellInfoDisplayString(cidLte.getCi()),
                 getCellInfoDisplayString(cidLte.getPci()),
                 getCellInfoDisplayString(cidLte.getEarfcn()),
+                getCellInfoDisplayString(cidLte.getBandwidth()),
                 getCellInfoDisplayString(ssLte.getDbm()),
                 getCellInfoDisplayString(ssLte.getRsrq()),
                 getCellInfoDisplayString(ssLte.getTimingAdvance()));
@@ -727,7 +816,7 @@
         CellSignalStrengthWcdma ssWcdma = ci.getCellSignalStrength();
 
         return String.format("%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-6.6s %-3.3s %-4.4s\n",
-                ci.isRegistered() ? "S  " : "   ",
+                getConnectionStatusString(ci),
                 getCellInfoDisplayString(cidWcdma.getMcc()),
                 getCellInfoDisplayString(cidWcdma.getMnc()),
                 getCellInfoDisplayString(cidWcdma.getLac()),
@@ -759,17 +848,21 @@
             }
             if (lteCells.length() != 0) {
                 value += String.format(
-                        "LTE\n%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-3.3s %-6.6s %-4.4s %-4.4s %-2.2s\n",
-                        "SRV", "MCC", "MNC", "TAC", "CID", "PCI", "EARFCN", "RSRP", "RSRQ", "TA");
+                        "LTE\n%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-3.3s"
+                                + " %-6.6s %-2.2s %-4.4s %-4.4s %-2.2s\n",
+                        "SRV", "MCC", "MNC", "TAC", "CID", "PCI",
+                        "EARFCN", "BW", "RSRP", "RSRQ", "TA");
                 value += lteCells.toString();
             }
             if (wcdmaCells.length() != 0) {
-                value += String.format("WCDMA\n%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-6.6s %-3.3s %-4.4s\n",
+                value += String.format(
+                        "WCDMA\n%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-6.6s %-3.3s %-4.4s\n",
                         "SRV", "MCC", "MNC", "LAC", "CID", "UARFCN", "PSC", "RSCP");
                 value += wcdmaCells.toString();
             }
             if (gsmCells.length() != 0) {
-                value += String.format("GSM\n%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-6.6s %-4.4s %-4.4s\n",
+                value += String.format(
+                        "GSM\n%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-6.6s %-4.4s %-4.4s\n",
                         "SRV", "MCC", "MNC", "LAC", "CID", "ARFCN", "BSIC", "RSSI");
                 value += gsmCells.toString();
             }
diff --git a/src/com/android/settings/accessibility/MagnificationGesturesPreferenceController.java b/src/com/android/settings/accessibility/MagnificationGesturesPreferenceController.java
index 71901af..603b698 100644
--- a/src/com/android/settings/accessibility/MagnificationGesturesPreferenceController.java
+++ b/src/com/android/settings/accessibility/MagnificationGesturesPreferenceController.java
@@ -19,9 +19,9 @@
 import android.support.v7.preference.Preference;
 
 import com.android.settings.R;
-import com.android.settings.core.BasePreferenceController;
+import com.android.settings.core.TogglePreferenceController;
 
-public class MagnificationGesturesPreferenceController extends BasePreferenceController {
+public class MagnificationGesturesPreferenceController extends TogglePreferenceController {
 
     private boolean mIsFromSUW = false;
 
@@ -29,6 +29,18 @@
         super(context, key);
     }
 
+    @Override
+    public boolean isChecked() {
+        return MagnificationPreferenceFragment.isChecked(mContext.getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED);
+    }
+
+    @Override
+    public boolean setChecked(boolean isChecked) {
+        return MagnificationPreferenceFragment.setChecked(mContext.getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, isChecked);
+    }
+
     public void setIsFromSUW(boolean fromSUW) {
         mIsFromSUW = fromSUW;
     }
@@ -38,6 +50,7 @@
         if (getPreferenceKey().equals(preference.getKey())) {
             Bundle extras = preference.getExtras();
             populateMagnificationGesturesPreferenceExtras(extras, mContext);
+            extras.putBoolean(AccessibilitySettings.EXTRA_CHECKED, isChecked());
             extras.putBoolean(AccessibilitySettings.EXTRA_LAUNCHED_FROM_SUW, mIsFromSUW);
         }
         return false;
@@ -54,8 +67,7 @@
         if (mIsFromSUW) {
             resId = R.string.accessibility_screen_magnification_short_summary;
         } else {
-            final boolean enabled = Settings.Secure.getInt(mContext.getContentResolver(),
-                    Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, 0) == 1;
+            final boolean enabled = isChecked();
             resId = (enabled ? R.string.accessibility_feature_state_on :
                     R.string.accessibility_feature_state_off);
         }
@@ -69,9 +81,6 @@
                 R.string.accessibility_screen_magnification_gestures_title);
         extras.putInt(AccessibilitySettings.EXTRA_SUMMARY_RES,
                 R.string.accessibility_screen_magnification_summary);
-        extras.putBoolean(AccessibilitySettings.EXTRA_CHECKED,
-                Settings.Secure.getInt(context.getContentResolver(),
-                        Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, 0) == 1);
         extras.putInt(AccessibilitySettings.EXTRA_VIDEO_RAW_RESOURCE_ID,
                 R.raw.accessibility_screen_magnification);
     }
diff --git a/src/com/android/settings/accessibility/MagnificationNavbarPreferenceController.java b/src/com/android/settings/accessibility/MagnificationNavbarPreferenceController.java
index 84063a1..9c6301b 100644
--- a/src/com/android/settings/accessibility/MagnificationNavbarPreferenceController.java
+++ b/src/com/android/settings/accessibility/MagnificationNavbarPreferenceController.java
@@ -19,9 +19,9 @@
 import android.support.v7.preference.Preference;
 
 import com.android.settings.R;
-import com.android.settings.core.BasePreferenceController;
+import com.android.settings.core.TogglePreferenceController;
 
-public class MagnificationNavbarPreferenceController extends BasePreferenceController {
+public class MagnificationNavbarPreferenceController extends TogglePreferenceController {
 
     private boolean mIsFromSUW = false;
 
@@ -29,6 +29,18 @@
         super(context, key);
     }
 
+    @Override
+    public boolean isChecked() {
+        return MagnificationPreferenceFragment.isChecked(mContext.getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED);
+    }
+
+    @Override
+    public boolean setChecked(boolean isChecked) {
+        return MagnificationPreferenceFragment.setChecked(mContext.getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED, isChecked);
+    }
+
     public void setIsFromSUW(boolean fromSUW) {
         mIsFromSUW = fromSUW;
     }
@@ -43,10 +55,7 @@
                     R.string.accessibility_screen_magnification_navbar_title);
             extras.putInt(AccessibilitySettings.EXTRA_SUMMARY_RES,
                     R.string.accessibility_screen_magnification_navbar_summary);
-            extras.putBoolean(AccessibilitySettings.EXTRA_CHECKED,
-                    Settings.Secure.getInt(mContext.getContentResolver(),
-                            Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED, 0)
-                            == 1);
+            extras.putBoolean(AccessibilitySettings.EXTRA_CHECKED, isChecked());
             extras.putBoolean(AccessibilitySettings.EXTRA_LAUNCHED_FROM_SUW, mIsFromSUW);
         }
         return false;
@@ -65,8 +74,7 @@
         if (mIsFromSUW) {
             resId = R.string.accessibility_screen_magnification_navbar_short_summary;
         } else {
-            final boolean enabled = Settings.Secure.getInt(mContext.getContentResolver(),
-                    Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED, 0) == 1;
+            final boolean enabled = isChecked();
             resId = (enabled ? R.string.accessibility_feature_state_on :
                     R.string.accessibility_feature_state_off);
         }
diff --git a/src/com/android/settings/accessibility/MagnificationPreferenceFragment.java b/src/com/android/settings/accessibility/MagnificationPreferenceFragment.java
index aa6d4f3..615c874 100644
--- a/src/com/android/settings/accessibility/MagnificationPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/MagnificationPreferenceFragment.java
@@ -18,11 +18,13 @@
 
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.content.ComponentName;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.res.Resources;
 import android.os.Bundle;
 import android.provider.SearchIndexableResource;
 import android.provider.Settings;
+import android.support.annotation.VisibleForTesting;
 import android.support.v7.preference.Preference;
 import android.text.TextUtils;
 import android.view.accessibility.AccessibilityManager;
@@ -39,6 +41,10 @@
 import java.util.List;
 
 public final class MagnificationPreferenceFragment extends DashboardFragment {
+    @VisibleForTesting
+    static final int ON = 1;
+    @VisibleForTesting
+    static final int OFF = 0;
 
     private static final String TAG = "MagnificationPreferenceFragment";
 
@@ -132,6 +138,15 @@
         return null;
     }
 
+    static boolean isChecked(ContentResolver contentResolver, String settingsKey) {
+        return Settings.Secure.getInt(contentResolver, settingsKey, OFF) == ON;
+    }
+
+    static boolean setChecked(ContentResolver contentResolver, String settingsKey,
+            boolean isChecked) {
+        return Settings.Secure.putInt(contentResolver, settingsKey, isChecked ? ON : OFF);
+    }
+
     /**
      * @return {@code true} if this fragment should be shown, {@code false} otherwise. This
      * fragment is shown in the case that more than one magnification mode is available.
diff --git a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java
index ecb4b9f..d7ca22a 100644
--- a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java
@@ -25,7 +25,6 @@
 import android.media.MediaPlayer.OnPreparedListener;
 import android.net.Uri;
 import android.os.Bundle;
-import android.provider.Settings;
 import android.support.v7.preference.Preference;
 import android.support.v7.preference.PreferenceScreen;
 import android.support.v7.preference.PreferenceViewHolder;
@@ -174,7 +173,7 @@
 
     @Override
     protected void onPreferenceToggled(String preferenceKey, boolean enabled) {
-        Settings.Secure.putInt(getContentResolver(), preferenceKey, enabled ? 1 : 0);
+        MagnificationPreferenceFragment.setChecked(getContentResolver(), preferenceKey, enabled);
         updateConfigurationWarningIfNeeded();
     }
 
@@ -183,7 +182,7 @@
         super.onInstallSwitchBarToggleSwitch();
 
         mSwitchBar.setCheckedInternal(
-                Settings.Secure.getInt(getContentResolver(), mPreferenceKey, 0) == 1);
+                MagnificationPreferenceFragment.isChecked(getContentResolver(), mPreferenceKey));
         mSwitchBar.addOnSwitchChangeListener(this);
     }
 
diff --git a/src/com/android/settings/applications/appinfo/AppHeaderViewPreferenceController.java b/src/com/android/settings/applications/appinfo/AppHeaderViewPreferenceController.java
index 4b7631a..15d1789 100644
--- a/src/com/android/settings/applications/appinfo/AppHeaderViewPreferenceController.java
+++ b/src/com/android/settings/applications/appinfo/AppHeaderViewPreferenceController.java
@@ -68,7 +68,7 @@
         mEntityHeaderController = EntityHeaderController
                 .newInstance(activity, mParent, mHeader.findViewById(R.id.entity_header))
                 .setPackageName(mPackageName)
-                .setButtonActions(EntityHeaderController.ActionType.ACTION_APP_PREFERENCE,
+                .setButtonActions(EntityHeaderController.ActionType.ACTION_NONE,
                         EntityHeaderController.ActionType.ACTION_NONE)
                 .bindHeaderButtons();
     }
diff --git a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java
index 4a0db4e..e71c8d1 100755
--- a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java
+++ b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java
@@ -167,6 +167,9 @@
         use(AppOpenByDefaultPreferenceController.class).setParentFragment(this);
         use(AppPermissionPreferenceController.class).setParentFragment(this);
         use(AppPermissionPreferenceController.class).setPackageName(packageName);
+        use(AppSettingPreferenceController.class)
+                .setPackageName(packageName)
+                .setParentFragment(this);
         use(AppStoragePreferenceController.class).setParentFragment(this);
         use(AppVersionPreferenceController.class).setParentFragment(this);
         use(InstantAppDomainsPreferenceController.class).setParentFragment(this);
diff --git a/src/com/android/settings/applications/appinfo/AppSettingPreferenceController.java b/src/com/android/settings/applications/appinfo/AppSettingPreferenceController.java
new file mode 100644
index 0000000..f2941b2
--- /dev/null
+++ b/src/com/android/settings/applications/appinfo/AppSettingPreferenceController.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.applications.appinfo;
+
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_OPEN_APP_SETTING;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ResolveInfo;
+import android.support.v7.preference.Preference;
+import android.text.TextUtils;
+
+import com.android.settings.overlay.FeatureFactory;
+
+public class AppSettingPreferenceController extends AppInfoPreferenceControllerBase {
+
+    private String mPackageName;
+
+    public AppSettingPreferenceController(Context context, String preferenceKey) {
+        super(context, preferenceKey);
+    }
+
+    public AppSettingPreferenceController setPackageName(String packageName) {
+        mPackageName = packageName;
+        return this;
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        if (TextUtils.isEmpty(mPackageName) || mParent == null) {
+            return CONDITIONALLY_UNAVAILABLE;
+        }
+        final Intent intent = resolveIntent(
+                new Intent(Intent.ACTION_APPLICATION_PREFERENCES).setPackage(mPackageName));
+        return intent != null ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
+    }
+
+    @Override
+    public boolean handlePreferenceTreeClick(Preference preference) {
+        if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) {
+            return false;
+        }
+        final Intent intent = resolveIntent(
+                new Intent(Intent.ACTION_APPLICATION_PREFERENCES).setPackage(mPackageName));
+        if (intent == null) {
+            return false;
+        }
+        FeatureFactory.getFactory(mContext).getMetricsFeatureProvider()
+                .actionWithSource(mContext, mParent.getMetricsCategory(),
+                        ACTION_OPEN_APP_SETTING);
+        mContext.startActivity(intent);
+        return true;
+    }
+
+    private Intent resolveIntent(Intent i) {
+        ResolveInfo result = mContext.getPackageManager().resolveActivity(i, 0);
+        if (result != null) {
+            return new Intent(i.getAction())
+                    .setClassName(result.activityInfo.packageName, result.activityInfo.name);
+        }
+        return null;
+    }
+}
diff --git a/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceController.java b/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceController.java
index 8827a71..05b5a8a 100644
--- a/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceController.java
@@ -32,7 +32,6 @@
 import com.android.settings.core.BasePreferenceController;
 import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
-import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnStart;
 import com.android.settingslib.core.lifecycle.events.OnStop;
@@ -44,16 +43,16 @@
         LifecycleObserver, OnStart, OnStop {
     private static final String TAG = "BluetoothNamePrefCtrl";
 
-    public static final String KEY_DEVICE_NAME = "device_name";
-
-
     @VisibleForTesting
     Preference mPreference;
     private LocalBluetoothManager mLocalManager;
     private LocalBluetoothAdapter mLocalAdapter;
 
-    public BluetoothDeviceNamePreferenceController(Context context, Lifecycle lifecycle) {
-        this(context, (LocalBluetoothAdapter) null);
+    /**
+     * Constructor exclusively used for Slice.
+     */
+    public BluetoothDeviceNamePreferenceController(Context context, String preferenceKey) {
+        super(context, preferenceKey);
 
         mLocalManager = Utils.getLocalBtManager(context);
         if (mLocalManager == null) {
@@ -61,22 +60,12 @@
             return;
         }
         mLocalAdapter = mLocalManager.getBluetoothAdapter();
-
-        if (lifecycle != null) {
-            lifecycle.addObserver(this);
-        }
-    }
-
-    /**
-     * Constructor exclusively used for Slice.
-     */
-    public BluetoothDeviceNamePreferenceController(Context context) {
-        this(context, (Lifecycle) null);
     }
 
     @VisibleForTesting
-    BluetoothDeviceNamePreferenceController(Context context, LocalBluetoothAdapter localAdapter) {
-        super(context, KEY_DEVICE_NAME);
+    BluetoothDeviceNamePreferenceController(Context context, LocalBluetoothAdapter localAdapter,
+            String preferenceKey) {
+        super(context, preferenceKey);
         mLocalAdapter = localAdapter;
     }
 
@@ -103,11 +92,6 @@
     }
 
     @Override
-    public String getPreferenceKey() {
-        return KEY_DEVICE_NAME;
-    }
-
-    @Override
     public void updateState(Preference preference) {
         updateDeviceName(preference);
     }
@@ -134,7 +118,7 @@
     public Preference createBluetoothDeviceNamePreference(PreferenceScreen screen, int order) {
         mPreference = new Preference(screen.getContext());
         mPreference.setOrder(order);
-        mPreference.setKey(KEY_DEVICE_NAME);
+        mPreference.setKey(getPreferenceKey());
         screen.addPreference(mPreference);
 
         return mPreference;
diff --git a/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceController.java b/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceController.java
index 262d6b3..21f0487 100644
--- a/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceController.java
@@ -26,44 +26,35 @@
 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
         BluetoothDeviceNamePreferenceController {
 
-    private final Fragment mFragment;
-    private String mPrefKey;
+    private Fragment mFragment;
     private MetricsFeatureProvider mMetricsFeatureProvider;
 
-    public BluetoothDeviceRenamePreferenceController(Context context, String prefKey,
-            Fragment fragment, Lifecycle lifecycle) {
-        super(context, lifecycle);
-        mPrefKey = prefKey;
-        mFragment = fragment;
-        mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
-    }
-
     /**
      * Constructor exclusively used for Slice.
      */
-    public BluetoothDeviceRenamePreferenceController(Context context, String prefKey) {
-        super(context, (Lifecycle) null);
-        mPrefKey = prefKey;
-        mFragment = null;
-    }
-
-    @VisibleForTesting
-    BluetoothDeviceRenamePreferenceController(Context context, String prefKey, Fragment fragment,
-            LocalBluetoothAdapter localAdapter) {
-        super(context, localAdapter);
-        mPrefKey = prefKey;
-        mFragment = fragment;
+    public BluetoothDeviceRenamePreferenceController(Context context, String preferenceKey) {
+        super(context, preferenceKey);
         mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
     }
 
-    @Override
-    public String getPreferenceKey() {
-        return mPrefKey;
+    @VisibleForTesting
+    BluetoothDeviceRenamePreferenceController(Context context, LocalBluetoothAdapter localAdapter,
+            String preferenceKey) {
+        super(context, localAdapter, preferenceKey);
+        mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
+    }
+
+    /**
+     * Set the {@link Fragment} that used to show {@link LocalDeviceNameDialogFragment}
+     * in {@code handlePreferenceTreeClick}
+     */
+    @VisibleForTesting
+    public void setFragment(Fragment fragment) {
+        mFragment = fragment;
     }
 
     @Override
@@ -78,7 +69,7 @@
 
     @Override
     public boolean handlePreferenceTreeClick(Preference preference) {
-        if (TextUtils.equals(mPrefKey, preference.getKey()) && mFragment != null) {
+        if (TextUtils.equals(getPreferenceKey(), preference.getKey()) && mFragment != null) {
             mMetricsFeatureProvider.action(mContext,
                     MetricsProto.MetricsEvent.ACTION_BLUETOOTH_RENAME);
             LocalDeviceNameDialogFragment.newInstance()
diff --git a/src/com/android/settings/bluetooth/BluetoothPairingDetail.java b/src/com/android/settings/bluetooth/BluetoothPairingDetail.java
index b31d4c8..1ab7f87 100644
--- a/src/com/android/settings/bluetooth/BluetoothPairingDetail.java
+++ b/src/com/android/settings/bluetooth/BluetoothPairingDetail.java
@@ -30,12 +30,8 @@
 import com.android.settings.search.Indexable;
 import com.android.settingslib.bluetooth.BluetoothDeviceFilter;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
-import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.widget.FooterPreference;
 
-import java.util.ArrayList;
-import java.util.List;
-
 /**
  * BluetoothPairingDetail is a page to scan bluetooth devices and pair them.
  */
@@ -47,7 +43,6 @@
     static final String KEY_AVAIL_DEVICES = "available_devices";
     @VisibleForTesting
     static final String KEY_FOOTER_PREF = "footer_preference";
-    private static final String KEY_RENAME_DEVICES = "bt_pair_rename_devices";
 
     @VisibleForTesting
     BluetoothProgressCategory mAvailableDevicesCategory;
@@ -80,6 +75,12 @@
         mAvailableDevicesCategory.setProgress(mLocalAdapter.isDiscovering());
     }
 
+    @Override
+    public void onAttach(Context context) {
+        super.onAttach(context);
+        use(BluetoothDeviceRenamePreferenceController.class).setFragment(this);
+    }
+
     @VisibleForTesting
     void updateBluetooth() {
         if (mLocalAdapter.isEnabled()) {
@@ -200,16 +201,6 @@
     }
 
     @Override
-    protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
-        final List<AbstractPreferenceController> controllers = new ArrayList<>();
-        controllers.add(
-                new BluetoothDeviceRenamePreferenceController(context, KEY_RENAME_DEVICES, this,
-                        getLifecycle()));
-
-        return controllers;
-    }
-
-    @Override
     public String getDeviceListKey() {
         return KEY_AVAIL_DEVICES;
     }
diff --git a/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragment.java b/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragment.java
index 45794c5..a64a430 100644
--- a/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragment.java
+++ b/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragment.java
@@ -24,6 +24,7 @@
 import com.android.settings.bluetooth.BluetoothFilesPreferenceController;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.nfc.AndroidBeamPreferenceController;
+import com.android.settings.nfc.NfcPreferenceController;
 import com.android.settings.print.PrintSettingPreferenceController;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settingslib.core.AbstractPreferenceController;
@@ -78,10 +79,16 @@
 
         final PrintSettingPreferenceController printerController =
                 new PrintSettingPreferenceController(context);
+        final NfcPreferenceController nfcPreferenceController =
+                new NfcPreferenceController(context);
+
         if (lifecycle != null) {
             lifecycle.addObserver(beamPreferenceController);
             lifecycle.addObserver(printerController);
+            lifecycle.addObserver(nfcPreferenceController);
         }
+
+        controllers.add(nfcPreferenceController);
         controllers.add(printerController);
 
         return controllers;
diff --git a/src/com/android/settings/connecteddevice/BluetoothDashboardFragment.java b/src/com/android/settings/connecteddevice/BluetoothDashboardFragment.java
index 77b75c5..3b24271 100644
--- a/src/com/android/settings/connecteddevice/BluetoothDashboardFragment.java
+++ b/src/com/android/settings/connecteddevice/BluetoothDashboardFragment.java
@@ -24,6 +24,7 @@
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
+import com.android.settings.bluetooth.BluetoothDeviceRenamePreferenceController;
 import com.android.settings.bluetooth.BluetoothSwitchPreferenceController;
 import com.android.settings.core.SubSettingLauncher;
 import com.android.settings.core.TogglePreferenceController;
@@ -79,6 +80,12 @@
     }
 
     @Override
+    public void onAttach(Context context) {
+        super.onAttach(context);
+        use(BluetoothDeviceRenamePreferenceController.class).setFragment(this);
+    }
+
+    @Override
     public void onActivityCreated(Bundle savedInstanceState) {
         super.onActivityCreated(savedInstanceState);
 
diff --git a/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java b/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java
index 227fd9b..3dc1437 100644
--- a/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java
+++ b/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java
@@ -26,10 +26,7 @@
 import com.android.settings.dashboard.SummaryLoader;
 import com.android.settings.nfc.NfcPreferenceController;
 import com.android.settings.search.BaseSearchIndexProvider;
-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;
 
@@ -63,25 +60,6 @@
     }
 
     @Override
-    protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
-        return buildPreferenceControllers(context, getLifecycle());
-    }
-
-    private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
-            Lifecycle lifecycle) {
-        final List<AbstractPreferenceController> controllers = new ArrayList<>();
-        final NfcPreferenceController nfcPreferenceController =
-                new NfcPreferenceController(context);
-        controllers.add(nfcPreferenceController);
-
-        if (lifecycle != null) {
-            lifecycle.addObserver(nfcPreferenceController);
-        }
-
-        return controllers;
-    }
-
-    @Override
     public void onAttach(Context context) {
         super.onAttach(context);
         use(AvailableMediaDeviceGroupController.class).init(this);
@@ -139,12 +117,6 @@
                 }
 
                 @Override
-                public List<AbstractPreferenceController> createPreferenceControllers(Context
-                        context) {
-                    return buildPreferenceControllers(context, null /* lifecycle */);
-                }
-
-                @Override
                 public List<String> getNonIndexableKeys(Context context) {
                     List<String> keys = super.getNonIndexableKeys(context);
                     // Disable because they show dynamic data
diff --git a/src/com/android/settings/core/TogglePreferenceController.java b/src/com/android/settings/core/TogglePreferenceController.java
index ffe7fd3..e01a38d 100644
--- a/src/com/android/settings/core/TogglePreferenceController.java
+++ b/src/com/android/settings/core/TogglePreferenceController.java
@@ -51,8 +51,10 @@
     public void updateState(Preference preference) {
         if (preference instanceof TwoStatePreference) {
             ((TwoStatePreference) preference).setChecked(isChecked());
-        } if (preference instanceof MasterSwitchPreference) {
+        } else if (preference instanceof MasterSwitchPreference) {
             ((MasterSwitchPreference) preference).setChecked(isChecked());
+        } else {
+            refreshSummary(preference);
         }
     }
 
diff --git a/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java b/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java
index e727521..b76aef0 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java
@@ -131,6 +131,7 @@
 
     @Override
     public boolean isSmartBatterySupported() {
-        return false;
+        return mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_smart_battery_available);
     }
 }
diff --git a/src/com/android/settings/gestures/GesturePreferenceController.java b/src/com/android/settings/gestures/GesturePreferenceController.java
index 7f1100b..c4ee8c2 100644
--- a/src/com/android/settings/gestures/GesturePreferenceController.java
+++ b/src/com/android/settings/gestures/GesturePreferenceController.java
@@ -59,9 +59,6 @@
     public void updateState(Preference preference) {
         super.updateState(preference);
         if (preference != null) {
-            if (!(preference instanceof TwoStatePreference)) {
-                preference.setSummary(getSummary());
-            }
             // Different meanings of "Enabled" for the Preference and Controller.
             preference.setEnabled(canHandleClicks());
         }
diff --git a/src/com/android/settings/gestures/SwipeUpPreferenceController.java b/src/com/android/settings/gestures/SwipeUpPreferenceController.java
index 27c7241..b768a2c 100644
--- a/src/com/android/settings/gestures/SwipeUpPreferenceController.java
+++ b/src/com/android/settings/gestures/SwipeUpPreferenceController.java
@@ -24,7 +24,7 @@
 import android.provider.Settings;
 import android.support.annotation.VisibleForTesting;
 
-import com.android.settings.R;
+import com.android.internal.R;
 
 public class SwipeUpPreferenceController extends GesturePreferenceController {
 
@@ -46,7 +46,7 @@
         }
 
         final ComponentName recentsComponentName = ComponentName.unflattenFromString(
-                context.getString(com.android.internal.R.string.config_recentsComponentName));
+                context.getString(R.string.config_recentsComponentName));
         final Intent quickStepIntent = new Intent(ACTION_QUICKSTEP)
                 .setPackage(recentsComponentName.getPackageName());
         if (context.getPackageManager().resolveService(quickStepIntent,
@@ -81,7 +81,7 @@
     @Override
     public boolean isChecked() {
         final int defaultValue = mContext.getResources()
-                .getBoolean(com.android.internal.R.bool.config_swipe_up_gesture_default) ? ON : OFF;
+                .getBoolean(R.bool.config_swipe_up_gesture_default) ? ON : OFF;
         final int swipeUpEnabled = Settings.Secure.getInt(mContext.getContentResolver(),
                 Settings.Secure.SWIPE_UP_TO_SWITCH_APPS_ENABLED, defaultValue);
         return swipeUpEnabled != OFF;
diff --git a/src/com/android/settings/network/TetherPreferenceController.java b/src/com/android/settings/network/TetherPreferenceController.java
index 1c9959e..1f19031 100644
--- a/src/com/android/settings/network/TetherPreferenceController.java
+++ b/src/com/android/settings/network/TetherPreferenceController.java
@@ -131,7 +131,8 @@
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
-        if (mBluetoothAdapter != null) {
+        if (mBluetoothAdapter != null &&
+            mBluetoothAdapter.getState() == BluetoothAdapter.STATE_ON) {
             mBluetoothAdapter.getProfileProxy(mContext, mBtProfileServiceListener,
                     BluetoothProfile.PAN);
         }
diff --git a/src/com/android/settings/notification/SoundSettings.java b/src/com/android/settings/notification/SoundSettings.java
index 3ba71a1..1005d20 100644
--- a/src/com/android/settings/notification/SoundSettings.java
+++ b/src/com/android/settings/notification/SoundSettings.java
@@ -26,16 +26,22 @@
 import android.preference.SeekBarVolumizer;
 import android.provider.SearchIndexableResource;
 import android.support.annotation.VisibleForTesting;
+import android.support.v7.preference.ListPreference;
 import android.support.v7.preference.Preference;
 import android.text.TextUtils;
 
+import com.android.internal.logging.nano.MetricsProto;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
 import com.android.settings.RingtonePreference;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.sound.HandsFreeProfileOutputPreferenceController;
+import com.android.settings.sound.MediaOutputPreferenceController;
 import com.android.settings.widget.PreferenceCategoryController;
+import com.android.settings.widget.UpdatableListPreferenceDialogFragment;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.instrumentation.Instrumentable;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 
 import java.util.ArrayList;
@@ -48,7 +54,6 @@
     private static final String SELECTED_PREFERENCE_KEY = "selected_preference";
     private static final int REQUEST_CODE = 200;
     private static final String KEY_ZEN_MODE = "zen_mode";
-
     private static final int SAMPLE_CUTOFF = 2000;  // manually cap sample playback at 2 seconds
 
     @VisibleForTesting
@@ -69,6 +74,9 @@
     };
 
     private RingtonePreference mRequestPreference;
+    private UpdatableListPreferenceDialogFragment mDialogFragment;
+    private String mMediaOutputControllerKey;
+    private String mHfpOutputControllerKey;
 
     @Override
     public int getMetricsCategory() {
@@ -83,6 +91,11 @@
             if (!TextUtils.isEmpty(selectedPreference)) {
                 mRequestPreference = (RingtonePreference) findPreference(selectedPreference);
             }
+
+            UpdatableListPreferenceDialogFragment dialogFragment =
+                    (UpdatableListPreferenceDialogFragment) getFragmentManager()
+                            .findFragmentByTag(TAG);
+            mDialogFragment = dialogFragment;
         }
     }
 
@@ -113,6 +126,23 @@
     }
 
     @Override
+    public void onDisplayPreferenceDialog(Preference preference) {
+        final int metricsCategory;
+        if (mHfpOutputControllerKey.equals(preference.getKey())) {
+            metricsCategory = MetricsProto.MetricsEvent.DIALOG_SWITCH_HFP_DEVICES;
+        } else if (mMediaOutputControllerKey.equals(preference.getKey())) {
+            metricsCategory = MetricsProto.MetricsEvent.DIALOG_SWITCH_A2DP_DEVICES;
+        } else {
+            metricsCategory = Instrumentable.METRICS_CATEGORY_UNKNOWN;
+        }
+
+        mDialogFragment = UpdatableListPreferenceDialogFragment.
+                newInstance(preference.getKey(), metricsCategory);
+        mDialogFragment.setTargetFragment(this, 0);
+        mDialogFragment.show(getFragmentManager(), TAG);
+    }
+
+    @Override
     protected String getLogTag() {
         return TAG;
     }
@@ -153,6 +183,14 @@
         volumeControllers.add(use(NotificationVolumePreferenceController.class));
         volumeControllers.add(use(CallVolumePreferenceController.class));
 
+        use(MediaOutputPreferenceController.class).setCallback(listPreference ->
+                onPreferenceDataChanged(listPreference));
+        mMediaOutputControllerKey = use(MediaOutputPreferenceController.class).getPreferenceKey();
+        use(HandsFreeProfileOutputPreferenceController.class).setCallback(listPreference ->
+            onPreferenceDataChanged(listPreference));
+        mHfpOutputControllerKey =
+                use(HandsFreeProfileOutputPreferenceController.class).getPreferenceKey();
+
         for (VolumeSeekBarPreferenceController controller : volumeControllers) {
             controller.setCallback(mVolumeCallback);
             getLifecycle().addObserver(controller);
@@ -195,7 +233,6 @@
             SoundSettings fragment, Lifecycle lifecycle) {
         final List<AbstractPreferenceController> controllers = new ArrayList<>();
         controllers.add(new ZenModePreferenceController(context, lifecycle, KEY_ZEN_MODE));
-        controllers.add(new VibrateWhenRingPreferenceController(context));
 
         // Volumes are added via xml
 
@@ -289,4 +326,10 @@
             workSoundController.enableWorkSync();
         }
     }
-}
+
+    private void onPreferenceDataChanged(ListPreference preference) {
+        if (mDialogFragment != null) {
+            mDialogFragment.onListPreferenceUpdated(preference);
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/notification/VibrateWhenRingPreferenceController.java b/src/com/android/settings/notification/VibrateWhenRingPreferenceController.java
index d41e16b..d2ff7c5 100644
--- a/src/com/android/settings/notification/VibrateWhenRingPreferenceController.java
+++ b/src/com/android/settings/notification/VibrateWhenRingPreferenceController.java
@@ -16,6 +16,8 @@
 
 package com.android.settings.notification;
 
+import static android.provider.Settings.System.VIBRATE_WHEN_RINGING;
+
 import android.content.ContentResolver;
 import android.content.Context;
 import android.database.ContentObserver;
@@ -24,26 +26,41 @@
 import android.provider.Settings;
 import android.support.v7.preference.Preference;
 import android.support.v7.preference.PreferenceScreen;
-import android.support.v7.preference.TwoStatePreference;
 
 import com.android.settings.Utils;
-import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settings.core.TogglePreferenceController;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnPause;
 import com.android.settingslib.core.lifecycle.events.OnResume;
 
-import static android.provider.Settings.System.VIBRATE_WHEN_RINGING;
-
-public class VibrateWhenRingPreferenceController extends AbstractPreferenceController
-        implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener,
-        LifecycleObserver, OnResume, OnPause {
+public class VibrateWhenRingPreferenceController extends TogglePreferenceController
+        implements LifecycleObserver, OnResume, OnPause {
 
     private static final String KEY_VIBRATE_WHEN_RINGING = "vibrate_when_ringing";
+    private final int DEFAULT_VALUE = 0;
+    private final int NOTIFICATION_VIBRATE_WHEN_RINGING = 1;
     private SettingObserver mSettingObserver;
 
-    public VibrateWhenRingPreferenceController(Context context) {
-        super(context);
+    public VibrateWhenRingPreferenceController(Context context, String key) {
+        super(context, key);
+    }
+
+    @Override
+    public boolean isChecked() {
+        return Settings.System.getInt(mContext.getContentResolver(),
+                VIBRATE_WHEN_RINGING, DEFAULT_VALUE) != DEFAULT_VALUE;
+    }
+
+    @Override
+    public boolean setChecked(boolean isChecked) {
+        return Settings.System.putInt(mContext.getContentResolver(), VIBRATE_WHEN_RINGING,
+                isChecked ? NOTIFICATION_VIBRATE_WHEN_RINGING : DEFAULT_VALUE);
+    }
+
+    @Override
+    @AvailabilityStatus
+    public int getAvailabilityStatus() {
+        return Utils.isVoiceCapable(mContext) ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
     }
 
     @Override
@@ -70,38 +87,10 @@
         }
     }
 
-    @Override
-    public boolean handlePreferenceTreeClick(Preference preference) {
-        return false;
-    }
-
-    @Override
-    public String getPreferenceKey() {
-        return KEY_VIBRATE_WHEN_RINGING;
-    }
-
-    @Override
-    public boolean isAvailable() {
-        return Utils.isVoiceCapable(mContext);
-    }
-
-    @Override
-    public void updateState(Preference preference) {
-        ((TwoStatePreference) preference).setChecked(
-            Settings.System.getInt(mContext.getContentResolver(), VIBRATE_WHEN_RINGING, 0) != 0);
-    }
-
-    @Override
-    public boolean onPreferenceChange(Preference preference, Object newValue) {
-        final boolean val = (Boolean) newValue;
-        return Settings.System.putInt(mContext.getContentResolver(),
-            VIBRATE_WHEN_RINGING, val ? 1 : 0);
-    }
-
     private final class SettingObserver extends ContentObserver {
 
         private final Uri VIBRATE_WHEN_RINGING_URI =
-            Settings.System.getUriFor(VIBRATE_WHEN_RINGING);
+                Settings.System.getUriFor(VIBRATE_WHEN_RINGING);
 
         private final Preference mPreference;
 
@@ -127,5 +116,4 @@
             }
         }
     }
-
 }
diff --git a/src/com/android/settings/slices/SliceBuilderUtils.java b/src/com/android/settings/slices/SliceBuilderUtils.java
index be2e8df..d744fbd 100644
--- a/src/com/android/settings/slices/SliceBuilderUtils.java
+++ b/src/com/android/settings/slices/SliceBuilderUtils.java
@@ -24,11 +24,11 @@
 import static com.android.settings.slices.SettingsSliceProvider.EXTRA_SLICE_KEY;
 import static com.android.settings.slices.SettingsSliceProvider.EXTRA_SLICE_PLATFORM_DEFINED;
 
+import android.annotation.ColorInt;
 import android.app.PendingIntent;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
-import android.content.pm.PackageManager;
 import android.net.Uri;
 import android.provider.Settings;
 import android.provider.SettingsSlicesContract;
@@ -41,6 +41,7 @@
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
 import com.android.settings.SubSettings;
+import com.android.settings.Utils;
 import com.android.settings.core.BasePreferenceController;
 import com.android.settings.core.SliderPreferenceController;
 import com.android.settings.core.TogglePreferenceController;
@@ -67,9 +68,6 @@
 
     private static final String TAG = "SliceBuilder";
 
-    // A Slice should not be store for longer than 60,000 milliseconds / 1 minute.
-    public static final long SLICE_TTL_MILLIS = 60000;
-
     /**
      * Build a Slice from {@link SliceData}.
      *
@@ -190,7 +188,12 @@
      */
     public static CharSequence getSubtitleText(Context context,
             AbstractPreferenceController controller, SliceData sliceData) {
-        CharSequence summaryText;
+        CharSequence summaryText = sliceData.getScreenTitle();
+        if (isValidSummary(context, summaryText) && !TextUtils.equals(summaryText,
+                sliceData.getTitle())) {
+            return summaryText;
+        }
+
         if (controller != null) {
             summaryText = controller.getSummary();
 
@@ -234,13 +237,15 @@
         final PendingIntent contentIntent = getContentPendingIntent(context, sliceData);
         final IconCompat icon = IconCompat.createWithResource(context, sliceData.getIconResource());
         final CharSequence subtitleText = getSubtitleText(context, controller, sliceData);
+        @ColorInt final int color = Utils.getColorAccent(context);
         final TogglePreferenceController toggleController =
                 (TogglePreferenceController) controller;
         final SliceAction sliceAction = getToggleAction(context, sliceData,
                 toggleController.isChecked());
         final List<String> keywords = buildSliceKeywords(sliceData);
 
-        return new ListBuilder(context, sliceData.getUri(), SLICE_TTL_MILLIS)
+        return new ListBuilder(context, sliceData.getUri(), ListBuilder.INFINITY)
+                .setAccentColor(color)
                 .addRow(rowBuilder -> rowBuilder
                         .setTitle(sliceData.getTitle())
                         .setSubtitle(subtitleText)
@@ -256,9 +261,11 @@
         final PendingIntent contentIntent = getContentPendingIntent(context, sliceData);
         final IconCompat icon = IconCompat.createWithResource(context, sliceData.getIconResource());
         final CharSequence subtitleText = getSubtitleText(context, controller, sliceData);
+        @ColorInt final int color = Utils.getColorAccent(context);
         final List<String> keywords = buildSliceKeywords(sliceData);
 
-        return new ListBuilder(context, sliceData.getUri(), SLICE_TTL_MILLIS)
+        return new ListBuilder(context, sliceData.getUri(), ListBuilder.INFINITY)
+                .setAccentColor(color)
                 .addRow(rowBuilder -> rowBuilder
                         .setTitle(sliceData.getTitle())
                         .setSubtitle(subtitleText)
@@ -274,11 +281,13 @@
         final PendingIntent actionIntent = getSliderAction(context, sliceData);
         final PendingIntent contentIntent = getContentPendingIntent(context, sliceData);
         final IconCompat icon = IconCompat.createWithResource(context, sliceData.getIconResource());
+        @ColorInt final int color = Utils.getColorAccent(context);
         final SliceAction primaryAction = new SliceAction(contentIntent, icon,
                 sliceData.getTitle());
         final List<String> keywords = buildSliceKeywords(sliceData);
 
-        return new ListBuilder(context, sliceData.getUri(), SLICE_TTL_MILLIS)
+        return new ListBuilder(context, sliceData.getUri(), ListBuilder.INFINITY)
+                .setAccentColor(color)
                 .addInputRange(builder -> builder
                         .setTitle(sliceData.getTitle())
                         .setMax(sliderController.getMaxSteps())
@@ -346,6 +355,7 @@
             BasePreferenceController controller) {
         final String title = data.getTitle();
         final List<String> keywords = buildSliceKeywords(data);
+        @ColorInt final int color = Utils.getColorAccent(context);
         final String summary;
         final SliceAction primaryAction;
         final IconCompat icon = IconCompat.createWithResource(context, data.getIconResource());
@@ -371,7 +381,8 @@
                 primaryAction = new SliceAction(getSettingsIntent(context), icon, title);
         }
 
-        return new ListBuilder(context, data.getUri(), SLICE_TTL_MILLIS)
+        return new ListBuilder(context, data.getUri(), ListBuilder.INFINITY)
+                .setAccentColor(color)
                 .addRow(builder -> builder
                         .setTitle(title)
                         .setSubtitle(summary)
diff --git a/src/com/android/settings/sound/AudioSwitchPreferenceController.java b/src/com/android/settings/sound/AudioSwitchPreferenceController.java
index dde2b30..6d9d3a4 100644
--- a/src/com/android/settings/sound/AudioSwitchPreferenceController.java
+++ b/src/com/android/settings/sound/AudioSwitchPreferenceController.java
@@ -78,6 +78,7 @@
     protected final LocalBluetoothProfileManager mProfileManager;
     protected int mSelectedIndex;
     protected Preference mPreference;
+    protected AudioSwitchCallback mAudioSwitchPreferenceCallback;
 
     private final AudioManagerAudioDeviceCallback mAudioManagerAudioDeviceCallback;
     private final LocalBluetoothManager mLocalBluetoothManager;
@@ -85,6 +86,10 @@
     private final WiredHeadsetBroadcastReceiver mReceiver;
     private final Handler mHandler;
 
+    public interface AudioSwitchCallback {
+        void onPreferenceDataChanged(ListPreference preference);
+    }
+
     public AudioSwitchPreferenceController(Context context, String preferenceKey) {
         super(context, preferenceKey);
         mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
@@ -207,6 +212,10 @@
     public void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState) {
     }
 
+    public void setCallback(AudioSwitchCallback callback) {
+        mAudioSwitchPreferenceCallback = callback;
+    }
+
     protected boolean isStreamFromOutputDevice(int streamType, int device) {
         return (device & mAudioManager.getDevicesForStream(streamType)) != 0;
     }
@@ -335,6 +344,7 @@
         listPreference.setEntryValues(mediaValues);
         listPreference.setValueIndex(mSelectedIndex);
         listPreference.setSummary(mediaOutputs[mSelectedIndex]);
+        mAudioSwitchPreferenceCallback.onPreferenceDataChanged(listPreference);
     }
 
     private int getConnectedDeviceIndex(String hardwareAddress) {
diff --git a/src/com/android/settings/widget/EntityHeaderController.java b/src/com/android/settings/widget/EntityHeaderController.java
index 5131159..6d67eb4 100644
--- a/src/com/android/settings/widget/EntityHeaderController.java
+++ b/src/com/android/settings/widget/EntityHeaderController.java
@@ -18,7 +18,6 @@
 
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent
         .ACTION_OPEN_APP_NOTIFICATION_SETTING;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_OPEN_APP_SETTING;
 
 import android.annotation.IdRes;
 import android.annotation.UserIdInt;
@@ -28,7 +27,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageInfo;
-import android.content.pm.ResolveInfo;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
@@ -59,15 +57,13 @@
 public class EntityHeaderController {
 
     @IntDef({ActionType.ACTION_NONE,
-            ActionType.ACTION_APP_PREFERENCE,
             ActionType.ACTION_NOTIF_PREFERENCE,
             ActionType.ACTION_DND_RULE_PREFERENCE,})
     @Retention(RetentionPolicy.SOURCE)
     public @interface ActionType {
         int ACTION_NONE = 0;
-        int ACTION_APP_PREFERENCE = 1;
-        int ACTION_NOTIF_PREFERENCE = 2;
-        int ACTION_DND_RULE_PREFERENCE = 3;
+        int ACTION_NOTIF_PREFERENCE = 1;
+        int ACTION_DND_RULE_PREFERENCE = 2;
     }
 
     public static final String PREF_KEY_APP_HEADER = "pref_app_header";
@@ -298,9 +294,9 @@
             @Override
             public void onClick(View v) {
                 AppInfoBase.startAppInfoFragment(
-                    AppInfoDashboardFragment.class, R.string.application_info_label,
-                    mPackageName, mUid, mFragment, 0 /* request */,
-                    mMetricsCategory);
+                        AppInfoDashboardFragment.class, R.string.application_info_label,
+                        mPackageName, mUid, mFragment, 0 /* request */,
+                        mMetricsCategory);
             }
         });
         return;
@@ -371,27 +367,6 @@
                 }
                 return;
             }
-            case ActionType.ACTION_APP_PREFERENCE: {
-                final Intent intent = resolveIntent(
-                        new Intent(Intent.ACTION_APPLICATION_PREFERENCES).setPackage(mPackageName));
-                if (intent == null) {
-                    button.setImageDrawable(null);
-                    button.setVisibility(View.GONE);
-                    return;
-                }
-                button.setOnClickListener(new View.OnClickListener() {
-                    @Override
-                    public void onClick(View v) {
-                        FeatureFactory.getFactory(mAppContext).getMetricsFeatureProvider()
-                                .actionWithSource(mAppContext, mMetricsCategory,
-                                        ACTION_OPEN_APP_SETTING);
-                        mFragment.startActivity(intent);
-                    }
-                });
-                button.setImageResource(R.drawable.ic_settings_24dp);
-                button.setVisibility(View.VISIBLE);
-                return;
-            }
             case ActionType.ACTION_NONE: {
                 button.setVisibility(View.GONE);
                 return;
@@ -399,14 +374,6 @@
         }
     }
 
-    private Intent resolveIntent(Intent i) {
-        ResolveInfo result = mAppContext.getPackageManager().resolveActivity(i, 0);
-        if (result != null) {
-            return new Intent(i.getAction())
-                    .setClassName(result.activityInfo.packageName, result.activityInfo.name);
-        }
-        return null;
-    }
 
     private void setText(@IdRes int id, CharSequence text) {
         TextView textView = mHeader.findViewById(id);
diff --git a/src/com/android/settings/widget/UpdatableListPreferenceDialogFragment.java b/src/com/android/settings/widget/UpdatableListPreferenceDialogFragment.java
new file mode 100644
index 0000000..9369778
--- /dev/null
+++ b/src/com/android/settings/widget/UpdatableListPreferenceDialogFragment.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright 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.widget;
+
+import android.app.AlertDialog;
+import android.content.res.TypedArray;
+import android.os.Bundle;
+import android.support.annotation.VisibleForTesting;
+import android.support.v14.preference.PreferenceDialogFragment;
+import android.support.v7.preference.ListPreference;
+import android.widget.ArrayAdapter;
+import com.android.settingslib.core.instrumentation.Instrumentable;
+
+import java.util.ArrayList;
+
+/**
+ * {@link PreferenceDialogFragment} that updates the available options
+ * when {@code onListPreferenceUpdated} is called."
+ */
+public class UpdatableListPreferenceDialogFragment extends PreferenceDialogFragment implements
+        Instrumentable {
+
+    private static final String SAVE_STATE_INDEX = "UpdatableListPreferenceDialogFragment.index";
+    private static final String SAVE_STATE_ENTRIES =
+            "UpdatableListPreferenceDialogFragment.entries";
+    private static final String SAVE_STATE_ENTRY_VALUES =
+            "UpdatableListPreferenceDialogFragment.entryValues";
+    private static final String METRICS_CATEGORY_KEY = "metrics_category_key";
+    private ArrayAdapter mAdapter;
+    private int mClickedDialogEntryIndex;
+    private ArrayList<CharSequence> mEntries;
+    private CharSequence[] mEntryValues;
+    private int mMetricsCategory = Instrumentable.METRICS_CATEGORY_UNKNOWN;
+
+    public static UpdatableListPreferenceDialogFragment newInstance(
+            String key, int metricsCategory) {
+        UpdatableListPreferenceDialogFragment fragment =
+                new UpdatableListPreferenceDialogFragment();
+        Bundle args = new Bundle(1);
+        args.putString(ARG_KEY, key);
+        args.putInt(METRICS_CATEGORY_KEY, metricsCategory);
+        fragment.setArguments(args);
+        return fragment;
+    }
+
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        final Bundle bundle = getArguments();
+        mMetricsCategory =
+                bundle.getInt(METRICS_CATEGORY_KEY, Instrumentable.METRICS_CATEGORY_UNKNOWN);
+        if (savedInstanceState == null) {
+            mEntries = new ArrayList<>();
+            setPreferenceData(getListPreference());
+        } else {
+            mClickedDialogEntryIndex = savedInstanceState.getInt(SAVE_STATE_INDEX, 0);
+            mEntries = savedInstanceState.getCharSequenceArrayList(SAVE_STATE_ENTRIES);
+            mEntryValues =
+                    savedInstanceState.getCharSequenceArray(SAVE_STATE_ENTRY_VALUES);
+        }
+    }
+
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putInt(SAVE_STATE_INDEX, mClickedDialogEntryIndex);
+        outState.putCharSequenceArrayList(SAVE_STATE_ENTRIES, mEntries);
+        outState.putCharSequenceArray(SAVE_STATE_ENTRY_VALUES, mEntryValues);
+    }
+
+    @Override
+    public void onDialogClosed(boolean positiveResult) {
+        final ListPreference preference = getListPreference();
+        if (positiveResult && mClickedDialogEntryIndex >= 0) {
+            final String value = mEntryValues[mClickedDialogEntryIndex].toString();
+            if (preference.callChangeListener(value)) {
+                preference.setValue(value);
+            }
+        }
+    }
+
+    @VisibleForTesting
+    void setAdapter(ArrayAdapter adapter) {
+        mAdapter = adapter;
+    }
+
+    @VisibleForTesting
+    void setEntries(ArrayList<CharSequence> entries) {
+        mEntries = entries;
+    }
+
+    @VisibleForTesting
+    ArrayAdapter getAdapter() {
+        return mAdapter;
+    }
+
+    @VisibleForTesting
+    void setMetricsCategory(Bundle bundle) {
+        mMetricsCategory =
+                bundle.getInt(METRICS_CATEGORY_KEY, Instrumentable.METRICS_CATEGORY_UNKNOWN);
+    }
+
+    @Override
+    protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
+        super.onPrepareDialogBuilder(builder);
+        final TypedArray a = getContext().obtainStyledAttributes(
+                null,
+                com.android.internal.R.styleable.AlertDialog,
+                com.android.internal.R.attr.alertDialogStyle, 0);
+
+        mAdapter = new ArrayAdapter<>(
+                getContext(),
+                a.getResourceId(
+                        com.android.internal.R.styleable.AlertDialog_singleChoiceItemLayout,
+                        com.android.internal.R.layout.select_dialog_singlechoice),
+                mEntries);
+
+        builder.setSingleChoiceItems(mAdapter, mClickedDialogEntryIndex,
+                (dialog, which) -> {
+                    mClickedDialogEntryIndex = which;
+                    onClick(dialog, -1);
+                    dialog.dismiss();
+                });
+        builder.setPositiveButton(null, null);
+        a.recycle();
+    }
+
+    @Override
+    public int getMetricsCategory() {
+        return mMetricsCategory;
+    }
+
+    private ListPreference getListPreference() {
+        return (ListPreference) getPreference();
+    }
+
+    private void setPreferenceData(ListPreference preference) {
+        mEntries.clear();
+        mClickedDialogEntryIndex = preference.findIndexOfValue(preference.getValue());
+        for (CharSequence entry : preference.getEntries()) {
+            mEntries.add(entry);
+        }
+        mEntryValues = preference.getEntryValues();
+    }
+
+    public void onListPreferenceUpdated(ListPreference preference) {
+        if (mAdapter != null) {
+            setPreferenceData(preference);
+            mAdapter.notifyDataSetChanged();
+        }
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/accessibility/MagnificationGesturesPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/MagnificationGesturesPreferenceControllerTest.java
index 23ac795..cd0558a 100644
--- a/tests/robotests/src/com/android/settings/accessibility/MagnificationGesturesPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/MagnificationGesturesPreferenceControllerTest.java
@@ -16,6 +16,9 @@
 
 package com.android.settings.accessibility;
 
+import static com.android.settings.accessibility.MagnificationPreferenceFragment.OFF;
+import static com.android.settings.accessibility.MagnificationPreferenceFragment.ON;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import android.content.Context;
@@ -57,13 +60,13 @@
     @Test
     public void updateState_shouldRefreshSummary() {
         Settings.System.putInt(mContext.getContentResolver(),
-                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, 1);
+                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, ON);
         mController.updateState(mPreference);
         assertThat(mPreference.getSummary())
                 .isEqualTo(mContext.getString(R.string.accessibility_feature_state_on));
 
         Settings.System.putInt(mContext.getContentResolver(),
-                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, 0);
+                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, OFF);
         mController.updateState(mPreference);
         assertThat(mPreference.getSummary())
                 .isEqualTo(mContext.getString(R.string.accessibility_feature_state_off));
@@ -77,4 +80,38 @@
                 .isEqualTo(mContext.getString(R.string.
                         accessibility_screen_magnification_short_summary));
     }
+
+    @Test
+    public void isChecked_enabled() {
+        Settings.System.putInt(mContext.getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, ON);
+
+        assertThat(mController.isChecked()).isTrue();
+    }
+
+    @Test
+    public void isChecked_disabled() {
+        Settings.System.putInt(mContext.getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, OFF);
+
+        assertThat(mController.isChecked()).isFalse();
+    }
+
+    @Test
+    public void setChecked_enabled() {
+        mController.setChecked(true);
+
+        assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, -1))
+                .isEqualTo(ON);
+    }
+
+    @Test
+    public void setChecked_disabled() {
+        mController.setChecked(false);
+
+        assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, -1))
+                .isEqualTo(OFF);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/accessibility/MagnificationNavbarPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/MagnificationNavbarPreferenceControllerTest.java
index 486ccd3..bca81a2 100644
--- a/tests/robotests/src/com/android/settings/accessibility/MagnificationNavbarPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/MagnificationNavbarPreferenceControllerTest.java
@@ -16,8 +16,12 @@
 
 package com.android.settings.accessibility;
 
+import static com.android.settings.accessibility.MagnificationPreferenceFragment.OFF;
+import static com.android.settings.accessibility.MagnificationPreferenceFragment.ON;
 import static com.android.settings.search.ResultPayload.Availability.AVAILABLE;
+
 import static com.google.common.truth.Truth.assertThat;
+
 import static org.mockito.Mockito.spy;
 
 import android.content.Context;
@@ -81,13 +85,13 @@
     @Test
     public void updateState_shouldRefreshSummary() {
         Settings.System.putInt(mContext.getContentResolver(),
-                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED, 1);
+                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED, ON);
         mController.updateState(mPreference);
         assertThat(mPreference.getSummary())
                 .isEqualTo(mContext.getText(R.string.accessibility_feature_state_on));
 
         Settings.System.putInt(mContext.getContentResolver(),
-                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED, 0);
+                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED, OFF);
         mController.updateState(mPreference);
         assertThat(mPreference.getSummary())
                 .isEqualTo(mContext.getText(R.string.accessibility_feature_state_off));
@@ -102,6 +106,40 @@
                         accessibility_screen_magnification_navbar_short_summary));
     }
 
+    @Test
+    public void isChecked_enabled() {
+        Settings.System.putInt(mContext.getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED, ON);
+
+        assertThat(mController.isChecked()).isTrue();
+    }
+
+    @Test
+    public void isChecked_disabled() {
+        Settings.System.putInt(mContext.getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED, OFF);
+
+        assertThat(mController.isChecked()).isFalse();
+    }
+
+    @Test
+    public void setChecked_enabled() {
+        mController.setChecked(true);
+
+        assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED, -1))
+                .isEqualTo(ON);
+    }
+
+    @Test
+    public void setChecked_disabled() {
+        mController.setChecked(false);
+
+        assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED, -1))
+                .isEqualTo(OFF);
+    }
+
     @Implements(MagnificationPreferenceFragment.class)
     public static class ShadowMagnificationPreferenceFragment {
         private static boolean sIsApplicable;
diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/AppSettingPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/AppSettingPreferenceControllerTest.java
new file mode 100644
index 0000000..66b58c8
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/applications/appinfo/AppSettingPreferenceControllerTest.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.applications.appinfo;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.robolectric.Shadows.shadowOf;
+
+import android.app.Application;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ResolveInfo;
+import android.support.v7.preference.Preference;
+
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadows.ShadowPackageManager;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class AppSettingPreferenceControllerTest {
+
+    private static final String TEST_PKG_NAME = "test_pkg";
+    private static final String TEST_CLASS_NAME = "name";
+    private static final Intent TEST_INTENT =
+        new Intent(Intent.ACTION_APPLICATION_PREFERENCES)
+            .setClassName(TEST_PKG_NAME, TEST_CLASS_NAME);
+    private static final Intent RESOLVED_INTENT =
+        new Intent(Intent.ACTION_APPLICATION_PREFERENCES)
+            .setPackage(TEST_PKG_NAME);
+
+    @Mock
+    private AppInfoDashboardFragment mParent;
+    private Application mApplication;
+    private ShadowPackageManager mPackageManager;
+    private AppSettingPreferenceController mController;
+    private Preference mPreference;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mApplication = RuntimeEnvironment.application;
+        mPackageManager = shadowOf(mApplication.getPackageManager());
+        mController = new AppSettingPreferenceController(mApplication, "test_key");
+        mController.setPackageName(TEST_PKG_NAME).setParentFragment(mParent);
+        mPreference = new Preference(mApplication);
+        mPreference.setKey(mController.getPreferenceKey());
+    }
+
+    @Test
+    public void getAvailabilityStatus_noAppSetting_shouldNotBeAvailable() {
+        assertThat(mController.isAvailable())
+                .isFalse();
+    }
+
+    @Test
+    public void getAvailabilityStatus_noPackageName_shouldNotBeAvailable() {
+        mController.setPackageName(null);
+
+        assertThat(mController.isAvailable())
+                .isFalse();
+    }
+
+    @Test
+    public void getAvailabilityStatus_hasAppSetting_shouldBeAvailable() {
+        final ResolveInfo info = new ResolveInfo();
+        info.activityInfo = new ActivityInfo();
+        info.activityInfo.packageName = TEST_PKG_NAME;
+        info.activityInfo.name = TEST_CLASS_NAME;
+
+        mPackageManager.addResolveInfoForIntent(RESOLVED_INTENT, info);
+
+        assertThat(mController.isAvailable())
+                .isTrue();
+    }
+
+    @Test
+    public void clickPreference_noAppSetting_shouldDoNothing() {
+        assertThat(mController.handlePreferenceTreeClick(mPreference)).isFalse();
+    }
+
+    @Test
+    public void clickPreference_hasAppSetting_shouldLaunchIntent() {
+        final ResolveInfo info = new ResolveInfo();
+        info.activityInfo = new ActivityInfo();
+        info.activityInfo.packageName = TEST_PKG_NAME;
+        info.activityInfo.name = TEST_CLASS_NAME;
+
+        mPackageManager.addResolveInfoForIntent(RESOLVED_INTENT, info);
+
+        assertThat(mController.handlePreferenceTreeClick(mPreference)).isTrue();
+        assertThat(shadowOf(mApplication).getNextStartedActivity().getComponent())
+            .isEqualTo(TEST_INTENT.getComponent());
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceControllerTest.java
index f5070ef..1d37883 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceControllerTest.java
@@ -43,6 +43,7 @@
 
     private static final String DEVICE_NAME = "Nightshade";
     private static final int ORDER = 1;
+    private static final String KEY_DEVICE_NAME = "test_key_name";
 
     private Context mContext;
     @Mock
@@ -61,8 +62,9 @@
 
         when(mPreferenceScreen.getContext()).thenReturn(mContext);
         mPreference = new Preference(mContext);
-        mPreference.setKey(BluetoothDeviceNamePreferenceController.KEY_DEVICE_NAME);
-        mController = spy(new BluetoothDeviceNamePreferenceController(mContext, mLocalAdapter));
+        mPreference.setKey(KEY_DEVICE_NAME);
+        mController = spy(new BluetoothDeviceNamePreferenceController(mContext, mLocalAdapter,
+                KEY_DEVICE_NAME));
         doReturn(DEVICE_NAME).when(mController).getDeviceName();
     }
 
@@ -82,7 +84,7 @@
         Preference preference =
             mController.createBluetoothDeviceNamePreference(mPreferenceScreen, ORDER);
 
-        assertThat(preference.getKey()).isEqualTo(mController.KEY_DEVICE_NAME);
+        assertThat(preference.getKey()).isEqualTo(mController.getPreferenceKey());
         assertThat(preference.getOrder()).isEqualTo(ORDER);
         verify(mPreferenceScreen).addPreference(preference);
     }
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceControllerTest.java
index 6ba8593..65eae2c 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceControllerTest.java
@@ -67,8 +67,9 @@
         mPreference = new Preference(mContext);
         mPreference.setKey(PREF_KEY);
 
-        mController = spy(new BluetoothDeviceRenamePreferenceController(
-                mContext, PREF_KEY, mFragment, mLocalAdapter));
+        mController = spy(new BluetoothDeviceRenamePreferenceController(mContext, mLocalAdapter,
+                PREF_KEY));
+        mController.setFragment(mFragment);
         doReturn(DEVICE_NAME).when(mController).getDeviceName();
     }
 
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImplTest.java
index 70acb73..6d18109 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImplTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImplTest.java
@@ -17,6 +17,7 @@
 package com.android.settings.fuelgauge;
 
 import static com.google.common.truth.Truth.assertThat;
+
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
@@ -29,6 +30,7 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Answers;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
@@ -43,7 +45,7 @@
     private static final String[] PACKAGES_MEDIA = {"com.android.providers.media"};
     private static final String[] PACKAGES_SYSTEMUI = {"com.android.systemui"};
 
-    @Mock
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     private Context mContext;
     @Mock
     private BatterySipper mBatterySipper;
@@ -55,6 +57,7 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
 
+        when(mContext.getApplicationContext()).thenReturn(mContext);
         mPowerFeatureProvider = new PowerUsageFeatureProviderImpl(mContext);
         when(mPackageManager.getPackagesForUid(UID_CALENDAR)).thenReturn(PACKAGES_CALENDAR);
         when(mPackageManager.getPackagesForUid(UID_MEDIA)).thenReturn(PACKAGES_MEDIA);
@@ -138,7 +141,18 @@
     }
 
     @Test
-    public void testIsSmartBatterySupported_returnFalse() {
+    public void testIsSmartBatterySupported_smartBatterySupported_returnTrue() {
+        when(mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_smart_battery_available)).thenReturn(true);
+
+        assertThat(mPowerFeatureProvider.isSmartBatterySupported()).isTrue();
+    }
+
+    @Test
+    public void testIsSmartBatterySupported_smartBatteryNotSupported_returnFalse() {
+        when(mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_smart_battery_available)).thenReturn(false);
+
         assertThat(mPowerFeatureProvider.isSmartBatterySupported()).isFalse();
     }
 }
diff --git a/tests/robotests/src/com/android/settings/gestures/SwipeUpPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/SwipeUpPreferenceControllerTest.java
index 4107b73..3585650 100644
--- a/tests/robotests/src/com/android/settings/gestures/SwipeUpPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/SwipeUpPreferenceControllerTest.java
@@ -27,7 +27,7 @@
 import android.os.UserManager;
 import android.provider.Settings;
 
-import com.android.settings.R;
+import com.android.internal.R;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.SettingsShadowResources;
 
@@ -57,8 +57,7 @@
     public void setUp() {
         SettingsShadowResources.overrideResource(R.bool.config_swipe_up_gesture_setting_available,
                 true);
-        SettingsShadowResources.overrideResource(
-                com.android.internal.R.bool.config_swipe_up_gesture_default, true);
+        SettingsShadowResources.overrideResource(R.bool.config_swipe_up_gesture_default, true);
 
         mContext = RuntimeEnvironment.application;
         mPackageManager = Shadows.shadowOf(mContext.getPackageManager());
@@ -107,8 +106,7 @@
 
     @Test
     public void testIsChecked_defaultIsFalse_shouldReturnFalse() {
-        SettingsShadowResources.overrideResource(
-                com.android.internal.R.bool.config_swipe_up_gesture_default, false);
+        SettingsShadowResources.overrideResource(R.bool.config_swipe_up_gesture_default, false);
         assertThat(mController.isChecked()).isFalse();
     }
 
diff --git a/tests/robotests/src/com/android/settings/network/TetherPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/TetherPreferenceControllerTest.java
index 6166d29..ac573b4 100644
--- a/tests/robotests/src/com/android/settings/network/TetherPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/TetherPreferenceControllerTest.java
@@ -75,10 +75,21 @@
 
     @Test
     public void lifeCycle_onCreate_shouldInitBluetoothPan() {
+        when(mBluetoothAdapter.getState()).thenReturn(BluetoothAdapter.STATE_ON);
         mController.onCreate(null);
 
-        verify(mBluetoothAdapter)
-            .getProfileProxy(mContext, mController.mBtProfileServiceListener, BluetoothProfile.PAN);
+        verify(mBluetoothAdapter).getState();
+        verify(mBluetoothAdapter).getProfileProxy(mContext, mController.mBtProfileServiceListener,
+                BluetoothProfile.PAN);
+    }
+
+    @Test
+    public void lifeCycle_onCreate_shouldNotInitBluetoothPanWhenBluetoothOff() {
+        when(mBluetoothAdapter.getState()).thenReturn(BluetoothAdapter.STATE_OFF);
+        mController.onCreate(null);
+
+        verify(mBluetoothAdapter).getState();
+        verifyNoMoreInteractions(mBluetoothAdapter);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/notification/VibrateWhenRingPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/VibrateWhenRingPreferenceControllerTest.java
index 9314109..4e69c46 100644
--- a/tests/robotests/src/com/android/settings/notification/VibrateWhenRingPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/VibrateWhenRingPreferenceControllerTest.java
@@ -17,11 +17,17 @@
 package com.android.settings.notification;
 
 import static android.provider.Settings.System.VIBRATE_WHEN_RINGING;
+
+import static com.android.settings.core.BasePreferenceController.AVAILABLE;
+import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
+
 import static com.google.common.truth.Truth.assertThat;
+
 import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
 
+import android.content.ContentResolver;
 import android.content.Context;
 import android.provider.Settings;
 import android.support.v7.preference.Preference;
@@ -37,26 +43,32 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadow.api.Shadow;
+import org.robolectric.shadows.ShadowContentResolver;
 
 @RunWith(SettingsRobolectricTestRunner.class)
 public class VibrateWhenRingPreferenceControllerTest {
 
-    @Mock
+    private static final String KEY_VIBRATE_WHEN_RINGING = "vibrate_when_ringing";
+    private final int DEFAULT_VALUE = 0;
+    private final int NOTIFICATION_VIBRATE_WHEN_RINGING = 1;
     private Context mContext;
+    private ContentResolver mContentResolver;
     @Mock
     private PreferenceScreen mScreen;
     @Mock
     private TelephonyManager mTelephonyManager;
-
     private VibrateWhenRingPreferenceController mController;
     private Preference mPreference;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
+        mContext = spy(RuntimeEnvironment.application);
+        mContentResolver = mContext.getContentResolver();
         when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
-        mController = new VibrateWhenRingPreferenceController(mContext);
-        mPreference = new Preference(RuntimeEnvironment.application);
+        mController = new VibrateWhenRingPreferenceController(mContext, KEY_VIBRATE_WHEN_RINGING);
+        mPreference = new Preference(mContext);
         mPreference.setKey(mController.getPreferenceKey());
         when(mScreen.findPreference(mPreference.getKey())).thenReturn(mPreference);
     }
@@ -80,26 +92,95 @@
     }
 
     @Test
+    public void testOnPreferenceChange_turnOn_returnOn() {
+        mController.onPreferenceChange(null, true);
+        final int mode = Settings.System.getInt(mContext.getContentResolver(),
+                VIBRATE_WHEN_RINGING, DEFAULT_VALUE);
+
+        assertThat(mode).isEqualTo(NOTIFICATION_VIBRATE_WHEN_RINGING);
+    }
+
+    @Test
+    public void testOnPreferenceChange_turnOff_returnOff() {
+        mController.onPreferenceChange(null, false);
+        final int mode = Settings.System.getInt(mContext.getContentResolver(),
+                VIBRATE_WHEN_RINGING, DEFAULT_VALUE);
+
+        assertThat(mode).isEqualTo(DEFAULT_VALUE);
+    }
+
+    @Test
+    public void voiceCapable_availabled() {
+        when(mTelephonyManager.isVoiceCapable()).thenReturn(true);
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
+    }
+
+    @Test
+    public void voiceCapable_notAvailabled() {
+        when(mTelephonyManager.isVoiceCapable()).thenReturn(false);
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
+    }
+
+    @Test
     public void updateState_settingIsOn_preferenceShouldBeChecked() {
         final TwoStatePreference preference = mock(TwoStatePreference.class);
-        final Context context = RuntimeEnvironment.application;
-        Settings.System.putInt(context.getContentResolver(), VIBRATE_WHEN_RINGING, 1);
+        Settings.System.putInt(mContext.getContentResolver(), VIBRATE_WHEN_RINGING, 1);
 
-        mController = new VibrateWhenRingPreferenceController(context);
         mController.updateState(preference);
 
-        verify(preference).setChecked(true);
+        assertThat(mController.isChecked()).isTrue();
     }
 
     @Test
     public void updateState_settingIsOff_preferenceShouldNotBeChecked() {
         final TwoStatePreference preference = mock(TwoStatePreference.class);
-        final Context context = RuntimeEnvironment.application;
-        Settings.System.putInt(context.getContentResolver(), VIBRATE_WHEN_RINGING, 0);
+        Settings.System.putInt(mContext.getContentResolver(), VIBRATE_WHEN_RINGING, 0);
 
-        mController = new VibrateWhenRingPreferenceController(context);
         mController.updateState(preference);
 
-        verify(preference).setChecked(false);
+        assertThat(mController.isChecked()).isFalse();
+    }
+
+    @Test
+    public void setChecked_settingsIsOn() {
+        mController.setChecked(true);
+        final int mode = Settings.System.getInt(mContext.getContentResolver(), VIBRATE_WHEN_RINGING,
+                -1);
+
+        assertThat(mode).isEqualTo(NOTIFICATION_VIBRATE_WHEN_RINGING);
+    }
+
+    @Test
+    public void setChecked_settingsIsOff() {
+        mController.setChecked(false);
+        final int mode = Settings.System.getInt(mContext.getContentResolver(), VIBRATE_WHEN_RINGING,
+                -1);
+
+        assertThat(mode).isEqualTo(DEFAULT_VALUE);
+    }
+
+    @Test
+    public void testObserver_onResume_shouldRegisterObserver() {
+        final ShadowContentResolver shadowContentResolver = Shadow.extract(mContentResolver);
+        mController.displayPreference(mScreen);
+
+        mController.onResume();
+
+        assertThat(shadowContentResolver.getContentObservers(
+                Settings.System.getUriFor(VIBRATE_WHEN_RINGING))).isNotEmpty();
+    }
+
+    @Test
+    public void testObserver_onPause_shouldUnregisterObserver() {
+        final ShadowContentResolver shadowContentResolver = Shadow.extract(mContentResolver);
+        mController.displayPreference(mScreen);
+
+        mController.onResume();
+        mController.onPause();
+
+        assertThat(shadowContentResolver.getContentObservers(
+                Settings.System.getUriFor(VIBRATE_WHEN_RINGING))).isEmpty();
     }
 }
diff --git a/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java b/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java
index bd589bf..00e8fe1 100644
--- a/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java
@@ -204,18 +204,18 @@
     }
 
     @Test
-    public void testDynamicSummary_returnsSliceSummary() {
+    public void getDynamicSummary_returnsScreenTitle() {
         final SliceData data = getDummyData();
         final FakePreferenceController controller = new FakePreferenceController(mContext, KEY);
 
         final CharSequence summary = SliceBuilderUtils.getSubtitleText(mContext, controller, data);
 
-        assertThat(summary).isEqualTo(data.getSummary());
+        assertThat(summary).isEqualTo(data.getScreenTitle());
     }
 
     @Test
-    public void testDynamicSummary_returnsFragmentSummary() {
-        final SliceData data = getDummyData(null);
+    public void getDynamicSummary_noScreenTitle_returnsPrefControllerSummary() {
+        final SliceData data = getDummyData("", "");
         final FakePreferenceController controller = spy(
                 new FakePreferenceController(mContext, KEY));
         final String controllerSummary = "new_Summary";
@@ -227,8 +227,21 @@
     }
 
     @Test
-    public void testDynamicSummary_returnsSliceEmptyString() {
-        final SliceData data = getDummyData(null);
+    public void getDynamicSummary_screenTitleMatchesTitle_returnsPrefControllerSummary() {
+        final SliceData data = getDummyData("", TITLE);
+        final FakePreferenceController controller = spy(
+                new FakePreferenceController(mContext, KEY));
+        final String controllerSummary = "new_Summary";
+        doReturn(controllerSummary).when(controller).getSummary();
+
+        final CharSequence summary = SliceBuilderUtils.getSubtitleText(mContext, controller, data);
+
+        assertThat(summary).isEqualTo(controllerSummary);
+    }
+
+    @Test
+    public void getDynamicSummary_emptyScreenTitle_emptyControllerSummary_returnsEmptyString() {
+        final SliceData data = getDummyData(null, null);
         final FakePreferenceController controller = new FakePreferenceController(mContext, KEY);
         final CharSequence summary = SliceBuilderUtils.getSubtitleText(mContext, controller, data);
 
@@ -236,8 +249,9 @@
     }
 
     @Test
-    public void testDynamicSummary_placeHolderString_returnsEmptyString() {
-        final SliceData data = getDummyData(mContext.getString(R.string.summary_placeholder));
+    public void
+    getDynamicSummary_emptyScreenTitle_placeHolderControllerSummary_returnsEmptyString() {
+        final SliceData data = getDummyData(mContext.getString(R.string.summary_placeholder), null);
         final FakePreferenceController controller = new FakePreferenceController(mContext, KEY);
         final CharSequence summary = SliceBuilderUtils.getSubtitleText(mContext, controller, data);
 
@@ -245,9 +259,9 @@
     }
 
     @Test
-    public void testDynamicSummary_sliceDataAndFragmentPlaceholder_returnsSliceEmptyString() {
+    public void getDynamicSummary_screenTitleAndControllerPlaceholder_returnsSliceEmptyString() {
         final String summaryPlaceholder = mContext.getString(R.string.summary_placeholder);
-        final SliceData data = getDummyData(summaryPlaceholder);
+        final SliceData data = getDummyData(summaryPlaceholder, summaryPlaceholder);
         final FakePreferenceController controller = spy(
                 new FakePreferenceController(mContext, KEY));
         doReturn(summaryPlaceholder).when(controller).getSummary();
@@ -258,18 +272,6 @@
     }
 
     @Test
-    public void summaryText_bothDynamicAndStaticSummary_dynamicSummaryReturned() {
-        SliceData data = getDummyData("bad_summary");
-        FakePreferenceController controller = spy(new FakePreferenceController(mContext, KEY));
-        String controllerSummary = "new_Summary";
-        doReturn(controllerSummary).when(controller).getSummary();
-
-        CharSequence summary = SliceBuilderUtils.getSubtitleText(mContext, controller, data);
-
-        assertThat(summary).isEqualTo(controllerSummary);
-    }
-
-    @Test
     public void getPathData_splitsIntentUri() {
         final Uri uri = new Uri.Builder()
                 .authority(SettingsSliceProvider.SLICE_AUTHORITY)
@@ -417,23 +419,24 @@
     }
 
     private SliceData getDummyData() {
-        return getDummyData(TOGGLE_CONTROLLER, SUMMARY, SliceData.SliceType.SWITCH);
+        return getDummyData(TOGGLE_CONTROLLER, SUMMARY, SliceData.SliceType.SWITCH, SCREEN_TITLE);
     }
 
-    private SliceData getDummyData(String summary) {
-        return getDummyData(TOGGLE_CONTROLLER, summary, SliceData.SliceType.SWITCH);
+    private SliceData getDummyData(String summary, String screenTitle) {
+        return getDummyData(TOGGLE_CONTROLLER, summary, SliceData.SliceType.SWITCH, screenTitle);
     }
 
     private SliceData getDummyData(Class prefController, int sliceType) {
-        return getDummyData(prefController, SUMMARY, sliceType);
+        return getDummyData(prefController, SUMMARY, sliceType, SCREEN_TITLE);
     }
 
-    private SliceData getDummyData(Class prefController, String summary, int sliceType) {
+    private SliceData getDummyData(Class prefController, String summary, int sliceType,
+            String screenTitle) {
         return new SliceData.Builder()
                 .setKey(KEY)
                 .setTitle(TITLE)
                 .setSummary(summary)
-                .setScreenTitle(SCREEN_TITLE)
+                .setScreenTitle(screenTitle)
                 .setKeywords(KEYWORDS)
                 .setIcon(ICON)
                 .setFragmentName(FRAGMENT_NAME)
diff --git a/tests/robotests/src/com/android/settings/sound/HandsFreeProfileOutputPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/sound/HandsFreeProfileOutputPreferenceControllerTest.java
index db09eab..6a573e0 100644
--- a/tests/robotests/src/com/android/settings/sound/HandsFreeProfileOutputPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/sound/HandsFreeProfileOutputPreferenceControllerTest.java
@@ -16,7 +16,6 @@
 
 package com.android.settings.sound;
 
-
 import static android.media.AudioSystem.DEVICE_OUT_BLUETOOTH_SCO;
 import static android.media.AudioSystem.DEVICE_OUT_HEARING_AID;
 import static android.media.AudioSystem.DEVICE_OUT_USB_HEADSET;
@@ -93,6 +92,8 @@
     private HeadsetProfile mHeadsetProfile;
     @Mock
     private HearingAidProfile mHearingAidProfile;
+    @Mock
+    private AudioSwitchPreferenceController.AudioSwitchCallback mAudioSwitchPreferenceCallback;
 
     private Context mContext;
     private PreferenceScreen mScreen;
@@ -156,6 +157,7 @@
         when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
         mScreen.addPreference(mPreference);
         mController.displayPreference(mScreen);
+        mController.setCallback(mAudioSwitchPreferenceCallback);
     }
 
     @After
diff --git a/tests/robotests/src/com/android/settings/sound/MediaOutputPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/sound/MediaOutputPreferenceControllerTest.java
index b777239..6aec5ef 100644
--- a/tests/robotests/src/com/android/settings/sound/MediaOutputPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/sound/MediaOutputPreferenceControllerTest.java
@@ -94,6 +94,8 @@
     private A2dpProfile mA2dpProfile;
     @Mock
     private HearingAidProfile mHearingAidProfile;
+    @Mock
+    private AudioSwitchPreferenceController.AudioSwitchCallback mAudioSwitchPreferenceCallback;
 
     private Context mContext;
     private PreferenceScreen mScreen;
@@ -157,6 +159,7 @@
         when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
         mScreen.addPreference(mPreference);
         mController.displayPreference(mScreen);
+        mController.setCallback(mAudioSwitchPreferenceCallback);
     }
 
     @After
diff --git a/tests/robotests/src/com/android/settings/testutils/SliceTester.java b/tests/robotests/src/com/android/settings/testutils/SliceTester.java
index 529e32d..4c4b040 100644
--- a/tests/robotests/src/com/android/settings/testutils/SliceTester.java
+++ b/tests/robotests/src/com/android/settings/testutils/SliceTester.java
@@ -17,6 +17,8 @@
 package com.android.settings.testutils;
 
 import static android.app.slice.Slice.HINT_TITLE;
+import static android.app.slice.Slice.SUBTYPE_COLOR;
+import static android.app.slice.SliceItem.FORMAT_INT;
 import static android.app.slice.SliceItem.FORMAT_TEXT;
 
 import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
@@ -37,11 +39,13 @@
 import androidx.slice.Slice;
 import androidx.slice.SliceItem;
 import androidx.slice.SliceMetadata;
+import androidx.slice.builders.ListBuilder;
 import androidx.slice.core.SliceAction;
 import androidx.slice.core.SliceQuery;
 
 import android.support.v4.graphics.drawable.IconCompat;
 
+import com.android.settings.Utils;
 import com.android.settings.slices.SettingsSliceProvider;
 import com.android.settings.slices.SliceBuilderUtils;
 import com.android.settings.slices.SliceData;
@@ -59,10 +63,19 @@
      * - Correct intent
      * - Correct title
      * - Correct keywords
+     * - TTL
+     * - Color
      */
     public static void testSettingsIntentSlice(Context context, Slice slice, SliceData sliceData) {
         final SliceMetadata metadata = SliceMetadata.from(context, slice);
 
+        final long sliceTTL = metadata.getExpiry();
+        assertThat(sliceTTL).isEqualTo(ListBuilder.INFINITY);
+
+        final SliceItem colorItem = SliceQuery.findSubtype(slice, FORMAT_INT, SUBTYPE_COLOR);
+        final int color = colorItem.getInt();
+        assertThat(color).isEqualTo(Utils.getColorAccent(context));
+
         final List<SliceAction> toggles = metadata.getToggles();
         assertThat(toggles).isEmpty();
 
@@ -83,13 +96,22 @@
      * - Correct content intent
      * - Correct title
      * - Correct keywords
+     * - TTL
+     * - Color
      */
     public static void testSettingsToggleSlice(Context context, Slice slice, SliceData sliceData) {
         final SliceMetadata metadata = SliceMetadata.from(context, slice);
 
+        final SliceItem colorItem = SliceQuery.findSubtype(slice, FORMAT_INT, SUBTYPE_COLOR);
+        final int color = colorItem.getInt();
+        assertThat(color).isEqualTo(Utils.getColorAccent(context));
+
         final List<SliceAction> toggles = metadata.getToggles();
         assertThat(toggles).hasSize(1);
 
+        final long sliceTTL = metadata.getExpiry();
+        assertThat(sliceTTL).isEqualTo(ListBuilder.INFINITY);
+
         final SliceAction mainToggleAction = toggles.get(0);
 
         final IconCompat expectedToggleIcon = IconCompat.createWithResource(context,
@@ -117,13 +139,22 @@
      * - No intent
      * - Correct title
      * - Correct keywords
+     * - TTL
+     * - Color
      */
     public static void testSettingsSliderSlice(Context context, Slice slice, SliceData sliceData) {
         final SliceMetadata metadata = SliceMetadata.from(context, slice);
 
+        final SliceItem colorItem = SliceQuery.findSubtype(slice, FORMAT_INT, SUBTYPE_COLOR);
+        final int color = colorItem.getInt();
+        assertThat(color).isEqualTo(Utils.getColorAccent(context));
+
         final IconCompat expectedToggleIcon = IconCompat.createWithResource(context,
                 sliceData.getIconResource());
 
+        final long sliceTTL = metadata.getExpiry();
+        assertThat(sliceTTL).isEqualTo(ListBuilder.INFINITY);
+
         // Check primary intent
         final PendingIntent primaryPendingIntent = metadata.getPrimaryAction().getAction();
         assertThat(primaryPendingIntent).isEqualTo(
@@ -141,11 +172,20 @@
      * - Correct title
      * - Correct intent
      * - Correct keywords
+     * - Color
+     * - TTL
      */
     public static void testSettingsUnavailableSlice(Context context, Slice slice,
             SliceData sliceData) {
         final SliceMetadata metadata = SliceMetadata.from(context, slice);
 
+        final long sliceTTL = metadata.getExpiry();
+        assertThat(sliceTTL).isEqualTo(ListBuilder.INFINITY);
+
+        final SliceItem colorItem = SliceQuery.findSubtype(slice, FORMAT_INT, SUBTYPE_COLOR);
+        final int color = colorItem.getInt();
+        assertThat(color).isEqualTo(Utils.getColorAccent(context));
+
         final List<SliceAction> toggles = metadata.getToggles();
         assertThat(toggles).isEmpty();
 
diff --git a/tests/robotests/src/com/android/settings/widget/EntityHeaderControllerTest.java b/tests/robotests/src/com/android/settings/widget/EntityHeaderControllerTest.java
index e32ef77..22ad764 100644
--- a/tests/robotests/src/com/android/settings/widget/EntityHeaderControllerTest.java
+++ b/tests/robotests/src/com/android/settings/widget/EntityHeaderControllerTest.java
@@ -41,7 +41,6 @@
 import android.widget.ImageButton;
 import android.widget.TextView;
 
-import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.R;
 import com.android.settings.applications.LayoutPreference;
 import com.android.settings.testutils.FakeFeatureFactory;
@@ -113,7 +112,7 @@
     public void bindViews_shouldBindAllData() {
         final String testString = "test";
         final View header =
-            mLayoutInflater.inflate(R.layout.settings_entity_header, null /* root */);
+                mLayoutInflater.inflate(R.layout.settings_entity_header, null /* root */);
         final TextView label = header.findViewById(R.id.entity_header_title);
         final TextView summary = header.findViewById(R.id.entity_header_summary);
         final TextView secondSummary = header.findViewById(R.id.entity_header_second_summary);
@@ -134,41 +133,6 @@
     }
 
     @Test
-    public void bindButton_hasAppPref_shouldShowButton() {
-        final ResolveInfo info = new ResolveInfo();
-        info.activityInfo = new ActivityInfo();
-        info.activityInfo.packageName = "123";
-        info.activityInfo.name = "321";
-        final View appLinks =
-            mLayoutInflater.inflate(R.layout.settings_entity_header, null /* root */);
-        when(mActivity.getApplicationContext()).thenReturn(mContext);
-        when(mContext.getPackageManager().resolveActivity(any(Intent.class), anyInt()))
-                .thenReturn(info);
-
-        mController = EntityHeaderController.newInstance(mActivity, mFragment, appLinks);
-        mController.setButtonActions(
-                EntityHeaderController.ActionType.ACTION_APP_PREFERENCE,
-                EntityHeaderController.ActionType.ACTION_NONE);
-        mController.done(mActivity);
-
-        final ImageButton button1 = appLinks.findViewById(android.R.id.button1);
-        assertThat(button1).isNotNull();
-        assertThat(button1.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(button1.getDrawable()).isNotNull();
-        assertThat(appLinks.findViewById(android.R.id.button2).getVisibility())
-                .isEqualTo(View.GONE);
-        try {
-            appLinks.findViewById(android.R.id.button1).performClick();
-        } catch (Exception e) {
-            // Ignore exception because the launching intent is fake.
-        }
-        verify(mFeatureFactory.metricsFeatureProvider).actionWithSource(mContext,
-                MetricsProto.MetricsEvent.VIEW_UNKNOWN,
-                MetricsProto.MetricsEvent.ACTION_OPEN_APP_SETTING);
-        verify(mFragment).startActivity(any(Intent.class));
-    }
-
-    @Test
     public void bindButton_hasEditRuleNameClickListener_shouldShowButton() {
         final ResolveInfo info = new ResolveInfo();
         info.activityInfo = new ActivityInfo();
@@ -217,30 +181,9 @@
 
 
     @Test
-    public void bindButton_noAppPref_shouldNotShowButton() {
-        final View appLinks =
-            mLayoutInflater.inflate(R.layout.settings_entity_header, null /* root */);
-        when(mContext.getPackageManager().resolveActivity(any(Intent.class), anyInt()))
-            .thenReturn(null);
-
-        mController = EntityHeaderController.newInstance(mActivity, mFragment, appLinks);
-        mController.setButtonActions(
-                EntityHeaderController.ActionType.ACTION_APP_PREFERENCE,
-                EntityHeaderController.ActionType.ACTION_NONE);
-        mController.done(mActivity);
-
-        final ImageButton button1 = appLinks.findViewById(android.R.id.button1);
-        assertThat(button1).isNotNull();
-        assertThat(button1.getVisibility()).isEqualTo(View.GONE);
-        assertThat(button1.getDrawable()).isNull();
-        assertThat(appLinks.findViewById(android.R.id.button2).getVisibility())
-                .isEqualTo(View.GONE);
-    }
-
-    @Test
     public void bindButton_noAppInfo_shouldNotAttachClickListener() {
         final View appLinks =
-            mLayoutInflater.inflate(R.layout.settings_entity_header, null /* root */);
+                mLayoutInflater.inflate(R.layout.settings_entity_header, null /* root */);
         final Activity activity = mock(Activity.class);
         when(mFragment.getActivity()).thenReturn(activity);
 
@@ -265,7 +208,7 @@
     @Test
     public void bindButton_hasAppInfo_shouldAttachClickListener() {
         final View appLinks =
-            mLayoutInflater.inflate(R.layout.settings_entity_header, null /* root */);
+                mLayoutInflater.inflate(R.layout.settings_entity_header, null /* root */);
         final Activity activity = mock(Activity.class);
         when(mFragment.getActivity()).thenReturn(activity);
         when(mContext.getString(eq(R.string.application_info_label))).thenReturn("App Info");
@@ -281,13 +224,13 @@
 
         appLinks.findViewById(R.id.entity_header_content).performClick();
         verify(activity)
-            .startActivityForResultAsUser(any(Intent.class), anyInt(), any(UserHandle.class));
+                .startActivityForResultAsUser(any(Intent.class), anyInt(), any(UserHandle.class));
     }
 
     @Test
     public void iconContentDescription_shouldWorkWithSetIcon() {
         final View view =
-            mLayoutInflater.inflate(R.layout.settings_entity_header, null /* root */);
+                mLayoutInflater.inflate(R.layout.settings_entity_header, null /* root */);
         when(mFragment.getActivity()).thenReturn(mock(Activity.class));
         mController = EntityHeaderController.newInstance(mActivity, mFragment, view);
         String description = "Fake Description";
diff --git a/tests/robotests/src/com/android/settings/widget/UpdatableListPreferenceDialogFragmentTest.java b/tests/robotests/src/com/android/settings/widget/UpdatableListPreferenceDialogFragmentTest.java
new file mode 100644
index 0000000..cd57654
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/widget/UpdatableListPreferenceDialogFragmentTest.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 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.widget;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.support.v7.preference.ListPreference;
+import android.widget.ArrayAdapter;
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
+
+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.ArrayList;
+
+import static org.mockito.Mockito.spy;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(shadows = ShadowBluetoothUtils.class)
+public class UpdatableListPreferenceDialogFragmentTest {
+
+    private Context mContext;
+    private UpdatableListPreferenceDialogFragment mUpdatableListPrefDlgFragment;
+    private static final String KEY = "Test_Key";
+    private ArrayAdapter mAdapter;
+    private ArrayList<CharSequence> mEntries;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = RuntimeEnvironment.application;
+
+        mUpdatableListPrefDlgFragment = UpdatableListPreferenceDialogFragment
+                .newInstance(KEY, MetricsProto.MetricsEvent.DIALOG_SWITCH_A2DP_DEVICES);
+        mEntries = spy(new ArrayList<>());
+        mUpdatableListPrefDlgFragment.setEntries(mEntries);
+        mUpdatableListPrefDlgFragment.
+                setMetricsCategory(mUpdatableListPrefDlgFragment.getArguments());
+        initAdapter();
+    }
+
+    private void initAdapter() {
+        mAdapter = spy(new ArrayAdapter<>(
+                mContext,
+                com.android.internal.R.layout.select_dialog_singlechoice,
+                mEntries));
+        mUpdatableListPrefDlgFragment.setAdapter(mAdapter);
+    }
+
+    @Test
+    public void getMetricsCategory() {
+        assertThat(mUpdatableListPrefDlgFragment.getMetricsCategory())
+                .isEqualTo(MetricsProto.MetricsEvent.DIALOG_SWITCH_A2DP_DEVICES);
+    }
+
+    @Test
+    public void onListPreferenceUpdated_verifyAdapterCanBeUpdate() {
+        assertThat(mUpdatableListPrefDlgFragment.getAdapter().getCount()).
+                isEqualTo(0);
+
+        ListPreference listPreference = new ListPreference(mContext);
+        final CharSequence[] charSequences = {"Test_DEVICE_1", "Test_DEVICE_2"};
+        listPreference.setEntries(charSequences);
+        mUpdatableListPrefDlgFragment.onListPreferenceUpdated(listPreference);
+
+        assertThat(mUpdatableListPrefDlgFragment.getAdapter().getCount()).
+                isEqualTo(2);
+    }
+}
\ No newline at end of file