Fix Bluetooth GATT API default handler assignment

Restores previous behaviour where GATT callbacks are invoked on the
binder thread and not the calling process main looper thread.

This fixes performance regressions as well as some
NetworkOnMainThreadException's for some applications.

Bug: 37544152
Bug: 37871717
Test: Covered by prior API tests.
Change-Id: Id8ab705dd4d7f00030e6ac29e056dde5180670e9
(cherry picked from commit 6bdc550e27)
This commit is contained in:
Ruben Brunk
2017-05-01 16:57:31 -07:00
committed by Andre Eisenbach
parent c497348c74
commit c131051e28
2 changed files with 31 additions and 18 deletions

View File

@@ -1714,7 +1714,7 @@ public final class BluetoothDevice implements Parcelable {
* an d{@link BluetoothDevice#PHY_LE_CODED_MASK}. This option does not take effect
* if {@code autoConnect} is set to true.
* @param handler The handler to use for the callback. If {@code null}, callbacks will happen
* on the service's main thread.
* on an un-specified background thread.
* @throws NullPointerException if callback is null
*/
public BluetoothGatt connectGatt(Context context, boolean autoConnect,
@@ -1723,9 +1723,6 @@ public final class BluetoothDevice implements Parcelable {
if (callback == null)
throw new NullPointerException("callback is null");
if (handler == null)
handler = new Handler(Looper.getMainLooper());
// TODO(Bluetooth) check whether platform support BLE
// Do the check here or in GattServer?
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();

View File

@@ -156,7 +156,7 @@ public final class BluetoothGatt implements BluetoothProfile {
}
mClientIf = clientIf;
if (status != GATT_SUCCESS) {
mHandler.post(new Runnable() {
runOrQueueCallback(new Runnable() {
@Override
public void run() {
if (mCallback != null) {
@@ -191,7 +191,7 @@ public final class BluetoothGatt implements BluetoothProfile {
return;
}
mHandler.post(new Runnable() {
runOrQueueCallback(new Runnable() {
@Override
public void run() {
if (mCallback != null) {
@@ -213,7 +213,7 @@ public final class BluetoothGatt implements BluetoothProfile {
return;
}
mHandler.post(new Runnable() {
runOrQueueCallback(new Runnable() {
@Override
public void run() {
if (mCallback != null) {
@@ -238,7 +238,7 @@ public final class BluetoothGatt implements BluetoothProfile {
int profileState = connected ? BluetoothProfile.STATE_CONNECTED :
BluetoothProfile.STATE_DISCONNECTED;
mHandler.post(new Runnable() {
runOrQueueCallback(new Runnable() {
@Override
public void run() {
if (mCallback != null) {
@@ -300,7 +300,7 @@ public final class BluetoothGatt implements BluetoothProfile {
}
}
mHandler.post(new Runnable() {
runOrQueueCallback(new Runnable() {
@Override
public void run() {
if (mCallback != null) {
@@ -352,7 +352,7 @@ public final class BluetoothGatt implements BluetoothProfile {
if (status == 0) characteristic.setValue(value);
mHandler.post(new Runnable() {
runOrQueueCallback(new Runnable() {
@Override
public void run() {
if (mCallback != null) {
@@ -401,7 +401,7 @@ public final class BluetoothGatt implements BluetoothProfile {
mAuthRetryState = AUTH_RETRY_STATE_IDLE;
mHandler.post(new Runnable() {
runOrQueueCallback(new Runnable() {
@Override
public void run() {
if (mCallback != null) {
@@ -430,7 +430,7 @@ public final class BluetoothGatt implements BluetoothProfile {
characteristic.setValue(value);
mHandler.post(new Runnable() {
runOrQueueCallback(new Runnable() {
@Override
public void run() {
if (mCallback != null) {
@@ -477,7 +477,7 @@ public final class BluetoothGatt implements BluetoothProfile {
mAuthRetryState = AUTH_RETRY_STATE_IDLE;
mHandler.post(new Runnable() {
runOrQueueCallback(new Runnable() {
@Override
public void run() {
if (mCallback != null) {
@@ -523,7 +523,7 @@ public final class BluetoothGatt implements BluetoothProfile {
mAuthRetryState = AUTH_RETRY_STATE_IDLE;
mHandler.post(new Runnable() {
runOrQueueCallback(new Runnable() {
@Override
public void run() {
if (mCallback != null) {
@@ -549,7 +549,7 @@ public final class BluetoothGatt implements BluetoothProfile {
mDeviceBusy = false;
}
mHandler.post(new Runnable() {
runOrQueueCallback(new Runnable() {
@Override
public void run() {
if (mCallback != null) {
@@ -570,7 +570,7 @@ public final class BluetoothGatt implements BluetoothProfile {
if (!address.equals(mDevice.getAddress())) {
return;
}
mHandler.post(new Runnable() {
runOrQueueCallback(new Runnable() {
@Override
public void run() {
if (mCallback != null) {
@@ -592,7 +592,7 @@ public final class BluetoothGatt implements BluetoothProfile {
return;
}
mHandler.post(new Runnable() {
runOrQueueCallback(new Runnable() {
@Override
public void run() {
if (mCallback != null) {
@@ -616,7 +616,7 @@ public final class BluetoothGatt implements BluetoothProfile {
return;
}
mHandler.post(new Runnable() {
runOrQueueCallback(new Runnable() {
@Override
public void run() {
if (mCallback != null) {
@@ -702,6 +702,22 @@ public final class BluetoothGatt implements BluetoothProfile {
return null;
}
/**
* Queue the runnable on a {@link Handler} provided by the user, or execute the runnable
* immediately if no Handler was provided.
*/
private void runOrQueueCallback(final Runnable cb) {
if (mHandler == null) {
try {
cb.run();
} catch (Exception ex) {
Log.w(TAG, "Unhandled exception in callback", ex);
}
} else {
mHandler.post(cb);
}
}
/**
* Register an application callback to start using GATT.
*