diff options
| -rw-r--r-- | api/current.txt | 2 | ||||
| -rw-r--r-- | media/java/android/media/AudioDeviceInfo.java | 54 | ||||
| -rw-r--r-- | media/java/android/media/AudioManager.java | 90 | ||||
| -rw-r--r-- | packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java | 2 | ||||
| -rw-r--r-- | services/core/java/com/android/server/audio/AudioService.java | 2 |
5 files changed, 145 insertions, 5 deletions
diff --git a/api/current.txt b/api/current.txt index 9bdcdadc7841..c38f2ac7c9dc 100644 --- a/api/current.txt +++ b/api/current.txt @@ -21636,7 +21636,9 @@ package android.media { method public int getRingerMode(); method public deprecated int getRouting(int); method public int getStreamMaxVolume(int); + method public int getStreamMinVolume(int); method public int getStreamVolume(int); + method public float getStreamVolumeDb(int, int, int); method public deprecated int getVibrateSetting(int); method public deprecated boolean isBluetoothA2dpOn(); method public boolean isBluetoothScoAvailableOffCall(); diff --git a/media/java/android/media/AudioDeviceInfo.java b/media/java/android/media/AudioDeviceInfo.java index 19d467a69c29..1a97b6ba762f 100644 --- a/media/java/android/media/AudioDeviceInfo.java +++ b/media/java/android/media/AudioDeviceInfo.java @@ -16,9 +16,12 @@ package android.media; +import android.annotation.IntDef; import android.annotation.NonNull; import android.util.SparseIntArray; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.TreeSet; /** @@ -120,6 +123,57 @@ public final class AudioDeviceInfo { */ public static final int TYPE_USB_HEADSET = 22; + /** @hide */ + @IntDef(flag = false, prefix = "TYPE", value = { + TYPE_BUILTIN_EARPIECE, + TYPE_BUILTIN_SPEAKER, + TYPE_WIRED_HEADSET, + TYPE_WIRED_HEADPHONES, + TYPE_BLUETOOTH_SCO, + TYPE_BLUETOOTH_A2DP, + TYPE_HDMI, + TYPE_DOCK, + TYPE_USB_ACCESSORY, + TYPE_USB_DEVICE, + TYPE_USB_HEADSET, + TYPE_TELEPHONY, + TYPE_LINE_ANALOG, + TYPE_HDMI_ARC, + TYPE_LINE_DIGITAL, + TYPE_FM, + TYPE_AUX_LINE, + TYPE_IP } + ) + @Retention(RetentionPolicy.SOURCE) + public @interface AudioDeviceTypeOut {} + + /** @hide */ + /*package*/ static boolean isValidAudioDeviceTypeOut(int type) { + switch (type) { + case TYPE_BUILTIN_EARPIECE: + case TYPE_BUILTIN_SPEAKER: + case TYPE_WIRED_HEADSET: + case TYPE_WIRED_HEADPHONES: + case TYPE_BLUETOOTH_SCO: + case TYPE_BLUETOOTH_A2DP: + case TYPE_HDMI: + case TYPE_DOCK: + case TYPE_USB_ACCESSORY: + case TYPE_USB_DEVICE: + case TYPE_USB_HEADSET: + case TYPE_TELEPHONY: + case TYPE_LINE_ANALOG: + case TYPE_HDMI_ARC: + case TYPE_LINE_DIGITAL: + case TYPE_FM: + case TYPE_AUX_LINE: + case TYPE_IP: + return true; + default: + return false; + } + } + private final AudioDevicePort mPort; AudioDeviceInfo(AudioDevicePort port) { diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index 58976ca0d5cc..f87c8461c7c6 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -16,6 +16,7 @@ package android.media; +import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; @@ -52,6 +53,8 @@ import android.util.Log; import android.util.Slog; import android.view.KeyEvent; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -911,13 +914,28 @@ public class AudioManager { /** * Returns the minimum volume index for a particular stream. - * - * @param streamType The stream type whose minimum volume index is returned. + * @param streamType The stream type whose minimum volume index is returned. Must be one of + * {@link #STREAM_VOICE_CALL}, {@link #STREAM_SYSTEM}, + * {@link #STREAM_RING}, {@link #STREAM_MUSIC}, {@link #STREAM_ALARM}, + * {@link #STREAM_NOTIFICATION}, {@link #STREAM_DTMF} or {@link #STREAM_ACCESSIBILITY}. * @return The minimum valid volume index for the stream. * @see #getStreamVolume(int) - * @hide */ public int getStreamMinVolume(int streamType) { + if (!isPublicStreamType(streamType)) { + throw new IllegalArgumentException("Invalid stream type " + streamType); + } + return getStreamMinVolumeInt(streamType); + } + + /** + * @hide + * Same as {@link #getStreamMinVolume(int)} but without the check on the public stream type. + * @param streamType The stream type whose minimum volume index is returned. + * @return The minimum valid volume index for the stream. + * @see #getStreamVolume(int) + */ + public int getStreamMinVolumeInt(int streamType) { final IAudioService service = getService(); try { return service.getStreamMinVolume(streamType); @@ -943,6 +961,72 @@ public class AudioManager { } } + // keep in sync with frameworks/av/services/audiopolicy/common/include/Volume.h + private static final float VOLUME_MIN_DB = -758.0f; + + /** @hide */ + @IntDef(flag = false, prefix = "STREAM", value = { + STREAM_VOICE_CALL, + STREAM_SYSTEM, + STREAM_RING, + STREAM_MUSIC, + STREAM_ALARM, + STREAM_NOTIFICATION, + STREAM_DTMF, + STREAM_ACCESSIBILITY } + ) + @Retention(RetentionPolicy.SOURCE) + public @interface PublicStreamTypes {} + + /** + * Returns the volume in dB (decibel) for the given stream type at the given volume index, on + * the given type of audio output device. + * @param streamType stream type for which the volume is queried. + * @param index the volume index for which the volume is queried. The index value must be + * between the minimum and maximum index values for the given stream type (see + * {@link #getStreamMinVolume(int)} and {@link #getStreamMaxVolume(int)}). + * @param deviceType the type of audio output device for which volume is queried. + * @return a volume expressed in dB. + * A negative value indicates the audio signal is attenuated. A typical maximum value + * at the maximum volume index is 0 dB (no attenuation nor amplification). Muting is + * reflected by a value of {@link Float#NEGATIVE_INFINITY}. + */ + public float getStreamVolumeDb(@PublicStreamTypes int streamType, int index, + @AudioDeviceInfo.AudioDeviceTypeOut int deviceType) { + if (!isPublicStreamType(streamType)) { + throw new IllegalArgumentException("Invalid stream type " + streamType); + } + if (index > getStreamMaxVolume(streamType) || index < getStreamMinVolume(streamType)) { + throw new IllegalArgumentException("Invalid stream volume index " + index); + } + if (!AudioDeviceInfo.isValidAudioDeviceTypeOut(deviceType)) { + throw new IllegalArgumentException("Invalid audio output device type " + deviceType); + } + final float gain = AudioSystem.getStreamVolumeDB(streamType, index, + AudioDeviceInfo.convertDeviceTypeToInternalDevice(deviceType)); + if (gain <= VOLUME_MIN_DB) { + return Float.NEGATIVE_INFINITY; + } else { + return gain; + } + } + + private static boolean isPublicStreamType(int streamType) { + switch (streamType) { + case STREAM_VOICE_CALL: + case STREAM_SYSTEM: + case STREAM_RING: + case STREAM_MUSIC: + case STREAM_ALARM: + case STREAM_NOTIFICATION: + case STREAM_DTMF: + case STREAM_ACCESSIBILITY: + return true; + default: + return false; + } + } + /** * Get last audible volume before stream was muted. * diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java index 212979004c89..4464f75bf9ec 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java @@ -168,7 +168,7 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa } protected int getAudioManagerStreamMinVolume(int stream) { - return mAudio.getStreamMinVolume(stream); + return mAudio.getStreamMinVolumeInt(stream); } public void register() { diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index efa0bf82f209..9cd4fe77d970 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -2203,7 +2203,7 @@ public class AudioService extends IAudioService.Stub return (mStreamStates[streamType].getMaxIndex() + 5) / 10; } - /** @see AudioManager#getStreamMinVolume(int) */ + /** @see AudioManager#getStreamMinVolumeInt(int) */ public int getStreamMinVolume(int streamType) { ensureValidStreamType(streamType); return (mStreamStates[streamType].getMinIndex() + 5) / 10; |