Remove BluetoothAdapterCallback. Simplify leScan Api

App does not need to explicitly register/unregister callback
bug 8599881

Change-Id: I18cfef14d7ddb344722945e657dcb959823b412b
diff --git a/api/current.txt b/api/current.txt
index ef00be7..4851c14 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -4625,13 +4625,11 @@
     method public boolean isEnabled();
     method public android.bluetooth.BluetoothServerSocket listenUsingInsecureRfcommWithServiceRecord(java.lang.String, java.util.UUID) throws java.io.IOException;
     method public android.bluetooth.BluetoothServerSocket listenUsingRfcommWithServiceRecord(java.lang.String, java.util.UUID) throws java.io.IOException;
-    method public boolean registerCallback(android.bluetooth.BluetoothAdapterCallback);
     method public boolean setName(java.lang.String);
     method public boolean startDiscovery();
-    method public boolean startLeScan();
-    method public boolean startLeScan(java.util.UUID[]);
-    method public void stopLeScan();
-    method public boolean unRegisterCallback(android.bluetooth.BluetoothAdapterCallback);
+    method public boolean startLeScan(android.bluetooth.BluetoothAdapter.LeScanCallback);
+    method public boolean startLeScan(java.util.UUID[], android.bluetooth.BluetoothAdapter.LeScanCallback);
+    method public void stopLeScan(android.bluetooth.BluetoothAdapter.LeScanCallback);
     field public static final java.lang.String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED";
     field public static final java.lang.String ACTION_DISCOVERY_FINISHED = "android.bluetooth.adapter.action.DISCOVERY_FINISHED";
     field public static final java.lang.String ACTION_DISCOVERY_STARTED = "android.bluetooth.adapter.action.DISCOVERY_STARTED";
@@ -4662,12 +4660,8 @@
     field public static final int STATE_TURNING_ON = 11; // 0xb
   }
 
