Bluetooth: Add handler parameter to connectGatt

Bug: 37544152
Test: sl4a GattReadTest GattWriteTest
Change-Id: I043dfefaafe9f3700418f2c855c52aac3644310f
(cherry picked from commit 4eab49652e48159fd37f827d30b822f2f187551e)
diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java
index 4aaf6bd..713dbf4 100644
--- a/core/java/android/bluetooth/BluetoothGatt.java
+++ b/core/java/android/bluetooth/BluetoothGatt.java
@@ -17,6 +17,7 @@
 package android.bluetooth;
 
 import android.content.Context;
+import android.os.Handler;
 import android.os.ParcelUuid;
 import android.os.RemoteException;
 import android.util.Log;
@@ -43,6 +44,7 @@
 
     private IBluetoothGatt mService;
     private BluetoothGattCallback mCallback;
+    private Handler mHandler;
     private int mClientIf;
     private BluetoothDevice mDevice;
     private boolean mAutoConnect;
@@ -154,8 +156,14 @@
                 }
                 mClientIf = clientIf;
                 if (status != GATT_SUCCESS) {
-                    mCallback.onConnectionStateChange(BluetoothGatt.this, GATT_FAILURE,
-                                                      BluetoothProfile.STATE_DISCONNECTED);
+                    mHandler.post(new Runnable() {
+                        @Override
+                        public void run() {
+                            mCallback.onConnectionStateChange(BluetoothGatt.this, GATT_FAILURE,
+                                              BluetoothProfile.STATE_DISCONNECTED);
+                        }
+                    });
+
                     synchronized(mStateLock) {
                         mConnState = CONN_STATE_IDLE;
                     }
@@ -181,11 +189,12 @@
                     return;
                 }
 
