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

Commit a1be7275 authored by Robert Wu's avatar Robert Wu
Browse files

Add client-side APIs for getRoutedDevices()

After you open an audio stream, you can call getRoutedDevice() to
get which output device is actually used.

However, if you play an ALARM with a headset attached, audio comes
out of both the speaker and the headset. This is not properly reflected
with our current APIs.

This CL adds the client side APIs for getRoutedDevices().

Bug: 367816690
Test: presubmit
Flag: android.media.audio.routed_device_ids
Change-Id: I23ba7c4a3dcaa9683db638778bdff65fe422f8df
parent 5fe41e4a
Loading
Loading
Loading
Loading
+6 −1
Original line number Original line Diff line number Diff line
@@ -21884,7 +21884,7 @@ package android.media {
  public final class AudioPlaybackConfiguration implements android.os.Parcelable {
  public final class AudioPlaybackConfiguration implements android.os.Parcelable {
    method public int describeContents();
    method public int describeContents();
    method public android.media.AudioAttributes getAudioAttributes();
    method public android.media.AudioAttributes getAudioAttributes();
    method @Nullable public android.media.AudioDeviceInfo getAudioDeviceInfo();
    method @Deprecated @FlaggedApi("android.media.audio.routed_device_ids") @Nullable public android.media.AudioDeviceInfo getAudioDeviceInfo();
    method public void writeToParcel(android.os.Parcel, int);
    method public void writeToParcel(android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.media.AudioPlaybackConfiguration> CREATOR;
    field @NonNull public static final android.os.Parcelable.Creator<android.media.AudioPlaybackConfiguration> CREATOR;
  }
  }
@@ -21967,6 +21967,7 @@ package android.media {
    method public android.media.AudioDeviceInfo getPreferredDevice();
    method public android.media.AudioDeviceInfo getPreferredDevice();
    method public int getRecordingState();
    method public int getRecordingState();
    method public android.media.AudioDeviceInfo getRoutedDevice();
    method public android.media.AudioDeviceInfo getRoutedDevice();
    method @FlaggedApi("android.media.audio.routed_device_ids") @NonNull public java.util.List<android.media.AudioDeviceInfo> getRoutedDevices();
    method public int getSampleRate();
    method public int getSampleRate();
    method public int getState();
    method public int getState();
    method public int getTimestamp(@NonNull android.media.AudioTimestamp, int);
    method public int getTimestamp(@NonNull android.media.AudioTimestamp, int);
@@ -22061,6 +22062,7 @@ package android.media {
    method public void addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
    method public void addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
    method public android.media.AudioDeviceInfo getPreferredDevice();
    method public android.media.AudioDeviceInfo getPreferredDevice();
    method public android.media.AudioDeviceInfo getRoutedDevice();
    method public android.media.AudioDeviceInfo getRoutedDevice();
    method @FlaggedApi("android.media.audio.routed_device_ids") @NonNull public default java.util.List<android.media.AudioDeviceInfo> getRoutedDevices();
    method public void removeOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener);
    method public void removeOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener);
    method public boolean setPreferredDevice(android.media.AudioDeviceInfo);
    method public boolean setPreferredDevice(android.media.AudioDeviceInfo);
  }
  }
