diff options
author | Paul McLean <pmclean@google.com> | 2015-05-12 15:36:56 -0700 |
---|---|---|
committer | Paul McLean <pmclean@google.com> | 2015-05-13 08:01:19 -0700 |
commit | 033468868dfa89e6c8dae2f8ad7365538329da42 (patch) | |
tree | 539025389b341a83946ccf05c1bfff385ae0c739 | |
parent | 1c82b221d46b4f235f4c7fd3fd8d029772f86abb (diff) | |
download | frameworks_base-033468868dfa89e6c8dae2f8ad7365538329da42.zip frameworks_base-033468868dfa89e6c8dae2f8ad7365538329da42.tar.gz frameworks_base-033468868dfa89e6c8dae2f8ad7365538329da42.tar.bz2 |
API Council Change Phase 2 - add/remove callback
Change-Id: Ic7d374c67ef46a2bc8427fa3555e3ad1a4b0723e
-rw-r--r-- | api/current.txt | 14 | ||||
-rw-r--r-- | api/system-current.txt | 14 | ||||
-rw-r--r-- | media/java/android/media/AudioDeviceCallback.java (renamed from media/java/android/media/OnAudioDeviceConnectionListener.java) | 5 | ||||
-rw-r--r-- | media/java/android/media/AudioManager.java | 153 |
4 files changed, 129 insertions, 57 deletions
diff --git a/api/current.txt b/api/current.txt index c5e4bdd..30f8faa 100644 --- a/api/current.txt +++ b/api/current.txt @@ -14727,6 +14727,12 @@ package android.media { method public android.media.AudioAttributes.Builder setUsage(int); } + public abstract class AudioDeviceCallback { + ctor public AudioDeviceCallback(); + method public void onAudioDevicesAdded(android.media.AudioDeviceInfo[]); + method public void onAudioDevicesRemoved(android.media.AudioDeviceInfo[]); + } + public final class AudioDeviceInfo { method public int[] getChannelCounts(); method public int[] getChannelMasks(); @@ -14829,7 +14835,6 @@ package android.media { public class AudioManager { method public int abandonAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener); - method public void addOnAudioDeviceConnectionListener(android.media.OnAudioDeviceConnectionListener, android.os.Handler); method public void adjustStreamVolume(int, int, int); method public void adjustSuggestedStreamVolume(int, int, int); method public void adjustVolume(int, int); @@ -14856,11 +14861,11 @@ package android.media { method public void loadSoundEffects(); method public void playSoundEffect(int); method public void playSoundEffect(int, float); + method public void registerAudioDeviceCallback(android.media.AudioDeviceCallback, android.os.Handler); method public deprecated void registerMediaButtonEventReceiver(android.content.ComponentName); method public deprecated void registerMediaButtonEventReceiver(android.app.PendingIntent); method public deprecated void registerRemoteControlClient(android.media.RemoteControlClient); method public deprecated boolean registerRemoteController(android.media.RemoteController); - method public void removeOnAudioDeviceConnectionListener(android.media.OnAudioDeviceConnectionListener); method public int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, int, int); method public deprecated void setBluetoothA2dpOn(boolean); method public void setBluetoothScoOn(boolean); @@ -14879,6 +14884,7 @@ package android.media { method public void startBluetoothSco(); method public void stopBluetoothSco(); method public void unloadSoundEffects(); + method public void unregisterAudioDeviceCallback(android.media.AudioDeviceCallback); method public deprecated void unregisterMediaButtonEventReceiver(android.content.ComponentName); method public deprecated void unregisterMediaButtonEventReceiver(android.app.PendingIntent); method public deprecated void unregisterRemoteControlClient(android.media.RemoteControlClient); @@ -16501,10 +16507,6 @@ package android.media { ctor public NotProvisionedException(java.lang.String); } - public abstract interface OnAudioDeviceConnectionListener { - method public abstract void onAudioDeviceConnection(); - } - public final class PlaybackParams { ctor public PlaybackParams(); method public android.media.PlaybackParams allowDefaults(); diff --git a/api/system-current.txt b/api/system-current.txt index 13796ff..4721df1 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -15925,6 +15925,12 @@ package android.media { method public android.media.AudioAttributes.Builder setUsage(int); } + public abstract class AudioDeviceCallback { + ctor public AudioDeviceCallback(); + method public void onAudioDevicesAdded(android.media.AudioDeviceInfo[]); + method public void onAudioDevicesRemoved(android.media.AudioDeviceInfo[]); + } + public final class AudioDeviceInfo { method public int[] getChannelCounts(); method public int[] getChannelMasks(); @@ -16040,7 +16046,6 @@ package android.media { public class AudioManager { method public int abandonAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener); method public int abandonAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, android.media.AudioAttributes); - method public void addOnAudioDeviceConnectionListener(android.media.OnAudioDeviceConnectionListener, android.os.Handler); method public void adjustStreamVolume(int, int, int); method public void adjustSuggestedStreamVolume(int, int, int); method public void adjustVolume(int, int); @@ -16068,12 +16073,12 @@ package android.media { method public void loadSoundEffects(); method public void playSoundEffect(int); method public void playSoundEffect(int, float); + method public void registerAudioDeviceCallback(android.media.AudioDeviceCallback, android.os.Handler); method public int registerAudioPolicy(android.media.audiopolicy.AudioPolicy); method public deprecated void registerMediaButtonEventReceiver(android.content.ComponentName); method public deprecated void registerMediaButtonEventReceiver(android.app.PendingIntent); method public deprecated void registerRemoteControlClient(android.media.RemoteControlClient); method public deprecated boolean registerRemoteController(android.media.RemoteController); - method public void removeOnAudioDeviceConnectionListener(android.media.OnAudioDeviceConnectionListener); method public int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, int, int); method public int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, android.media.AudioAttributes, int, int) throws java.lang.IllegalArgumentException; method public int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, android.media.AudioAttributes, int, int, android.media.audiopolicy.AudioPolicy) throws java.lang.IllegalArgumentException; @@ -16094,6 +16099,7 @@ package android.media { method public void startBluetoothSco(); method public void stopBluetoothSco(); method public void unloadSoundEffects(); + method public void unregisterAudioDeviceCallback(android.media.AudioDeviceCallback); method public void unregisterAudioPolicyAsync(android.media.audiopolicy.AudioPolicy); method public deprecated void unregisterMediaButtonEventReceiver(android.content.ComponentName); method public deprecated void unregisterMediaButtonEventReceiver(android.app.PendingIntent); @@ -17726,10 +17732,6 @@ package android.media { ctor public NotProvisionedException(java.lang.String); } - public abstract interface OnAudioDeviceConnectionListener { - method public abstract void onAudioDeviceConnection(); - } - public final class PlaybackParams { ctor public PlaybackParams(); method public android.media.PlaybackParams allowDefaults(); diff --git a/media/java/android/media/OnAudioDeviceConnectionListener.java b/media/java/android/media/AudioDeviceCallback.java index 57e9e17..d7fa492 100644 --- a/media/java/android/media/OnAudioDeviceConnectionListener.java +++ b/media/java/android/media/AudioDeviceCallback.java @@ -20,12 +20,13 @@ package android.media; * OnAudioDeviceConnectionListener defines the interface for notification listeners in the * {@link AudioManager} */ -public interface OnAudioDeviceConnectionListener { +public abstract class AudioDeviceCallback { /** * Called by the {@link AudioManager} to indicate that an audio device has been * connected or disconnected. A listener will probably call the * {@link AudioManager#getDevices} method to retrieve the current list of audio * devices. */ - public void onAudioDeviceConnection(); + public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) {} + public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {} } diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index cba83f9..e7013a5 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -3710,11 +3710,12 @@ public class AudioManager { * The message sent to apps when the contents of the device list changes if they provide * a {#link Handler} object to addOnAudioDeviceConnectionListener(). */ - private final static int MSG_DEVICES_LIST_CHANGE = 0; + private final static int MSG_DEVICES_DEVICES_ADDED = 0; + private final static int MSG_DEVICES_DEVICES_REMOVED = 1; - private ArrayMap<OnAudioDeviceConnectionListener, NativeEventHandlerDelegate> - mDeviceConnectionListeners = - new ArrayMap<OnAudioDeviceConnectionListener, NativeEventHandlerDelegate>(); + private ArrayMap<AudioDeviceCallback, NativeEventHandlerDelegate> + mDeviceCallbacks = + new ArrayMap<AudioDeviceCallback, NativeEventHandlerDelegate>(); /** * Specifies to the {@link AudioManager#getDevices(int)} method to include @@ -3757,22 +3758,8 @@ public class AudioManager { return getDevicesStatic(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 GET_DEVICES_OUTPUTS}, {@link GET_DEVICES_INPUTS} and {@link GET_DEVICES_ALL}. - * @return A (possibly zero-length) array of AudioDeviceInfo objects. - * @hide - */ - public static AudioDeviceInfo[] getDevicesStatic(int flags) { - ArrayList<AudioDevicePort> ports = new ArrayList<AudioDevicePort>(); - int status = AudioManager.listAudioDevicePorts(ports); - if (status != AudioManager.SUCCESS) { - // fail and bail! - return new AudioDeviceInfo[0]; - } + private static AudioDeviceInfo[] + infoListFromPortList(ArrayList<AudioDevicePort> ports, int flags) { // figure out how many AudioDeviceInfo we need space for int numRecs = 0; @@ -3794,28 +3781,74 @@ public class AudioManager { return deviceList; } + /* + * Calculate the list of ports that are in ports_B, but not in ports_A + */ + private static AudioDeviceInfo[] calcListDeltas( + ArrayList<AudioDevicePort> ports_A, ArrayList<AudioDevicePort> ports_B, int flags) { + + ArrayList<AudioDevicePort> delta_ports = new ArrayList<AudioDevicePort>(); + + AudioDevicePort cur_port = null; + for (int cur_index = 0; cur_index < ports_B.size(); cur_index++) { + boolean cur_port_found = false; + cur_port = ports_B.get(cur_index); + for (int prev_index = 0; + prev_index < ports_A.size() && !cur_port_found; + prev_index++) { + cur_port_found = (cur_port.id() == ports_A.get(prev_index).id()); + } + + if (!cur_port_found) { + delta_ports.add(cur_port); + } + } + + return infoListFromPortList(delta_ports, 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 GET_DEVICES_OUTPUTS}, {@link GET_DEVICES_INPUTS} and {@link GET_DEVICES_ALL}. + * @return A (possibly zero-length) array of AudioDeviceInfo objects. + * @hide + */ + public static AudioDeviceInfo[] getDevicesStatic(int flags) { + ArrayList<AudioDevicePort> ports = new ArrayList<AudioDevicePort>(); + int status = AudioManager.listAudioDevicePorts(ports); + if (status != AudioManager.SUCCESS) { + // fail and bail! + return new AudioDeviceInfo[0]; + } + + return infoListFromPortList(ports, flags); + } + /** - * Adds an {@link OnAudioDeviceConnectionListener} to receive notifications of changes + * Adds an {@link AudioDeviceCallback} to receive notifications of changes * to the set of connected audio devices. */ - public void addOnAudioDeviceConnectionListener(OnAudioDeviceConnectionListener listener, + public void registerAudioDeviceCallback(AudioDeviceCallback callback, android.os.Handler handler) { - if (listener != null && !mDeviceConnectionListeners.containsKey(listener)) { - synchronized (mDeviceConnectionListeners) { - mDeviceConnectionListeners.put( - listener, new NativeEventHandlerDelegate(listener, handler)); + if (callback != null && !mDeviceCallbacks.containsKey(callback)) { + synchronized (mDeviceCallbacks) { + mDeviceCallbacks.put( + callback, new NativeEventHandlerDelegate(callback, handler)); } } } /** - * Removes an {@link OnAudioDeviceConnectionListener} which has been previously registered + * Removes an {@link AudioDeviceCallback} which has been previously registered * to receive notifications of changes to the set of connected audio devices. */ - public void removeOnAudioDeviceConnectionListener(OnAudioDeviceConnectionListener listener) { - synchronized (mDeviceConnectionListeners) { - if (mDeviceConnectionListeners.containsKey(listener)) { - mDeviceConnectionListeners.remove(listener); + public void unregisterAudioDeviceCallback(AudioDeviceCallback callback) { + synchronized (mDeviceCallbacks) { + if (mDeviceCallbacks.containsKey(callback)) { + mDeviceCallbacks.remove(callback); } } } @@ -3824,14 +3857,42 @@ public class AudioManager { * Sends device list change notification to all listeners. */ private void broadcastDeviceListChange() { - Collection<NativeEventHandlerDelegate> values; - synchronized (mDeviceConnectionListeners) { - values = mDeviceConnectionListeners.values(); + int status; + + ArrayList<AudioDevicePort> previous_ports = new ArrayList<AudioDevicePort>(); + status = AudioManager.listPreviousAudioDevicePorts(previous_ports); + if (status != AudioManager.SUCCESS) { + return; } - for (NativeEventHandlerDelegate delegate : values) { - Handler handler = delegate.getHandler(); - if (handler != null) { - handler.sendEmptyMessage(MSG_DEVICES_LIST_CHANGE); + + ArrayList<AudioDevicePort> current_ports = new ArrayList<AudioDevicePort>(); + status = AudioManager.listAudioDevicePorts(current_ports); + if (status != AudioManager.SUCCESS) { + return; + } + + AudioDeviceInfo[] added_devices = + calcListDeltas(previous_ports, current_ports, GET_DEVICES_ALL); + AudioDeviceInfo[] removed_devices = + calcListDeltas(current_ports, previous_ports, GET_DEVICES_ALL); + + if (added_devices.length != 0 || removed_devices.length != 0) { + Collection<NativeEventHandlerDelegate> values; + synchronized (mDeviceCallbacks) { + values = mDeviceCallbacks.values(); + } + for (NativeEventHandlerDelegate delegate : values) { + Handler handler = delegate.getHandler(); + if (handler != null) { + if (added_devices.length != 0) { + handler.sendMessage( + Message.obtain(handler,MSG_DEVICES_DEVICES_ADDED, added_devices)); + } + if (removed_devices.length != 0) { + handler.sendMessage( + Message.obtain(handler,MSG_DEVICES_DEVICES_REMOVED, removed_devices)); + } + } } } } @@ -3869,7 +3930,7 @@ public class AudioManager { private class NativeEventHandlerDelegate { private final Handler mHandler; - NativeEventHandlerDelegate(final OnAudioDeviceConnectionListener listener, + NativeEventHandlerDelegate(final AudioDeviceCallback callback, Handler handler) { // find the looper for our new event handler Looper looper; @@ -3887,12 +3948,19 @@ public class AudioManager { @Override public void handleMessage(Message msg) { switch(msg.what) { - case MSG_DEVICES_LIST_CHANGE: + case MSG_DEVICES_DEVICES_ADDED: // call the OnAudioDeviceConnectionListener - if (listener != null) { - listener.onAudioDeviceConnection(); + if (callback != null) { + callback.onAudioDevicesAdded((AudioDeviceInfo[])msg.obj); } break; + + case MSG_DEVICES_DEVICES_REMOVED: + if (callback != null) { + callback.onAudioDevicesRemoved((AudioDeviceInfo[])msg.obj); + } + break; + default: Log.e(TAG, "Unknown native event type: " + msg.what); break; @@ -3908,5 +3976,4 @@ public class AudioManager { return mHandler; } } - } |