summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Robert Wu <robertwu@google.com> 2024-11-13 18:43:04 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2024-11-13 18:43:04 +0000
commit2f441a5490e194ef3bbb91cf8849062306bcc6af (patch)
tree41e8fba0f644f556cf4daf39a1b9c97b31069bde
parent7a71de78935970d28a51111140f148f125230476 (diff)
parenta1be72756c4dbb7eb5c1e480a869ccb1518d9139 (diff)
Merge "Add client-side APIs for getRoutedDevices()" into main
-rw-r--r--core/api/current.txt7
-rw-r--r--core/api/system-current.txt1
-rw-r--r--media/java/android/media/AudioPlaybackConfiguration.java26
-rw-r--r--media/java/android/media/AudioRecord.java19
-rw-r--r--media/java/android/media/AudioRouting.java23
-rw-r--r--media/java/android/media/AudioTrack.java23
-rw-r--r--media/java/android/media/MediaPlayer.java22
-rw-r--r--media/java/android/media/MediaRecorder.java21
8 files changed, 140 insertions, 2 deletions
diff --git a/core/api/current.txt b/core/api/current.txt
index 06cf9a5631ee..8c36a472ba29 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -21982,7 +21982,7 @@ package android.media {
public final class AudioPlaybackConfiguration implements android.os.Parcelable {
method public int describeContents();
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);
field @NonNull public static final android.os.Parcelable.Creator<android.media.AudioPlaybackConfiguration> CREATOR;
}
@@ -22065,6 +22065,7 @@ package android.media {
method public android.media.AudioDeviceInfo getPreferredDevice();
method public int getRecordingState();
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 getState();
method public int getTimestamp(@NonNull android.media.AudioTimestamp, int);
@@ -22159,6 +22160,7 @@ package android.media {
method public void addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
method public android.media.AudioDeviceInfo getPreferredDevice();
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 boolean setPreferredDevice(android.media.AudioDeviceInfo);
}
@@ -22217,6 +22219,7 @@ package android.media {
method public int getPositionNotificationPeriod();
method public android.media.AudioDeviceInfo getPreferredDevice();
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 @IntRange(from=1) public int getStartThresholdInFrames();
method public int getState();
@@ -24385,6 +24388,7 @@ package android.media {
method @NonNull public android.media.PlaybackParams getPlaybackParams();
method public android.media.AudioDeviceInfo getPreferredDevice();
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 @NonNull public android.media.SyncParams getSyncParams();
method @Nullable public android.media.MediaTimestamp getTimestamp();
@@ -24598,6 +24602,7 @@ package android.media {
method public android.os.PersistableBundle getMetrics();
method public android.media.AudioDeviceInfo getPreferredDevice();
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 boolean isPrivacySensitive();
method public void pause() throws java.lang.IllegalStateException;
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index ed95fdd52f45..9079996865fe 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -7464,6 +7464,7 @@ package android.media {
}
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 getClientPid();
method public int getClientUid();
diff --git a/media/java/android/media/AudioPlaybackConfiguration.java b/media/java/android/media/AudioPlaybackConfiguration.java
index 3cd5f5266ef2..da50f2cd86c4 100644
--- a/media/java/android/media/AudioPlaybackConfiguration.java
+++ b/media/java/android/media/AudioPlaybackConfiguration.java
@@ -19,6 +19,7 @@ package android.media;
import static android.media.AudioAttributes.ALLOW_CAPTURE_BY_ALL;
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_ROUTED_DEVICE_IDS;
import android.annotation.FlaggedApi;
import android.annotation.IntDef;
@@ -39,6 +40,8 @@ import com.android.internal.annotations.GuardedBy;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Objects;
/**
@@ -461,8 +464,12 @@ public final class AudioPlaybackConfiguration implements Parcelable {
/**
* 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() {
final int deviceId;
synchronized (mUpdateablePropLock) {
@@ -476,6 +483,23 @@ public final class AudioPlaybackConfiguration implements Parcelable {
/**
* @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
* Return the audio session ID associated with this player.
* See {@link AudioManager#generateAudioSessionId()}.
* @return an audio session ID
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index 80e57193d0dc..939494152116 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -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.content.Context.DEVICE_ID_DEFAULT;
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.FlaggedApi;
import android.annotation.FloatRange;
import android.annotation.IntDef;
import android.annotation.IntRange;
@@ -1920,6 +1922,23 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection,
}
/**
+ * 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.
*/
private static final long MAX_SHARED_AUDIO_HISTORY_MS = 5000;
diff --git a/media/java/android/media/AudioRouting.java b/media/java/android/media/AudioRouting.java
index 26fa631ac6ac..22aa9a09d560 100644
--- a/media/java/android/media/AudioRouting.java
+++ b/media/java/android/media/AudioRouting.java
@@ -16,9 +16,16 @@
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.Looper;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* AudioRouting defines an interface for controlling routing and routing notifications in
* AudioTrack and AudioRecord objects.
@@ -49,6 +56,22 @@ public interface AudioRouting {
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
* changes on this AudioTrack/AudioRecord.
* @param listener The {@link AudioRouting.OnRoutingChangedListener} interface to receive
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 03cd53580b1b..93a183188793 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -17,8 +17,10 @@
package android.media;
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.FlaggedApi;
import android.annotation.FloatRange;
import android.annotation.IntDef;
import android.annotation.IntRange;
@@ -54,7 +56,9 @@ import java.lang.ref.WeakReference;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.NioUtils;
+import java.util.ArrayList;
import java.util.LinkedList;
+import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.Executor;
@@ -3783,6 +3787,8 @@ public class AudioTrack extends PlayerBase
* Returns an {@link AudioDeviceInfo} identifying the current routing of this AudioTrack.
* Note: The query is only valid if the AudioTrack is currently playing. If it is not,
* <code>getRoutedDevice()</code> will return null.
+ * Audio may play on multiple devices simultaneously (e.g. an alarm playing on headphones and
+ * speaker on a phone), so prefer using {@link #getRoutedDevices}.
*/
@Override
public AudioDeviceInfo getRoutedDevice() {
@@ -3793,6 +3799,23 @@ public class AudioTrack extends PlayerBase
return AudioManager.getDeviceForPortId(deviceId, AudioManager.GET_DEVICES_OUTPUTS);
}
+ /**
+ * Returns a List of {@link AudioDeviceInfo} identifying the current routing of this
+ * AudioTrack.
+ * Note: The query is only valid if the AudioTrack 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;
+ }
+
private void tryToDisableNativeRoutingCallback() {
synchronized (mRoutingChangeListeners) {
if (mEnableSelfRoutingMonitor) {
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index a0f8ae5defeb..158bc7fcd482 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -18,7 +18,9 @@ package android.media;
import static android.Manifest.permission.BIND_IMS_SERVICE;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.media.audio.Flags.FLAG_ROUTED_DEVICE_IDS;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -84,6 +86,7 @@ import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.URL;
import java.nio.ByteOrder;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.HashMap;
@@ -1542,6 +1545,8 @@ public class MediaPlayer extends PlayerBase
* Note: The query is only valid if the MediaPlayer is currently playing.
* If the player is not playing, the returned device can be null or correspond to previously
* selected device when the player was last active.
+ * Audio may play on multiple devices simultaneously (e.g. an alarm playing on headphones and
+ * speaker on a phone), so prefer using {@link #getRoutedDevices}.
*/
@Override
public AudioDeviceInfo getRoutedDevice() {
@@ -1552,6 +1557,23 @@ public class MediaPlayer extends PlayerBase
return AudioManager.getDeviceForPortId(deviceId, AudioManager.GET_DEVICES_OUTPUTS);
}
+ /**
+ * Returns a List of {@link AudioDeviceInfo} identifying the current routing of this
+ * MediaPlayer.
+ * Note: The query is only valid if the MediaPlayer is currently playing.
+ * If the player is not playing, the returned devices can be empty or correspond to previously
+ * selected devices when the player was last active.
+ */
+ @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;
+ }
/**
* Sends device list change notification to all listeners.
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 2d17bf500f12..f75bcf3c437d 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -16,7 +16,10 @@
package android.media;
+import static android.media.audio.Flags.FLAG_ROUTED_DEVICE_IDS;
+
import android.annotation.CallbackExecutor;
+import android.annotation.FlaggedApi;
import android.annotation.FloatRange;
import android.annotation.IntDef;
import android.annotation.NonNull;
@@ -1695,6 +1698,24 @@ public class MediaRecorder implements AudioRouting,
return AudioManager.getDeviceForPortId(deviceId, AudioManager.GET_DEVICES_INPUTS);
}
+ /**
+ * Returns a List of {@link AudioDeviceInfo} identifying the current routing of this
+ * MediaRecorder.
+ * Note: The query is only valid if the MediaRecorder is currently recording.
+ * If the recorder is not recording, the returned devices can be empty or correspond to
+ * previously selected devices when the recorder was last active.
+ */
+ @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;
+ }
+
/*
* Call BEFORE adding a routing callback handler or AFTER removing a routing callback handler.
*/