Add batch volume adjust support to adjustMasterVolume() in AudioManager and
AudioService.

Change-Id: I09b1dfc93f14ca836e1ba2a400c00caed01fd541
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 60b9ac0..5f6a61d 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -159,6 +159,9 @@
     // but to support integer based AudioManager API we translate it to 0 - 100
     private static final int MAX_MASTER_VOLUME = 100;
 
+    // Maximum volume adjust steps allowed in a single batch call.
+    private static final int MAX_BATCH_VOLUME_ADJUST_STEPS = 4;
+
     /* Sound effect file names  */
     private static final String SOUND_EFFECTS_PATH = "/media/audio/ui/";
     private static final String[] SOUND_EFFECT_FILES = new String[] {
@@ -619,38 +622,19 @@
     }
 
     /** @see AudioManager#adjustMasterVolume(int) */
-    public void adjustMasterVolume(int direction, int flags) {
-        ensureValidDirection(direction);
+    public void adjustMasterVolume(int steps, int flags) {
+        ensureValidSteps(steps);
         int volume = Math.round(AudioSystem.getMasterVolume() * MAX_MASTER_VOLUME);
         int delta = 0;
-
-        if (direction == AudioManager.ADJUST_RAISE) {
-            // This is the default value if we make it to the end
-            delta = mMasterVolumeRamp[1];
-            // If we're raising the volume move down the ramp array until we
-            // find the volume we're above and use that groups delta.
-            for (int i = mMasterVolumeRamp.length - 1; i > 1; i -= 2) {
-                if (volume >= mMasterVolumeRamp[i - 1]) {
-                    delta = mMasterVolumeRamp[i];
-                    break;
-                }
-            }
-        } else if (direction == AudioManager.ADJUST_LOWER){
-            int length = mMasterVolumeRamp.length;
-            // This is the default value if we make it to the end
-            delta = -mMasterVolumeRamp[length - 1];
-            // If we're lowering the volume move up the ramp array until we
-            // find the volume we're below and use the group below it's delta
-            for (int i = 2; i < length; i += 2) {
-                if (volume <= mMasterVolumeRamp[i]) {
-                    delta = -mMasterVolumeRamp[i - 1];
-                    break;
-                }
-            }
+        int numSteps = Math.abs(steps);
+        int direction = steps > 0 ? AudioManager.ADJUST_RAISE : AudioManager.ADJUST_LOWER;
+        for (int i = 0; i < numSteps; ++i) {
+            delta = findVolumeDelta(direction, volume);
+            volume += delta;
         }
 
-//        Log.d(TAG, "adjustMasterVolume volume: " + volume + " delta: " + delta + " direction: " + direction);
-        setMasterVolume(volume + delta, flags);
+        //Log.d(TAG, "adjustMasterVolume volume: " + volume + " steps: " + steps);
+        setMasterVolume(volume, flags);
     }
 
     /** @see AudioManager#setStreamVolume(int, int, int) */
@@ -691,6 +675,41 @@
         sendVolumeUpdate(streamType, oldIndex, index, flags);
     }
 
+    private int findVolumeDelta(int direction, int volume) {
+        int delta = 0;
+        if (direction == AudioManager.ADJUST_RAISE) {
+            if (volume == MAX_MASTER_VOLUME) {
+                return 0;
+            }
+            // This is the default value if we make it to the end
+            delta = mMasterVolumeRamp[1];
+            // If we're raising the volume move down the ramp array until we
+            // find the volume we're above and use that groups delta.
+            for (int i = mMasterVolumeRamp.length - 1; i > 1; i -= 2) {
+                if (volume >= mMasterVolumeRamp[i - 1]) {
+                    delta = mMasterVolumeRamp[i];
+                    break;
+                }
+            }
+        } else if (direction == AudioManager.ADJUST_LOWER){
+            if (volume == 0) {
+                return 0;
+            }
+            int length = mMasterVolumeRamp.length;
+            // This is the default value if we make it to the end
+            delta = -mMasterVolumeRamp[length - 1];
+            // If we're lowering the volume move up the ramp array until we
+            // find the volume we're below and use the group below it's delta
+            for (int i = 2; i < length; i += 2) {
+                if (volume <= mMasterVolumeRamp[i]) {
+                    delta = -mMasterVolumeRamp[i - 1];
+                    break;
+                }
+            }
+        }
+        return delta;
+    }
+
     // UI update and Broadcast Intent
     private void sendVolumeUpdate(int streamType, int oldIndex, int index, int flags) {
         if (!mVoiceCapable && (streamType == AudioSystem.STREAM_RING)) {
@@ -1871,6 +1890,12 @@
         }
     }
 
+    private void ensureValidSteps(int steps) {
+        if (Math.abs(steps) > MAX_BATCH_VOLUME_ADJUST_STEPS) {
+            throw new IllegalArgumentException("Bad volume adjust steps " + steps);
+        }
+    }
+
     private void ensureValidStreamType(int streamType) {
         if (streamType < 0 || streamType >= mStreamStates.length) {
             throw new IllegalArgumentException("Bad stream type " + streamType);