Initial implementation of HID, add IBluetoothInputDevice idl

Change-Id: Iadc79a425b4b6e12329d86dd2ac0782adcb0174d
diff --git a/Android.mk b/Android.mk
index e0c388b..64300e2 100644
--- a/Android.mk
+++ b/Android.mk
@@ -91,6 +91,7 @@
 	core/java/android/bluetooth/IBluetoothHeadset.aidl \
 	core/java/android/bluetooth/IBluetoothHeadsetPhone.aidl \
 	core/java/android/bluetooth/IBluetoothHealthCallback.aidl \
+	core/java/android/bluetooth/IBluetoothInputDevice.aidl \
 	core/java/android/bluetooth/IBluetoothPbap.aidl \
 	core/java/android/bluetooth/IBluetoothStateChangeCallback.aidl \
 	core/java/android/content/IClipboard.aidl \
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
index adf07b4..7797d94 100644
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ b/core/java/android/bluetooth/BluetoothHeadset.java
@@ -219,7 +219,7 @@
     private Context mContext;
     private ServiceListener mServiceListener;
     private IBluetoothHeadset mService;
-    BluetoothAdapter mAdapter;
+    private BluetoothAdapter mAdapter;
 
     /**
      * Create a BluetoothHeadset proxy object.
diff --git a/core/java/android/bluetooth/BluetoothInputDevice.java b/core/java/android/bluetooth/BluetoothInputDevice.java
index 62c7bdec..199cc7a 100644
--- a/core/java/android/bluetooth/BluetoothInputDevice.java
+++ b/core/java/android/bluetooth/BluetoothInputDevice.java
@@ -18,10 +18,12 @@
 
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
 import android.os.IBinder;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -91,34 +93,32 @@
      */
     public static final int INPUT_OPERATION_SUCCESS = 5004;
 
+    private Context mContext;
     private ServiceListener mServiceListener;
     private BluetoothAdapter mAdapter;
-    private IBluetooth mService;
+    private IBluetoothInputDevice mService;
 
     /**
      * Create a BluetoothInputDevice proxy object for interacting with the local
      * Bluetooth Service which handles the InputDevice profile
      *
      */
