Merge "Refactor Build number preference control into a controller."
diff --git a/src/com/android/settings/ChooseLockGeneric.java b/src/com/android/settings/ChooseLockGeneric.java
index 06858b7..3a1f501 100644
--- a/src/com/android/settings/ChooseLockGeneric.java
+++ b/src/com/android/settings/ChooseLockGeneric.java
@@ -298,7 +298,11 @@
                 intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT,
                         mForFingerprint);
                 intent.putExtra(EXTRA_HIDE_DRAWER, mHideDrawer);
-                startActivityForResult(intent, ENABLE_ENCRYPTION_REQUEST);
+                startActivityForResult(
+                        intent,
+                        mIsSetNewPassword && mHasChallenge
+                                ? CHOOSE_LOCK_BEFORE_FINGERPRINT_REQUEST
+                                : ENABLE_ENCRYPTION_REQUEST);
             } else {
                 if (mForChangeCredRequiredForBoot) {
                     // Welp, couldn't change it. Oh well.
diff --git a/src/com/android/settings/bluetooth/BluetoothPairingController.java b/src/com/android/settings/bluetooth/BluetoothPairingController.java
index 38b30a8..ce82612 100644
--- a/src/com/android/settings/bluetooth/BluetoothPairingController.java
+++ b/src/com/android/settings/bluetooth/BluetoothPairingController.java
@@ -188,7 +188,7 @@
      *
      * @return - The message ID to show the user.
      */
-    public int getDeviceVariantMessageID() {
+    public int getDeviceVariantMessageId() {
         switch (mType) {
             case BluetoothDevice.PAIRING_VARIANT_PIN_16_DIGITS:
             case BluetoothDevice.PAIRING_VARIANT_PIN:
@@ -198,7 +198,7 @@
                 return R.string.bluetooth_enter_passkey_other_device;
 
             default:
-                return -1;
+                return INVALID_DIALOG_TYPE;
         }
     }
 
@@ -208,7 +208,7 @@
      *
      * @return - The message ID to show the user.
      */
-    public int getDeviceVariantMessageHint() {
+    public int getDeviceVariantMessageHintId() {
         switch (mType) {
             case BluetoothDevice.PAIRING_VARIANT_PIN_16_DIGITS:
                 return R.string.bluetooth_pin_values_hint_16_digits;
@@ -218,7 +218,7 @@
                 return R.string.bluetooth_pin_values_hint;
 
             default:
-                return -1;
+                return INVALID_DIALOG_TYPE;
         }
     }
 
diff --git a/src/com/android/settings/bluetooth/BluetoothPairingDialogFragment.java b/src/com/android/settings/bluetooth/BluetoothPairingDialogFragment.java
index d4247c0..abeb862 100644
--- a/src/com/android/settings/bluetooth/BluetoothPairingDialogFragment.java
+++ b/src/com/android/settings/bluetooth/BluetoothPairingDialogFragment.java
@@ -45,10 +45,9 @@
     private static final String TAG = "BTPairingDialogFragment";
 
     private AlertDialog.Builder mBuilder;
-    private BluetoothPairingController mPairingController;
     private AlertDialog mDialog;
+    private BluetoothPairingController mPairingController;
     private EditText mPairingView;
-
     /**
      * The interface we expect a listener to implement. Typically this should be done by
      * the controller.
@@ -106,11 +105,25 @@
     }
 
     /**
+     * Used in testing to get a reference to the dialog.
+     * @return - The fragments current dialog
+     */
+    protected AlertDialog getmDialog() {
+        return mDialog;
+    }
+
+    /**
      * Sets the controller that the fragment should use. this method MUST be called
      * before you try to show the dialog or an error will be thrown. An implementation
-     * of a pairing controller can be found at {@link BluetoothPairingController}.
+     * of a pairing controller can be found at {@link BluetoothPairingController}. A
+     * controller may not be substituted once it is assigned. Forcibly switching a
+     * controller for a new one will lead to undefined behavior.
      */
     public void setPairingController(BluetoothPairingController pairingController) {
+        if (mPairingController != null) {
+            throw new IllegalStateException("The controller can only be set once. "
+                    + "Forcibly replacing it will lead to undefined behavior");
+        }
         mPairingController = pairingController;
     }
 
@@ -146,7 +159,7 @@
         mBuilder.setPositiveButton(getString(android.R.string.ok), this);
         mBuilder.setNegativeButton(getString(android.R.string.cancel), this);
         AlertDialog dialog = mBuilder.create();
-        dialog.getButton(Dialog.BUTTON_POSITIVE).setEnabled(false);
+        dialog.setOnShowListener(d -> mDialog.getButton(Dialog.BUTTON_POSITIVE).setEnabled(false));
         return dialog;
     }
 
@@ -171,6 +184,7 @@
 
         mPairingView = pairingView;
 
+        pairingView.setInputType(InputType.TYPE_CLASS_NUMBER);
         pairingView.addTextChangedListener(this);
         alphanumericPin.setOnCheckedChangeListener((buttonView, isChecked) -> {
             // change input type for soft keyboard to numeric or alphanumeric
@@ -181,15 +195,21 @@
             }
         });
 
-        int messageId = mPairingController.getDeviceVariantMessageID();
-        int messageIdHint = mPairingController.getDeviceVariantMessageHint();
+        int messageId = mPairingController.getDeviceVariantMessageId();
+        int messageIdHint = mPairingController.getDeviceVariantMessageHintId();
         int maxLength = mPairingController.getDeviceMaxPasskeyLength();
         alphanumericPin.setVisibility(mPairingController.pairingCodeIsAlphanumeric()
                 ? View.VISIBLE : View.GONE);
-
-        messageViewCaptionHint.setText(messageIdHint);
-        messageView2.setText(messageId);
-        pairingView.setInputType(InputType.TYPE_CLASS_NUMBER);
+        if (messageId != BluetoothPairingController.INVALID_DIALOG_TYPE) {
+            messageView2.setText(messageId);
+        } else {
+            messageView2.setVisibility(View.GONE);
+        }
+        if (messageIdHint != BluetoothPairingController.INVALID_DIALOG_TYPE) {
+            messageViewCaptionHint.setText(messageIdHint);
+        } else {
+            messageViewCaptionHint.setVisibility(View.GONE);
+        }
         pairingView.setFilters(new InputFilter[]{
                 new LengthFilter(maxLength)});
 
@@ -203,10 +223,8 @@
         mBuilder.setTitle(getString(R.string.bluetooth_pairing_request,
                 mPairingController.getDeviceName()));
         mBuilder.setView(createView());
-        mBuilder.setPositiveButton(getString(R.string.bluetooth_pairing_accept),
-                this);
-        mBuilder.setNegativeButton(getString(R.string.bluetooth_pairing_decline),
-                this);
+        mBuilder.setPositiveButton(getString(R.string.bluetooth_pairing_accept), this);
+        mBuilder.setNegativeButton(getString(R.string.bluetooth_pairing_decline), this);
         AlertDialog dialog = mBuilder.create();
         return dialog;
     }
diff --git a/src/com/android/settings/bluetooth/BluetoothSettings.java b/src/com/android/settings/bluetooth/BluetoothSettings.java
index 3dfcfc7..9b222fa 100644
--- a/src/com/android/settings/bluetooth/BluetoothSettings.java
+++ b/src/com/android/settings/bluetooth/BluetoothSettings.java
@@ -180,13 +180,13 @@
     }
 
     @Override
