API changes for audio recording notifications
Make AudioRecordConfiguration final since it is parcelable.
In AudioRecordingCallback, pass the array of active recording
configurations.
Add @IntDef for return values for
AudioRecordConfiguration.getClientAudioSource()
Bug 27385560
Change-Id: I01193577f50e50496742d888b45f89a2c3b67904
diff --git a/api/current.txt b/api/current.txt
index f7a316d..d025672 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -19934,7 +19934,7 @@
public static abstract class AudioManager.AudioRecordingCallback {
ctor public AudioManager.AudioRecordingCallback();
- method public void onRecordConfigChanged();
+ method public void onRecordConfigChanged(android.media.AudioRecordConfiguration[]);
}
public static abstract interface AudioManager.OnAudioFocusChangeListener {
@@ -20008,7 +20008,7 @@
method public abstract void onRoutingChanged(android.media.AudioRecord);
}
- public class AudioRecordConfiguration implements android.os.Parcelable {
+ public final class AudioRecordConfiguration implements android.os.Parcelable {
method public int describeContents();
method public android.media.AudioDeviceInfo getAudioDevice();
method public int getClientAudioSessionId();
diff --git a/api/system-current.txt b/api/system-current.txt
index b2b5982..6e217da5 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -21439,7 +21439,7 @@
public static abstract class AudioManager.AudioRecordingCallback {
ctor public AudioManager.AudioRecordingCallback();
- method public void onRecordConfigChanged();
+ method public void onRecordConfigChanged(android.media.AudioRecordConfiguration[]);
}
public static abstract interface AudioManager.OnAudioFocusChangeListener {
@@ -21516,7 +21516,7 @@
method public abstract void onRoutingChanged(android.media.AudioRecord);
}
- public class AudioRecordConfiguration implements android.os.Parcelable {
+ public final class AudioRecordConfiguration implements android.os.Parcelable {
method public int describeContents();
method public android.media.AudioDeviceInfo getAudioDevice();
method public int getClientAudioSessionId();
diff --git a/api/test-current.txt b/api/test-current.txt
index 472daf6..9d3f97d 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -19943,7 +19943,7 @@
public static abstract class AudioManager.AudioRecordingCallback {
ctor public AudioManager.AudioRecordingCallback();
- method public void onRecordConfigChanged();
+ method public void onRecordConfigChanged(android.media.AudioRecordConfiguration[]);
}
public static abstract interface AudioManager.OnAudioFocusChangeListener {
@@ -20017,7 +20017,7 @@
method public abstract void onRoutingChanged(android.media.AudioRecord);
}
- public class AudioRecordConfiguration implements android.os.Parcelable {
+ public final class AudioRecordConfiguration implements android.os.Parcelable {
method public int describeContents();
method public android.media.AudioDeviceInfo getAudioDevice();
method public int getClientAudioSessionId();
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index c7e96cf..8206d23 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -2147,9 +2147,10 @@
}
break;
case MSSG_RECORDING_CONFIG_CHANGE:
- final AudioRecordingCallback cb = (AudioRecordingCallback) msg.obj;
- if (cb != null) {
- cb.onRecordConfigChanged();
+ final RecordConfigChangeCallbackData cbData =
+ (RecordConfigChangeCallbackData) msg.obj;
+ if (cbData.mCb != null) {
+ cbData.mCb.onRecordConfigChanged(cbData.mConfigs);
}
break;
default:
@@ -2734,8 +2735,10 @@
public static abstract class AudioRecordingCallback {
/**
* Called whenever the device recording configuration has changed.
+ * @param configs array containing the results of
+ * {@link AudioManager#getActiveRecordConfigurations()}.
*/
- public void onRecordConfigChanged() {}
+ public void onRecordConfigChanged(AudioRecordConfiguration[] configs) {}
}
private static class AudioRecordingCallbackInfo {
@@ -2747,6 +2750,17 @@
}
}
+ private final static class RecordConfigChangeCallbackData {
+ final AudioRecordingCallback mCb;
+ final AudioRecordConfiguration[] mConfigs;
+
+ RecordConfigChangeCallbackData(AudioRecordingCallback cb,
+ AudioRecordConfiguration[] configs) {
+ mCb = cb;
+ mConfigs = configs;
+ }
+ }
+
/**
* Register a callback to be notified of audio recording changes through
* {@link AudioRecordingCallback}
@@ -2882,14 +2896,15 @@
private final IRecordingConfigDispatcher mRecCb = new IRecordingConfigDispatcher.Stub() {
- public void dispatchRecordingConfigChange() {
+ public void dispatchRecordingConfigChange(AudioRecordConfiguration[] configs) {
synchronized(mRecordCallbackLock) {
if (mRecordCallbackList != null) {
for (int i=0 ; i < mRecordCallbackList.size() ; i++) {
final AudioRecordingCallbackInfo arci = mRecordCallbackList.get(i);
if (arci.mHandler != null) {
final Message m = arci.mHandler.obtainMessage(
- MSSG_RECORDING_CONFIG_CHANGE/*what*/, arci.mCb/*obj*/);
+ MSSG_RECORDING_CONFIG_CHANGE/*what*/,
+ new RecordConfigChangeCallbackData(arci.mCb, configs)/*obj*/);
arci.mHandler.sendMessage(m);
}
}
diff --git a/media/java/android/media/AudioRecordConfiguration.java b/media/java/android/media/AudioRecordConfiguration.java
index c2cd9b3..de78a5a 100644
--- a/media/java/android/media/AudioRecordConfiguration.java
+++ b/media/java/android/media/AudioRecordConfiguration.java
@@ -16,10 +16,13 @@
package android.media;
+import android.annotation.IntDef;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Objects;
@@ -29,7 +32,7 @@
* {@link AudioManager#getActiveRecordConfigurations()} method.
*
*/
-public class AudioRecordConfiguration implements Parcelable {
+public final class AudioRecordConfiguration implements Parcelable {
private final static String TAG = new String("AudioRecordConfiguration");
private final int mSessionId;
@@ -53,6 +56,19 @@
mPatchHandle = patchHandle;
}
+ /** @hide */
+ @IntDef({
+ MediaRecorder.AudioSource.DEFAULT,
+ MediaRecorder.AudioSource.VOICE_UPLINK,
+ MediaRecorder.AudioSource.VOICE_DOWNLINK,
+ MediaRecorder.AudioSource.VOICE_CALL,
+ MediaRecorder.AudioSource.CAMCORDER,
+ MediaRecorder.AudioSource.VOICE_RECOGNITION,
+ MediaRecorder.AudioSource.VOICE_COMMUNICATION
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface AudioSource {}
+
/**
* Returns the audio source being used for the recording.
* @return one of {@link MediaRecorder.AudioSource#MIC},
@@ -63,7 +79,7 @@
* {@link MediaRecorder.AudioSource#VOICE_RECOGNITION},
* {@link MediaRecorder.AudioSource#VOICE_COMMUNICATION}.
*/
- public int getClientAudioSource() { return mClientSource; }
+ public @AudioSource int getClientAudioSource() { return mClientSource; }
/**
* Returns the session number of the recording, see {@link AudioRecord#getAudioSessionId()}.
diff --git a/media/java/android/media/IRecordingConfigDispatcher.aidl b/media/java/android/media/IRecordingConfigDispatcher.aidl
index a5eb8b9f..eaa92ca 100644
--- a/media/java/android/media/IRecordingConfigDispatcher.aidl
+++ b/media/java/android/media/IRecordingConfigDispatcher.aidl
@@ -16,6 +16,8 @@
package android.media;
+import android.media.AudioRecordConfiguration;
+
/**
* AIDL for the RecordingActivity monitor in AudioService to signal audio recording updates.
*
@@ -23,6 +25,6 @@
*/
oneway interface IRecordingConfigDispatcher {
- void dispatchRecordingConfigChange();
+ void dispatchRecordingConfigChange(in AudioRecordConfiguration[] configs);
}
diff --git a/services/core/java/com/android/server/audio/RecordingActivityMonitor.java b/services/core/java/com/android/server/audio/RecordingActivityMonitor.java
index 7e76ac4..86dcd0f 100644
--- a/services/core/java/com/android/server/audio/RecordingActivityMonitor.java
+++ b/services/core/java/com/android/server/audio/RecordingActivityMonitor.java
@@ -54,12 +54,15 @@
if (MediaRecorder.isSystemOnlyAudioSource(source)) {
return;
}
- if (updateSnapshot(event, session, source, recordingInfo)) {
- final Iterator<RecMonitorClient> clientIterator = mClients.iterator();
+ final AudioRecordConfiguration[] configs =
+ updateSnapshot(event, session, source, recordingInfo);
+ if (configs != null){
synchronized(mClients) {
+ final Iterator<RecMonitorClient> clientIterator = mClients.iterator();
while (clientIterator.hasNext()) {
try {
- clientIterator.next().mDispatcherCb.dispatchRecordingConfigChange();
+ clientIterator.next().mDispatcherCb.dispatchRecordingConfigChange(
+ configs);
} catch (RemoteException e) {
Log.w(TAG, "Could not call dispatchRecordingConfigChange() on client", e);
}
@@ -115,14 +118,19 @@
* @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.
+ * @return null if the list of active recording sessions has not been modified, an array
+ * with the current active configurations otherwise.
*/
- private boolean updateSnapshot(int event, int session, int source, int[] recordingInfo) {
+ private AudioRecordConfiguration[] updateSnapshot(int event, int session, int source,
+ int[] recordingInfo) {
+ final boolean configChanged;
+ final AudioRecordConfiguration[] configs;
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);
+ configChanged = (mRecordConfigs.remove(new Integer(session)) != null);
+ break;
case AudioManager.RECORD_CONFIG_EVENT_START:
final AudioFormat clientFormat = new AudioFormat.Builder()
.setEncoding(recordingInfo[0])
@@ -143,25 +151,32 @@
new AudioRecordConfiguration(session, source,
clientFormat, deviceFormat, patchHandle);
if (updatedConfig.equals(mRecordConfigs.get(sessionKey))) {
- return false;
+ configChanged = false;
} else {
// config exists but has been modified
mRecordConfigs.remove(sessionKey);
mRecordConfigs.put(sessionKey, updatedConfig);
- return true;
+ configChanged = true;
}
} else {
mRecordConfigs.put(sessionKey,
new AudioRecordConfiguration(session, source,
clientFormat, deviceFormat, patchHandle));
- return true;
+ configChanged = true;
}
+ break;
default:
Log.e(TAG, String.format("Unknown event %d for session %d, source %d",
event, session, source));
- return false;
+ configChanged = false;
+ }
+ if (configChanged) {
+ configs = mRecordConfigs.values().toArray(new AudioRecordConfiguration[0]);
+ } else {
+ configs = null;
}
}
+ return configs;
}
/**