Loading android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java +15 −9 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ import android.annotation.SuppressLint; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothClass; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHapClient; import android.bluetooth.BluetoothHearingAid; import android.bluetooth.BluetoothLeAudio; import android.bluetooth.BluetoothProfile; Loading Loading @@ -189,13 +188,6 @@ public class ActiveDeviceManager { mHandler.post(() -> handleLeAudioDisconnected(device)); } break; case BluetoothHapClient.ACTION_HAP_CONNECTION_STATE_CHANGED: if (currentState == BluetoothProfile.STATE_CONNECTED) { mHandler.post(() -> handleHapConnected(device)); } else if (previousState == BluetoothProfile.STATE_CONNECTED) { mHandler.post(() -> handleHapDisconnected(device)); } break; case BluetoothLeAudio.ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED: mHandler.post(() -> handleLeAudioActiveDeviceChanged(device)); break; Loading Loading @@ -279,6 +271,21 @@ public class ActiveDeviceManager { mHandler.post(() -> handleHearingAidActiveDeviceChanged(device)); } /** * Called when HAP connection state changed by HapClientService * * @param device The device of which connection state was changed * @param prevState The previous connection state of the device * @param newState The new connection state of the device */ public void hapConnectionStateChanged(BluetoothDevice device, int prevState, int newState) { if (newState == BluetoothProfile.STATE_CONNECTED) { mHandler.post(() -> handleHapConnected(device)); } else if (prevState == BluetoothProfile.STATE_CONNECTED) { mHandler.post(() -> handleHapDisconnected(device)); } } private void handleAdapterStateChanged(int currentState) { if (DBG) { Log.d(TAG, "handleAdapterStateChanged: currentState=" + currentState); Loading Loading @@ -843,7 +850,6 @@ public class ActiveDeviceManager { filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); filter.addAction(BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED); filter.addAction(BluetoothLeAudio.ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED); filter.addAction(BluetoothHapClient.ACTION_HAP_CONNECTION_STATE_CHANGED); mAdapterService.registerReceiver(mReceiver, filter, Context.RECEIVER_EXPORTED); mAudioManager.registerAudioDeviceCallback(mAudioManagerAudioDeviceCallback, mHandler); Loading android/app/src/com/android/bluetooth/hap/HapClientService.java +5 −23 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.bluetooth.hap; import static android.Manifest.permission.BLUETOOTH_CONNECT; import static android.Manifest.permission.BLUETOOTH_PRIVILEGED; import static com.android.bluetooth.Utils.enforceBluetoothPrivilegedPermission; Loading Loading @@ -46,6 +45,7 @@ import android.sysprop.BluetoothProperties; import android.util.Log; import com.android.bluetooth.Utils; import com.android.bluetooth.btservice.ActiveDeviceManager; import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.ProfileService; import com.android.bluetooth.btservice.ServiceFactory; Loading Loading @@ -83,7 +83,6 @@ public class HapClientService extends ProfileService { private DatabaseManager mDatabaseManager; private HandlerThread mStateMachinesThread; private BroadcastReceiver mBondStateChangedReceiver; private BroadcastReceiver mConnectionStateChangedReceiver; private final Map<BluetoothDevice, Integer> mDeviceCurrentPresetMap = new HashMap<>(); private final Map<BluetoothDevice, Integer> mDeviceFeaturesMap = new HashMap<>(); Loading Loading @@ -175,11 +174,6 @@ public class HapClientService extends ProfileService { filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED); mBondStateChangedReceiver = new BondStateChangedReceiver(); registerReceiver(mBondStateChangedReceiver, filter); filter = new IntentFilter(); filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); filter.addAction(BluetoothHapClient.ACTION_HAP_CONNECTION_STATE_CHANGED); mConnectionStateChangedReceiver = new ConnectionStateChangedReceiver(); registerReceiver(mConnectionStateChangedReceiver, filter, Context.RECEIVER_NOT_EXPORTED); mCallbacks = new RemoteCallbackList<IBluetoothHapClientCallback>(); Loading Loading @@ -208,8 +202,6 @@ public class HapClientService extends ProfileService { // Unregister broadcast receivers unregisterReceiver(mBondStateChangedReceiver); mBondStateChangedReceiver = null; unregisterReceiver(mConnectionStateChangedReceiver); mConnectionStateChangedReceiver = null; // Destroy state machines and stop handler thread synchronized (mStateMachines) { Loading Loading @@ -453,6 +445,10 @@ public class HapClientService extends ProfileService { removeStateMachine(device); } } ActiveDeviceManager adManager = mAdapterService.getActiveDeviceManager(); if (adManager != null) { adManager.hapConnectionStateChanged(device, fromState, toState); } } /** Loading Loading @@ -1659,18 +1655,4 @@ public class HapClientService extends ProfileService { bondStateChanged(device, state); } } private class ConnectionStateChangedReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (!BluetoothHapClient.ACTION_HAP_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); } } } android/app/src/com/android/bluetooth/hap/HapClientStateMachine.java +1 −0 Original line number Diff line number Diff line Loading @@ -179,6 +179,7 @@ final class HapClientStateMachine extends StateMachine { log("Connection state " + mDevice + ": " + profileStateToString(prevState) + "->" + profileStateToString(newState)); mService.connectionStateChanged(mDevice, prevState, newState); Intent intent = new Intent(BluetoothHapClient.ACTION_HAP_CONNECTION_STATE_CHANGED); intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState); intent.putExtra(BluetoothProfile.EXTRA_STATE, newState); Loading android/app/tests/unit/src/com/android/bluetooth/btservice/ActiveDeviceManagerTest.java +7 −27 Original line number Diff line number Diff line Loading @@ -32,7 +32,6 @@ import static org.mockito.Mockito.when; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHapClient; import android.bluetooth.BluetoothLeAudio; import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothSinkAudioPolicy; Loading @@ -50,6 +49,7 @@ import com.android.bluetooth.TestUtils; import com.android.bluetooth.Utils; import com.android.bluetooth.a2dp.A2dpService; import com.android.bluetooth.btservice.storage.DatabaseManager; import com.android.bluetooth.hap.HapClientService; import com.android.bluetooth.hearingaid.HearingAidService; import com.android.bluetooth.hfp.HeadsetService; import com.android.bluetooth.le_audio.LeAudioService; Loading Loading @@ -100,6 +100,7 @@ public class ActiveDeviceManagerTest { @Mock private HearingAidService mHearingAidService; @Mock private LeAudioService mLeAudioService; @Mock private AudioManager mAudioManager; @Mock private HapClientService mHapClientService; @Before public void setUp() throws Exception { Loading Loading @@ -1290,39 +1291,18 @@ public class ActiveDeviceManagerTest { mDeviceConnectionStack.add(device); mMostRecentDevice = device; Intent intent = new Intent(BluetoothHapClient.ACTION_HAP_CONNECTION_STATE_CHANGED); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_DISCONNECTED); intent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED); mActiveDeviceManager.getBroadcastReceiver().onReceive(mContext, intent); mActiveDeviceManager.hapConnectionStateChanged( device, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTED); } /** * Helper to indicate LE Hearing Aid disconnected for a device. */ /** Helper to indicate LE Hearing Aid disconnected for a device. */ private void leHearingAidDisconnected(BluetoothDevice device) { mDeviceConnectionStack.remove(device); mMostRecentDevice = (mDeviceConnectionStack.size() > 0) ? mDeviceConnectionStack.get(mDeviceConnectionStack.size() - 1) : null; Intent intent = new Intent(BluetoothHapClient.ACTION_HAP_CONNECTION_STATE_CHANGED); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_CONNECTED); intent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_DISCONNECTED); mActiveDeviceManager.getBroadcastReceiver().onReceive(mContext, intent); } /** * Helper to indicate LE Audio Hearing Aid device changed for a device. */ private void leHearingAidActiveDeviceChanged(BluetoothDevice device) { mDeviceConnectionStack.remove(device); mDeviceConnectionStack.add(device); mMostRecentDevice = device; Intent intent = new Intent(BluetoothHapClient.ACTION_HAP_DEVICE_AVAILABLE); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); mActiveDeviceManager.getBroadcastReceiver().onReceive(mContext, intent); mActiveDeviceManager.hapConnectionStateChanged( device, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED); } private class TestDatabaseManager extends DatabaseManager { Loading android/app/tests/unit/src/com/android/bluetooth/hap/HapClientStateMachineTest.java +0 −4 Original line number Diff line number Diff line Loading @@ -28,13 +28,11 @@ import static org.mockito.Mockito.verify; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothProfile; import android.content.Context; import android.content.Intent; import android.os.HandlerThread; import android.os.Message; import android.test.suitebuilder.annotation.MediumTest; import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; import com.android.bluetooth.TestUtils; Loading @@ -55,7 +53,6 @@ import org.mockito.MockitoAnnotations; @RunWith(AndroidJUnit4.class) public class HapClientStateMachineTest { private BluetoothAdapter mAdapter; private Context mTargetContext; private HandlerThread mHandlerThread; private HapClientStateMachine mHapClientStateMachine; private BluetoothDevice mTestDevice; Loading @@ -70,7 +67,6 @@ public class HapClientStateMachineTest { @Before public void setUp() throws Exception { mTargetContext = InstrumentationRegistry.getTargetContext(); // Set up mocks and test assets MockitoAnnotations.initMocks(this); TestUtils.setAdapterService(mAdapterService); Loading Loading
android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java +15 −9 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ import android.annotation.SuppressLint; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothClass; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHapClient; import android.bluetooth.BluetoothHearingAid; import android.bluetooth.BluetoothLeAudio; import android.bluetooth.BluetoothProfile; Loading Loading @@ -189,13 +188,6 @@ public class ActiveDeviceManager { mHandler.post(() -> handleLeAudioDisconnected(device)); } break; case BluetoothHapClient.ACTION_HAP_CONNECTION_STATE_CHANGED: if (currentState == BluetoothProfile.STATE_CONNECTED) { mHandler.post(() -> handleHapConnected(device)); } else if (previousState == BluetoothProfile.STATE_CONNECTED) { mHandler.post(() -> handleHapDisconnected(device)); } break; case BluetoothLeAudio.ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED: mHandler.post(() -> handleLeAudioActiveDeviceChanged(device)); break; Loading Loading @@ -279,6 +271,21 @@ public class ActiveDeviceManager { mHandler.post(() -> handleHearingAidActiveDeviceChanged(device)); } /** * Called when HAP connection state changed by HapClientService * * @param device The device of which connection state was changed * @param prevState The previous connection state of the device * @param newState The new connection state of the device */ public void hapConnectionStateChanged(BluetoothDevice device, int prevState, int newState) { if (newState == BluetoothProfile.STATE_CONNECTED) { mHandler.post(() -> handleHapConnected(device)); } else if (prevState == BluetoothProfile.STATE_CONNECTED) { mHandler.post(() -> handleHapDisconnected(device)); } } private void handleAdapterStateChanged(int currentState) { if (DBG) { Log.d(TAG, "handleAdapterStateChanged: currentState=" + currentState); Loading Loading @@ -843,7 +850,6 @@ public class ActiveDeviceManager { filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); filter.addAction(BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED); filter.addAction(BluetoothLeAudio.ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED); filter.addAction(BluetoothHapClient.ACTION_HAP_CONNECTION_STATE_CHANGED); mAdapterService.registerReceiver(mReceiver, filter, Context.RECEIVER_EXPORTED); mAudioManager.registerAudioDeviceCallback(mAudioManagerAudioDeviceCallback, mHandler); Loading
android/app/src/com/android/bluetooth/hap/HapClientService.java +5 −23 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.bluetooth.hap; import static android.Manifest.permission.BLUETOOTH_CONNECT; import static android.Manifest.permission.BLUETOOTH_PRIVILEGED; import static com.android.bluetooth.Utils.enforceBluetoothPrivilegedPermission; Loading Loading @@ -46,6 +45,7 @@ import android.sysprop.BluetoothProperties; import android.util.Log; import com.android.bluetooth.Utils; import com.android.bluetooth.btservice.ActiveDeviceManager; import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.ProfileService; import com.android.bluetooth.btservice.ServiceFactory; Loading Loading @@ -83,7 +83,6 @@ public class HapClientService extends ProfileService { private DatabaseManager mDatabaseManager; private HandlerThread mStateMachinesThread; private BroadcastReceiver mBondStateChangedReceiver; private BroadcastReceiver mConnectionStateChangedReceiver; private final Map<BluetoothDevice, Integer> mDeviceCurrentPresetMap = new HashMap<>(); private final Map<BluetoothDevice, Integer> mDeviceFeaturesMap = new HashMap<>(); Loading Loading @@ -175,11 +174,6 @@ public class HapClientService extends ProfileService { filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED); mBondStateChangedReceiver = new BondStateChangedReceiver(); registerReceiver(mBondStateChangedReceiver, filter); filter = new IntentFilter(); filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); filter.addAction(BluetoothHapClient.ACTION_HAP_CONNECTION_STATE_CHANGED); mConnectionStateChangedReceiver = new ConnectionStateChangedReceiver(); registerReceiver(mConnectionStateChangedReceiver, filter, Context.RECEIVER_NOT_EXPORTED); mCallbacks = new RemoteCallbackList<IBluetoothHapClientCallback>(); Loading Loading @@ -208,8 +202,6 @@ public class HapClientService extends ProfileService { // Unregister broadcast receivers unregisterReceiver(mBondStateChangedReceiver); mBondStateChangedReceiver = null; unregisterReceiver(mConnectionStateChangedReceiver); mConnectionStateChangedReceiver = null; // Destroy state machines and stop handler thread synchronized (mStateMachines) { Loading Loading @@ -453,6 +445,10 @@ public class HapClientService extends ProfileService { removeStateMachine(device); } } ActiveDeviceManager adManager = mAdapterService.getActiveDeviceManager(); if (adManager != null) { adManager.hapConnectionStateChanged(device, fromState, toState); } } /** Loading Loading @@ -1659,18 +1655,4 @@ public class HapClientService extends ProfileService { bondStateChanged(device, state); } } private class ConnectionStateChangedReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (!BluetoothHapClient.ACTION_HAP_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); } } }
android/app/src/com/android/bluetooth/hap/HapClientStateMachine.java +1 −0 Original line number Diff line number Diff line Loading @@ -179,6 +179,7 @@ final class HapClientStateMachine extends StateMachine { log("Connection state " + mDevice + ": " + profileStateToString(prevState) + "->" + profileStateToString(newState)); mService.connectionStateChanged(mDevice, prevState, newState); Intent intent = new Intent(BluetoothHapClient.ACTION_HAP_CONNECTION_STATE_CHANGED); intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState); intent.putExtra(BluetoothProfile.EXTRA_STATE, newState); Loading
android/app/tests/unit/src/com/android/bluetooth/btservice/ActiveDeviceManagerTest.java +7 −27 Original line number Diff line number Diff line Loading @@ -32,7 +32,6 @@ import static org.mockito.Mockito.when; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHapClient; import android.bluetooth.BluetoothLeAudio; import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothSinkAudioPolicy; Loading @@ -50,6 +49,7 @@ import com.android.bluetooth.TestUtils; import com.android.bluetooth.Utils; import com.android.bluetooth.a2dp.A2dpService; import com.android.bluetooth.btservice.storage.DatabaseManager; import com.android.bluetooth.hap.HapClientService; import com.android.bluetooth.hearingaid.HearingAidService; import com.android.bluetooth.hfp.HeadsetService; import com.android.bluetooth.le_audio.LeAudioService; Loading Loading @@ -100,6 +100,7 @@ public class ActiveDeviceManagerTest { @Mock private HearingAidService mHearingAidService; @Mock private LeAudioService mLeAudioService; @Mock private AudioManager mAudioManager; @Mock private HapClientService mHapClientService; @Before public void setUp() throws Exception { Loading Loading @@ -1290,39 +1291,18 @@ public class ActiveDeviceManagerTest { mDeviceConnectionStack.add(device); mMostRecentDevice = device; Intent intent = new Intent(BluetoothHapClient.ACTION_HAP_CONNECTION_STATE_CHANGED); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_DISCONNECTED); intent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED); mActiveDeviceManager.getBroadcastReceiver().onReceive(mContext, intent); mActiveDeviceManager.hapConnectionStateChanged( device, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTED); } /** * Helper to indicate LE Hearing Aid disconnected for a device. */ /** Helper to indicate LE Hearing Aid disconnected for a device. */ private void leHearingAidDisconnected(BluetoothDevice device) { mDeviceConnectionStack.remove(device); mMostRecentDevice = (mDeviceConnectionStack.size() > 0) ? mDeviceConnectionStack.get(mDeviceConnectionStack.size() - 1) : null; Intent intent = new Intent(BluetoothHapClient.ACTION_HAP_CONNECTION_STATE_CHANGED); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_CONNECTED); intent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_DISCONNECTED); mActiveDeviceManager.getBroadcastReceiver().onReceive(mContext, intent); } /** * Helper to indicate LE Audio Hearing Aid device changed for a device. */ private void leHearingAidActiveDeviceChanged(BluetoothDevice device) { mDeviceConnectionStack.remove(device); mDeviceConnectionStack.add(device); mMostRecentDevice = device; Intent intent = new Intent(BluetoothHapClient.ACTION_HAP_DEVICE_AVAILABLE); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); mActiveDeviceManager.getBroadcastReceiver().onReceive(mContext, intent); mActiveDeviceManager.hapConnectionStateChanged( device, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED); } private class TestDatabaseManager extends DatabaseManager { Loading
android/app/tests/unit/src/com/android/bluetooth/hap/HapClientStateMachineTest.java +0 −4 Original line number Diff line number Diff line Loading @@ -28,13 +28,11 @@ import static org.mockito.Mockito.verify; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothProfile; import android.content.Context; import android.content.Intent; import android.os.HandlerThread; import android.os.Message; import android.test.suitebuilder.annotation.MediumTest; import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; import com.android.bluetooth.TestUtils; Loading @@ -55,7 +53,6 @@ import org.mockito.MockitoAnnotations; @RunWith(AndroidJUnit4.class) public class HapClientStateMachineTest { private BluetoothAdapter mAdapter; private Context mTargetContext; private HandlerThread mHandlerThread; private HapClientStateMachine mHapClientStateMachine; private BluetoothDevice mTestDevice; Loading @@ -70,7 +67,6 @@ public class HapClientStateMachineTest { @Before public void setUp() throws Exception { mTargetContext = InstrumentationRegistry.getTargetContext(); // Set up mocks and test assets MockitoAnnotations.initMocks(this); TestUtils.setAdapterService(mAdapterService); Loading