@@ -22119,6 +22121,7 @@ package android.media {
    method public int getPositionNotificationPeriod();
    method public int getPositionNotificationPeriod();
    method public android.media.AudioDeviceInfo getPreferredDevice();
    method public android.media.AudioDeviceInfo getPreferredDevice();
    method public android.media.AudioDeviceInfo getRoutedDevice();
    method public android.media.AudioDeviceInfo getRoutedDevice();
    method @FlaggedApi("android.media.audio.routed_device_ids") @NonNull public java.util.List<android.media.AudioDeviceInfo> getRoutedDevices();
    method public int getSampleRate();
    method public int getSampleRate();
    method @IntRange(from=1) public int getStartThresholdInFrames();
    method @IntRange(from=1) public int getStartThresholdInFrames();
    method public int getState();
    method public int getState();
@@ -24285,6 +24288,7 @@ package android.media {
    method @NonNull public android.media.PlaybackParams getPlaybackParams();
    method @NonNull public android.media.PlaybackParams getPlaybackParams();
    method public android.media.AudioDeviceInfo getPreferredDevice();
    method public android.media.AudioDeviceInfo getPreferredDevice();
    method public android.media.AudioDeviceInfo getRoutedDevice();
    method public android.media.AudioDeviceInfo getRoutedDevice();
    method @FlaggedApi("android.media.audio.routed_device_ids") @NonNull public java.util.List<android.media.AudioDeviceInfo> getRoutedDevices();
    method public int getSelectedTrack(int) throws java.lang.IllegalStateException;
    method public int getSelectedTrack(int) throws java.lang.IllegalStateException;
    method @NonNull public android.media.SyncParams getSyncParams();
    method @NonNull public android.media.SyncParams getSyncParams();
    method @Nullable public android.media.MediaTimestamp getTimestamp();
    method @Nullable public android.media.MediaTimestamp getTimestamp();
@@ -24498,6 +24502,7 @@ package android.media {
    method public android.os.PersistableBundle getMetrics();
    method public android.os.PersistableBundle getMetrics();
    method public android.media.AudioDeviceInfo getPreferredDevice();
    method public android.media.AudioDeviceInfo getPreferredDevice();
    method public android.media.AudioDeviceInfo getRoutedDevice();
    method public android.media.AudioDeviceInfo getRoutedDevice();
    method @FlaggedApi("android.media.audio.routed_device_ids") @NonNull public java.util.List<android.media.AudioDeviceInfo> getRoutedDevices();
    method public android.view.Surface getSurface();
    method public android.view.Surface getSurface();
    method public boolean isPrivacySensitive();
    method public boolean isPrivacySensitive();
    method public void pause() throws java.lang.IllegalStateException;
    method public void pause() throws java.lang.IllegalStateException;
+1 −0
Original line number Original line Diff line number Diff line
@@ -7449,6 +7449,7 @@ package android.media {
  }
  }
  public final class AudioPlaybackConfiguration implements android.os.Parcelable {
  public final class AudioPlaybackConfiguration implements android.os.Parcelable {
    method @FlaggedApi("android.media.audio.routed_device_ids") @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public java.util.List<android.media.AudioDeviceInfo> getAudioDeviceInfos();
    method public int getChannelMask();
    method public int getChannelMask();
    method public int getClientPid();
    method public int getClientPid();
    method public int getClientUid();
    method public int getClientUid();
+25 −1
Original line number Original line Diff line number Diff line
@@ -19,6 +19,7 @@ package android.media;
import static android.media.AudioAttributes.ALLOW_CAPTURE_BY_ALL;
import static android.media.AudioAttributes.ALLOW_CAPTURE_BY_ALL;
import static android.media.AudioAttributes.ALLOW_CAPTURE_BY_NONE;
import static android.media.AudioAttributes.ALLOW_CAPTURE_BY_NONE;
import static android.media.audio.Flags.FLAG_MUTED_BY_PORT_VOLUME_API;
import static android.media.audio.Flags.FLAG_MUTED_BY_PORT_VOLUME_API;
import static android.media.audio.Flags.FLAG_ROUTED_DEVICE_IDS;


import android.annotation.FlaggedApi;
import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.IntDef;
@@ -39,6 +40,8 @@ import com.android.internal.annotations.GuardedBy;
import java.io.PrintWriter;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Objects;


/**
/**
@@ -461,8 +464,12 @@ public final class AudioPlaybackConfiguration implements Parcelable {


    /**
    /**
     * Returns information about the {@link AudioDeviceInfo} used for this playback.
     * Returns information about the {@link AudioDeviceInfo} used for this playback.
     * @return the audio playback device or null if the device is not available at the time of query
     * @return the audio playback device or null if the device is not available at the time of
     * query.
     * @deprecated this information was never populated
     */
     */
    @Deprecated
    @FlaggedApi(FLAG_ROUTED_DEVICE_IDS)
    public @Nullable AudioDeviceInfo getAudioDeviceInfo() {
    public @Nullable AudioDeviceInfo getAudioDeviceInfo() {
        final int deviceId;
        final int deviceId;
        synchronized (mUpdateablePropLock) {
        synchronized (mUpdateablePropLock) {
@@ -474,6 +481,23 @@ public final class AudioPlaybackConfiguration implements Parcelable {
        return AudioManager.getDeviceForPortId(deviceId, AudioManager.GET_DEVICES_OUTPUTS);
        return AudioManager.getDeviceForPortId(deviceId, AudioManager.GET_DEVICES_OUTPUTS);
    }
    }


    /**
     * @hide
     * Returns information about the List of {@link AudioDeviceInfo} used for this playback.
     * @return the audio playback devices
     */
    @SystemApi
    @FlaggedApi(FLAG_ROUTED_DEVICE_IDS)
    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
    public @NonNull List<AudioDeviceInfo> getAudioDeviceInfos() {
        List<AudioDeviceInfo> audioDeviceInfos = new ArrayList<AudioDeviceInfo>();
        AudioDeviceInfo audioDeviceInfo = getAudioDeviceInfo();
        if (audioDeviceInfo != null) {
            audioDeviceInfos.add(audioDeviceInfo);
        }
        return audioDeviceInfos;
    }

    /**
    /**
     * @hide
     * @hide
     * Return the audio session ID associated with this player.
     * Return the audio session ID associated with this player.
+19 −0
Original line number Original line Diff line number Diff line
@@ -20,8 +20,10 @@ import static android.companion.virtual.VirtualDeviceParams.DEVICE_POLICY_DEFAUL
import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_AUDIO;
import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_AUDIO;
import static android.content.Context.DEVICE_ID_DEFAULT;
import static android.content.Context.DEVICE_ID_DEFAULT;
import static android.media.AudioManager.AUDIO_SESSION_ID_GENERATE;
import static android.media.AudioManager.AUDIO_SESSION_ID_GENERATE;
import static android.media.audio.Flags.FLAG_ROUTED_DEVICE_IDS;


import android.annotation.CallbackExecutor;
import android.annotation.CallbackExecutor;
import android.annotation.FlaggedApi;
import android.annotation.FloatRange;
import android.annotation.FloatRange;
import android.annotation.IntDef;
import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.IntRange;
@@ -1919,6 +1921,23 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection,
        return AudioManager.getDeviceForPortId(deviceId, AudioManager.GET_DEVICES_INPUTS);
        return AudioManager.getDeviceForPortId(deviceId, AudioManager.GET_DEVICES_INPUTS);
    }
    }


    /**
     * Returns a List of {@link AudioDeviceInfo} identifying the current routing of this
     * AudioRecord.
     * Note: The query is only valid if the AudioRecord is currently playing. If it is not,
     * <code>getRoutedDevices()</code> will return an empty list.
     */
    @Override
    @FlaggedApi(FLAG_ROUTED_DEVICE_IDS)
    public @NonNull List<AudioDeviceInfo> getRoutedDevices() {
        List<AudioDeviceInfo> audioDeviceInfos = new ArrayList<AudioDeviceInfo>();
        AudioDeviceInfo audioDeviceInfo = getRoutedDevice();
        if (audioDeviceInfo != null) {
            audioDeviceInfos.add(audioDeviceInfo);
        }
        return audioDeviceInfos;
    }

    /**
    /**
     * Must match the native definition in frameworks/av/service/audioflinger/Audioflinger.h.
     * Must match the native definition in frameworks/av/service/audioflinger/Audioflinger.h.
     */
     */
+23 −0
Original line number Original line Diff line number Diff line
@@ -16,9 +16,16 @@


package android.media;
package android.media;


import static android.media.audio.Flags.FLAG_ROUTED_DEVICE_IDS;

import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.os.Handler;
import android.os.Handler;
import android.os.Looper;
import android.os.Looper;


import java.util.ArrayList;
import java.util.List;

/**
/**
 * AudioRouting defines an interface for controlling routing and routing notifications in
 * AudioRouting defines an interface for controlling routing and routing notifications in
 * AudioTrack and AudioRecord objects.
 * AudioTrack and AudioRecord objects.
@@ -48,6 +55,22 @@ public interface AudioRouting {
     */
     */
    public AudioDeviceInfo getRoutedDevice();
    public AudioDeviceInfo getRoutedDevice();


    /**
     * Returns a List of {@link AudioDeviceInfo} identifying the current routing of this
     * AudioTrack/AudioRecord.
     * Note: The query is only valid if the AudioTrack/AudioRecord is currently playing.
     * If it is not, <code>getRoutedDevices()</code> will return an empty List.
     */
    @FlaggedApi(FLAG_ROUTED_DEVICE_IDS)
    default @NonNull List<AudioDeviceInfo> getRoutedDevices() {
        List<AudioDeviceInfo> audioDeviceInfos = new ArrayList<AudioDeviceInfo>();
        AudioDeviceInfo audioDeviceInfo = getRoutedDevice();
        if (audioDeviceInfo != null) {
            audioDeviceInfos.add(audioDeviceInfo);
        }
        return new ArrayList<AudioDeviceInfo>();
    }

    /**
    /**
     * Adds an {@link AudioRouting.OnRoutingChangedListener} to receive notifications of routing
     * Adds an {@link AudioRouting.OnRoutingChangedListener} to receive notifications of routing
     * changes on this AudioTrack/AudioRecord.
     * changes on this AudioTrack/AudioRecord.
Loading