Merge "Audio record notification: report client/device configuration" into nyc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
16ad43c000
@@ -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
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -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()) {
|
||||
@@ -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
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user