diff options
| author | 2018-02-01 01:35:26 +0000 | |
|---|---|---|
| committer | 2018-02-01 01:35:26 +0000 | |
| commit | 23a7b8d36b5055dcb1cdebb10b5b97688f675fdc (patch) | |
| tree | 181443a5f2967b160c3a9ff7968b5cf30f200df4 | |
| parent | 158c1d1778eb3c4650b24cfdb4aa0e9d30ae7db2 (diff) | |
| parent | 23675f6c79d0c76caa837402a1e5e49ca11e2a02 (diff) | |
Merge "Support query active microphones information in AudioRecord."
| -rw-r--r-- | api/current.txt | 1 | ||||
| -rw-r--r-- | core/jni/android_media_AudioRecord.cpp | 54 | ||||
| -rw-r--r-- | media/java/android/media/AudioRecord.java | 33 |
3 files changed, 88 insertions, 0 deletions
diff --git a/api/current.txt b/api/current.txt index 6fa7976e6835..ded0e438a7b7 100644 --- a/api/current.txt +++ b/api/current.txt @@ -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(); diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp index ebd16c7084ac..375d68b85824 100644 --- a/core/jni/android_media_AudioRecord.cpp +++ b/core/jni/android_media_AudioRecord.cpp @@ -25,6 +25,8 @@ #include <utils/Log.h> #include <media/AudioRecord.h> +#include <media/MicrophoneInfo.h> +#include <vector> #include <nativehelper/ScopedUtfChars.h> @@ -32,6 +34,7 @@ #include "android_media_AudioErrors.h" #include "android_media_DeviceCallback.h" #include "android_media_MediaMetricsJNI.h" +#include "android_media_MicrophoneInfo.h" // ---------------------------------------------------------------------------- @@ -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 @@ -785,6 +793,46 @@ android_media_AudioRecord_native_getMetrics(JNIEnv *env, jobject thiz) } // ---------------------------------------------------------------------------- +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[] = { // name, signature, funcPtr @@ -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 @@ -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)); } diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java index eb6e83065fe9..d0963cbcb87f 100644 --- a/media/java/android/media/AudioRecord.java +++ b/media/java/android/media/AudioRecord.java @@ -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; @@ -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; @@ -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 //-------------------- @@ -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 //------------------ |