Loading android/app/src/com/android/bluetooth/a2dp/A2dpService.java +18 −26 Original line number Diff line number Diff line Loading @@ -497,32 +497,13 @@ public class A2dpService extends ProfileService { previousActiveDevice = mActiveDevice; } int prevActiveConnectionState = getConnectionState(previousActiveDevice); // As per b/202602952, if we remove the active device due to a disconnection, // we need to check if another device is connected and set it active instead. // Calling this before any other active related calls has the same effect as // a classic active device switch. BluetoothDevice fallbackdevice = getFallbackDevice(); if (fallbackdevice != null && prevActiveConnectionState != BluetoothProfile.STATE_CONNECTED) { setActiveDevice(fallbackdevice); return; } // This needs to happen before we inform the audio manager that the device // disconnected. Please see comment in updateAndBroadcastActiveDevice() for why. updateAndBroadcastActiveDevice(null); // Make sure the Audio Manager knows the previous Active device is disconnected. // However, if A2DP is still connected and not forcing stop audio for that remote // device, the user has explicitly switched the output to the local device and music // should continue playing. Otherwise, the remote device has been indeed disconnected // and audio should be suspended before switching the output to the local device. boolean stopAudio = forceStopPlayingAudio || (prevActiveConnectionState != BluetoothProfile.STATE_CONNECTED); // Make sure the Audio Manager knows the previous Active device is removed. mAudioManager.handleBluetoothActiveDeviceChanged(null, previousActiveDevice, BluetoothProfileConnectionInfo.createA2dpInfo(!stopAudio, -1)); BluetoothProfileConnectionInfo.createA2dpInfo(!forceStopPlayingAudio, -1)); synchronized (mStateMachines) { // Make sure the Active device in native layer is set to null and audio is off Loading Loading @@ -566,10 +547,22 @@ public class A2dpService extends ProfileService { * @return true on success, otherwise false */ public boolean setActiveDevice(BluetoothDevice device) { return setActiveDevice(device, false); } /** * Set the active device. * * @param device the active device * @param hasFallbackDevice whether it has fallback device when the {@code device} * is {@code null}. * @return true on success, otherwise false */ public boolean setActiveDevice(BluetoothDevice device, boolean hasFallbackDevice) { synchronized (mActiveSwitchingGuard) { if (device == null) { // Remove active device and continue playing audio only if necessary. removeActiveDevice(false); removeActiveDevice(!hasFallbackDevice); return true; } Loading Loading @@ -1225,10 +1218,9 @@ public class A2dpService extends ProfileService { if (toState == BluetoothProfile.STATE_CONNECTED && (mMaxConnectedAudioDevices == 1)) { setActiveDevice(device); } // Check if the active device is not connected anymore if (isActiveDevice(device) && (fromState == BluetoothProfile.STATE_CONNECTED)) { setActiveDevice(null); } // When disconnected, ActiveDeviceManager will call setActiveDevice(null) // Check if the device is disconnected - if unbond, remove the state machine if (toState == BluetoothProfile.STATE_DISCONNECTED) { if (mAdapterService.getBondState(device) == BluetoothDevice.BOND_NONE) { Loading android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java +64 −44 Original line number Diff line number Diff line Loading @@ -279,7 +279,7 @@ class ActiveDeviceManager { if (mPendingA2dpActiveDevice == null) { // select the device as active if not lazy active setA2dpActiveDevice(device); setLeAudioActiveDevice(null); setLeAudioActiveDevice(null, true); } } break; Loading @@ -292,12 +292,10 @@ class ActiveDeviceManager { + "device " + device + " disconnected"); } mA2dpConnectedDevices.remove(device); if (Objects.equals(mA2dpActiveDevice, device)) { if (mA2dpConnectedDevices.isEmpty()) { if (Objects.equals(mA2dpActiveDevice, device) && !setFallbackDeviceActive() && mA2dpConnectedDevices.isEmpty()) { setA2dpActiveDevice(null); } setFallbackDeviceActive(); } } } break; Loading @@ -312,7 +310,7 @@ class ActiveDeviceManager { } if (device != null && !Objects.equals(mA2dpActiveDevice, device)) { setHearingAidActiveDevice(null); setLeAudioActiveDevice(null); setLeAudioActiveDevice(null, true); } if (mHfpConnectedDevices.contains(device)) { setHfpActiveDevice(device); Loading Loading @@ -379,12 +377,10 @@ class ActiveDeviceManager { + "device " + device + " disconnected"); } mHfpConnectedDevices.remove(device); if (Objects.equals(mHfpActiveDevice, device)) { if (mHfpConnectedDevices.isEmpty()) { if (Objects.equals(mHfpActiveDevice, device) && !setFallbackDeviceActive() && mHfpConnectedDevices.isEmpty()) { setHfpActiveDevice(null); } setFallbackDeviceActive(); } } } break; Loading Loading @@ -431,9 +427,9 @@ class ActiveDeviceManager { mHearingAidConnectedDevices.add(device); // New connected hearing aid device: select it as active setHearingAidActiveDevice(device); setA2dpActiveDevice(null); setA2dpActiveDevice(null, true); setHfpActiveDevice(null); setLeAudioActiveDevice(null); setLeAudioActiveDevice(null, true); break; } if (prevState == BluetoothProfile.STATE_CONNECTED) { Loading @@ -443,12 +439,11 @@ class ActiveDeviceManager { + "_CHANGED): device " + device + " disconnected"); } mHearingAidConnectedDevices.remove(device); if (Objects.equals(mHearingAidActiveDevice, device)) { if (mHearingAidConnectedDevices.isEmpty()) { if (Objects.equals(mHearingAidActiveDevice, device) && !setFallbackDeviceActive() && mHearingAidConnectedDevices.isEmpty()) { setHearingAidActiveDevice(null); } setFallbackDeviceActive(); } } } break; Loading @@ -464,9 +459,9 @@ class ActiveDeviceManager { // Just assign locally the new value mHearingAidActiveDevice = device; if (device != null) { setA2dpActiveDevice(null); setA2dpActiveDevice(null, true); setHfpActiveDevice(null); setLeAudioActiveDevice(null); setLeAudioActiveDevice(null, true); } } break; Loading @@ -481,12 +476,17 @@ class ActiveDeviceManager { // Nothing has changed break; } final LeAudioService leAudioService = mFactory.getLeAudioService(); if (nextState == BluetoothProfile.STATE_CONNECTED) { // Device connected if (DBG) { Log.d(TAG, "handleMessage(MESSAGE_LE_AUDIO_ACTION_CONNECTION_STATE" + "_CHANGED): device " + device + " connected"); } if (leAudioService != null && device != null) { leAudioService.deviceConnected(device); } if (mLeAudioConnectedDevices.contains(device)) { break; // The device is already connected } Loading @@ -495,12 +495,12 @@ class ActiveDeviceManager { && mPendingLeHearingAidActiveDevice.isEmpty()) { // New connected LE audio device: select it as active setLeAudioActiveDevice(device); setA2dpActiveDevice(null); setA2dpActiveDevice(null, true); setHfpActiveDevice(null); } else if (mPendingLeHearingAidActiveDevice.contains(device)) { setLeHearingAidActiveDevice(device); setHearingAidActiveDevice(null); setA2dpActiveDevice(null); setA2dpActiveDevice(null, true); setHfpActiveDevice(null); } break; Loading @@ -513,11 +513,15 @@ class ActiveDeviceManager { } mLeAudioConnectedDevices.remove(device); mLeHearingAidConnectedDevices.remove(device); boolean hasFallbackDevice = false; if (Objects.equals(mLeAudioActiveDevice, device)) { if (mLeAudioConnectedDevices.isEmpty()) { hasFallbackDevice = setFallbackDeviceActive(); if (!hasFallbackDevice && mLeAudioConnectedDevices.isEmpty()) { setLeAudioActiveDevice(null); } setFallbackDeviceActive(); } if (leAudioService != null && device != null) { leAudioService.deviceDisconnected(device, hasFallbackDevice); } } } Loading @@ -536,7 +540,7 @@ class ActiveDeviceManager { } // Just assign locally the new value if (device != null && !Objects.equals(mLeAudioActiveDevice, device)) { setA2dpActiveDevice(null); setA2dpActiveDevice(null, true); setHfpActiveDevice(null); setHearingAidActiveDevice(null); } Loading Loading @@ -572,7 +576,7 @@ class ActiveDeviceManager { // New connected LE hearing aid device: select it as active setLeHearingAidActiveDevice(device); setHearingAidActiveDevice(null); setA2dpActiveDevice(null); setA2dpActiveDevice(null, true); setHfpActiveDevice(null); } break; Loading Loading @@ -605,7 +609,7 @@ class ActiveDeviceManager { } // Just assign locally the new value if (device != null && !Objects.equals(mLeHearingAidActiveDevice, device)) { setA2dpActiveDevice(null); setA2dpActiveDevice(null, true); setHfpActiveDevice(null); setHearingAidActiveDevice(null); } Loading @@ -622,7 +626,7 @@ class ActiveDeviceManager { case AudioManager.MODE_NORMAL: { if (mPendingA2dpActiveDevice != null) { setA2dpActiveDevice(mPendingA2dpActiveDevice); setLeAudioActiveDevice(null); setLeAudioActiveDevice(null, true); } break; } Loading Loading @@ -760,6 +764,10 @@ class ActiveDeviceManager { } private void setA2dpActiveDevice(BluetoothDevice device) { setA2dpActiveDevice(device, false); } private void setA2dpActiveDevice(BluetoothDevice device, boolean hasFallbackDevice) { if (DBG) { Log.d(TAG, "setA2dpActiveDevice(" + device + ")"); } Loading @@ -767,7 +775,7 @@ class ActiveDeviceManager { if (a2dpService == null) { return; } if (!a2dpService.setActiveDevice(device)) { if (!a2dpService.setActiveDevice(device, hasFallbackDevice)) { return; } mA2dpActiveDevice = device; Loading Loading @@ -797,6 +805,10 @@ class ActiveDeviceManager { } private void setHearingAidActiveDevice(BluetoothDevice device) { setHearingAidActiveDevice(device, false); } private void setHearingAidActiveDevice(BluetoothDevice device, boolean hasFallbackDevice) { if (DBG) { Log.d(TAG, "setHearingAidActiveDevice(" + device + ")"); } Loading @@ -804,13 +816,16 @@ class ActiveDeviceManager { if (hearingAidService == null) { return; } if (!hearingAidService.setActiveDevice(device)) { if (!hearingAidService.setActiveDevice(device, hasFallbackDevice)) { return; } mHearingAidActiveDevice = device; } private void setLeAudioActiveDevice(BluetoothDevice device) { setLeAudioActiveDevice(device, false); } private void setLeAudioActiveDevice(BluetoothDevice device, boolean hasFallbackDevice) { if (DBG) { Log.d(TAG, "setLeAudioActiveDevice(" + device + ")"); } Loading @@ -818,7 +833,7 @@ class ActiveDeviceManager { if (leAudioService == null) { return; } if (!leAudioService.setActiveDevice(device)) { if (!leAudioService.setActiveDevice(device, hasFallbackDevice)) { return; } mLeAudioActiveDevice = device; Loading @@ -829,6 +844,9 @@ class ActiveDeviceManager { } private void setLeHearingAidActiveDevice(BluetoothDevice device) { if (DBG) { Log.d(TAG, "setLeHearingAidActiveDevice(" + device + ")"); } if (!Objects.equals(mLeAudioActiveDevice, device)) { setLeAudioActiveDevice(device); } Loading @@ -839,13 +857,13 @@ class ActiveDeviceManager { } } private void setFallbackDeviceActive() { private boolean setFallbackDeviceActive() { if (DBG) { Log.d(TAG, "setFallbackDeviceActive"); } DatabaseManager dbManager = mAdapterService.getDatabase(); if (dbManager == null) { return; return false; } List<BluetoothDevice> connectedHearingAidDevices = new ArrayList<>(); if (!mHearingAidConnectedDevices.isEmpty()) { Loading @@ -863,19 +881,19 @@ class ActiveDeviceManager { Log.d(TAG, "set hearing aid device active: " + device); } setHearingAidActiveDevice(device); setA2dpActiveDevice(null); setA2dpActiveDevice(null, true); setHfpActiveDevice(null); setLeAudioActiveDevice(null); setLeAudioActiveDevice(null, true); } else { if (DBG) { Log.d(TAG, "set LE hearing aid device active: " + device); } setLeHearingAidActiveDevice(device); setHearingAidActiveDevice(null); setA2dpActiveDevice(null); setHearingAidActiveDevice(null, true); setA2dpActiveDevice(null, true); setHfpActiveDevice(null); } return; return true; } } Loading Loading @@ -919,14 +937,14 @@ class ActiveDeviceManager { setA2dpActiveDevice(device); if (headsetFallbackDevice != null) { setHfpActiveDevice(device); setLeAudioActiveDevice(null); setLeAudioActiveDevice(null, true); } } else { if (DBG) { Log.d(TAG, "set LE audio device active: " + device); } setLeAudioActiveDevice(device); setA2dpActiveDevice(null); setA2dpActiveDevice(null, true); setHfpActiveDevice(null); } } else { Loading @@ -937,18 +955,20 @@ class ActiveDeviceManager { setHfpActiveDevice(device); if (a2dpFallbackDevice != null) { setA2dpActiveDevice(a2dpFallbackDevice); setLeAudioActiveDevice(null); setLeAudioActiveDevice(null, true); } } else { if (DBG) { Log.d(TAG, "set LE audio device active: " + device); } setLeAudioActiveDevice(device); setA2dpActiveDevice(null); setA2dpActiveDevice(null, true); setHfpActiveDevice(null); } } return true; } return false; } private void resetState() { Loading android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java +16 −6 Original line number Diff line number Diff line Loading @@ -571,13 +571,24 @@ public class HearingAidService extends ProfileService { * @return true on success, otherwise false */ public boolean setActiveDevice(BluetoothDevice device) { return setActiveDevice(device, false); } /** * Set the active device. * @param device the new active device * @param hasFallbackDevice whether it has fallback device when the {@code device} * is {@code null}. * @return true on success, otherwise false */ public boolean setActiveDevice(BluetoothDevice device, boolean hasFallbackDevice) { if (DBG) { Log.d(TAG, "setActiveDevice:" + device); } synchronized (mStateMachines) { if (device == null) { if (mActiveDeviceHiSyncId != BluetoothHearingAid.HI_SYNC_ID_INVALID) { reportActiveDevice(null); reportActiveDevice(null, hasFallbackDevice); mActiveDeviceHiSyncId = BluetoothHearingAid.HI_SYNC_ID_INVALID; } return true; Loading @@ -590,7 +601,7 @@ public class HearingAidService extends ProfileService { BluetoothHearingAid.HI_SYNC_ID_INVALID); if (deviceHiSyncId != mActiveDeviceHiSyncId) { mActiveDeviceHiSyncId = deviceHiSyncId; reportActiveDevice(device); reportActiveDevice(device, false); } } return true; Loading Loading @@ -701,7 +712,7 @@ public class HearingAidService extends ProfileService { * Report the active device change to the active device manager and the media framework. * @param device the new active device; or null if no active device */ private void reportActiveDevice(BluetoothDevice device) { private void reportActiveDevice(BluetoothDevice device, boolean hasFallbackDevice) { if (DBG) { Log.d(TAG, "reportActiveDevice(" + device + ")"); } Loading @@ -716,8 +727,7 @@ public class HearingAidService extends ProfileService { | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); sendBroadcast(intent, BLUETOOTH_CONNECT, Utils.getTempAllowlistBroadcastOptions()); boolean stopAudio = device == null && (getConnectionState(mPreviousAudioDevice) != BluetoothProfile.STATE_CONNECTED); boolean stopAudio = device == null && !hasFallbackDevice; if (DBG) { Log.d(TAG, "Hearing Aid audio: " + mPreviousAudioDevice + " -> " + device + ". Stop audio: " + stopAudio); Loading Loading @@ -822,7 +832,7 @@ public class HearingAidService extends ProfileService { } } if (fromState == BluetoothProfile.STATE_CONNECTED && getConnectedDevices().isEmpty()) { setActiveDevice(null); // When disconnected, ActiveDeviceManager will call setActiveDevice(null) long myHiSyncId = getHiSyncId(device); mHiSyncIdConnectedMap.put(myHiSyncId, false); } Loading Loading
android/app/src/com/android/bluetooth/a2dp/A2dpService.java +18 −26 Original line number Diff line number Diff line Loading @@ -497,32 +497,13 @@ public class A2dpService extends ProfileService { previousActiveDevice = mActiveDevice; } int prevActiveConnectionState = getConnectionState(previousActiveDevice); // As per b/202602952, if we remove the active device due to a disconnection, // we need to check if another device is connected and set it active instead. // Calling this before any other active related calls has the same effect as // a classic active device switch. BluetoothDevice fallbackdevice = getFallbackDevice(); if (fallbackdevice != null && prevActiveConnectionState != BluetoothProfile.STATE_CONNECTED) { setActiveDevice(fallbackdevice); return; } // This needs to happen before we inform the audio manager that the device // disconnected. Please see comment in updateAndBroadcastActiveDevice() for why. updateAndBroadcastActiveDevice(null); // Make sure the Audio Manager knows the previous Active device is disconnected. // However, if A2DP is still connected and not forcing stop audio for that remote // device, the user has explicitly switched the output to the local device and music // should continue playing. Otherwise, the remote device has been indeed disconnected // and audio should be suspended before switching the output to the local device. boolean stopAudio = forceStopPlayingAudio || (prevActiveConnectionState != BluetoothProfile.STATE_CONNECTED); // Make sure the Audio Manager knows the previous Active device is removed. mAudioManager.handleBluetoothActiveDeviceChanged(null, previousActiveDevice, BluetoothProfileConnectionInfo.createA2dpInfo(!stopAudio, -1)); BluetoothProfileConnectionInfo.createA2dpInfo(!forceStopPlayingAudio, -1)); synchronized (mStateMachines) { // Make sure the Active device in native layer is set to null and audio is off Loading Loading @@ -566,10 +547,22 @@ public class A2dpService extends ProfileService { * @return true on success, otherwise false */ public boolean setActiveDevice(BluetoothDevice device) { return setActiveDevice(device, false); } /** * Set the active device. * * @param device the active device * @param hasFallbackDevice whether it has fallback device when the {@code device} * is {@code null}. * @return true on success, otherwise false */ public boolean setActiveDevice(BluetoothDevice device, boolean hasFallbackDevice) { synchronized (mActiveSwitchingGuard) { if (device == null) { // Remove active device and continue playing audio only if necessary. removeActiveDevice(false); removeActiveDevice(!hasFallbackDevice); return true; } Loading Loading @@ -1225,10 +1218,9 @@ public class A2dpService extends ProfileService { if (toState == BluetoothProfile.STATE_CONNECTED && (mMaxConnectedAudioDevices == 1)) { setActiveDevice(device); } // Check if the active device is not connected anymore if (isActiveDevice(device) && (fromState == BluetoothProfile.STATE_CONNECTED)) { setActiveDevice(null); } // When disconnected, ActiveDeviceManager will call setActiveDevice(null) // Check if the device is disconnected - if unbond, remove the state machine if (toState == BluetoothProfile.STATE_DISCONNECTED) { if (mAdapterService.getBondState(device) == BluetoothDevice.BOND_NONE) { Loading
android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java +64 −44 Original line number Diff line number Diff line Loading @@ -279,7 +279,7 @@ class ActiveDeviceManager { if (mPendingA2dpActiveDevice == null) { // select the device as active if not lazy active setA2dpActiveDevice(device); setLeAudioActiveDevice(null); setLeAudioActiveDevice(null, true); } } break; Loading @@ -292,12 +292,10 @@ class ActiveDeviceManager { + "device " + device + " disconnected"); } mA2dpConnectedDevices.remove(device); if (Objects.equals(mA2dpActiveDevice, device)) { if (mA2dpConnectedDevices.isEmpty()) { if (Objects.equals(mA2dpActiveDevice, device) && !setFallbackDeviceActive() && mA2dpConnectedDevices.isEmpty()) { setA2dpActiveDevice(null); } setFallbackDeviceActive(); } } } break; Loading @@ -312,7 +310,7 @@ class ActiveDeviceManager { } if (device != null && !Objects.equals(mA2dpActiveDevice, device)) { setHearingAidActiveDevice(null); setLeAudioActiveDevice(null); setLeAudioActiveDevice(null, true); } if (mHfpConnectedDevices.contains(device)) { setHfpActiveDevice(device); Loading Loading @@ -379,12 +377,10 @@ class ActiveDeviceManager { + "device " + device + " disconnected"); } mHfpConnectedDevices.remove(device); if (Objects.equals(mHfpActiveDevice, device)) { if (mHfpConnectedDevices.isEmpty()) { if (Objects.equals(mHfpActiveDevice, device) && !setFallbackDeviceActive() && mHfpConnectedDevices.isEmpty()) { setHfpActiveDevice(null); } setFallbackDeviceActive(); } } } break; Loading Loading @@ -431,9 +427,9 @@ class ActiveDeviceManager { mHearingAidConnectedDevices.add(device); // New connected hearing aid device: select it as active setHearingAidActiveDevice(device); setA2dpActiveDevice(null); setA2dpActiveDevice(null, true); setHfpActiveDevice(null); setLeAudioActiveDevice(null); setLeAudioActiveDevice(null, true); break; } if (prevState == BluetoothProfile.STATE_CONNECTED) { Loading @@ -443,12 +439,11 @@ class ActiveDeviceManager { + "_CHANGED): device " + device + " disconnected"); } mHearingAidConnectedDevices.remove(device); if (Objects.equals(mHearingAidActiveDevice, device)) { if (mHearingAidConnectedDevices.isEmpty()) { if (Objects.equals(mHearingAidActiveDevice, device) && !setFallbackDeviceActive() && mHearingAidConnectedDevices.isEmpty()) { setHearingAidActiveDevice(null); } setFallbackDeviceActive(); } } } break; Loading @@ -464,9 +459,9 @@ class ActiveDeviceManager { // Just assign locally the new value mHearingAidActiveDevice = device; if (device != null) { setA2dpActiveDevice(null); setA2dpActiveDevice(null, true); setHfpActiveDevice(null); setLeAudioActiveDevice(null); setLeAudioActiveDevice(null, true); } } break; Loading @@ -481,12 +476,17 @@ class ActiveDeviceManager { // Nothing has changed break; } final LeAudioService leAudioService = mFactory.getLeAudioService(); if (nextState == BluetoothProfile.STATE_CONNECTED) { // Device connected if (DBG) { Log.d(TAG, "handleMessage(MESSAGE_LE_AUDIO_ACTION_CONNECTION_STATE" + "_CHANGED): device " + device + " connected"); } if (leAudioService != null && device != null) { leAudioService.deviceConnected(device); } if (mLeAudioConnectedDevices.contains(device)) { break; // The device is already connected } Loading @@ -495,12 +495,12 @@ class ActiveDeviceManager { && mPendingLeHearingAidActiveDevice.isEmpty()) { // New connected LE audio device: select it as active setLeAudioActiveDevice(device); setA2dpActiveDevice(null); setA2dpActiveDevice(null, true); setHfpActiveDevice(null); } else if (mPendingLeHearingAidActiveDevice.contains(device)) { setLeHearingAidActiveDevice(device); setHearingAidActiveDevice(null); setA2dpActiveDevice(null); setA2dpActiveDevice(null, true); setHfpActiveDevice(null); } break; Loading @@ -513,11 +513,15 @@ class ActiveDeviceManager { } mLeAudioConnectedDevices.remove(device); mLeHearingAidConnectedDevices.remove(device); boolean hasFallbackDevice = false; if (Objects.equals(mLeAudioActiveDevice, device)) { if (mLeAudioConnectedDevices.isEmpty()) { hasFallbackDevice = setFallbackDeviceActive(); if (!hasFallbackDevice && mLeAudioConnectedDevices.isEmpty()) { setLeAudioActiveDevice(null); } setFallbackDeviceActive(); } if (leAudioService != null && device != null) { leAudioService.deviceDisconnected(device, hasFallbackDevice); } } } Loading @@ -536,7 +540,7 @@ class ActiveDeviceManager { } // Just assign locally the new value if (device != null && !Objects.equals(mLeAudioActiveDevice, device)) { setA2dpActiveDevice(null); setA2dpActiveDevice(null, true); setHfpActiveDevice(null); setHearingAidActiveDevice(null); } Loading Loading @@ -572,7 +576,7 @@ class ActiveDeviceManager { // New connected LE hearing aid device: select it as active setLeHearingAidActiveDevice(device); setHearingAidActiveDevice(null); setA2dpActiveDevice(null); setA2dpActiveDevice(null, true); setHfpActiveDevice(null); } break; Loading Loading @@ -605,7 +609,7 @@ class ActiveDeviceManager { } // Just assign locally the new value if (device != null && !Objects.equals(mLeHearingAidActiveDevice, device)) { setA2dpActiveDevice(null); setA2dpActiveDevice(null, true); setHfpActiveDevice(null); setHearingAidActiveDevice(null); } Loading @@ -622,7 +626,7 @@ class ActiveDeviceManager { case AudioManager.MODE_NORMAL: { if (mPendingA2dpActiveDevice != null) { setA2dpActiveDevice(mPendingA2dpActiveDevice); setLeAudioActiveDevice(null); setLeAudioActiveDevice(null, true); } break; } Loading Loading @@ -760,6 +764,10 @@ class ActiveDeviceManager { } private void setA2dpActiveDevice(BluetoothDevice device) { setA2dpActiveDevice(device, false); } private void setA2dpActiveDevice(BluetoothDevice device, boolean hasFallbackDevice) { if (DBG) { Log.d(TAG, "setA2dpActiveDevice(" + device + ")"); } Loading @@ -767,7 +775,7 @@ class ActiveDeviceManager { if (a2dpService == null) { return; } if (!a2dpService.setActiveDevice(device)) { if (!a2dpService.setActiveDevice(device, hasFallbackDevice)) { return; } mA2dpActiveDevice = device; Loading Loading @@ -797,6 +805,10 @@ class ActiveDeviceManager { } private void setHearingAidActiveDevice(BluetoothDevice device) { setHearingAidActiveDevice(device, false); } private void setHearingAidActiveDevice(BluetoothDevice device, boolean hasFallbackDevice) { if (DBG) { Log.d(TAG, "setHearingAidActiveDevice(" + device + ")"); } Loading @@ -804,13 +816,16 @@ class ActiveDeviceManager { if (hearingAidService == null) { return; } if (!hearingAidService.setActiveDevice(device)) { if (!hearingAidService.setActiveDevice(device, hasFallbackDevice)) { return; } mHearingAidActiveDevice = device; } private void setLeAudioActiveDevice(BluetoothDevice device) { setLeAudioActiveDevice(device, false); } private void setLeAudioActiveDevice(BluetoothDevice device, boolean hasFallbackDevice) { if (DBG) { Log.d(TAG, "setLeAudioActiveDevice(" + device + ")"); } Loading @@ -818,7 +833,7 @@ class ActiveDeviceManager { if (leAudioService == null) { return; } if (!leAudioService.setActiveDevice(device)) { if (!leAudioService.setActiveDevice(device, hasFallbackDevice)) { return; } mLeAudioActiveDevice = device; Loading @@ -829,6 +844,9 @@ class ActiveDeviceManager { } private void setLeHearingAidActiveDevice(BluetoothDevice device) { if (DBG) { Log.d(TAG, "setLeHearingAidActiveDevice(" + device + ")"); } if (!Objects.equals(mLeAudioActiveDevice, device)) { setLeAudioActiveDevice(device); } Loading @@ -839,13 +857,13 @@ class ActiveDeviceManager { } } private void setFallbackDeviceActive() { private boolean setFallbackDeviceActive() { if (DBG) { Log.d(TAG, "setFallbackDeviceActive"); } DatabaseManager dbManager = mAdapterService.getDatabase(); if (dbManager == null) { return; return false; } List<BluetoothDevice> connectedHearingAidDevices = new ArrayList<>(); if (!mHearingAidConnectedDevices.isEmpty()) { Loading @@ -863,19 +881,19 @@ class ActiveDeviceManager { Log.d(TAG, "set hearing aid device active: " + device); } setHearingAidActiveDevice(device); setA2dpActiveDevice(null); setA2dpActiveDevice(null, true); setHfpActiveDevice(null); setLeAudioActiveDevice(null); setLeAudioActiveDevice(null, true); } else { if (DBG) { Log.d(TAG, "set LE hearing aid device active: " + device); } setLeHearingAidActiveDevice(device); setHearingAidActiveDevice(null); setA2dpActiveDevice(null); setHearingAidActiveDevice(null, true); setA2dpActiveDevice(null, true); setHfpActiveDevice(null); } return; return true; } } Loading Loading @@ -919,14 +937,14 @@ class ActiveDeviceManager { setA2dpActiveDevice(device); if (headsetFallbackDevice != null) { setHfpActiveDevice(device); setLeAudioActiveDevice(null); setLeAudioActiveDevice(null, true); } } else { if (DBG) { Log.d(TAG, "set LE audio device active: " + device); } setLeAudioActiveDevice(device); setA2dpActiveDevice(null); setA2dpActiveDevice(null, true); setHfpActiveDevice(null); } } else { Loading @@ -937,18 +955,20 @@ class ActiveDeviceManager { setHfpActiveDevice(device); if (a2dpFallbackDevice != null) { setA2dpActiveDevice(a2dpFallbackDevice); setLeAudioActiveDevice(null); setLeAudioActiveDevice(null, true); } } else { if (DBG) { Log.d(TAG, "set LE audio device active: " + device); } setLeAudioActiveDevice(device); setA2dpActiveDevice(null); setA2dpActiveDevice(null, true); setHfpActiveDevice(null); } } return true; } return false; } private void resetState() { Loading
android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java +16 −6 Original line number Diff line number Diff line Loading @@ -571,13 +571,24 @@ public class HearingAidService extends ProfileService { * @return true on success, otherwise false */ public boolean setActiveDevice(BluetoothDevice device) { return setActiveDevice(device, false); } /** * Set the active device. * @param device the new active device * @param hasFallbackDevice whether it has fallback device when the {@code device} * is {@code null}. * @return true on success, otherwise false */ public boolean setActiveDevice(BluetoothDevice device, boolean hasFallbackDevice) { if (DBG) { Log.d(TAG, "setActiveDevice:" + device); } synchronized (mStateMachines) { if (device == null) { if (mActiveDeviceHiSyncId != BluetoothHearingAid.HI_SYNC_ID_INVALID) { reportActiveDevice(null); reportActiveDevice(null, hasFallbackDevice); mActiveDeviceHiSyncId = BluetoothHearingAid.HI_SYNC_ID_INVALID; } return true; Loading @@ -590,7 +601,7 @@ public class HearingAidService extends ProfileService { BluetoothHearingAid.HI_SYNC_ID_INVALID); if (deviceHiSyncId != mActiveDeviceHiSyncId) { mActiveDeviceHiSyncId = deviceHiSyncId; reportActiveDevice(device); reportActiveDevice(device, false); } } return true; Loading Loading @@ -701,7 +712,7 @@ public class HearingAidService extends ProfileService { * Report the active device change to the active device manager and the media framework. * @param device the new active device; or null if no active device */ private void reportActiveDevice(BluetoothDevice device) { private void reportActiveDevice(BluetoothDevice device, boolean hasFallbackDevice) { if (DBG) { Log.d(TAG, "reportActiveDevice(" + device + ")"); } Loading @@ -716,8 +727,7 @@ public class HearingAidService extends ProfileService { | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); sendBroadcast(intent, BLUETOOTH_CONNECT, Utils.getTempAllowlistBroadcastOptions()); boolean stopAudio = device == null && (getConnectionState(mPreviousAudioDevice) != BluetoothProfile.STATE_CONNECTED); boolean stopAudio = device == null && !hasFallbackDevice; if (DBG) { Log.d(TAG, "Hearing Aid audio: " + mPreviousAudioDevice + " -> " + device + ". Stop audio: " + stopAudio); Loading Loading @@ -822,7 +832,7 @@ public class HearingAidService extends ProfileService { } } if (fromState == BluetoothProfile.STATE_CONNECTED && getConnectedDevices().isEmpty()) { setActiveDevice(null); // When disconnected, ActiveDeviceManager will call setActiveDevice(null) long myHiSyncId = getHiSyncId(device); mHiSyncIdConnectedMap.put(myHiSyncId, false); } Loading