Merge "Make volume sliders sliceable" into pi-dev
diff --git a/res/xml/sound_settings.xml b/res/xml/sound_settings.xml
index 23936a7..7fd3709 100644
--- a/res/xml/sound_settings.xml
+++ b/res/xml/sound_settings.xml
@@ -27,6 +27,7 @@
         android:key="media_volume"
         android:icon="@*android:drawable/ic_audio_media"
         android:title="@string/media_volume_option_title"
+        settings:controller="com.android.settings.notification.MediaVolumePreferenceController"
         android:order="-170"/>
 
     <!-- Alarm volume -->
@@ -34,6 +35,7 @@
         android:key="alarm_volume"
         android:icon="@*android:drawable/ic_audio_alarm"
         android:title="@string/alarm_volume_option_title"
+        settings:controller="com.android.settings.notification.AlarmVolumePreferenceController"
         android:order="-160"/>
 
     <!-- Ring volume -->
@@ -41,6 +43,7 @@
         android:key="ring_volume"
         android:icon="@*android:drawable/ic_audio_ring_notif"
         android:title="@string/ring_volume_option_title"
+        settings:controller="com.android.settings.notification.RingVolumePreferenceController"
         android:order="-150"/>
 
     <!-- Notification volume -->
@@ -48,6 +51,7 @@
         android:key="notification_volume"
         android:icon="@*android:drawable/ic_audio_ring_notif"
         android:title="@string/notification_volume_option_title"
+        settings:controller="com.android.settings.notification.NotificationVolumePreferenceController"
         android:order="-140"/>
 
     <!-- Also vibrate for calls -->
diff --git a/src/com/android/settings/notification/AdjustVolumeRestrictedPreferenceController.java b/src/com/android/settings/notification/AdjustVolumeRestrictedPreferenceController.java
index bad626a..03032c5 100644
--- a/src/com/android/settings/notification/AdjustVolumeRestrictedPreferenceController.java
+++ b/src/com/android/settings/notification/AdjustVolumeRestrictedPreferenceController.java
@@ -24,6 +24,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.settings.accounts.AccountRestrictionHelper;
 import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.core.SliderPreferenceController;
 import com.android.settingslib.RestrictedPreference;
 import com.android.settingslib.core.AbstractPreferenceController;
 
@@ -32,17 +33,18 @@
  * restriction
  */
 public abstract class AdjustVolumeRestrictedPreferenceController extends
