Loading services/core/java/com/android/server/audio/AudioDeviceBroker.java +17 −33 Original line number Diff line number Diff line Loading @@ -257,24 +257,19 @@ public class AudioDeviceBroker { sendMsgNoDelay(MSG_TOGGLE_HDMI, SENDMSG_QUEUE); } /*package*/ void disconnectAllBluetoothProfiles() { synchronized (mDeviceStateLock) { mBtHelper.disconnectAllBluetoothProfiles(); } } /** * Handle BluetoothHeadset intents where the action is one of * {@link BluetoothHeadset#ACTION_ACTIVE_DEVICE_CHANGED} or * {@link BluetoothHeadset#ACTION_AUDIO_STATE_CHANGED}. * @param intent */ /*package*/ void receiveBtEvent(@NonNull Intent intent) { synchronized (mSetModeLock) { synchronized (mDeviceStateLock) { mBtHelper.receiveBtEvent(intent); } private void onReceiveBtEvent(@NonNull Intent intent) { mBtHelper.onReceiveBtEvent(intent); } @GuardedBy("mDeviceStateLock") /*package*/ void onSetBtScoActiveDevice(BluetoothDevice btDevice) { mBtHelper.onSetBtScoActiveDevice(btDevice); } /*package*/ void setBluetoothA2dpOn_Async(boolean on, String source) { Loading Loading @@ -1404,14 +1399,14 @@ public class AudioDeviceBroker { sendLMsgNoDelay(MSG_L_SET_COMMUNICATION_DEVICE_FOR_CLIENT, SENDMSG_QUEUE, info); } /*package*/ void postScoAudioStateChanged(int state) { sendIMsgNoDelay(MSG_I_SCO_AUDIO_STATE_CHANGED, SENDMSG_QUEUE, state); } /*package*/ void postNotifyPreferredAudioProfileApplied(BluetoothDevice btDevice) { sendLMsgNoDelay(MSG_L_NOTIFY_PREFERRED_AUDIOPROFILE_APPLIED, SENDMSG_QUEUE, btDevice); } /*package*/ void postReceiveBtEvent(Intent intent) { sendLMsgNoDelay(MSG_L_RECEIVED_BT_EVENT, SENDMSG_QUEUE, intent); } /*package*/ static final class CommunicationDeviceInfo { final @NonNull IBinder mCb; // Identifies the requesting client for death handler final int mUid; // Requester UID Loading Loading @@ -1807,10 +1802,10 @@ public class AudioDeviceBroker { } break; case MSG_I_SCO_AUDIO_STATE_CHANGED: case MSG_L_RECEIVED_BT_EVENT: synchronized (mSetModeLock) { synchronized (mDeviceStateLock) { mBtHelper.onScoAudioStateChanged(msg.arg1); onReceiveBtEvent((Intent) msg.obj); } } break; Loading @@ -1821,29 +1816,17 @@ public class AudioDeviceBroker { } break; case MSG_I_BT_SERVICE_DISCONNECTED_PROFILE: if (msg.arg1 != BluetoothProfile.HEADSET) { synchronized (mSetModeLock) { synchronized (mDeviceStateLock) { mBtHelper.onBtProfileDisconnected(msg.arg1); mDeviceInventory.onBtProfileDisconnected(msg.arg1); } } else { synchronized (mSetModeLock) { synchronized (mDeviceStateLock) { mBtHelper.disconnectHeadset(); } } } break; case MSG_IL_BT_SERVICE_CONNECTED_PROFILE: if (msg.arg1 != BluetoothProfile.HEADSET) { synchronized (mDeviceStateLock) { mBtHelper.onBtProfileConnected(msg.arg1, (BluetoothProfile) msg.obj); } } else { synchronized (mSetModeLock) { synchronized (mDeviceStateLock) { mBtHelper.onHeadsetProfileConnected((BluetoothHeadset) msg.obj); } mBtHelper.onBtProfileConnected(msg.arg1, (BluetoothProfile) msg.obj); } } break; Loading Loading @@ -1978,7 +1961,6 @@ public class AudioDeviceBroker { private static final int MSG_L_SET_COMMUNICATION_DEVICE_FOR_CLIENT = 42; private static final int MSG_IL_UPDATE_COMMUNICATION_ROUTE_CLIENT = 43; private static final int MSG_I_SCO_AUDIO_STATE_CHANGED = 44; private static final int MSG_L_BT_ACTIVE_DEVICE_CHANGE_EXT = 45; // Loading @@ -1994,6 +1976,8 @@ public class AudioDeviceBroker { private static final int MSG_PERSIST_AUDIO_DEVICE_SETTINGS = 54; private static final int MSG_L_RECEIVED_BT_EVENT = 55; private static boolean isMessageHandledUnderWakelock(int msgId) { switch(msgId) { case MSG_L_SET_WIRED_DEVICE_CONNECTION_STATE: Loading services/core/java/com/android/server/audio/AudioDeviceInventory.java +23 −1 Original line number Diff line number Diff line Loading @@ -1489,8 +1489,12 @@ public class AudioDeviceInventory { } } /*package*/ synchronized void onBtProfileDisconnected(int profile) { @GuardedBy("AudioDeviceBroker.mDeviceStateLock") /*package*/ void onBtProfileDisconnected(int profile) { switch (profile) { case BluetoothProfile.HEADSET: disconnectHeadset(); break; case BluetoothProfile.A2DP: disconnectA2dp(); break; Loading Loading @@ -1550,6 +1554,24 @@ public class AudioDeviceInventory { disconnectLeAudio(AudioSystem.DEVICE_OUT_BLE_BROADCAST); } @GuardedBy("AudioDeviceBroker.mDeviceStateLock") private void disconnectHeadset() { boolean disconnect = false; synchronized (mDevicesLock) { for (DeviceInfo di : mConnectedDevices.values()) { if (AudioSystem.isBluetoothScoDevice(di.mDeviceType)) { // There is only one HFP active device and setting the active // device to null will disconnect both in and out devices disconnect = true; break; } } } if (disconnect) { mDeviceBroker.onSetBtScoActiveDevice(null); } } // must be called before removing the device from mConnectedDevices // musicDevice argument is used when not AudioSystem.DEVICE_NONE instead of querying // from AudioSystem Loading services/core/java/com/android/server/audio/AudioService.java +1 −12 Original line number Diff line number Diff line Loading @@ -61,7 +61,6 @@ import android.app.NotificationManager; import android.app.UidObserver; import android.app.role.OnRoleHoldersChangedListener; import android.app.role.RoleManager; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHeadset; import android.bluetooth.BluetoothProfile; Loading Loading @@ -1366,7 +1365,6 @@ public class AudioService extends IAudioService.Stub intentFilter.addAction(Intent.ACTION_USER_BACKGROUND); intentFilter.addAction(Intent.ACTION_USER_FOREGROUND); intentFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED); intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); intentFilter.addAction(Intent.ACTION_PACKAGES_SUSPENDED); intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); Loading Loading @@ -9570,7 +9568,7 @@ public class AudioService extends IAudioService.Stub mDockState = dockState; } else if (action.equals(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED) || action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) { mDeviceBroker.receiveBtEvent(intent); mDeviceBroker.postReceiveBtEvent(intent); } else if (action.equals(Intent.ACTION_SCREEN_ON)) { if (mMonitorRotation) { RotationHelper.enable(); Loading Loading @@ -9638,15 +9636,6 @@ public class AudioService extends IAudioService.Stub } catch (IllegalArgumentException e) { Slog.w(TAG, "Failed to apply DISALLOW_RECORD_AUDIO restriction: " + e); } } else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) { state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1); sDeviceLogger.enqueue(new EventLogger.StringEvent( "BluetoothAdapter ACTION_STATE_CHANGED with state " + state)); if (state == BluetoothAdapter.STATE_OFF || state == BluetoothAdapter.STATE_TURNING_OFF) { mDeviceBroker.disconnectAllBluetoothProfiles(); } } else if (action.equals(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION) || action.equals(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION)) { handleAudioEffectBroadcast(context, intent); Loading services/core/java/com/android/server/audio/BtHelper.java +52 −56 Original line number Diff line number Diff line Loading @@ -191,10 +191,14 @@ public class BtHelper { if (adapter != null) { adapter.getProfileProxy(mDeviceBroker.getContext(), mBluetoothProfileServiceListener, BluetoothProfile.A2DP); adapter.getProfileProxy(mDeviceBroker.getContext(), mBluetoothProfileServiceListener, BluetoothProfile.A2DP_SINK); adapter.getProfileProxy(mDeviceBroker.getContext(), mBluetoothProfileServiceListener, BluetoothProfile.HEARING_AID); adapter.getProfileProxy(mDeviceBroker.getContext(), mBluetoothProfileServiceListener, BluetoothProfile.LE_AUDIO); adapter.getProfileProxy(mDeviceBroker.getContext(), mBluetoothProfileServiceListener, BluetoothProfile.LE_AUDIO_BROADCAST); } } Loading Loading @@ -261,27 +265,27 @@ public class BtHelper { // @GuardedBy("AudioDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.mDeviceStateLock") /*package*/ synchronized void receiveBtEvent(Intent intent) { /*package*/ synchronized void onReceiveBtEvent(Intent intent) { final String action = intent.getAction(); Log.i(TAG, "receiveBtEvent action: " + action + " mScoAudioState: " + mScoAudioState); Log.i(TAG, "onReceiveBtEvent action: " + action + " mScoAudioState: " + mScoAudioState); if (action.equals(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED)) { BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE, android.bluetooth.BluetoothDevice.class); setBtScoActiveDevice(btDevice); BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE, android.bluetooth.BluetoothDevice.class); onSetBtScoActiveDevice(btDevice); } else if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) { int btState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1); Log.i(TAG,"receiveBtEvent ACTION_AUDIO_STATE_CHANGED: "+btState); mDeviceBroker.postScoAudioStateChanged(btState); onScoAudioStateChanged(btState); } } /** * Exclusively called from AudioDeviceBroker when handling MSG_I_SCO_AUDIO_STATE_CHANGED * Exclusively called from AudioDeviceBroker when handling MSG_L_RECEIVED_BT_EVENT * as part of the serialization of the communication route selection */ // @GuardedBy("AudioDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.mDeviceStateLock") void onScoAudioStateChanged(int state) { private void onScoAudioStateChanged(int state) { boolean broadcast = false; int scoAudioState = AudioManager.SCO_AUDIO_STATE_ERROR; switch (state) { Loading @@ -294,10 +298,10 @@ public class BtHelper { // broadcast intent if the connection was initated by AudioService broadcast = true; } mDeviceBroker.setBluetoothScoOn(true, "BtHelper.receiveBtEvent"); mDeviceBroker.setBluetoothScoOn(true, "BtHelper.onScoAudioStateChanged"); break; case BluetoothHeadset.STATE_AUDIO_DISCONNECTED: mDeviceBroker.setBluetoothScoOn(false, "BtHelper.receiveBtEvent"); mDeviceBroker.setBluetoothScoOn(false, "BtHelper.onScoAudioStateChanged"); scoAudioState = AudioManager.SCO_AUDIO_STATE_DISCONNECTED; // There are two cases where we want to immediately reconnect audio: // 1) If a new start request was received while disconnecting: this was Loading Loading @@ -431,15 +435,6 @@ public class BtHelper { mScoConnectionState = state; } /*package*/ synchronized void disconnectAllBluetoothProfiles() { mDeviceBroker.postBtProfileDisconnected(BluetoothProfile.A2DP); mDeviceBroker.postBtProfileDisconnected(BluetoothProfile.A2DP_SINK); mDeviceBroker.postBtProfileDisconnected(BluetoothProfile.HEADSET); mDeviceBroker.postBtProfileDisconnected(BluetoothProfile.HEARING_AID); mDeviceBroker.postBtProfileDisconnected(BluetoothProfile.LE_AUDIO); mDeviceBroker.postBtProfileDisconnected(BluetoothProfile.LE_AUDIO_BROADCAST); } // @GuardedBy("AudioDeviceBroker.mSetModeLock") //@GuardedBy("AudioDeviceBroker.mDeviceStateLock") /*package*/ synchronized void resetBluetoothSco() { Loading @@ -450,18 +445,14 @@ public class BtHelper { mDeviceBroker.setBluetoothScoOn(false, "resetBluetoothSco"); } // @GuardedBy("AudioDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.mDeviceStateLock") /*package*/ synchronized void disconnectHeadset() { setBtScoActiveDevice(null); mBluetoothHeadset = null; } //@GuardedBy("AudioDeviceBroker.mDeviceStateLock") /*package*/ synchronized void onBtProfileDisconnected(int profile) { AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent( "BT profile " + BluetoothProfile.getProfileName(profile) + " disconnected")); switch (profile) { case BluetoothProfile.HEADSET: mBluetoothHeadset = null; break; case BluetoothProfile.A2DP: mA2dp = null; break; Loading @@ -471,14 +462,10 @@ public class BtHelper { case BluetoothProfile.LE_AUDIO: mLeAudio = null; break; case BluetoothProfile.A2DP_SINK: case BluetoothProfile.LE_AUDIO_BROADCAST: // shouldn't be received here as profile doesn't involve BtHelper Log.e(TAG, "onBtProfileDisconnected: Not a profile handled by BtHelper " + BluetoothProfile.getProfileName(profile)); // nothing to do in BtHelper break; default: // Not a valid profile to disconnect Log.e(TAG, "onBtProfileDisconnected: Not a valid profile to disconnect " Loading @@ -492,17 +479,31 @@ public class BtHelper { AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent( "BT profile " + BluetoothProfile.getProfileName(profile) + " connected to proxy " + proxy)); if (profile == BluetoothProfile.HEADSET) { switch (profile) { case BluetoothProfile.HEADSET: onHeadsetProfileConnected((BluetoothHeadset) proxy); return; } if (profile == BluetoothProfile.A2DP) { case BluetoothProfile.A2DP: mA2dp = (BluetoothA2dp) proxy; } else if (profile == BluetoothProfile.HEARING_AID) { break; case BluetoothProfile.HEARING_AID: mHearingAid = (BluetoothHearingAid) proxy; } else if (profile == BluetoothProfile.LE_AUDIO) { break; case BluetoothProfile.LE_AUDIO: mLeAudio = (BluetoothLeAudio) proxy; break; case BluetoothProfile.A2DP_SINK: case BluetoothProfile.LE_AUDIO_BROADCAST: // nothing to do in BtHelper return; default: // Not a valid profile to connect Log.e(TAG, "onBtProfileConnected: Not a valid profile to connect " + BluetoothProfile.getProfileName(profile)); break; } // this part is only for A2DP, LE Audio unicast and Hearing aid final List<BluetoothDevice> deviceList = proxy.getConnectedDevices(); if (deviceList.isEmpty()) { return; Loading @@ -523,7 +524,7 @@ public class BtHelper { // @GuardedBy("AudioDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.mDeviceStateLock") /*package*/ synchronized void onHeadsetProfileConnected(BluetoothHeadset headset) { private void onHeadsetProfileConnected(BluetoothHeadset headset) { // Discard timeout message mDeviceBroker.handleCancelFailureToConnectToBtHeadsetService(); mBluetoothHeadset = headset; Loading @@ -532,7 +533,7 @@ public class BtHelper { if (adapter != null) { activeDevices = adapter.getActiveDevices(BluetoothProfile.HEADSET); } setBtScoActiveDevice((activeDevices.size() > 0) ? activeDevices.get(0) : null); onSetBtScoActiveDevice((activeDevices.size() > 0) ? activeDevices.get(0) : null); // Refresh SCO audio state checkScoAudioState(); if (mScoAudioState != SCO_STATE_ACTIVATE_REQ Loading Loading @@ -643,20 +644,19 @@ public class BtHelper { // @GuardedBy("AudioDeviceBroker.mSetModeLock") //@GuardedBy("AudioDeviceBroker.mDeviceStateLock") @GuardedBy("BtHelper.this") private void setBtScoActiveDevice(BluetoothDevice btDevice) { Log.i(TAG, "setBtScoActiveDevice: " + getAnonymizedAddress(mBluetoothHeadsetDevice) /*package */ synchronized void onSetBtScoActiveDevice(BluetoothDevice btDevice) { Log.i(TAG, "onSetBtScoActiveDevice: " + getAnonymizedAddress(mBluetoothHeadsetDevice) + " -> " + getAnonymizedAddress(btDevice)); final BluetoothDevice previousActiveDevice = mBluetoothHeadsetDevice; if (Objects.equals(btDevice, previousActiveDevice)) { return; } if (!handleBtScoActiveDeviceChange(previousActiveDevice, false)) { Log.w(TAG, "setBtScoActiveDevice() failed to remove previous device " Log.w(TAG, "onSetBtScoActiveDevice() failed to remove previous device " + getAnonymizedAddress(previousActiveDevice)); } if (!handleBtScoActiveDeviceChange(btDevice, true)) { Log.e(TAG, "setBtScoActiveDevice() failed to add new device " Log.e(TAG, "onSetBtScoActiveDevice() failed to add new device " + getAnonymizedAddress(btDevice)); // set mBluetoothHeadsetDevice to null when failing to add new device btDevice = null; Loading @@ -677,16 +677,14 @@ public class BtHelper { case BluetoothProfile.HEADSET: case BluetoothProfile.HEARING_AID: case BluetoothProfile.LE_AUDIO: case BluetoothProfile.A2DP_SINK: case BluetoothProfile.LE_AUDIO_BROADCAST: AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent( "BT profile service: connecting " + BluetoothProfile.getProfileName(profile) + " profile")); mDeviceBroker.postBtProfileConnected(profile, proxy); break; case BluetoothProfile.A2DP_SINK: // no A2DP sink functionality handled by BtHelper case BluetoothProfile.LE_AUDIO_BROADCAST: // no broadcast functionality handled by BtHelper default: break; } Loading @@ -698,16 +696,14 @@ public class BtHelper { case BluetoothProfile.HEADSET: case BluetoothProfile.HEARING_AID: case BluetoothProfile.LE_AUDIO: case BluetoothProfile.A2DP_SINK: case BluetoothProfile.LE_AUDIO_BROADCAST: AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent( "BT profile service: disconnecting " + BluetoothProfile.getProfileName(profile) + " profile")); mDeviceBroker.postBtProfileDisconnected(profile); break; case BluetoothProfile.A2DP_SINK: // no A2DP sink functionality handled by BtHelper case BluetoothProfile.LE_AUDIO_BROADCAST: // no broadcast functionality handled by BtHelper default: break; } Loading Loading
services/core/java/com/android/server/audio/AudioDeviceBroker.java +17 −33 Original line number Diff line number Diff line Loading @@ -257,24 +257,19 @@ public class AudioDeviceBroker { sendMsgNoDelay(MSG_TOGGLE_HDMI, SENDMSG_QUEUE); } /*package*/ void disconnectAllBluetoothProfiles() { synchronized (mDeviceStateLock) { mBtHelper.disconnectAllBluetoothProfiles(); } } /** * Handle BluetoothHeadset intents where the action is one of * {@link BluetoothHeadset#ACTION_ACTIVE_DEVICE_CHANGED} or * {@link BluetoothHeadset#ACTION_AUDIO_STATE_CHANGED}. * @param intent */ /*package*/ void receiveBtEvent(@NonNull Intent intent) { synchronized (mSetModeLock) { synchronized (mDeviceStateLock) { mBtHelper.receiveBtEvent(intent); } private void onReceiveBtEvent(@NonNull Intent intent) { mBtHelper.onReceiveBtEvent(intent); } @GuardedBy("mDeviceStateLock") /*package*/ void onSetBtScoActiveDevice(BluetoothDevice btDevice) { mBtHelper.onSetBtScoActiveDevice(btDevice); } /*package*/ void setBluetoothA2dpOn_Async(boolean on, String source) { Loading Loading @@ -1404,14 +1399,14 @@ public class AudioDeviceBroker { sendLMsgNoDelay(MSG_L_SET_COMMUNICATION_DEVICE_FOR_CLIENT, SENDMSG_QUEUE, info); } /*package*/ void postScoAudioStateChanged(int state) { sendIMsgNoDelay(MSG_I_SCO_AUDIO_STATE_CHANGED, SENDMSG_QUEUE, state); } /*package*/ void postNotifyPreferredAudioProfileApplied(BluetoothDevice btDevice) { sendLMsgNoDelay(MSG_L_NOTIFY_PREFERRED_AUDIOPROFILE_APPLIED, SENDMSG_QUEUE, btDevice); } /*package*/ void postReceiveBtEvent(Intent intent) { sendLMsgNoDelay(MSG_L_RECEIVED_BT_EVENT, SENDMSG_QUEUE, intent); } /*package*/ static final class CommunicationDeviceInfo { final @NonNull IBinder mCb; // Identifies the requesting client for death handler final int mUid; // Requester UID Loading Loading @@ -1807,10 +1802,10 @@ public class AudioDeviceBroker { } break; case MSG_I_SCO_AUDIO_STATE_CHANGED: case MSG_L_RECEIVED_BT_EVENT: synchronized (mSetModeLock) { synchronized (mDeviceStateLock) { mBtHelper.onScoAudioStateChanged(msg.arg1); onReceiveBtEvent((Intent) msg.obj); } } break; Loading @@ -1821,29 +1816,17 @@ public class AudioDeviceBroker { } break; case MSG_I_BT_SERVICE_DISCONNECTED_PROFILE: if (msg.arg1 != BluetoothProfile.HEADSET) { synchronized (mSetModeLock) { synchronized (mDeviceStateLock) { mBtHelper.onBtProfileDisconnected(msg.arg1); mDeviceInventory.onBtProfileDisconnected(msg.arg1); } } else { synchronized (mSetModeLock) { synchronized (mDeviceStateLock) { mBtHelper.disconnectHeadset(); } } } break; case MSG_IL_BT_SERVICE_CONNECTED_PROFILE: if (msg.arg1 != BluetoothProfile.HEADSET) { synchronized (mDeviceStateLock) { mBtHelper.onBtProfileConnected(msg.arg1, (BluetoothProfile) msg.obj); } } else { synchronized (mSetModeLock) { synchronized (mDeviceStateLock) { mBtHelper.onHeadsetProfileConnected((BluetoothHeadset) msg.obj); } mBtHelper.onBtProfileConnected(msg.arg1, (BluetoothProfile) msg.obj); } } break; Loading Loading @@ -1978,7 +1961,6 @@ public class AudioDeviceBroker { private static final int MSG_L_SET_COMMUNICATION_DEVICE_FOR_CLIENT = 42; private static final int MSG_IL_UPDATE_COMMUNICATION_ROUTE_CLIENT = 43; private static final int MSG_I_SCO_AUDIO_STATE_CHANGED = 44; private static final int MSG_L_BT_ACTIVE_DEVICE_CHANGE_EXT = 45; // Loading @@ -1994,6 +1976,8 @@ public class AudioDeviceBroker { private static final int MSG_PERSIST_AUDIO_DEVICE_SETTINGS = 54; private static final int MSG_L_RECEIVED_BT_EVENT = 55; private static boolean isMessageHandledUnderWakelock(int msgId) { switch(msgId) { case MSG_L_SET_WIRED_DEVICE_CONNECTION_STATE: Loading
services/core/java/com/android/server/audio/AudioDeviceInventory.java +23 −1 Original line number Diff line number Diff line Loading @@ -1489,8 +1489,12 @@ public class AudioDeviceInventory { } } /*package*/ synchronized void onBtProfileDisconnected(int profile) { @GuardedBy("AudioDeviceBroker.mDeviceStateLock") /*package*/ void onBtProfileDisconnected(int profile) { switch (profile) { case BluetoothProfile.HEADSET: disconnectHeadset(); break; case BluetoothProfile.A2DP: disconnectA2dp(); break; Loading Loading @@ -1550,6 +1554,24 @@ public class AudioDeviceInventory { disconnectLeAudio(AudioSystem.DEVICE_OUT_BLE_BROADCAST); } @GuardedBy("AudioDeviceBroker.mDeviceStateLock") private void disconnectHeadset() { boolean disconnect = false; synchronized (mDevicesLock) { for (DeviceInfo di : mConnectedDevices.values()) { if (AudioSystem.isBluetoothScoDevice(di.mDeviceType)) { // There is only one HFP active device and setting the active // device to null will disconnect both in and out devices disconnect = true; break; } } } if (disconnect) { mDeviceBroker.onSetBtScoActiveDevice(null); } } // must be called before removing the device from mConnectedDevices // musicDevice argument is used when not AudioSystem.DEVICE_NONE instead of querying // from AudioSystem Loading
services/core/java/com/android/server/audio/AudioService.java +1 −12 Original line number Diff line number Diff line Loading @@ -61,7 +61,6 @@ import android.app.NotificationManager; import android.app.UidObserver; import android.app.role.OnRoleHoldersChangedListener; import android.app.role.RoleManager; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHeadset; import android.bluetooth.BluetoothProfile; Loading Loading @@ -1366,7 +1365,6 @@ public class AudioService extends IAudioService.Stub intentFilter.addAction(Intent.ACTION_USER_BACKGROUND); intentFilter.addAction(Intent.ACTION_USER_FOREGROUND); intentFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED); intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); intentFilter.addAction(Intent.ACTION_PACKAGES_SUSPENDED); intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); Loading Loading @@ -9570,7 +9568,7 @@ public class AudioService extends IAudioService.Stub mDockState = dockState; } else if (action.equals(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED) || action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) { mDeviceBroker.receiveBtEvent(intent); mDeviceBroker.postReceiveBtEvent(intent); } else if (action.equals(Intent.ACTION_SCREEN_ON)) { if (mMonitorRotation) { RotationHelper.enable(); Loading Loading @@ -9638,15 +9636,6 @@ public class AudioService extends IAudioService.Stub } catch (IllegalArgumentException e) { Slog.w(TAG, "Failed to apply DISALLOW_RECORD_AUDIO restriction: " + e); } } else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) { state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1); sDeviceLogger.enqueue(new EventLogger.StringEvent( "BluetoothAdapter ACTION_STATE_CHANGED with state " + state)); if (state == BluetoothAdapter.STATE_OFF || state == BluetoothAdapter.STATE_TURNING_OFF) { mDeviceBroker.disconnectAllBluetoothProfiles(); } } else if (action.equals(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION) || action.equals(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION)) { handleAudioEffectBroadcast(context, intent); Loading
services/core/java/com/android/server/audio/BtHelper.java +52 −56 Original line number Diff line number Diff line Loading @@ -191,10 +191,14 @@ public class BtHelper { if (adapter != null) { adapter.getProfileProxy(mDeviceBroker.getContext(), mBluetoothProfileServiceListener, BluetoothProfile.A2DP); adapter.getProfileProxy(mDeviceBroker.getContext(), mBluetoothProfileServiceListener, BluetoothProfile.A2DP_SINK); adapter.getProfileProxy(mDeviceBroker.getContext(), mBluetoothProfileServiceListener, BluetoothProfile.HEARING_AID); adapter.getProfileProxy(mDeviceBroker.getContext(), mBluetoothProfileServiceListener, BluetoothProfile.LE_AUDIO); adapter.getProfileProxy(mDeviceBroker.getContext(), mBluetoothProfileServiceListener, BluetoothProfile.LE_AUDIO_BROADCAST); } } Loading Loading @@ -261,27 +265,27 @@ public class BtHelper { // @GuardedBy("AudioDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.mDeviceStateLock") /*package*/ synchronized void receiveBtEvent(Intent intent) { /*package*/ synchronized void onReceiveBtEvent(Intent intent) { final String action = intent.getAction(); Log.i(TAG, "receiveBtEvent action: " + action + " mScoAudioState: " + mScoAudioState); Log.i(TAG, "onReceiveBtEvent action: " + action + " mScoAudioState: " + mScoAudioState); if (action.equals(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED)) { BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE, android.bluetooth.BluetoothDevice.class); setBtScoActiveDevice(btDevice); BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE, android.bluetooth.BluetoothDevice.class); onSetBtScoActiveDevice(btDevice); } else if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) { int btState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1); Log.i(TAG,"receiveBtEvent ACTION_AUDIO_STATE_CHANGED: "+btState); mDeviceBroker.postScoAudioStateChanged(btState); onScoAudioStateChanged(btState); } } /** * Exclusively called from AudioDeviceBroker when handling MSG_I_SCO_AUDIO_STATE_CHANGED * Exclusively called from AudioDeviceBroker when handling MSG_L_RECEIVED_BT_EVENT * as part of the serialization of the communication route selection */ // @GuardedBy("AudioDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.mDeviceStateLock") void onScoAudioStateChanged(int state) { private void onScoAudioStateChanged(int state) { boolean broadcast = false; int scoAudioState = AudioManager.SCO_AUDIO_STATE_ERROR; switch (state) { Loading @@ -294,10 +298,10 @@ public class BtHelper { // broadcast intent if the connection was initated by AudioService broadcast = true; } mDeviceBroker.setBluetoothScoOn(true, "BtHelper.receiveBtEvent"); mDeviceBroker.setBluetoothScoOn(true, "BtHelper.onScoAudioStateChanged"); break; case BluetoothHeadset.STATE_AUDIO_DISCONNECTED: mDeviceBroker.setBluetoothScoOn(false, "BtHelper.receiveBtEvent"); mDeviceBroker.setBluetoothScoOn(false, "BtHelper.onScoAudioStateChanged"); scoAudioState = AudioManager.SCO_AUDIO_STATE_DISCONNECTED; // There are two cases where we want to immediately reconnect audio: // 1) If a new start request was received while disconnecting: this was Loading Loading @@ -431,15 +435,6 @@ public class BtHelper { mScoConnectionState = state; } /*package*/ synchronized void disconnectAllBluetoothProfiles() { mDeviceBroker.postBtProfileDisconnected(BluetoothProfile.A2DP); mDeviceBroker.postBtProfileDisconnected(BluetoothProfile.A2DP_SINK); mDeviceBroker.postBtProfileDisconnected(BluetoothProfile.HEADSET); mDeviceBroker.postBtProfileDisconnected(BluetoothProfile.HEARING_AID); mDeviceBroker.postBtProfileDisconnected(BluetoothProfile.LE_AUDIO); mDeviceBroker.postBtProfileDisconnected(BluetoothProfile.LE_AUDIO_BROADCAST); } // @GuardedBy("AudioDeviceBroker.mSetModeLock") //@GuardedBy("AudioDeviceBroker.mDeviceStateLock") /*package*/ synchronized void resetBluetoothSco() { Loading @@ -450,18 +445,14 @@ public class BtHelper { mDeviceBroker.setBluetoothScoOn(false, "resetBluetoothSco"); } // @GuardedBy("AudioDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.mDeviceStateLock") /*package*/ synchronized void disconnectHeadset() { setBtScoActiveDevice(null); mBluetoothHeadset = null; } //@GuardedBy("AudioDeviceBroker.mDeviceStateLock") /*package*/ synchronized void onBtProfileDisconnected(int profile) { AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent( "BT profile " + BluetoothProfile.getProfileName(profile) + " disconnected")); switch (profile) { case BluetoothProfile.HEADSET: mBluetoothHeadset = null; break; case BluetoothProfile.A2DP: mA2dp = null; break; Loading @@ -471,14 +462,10 @@ public class BtHelper { case BluetoothProfile.LE_AUDIO: mLeAudio = null; break; case BluetoothProfile.A2DP_SINK: case BluetoothProfile.LE_AUDIO_BROADCAST: // shouldn't be received here as profile doesn't involve BtHelper Log.e(TAG, "onBtProfileDisconnected: Not a profile handled by BtHelper " + BluetoothProfile.getProfileName(profile)); // nothing to do in BtHelper break; default: // Not a valid profile to disconnect Log.e(TAG, "onBtProfileDisconnected: Not a valid profile to disconnect " Loading @@ -492,17 +479,31 @@ public class BtHelper { AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent( "BT profile " + BluetoothProfile.getProfileName(profile) + " connected to proxy " + proxy)); if (profile == BluetoothProfile.HEADSET) { switch (profile) { case BluetoothProfile.HEADSET: onHeadsetProfileConnected((BluetoothHeadset) proxy); return; } if (profile == BluetoothProfile.A2DP) { case BluetoothProfile.A2DP: mA2dp = (BluetoothA2dp) proxy; } else if (profile == BluetoothProfile.HEARING_AID) { break; case BluetoothProfile.HEARING_AID: mHearingAid = (BluetoothHearingAid) proxy; } else if (profile == BluetoothProfile.LE_AUDIO) { break; case BluetoothProfile.LE_AUDIO: mLeAudio = (BluetoothLeAudio) proxy; break; case BluetoothProfile.A2DP_SINK: case BluetoothProfile.LE_AUDIO_BROADCAST: // nothing to do in BtHelper return; default: // Not a valid profile to connect Log.e(TAG, "onBtProfileConnected: Not a valid profile to connect " + BluetoothProfile.getProfileName(profile)); break; } // this part is only for A2DP, LE Audio unicast and Hearing aid final List<BluetoothDevice> deviceList = proxy.getConnectedDevices(); if (deviceList.isEmpty()) { return; Loading @@ -523,7 +524,7 @@ public class BtHelper { // @GuardedBy("AudioDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.mDeviceStateLock") /*package*/ synchronized void onHeadsetProfileConnected(BluetoothHeadset headset) { private void onHeadsetProfileConnected(BluetoothHeadset headset) { // Discard timeout message mDeviceBroker.handleCancelFailureToConnectToBtHeadsetService(); mBluetoothHeadset = headset; Loading @@ -532,7 +533,7 @@ public class BtHelper { if (adapter != null) { activeDevices = adapter.getActiveDevices(BluetoothProfile.HEADSET); } setBtScoActiveDevice((activeDevices.size() > 0) ? activeDevices.get(0) : null); onSetBtScoActiveDevice((activeDevices.size() > 0) ? activeDevices.get(0) : null); // Refresh SCO audio state checkScoAudioState(); if (mScoAudioState != SCO_STATE_ACTIVATE_REQ Loading Loading @@ -643,20 +644,19 @@ public class BtHelper { // @GuardedBy("AudioDeviceBroker.mSetModeLock") //@GuardedBy("AudioDeviceBroker.mDeviceStateLock") @GuardedBy("BtHelper.this") private void setBtScoActiveDevice(BluetoothDevice btDevice) { Log.i(TAG, "setBtScoActiveDevice: " + getAnonymizedAddress(mBluetoothHeadsetDevice) /*package */ synchronized void onSetBtScoActiveDevice(BluetoothDevice btDevice) { Log.i(TAG, "onSetBtScoActiveDevice: " + getAnonymizedAddress(mBluetoothHeadsetDevice) + " -> " + getAnonymizedAddress(btDevice)); final BluetoothDevice previousActiveDevice = mBluetoothHeadsetDevice; if (Objects.equals(btDevice, previousActiveDevice)) { return; } if (!handleBtScoActiveDeviceChange(previousActiveDevice, false)) { Log.w(TAG, "setBtScoActiveDevice() failed to remove previous device " Log.w(TAG, "onSetBtScoActiveDevice() failed to remove previous device " + getAnonymizedAddress(previousActiveDevice)); } if (!handleBtScoActiveDeviceChange(btDevice, true)) { Log.e(TAG, "setBtScoActiveDevice() failed to add new device " Log.e(TAG, "onSetBtScoActiveDevice() failed to add new device " + getAnonymizedAddress(btDevice)); // set mBluetoothHeadsetDevice to null when failing to add new device btDevice = null; Loading @@ -677,16 +677,14 @@ public class BtHelper { case BluetoothProfile.HEADSET: case BluetoothProfile.HEARING_AID: case BluetoothProfile.LE_AUDIO: case BluetoothProfile.A2DP_SINK: case BluetoothProfile.LE_AUDIO_BROADCAST: AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent( "BT profile service: connecting " + BluetoothProfile.getProfileName(profile) + " profile")); mDeviceBroker.postBtProfileConnected(profile, proxy); break; case BluetoothProfile.A2DP_SINK: // no A2DP sink functionality handled by BtHelper case BluetoothProfile.LE_AUDIO_BROADCAST: // no broadcast functionality handled by BtHelper default: break; } Loading @@ -698,16 +696,14 @@ public class BtHelper { case BluetoothProfile.HEADSET: case BluetoothProfile.HEARING_AID: case BluetoothProfile.LE_AUDIO: case BluetoothProfile.A2DP_SINK: case BluetoothProfile.LE_AUDIO_BROADCAST: AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent( "BT profile service: disconnecting " + BluetoothProfile.getProfileName(profile) + " profile")); mDeviceBroker.postBtProfileDisconnected(profile); break; case BluetoothProfile.A2DP_SINK: // no A2DP sink functionality handled by BtHelper case BluetoothProfile.LE_AUDIO_BROADCAST: // no broadcast functionality handled by BtHelper default: break; } Loading