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

Commit 2dbacb6c authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add SystemApi for querying audio routing"

parents c54923ca 56b97b74
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -23663,6 +23663,7 @@ package android.media {
    field public static final int TYPE_BUILTIN_EARPIECE = 1; // 0x1
    field public static final int TYPE_BUILTIN_MIC = 15; // 0xf
    field public static final int TYPE_BUILTIN_SPEAKER = 2; // 0x2
    field public static final int TYPE_BUILTIN_SPEAKER_SAFE = 24; // 0x18
    field public static final int TYPE_BUS = 21; // 0x15
    field public static final int TYPE_DOCK = 13; // 0xd
    field public static final int TYPE_FM = 14; // 0xe
+5 −0
Original line number Diff line number Diff line
@@ -4063,6 +4063,10 @@ package android.media {
    field public static final int ROLE_OUTPUT = 2; // 0x2
  }
  public final class AudioDeviceInfo {
    field public static final int TYPE_REMOTE_SUBMIX = 25; // 0x19
  }
  public final class AudioFocusInfo implements android.os.Parcelable {
    method public int describeContents();
    method @NonNull public android.media.AudioAttributes getAttributes();
@@ -4090,6 +4094,7 @@ package android.media {
    method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int dispatchAudioFocusChange(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy);
    method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static java.util.List<android.media.audiopolicy.AudioProductStrategy> getAudioProductStrategies();
    method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static java.util.List<android.media.audiopolicy.AudioVolumeGroup> getAudioVolumeGroups();
    method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public java.util.List<android.media.AudioDeviceAddress> getDevicesForAttributes(@NonNull android.media.AudioAttributes);
    method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getMaxVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
    method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getMinVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
    method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public android.media.AudioDeviceAddress getPreferredDeviceForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy);
+43 −0
Original line number Diff line number Diff line
@@ -2312,6 +2312,48 @@ android_media_AudioSystem_getPreferredDeviceForStrategy(JNIEnv *env, jobject thi
    return jStatus;
}

static jint
android_media_AudioSystem_getDevicesForAttributes(JNIEnv *env, jobject thiz,
        jobject jaa, jobjectArray jDeviceArray)
{
    const jsize maxResultSize = env->GetArrayLength(jDeviceArray);
    // the JNI is always expected to provide us with an array capable of holding enough
    // devices i.e. the most we ever route a track to. This is preferred over receiving an ArrayList
    // with reverse JNI to make the array grow as need as this would be less efficient, and some
    // components call this method often
    if (jDeviceArray == nullptr || maxResultSize == 0) {
        ALOGE("%s invalid array to store AudioDeviceAddress", __FUNCTION__);
        return (jint)AUDIO_JAVA_BAD_VALUE;
    }

    JNIAudioAttributeHelper::UniqueAaPtr paa = JNIAudioAttributeHelper::makeUnique();
    jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jaa, paa.get());
    if (jStatus != (jint) AUDIO_JAVA_SUCCESS) {
        return jStatus;
    }

    AudioDeviceTypeAddrVector devices;
    jStatus = check_AudioSystem_Command(
            AudioSystem::getDevicesForAttributes(*(paa.get()), &devices));
    if (jStatus != NO_ERROR) {
        return jStatus;
    }

    if (devices.size() > maxResultSize) {
        return AUDIO_JAVA_INVALID_OPERATION;
    }
    size_t index = 0;
    jobject jAudioDeviceAddress = NULL;
    for (const auto& device : devices) {
        jStatus = createAudioDeviceAddressFromNative(env, &jAudioDeviceAddress, &device);
        if (jStatus != AUDIO_JAVA_SUCCESS) {
            return jStatus;
        }
        env->SetObjectArrayElement(jDeviceArray, index++, jAudioDeviceAddress);
    }
    return jStatus;
}

// ----------------------------------------------------------------------------

static const JNINativeMethod gMethods[] = {
@@ -2395,6 +2437,7 @@ static const JNINativeMethod gMethods[] = {
    {"setPreferredDeviceForStrategy", "(IILjava/lang/String;)I", (void *)android_media_AudioSystem_setPreferredDeviceForStrategy},
    {"removePreferredDeviceForStrategy", "(I)I", (void *)android_media_AudioSystem_removePreferredDeviceForStrategy},
    {"getPreferredDeviceForStrategy", "(I[Landroid/media/AudioDeviceAddress;)I", (void *)android_media_AudioSystem_getPreferredDeviceForStrategy},
    {"getDevicesForAttributes", "(Landroid/media/AudioAttributes;[Landroid/media/AudioDeviceAddress;)I", (void *)android_media_AudioSystem_getDevicesForAttributes}
};

static const JNINativeMethod gEventHandlerMethods[] = {
+28 −4
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.media;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.util.SparseIntArray;

import java.lang.annotation.Retention;
@@ -127,6 +128,23 @@ public final class AudioDeviceInfo {
     * A device type describing a Hearing Aid.
     */
    public static final int TYPE_HEARING_AID   = 23;
    /**
     * A device type describing the speaker system (i.e. a mono speaker or stereo speakers) built
     * in a device, that is specifically tuned for outputting sounds like notifications and alarms
     * (i.e. sounds the user couldn't necessarily anticipate).
     * <p>Note that this physical audio device may be the same as {@link #TYPE_BUILTIN_SPEAKER}
     * but is driven differently to safely accommodate the different use case.</p>
     */
    public static final int TYPE_BUILTIN_SPEAKER_SAFE = 24;
    /**
     * @hide
     * A device type for rerouting audio within the Android framework between mixes and
     * system applications. Typically created when using
     * {@link android.media.audiopolicy.AudioPolicy} for mixes created with the
     * {@link android.media.audiopolicy.AudioMix#ROUTE_FLAG_RENDER} flag.
     */
    @SystemApi
    public static final int TYPE_REMOTE_SUBMIX = 25;

    /** @hide */
    @IntDef(flag = false, prefix = "TYPE", value = {
@@ -228,6 +246,8 @@ public final class AudioDeviceInfo {
            case TYPE_IP:
            case TYPE_BUS:
            case TYPE_HEARING_AID:
            case TYPE_BUILTIN_SPEAKER_SAFE:
            case TYPE_REMOTE_SUBMIX:
                return true;
            default:
                return false;
@@ -253,6 +273,7 @@ public final class AudioDeviceInfo {
            case TYPE_LINE_DIGITAL:
            case TYPE_IP:
            case TYPE_BUS:
            case TYPE_REMOTE_SUBMIX:
                return true;
            default:
                return false;
@@ -449,6 +470,9 @@ public final class AudioDeviceInfo {
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_IP, TYPE_IP);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BUS, TYPE_BUS);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_HEARING_AID, TYPE_HEARING_AID);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_SPEAKER_SAFE,
                TYPE_BUILTIN_SPEAKER_SAFE);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX, TYPE_REMOTE_SUBMIX);

        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BUILTIN_MIC, TYPE_BUILTIN_MIC);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BLUETOOTH_SCO_HEADSET, TYPE_BLUETOOTH_SCO);
@@ -468,10 +492,7 @@ public final class AudioDeviceInfo {
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, TYPE_BLUETOOTH_A2DP);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_IP, TYPE_IP);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BUS, TYPE_BUS);

        // not covered here, legacy
        //AudioSystem.DEVICE_OUT_REMOTE_SUBMIX
        //AudioSystem.DEVICE_IN_REMOTE_SUBMIX
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_REMOTE_SUBMIX, TYPE_REMOTE_SUBMIX);

        // privileges mapping to output device
        EXT_TO_INT_DEVICE_MAPPING = new SparseIntArray();
