AudioService: Define minimum levels for volume streams.

 - Set a floor of 1 for voice call + bluetooth sco, otherwise 0.
 - All api calls validated to ensure a floor of the min level.
 - Volume UI updated to shift the seekbar by the min value.
 - Remove duplicate static max method in AudioService.
 - Ensure streams with a min level > 0 are not considered muteable.

Bug: 19260237
Change-Id: I213180c9c277f51bd3897b7f777e5f88ed1db125
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java b/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
index 51adaac..d16b818 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
@@ -253,6 +253,7 @@
         int iconRes;
         int iconMuteRes;
         int iconSuppressedRes;
+        int minVolume;
     }
 
     // Synchronize when accessing this
@@ -558,6 +559,14 @@
         }
     }
 
+    private int getStreamMinVolume(int streamType) {
+        if (streamType == STREAM_REMOTE_MUSIC) {
+            return 0;
+        } else {
+            return mAudioManager.getStreamMinVolume(streamType);
+        }
+    }
+
     private int getStreamMaxVolume(int streamType) {
         if (streamType == STREAM_REMOTE_MUSIC) {
             if (mStreamControls != null) {
@@ -661,9 +670,8 @@
                     }
                 });
             }
-            final int plusOne = (streamType == AudioSystem.STREAM_BLUETOOTH_SCO ||
-                    streamType == AudioSystem.STREAM_VOICE_CALL) ? 1 : 0;
-            sc.seekbarView.setMax(getStreamMaxVolume(streamType) + plusOne);
+            sc.minVolume = getStreamMinVolume(streamType);
+            sc.seekbarView.setMax(getStreamMaxVolume(streamType) - sc.minVolume);
             sc.seekbarView.setOnSeekBarChangeListener(mSeekListener);
             sc.seekbarView.setTag(sc);
             mStreamControls.put(streamType, sc);
@@ -706,7 +714,7 @@
         if (progress < 0) {
             progress = getStreamVolume(sc.streamType);
         }
-        sc.seekbarView.setProgress(progress);
+        sc.seekbarView.setProgress(progress - sc.minVolume);
         if (isRinger) {
             mLastRingerProgress = progress;
         }
@@ -1034,7 +1042,7 @@
 
         // get max volume for progress bar
 
-        int max = getStreamMaxVolume(streamType);
+        int max = getStreamMaxVolume(streamType) - getStreamMinVolume(streamType);
         StreamControl sc = mStreamControls.get(streamType);
 
         switch (streamType) {
@@ -1061,17 +1069,6 @@
                 break;
             }
 
-            case AudioManager.STREAM_VOICE_CALL: {
-                /*
-                 * For in-call voice call volume, there is no inaudible volume.
-                 * Rescale the UI control so the progress bar doesn't go all
-                 * the way to zero and don't show the mute icon.
-                 */
-                index++;
-                max++;
-                break;
-            }
-
             case AudioManager.STREAM_ALARM: {
                 break;
             }
@@ -1085,17 +1082,6 @@
                 break;
             }
 
-            case AudioManager.STREAM_BLUETOOTH_SCO: {
-                /*
-                 * For in-call voice call volume, there is no inaudible volume.
-                 * Rescale the UI control so the progress bar doesn't go all
-                 * the way to zero and don't show the mute icon.
-                 */
-                index++;
-                max++;
-                break;
-            }
-
             case STREAM_REMOTE_MUSIC: {
                 if (controller == null && sc != null) {
                     // If we weren't passed one try using the last one set.
@@ -1493,7 +1479,7 @@
             final Object tag = seekBar.getTag();
             if (fromUser && tag instanceof StreamControl) {
                 StreamControl sc = (StreamControl) tag;
-                setStreamVolume(sc, progress,
+                setStreamVolume(sc, progress + sc.minVolume,
                         AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_VIBRATE);
             }
             resetTimeout();