diff --git a/core/api/current.txt b/core/api/current.txt index 4b3e35ee1f188..64f95774d601f 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -21197,6 +21197,7 @@ package android.media { method @NonNull public android.media.AudioTrack.Builder setAudioAttributes(@NonNull android.media.AudioAttributes) throws java.lang.IllegalArgumentException; method @NonNull public android.media.AudioTrack.Builder setAudioFormat(@NonNull android.media.AudioFormat) throws java.lang.IllegalArgumentException; method @NonNull public android.media.AudioTrack.Builder setBufferSizeInBytes(@IntRange(from=0) int) throws java.lang.IllegalArgumentException; + method @NonNull public android.media.AudioTrack.Builder setContext(@NonNull android.content.Context); method @NonNull public android.media.AudioTrack.Builder setEncapsulationMode(int); method @NonNull public android.media.AudioTrack.Builder setOffloadedPlayback(boolean); method @NonNull public android.media.AudioTrack.Builder setPerformanceMode(int); diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 50c3c78ce9d44..567a570309a31 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -3043,6 +3043,7 @@ package android.companion.virtual { field public static final int LOCK_STATE_DEFAULT = 0; // 0x0 field public static final int NAVIGATION_POLICY_DEFAULT_ALLOWED = 0; // 0x0 field public static final int NAVIGATION_POLICY_DEFAULT_BLOCKED = 1; // 0x1 + field public static final int POLICY_TYPE_AUDIO = 1; // 0x1 field public static final int POLICY_TYPE_SENSORS = 0; // 0x0 field public static final int RECENTS_POLICY_ALLOW_IN_HOST_DEVICE_RECENTS = 1; // 0x1 } diff --git a/core/java/android/companion/virtual/VirtualDeviceManager.java b/core/java/android/companion/virtual/VirtualDeviceManager.java index cc452e27a650c..f851c319580ef 100644 --- a/core/java/android/companion/virtual/VirtualDeviceManager.java +++ b/core/java/android/companion/virtual/VirtualDeviceManager.java @@ -16,6 +16,8 @@ package android.companion.virtual; +import static android.media.AudioManager.AUDIO_SESSION_ID_GENERATE; + import android.annotation.CallbackExecutor; import android.annotation.IntDef; import android.annotation.IntRange; @@ -254,6 +256,42 @@ public final class VirtualDeviceManager { } } + /** + * Returns device-specific audio session id for audio playback. + * + * @param deviceId - id of the virtual audio device + * @return Device specific session id to be used for audio playback (see + * {@link android.media.AudioManager.generateAudioSessionId}) if virtual device has + * {@link VirtualDeviceParams.POLICY_TYPE_AUDIO} set to + * {@link VirtualDeviceParams.DEVICE_POLICY_CUSTOM} and Virtual Audio Device + * is configured in context-aware mode. + * Otherwise {@link AUDIO_SESSION_ID_GENERATE} constant is returned. + * @hide + */ + public int getAudioPlaybackSessionId(int deviceId) { + //TODO - Return session id rerouted to VirtualAudioDevice if the VirtualAudioDevice + //is configured to operate in context-aware mode. + return AUDIO_SESSION_ID_GENERATE; + } + + /** + * Returns device-specific audio session id for audio recording. + * + * @param deviceId - id of the virtual audio device + * @return Device specific session id to be used for audio recording (see + * {@link android.media.AudioManager.generateAudioSessionId}) if virtual device has + * {@link VirtualDeviceParams.POLICY_TYPE_AUDIO} set to + * {@link VirtualDeviceParams.DEVICE_POLICY_CUSTOM} and Virtual Audio Device + * is configured in context-aware mode. + * Otherwise {@link AUDIO_SESSION_ID_GENERATE} constant is returned. + * @hide + */ + public int getAudioRecordingSessionId(int deviceId) { + //TODO - Return session id corresponding to VirtualAudioDevice injection if the + // VirtualAudioDevice is configured to operate in context-aware mode. + return AUDIO_SESSION_ID_GENERATE; + } + /** * A virtual device has its own virtual display, audio output, microphone, and camera etc. The * creator of a virtual device can take the output from the virtual display and stream it over diff --git a/core/java/android/companion/virtual/VirtualDeviceParams.java b/core/java/android/companion/virtual/VirtualDeviceParams.java index be77f2b7e0f5e..f59a7a9b66683 100644 --- a/core/java/android/companion/virtual/VirtualDeviceParams.java +++ b/core/java/android/companion/virtual/VirtualDeviceParams.java @@ -129,7 +129,7 @@ public final class VirtualDeviceParams implements Parcelable { * a given policy type. * @hide */ - @IntDef(prefix = "POLICY_TYPE_", value = {POLICY_TYPE_SENSORS}) + @IntDef(prefix = "POLICY_TYPE_", value = {POLICY_TYPE_SENSORS, POLICY_TYPE_AUDIO}) @Retention(RetentionPolicy.SOURCE) @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE}) public @interface PolicyType {} @@ -147,6 +147,21 @@ public final class VirtualDeviceParams implements Parcelable { */ public static final int POLICY_TYPE_SENSORS = 0; + /** + * Tells the audio framework whether to configure the players ({@link android.media.AudioTrack}, + * {@link android.media.MediaPlayer}, {@link android.media.SoundPool} and recorders + * {@link android.media.AudioRecord}) to use specific session ids re-routed to + * VirtualAudioDevice. + * + *
AudioTrack via {@link AudioTrack#getAudioSessionId()} or allocated by
* {@link AudioManager} via {@link AudioManager#generateAudioSessionId()}, or
@@ -1161,7 +1192,7 @@ public class AudioTrack extends PlayerBase
*/
public @NonNull Builder setSessionId(@IntRange(from = 1) int sessionId)
throws IllegalArgumentException {
- if ((sessionId != AudioManager.AUDIO_SESSION_ID_GENERATE) && (sessionId < 1)) {
+ if ((sessionId != AUDIO_SESSION_ID_GENERATE) && (sessionId < 1)) {
throw new IllegalArgumentException("Invalid audio session ID " + sessionId);
}
mSessionId = sessionId;
@@ -1371,8 +1402,8 @@ public class AudioTrack extends PlayerBase
try {
final AudioTrack track = new AudioTrack(
- mAttributes, mFormat, mBufferSizeInBytes, mMode, mSessionId, mOffload,
- mEncapsulationMode, mTunerConfiguration);
+ mContext, mAttributes, mFormat, mBufferSizeInBytes, mMode, mSessionId,
+ mOffload, mEncapsulationMode, mTunerConfiguration);
if (track.getState() == STATE_UNINITIALIZED) {
// release is not necessary
throw new UnsupportedOperationException("Cannot create AudioTrack");
@@ -1384,6 +1415,32 @@ public class AudioTrack extends PlayerBase
}
}
+ /**
+ * Helper method to extract device specific audio session id from Context.
+ *
+ * @param context {@link Context} to use for extraction of device specific session id.
+ * @return device specific session id. If context is null or doesn't have specific audio
+ * session id associated, this method returns {@link AUDIO_SESSION_ID_GENERATE}.
+ */
+ private static int getSessionIdForContext(@Nullable Context context) {
+ if (context == null) {
+ return AUDIO_SESSION_ID_GENERATE;
+ }
+
+ int deviceId = context.getDeviceId();
+ if (deviceId == DEVICE_ID_DEFAULT) {
+ return AUDIO_SESSION_ID_GENERATE;
+ }
+
+ VirtualDeviceManager vdm = context.getSystemService(VirtualDeviceManager.class);
+ if (vdm == null || vdm.getDevicePolicy(deviceId, POLICY_TYPE_AUDIO)
+ == DEVICE_POLICY_DEFAULT) {
+ return AUDIO_SESSION_ID_GENERATE;
+ }
+
+ return vdm.getAudioPlaybackSessionId(deviceId);
+ }
+
/**
* Sets an {@link AudioPolicy} to automatically unregister when the track is released.
*
diff --git a/media/tests/MediaFrameworkTest/Android.bp b/media/tests/MediaFrameworkTest/Android.bp
index 48d56d898138f..06ec949e67365 100644
--- a/media/tests/MediaFrameworkTest/Android.bp
+++ b/media/tests/MediaFrameworkTest/Android.bp
@@ -13,13 +13,18 @@ android_test {
libs: [
"android.test.runner",
"android.test.base",
+ "android.test.mock",
],
static_libs: [
- "mockito-target-minus-junit4",
+ "mockito-target-inline-minus-junit4",
"androidx.test.ext.junit",
"androidx.test.rules",
"android-ex-camera2",
- "testng"
+ "testng",
+ ],
+ jni_libs: [
+ "libdexmakerjvmtiagent",
+ "libstaticjvmtiagent",
],
platform_apis: true,
}
diff --git a/media/tests/MediaFrameworkTest/AndroidManifest.xml b/media/tests/MediaFrameworkTest/AndroidManifest.xml
index 9211a7e341cd6..41ac285e49f51 100644
--- a/media/tests/MediaFrameworkTest/AndroidManifest.xml
+++ b/media/tests/MediaFrameworkTest/AndroidManifest.xml
@@ -24,7 +24,8 @@