@@ -498,6 +519,9 @@ public final class AudioDeviceInfo {
        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_IP, AudioSystem.DEVICE_OUT_IP);
        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BUS, AudioSystem.DEVICE_OUT_BUS);
        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_HEARING_AID, AudioSystem.DEVICE_OUT_HEARING_AID);
        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BUILTIN_SPEAKER_SAFE,
                AudioSystem.DEVICE_OUT_SPEAKER_SAFE);
        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_REMOTE_SUBMIX, AudioSystem.DEVICE_OUT_REMOTE_SUBMIX);
    }
}
+20 −0
Original line number Diff line number Diff line
@@ -4331,6 +4331,26 @@ public class AudioManager {
        }
    }

    /**
     * @hide
     * Get the audio devices that would be used for the routing of the given audio attributes.
     * @param attributes the {@link AudioAttributes} for which the routing is being queried
     * @return an empty list if there was an issue with the request, a list of audio devices
     *   otherwise (typically one device, except for duplicated paths).
     */
    @SystemApi
    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
    public @NonNull List<AudioDeviceAddress> getDevicesForAttributes(
            @NonNull AudioAttributes attributes) {
        Objects.requireNonNull(attributes);
        final IAudioService service = getService();
        try {
            return service.getDevicesForAttributes(attributes);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

     /**
     * Indicate wired accessory connection state change.
     * @param device type of device connected/disconnected (AudioManager.DEVICE_OUT_xxx)
Loading