Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Android] Fix Android Bluetooth connect issue (Specific Android Device) #33087

Merged
merged 1 commit into from
Apr 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,12 @@ class BluetoothManager : BleCallback {

private val coroutineContinuation = continuation

private val STATE_INIT = 1
private val STATE_DISCOVER_SERVICE = 2
private val STATE_REQUEST_MTU = 3

private var mState = STATE_INIT

override fun onConnectionStateChange(gatt: BluetoothGatt?, status: Int, newState: Int) {
super.onConnectionStateChange(gatt, status, newState)
Log.i(
Expand All @@ -148,21 +154,31 @@ class BluetoothManager : BleCallback {

if (newState == BluetoothProfile.STATE_CONNECTED && status == BluetoothGatt.GATT_SUCCESS) {
Log.i("$TAG|onConnectionStateChange", "Discovering Services...")
mState = STATE_DISCOVER_SERVICE
gatt?.discoverServices()
}
}

override fun onServicesDiscovered(gatt: BluetoothGatt?, status: Int) {
Log.d(TAG, "${gatt?.device?.name}.onServicesDiscovered status = $status")
if (mState != STATE_DISCOVER_SERVICE) {
Log.d(TAG, "Invalid state : $mState")
return
}
wrappedCallback.onServicesDiscovered(gatt, status)

Log.i("$TAG|onServicesDiscovered", "Services Discovered")
mState = STATE_REQUEST_MTU
gatt?.requestMtu(247)
}

override fun onMtuChanged(gatt: BluetoothGatt?, mtu: Int, status: Int) {
Log.d(TAG, "${gatt?.device?.name}.onMtuChanged: connecting to CHIP device")
super.onMtuChanged(gatt, mtu, status)
if (mState != STATE_REQUEST_MTU) {
Log.d(TAG, "Invalid state : $mState")
return
}
wrappedCallback.onMtuChanged(gatt, mtu, status)
if (coroutineContinuation.isActive) {
coroutineContinuation.resume(gatt)
Expand Down
16 changes: 16 additions & 0 deletions src/platform/android/java/chip/platform/AndroidBleManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -584,12 +584,19 @@ private void connectBLE(Object bluetoothDeviceObj) {
}

class ConnectionGattCallback extends AndroidBluetoothGattCallback {
private static final int STATE_INIT = 1;
private static final int STATE_DISCOVER_SERVICE = 2;
private static final int STATE_REQUEST_MTU = 3;

private int mState = STATE_INIT;

@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
Log.i(TAG, "onConnectionStateChange status = " + status + ", newState= + " + newState);
super.onConnectionStateChange(gatt, status, newState);
if (newState == BluetoothProfile.STATE_CONNECTED && status == BluetoothGatt.GATT_SUCCESS) {
Log.i(TAG, "Discovering Services...");
mState = STATE_DISCOVER_SERVICE;
gatt.discoverServices();
return;
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
Expand All @@ -602,14 +609,23 @@ public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
Log.d(TAG, "onServicesDiscovered status = " + status);
super.onServicesDiscovered(gatt, status);
if (mState != STATE_DISCOVER_SERVICE) {
Log.d(TAG, "Invalid state : " + mState);
return;
}

Log.i(TAG, "Services Discovered");
mState = STATE_REQUEST_MTU;
gatt.requestMtu(247);
Comment on lines +618 to 619
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The request of MTU from here is probably what broke on the devices. gatt calls should not be done inside of AndroidBluetoothGattCallback. See https://developer.android.com/develop/connectivity/bluetooth/ble/connect-gatt-server#broadcast-updates for guidance, where it is required to post to a different context to properly handle callbacks rather than calling back in, which can be unsafe on some Android platforms.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The previous state of the Android driver had the same problem, but adding complex statefulness to this file may add risk and hard-to-debug issues in other situations.

}

@Override
public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
super.onMtuChanged(gatt, mtu, status);
if (mState != STATE_REQUEST_MTU) {
Log.d(TAG, "Invalid state : " + mState);
return;
}
String deviceName = "";
if (gatt != null && gatt.getDevice() != null) {
deviceName = gatt.getDevice().getName();
Expand Down
Loading