Change BluetoothGattCallback methods argument from BluetoothDevice to BluetoothGatt

Change name of BluetoothDevice#connectGattServer to BluetoothDevice#connectGatt
Add BluetoothGatt#getDevice to retrieve device from BluetoothGatt
Add BluetoothGatt#connect() to reconnect back to the server.
Make BluetoothGatt#close() public to clean up/unregister callback
Add BluetoothDevice.getType() to return int of
bug 8529188

Change-Id: Iebd9ac68cc7a64c43972e617dd3068f66c8ea0b2
diff --git a/api/current.txt b/api/current.txt
index 207a25d..acb763f 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -4850,7 +4850,7 @@
   }
 
   public final class BluetoothDevice implements android.os.Parcelable {
-    method public android.bluetooth.BluetoothGatt connectGattServer(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback);
+    method public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback);
     method public android.bluetooth.BluetoothSocket createInsecureRfcommSocketToServiceRecord(java.util.UUID) throws java.io.IOException;
     method public android.bluetooth.BluetoothSocket createRfcommSocketToServiceRecord(java.util.UUID) throws java.io.IOException;
     method public int describeContents();
@@ -4859,6 +4859,7 @@
     method public android.bluetooth.BluetoothClass getBluetoothClass();
     method public int getBondState();
     method public java.lang.String getName();
+    method public int getType();
     method public android.os.ParcelUuid[] getUuids();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final java.lang.String ACTION_ACL_CONNECTED = "android.bluetooth.device.action.ACL_CONNECTED";
@@ -4873,6 +4874,10 @@
     field public static final int BOND_BONDING = 11; // 0xb
     field public static final int BOND_NONE = 10; // 0xa
     field public static final android.os.Parcelable.Creator CREATOR;
+    field public static final int DEVICE_TYPE_CLASSIC = 1; // 0x1
+    field public static final int DEVICE_TYPE_DUAL = 3; // 0x3
+    field public static final int DEVICE_TYPE_LE = 2; // 0x2
+    field public static final int DEVICE_TYPE_UNKNOWN = 0; // 0x0
     field public static final int ERROR = -2147483648; // 0x80000000
     field public static final java.lang.String EXTRA_BOND_STATE = "android.bluetooth.device.extra.BOND_STATE";
     field public static final java.lang.String EXTRA_CLASS = "android.bluetooth.device.extra.CLASS";
