Add API to set context and session id to SoundPool.
Bug: 174876164
Bug: 261698699
Bug: 249777386
Test: atest SoundPoolTest
Change-Id: I3dbf0de523dc2047a5c90aabb502f3abb312ab2a
diff --git a/core/api/current.txt b/core/api/current.txt
index 9da95c0..0c8b010 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -24191,6 +24191,8 @@
ctor public SoundPool.Builder();
method public android.media.SoundPool build();
method public android.media.SoundPool.Builder setAudioAttributes(android.media.AudioAttributes) throws java.lang.IllegalArgumentException;
+ method @NonNull public android.media.SoundPool.Builder setAudioSessionId(int);
+ method @NonNull public android.media.SoundPool.Builder setContext(@NonNull android.content.Context);
method public android.media.SoundPool.Builder setMaxStreams(int) throws java.lang.IllegalArgumentException;
}
diff --git a/media/java/android/media/SoundPool.java b/media/java/android/media/SoundPool.java
index dc09359..f33a744 100644
--- a/media/java/android/media/SoundPool.java
+++ b/media/java/android/media/SoundPool.java
@@ -16,6 +16,8 @@
package android.media;
+import static android.media.AudioManager.AUDIO_SESSION_ID_GENERATE;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
@@ -29,6 +31,7 @@
import java.io.File;
import java.io.FileDescriptor;
+import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;
@@ -146,12 +149,14 @@
* SoundPool instance
*/
public SoundPool(int maxStreams, int streamType, int srcQuality) {
- this(maxStreams,
- new AudioAttributes.Builder().setInternalLegacyStreamType(streamType).build());
+ this(/*context=*/null, maxStreams,
+ new AudioAttributes.Builder().setInternalLegacyStreamType(streamType).build(),
+ AUDIO_SESSION_ID_GENERATE);
PlayerBase.deprecateStreamTypeForPlayback(streamType, "SoundPool", "SoundPool()");
}
- private SoundPool(int maxStreams, AudioAttributes attributes) {
+ private SoundPool(@Nullable Context context, int maxStreams,
+ @NonNull AudioAttributes attributes, int sessionId) {
super(attributes, AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL);
// do native setup
@@ -160,8 +165,7 @@
}
mAttributes = attributes;
- // FIXME: b/174876164 implement session id for soundpool
- baseRegisterPlayer(AudioSystem.AUDIO_SESSION_ALLOCATE);
+ baseRegisterPlayer(resolvePlaybackSessionId(context, sessionId));
}
/**
@@ -555,6 +559,8 @@
public static class Builder {
private int mMaxStreams = 1;
private AudioAttributes mAudioAttributes;
+ private Context mContext;
+ private int mSessionId = AUDIO_SESSION_ID_GENERATE;
/**
* Constructs a new Builder with the defaults format values.
@@ -596,12 +602,49 @@
return this;
}
+ /**
+ * Sets the session ID the {@link SoundPool} will be attached to.
+ *
+ * Note, that if there's a device specific session id associated with the context
+ * (see {@link Builder#setContext(Context)}), explicitly setting a session id using this
+ * method will override it.
+ *
+ * @param sessionId a strictly positive ID number retrieved from another player or
+ * allocated by {@link AudioManager} via {@link AudioManager#generateAudioSessionId()},
+ * or {@link AudioManager#AUDIO_SESSION_ID_GENERATE}.
+ * @return the same {@link Builder} instance
+ * @throws IllegalArgumentException when sessionId is invalid.
+ */
+ public @NonNull Builder setAudioSessionId(int sessionId) {
+ if ((sessionId != AUDIO_SESSION_ID_GENERATE) && (sessionId < 1)) {
+ throw new IllegalArgumentException("Invalid audio session ID " + sessionId);
+ }
+ mSessionId = sessionId;
+ return this;
+ }
+
+ /**
+ * Sets the context the SoundPool belongs to.
+ *
+ * The context will be used to pull information, such as
+ * {@link android.content.AttributionSource} and device specific audio session ids,
+ * which will be associated with the {@link SoundPool}. However, the context itself will
+ * not be retained by the {@link SoundPool} instance after initialization.
+ *
+ * @param context a non-null {@link Context} instance
+ * @return the same {@link Builder} instance.
+ */
+ public @NonNull Builder setContext(@NonNull Context context) {
+ mContext = Objects.requireNonNull(context);
+ return this;
+ }
+
public SoundPool build() {
if (mAudioAttributes == null) {
mAudioAttributes = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA).build();
}
- return new SoundPool(mMaxStreams, mAudioAttributes);
+ return new SoundPool(mContext, mMaxStreams, mAudioAttributes, mSessionId);
}
}
}