-    /*package*/ BluetoothInputDevice(Context mContext, ServiceListener l) {
-        IBinder b = ServiceManager.getService(BluetoothAdapter.BLUETOOTH_SERVICE);
+    /*package*/ BluetoothInputDevice(Context context, ServiceListener l) {
+        mContext = context;
         mServiceListener = l;
         mAdapter = BluetoothAdapter.getDefaultAdapter();
-        if (b != null) {
-            mService = IBluetooth.Stub.asInterface(b);
-            if (mServiceListener != null) {
-                mServiceListener.onServiceConnected(BluetoothProfile.INPUT_DEVICE, this);
-            }
-        } else {
-            Log.w(TAG, "Bluetooth Service not available!");
-
-            // Instead of throwing an exception which prevents people from going
-            // into Wireless settings in the emulator. Let it crash later when it is actually used.
-            mService = null;
+        if (!context.bindService(new Intent(IBluetoothInputDevice.class.getName()),
+                                 mConnection, 0)) {
+            Log.e(TAG, "Could not bind to Bluetooth HID Service");
         }
     }
 
     /*package*/ void close() {
+        if (DBG) log("close()");
+        if (mConnection != null) {
+            mContext.unbindService(mConnection);
+            mConnection = null;
+        }
         mServiceListener = null;
     }
 
@@ -144,16 +144,13 @@
      */
     public boolean connect(BluetoothDevice device) {
         if (DBG) log("connect(" + device + ")");
-        if (mService != null && isEnabled() &&
-            isValidDevice(device)) {
-            //TODO(BT)
-            /*
+        if (mService != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.connectInputDevice(device);
+                return mService.connect(device);
             } catch (RemoteException e) {
                 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
                 return false;
-            }*/
+            }
         }
         if (mService == null) Log.w(TAG, "Proxy not attached to service");
         return false;
@@ -187,16 +184,13 @@
      */
     public boolean disconnect(BluetoothDevice device) {
         if (DBG) log("disconnect(" + device + ")");
-        if (mService != null && isEnabled() &&
-            isValidDevice(device)) {
-            //TODO(BT)
-            /*
+        if (mService != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.disconnectInputDevice(device);
+                return mService.disconnect(device);
             } catch (RemoteException e) {
                 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
                 return false;
-            }*/
+            }
         }
         if (mService == null) Log.w(TAG, "Proxy not attached to service");
         return false;
@@ -208,14 +202,12 @@
     public List<BluetoothDevice> getConnectedDevices() {
         if (DBG) log("getConnectedDevices()");
         if (mService != null && isEnabled()) {
-            //TODO(BT)
-            /*
             try {
-                return mService.getConnectedInputDevices();
+                return mService.getConnectedDevices();
             } catch (RemoteException e) {
                 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
                 return new ArrayList<BluetoothDevice>();
-            }*/
+            }
         }
         if (mService == null) Log.w(TAG, "Proxy not attached to service");
         return new ArrayList<BluetoothDevice>();
@@ -227,14 +219,12 @@
     public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
         if (DBG) log("getDevicesMatchingStates()");
         if (mService != null && isEnabled()) {
-            //TODO(BT)
-            /*
             try {
-                return mService.getInputDevicesMatchingConnectionStates(states);
+                return mService.getDevicesMatchingConnectionStates(states);
             } catch (RemoteException e) {
                 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
                 return new ArrayList<BluetoothDevice>();
-            }*/
+            }
         }
         if (mService == null) Log.w(TAG, "Proxy not attached to service");
         return new ArrayList<BluetoothDevice>();
@@ -245,16 +235,13 @@
      */
     public int getConnectionState(BluetoothDevice device) {
         if (DBG) log("getState(" + device + ")");
-        if (mService != null && isEnabled()
-            && isValidDevice(device)) {
-            //TODO(BT)
-            /*
+        if (mService != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.getInputDeviceConnectionState(device);
+                return mService.getConnectionState(device);
             } catch (RemoteException e) {
                 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
                 return BluetoothProfile.STATE_DISCONNECTED;
-            }*/
+            }
         }
         if (mService == null) Log.w(TAG, "Proxy not attached to service");
         return BluetoothProfile.STATE_DISCONNECTED;
@@ -277,20 +264,17 @@
      */
     public boolean setPriority(BluetoothDevice device, int priority) {
         if (DBG) log("setPriority(" + device + ", " + priority + ")");
-        if (mService != null && isEnabled()
-            && isValidDevice(device)) {
+        if (mService != null && isEnabled() && isValidDevice(device)) {
             if (priority != BluetoothProfile.PRIORITY_OFF &&
                 priority != BluetoothProfile.PRIORITY_ON) {
               return false;
             }
-            //TODO(BT)
-            /*
             try {
-                return mService.setInputDevicePriority(device, priority);
+                return mService.setPriority(device, priority);
             } catch (RemoteException e) {
                 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
                 return false;
-            }*/
+            }
         }
         if (mService == null) Log.w(TAG, "Proxy not attached to service");
         return false;
@@ -311,21 +295,36 @@
      */
     public int getPriority(BluetoothDevice device) {
         if (DBG) log("getPriority(" + device + ")");
-        if (mService != null && isEnabled()
-            && isValidDevice(device)) {
-            //TODO(BT)
-            /*
+        if (mService != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.getInputDevicePriority(device);
+                return mService.getPriority(device);
             } catch (RemoteException e) {
                 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
                 return BluetoothProfile.PRIORITY_OFF;
-            }*/
+            }
         }
         if (mService == null) Log.w(TAG, "Proxy not attached to service");
         return BluetoothProfile.PRIORITY_OFF;
     }
 
+    private ServiceConnection mConnection = new ServiceConnection() {
+        public void onServiceConnected(ComponentName className, IBinder service) {
+            if (DBG) Log.d(TAG, "Proxy object connected");
+            mService = IBluetoothInputDevice.Stub.asInterface(service);
+
+            if (mServiceListener != null) {
+                mServiceListener.onServiceConnected(BluetoothProfile.INPUT_DEVICE, BluetoothInputDevice.this);
+            }
+        }
+        public void onServiceDisconnected(ComponentName className) {
+            if (DBG) Log.d(TAG, "Proxy object disconnected");
+            mService = null;
+            if (mServiceListener != null) {
+                mServiceListener.onServiceDisconnected(BluetoothProfile.INPUT_DEVICE);
+            }
+        }
+    };
+
     private boolean isEnabled() {
        if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
        return false;
diff --git a/core/java/android/bluetooth/IBluetoothInputDevice.aidl b/core/java/android/bluetooth/IBluetoothInputDevice.aidl
new file mode 100644
index 0000000..df061db
--- /dev/null
+++ b/core/java/android/bluetooth/IBluetoothInputDevice.aidl
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2012 Google Inc.
+ */
+package android.bluetooth;
+
+import android.bluetooth.BluetoothDevice;
+
+/**
+ * API for Bluetooth HID service
+ *
+ * {@hide}
+ */
+interface IBluetoothInputDevice {
+    // Public API
+    boolean connect(in BluetoothDevice device);
+    boolean disconnect(in BluetoothDevice device);
+    List<BluetoothDevice> getConnectedDevices();
+    List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states);
+    int getConnectionState(in BluetoothDevice device);
+    boolean setPriority(in BluetoothDevice device, int priority);
+    int getPriority(in BluetoothDevice device);
+}