diff options
| author | Eric Laurent <elaurent@google.com> | 2012-04-09 08:39:05 -0700 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2012-04-09 08:39:05 -0700 |
| commit | 079f09c6ca4148d8e640e34ec03a3eb4fb3507cc (patch) | |
| tree | bf789fd8321728a7c5e2094c632e3ea522999dab | |
| parent | d1404465df624a66e9f80b2957bf18624a91df7a (diff) | |
| parent | 59f482764e346a5c5ac118ee1f7b24da645c2559 (diff) | |
| download | frameworks_base-079f09c6ca4148d8e640e34ec03a3eb4fb3507cc.zip frameworks_base-079f09c6ca4148d8e640e34ec03a3eb4fb3507cc.tar.gz frameworks_base-079f09c6ca4148d8e640e34ec03a3eb4fb3507cc.tar.bz2 | |
Merge "Added support for USB audio devices"
| -rw-r--r-- | core/java/android/content/Intent.java | 20 | ||||
| -rw-r--r-- | media/java/android/media/AudioManager.java | 8 | ||||
| -rw-r--r-- | media/java/android/media/AudioService.java | 189 | ||||
| -rw-r--r-- | media/java/android/media/AudioSystem.java | 11 | ||||
| -rw-r--r-- | services/java/com/android/server/WiredAccessoryObserver.java | 4 |
5 files changed, 102 insertions, 130 deletions
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 736dd24..18d682d 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -2000,8 +2000,8 @@ public class Intent implements Parcelable, Cloneable { * @hide */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String ACTION_USB_ANLG_HEADSET_PLUG = - "android.intent.action.USB_ANLG_HEADSET_PLUG"; + public static final String ACTION_ANALOG_AUDIO_DOCK_PLUG = + "android.intent.action.ANALOG_AUDIO_DOCK_PLUG"; /** * Broadcast Action: A digital audio speaker/headset plugged in or unplugged. @@ -2015,8 +2015,8 @@ public class Intent implements Parcelable, Cloneable { * @hide */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String ACTION_USB_DGTL_HEADSET_PLUG = - "android.intent.action.USB_DGTL_HEADSET_PLUG"; + public static final String ACTION_DIGITAL_AUDIO_DOCK_PLUG = + "android.intent.action.DIGITAL_AUDIO_DOCK_PLUG"; /** * Broadcast Action: A HMDI cable was plugged or unplugged @@ -2034,7 +2034,7 @@ public class Intent implements Parcelable, Cloneable { "android.intent.action.HDMI_AUDIO_PLUG"; /** - * Broadcast Action: A USB audio device was plugged in or unplugged. + * Broadcast Action: A USB audio accessory was plugged in or unplugged. * * <p>The intent will have the following extra values: * <ul> @@ -2046,11 +2046,11 @@ public class Intent implements Parcelable, Cloneable { * @hide */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String ACTION_USB_AUDIO_DEVICE_PLUG = - "android.intent.action.USB_AUDIO_DEVICE_PLUG"; + public static final String ACTION_USB_AUDIO_ACCESSORY_PLUG = + "android.intent.action.USB_AUDIO_ACCESSORY_PLUG"; /** - * Broadcast Action: A USB audio accessory was plugged in or unplugged. + * Broadcast Action: A USB audio device was plugged in or unplugged. * * <p>The intent will have the following extra values: * <ul> @@ -2062,8 +2062,8 @@ public class Intent implements Parcelable, Cloneable { * @hide */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String ACTION_USB_AUDIO_ACCESSORY_PLUG = - "android.intent.action.USB_AUDIO_ACCESSORY_PLUG"; + public static final String ACTION_USB_AUDIO_DEVICE_PLUG = + "android.intent.action.USB_AUDIO_DEVICE_PLUG"; /** * <p>Broadcast Action: The user has switched on advanced settings in the settings app:</p> diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index c7e71eb..41d5c32 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -2237,6 +2237,14 @@ public class AudioManager { * docking station */ public static final int DEVICE_OUT_DGTL_DOCK_HEADSET = AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET; + /** {@hide} The audio output device code for a USB audio accessory. The accessory is in USB host + * mode and the Android device in USB device mode + */ + public static final int DEVICE_OUT_USB_ACCESSORY = AudioSystem.DEVICE_OUT_USB_ACCESSORY; + /** {@hide} The audio output device code for a USB audio device. The device is in USB device + * mode and the Android device in USB host mode + */ + public static final int DEVICE_OUT_USB_DEVICE = AudioSystem.DEVICE_OUT_USB_DEVICE; /** {@hide} This is not used as a returned value from {@link #getDevicesForStream}, but could be * used in the future in a set method to select whatever default device is chosen by the * platform-specific implementation. diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java index 2e456f0..48d3712 100644 --- a/media/java/android/media/AudioService.java +++ b/media/java/android/media/AudioService.java @@ -389,9 +389,11 @@ public class AudioService extends IAudioService.Stub { intentFilter.addAction(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED); intentFilter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED); intentFilter.addAction(Intent.ACTION_DOCK_EVENT); - intentFilter.addAction(Intent.ACTION_USB_ANLG_HEADSET_PLUG); - intentFilter.addAction(Intent.ACTION_USB_DGTL_HEADSET_PLUG); + intentFilter.addAction(Intent.ACTION_ANALOG_AUDIO_DOCK_PLUG); + intentFilter.addAction(Intent.ACTION_DIGITAL_AUDIO_DOCK_PLUG); intentFilter.addAction(Intent.ACTION_HDMI_AUDIO_PLUG); + intentFilter.addAction(Intent.ACTION_USB_AUDIO_ACCESSORY_PLUG); + intentFilter.addAction(Intent.ACTION_USB_AUDIO_DEVICE_PLUG); intentFilter.addAction(Intent.ACTION_BOOT_COMPLETED); intentFilter.addAction(Intent.ACTION_SCREEN_ON); intentFilter.addAction(Intent.ACTION_SCREEN_OFF); @@ -2800,6 +2802,28 @@ public class AudioService extends IAudioService.Stub { } } + private boolean handleDeviceConnection(boolean connected, int device, String params) { + synchronized (mConnectedDevices) { + boolean isConnected = (mConnectedDevices.containsKey(device) && + mConnectedDevices.get(device).equals(params)); + + if (isConnected && !connected) { + AudioSystem.setDeviceConnectionState(device, + AudioSystem.DEVICE_STATE_UNAVAILABLE, + params); + mConnectedDevices.remove(device); + return true; + } else if (!isConnected && connected) { + AudioSystem.setDeviceConnectionState(device, + AudioSystem.DEVICE_STATE_AVAILABLE, + params); + mConnectedDevices.put(new Integer(device), params); + return true; + } + } + return false; + } + /* cache of the address of the last dock the device was connected to */ private String mDockAddress; @@ -2810,6 +2834,8 @@ public class AudioService extends IAudioService.Stub { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); + int device; + int state; if (action.equals(Intent.ACTION_DOCK_EVENT)) { int dockState = intent.getIntExtra(Intent.EXTRA_DOCK_STATE, @@ -2834,15 +2860,15 @@ public class AudioService extends IAudioService.Stub { } AudioSystem.setForceUse(AudioSystem.FOR_DOCK, config); } else if (action.equals(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED)) { - int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, + state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_DISCONNECTED); BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); handleA2dpConnectionStateChange(btDevice, state); } else if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) { - int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, + state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_DISCONNECTED); - int device = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO; + device = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO; String address = null; BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); @@ -2868,129 +2894,56 @@ public class AudioService extends IAudioService.Stub { address = ""; } - synchronized (mConnectedDevices) { - boolean isConnected = (mConnectedDevices.containsKey(device) && - mConnectedDevices.get(device).equals(address)); - + boolean connected = (state == BluetoothProfile.STATE_CONNECTED); + if (handleDeviceConnection(connected, device, address)) { synchronized (mScoClients) { - if (isConnected && state != BluetoothProfile.STATE_CONNECTED) { - AudioSystem.setDeviceConnectionState(device, - AudioSystem.DEVICE_STATE_UNAVAILABLE, - address); - mConnectedDevices.remove(device); + if (connected) { + mBluetoothHeadsetDevice = btDevice; + } else { mBluetoothHeadsetDevice = null; resetBluetoothSco(); - } else if (!isConnected && state == BluetoothProfile.STATE_CONNECTED) { - AudioSystem.setDeviceConnectionState(device, - AudioSystem.DEVICE_STATE_AVAILABLE, - address); - mConnectedDevices.put(new Integer(device), address); - mBluetoothHeadsetDevice = btDevice; } } } } else if (action.equals(Intent.ACTION_HEADSET_PLUG)) { - int state = intent.getIntExtra("state", 0); + state = intent.getIntExtra("state", 0); int microphone = intent.getIntExtra("microphone", 0); - synchronized (mConnectedDevices) { - if (microphone != 0) { - boolean isConnected = - mConnectedDevices.containsKey(AudioSystem.DEVICE_OUT_WIRED_HEADSET); - if (state == 0 && isConnected) { - AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_WIRED_HEADSET, - AudioSystem.DEVICE_STATE_UNAVAILABLE, - ""); - mConnectedDevices.remove(AudioSystem.DEVICE_OUT_WIRED_HEADSET); - } else if (state == 1 && !isConnected) { - AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_WIRED_HEADSET, - AudioSystem.DEVICE_STATE_AVAILABLE, - ""); - mConnectedDevices.put( - new Integer(AudioSystem.DEVICE_OUT_WIRED_HEADSET), ""); - } - } else { - boolean isConnected = - mConnectedDevices.containsKey(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE); - if (state == 0 && isConnected) { - AudioSystem.setDeviceConnectionState( - AudioSystem.DEVICE_OUT_WIRED_HEADPHONE, - AudioSystem.DEVICE_STATE_UNAVAILABLE, - ""); - mConnectedDevices.remove(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE); - } else if (state == 1 && !isConnected) { - AudioSystem.setDeviceConnectionState( - AudioSystem.DEVICE_OUT_WIRED_HEADPHONE, - AudioSystem.DEVICE_STATE_AVAILABLE, - ""); - mConnectedDevices.put( - new Integer(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE), ""); - } - } - } - } else if (action.equals(Intent.ACTION_USB_ANLG_HEADSET_PLUG)) { - int state = intent.getIntExtra("state", 0); - Log.v(TAG, "Broadcast Receiver: Got ACTION_USB_ANLG_HEADSET_PLUG, state = "+state); - synchronized (mConnectedDevices) { - boolean isConnected = - mConnectedDevices.containsKey(AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET); - if (state == 0 && isConnected) { - AudioSystem.setDeviceConnectionState( - AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET, - AudioSystem.DEVICE_STATE_UNAVAILABLE, - ""); - mConnectedDevices.remove(AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET); - } else if (state == 1 && !isConnected) { - AudioSystem.setDeviceConnectionState( - AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET, - AudioSystem.DEVICE_STATE_AVAILABLE, - ""); - mConnectedDevices.put( - new Integer(AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET), ""); - } + if (microphone != 0) { + device = AudioSystem.DEVICE_OUT_WIRED_HEADSET; + } else { + device = AudioSystem.DEVICE_OUT_WIRED_HEADPHONE; } + handleDeviceConnection((state == 1), device, ""); + } else if (action.equals(Intent.ACTION_ANALOG_AUDIO_DOCK_PLUG)) { + state = intent.getIntExtra("state", 0); + Log.v(TAG, "Broadcast Receiver: Got ACTION_ANALOG_AUDIO_DOCK_PLUG, state = "+state); + handleDeviceConnection((state == 1), AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET, ""); } else if (action.equals(Intent.ACTION_HDMI_AUDIO_PLUG)) { - int state = intent.getIntExtra("state", 0); + state = intent.getIntExtra("state", 0); Log.v(TAG, "Broadcast Receiver: Got ACTION_HDMI_AUDIO_PLUG, state = "+state); - synchronized (mConnectedDevices) { - boolean isConnected = - mConnectedDevices.containsKey(AudioSystem.DEVICE_OUT_AUX_DIGITAL); - if (state == 0 && isConnected) { - AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_AUX_DIGITAL, - AudioSystem.DEVICE_STATE_UNAVAILABLE, - ""); - mConnectedDevices.remove(AudioSystem.DEVICE_OUT_AUX_DIGITAL); - } else if (state == 1 && !isConnected) { - AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_AUX_DIGITAL, - AudioSystem.DEVICE_STATE_AVAILABLE, - ""); - mConnectedDevices.put( new Integer(AudioSystem.DEVICE_OUT_AUX_DIGITAL), ""); - } - } - } else if (action.equals(Intent.ACTION_USB_DGTL_HEADSET_PLUG)) { - int state = intent.getIntExtra("state", 0); - Log.v(TAG, "Broadcast Receiver: Got ACTION_USB_DGTL_HEADSET_PLUG, state = "+state); - synchronized (mConnectedDevices) { - boolean isConnected = - mConnectedDevices.containsKey(AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET); - if (state == 0 && isConnected) { - AudioSystem.setDeviceConnectionState( - AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET, - AudioSystem.DEVICE_STATE_UNAVAILABLE, - ""); - mConnectedDevices.remove(AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET); - } else if (state == 1 && !isConnected) { - AudioSystem.setDeviceConnectionState( - AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET, - AudioSystem.DEVICE_STATE_AVAILABLE, - ""); - mConnectedDevices.put( - new Integer(AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET), ""); - } - } + handleDeviceConnection((state == 1), AudioSystem.DEVICE_OUT_AUX_DIGITAL, ""); + } else if (action.equals(Intent.ACTION_DIGITAL_AUDIO_DOCK_PLUG)) { + state = intent.getIntExtra("state", 0); + Log.v(TAG, + "Broadcast Receiver Got ACTION_DIGITAL_AUDIO_DOCK_PLUG, state = " + state); + handleDeviceConnection((state == 1), AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET, ""); + } else if (action.equals(Intent.ACTION_USB_AUDIO_ACCESSORY_PLUG) || + action.equals(Intent.ACTION_USB_AUDIO_DEVICE_PLUG)) { + state = intent.getIntExtra("state", 0); + int alsaCard = intent.getIntExtra("card", -1); + int alsaDevice = intent.getIntExtra("device", -1); + String params = "card=" + alsaCard + ";device=" + alsaDevice; + device = action.equals(Intent.ACTION_USB_AUDIO_ACCESSORY_PLUG) ? + AudioSystem.DEVICE_OUT_USB_ACCESSORY : AudioSystem.DEVICE_OUT_USB_DEVICE; + Log.v(TAG, "Broadcast Receiver: Got " + + (action.equals(Intent.ACTION_USB_AUDIO_ACCESSORY_PLUG) ? + "ACTION_USB_AUDIO_ACCESSORY_PLUG" : "ACTION_USB_AUDIO_DEVICE_PLUG") + + ", state = " + state + ", card: " + alsaCard + ", device: " + alsaDevice); + handleDeviceConnection((state == 1), device, params); } else if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) { boolean broadcast = false; - int state = AudioManager.SCO_AUDIO_STATE_ERROR; + int scoAudioState = AudioManager.SCO_AUDIO_STATE_ERROR; synchronized (mScoClients) { int btState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1); // broadcast intent if the connection was initated by AudioService @@ -3002,7 +2955,7 @@ public class AudioService extends IAudioService.Stub { } switch (btState) { case BluetoothHeadset.STATE_AUDIO_CONNECTED: - state = AudioManager.SCO_AUDIO_STATE_CONNECTED; + scoAudioState = AudioManager.SCO_AUDIO_STATE_CONNECTED; if (mScoAudioState != SCO_STATE_ACTIVE_INTERNAL && mScoAudioState != SCO_STATE_DEACTIVATE_REQ && mScoAudioState != SCO_STATE_DEACTIVATE_EXT_REQ) { @@ -3010,7 +2963,7 @@ public class AudioService extends IAudioService.Stub { } break; case BluetoothHeadset.STATE_AUDIO_DISCONNECTED: - state = AudioManager.SCO_AUDIO_STATE_DISCONNECTED; + scoAudioState = AudioManager.SCO_AUDIO_STATE_DISCONNECTED; mScoAudioState = SCO_STATE_INACTIVE; clearAllScoClients(0, false); break; @@ -3027,11 +2980,11 @@ public class AudioService extends IAudioService.Stub { } } if (broadcast) { - broadcastScoConnectionState(state); + broadcastScoConnectionState(scoAudioState); //FIXME: this is to maintain compatibility with deprecated intent // AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED. Remove when appropriate. Intent newIntent = new Intent(AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED); - newIntent.putExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, state); + newIntent.putExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, scoAudioState); mContext.sendStickyBroadcast(newIntent); } } else if (action.equals(Intent.ACTION_BOOT_COMPLETED)) { diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java index 18a00bc..9bafa5c 100644 --- a/media/java/android/media/AudioSystem.java +++ b/media/java/android/media/AudioSystem.java @@ -202,6 +202,9 @@ public class AudioSystem public static final int DEVICE_OUT_AUX_DIGITAL = 0x400; public static final int DEVICE_OUT_ANLG_DOCK_HEADSET = 0x800; public static final int DEVICE_OUT_DGTL_DOCK_HEADSET = 0x1000; + public static final int DEVICE_OUT_USB_ACCESSORY = 0x2000; + public static final int DEVICE_OUT_USB_DEVICE = 0x4000; + public static final int DEVICE_OUT_DEFAULT = 0x8000; public static final int DEVICE_OUT_ALL = (DEVICE_OUT_EARPIECE | DEVICE_OUT_SPEAKER | @@ -216,10 +219,18 @@ public class AudioSystem DEVICE_OUT_AUX_DIGITAL | DEVICE_OUT_ANLG_DOCK_HEADSET | DEVICE_OUT_DGTL_DOCK_HEADSET | + DEVICE_OUT_USB_ACCESSORY | + DEVICE_OUT_USB_DEVICE | DEVICE_OUT_DEFAULT); public static final int DEVICE_OUT_ALL_A2DP = (DEVICE_OUT_BLUETOOTH_A2DP | DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES | DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER); + public static final int DEVICE_OUT_ALL_SCO = (DEVICE_OUT_BLUETOOTH_SCO | + DEVICE_OUT_BLUETOOTH_SCO_HEADSET | + DEVICE_OUT_BLUETOOTH_SCO_CARKIT); + public static final int DEVICE_OUT_ALL_USB = (DEVICE_OUT_USB_ACCESSORY | + DEVICE_OUT_USB_DEVICE); + // input devices public static final int DEVICE_IN_COMMUNICATION = 0x10000; public static final int DEVICE_IN_AMBIENT = 0x20000; diff --git a/services/java/com/android/server/WiredAccessoryObserver.java b/services/java/com/android/server/WiredAccessoryObserver.java index 9b4eddc..53d1f0e 100644 --- a/services/java/com/android/server/WiredAccessoryObserver.java +++ b/services/java/com/android/server/WiredAccessoryObserver.java @@ -301,13 +301,13 @@ class WiredAccessoryObserver extends UEventObserver { // Pack up the values and broadcast them to everyone if (headset == BIT_USB_HEADSET_ANLG) { - intent = new Intent(Intent.ACTION_USB_ANLG_HEADSET_PLUG); + intent = new Intent(Intent.ACTION_ANALOG_AUDIO_DOCK_PLUG); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); intent.putExtra("state", state); intent.putExtra("name", headsetName); ActivityManagerNative.broadcastStickyIntent(intent, null); } else if (headset == BIT_USB_HEADSET_DGTL) { - intent = new Intent(Intent.ACTION_USB_DGTL_HEADSET_PLUG); + intent = new Intent(Intent.ACTION_DIGITAL_AUDIO_DOCK_PLUG); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); intent.putExtra("state", state); intent.putExtra("name", headsetName); |
