Loading core/api/system-current.txt +14 −2 Original line number Diff line number Diff line Loading @@ -2849,19 +2849,31 @@ package android.companion.virtual { package android.companion.virtual.audio { public final class AudioCapture { ctor public AudioCapture(); method @NonNull public android.media.AudioFormat getFormat(); method public int getRecordingState(); method public int read(@NonNull byte[], int, int); method public int read(@NonNull byte[], int, int, int); method public int read(@NonNull java.nio.ByteBuffer, int); method public int read(@NonNull java.nio.ByteBuffer, int, int); method public int read(@NonNull float[], int, int, int); method public int read(@NonNull short[], int, int); method public int read(@NonNull short[], int, int, int); method public void startRecording(); method public void stop(); } public final class AudioInjection { ctor public AudioInjection(); method @NonNull public android.media.AudioFormat getFormat(); method public int getPlayState(); method public void play(); method public void stop(); method public int write(@NonNull byte[], int, int); method public int write(@NonNull byte[], int, int, int); method public int write(@NonNull java.nio.ByteBuffer, int, int); method public int write(@NonNull java.nio.ByteBuffer, int, int, long); method public int write(@NonNull float[], int, int, int); method public int write(@NonNull short[], int, int); method public int write(@NonNull short[], int, int, int); } public final class VirtualAudioDevice implements java.io.Closeable { core/java/android/companion/virtual/audio/AudioCapture.java +90 −6 Original line number Diff line number Diff line Loading @@ -16,13 +16,16 @@ package android.companion.virtual.audio; import static android.media.AudioRecord.READ_BLOCKING; import static android.media.AudioRecord.RECORDSTATE_RECORDING; import static android.media.AudioRecord.RECORDSTATE_STOPPED; import static android.media.AudioRecord.STATE_INITIALIZED; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.media.AudioFormat; import android.media.AudioRecord; import android.util.Log; Loading @@ -42,12 +45,12 @@ import java.nio.ByteBuffer; public final class AudioCapture { private static final String TAG = "AudioCapture"; private final AudioFormat mAudioFormat; private final Object mLock = new Object(); @GuardedBy("mLock") @Nullable private AudioRecord mAudioRecord; @GuardedBy("mLock") private int mRecordingState = RECORDSTATE_STOPPED; Loading @@ -63,12 +66,12 @@ public final class AudioCapture { void setAudioRecord(@Nullable AudioRecord audioRecord) { Log.d(TAG, "set AudioRecord with " + audioRecord); synchronized (mLock) { // Release old reference. if (mAudioRecord != null) { mAudioRecord.release(); } // Sync recording state for new reference. if (audioRecord != null) { if (audioRecord.getState() != STATE_INITIALIZED) { throw new IllegalStateException("set an uninitialized AudioRecord."); } if (mRecordingState == RECORDSTATE_RECORDING && audioRecord.getRecordingState() != RECORDSTATE_RECORDING) { audioRecord.startRecording(); Loading @@ -78,16 +81,97 @@ public final class AudioCapture { audioRecord.stop(); } } // Release old reference before assigning the new reference. if (mAudioRecord != null) { mAudioRecord.release(); } mAudioRecord = audioRecord; } } AudioCapture(@NonNull AudioFormat audioFormat) { mAudioFormat = audioFormat; } void close() { synchronized (mLock) { if (mAudioRecord != null) { mAudioRecord.release(); mAudioRecord = null; } } } /** See {@link AudioRecord#getFormat()} */ public @NonNull AudioFormat getFormat() { return mAudioFormat; } /** See {@link AudioRecord#read(byte[], int, int)} */ public int read(@NonNull byte[] audioData, int offsetInBytes, int sizeInBytes) { return read(audioData, offsetInBytes, sizeInBytes, READ_BLOCKING); } /** See {@link AudioRecord#read(byte[], int, int, int)} */ public int read(@NonNull byte[] audioData, int offsetInBytes, int sizeInBytes, @AudioRecord.ReadMode int readMode) { final int sizeRead; synchronized (mLock) { if (mAudioRecord != null) { sizeRead = mAudioRecord.read(audioData, offsetInBytes, sizeInBytes, readMode); } else { sizeRead = 0; } } return sizeRead; } /** See {@link AudioRecord#read(ByteBuffer, int)}. */ public int read(@NonNull ByteBuffer audioBuffer, int sizeInBytes) { return read(audioBuffer, sizeInBytes, READ_BLOCKING); } /** See {@link AudioRecord#read(ByteBuffer, int, int)}. */ public int read(@NonNull ByteBuffer audioBuffer, int sizeInBytes, @AudioRecord.ReadMode int readMode) { final int sizeRead; synchronized (mLock) { if (mAudioRecord != null) { sizeRead = mAudioRecord.read(audioBuffer, sizeInBytes, readMode); } else { sizeRead = 0; } } return sizeRead; } /** See {@link AudioRecord#read(float[], int, int, int)}. */ public int read(@NonNull float[] audioData, int offsetInFloats, int sizeInFloats, @AudioRecord.ReadMode int readMode) { final int sizeRead; synchronized (mLock) { if (mAudioRecord != null) { sizeRead = mAudioRecord.read(audioData, offsetInFloats, sizeInFloats, readMode); } else { sizeRead = 0; } } return sizeRead; } /** See {@link AudioRecord#read(short[], int, int)}. */ public int read(@NonNull short[] audioData, int offsetInShorts, int sizeInShorts) { return read(audioData, offsetInShorts, sizeInShorts, READ_BLOCKING); } /** See {@link AudioRecord#read(short[], int, int, int)}. */ public int read(@NonNull short[] audioData, int offsetInShorts, int sizeInShorts, @AudioRecord.ReadMode int readMode) { final int sizeRead; synchronized (mLock) { if (mAudioRecord != null) { sizeRead = mAudioRecord.read(audioBuffer, sizeInBytes); sizeRead = mAudioRecord.read(audioData, offsetInShorts, sizeInShorts, readMode); } else { sizeRead = 0; } Loading core/java/android/companion/virtual/audio/AudioInjection.java +98 −4 Original line number Diff line number Diff line Loading @@ -18,11 +18,14 @@ package android.companion.virtual.audio; import static android.media.AudioTrack.PLAYSTATE_PLAYING; import static android.media.AudioTrack.PLAYSTATE_STOPPED; import static android.media.AudioTrack.STATE_INITIALIZED; import static android.media.AudioTrack.WRITE_BLOCKING; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.media.AudioFormat; import android.media.AudioTrack; import android.util.Log; Loading @@ -42,7 +45,9 @@ import java.nio.ByteBuffer; public final class AudioInjection { private static final String TAG = "AudioInjection"; private final AudioFormat mAudioFormat; private final Object mLock = new Object(); @GuardedBy("mLock") @Nullable private AudioTrack mAudioTrack; Loading Loading @@ -70,12 +75,12 @@ public final class AudioInjection { void setAudioTrack(@Nullable AudioTrack audioTrack) { Log.d(TAG, "set AudioTrack with " + audioTrack); synchronized (mLock) { // Release old reference. if (mAudioTrack != null) { mAudioTrack.release(); } // Sync play state for new reference. if (audioTrack != null) { if (audioTrack.getState() != STATE_INITIALIZED) { throw new IllegalStateException("set an uninitialized AudioTrack."); } if (mPlayState == PLAYSTATE_PLAYING && audioTrack.getPlayState() != PLAYSTATE_PLAYING) { audioTrack.play(); Loading @@ -85,10 +90,52 @@ public final class AudioInjection { audioTrack.stop(); } } // Release old reference before assigning the new reference. if (mAudioTrack != null) { mAudioTrack.release(); } mAudioTrack = audioTrack; } } AudioInjection(@NonNull AudioFormat audioFormat) { mAudioFormat = audioFormat; } void close() { synchronized (mLock) { if (mAudioTrack != null) { mAudioTrack.release(); mAudioTrack = null; } } } /** See {@link AudioTrack#getFormat()}. */ public @NonNull AudioFormat getFormat() { return mAudioFormat; } /** See {@link AudioTrack#write(byte[], int, int)}. */ public int write(@NonNull byte[] audioData, int offsetInBytes, int sizeInBytes) { return write(audioData, offsetInBytes, sizeInBytes, WRITE_BLOCKING); } /** See {@link AudioTrack#write(byte[], int, int, int)}. */ public int write(@NonNull byte[] audioData, int offsetInBytes, int sizeInBytes, @AudioTrack.WriteMode int writeMode) { final int sizeWrite; synchronized (mLock) { if (mAudioTrack != null && !mIsSilent) { sizeWrite = mAudioTrack.write(audioData, offsetInBytes, sizeInBytes, writeMode); } else { sizeWrite = 0; } } return sizeWrite; } /** See {@link AudioTrack#write(ByteBuffer, int, int)}. */ public int write(@NonNull ByteBuffer audioBuffer, int sizeInBytes, int writeMode) { final int sizeWrite; Loading @@ -102,6 +149,53 @@ public final class AudioInjection { return sizeWrite; } /** See {@link AudioTrack#write(ByteBuffer, int, int, long)}. */ public int write(@NonNull ByteBuffer audioBuffer, int sizeInBytes, @AudioTrack.WriteMode int writeMode, long timestamp) { final int sizeWrite; synchronized (mLock) { if (mAudioTrack != null && !mIsSilent) { sizeWrite = mAudioTrack.write(audioBuffer, sizeInBytes, writeMode, timestamp); } else { sizeWrite = 0; } } return sizeWrite; } /** See {@link AudioTrack#write(float[], int, int, int)}. */ public int write(@NonNull float[] audioData, int offsetInFloats, int sizeInFloats, @AudioTrack.WriteMode int writeMode) { final int sizeWrite; synchronized (mLock) { if (mAudioTrack != null && !mIsSilent) { sizeWrite = mAudioTrack.write(audioData, offsetInFloats, sizeInFloats, writeMode); } else { sizeWrite = 0; } } return sizeWrite; } /** See {@link AudioTrack#write(short[], int, int)}. */ public int write(@NonNull short[] audioData, int offsetInShorts, int sizeInShorts) { return write(audioData, offsetInShorts, sizeInShorts, WRITE_BLOCKING); } /** See {@link AudioTrack#write(short[], int, int, int)}. */ public int write(@NonNull short[] audioData, int offsetInShorts, int sizeInShorts, @AudioTrack.WriteMode int writeMode) { final int sizeWrite; synchronized (mLock) { if (mAudioTrack != null && !mIsSilent) { sizeWrite = mAudioTrack.write(audioData, offsetInShorts, sizeInShorts, writeMode); } else { sizeWrite = 0; } } return sizeWrite; } /** See {@link AudioTrack#play()}. */ public void play() { synchronized (mLock) { Loading core/java/android/companion/virtual/audio/VirtualAudioSession.java +16 −20 Original line number Diff line number Diff line Loading @@ -68,12 +68,6 @@ public final class VirtualAudioSession extends IAudioSessionCallback.Stub implem private AudioPolicy mAudioPolicy; @Nullable @GuardedBy("mLock") private AudioFormat mCaptureFormat; @Nullable @GuardedBy("mLock") private AudioFormat mInjectionFormat; @Nullable @GuardedBy("mLock") private AudioCapture mAudioCapture; @Nullable @GuardedBy("mLock") Loading Loading @@ -104,8 +98,7 @@ public final class VirtualAudioSession extends IAudioSessionCallback.Stub implem "Cannot start capture while another capture is ongoing."); } mCaptureFormat = captureFormat; mAudioCapture = new AudioCapture(); mAudioCapture = new AudioCapture(captureFormat); mAudioCapture.startRecording(); return mAudioCapture; } Loading @@ -127,8 +120,7 @@ public final class VirtualAudioSession extends IAudioSessionCallback.Stub implem "Cannot start injection while injection is already ongoing."); } mInjectionFormat = injectionFormat; mAudioInjection = new AudioInjection(); mAudioInjection = new AudioInjection(injectionFormat); mAudioInjection.play(); mUserRestrictionsDetector.register(/* callback= */ this); Loading Loading @@ -179,10 +171,14 @@ public final class VirtualAudioSession extends IAudioSessionCallback.Stub implem mUserRestrictionsDetector.unregister(); releaseAudioStreams(); synchronized (mLock) { if (mAudioCapture != null) { mAudioCapture.close(); mAudioCapture = null; } if (mAudioInjection != null) { mAudioInjection.close(); mAudioInjection = null; mCaptureFormat = null; mInjectionFormat = null; } } } Loading @@ -198,9 +194,9 @@ public final class VirtualAudioSession extends IAudioSessionCallback.Stub implem @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) private void createAudioStreams(int[] appUids) { synchronized (mLock) { if (mCaptureFormat == null && mInjectionFormat == null) { if (mAudioCapture == null && mAudioInjection == null) { throw new IllegalStateException( "At least one of captureFormat and injectionFormat must be specified."); "At least one of AudioCapture and AudioInjection must be started."); } if (mAudioPolicy != null) { throw new IllegalStateException( Loading @@ -218,12 +214,12 @@ public final class VirtualAudioSession extends IAudioSessionCallback.Stub implem AudioMix audioRecordMix = null; AudioMix audioTrackMix = null; AudioPolicy.Builder builder = new AudioPolicy.Builder(mContext); if (mCaptureFormat != null) { audioRecordMix = createAudioRecordMix(mCaptureFormat, appUids); if (mAudioCapture != null) { audioRecordMix = createAudioRecordMix(mAudioCapture.getFormat(), appUids); builder.addMix(audioRecordMix); } if (mInjectionFormat != null) { audioTrackMix = createAudioTrackMix(mInjectionFormat, appUids); if (mAudioInjection != null) { audioTrackMix = createAudioTrackMix(mAudioInjection.getFormat(), appUids); builder.addMix(audioTrackMix); } mAudioPolicy = builder.build(); Loading Loading
core/api/system-current.txt +14 −2 Original line number Diff line number Diff line Loading @@ -2849,19 +2849,31 @@ package android.companion.virtual { package android.companion.virtual.audio { public final class AudioCapture { ctor public AudioCapture(); method @NonNull public android.media.AudioFormat getFormat(); method public int getRecordingState(); method public int read(@NonNull byte[], int, int); method public int read(@NonNull byte[], int, int, int); method public int read(@NonNull java.nio.ByteBuffer, int); method public int read(@NonNull java.nio.ByteBuffer, int, int); method public int read(@NonNull float[], int, int, int); method public int read(@NonNull short[], int, int); method public int read(@NonNull short[], int, int, int); method public void startRecording(); method public void stop(); } public final class AudioInjection { ctor public AudioInjection(); method @NonNull public android.media.AudioFormat getFormat(); method public int getPlayState(); method public void play(); method public void stop(); method public int write(@NonNull byte[], int, int); method public int write(@NonNull byte[], int, int, int); method public int write(@NonNull java.nio.ByteBuffer, int, int); method public int write(@NonNull java.nio.ByteBuffer, int, int, long); method public int write(@NonNull float[], int, int, int); method public int write(@NonNull short[], int, int); method public int write(@NonNull short[], int, int, int); } public final class VirtualAudioDevice implements java.io.Closeable {
core/java/android/companion/virtual/audio/AudioCapture.java +90 −6 Original line number Diff line number Diff line Loading @@ -16,13 +16,16 @@ package android.companion.virtual.audio; import static android.media.AudioRecord.READ_BLOCKING; import static android.media.AudioRecord.RECORDSTATE_RECORDING; import static android.media.AudioRecord.RECORDSTATE_STOPPED; import static android.media.AudioRecord.STATE_INITIALIZED; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.media.AudioFormat; import android.media.AudioRecord; import android.util.Log; Loading @@ -42,12 +45,12 @@ import java.nio.ByteBuffer; public final class AudioCapture { private static final String TAG = "AudioCapture"; private final AudioFormat mAudioFormat; private final Object mLock = new Object(); @GuardedBy("mLock") @Nullable private AudioRecord mAudioRecord; @GuardedBy("mLock") private int mRecordingState = RECORDSTATE_STOPPED; Loading @@ -63,12 +66,12 @@ public final class AudioCapture { void setAudioRecord(@Nullable AudioRecord audioRecord) { Log.d(TAG, "set AudioRecord with " + audioRecord); synchronized (mLock) { // Release old reference. if (mAudioRecord != null) { mAudioRecord.release(); } // Sync recording state for new reference. if (audioRecord != null) { if (audioRecord.getState() != STATE_INITIALIZED) { throw new IllegalStateException("set an uninitialized AudioRecord."); } if (mRecordingState == RECORDSTATE_RECORDING && audioRecord.getRecordingState() != RECORDSTATE_RECORDING) { audioRecord.startRecording(); Loading @@ -78,16 +81,97 @@ public final class AudioCapture { audioRecord.stop(); } } // Release old reference before assigning the new reference. if (mAudioRecord != null) { mAudioRecord.release(); } mAudioRecord = audioRecord; } } AudioCapture(@NonNull AudioFormat audioFormat) { mAudioFormat = audioFormat; } void close() { synchronized (mLock) { if (mAudioRecord != null) { mAudioRecord.release(); mAudioRecord = null; } } } /** See {@link AudioRecord#getFormat()} */ public @NonNull AudioFormat getFormat() { return mAudioFormat; } /** See {@link AudioRecord#read(byte[], int, int)} */ public int read(@NonNull byte[] audioData, int offsetInBytes, int sizeInBytes) { return read(audioData, offsetInBytes, sizeInBytes, READ_BLOCKING); } /** See {@link AudioRecord#read(byte[], int, int, int)} */ public int read(@NonNull byte[] audioData, int offsetInBytes, int sizeInBytes, @AudioRecord.ReadMode int readMode) { final int sizeRead; synchronized (mLock) { if (mAudioRecord != null) { sizeRead = mAudioRecord.read(audioData, offsetInBytes, sizeInBytes, readMode); } else { sizeRead = 0; } } return sizeRead; } /** See {@link AudioRecord#read(ByteBuffer, int)}. */ public int read(@NonNull ByteBuffer audioBuffer, int sizeInBytes) { return read(audioBuffer, sizeInBytes, READ_BLOCKING); } /** See {@link AudioRecord#read(ByteBuffer, int, int)}. */ public int read(@NonNull ByteBuffer audioBuffer, int sizeInBytes, @AudioRecord.ReadMode int readMode) { final int sizeRead; synchronized (mLock) { if (mAudioRecord != null) { sizeRead = mAudioRecord.read(audioBuffer, sizeInBytes, readMode); } else { sizeRead = 0; } } return sizeRead; } /** See {@link AudioRecord#read(float[], int, int, int)}. */ public int read(@NonNull float[] audioData, int offsetInFloats, int sizeInFloats, @AudioRecord.ReadMode int readMode) { final int sizeRead; synchronized (mLock) { if (mAudioRecord != null) { sizeRead = mAudioRecord.read(audioData, offsetInFloats, sizeInFloats, readMode); } else { sizeRead = 0; } } return sizeRead; } /** See {@link AudioRecord#read(short[], int, int)}. */ public int read(@NonNull short[] audioData, int offsetInShorts, int sizeInShorts) { return read(audioData, offsetInShorts, sizeInShorts, READ_BLOCKING); } /** See {@link AudioRecord#read(short[], int, int, int)}. */ public int read(@NonNull short[] audioData, int offsetInShorts, int sizeInShorts, @AudioRecord.ReadMode int readMode) { final int sizeRead; synchronized (mLock) { if (mAudioRecord != null) { sizeRead = mAudioRecord.read(audioBuffer, sizeInBytes); sizeRead = mAudioRecord.read(audioData, offsetInShorts, sizeInShorts, readMode); } else { sizeRead = 0; } Loading
core/java/android/companion/virtual/audio/AudioInjection.java +98 −4 Original line number Diff line number Diff line Loading @@ -18,11 +18,14 @@ package android.companion.virtual.audio; import static android.media.AudioTrack.PLAYSTATE_PLAYING; import static android.media.AudioTrack.PLAYSTATE_STOPPED; import static android.media.AudioTrack.STATE_INITIALIZED; import static android.media.AudioTrack.WRITE_BLOCKING; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.media.AudioFormat; import android.media.AudioTrack; import android.util.Log; Loading @@ -42,7 +45,9 @@ import java.nio.ByteBuffer; public final class AudioInjection { private static final String TAG = "AudioInjection"; private final AudioFormat mAudioFormat; private final Object mLock = new Object(); @GuardedBy("mLock") @Nullable private AudioTrack mAudioTrack; Loading Loading @@ -70,12 +75,12 @@ public final class AudioInjection { void setAudioTrack(@Nullable AudioTrack audioTrack) { Log.d(TAG, "set AudioTrack with " + audioTrack); synchronized (mLock) { // Release old reference. if (mAudioTrack != null) { mAudioTrack.release(); } // Sync play state for new reference. if (audioTrack != null) { if (audioTrack.getState() != STATE_INITIALIZED) { throw new IllegalStateException("set an uninitialized AudioTrack."); } if (mPlayState == PLAYSTATE_PLAYING && audioTrack.getPlayState() != PLAYSTATE_PLAYING) { audioTrack.play(); Loading @@ -85,10 +90,52 @@ public final class AudioInjection { audioTrack.stop(); } } // Release old reference before assigning the new reference. if (mAudioTrack != null) { mAudioTrack.release(); } mAudioTrack = audioTrack; } } AudioInjection(@NonNull AudioFormat audioFormat) { mAudioFormat = audioFormat; } void close() { synchronized (mLock) { if (mAudioTrack != null) { mAudioTrack.release(); mAudioTrack = null; } } } /** See {@link AudioTrack#getFormat()}. */ public @NonNull AudioFormat getFormat() { return mAudioFormat; } /** See {@link AudioTrack#write(byte[], int, int)}. */ public int write(@NonNull byte[] audioData, int offsetInBytes, int sizeInBytes) { return write(audioData, offsetInBytes, sizeInBytes, WRITE_BLOCKING); } /** See {@link AudioTrack#write(byte[], int, int, int)}. */ public int write(@NonNull byte[] audioData, int offsetInBytes, int sizeInBytes, @AudioTrack.WriteMode int writeMode) { final int sizeWrite; synchronized (mLock) { if (mAudioTrack != null && !mIsSilent) { sizeWrite = mAudioTrack.write(audioData, offsetInBytes, sizeInBytes, writeMode); } else { sizeWrite = 0; } } return sizeWrite; } /** See {@link AudioTrack#write(ByteBuffer, int, int)}. */ public int write(@NonNull ByteBuffer audioBuffer, int sizeInBytes, int writeMode) { final int sizeWrite; Loading @@ -102,6 +149,53 @@ public final class AudioInjection { return sizeWrite; } /** See {@link AudioTrack#write(ByteBuffer, int, int, long)}. */ public int write(@NonNull ByteBuffer audioBuffer, int sizeInBytes, @AudioTrack.WriteMode int writeMode, long timestamp) { final int sizeWrite; synchronized (mLock) { if (mAudioTrack != null && !mIsSilent) { sizeWrite = mAudioTrack.write(audioBuffer, sizeInBytes, writeMode, timestamp); } else { sizeWrite = 0; } } return sizeWrite; } /** See {@link AudioTrack#write(float[], int, int, int)}. */ public int write(@NonNull float[] audioData, int offsetInFloats, int sizeInFloats, @AudioTrack.WriteMode int writeMode) { final int sizeWrite; synchronized (mLock) { if (mAudioTrack != null && !mIsSilent) { sizeWrite = mAudioTrack.write(audioData, offsetInFloats, sizeInFloats, writeMode); } else { sizeWrite = 0; } } return sizeWrite; } /** See {@link AudioTrack#write(short[], int, int)}. */ public int write(@NonNull short[] audioData, int offsetInShorts, int sizeInShorts) { return write(audioData, offsetInShorts, sizeInShorts, WRITE_BLOCKING); } /** See {@link AudioTrack#write(short[], int, int, int)}. */ public int write(@NonNull short[] audioData, int offsetInShorts, int sizeInShorts, @AudioTrack.WriteMode int writeMode) { final int sizeWrite; synchronized (mLock) { if (mAudioTrack != null && !mIsSilent) { sizeWrite = mAudioTrack.write(audioData, offsetInShorts, sizeInShorts, writeMode); } else { sizeWrite = 0; } } return sizeWrite; } /** See {@link AudioTrack#play()}. */ public void play() { synchronized (mLock) { Loading
core/java/android/companion/virtual/audio/VirtualAudioSession.java +16 −20 Original line number Diff line number Diff line Loading @@ -68,12 +68,6 @@ public final class VirtualAudioSession extends IAudioSessionCallback.Stub implem private AudioPolicy mAudioPolicy; @Nullable @GuardedBy("mLock") private AudioFormat mCaptureFormat; @Nullable @GuardedBy("mLock") private AudioFormat mInjectionFormat; @Nullable @GuardedBy("mLock") private AudioCapture mAudioCapture; @Nullable @GuardedBy("mLock") Loading Loading @@ -104,8 +98,7 @@ public final class VirtualAudioSession extends IAudioSessionCallback.Stub implem "Cannot start capture while another capture is ongoing."); } mCaptureFormat = captureFormat; mAudioCapture = new AudioCapture(); mAudioCapture = new AudioCapture(captureFormat); mAudioCapture.startRecording(); return mAudioCapture; } Loading @@ -127,8 +120,7 @@ public final class VirtualAudioSession extends IAudioSessionCallback.Stub implem "Cannot start injection while injection is already ongoing."); } mInjectionFormat = injectionFormat; mAudioInjection = new AudioInjection(); mAudioInjection = new AudioInjection(injectionFormat); mAudioInjection.play(); mUserRestrictionsDetector.register(/* callback= */ this); Loading Loading @@ -179,10 +171,14 @@ public final class VirtualAudioSession extends IAudioSessionCallback.Stub implem mUserRestrictionsDetector.unregister(); releaseAudioStreams(); synchronized (mLock) { if (mAudioCapture != null) { mAudioCapture.close(); mAudioCapture = null; } if (mAudioInjection != null) { mAudioInjection.close(); mAudioInjection = null; mCaptureFormat = null; mInjectionFormat = null; } } } Loading @@ -198,9 +194,9 @@ public final class VirtualAudioSession extends IAudioSessionCallback.Stub implem @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) private void createAudioStreams(int[] appUids) { synchronized (mLock) { if (mCaptureFormat == null && mInjectionFormat == null) { if (mAudioCapture == null && mAudioInjection == null) { throw new IllegalStateException( "At least one of captureFormat and injectionFormat must be specified."); "At least one of AudioCapture and AudioInjection must be started."); } if (mAudioPolicy != null) { throw new IllegalStateException( Loading @@ -218,12 +214,12 @@ public final class VirtualAudioSession extends IAudioSessionCallback.Stub implem AudioMix audioRecordMix = null; AudioMix audioTrackMix = null; AudioPolicy.Builder builder = new AudioPolicy.Builder(mContext); if (mCaptureFormat != null) { audioRecordMix = createAudioRecordMix(mCaptureFormat, appUids); if (mAudioCapture != null) { audioRecordMix = createAudioRecordMix(mAudioCapture.getFormat(), appUids); builder.addMix(audioRecordMix); } if (mInjectionFormat != null) { audioTrackMix = createAudioTrackMix(mInjectionFormat, appUids); if (mAudioInjection != null) { audioTrackMix = createAudioTrackMix(mAudioInjection.getFormat(), appUids); builder.addMix(audioTrackMix); } mAudioPolicy = builder.build(); Loading