diff options
author | Eric Laurent <elaurent@google.com> | 2015-05-06 17:51:52 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2015-05-06 17:51:53 +0000 |
commit | b65cd17b0508a5a7afdd92e69437825071a1631b (patch) | |
tree | c727a8fe013d5eb6135bd6e4f453e9ee262a35ad /media | |
parent | 6223ec129b256526d8c30920271b2ee3960bcf1f (diff) | |
parent | 4bcdba848449b33d7022de527c526943aff1f5fd (diff) | |
download | frameworks_base-b65cd17b0508a5a7afdd92e69437825071a1631b.zip frameworks_base-b65cd17b0508a5a7afdd92e69437825071a1631b.tar.gz frameworks_base-b65cd17b0508a5a7afdd92e69437825071a1631b.tar.bz2 |
Merge "Implement audio routing callbacks" into mnc-dev
Diffstat (limited to 'media')
-rw-r--r-- | media/java/android/media/AudioDevicePort.java | 10 | ||||
-rw-r--r-- | media/java/android/media/AudioDevicesManager.java | 17 | ||||
-rw-r--r-- | media/java/android/media/AudioManager.java | 12 | ||||
-rw-r--r-- | media/java/android/media/AudioMixPort.java | 19 | ||||
-rw-r--r-- | media/java/android/media/AudioPort.java | 8 | ||||
-rw-r--r-- | media/java/android/media/AudioRecord.java | 58 | ||||
-rw-r--r-- | media/java/android/media/AudioSystem.java | 6 | ||||
-rw-r--r-- | media/java/android/media/AudioTrack.java | 53 |
8 files changed, 146 insertions, 37 deletions
diff --git a/media/java/android/media/AudioDevicePort.java b/media/java/android/media/AudioDevicePort.java index 82da27d..c078260 100644 --- a/media/java/android/media/AudioDevicePort.java +++ b/media/java/android/media/AudioDevicePort.java @@ -83,6 +83,16 @@ public class AudioDevicePort extends AudioPort { if (o == null || !(o instanceof AudioDevicePort)) { return false; } + AudioDevicePort other = (AudioDevicePort)o; + if (mType != other.type()) { + return false; + } + if (mAddress == null && other.address() != null) { + return false; + } + if (!mAddress.equals(other.address())) { + return false; + } return super.equals(o); } diff --git a/media/java/android/media/AudioDevicesManager.java b/media/java/android/media/AudioDevicesManager.java index ca238d7..8b83c17 100644 --- a/media/java/android/media/AudioDevicesManager.java +++ b/media/java/android/media/AudioDevicesManager.java @@ -96,7 +96,7 @@ public class AudioDevicesManager { * @param flags A set of bitflags specifying the criteria to test. * @see {@link LIST_DEVICES_OUTPUTS} and {@link LIST_DEVICES_INPUTS} **/ - private boolean checkFlags(AudioDevicePort port, int flags) { + private static boolean checkFlags(AudioDevicePort port, int flags) { return port.role() == AudioPort.ROLE_SINK && (flags & LIST_DEVICES_OUTPUTS) != 0 || port.role() == AudioPort.ROLE_SOURCE && (flags & LIST_DEVICES_INPUTS) != 0; } @@ -110,8 +110,21 @@ public class AudioDevicesManager { * @return A (possibly zero-length) array of AudioDeviceInfo objects. */ public AudioDeviceInfo[] listDevices(int flags) { + return listDevicesStatic(flags); + } + + /** + * Generates a list of AudioDeviceInfo objects corresponding to the audio devices currently + * connected to the system and meeting the criteria specified in the <code>flags</code> + * parameter. + * @param flags A set of bitflags specifying the criteria to test. + * @see {@link LIST_DEVICES_OUTPUTS}, {@link LIST_DEVICES_INPUTS} and {@link LIST_DEVICES_ALL}. + * @return A (possibly zero-length) array of AudioDeviceInfo objects. + * @hide + */ + public static AudioDeviceInfo[] listDevicesStatic(int flags) { ArrayList<AudioDevicePort> ports = new ArrayList<AudioDevicePort>(); - int status = mAudioManager.listAudioDevicePorts(ports); + int status = AudioManager.listAudioDevicePorts(ports); if (status != AudioManager.SUCCESS) { // fail and bail! return new AudioDeviceInfo[0]; diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index 6eaf812..19900d0 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -3401,7 +3401,7 @@ public class AudioManager { * @param ports An AudioPort ArrayList where the list will be returned. * @hide */ - public int listAudioPorts(ArrayList<AudioPort> ports) { + public static int listAudioPorts(ArrayList<AudioPort> ports) { return updateAudioPortCache(ports, null); } @@ -3410,7 +3410,7 @@ public class AudioManager { * @see listAudioPorts(ArrayList<AudioPort>) * @hide */ - public int listAudioDevicePorts(ArrayList<AudioDevicePort> devices) { + public static int listAudioDevicePorts(ArrayList<AudioDevicePort> devices) { ArrayList<AudioPort> ports = new ArrayList<AudioPort>(); int status = updateAudioPortCache(ports, null); if (status == SUCCESS) { @@ -3447,7 +3447,7 @@ public class AudioManager { * patch[0] contains the newly created patch * @hide */ - public int createAudioPatch(AudioPatch[] patch, + public static int createAudioPatch(AudioPatch[] patch, AudioPortConfig[] sources, AudioPortConfig[] sinks) { return AudioSystem.createAudioPatch(patch, sources, sinks); @@ -3464,7 +3464,7 @@ public class AudioManager { * - {@link #ERROR} if patch cannot be released for any other reason. * @hide */ - public int releaseAudioPatch(AudioPatch patch) { + public static int releaseAudioPatch(AudioPatch patch) { return AudioSystem.releaseAudioPatch(patch); } @@ -3473,7 +3473,7 @@ public class AudioManager { * @param patches An AudioPatch array where the list will be returned. * @hide */ - public int listAudioPatches(ArrayList<AudioPatch> patches) { + public static int listAudioPatches(ArrayList<AudioPatch> patches) { return updateAudioPortCache(null, patches); } @@ -3482,7 +3482,7 @@ public class AudioManager { * AudioGain.buildConfig() * @hide */ - public int setAudioPortGain(AudioPort port, AudioGainConfig gain) { + public static int setAudioPortGain(AudioPort port, AudioGainConfig gain) { if (port == null || gain == null) { return ERROR_BAD_VALUE; } diff --git a/media/java/android/media/AudioMixPort.java b/media/java/android/media/AudioMixPort.java index 9fac8d1..ab55c8d 100644 --- a/media/java/android/media/AudioMixPort.java +++ b/media/java/android/media/AudioMixPort.java @@ -20,16 +20,21 @@ package android.media; * The AudioMixPort is a specialized type of AudioPort * describing an audio mix or stream at an input or output stream of the audio * framework. + * In addition to base audio port attributes, the mix descriptor contains: + * - the unique audio I/O handle assigned by AudioFlinger to this mix. * @see AudioPort * @hide */ public class AudioMixPort extends AudioPort { - AudioMixPort(AudioHandle handle, int role, String deviceName, + private final int mIoHandle; + + AudioMixPort(AudioHandle handle, int ioHandle, int role, String deviceName, int[] samplingRates, int[] channelMasks, int[] formats, AudioGain[] gains) { super(handle, role, deviceName, samplingRates, channelMasks, formats, gains); + mIoHandle = ioHandle; } /** @@ -41,11 +46,23 @@ public class AudioMixPort extends AudioPort { return new AudioMixPortConfig(this, samplingRate, channelMask, format, gain); } + /** + * Get the device type (e.g AudioManager.DEVICE_OUT_SPEAKER) + */ + public int ioHandle() { + return mIoHandle; + } + @Override public boolean equals(Object o) { if (o == null || !(o instanceof AudioMixPort)) { return false; } + AudioMixPort other = (AudioMixPort)o; + if (mIoHandle != other.ioHandle()) { + return false; + } + return super.equals(o); } diff --git a/media/java/android/media/AudioPort.java b/media/java/android/media/AudioPort.java index 88e784a..7328d7a 100644 --- a/media/java/android/media/AudioPort.java +++ b/media/java/android/media/AudioPort.java @@ -93,6 +93,14 @@ public class AudioPort { } /** + * Get the system unique device ID. + */ + public int id() { + return mHandle.id(); + } + + + /** * Get the audio port role */ public int role() { diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java index 472da02..11671d8 100644 --- a/media/java/android/media/AudioRecord.java +++ b/media/java/android/media/AudioRecord.java @@ -116,11 +116,6 @@ public class AudioRecord */ private static final int NATIVE_EVENT_NEW_POS = 3; - /** - * Event id denotes when the routing changes. - */ - private final static int NATIVE_EVENT_ROUTING_CHANGE = 1000; - private final static String TAG = "android.media.AudioRecord"; /** @hide */ @@ -161,6 +156,12 @@ public class AudioRecord @SuppressWarnings("unused") private long mNativeCallbackCookie; + /** + * Accessed by native methods: provides access to the JNIDeviceCallback instance. + */ + @SuppressWarnings("unused") + private long mNativeDeviceCallback; + //--------------------------------------------------------- // Member variables @@ -1205,6 +1206,17 @@ public class AudioRecord * Returns an {@link AudioDeviceInfo} identifying the current routing of this AudioRecord. */ public AudioDeviceInfo getRoutedDevice() { + int deviceId = native_getRoutedDeviceId(); + if (deviceId == 0) { + return null; + } + AudioDeviceInfo[] devices = + AudioDevicesManager.listDevicesStatic(AudioDevicesManager.LIST_DEVICES_INPUTS); + for (int i = 0; i < devices.length; i++) { + if (devices[i].getId() == deviceId) { + return devices[i]; + } + } return null; } @@ -1224,6 +1236,9 @@ public class AudioRecord android.os.Handler handler) { if (listener != null && !mRoutingChangeListeners.containsKey(listener)) { synchronized (mRoutingChangeListeners) { + if (mRoutingChangeListeners.size() == 0) { + native_enableDeviceCallback(); + } mRoutingChangeListeners.put( listener, new NativeRoutingEventHandlerDelegate(this, listener, handler)); } @@ -1238,6 +1253,9 @@ public class AudioRecord synchronized (mRoutingChangeListeners) { if (mRoutingChangeListeners.containsKey(listener)) { mRoutingChangeListeners.remove(listener); + if (mRoutingChangeListeners.size() == 0) { + native_disableDeviceCallback(); + } } } } @@ -1271,7 +1289,7 @@ public class AudioRecord return; } switch(msg.what) { - case NATIVE_EVENT_ROUTING_CHANGE: + case AudioSystem.NATIVE_EVENT_ROUTING_CHANGE: if (listener != null) { listener.onAudioRecordRouting(record); } @@ -1299,10 +1317,11 @@ public class AudioRecord synchronized (mRoutingChangeListeners) { values = mRoutingChangeListeners.values(); } + AudioManager.resetAudioPortGeneration(); for(NativeRoutingEventHandlerDelegate delegate : values) { Handler handler = delegate.getHandler(); if (handler != null) { - handler.sendEmptyMessage(NATIVE_EVENT_ROUTING_CHANGE); + handler.sendEmptyMessage(AudioSystem.NATIVE_EVENT_ROUTING_CHANGE); } } } @@ -1341,10 +1360,14 @@ public class AudioRecord return false; } - mPreferredDevice = deviceInfo; - int preferredDeviceId = mPreferredDevice != null ? deviceInfo.getId() : 0; - - return native_setInputDevice(preferredDeviceId); + int preferredDeviceId = deviceInfo != null ? deviceInfo.getId() : 0; + boolean status = native_setInputDevice(preferredDeviceId); + if (status == true) { + synchronized (this) { + mPreferredDevice = deviceInfo; + } + } + return status; } /** @@ -1352,7 +1375,9 @@ public class AudioRecord * is not guarenteed to correspond to the actual device being used for recording. */ public AudioDeviceInfo getPreferredInputDevice() { - return mPreferredDevice; + synchronized (this) { + return mPreferredDevice; + } } //--------------------------------------------------------- @@ -1435,6 +1460,11 @@ public class AudioRecord return; } + if (what == AudioSystem.NATIVE_EVENT_ROUTING_CHANGE) { + recorder.broadcastRoutingChange(); + return; + } + if (recorder.mEventHandler != null) { Message m = recorder.mEventHandler.obtainMessage(what, arg1, arg2, obj); @@ -1486,7 +1516,9 @@ public class AudioRecord int sampleRateInHz, int channelCount, int audioFormat); private native final boolean native_setInputDevice(int deviceId); - + private native final int native_getRoutedDeviceId(); + private native final void native_enableDeviceCallback(); + private native final void native_disableDeviceCallback(); //--------------------------------------------------------- // Utility methods diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java index 3dae543..ee12374 100644 --- a/media/java/android/media/AudioSystem.java +++ b/media/java/android/media/AudioSystem.java @@ -721,5 +721,11 @@ public class AudioSystem (1 << STREAM_RING) | (1 << STREAM_NOTIFICATION) | (1 << STREAM_SYSTEM); + + /** + * Event posted by AudioTrack and AudioRecord JNI (JNIDeviceCallback) when routing changes. + * Keep in sync with core/jni/android_media_DeviceCallback.h. + */ + final static int NATIVE_EVENT_ROUTING_CHANGE = 1000; } diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java index cb05cc5..a66a1e5 100644 --- a/media/java/android/media/AudioTrack.java +++ b/media/java/android/media/AudioTrack.java @@ -178,12 +178,6 @@ public class AudioTrack */ private static final int NATIVE_EVENT_NEW_POS = 4; - /** - * Event id denotes when the routing changes. - */ - private final static int NATIVE_EVENT_ROUTING_CHANGE = 1000; - - private final static String TAG = "android.media.AudioTrack"; @@ -2057,11 +2051,14 @@ public class AudioTrack if (deviceInfo != null && !deviceInfo.isSink()) { return false; } - - mPreferredDevice = deviceInfo; - int preferredDeviceId = mPreferredDevice != null ? deviceInfo.getId() : 0; - - return native_setOutputDevice(preferredDeviceId); + int preferredDeviceId = deviceInfo != null ? deviceInfo.getId() : 0; + boolean status = native_setOutputDevice(preferredDeviceId); + if (status == true) { + synchronized (this) { + mPreferredDevice = deviceInfo; + } + } + return status; } /** @@ -2069,7 +2066,9 @@ public class AudioTrack * is not guaranteed to correspond to the actual device being used for playback. */ public AudioDeviceInfo getPreferredOutputDevice() { - return mPreferredDevice; + synchronized (this) { + return mPreferredDevice; + } } //-------------------------------------------------------------------------- @@ -2079,6 +2078,17 @@ public class AudioTrack * Returns an {@link AudioDeviceInfo} identifying the current routing of this AudioTrack. */ public AudioDeviceInfo getRoutedDevice() { + int deviceId = native_getRoutedDeviceId(); + if (deviceId == 0) { + return null; + } + AudioDeviceInfo[] devices = + AudioDevicesManager.listDevicesStatic(AudioDevicesManager.LIST_DEVICES_OUTPUTS); + for (int i = 0; i < devices.length; i++) { + if (devices[i].getId() == deviceId) { + return devices[i]; + } + } return null; } @@ -2098,6 +2108,9 @@ public class AudioTrack android.os.Handler handler) { if (listener != null && !mRoutingChangeListeners.containsKey(listener)) { synchronized (mRoutingChangeListeners) { + if (mRoutingChangeListeners.size() == 0) { + native_enableDeviceCallback(); + } mRoutingChangeListeners.put( listener, new NativeRoutingEventHandlerDelegate(this, listener, handler)); } @@ -2113,6 +2126,9 @@ public class AudioTrack if (mRoutingChangeListeners.containsKey(listener)) { mRoutingChangeListeners.remove(listener); } + if (mRoutingChangeListeners.size() == 0) { + native_disableDeviceCallback(); + } } } @@ -2124,10 +2140,11 @@ public class AudioTrack synchronized (mRoutingChangeListeners) { values = mRoutingChangeListeners.values(); } + AudioManager.resetAudioPortGeneration(); for(NativeRoutingEventHandlerDelegate delegate : values) { Handler handler = delegate.getHandler(); if (handler != null) { - handler.sendEmptyMessage(NATIVE_EVENT_ROUTING_CHANGE); + handler.sendEmptyMessage(AudioSystem.NATIVE_EVENT_ROUTING_CHANGE); } } } @@ -2240,7 +2257,7 @@ public class AudioTrack return; } switch(msg.what) { - case NATIVE_EVENT_ROUTING_CHANGE: + case AudioSystem.NATIVE_EVENT_ROUTING_CHANGE: if (listener != null) { listener.onAudioTrackRouting(track); } @@ -2273,6 +2290,10 @@ public class AudioTrack return; } + if (what == AudioSystem.NATIVE_EVENT_ROUTING_CHANGE) { + track.broadcastRoutingChange(); + return; + } NativePositionEventHandlerDelegate delegate = track.mEventHandlerDelegate; if (delegate != null) { Handler handler = delegate.getHandler(); @@ -2281,7 +2302,6 @@ public class AudioTrack handler.sendMessage(m); } } - } @@ -2362,6 +2382,9 @@ public class AudioTrack private native final int native_setAuxEffectSendLevel(float level); private native final boolean native_setOutputDevice(int deviceId); + private native final int native_getRoutedDeviceId(); + private native final void native_enableDeviceCallback(); + private native final void native_disableDeviceCallback(); //--------------------------------------------------------- // Utility methods |