Loading api/current.txt +13 −0 Original line number Diff line number Diff line Loading @@ -23371,6 +23371,18 @@ package android.media { method public void onAudioFocusChange(int); } public final class AudioPlaybackCaptureConfiguration { } public static final class AudioPlaybackCaptureConfiguration.Builder { ctor public AudioPlaybackCaptureConfiguration.Builder(); method public android.media.AudioPlaybackCaptureConfiguration.Builder addMatchingUid(int); method public android.media.AudioPlaybackCaptureConfiguration.Builder addMatchingUsage(@NonNull android.media.AudioAttributes); method public android.media.AudioPlaybackCaptureConfiguration build(); method public android.media.AudioPlaybackCaptureConfiguration.Builder excludeUid(int); method public android.media.AudioPlaybackCaptureConfiguration.Builder excludeUsage(@NonNull android.media.AudioAttributes); } public final class AudioPlaybackConfiguration implements android.os.Parcelable { method public int describeContents(); method public android.media.AudioAttributes getAudioAttributes(); Loading Loading @@ -23469,6 +23481,7 @@ package android.media { ctor public AudioRecord.Builder(); method public android.media.AudioRecord build() throws java.lang.UnsupportedOperationException; method public android.media.AudioRecord.Builder setAudioFormat(@NonNull android.media.AudioFormat) throws java.lang.IllegalArgumentException; method public android.media.AudioRecord.Builder setAudioPlaybackCaptureConfig(@NonNull android.media.AudioPlaybackCaptureConfiguration); method public android.media.AudioRecord.Builder setAudioSource(int) throws java.lang.IllegalArgumentException; method public android.media.AudioRecord.Builder setBufferSizeInBytes(int) throws java.lang.IllegalArgumentException; } media/java/android/media/AudioManager.java +8 −0 Original line number Diff line number Diff line Loading @@ -3188,6 +3188,10 @@ public class AudioManager { @SystemApi @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int registerAudioPolicy(@NonNull AudioPolicy policy) { return registerAudioPolicyStatic(policy); } static int registerAudioPolicyStatic(@NonNull AudioPolicy policy) { if (policy == null) { throw new IllegalArgumentException("Illegal null AudioPolicy argument"); } Loading @@ -3214,6 +3218,10 @@ public class AudioManager { @SystemApi @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void unregisterAudioPolicyAsync(@NonNull AudioPolicy policy) { unregisterAudioPolicyAsyncStatic(policy); } static void unregisterAudioPolicyAsyncStatic(@NonNull AudioPolicy policy) { if (policy == null) { throw new IllegalArgumentException("Illegal null AudioPolicy argument"); } Loading media/java/android/media/AudioPlaybackCaptureConfiguration.java 0 → 100644 +161 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.media; import android.annotation.NonNull; import android.media.audiopolicy.AudioMix; import android.media.audiopolicy.AudioMixingRule; import com.android.internal.util.Preconditions; /** * Configuration for capturing audio played by other apps. * * <p>An example for creating a capture configuration for capturing all media playback: * * <pre> * AudioAttributes mediaAttr = new AudioAttributes.Builder() * .setUsage(AudioAttributes.USAGE_MEDIA) * .build(); * AudioPlaybackCaptureConfiguration config = new AudioPlaybackCaptureConfiguration.Builder() * .addMatchingUsage(mediaAttr) * .build(); * AudioRecord record = new AudioRecord.Builder() * .setPlaybackCaptureConfig(config) * .build(); * </pre> * * @see AudioRecord.Builder#setPlaybackCaptureConfig(AudioPlaybackCaptureConfiguration) */ public final class AudioPlaybackCaptureConfiguration { private final AudioMixingRule mAudioMixingRule; private AudioPlaybackCaptureConfiguration(AudioMixingRule audioMixingRule) { mAudioMixingRule = audioMixingRule; } /** * Returns a mix that routes audio back into the app while still playing it from the speakers. * * @param audioFormat The format in which to capture the audio. */ AudioMix createAudioMix(AudioFormat audioFormat) { return new AudioMix.Builder(mAudioMixingRule) .setFormat(audioFormat) .setRouteFlags(AudioMix.ROUTE_FLAG_LOOP_BACK | AudioMix.ROUTE_FLAG_RENDER) .build(); } /** Builder for creating {@link AudioPlaybackCaptureConfiguration} instances. */ public static final class Builder { private static final int MATCH_TYPE_UNSPECIFIED = 0; private static final int MATCH_TYPE_INCLUSIVE = 1; private static final int MATCH_TYPE_EXCLUSIVE = 2; private static final String ERROR_MESSAGE_MISMATCHED_RULES = "Inclusive and exclusive usage rules cannot be combined"; private final AudioMixingRule.Builder mAudioMixingRuleBuilder; private int mUsageMatchType = MATCH_TYPE_UNSPECIFIED; private int mUidMatchType = MATCH_TYPE_UNSPECIFIED; public Builder() { mAudioMixingRuleBuilder = new AudioMixingRule.Builder(); } /** * Only capture audio output with the given {@link AudioAttributes}. * * <p>If called multiple times, will capture audio output that matches any of the given * attributes. * * @throws IllegalStateException if called in conjunction with * {@link #excludeUsage(AudioAttributes)}. */ public Builder addMatchingUsage(@NonNull AudioAttributes audioAttributes) { Preconditions.checkNotNull(audioAttributes); Preconditions.checkState( mUsageMatchType != MATCH_TYPE_EXCLUSIVE, ERROR_MESSAGE_MISMATCHED_RULES); mAudioMixingRuleBuilder .addRule(audioAttributes, AudioMixingRule.RULE_MATCH_ATTRIBUTE_USAGE); mUsageMatchType = MATCH_TYPE_INCLUSIVE; return this; } /** * Only capture audio output by app with the matching {@code uid}. * * <p>If called multiple times, will capture audio output by apps whose uid is any of the * given uids. * * @throws IllegalStateException if called in conjunction with {@link #excludeUid(int)}. */ public Builder addMatchingUid(int uid) { Preconditions.checkState( mUidMatchType != MATCH_TYPE_EXCLUSIVE, ERROR_MESSAGE_MISMATCHED_RULES); mAudioMixingRuleBuilder.addMixRule(AudioMixingRule.RULE_MATCH_UID, uid); mUidMatchType = MATCH_TYPE_INCLUSIVE; return this; } /** * Only capture audio output that does not match the given {@link AudioAttributes}. * * <p>If called multiple times, will capture audio output that does not match any of the * given attributes. * * @throws IllegalStateException if called in conjunction with * {@link #addMatchingUsage(AudioAttributes)}. */ public Builder excludeUsage(@NonNull AudioAttributes audioAttributes) { Preconditions.checkNotNull(audioAttributes); Preconditions.checkState( mUsageMatchType != MATCH_TYPE_INCLUSIVE, ERROR_MESSAGE_MISMATCHED_RULES); mAudioMixingRuleBuilder.excludeRule(audioAttributes, AudioMixingRule.RULE_MATCH_ATTRIBUTE_USAGE); mUsageMatchType = MATCH_TYPE_EXCLUSIVE; return this; } /** * Only capture audio output by apps that do not have the matching {@code uid}. * * <p>If called multiple times, will capture audio output by apps whose uid is not any of * the given uids. * * @throws IllegalStateException if called in conjunction with {@link #addMatchingUid(int)}. */ public Builder excludeUid(int uid) { Preconditions.checkState( mUidMatchType != MATCH_TYPE_INCLUSIVE, ERROR_MESSAGE_MISMATCHED_RULES); mAudioMixingRuleBuilder.excludeMixRule(AudioMixingRule.RULE_MATCH_UID, uid); mUidMatchType = MATCH_TYPE_EXCLUSIVE; return this; } /** * Builds the configuration instance. * * @throws UnsupportedOperationException if the parameters set are incompatible. */ public AudioPlaybackCaptureConfiguration build() { return new AudioPlaybackCaptureConfiguration(mAudioMixingRuleBuilder.build()); } } } media/java/android/media/AudioRecord.java +58 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,8 @@ import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread; import android.media.audiopolicy.AudioMix; import android.media.audiopolicy.AudioPolicy; import android.os.Binder; import android.os.Handler; import android.os.IBinder; Loading @@ -37,6 +39,7 @@ import android.util.Log; import android.util.Pair; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.Preconditions; import java.io.IOException; import java.lang.annotation.Retention; Loading Loading @@ -182,6 +185,8 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection, //--------------------------------------------------------- // Member variables //-------------------- private AudioPolicy mAudioCapturePolicy; /** * The audio data sampling rate in Hz. * Never {@link AudioFormat#SAMPLE_RATE_UNSPECIFIED}. Loading Loading @@ -428,6 +433,16 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection, } } /** * Sets an {@link AudioPolicy} to automatically unregister when the record is released. * * <p>This is to prevent users of the audio capture API from having to manually unregister the * policy that was used to create the record. */ private void unregisterAudioPolicyOnRelease(AudioPolicy audioPolicy) { mAudioCapturePolicy = audioPolicy; } /** * @hide */ Loading Loading @@ -491,6 +506,11 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection, * the minimum buffer size for the source is used. */ public static class Builder { private static final String ERROR_MESSAGE_SOURCE_MISMATCH = "Cannot both set audio source and set playback capture config"; private AudioPlaybackCaptureConfiguration mAudioPlaybackCaptureConfiguration; private AudioAttributes mAttributes; private AudioFormat mFormat; private int mBufferSizeInBytes; Loading @@ -509,6 +529,9 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection, * @throws IllegalArgumentException */ public Builder setAudioSource(int source) throws IllegalArgumentException { Preconditions.checkState( mAudioPlaybackCaptureConfiguration == null, ERROR_MESSAGE_SOURCE_MISMATCH); if ( (source < MediaRecorder.AudioSource.DEFAULT) || (source > MediaRecorder.getAudioSourceMax()) ) { throw new IllegalArgumentException("Invalid audio source " + source); Loading Loading @@ -577,6 +600,25 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection, return this; } /** * Sets the {@link AudioRecord} to record audio played by other apps. * * @param config Defines what apps to record audio from (i.e., via either their uid or * the type of audio). * @throws IllegalStateException if called in conjunction with {@link #setAudioSource(int)}. * @throws NullPointerException if {@code config} is null. */ public Builder setAudioPlaybackCaptureConfig( @NonNull AudioPlaybackCaptureConfiguration config) { Preconditions.checkNotNull( config, "Illegal null AudioPlaybackCaptureConfiguration argument"); Preconditions.checkState( mAttributes == null, ERROR_MESSAGE_SOURCE_MISMATCH); mAudioPlaybackCaptureConfiguration = config; return this; } /** * @hide * To be only used by system components. Loading @@ -595,6 +637,15 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection, return this; } private AudioRecord buildAudioPlaybackCaptureRecord() { AudioMix audioMix = mAudioPlaybackCaptureConfiguration.createAudioMix(mFormat); AudioPolicy audioPolicy = new AudioPolicy.Builder(/*context=*/ null) .addMix(audioMix).build(); AudioRecord record = audioPolicy.createAudioRecordSink(audioMix); record.unregisterAudioPolicyOnRelease(audioPolicy); return record; } /** * @return a new {@link AudioRecord} instance successfully initialized with all * the parameters set on this <code>Builder</code>. Loading @@ -603,6 +654,10 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection, * or if the device was not available. */ public AudioRecord build() throws UnsupportedOperationException { if (mAudioPlaybackCaptureConfiguration != null) { return buildAudioPlaybackCaptureRecord(); } if (mFormat == null) { mFormat = new AudioFormat.Builder() .setEncoding(AudioFormat.ENCODING_PCM_16BIT) Loading Loading @@ -757,6 +812,9 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection, } catch(IllegalStateException ise) { // don't raise an exception, we're releasing the resources. } if (mAudioCapturePolicy != null) { AudioManager.unregisterAudioPolicyAsyncStatic(mAudioCapturePolicy); } native_release(); mState = STATE_UNINITIALIZED; } Loading Loading
api/current.txt +13 −0 Original line number Diff line number Diff line Loading @@ -23371,6 +23371,18 @@ package android.media { method public void onAudioFocusChange(int); } public final class AudioPlaybackCaptureConfiguration { } public static final class AudioPlaybackCaptureConfiguration.Builder { ctor public AudioPlaybackCaptureConfiguration.Builder(); method public android.media.AudioPlaybackCaptureConfiguration.Builder addMatchingUid(int); method public android.media.AudioPlaybackCaptureConfiguration.Builder addMatchingUsage(@NonNull android.media.AudioAttributes); method public android.media.AudioPlaybackCaptureConfiguration build(); method public android.media.AudioPlaybackCaptureConfiguration.Builder excludeUid(int); method public android.media.AudioPlaybackCaptureConfiguration.Builder excludeUsage(@NonNull android.media.AudioAttributes); } public final class AudioPlaybackConfiguration implements android.os.Parcelable { method public int describeContents(); method public android.media.AudioAttributes getAudioAttributes(); Loading Loading @@ -23469,6 +23481,7 @@ package android.media { ctor public AudioRecord.Builder(); method public android.media.AudioRecord build() throws java.lang.UnsupportedOperationException; method public android.media.AudioRecord.Builder setAudioFormat(@NonNull android.media.AudioFormat) throws java.lang.IllegalArgumentException; method public android.media.AudioRecord.Builder setAudioPlaybackCaptureConfig(@NonNull android.media.AudioPlaybackCaptureConfiguration); method public android.media.AudioRecord.Builder setAudioSource(int) throws java.lang.IllegalArgumentException; method public android.media.AudioRecord.Builder setBufferSizeInBytes(int) throws java.lang.IllegalArgumentException; }
media/java/android/media/AudioManager.java +8 −0 Original line number Diff line number Diff line Loading @@ -3188,6 +3188,10 @@ public class AudioManager { @SystemApi @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int registerAudioPolicy(@NonNull AudioPolicy policy) { return registerAudioPolicyStatic(policy); } static int registerAudioPolicyStatic(@NonNull AudioPolicy policy) { if (policy == null) { throw new IllegalArgumentException("Illegal null AudioPolicy argument"); } Loading @@ -3214,6 +3218,10 @@ public class AudioManager { @SystemApi @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void unregisterAudioPolicyAsync(@NonNull AudioPolicy policy) { unregisterAudioPolicyAsyncStatic(policy); } static void unregisterAudioPolicyAsyncStatic(@NonNull AudioPolicy policy) { if (policy == null) { throw new IllegalArgumentException("Illegal null AudioPolicy argument"); } Loading
media/java/android/media/AudioPlaybackCaptureConfiguration.java 0 → 100644 +161 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.media; import android.annotation.NonNull; import android.media.audiopolicy.AudioMix; import android.media.audiopolicy.AudioMixingRule; import com.android.internal.util.Preconditions; /** * Configuration for capturing audio played by other apps. * * <p>An example for creating a capture configuration for capturing all media playback: * * <pre> * AudioAttributes mediaAttr = new AudioAttributes.Builder() * .setUsage(AudioAttributes.USAGE_MEDIA) * .build(); * AudioPlaybackCaptureConfiguration config = new AudioPlaybackCaptureConfiguration.Builder() * .addMatchingUsage(mediaAttr) * .build(); * AudioRecord record = new AudioRecord.Builder() * .setPlaybackCaptureConfig(config) * .build(); * </pre> * * @see AudioRecord.Builder#setPlaybackCaptureConfig(AudioPlaybackCaptureConfiguration) */ public final class AudioPlaybackCaptureConfiguration { private final AudioMixingRule mAudioMixingRule; private AudioPlaybackCaptureConfiguration(AudioMixingRule audioMixingRule) { mAudioMixingRule = audioMixingRule; } /** * Returns a mix that routes audio back into the app while still playing it from the speakers. * * @param audioFormat The format in which to capture the audio. */ AudioMix createAudioMix(AudioFormat audioFormat) { return new AudioMix.Builder(mAudioMixingRule) .setFormat(audioFormat) .setRouteFlags(AudioMix.ROUTE_FLAG_LOOP_BACK | AudioMix.ROUTE_FLAG_RENDER) .build(); } /** Builder for creating {@link AudioPlaybackCaptureConfiguration} instances. */ public static final class Builder { private static final int MATCH_TYPE_UNSPECIFIED = 0; private static final int MATCH_TYPE_INCLUSIVE = 1; private static final int MATCH_TYPE_EXCLUSIVE = 2; private static final String ERROR_MESSAGE_MISMATCHED_RULES = "Inclusive and exclusive usage rules cannot be combined"; private final AudioMixingRule.Builder mAudioMixingRuleBuilder; private int mUsageMatchType = MATCH_TYPE_UNSPECIFIED; private int mUidMatchType = MATCH_TYPE_UNSPECIFIED; public Builder() { mAudioMixingRuleBuilder = new AudioMixingRule.Builder(); } /** * Only capture audio output with the given {@link AudioAttributes}. * * <p>If called multiple times, will capture audio output that matches any of the given * attributes. * * @throws IllegalStateException if called in conjunction with * {@link #excludeUsage(AudioAttributes)}. */ public Builder addMatchingUsage(@NonNull AudioAttributes audioAttributes) { Preconditions.checkNotNull(audioAttributes); Preconditions.checkState( mUsageMatchType != MATCH_TYPE_EXCLUSIVE, ERROR_MESSAGE_MISMATCHED_RULES); mAudioMixingRuleBuilder .addRule(audioAttributes, AudioMixingRule.RULE_MATCH_ATTRIBUTE_USAGE); mUsageMatchType = MATCH_TYPE_INCLUSIVE; return this; } /** * Only capture audio output by app with the matching {@code uid}. * * <p>If called multiple times, will capture audio output by apps whose uid is any of the * given uids. * * @throws IllegalStateException if called in conjunction with {@link #excludeUid(int)}. */ public Builder addMatchingUid(int uid) { Preconditions.checkState( mUidMatchType != MATCH_TYPE_EXCLUSIVE, ERROR_MESSAGE_MISMATCHED_RULES); mAudioMixingRuleBuilder.addMixRule(AudioMixingRule.RULE_MATCH_UID, uid); mUidMatchType = MATCH_TYPE_INCLUSIVE; return this; } /** * Only capture audio output that does not match the given {@link AudioAttributes}. * * <p>If called multiple times, will capture audio output that does not match any of the * given attributes. * * @throws IllegalStateException if called in conjunction with * {@link #addMatchingUsage(AudioAttributes)}. */ public Builder excludeUsage(@NonNull AudioAttributes audioAttributes) { Preconditions.checkNotNull(audioAttributes); Preconditions.checkState( mUsageMatchType != MATCH_TYPE_INCLUSIVE, ERROR_MESSAGE_MISMATCHED_RULES); mAudioMixingRuleBuilder.excludeRule(audioAttributes, AudioMixingRule.RULE_MATCH_ATTRIBUTE_USAGE); mUsageMatchType = MATCH_TYPE_EXCLUSIVE; return this; } /** * Only capture audio output by apps that do not have the matching {@code uid}. * * <p>If called multiple times, will capture audio output by apps whose uid is not any of * the given uids. * * @throws IllegalStateException if called in conjunction with {@link #addMatchingUid(int)}. */ public Builder excludeUid(int uid) { Preconditions.checkState( mUidMatchType != MATCH_TYPE_INCLUSIVE, ERROR_MESSAGE_MISMATCHED_RULES); mAudioMixingRuleBuilder.excludeMixRule(AudioMixingRule.RULE_MATCH_UID, uid); mUidMatchType = MATCH_TYPE_EXCLUSIVE; return this; } /** * Builds the configuration instance. * * @throws UnsupportedOperationException if the parameters set are incompatible. */ public AudioPlaybackCaptureConfiguration build() { return new AudioPlaybackCaptureConfiguration(mAudioMixingRuleBuilder.build()); } } }
media/java/android/media/AudioRecord.java +58 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,8 @@ import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread; import android.media.audiopolicy.AudioMix; import android.media.audiopolicy.AudioPolicy; import android.os.Binder; import android.os.Handler; import android.os.IBinder; Loading @@ -37,6 +39,7 @@ import android.util.Log; import android.util.Pair; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.Preconditions; import java.io.IOException; import java.lang.annotation.Retention; Loading Loading @@ -182,6 +185,8 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection, //--------------------------------------------------------- // Member variables //-------------------- private AudioPolicy mAudioCapturePolicy; /** * The audio data sampling rate in Hz. * Never {@link AudioFormat#SAMPLE_RATE_UNSPECIFIED}. Loading Loading @@ -428,6 +433,16 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection, } } /** * Sets an {@link AudioPolicy} to automatically unregister when the record is released. * * <p>This is to prevent users of the audio capture API from having to manually unregister the * policy that was used to create the record. */ private void unregisterAudioPolicyOnRelease(AudioPolicy audioPolicy) { mAudioCapturePolicy = audioPolicy; } /** * @hide */ Loading Loading @@ -491,6 +506,11 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection, * the minimum buffer size for the source is used. */ public static class Builder { private static final String ERROR_MESSAGE_SOURCE_MISMATCH = "Cannot both set audio source and set playback capture config"; private AudioPlaybackCaptureConfiguration mAudioPlaybackCaptureConfiguration; private AudioAttributes mAttributes; private AudioFormat mFormat; private int mBufferSizeInBytes; Loading @@ -509,6 +529,9 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection, * @throws IllegalArgumentException */ public Builder setAudioSource(int source) throws IllegalArgumentException { Preconditions.checkState( mAudioPlaybackCaptureConfiguration == null, ERROR_MESSAGE_SOURCE_MISMATCH); if ( (source < MediaRecorder.AudioSource.DEFAULT) || (source > MediaRecorder.getAudioSourceMax()) ) { throw new IllegalArgumentException("Invalid audio source " + source); Loading Loading @@ -577,6 +600,25 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection, return this; } /** * Sets the {@link AudioRecord} to record audio played by other apps. * * @param config Defines what apps to record audio from (i.e., via either their uid or * the type of audio). * @throws IllegalStateException if called in conjunction with {@link #setAudioSource(int)}. * @throws NullPointerException if {@code config} is null. */ public Builder setAudioPlaybackCaptureConfig( @NonNull AudioPlaybackCaptureConfiguration config) { Preconditions.checkNotNull( config, "Illegal null AudioPlaybackCaptureConfiguration argument"); Preconditions.checkState( mAttributes == null, ERROR_MESSAGE_SOURCE_MISMATCH); mAudioPlaybackCaptureConfiguration = config; return this; } /** * @hide * To be only used by system components. Loading @@ -595,6 +637,15 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection, return this; } private AudioRecord buildAudioPlaybackCaptureRecord() { AudioMix audioMix = mAudioPlaybackCaptureConfiguration.createAudioMix(mFormat); AudioPolicy audioPolicy = new AudioPolicy.Builder(/*context=*/ null) .addMix(audioMix).build(); AudioRecord record = audioPolicy.createAudioRecordSink(audioMix); record.unregisterAudioPolicyOnRelease(audioPolicy); return record; } /** * @return a new {@link AudioRecord} instance successfully initialized with all * the parameters set on this <code>Builder</code>. Loading @@ -603,6 +654,10 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection, * or if the device was not available. */ public AudioRecord build() throws UnsupportedOperationException { if (mAudioPlaybackCaptureConfiguration != null) { return buildAudioPlaybackCaptureRecord(); } if (mFormat == null) { mFormat = new AudioFormat.Builder() .setEncoding(AudioFormat.ENCODING_PCM_16BIT) Loading Loading @@ -757,6 +812,9 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection, } catch(IllegalStateException ise) { // don't raise an exception, we're releasing the resources. } if (mAudioCapturePolicy != null) { AudioManager.unregisterAudioPolicyAsyncStatic(mAudioCapturePolicy); } native_release(); mState = STATE_UNINITIALIZED; } Loading