Add Bluetooth device picker support

- add Intent and Extra definition
- move profile filter into BluetoothClass
diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java
index 6e48b66..b531a50 100644
--- a/core/java/android/bluetooth/BluetoothA2dp.java
+++ b/core/java/android/bluetooth/BluetoothA2dp.java
@@ -213,31 +213,6 @@
         }
     }
 
-    /**
-     * Check class bits for possible A2DP Sink support.
-     * This is a simple heuristic that tries to guess if a device with the
-     * given class bits might be a A2DP Sink. It is not accurate for all
-     * devices. It tries to err on the side of false positives.
-     * @return True if this device might be a A2DP sink
-     */
-    public static boolean doesClassMatchSink(int btClass) {
-        if (BluetoothClass.Service.hasService(btClass, BluetoothClass.Service.RENDER)) {
-            return true;
-        }
-        // By the A2DP spec, sinks must indicate the RENDER service.
-        // However we found some that do not (Chordette). So lets also
-        // match on some other class bits.
-        switch (BluetoothClass.Device.getDevice(btClass)) {
-        case BluetoothClass.Device.AUDIO_VIDEO_HIFI_AUDIO:
-        case BluetoothClass.Device.AUDIO_VIDEO_HEADPHONES:
-        case BluetoothClass.Device.AUDIO_VIDEO_LOUDSPEAKER:
-        case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO:
-            return true;
-        default:
-            return false;
-        }
-    }
-
     /** Helper for converting a state to a string.
      * For debug use only - strings are not internationalized.
      * @hide
diff --git a/core/java/android/bluetooth/BluetoothClass.java b/core/java/android/bluetooth/BluetoothClass.java
index 88ce18b..0061f10 100644
--- a/core/java/android/bluetooth/BluetoothClass.java
+++ b/core/java/android/bluetooth/BluetoothClass.java
@@ -46,6 +46,10 @@
     /** Indicates the Bluetooth API could not retrieve the class */
     public static final int ERROR = 0xFF000000;
 
+    public static final int PROFILE_HEADSET = 0;
+    public static final int PROFILE_A2DP = 1;
+    public static final int PROFILE_OPP = 2;
+
     /** Every Bluetooth device has zero or more service classes */
     public static class Service {
         public static final int BITMASK                 = 0xFFE000;
@@ -187,5 +191,74 @@
             return (btClass & Device.BITMASK);
         }
     }
+
+    /**
+     * Check class bits for possible bluetooth profile support.
+     * This is a simple heuristic that tries to guess if a device with the
+     * given class bits might support specified profile. It is not accurate for all
+     * devices. It tries to err on the side of false positives.
+     * @param btClass The class
+     * @param profile The profile to be checked
+     * @return True if this device might support specified profile.
+     */
+    public static boolean doesClassMatch(int btClass, int profile) {
+        if (profile == PROFILE_A2DP) {
+            if (BluetoothClass.Service.hasService(btClass, BluetoothClass.Service.RENDER)) {
+                return true;
+            }
+            // By the A2DP spec, sinks must indicate the RENDER service.
+            // However we found some that do not (Chordette). So lets also
+            // match on some other class bits.
+            switch (BluetoothClass.Device.getDevice(btClass)) {
+                case BluetoothClass.Device.AUDIO_VIDEO_HIFI_AUDIO:
+                case BluetoothClass.Device.AUDIO_VIDEO_HEADPHONES:
+                case BluetoothClass.Device.AUDIO_VIDEO_LOUDSPEAKER:
+                case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO:
+                    return true;
+                default:
+                    return false;
+            }
+        } else if (profile == PROFILE_HEADSET) {
+            // The render service class is required by the spec for HFP, so is a
+            // pretty good signal
+            if (BluetoothClass.Service.hasService(btClass, BluetoothClass.Service.RENDER)) {
+                return true;
+            }
+            // Just in case they forgot the render service class
+            switch (BluetoothClass.Device.getDevice(btClass)) {
+                case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE:
+                case BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET:
+                case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO:
+                    return true;
+                default:
+                    return false;
+            }
+        } else if (profile == PROFILE_OPP) {
+            if (BluetoothClass.Service.hasService(btClass, BluetoothClass.Service.OBJECT_TRANSFER)) {
+                return true;
+            }
+
+            switch (BluetoothClass.Device.getDevice(btClass)) {
+                case BluetoothClass.Device.COMPUTER_UNCATEGORIZED:
+                case BluetoothClass.Device.COMPUTER_DESKTOP:
+                case BluetoothClass.Device.COMPUTER_SERVER:
+                case BluetoothClass.Device.COMPUTER_LAPTOP:
+                case BluetoothClass.Device.COMPUTER_HANDHELD_PC_PDA:
+                case BluetoothClass.Device.COMPUTER_PALM_SIZE_PC_PDA:
+                case BluetoothClass.Device.COMPUTER_WEARABLE:
+                case BluetoothClass.Device.PHONE_UNCATEGORIZED:
+                case BluetoothClass.Device.PHONE_CELLULAR:
+                case BluetoothClass.Device.PHONE_CORDLESS:
+                case BluetoothClass.Device.PHONE_SMART:
+                case BluetoothClass.Device.PHONE_MODEM_OR_GATEWAY:
+                case BluetoothClass.Device.PHONE_ISDN:
+                    return true;
+                default:
+                    return false;
+            }
+        } else {
+            return false;
+        }
+    }
 }
 
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 1a97924..0a71961 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -55,6 +55,16 @@
      *  @hide */
     public static final int BOND_BONDING = 2;
 
