Refactor Bluetooth Profile.

Move connect / disconnect / set and get priority
functions down the interface as they are not generic enough
for all profiles.

Change-Id: I2656e1bdbc8046c53bb0dfbd9172f5f10b57aa7d
diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java
index 9246a10..61d3707 100644
--- a/core/java/android/bluetooth/BluetoothA2dp.java
+++ b/core/java/android/bluetooth/BluetoothA2dp.java
@@ -130,7 +130,25 @@
     }
 
     /**
-     * {@inheritDoc}
+     * Initiate connection to a profile of the remote bluetooth device.
+     *
+     * <p> Currently, the system supports only 1 connection to the
+     * A2DP profile. The API will automatically disconnect connected
+     * devices before connecting.
+     *
+     * <p> This API returns false in scenarios like the profile on the
+     * device is already connected or Bluetooth is not turned on.
+     * When this API returns true, it is guaranteed that
+     * connection state intent for the profile will be broadcasted with
+     * the state. Users can get the connection state of the profile
+     * from this intent.
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
+     * permission.
+     *
+     * @param device Remote Bluetooth Device
+     * @return false on immediate error,
+     *               true otherwise
      * @hide
      */
     public boolean connect(BluetoothDevice device) {
@@ -149,7 +167,29 @@
     }
 
     /**
-     * {@inheritDoc}
+     * Initiate disconnection from a profile
+     *
+     * <p> This API will return false in scenarios like the profile on the
+     * Bluetooth device is not in connected state etc. When this API returns,
+     * true, it is guaranteed that the connection state change
+     * intent will be broadcasted with the state. Users can get the
+     * disconnection state of the profile from this intent.
+     *
+     * <p> If the disconnection is initiated by a remote device, the state
+     * will transition from {@link #STATE_CONNECTED} to
+     * {@link #STATE_DISCONNECTED}. If the disconnect is initiated by the
+     * host (local) device the state will transition from
+     * {@link #STATE_CONNECTED} to state {@link #STATE_DISCONNECTING} to
+     * state {@link #STATE_DISCONNECTED}. The transition to
+     * {@link #STATE_DISCONNECTING} can be used to distinguish between the
+     * two scenarios.
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
+     * permission.
+     *
+     * @param device Remote Bluetooth Device
+     * @return false on immediate error,
+     *               true otherwise
      * @hide
      */
     public boolean disconnect(BluetoothDevice device) {
@@ -220,7 +260,18 @@
     }
 
     /**
-     * {@inheritDoc}
+     * Set priority of the profile
+     *
+     * <p> The device should already be paired.
+     *  Priority can be one of {@link #PRIORITY_ON} or
+     * {@link #PRIORITY_OFF},
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
+     * permission.
+     *
+     * @param device Paired bluetooth device
+     * @param priority
+     * @return true if priority is set, false on error
      * @hide
      */
     public boolean setPriority(BluetoothDevice device, int priority) {
@@ -243,7 +294,16 @@
     }
 
     /**
-     * {@inheritDoc}
+     * Get the priority of the profile.
+     *
+     * <p> The priority can be any of:
+     * {@link #PRIORITY_AUTO_CONNECT}, {@link #PRIORITY_OFF},
+     * {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
+     *
+     * @param device Bluetooth device
+     * @return priority of the device
      * @hide
      */
     public int getPriority(BluetoothDevice device) {
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
index 8a9bef0..23724f2 100644
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ b/core/java/android/bluetooth/BluetoothHeadset.java
@@ -248,7 +248,25 @@
     }
 
     /**
-     * {@inheritDoc}
+     * Initiate connection to a profile of the remote bluetooth device.
+     *
+     * <p> Currently, the system supports only 1 connection to the
+     * headset/handsfree profile. The API will automatically disconnect connected
+     * devices before connecting.
+     *
+     * <p> This API returns false in scenarios like the profile on the
+     * device is already connected or Bluetooth is not turned on.
+     * When this API returns true, it is guaranteed that
+     * connection state intent for the profile will be broadcasted with
+     * the state. Users can get the connection state of the profile
+     * from this intent.
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
+     * permission.
+     *
+     * @param device Remote Bluetooth Device
+     * @return false on immediate error,
+     *               true otherwise
      * @hide
      */
     public boolean connect(BluetoothDevice device) {
@@ -267,7 +285,29 @@
     }
 
     /**
-     * {@inheritDoc}
+     * Initiate disconnection from a profile
+     *
+     * <p> This API will return false in scenarios like the profile on the
+     * Bluetooth device is not in connected state etc. When this API returns,
+     * true, it is guaranteed that the connection state change
+     * intent will be broadcasted with the state. Users can get the
+     * disconnection state of the profile from this intent.
+     *
+     * <p> If the disconnection is initiated by a remote device, the state
+     * will transition from {@link #STATE_CONNECTED} to
+     * {@link #STATE_DISCONNECTED}. If the disconnect is initiated by the
+     * host (local) device the state will transition from
+     * {@link #STATE_CONNECTED} to state {@link #STATE_DISCONNECTING} to
+     * state {@link #STATE_DISCONNECTED}. The transition to
+     * {@link #STATE_DISCONNECTING} can be used to distinguish between the
+     * two scenarios.
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
+     * permission.
+     *
+     * @param device Remote Bluetooth Device
+     * @return false on immediate error,
+     *               true otherwise
      * @hide
      */
     public boolean disconnect(BluetoothDevice device) {
@@ -338,7 +378,18 @@
     }
 
     /**
-     * {@inheritDoc}
+     * Set priority of the profile
+     *
+     * <p> The device should already be paired.
+     *  Priority can be one of {@link #PRIORITY_ON} or
+     * {@link #PRIORITY_OFF},
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
+     * permission.
+     *
+     * @param device Paired bluetooth device
+     * @param priority
+     * @return true if priority is set, false on error
      * @hide
      */
     public boolean setPriority(BluetoothDevice device, int priority) {
@@ -361,7 +412,16 @@
     }
 
     /**
-     * {@inheritDoc}
+     * Get the priority of the profile.
+     *
+     * <p> The priority can be any of:
+     * {@link #PRIORITY_AUTO_CONNECT}, {@link #PRIORITY_OFF},
+     * {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
+     *
+     * @param device Bluetooth device
+     * @return priority of the device
      * @hide
      */
     public int getPriority(BluetoothDevice device) {
diff --git a/core/java/android/bluetooth/BluetoothInputDevice.java b/core/java/android/bluetooth/BluetoothInputDevice.java
index df212a8..282b70a 100644
--- a/core/java/android/bluetooth/BluetoothInputDevice.java
+++ b/core/java/android/bluetooth/BluetoothInputDevice.java
@@ -119,7 +119,23 @@
     }
 
     /**
-     * {@inheritDoc}
+     * Initiate connection to a profile of the remote bluetooth device.
+     *
+     * <p> The system supports connection to multiple input devices.
+     *
+     * <p> This API returns false in scenarios like the profile on the
+     * device is already connected or Bluetooth is not turned on.
+     * When this API returns true, it is guaranteed that
+     * connection state intent for the profile will be broadcasted with
+     * the state. Users can get the connection state of the profile
+     * from this intent.
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
+     * permission.
+     *
+     * @param device Remote Bluetooth Device
+     * @return false on immediate error,
+     *               true otherwise
      * @hide
      */
     public boolean connect(BluetoothDevice device) {
@@ -138,7 +154,29 @@
     }
 
     /**
-     * {@inheritDoc}
+     * Initiate disconnection from a profile
+     *
+     * <p> This API will return false in scenarios like the profile on the
+     * Bluetooth device is not in connected state etc. When this API returns,
+     * true, it is guaranteed that the connection state change
+     * intent will be broadcasted with the state. Users can get the
+     * disconnection state of the profile from this intent.
+     *
+     * <p> If the disconnection is initiated by a remote device, the state
+     * will transition from {@link #STATE_CONNECTED} to
+     * {@link #STATE_DISCONNECTED}. If the disconnect is initiated by the
+     * host (local) device the state will transition from
+     * {@link #STATE_CONNECTED} to state {@link #STATE_DISCONNECTING} to
+     * state {@link #STATE_DISCONNECTED}. The transition to
+     * {@link #STATE_DISCONNECTING} can be used to distinguish between the
+     * two scenarios.
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
+     * permission.
+     *
+     * @param device Remote Bluetooth Device
+     * @return false on immediate error,
+     *               true otherwise
      * @hide
      */
     public boolean disconnect(BluetoothDevice device) {
@@ -209,7 +247,18 @@
     }
 
     /**
-     * {@inheritDoc}
+     * Set priority of the profile
+     *
+     * <p> The device should already be paired.
+     *  Priority can be one of {@link #PRIORITY_ON} or
+     * {@link #PRIORITY_OFF},
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
+     * permission.
+     *
+     * @param device Paired bluetooth device
+     * @param priority
+     * @return true if priority is set, false on error
      * @hide
      */
     public boolean setPriority(BluetoothDevice device, int priority) {
@@ -232,7 +281,16 @@
     }
 
     /**
-     * {@inheritDoc}
+     * Get the priority of the profile.
+     *
+     * <p> The priority can be any of:
+     * {@link #PRIORITY_AUTO_CONNECT}, {@link #PRIORITY_OFF},
+     * {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
+     *
+     * @param device Bluetooth device
+     * @return priority of the device
      * @hide
      */
     public int getPriority(BluetoothDevice device) {
diff --git a/core/java/android/bluetooth/BluetoothPan.java b/core/java/android/bluetooth/BluetoothPan.java
index 9ffed26..7490f9e 100644
--- a/core/java/android/bluetooth/BluetoothPan.java
+++ b/core/java/android/bluetooth/BluetoothPan.java
@@ -140,7 +140,21 @@
     }
 
     /**
-     * {@inheritDoc}
+     * Initiate connection to a profile of the remote bluetooth device.
+     *
+     * <p> This API returns false in scenarios like the profile on the
+     * device is already connected or Bluetooth is not turned on.
+     * When this API returns true, it is guaranteed that
+     * connection state intent for the profile will be broadcasted with
+     * the state. Users can get the connection state of the profile
+     * from this intent.
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
+     * permission.
+     *
+     * @param device Remote Bluetooth Device
+     * @return false on immediate error,
+     *               true otherwise
      * @hide
      */
     public boolean connect(BluetoothDevice device) {
@@ -159,7 +173,29 @@
     }
 
     /**
-     * {@inheritDoc}
+     * Initiate disconnection from a profile
+     *
+     * <p> This API will return false in scenarios like the profile on the
+     * Bluetooth device is not in connected state etc. When this API returns,
+     * true, it is guaranteed that the connection state change
+     * intent will be broadcasted with the state. Users can get the
+     * disconnection state of the profile from this intent.
+     *
+     * <p> If the disconnection is initiated by a remote device, the state
+     * will transition from {@link #STATE_CONNECTED} to
+     * {@link #STATE_DISCONNECTED}. If the disconnect is initiated by the
+     * host (local) device the state will transition from
+     * {@link #STATE_CONNECTED} to state {@link #STATE_DISCONNECTING} to
+     * state {@link #STATE_DISCONNECTED}. The transition to
+     * {@link #STATE_DISCONNECTING} can be used to distinguish between the
+     * two scenarios.
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
+     * permission.
+     *
+     * @param device Remote Bluetooth Device
+     * @return false on immediate error,
+     *               true otherwise
      * @hide
      */
     public boolean disconnect(BluetoothDevice device) {
@@ -229,27 +265,6 @@
         return BluetoothProfile.STATE_DISCONNECTED;
     }
 
