Loading android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java +37 −24 Original line number Diff line number Diff line Loading @@ -371,7 +371,7 @@ class ActiveDeviceManager { } } else if (mPendingLeHearingAidActiveDevice.contains(device)) { setLeHearingAidActiveDevice(device); setHearingAidActiveDevice(null); setHearingAidActiveDevice(null, true); setA2dpActiveDevice(null, true); setHfpActiveDevice(null); } Loading @@ -394,7 +394,7 @@ class ActiveDeviceManager { } else { // New connected device: select it as active setLeHearingAidActiveDevice(device); setHearingAidActiveDevice(null); setHearingAidActiveDevice(null, true); setA2dpActiveDevice(null, true); setHfpActiveDevice(null); } Loading Loading @@ -437,10 +437,9 @@ class ActiveDeviceManager { } mHearingAidConnectedDevices.remove(device); if (mHearingAidActiveDevices.remove(device) && mHearingAidActiveDevices.isEmpty()) { if (mHearingAidConnectedDevices.isEmpty()) { setHearingAidActiveDevice(null); if (!setFallbackDeviceActiveLocked()) { setHearingAidActiveDevice(null, false); } setFallbackDeviceActiveLocked(); } } } Loading Loading @@ -500,7 +499,7 @@ class ActiveDeviceManager { } if (!Objects.equals(mA2dpActiveDevice, device)) { if (device != null) { setHearingAidActiveDevice(null); setHearingAidActiveDevice(null, true); } if (Utils.isDualModeAudioEnabled() && mAdapterService.isAllSupportedClassicAudioProfilesActive(device)) { Loading Loading @@ -534,7 +533,7 @@ class ActiveDeviceManager { } if (!Objects.equals(mHfpActiveDevice, device)) { if (device != null) { setHearingAidActiveDevice(null); setHearingAidActiveDevice(null, true); } if (Utils.isDualModeAudioEnabled() && mAdapterService.isAllSupportedClassicAudioProfilesActive(device)) { Loading Loading @@ -590,7 +589,7 @@ class ActiveDeviceManager { setA2dpActiveDevice(null, true); setHfpActiveDevice(null); } setHearingAidActiveDevice(null); setHearingAidActiveDevice(null, true); } if (mLeHearingAidConnectedDevices.contains(device)) { Loading Loading @@ -754,18 +753,24 @@ class ActiveDeviceManager { } } private void setHearingAidActiveDevice(BluetoothDevice device) { synchronized (mLock) { private void setHearingAidActiveDevice(@NonNull BluetoothDevice device) { setHearingAidActiveDevice(device, false); } private void setHearingAidActiveDevice(@Nullable BluetoothDevice device, boolean hasFallbackDevice) { if (DBG) { Log.d(TAG, "setHearingAidActiveDevice(" + device + ")"); Log.d(TAG, "setHearingAidActiveDevice(" + device + ")" + (device == null ? " hasFallbackDevice=" + hasFallbackDevice : "")); } synchronized (mLock) { final HearingAidService hearingAidService = mFactory.getHearingAidService(); if (hearingAidService == null) { return; } if (device == null) { hearingAidService.setActiveDevice(null); hearingAidService.removeActiveDevice(!hasFallbackDevice); mHearingAidActiveDevices.clear(); return; } Loading Loading @@ -870,7 +875,7 @@ class ActiveDeviceManager { Log.d(TAG, "set LE hearing aid device active: " + device); } setLeHearingAidActiveDevice(device); setHearingAidActiveDevice(null); setHearingAidActiveDevice(null, true); setA2dpActiveDevice(null, true); setHfpActiveDevice(null); } Loading Loading @@ -916,14 +921,17 @@ class ActiveDeviceManager { Log.d(TAG, "set A2DP device active: " + device); } setA2dpActiveDevice(device); if (headsetFallbackDevice != null) { if (Objects.equals(headsetFallbackDevice, device)) { setHfpActiveDevice(device); } else { setHfpActiveDevice(null); } /* If dual mode is enabled, LEA will be made active once all supported classic audio profiles are made active for the device. */ if (!Utils.isDualModeAudioEnabled()) { setLeAudioActiveDevice(null, true); } } setHearingAidActiveDevice(null, true); } else { if (DBG) { Log.d(TAG, "set LE audio device active: " + device); Loading @@ -933,6 +941,7 @@ class ActiveDeviceManager { setA2dpActiveDevice(null, true); setHfpActiveDevice(null); } setHearingAidActiveDevice(null, true); } } else { if (Objects.equals(headsetFallbackDevice, device)) { Loading @@ -940,12 +949,15 @@ class ActiveDeviceManager { Log.d(TAG, "set HFP device active: " + device); } setHfpActiveDevice(device); if (a2dpFallbackDevice != null) { if (Objects.equals(a2dpFallbackDevice, device)) { setA2dpActiveDevice(a2dpFallbackDevice); } else { setA2dpActiveDevice(null, true); } if (!Utils.isDualModeAudioEnabled()) { setLeAudioActiveDevice(null, true); } } setHearingAidActiveDevice(null, true); } else { if (DBG) { Log.d(TAG, "set LE audio device active: " + device); Loading @@ -955,6 +967,7 @@ class ActiveDeviceManager { setA2dpActiveDevice(null, true); setHfpActiveDevice(null); } setHearingAidActiveDevice(null, true); } } return true; Loading Loading @@ -1029,7 +1042,7 @@ class ActiveDeviceManager { } setA2dpActiveDevice(null, true); setHfpActiveDevice(null); setHearingAidActiveDevice(null); setHearingAidActiveDevice(null, true); setLeAudioActiveDevice(null, true); } } android/app/src/com/android/bluetooth/btservice/AdapterService.java +5 −1 Original line number Diff line number Diff line Loading @@ -5607,8 +5607,12 @@ public class AdapterService extends Service { || mHearingAidService.getConnectionPolicy(device) == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) { Log.i(TAG, "setActiveDevice: Setting active Hearing Aid " + device); if (device == null) { mHearingAidService.removeActiveDevice(false); } else { mHearingAidService.setActiveDevice(device); } } if (setHeadset && hfpSupported) { Log.i(TAG, "setActiveDevice: Setting active Headset " + device); Loading android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java +57 −44 Original line number Diff line number Diff line Loading @@ -80,7 +80,6 @@ public class HearingAidService extends ProfileService { private AdapterService mAdapterService; private DatabaseManager mDatabaseManager; private HandlerThread mStateMachinesThread; private BluetoothDevice mPreviousAudioDevice; private BluetoothDevice mActiveDevice; @VisibleForTesting Loading @@ -96,7 +95,6 @@ public class HearingAidService extends ProfileService { private long mActiveDeviceHiSyncId = BluetoothHearingAid.HI_SYNC_ID_INVALID; private BroadcastReceiver mBondStateChangedReceiver; private BroadcastReceiver mConnectionStateChangedReceiver; private Handler mHandler = new Handler(Looper.getMainLooper()); private final AudioManagerOnAudioDevicesAddedCallback mAudioManagerOnAudioDevicesAddedCallback = new AudioManagerOnAudioDevicesAddedCallback(); Loading Loading @@ -158,8 +156,6 @@ public class HearingAidService extends ProfileService { registerReceiver(mBondStateChangedReceiver, filter); filter = new IntentFilter(); filter.addAction(BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED); mConnectionStateChangedReceiver = new ConnectionStateChangedReceiver(); registerReceiver(mConnectionStateChangedReceiver, filter); // Mark service as started setHearingAidService(this); Loading Loading @@ -194,8 +190,6 @@ public class HearingAidService extends ProfileService { // Unregister broadcast receivers unregisterReceiver(mBondStateChangedReceiver); mBondStateChangedReceiver = null; unregisterReceiver(mConnectionStateChangedReceiver); mConnectionStateChangedReceiver = null; // Destroy state machines and stop handler thread synchronized (mStateMachines) { Loading Loading @@ -609,25 +603,44 @@ public class HearingAidService extends ProfileService { } /** * Set the active device. * @param device the new active device * Remove the active device. * * @param stopAudio whether to stop current media playback. * @return true on success, otherwise false */ public boolean setActiveDevice(BluetoothDevice device) { public boolean removeActiveDevice(boolean stopAudio) { if (DBG) { Log.d(TAG, "setActiveDevice:" + device); Log.d(TAG, "removeActiveDevice: stopAudio=" + stopAudio); } synchronized (mStateMachines) { if (device == null) { if (mActiveDeviceHiSyncId != BluetoothHearingAid.HI_SYNC_ID_INVALID) { reportActiveDevice(null); reportActiveDevice(null, stopAudio); mActiveDeviceHiSyncId = BluetoothHearingAid.HI_SYNC_ID_INVALID; } } return true; } /** * Set the active device. * * @param device the new active device. Should not be null. * @return true on success, otherwise false */ public boolean setActiveDevice(BluetoothDevice device) { if (device == null) { Log.e(TAG, "setActiveDevice: device should not be null!"); return removeActiveDevice(true); } if (DBG) { Log.d(TAG, "setActiveDevice: " + device); } synchronized (mStateMachines) { /* No action needed since this is the same device as previousely activated */ if (device.equals(mActiveDevice)) { if (DBG) { Log.d(TAG, "setActiveDevice: The device is already active. Ignoring."); } return true; } Loading @@ -639,7 +652,7 @@ public class HearingAidService extends ProfileService { BluetoothHearingAid.HI_SYNC_ID_INVALID); if (deviceHiSyncId != mActiveDeviceHiSyncId) { mActiveDeviceHiSyncId = deviceHiSyncId; reportActiveDevice(device); reportActiveDevice(device, false); } } return true; Loading @@ -653,9 +666,6 @@ public class HearingAidService extends ProfileService { * is not active, it will be null on that position */ public List<BluetoothDevice> getActiveDevices() { if (DBG) { Log.d(TAG, "getActiveDevices"); } ArrayList<BluetoothDevice> activeDevices = new ArrayList<>(); activeDevices.add(null); activeDevices.add(null); Loading Loading @@ -788,23 +798,38 @@ 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 * @param stopAudio whether to stop audio when device is null. */ private void reportActiveDevice(BluetoothDevice device) { private void reportActiveDevice(BluetoothDevice device, boolean stopAudio) { if (DBG) { Log.d(TAG, "reportActiveDevice(" + device + ")"); Log.d(TAG, "reportActiveDevice: device=" + device + " stopAudio=" + stopAudio); } if (device != null && stopAudio) { Log.e(TAG, "Illegal arguments: stopAudio should be false when device is not null!"); stopAudio = false; } // Note: This is just a safety check for handling illegal call - setActiveDevice(null). if (device == null && stopAudio && getConnectionState(mActiveDevice) == BluetoothProfile.STATE_CONNECTED) { Log.e(TAG, "Illegal arguments: stopAudio should be false when the active hearing aid " + "is still connected!"); stopAudio = false; } BluetoothDevice previousAudioDevice = mActiveDevice; mActiveDevice = device; BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_ACTIVE_DEVICE_CHANGED, BluetoothProfile.HEARING_AID, mAdapterService.obfuscateAddress(device), mAdapterService.getMetricId(device)); boolean stopAudio = device == null && (getConnectionState(mPreviousAudioDevice) != BluetoothProfile.STATE_CONNECTED); if (DBG) { Log.d(TAG, "Hearing Aid audio: " + mPreviousAudioDevice + " -> " + device Log.d(TAG, "Hearing Aid audio: " + previousAudioDevice + " -> " + device + ". Stop audio: " + stopAudio); } Loading @@ -816,9 +841,8 @@ public class HearingAidService extends ProfileService { mHandler); } mAudioManager.handleBluetoothActiveDeviceChanged(device, mPreviousAudioDevice, mAudioManager.handleBluetoothActiveDeviceChanged(device, previousAudioDevice, BluetoothProfileConnectionInfo.createHearingAidInfo(!stopAudio)); mPreviousAudioDevice = device; } // Remove state machine if the bonding for a device is removed Loading Loading @@ -895,8 +919,6 @@ public class HearingAidService extends ProfileService { return result; } @VisibleForTesting @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) synchronized void connectionStateChanged(BluetoothDevice device, int fromState, int toState) { if ((device == null) || (fromState == toState)) { Loading @@ -918,9 +940,9 @@ public class HearingAidService extends ProfileService { } } if (fromState == BluetoothProfile.STATE_CONNECTED && getConnectedDevices().isEmpty()) { setActiveDevice(null); long myHiSyncId = getHiSyncId(device); mHiSyncIdConnectedMap.put(myHiSyncId, false); // ActiveDeviceManager will call removeActiveDevice(). } // Check if the device is disconnected - if unbond, remove the state machine if (toState == BluetoothProfile.STATE_DISCONNECTED) { Loading @@ -934,19 +956,6 @@ public class HearingAidService extends ProfileService { } } private class ConnectionStateChangedReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (!BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED.equals(intent.getAction())) { return; } BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); int toState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1); int fromState = intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, -1); connectionStateChanged(device, fromState, toState); } } /** * Binder object: must be a static class or memory leak may occur */ Loading Loading @@ -1061,8 +1070,12 @@ public class HearingAidService extends ProfileService { HearingAidService service = getService(source); boolean result = false; if (service != null) { if (device == null) { result = service.removeActiveDevice(false); } else { result = service.setActiveDevice(device); } } receiver.send(result); } catch (RuntimeException e) { receiver.propagateException(e); Loading android/app/src/com/android/bluetooth/hearingaid/HearingAidStateMachine.java +2 −0 Original line number Diff line number Diff line Loading @@ -520,6 +520,8 @@ final class HearingAidStateMachine extends StateMachine { log("Connection state " + mDevice + ": " + profileStateToString(prevState) + "->" + profileStateToString(newState)); mService.connectionStateChanged(mDevice, prevState, newState); Intent intent = new Intent(BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED); intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState); intent.putExtra(BluetoothProfile.EXTRA_STATE, newState); Loading android/app/src/com/android/bluetooth/mcp/MediaControlGattService.java +1 −1 Original line number Diff line number Diff line Loading @@ -991,7 +991,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface A2dpService.getA2dpService().removeActiveDevice(false); } if (mAdapterService.getActiveDevices(BluetoothProfile.HEARING_AID).size() > 0) { HearingAidService.getHearingAidService().setActiveDevice(null); HearingAidService.getHearingAidService().removeActiveDevice(false); } if (mLeAudioService == null) { mLeAudioService = LeAudioService.getLeAudioService(); Loading Loading
android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java +37 −24 Original line number Diff line number Diff line Loading @@ -371,7 +371,7 @@ class ActiveDeviceManager { } } else if (mPendingLeHearingAidActiveDevice.contains(device)) { setLeHearingAidActiveDevice(device); setHearingAidActiveDevice(null); setHearingAidActiveDevice(null, true); setA2dpActiveDevice(null, true); setHfpActiveDevice(null); } Loading @@ -394,7 +394,7 @@ class ActiveDeviceManager { } else { // New connected device: select it as active setLeHearingAidActiveDevice(device); setHearingAidActiveDevice(null); setHearingAidActiveDevice(null, true); setA2dpActiveDevice(null, true); setHfpActiveDevice(null); } Loading Loading @@ -437,10 +437,9 @@ class ActiveDeviceManager { } mHearingAidConnectedDevices.remove(device); if (mHearingAidActiveDevices.remove(device) && mHearingAidActiveDevices.isEmpty()) { if (mHearingAidConnectedDevices.isEmpty()) { setHearingAidActiveDevice(null); if (!setFallbackDeviceActiveLocked()) { setHearingAidActiveDevice(null, false); } setFallbackDeviceActiveLocked(); } } } Loading Loading @@ -500,7 +499,7 @@ class ActiveDeviceManager { } if (!Objects.equals(mA2dpActiveDevice, device)) { if (device != null) { setHearingAidActiveDevice(null); setHearingAidActiveDevice(null, true); } if (Utils.isDualModeAudioEnabled() && mAdapterService.isAllSupportedClassicAudioProfilesActive(device)) { Loading Loading @@ -534,7 +533,7 @@ class ActiveDeviceManager { } if (!Objects.equals(mHfpActiveDevice, device)) { if (device != null) { setHearingAidActiveDevice(null); setHearingAidActiveDevice(null, true); } if (Utils.isDualModeAudioEnabled() && mAdapterService.isAllSupportedClassicAudioProfilesActive(device)) { Loading Loading @@ -590,7 +589,7 @@ class ActiveDeviceManager { setA2dpActiveDevice(null, true); setHfpActiveDevice(null); } setHearingAidActiveDevice(null); setHearingAidActiveDevice(null, true); } if (mLeHearingAidConnectedDevices.contains(device)) { Loading Loading @@ -754,18 +753,24 @@ class ActiveDeviceManager { } } private void setHearingAidActiveDevice(BluetoothDevice device) { synchronized (mLock) { private void setHearingAidActiveDevice(@NonNull BluetoothDevice device) { setHearingAidActiveDevice(device, false); } private void setHearingAidActiveDevice(@Nullable BluetoothDevice device, boolean hasFallbackDevice) { if (DBG) { Log.d(TAG, "setHearingAidActiveDevice(" + device + ")"); Log.d(TAG, "setHearingAidActiveDevice(" + device + ")" + (device == null ? " hasFallbackDevice=" + hasFallbackDevice : "")); } synchronized (mLock) { final HearingAidService hearingAidService = mFactory.getHearingAidService(); if (hearingAidService == null) { return; } if (device == null) { hearingAidService.setActiveDevice(null); hearingAidService.removeActiveDevice(!hasFallbackDevice); mHearingAidActiveDevices.clear(); return; } Loading Loading @@ -870,7 +875,7 @@ class ActiveDeviceManager { Log.d(TAG, "set LE hearing aid device active: " + device); } setLeHearingAidActiveDevice(device); setHearingAidActiveDevice(null); setHearingAidActiveDevice(null, true); setA2dpActiveDevice(null, true); setHfpActiveDevice(null); } Loading Loading @@ -916,14 +921,17 @@ class ActiveDeviceManager { Log.d(TAG, "set A2DP device active: " + device); } setA2dpActiveDevice(device); if (headsetFallbackDevice != null) { if (Objects.equals(headsetFallbackDevice, device)) { setHfpActiveDevice(device); } else { setHfpActiveDevice(null); } /* If dual mode is enabled, LEA will be made active once all supported classic audio profiles are made active for the device. */ if (!Utils.isDualModeAudioEnabled()) { setLeAudioActiveDevice(null, true); } } setHearingAidActiveDevice(null, true); } else { if (DBG) { Log.d(TAG, "set LE audio device active: " + device); Loading @@ -933,6 +941,7 @@ class ActiveDeviceManager { setA2dpActiveDevice(null, true); setHfpActiveDevice(null); } setHearingAidActiveDevice(null, true); } } else { if (Objects.equals(headsetFallbackDevice, device)) { Loading @@ -940,12 +949,15 @@ class ActiveDeviceManager { Log.d(TAG, "set HFP device active: " + device); } setHfpActiveDevice(device); if (a2dpFallbackDevice != null) { if (Objects.equals(a2dpFallbackDevice, device)) { setA2dpActiveDevice(a2dpFallbackDevice); } else { setA2dpActiveDevice(null, true); } if (!Utils.isDualModeAudioEnabled()) { setLeAudioActiveDevice(null, true); } } setHearingAidActiveDevice(null, true); } else { if (DBG) { Log.d(TAG, "set LE audio device active: " + device); Loading @@ -955,6 +967,7 @@ class ActiveDeviceManager { setA2dpActiveDevice(null, true); setHfpActiveDevice(null); } setHearingAidActiveDevice(null, true); } } return true; Loading Loading @@ -1029,7 +1042,7 @@ class ActiveDeviceManager { } setA2dpActiveDevice(null, true); setHfpActiveDevice(null); setHearingAidActiveDevice(null); setHearingAidActiveDevice(null, true); setLeAudioActiveDevice(null, true); } }
android/app/src/com/android/bluetooth/btservice/AdapterService.java +5 −1 Original line number Diff line number Diff line Loading @@ -5607,8 +5607,12 @@ public class AdapterService extends Service { || mHearingAidService.getConnectionPolicy(device) == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) { Log.i(TAG, "setActiveDevice: Setting active Hearing Aid " + device); if (device == null) { mHearingAidService.removeActiveDevice(false); } else { mHearingAidService.setActiveDevice(device); } } if (setHeadset && hfpSupported) { Log.i(TAG, "setActiveDevice: Setting active Headset " + device); Loading
android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java +57 −44 Original line number Diff line number Diff line Loading @@ -80,7 +80,6 @@ public class HearingAidService extends ProfileService { private AdapterService mAdapterService; private DatabaseManager mDatabaseManager; private HandlerThread mStateMachinesThread; private BluetoothDevice mPreviousAudioDevice; private BluetoothDevice mActiveDevice; @VisibleForTesting Loading @@ -96,7 +95,6 @@ public class HearingAidService extends ProfileService { private long mActiveDeviceHiSyncId = BluetoothHearingAid.HI_SYNC_ID_INVALID; private BroadcastReceiver mBondStateChangedReceiver; private BroadcastReceiver mConnectionStateChangedReceiver; private Handler mHandler = new Handler(Looper.getMainLooper()); private final AudioManagerOnAudioDevicesAddedCallback mAudioManagerOnAudioDevicesAddedCallback = new AudioManagerOnAudioDevicesAddedCallback(); Loading Loading @@ -158,8 +156,6 @@ public class HearingAidService extends ProfileService { registerReceiver(mBondStateChangedReceiver, filter); filter = new IntentFilter(); filter.addAction(BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED); mConnectionStateChangedReceiver = new ConnectionStateChangedReceiver(); registerReceiver(mConnectionStateChangedReceiver, filter); // Mark service as started setHearingAidService(this); Loading Loading @@ -194,8 +190,6 @@ public class HearingAidService extends ProfileService { // Unregister broadcast receivers unregisterReceiver(mBondStateChangedReceiver); mBondStateChangedReceiver = null; unregisterReceiver(mConnectionStateChangedReceiver); mConnectionStateChangedReceiver = null; // Destroy state machines and stop handler thread synchronized (mStateMachines) { Loading Loading @@ -609,25 +603,44 @@ public class HearingAidService extends ProfileService { } /** * Set the active device. * @param device the new active device * Remove the active device. * * @param stopAudio whether to stop current media playback. * @return true on success, otherwise false */ public boolean setActiveDevice(BluetoothDevice device) { public boolean removeActiveDevice(boolean stopAudio) { if (DBG) { Log.d(TAG, "setActiveDevice:" + device); Log.d(TAG, "removeActiveDevice: stopAudio=" + stopAudio); } synchronized (mStateMachines) { if (device == null) { if (mActiveDeviceHiSyncId != BluetoothHearingAid.HI_SYNC_ID_INVALID) { reportActiveDevice(null); reportActiveDevice(null, stopAudio); mActiveDeviceHiSyncId = BluetoothHearingAid.HI_SYNC_ID_INVALID; } } return true; } /** * Set the active device. * * @param device the new active device. Should not be null. * @return true on success, otherwise false */ public boolean setActiveDevice(BluetoothDevice device) { if (device == null) { Log.e(TAG, "setActiveDevice: device should not be null!"); return removeActiveDevice(true); } if (DBG) { Log.d(TAG, "setActiveDevice: " + device); } synchronized (mStateMachines) { /* No action needed since this is the same device as previousely activated */ if (device.equals(mActiveDevice)) { if (DBG) { Log.d(TAG, "setActiveDevice: The device is already active. Ignoring."); } return true; } Loading @@ -639,7 +652,7 @@ public class HearingAidService extends ProfileService { BluetoothHearingAid.HI_SYNC_ID_INVALID); if (deviceHiSyncId != mActiveDeviceHiSyncId) { mActiveDeviceHiSyncId = deviceHiSyncId; reportActiveDevice(device); reportActiveDevice(device, false); } } return true; Loading @@ -653,9 +666,6 @@ public class HearingAidService extends ProfileService { * is not active, it will be null on that position */ public List<BluetoothDevice> getActiveDevices() { if (DBG) { Log.d(TAG, "getActiveDevices"); } ArrayList<BluetoothDevice> activeDevices = new ArrayList<>(); activeDevices.add(null); activeDevices.add(null); Loading Loading @@ -788,23 +798,38 @@ 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 * @param stopAudio whether to stop audio when device is null. */ private void reportActiveDevice(BluetoothDevice device) { private void reportActiveDevice(BluetoothDevice device, boolean stopAudio) { if (DBG) { Log.d(TAG, "reportActiveDevice(" + device + ")"); Log.d(TAG, "reportActiveDevice: device=" + device + " stopAudio=" + stopAudio); } if (device != null && stopAudio) { Log.e(TAG, "Illegal arguments: stopAudio should be false when device is not null!"); stopAudio = false; } // Note: This is just a safety check for handling illegal call - setActiveDevice(null). if (device == null && stopAudio && getConnectionState(mActiveDevice) == BluetoothProfile.STATE_CONNECTED) { Log.e(TAG, "Illegal arguments: stopAudio should be false when the active hearing aid " + "is still connected!"); stopAudio = false; } BluetoothDevice previousAudioDevice = mActiveDevice; mActiveDevice = device; BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_ACTIVE_DEVICE_CHANGED, BluetoothProfile.HEARING_AID, mAdapterService.obfuscateAddress(device), mAdapterService.getMetricId(device)); boolean stopAudio = device == null && (getConnectionState(mPreviousAudioDevice) != BluetoothProfile.STATE_CONNECTED); if (DBG) { Log.d(TAG, "Hearing Aid audio: " + mPreviousAudioDevice + " -> " + device Log.d(TAG, "Hearing Aid audio: " + previousAudioDevice + " -> " + device + ". Stop audio: " + stopAudio); } Loading @@ -816,9 +841,8 @@ public class HearingAidService extends ProfileService { mHandler); } mAudioManager.handleBluetoothActiveDeviceChanged(device, mPreviousAudioDevice, mAudioManager.handleBluetoothActiveDeviceChanged(device, previousAudioDevice, BluetoothProfileConnectionInfo.createHearingAidInfo(!stopAudio)); mPreviousAudioDevice = device; } // Remove state machine if the bonding for a device is removed Loading Loading @@ -895,8 +919,6 @@ public class HearingAidService extends ProfileService { return result; } @VisibleForTesting @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) synchronized void connectionStateChanged(BluetoothDevice device, int fromState, int toState) { if ((device == null) || (fromState == toState)) { Loading @@ -918,9 +940,9 @@ public class HearingAidService extends ProfileService { } } if (fromState == BluetoothProfile.STATE_CONNECTED && getConnectedDevices().isEmpty()) { setActiveDevice(null); long myHiSyncId = getHiSyncId(device); mHiSyncIdConnectedMap.put(myHiSyncId, false); // ActiveDeviceManager will call removeActiveDevice(). } // Check if the device is disconnected - if unbond, remove the state machine if (toState == BluetoothProfile.STATE_DISCONNECTED) { Loading @@ -934,19 +956,6 @@ public class HearingAidService extends ProfileService { } } private class ConnectionStateChangedReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (!BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED.equals(intent.getAction())) { return; } BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); int toState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1); int fromState = intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, -1); connectionStateChanged(device, fromState, toState); } } /** * Binder object: must be a static class or memory leak may occur */ Loading Loading @@ -1061,8 +1070,12 @@ public class HearingAidService extends ProfileService { HearingAidService service = getService(source); boolean result = false; if (service != null) { if (device == null) { result = service.removeActiveDevice(false); } else { result = service.setActiveDevice(device); } } receiver.send(result); } catch (RuntimeException e) { receiver.propagateException(e); Loading
android/app/src/com/android/bluetooth/hearingaid/HearingAidStateMachine.java +2 −0 Original line number Diff line number Diff line Loading @@ -520,6 +520,8 @@ final class HearingAidStateMachine extends StateMachine { log("Connection state " + mDevice + ": " + profileStateToString(prevState) + "->" + profileStateToString(newState)); mService.connectionStateChanged(mDevice, prevState, newState); Intent intent = new Intent(BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED); intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState); intent.putExtra(BluetoothProfile.EXTRA_STATE, newState); Loading
android/app/src/com/android/bluetooth/mcp/MediaControlGattService.java +1 −1 Original line number Diff line number Diff line Loading @@ -991,7 +991,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface A2dpService.getA2dpService().removeActiveDevice(false); } if (mAdapterService.getActiveDevices(BluetoothProfile.HEARING_AID).size() > 0) { HearingAidService.getHearingAidService().setActiveDevice(null); HearingAidService.getHearingAidService().removeActiveDevice(false); } if (mLeAudioService == null) { mLeAudioService = LeAudioService.getLeAudioService(); Loading