+    /** Ask device picker to show all kinds of BT devices.
+     *  @hide */
+    public static final int DEVICE_PICKER_FILTER_TYPE_ALL = 0;
+    /** Ask device picker to show BT devices that support AUDIO profiles.
+     *  @hide */
+    public static final int DEVICE_PICKER_FILTER_TYPE_AUDIO = 1;
+    /** Ask device picker to show BT devices that support Object Transfer.
+     *  @hide */
+    public static final int DEVICE_PICKER_FILTER_TYPE_TRANSFER = 2;
+
     //TODO: Unify these result codes in BluetoothResult or BluetoothError
     /** A bond attempt failed because pins did not match, or remote device did
      * not respond to pin request in time 
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
index 0e3d2bb..d31b6ae 100644
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ b/core/java/android/bluetooth/BluetoothHeadset.java
@@ -356,30 +356,6 @@
         return -1;
     }
 
-    /**
-     * Check class bits for possible HSP or HFP support.
-     * This is a simple heuristic that tries to guess if a device with the
-     * given class bits might support HSP or HFP. It is not accurate for all
-     * devices. It tries to err on the side of false positives.
-     * @return True if this device might support HSP or HFP.
-     */
-    public static boolean doesClassMatch(int btClass) {
-        // The render service class is required by the spec for HFP, so is a
-        // pretty good signal
-        if (BluetoothClass.Service.hasService(btClass, BluetoothClass.Service.RENDER)) {
-            return true;
-        }
-        // Just in case they forgot the render service class
-        switch (BluetoothClass.Device.getDevice(btClass)) {
-        case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE:
-        case BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET:
-        case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO:
-            return true;
-        default:
-            return false;
-        }
-    }
-
     private ServiceConnection mConnection = new ServiceConnection() {
         public void onServiceConnected(ComponentName className, IBinder service) {
             if (DBG) Log.d(TAG, "Proxy object connected");
diff --git a/core/java/android/bluetooth/BluetoothIntent.java b/core/java/android/bluetooth/BluetoothIntent.java
index 2a0de61..c39bc3d 100644
--- a/core/java/android/bluetooth/BluetoothIntent.java
+++ b/core/java/android/bluetooth/BluetoothIntent.java
@@ -62,6 +62,35 @@
     public static final String PASSKEY =
         "android.bluetooth.intent.PASSKEY";
 
+    public static final String DEVICE_PICKER_NEED_AUTH =
+        "android.bluetooth.intent.DEVICE_PICKER_NEED_AUTH";
+    public static final String DEVICE_PICKER_FILTER_TYPE =
+        "android.bluetooth.intent.DEVICE_PICKER_FILTER_TYPE";
+    public static final String DEVICE_PICKER_LAUNCH_PACKAGE =
+        "android.bluetooth.intent.DEVICE_PICKER_LAUNCH_PACKAGE";
+    public static final String DEVICE_PICKER_LAUNCH_CLASS =
+        "android.bluetooth.intent.DEVICE_PICKER_LAUNCH_CLASS";
+
+     /**
+     * Broadcast when one BT device is selected from BT device picker screen.
+     * Selected BT device address is contained in extra string "BluetoothIntent.ADDRESS".
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String DEVICE_PICKER_DEVICE_SELECTED =
+        "android.bluetooth.intent.action.DEVICE_SELECTED";
+
+    /**
+     * Broadcast when someone want to select one BT device from devices list.
+     * This intent contains below extra data:
+     * - BluetoothIntent.DEVICE_PICKER_NEED_AUTH (boolean): if need authentication
+     * - BluetoothIntent.DEVICE_PICKER_FILTER_TYPE (int): what kinds of device should be listed
+     * - BluetoothIntent.DEVICE_PICKER_LAUNCH_PACKAGE (string): where(which package) this intent come from
+     * - BluetoothIntent.DEVICE_PICKER_LAUNCH_CLASS (string): where(which class) this intent come from
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String DEVICE_PICKER_DEVICE_PICKER =
+        "android.bluetooth.intent.action.DEVICE_PICKER";
+
     /** Broadcast when the local Bluetooth device state changes, for example
      *  when Bluetooth is enabled. Will contain int extra's BLUETOOTH_STATE and
      *  BLUETOOTH_PREVIOUS_STATE. */