diff options
| author | 2016-02-26 22:37:32 +0000 | |
|---|---|---|
| committer | 2016-02-26 22:37:34 +0000 | |
| commit | 768d81374ba50d215064ca11ed3ca34cf46d087c (patch) | |
| tree | 0b219f8675e64bdd8fdf81c2cb01de3cab7983fe | |
| parent | 203b353018e1533251528b087345cc9933aa38fe (diff) | |
| parent | 8ab728093eed85c176822d58a0d2ba1f4ebbb362 (diff) | |
Merge "Audio record notification: report audio device information" into nyc-dev
| -rw-r--r-- | core/jni/android_media_AudioSystem.cpp | 12 | ||||
| -rw-r--r-- | media/java/android/media/AudioFormat.java | 20 | ||||
| -rw-r--r-- | media/java/android/media/AudioPatch.java | 7 | ||||
| -rw-r--r-- | media/java/android/media/AudioRecordConfiguration.java | 70 | ||||
| -rw-r--r-- | media/java/android/media/AudioSystem.java | 10 | ||||
| -rw-r--r-- | services/core/java/com/android/server/audio/RecordingActivityMonitor.java | 41 |
6 files changed, 114 insertions, 46 deletions
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp index 7d9e4a284cec..2fb749866f62 100644 --- a/core/jni/android_media_AudioSystem.cpp +++ b/core/jni/android_media_AudioSystem.cpp @@ -389,7 +389,8 @@ android_media_AudioSystem_dyn_policy_callback(int event, String8 regId, int val) static void android_media_AudioSystem_recording_callback(int event, int session, int source, - const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig) + const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig, + audio_patch_handle_t patchHandle) { JNIEnv *env = AndroidRuntime::getJNIEnv(); if (env == NULL) { @@ -401,12 +402,14 @@ android_media_AudioSystem_recording_callback(int event, int session, int source, } // create an array for 2*3 integers to store the record configurations (client + device) - jintArray recParamArray = env->NewIntArray(6); + // plus 1 integer for the patch handle + const int REC_PARAM_SIZE = 7; + jintArray recParamArray = env->NewIntArray(REC_PARAM_SIZE); if (recParamArray == NULL) { ALOGE("recording callback: Couldn't allocate int array for configuration data"); return; } - jint recParamData[6]; + jint recParamData[REC_PARAM_SIZE]; recParamData[0] = (jint) audioFormatFromNative(clientConfig->format); // FIXME this doesn't support index-based masks recParamData[1] = (jint) inChannelMaskFromNative(clientConfig->channel_mask); @@ -415,7 +418,8 @@ android_media_AudioSystem_recording_callback(int event, int session, int source, // FIXME this doesn't support index-based masks recParamData[4] = (jint) inChannelMaskFromNative(deviceConfig->channel_mask); recParamData[5] = (jint) deviceConfig->sample_rate; - env->SetIntArrayRegion(recParamArray, 0, 6, recParamData); + recParamData[6] = (jint) patchHandle; + env->SetIntArrayRegion(recParamArray, 0, REC_PARAM_SIZE, recParamData); // callback into java jclass clazz = env->FindClass(kClassPathName); diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java index a0dfaa0f6fc6..b0411a2b63f5 100644 --- a/media/java/android/media/AudioFormat.java +++ b/media/java/android/media/AudioFormat.java @@ -898,6 +898,26 @@ public class AudioFormat implements Parcelable { } @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + AudioFormat that = (AudioFormat) o; + + if (mPropertySetMask != that.mPropertySetMask) return false; + + // return false if any of the properties is set and the values differ + return !((((mPropertySetMask & AUDIO_FORMAT_HAS_PROPERTY_ENCODING) != 0) + && (mEncoding != that.mEncoding)) + || (((mPropertySetMask & AUDIO_FORMAT_HAS_PROPERTY_SAMPLE_RATE) != 0) + && (mSampleRate != that.mSampleRate)) + || (((mPropertySetMask & AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_MASK) != 0) + && (mChannelMask != that.mChannelMask)) + || (((mPropertySetMask & AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_INDEX_MASK) != 0) + && (mChannelIndexMask != that.mChannelIndexMask))); + } + + @Override public int hashCode() { return Objects.hash(mPropertySetMask, mSampleRate, mEncoding, mChannelMask, mChannelIndexMask); diff --git a/media/java/android/media/AudioPatch.java b/media/java/android/media/AudioPatch.java index acadb413e429..6c70213ad83a 100644 --- a/media/java/android/media/AudioPatch.java +++ b/media/java/android/media/AudioPatch.java @@ -53,6 +53,13 @@ public class AudioPatch { return mSinks; } + /** + * Get the system unique patch ID. + */ + public int id() { + return mHandle.id(); + } + @Override public String toString() { StringBuilder s = new StringBuilder(); diff --git a/media/java/android/media/AudioRecordConfiguration.java b/media/java/android/media/AudioRecordConfiguration.java index 61d239c0e70b..c2cd9b3d0637 100644 --- a/media/java/android/media/AudioRecordConfiguration.java +++ b/media/java/android/media/AudioRecordConfiguration.java @@ -18,7 +18,9 @@ package android.media; import android.os.Parcel; import android.os.Parcelable; +import android.util.Log; +import java.util.ArrayList; import java.util.Objects; /** @@ -28,6 +30,7 @@ import java.util.Objects; * */ public class AudioRecordConfiguration implements Parcelable { + private final static String TAG = new String("AudioRecordConfiguration"); private final int mSessionId; @@ -36,30 +39,18 @@ public class AudioRecordConfiguration implements Parcelable { private final AudioFormat mDeviceFormat; private final AudioFormat mClientFormat; - private final AudioDeviceInfo mRecDevice; - - /** - * @hide - */ - public AudioRecordConfiguration(int session, int source, - AudioFormat clientFormat, AudioFormat deviceFormat) { - mSessionId = session; - mClientSource = source; - mDeviceFormat = deviceFormat; - mClientFormat = clientFormat; - mRecDevice = null; - } + private final int mPatchHandle; /** * @hide */ public AudioRecordConfiguration(int session, int source, AudioFormat devFormat, - AudioFormat clientFormat, AudioDeviceInfo device) { + AudioFormat clientFormat, int patchHandle) { mSessionId = session; mClientSource = source; mDeviceFormat = devFormat; mClientFormat = clientFormat; - mRecDevice = device; + mPatchHandle = patchHandle; } /** @@ -96,10 +87,38 @@ public class AudioRecordConfiguration implements Parcelable { public AudioFormat getClientFormat() { return mClientFormat; } /** - * Returns the audio input device used for this recording. - * @return the audio recording device + * Returns information about the audio input device used for this recording. + * @return the audio recording device or null if this information cannot be retrieved */ - public AudioDeviceInfo getAudioDevice() { return mRecDevice; } + public AudioDeviceInfo getAudioDevice() { + // build the AudioDeviceInfo from the patch handle + ArrayList<AudioPatch> patches = new ArrayList<AudioPatch>(); + if (AudioManager.listAudioPatches(patches) != AudioManager.SUCCESS) { + Log.e(TAG, "Error retrieving list of audio patches"); + return null; + } + for (int i = 0 ; i < patches.size() ; i++) { + final AudioPatch patch = patches.get(i); + if (patch.id() == mPatchHandle) { + final AudioPortConfig[] sources = patch.sources(); + if ((sources != null) && (sources.length > 0)) { + // not supporting multiple sources, so just look at the first source + final int devId = sources[0].port().id(); + final AudioDeviceInfo[] devices = + AudioManager.getDevicesStatic(AudioManager.GET_DEVICES_INPUTS); + for (int j = 0; j < devices.length; j++) { + if (devices[j].getId() == devId) { + return devices[j]; + } + } + } + // patch handle is unique, there won't be another with the same handle + break; + } + } + Log.e(TAG, "Couldn't find device for recording, did recording end already?"); + return null; + } public static final Parcelable.Creator<AudioRecordConfiguration> CREATOR = new Parcelable.Creator<AudioRecordConfiguration>() { @@ -132,7 +151,7 @@ public class AudioRecordConfiguration implements Parcelable { dest.writeInt(mClientSource); mClientFormat.writeToParcel(dest, 0); mDeviceFormat.writeToParcel(dest, 0); - //TODO marshall device info + dest.writeInt(mPatchHandle); } private AudioRecordConfiguration(Parcel in) { @@ -140,8 +159,7 @@ public class AudioRecordConfiguration implements Parcelable { mClientSource = in.readInt(); mClientFormat = AudioFormat.CREATOR.createFromParcel(in); mDeviceFormat = AudioFormat.CREATOR.createFromParcel(in); - //TODO unmarshall device info - mRecDevice = null; + mPatchHandle = in.readInt(); } @Override @@ -149,8 +167,12 @@ public class AudioRecordConfiguration implements Parcelable { if (this == o) return true; if (o == null || !(o instanceof AudioRecordConfiguration)) return false; - final AudioRecordConfiguration that = (AudioRecordConfiguration) o; - return ((mSessionId == that.mSessionId) - && (mClientSource == that.mClientSource)); + AudioRecordConfiguration that = (AudioRecordConfiguration) o; + + return ((mSessionId == that.mSessionId) + && (mClientSource == that.mClientSource) + && (mPatchHandle == that.mPatchHandle) + && (mClientFormat.equals(that.mClientFormat)) + && (mDeviceFormat.equals(that.mDeviceFormat))); } }
\ No newline at end of file diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java index 59782cb99a46..247c4aea9106 100644 --- a/media/java/android/media/AudioSystem.java +++ b/media/java/android/media/AudioSystem.java @@ -279,8 +279,14 @@ public class AudioSystem * @param session * @param source * @param recordingFormat an array of ints containing respectively the client and device - * recording configuration. Each set of parameters contains the following parameters - * in this order: format, channel mask, sample rate + * recording configurations (2*3 ints), followed by the patch handle: + * index 0: client format + * 1: client channel mask + * 2: client sample rate + * 3: device format + * 4: device channel mask + * 5: device sample rate + * 6: patch handle */ void onRecordingConfigurationChanged(int event, int session, int source, int[] recordingFormat); diff --git a/services/core/java/com/android/server/audio/RecordingActivityMonitor.java b/services/core/java/com/android/server/audio/RecordingActivityMonitor.java index 4b0a14241d6b..7e76ac46a545 100644 --- a/services/core/java/com/android/server/audio/RecordingActivityMonitor.java +++ b/services/core/java/com/android/server/audio/RecordingActivityMonitor.java @@ -50,11 +50,11 @@ public final class RecordingActivityMonitor implements AudioSystem.AudioRecordin * Implementation of android.media.AudioSystem.AudioRecordingCallback */ public void onRecordingConfigurationChanged(int event, int session, int source, - int[] recordingFormat) { + int[] recordingInfo) { if (MediaRecorder.isSystemOnlyAudioSource(source)) { return; } - if (updateSnapshot(event, session, source, recordingFormat)) { + if (updateSnapshot(event, session, source, recordingInfo)) { final Iterator<RecMonitorClient> clientIterator = mClients.iterator(); synchronized(mClients) { while (clientIterator.hasNext()) { @@ -117,7 +117,7 @@ public final class RecordingActivityMonitor implements AudioSystem.AudioRecordin * for the definition of the contents of the array * @return true if the list of active recording sessions has been modified, false otherwise. */ - private boolean updateSnapshot(int event, int session, int source, int[] recordingFormat) { + private boolean updateSnapshot(int event, int session, int source, int[] recordingInfo) { synchronized(mRecordConfigs) { switch (event) { case AudioManager.RECORD_CONFIG_EVENT_STOP: @@ -125,26 +125,35 @@ public final class RecordingActivityMonitor implements AudioSystem.AudioRecordin return (mRecordConfigs.remove(new Integer(session)) != null); case AudioManager.RECORD_CONFIG_EVENT_START: final AudioFormat clientFormat = new AudioFormat.Builder() - .setEncoding(recordingFormat[0]) + .setEncoding(recordingInfo[0]) // FIXME this doesn't support index-based masks - .setChannelMask(recordingFormat[1]) - .setSampleRate(recordingFormat[2]) + .setChannelMask(recordingInfo[1]) + .setSampleRate(recordingInfo[2]) .build(); final AudioFormat deviceFormat = new AudioFormat.Builder() - .setEncoding(recordingFormat[3]) + .setEncoding(recordingInfo[3]) // FIXME this doesn't support index-based masks - .setChannelMask(recordingFormat[4]) - .setSampleRate(recordingFormat[5]) + .setChannelMask(recordingInfo[4]) + .setSampleRate(recordingInfo[5]) .build(); - if (mRecordConfigs.containsKey(new Integer(session))) { - // start of session that's already tracked, not worth an update - // TO DO in the future when tracking record format: there might be a record - // format change during a recording that requires reporting - return false; + final int patchHandle = recordingInfo[6]; + final Integer sessionKey = new Integer(session); + if (mRecordConfigs.containsKey(sessionKey)) { + final AudioRecordConfiguration updatedConfig = + new AudioRecordConfiguration(session, source, + clientFormat, deviceFormat, patchHandle); + if (updatedConfig.equals(mRecordConfigs.get(sessionKey))) { + return false; + } else { + // config exists but has been modified + mRecordConfigs.remove(sessionKey); + mRecordConfigs.put(sessionKey, updatedConfig); + return true; + } } else { - mRecordConfigs.put(new Integer(session), + mRecordConfigs.put(sessionKey, new AudioRecordConfiguration(session, source, - clientFormat, deviceFormat)); + clientFormat, deviceFormat, patchHandle)); return true; } default: |