Loading api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -22155,6 +22155,7 @@ package android.media { method public void addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler); method public deprecated void addOnRoutingChangedListener(android.media.AudioRecord.OnRoutingChangedListener, android.os.Handler); method protected void finalize(); method public java.util.List<android.media.MicrophoneInfo> getActiveMicrophones() throws java.io.IOException; method public int getAudioFormat(); method public int getAudioSessionId(); method public int getAudioSource(); core/jni/android_media_AudioRecord.cpp +54 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,8 @@ #include <utils/Log.h> #include <media/AudioRecord.h> #include <media/MicrophoneInfo.h> #include <vector> #include <nativehelper/ScopedUtfChars.h> Loading @@ -32,6 +34,7 @@ #include "android_media_AudioErrors.h" #include "android_media_DeviceCallback.h" #include "android_media_MediaMetricsJNI.h" #include "android_media_MicrophoneInfo.h" // ---------------------------------------------------------------------------- Loading @@ -41,6 +44,11 @@ using namespace android; static const char* const kClassPathName = "android/media/AudioRecord"; static const char* const kAudioAttributesClassPathName = "android/media/AudioAttributes"; static jclass gArrayListClass; static struct { jmethodID add; } gArrayListMethods; struct audio_record_fields_t { // these fields provide access from C++ to the... jmethodID postNativeEventInJava; //... event post callback method Loading Loading @@ -784,6 +792,46 @@ android_media_AudioRecord_native_getMetrics(JNIEnv *env, jobject thiz) return mybundle; } // ---------------------------------------------------------------------------- static jint android_media_AudioRecord_get_active_microphones(JNIEnv *env, jobject thiz, jobject jActiveMicrophones) { if (jActiveMicrophones == NULL) { ALOGE("jActiveMicrophones is null"); return (jint)AUDIO_JAVA_BAD_VALUE; } if (!env->IsInstanceOf(jActiveMicrophones, gArrayListClass)) { ALOGE("getActiveMicrophones not an arraylist"); return (jint)AUDIO_JAVA_BAD_VALUE; } sp<AudioRecord> lpRecorder = getAudioRecord(env, thiz); if (lpRecorder == NULL) { jniThrowException(env, "java/lang/IllegalStateException", "Unable to retrieve AudioRecord pointer for getActiveMicrophones()"); return (jint)AUDIO_JAVA_ERROR; } jint jStatus = AUDIO_JAVA_SUCCESS; std::vector<media::MicrophoneInfo> activeMicrophones; status_t status = lpRecorder->getActiveMicrophones(&activeMicrophones); if (status != NO_ERROR) { ALOGE_IF(status != NO_ERROR, "AudioRecord::getActiveMicrophones error %d", status); jStatus = nativeToJavaStatus(status); return jStatus; } for (size_t i = 0; i < activeMicrophones.size(); i++) { jobject jMicrophoneInfo; jStatus = convertMicrophoneInfoFromNative(env, &jMicrophoneInfo, &activeMicrophones[i]); if (jStatus != AUDIO_JAVA_SUCCESS) { return jStatus; } env->CallBooleanMethod(jActiveMicrophones, gArrayListMethods.add, jMicrophoneInfo); env->DeleteLocalRef(jMicrophoneInfo); } return jStatus; } // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- static const JNINativeMethod gMethods[] = { Loading Loading @@ -824,6 +872,8 @@ static const JNINativeMethod gMethods[] = { (void *)android_media_AudioRecord_disableDeviceCallback}, {"native_get_timestamp", "(Landroid/media/AudioTimestamp;I)I", (void *)android_media_AudioRecord_get_timestamp}, {"native_get_active_microphones", "(Ljava/util/ArrayList;)I", (void *)android_media_AudioRecord_get_active_microphones}, }; // field names found in android/media/AudioRecord.java Loading Loading @@ -873,6 +923,10 @@ int register_android_media_AudioRecord(JNIEnv *env) javaAudioTimestampFields.fieldNanoTime = GetFieldIDOrDie(env, audioTimestampClass, "nanoTime", "J"); jclass arrayListClass = FindClassOrDie(env, "java/util/ArrayList"); gArrayListClass = MakeGlobalRefOrDie(env, arrayListClass); gArrayListMethods.add = GetMethodIDOrDie(env, arrayListClass, "add", "(Ljava/lang/Object;)Z"); return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods)); } Loading media/java/android/media/AudioRecord.java +33 −0 Original line number Diff line number Diff line Loading @@ -16,12 +16,15 @@ package android.media; import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; import java.nio.ByteBuffer; import java.util.Collection; import java.util.Iterator; import java.util.ArrayList; import java.util.List; import android.annotation.IntDef; import android.annotation.NonNull; Loading @@ -35,6 +38,7 @@ import android.os.Message; import android.os.PersistableBundle; import android.os.RemoteException; import android.os.ServiceManager; import android.text.TextUtils; import android.util.ArrayMap; import android.util.Log; Loading Loading @@ -1601,6 +1605,32 @@ public class AudioRecord implements AudioRouting } } //-------------------------------------------------------------------------- // Microphone information //-------------------- /** * Returns a lists of {@link MicrophoneInfo} representing the active microphones. * By querying channel mapping for each active microphone, developer can know how * the microphone is used by each channels or a capture stream. * Note that the information about the active microphones may change during a recording. * See {@link AudioManager#registerAudioDeviceCallback} to be notified of changes * in the audio devices, querying the active microphones then will return the latest * information. * * @return a lists of {@link MicrophoneInfo} representing the active microphones. * @throws IOException if an error occurs */ public List<MicrophoneInfo> getActiveMicrophones() throws IOException { ArrayList<MicrophoneInfo> activeMicrophones = new ArrayList<>(); int status = native_get_active_microphones(activeMicrophones); if (status != AudioManager.SUCCESS) { Log.e(TAG, "getActiveMicrophones failed:" + status); return new ArrayList<MicrophoneInfo>(); } AudioManager.setPortIdForMicrophones(activeMicrophones); return activeMicrophones; } //--------------------------------------------------------- // Interface definitions //-------------------- Loading Loading @@ -1746,6 +1776,9 @@ public class AudioRecord implements AudioRouting private native final int native_get_timestamp(@NonNull AudioTimestamp outTimestamp, @AudioTimestamp.Timebase int timebase); private native final int native_get_active_microphones( ArrayList<MicrophoneInfo> activeMicrophones); //--------------------------------------------------------- // Utility methods //------------------ Loading Loading
api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -22155,6 +22155,7 @@ package android.media { method public void addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler); method public deprecated void addOnRoutingChangedListener(android.media.AudioRecord.OnRoutingChangedListener, android.os.Handler); method protected void finalize(); method public java.util.List<android.media.MicrophoneInfo> getActiveMicrophones() throws java.io.IOException; method public int getAudioFormat(); method public int getAudioSessionId(); method public int getAudioSource();
core/jni/android_media_AudioRecord.cpp +54 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,8 @@ #include <utils/Log.h> #include <media/AudioRecord.h> #include <media/MicrophoneInfo.h> #include <vector> #include <nativehelper/ScopedUtfChars.h> Loading @@ -32,6 +34,7 @@ #include "android_media_AudioErrors.h" #include "android_media_DeviceCallback.h" #include "android_media_MediaMetricsJNI.h" #include "android_media_MicrophoneInfo.h" // ---------------------------------------------------------------------------- Loading @@ -41,6 +44,11 @@ using namespace android; static const char* const kClassPathName = "android/media/AudioRecord"; static const char* const kAudioAttributesClassPathName = "android/media/AudioAttributes"; static jclass gArrayListClass; static struct { jmethodID add; } gArrayListMethods; struct audio_record_fields_t { // these fields provide access from C++ to the... jmethodID postNativeEventInJava; //... event post callback method Loading Loading @@ -784,6 +792,46 @@ android_media_AudioRecord_native_getMetrics(JNIEnv *env, jobject thiz) return mybundle; } // ---------------------------------------------------------------------------- static jint android_media_AudioRecord_get_active_microphones(JNIEnv *env, jobject thiz, jobject jActiveMicrophones) { if (jActiveMicrophones == NULL) { ALOGE("jActiveMicrophones is null"); return (jint)AUDIO_JAVA_BAD_VALUE; } if (!env->IsInstanceOf(jActiveMicrophones, gArrayListClass)) { ALOGE("getActiveMicrophones not an arraylist"); return (jint)AUDIO_JAVA_BAD_VALUE; } sp<AudioRecord> lpRecorder = getAudioRecord(env, thiz); if (lpRecorder == NULL) { jniThrowException(env, "java/lang/IllegalStateException", "Unable to retrieve AudioRecord pointer for getActiveMicrophones()"); return (jint)AUDIO_JAVA_ERROR; } jint jStatus = AUDIO_JAVA_SUCCESS; std::vector<media::MicrophoneInfo> activeMicrophones; status_t status = lpRecorder->getActiveMicrophones(&activeMicrophones); if (status != NO_ERROR) { ALOGE_IF(status != NO_ERROR, "AudioRecord::getActiveMicrophones error %d", status); jStatus = nativeToJavaStatus(status); return jStatus; } for (size_t i = 0; i < activeMicrophones.size(); i++) { jobject jMicrophoneInfo; jStatus = convertMicrophoneInfoFromNative(env, &jMicrophoneInfo, &activeMicrophones[i]); if (jStatus != AUDIO_JAVA_SUCCESS) { return jStatus; } env->CallBooleanMethod(jActiveMicrophones, gArrayListMethods.add, jMicrophoneInfo); env->DeleteLocalRef(jMicrophoneInfo); } return jStatus; } // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- static const JNINativeMethod gMethods[] = { Loading Loading @@ -824,6 +872,8 @@ static const JNINativeMethod gMethods[] = { (void *)android_media_AudioRecord_disableDeviceCallback}, {"native_get_timestamp", "(Landroid/media/AudioTimestamp;I)I", (void *)android_media_AudioRecord_get_timestamp}, {"native_get_active_microphones", "(Ljava/util/ArrayList;)I", (void *)android_media_AudioRecord_get_active_microphones}, }; // field names found in android/media/AudioRecord.java Loading Loading @@ -873,6 +923,10 @@ int register_android_media_AudioRecord(JNIEnv *env) javaAudioTimestampFields.fieldNanoTime = GetFieldIDOrDie(env, audioTimestampClass, "nanoTime", "J"); jclass arrayListClass = FindClassOrDie(env, "java/util/ArrayList"); gArrayListClass = MakeGlobalRefOrDie(env, arrayListClass); gArrayListMethods.add = GetMethodIDOrDie(env, arrayListClass, "add", "(Ljava/lang/Object;)Z"); return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods)); } Loading
media/java/android/media/AudioRecord.java +33 −0 Original line number Diff line number Diff line Loading @@ -16,12 +16,15 @@ package android.media; import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; import java.nio.ByteBuffer; import java.util.Collection; import java.util.Iterator; import java.util.ArrayList; import java.util.List; import android.annotation.IntDef; import android.annotation.NonNull; Loading @@ -35,6 +38,7 @@ import android.os.Message; import android.os.PersistableBundle; import android.os.RemoteException; import android.os.ServiceManager; import android.text.TextUtils; import android.util.ArrayMap; import android.util.Log; Loading Loading @@ -1601,6 +1605,32 @@ public class AudioRecord implements AudioRouting } } //-------------------------------------------------------------------------- // Microphone information //-------------------- /** * Returns a lists of {@link MicrophoneInfo} representing the active microphones. * By querying channel mapping for each active microphone, developer can know how * the microphone is used by each channels or a capture stream. * Note that the information about the active microphones may change during a recording. * See {@link AudioManager#registerAudioDeviceCallback} to be notified of changes * in the audio devices, querying the active microphones then will return the latest * information. * * @return a lists of {@link MicrophoneInfo} representing the active microphones. * @throws IOException if an error occurs */ public List<MicrophoneInfo> getActiveMicrophones() throws IOException { ArrayList<MicrophoneInfo> activeMicrophones = new ArrayList<>(); int status = native_get_active_microphones(activeMicrophones); if (status != AudioManager.SUCCESS) { Log.e(TAG, "getActiveMicrophones failed:" + status); return new ArrayList<MicrophoneInfo>(); } AudioManager.setPortIdForMicrophones(activeMicrophones); return activeMicrophones; } //--------------------------------------------------------- // Interface definitions //-------------------- Loading Loading @@ -1746,6 +1776,9 @@ public class AudioRecord implements AudioRouting private native final int native_get_timestamp(@NonNull AudioTimestamp outTimestamp, @AudioTimestamp.Timebase int timebase); private native final int native_get_active_microphones( ArrayList<MicrophoneInfo> activeMicrophones); //--------------------------------------------------------- // Utility methods //------------------ Loading