Loading core/jni/android_media_AudioSystem.cpp +28 −3 Original line number Diff line number Diff line Loading @@ -388,18 +388,43 @@ 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) android_media_AudioSystem_recording_callback(int event, int session, int source, const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig) { JNIEnv *env = AndroidRuntime::getJNIEnv(); if (env == NULL) { return; } if (clientConfig == NULL || deviceConfig == NULL) { ALOGE("Unexpected null client/device configurations in recording callback"); return; } // create an array for 2*3 integers to store the record configurations (client + device) jintArray recParamArray = env->NewIntArray(6); if (recParamArray == NULL) { ALOGE("recording callback: Couldn't allocate int array for configuration data"); return; } jint recParamData[6]; recParamData[0] = (jint) audioFormatFromNative(clientConfig->format); // FIXME this doesn't support index-based masks recParamData[1] = (jint) inChannelMaskFromNative(clientConfig->channel_mask); recParamData[2] = (jint) clientConfig->sample_rate; recParamData[3] = (jint) audioFormatFromNative(deviceConfig->format); // 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); // callback into java jclass clazz = env->FindClass(kClassPathName); env->CallStaticVoidMethod(clazz, gAudioPolicyEventHandlerMethods.postRecordConfigEventFromNative, event, session, source); event, session, source, recParamArray); env->DeleteLocalRef(clazz); env->DeleteLocalRef(recParamArray); } static jint Loading Loading @@ -1819,7 +1844,7 @@ int register_android_media_AudioSystem(JNIEnv *env) "dynamicPolicyCallbackFromNative", "(ILjava/lang/String;I)V"); gAudioPolicyEventHandlerMethods.postRecordConfigEventFromNative = GetStaticMethodIDOrDie(env, env->FindClass(kClassPathName), "recordingCallbackFromNative", "(III)V"); "recordingCallbackFromNative", "(III[I)V"); jclass audioMixClass = FindClassOrDie(env, "android/media/audiopolicy/AudioMix"); gAudioMixClass = MakeGlobalRefOrDie(env, audioMixClass); Loading media/java/android/media/AudioRecordConfiguration.java +10 −5 Original line number Diff line number Diff line Loading @@ -41,11 +41,12 @@ public class AudioRecordConfiguration implements Parcelable { /** * @hide */ public AudioRecordConfiguration(int session, int source) { public AudioRecordConfiguration(int session, int source, AudioFormat clientFormat, AudioFormat deviceFormat) { mSessionId = session; mClientSource = source; mDeviceFormat = new AudioFormat.Builder().build(); mClientFormat = new AudioFormat.Builder().build(); mDeviceFormat = deviceFormat; mClientFormat = clientFormat; mRecDevice = null; } Loading Loading @@ -129,13 +130,17 @@ public class AudioRecordConfiguration implements Parcelable { public void writeToParcel(Parcel dest, int flags) { dest.writeInt(mSessionId); dest.writeInt(mClientSource); mClientFormat.writeToParcel(dest, 0); mDeviceFormat.writeToParcel(dest, 0); //TODO marshall device info } private AudioRecordConfiguration(Parcel in) { mSessionId = in.readInt(); mClientSource = in.readInt(); mDeviceFormat = new AudioFormat.Builder().build(); mClientFormat = new AudioFormat.Builder().build(); mClientFormat = AudioFormat.CREATOR.createFromParcel(in); mDeviceFormat = AudioFormat.CREATOR.createFromParcel(in); //TODO unmarshall device info mRecDevice = null; } Loading media/java/android/media/AudioSystem.java +23 −3 Original line number Diff line number Diff line Loading @@ -273,7 +273,17 @@ public class AudioSystem */ public interface AudioRecordingCallback { void onRecordingConfigurationChanged(int event, int session, int source); /** * Callback for recording activity notifications events * @param event * @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 */ void onRecordingConfigurationChanged(int event, int session, int source, int[] recordingFormat); } private static AudioRecordingCallback sRecordingCallback; Loading @@ -285,13 +295,23 @@ public class AudioSystem } } private static void recordingCallbackFromNative(int event, int session, int source) { /** * Callback from native for recording configuration updates. * @param event * @param session * @param source * @param recordingFormat see * {@link AudioRecordingCallback#onRecordingConfigurationChanged(int, int, int, int[])} for * the description of the record format. */ private static void recordingCallbackFromNative(int event, int session, int source, int[] recordingFormat) { AudioRecordingCallback cb = null; synchronized (AudioSystem.class) { cb = sRecordingCallback; } if (cb != null) { cb.onRecordingConfigurationChanged(event, session, source); cb.onRecordingConfigurationChanged(event, session, source, recordingFormat); } } Loading services/core/java/com/android/server/audio/RecordingActivityMonitor.java +22 −4 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.audio; import android.media.AudioFormat; import android.media.AudioManager; import android.media.AudioRecordConfiguration; import android.media.AudioSystem; Loading Loading @@ -48,11 +49,12 @@ public final class RecordingActivityMonitor implements AudioSystem.AudioRecordin /** * Implementation of android.media.AudioSystem.AudioRecordingCallback */ public void onRecordingConfigurationChanged(int event, int session, int source) { public void onRecordingConfigurationChanged(int event, int session, int source, int[] recordingFormat) { if (MediaRecorder.isSystemOnlyAudioSource(source)) { return; } if (updateSnapshot(event, session, source)) { if (updateSnapshot(event, session, source, recordingFormat)) { final Iterator<RecMonitorClient> clientIterator = mClients.iterator(); synchronized(mClients) { while (clientIterator.hasNext()) { Loading Loading @@ -110,15 +112,30 @@ public final class RecordingActivityMonitor implements AudioSystem.AudioRecordin * @param event * @param session * @param source * @param recordingFormat see * {@link AudioSystem.AudioRecordingCallback#onRecordingConfigurationChanged(int, int, int, int[])} * 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) { private boolean updateSnapshot(int event, int session, int source, int[] recordingFormat) { synchronized(mRecordConfigs) { switch (event) { case AudioManager.RECORD_CONFIG_EVENT_STOP: // return failure if an unknown recording session stopped return (mRecordConfigs.remove(new Integer(session)) != null); case AudioManager.RECORD_CONFIG_EVENT_START: final AudioFormat clientFormat = new AudioFormat.Builder() .setEncoding(recordingFormat[0]) // FIXME this doesn't support index-based masks .setChannelMask(recordingFormat[1]) .setSampleRate(recordingFormat[2]) .build(); final AudioFormat deviceFormat = new AudioFormat.Builder() .setEncoding(recordingFormat[3]) // FIXME this doesn't support index-based masks .setChannelMask(recordingFormat[4]) .setSampleRate(recordingFormat[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 Loading @@ -126,7 +143,8 @@ public final class RecordingActivityMonitor implements AudioSystem.AudioRecordin return false; } else { mRecordConfigs.put(new Integer(session), new AudioRecordConfiguration(session, source)); new AudioRecordConfiguration(session, source, clientFormat, deviceFormat)); return true; } default: Loading Loading
core/jni/android_media_AudioSystem.cpp +28 −3 Original line number Diff line number Diff line Loading @@ -388,18 +388,43 @@ 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) android_media_AudioSystem_recording_callback(int event, int session, int source, const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig) { JNIEnv *env = AndroidRuntime::getJNIEnv(); if (env == NULL) { return; } if (clientConfig == NULL || deviceConfig == NULL) { ALOGE("Unexpected null client/device configurations in recording callback"); return; } // create an array for 2*3 integers to store the record configurations (client + device) jintArray recParamArray = env->NewIntArray(6); if (recParamArray == NULL) { ALOGE("recording callback: Couldn't allocate int array for configuration data"); return; } jint recParamData[6]; recParamData[0] = (jint) audioFormatFromNative(clientConfig->format); // FIXME this doesn't support index-based masks recParamData[1] = (jint) inChannelMaskFromNative(clientConfig->channel_mask); recParamData[2] = (jint) clientConfig->sample_rate; recParamData[3] = (jint) audioFormatFromNative(deviceConfig->format); // 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); // callback into java jclass clazz = env->FindClass(kClassPathName); env->CallStaticVoidMethod(clazz, gAudioPolicyEventHandlerMethods.postRecordConfigEventFromNative, event, session, source); event, session, source, recParamArray); env->DeleteLocalRef(clazz); env->DeleteLocalRef(recParamArray); } static jint Loading Loading @@ -1819,7 +1844,7 @@ int register_android_media_AudioSystem(JNIEnv *env) "dynamicPolicyCallbackFromNative", "(ILjava/lang/String;I)V"); gAudioPolicyEventHandlerMethods.postRecordConfigEventFromNative = GetStaticMethodIDOrDie(env, env->FindClass(kClassPathName), "recordingCallbackFromNative", "(III)V"); "recordingCallbackFromNative", "(III[I)V"); jclass audioMixClass = FindClassOrDie(env, "android/media/audiopolicy/AudioMix"); gAudioMixClass = MakeGlobalRefOrDie(env, audioMixClass); Loading
media/java/android/media/AudioRecordConfiguration.java +10 −5 Original line number Diff line number Diff line Loading @@ -41,11 +41,12 @@ public class AudioRecordConfiguration implements Parcelable { /** * @hide */ public AudioRecordConfiguration(int session, int source) { public AudioRecordConfiguration(int session, int source, AudioFormat clientFormat, AudioFormat deviceFormat) { mSessionId = session; mClientSource = source; mDeviceFormat = new AudioFormat.Builder().build(); mClientFormat = new AudioFormat.Builder().build(); mDeviceFormat = deviceFormat; mClientFormat = clientFormat; mRecDevice = null; } Loading Loading @@ -129,13 +130,17 @@ public class AudioRecordConfiguration implements Parcelable { public void writeToParcel(Parcel dest, int flags) { dest.writeInt(mSessionId); dest.writeInt(mClientSource); mClientFormat.writeToParcel(dest, 0); mDeviceFormat.writeToParcel(dest, 0); //TODO marshall device info } private AudioRecordConfiguration(Parcel in) { mSessionId = in.readInt(); mClientSource = in.readInt(); mDeviceFormat = new AudioFormat.Builder().build(); mClientFormat = new AudioFormat.Builder().build(); mClientFormat = AudioFormat.CREATOR.createFromParcel(in); mDeviceFormat = AudioFormat.CREATOR.createFromParcel(in); //TODO unmarshall device info mRecDevice = null; } Loading
media/java/android/media/AudioSystem.java +23 −3 Original line number Diff line number Diff line Loading @@ -273,7 +273,17 @@ public class AudioSystem */ public interface AudioRecordingCallback { void onRecordingConfigurationChanged(int event, int session, int source); /** * Callback for recording activity notifications events * @param event * @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 */ void onRecordingConfigurationChanged(int event, int session, int source, int[] recordingFormat); } private static AudioRecordingCallback sRecordingCallback; Loading @@ -285,13 +295,23 @@ public class AudioSystem } } private static void recordingCallbackFromNative(int event, int session, int source) { /** * Callback from native for recording configuration updates. * @param event * @param session * @param source * @param recordingFormat see * {@link AudioRecordingCallback#onRecordingConfigurationChanged(int, int, int, int[])} for * the description of the record format. */ private static void recordingCallbackFromNative(int event, int session, int source, int[] recordingFormat) { AudioRecordingCallback cb = null; synchronized (AudioSystem.class) { cb = sRecordingCallback; } if (cb != null) { cb.onRecordingConfigurationChanged(event, session, source); cb.onRecordingConfigurationChanged(event, session, source, recordingFormat); } } Loading
services/core/java/com/android/server/audio/RecordingActivityMonitor.java +22 −4 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.audio; import android.media.AudioFormat; import android.media.AudioManager; import android.media.AudioRecordConfiguration; import android.media.AudioSystem; Loading Loading @@ -48,11 +49,12 @@ public final class RecordingActivityMonitor implements AudioSystem.AudioRecordin /** * Implementation of android.media.AudioSystem.AudioRecordingCallback */ public void onRecordingConfigurationChanged(int event, int session, int source) { public void onRecordingConfigurationChanged(int event, int session, int source, int[] recordingFormat) { if (MediaRecorder.isSystemOnlyAudioSource(source)) { return; } if (updateSnapshot(event, session, source)) { if (updateSnapshot(event, session, source, recordingFormat)) { final Iterator<RecMonitorClient> clientIterator = mClients.iterator(); synchronized(mClients) { while (clientIterator.hasNext()) { Loading Loading @@ -110,15 +112,30 @@ public final class RecordingActivityMonitor implements AudioSystem.AudioRecordin * @param event * @param session * @param source * @param recordingFormat see * {@link AudioSystem.AudioRecordingCallback#onRecordingConfigurationChanged(int, int, int, int[])} * 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) { private boolean updateSnapshot(int event, int session, int source, int[] recordingFormat) { synchronized(mRecordConfigs) { switch (event) { case AudioManager.RECORD_CONFIG_EVENT_STOP: // return failure if an unknown recording session stopped return (mRecordConfigs.remove(new Integer(session)) != null); case AudioManager.RECORD_CONFIG_EVENT_START: final AudioFormat clientFormat = new AudioFormat.Builder() .setEncoding(recordingFormat[0]) // FIXME this doesn't support index-based masks .setChannelMask(recordingFormat[1]) .setSampleRate(recordingFormat[2]) .build(); final AudioFormat deviceFormat = new AudioFormat.Builder() .setEncoding(recordingFormat[3]) // FIXME this doesn't support index-based masks .setChannelMask(recordingFormat[4]) .setSampleRate(recordingFormat[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 Loading @@ -126,7 +143,8 @@ public final class RecordingActivityMonitor implements AudioSystem.AudioRecordin return false; } else { mRecordConfigs.put(new Integer(session), new AudioRecordConfiguration(session, source)); new AudioRecordConfiguration(session, source, clientFormat, deviceFormat)); return true; } default: Loading