-                try {
-                    mCallback.onPhyUpdate(BluetoothGatt.this, txPhy, rxPhy, status);
-                } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception in callback", ex);
-                }
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        mCallback.onPhyUpdate(BluetoothGatt.this, txPhy, rxPhy, status);
+                    }
+                });
             }
 
             /**
@@ -200,11 +209,12 @@
                     return;
                 }
 
-                try {
-                    mCallback.onPhyRead(BluetoothGatt.this, txPhy, rxPhy, status);
-                } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception in callback", ex);
-                }
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        mCallback.onPhyRead(BluetoothGatt.this, txPhy, rxPhy, status);
+                    }
+                });
             }
 
             /**
@@ -221,11 +231,13 @@
                 }
                 int profileState = connected ? BluetoothProfile.STATE_CONNECTED :
                                                BluetoothProfile.STATE_DISCONNECTED;
-                try {
-                    mCallback.onConnectionStateChange(BluetoothGatt.this, status, profileState);
-                } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception in callback", ex);
-                }
+
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        mCallback.onConnectionStateChange(BluetoothGatt.this, status, profileState);
+                    }
+                });
 
                 synchronized(mStateLock) {
                     if (connected) {
@@ -279,11 +291,12 @@
                     }
                 }
 
-                try {
-                    mCallback.onServicesDiscovered(BluetoothGatt.this, status);
-                } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception in callback", ex);
-                }
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        mCallback.onServicesDiscovered(BluetoothGatt.this, status);
+                    }
+                });
             }
 
             /**
@@ -328,11 +341,12 @@
 
                 if (status == 0) characteristic.setValue(value);
 
-                try {
-                    mCallback.onCharacteristicRead(BluetoothGatt.this, characteristic, status);
-                } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception in callback", ex);
-                }
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        mCallback.onCharacteristicRead(BluetoothGatt.this, characteristic, status);
+                    }
+                });
             }
 
             /**
@@ -373,11 +387,12 @@
 
                 mAuthRetryState = AUTH_RETRY_STATE_IDLE;
 
-                try {
-                    mCallback.onCharacteristicWrite(BluetoothGatt.this, characteristic, status);
-                } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception in callback", ex);
-                }
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        mCallback.onCharacteristicWrite(BluetoothGatt.this, characteristic, status);
+                    }
+                });
             }
 
             /**
@@ -398,11 +413,12 @@
 
                 characteristic.setValue(value);
 
-                try {
-                    mCallback.onCharacteristicChanged(BluetoothGatt.this, characteristic);
-                } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception in callback", ex);
-                }
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        mCallback.onCharacteristicChanged(BluetoothGatt.this, characteristic);
+                    }
+                });
             }
 
             /**
@@ -442,11 +458,12 @@
 
                 mAuthRetryState = AUTH_RETRY_STATE_IDLE;
 
-                try {
-                    mCallback.onDescriptorRead(BluetoothGatt.this, descriptor, status);
-                } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception in callback", ex);
-                }
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        mCallback.onDescriptorRead(BluetoothGatt.this, descriptor, status);
+                    }
+                });
             }
 
             /**
@@ -485,11 +502,12 @@
 
                 mAuthRetryState = AUTH_RETRY_STATE_IDLE;
 
-                try {
-                    mCallback.onDescriptorWrite(BluetoothGatt.this, descriptor, status);
-                } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception in callback", ex);
-                }
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        mCallback.onDescriptorWrite(BluetoothGatt.this, descriptor, status);
+                    }
+                });
             }
 
             /**
@@ -508,11 +526,12 @@
                     mDeviceBusy = false;
                 }
 
-                try {
-                    mCallback.onReliableWriteCompleted(BluetoothGatt.this, status);
-                } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception in callback", ex);
-                }
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        mCallback.onReliableWriteCompleted(BluetoothGatt.this, status);
+                    }
+                });
             }
 
             /**
@@ -526,11 +545,12 @@
                 if (!address.equals(mDevice.getAddress())) {
                     return;
                 }
-                try {
-                    mCallback.onReadRemoteRssi(BluetoothGatt.this, rssi, status);
-                } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception in callback", ex);
-                }
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        mCallback.onReadRemoteRssi(BluetoothGatt.this, rssi, status);
+                    }
+                });
             }
 
             /**
@@ -544,11 +564,13 @@
                 if (!address.equals(mDevice.getAddress())) {
                     return;
                 }
-                try {
-                    mCallback.onMtuChanged(BluetoothGatt.this, mtu, status);
-                } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception in callback", ex);
-                }
+
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        mCallback.onMtuChanged(BluetoothGatt.this, mtu, status);
+                    }
+                });
             }
 
             /**
@@ -564,12 +586,14 @@
                 if (!address.equals(mDevice.getAddress())) {
                     return;
                 }
-                try {
-                    mCallback.onConnectionUpdated(BluetoothGatt.this, interval, latency,
-                                                  timeout, status);
-                } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception in callback", ex);
-                }
+
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        mCallback.onConnectionUpdated(BluetoothGatt.this, interval, latency,
+                                                      timeout, status);
+                    }
+                });
             }
         };
 
@@ -659,11 +683,12 @@
      * @return If true, the callback will be called to notify success or failure,
      *         false on immediate error
      */
-    private boolean registerApp(BluetoothGattCallback callback) {
+    private boolean registerApp(BluetoothGattCallback callback, Handler handler) {
         if (DBG) Log.d(TAG, "registerApp()");
         if (mService == null) return false;
 
         mCallback = callback;
+        mHandler = handler;
         UUID uuid = UUID.randomUUID();
         if (DBG) Log.d(TAG, "registerApp() - UUID=" + uuid);
 
@@ -716,7 +741,8 @@
      *                    device becomes available (true).
      * @return true, if the connection attempt was initiated successfully
      */
-    /*package*/ boolean connect(Boolean autoConnect, BluetoothGattCallback callback) {
+    /*package*/ boolean connect(Boolean autoConnect, BluetoothGattCallback callback,
+                                Handler handler) {
         if (DBG) Log.d(TAG, "connect() - device: " + mDevice.getAddress() + ", auto: " + autoConnect);
         synchronized(mStateLock) {
             if (mConnState != CONN_STATE_IDLE) {
@@ -727,7 +753,7 @@
 
         mAutoConnect = autoConnect;
 
-        if (!registerApp(callback)) {
+        if (!registerApp(callback, handler)) {
             synchronized(mStateLock) {
                 mConnState = CONN_STATE_IDLE;
             }