@@ -4886,11 +4891,14 @@
   public final class BluetoothGatt implements android.bluetooth.BluetoothProfile {
     method public void abortReliableWrite(android.bluetooth.BluetoothDevice);
     method public boolean beginReliableWrite();
+    method public void close();
+    method public boolean connect();
     method public void disconnect();
     method public boolean discoverServices();
     method public boolean executeReliableWrite();
     method public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
     method public int getConnectionState(android.bluetooth.BluetoothDevice);
+    method public android.bluetooth.BluetoothDevice getDevice();
     method public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(int[]);
     method public android.bluetooth.BluetoothGattService getService(java.util.UUID);
     method public java.util.List<android.bluetooth.BluetoothGattService> getServices();
@@ -4913,15 +4921,15 @@
 
   public abstract class BluetoothGattCallback {
     ctor public BluetoothGattCallback();
-    method public void onCharacteristicChanged(android.bluetooth.BluetoothGattCharacteristic);
-    method public void onCharacteristicRead(android.bluetooth.BluetoothGattCharacteristic, int);
-    method public void onCharacteristicWrite(android.bluetooth.BluetoothGattCharacteristic, int);
-    method public void onConnectionStateChange(android.bluetooth.BluetoothDevice, int, int);
-    method public void onDescriptorRead(android.bluetooth.BluetoothGattDescriptor, int);
-    method public void onDescriptorWrite(android.bluetooth.BluetoothGattDescriptor, int);
-    method public void onReadRemoteRssi(android.bluetooth.BluetoothDevice, int, int);
-    method public void onReliableWriteCompleted(android.bluetooth.BluetoothDevice, int);
-    method public void onServicesDiscovered(android.bluetooth.BluetoothDevice, int);
+    method public void onCharacteristicChanged(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic);
+    method public void onCharacteristicRead(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic, int);
+    method public void onCharacteristicWrite(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic, int);
+    method public void onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int);
+    method public void onDescriptorRead(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattDescriptor, int);
+    method public void onDescriptorWrite(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattDescriptor, int);
+    method public void onReadRemoteRssi(android.bluetooth.BluetoothGatt, int, int);
+    method public void onReliableWriteCompleted(android.bluetooth.BluetoothGatt, int);
+    method public void onServicesDiscovered(android.bluetooth.BluetoothGatt, int);
   }
 
   public class BluetoothGattCharacteristic {
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 83e95ca..3c1ec90 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -262,6 +262,26 @@
     public static final String EXTRA_PAIRING_KEY = "android.bluetooth.device.extra.PAIRING_KEY";
 
     /**
+     * Bluetooth device type, Unknown
+     */
+    public static final int DEVICE_TYPE_UNKNOWN = 0;
+
+    /**
+     * Bluetooth device type, Classic - BR/EDR devices
+     */
+    public static final int DEVICE_TYPE_CLASSIC = 1;
+
+    /**
+     * Bluetooth device type, Low Energy - LE-only
+     */
+    public static final int DEVICE_TYPE_LE = 2;
+
+    /**
+     * Bluetooth device type, Dual Mode - BR/EDR/LE
+     */
+    public static final int DEVICE_TYPE_DUAL = 3;
+
+    /**
      * Broadcast Action: This intent is used to broadcast the {@link UUID}
      * wrapped as a {@link android.os.ParcelUuid} of the remote device after it
      * has been fetched. This intent is sent only when the UUIDs of the remote
@@ -602,6 +622,26 @@
     }
 
     /**
+     * Get the Bluetooth device type of the remote device.
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
+     *
+     * @return the device type {@link #DEVICE_TYPE_CLASSIC}, {@link #DEVICE_TYPE_LE}
+     *                         {@link #DEVICE_TYPE_DUAL}.
+     *         {@link #DEVICE_TYPE_UNKNOWN} if it's not available
+     */
+    public int getType() {
+        if (sService == null) {
+            Log.e(TAG, "BT not enabled. Cannot get Remote Device type");
+            return DEVICE_TYPE_UNKNOWN;
+        }
+        try {
+            return sService.getRemoteType(this);
+        } catch (RemoteException e) {Log.e(TAG, "", e);}
+        return DEVICE_TYPE_UNKNOWN;
+    }
+
+    /**
      * Get the Bluetooth alias of the remote device.
      * <p>Alias is the locally modified name of a remote device.
      *
@@ -1139,8 +1179,8 @@
      *                    device becomes available (true).
      * @throws IllegalArgumentException if callback is null
      */
-    public BluetoothGatt connectGattServer(Context context, boolean autoConnect,
-                                           BluetoothGattCallback callback) {
+    public BluetoothGatt connectGatt(Context context, boolean autoConnect,
+                                     BluetoothGattCallback callback) {
         // TODO(Bluetooth) check whether platform support BLE
         //     Do the check here or in GattServer?
         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java
index f9ce6ea..bffe64b 100644
--- a/core/java/android/bluetooth/BluetoothGatt.java
+++ b/core/java/android/bluetooth/BluetoothGatt.java
@@ -43,7 +43,7 @@
  * with Bluetooth Smart or Smart Ready devices.
  *
  * <p>To connect to a remote peripheral device, create a {@link BluetoothGattCallback}
- * and call {@link BluetoothDevice#connectGattServer} to get a instance of this class.
+ * and call {@link BluetoothDevice#connectGatt} to get a instance of this class.
  * GATT capable devices can be discovered using the Bluetooth device discovery or BLE
  * scan process.
  */
@@ -66,6 +66,7 @@
     private static final int CONN_STATE_CONNECTING = 1;
     private static final int CONN_STATE_CONNECTED = 2;
     private static final int CONN_STATE_DISCONNECTING = 3;
+    private static final int CONN_STATE_CLOSED = 4;
 
     private List<BluetoothGattService> mServices;
 
@@ -135,7 +136,7 @@
                 }
                 mClientIf = clientIf;
                 if (status != GATT_SUCCESS) {
-                    mCallback.onConnectionStateChange(mDevice, GATT_FAILURE,
+                    mCallback.onConnectionStateChange(BluetoothGatt.this, GATT_FAILURE,
                                                       BluetoothProfile.STATE_DISCONNECTED);
                     synchronized(mStateLock) {
                         mConnState = CONN_STATE_IDLE;
@@ -164,7 +165,7 @@
                 int profileState = connected ? BluetoothProfile.STATE_CONNECTED :
                                                BluetoothProfile.STATE_DISCONNECTED;
                 try {
-                    mCallback.onConnectionStateChange(mDevice, status, profileState);
+                    mCallback.onConnectionStateChange(BluetoothGatt.this, status, profileState);
                 } catch (Exception ex) {
                     Log.w(TAG, "Unhandled exception: " + ex);
                 }
@@ -291,7 +292,7 @@
                     return;
                 }
                 try {
-                    mCallback.onServicesDiscovered(mDevice, status);
+                    mCallback.onServicesDiscovered(BluetoothGatt.this, status);
                 } catch (Exception ex) {
                     Log.w(TAG, "Unhandled exception: " + ex);
                 }
@@ -338,7 +339,7 @@
                 if (status == 0) characteristic.setValue(value);
 
                 try {
-                    mCallback.onCharacteristicRead(characteristic, status);
+                    mCallback.onCharacteristicRead(BluetoothGatt.this, characteristic, status);
                 } catch (Exception ex) {
                     Log.w(TAG, "Unhandled exception: " + ex);
                 }
@@ -384,7 +385,7 @@
                 mAuthRetry = false;
 
                 try {
-                    mCallback.onCharacteristicWrite(characteristic, status);
+                    mCallback.onCharacteristicWrite(BluetoothGatt.this, characteristic, status);
                 } catch (Exception ex) {
                     Log.w(TAG, "Unhandled exception: " + ex);
                 }
@@ -415,7 +416,7 @@
                 characteristic.setValue(value);
 
                 try {
-                    mCallback.onCharacteristicChanged(characteristic);
+                    mCallback.onCharacteristicChanged(BluetoothGatt.this, characteristic);
                 } catch (Exception ex) {
                     Log.w(TAG, "Unhandled exception: " + ex);
                 }
@@ -464,7 +465,7 @@
                 mAuthRetry = true;
 
                 try {
-                    mCallback.onDescriptorRead(descriptor, status);
+                    mCallback.onDescriptorRead(BluetoothGatt.this, descriptor, status);
                 } catch (Exception ex) {
                     Log.w(TAG, "Unhandled exception: " + ex);
                 }
@@ -512,7 +513,7 @@
                 mAuthRetry = false;
 
                 try {
-                    mCallback.onDescriptorWrite(descriptor, status);
+                    mCallback.onDescriptorWrite(BluetoothGatt.this, descriptor, status);
                 } catch (Exception ex) {
                     Log.w(TAG, "Unhandled exception: " + ex);
                 }
@@ -529,7 +530,7 @@
                     return;
                 }
                 try {
-                    mCallback.onReliableWriteCompleted(mDevice, status);
+                    mCallback.onReliableWriteCompleted(BluetoothGatt.this, status);
                 } catch (Exception ex) {
                     Log.w(TAG, "Unhandled exception: " + ex);
                 }
@@ -546,7 +547,7 @@
                     return;
                 }
                 try {
-                    mCallback.onReadRemoteRssi(mDevice, rssi, status);
+                    mCallback.onReadRemoteRssi(BluetoothGatt.this, rssi, status);
                 } catch (Exception ex) {
                     Log.w(TAG, "Unhandled exception: " + ex);
                 }
@@ -563,12 +564,13 @@
     }
 
     /**
-     * Close the connection to the gatt service.
+     * Close this Bluetooth GATT client.
      */
-    /*package*/ void close() {
+    public void close() {
         if (DBG) Log.d(TAG, "close()");
 
         unregisterApp();
+        mConnState = CONN_STATE_CLOSED;
     }
 
     /**
@@ -694,7 +696,35 @@
         } catch (RemoteException e) {
             Log.e(TAG,"",e);
         }
-        // TBD deregister after conneciton is torn down
+    }
+
+    /**
+     * Connect back to remote device.
+     *
+     * <p>This method is used to re-connect to a remote device after the
+     * connection has been dropped. If the device is not in range, the
+     * re-connection will be triggered once the device is back in range.
+     *
+     * @return true, if the connection attempt was initiated successfully
+     */
+    public boolean connect() {
+        try {
+            mService.clientConnect(mClientIf, mDevice.getAddress(),
+                                   false); // autoConnect is inverse of "isDirect"
+            return true;
+        } catch (RemoteException e) {
+            Log.e(TAG,"",e);
+            return false;
+        }
+    }
+
+    /**
+     * Return the remote bluetooth device this GATT client targets to
+     *
+     * @return remote bluetooth device
+     */
+    public BluetoothDevice getDevice() {
+        return mDevice;
     }
 
     /**
diff --git a/core/java/android/bluetooth/BluetoothGattCallback.java b/core/java/android/bluetooth/BluetoothGattCallback.java
index c9e5fea..2259c1e 100644
--- a/core/java/android/bluetooth/BluetoothGattCallback.java
+++ b/core/java/android/bluetooth/BluetoothGattCallback.java
@@ -16,23 +16,22 @@
 
 package android.bluetooth;
 
-import android.bluetooth.BluetoothDevice;
-
 /**
  * This abstract class is used to implement {@link BluetoothGatt} callbacks.
  */
 public abstract class BluetoothGattCallback {
 
     /**
-     * Callback indicating when a remote device has been connected or disconnected.
+     * Callback indicating when GATT client has connected/disconnected to/from a remote
+     * GATT server.
      *
-     * @param device Remote device that has been connected or disconnected.
+     * @param gatt GATT client
      * @param status Status of the connect or disconnect operation.
      * @param newState Returns the new connection state. Can be one of
      *                  {@link BluetoothProfile#STATE_DISCONNECTED} or
      *                  {@link BluetoothProfile#STATE_CONNECTED}
      */
-    public void onConnectionStateChange(BluetoothDevice device, int status,
+    public void onConnectionStateChange(BluetoothGatt gatt, int status,
                                         int newState) {
     }
 
@@ -40,22 +39,23 @@
      * Callback invoked when the list of remote services, characteristics and descriptors
      * for the remote device have been updated, ie new services have been discovered.
      *
-     * @param device Remote device
+     * @param gatt GATT client invoked {@link BluetoothGatt#discoverServices}
      * @param status {@link BluetoothGatt#GATT_SUCCESS} if the remote device
      *               has been explored successfully.
      */
-    public void onServicesDiscovered(BluetoothDevice device, int status) {
+    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
     }
 
     /**
      * Callback reporting the result of a characteristic read operation.
      *
+     * @param gatt GATT client invoked {@link BluetoothGatt#readCharacteristic}
      * @param characteristic Characteristic that was read from the associated
      *                       remote device.
      * @param status {@link BluetoothGatt#GATT_SUCCESS} if the read operation
      *               was completed successfully.
      */
-    public void onCharacteristicRead(BluetoothGattCharacteristic characteristic,
+    public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic,
                                      int status) {
     }
 
@@ -68,52 +68,59 @@
      * value to the desired value to be written. If the values don't match,
      * the application must abort the reliable write transaction.
      *
+     * @param gatt GATT client invoked {@link BluetoothGatt#writeCharacteristic}
      * @param characteristic Characteristic that was written to the associated
      *                       remote device.
      * @param status The result of the write operation
      */
-    public void onCharacteristicWrite(BluetoothGattCharacteristic characteristic,
-                                      int status) {
+    public void onCharacteristicWrite(BluetoothGatt gatt,
+                                      BluetoothGattCharacteristic characteristic, int status) {
     }
 
     /**
      * Callback triggered as a result of a remote characteristic notification.
      *
+     * @param gatt GATT client the characteristic is associated with
      * @param characteristic Characteristic that has been updated as a result
      *                       of a remote notification event.
      */
-    public void onCharacteristicChanged(BluetoothGattCharacteristic characteristic) {
+    public void onCharacteristicChanged(BluetoothGatt gatt,
+                                        BluetoothGattCharacteristic characteristic) {
     }
 
     /**
      * Callback reporting the result of a descriptor read operation.
      *
+     * @param gatt GATT client invoked {@link BluetoothGatt#readDescriptor}
      * @param descriptor Descriptor that was read from the associated
      *                   remote device.
      * @param status {@link BluetoothGatt#GATT_SUCCESS} if the read operation
      *               was completed successfully
      */
-    public void onDescriptorRead(BluetoothGattDescriptor descriptor, int status) {
+    public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
+                                 int status) {
     }
 
     /**
      * Callback indicating the result of a descriptor write operation.
      *
+     * @param gatt GATT client invoked {@link BluetoothGatt#writeDescriptor}
      * @param descriptor Descriptor that was writte to the associated
      *                   remote device.
      * @param status The result of the write operation
      */
-    public void onDescriptorWrite(BluetoothGattDescriptor descriptor, int status) {
+    public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
+                                  int status) {
     }
 
     /**
      * Callback invoked when a reliable write transaction has been completed.
      *
-     * @param device Remote device
+     * @param gatt GATT client invoked {@link BluetoothGatt#executeReliableWrite}
      * @param status {@link BluetoothGatt#GATT_SUCCESS} if the reliable write
      *               transaction was executed successfully
      */
-    public void onReliableWriteCompleted(BluetoothDevice device, int status) {
+    public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
     }
 
     /**
@@ -122,10 +129,10 @@
      * This callback is triggered in response to the
      * {@link BluetoothGatt#readRemoteRssi} function.
      *
-     * @param device Identifies the remote device
+     * @param gatt GATT client invoked {@link BluetoothGatt#readRemoteRssi}
      * @param rssi The RSSI value for the remote device
      * @param status {@link BluetoothGatt#GATT_SUCCESS} if the RSSI was read successfully
      */
-    public void onReadRemoteRssi(BluetoothDevice device, int rssi, int status) {
+    public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
     }
 }
diff --git a/core/java/android/bluetooth/BluetoothGattCharacteristic.java b/core/java/android/bluetooth/BluetoothGattCharacteristic.java
index d63d97e..033f079 100644
--- a/core/java/android/bluetooth/BluetoothGattCharacteristic.java
+++ b/core/java/android/bluetooth/BluetoothGattCharacteristic.java
@@ -22,6 +22,10 @@
 
 /**
  * Represents a Bluetooth GATT Characteristic
+ *
+ * <p>A GATT characteristic is a basic data element used to construct a GATT service,
+ * {@link BluetoothGattService}. The characteristic contains a value as well as
+ * additional information and optional GATT descriptors, {@link BluetoothGattDescriptor}.
  */
 public class BluetoothGattCharacteristic {
 
diff --git a/core/java/android/bluetooth/BluetoothGattDescriptor.java b/core/java/android/bluetooth/BluetoothGattDescriptor.java
index 6ba2db7..1cd6878 100644
--- a/core/java/android/bluetooth/BluetoothGattDescriptor.java
+++ b/core/java/android/bluetooth/BluetoothGattDescriptor.java
@@ -20,6 +20,10 @@
 
 /**
  * Represents a Bluetooth GATT Descriptor
+ *
+ * <p> GATT Descriptors contain additional information and attributes of a GATT
+ * characteristic, {@link BluetoothGattCharacteristic}. They can be used to describe
+ * the characteristic's features or to control certain behaviours of the characteristic.
  */
 public class BluetoothGattDescriptor {
 
diff --git a/core/java/android/bluetooth/BluetoothGattService.java b/core/java/android/bluetooth/BluetoothGattService.java
index c3b3cfe..39a435b 100644
--- a/core/java/android/bluetooth/BluetoothGattService.java
+++ b/core/java/android/bluetooth/BluetoothGattService.java
@@ -23,6 +23,9 @@
 
 /**
  * Represents a Bluetooth GATT Service
+ *
+ * <p> Gatt Service contains a collection of {@link BluetoothGattCharacteristic},
+ * as well as referenced services.
  */
 public class BluetoothGattService {
 
diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl
index d016c26..80806f9 100644
--- a/core/java/android/bluetooth/IBluetooth.aidl
+++ b/core/java/android/bluetooth/IBluetooth.aidl
@@ -60,6 +60,7 @@
     int getBondState(in BluetoothDevice device);
 
     String getRemoteName(in BluetoothDevice device);
+    int getRemoteType(in BluetoothDevice device);
     String getRemoteAlias(in BluetoothDevice device);
     boolean setRemoteAlias(in BluetoothDevice device, in String name);
     int getRemoteClass(in BluetoothDevice device);