Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8e7aca38 authored by Jean-Michel Trivi's avatar Jean-Michel Trivi
Browse files

AudioManager: add method to query stream attenuations in dB

AudioManager: new methods in SDK for querying:
 - the minimum volume index
 - the volume in dB for a given index on a given device type

Bug: 64844598
Test: cts-tradefed run cts-dev -m CtsMediaTestCases -t android.media.cts.AudioManagerTest
Change-Id: Iac999e7676643272820a4f1f4a32cf3a781ab7cd
parent 53b2d749
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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();
+54 −0
Original line number Diff line number Diff line
@@ -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) {
+87 −3
Original line number Diff line number Diff line
@@ -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.
     *
+1 −1
Original line number Diff line number Diff line
@@ -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() {
+1 −1
Original line number Diff line number Diff line
@@ -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;