@@ -135,6 +135,8 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
135135 private static final int MSG_RCDISPLAY_UPDATE = 13 ;
136136 private static final int MSG_SET_ALL_VOLUMES = 14 ;
137137 private static final int MSG_PERSIST_MASTER_VOLUME_MUTE = 15 ;
138+ private static final int MSG_SET_WIRED_DEVICE_CONNECTION_STATE = 16 ;
139+ private static final int MSG_SET_A2DP_CONNECTION_STATE = 17 ;
138140
139141
140142 // flags for MSG_PERSIST_VOLUME indicating if current and/or last audible volume should be
@@ -442,15 +444,9 @@ public AudioService(Context context) {
442444
443445 // Register for device connection intent broadcasts.
444446 IntentFilter intentFilter =
445- new IntentFilter (Intent .ACTION_HEADSET_PLUG );
446-
447- intentFilter .addAction (BluetoothA2dp .ACTION_CONNECTION_STATE_CHANGED );
448- intentFilter .addAction (BluetoothHeadset .ACTION_AUDIO_STATE_CHANGED );
447+ new IntentFilter (BluetoothHeadset .ACTION_AUDIO_STATE_CHANGED );
449448 intentFilter .addAction (BluetoothHeadset .ACTION_CONNECTION_STATE_CHANGED );
450449 intentFilter .addAction (Intent .ACTION_DOCK_EVENT );
451- intentFilter .addAction (Intent .ACTION_ANALOG_AUDIO_DOCK_PLUG );
452- intentFilter .addAction (Intent .ACTION_DIGITAL_AUDIO_DOCK_PLUG );
453- intentFilter .addAction (Intent .ACTION_HDMI_AUDIO_PLUG );
454450 intentFilter .addAction (Intent .ACTION_USB_AUDIO_ACCESSORY_PLUG );
455451 intentFilter .addAction (Intent .ACTION_USB_AUDIO_DEVICE_PLUG );
456452 intentFilter .addAction (Intent .ACTION_BOOT_COMPLETED );
@@ -1961,7 +1957,19 @@ public void onServiceConnected(int profile, BluetoothProfile proxy) {
19611957 deviceList = a2dp .getConnectedDevices ();
19621958 if (deviceList .size () > 0 ) {
19631959 btDevice = deviceList .get (0 );
1964- handleA2dpConnectionStateChange (btDevice , a2dp .getConnectionState (btDevice ));
1960+ synchronized (mConnectedDevices ) {
1961+ int state = a2dp .getConnectionState (btDevice );
1962+ int delay = checkSendBecomingNoisyIntent (
1963+ AudioSystem .DEVICE_OUT_BLUETOOTH_A2DP ,
1964+ (state == BluetoothA2dp .STATE_CONNECTED ) ? 1 : 0 );
1965+ sendMsg (mAudioHandler ,
1966+ MSG_SET_A2DP_CONNECTION_STATE ,
1967+ SENDMSG_QUEUE ,
1968+ state ,
1969+ 0 ,
1970+ btDevice ,
1971+ delay );
1972+ }
19651973 }
19661974 break ;
19671975
@@ -2262,6 +2270,36 @@ private int getDeviceForStream(int stream) {
22622270 return device ;
22632271 }
22642272
2273+ public void setWiredDeviceConnectionState (int device , int state , String name ) {
2274+ synchronized (mConnectedDevices ) {
2275+ int delay = checkSendBecomingNoisyIntent (device , state );
2276+ sendMsg (mAudioHandler ,
2277+ MSG_SET_WIRED_DEVICE_CONNECTION_STATE ,
2278+ SENDMSG_QUEUE ,
2279+ device ,
2280+ state ,
2281+ name ,
2282+ delay );
2283+ }
2284+ }
2285+
2286+ public int setBluetoothA2dpDeviceConnectionState (BluetoothDevice device , int state )
2287+ {
2288+ int delay ;
2289+ synchronized (mConnectedDevices ) {
2290+ delay = checkSendBecomingNoisyIntent (AudioSystem .DEVICE_OUT_BLUETOOTH_A2DP ,
2291+ (state == BluetoothA2dp .STATE_CONNECTED ) ? 1 : 0 );
2292+ sendMsg (mAudioHandler ,
2293+ MSG_SET_A2DP_CONNECTION_STATE ,
2294+ SENDMSG_QUEUE ,
2295+ state ,
2296+ 0 ,
2297+ device ,
2298+ delay );
2299+ }
2300+ return delay ;
2301+ }
2302+
22652303 ///////////////////////////////////////////////////////////////////////////
22662304 // Inner classes
22672305 ///////////////////////////////////////////////////////////////////////////
@@ -2959,6 +2997,14 @@ public void handleMessage(Message msg) {
29592997 case MSG_BT_HEADSET_CNCT_FAILED :
29602998 resetBluetoothSco ();
29612999 break ;
3000+
3001+ case MSG_SET_WIRED_DEVICE_CONNECTION_STATE :
3002+ onSetWiredDeviceConnectionState (msg .arg1 , msg .arg2 , (String )msg .obj );
3003+ break ;
3004+
3005+ case MSG_SET_A2DP_CONNECTION_STATE :
3006+ onSetA2dpConnectionState ((BluetoothDevice )msg .obj , msg .arg1 );
3007+ break ;
29623008 }
29633009 }
29643010 }
@@ -3020,7 +3066,6 @@ private void sendBecomingNoisyIntent() {
30203066
30213067 // must be called synchronized on mConnectedDevices
30223068 private void makeA2dpDeviceUnavailableNow (String address ) {
3023- sendBecomingNoisyIntent ();
30243069 AudioSystem .setDeviceConnectionState (AudioSystem .DEVICE_OUT_BLUETOOTH_A2DP ,
30253070 AudioSystem .DEVICE_STATE_UNAVAILABLE ,
30263071 address );
@@ -3050,7 +3095,7 @@ private boolean hasScheduledA2dpDockTimeout() {
30503095 return mAudioHandler .hasMessages (MSG_BTA2DP_DOCK_TIMEOUT );
30513096 }
30523097
3053- private void handleA2dpConnectionStateChange (BluetoothDevice btDevice , int state )
3098+ private void onSetA2dpConnectionState (BluetoothDevice btDevice , int state )
30543099 {
30553100 if (btDevice == null ) {
30563101 return ;
@@ -3116,6 +3161,76 @@ private boolean handleDeviceConnection(boolean connected, int device, String par
31163161 return false ;
31173162 }
31183163
3164+ // Devices which removal triggers intent ACTION_AUDIO_BECOMING_NOISY. The intent is only
3165+ // sent if none of these devices is connected.
3166+ int mBecomingNoisyIntentDevices =
3167+ AudioSystem .DEVICE_OUT_WIRED_HEADSET | AudioSystem .DEVICE_OUT_WIRED_HEADPHONE |
3168+ AudioSystem .DEVICE_OUT_ALL_A2DP ;
3169+
3170+ // must be called before removing the device from mConnectedDevices
3171+ private int checkSendBecomingNoisyIntent (int device , int state ) {
3172+ int delay = 0 ;
3173+ if ((state == 0 ) && ((device & mBecomingNoisyIntentDevices ) != 0 )) {
3174+ int devices = 0 ;
3175+ for (int dev : mConnectedDevices .keySet ()) {
3176+ if ((dev & mBecomingNoisyIntentDevices ) != 0 ) {
3177+ devices |= dev ;
3178+ }
3179+ }
3180+ if (devices == device ) {
3181+ delay = 1000 ;
3182+ sendBecomingNoisyIntent ();
3183+ }
3184+ }
3185+
3186+ if (mAudioHandler .hasMessages (MSG_SET_A2DP_CONNECTION_STATE ) ||
3187+ mAudioHandler .hasMessages (MSG_SET_WIRED_DEVICE_CONNECTION_STATE )) {
3188+ delay = 1000 ;
3189+ }
3190+ return delay ;
3191+ }
3192+
3193+ private void sendDeviceConnectionIntent (int device , int state , String name )
3194+ {
3195+ Intent intent = new Intent ();
3196+
3197+ intent .putExtra ("state" , state );
3198+ intent .putExtra ("name" , name );
3199+ intent .addFlags (Intent .FLAG_RECEIVER_REGISTERED_ONLY );
3200+
3201+ if (device == AudioSystem .DEVICE_OUT_WIRED_HEADSET ) {
3202+ intent .setAction (Intent .ACTION_HEADSET_PLUG );
3203+ intent .putExtra ("microphone" , 1 );
3204+ } else if (device == AudioSystem .DEVICE_OUT_WIRED_HEADPHONE ) {
3205+ intent .setAction (Intent .ACTION_HEADSET_PLUG );
3206+ intent .putExtra ("microphone" , 0 );
3207+ } else if (device == AudioSystem .DEVICE_OUT_ANLG_DOCK_HEADSET ) {
3208+ intent .setAction (Intent .ACTION_ANALOG_AUDIO_DOCK_PLUG );
3209+ } else if (device == AudioSystem .DEVICE_OUT_DGTL_DOCK_HEADSET ) {
3210+ intent .setAction (Intent .ACTION_DIGITAL_AUDIO_DOCK_PLUG );
3211+ } else if (device == AudioSystem .DEVICE_OUT_AUX_DIGITAL ) {
3212+ intent .setAction (Intent .ACTION_HDMI_AUDIO_PLUG );
3213+ }
3214+
3215+ ActivityManagerNative .broadcastStickyIntent (intent , null );
3216+ }
3217+
3218+ private void onSetWiredDeviceConnectionState (int device , int state , String name )
3219+ {
3220+ synchronized (mConnectedDevices ) {
3221+ if ((state == 0 ) && ((device == AudioSystem .DEVICE_OUT_WIRED_HEADSET ) ||
3222+ (device == AudioSystem .DEVICE_OUT_WIRED_HEADPHONE ))) {
3223+ setBluetoothA2dpOnInt (true );
3224+ }
3225+ handleDeviceConnection ((state == 1 ), device , "" );
3226+ if ((state != 0 ) && ((device == AudioSystem .DEVICE_OUT_WIRED_HEADSET ) ||
3227+ (device == AudioSystem .DEVICE_OUT_WIRED_HEADPHONE ))) {
3228+ setBluetoothA2dpOnInt (false );
3229+ }
3230+ sendDeviceConnectionIntent (device , state , name );
3231+ }
3232+ }
3233+
31193234 /* cache of the address of the last dock the device was connected to */
31203235 private String mDockAddress ;
31213236
@@ -3151,12 +3266,6 @@ public void onReceive(Context context, Intent intent) {
31513266 config = AudioSystem .FORCE_NONE ;
31523267 }
31533268 AudioSystem .setForceUse (AudioSystem .FOR_DOCK , config );
3154- } else if (action .equals (BluetoothA2dp .ACTION_CONNECTION_STATE_CHANGED )) {
3155- state = intent .getIntExtra (BluetoothProfile .EXTRA_STATE ,
3156- BluetoothProfile .STATE_DISCONNECTED );
3157- BluetoothDevice btDevice = intent .getParcelableExtra (BluetoothDevice .EXTRA_DEVICE );
3158-
3159- handleA2dpConnectionStateChange (btDevice , state );
31603269 } else if (action .equals (BluetoothHeadset .ACTION_CONNECTION_STATE_CHANGED )) {
31613270 state = intent .getIntExtra (BluetoothProfile .EXTRA_STATE ,
31623271 BluetoothProfile .STATE_DISCONNECTED );
@@ -3197,43 +3306,9 @@ public void onReceive(Context context, Intent intent) {
31973306 }
31983307 }
31993308 }
3200- } else if (action .equals (Intent .ACTION_HEADSET_PLUG )) {
3201- state = intent .getIntExtra ("state" , 0 );
3202- int microphone = intent .getIntExtra ("microphone" , 0 );
3203-
3204- if (microphone != 0 ) {
3205- device = AudioSystem .DEVICE_OUT_WIRED_HEADSET ;
3206- } else {
3207- device = AudioSystem .DEVICE_OUT_WIRED_HEADPHONE ;
3208- }
3209- // enable A2DP before notifying headset disconnection to avoid glitches
3210- if (state == 0 ) {
3211- setBluetoothA2dpOnInt (true );
3212- }
3213- handleDeviceConnection ((state == 1 ), device , "" );
3214- // disable A2DP after notifying headset connection to avoid glitches
3215- if (state != 0 ) {
3216- setBluetoothA2dpOnInt (false );
3217- }
3218- } else if (action .equals (Intent .ACTION_ANALOG_AUDIO_DOCK_PLUG )) {
3219- state = intent .getIntExtra ("state" , 0 );
3220- Log .v (TAG , "Broadcast Receiver: Got ACTION_ANALOG_AUDIO_DOCK_PLUG, state = " +state );
3221- handleDeviceConnection ((state == 1 ), AudioSystem .DEVICE_OUT_ANLG_DOCK_HEADSET , "" );
3222- } else if (action .equals (Intent .ACTION_HDMI_AUDIO_PLUG )) {
3223- state = intent .getIntExtra ("state" , 0 );
3224- Log .v (TAG , "Broadcast Receiver: Got ACTION_HDMI_AUDIO_PLUG, state = " +state );
3225- handleDeviceConnection ((state == 1 ), AudioSystem .DEVICE_OUT_AUX_DIGITAL , "" );
3226- } else if (action .equals (Intent .ACTION_DIGITAL_AUDIO_DOCK_PLUG )) {
3227- state = intent .getIntExtra ("state" , 0 );
3228- Log .v (TAG ,
3229- "Broadcast Receiver Got ACTION_DIGITAL_AUDIO_DOCK_PLUG, state = " + state );
3230- handleDeviceConnection ((state == 1 ), AudioSystem .DEVICE_OUT_DGTL_DOCK_HEADSET , "" );
32313309 } else if (action .equals (Intent .ACTION_USB_AUDIO_ACCESSORY_PLUG ) ||
32323310 action .equals (Intent .ACTION_USB_AUDIO_DEVICE_PLUG )) {
32333311 state = intent .getIntExtra ("state" , 0 );
3234- if (state == 0 ) {
3235- sendBecomingNoisyIntent ();
3236- }
32373312 int alsaCard = intent .getIntExtra ("card" , -1 );
32383313 int alsaDevice = intent .getIntExtra ("device" , -1 );
32393314 String params = (alsaCard == -1 && alsaDevice == -1 ? ""
0 commit comments