-    public void onResume() {
-        // resume BluetoothEnabler before calling super.onResume() so we don't get
+    public void onStart() {
+        // resume BluetoothEnabler before calling super.onStart() so we don't get
         // any onDeviceAdded() callbacks before setting up view in updateContent()
         if (mBluetoothEnabler != null) {
             mBluetoothEnabler.resume(getActivity());
         }
-        super.onResume();
+        super.onStart();
 
         mInitiateDiscoverable = true;
 
@@ -206,8 +206,8 @@
     }
 
     @Override
-    public void onPause() {
-        super.onPause();
+    public void onStop() {
+        super.onStop();
         if (mBluetoothEnabler != null) {
             mBluetoothEnabler.pause();
         }
diff --git a/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java b/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java
index e6fcbcb..c132163 100644
--- a/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java
+++ b/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java
@@ -98,8 +98,8 @@
     abstract void addPreferencesForActivity();
 
     @Override
-    public void onResume() {
-        super.onResume();
+    public void onStart() {
+        super.onStart();
         if (mLocalManager == null || isUiRestricted()) return;
 
         mLocalManager.setForegroundActivity(getActivity());
@@ -109,8 +109,8 @@
     }
 
     @Override
-    public void onPause() {
-        super.onPause();
+    public void onStop() {
+        super.onStop();
         if (mLocalManager == null || isUiRestricted()) {
             return;
         }
diff --git a/src/com/android/settings/bluetooth/DevicePickerFragment.java b/src/com/android/settings/bluetooth/DevicePickerFragment.java
index 3fbd7bd..066f5d2 100644
--- a/src/com/android/settings/bluetooth/DevicePickerFragment.java
+++ b/src/com/android/settings/bluetooth/DevicePickerFragment.java
@@ -47,7 +47,7 @@
     private boolean mNeedAuth;
     private String mLaunchPackage;
     private String mLaunchClass;
-    private boolean mStartScanOnResume;
+    private boolean mStartScanOnStart;
 
     @Override
     void addPreferencesForActivity() {
@@ -94,18 +94,18 @@
         super.onCreate(savedInstanceState);
         getActivity().setTitle(getString(R.string.device_picker));
         UserManager um = (UserManager) getSystemService(Context.USER_SERVICE);
-        mStartScanOnResume = !um.hasUserRestriction(DISALLOW_CONFIG_BLUETOOTH)
+        mStartScanOnStart = !um.hasUserRestriction(DISALLOW_CONFIG_BLUETOOTH)
                 && (savedInstanceState == null);  // don't start scan after rotation
         setHasOptionsMenu(true);
     }
 
     @Override
-    public void onResume() {
-        super.onResume();
+    public void onStart() {
+        super.onStart();
         addCachedDevices();
-        if (mStartScanOnResume) {
+        if (mStartScanOnStart) {
             mLocalAdapter.startScanning(true);
-            mStartScanOnResume = false;
+            mStartScanOnStart = false;
         }
     }
 
diff --git a/src/com/android/settings/core/PreferenceController.java b/src/com/android/settings/core/PreferenceController.java
index 8a4a245..50e9b2c 100644
--- a/src/com/android/settings/core/PreferenceController.java
+++ b/src/com/android/settings/core/PreferenceController.java
@@ -66,6 +66,11 @@
     }
 
     /**
+     * Returns true if preference is available (should be displayed)
+     */
+    public abstract boolean isAvailable();
+
+    /**
      * Handles preference tree click
      *
      * @param preference the preference being clicked
@@ -87,9 +92,4 @@
             screen.removePreference(pref);
         }
     }
-
-    /**
-     * Returns true if preference is available (should be displayed)
-     */
-    protected abstract boolean isAvailable();
 }
diff --git a/src/com/android/settings/dashboard/DashboardFragment.java b/src/com/android/settings/dashboard/DashboardFragment.java
index fd125af..d76fe7a 100644
--- a/src/com/android/settings/dashboard/DashboardFragment.java
+++ b/src/com/android/settings/dashboard/DashboardFragment.java
@@ -251,11 +251,15 @@
         Collection<PreferenceController> controllers = mPreferenceControllers.values();
         final PreferenceScreen screen = getPreferenceScreen();
         for (PreferenceController controller : controllers) {
+            if (!controller.isAvailable()) {
+                continue;
+            }
             final String key = controller.getPreferenceKey();
 
             final Preference preference = mProgressiveDisclosureMixin.findPreference(screen, key);
             if (preference == null) {
-                Log.d(TAG, "Cannot find preference with key " + key);
+                Log.d(TAG, String.format("Cannot find preference with key %s in Controller %s",
+                        key, controller.getClass().getSimpleName()));
                 continue;
             }
             controller.updateState(preference);
diff --git a/src/com/android/settings/deviceinfo/AdditionalSystemUpdatePreferenceController.java b/src/com/android/settings/deviceinfo/AdditionalSystemUpdatePreferenceController.java
index 7290250..3435b53 100644
--- a/src/com/android/settings/deviceinfo/AdditionalSystemUpdatePreferenceController.java
+++ b/src/com/android/settings/deviceinfo/AdditionalSystemUpdatePreferenceController.java
@@ -34,7 +34,7 @@
     }
 
     @Override
-    protected boolean isAvailable() {
+    public boolean isAvailable() {
         return mContext.getResources().getBoolean(
                 com.android.settings.R.bool.config_additional_system_update_setting_enable);
     }
diff --git a/src/com/android/settings/deviceinfo/ManageStoragePreferenceController.java b/src/com/android/settings/deviceinfo/ManageStoragePreferenceController.java
index d4d53d4..e64525b 100644
--- a/src/com/android/settings/deviceinfo/ManageStoragePreferenceController.java
+++ b/src/com/android/settings/deviceinfo/ManageStoragePreferenceController.java
@@ -17,13 +17,10 @@
 
 import android.content.Context;
 import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceScreen;
 
 import com.android.settings.R;
 import com.android.settings.core.PreferenceController;
 
-import java.util.List;
-
 public class ManageStoragePreferenceController extends PreferenceController {
 
     public static final String KEY_MANAGE_STORAGE = "pref_manage_storage";
@@ -43,7 +40,7 @@
     }
 
     @Override
-    protected boolean isAvailable() {
+    public boolean isAvailable() {
         return mContext.getResources().getBoolean(R.bool.config_storage_manager_settings_enabled);
     }
 }
diff --git a/src/com/android/settings/deviceinfo/SystemUpdatePreferenceController.java b/src/com/android/settings/deviceinfo/SystemUpdatePreferenceController.java
index e086a56..0bf43e2 100644
--- a/src/com/android/settings/deviceinfo/SystemUpdatePreferenceController.java
+++ b/src/com/android/settings/deviceinfo/SystemUpdatePreferenceController.java
@@ -46,7 +46,7 @@
     }
 
     @Override
-    protected boolean isAvailable() {
+    public boolean isAvailable() {
         return mUm.isAdminUser();
     }
 
diff --git a/src/com/android/settings/display/AutoBrightnessPreferenceController.java b/src/com/android/settings/display/AutoBrightnessPreferenceController.java
index 775e60c..df2000e 100644
--- a/src/com/android/settings/display/AutoBrightnessPreferenceController.java
+++ b/src/com/android/settings/display/AutoBrightnessPreferenceController.java
@@ -35,7 +35,7 @@
     }
 
     @Override
-    protected boolean isAvailable() {
+    public boolean isAvailable() {
         return mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_automatic_brightness_available);
     }
diff --git a/src/com/android/settings/display/AutoRotatePreferenceController.java b/src/com/android/settings/display/AutoRotatePreferenceController.java
index 44d2158..567393e 100644
--- a/src/com/android/settings/display/AutoRotatePreferenceController.java
+++ b/src/com/android/settings/display/AutoRotatePreferenceController.java
@@ -73,7 +73,7 @@
     }
 
     @Override
-    protected boolean isAvailable() {
+    public boolean isAvailable() {
         return RotationPolicy.isRotationLockToggleVisible(mContext);
     }
 
diff --git a/src/com/android/settings/display/CameraGesturePreferenceController.java b/src/com/android/settings/display/CameraGesturePreferenceController.java
index 3f5d0de..a3dc6cf 100644
--- a/src/com/android/settings/display/CameraGesturePreferenceController.java
+++ b/src/com/android/settings/display/CameraGesturePreferenceController.java
@@ -50,7 +50,7 @@
     }
 
     @Override
-    protected boolean isAvailable() {
+    public boolean isAvailable() {
         boolean configSet = mContext.getResources().getInteger(
                 com.android.internal.R.integer.config_cameraLaunchGestureSensorType) != -1;
         return configSet
diff --git a/src/com/android/settings/display/DozePreferenceController.java b/src/com/android/settings/display/DozePreferenceController.java
index bf5d8f3..16b0e81 100644
--- a/src/com/android/settings/display/DozePreferenceController.java
+++ b/src/com/android/settings/display/DozePreferenceController.java
@@ -67,7 +67,7 @@
     }
 
     @Override
-    protected boolean isAvailable() {
+    public boolean isAvailable() {
         String name = Build.IS_DEBUGGABLE ? SystemProperties.get("debug.doze.component") : null;
         if (TextUtils.isEmpty(name)) {
             name = mContext.getResources().getString(
diff --git a/src/com/android/settings/display/FontSizePreferenceController.java b/src/com/android/settings/display/FontSizePreferenceController.java
index fcd423d..5014bda 100644
--- a/src/com/android/settings/display/FontSizePreferenceController.java
+++ b/src/com/android/settings/display/FontSizePreferenceController.java
@@ -31,7 +31,7 @@
     }
 
     @Override
-    protected boolean isAvailable() {
+    public boolean isAvailable() {
         return true;
     }
 
diff --git a/src/com/android/settings/display/LiftToWakePreferenceController.java b/src/com/android/settings/display/LiftToWakePreferenceController.java
index c518f68..81ba5f5 100644
--- a/src/com/android/settings/display/LiftToWakePreferenceController.java
+++ b/src/com/android/settings/display/LiftToWakePreferenceController.java
@@ -34,7 +34,7 @@
     }
 
     @Override
-    protected boolean isAvailable() {
+    public boolean isAvailable() {
         SensorManager sensors = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
         return sensors != null && sensors.getDefaultSensor(Sensor.TYPE_WAKE_GESTURE) != null;
     }
diff --git a/src/com/android/settings/display/NightDisplayPreferenceController.java b/src/com/android/settings/display/NightDisplayPreferenceController.java
index c52df23..9cf2409 100644
--- a/src/com/android/settings/display/NightDisplayPreferenceController.java
+++ b/src/com/android/settings/display/NightDisplayPreferenceController.java
@@ -33,7 +33,7 @@
     }
 
     @Override
-    protected boolean isAvailable() {
+    public boolean isAvailable() {
         return NightDisplayController.isAvailable(mContext);
     }
 
diff --git a/src/com/android/settings/display/NightModePreferenceController.java b/src/com/android/settings/display/NightModePreferenceController.java
index c0f0c17..874d84f 100644
--- a/src/com/android/settings/display/NightModePreferenceController.java
+++ b/src/com/android/settings/display/NightModePreferenceController.java
@@ -35,7 +35,7 @@
     }
 
     @Override
-    protected boolean isAvailable() {
+    public boolean isAvailable() {
         return false;
     }
 
diff --git a/src/com/android/settings/display/ScreenSaverPreferenceController.java b/src/com/android/settings/display/ScreenSaverPreferenceController.java
index 64d9dec..7335b1f 100644
--- a/src/com/android/settings/display/ScreenSaverPreferenceController.java
+++ b/src/com/android/settings/display/ScreenSaverPreferenceController.java
@@ -28,7 +28,7 @@
     }
 
     @Override
-    protected boolean isAvailable() {
+    public boolean isAvailable() {
         return mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_dreamsSupported);
     }
diff --git a/src/com/android/settings/display/TapToWakePreferenceController.java b/src/com/android/settings/display/TapToWakePreferenceController.java
index 4c5aaa0..18c877a 100644
--- a/src/com/android/settings/display/TapToWakePreferenceController.java
+++ b/src/com/android/settings/display/TapToWakePreferenceController.java
@@ -35,7 +35,7 @@
     }
 
     @Override
-    protected boolean isAvailable() {
+    public boolean isAvailable() {
         return mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_supportDoubleTapWake);
     }
diff --git a/src/com/android/settings/display/TimeoutPreferenceController.java b/src/com/android/settings/display/TimeoutPreferenceController.java
index 8c73c31..d33f813 100644
--- a/src/com/android/settings/display/TimeoutPreferenceController.java
+++ b/src/com/android/settings/display/TimeoutPreferenceController.java
@@ -42,7 +42,7 @@
     }
 
     @Override
-    protected boolean isAvailable() {
+    public boolean isAvailable() {
         return true;
     }
 
diff --git a/src/com/android/settings/display/VrDisplayPreferenceController.java b/src/com/android/settings/display/VrDisplayPreferenceController.java
index 84d7462..61c3ed2 100644
--- a/src/com/android/settings/display/VrDisplayPreferenceController.java
+++ b/src/com/android/settings/display/VrDisplayPreferenceController.java
@@ -35,7 +35,7 @@
     }
 
     @Override
-    protected boolean isAvailable() {
+    public boolean isAvailable() {
         final PackageManager pm = mContext.getPackageManager();
         return pm.hasSystemFeature(PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE);
     }
diff --git a/src/com/android/settings/display/WallpaperPreferenceController.java b/src/com/android/settings/display/WallpaperPreferenceController.java
index 29415e9..8352377 100644
--- a/src/com/android/settings/display/WallpaperPreferenceController.java
+++ b/src/com/android/settings/display/WallpaperPreferenceController.java
@@ -32,7 +32,7 @@
     }
 
     @Override
-    protected boolean isAvailable() {
+    public boolean isAvailable() {
         return true;
     }
 
diff --git a/src/com/android/settings/gestures/SwipeToNotificationPreferenceController.java b/src/com/android/settings/gestures/SwipeToNotificationPreferenceController.java
index dee532f..353eed8 100644
--- a/src/com/android/settings/gestures/SwipeToNotificationPreferenceController.java
+++ b/src/com/android/settings/gestures/SwipeToNotificationPreferenceController.java
@@ -51,7 +51,7 @@
     }
 
     @Override
-    protected boolean isAvailable() {
+    public boolean isAvailable() {
         return mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_supportSystemNavigationKeys);
     }
diff --git a/src/com/android/settings/network/AirplaneModePreferenceController.java b/src/com/android/settings/network/AirplaneModePreferenceController.java
index bd1918f..a25c5f8 100644
--- a/src/com/android/settings/network/AirplaneModePreferenceController.java
+++ b/src/com/android/settings/network/AirplaneModePreferenceController.java
@@ -87,7 +87,7 @@
     }
 
     @Override
-    protected boolean isAvailable() {
+    public boolean isAvailable() {
         return !mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEVISION);
     }
 
diff --git a/src/com/android/settings/network/MobileNetworkPreferenceController.java b/src/com/android/settings/network/MobileNetworkPreferenceController.java
index 14dcf9e..588d80c 100644
--- a/src/com/android/settings/network/MobileNetworkPreferenceController.java
+++ b/src/com/android/settings/network/MobileNetworkPreferenceController.java
@@ -45,7 +45,7 @@
     }
 
     @Override
-    protected boolean isAvailable() {
+    public boolean isAvailable() {
         return !mIsSecondaryUser
                 && !Utils.isWifiOnly(mContext)
                 && !hasBaseUserRestriction(mContext, DISALLOW_CONFIG_MOBILE_NETWORKS, myUserId());
diff --git a/src/com/android/settings/network/MobilePlanPreferenceController.java b/src/com/android/settings/network/MobilePlanPreferenceController.java
index 8dfff15..42b2bea 100644
--- a/src/com/android/settings/network/MobilePlanPreferenceController.java
+++ b/src/com/android/settings/network/MobilePlanPreferenceController.java
@@ -111,7 +111,7 @@
     }
 
     @Override
-    protected boolean isAvailable() {
+    public boolean isAvailable() {
         final boolean isPrefAllowedOnDevice = mContext.getResources().getBoolean(
                 com.android.settings.R.bool.config_show_mobile_plan);
         final boolean isPrefAllowedForUser = !mIsSecondaryUser
diff --git a/src/com/android/settings/network/NetworkResetPreferenceController.java b/src/com/android/settings/network/NetworkResetPreferenceController.java
index b313cc0..2842139 100644
--- a/src/com/android/settings/network/NetworkResetPreferenceController.java
+++ b/src/com/android/settings/network/NetworkResetPreferenceController.java
@@ -37,7 +37,7 @@
     }
 
     @Override
-    protected boolean isAvailable() {
+    public boolean isAvailable() {
         return !RestrictedLockUtils.hasBaseUserRestriction(mContext,
                 UserManager.DISALLOW_NETWORK_RESET, UserHandle.myUserId());
     }
diff --git a/src/com/android/settings/network/ProxyPreferenceController.java b/src/com/android/settings/network/ProxyPreferenceController.java
index 5feb5d0..54b8ca9 100644
--- a/src/com/android/settings/network/ProxyPreferenceController.java
+++ b/src/com/android/settings/network/ProxyPreferenceController.java
@@ -36,7 +36,7 @@
     }
 
     @Override
-    protected boolean isAvailable() {
+    public boolean isAvailable() {
         // proxy UI disabled until we have better app support
         return false;
     }
diff --git a/src/com/android/settings/network/TetherPreferenceController.java b/src/com/android/settings/network/TetherPreferenceController.java
index 96f037b..f6ef678 100644
--- a/src/com/android/settings/network/TetherPreferenceController.java
+++ b/src/com/android/settings/network/TetherPreferenceController.java
@@ -67,7 +67,7 @@
     }
 
     @Override
-    protected boolean isAvailable() {
+    public boolean isAvailable() {
         final boolean isBlocked =
                 (!mConnectivityManager.isTetheringSupported() && !mAdminDisallowedTetherConfig)
                         || hasBaseUserRestriction(mContext, DISALLOW_CONFIG_TETHERING,
diff --git a/src/com/android/settings/network/VpnPreferenceController.java b/src/com/android/settings/network/VpnPreferenceController.java
index 0703ed3..3c4877f 100644
--- a/src/com/android/settings/network/VpnPreferenceController.java
+++ b/src/com/android/settings/network/VpnPreferenceController.java
@@ -58,7 +58,7 @@
     }
 
     @Override
-    protected boolean isAvailable() {
+    public boolean isAvailable() {
         // TODO: http://b/23693383
         return mIsSecondaryUser || RestrictedLockUtils.hasBaseUserRestriction(mContext,
                 UserManager.DISALLOW_CONFIG_VPN, UserHandle.myUserId());
diff --git a/src/com/android/settings/network/WifiCallingPreferenceController.java b/src/com/android/settings/network/WifiCallingPreferenceController.java
index 61ab92e..5036c46 100644
--- a/src/com/android/settings/network/WifiCallingPreferenceController.java
+++ b/src/com/android/settings/network/WifiCallingPreferenceController.java
@@ -50,7 +50,7 @@
     }
 
     @Override
-    protected boolean isAvailable() {
+    public boolean isAvailable() {
         return ImsManager.isWfcEnabledByPlatform(mContext)
                 && ImsManager.isWfcProvisionedOnDevice(mContext);
     }
diff --git a/src/com/android/settings/nfc/NfcPreferenceController.java b/src/com/android/settings/nfc/NfcPreferenceController.java
index b7cd702..6303d5b 100644
--- a/src/com/android/settings/nfc/NfcPreferenceController.java
+++ b/src/com/android/settings/nfc/NfcPreferenceController.java
@@ -101,7 +101,7 @@
     }
 
     @Override
-    protected boolean isAvailable() {
+    public boolean isAvailable() {
         return mNfcAdapter != null;
     }
 
diff --git a/src/com/android/settings/notification/LockScreenNotificationPreferenceController.java b/src/com/android/settings/notification/LockScreenNotificationPreferenceController.java
index f349a84..15f8c9f 100644
--- a/src/com/android/settings/notification/LockScreenNotificationPreferenceController.java
+++ b/src/com/android/settings/notification/LockScreenNotificationPreferenceController.java
@@ -190,7 +190,7 @@
     }
 
     @Override
-    protected boolean isAvailable() {
+    public boolean isAvailable() {
         return false;
     }
 
diff --git a/src/com/android/settings/notification/PulseNotificationPreferenceController.java b/src/com/android/settings/notification/PulseNotificationPreferenceController.java
index 03832e5..de365f1 100644
--- a/src/com/android/settings/notification/PulseNotificationPreferenceController.java
+++ b/src/com/android/settings/notification/PulseNotificationPreferenceController.java
@@ -79,7 +79,7 @@
     }
 
     @Override
-    protected boolean isAvailable() {
+    public boolean isAvailable() {
         return mContext.getResources()
                 .getBoolean(com.android.internal.R.bool.config_intrusiveNotificationLed);
     }
diff --git a/tests/robotests/src/com/android/settings/DisplaySettingsTest.java b/tests/robotests/src/com/android/settings/DisplaySettingsTest.java
index 5af8544..ac499eb 100644
--- a/tests/robotests/src/com/android/settings/DisplaySettingsTest.java
+++ b/tests/robotests/src/com/android/settings/DisplaySettingsTest.java
@@ -18,16 +18,13 @@
 
 import android.app.Activity;
 import android.provider.Settings.System;
-
 import com.android.settings.dashboard.SummaryLoader;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
 import org.robolectric.annotation.Config;
 
 import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
@@ -36,7 +33,7 @@
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
-@RunWith(RobolectricTestRunner.class)
+@RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class DisplaySettingsTest {
 
diff --git a/tests/robotests/src/com/android/settings/SettingsDialogFragmentTest.java b/tests/robotests/src/com/android/settings/SettingsDialogFragmentTest.java
index da23d5f..86b613c 100644
--- a/tests/robotests/src/com/android/settings/SettingsDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/SettingsDialogFragmentTest.java
@@ -17,13 +17,11 @@
 
 import android.app.Dialog;
 import android.app.Fragment;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
 import org.robolectric.annotation.Config;
 
 import static org.junit.Assert.fail;
@@ -31,7 +29,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-@RunWith(RobolectricTestRunner.class)
+@RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class SettingsDialogFragmentTest {
 
diff --git a/tests/robotests/src/com/android/settings/SettingsRobolectricTestRunner.java b/tests/robotests/src/com/android/settings/SettingsRobolectricTestRunner.java
new file mode 100644
index 0000000..1a7647d
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/SettingsRobolectricTestRunner.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.settings;
+
+import java.util.List;
+import org.junit.runners.model.InitializationError;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+import org.robolectric.manifest.AndroidManifest;
+import org.robolectric.res.Fs;
+import org.robolectric.res.ResourcePath;
+
+/**
+ * Custom test runner for the testing of BluetoothPairingDialogs. This is needed because the
+ * default behavior for robolectric is just to grab the resource directory in the target package.
+ * We want to override this to add several spanning different projects.
+ */
+public class SettingsRobolectricTestRunner extends RobolectricTestRunner {
+
+    /**
+     * We don't actually want to change this behavior, so we just call super.
+     */
+    public SettingsRobolectricTestRunner(Class<?> testClass) throws InitializationError {
+        super(testClass);
+    }
+
+    /**
+     * We are going to create our own custom manifest so that we can add multiple resource
+     * paths to it. This lets us access resources in both Settings and SettingsLib in our tests.
+     */
+    @Override
+    protected AndroidManifest getAppManifest(Config config) {
+        // Using the manifest file's relative path, we can figure out the application directory.
+        final String appRoot = "packages/apps/Settings";
+        final String manifestPath = appRoot + "/AndroidManifest.xml";
+        final String resDir = appRoot + "/res";
+        final String assetsDir = appRoot + "/assets";
+
+        // By adding any resources from libraries we need to the AndroidManifest, we can access
+        // them from within the parallel universe's resource loader.
+        final AndroidManifest manifest = new AndroidManifest(Fs.fileFromPath(manifestPath),
+                Fs.fileFromPath(resDir), Fs.fileFromPath(assetsDir)) {
+            @Override
+            public List<ResourcePath> getIncludedResourcePaths() {
+                List<ResourcePath> paths = super.getIncludedResourcePaths();
+                paths.add(new ResourcePath(
+                        getPackageName(),
+                        Fs.fileFromPath("./packages/apps/Settings/res"),
+                        null));
+                paths.add(new ResourcePath(
+                        getPackageName(),
+                        Fs.fileFromPath("./frameworks/base/packages/SettingsLib/res"),
+                        null));
+                return paths;
+            }
+        };
+
+        // Set the package name to the renamed one
+        manifest.setPackageName("com.android.settings");
+        return manifest;
+    }
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/SummaryPreferenceTest.java b/tests/robotests/src/com/android/settings/SummaryPreferenceTest.java
index e55f069..e8440dd 100644
--- a/tests/robotests/src/com/android/settings/SummaryPreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/SummaryPreferenceTest.java
@@ -22,18 +22,16 @@
 import android.view.View;
 import android.widget.LinearLayout;
 import android.widget.TextView;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
 
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertTrue;
 
-@RunWith(RobolectricTestRunner.class)
+@RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class SummaryPreferenceTest {
 
diff --git a/tests/robotests/src/com/android/settings/UtilsTest.java b/tests/robotests/src/com/android/settings/UtilsTest.java
index e486d31..dacd303 100644
--- a/tests/robotests/src/com/android/settings/UtilsTest.java
+++ b/tests/robotests/src/com/android/settings/UtilsTest.java
@@ -1,9 +1,5 @@
 package com.android.settings;
 
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.when;
-
 import android.content.Context;
 import android.net.ConnectivityManager;
 import android.net.LinkAddress;
@@ -16,11 +12,14 @@
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
 
-@RunWith(RobolectricTestRunner.class)
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+@RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class UtilsTest {
 
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothPairingDialogTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothPairingDialogTest.java
new file mode 100644
index 0000000..035d29e
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothPairingDialogTest.java
@@ -0,0 +1,340 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.settings.bluetooth;
+
+import android.app.AlertDialog;
+import android.text.SpannableStringBuilder;
+import android.text.TextUtils;
+import android.view.View;
+import android.widget.CheckBox;
+import android.widget.TextView;
+import com.android.settings.R;
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.util.FragmentTestUtil;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class BluetoothPairingDialogTest {
+
+    private static final String FILLER = "text that goes in a view";
+    private static final String FAKE_DEVICE_NAME = "Fake Bluetooth Device";
+
+    @Mock
+    private BluetoothPairingController controller;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @Test
+    public void dialogUpdatesControllerWithUserInput() {
+        // set the correct dialog type
+        when(controller.getDialogType()).thenReturn(BluetoothPairingController.USER_ENTRY_DIALOG);
+
+        // we don't care about these for this test
+        when(controller.getDeviceVariantMessageId())
+                .thenReturn(BluetoothPairingController.INVALID_DIALOG_TYPE);
+        when(controller.getDeviceVariantMessageHintId())
+                .thenReturn(BluetoothPairingController.INVALID_DIALOG_TYPE);
+
+        // build fragment
+        BluetoothPairingDialogFragment frag = makeFragment();
+
+        // test that controller is updated on text change
+        frag.afterTextChanged(new SpannableStringBuilder(FILLER));
+        verify(controller, times(1)).updateUserInput(any());
+    }
+
+    @Test
+    public void dialogEnablesSubmitButtonOnValidationFromController() {
+        // set the correct dialog type
+        when(controller.getDialogType()).thenReturn(BluetoothPairingController.USER_ENTRY_DIALOG);
+
+        // we don't care about these for this test
+        when(controller.getDeviceVariantMessageId())
+                .thenReturn(BluetoothPairingController.INVALID_DIALOG_TYPE);
+        when(controller.getDeviceVariantMessageHintId())
+                .thenReturn(BluetoothPairingController.INVALID_DIALOG_TYPE);
+
+        // force the controller to say that any passkey is valid
+        when(controller.isPasskeyValid(any())).thenReturn(true);
+
+        // build fragment
+        BluetoothPairingDialogFragment frag = makeFragment();
+
+        // test that the positive button is enabled when passkey is valid
+        frag.afterTextChanged(new SpannableStringBuilder(FILLER));
+        View button = frag.getmDialog().getButton(AlertDialog.BUTTON_POSITIVE);
+        assertThat(button).isNotNull();
+        assertThat(button.getVisibility()).isEqualTo(View.VISIBLE);
+    }
+
+    @Test
+    public void dialogDoesNotAskForPairCodeOnConsentVariant() {
+        // set the dialog variant to confirmation/consent
+        when(controller.getDialogType()).thenReturn(BluetoothPairingController.CONFIRMATION_DIALOG);
+
+        // build the fragment
+        BluetoothPairingDialogFragment frag = makeFragment();
+
+        // check that the input field used by the entry dialog fragment does not exist
+        View view = frag.getmDialog().findViewById(R.id.text);
+        assertThat(view).isNull();
+    }
+
+    @Test
+    public void dialogAsksForPairCodeOnUserEntryVariant() {
+        // set the dialog variant to user entry
+        when(controller.getDialogType()).thenReturn(BluetoothPairingController.USER_ENTRY_DIALOG);
+
+        // we don't care about these for this test
+        when(controller.getDeviceVariantMessageId())
+                .thenReturn(BluetoothPairingController.INVALID_DIALOG_TYPE);
+        when(controller.getDeviceVariantMessageHintId())
+                .thenReturn(BluetoothPairingController.INVALID_DIALOG_TYPE);
+
+        // build the fragment
+        BluetoothPairingDialogFragment frag = makeFragment();
+
+        // check that the pin/passkey input field is visible to the user
+        View view = frag.getmDialog().findViewById(R.id.text);
+        assertThat(view.getVisibility()).isEqualTo(View.VISIBLE);
+    }
+
+    @Test
+    public void dialogDisplaysPairCodeOnDisplayPasskeyVariant() {
+        // set the dialog variant to display passkey
+        when(controller.getDialogType())
+                .thenReturn(BluetoothPairingController.DISPLAY_PASSKEY_DIALOG);
+
+        // ensure that the controller returns good values to indicate a passkey needs to be shown
+        when(controller.isDisplayPairingKeyVariant()).thenReturn(true);
+        when(controller.hasPairingContent()).thenReturn(true);
+        when(controller.getPairingContent()).thenReturn(FILLER);
+
+        // build the fragment
+        BluetoothPairingDialogFragment frag = makeFragment();
+
+        // get the relevant views
+        View messagePairing = frag.getmDialog().findViewById(R.id.pairing_code_message);
+        TextView pairingViewContent =
+                (TextView) frag.getmDialog().findViewById(R.id.pairing_subhead);
+        View pairingViewCaption = frag.getmDialog().findViewById(R.id.pairing_caption);
+
+        // check that the relevant views are visible and that the passkey is shown
+        assertThat(messagePairing.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(pairingViewCaption.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(pairingViewContent.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(TextUtils.equals(FILLER, pairingViewContent.getText())).isTrue();
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void dialogThrowsExceptionIfNoControllerSet() {
+        // instantiate a fragment
+        BluetoothPairingDialogFragment frag = new BluetoothPairingDialogFragment();
+
+        // this should throw an error
+        FragmentTestUtil.startFragment(frag);
+        fail("Starting the fragment with no controller set should have thrown an exception.");
+    }
+
+    @Test
+    public void dialogCallsHookOnPositiveButtonPress() {
+        // set the dialog variant to confirmation/consent
+        when(controller.getDialogType()).thenReturn(BluetoothPairingController.CONFIRMATION_DIALOG);
+
+        // we don't care what this does, just that it is called
+        doNothing().when(controller).onDialogPositiveClick(any());
+
+        // build the fragment
+        BluetoothPairingDialogFragment frag = makeFragment();
+
+        // click the button and verify that the controller hook was called
+        frag.onClick(frag.getmDialog(), AlertDialog.BUTTON_POSITIVE);
+        verify(controller, times(1)).onDialogPositiveClick(any());
+    }
+
+    @Test
+    public void dialogCallsHookOnNegativeButtonPress() {
+        // set the dialog variant to confirmation/consent
+        when(controller.getDialogType()).thenReturn(BluetoothPairingController.CONFIRMATION_DIALOG);
+
+        // we don't care what this does, just that it is called
+        doNothing().when(controller).onDialogNegativeClick(any());
+
+        // build the fragment
+        BluetoothPairingDialogFragment frag = makeFragment();
+
+        // click the button and verify that the controller hook was called
+        frag.onClick(frag.getmDialog(), AlertDialog.BUTTON_NEGATIVE);
+        verify(controller, times(1)).onDialogNegativeClick(any());
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void dialogDoesNotAllowSwappingController() {
+        // instantiate a fragment
+        BluetoothPairingDialogFragment frag = new BluetoothPairingDialogFragment();
+        frag.setPairingController(controller);
+
+        // this should throw an error
+        frag.setPairingController(controller);
+        fail("Setting the controller multiple times should throw an exception.");
+    }
+
+    @Test
+    public void dialogPositiveButtonDisabledWhenUserInputInvalid() {
+        // set the correct dialog type
+        when(controller.getDialogType()).thenReturn(BluetoothPairingController.USER_ENTRY_DIALOG);
+
+        // we don't care about these for this test
+        when(controller.getDeviceVariantMessageId())
+                .thenReturn(BluetoothPairingController.INVALID_DIALOG_TYPE);
+        when(controller.getDeviceVariantMessageHintId())
+                .thenReturn(BluetoothPairingController.INVALID_DIALOG_TYPE);
+
+        // force the controller to say that any passkey is valid
+        when(controller.isPasskeyValid(any())).thenReturn(false);
+
+        // build fragment
+        BluetoothPairingDialogFragment frag = makeFragment();
+
+        // test that the positive button is enabled when passkey is valid
+        frag.afterTextChanged(new SpannableStringBuilder(FILLER));
+        View button = frag.getmDialog().getButton(AlertDialog.BUTTON_POSITIVE);
+        assertThat(button).isNotNull();
+        assertThat(button.isEnabled()).isFalse();
+    }
+
+    @Test
+    public void dialogShowsContactSharingCheckboxWhenBluetoothProfileNotReady() {
+        // set the dialog variant to confirmation/consent
+        when(controller.getDialogType()).thenReturn(BluetoothPairingController.CONFIRMATION_DIALOG);
+
+        // set a fake device name and pretend the profile has not been set up for it
+        when(controller.getDeviceName()).thenReturn(FAKE_DEVICE_NAME);
+        when(controller.isProfileReady()).thenReturn(false);
+
+        // build the fragment
+        BluetoothPairingDialogFragment frag = makeFragment();
+
+        // verify that the checkbox is visible and that the device name is correct
+        CheckBox sharingCheckbox = (CheckBox) frag.getmDialog()
+                .findViewById(R.id.phonebook_sharing_message_confirm_pin);
+        assertThat(sharingCheckbox.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(sharingCheckbox.getText().toString().contains(FAKE_DEVICE_NAME)).isTrue();
+    }
+
+    @Test
+    public void dialogHidesContactSharingCheckboxWhenBluetoothProfileIsReady() {
+        // set the dialog variant to confirmation/consent
+        when(controller.getDialogType()).thenReturn(BluetoothPairingController.CONFIRMATION_DIALOG);
+
+        // set a fake device name and pretend the profile has been set up for it
+        when(controller.getDeviceName()).thenReturn(FAKE_DEVICE_NAME);
+        when(controller.isProfileReady()).thenReturn(true);
+
+        // build the fragment
+        BluetoothPairingDialogFragment frag = makeFragment();
+
+        // verify that the checkbox is gone
+        CheckBox sharingCheckbox = (CheckBox) frag.getmDialog()
+                .findViewById(R.id.phonebook_sharing_message_confirm_pin);
+        assertThat(sharingCheckbox.getVisibility()).isEqualTo(View.GONE);
+    }
+
+    @Test
+    public void dialogShowsMessageOnPinEntryView() {
+        // set the correct dialog type
+        when(controller.getDialogType()).thenReturn(BluetoothPairingController.USER_ENTRY_DIALOG);
+
+        // Set the message id to something specific to verify later
+        when(controller.getDeviceVariantMessageId()).thenReturn(R.string.cancel);
+        when(controller.getDeviceVariantMessageHintId())
+                .thenReturn(BluetoothPairingController.INVALID_DIALOG_TYPE);
+
+        // build the fragment
+        BluetoothPairingDialogFragment frag = makeFragment();
+
+        // verify message is what we expect it to be and is visible
+        TextView message = (TextView) frag.getmDialog().findViewById(R.id.message_below_pin);
+        assertThat(message.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(TextUtils.equals(frag.getString(R.string.cancel), message.getText())).isTrue();
+    }
+
+    @Test
+    public void dialogShowsMessageHintOnPinEntryView() {
+        // set the correct dialog type
+        when(controller.getDialogType()).thenReturn(BluetoothPairingController.USER_ENTRY_DIALOG);
+
+        // Set the message id hint to something specific to verify later
+        when(controller.getDeviceVariantMessageHintId()).thenReturn(R.string.cancel);
+        when(controller.getDeviceVariantMessageId())
+                .thenReturn(BluetoothPairingController.INVALID_DIALOG_TYPE);
+
+        // build the fragment
+        BluetoothPairingDialogFragment frag = makeFragment();
+
+        // verify message is what we expect it to be and is visible
+        TextView hint = (TextView) frag.getmDialog().findViewById(R.id.pin_values_hint);
+        assertThat(hint.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(TextUtils.equals(frag.getString(R.string.cancel), hint.getText())).isTrue();
+    }
+
+    @Test
+    public void dialogHidesMessageAndHintWhenNotProvidedOnPinEntryView() {
+        // set the correct dialog type
+        when(controller.getDialogType()).thenReturn(BluetoothPairingController.USER_ENTRY_DIALOG);
+
+        // Set the id's to what is returned when it is not provided
+        when(controller.getDeviceVariantMessageHintId())
+                .thenReturn(BluetoothPairingController.INVALID_DIALOG_TYPE);
+        when(controller.getDeviceVariantMessageId())
+                .thenReturn(BluetoothPairingController.INVALID_DIALOG_TYPE);
+
+        // build the fragment
+        BluetoothPairingDialogFragment frag = makeFragment();
+
+        // verify message is what we expect it to be and is visible
+        TextView hint = (TextView) frag.getmDialog().findViewById(R.id.pin_values_hint);
+        assertThat(hint.getVisibility()).isEqualTo(View.GONE);
+        TextView message = (TextView) frag.getmDialog().findViewById(R.id.message_below_pin);
+        assertThat(message.getVisibility()).isEqualTo(View.GONE);
+    }
+
+    private BluetoothPairingDialogFragment makeFragment() {
+        BluetoothPairingDialogFragment frag = new BluetoothPairingDialogFragment();
+        frag.setPairingController(controller);
+        FragmentTestUtil.startFragment(frag);
+        assertThat(frag.getmDialog()).isNotNull();
+        return frag;
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragmentTest.java
index e6570e1..d53a27b 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragmentTest.java
@@ -16,23 +16,21 @@
 package com.android.settings.connecteddevice;
 
 import android.content.Context;
-
+import com.android.settings.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settingslib.drawer.CategoryKey;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Answers;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
 import org.robolectric.annotation.Config;
 
 import static com.google.common.truth.Truth.assertThat;
 
-@RunWith(RobolectricTestRunner.class)
+@RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class ConnectedDeviceDashboardFragmentTest {
 
diff --git a/tests/robotests/src/com/android/settings/core/PreferenceControllerTest.java b/tests/robotests/src/com/android/settings/core/PreferenceControllerTest.java
index 9a526b1..aaab183 100644
--- a/tests/robotests/src/com/android/settings/core/PreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/core/PreferenceControllerTest.java
@@ -18,15 +18,13 @@
 import android.content.Context;
 import android.support.v7.preference.Preference;
 import android.support.v7.preference.PreferenceScreen;
-
+import com.android.settings.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
 import org.robolectric.annotation.Config;
 
 import static org.mockito.Matchers.any;
@@ -34,7 +32,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-@RunWith(RobolectricTestRunner.class)
+@RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class PreferenceControllerTest {
 
@@ -102,7 +100,7 @@
         }
 
         @Override
-        protected boolean isAvailable() {
+        public boolean isAvailable() {
             return isAvailable;
         }
 
diff --git a/tests/robotests/src/com/android/settings/core/instrumentation/InstrumentedDialogFragmentTest.java b/tests/robotests/src/com/android/settings/core/instrumentation/InstrumentedDialogFragmentTest.java
index 14b3bb4..0abac1d 100644
--- a/tests/robotests/src/com/android/settings/core/instrumentation/InstrumentedDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/core/instrumentation/InstrumentedDialogFragmentTest.java
@@ -16,18 +16,16 @@
 package com.android.settings.core.instrumentation;
 
 import android.os.Bundle;
-
+import com.android.settings.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
-
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
 import org.robolectric.annotation.Config;
 import org.robolectric.shadows.ShadowApplication;
 
 import static com.google.common.truth.Truth.assertThat;
 
-@RunWith(RobolectricTestRunner.class)
+@RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class InstrumentedDialogFragmentTest {
 
diff --git a/tests/robotests/src/com/android/settings/core/instrumentation/MetricsFeatureProviderTest.java b/tests/robotests/src/com/android/settings/core/instrumentation/MetricsFeatureProviderTest.java
index 22be988..41a2a71 100644
--- a/tests/robotests/src/com/android/settings/core/instrumentation/MetricsFeatureProviderTest.java
+++ b/tests/robotests/src/com/android/settings/core/instrumentation/MetricsFeatureProviderTest.java
@@ -16,22 +16,20 @@
 package com.android.settings.core.instrumentation;
 
 import android.content.Context;
-
+import com.android.settings.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
 import com.android.settings.overlay.FeatureFactory;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
 import org.robolectric.annotation.Config;
 import org.robolectric.shadows.ShadowApplication;
 
 import static com.google.common.truth.Truth.assertThat;
 
-@RunWith(RobolectricTestRunner.class)
+@RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class MetricsFeatureProviderTest {
 
diff --git a/tests/robotests/src/com/android/settings/core/instrumentation/SharedPreferenceLoggerTest.java b/tests/robotests/src/com/android/settings/core/instrumentation/SharedPreferenceLoggerTest.java
index a3e0e45..dad6fa9 100644
--- a/tests/robotests/src/com/android/settings/core/instrumentation/SharedPreferenceLoggerTest.java
+++ b/tests/robotests/src/com/android/settings/core/instrumentation/SharedPreferenceLoggerTest.java
@@ -17,16 +17,14 @@
 
 import android.content.Context;
 import android.content.SharedPreferences;
-
+import com.android.settings.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
 import com.android.settings.overlay.FeatureFactory;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
 import org.robolectric.annotation.Config;
 import org.robolectric.shadows.ShadowApplication;
 
@@ -36,7 +34,7 @@
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
-@RunWith(RobolectricTestRunner.class)
+@RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class SharedPreferenceLoggerTest {
 
diff --git a/tests/robotests/src/com/android/settings/core/instrumentation/VisibilityLoggerMixinTest.java b/tests/robotests/src/com/android/settings/core/instrumentation/VisibilityLoggerMixinTest.java
index 3fa8c94..56fa786 100644
--- a/tests/robotests/src/com/android/settings/core/instrumentation/VisibilityLoggerMixinTest.java
+++ b/tests/robotests/src/com/android/settings/core/instrumentation/VisibilityLoggerMixinTest.java
@@ -16,15 +16,13 @@
 package com.android.settings.core.instrumentation;
 
 import android.content.Context;
-
+import com.android.settings.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
 import org.robolectric.annotation.Config;
 
 import static com.android.settings.core.instrumentation.Instrumentable.METRICS_CATEGORY_UNKNOWN;
@@ -36,7 +34,7 @@
 import static org.mockito.Mockito.verify;
 
 
-@RunWith(RobolectricTestRunner.class)
+@RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class VisibilityLoggerMixinTest {
 
diff --git a/tests/robotests/src/com/android/settings/core/lifecycle/LifecycleTest.java b/tests/robotests/src/com/android/settings/core/lifecycle/LifecycleTest.java
index bc7b129..6aae543 100644
--- a/tests/robotests/src/com/android/settings/core/lifecycle/LifecycleTest.java
+++ b/tests/robotests/src/com/android/settings/core/lifecycle/LifecycleTest.java
@@ -16,7 +16,7 @@
 package com.android.settings.core.lifecycle;
 
 import android.content.Context;
-
+import com.android.settings.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
 import com.android.settings.core.lifecycle.events.OnAttach;
 import com.android.settings.core.lifecycle.events.OnDestroy;
@@ -24,18 +24,16 @@
 import com.android.settings.core.lifecycle.events.OnResume;
 import com.android.settings.core.lifecycle.events.OnStart;
 import com.android.settings.core.lifecycle.events.OnStop;
-
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
 import org.robolectric.annotation.Config;
 import org.robolectric.util.ActivityController;
 import org.robolectric.util.FragmentController;
 
 import static com.google.common.truth.Truth.assertThat;
 
-@RunWith(RobolectricTestRunner.class)
+@RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class LifecycleTest {
 
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardDividerDecorationTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardDividerDecorationTest.java
index adfa608..e829eb2 100644
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardDividerDecorationTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardDividerDecorationTest.java
@@ -24,18 +24,16 @@
 import android.support.v7.preference.PreferenceGroupAdapter;
 import android.support.v7.widget.RecyclerView;
 import android.view.View;
-
+import com.android.settings.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.testutils.FakeFeatureFactory;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Answers;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
 import org.robolectric.annotation.Config;
 
 import static org.mockito.Matchers.any;
@@ -43,7 +41,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-@RunWith(RobolectricTestRunner.class)
+@RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class DashboardDividerDecorationTest {
 
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java
index 6d11041..f47a244 100644
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java
@@ -22,8 +22,8 @@
 import android.os.Bundle;
 import android.support.v7.preference.Preference;
 import android.support.v7.preference.PreferenceScreen;
-
 import com.android.settings.SettingsActivity;
+import com.android.settings.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
 import com.android.settings.core.PreferenceController;
 import com.android.settings.overlay.FeatureFactory;
@@ -31,20 +31,17 @@
 import com.android.settingslib.drawer.CategoryKey;
 import com.android.settingslib.drawer.DashboardCategory;
 import com.android.settingslib.drawer.Tile;
-
+import java.util.ArrayList;
+import java.util.List;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Answers;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
 import org.robolectric.annotation.Config;
 import org.robolectric.shadows.ShadowApplication;
 
-import java.util.ArrayList;
-import java.util.List;
-
 import static com.google.common.truth.Truth.assertThat;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyString;
@@ -54,7 +51,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-@RunWith(RobolectricTestRunner.class)
+@RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class DashboardFragmentTest {
 
@@ -158,6 +155,21 @@
         assertThat(preference.getOrder()).isEqualTo(-tile.priority);
     }
 
+    @Test
+    public void updateState_skipUnavailablePrefs() {
+        List<PreferenceController> preferenceControllers = mTestFragment.mControllers;
+        preferenceControllers.add(mock(PreferenceController.class));
+        preferenceControllers.add(mock(PreferenceController.class));
+        when(preferenceControllers.get(0).isAvailable()).thenReturn(false);
+        when(preferenceControllers.get(1).isAvailable()).thenReturn(true);
+
+        mTestFragment.onAttach(ShadowApplication.getInstance().getApplicationContext());
+        mTestFragment.onResume();
+
+        verify(mTestFragment.mControllers.get(0), never()).getPreferenceKey();
+        verify(mTestFragment.mControllers.get(1)).getPreferenceKey();
+    }
+
     public static class TestPreferenceController extends PreferenceController {
 
         public TestPreferenceController(Context context) {
@@ -170,7 +182,7 @@
         }
 
         @Override
-        protected boolean isAvailable() {
+        public boolean isAvailable() {
             return false;
         }
 
@@ -189,10 +201,12 @@
 
         private final Context mContext;
         public PreferenceScreen mScreen;
+        private List<PreferenceController> mControllers;
 
         public TestFragment(Context context) {
             mContext = context;
             mScreen = mock(PreferenceScreen.class);
+            mControllers = new ArrayList<>();
         }
 
         @Override
@@ -227,7 +241,7 @@
 
         @Override
         protected List<PreferenceController> getPreferenceControllers(Context context) {
-            return null;
+            return mControllers;
         }
     }
 
diff --git a/tests/robotests/src/com/android/settings/dashboard/ProgressiveDisclosureTest.java b/tests/robotests/src/com/android/settings/dashboard/ProgressiveDisclosureTest.java
index be02596..ab94f35 100644
--- a/tests/robotests/src/com/android/settings/dashboard/ProgressiveDisclosureTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/ProgressiveDisclosureTest.java
@@ -20,23 +20,20 @@
 import android.support.v14.preference.PreferenceFragment;
 import android.support.v7.preference.Preference;
 import android.support.v7.preference.PreferenceScreen;
-
+import com.android.settings.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.testutils.FakeFeatureFactory;
-
+import java.util.List;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Answers;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
 import org.robolectric.annotation.Config;
 import org.robolectric.shadows.ShadowApplication;
 
-import java.util.List;
-
 import static com.google.common.truth.Truth.assertThat;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyInt;
@@ -46,7 +43,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-@RunWith(RobolectricTestRunner.class)
+@RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class ProgressiveDisclosureTest {
 
diff --git a/tests/robotests/src/com/android/settings/dashboard/conditional/ConditionTest.java b/tests/robotests/src/com/android/settings/dashboard/conditional/ConditionTest.java
index 5c0c02a..f8797aa 100644
--- a/tests/robotests/src/com/android/settings/dashboard/conditional/ConditionTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/conditional/ConditionTest.java
@@ -17,17 +17,15 @@
 
 import android.content.Context;
 import android.graphics.drawable.Icon;
-
 import com.android.internal.logging.MetricsProto;
+import com.android.settings.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
 import com.android.settings.core.instrumentation.MetricsFeatureProvider;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
 import org.robolectric.annotation.Config;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -35,7 +33,7 @@
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.verify;
 
-@RunWith(RobolectricTestRunner.class)
+@RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class ConditionTest {
 
diff --git a/tests/robotests/src/com/android/settings/dashboard/conditional/DashboardTilePreferenceTest.java b/tests/robotests/src/com/android/settings/dashboard/conditional/DashboardTilePreferenceTest.java
index 470eb43..b726419 100644
--- a/tests/robotests/src/com/android/settings/dashboard/conditional/DashboardTilePreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/conditional/DashboardTilePreferenceTest.java
@@ -21,20 +21,18 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.LinearLayout;
-
+import com.android.settings.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
 import com.android.settings.dashboard.DashboardTilePreference;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
 import org.robolectric.annotation.Config;
 import org.robolectric.shadows.ShadowApplication;
 
 import static com.google.common.truth.Truth.assertThat;
 
-@RunWith(RobolectricTestRunner.class)
+@RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class DashboardTilePreferenceTest {
 
diff --git a/tests/robotests/src/com/android/settings/datausage/BillingCycleSettingsTest.java b/tests/robotests/src/com/android/settings/datausage/BillingCycleSettingsTest.java
index 9ebb580..eec4324 100644
--- a/tests/robotests/src/com/android/settings/datausage/BillingCycleSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/datausage/BillingCycleSettingsTest.java
@@ -20,15 +20,13 @@
 import android.content.SharedPreferences;
 import android.os.Bundle;
 import android.support.v7.preference.PreferenceManager;
-
+import com.android.settings.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
 
@@ -39,7 +37,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-@RunWith(RobolectricTestRunner.class)
+@RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class BillingCycleSettingsTest {
 
diff --git a/tests/robotests/src/com/android/settings/datausage/DataUsageInfoControllerTest.java b/tests/robotests/src/com/android/settings/datausage/DataUsageInfoControllerTest.java
index 368d0a1..003f4d3 100644
--- a/tests/robotests/src/com/android/settings/datausage/DataUsageInfoControllerTest.java
+++ b/tests/robotests/src/com/android/settings/datausage/DataUsageInfoControllerTest.java
@@ -2,17 +2,17 @@
 
 import android.net.NetworkPolicy;
 import android.net.NetworkTemplate;
+import com.android.settings.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
 import com.android.settingslib.net.DataUsageController.DataUsageInfo;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
 import org.robolectric.annotation.Config;
 
 import static com.google.common.truth.Truth.assertThat;
 
-@RunWith(RobolectricTestRunner.class)
+@RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class DataUsageInfoControllerTest {
     private DataUsageInfoController mInfoController;
diff --git a/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java b/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java
index e9f4446..e8a2ee4 100644
--- a/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java
+++ b/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java
@@ -18,13 +18,13 @@
 
 import android.content.Context;
 import android.net.ConnectivityManager;
+import com.android.settings.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
 import org.robolectric.annotation.Config;
 import org.robolectric.shadows.ShadowApplication;
 
@@ -32,7 +32,7 @@
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Mockito.when;
 
-@RunWith(RobolectricTestRunner.class)
+@RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class DataUsageSummaryTest {
     @Mock private ConnectivityManager mManager;
diff --git a/tests/robotests/src/com/android/settings/datausage/UnrestrictedDataAccessTest.java b/tests/robotests/src/com/android/settings/datausage/UnrestrictedDataAccessTest.java
index a04861d..c7b8dee 100644
--- a/tests/robotests/src/com/android/settings/datausage/UnrestrictedDataAccessTest.java
+++ b/tests/robotests/src/com/android/settings/datausage/UnrestrictedDataAccessTest.java
@@ -17,21 +17,19 @@
 
 import android.content.pm.ApplicationInfo;
 import android.os.Process;
-
+import com.android.settings.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
 import com.android.settingslib.applications.ApplicationsState;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
 import org.robolectric.annotation.Config;
 
 import static com.google.common.truth.Truth.assertThat;
 
-@RunWith(RobolectricTestRunner.class)
+@RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class UnrestrictedDataAccessTest {
 
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/ManageStoragePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/ManageStoragePreferenceControllerTest.java
index d2c169e..12b3218 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/ManageStoragePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/ManageStoragePreferenceControllerTest.java
@@ -19,21 +19,18 @@
 import android.content.Context;
 import android.support.v7.preference.Preference;
 import android.support.v7.preference.PreferenceScreen;
-
+import com.android.settings.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
-
+import java.util.ArrayList;
+import java.util.List;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Answers;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
 import org.robolectric.annotation.Config;
 
-import java.util.ArrayList;
-import java.util.List;
-
 import static com.google.common.truth.Truth.assertThat;
 import static org.mockito.Answers.RETURNS_DEEP_STUBS;
 import static org.mockito.Matchers.any;
@@ -41,7 +38,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-@RunWith(RobolectricTestRunner.class)
+@RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class ManageStoragePreferenceControllerTest {
 
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/SystemUpdatePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/SystemUpdatePreferenceControllerTest.java
index 70cf454..9ca218c 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/SystemUpdatePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/SystemUpdatePreferenceControllerTest.java
@@ -19,28 +19,25 @@
 import android.os.UserManager;
 import android.support.v7.preference.Preference;
 import android.support.v7.preference.PreferenceScreen;
-
 import com.android.settings.R;
+import com.android.settings.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
-
+import java.util.ArrayList;
+import java.util.List;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
 import org.robolectric.annotation.Config;
 
-import java.util.ArrayList;
-import java.util.List;
-
 import static com.google.common.truth.Truth.assertThat;
 import static org.mockito.Answers.RETURNS_DEEP_STUBS;
 import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-@RunWith(RobolectricTestRunner.class)
+@RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class SystemUpdatePreferenceControllerTest {
 
diff --git a/tests/robotests/src/com/android/settings/network/MobileNetworkPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/MobileNetworkPreferenceControllerTest.java
index 0adfea8..d3d6836 100644
--- a/tests/robotests/src/com/android/settings/network/MobileNetworkPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/MobileNetworkPreferenceControllerTest.java
@@ -19,16 +19,14 @@
 import android.net.ConnectivityManager;
 import android.os.UserHandle;
 import android.os.UserManager;
-
+import com.android.settings.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Answers;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
 import org.robolectric.annotation.Config;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -36,7 +34,7 @@
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Mockito.when;
 
-@RunWith(RobolectricTestRunner.class)
+@RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class MobileNetworkPreferenceControllerTest {
 
diff --git a/tests/robotests/src/com/android/settings/network/NetworkDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/network/NetworkDashboardFragmentTest.java
index 386fbc6..6dd9c75 100644
--- a/tests/robotests/src/com/android/settings/network/NetworkDashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/network/NetworkDashboardFragmentTest.java
@@ -16,23 +16,21 @@
 package com.android.settings.network;
 
 import android.content.Context;
-
+import com.android.settings.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settingslib.drawer.CategoryKey;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Answers;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
 import org.robolectric.annotation.Config;
 
 import static com.google.common.truth.Truth.assertThat;
 
-@RunWith(RobolectricTestRunner.class)
+@RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class NetworkDashboardFragmentTest {
 
diff --git a/tests/robotests/src/com/android/settings/password/SetNewPasswordControllerTest.java b/tests/robotests/src/com/android/settings/password/SetNewPasswordControllerTest.java
index 61dbe08..2921b30 100644
--- a/tests/robotests/src/com/android/settings/password/SetNewPasswordControllerTest.java
+++ b/tests/robotests/src/com/android/settings/password/SetNewPasswordControllerTest.java
@@ -16,6 +16,22 @@
 
 package com.android.settings.password;
 
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.hardware.fingerprint.FingerprintManager;
+import android.os.Bundle;
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+
 import static android.content.pm.PackageManager.FEATURE_FINGERPRINT;
 import static com.android.settings.ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS;
 import static com.android.settings.ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY;
@@ -29,28 +45,10 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import android.app.admin.DevicePolicyManager;
-import android.content.ComponentName;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.hardware.fingerprint.FingerprintManager;
-import android.os.Bundle;
-
-import com.android.settings.TestConfig;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
 /**
  * Tests for {@link SetNewPasswordController}.
  */
-@RunWith(RobolectricTestRunner.class)
+@RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public final class SetNewPasswordControllerTest {
     private static final int CURRENT_UID = 101;
diff --git a/tests/robotests/src/com/android/settings/system/SystemDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/system/SystemDashboardFragmentTest.java
index eb8b43b..65a8805 100644
--- a/tests/robotests/src/com/android/settings/system/SystemDashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/system/SystemDashboardFragmentTest.java
@@ -18,20 +18,17 @@
 
 
 import android.app.Activity;
-
+import com.android.settings.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
 import com.android.settings.dashboard.SummaryLoader;
 import com.android.settings.testutils.FakeFeatureFactory;
-
 import com.google.common.truth.Truth;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Answers;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
 import org.robolectric.annotation.Config;
 
 import static com.android.settings.system.SystemDashboardFragment.SUMMARY_PROVIDER_FACTORY;
@@ -40,7 +37,7 @@
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 
-@RunWith(RobolectricTestRunner.class)
+@RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class SystemDashboardFragmentTest {
 
diff --git a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
index d872f7c..7bf908d 100644
--- a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
+++ b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
@@ -16,7 +16,6 @@
 package com.android.settings.testutils;
 
 import android.content.Context;
-
 import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.dashboard.DashboardFeatureProvider;
 import com.android.settings.fuelgauge.PowerUsageFeatureProvider;
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowTextUtils.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowTextUtils.java
index c6ed2fa..03991e6 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowTextUtils.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowTextUtils.java
@@ -21,11 +21,10 @@
 import android.provider.Settings;
 import android.text.TextUtils;
 import android.view.View;
+import java.util.Locale;
 import org.robolectric.annotation.Implementation;
 import org.robolectric.annotation.Implements;
 
-import java.util.Locale;
-
 /**
  * Important: The current robolectric doesn't support API 24, so I copy the code
  * from API 24 here to make it compatible. Once robolectric is upgraded to 24,
diff --git a/tests/robotests/src/com/android/settings/utils/ThreadUtilsTest.java b/tests/robotests/src/com/android/settings/utils/ThreadUtilsTest.java
index 6a804d0..4267ed1 100644
--- a/tests/robotests/src/com/android/settings/utils/ThreadUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/utils/ThreadUtilsTest.java
@@ -17,14 +17,13 @@
 
 
 import com.android.settings.TestConfig;
-
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.annotation.Config;
 
-import static org.junit.Assert.fail;
 import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.fail;
 
 @RunWith(RobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
diff --git a/tests/robotests/src/com/android/settings/widget/RtlCompatibleViewPagerTest.java b/tests/robotests/src/com/android/settings/widget/RtlCompatibleViewPagerTest.java
index cce0f32..da7b092 100644
--- a/tests/robotests/src/com/android/settings/widget/RtlCompatibleViewPagerTest.java
+++ b/tests/robotests/src/com/android/settings/widget/RtlCompatibleViewPagerTest.java
@@ -21,22 +21,19 @@
 import android.text.TextUtils;
 import android.view.View;
 import android.view.ViewGroup;
-
+import com.android.settings.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
 import com.android.settings.testutils.shadow.ShadowTextUtils;
-
+import java.util.Locale;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
 import org.robolectric.annotation.Config;
 import org.robolectric.shadows.ShadowApplication;
 
-import java.util.Locale;
-
 import static com.google.common.truth.Truth.assertThat;
 
-@RunWith(RobolectricTestRunner.class)
+@RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class RtlCompatibleViewPagerTest {