diff options
| -rw-r--r-- | api/current.txt | 8 | ||||
| -rw-r--r-- | core/jni/android_media_MicrophoneInfo.cpp | 4 | ||||
| -rw-r--r-- | media/java/android/media/AudioManager.java | 32 | ||||
| -rw-r--r-- | media/java/android/media/AudioRecord.java | 15 | ||||
| -rw-r--r-- | media/java/android/media/MediaRecorder.java | 19 | ||||
| -rw-r--r-- | media/java/android/media/MicrophoneInfo.java | 74 |
6 files changed, 139 insertions, 13 deletions
diff --git a/api/current.txt b/api/current.txt index aba4e2f0878a..e2d33d0df049 100644 --- a/api/current.txt +++ b/api/current.txt @@ -24582,13 +24582,19 @@ package android.media { field public static final int DIRECTIONALITY_OMNI = 1; // 0x1 field public static final int DIRECTIONALITY_SUPER_CARDIOID = 5; // 0x5 field public static final int DIRECTIONALITY_UNKNOWN = 0; // 0x0 + field public static final int GROUP_UNKNOWN = -1; // 0xffffffff + field public static final int INDEX_IN_THE_GROUP_UNKNOWN = -1; // 0xffffffff field public static final int LOCATION_MAINBODY = 1; // 0x1 field public static final int LOCATION_MAINBODY_MOVABLE = 2; // 0x2 field public static final int LOCATION_PERIPHERAL = 3; // 0x3 field public static final int LOCATION_UNKNOWN = 0; // 0x0 + field public static final android.media.MicrophoneInfo.Coordinate3F ORIENTATION_UNKNOWN; + field public static final android.media.MicrophoneInfo.Coordinate3F POSITION_UNKNOWN; + field public static final float SENSITIVITY_UNKNOWN = -3.4028235E38f; + field public static final float SPL_UNKNOWN = -3.4028235E38f; } - public class MicrophoneInfo.Coordinate3F { + public static final class MicrophoneInfo.Coordinate3F { field public final float x; field public final float y; field public final float z; diff --git a/core/jni/android_media_MicrophoneInfo.cpp b/core/jni/android_media_MicrophoneInfo.cpp index 9198cbe648eb..5bd808b67c57 100644 --- a/core/jni/android_media_MicrophoneInfo.cpp +++ b/core/jni/android_media_MicrophoneInfo.cpp @@ -65,13 +65,11 @@ jint convertMicrophoneInfoFromNative(JNIEnv *env, jobject *jMicrophoneInfo, } jGeometricLocation = env->NewObject(gMicrophoneInfoCoordinateClass, gMicrophoneInfoCoordinateCstor, - NULL, microphoneInfo->getGeometricLocation()[0], microphoneInfo->getGeometricLocation()[1], microphoneInfo->getGeometricLocation()[2]); jOrientation = env->NewObject(gMicrophoneInfoCoordinateClass, gMicrophoneInfoCoordinateCstor, - NULL, microphoneInfo->getOrientation()[0], microphoneInfo->getOrientation()[1], microphoneInfo->getOrientation()[2]); @@ -177,7 +175,7 @@ int register_android_media_MicrophoneInfo(JNIEnv *env) env, "android/media/MicrophoneInfo$Coordinate3F"); gMicrophoneInfoCoordinateClass = MakeGlobalRefOrDie(env, microphoneInfoCoordinateClass); gMicrophoneInfoCoordinateCstor = GetMethodIDOrDie(env, microphoneInfoCoordinateClass, "<init>", - "(Landroid/media/MicrophoneInfo;FFF)V"); + "(FFF)V"); jclass pairClass = FindClassOrDie(env, "android/util/Pair"); gPairClass = MakeGlobalRefOrDie(env, pairClass); diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index 17a8d5c9a1d4..5b627ec2ed56 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -53,6 +53,7 @@ import android.provider.Settings; import android.text.TextUtils; import android.util.ArrayMap; import android.util.Log; +import android.util.Pair; import android.util.Slog; import android.view.KeyEvent; @@ -4784,6 +4785,28 @@ public class AudioManager { } /** + * Convert {@link AudioDeviceInfo} to {@link MicrophoneInfo}. + * @hide + */ + public static MicrophoneInfo microphoneInfoFromAudioDeviceInfo(AudioDeviceInfo deviceInfo) { + int deviceType = deviceInfo.getType(); + int micLocation = (deviceType == AudioDeviceInfo.TYPE_BUILTIN_MIC + || deviceType == AudioDeviceInfo.TYPE_TELEPHONY) ? MicrophoneInfo.LOCATION_MAINBODY + : deviceType == AudioDeviceInfo.TYPE_UNKNOWN ? MicrophoneInfo.LOCATION_UNKNOWN + : MicrophoneInfo.LOCATION_PERIPHERAL; + MicrophoneInfo microphone = new MicrophoneInfo( + deviceInfo.getPort().name() + deviceInfo.getId(), + deviceInfo.getPort().type(), deviceInfo.getAddress(), micLocation, + MicrophoneInfo.GROUP_UNKNOWN, MicrophoneInfo.INDEX_IN_THE_GROUP_UNKNOWN, + MicrophoneInfo.POSITION_UNKNOWN, MicrophoneInfo.ORIENTATION_UNKNOWN, + new ArrayList<Pair<Float, Float>>(), new ArrayList<Pair<Integer, Integer>>(), + MicrophoneInfo.SENSITIVITY_UNKNOWN, MicrophoneInfo.SPL_UNKNOWN, + MicrophoneInfo.SPL_UNKNOWN, MicrophoneInfo.DIRECTIONALITY_UNKNOWN); + microphone.setId(deviceInfo.getId()); + return microphone; + } + + /** * Returns a list of {@link MicrophoneInfo} that corresponds to the characteristics * of all available microphones. The list is empty when no microphones are available * on the device. An error during the query will result in an IOException being thrown. @@ -4800,6 +4823,15 @@ public class AudioManager { return new ArrayList<MicrophoneInfo>(); // Always return a list. } setPortIdForMicrophones(microphones); + AudioDeviceInfo[] devices = getDevicesStatic(GET_DEVICES_INPUTS); + for (AudioDeviceInfo device : devices) { + if (device.getType() == AudioDeviceInfo.TYPE_BUILTIN_MIC || + device.getType() == AudioDeviceInfo.TYPE_TELEPHONY) { + continue; + } + MicrophoneInfo microphone = microphoneInfoFromAudioDeviceInfo(device); + microphones.add(microphone); + } return microphones; } diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java index 384753018bc8..4f0dccb8a088 100644 --- a/media/java/android/media/AudioRecord.java +++ b/media/java/android/media/AudioRecord.java @@ -41,6 +41,7 @@ import android.os.ServiceManager; import android.text.TextUtils; import android.util.ArrayMap; import android.util.Log; +import android.util.Pair; import com.android.internal.annotations.GuardedBy; @@ -1630,6 +1631,20 @@ public class AudioRecord implements AudioRouting return new ArrayList<MicrophoneInfo>(); } AudioManager.setPortIdForMicrophones(activeMicrophones); + + // Use routed device when there is not information returned by hal. + if (activeMicrophones.size() == 0) { + AudioDeviceInfo device = getRoutedDevice(); + if (device != null) { + MicrophoneInfo microphone = AudioManager.microphoneInfoFromAudioDeviceInfo(device); + ArrayList<Pair<Integer, Integer>> channelMapping = new ArrayList<>(); + for (int i = 0; i < mChannelCount; i++) { + channelMapping.add(new Pair(i, MicrophoneInfo.CHANNEL_MAPPING_DIRECT)); + } + microphone.setChannelMapping(channelMapping); + activeMicrophones.add(microphone); + } + } return activeMicrophones; } diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java index 9ad5cd93e1e2..90b6bff63874 100644 --- a/media/java/android/media/MediaRecorder.java +++ b/media/java/android/media/MediaRecorder.java @@ -29,6 +29,7 @@ import android.os.PersistableBundle; import android.text.TextUtils; import android.util.ArrayMap; import android.util.Log; +import android.util.Pair; import android.view.Surface; import java.io.File; @@ -105,6 +106,8 @@ public class MediaRecorder implements AudioRouting private OnErrorListener mOnErrorListener; private OnInfoListener mOnInfoListener; + private int mChannelCount; + /** * Default constructor. */ @@ -119,6 +122,7 @@ public class MediaRecorder implements AudioRouting mEventHandler = null; } + mChannelCount = 1; String packageName = ActivityThread.currentPackageName(); /* Native setup requires a weak reference to our object. * It's easier to create it here than in C++. @@ -755,6 +759,7 @@ public class MediaRecorder implements AudioRouting if (numChannels <= 0) { throw new IllegalArgumentException("Number of channels is not positive"); } + mChannelCount = numChannels; setParameter("audio-param-number-of-channels=" + numChannels); } @@ -1432,6 +1437,20 @@ public class MediaRecorder implements AudioRouting return new ArrayList<MicrophoneInfo>(); } AudioManager.setPortIdForMicrophones(activeMicrophones); + + // Use routed device when there is not information returned by hal. + if (activeMicrophones.size() == 0) { + AudioDeviceInfo device = getRoutedDevice(); + if (device != null) { + MicrophoneInfo microphone = AudioManager.microphoneInfoFromAudioDeviceInfo(device); + ArrayList<Pair<Integer, Integer>> channelMapping = new ArrayList<>(); + for (int i = 0; i < mChannelCount; i++) { + channelMapping.add(new Pair(i, MicrophoneInfo.CHANNEL_MAPPING_DIRECT)); + } + microphone.setChannelMapping(channelMapping); + activeMicrophones.add(microphone); + } + } return activeMicrophones; } diff --git a/media/java/android/media/MicrophoneInfo.java b/media/java/android/media/MicrophoneInfo.java index 131e37bd6646..004efea64d2d 100644 --- a/media/java/android/media/MicrophoneInfo.java +++ b/media/java/android/media/MicrophoneInfo.java @@ -92,6 +92,38 @@ public final class MicrophoneInfo { */ public static final int CHANNEL_MAPPING_PROCESSED = 2; + /** + * Value used for when the group of the microphone is unknown. + */ + public static final int GROUP_UNKNOWN = -1; + + /** + * Value used for when the index in the group of the microphone is unknown. + */ + public static final int INDEX_IN_THE_GROUP_UNKNOWN = -1; + + /** + * Value used for when the position of the microphone is unknown. + */ + public static final Coordinate3F POSITION_UNKNOWN = new Coordinate3F( + -Float.MAX_VALUE, -Float.MAX_VALUE, -Float.MAX_VALUE); + + /** + * Value used for when the orientation of the microphone is unknown. + */ + public static final Coordinate3F ORIENTATION_UNKNOWN = new Coordinate3F(0.0f, 0.0f, 0.0f); + + /** + * Value used for when the sensitivity of the microphone is unknown. + */ + public static final float SENSITIVITY_UNKNOWN = -Float.MAX_VALUE; + + /** + * Value used for when the SPL of the microphone is unknown. This value could be used when + * maximum SPL or minimum SPL is unknown. + */ + public static final float SPL_UNKNOWN = -Float.MAX_VALUE; + /** @hide */ @IntDef(flag = true, prefix = { "LOCATION_" }, value = { LOCATION_UNKNOWN, @@ -216,7 +248,7 @@ public final class MicrophoneInfo { * Returns A device group id that can be used to group together microphones on the same * peripheral, attachments or logical groups. Main body is usually group 0. * - * @return the group of the microphone + * @return the group of the microphone or {@link #GROUP_UNKNOWN} if the group is unknown */ public int getGroup() { return mGroup; @@ -225,7 +257,8 @@ public final class MicrophoneInfo { /** * Returns unique index for device within its group. * - * @return the microphone's index in its group + * @return the microphone's index in its group or {@link #INDEX_IN_THE_GROUP_UNKNOWN} if the + * index in the group is unknown */ public int getIndexInTheGroup() { return mIndexInTheGroup; @@ -233,10 +266,11 @@ public final class MicrophoneInfo { /** * Returns A {@link Coordinate3F} object that represents the geometric location of microphone - * in meters, from botton-left-back corner of appliance. X-axis, Y-axis and Z-axis show + * in meters, from bottom-left-back corner of appliance. X-axis, Y-axis and Z-axis show * as the x, y, z values. * - * @return the geometric location of the microphone + * @return the geometric location of the microphone or {@link #POSITION_UNKNOWN} if the + * geometric location is unknown */ public Coordinate3F getPosition() { return mPosition; @@ -247,7 +281,8 @@ public final class MicrophoneInfo { * X-axis, Y-axis and Z-axis show as the x, y, z value. The orientation will be normalized * such as sqrt(x^2 + y^2 + z^2) equals 1. * - * @return the orientation of the microphone + * @return the orientation of the microphone or {@link #ORIENTATION_UNKNOWN} if orientation + * is unknown */ public Coordinate3F getOrientation() { return mOrientation; @@ -283,7 +318,8 @@ public final class MicrophoneInfo { /** * Returns the level in dBFS produced by a 1000Hz tone at 94 dB SPL. * - * @return the sensitivity of the microphone + * @return the sensitivity of the microphone or {@link #SENSITIVITY_UNKNOWN} if the sensitivity + * is unknown */ public float getSensitivity() { return mSensitivity; @@ -292,7 +328,7 @@ public final class MicrophoneInfo { /** * Returns the level in dB of the maximum SPL supported by the device at 1000Hz. * - * @return the maximum level in dB + * @return the maximum level in dB or {@link #SPL_UNKNOWN} if maximum SPL is unknown */ public float getMaxSpl() { return mMaxSpl; @@ -301,7 +337,7 @@ public final class MicrophoneInfo { /** * Returns the level in dB of the minimum SPL that can be registered by the device at 1000Hz. * - * @return the minimum level in dB + * @return the minimum level in dB or {@link #SPL_UNKNOWN} if minimum SPL is unknown */ public float getMinSpl() { return mMinSpl; @@ -327,8 +363,16 @@ public final class MicrophoneInfo { mPortId = portId; } + /** + * Set the channel mapping for the device. + * @hide + */ + public void setChannelMapping(List<Pair<Integer, Integer>> channelMapping) { + mChannelMapping = channelMapping; + } + /* A class containing three float value to represent a 3D coordinate */ - public class Coordinate3F { + public static final class Coordinate3F { public final float x; public final float y; public final float z; @@ -338,5 +382,17 @@ public final class MicrophoneInfo { this.y = y; this.z = z; } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof Coordinate3F)) { + return false; + } + Coordinate3F other = (Coordinate3F) obj; + return this.x == other.x && this.y == other.y && this.z == other.z; + } } } |