Loading core/api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -19907,6 +19907,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 getAudioDevice(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.media.AudioPlaybackConfiguration> CREATOR; } media/java/android/media/AudioPlaybackConfiguration.java +59 −6 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.media.AudioAttributes.ALLOW_CAPTURE_BY_NONE; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.os.Binder; import android.os.IBinder; Loading @@ -47,6 +48,8 @@ public final class AudioPlaybackConfiguration implements Parcelable { public static final int PLAYER_PIID_INVALID = -1; /** @hide */ public static final int PLAYER_UPID_INVALID = -1; /** @hide */ public static final int PLAYER_DEVICEID_INVALID = 0; // information about the implementation /** Loading Loading @@ -158,6 +161,11 @@ public final class AudioPlaybackConfiguration implements Parcelable { */ @SystemApi public static final int PLAYER_STATE_STOPPED = 4; /** * @hide * The state used to update device id, does not actually change the state of the player */ public static final int PLAYER_UPDATE_DEVICE_ID = 5; /** @hide */ @IntDef({ Loading @@ -166,7 +174,8 @@ public final class AudioPlaybackConfiguration implements Parcelable { PLAYER_STATE_IDLE, PLAYER_STATE_STARTED, PLAYER_STATE_PAUSED, PLAYER_STATE_STOPPED PLAYER_STATE_STOPPED, PLAYER_UPDATE_DEVICE_ID }) @Retention(RetentionPolicy.SOURCE) public @interface PlayerState {} Loading @@ -184,6 +193,8 @@ public final class AudioPlaybackConfiguration implements Parcelable { private int mPlayerState; private AudioAttributes mPlayerAttr; // never null private int mDeviceId; /** * Never use without initializing parameters afterwards */ Loading @@ -201,6 +212,7 @@ public final class AudioPlaybackConfiguration implements Parcelable { mPlayerType = pic.mPlayerType; mClientUid = uid; mClientPid = pid; mDeviceId = PLAYER_DEVICEID_INVALID; mPlayerState = PLAYER_STATE_IDLE; mPlayerAttr = pic.mAttributes; if ((sPlayerDeathMonitor != null) && (pic.mIPlayer != null)) { Loading Loading @@ -241,6 +253,7 @@ public final class AudioPlaybackConfiguration implements Parcelable { in.mPlayerAttr.getAllowedCapturePolicy() == ALLOW_CAPTURE_BY_ALL ? ALLOW_CAPTURE_BY_ALL : ALLOW_CAPTURE_BY_NONE) .build(); anonymCopy.mDeviceId = in.mDeviceId; // anonymized data anonymCopy.mPlayerType = PLAYER_TYPE_UNKNOWN; anonymCopy.mClientUid = PLAYER_UPID_INVALID; Loading Loading @@ -277,6 +290,25 @@ public final class AudioPlaybackConfiguration implements Parcelable { return mClientPid; } /** * 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 */ public @Nullable AudioDeviceInfo getAudioDevice() { if (mDeviceId == PLAYER_DEVICEID_INVALID) { return null; } // TODO(175802592): change this to AudioManager.getDeviceForPortId() when available AudioDeviceInfo[] devices = AudioManager.getDevicesStatic(AudioManager.GET_DEVICES_OUTPUTS); for (int i = 0; i < devices.length; i++) { if (devices[i].getId() == mDeviceId) { return devices[i]; } } return null; } /** * @hide * Return the type of player linked to this configuration. Loading Loading @@ -359,13 +391,29 @@ public final class AudioPlaybackConfiguration implements Parcelable { * @hide * Handle a player state change * @param event * @param deviceId active device id or {@Code PLAYER_DEVICEID_INVALID} * <br>Note device id is valid for {@code PLAYER_UPDATE_DEVICE_ID} or * <br>{@code PLAYER_STATE_STARTED} events, as the device id will be reset to none when * <br>pausing or stopping playback. It will be set to active device when playback starts or * <br>it will be changed when PLAYER_UPDATE_DEVICE_ID is sent. The latter can happen if the * <br>device changes in the middle of playback. * @return true if the state changed, false otherwise */ public boolean handleStateEvent(int event) { final boolean changed; public boolean handleStateEvent(int event, int deviceId) { boolean changed = false; synchronized (this) { // Do not update if it is only device id update if (event != PLAYER_UPDATE_DEVICE_ID) { changed = (mPlayerState != event); mPlayerState = event; } if (event == PLAYER_STATE_STARTED || event == PLAYER_UPDATE_DEVICE_ID) { changed = changed || (mDeviceId != deviceId); mDeviceId = deviceId; } if (changed && (event == PLAYER_STATE_RELEASED) && (mIPlayerShell != null)) { mIPlayerShell.release(); mIPlayerShell = null; Loading Loading @@ -436,7 +484,7 @@ public final class AudioPlaybackConfiguration implements Parcelable { @Override public int hashCode() { return Objects.hash(mPlayerIId, mPlayerType, mClientUid, mClientPid); return Objects.hash(mPlayerIId, mDeviceId, mPlayerType, mClientUid, mClientPid); } @Override Loading @@ -447,6 +495,7 @@ public final class AudioPlaybackConfiguration implements Parcelable { @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(mPlayerIId); dest.writeInt(mDeviceId); dest.writeInt(mPlayerType); dest.writeInt(mClientUid); dest.writeInt(mClientPid); Loading @@ -461,6 +510,7 @@ public final class AudioPlaybackConfiguration implements Parcelable { private AudioPlaybackConfiguration(Parcel in) { mPlayerIId = in.readInt(); mDeviceId = in.readInt(); mPlayerType = in.readInt(); mClientUid = in.readInt(); mClientPid = in.readInt(); Loading @@ -478,6 +528,7 @@ public final class AudioPlaybackConfiguration implements Parcelable { AudioPlaybackConfiguration that = (AudioPlaybackConfiguration) o; return ((mPlayerIId == that.mPlayerIId) && (mDeviceId == that.mDeviceId) && (mPlayerType == that.mPlayerType) && (mClientUid == that.mClientUid) && (mClientPid == that.mClientPid)); Loading @@ -486,6 +537,7 @@ public final class AudioPlaybackConfiguration implements Parcelable { @Override public String toString() { return "AudioPlaybackConfiguration piid:" + mPlayerIId + " deviceId:" + mDeviceId + " type:" + toLogFriendlyPlayerType(mPlayerType) + " u/pid:" + mClientUid + "/" + mClientPid + " state:" + toLogFriendlyPlayerState(mPlayerState) Loading Loading @@ -571,6 +623,7 @@ public final class AudioPlaybackConfiguration implements Parcelable { case PLAYER_STATE_STARTED: return "started"; case PLAYER_STATE_PAUSED: return "paused"; case PLAYER_STATE_STOPPED: return "stopped"; case PLAYER_UPDATE_DEVICE_ID: return "device"; default: return "unknown player state - FIXME"; } Loading media/java/android/media/AudioTrack.java +24 −3 Original line number Diff line number Diff line Loading @@ -1824,6 +1824,7 @@ public class AudioTrack extends PlayerBase @Override protected void finalize() { tryToDisableNativeRoutingCallback(); baseRelease(); native_finalize(); } Loading Loading @@ -2717,9 +2718,15 @@ public class AudioTrack extends PlayerBase } private void startImpl() { synchronized (mRoutingChangeListeners) { if (!mEnableSelfRoutingMonitor) { testEnableNativeRoutingCallbacksLocked(); mEnableSelfRoutingMonitor = true; } } synchronized(mPlayStateLock) { baseStart(); native_start(); baseStart(native_getRoutedDeviceId()); if (mPlayState == PLAYSTATE_PAUSED_STOPPING) { mPlayState = PLAYSTATE_STOPPING; } else { Loading Loading @@ -2757,6 +2764,7 @@ public class AudioTrack extends PlayerBase mPlayStateLock.notify(); } } tryToDisableNativeRoutingCallback(); } /** Loading Loading @@ -3496,12 +3504,21 @@ public class AudioTrack extends PlayerBase return null; } private void tryToDisableNativeRoutingCallback() { synchronized (mRoutingChangeListeners) { if (mEnableSelfRoutingMonitor) { mEnableSelfRoutingMonitor = false; testDisableNativeRoutingCallbacksLocked(); } } } /* * Call BEFORE adding a routing callback handler. */ @GuardedBy("mRoutingChangeListeners") private void testEnableNativeRoutingCallbacksLocked() { if (mRoutingChangeListeners.size() == 0) { if (mRoutingChangeListeners.size() == 0 && !mEnableSelfRoutingMonitor) { native_enableDeviceCallback(); } } Loading @@ -3511,7 +3528,7 @@ public class AudioTrack extends PlayerBase */ @GuardedBy("mRoutingChangeListeners") private void testDisableNativeRoutingCallbacksLocked() { if (mRoutingChangeListeners.size() == 0) { if (mRoutingChangeListeners.size() == 0 && !mEnableSelfRoutingMonitor) { native_disableDeviceCallback(); } } Loading @@ -3528,6 +3545,9 @@ public class AudioTrack extends PlayerBase private ArrayMap<AudioRouting.OnRoutingChangedListener, NativeRoutingEventHandlerDelegate> mRoutingChangeListeners = new ArrayMap<>(); @GuardedBy("mRoutingChangeListeners") private boolean mEnableSelfRoutingMonitor; /** * Adds an {@link AudioRouting.OnRoutingChangedListener} to receive notifications of routing * changes on this AudioTrack. Loading Loading @@ -3627,6 +3647,7 @@ public class AudioTrack extends PlayerBase */ private void broadcastRoutingChange() { AudioManager.resetAudioPortGeneration(); baseUpdateDeviceId(getRoutedDevice()); synchronized (mRoutingChangeListeners) { for (NativeRoutingEventHandlerDelegate delegate : mRoutingChangeListeners.values()) { delegate.notifyClient(); Loading media/java/android/media/HwAudioSource.java +25 −1 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ import android.annotation.SystemApi; import com.android.internal.util.Preconditions; import java.util.ArrayList; /** * The HwAudioSource represents the audio playback directly from a source audio device. * It currently supports {@link HwAudioSource#start()} and {@link HwAudioSource#stop()} only Loading Loading @@ -130,10 +132,32 @@ public class HwAudioSource extends PlayerBase { */ public void start() { Preconditions.checkState(!isPlaying(), "HwAudioSource is currently playing"); baseStart(); mNativeHandle = AudioSystem.startAudioSource( mAudioDeviceInfo.getPort().activeConfig(), mAudioAttributes); // FIXME: b/174876389 clean up device id reporting baseStart(getDeviceId()); } private int getDeviceId() { ArrayList<AudioPatch> patches = new ArrayList<AudioPatch>(); if (AudioManager.listAudioPatches(patches) != AudioManager.SUCCESS) { return 0; } for (int i = 0; i < patches.size(); i++) { AudioPatch patch = patches.get(i); AudioPortConfig[] sources = patch.sources(); AudioPortConfig[] sinks = patch.sinks(); if ((sources != null) && (sources.length > 0)) { for (int c = 0; c < sources.length; c++) { if (sources[c].port().id() == mAudioDeviceInfo.getId()) { return sinks[c].port().id(); } } } } return 0; } /** Loading media/java/android/media/IAudioService.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -62,7 +62,7 @@ interface IAudioService { oneway void playerAttributes(in int piid, in AudioAttributes attr); oneway void playerEvent(in int piid, in int event); oneway void playerEvent(in int piid, in int event, in int deviceId); oneway void releasePlayer(in int piid); Loading Loading
core/api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -19907,6 +19907,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 getAudioDevice(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.media.AudioPlaybackConfiguration> CREATOR; }
media/java/android/media/AudioPlaybackConfiguration.java +59 −6 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.media.AudioAttributes.ALLOW_CAPTURE_BY_NONE; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.os.Binder; import android.os.IBinder; Loading @@ -47,6 +48,8 @@ public final class AudioPlaybackConfiguration implements Parcelable { public static final int PLAYER_PIID_INVALID = -1; /** @hide */ public static final int PLAYER_UPID_INVALID = -1; /** @hide */ public static final int PLAYER_DEVICEID_INVALID = 0; // information about the implementation /** Loading Loading @@ -158,6 +161,11 @@ public final class AudioPlaybackConfiguration implements Parcelable { */ @SystemApi public static final int PLAYER_STATE_STOPPED = 4; /** * @hide * The state used to update device id, does not actually change the state of the player */ public static final int PLAYER_UPDATE_DEVICE_ID = 5; /** @hide */ @IntDef({ Loading @@ -166,7 +174,8 @@ public final class AudioPlaybackConfiguration implements Parcelable { PLAYER_STATE_IDLE, PLAYER_STATE_STARTED, PLAYER_STATE_PAUSED, PLAYER_STATE_STOPPED PLAYER_STATE_STOPPED, PLAYER_UPDATE_DEVICE_ID }) @Retention(RetentionPolicy.SOURCE) public @interface PlayerState {} Loading @@ -184,6 +193,8 @@ public final class AudioPlaybackConfiguration implements Parcelable { private int mPlayerState; private AudioAttributes mPlayerAttr; // never null private int mDeviceId; /** * Never use without initializing parameters afterwards */ Loading @@ -201,6 +212,7 @@ public final class AudioPlaybackConfiguration implements Parcelable { mPlayerType = pic.mPlayerType; mClientUid = uid; mClientPid = pid; mDeviceId = PLAYER_DEVICEID_INVALID; mPlayerState = PLAYER_STATE_IDLE; mPlayerAttr = pic.mAttributes; if ((sPlayerDeathMonitor != null) && (pic.mIPlayer != null)) { Loading Loading @@ -241,6 +253,7 @@ public final class AudioPlaybackConfiguration implements Parcelable { in.mPlayerAttr.getAllowedCapturePolicy() == ALLOW_CAPTURE_BY_ALL ? ALLOW_CAPTURE_BY_ALL : ALLOW_CAPTURE_BY_NONE) .build(); anonymCopy.mDeviceId = in.mDeviceId; // anonymized data anonymCopy.mPlayerType = PLAYER_TYPE_UNKNOWN; anonymCopy.mClientUid = PLAYER_UPID_INVALID; Loading Loading @@ -277,6 +290,25 @@ public final class AudioPlaybackConfiguration implements Parcelable { return mClientPid; } /** * 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 */ public @Nullable AudioDeviceInfo getAudioDevice() { if (mDeviceId == PLAYER_DEVICEID_INVALID) { return null; } // TODO(175802592): change this to AudioManager.getDeviceForPortId() when available AudioDeviceInfo[] devices = AudioManager.getDevicesStatic(AudioManager.GET_DEVICES_OUTPUTS); for (int i = 0; i < devices.length; i++) { if (devices[i].getId() == mDeviceId) { return devices[i]; } } return null; } /** * @hide * Return the type of player linked to this configuration. Loading Loading @@ -359,13 +391,29 @@ public final class AudioPlaybackConfiguration implements Parcelable { * @hide * Handle a player state change * @param event * @param deviceId active device id or {@Code PLAYER_DEVICEID_INVALID} * <br>Note device id is valid for {@code PLAYER_UPDATE_DEVICE_ID} or * <br>{@code PLAYER_STATE_STARTED} events, as the device id will be reset to none when * <br>pausing or stopping playback. It will be set to active device when playback starts or * <br>it will be changed when PLAYER_UPDATE_DEVICE_ID is sent. The latter can happen if the * <br>device changes in the middle of playback. * @return true if the state changed, false otherwise */ public boolean handleStateEvent(int event) { final boolean changed; public boolean handleStateEvent(int event, int deviceId) { boolean changed = false; synchronized (this) { // Do not update if it is only device id update if (event != PLAYER_UPDATE_DEVICE_ID) { changed = (mPlayerState != event); mPlayerState = event; } if (event == PLAYER_STATE_STARTED || event == PLAYER_UPDATE_DEVICE_ID) { changed = changed || (mDeviceId != deviceId); mDeviceId = deviceId; } if (changed && (event == PLAYER_STATE_RELEASED) && (mIPlayerShell != null)) { mIPlayerShell.release(); mIPlayerShell = null; Loading Loading @@ -436,7 +484,7 @@ public final class AudioPlaybackConfiguration implements Parcelable { @Override public int hashCode() { return Objects.hash(mPlayerIId, mPlayerType, mClientUid, mClientPid); return Objects.hash(mPlayerIId, mDeviceId, mPlayerType, mClientUid, mClientPid); } @Override Loading @@ -447,6 +495,7 @@ public final class AudioPlaybackConfiguration implements Parcelable { @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(mPlayerIId); dest.writeInt(mDeviceId); dest.writeInt(mPlayerType); dest.writeInt(mClientUid); dest.writeInt(mClientPid); Loading @@ -461,6 +510,7 @@ public final class AudioPlaybackConfiguration implements Parcelable { private AudioPlaybackConfiguration(Parcel in) { mPlayerIId = in.readInt(); mDeviceId = in.readInt(); mPlayerType = in.readInt(); mClientUid = in.readInt(); mClientPid = in.readInt(); Loading @@ -478,6 +528,7 @@ public final class AudioPlaybackConfiguration implements Parcelable { AudioPlaybackConfiguration that = (AudioPlaybackConfiguration) o; return ((mPlayerIId == that.mPlayerIId) && (mDeviceId == that.mDeviceId) && (mPlayerType == that.mPlayerType) && (mClientUid == that.mClientUid) && (mClientPid == that.mClientPid)); Loading @@ -486,6 +537,7 @@ public final class AudioPlaybackConfiguration implements Parcelable { @Override public String toString() { return "AudioPlaybackConfiguration piid:" + mPlayerIId + " deviceId:" + mDeviceId + " type:" + toLogFriendlyPlayerType(mPlayerType) + " u/pid:" + mClientUid + "/" + mClientPid + " state:" + toLogFriendlyPlayerState(mPlayerState) Loading Loading @@ -571,6 +623,7 @@ public final class AudioPlaybackConfiguration implements Parcelable { case PLAYER_STATE_STARTED: return "started"; case PLAYER_STATE_PAUSED: return "paused"; case PLAYER_STATE_STOPPED: return "stopped"; case PLAYER_UPDATE_DEVICE_ID: return "device"; default: return "unknown player state - FIXME"; } Loading
media/java/android/media/AudioTrack.java +24 −3 Original line number Diff line number Diff line Loading @@ -1824,6 +1824,7 @@ public class AudioTrack extends PlayerBase @Override protected void finalize() { tryToDisableNativeRoutingCallback(); baseRelease(); native_finalize(); } Loading Loading @@ -2717,9 +2718,15 @@ public class AudioTrack extends PlayerBase } private void startImpl() { synchronized (mRoutingChangeListeners) { if (!mEnableSelfRoutingMonitor) { testEnableNativeRoutingCallbacksLocked(); mEnableSelfRoutingMonitor = true; } } synchronized(mPlayStateLock) { baseStart(); native_start(); baseStart(native_getRoutedDeviceId()); if (mPlayState == PLAYSTATE_PAUSED_STOPPING) { mPlayState = PLAYSTATE_STOPPING; } else { Loading Loading @@ -2757,6 +2764,7 @@ public class AudioTrack extends PlayerBase mPlayStateLock.notify(); } } tryToDisableNativeRoutingCallback(); } /** Loading Loading @@ -3496,12 +3504,21 @@ public class AudioTrack extends PlayerBase return null; } private void tryToDisableNativeRoutingCallback() { synchronized (mRoutingChangeListeners) { if (mEnableSelfRoutingMonitor) { mEnableSelfRoutingMonitor = false; testDisableNativeRoutingCallbacksLocked(); } } } /* * Call BEFORE adding a routing callback handler. */ @GuardedBy("mRoutingChangeListeners") private void testEnableNativeRoutingCallbacksLocked() { if (mRoutingChangeListeners.size() == 0) { if (mRoutingChangeListeners.size() == 0 && !mEnableSelfRoutingMonitor) { native_enableDeviceCallback(); } } Loading @@ -3511,7 +3528,7 @@ public class AudioTrack extends PlayerBase */ @GuardedBy("mRoutingChangeListeners") private void testDisableNativeRoutingCallbacksLocked() { if (mRoutingChangeListeners.size() == 0) { if (mRoutingChangeListeners.size() == 0 && !mEnableSelfRoutingMonitor) { native_disableDeviceCallback(); } } Loading @@ -3528,6 +3545,9 @@ public class AudioTrack extends PlayerBase private ArrayMap<AudioRouting.OnRoutingChangedListener, NativeRoutingEventHandlerDelegate> mRoutingChangeListeners = new ArrayMap<>(); @GuardedBy("mRoutingChangeListeners") private boolean mEnableSelfRoutingMonitor; /** * Adds an {@link AudioRouting.OnRoutingChangedListener} to receive notifications of routing * changes on this AudioTrack. Loading Loading @@ -3627,6 +3647,7 @@ public class AudioTrack extends PlayerBase */ private void broadcastRoutingChange() { AudioManager.resetAudioPortGeneration(); baseUpdateDeviceId(getRoutedDevice()); synchronized (mRoutingChangeListeners) { for (NativeRoutingEventHandlerDelegate delegate : mRoutingChangeListeners.values()) { delegate.notifyClient(); Loading
media/java/android/media/HwAudioSource.java +25 −1 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ import android.annotation.SystemApi; import com.android.internal.util.Preconditions; import java.util.ArrayList; /** * The HwAudioSource represents the audio playback directly from a source audio device. * It currently supports {@link HwAudioSource#start()} and {@link HwAudioSource#stop()} only Loading Loading @@ -130,10 +132,32 @@ public class HwAudioSource extends PlayerBase { */ public void start() { Preconditions.checkState(!isPlaying(), "HwAudioSource is currently playing"); baseStart(); mNativeHandle = AudioSystem.startAudioSource( mAudioDeviceInfo.getPort().activeConfig(), mAudioAttributes); // FIXME: b/174876389 clean up device id reporting baseStart(getDeviceId()); } private int getDeviceId() { ArrayList<AudioPatch> patches = new ArrayList<AudioPatch>(); if (AudioManager.listAudioPatches(patches) != AudioManager.SUCCESS) { return 0; } for (int i = 0; i < patches.size(); i++) { AudioPatch patch = patches.get(i); AudioPortConfig[] sources = patch.sources(); AudioPortConfig[] sinks = patch.sinks(); if ((sources != null) && (sources.length > 0)) { for (int c = 0; c < sources.length; c++) { if (sources[c].port().id() == mAudioDeviceInfo.getId()) { return sinks[c].port().id(); } } } } return 0; } /** Loading
media/java/android/media/IAudioService.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -62,7 +62,7 @@ interface IAudioService { oneway void playerAttributes(in int piid, in AudioAttributes attr); oneway void playerEvent(in int piid, in int event); oneway void playerEvent(in int piid, in int event, in int deviceId); oneway void releasePlayer(in int piid); Loading