Loading services/core/java/com/android/server/audio/AudioService.java +56 −55 Original line number Original line Diff line number Diff line Loading @@ -138,7 +138,6 @@ import java.io.IOException; import java.io.PrintWriter; import java.io.PrintWriter; import java.lang.reflect.Field; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashMap; import java.util.Iterator; import java.util.Iterator; import java.util.List; import java.util.List; Loading Loading @@ -771,7 +770,7 @@ public class AudioService extends IAudioService.Stub // Register for device connection intent broadcasts. // Register for device connection intent broadcasts. IntentFilter intentFilter = IntentFilter intentFilter = new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED); new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED); intentFilter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED); intentFilter.addAction(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED); intentFilter.addAction(Intent.ACTION_DOCK_EVENT); intentFilter.addAction(Intent.ACTION_DOCK_EVENT); intentFilter.addAction(Intent.ACTION_SCREEN_ON); intentFilter.addAction(Intent.ACTION_SCREEN_ON); intentFilter.addAction(Intent.ACTION_SCREEN_OFF); intentFilter.addAction(Intent.ACTION_SCREEN_OFF); Loading Loading @@ -2967,16 +2966,30 @@ public class AudioService extends IAudioService.Stub } } public void setBluetoothScoOnInt(boolean on, String eventSource) { public void setBluetoothScoOnInt(boolean on, String eventSource) { if (DEBUG_DEVICES) { Log.d(TAG, "setBluetoothScoOnInt: " + on + " " + eventSource); } if (on) { if (on) { // do not accept SCO ON if SCO audio is not connected // do not accept SCO ON if SCO audio is not connected synchronized (mScoClients) { synchronized (mScoClients) { if ((mBluetoothHeadset != null) && if (mBluetoothHeadset != null) { (mBluetoothHeadset.getAudioState(mBluetoothHeadsetDevice) if (mBluetoothHeadsetDevice == null) { != BluetoothHeadset.STATE_AUDIO_CONNECTED)) { BluetoothDevice activeDevice = mBluetoothHeadset.getActiveDevice(); if (activeDevice != null) { // setBtScoActiveDevice() might trigger resetBluetoothSco() which // will call setBluetoothScoOnInt(false, "resetBluetoothSco") setBtScoActiveDevice(activeDevice); } } if (mBluetoothHeadset.getAudioState(mBluetoothHeadsetDevice) != BluetoothHeadset.STATE_AUDIO_CONNECTED) { mForcedUseForCommExt = AudioSystem.FORCE_BT_SCO; mForcedUseForCommExt = AudioSystem.FORCE_BT_SCO; Log.w(TAG, "setBluetoothScoOnInt(true) failed because " + mBluetoothHeadsetDevice + " is not in audio connected mode"); return; return; } } } } } mForcedUseForComm = AudioSystem.FORCE_BT_SCO; mForcedUseForComm = AudioSystem.FORCE_BT_SCO; } else if (mForcedUseForComm == AudioSystem.FORCE_BT_SCO) { } else if (mForcedUseForComm == AudioSystem.FORCE_BT_SCO) { mForcedUseForComm = AudioSystem.FORCE_NONE; mForcedUseForComm = AudioSystem.FORCE_NONE; Loading Loading @@ -3362,11 +3375,10 @@ public class AudioService extends IAudioService.Stub } } } } void setBtScoDeviceConnectionState(BluetoothDevice btDevice, int state) { private boolean handleBtScoActiveDeviceChange(BluetoothDevice btDevice, boolean isActive) { if (btDevice == null) { if (btDevice == null) { return; return true; } } String address = btDevice.getAddress(); String address = btDevice.getAddress(); BluetoothClass btClass = btDevice.getBluetoothClass(); BluetoothClass btClass = btDevice.getBluetoothClass(); int outDevice = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO; int outDevice = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO; Loading @@ -3387,37 +3399,36 @@ public class AudioService extends IAudioService.Stub address = ""; address = ""; } } boolean connected = (state == BluetoothProfile.STATE_CONNECTED); String btDeviceName = btDevice.getName(); String btDeviceName = btDevice.getName(); boolean success = boolean result = handleDeviceConnection(isActive, outDevice, address, btDeviceName); handleDeviceConnection(connected, outDevice, address, btDeviceName) && // handleDeviceConnection() && result to make sure the method get executed handleDeviceConnection(connected, inDevice, address, btDeviceName); result = handleDeviceConnection(isActive, inDevice, address, btDeviceName) && result; return result; if (!success) { return; } } /* When one BT headset is disconnected while another BT headset void setBtScoActiveDevice(BluetoothDevice btDevice) { * is connected, don't mess with the headset device. if (DEBUG_DEVICES) { */ Log.d(TAG, "setBtScoActiveDevice(" + btDevice + ")"); if ((state == BluetoothProfile.STATE_DISCONNECTED || state == BluetoothProfile.STATE_DISCONNECTING) && mBluetoothHeadset != null && mBluetoothHeadset.getAudioState(btDevice) == BluetoothHeadset.STATE_AUDIO_CONNECTED) { Log.w(TAG, "SCO connected through another device, returning"); return; } } synchronized (mScoClients) { synchronized (mScoClients) { if (connected) { final BluetoothDevice previousActiveDevice = mBluetoothHeadsetDevice; if (!Objects.equals(btDevice, previousActiveDevice)) { if (!handleBtScoActiveDeviceChange(previousActiveDevice, false)) { Log.w(TAG, "setBtScoActiveDevice() failed to remove previous device " + previousActiveDevice); } if (!handleBtScoActiveDeviceChange(btDevice, true)) { Log.e(TAG, "setBtScoActiveDevice() failed to add new device " + btDevice); // set mBluetoothHeadsetDevice to null when failing to add new device btDevice = null; } mBluetoothHeadsetDevice = btDevice; mBluetoothHeadsetDevice = btDevice; } else { if (mBluetoothHeadsetDevice == null) { mBluetoothHeadsetDevice = null; resetBluetoothSco(); resetBluetoothSco(); } } } } } } } private BluetoothProfile.ServiceListener mBluetoothProfileServiceListener = private BluetoothProfile.ServiceListener mBluetoothProfileServiceListener = new BluetoothProfile.ServiceListener() { new BluetoothProfile.ServiceListener() { Loading Loading @@ -3469,12 +3480,7 @@ public class AudioService extends IAudioService.Stub // Discard timeout message // Discard timeout message mAudioHandler.removeMessages(MSG_BT_HEADSET_CNCT_FAILED); mAudioHandler.removeMessages(MSG_BT_HEADSET_CNCT_FAILED); mBluetoothHeadset = (BluetoothHeadset) proxy; mBluetoothHeadset = (BluetoothHeadset) proxy; deviceList = mBluetoothHeadset.getConnectedDevices(); setBtScoActiveDevice(mBluetoothHeadset.getActiveDevice()); if (deviceList.size() > 0) { mBluetoothHeadsetDevice = deviceList.get(0); } else { mBluetoothHeadsetDevice = null; } // Refresh SCO audio state // Refresh SCO audio state checkScoAudioState(); checkScoAudioState(); // Continue pending action if any // Continue pending action if any Loading Loading @@ -3595,10 +3601,7 @@ public class AudioService extends IAudioService.Stub void disconnectHeadset() { void disconnectHeadset() { synchronized (mScoClients) { synchronized (mScoClients) { if (mBluetoothHeadsetDevice != null) { setBtScoActiveDevice(null); setBtScoDeviceConnectionState(mBluetoothHeadsetDevice, BluetoothProfile.STATE_DISCONNECTED); } mBluetoothHeadset = null; mBluetoothHeadset = null; } } } } Loading Loading @@ -5788,11 +5791,9 @@ public class AudioService extends IAudioService.Stub AudioSystem.setForceUse(AudioSystem.FOR_DOCK, config); AudioSystem.setForceUse(AudioSystem.FOR_DOCK, config); } } mDockState = dockState; mDockState = dockState; } else if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) { } else if (action.equals(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED)) { state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_DISCONNECTED); BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); setBtScoDeviceConnectionState(btDevice, state); setBtScoActiveDevice(btDevice); } else if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) { } else if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) { boolean broadcast = false; boolean broadcast = false; int scoAudioState = AudioManager.SCO_AUDIO_STATE_ERROR; int scoAudioState = AudioManager.SCO_AUDIO_STATE_ERROR; Loading Loading
services/core/java/com/android/server/audio/AudioService.java +56 −55 Original line number Original line Diff line number Diff line Loading @@ -138,7 +138,6 @@ import java.io.IOException; import java.io.PrintWriter; import java.io.PrintWriter; import java.lang.reflect.Field; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashMap; import java.util.Iterator; import java.util.Iterator; import java.util.List; import java.util.List; Loading Loading @@ -771,7 +770,7 @@ public class AudioService extends IAudioService.Stub // Register for device connection intent broadcasts. // Register for device connection intent broadcasts. IntentFilter intentFilter = IntentFilter intentFilter = new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED); new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED); intentFilter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED); intentFilter.addAction(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED); intentFilter.addAction(Intent.ACTION_DOCK_EVENT); intentFilter.addAction(Intent.ACTION_DOCK_EVENT); intentFilter.addAction(Intent.ACTION_SCREEN_ON); intentFilter.addAction(Intent.ACTION_SCREEN_ON); intentFilter.addAction(Intent.ACTION_SCREEN_OFF); intentFilter.addAction(Intent.ACTION_SCREEN_OFF); Loading Loading @@ -2967,16 +2966,30 @@ public class AudioService extends IAudioService.Stub } } public void setBluetoothScoOnInt(boolean on, String eventSource) { public void setBluetoothScoOnInt(boolean on, String eventSource) { if (DEBUG_DEVICES) { Log.d(TAG, "setBluetoothScoOnInt: " + on + " " + eventSource); } if (on) { if (on) { // do not accept SCO ON if SCO audio is not connected // do not accept SCO ON if SCO audio is not connected synchronized (mScoClients) { synchronized (mScoClients) { if ((mBluetoothHeadset != null) && if (mBluetoothHeadset != null) { (mBluetoothHeadset.getAudioState(mBluetoothHeadsetDevice) if (mBluetoothHeadsetDevice == null) { != BluetoothHeadset.STATE_AUDIO_CONNECTED)) { BluetoothDevice activeDevice = mBluetoothHeadset.getActiveDevice(); if (activeDevice != null) { // setBtScoActiveDevice() might trigger resetBluetoothSco() which // will call setBluetoothScoOnInt(false, "resetBluetoothSco") setBtScoActiveDevice(activeDevice); } } if (mBluetoothHeadset.getAudioState(mBluetoothHeadsetDevice) != BluetoothHeadset.STATE_AUDIO_CONNECTED) { mForcedUseForCommExt = AudioSystem.FORCE_BT_SCO; mForcedUseForCommExt = AudioSystem.FORCE_BT_SCO; Log.w(TAG, "setBluetoothScoOnInt(true) failed because " + mBluetoothHeadsetDevice + " is not in audio connected mode"); return; return; } } } } } mForcedUseForComm = AudioSystem.FORCE_BT_SCO; mForcedUseForComm = AudioSystem.FORCE_BT_SCO; } else if (mForcedUseForComm == AudioSystem.FORCE_BT_SCO) { } else if (mForcedUseForComm == AudioSystem.FORCE_BT_SCO) { mForcedUseForComm = AudioSystem.FORCE_NONE; mForcedUseForComm = AudioSystem.FORCE_NONE; Loading Loading @@ -3362,11 +3375,10 @@ public class AudioService extends IAudioService.Stub } } } } void setBtScoDeviceConnectionState(BluetoothDevice btDevice, int state) { private boolean handleBtScoActiveDeviceChange(BluetoothDevice btDevice, boolean isActive) { if (btDevice == null) { if (btDevice == null) { return; return true; } } String address = btDevice.getAddress(); String address = btDevice.getAddress(); BluetoothClass btClass = btDevice.getBluetoothClass(); BluetoothClass btClass = btDevice.getBluetoothClass(); int outDevice = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO; int outDevice = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO; Loading @@ -3387,37 +3399,36 @@ public class AudioService extends IAudioService.Stub address = ""; address = ""; } } boolean connected = (state == BluetoothProfile.STATE_CONNECTED); String btDeviceName = btDevice.getName(); String btDeviceName = btDevice.getName(); boolean success = boolean result = handleDeviceConnection(isActive, outDevice, address, btDeviceName); handleDeviceConnection(connected, outDevice, address, btDeviceName) && // handleDeviceConnection() && result to make sure the method get executed handleDeviceConnection(connected, inDevice, address, btDeviceName); result = handleDeviceConnection(isActive, inDevice, address, btDeviceName) && result; return result; if (!success) { return; } } /* When one BT headset is disconnected while another BT headset void setBtScoActiveDevice(BluetoothDevice btDevice) { * is connected, don't mess with the headset device. if (DEBUG_DEVICES) { */ Log.d(TAG, "setBtScoActiveDevice(" + btDevice + ")"); if ((state == BluetoothProfile.STATE_DISCONNECTED || state == BluetoothProfile.STATE_DISCONNECTING) && mBluetoothHeadset != null && mBluetoothHeadset.getAudioState(btDevice) == BluetoothHeadset.STATE_AUDIO_CONNECTED) { Log.w(TAG, "SCO connected through another device, returning"); return; } } synchronized (mScoClients) { synchronized (mScoClients) { if (connected) { final BluetoothDevice previousActiveDevice = mBluetoothHeadsetDevice; if (!Objects.equals(btDevice, previousActiveDevice)) { if (!handleBtScoActiveDeviceChange(previousActiveDevice, false)) { Log.w(TAG, "setBtScoActiveDevice() failed to remove previous device " + previousActiveDevice); } if (!handleBtScoActiveDeviceChange(btDevice, true)) { Log.e(TAG, "setBtScoActiveDevice() failed to add new device " + btDevice); // set mBluetoothHeadsetDevice to null when failing to add new device btDevice = null; } mBluetoothHeadsetDevice = btDevice; mBluetoothHeadsetDevice = btDevice; } else { if (mBluetoothHeadsetDevice == null) { mBluetoothHeadsetDevice = null; resetBluetoothSco(); resetBluetoothSco(); } } } } } } } private BluetoothProfile.ServiceListener mBluetoothProfileServiceListener = private BluetoothProfile.ServiceListener mBluetoothProfileServiceListener = new BluetoothProfile.ServiceListener() { new BluetoothProfile.ServiceListener() { Loading Loading @@ -3469,12 +3480,7 @@ public class AudioService extends IAudioService.Stub // Discard timeout message // Discard timeout message mAudioHandler.removeMessages(MSG_BT_HEADSET_CNCT_FAILED); mAudioHandler.removeMessages(MSG_BT_HEADSET_CNCT_FAILED); mBluetoothHeadset = (BluetoothHeadset) proxy; mBluetoothHeadset = (BluetoothHeadset) proxy; deviceList = mBluetoothHeadset.getConnectedDevices(); setBtScoActiveDevice(mBluetoothHeadset.getActiveDevice()); if (deviceList.size() > 0) { mBluetoothHeadsetDevice = deviceList.get(0); } else { mBluetoothHeadsetDevice = null; } // Refresh SCO audio state // Refresh SCO audio state checkScoAudioState(); checkScoAudioState(); // Continue pending action if any // Continue pending action if any Loading Loading @@ -3595,10 +3601,7 @@ public class AudioService extends IAudioService.Stub void disconnectHeadset() { void disconnectHeadset() { synchronized (mScoClients) { synchronized (mScoClients) { if (mBluetoothHeadsetDevice != null) { setBtScoActiveDevice(null); setBtScoDeviceConnectionState(mBluetoothHeadsetDevice, BluetoothProfile.STATE_DISCONNECTED); } mBluetoothHeadset = null; mBluetoothHeadset = null; } } } } Loading Loading @@ -5788,11 +5791,9 @@ public class AudioService extends IAudioService.Stub AudioSystem.setForceUse(AudioSystem.FOR_DOCK, config); AudioSystem.setForceUse(AudioSystem.FOR_DOCK, config); } } mDockState = dockState; mDockState = dockState; } else if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) { } else if (action.equals(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED)) { state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_DISCONNECTED); BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); setBtScoDeviceConnectionState(btDevice, state); setBtScoActiveDevice(btDevice); } else if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) { } else if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) { boolean broadcast = false; boolean broadcast = false; int scoAudioState = AudioManager.SCO_AUDIO_STATE_ERROR; int scoAudioState = AudioManager.SCO_AUDIO_STATE_ERROR; Loading