-  public abstract class BluetoothAdapterCallback {
-    ctor public BluetoothAdapterCallback();
-    method public void onCallbackRegistration(int);
-    method public void onLeScan(android.bluetooth.BluetoothDevice, int, byte[]);
-    field public static final int CALLBACK_REGISTERED = 0; // 0x0
-    field public static final int CALLBACK_REGISTRATION_FAILURE = 1; // 0x1
+  public static abstract interface BluetoothAdapter.LeScanCallback {
+    method public abstract void onLeScan(android.bluetooth.BluetoothDevice, int, byte[]);
   }
 
   public class BluetoothAssignedNumbers {
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 2e9c9e3..3498bb8 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -20,7 +20,6 @@
 import android.annotation.SdkConstant.SdkConstantType;
 import android.content.Context;
 import android.os.Binder;
-import android.os.Handler;
 import android.os.IBinder;
 import android.os.Message;
 import android.os.ParcelUuid;
@@ -30,11 +29,14 @@
 import android.util.Pair;
 
 import java.io.IOException;
+import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.HashMap;
 import java.util.LinkedList;
+import java.util.Map;
 import java.util.Random;
 import java.util.Set;
 import java.util.UUID;
@@ -357,9 +359,7 @@
     private final IBluetoothManager mManagerService;
     private IBluetooth mService;
 
-    private Handler mServiceRecordHandler;
-    private BluetoothAdapterCallback mCallback;
-    private int mClientIf;
+    private final Map<LeScanCallback, GattCallbackWrapper> mLeScanClients;
 
     /**
      * Get a handle to the default local Bluetooth adapter.
@@ -394,7 +394,7 @@
             mService = managerService.registerAdapter(mManagerCallback);
         } catch (RemoteException e) {Log.e(TAG, "", e);}
         mManagerService = managerService;
-        mServiceRecordHandler = null;
+        mLeScanClients = new HashMap<LeScanCallback, GattCallbackWrapper>();
     }
 
     /**
@@ -1409,72 +1409,38 @@
     }
 
     /**
-     * Register an callback to receive async results, such as LE scan result.
+     * Callback interface used to deliver LE scan results.
      *
-     * <p>This is an asynchronous call. The callback
-     * {@link BluetoothAdapterCallback#onCallbackRegistration}
-     * is used to notify success or failure if the function returns true.
-     *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
-     *
-     * @param callback BluetootAdapter callback handler that will receive asynchronous callbacks.
-     * @return If true, the callback will be called to notify success or failure,
-     *         false on immediate error
+     * @see #startLeScan(LeScanCallback)
+     * @see #startLeScan(UUID[], LeScanCallback)
      */
-    public boolean registerCallback(BluetoothAdapterCallback callback) {
-        try {
-            IBluetoothGatt iGatt = (IBluetoothGatt) mManagerService.getBluetoothGatt();
-            mCallback = callback;
-            UUID uuid = UUID.randomUUID();
-            if (DBG) Log.d(TAG, "registerCallback() - UUID=" + uuid);
-
-            iGatt.registerClient(new ParcelUuid(uuid), mBluetoothGattCallback);
-            return true;
-        } catch (RemoteException e) {
-            Log.e(TAG,"",e);
-            return false;
-        }
-    }
-
-    /**
-     * Unregister the registered callback.
-     */
-    public boolean unRegisterCallback(BluetoothAdapterCallback callback) {
-        if (callback != mCallback) return false;
-        try {
-            IBluetoothGatt iGatt = (IBluetoothGatt) mManagerService.getBluetoothGatt();
-
-            iGatt.unregisterClient(mClientIf);
-            return true;
-        } catch (RemoteException e) {
-            Log.e(TAG,"",e);
-            return false;
-        }
+    public interface LeScanCallback {
+        /**
+         * Callback reporting an LE device found during a device scan initiated
+         * by the {@link BluetoothAdapter#startLeScan} function.
+         *
+         * @param device Identifies the remote device
+         * @param rssi The RSSI value for the remote device as reported by the
+         *             Bluetooth hardware. 0 if no RSSI value is available.
+         * @param scanRecord The content of the advertisement record offered by
+         *                   the remote device.
+         */
+        public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord);
     }
 
     /**
      * Starts a scan for Bluetooth LE devices.
      *
      * <p>Results of the scan are reported using the
-     * {@link BluetoothAdapterCallback#onLeScan} callback.
+     * {@link LeScanCallback#onLeScan} callback.
      *
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
      *
+     * @param callback the callback LE scan results are delivered
      * @return true, if the scan was started successfully
      */
-    public boolean startLeScan() {
-        if (DBG) Log.d(TAG, "startLeScan()");
-        if (mClientIf == 0) return false;
-
-        try {
-            IBluetoothGatt iGatt = (IBluetoothGatt) mManagerService.getBluetoothGatt();
-            iGatt.startScan(mClientIf, false);
-        } catch (RemoteException e) {
-            Log.e(TAG,"",e);
-            return false;
-        }
-
-        return true;
+    public boolean startLeScan(LeScanCallback callback) {
+        return startLeScan(null, callback);
     }
 
     /**
@@ -1482,155 +1448,281 @@
      * advertise given services.
      *
      * <p>Devices which advertise all specified services are reported using the
-     * {@link BluetoothAdapterCallback#onLeScan} callback.
+     * {@link LeScanCallback#onLeScan} callback.
      *
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
      *
      * @param serviceUuids Array of services to look for
+     * @param callback the callback LE scan results are delivered
      * @return true, if the scan was started successfully
      */
-    public boolean startLeScan(UUID[] serviceUuids) {
-        if (DBG) Log.d(TAG, "startLeScan() - with UUIDs");
-        if (mClientIf == 0) return false;
+    public boolean startLeScan(UUID[] serviceUuids, LeScanCallback callback) {
+        if (DBG) Log.d(TAG, "startLeScan(): " + serviceUuids);
 
-        try {
-            IBluetoothGatt iGatt = (IBluetoothGatt) mManagerService.getBluetoothGatt();
-            ParcelUuid[] uuids = new ParcelUuid[serviceUuids.length];
-            for(int i = 0; i != uuids.length; ++i) {
-                uuids[i] = new ParcelUuid(serviceUuids[i]);
-            }
-            iGatt.startScanWithUuids(mClientIf, false, uuids);
-        } catch (RemoteException e) {
-            Log.e(TAG,"",e);
+        if (callback == null) {
+            if (DBG) Log.e(TAG, "startLeScan: null callback");
             return false;
         }
 
-        return true;
+        synchronized(mLeScanClients) {
+            if (mLeScanClients.containsKey(callback)) {
+                if (DBG) Log.e(TAG, "LE Scan has already started");
+                return false;
+            }
+
+            try {
+                IBluetoothGatt iGatt = mManagerService.getBluetoothGatt();
+                UUID uuid = UUID.randomUUID();
+                GattCallbackWrapper wrapper = new GattCallbackWrapper(this, callback, serviceUuids);
+
+                iGatt.registerClient(new ParcelUuid(uuid), wrapper);
+                if (wrapper.scanStarted()) {
+                    mLeScanClients.put(callback, wrapper);
+                    return true;
+                }
+            } catch (RemoteException e) {
+                Log.e(TAG,"",e);
+            }
+        }
+        return false;
     }
 
     /**
      * Stops an ongoing Bluetooth LE device scan.
      *
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
+     *
+     * @param callback used to identify which scan to stop
+     *        must be the same handle used to start the scan
      */
-    public void stopLeScan() {
-        if (DBG) Log.d(TAG, "stopScan()");
-        if (mClientIf == 0) return;
-
-        try {
-            IBluetoothGatt iGatt = (IBluetoothGatt) mManagerService.getBluetoothGatt();
-            iGatt.stopScan(mClientIf, false);
-        } catch (RemoteException e) {
-            Log.e(TAG,"",e);
+    public void stopLeScan(LeScanCallback callback) {
+        if (DBG) Log.d(TAG, "stopLeScan()");
+        GattCallbackWrapper wrapper;
+        synchronized(mLeScanClients) {
+            wrapper = mLeScanClients.remove(callback);
+            if (wrapper == null) return;
         }
+        wrapper.stopLeScan();
     }
 
     /**
      * Bluetooth GATT interface callbacks
      */
-    private final IBluetoothGattCallback mBluetoothGattCallback =
-        new IBluetoothGattCallback.Stub() {
-            /**
-             * Application interface registered - app is ready to go
-             */
-            public void onClientRegistered(int status, int clientIf) {
-                if (DBG) Log.d(TAG, "onClientRegistered() - status=" + status
-                    + " clientIf=" + clientIf);
-                mClientIf = clientIf;
-                mCallback.onCallbackRegistration(status == BluetoothGatt.GATT_SUCCESS ?
-                                  BluetoothAdapterCallback.CALLBACK_REGISTERED :
-                                  BluetoothAdapterCallback.CALLBACK_REGISTRATION_FAILURE);
-            }
+    private static class GattCallbackWrapper extends IBluetoothGattCallback.Stub {
+        private static final int LE_CALLBACK_REG_TIMEOUT = 2000;
+        private static final int LE_CALLBACK_REG_WAIT_COUNT = 5;
 
-            public void onClientConnectionState(int status, int clientIf,
-                                                boolean connected, String address) {
-                // no op
-            }
+        private final LeScanCallback mLeScanCb;
+        // mLeHandle 0: not registered
+        //           -1: scan stopped
+        //           >0: registered and scan started
+        private int mLeHandle;
+        private final UUID[] mScanFilter;
+        private WeakReference<BluetoothAdapter> mBluetoothAdapter;
 
-            /**
-             * Callback reporting an LE scan result.
-             * @hide
-             */
-            public void onScanResult(String address, int rssi, byte[] advData) {
-                if (DBG) Log.d(TAG, "onScanResult() - Device=" + address + " RSSI=" +rssi);
+        public GattCallbackWrapper(BluetoothAdapter bluetoothAdapter,
+                                   LeScanCallback leScanCb, UUID[] uuid) {
+            mBluetoothAdapter = new WeakReference<BluetoothAdapter>(bluetoothAdapter);
+            mLeScanCb = leScanCb;
+            mScanFilter = uuid;
+            mLeHandle = 0;
+        }
 
-                try {
-                    mCallback.onLeScan(getRemoteDevice(address), rssi, advData);
-                } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception: " + ex);
+        public boolean scanStarted() {
+            boolean started = false;
+            synchronized(this) {
+                if (mLeHandle == -1) return false;
+
+                int count = 0;
+                // wait for callback registration and LE scan to start
+                while (mLeHandle == 0 && count < LE_CALLBACK_REG_WAIT_COUNT) {
+                    try {
+                        wait(LE_CALLBACK_REG_TIMEOUT);
+                    } catch (InterruptedException e) {
+                        Log.e(TAG, "Callback reg wait interrupted: " + e);
+                    }
+                    count++;
                 }
+                started = (mLeHandle > 0);
             }
+            return started;
+        }
 
-            public void onGetService(String address, int srvcType,
-                                     int srvcInstId, ParcelUuid srvcUuid) {
-                // no op
+        public void stopLeScan() {
+            synchronized(this) {
+                if (mLeHandle <= 0) {
+                    Log.e(TAG, "Error state, mLeHandle: " + mLeHandle);
+                    return;
+                }
+                BluetoothAdapter adapter = mBluetoothAdapter.get();
+                if (adapter != null) {
+                    try {
+                        IBluetoothGatt iGatt = adapter.getBluetoothManager().getBluetoothGatt();
+                        iGatt.stopScan(mLeHandle, false);
+                        iGatt.unregisterClient(mLeHandle);
+                    } catch (RemoteException e) {
+                        Log.e(TAG, "Failed to stop scan and unregister" + e);
+                    }
+                } else {
+                    Log.e(TAG, "stopLeScan, BluetoothAdapter is null");
+                }
+                mLeHandle = -1;
+                notifyAll();
             }
+        }
 
-            public void onGetIncludedService(String address, int srvcType,
-                                             int srvcInstId, ParcelUuid srvcUuid,
-                                             int inclSrvcType, int inclSrvcInstId,
-                                             ParcelUuid inclSrvcUuid) {
-                // no op
+        /**
+         * Application interface registered - app is ready to go
+         */
+        public void onClientRegistered(int status, int clientIf) {
+            if (DBG) Log.d(TAG, "onClientRegistered() - status=" + status +
+                           " clientIf=" + clientIf);
+            synchronized(this) {
+                if (mLeHandle == -1) {
+                    if (DBG) Log.d(TAG, "onClientRegistered LE scan canceled");
+                }
+
+                if (status == BluetoothGatt.GATT_SUCCESS) {
+                    mLeHandle = clientIf;
+                    IBluetoothGatt iGatt = null;
+                    try {
+                        BluetoothAdapter adapter = mBluetoothAdapter.get();
+                        if (adapter != null) {
+                            iGatt = adapter.getBluetoothManager().getBluetoothGatt();
+                            if (mScanFilter == null) {
+                                iGatt.startScan(mLeHandle, false);
+                            } else {
+                                ParcelUuid[] uuids = new ParcelUuid[mScanFilter.length];
+                                for(int i = 0; i != uuids.length; ++i) {
+                                    uuids[i] = new ParcelUuid(mScanFilter[i]);
+                                }
+                                iGatt.startScanWithUuids(mLeHandle, false, uuids);
+                            }
+                        } else {
+                            Log.e(TAG, "onClientRegistered, BluetoothAdapter null");
+                            mLeHandle = -1;
+                        }
+                    } catch (RemoteException e) {
+                        Log.e(TAG, "fail to start le scan: " + e);
+                        mLeHandle = -1;
+                    }
+                    if (mLeHandle == -1) {
+                        // registration succeeded but start scan failed
+                        if (iGatt != null) {
+                            try {
+                                iGatt.unregisterClient(mLeHandle);
+                            } catch (RemoteException e) {
+                                Log.e(TAG, "fail to unregister callback: " + mLeHandle +
+                                      " error: " + e);
+                            }
+                        }
+                    }
+                } else {
+                    // registration failed
+                    mLeHandle = -1;
+                }
+                notifyAll();
             }
+        }
 
-            public void onGetCharacteristic(String address, int srvcType,
-                             int srvcInstId, ParcelUuid srvcUuid,
-                             int charInstId, ParcelUuid charUuid,
-                             int charProps) {
-                // no op
+        public void onClientConnectionState(int status, int clientIf,
+                                            boolean connected, String address) {
+            // no op
+        }
+
+        /**
+         * Callback reporting an LE scan result.
+         * @hide
+         */
+        public void onScanResult(String address, int rssi, byte[] advData) {
+            if (DBG) Log.d(TAG, "onScanResult() - Device=" + address + " RSSI=" +rssi);
+
+            // Check null in case the scan has been stopped
+            synchronized(this) {
+                if (mLeHandle <= 0) return;
             }
-
-            public void onGetDescriptor(String address, int srvcType,
-                             int srvcInstId, ParcelUuid srvcUuid,
-                             int charInstId, ParcelUuid charUuid,
-                             ParcelUuid descUuid) {
-                // no op
+            try {
+                BluetoothAdapter adapter = mBluetoothAdapter.get();
+                if (adapter == null) {
+                    Log.d(TAG, "onScanResult, BluetoothAdapter null");
+                    return;
+                }
+                mLeScanCb.onLeScan(adapter.getRemoteDevice(address), rssi, advData);
+            } catch (Exception ex) {
+                Log.w(TAG, "Unhandled exception: " + ex);
             }
+        }
 
-            public void onSearchComplete(String address, int status) {
-                // no op
-            }
+        public void onGetService(String address, int srvcType,
+                                 int srvcInstId, ParcelUuid srvcUuid) {
+            // no op
+        }
 
-            public void onCharacteristicRead(String address, int status, int srvcType,
-                             int srvcInstId, ParcelUuid srvcUuid,
-                             int charInstId, ParcelUuid charUuid, byte[] value) {
-                // no op
-            }
+        public void onGetIncludedService(String address, int srvcType,
+                                         int srvcInstId, ParcelUuid srvcUuid,
+                                         int inclSrvcType, int inclSrvcInstId,
+                                         ParcelUuid inclSrvcUuid) {
+            // no op
+        }
 
-            public void onCharacteristicWrite(String address, int status, int srvcType,
-                             int srvcInstId, ParcelUuid srvcUuid,
-                             int charInstId, ParcelUuid charUuid) {
-                // no op
-            }
+        public void onGetCharacteristic(String address, int srvcType,
+                                        int srvcInstId, ParcelUuid srvcUuid,
+                                        int charInstId, ParcelUuid charUuid,
+                                        int charProps) {
+            // no op
+        }
 
-            public void onNotify(String address, int srvcType,
+        public void onGetDescriptor(String address, int srvcType,
+                                    int srvcInstId, ParcelUuid srvcUuid,
+                                    int charInstId, ParcelUuid charUuid,
+                                    ParcelUuid descUuid) {
+            // no op
+        }
+
+        public void onSearchComplete(String address, int status) {
+            // no op
+        }
+
+        public void onCharacteristicRead(String address, int status, int srvcType,
+                                         int srvcInstId, ParcelUuid srvcUuid,
+                                         int charInstId, ParcelUuid charUuid, byte[] value) {
+            // no op
+        }
+
+        public void onCharacteristicWrite(String address, int status, int srvcType,
+                                          int srvcInstId, ParcelUuid srvcUuid,
+                                          int charInstId, ParcelUuid charUuid) {
+            // no op
+        }
+
+        public void onNotify(String address, int srvcType,
                              int srvcInstId, ParcelUuid srvcUuid,
                              int charInstId, ParcelUuid charUuid,
                              byte[] value) {
-                // no op
-            }
+            // no op
+        }
 
-            public void onDescriptorRead(String address, int status, int srvcType,
-                             int srvcInstId, ParcelUuid srvcUuid,
-                             int charInstId, ParcelUuid charUuid,
-                             ParcelUuid descrUuid, byte[] value) {
-                // no op
-            }
+        public void onDescriptorRead(String address, int status, int srvcType,
+                                     int srvcInstId, ParcelUuid srvcUuid,
+                                     int charInstId, ParcelUuid charUuid,
+                                     ParcelUuid descrUuid, byte[] value) {
+            // no op
+        }
 
-            public void onDescriptorWrite(String address, int status, int srvcType,
-                             int srvcInstId, ParcelUuid srvcUuid,
-                             int charInstId, ParcelUuid charUuid,
-                             ParcelUuid descrUuid) {
-                // no op
-            }
+        public void onDescriptorWrite(String address, int status, int srvcType,
+                                      int srvcInstId, ParcelUuid srvcUuid,
+                                      int charInstId, ParcelUuid charUuid,
+                                      ParcelUuid descrUuid) {
+            // no op
+        }
 
-            public void onExecuteWrite(String address, int status) {
-                // no op
-            }
+        public void onExecuteWrite(String address, int status) {
+            // no op
+        }
 
-            public void onReadRemoteRssi(String address, int rssi, int status) {
-                // no op
-            }
-        };
+        public void onReadRemoteRssi(String address, int rssi, int status) {
+            // no op
+        }
+    }
 
 }
diff --git a/core/java/android/bluetooth/BluetoothAdapterCallback.java b/core/java/android/bluetooth/BluetoothAdapterCallback.java
deleted file mode 100644
index a726bc9..0000000
--- a/core/java/android/bluetooth/BluetoothAdapterCallback.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import android.bluetooth.BluetoothDevice;
-
-/**
- * This abstract class is used to implement {@link BluetoothAdapter} callbacks.
- */
-public abstract class BluetoothAdapterCallback {
-
-    /**
-     * Indicates the callback has been registered successfully
-     */
-    public static final int CALLBACK_REGISTERED = 0;
-
-    /**
-     * Indicates the callback registration has failed
-     */
-    public static final int CALLBACK_REGISTRATION_FAILURE = 1;
-
-    /**
-     * Callback to inform change in registration state of the  application.
-     *
-     * @param status Returns {@link #CALLBACK_REGISTERED} if the application
-     *               was successfully registered.
-     */
-    public void onCallbackRegistration(int status) {
-    }
-
-    /**
-     * Callback reporting an LE device found during a device scan initiated
-     * by the {@link BluetoothAdapter#startLeScan} function.
-     *
-     * @param device Identifies the remote device
-     * @param rssi The RSSI value for the remote device as reported by the
-     *             Bluetooth hardware. 0 if no RSSI value is available.
-     * @param scanRecord The content of the advertisement record offered by
-     *                   the remote device.
-     */
-    public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothManager.java b/core/java/android/bluetooth/BluetoothManager.java
index 19083b5..172f3bc 100644
--- a/core/java/android/bluetooth/BluetoothManager.java
+++ b/core/java/android/bluetooth/BluetoothManager.java
@@ -127,7 +127,7 @@
 
         try {
             IBluetoothManager managerService = mAdapter.getBluetoothManager();
-            IBluetoothGatt iGatt = (IBluetoothGatt) managerService.getBluetoothGatt();
+            IBluetoothGatt iGatt = managerService.getBluetoothGatt();
             if (iGatt == null) return connectedDevices;
 
             connectedDevices = iGatt.getDevicesMatchingConnectionStates(
@@ -172,7 +172,7 @@
 
         try {
             IBluetoothManager managerService = mAdapter.getBluetoothManager();
-            IBluetoothGatt iGatt = (IBluetoothGatt) managerService.getBluetoothGatt();
+            IBluetoothGatt iGatt = managerService.getBluetoothGatt();
             if (iGatt == null) return devices;
             devices = iGatt.getDevicesMatchingConnectionStates(states);
         } catch (RemoteException e) {
@@ -203,7 +203,7 @@
 
         try {
             IBluetoothManager managerService = mAdapter.getBluetoothManager();
-            IBluetoothGatt iGatt = (IBluetoothGatt) managerService.getBluetoothGatt();
+            IBluetoothGatt iGatt = managerService.getBluetoothGatt();
             if (iGatt == null) {
                 Log.e(TAG, "Fail to get GATT Server connection");
                 return null;