-        AbstractPreferenceController implements PreferenceControllerMixin {
+        SliderPreferenceController implements PreferenceControllerMixin {
 
     private AccountRestrictionHelper mHelper;
 
-    public AdjustVolumeRestrictedPreferenceController(Context context) {
-        this(context, new AccountRestrictionHelper(context));
+    public AdjustVolumeRestrictedPreferenceController(Context context, String key) {
+        this(context, new AccountRestrictionHelper(context), key);
     }
 
     @VisibleForTesting
-    AdjustVolumeRestrictedPreferenceController(Context context, AccountRestrictionHelper helper) {
-        super(context);
+    AdjustVolumeRestrictedPreferenceController(Context context, AccountRestrictionHelper helper,
+            String key) {
+        super(context, key);
         mHelper = helper;
     }
 
diff --git a/src/com/android/settings/notification/AlarmVolumePreferenceController.java b/src/com/android/settings/notification/AlarmVolumePreferenceController.java
index c9b283b..0900e3c 100644
--- a/src/com/android/settings/notification/AlarmVolumePreferenceController.java
+++ b/src/com/android/settings/notification/AlarmVolumePreferenceController.java
@@ -20,32 +20,21 @@
 import android.media.AudioManager;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.settings.notification.VolumeSeekBarPreference.Callback;
 import com.android.settings.R;
-import com.android.settingslib.core.lifecycle.Lifecycle;
 
 public class AlarmVolumePreferenceController extends
     VolumeSeekBarPreferenceController {
 
     private static final String KEY_ALARM_VOLUME = "alarm_volume";
-    private AudioHelper mHelper;
 
-    public AlarmVolumePreferenceController(Context context, Callback callback,
-        Lifecycle lifecycle) {
-        this(context, callback, lifecycle, new AudioHelper(context));
-    }
-
-    @VisibleForTesting
-    AlarmVolumePreferenceController(Context context, Callback callback, Lifecycle lifecycle,
-        AudioHelper helper) {
-        super(context, callback, lifecycle);
-        mHelper = helper;
+    public AlarmVolumePreferenceController(Context context) {
+        super(context, KEY_ALARM_VOLUME);
     }
 
     @Override
-    public boolean isAvailable() {
+    public int getAvailabilityStatus() {
         return mContext.getResources().getBoolean(R.bool.config_show_alarm_volume)
-                && !mHelper.isSingleVolume();
+                && !mHelper.isSingleVolume() ? AVAILABLE : DISABLED_UNSUPPORTED;
     }
 
     @Override
@@ -62,5 +51,4 @@
     public int getMuteIcon() {
         return com.android.internal.R.drawable.ic_audio_alarm_mute;
     }
-
 }
diff --git a/src/com/android/settings/notification/AudioHelper.java b/src/com/android/settings/notification/AudioHelper.java
index 51ba74c..5f745c8 100644
--- a/src/com/android/settings/notification/AudioHelper.java
+++ b/src/com/android/settings/notification/AudioHelper.java
@@ -18,6 +18,7 @@
 
 import android.annotation.UserIdInt;
 import android.content.Context;
+import android.media.AudioManager;
 import android.media.AudioSystem;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -29,9 +30,11 @@
 public class AudioHelper {
 
     private Context mContext;
+    private AudioManager mAudioManager;
 
     public AudioHelper(Context context) {
         mContext = context;
+        mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
     }
 
     public boolean isSingleVolume() {
@@ -49,4 +52,25 @@
     public Context createPackageContextAsUser(@UserIdInt int profileId) {
         return Utils.createPackageContextAsUser(mContext, profileId);
     }
+
+    public int getRingerModeInternal() {
+        return mAudioManager.getRingerModeInternal();
+    }
+
+    public int getLastAudibleStreamVolume(int stream) {
+        return mAudioManager.getLastAudibleStreamVolume(stream);
+    }
+
+    public int getStreamVolume(int stream) {
+        return mAudioManager.getStreamVolume(stream);
+    }
+
+    public boolean setStreamVolume(int stream, int volume) {
+        mAudioManager.setStreamVolume(stream, volume, 0);
+        return true;
+    }
+
+    public int getMaxVolume(int stream) {
+        return mAudioManager.getStreamMaxVolume(stream);
+    }
 }
diff --git a/src/com/android/settings/notification/MediaVolumePreferenceController.java b/src/com/android/settings/notification/MediaVolumePreferenceController.java
index 381135e..8f0a7f9 100644
--- a/src/com/android/settings/notification/MediaVolumePreferenceController.java
+++ b/src/com/android/settings/notification/MediaVolumePreferenceController.java
@@ -27,13 +27,15 @@
 
     private static final String KEY_MEDIA_VOLUME = "media_volume";
 
-    public MediaVolumePreferenceController(Context context, Callback callback, Lifecycle lifecycle) {
-        super(context, callback, lifecycle);
+    public MediaVolumePreferenceController(Context context) {
+        super(context, KEY_MEDIA_VOLUME);
     }
 
     @Override
-    public boolean isAvailable() {
-        return mContext.getResources().getBoolean(R.bool.config_show_media_volume);
+    public int getAvailabilityStatus() {
+        return mContext.getResources().getBoolean(R.bool.config_show_media_volume)
+                ? AVAILABLE
+                : DISABLED_UNSUPPORTED;
     }
 
     @Override
@@ -50,5 +52,4 @@
     public int getMuteIcon() {
         return com.android.internal.R.drawable.ic_audio_media_mute;
     }
-
 }
diff --git a/src/com/android/settings/notification/NotificationVolumePreferenceController.java b/src/com/android/settings/notification/NotificationVolumePreferenceController.java
index 4024f9f..8e7171d 100644
--- a/src/com/android/settings/notification/NotificationVolumePreferenceController.java
+++ b/src/com/android/settings/notification/NotificationVolumePreferenceController.java
@@ -22,32 +22,21 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.settings.R;
 import com.android.settings.Utils;
-import com.android.settings.notification.VolumeSeekBarPreference.Callback;
-import com.android.settingslib.core.lifecycle.Lifecycle;
 
 public class NotificationVolumePreferenceController extends
     RingVolumePreferenceController {
 
     private static final String KEY_NOTIFICATION_VOLUME = "notification_volume";
-    private AudioHelper mHelper;
 
-    public NotificationVolumePreferenceController(Context context, Callback callback,
-        Lifecycle lifecycle) {
-        this(context, callback, lifecycle, new AudioHelper(context));
+    public NotificationVolumePreferenceController(Context context) {
+        super(context, KEY_NOTIFICATION_VOLUME);
     }
 
-    @VisibleForTesting
-    NotificationVolumePreferenceController(Context context,
-        Callback callback, Lifecycle lifecycle, AudioHelper helper) {
-        super(context, callback, lifecycle);
-        mHelper = helper;
-    }
-
-
     @Override
-    public boolean isAvailable() {
+    public int getAvailabilityStatus() {
         return mContext.getResources().getBoolean(R.bool.config_show_notification_volume)
-                && !Utils.isVoiceCapable(mContext) && !mHelper.isSingleVolume();
+                && !Utils.isVoiceCapable(mContext) && !mHelper.isSingleVolume()
+                ? AVAILABLE : DISABLED_UNSUPPORTED;
     }
 
     @Override
diff --git a/src/com/android/settings/notification/RingVolumePreferenceController.java b/src/com/android/settings/notification/RingVolumePreferenceController.java
index 5acca04..ea071fa 100644
--- a/src/com/android/settings/notification/RingVolumePreferenceController.java
+++ b/src/com/android/settings/notification/RingVolumePreferenceController.java
@@ -31,8 +31,6 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.settings.R;
 import com.android.settings.Utils;
-import com.android.settings.notification.VolumeSeekBarPreference.Callback;
-import com.android.settingslib.core.lifecycle.Lifecycle;
 
 import java.util.Objects;
 
@@ -41,24 +39,18 @@
     private static final String TAG = "RingVolumeController";
     private static final String KEY_RING_VOLUME = "ring_volume";
 
-    private AudioManager mAudioManager;
     private Vibrator mVibrator;
     private int mRingerMode = -1;
     private ComponentName mSuppressor;
     private final RingReceiver mReceiver = new RingReceiver();
     private final H mHandler = new H();
-    private AudioHelper mHelper;
 
-    public RingVolumePreferenceController(Context context, Callback callback, Lifecycle lifecycle) {
-        this(context, callback, lifecycle, new AudioHelper(context));
+    public RingVolumePreferenceController(Context context) {
+        this(context, KEY_RING_VOLUME);
     }
 
-    @VisibleForTesting
-    RingVolumePreferenceController(Context context, Callback callback, Lifecycle lifecycle,
-        AudioHelper helper) {
-        super(context, callback, lifecycle);
-        mHelper = helper;
-        mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+    public RingVolumePreferenceController(Context context, String key) {
+        super(context, key);
         mVibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
         if (mVibrator != null && !mVibrator.hasVibrator()) {
             mVibrator = null;
@@ -86,8 +78,9 @@
     }
 
     @Override
-    public boolean isAvailable() {
-        return Utils.isVoiceCapable(mContext) && !mHelper.isSingleVolume();
+    public int getAvailabilityStatus() {
+        return Utils.isVoiceCapable(mContext) && !mHelper.isSingleVolume()
+                ? AVAILABLE : DISABLED_UNSUPPORTED;
     }
 
     @Override
@@ -101,7 +94,7 @@
     }
 
     private void updateRingerMode() {
-        final int ringerMode = mAudioManager.getRingerModeInternal();
+        final int ringerMode = mHelper.getRingerModeInternal();
         if (mRingerMode == ringerMode) return;
         mRingerMode = ringerMode;
         updatePreferenceIcon();
@@ -109,7 +102,7 @@
 
     private boolean wasRingerModeVibrate() {
         return mVibrator != null && mRingerMode == AudioManager.RINGER_MODE_SILENT
-            && mAudioManager.getLastAudibleStreamVolume(AudioManager.STREAM_RING) == 0;
+            && mHelper.getLastAudibleStreamVolume(getAudioStream()) == 0;
     }
 
     private void updateEffectsSuppressor() {
diff --git a/src/com/android/settings/notification/SoundSettings.java b/src/com/android/settings/notification/SoundSettings.java
index a7ba707..4c9ee38 100644
--- a/src/com/android/settings/notification/SoundSettings.java
+++ b/src/com/android/settings/notification/SoundSettings.java
@@ -124,7 +124,7 @@
 
     @Override
     protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
-        return buildPreferenceControllers(context, this, mVolumeCallback, getLifecycle());
+        return buildPreferenceControllers(context, this, getLifecycle());
     }
 
     @Override
@@ -143,6 +143,15 @@
         }
     }
 
+    @Override
+    public void onAttach(Context context) {
+        super.onAttach(context);
+        use(AlarmVolumePreferenceController.class).setCallback(mVolumeCallback);
+        use(MediaVolumePreferenceController.class).setCallback(mVolumeCallback);
+        use(RingVolumePreferenceController.class).setCallback(mVolumeCallback);
+        use(NotificationVolumePreferenceController.class).setCallback(mVolumeCallback);
+    }
+
     // === Volumes ===
 
     final class VolumePreferenceCallback implements VolumeSeekBarPreference.Callback {
@@ -176,18 +185,12 @@
     }
 
     private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
-            SoundSettings fragment, VolumeSeekBarPreference.Callback callback,
-            Lifecycle lifecycle) {
+            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 ===
-        controllers.add(new AlarmVolumePreferenceController(context, callback, lifecycle));
-        controllers.add(new MediaVolumePreferenceController(context, callback, lifecycle));
-        controllers.add(
-                new NotificationVolumePreferenceController(context, callback, lifecycle));
-        controllers.add(new RingVolumePreferenceController(context, callback, lifecycle));
+        // Volumes are added via xml
 
         // === Phone & notification ringtone ===
         controllers.add(new PhoneRingtonePreferenceController(context));
@@ -257,7 +260,7 @@
                 public List<AbstractPreferenceController> createPreferenceControllers(
                         Context context) {
                     return buildPreferenceControllers(context, null /* fragment */,
-                            null /* callback */, null /* lifecycle */);
+                            null /* lifecycle */);
                 }
 
                 @Override
diff --git a/src/com/android/settings/notification/VolumeSeekBarPreferenceController.java b/src/com/android/settings/notification/VolumeSeekBarPreferenceController.java
index 501cedc..74e801e 100644
--- a/src/com/android/settings/notification/VolumeSeekBarPreferenceController.java
+++ b/src/com/android/settings/notification/VolumeSeekBarPreferenceController.java
@@ -16,31 +16,37 @@
 
 package com.android.settings.notification;
 
+import android.arch.lifecycle.LifecycleObserver;
+import android.arch.lifecycle.OnLifecycleEvent;
 import android.content.Context;
 import android.support.v7.preference.PreferenceScreen;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.settings.notification.VolumeSeekBarPreference.Callback;
 import com.android.settingslib.core.lifecycle.Lifecycle;
-import com.android.settingslib.core.lifecycle.LifecycleObserver;
-import com.android.settingslib.core.lifecycle.events.OnPause;
-import com.android.settingslib.core.lifecycle.events.OnResume;
 
 /**
  * Base class for preference controller that handles VolumeSeekBarPreference
  */
 public abstract class VolumeSeekBarPreferenceController extends
-        AdjustVolumeRestrictedPreferenceController implements LifecycleObserver, OnResume, OnPause {
+        AdjustVolumeRestrictedPreferenceController implements LifecycleObserver {
 
     protected VolumeSeekBarPreference mPreference;
     protected VolumeSeekBarPreference.Callback mVolumePreferenceCallback;
+    protected AudioHelper mHelper;
 
-    public VolumeSeekBarPreferenceController(Context context, Callback callback,
-            Lifecycle lifecycle) {
-        super(context);
+    public VolumeSeekBarPreferenceController(Context context, String key) {
+        super(context, key);
+        setAudioHelper(new AudioHelper(context));
+    }
+
+    @VisibleForTesting
+    void setAudioHelper(AudioHelper helper) {
+        mHelper = helper;
+    }
+
+    public void setCallback(Callback callback) {
         mVolumePreferenceCallback = callback;
-        if (lifecycle != null) {
-            lifecycle.addObserver(this);
-        }
     }
 
     @Override
@@ -54,20 +60,44 @@
         }
     }
 
-    @Override
+    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
     public void onResume() {
         if (mPreference != null) {
             mPreference.onActivityResume();
         }
     }
 
-    @Override
+    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
     public void onPause() {
         if (mPreference != null) {
             mPreference.onActivityPause();
         }
     }
 
+    @Override
+    public int getSliderPosition() {
+        if (mPreference != null) {
+            return mPreference.getProgress();
+        }
+        return mHelper.getStreamVolume(getAudioStream());
+    }
+
+    @Override
+    public boolean setSliderPosition(int position) {
+        if (mPreference != null) {
+            mPreference.setProgress(position);
+        }
+        return mHelper.setStreamVolume(getAudioStream(), position);
+    }
+
+    @Override
+    public int getMaxSteps() {
+        if (mPreference != null) {
+            return mPreference.getMax();
+        }
+        return mHelper.getMaxVolume(getAudioStream());
+    }
+
     protected abstract int getAudioStream();
 
     protected abstract int getMuteIcon();
diff --git a/src/com/android/settings/notification/ZenModePreferenceController.java b/src/com/android/settings/notification/ZenModePreferenceController.java
index 5b59000..5c9c33b 100644
--- a/src/com/android/settings/notification/ZenModePreferenceController.java
+++ b/src/com/android/settings/notification/ZenModePreferenceController.java
@@ -27,13 +27,15 @@
 import android.support.v7.preference.PreferenceScreen;
 import android.util.Slog;
 
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnPause;
 import com.android.settingslib.core.lifecycle.events.OnResume;
 
-public class ZenModePreferenceController extends AdjustVolumeRestrictedPreferenceController
-        implements LifecycleObserver, OnResume, OnPause {
+public class ZenModePreferenceController extends AbstractPreferenceController
+        implements LifecycleObserver, OnResume, OnPause, PreferenceControllerMixin {
 
     private final String mKey;
     private SettingObserver mSettingObserver;
diff --git a/tests/robotests/src/com/android/settings/notification/AdjustVolumeRestrictedPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/AdjustVolumeRestrictedPreferenceControllerTest.java
index 999f83a..31b2eb1 100644
--- a/tests/robotests/src/com/android/settings/notification/AdjustVolumeRestrictedPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/AdjustVolumeRestrictedPreferenceControllerTest.java
@@ -43,6 +43,7 @@
 @RunWith(SettingsRobolectricTestRunner.class)
 public class AdjustVolumeRestrictedPreferenceControllerTest {
 
+    private static final String KEY = "key";
     @Mock
     private AccountRestrictionHelper mAccountHelper;
 
@@ -54,7 +55,7 @@
         MockitoAnnotations.initMocks(this);
         mContext = spy(RuntimeEnvironment.application);
         mController =
-            new AdjustVolumeRestrictedPreferenceControllerTestable(mContext, mAccountHelper);
+            new AdjustVolumeRestrictedPreferenceControllerTestable(mContext, mAccountHelper, KEY);
     }
 
     @Test
@@ -88,13 +89,18 @@
         extends AdjustVolumeRestrictedPreferenceController {
 
         private AdjustVolumeRestrictedPreferenceControllerTestable(Context context,
-            AccountRestrictionHelper helper) {
-            super(context, helper);
+            AccountRestrictionHelper helper, String key) {
+            super(context, helper, key);
+        }
+
+        @Override
+        public int getAvailabilityStatus() {
+            return 0;
         }
 
         @Override
         public String getPreferenceKey() {
-            return null;
+            return KEY;
         }
 
         @Override
@@ -103,8 +109,18 @@
         }
 
         @Override
-        public boolean isAvailable() {
-            return true;
+        public int getSliderPosition() {
+            return 0;
+        }
+
+        @Override
+        public boolean setSliderPosition(int position) {
+            return false;
+        }
+
+        @Override
+        public int getMaxSteps() {
+            return 0;
         }
     }
 }
diff --git a/tests/robotests/src/com/android/settings/notification/AlarmVolumePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/AlarmVolumePreferenceControllerTest.java
index 017a26a..6e8476c 100644
--- a/tests/robotests/src/com/android/settings/notification/AlarmVolumePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/AlarmVolumePreferenceControllerTest.java
@@ -45,7 +45,8 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mContext = RuntimeEnvironment.application;
-        mController = new AlarmVolumePreferenceController(mContext, null, null, mHelper);
+        mController = new AlarmVolumePreferenceController(mContext);
+        mController.setAudioHelper(mHelper);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/notification/MediaVolumePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/MediaVolumePreferenceControllerTest.java
index 65680b1..3659a30 100644
--- a/tests/robotests/src/com/android/settings/notification/MediaVolumePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/MediaVolumePreferenceControllerTest.java
@@ -35,8 +35,7 @@
 
     @Before
     public void setUp() {
-        mController =
-            new MediaVolumePreferenceController(RuntimeEnvironment.application, null, null);
+        mController = new MediaVolumePreferenceController(RuntimeEnvironment.application);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/notification/NotificationVolumePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/NotificationVolumePreferenceControllerTest.java
index 1c605b9..c209c1b 100644
--- a/tests/robotests/src/com/android/settings/notification/NotificationVolumePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/NotificationVolumePreferenceControllerTest.java
@@ -57,7 +57,8 @@
         when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
         when(mContext.getSystemService(Context.AUDIO_SERVICE)).thenReturn(mAudioManager);
         when(mContext.getSystemService(Context.VIBRATOR_SERVICE)).thenReturn(mVibrator);
-        mController = new NotificationVolumePreferenceController(mContext, null, null, mHelper);
+        mController = new NotificationVolumePreferenceController(mContext);
+        mController.setAudioHelper(mHelper);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/notification/RingVolumePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/RingVolumePreferenceControllerTest.java
index f5e87e7..e006530 100644
--- a/tests/robotests/src/com/android/settings/notification/RingVolumePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/RingVolumePreferenceControllerTest.java
@@ -65,7 +65,8 @@
         shadowContext.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
         mContext = RuntimeEnvironment.application;
         when(mNotificationManager.getEffectsSuppressor()).thenReturn(mSuppressor);
-        mController = new RingVolumePreferenceController(mContext, null, null, mHelper);
+        mController = new RingVolumePreferenceController(mContext);
+        mController.setAudioHelper(mHelper);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/notification/VolumeSeekBarPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/VolumeSeekBarPreferenceControllerTest.java
index a6addb3..675ac57 100644
--- a/tests/robotests/src/com/android/settings/notification/VolumeSeekBarPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/VolumeSeekBarPreferenceControllerTest.java
@@ -16,6 +16,7 @@
 
 package com.android.settings.notification;
 
+import static com.google.common.truth.Truth.assertThat;
 import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyInt;
@@ -46,6 +47,8 @@
     private VolumeSeekBarPreference mPreference;
     @Mock
     private VolumeSeekBarPreference.Callback mCallback;
+    @Mock
+    private AudioHelper mHelper;
 
     private VolumeSeekBarPreferenceControllerTestable mController;
 
@@ -53,7 +56,10 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         when(mScreen.findPreference(nullable(String.class))).thenReturn(mPreference);
-        mController = new VolumeSeekBarPreferenceControllerTestable(mContext, mCallback);
+        when(mPreference.getKey()).thenReturn("key");
+        mController = new VolumeSeekBarPreferenceControllerTestable(mContext, mCallback,
+                mPreference.getKey());
+        mController.setAudioHelper(mHelper);
     }
 
     @Test
@@ -67,7 +73,8 @@
 
     @Test
     public void displayPreference_notAvailable_shouldNotUpdatePreference() {
-        mController = new VolumeSeekBarPreferenceControllerTestable(mContext, mCallback, false);
+        mController = new VolumeSeekBarPreferenceControllerTestable(mContext, mCallback, false,
+                mPreference.getKey());
 
         mController.displayPreference(mScreen);
 
@@ -94,6 +101,42 @@
         verify(mPreference).onActivityPause();
     }
 
+    @Test
+    public void sliderMethods_handleNullPreference() {
+        when(mHelper.getStreamVolume(mController.getAudioStream())).thenReturn(4);
+        when(mHelper.getMaxVolume(mController.getAudioStream())).thenReturn(10);
+
+        assertThat(mController.getMaxSteps()).isEqualTo(10);
+        assertThat(mController.getSliderPosition()).isEqualTo(4);
+
+        mController.setSliderPosition(9);
+        verify(mHelper).setStreamVolume(mController.getAudioStream(), 9);
+    }
+
+    @Test
+    public void setSliderPosition_passesAlongValue() {
+        mController.displayPreference(mScreen);
+
+        mController.setSliderPosition(2);
+        verify(mPreference).setProgress(2);
+    }
+
+    @Test
+    public void getMaxSteps_passesAlongValue() {
+        when(mPreference.getMax()).thenReturn(6);
+        mController.displayPreference(mScreen);
+
+        assertThat(mController.getMaxSteps()).isEqualTo(6);
+    }
+
+    @Test
+    public void getSliderPosition_passesAlongValue() {
+        when(mPreference.getProgress()).thenReturn(7);
+        mController.displayPreference(mScreen);
+
+        assertThat(mController.getSliderPosition()).isEqualTo(7);
+    }
+
     private class VolumeSeekBarPreferenceControllerTestable
         extends VolumeSeekBarPreferenceController {
 
@@ -103,19 +146,20 @@
         private boolean mAvailable;
 
         VolumeSeekBarPreferenceControllerTestable(Context context,
-            VolumeSeekBarPreference.Callback callback) {
-            this(context, callback, true);
+            VolumeSeekBarPreference.Callback callback, String key) {
+            this(context, callback, true, key);
         }
 
         VolumeSeekBarPreferenceControllerTestable(Context context,
-            VolumeSeekBarPreference.Callback callback, boolean available) {
-            super(context, callback, null);
+            VolumeSeekBarPreference.Callback callback, boolean available, String key) {
+            super(context, key);
+            setCallback(callback);
             mAvailable = available;
         }
 
         @Override
         public String getPreferenceKey() {
-            return null;
+            return "key";
         }
 
         @Override
@@ -124,8 +168,8 @@
         }
 
         @Override
-        public boolean isAvailable() {
-            return mAvailable;
+        public int getAvailabilityStatus() {
+            return mAvailable ? AVAILABLE : DISABLED_UNSUPPORTED;
         }
 
         @Override