-    /**
-     * {@inheritDoc}
-     * @hide
-     */
-    public boolean setPriority(BluetoothDevice device, int priority) {
-        // Priorities are not supported for PAN devices - since we don't
-        // auto connect.
-        return false;
-    }
-
-    /**
-     * {@inheritDoc}
-     * @hide
-     */
-    public int getPriority(BluetoothDevice device) {
-        if (DBG) log("getPriority(" + device + ")");
-        // Priorities are not supported for PAN devices - since we don't
-        // auto connect.
-        return BluetoothProfile.PRIORITY_ON;
-    }
-
     public void setBluetoothTethering(boolean value) {
         if (DBG) log("setBluetoothTethering(" + value + ")");
         try {
diff --git a/core/java/android/bluetooth/BluetoothProfile.java b/core/java/android/bluetooth/BluetoothProfile.java
index 1ad66f7..22555f0 100644
--- a/core/java/android/bluetooth/BluetoothProfile.java
+++ b/core/java/android/bluetooth/BluetoothProfile.java
@@ -104,58 +104,6 @@
     public static final int PRIORITY_UNDEFINED = -1;
 
     /**
-     * Initiate connection to a profile of the remote bluetooth device.
-     *
-     * <p> Currently, the system supports only 1 connection to the
-     * A2DP and Headset/Handsfree profile. The API will automatically
-     * disconnect connected devices before connecting.
-     *
-     * <p> This API returns false in scenarios like the profile on the
-     * device is already connected or Bluetooth is not turned on.
-     * When this API returns true, it is guaranteed that
-     * connection state intent for the profile will be broadcasted with
-     * the state. Users can get the connection state of the profile
-     * from this intent.
-     *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
-     * permission.
-     *
-     * @param device Remote Bluetooth Device
-     * @return false on immediate error,
-     *               true otherwise
-     * @hide
-     */
-    public boolean connect(BluetoothDevice device);
-
-    /**
-     * Initiate disconnection from a profile
-     *
-     * <p> This API will return false in scenarios like the profile on the
-     * Bluetooth device is not in connected state etc. When this API returns,
-     * true, it is guaranteed that the connection state change
-     * intent will be broadcasted with the state. Users can get the
-     * disconnection state of the profile from this intent.
-     *
-     * <p> If the disconnection is initiated by a remote device, the state
-     * will transition from {@link #STATE_CONNECTED} to
-     * {@link #STATE_DISCONNECTED}. If the disconnect is initiated by the
-     * host (local) device the state will transition from
-     * {@link #STATE_CONNECTED} to state {@link #STATE_DISCONNECTING} to
-     * state {@link #STATE_DISCONNECTED}. The transition to
-     * {@link #STATE_DISCONNECTING} can be used to distinguish between the
-     * two scenarios.
-     *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
-     * permission.
-     *
-     * @param device Remote Bluetooth Device
-     * @return false on immediate error,
-     *               true otherwise
-     * @hide
-     */
-    public boolean disconnect(BluetoothDevice device);
-
-    /**
      * Get connected devices for this specific profile.
      *
      * <p> Return the set of devices which are in state {@link #STATE_CONNECTED}
@@ -195,38 +143,6 @@
     public int getConnectionState(BluetoothDevice device);
 
     /**
-     * Set priority of the profile
-     *
-     * <p> The device should already be paired.
-     *  Priority can be one of {@link #PRIORITY_ON} or
-     * {@link #PRIORITY_OFF},
-     *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
-     * permission.
-     *
-     * @param device Paired bluetooth device
-     * @param priority
-     * @return true if priority is set, false on error
-     * @hide
-     */
-    public boolean setPriority(BluetoothDevice device, int priority);
-
-    /**
-     * Get the priority of the profile.
-     *
-     * <p> The priority can be any of:
-     * {@link #PRIORITY_AUTO_CONNECT}, {@link #PRIORITY_OFF},
-     * {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
-     *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
-     *
-     * @param device Bluetooth device
-     * @return priority of the device
-     * @hide
-     */
-    public int getPriority(BluetoothDevice device);
-
-    /**
      * An interface for notifying BluetoothProfile IPC clients when they have
      * been connected or disconnected to the service.
      */
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index 60bee9a..62792f4 100755
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -1737,7 +1737,6 @@
                 pw.println("Number of connected devices:" + deviceList.size());
                 BluetoothDevice device = deviceList.get(0);
                 pw.println("getConnectedDevices[0] = " + device);
-                pw.println("Priority of Connected device = " + mPan.getPriority(device));
 
                 switch (mPan.getConnectionState(device)) {
                     case BluetoothInputDevice.STATE_CONNECTING:
diff --git a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothTestUtils.java b/core/tests/bluetoothtests/src/android/bluetooth/BluetoothTestUtils.java
index 5f4c226..0efa377 100644
--- a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothTestUtils.java
+++ b/core/tests/bluetoothtests/src/android/bluetooth/BluetoothTestUtils.java
@@ -936,7 +936,13 @@
             case BluetoothProfile.STATE_DISCONNECTED:
             case BluetoothProfile.STATE_DISCONNECTING:
                 start = System.currentTimeMillis();
-                assertTrue(proxy.connect(device));
+                if (profile == BluetoothProfile.A2DP) {
+                    assertTrue(((BluetoothA2dp)proxy).connect(device));
+                } else if (profile == BluetoothProfile.HEADSET) {
+                    assertTrue(((BluetoothHeadset)proxy).connect(device));
+                } else if (profile == BluetoothProfile.INPUT_DEVICE) {
+                    assertTrue(((BluetoothInputDevice)proxy).connect(device));
+                }
                 break;
             default:
                 removeReceiver(receiver);
@@ -1005,7 +1011,13 @@
             case BluetoothProfile.STATE_CONNECTED:
             case BluetoothProfile.STATE_CONNECTING:
                 start = System.currentTimeMillis();
-                assertTrue(proxy.disconnect(device));
+                if (profile == BluetoothProfile.A2DP) {
+                    assertTrue(((BluetoothA2dp)proxy).disconnect(device));
+                } else if (profile == BluetoothProfile.HEADSET) {
+                    assertTrue(((BluetoothHeadset)proxy).disconnect(device));
+                } else if (profile == BluetoothProfile.INPUT_DEVICE) {
+                    assertTrue(((BluetoothInputDevice)proxy).disconnect(device));
+                }
                 break;
             case BluetoothProfile.STATE_DISCONNECTED:
                 removeReceiver(receiver);