diff options
Diffstat (limited to 'core/java')
-rw-r--r-- | core/java/android/bluetooth/BluetoothA2dp.java | 21 | ||||
-rw-r--r-- | core/java/android/bluetooth/BluetoothAdapter.java | 192 | ||||
-rw-r--r-- | core/java/android/bluetooth/BluetoothClass.java | 254 | ||||
-rw-r--r-- | core/java/android/bluetooth/BluetoothDevice.java | 328 | ||||
-rw-r--r-- | core/java/android/bluetooth/BluetoothDevicePicker.java | 66 | ||||
-rw-r--r-- | core/java/android/bluetooth/BluetoothHeadset.java | 23 | ||||
-rw-r--r-- | core/java/android/bluetooth/BluetoothIntent.java | 154 | ||||
-rw-r--r-- | core/java/android/bluetooth/BluetoothPbap.java | 4 | ||||
-rw-r--r-- | core/java/android/server/BluetoothA2dpService.java | 25 | ||||
-rw-r--r-- | core/java/android/server/BluetoothEventLoop.java | 80 | ||||
-rw-r--r-- | core/java/android/server/BluetoothService.java | 53 |
11 files changed, 718 insertions, 482 deletions
diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java index 060f20e..2e9612a 100644 --- a/core/java/android/bluetooth/BluetoothA2dp.java +++ b/core/java/android/bluetooth/BluetoothA2dp.java @@ -51,20 +51,21 @@ public final class BluetoothA2dp { private static final String TAG = "BluetoothA2dp"; private static final boolean DBG = false; - /** int extra for SINK_STATE_CHANGED_ACTION */ - public static final String SINK_STATE = - "android.bluetooth.a2dp.intent.SINK_STATE"; - /** int extra for SINK_STATE_CHANGED_ACTION */ - public static final String SINK_PREVIOUS_STATE = - "android.bluetooth.a2dp.intent.SINK_PREVIOUS_STATE"; + /** int extra for ACTION_SINK_STATE_CHANGED */ + public static final String EXTRA_SINK_STATE = + "android.bluetooth.a2dp.extra.SINK_STATE"; + /** int extra for ACTION_SINK_STATE_CHANGED */ + public static final String EXTRA_PREVIOUS_SINK_STATE = + "android.bluetooth.a2dp.extra.PREVIOUS_SINK_STATE"; /** Indicates the state of an A2DP audio sink has changed. - * This intent will always contain SINK_STATE, SINK_PREVIOUS_STATE and - * BluetoothIntent.ADDRESS extras. + * This intent will always contain EXTRA_SINK_STATE, + * EXTRA_PREVIOUS_SINK_STATE and BluetoothDevice.EXTRA_DEVICE + * extras. */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String SINK_STATE_CHANGED_ACTION = - "android.bluetooth.a2dp.intent.action.SINK_STATE_CHANGED"; + public static final String ACTION_SINK_STATE_CHANGED = + "android.bluetooth.a2dp.action.SINK_STATE_CHANGED"; public static final int STATE_DISCONNECTED = 0; public static final int STATE_CONNECTING = 1; diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java index 18f6995..96a927b 100644 --- a/core/java/android/bluetooth/BluetoothAdapter.java +++ b/core/java/android/bluetooth/BluetoothAdapter.java @@ -36,8 +36,6 @@ import java.util.HashSet; * * <p>Use the {@link BluetoothDevice} class for operations on remote Bluetooth * devices. - * - * <p>TODO: unhide more of this class */ public final class BluetoothAdapter { private static final String TAG = "BluetoothAdapter"; @@ -49,20 +47,20 @@ public final class BluetoothAdapter { * <p><code>Intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, * BluetoothAdapter.ERROR)</code> */ - public static final int ERROR = -1; + public static final int ERROR = Integer.MIN_VALUE; /** * Broadcast Action: The state of the local Bluetooth adapter has been * changed. * <p>For example, Bluetooth has been turned on or off. - * <p>Contains the extra fields {@link #EXTRA_STATE} and {@link + * <p>Always contains the extra fields {@link #EXTRA_STATE} and {@link * #EXTRA_PREVIOUS_STATE} containing the new and old states * respectively. * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive. */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_STATE_CHANGED = - "android.bluetooth.intent.action.STATE_CHANGED"; + "android.bluetooth.adapter.action.STATE_CHANGED"; /** * Used as an int extra field in {@link #ACTION_STATE_CHANGED} @@ -73,7 +71,7 @@ public final class BluetoothAdapter { * {@link #STATE_TURNING_OFF}, */ public static final String EXTRA_STATE = - "android.bluetooth.intent.extra.STATE"; + "android.bluetooth.adapter.extra.STATE"; /** * Used as an int extra field in {@link #ACTION_STATE_CHANGED} * intents to request the previous power state. Possible values are: @@ -83,39 +81,39 @@ public final class BluetoothAdapter { * {@link #STATE_TURNING_OFF}, */ public static final String EXTRA_PREVIOUS_STATE = - "android.bluetooth.intent.extra.PREVIOUS_STATE"; + "android.bluetooth.adapter.extra.PREVIOUS_STATE"; /** * Indicates the local Bluetooth adapter is off. */ - public static final int STATE_OFF = 40; + public static final int STATE_OFF = 10; /** * Indicates the local Bluetooth adapter is turning on. However local * clients should wait for {@link #STATE_ON} before attempting to * use the adapter. */ - public static final int STATE_TURNING_ON = 41; + public static final int STATE_TURNING_ON = 11; /** * Indicates the local Bluetooth adapter is on, and ready for use. */ - public static final int STATE_ON = 42; + public static final int STATE_ON = 12; /** * Indicates the local Bluetooth adapter is turning off. Local clients * should immediately attempt graceful disconnection of any remote links. */ - public static final int STATE_TURNING_OFF = 43; + public static final int STATE_TURNING_OFF = 13; /** * Broadcast Action: Indicates the Bluetooth scan mode of the local Adapter * has changed. - * <p>Contains the extra fields {@link #EXTRA_SCAN_MODE} and {@link + * <p>Always contains the extra fields {@link #EXTRA_SCAN_MODE} and {@link * #EXTRA_PREVIOUS_SCAN_MODE} containing the new and old scan modes * respectively. * <p>Requires {@link android.Manifest.permission#BLUETOOTH} */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_SCAN_MODE_CHANGED = - "android.bluetooth.intent.action.SCAN_MODE_CHANGED"; + "android.bluetooth.adapter.action.SCAN_MODE_CHANGED"; /** * Used as an int extra field in {@link #ACTION_SCAN_MODE_CHANGED} @@ -124,7 +122,7 @@ public final class BluetoothAdapter { * {@link #SCAN_MODE_CONNECTABLE}, * {@link #SCAN_MODE_CONNECTABLE_DISCOVERABLE}, */ - public static final String EXTRA_SCAN_MODE = "android.bluetooth.intent.extra.SCAN_MODE"; + public static final String EXTRA_SCAN_MODE = "android.bluetooth.adapter.extra.SCAN_MODE"; /** * Used as an int extra field in {@link #ACTION_SCAN_MODE_CHANGED} * intents to request the previous scan mode. Possible values are: @@ -133,37 +131,73 @@ public final class BluetoothAdapter { * {@link #SCAN_MODE_CONNECTABLE_DISCOVERABLE}, */ public static final String EXTRA_PREVIOUS_SCAN_MODE = - "android.bluetooth.intent.extra.PREVIOUS_SCAN_MODE"; + "android.bluetooth.adapter.extra.PREVIOUS_SCAN_MODE"; /** * Indicates that both inquiry scan and page scan are disabled on the local * Bluetooth adapter. Therefore this device is neither discoverable * nor connectable from remote Bluetooth devices. */ - public static final int SCAN_MODE_NONE = 50; + public static final int SCAN_MODE_NONE = 20; /** * Indicates that inquiry scan is disabled, but page scan is enabled on the * local Bluetooth adapter. Therefore this device is not discoverable from * remote Bluetooth devices, but is connectable from remote devices that * have previously discovered this device. */ - public static final int SCAN_MODE_CONNECTABLE = 51; + public static final int SCAN_MODE_CONNECTABLE = 21; /** * Indicates that both inquiry scan and page scan are enabled on the local * Bluetooth adapter. Therefore this device is both discoverable and * connectable from remote Bluetooth devices. */ - public static final int SCAN_MODE_CONNECTABLE_DISCOVERABLE = 53; + public static final int SCAN_MODE_CONNECTABLE_DISCOVERABLE = 23; + + + /** + * Broadcast Action: The local Bluetooth adapter has started the remote + * device discovery process. + * <p>This usually involves an inquiry scan of about 12 seconds, followed + * by a page scan of each new device to retrieve its Bluetooth name. + * <p>Register for {@link BluetoothDevice#ACTION_FOUND} to be notified as + * remote Bluetooth devices are found. + * <p>Device discovery is a heavyweight procedure. New connections to + * remote Bluetooth devices should not be attempted while discovery is in + * progress, and existing connections will experience limited bandwidth + * and high latency. Use {@link #cancelDiscovery()} to cancel an ongoing + * discovery. + * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive. + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_DISCOVERY_STARTED = + "android.bluetooth.adapter.action.DISCOVERY_STARTED"; + /** + * Broadcast Action: The local Bluetooth adapter has finished the device + * discovery process. + * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive. + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_DISCOVERY_FINISHED = + "android.bluetooth.adapter.action.DISCOVERY_FINISHED"; + + /** + * Broadcast Action: The local Bluetooth adapter has changed its friendly + * Bluetooth name. + * <p>This name is visible to remote Bluetooth devices. + * <p>Always contains the extra field {@link #EXTRA_LOCAL_NAME} containing + * the name. + * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive. + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_LOCAL_NAME_CHANGED = + "android.bluetooth.adapter.action.LOCAL_NAME_CHANGED"; + /** + * Used as a String extra field in {@link #ACTION_LOCAL_NAME_CHANGED} + * intents to request the local Bluetooth name. + */ + public static final String EXTRA_LOCAL_NAME = "android.bluetooth.adapter.extra.LOCAL_NAME"; - /** The user will be prompted to enter a pin - * @hide */ - public static final int PAIRING_VARIANT_PIN = 0; - /** The user will be prompted to enter a passkey - * @hide */ - public static final int PAIRING_VARIANT_PASSKEY = 1; - /** The user will be prompted to confirm the passkey displayed on the screen - * @hide */ - public static final int PAIRING_VARIANT_CONFIRMATION = 2; + private static final int ADDRESS_LENGTH = 17; private final IBluetooth mService; @@ -182,7 +216,8 @@ public final class BluetoothAdapter { * Get a {@link BluetoothDevice} object for the given Bluetooth hardware * address. * <p>Valid Bluetooth hardware addresses must be upper case, in a format - * such as "00:11:22:33:AA:BB". + * such as "00:11:22:33:AA:BB". The helper {@link #checkBluetoothAddress} is + * available to validate a Bluetooth address. * <p>A {@link BluetoothDevice} will always be returned for a valid * hardware address, even if this adapter has never seen that device. * @@ -380,7 +415,29 @@ public final class BluetoothAdapter { } catch (RemoteException e) {Log.e(TAG, "", e);} } - /** @hide */ + /** + * Start the remote device discovery process. + * <p>The discovery process usually involves an inquiry scan of about 12 + * seconds, followed by a page scan of each new device to retrieve its + * Bluetooth name. + * <p>This is an asynchronous call, it will return immediately. Register + * for {@link #ACTION_DISCOVERY_STARTED} and {@link + * #ACTION_DISCOVERY_FINISHED} intents to determine exactly when the + * discovery starts and completes. Register for {@link + * BluetoothDevice#ACTION_FOUND} to be notified as remote Bluetooth devices + * are found. + * <p>Device discovery is a heavyweight procedure. New connections to + * remote Bluetooth devices should not be attempted while discovery is in + * progress, and existing connections will experience limited bandwidth + * and high latency. Use {@link #cancelDiscovery()} to cancel an ongoing + * discovery. + * <p>Device discovery will only find remote devices that are currently + * <i>discoverable</i> (inquiry scan enabled). Many Bluetooth devices are + * not discoverable by default, and need to be entered into a special mode. + * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}. + * + * @return true on success, false on error + */ public boolean startDiscovery() { try { return mService.startDiscovery(); @@ -388,14 +445,33 @@ public final class BluetoothAdapter { return false; } - /** @hide */ - public void cancelDiscovery() { + /** + * Cancel the current device discovery process. + * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}. + * + * @return true on success, false on error + */ + public boolean cancelDiscovery() { try { mService.cancelDiscovery(); } catch (RemoteException e) {Log.e(TAG, "", e);} + return false; } - /** @hide */ + /** + * Return true if the local Bluetooth adapter is currently in the device + * discovery process. + * <p>Device discovery is a heavyweight procedure. New connections to + * remote Bluetooth devices should not be attempted while discovery is in + * progress, and existing connections will experience limited bandwidth + * and high latency. Use {@link #cancelDiscovery()} to cancel an ongoing + * discovery. + * <p>Applications can also register for {@link #ACTION_DISCOVERY_STARTED} + * or {@link #ACTION_DISCOVERY_FINISHED} to be notified when discovery + * starts or completes. + * + * @return true if discovering + */ public boolean isDiscovering() { try { return mService.isDiscovering(); @@ -404,27 +480,10 @@ public final class BluetoothAdapter { } /** - * List remote devices that are bonded (paired) to the local adapter. - * - * Bonding (pairing) is the process by which the user enters a pin code for - * the device, which generates a shared link key, allowing for - * authentication and encryption of future connections. In Android we - * require bonding before RFCOMM or SCO connections can be made to a remote - * device. + * Return the set of {@link BluetoothDevice} objects that are bonded + * (paired) to the local adapter. * - * This function lists which remote devices we have a link key for. It does - * not cause any RF transmission, and does not check if the remote device - * still has it's link key with us. If the other side no longer has its - * link key then the RFCOMM or SCO connection attempt will result in an - * error. - * - * This function does not check if the remote device is in range. - * - * Remote devices that have an in-progress bonding attempt are not - * returned. - * - * @return unmodifiable set of bonded devices, or null on error - * @hide + * @return unmodifiable set of {@link BluetoothDevice}, or null on error */ public Set<BluetoothDevice> getBondedDevices() { try { @@ -511,4 +570,33 @@ public final class BluetoothAdapter { } return Collections.unmodifiableSet(devices); } + + /** + * Validate a Bluetooth address, such as "00:43:A8:23:10:F0" + * + * @param address Bluetooth address as string + * @return true if the address is valid, false otherwise + */ + public static boolean checkBluetoothAddress(String address) { + if (address == null || address.length() != ADDRESS_LENGTH) { + return false; + } + for (int i = 0; i < ADDRESS_LENGTH; i++) { + char c = address.charAt(i); + switch (i % 3) { + case 0: + case 1: + if (Character.digit(c, 16) != -1) { + break; // hex character, OK + } + return false; + case 2: + if (c == ':') { + break; // OK + } + return false; + } + } + return true; + } } diff --git a/core/java/android/bluetooth/BluetoothClass.java b/core/java/android/bluetooth/BluetoothClass.java index 0061f10..1fbbf78 100644 --- a/core/java/android/bluetooth/BluetoothClass.java +++ b/core/java/android/bluetooth/BluetoothClass.java @@ -16,43 +16,89 @@ package android.bluetooth; +import android.os.Parcel; +import android.os.Parcelable; + /** - * The Android Bluetooth API is not finalized, and *will* change. Use at your - * own risk. - * - * Static helper methods and constants to decode the device class bit vector - * returned by the Bluetooth API. + * Represents a Bluetooth class. * - * The Android Bluetooth API returns a 32-bit integer to represent the class. - * The format of these bits is defined at + * <p>Bluetooth Class is a 32 bit field. The format of these bits is defined at * http://www.bluetooth.org/Technical/AssignedNumbers/baseband.htm - * (login required). This class provides static helper methods and constants to - * determine what Service Class(es) and Device Class are encoded in the 32-bit - * class. + * (login required). This class contains that 32 bit field, and provides + * constants and methods to determine which Service Class(es) and Device Class + * are encoded in that field. * - * Devices typically have zero or more service classes, and exactly one device - * class. The device class is encoded as a major and minor device class, the - * minor being a subset of the major. + * <p>Every Bluetooth Class is composed of zero or more service classes, and + * exactly one device class. The device class is further broken down into major + * and minor device class components. * - * Class is useful to describe a device (for example to show an icon), - * but does not reliably describe what profiles a device supports. To determine - * profile support you usually need to perform SDP queries. + * <p>Class is useful as a hint to roughly describe a device (for example to + * show an icon in the UI), but does not reliably describe which Bluetooth + * profiles or services are actually supported by a device. Accurate service + * discovery is done through SDP requests. * - * Each of these helper methods takes the 32-bit integer class as an argument. - * - * @hide + * <p>Use {@link BluetoothDevice#getBluetoothClass} to retrieve the class for + * a remote device. */ -public class BluetoothClass { - /** Indicates the Bluetooth API could not retrieve the class */ +public final class BluetoothClass implements Parcelable { + /** + * Legacy error value. Applications should use null instead. + * @hide + */ 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; + private final int mClass; + + /** @hide */ + public BluetoothClass(int classInt) { + mClass = classInt; + } - /** Every Bluetooth device has zero or more service classes */ - public static class Service { - public static final int BITMASK = 0xFFE000; + @Override + public boolean equals(Object o) { + if (o instanceof BluetoothClass) { + return mClass == ((BluetoothClass)o).mClass; + } + return false; + } + + @Override + public int hashCode() { + return mClass; + } + + @Override + public String toString() { + return Integer.toHexString(mClass); + } + + /** @hide */ + public int describeContents() { + return 0; + } + + /** @hide */ + public static final Parcelable.Creator<BluetoothClass> CREATOR = + new Parcelable.Creator<BluetoothClass>() { + public BluetoothClass createFromParcel(Parcel in) { + return new BluetoothClass(in.readInt()); + } + public BluetoothClass[] newArray(int size) { + return new BluetoothClass[size]; + } + }; + + /** @hide */ + public void writeToParcel(Parcel out, int flags) { + out.writeInt(mClass); + } + + /** + * Bluetooth service classes. + * <p>Each {@link BluetoothClass} encodes zero or more service classes. + */ + public static final class Service { + private static final int BITMASK = 0xFFE000; public static final int LIMITED_DISCOVERABILITY = 0x002000; public static final int POSITIONING = 0x010000; @@ -63,32 +109,35 @@ public class BluetoothClass { public static final int AUDIO = 0x200000; public static final int TELEPHONY = 0x400000; public static final int INFORMATION = 0x800000; + } - /** Returns true if the given class supports the given Service Class. - * A bluetooth device can claim to support zero or more service classes. - * @param btClass The bluetooth class. - * @param serviceClass The service class constant to test for. For - * example, Service.AUDIO. Must be one of the - * Service.FOO constants. - * @return True if the service class is supported. - */ - public static boolean hasService(int btClass, int serviceClass) { - if (btClass == ERROR) { - return false; - } - return ((btClass & Service.BITMASK & serviceClass) != 0); - } + /** + * Return true if the specified service class is supported by this class. + * <p>Valid service classes are the public constants in + * {@link BluetoothClass.Service}. For example, {@link + * BluetoothClass.Service#AUDIO}. + * + * @param service valid service class + * @return true if the service class is supported + */ + public boolean hasService(int service) { + return ((mClass & Service.BITMASK & service) != 0); } - /** Every Bluetooth device has exactly one device class, comprimised of - * major and minor components. We have not included the minor classes for - * major classes: NETWORKING, PERIPHERAL and IMAGING yet because they work - * a little differently. */ + /** + * Bluetooth device classes. + * <p>Each {@link BluetoothClass} encodes exactly one device class, with + * major and minor components. + * <p>The constants in {@link + * BluetoothClass.Device} represent a combination of major and minor + * components (the complete device class). The constants in {@link + * BluetoothClass.Device.Major} represent just the major device classes. + */ public static class Device { - public static final int BITMASK = 0x1FFC; + private static final int BITMASK = 0x1FFC; public static class Major { - public static final int BITMASK = 0x1F00; + private static final int BITMASK = 0x1F00; public static final int MISC = 0x0000; public static final int COMPUTER = 0x0100; @@ -101,18 +150,6 @@ public class BluetoothClass { public static final int TOY = 0x0800; public static final int HEALTH = 0x0900; public static final int UNCATEGORIZED = 0x1F00; - - /** Returns the Major Device Class component of a bluetooth class. - * Values returned from this function can be compared with the constants - * Device.Major.FOO. A bluetooth device can only be associated - * with one major class. - */ - public static int getDeviceMajor(int btClass) { - if (btClass == ERROR) { - return ERROR; - } - return (btClass & Device.Major.BITMASK); - } } // Devices in the COMPUTER major class @@ -178,42 +215,62 @@ public class BluetoothClass { public static final int HEALTH_PULSE_OXIMETER = 0x0914; public static final int HEALTH_PULSE_RATE = 0x0918; public static final int HEALTH_DATA_DISPLAY = 0x091C; + } - /** Returns the Device Class component of a bluetooth class. This includes - * both the major and minor device components. Values returned from this - * function can be compared with the constants Device.FOO. A bluetooth - * device can only be associated with one device class. - */ - public static int getDevice(int btClass) { - if (btClass == ERROR) { - return ERROR; - } - return (btClass & Device.BITMASK); - } + /** + * Return the major device class component of this Bluetooth class. + * <p>Values returned from this function can be compared with the + * public constants in {@link BluetoothClass.Device.Major} to determine + * which major class is encoded in this Bluetooth class. + * + * @return major device class component + */ + public int getMajorDeviceClass() { + return (mClass & Device.Major.BITMASK); + } + + /** + * Return the (major and minor) device class component of this + * {@link BluetoothClass}. + * <p>Values returned from this function can be compared with the + * public constants in {@link BluetoothClass.Device} to determine which + * device class is encoded in this Bluetooth class. + * + * @return device class component + */ + public int getDeviceClass() { + return (mClass & Device.BITMASK); } + /** @hide */ + public static final int PROFILE_HEADSET = 0; + /** @hide */ + public static final int PROFILE_A2DP = 1; + /** @hide */ + public static final int PROFILE_OPP = 2; + /** * 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. + * @hide */ - public static boolean doesClassMatch(int btClass, int profile) { + public boolean doesClassMatch(int profile) { if (profile == PROFILE_A2DP) { - if (BluetoothClass.Service.hasService(btClass, BluetoothClass.Service.RENDER)) { + if (hasService(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: + switch (getDeviceClass()) { + case Device.AUDIO_VIDEO_HIFI_AUDIO: + case Device.AUDIO_VIDEO_HEADPHONES: + case Device.AUDIO_VIDEO_LOUDSPEAKER: + case Device.AUDIO_VIDEO_CAR_AUDIO: return true; default: return false; @@ -221,37 +278,37 @@ public class BluetoothClass { } 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)) { + if (hasService(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: + switch (getDeviceClass()) { + case Device.AUDIO_VIDEO_HANDSFREE: + case Device.AUDIO_VIDEO_WEARABLE_HEADSET: + case Device.AUDIO_VIDEO_CAR_AUDIO: return true; default: return false; } } else if (profile == PROFILE_OPP) { - if (BluetoothClass.Service.hasService(btClass, BluetoothClass.Service.OBJECT_TRANSFER)) { + if (hasService(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: + switch (getDeviceClass()) { + case Device.COMPUTER_UNCATEGORIZED: + case Device.COMPUTER_DESKTOP: + case Device.COMPUTER_SERVER: + case Device.COMPUTER_LAPTOP: + case Device.COMPUTER_HANDHELD_PC_PDA: + case Device.COMPUTER_PALM_SIZE_PC_PDA: + case Device.COMPUTER_WEARABLE: + case Device.PHONE_UNCATEGORIZED: + case Device.PHONE_CELLULAR: + case Device.PHONE_CORDLESS: + case Device.PHONE_SMART: + case Device.PHONE_MODEM_OR_GATEWAY: + case Device.PHONE_ISDN: return true; default: return false; @@ -261,4 +318,3 @@ public class BluetoothClass { } } } - diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java index 1ab4389..a9cec50 100644 --- a/core/java/android/bluetooth/BluetoothDevice.java +++ b/core/java/android/bluetooth/BluetoothDevice.java @@ -16,6 +16,8 @@ package android.bluetooth; +import android.annotation.SdkConstant; +import android.annotation.SdkConstant.SdkConstantType; import android.content.Context; import android.os.IBinder; import android.os.Parcel; @@ -38,8 +40,6 @@ import java.io.UnsupportedEncodingException; * are performed on the remote Bluetooth hardware address, using the * {@link BluetoothAdapter} that was used to create this {@link * BluetoothDevice}. - * - * TODO: unhide more of this class */ public final class BluetoothDevice implements Parcelable { private static final String TAG = "BluetoothDevice"; @@ -48,31 +48,203 @@ public final class BluetoothDevice implements Parcelable { * Sentinel error value for this class. Guaranteed to not equal any other * integer constant in this class. Provided as a convenience for functions * that require a sentinel error value, for example: - * <p><code>Intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, - * BluetoothAdapter.ERROR)</code> - */ - public static final int ERROR = -1; - - /** We do not have a link key for the remote device, and are therefore not - * bonded - * @hide*/ - public static final int BOND_NOT_BONDED = 0; - /** We have a link key for the remote device, and are probably bonded. - * @hide */ - public static final int BOND_BONDED = 1; - /** We are currently attempting bonding - * @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; + * <p><code>Intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, + * BluetoothDevice.ERROR)</code> + */ + public static final int ERROR = Integer.MIN_VALUE; + + /** + * Broadcast Action: Remote device discovered. + * <p>Sent when a remote device is found during discovery. + * <p>Always contains the extra fields {@link #EXTRA_DEVICE} and {@link + * #EXTRA_CLASS}. Can contain the extra fields {@link #EXTRA_NAME} and/or + * {@link #EXTRA_RSSI} if they are available. + * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive. + */ + // TODO: Change API to not broadcast RSSI if not available (incoming connection) + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_FOUND = + "android.bluetooth.device.action.FOUND"; + + /** + * Broadcast Action: Remote device disappeared. + * <p>Sent when a remote device that was found in the last discovery is not + * found in the current discovery. + * <p>Always contains the extra field {@link #EXTRA_DEVICE}. + * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive. + * @hide + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_DISAPPEARED = + "android.bluetooth.device.action.DISAPPEARED"; + + /** + * Broadcast Action: Bluetooth class of a remote device has changed. + * <p>Always contains the extra fields {@link #EXTRA_DEVICE} and {@link + * #EXTRA_CLASS}. + * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive. + * @see {@link BluetoothClass} + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_CLASS_CHANGED = + "android.bluetooth.device.action.CLASS_CHANGED"; + + /** + * Broadcast Action: Indicates a low level (ACL) connection has been + * established with a remote device. + * <p>Always contains the extra field {@link #EXTRA_DEVICE}. + * <p>ACL connections are managed automatically by the Android Bluetooth + * stack. + * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive. + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_ACL_CONNECTED = + "android.bluetooth.device.action.ACL_CONNECTED"; + + /** + * Broadcast Action: Indicates that a low level (ACL) disconnection has + * been requested for a remote device, and it will soon be disconnected. + * <p>This is useful for graceful disconnection. Applications should use + * this intent as a hint to immediately terminate higher level connections + * (RFCOMM, L2CAP, or profile connections) to the remote device. + * <p>Always contains the extra field {@link #EXTRA_DEVICE}. + * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive. + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_ACL_DISCONNECT_REQUESTED = + "android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED"; + + /** + * Broadcast Action: Indicates a low level (ACL) disconnection from a + * remote device. + * <p>Always contains the extra field {@link #EXTRA_DEVICE}. + * <p>ACL connections are managed automatically by the Android Bluetooth + * stack. + * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive. + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_ACL_DISCONNECTED = + "android.bluetooth.device.action.ACL_DISCONNECTED"; + + /** + * Broadcast Action: Indicates the friendly name of a remote device has + * been retrieved for the first time, or changed since the last retrieval. + * <p>Always contains the extra fields {@link #EXTRA_DEVICE} and {@link + * #EXTRA_NAME}. + * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive. + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_NAME_CHANGED = + "android.bluetooth.device.action.NAME_CHANGED"; + + /** + * Broadcast Action: Indicates a change in the bond state of a remote + * device. For example, if a device is bonded (paired). + * <p>Always contains the extra fields {@link #EXTRA_DEVICE}, {@link + * #EXTRA_BOND_STATE} and {@link #EXTRA_PREVIOUS_BOND_STATE}. + * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive. + */ + // Note: When EXTRA_BOND_STATE is BOND_NONE then this will also + // contain a hidden extra field EXTRA_REASON with the result code. + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_BOND_STATE_CHANGED = + "android.bluetooth.device.action.BOND_STATE_CHANGED"; + + /** + * Used as a Parcelable {@link BluetoothDevice} extra field in every intent + * broadcast by this class. It contains the {@link BluetoothDevice} that + * the intent applies to. + */ + public static final String EXTRA_DEVICE = "android.bluetooth.device.extra.DEVICE"; + + /** + * Used as a String extra field in {@link #ACTION_NAME_CHANGED} and {@link + * #ACTION_FOUND} intents. It contains the friendly Bluetooth name. + */ + public static final String EXTRA_NAME = "android.bluetooth.device.extra.NAME"; + + /** + * Used as an optional short extra field in {@link #ACTION_FOUND} intents. + * Contains the RSSI value of the remote device as reported by the + * Bluetooth hardware. + */ + public static final String EXTRA_RSSI = "android.bluetooth.device.extra.RSSI"; + + /** + * Used as an Parcelable {@link BluetoothClass} extra field in {@link + * #ACTION_FOUND} and {@link #ACTION_CLASS_CHANGED} intents. + */ + public static final String EXTRA_CLASS = "android.bluetooth.device.extra.CLASS"; + + /** + * Used as an int extra field in {@link #ACTION_BOND_STATE_CHANGED} intents. + * Contains the bond state of the remote device. + * <p>Possible values are: + * {@link #BOND_NONE}, + * {@link #BOND_BONDING}, + * {@link #BOND_BONDED}. + */ + public static final String EXTRA_BOND_STATE = "android.bluetooth.device.extra.BOND_STATE"; + /** + * Used as an int extra field in {@link #ACTION_BOND_STATE_CHANGED} intents. + * Contains the previous bond state of the remote device. + * <p>Possible values are: + * {@link #BOND_NONE}, + * {@link #BOND_BONDING}, + * {@link #BOND_BONDED}. + */ + public static final String EXTRA_PREVIOUS_BOND_STATE = + "android.bluetooth.device.extra.PREVIOUS_BOND_STATE"; + /** + * Indicates the remote device is not bonded (paired). + * <p>There is no shared link key with the remote device, so communication + * (if it is allowed at all) will be unauthenticated and unencrypted. + */ + public static final int BOND_NONE = 10; + /** + * Indicates bonding (pairing) is in progress with the remote device. + */ + public static final int BOND_BONDING = 11; + /** + * Indicates the remote device is bonded (paired). + * <p>A shared link keys exists locally for the remote device, so + * communication can be authenticated and encrypted. + * <p><i>Being bonded (paired) with a remote device does not necessarily + * mean the device is currently connected. It just means that the ponding + * procedure was compeleted at some earlier time, and the link key is still + * stored locally, ready to use on the next connection. + * </i> + */ + public static final int BOND_BONDED = 12; + + /** @hide */ + public static final String EXTRA_REASON = "android.bluetooth.device.extra.REASON"; + /** @hide */ + public static final String EXTRA_PAIRING_VARIANT = + "android.bluetooth.device.extra.PAIRING_VARIANT"; + /** @hide */ + public static final String EXTRA_PASSKEY = "android.bluetooth.device.extra.PASSKEY"; + + /** + * Broadcast Action: Indicates a failure to retrieve the name of a remote + * device. + * <p>Always contains the extra field {@link #EXTRA_DEVICE}. + * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive. + * @hide + */ + //TODO: is this actually useful? + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_NAME_FAILED = + "android.bluetooth.device.action.NAME_FAILED"; + + /** @hide */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_PAIRING_REQUEST = + "android.bluetooth.device.action.PAIRING_REQUEST"; + /** @hide */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_PAIRING_CANCEL = + "android.bluetooth.device.action.PAIRING_CANCEL"; /** A bond attempt succeeded * @hide */ @@ -98,7 +270,6 @@ public final class BluetoothDevice implements Parcelable { * @hide */ public static final int UNBOND_REASON_REMOVED = 6; - //TODO: Remove duplicates between here and BluetoothAdapter /** The user will be prompted to enter a pin * @hide */ public static final int PAIRING_VARIANT_PIN = 0; @@ -109,8 +280,6 @@ public final class BluetoothDevice implements Parcelable { * @hide */ public static final int PAIRING_VARIANT_CONFIRMATION = 2; - private static final int ADDRESS_LENGTH = 17; - private static IBluetooth sService; /* Guarenteed constant after first object constructed */ private final String mAddress; @@ -135,7 +304,7 @@ public final class BluetoothDevice implements Parcelable { } } - if (!checkBluetoothAddress(address)) { + if (!BluetoothAdapter.checkBluetoothAddress(address)) { throw new IllegalArgumentException(address + " is not a valid Bluetooth address"); } @@ -216,15 +385,15 @@ public final class BluetoothDevice implements Parcelable { } /** - * Create a bonding with a remote bluetooth device. - * - * This is an asynchronous call. The result of this bonding attempt can be - * observed through BluetoothIntent.BOND_STATE_CHANGED_ACTION intents. + * Start the bonding (pairing) process with the remote device. + * <p>This is an asynchronous call, it will return immediately. Register + * for {@link #ACTION_BOND_STATE_CHANGED} intents to be notified when + * the bonding process completes, and its result. + * <p>Android system services will handle the necessary user interactions + * to confirm and complete the bonding process. + * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}. * - * @param address the remote device Bluetooth address. - * @return false If there was an immediate problem creating the bonding, - * true otherwise. - * @hide + * @return false on immediate error, true if bonding will begin */ public boolean createBond() { try { @@ -234,8 +403,10 @@ public final class BluetoothDevice implements Parcelable { } /** - * Cancel an in-progress bonding request started with createBond. - * @hide + * Cancel an in-progress bonding request started with {@link #createBond}. + * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}. + * + * @return true on sucess, false on error */ public boolean cancelBondProcess() { try { @@ -245,12 +416,13 @@ public final class BluetoothDevice implements Parcelable { } /** - * Removes the remote device and the pairing information associated - * with it. + * Remove bond (pairing) with the remote device. + * <p>Delete the link key associated with the remote device, and + * immediately terminate connections to that device that require + * authentication and encryption. + * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}. * - * @return true if the device was disconnected, false otherwise and on - * error. - * @hide + * @return true on sucess, false on error */ public boolean removeBond() { try { @@ -260,21 +432,35 @@ public final class BluetoothDevice implements Parcelable { } /** - * Get the bonding state of a remote device. - * - * Result is one of: - * BOND_* - * ERROR + * Get the bond state of the remote device. + * <p>Possible values for the bond state are: + * {@link #BOND_NONE}, + * {@link #BOND_BONDING}, + * {@link #BOND_BONDED}. + * <p>Requires {@link android.Manifest.permission#BLUETOOTH}. * - * @param address Bluetooth hardware address of the remote device to check. - * @return Result code - * @hide + * @return the bond state */ public int getBondState() { try { return sService.getBondState(mAddress); } catch (RemoteException e) {Log.e(TAG, "", e);} - return BluetoothDevice.ERROR; + return BOND_NONE; + } + + /** + * Get the Bluetooth class of the remote device. + * <p>Requires {@link android.Manifest.permission#BLUETOOTH}. + * + * @return Bluetooth class object, or null on error + */ + public BluetoothClass getBluetoothClass() { + try { + int classInt = sService.getRemoteClass(mAddress); + if (classInt == BluetoothClass.ERROR) return null; + return new BluetoothClass(classInt); + } catch (RemoteException e) {Log.e(TAG, "", e);} + return null; } /** @@ -305,14 +491,6 @@ public final class BluetoothDevice implements Parcelable { } /** @hide */ - public int getBluetoothClass() { - try { - return sService.getRemoteClass(mAddress); - } catch (RemoteException e) {Log.e(TAG, "", e);} - return BluetoothDevice.ERROR; - } - - /** @hide */ public String[] getUuids() { try { return sService.getRemoteUuids(mAddress); @@ -433,28 +611,4 @@ public final class BluetoothDevice implements Parcelable { return pinBytes; } - /** Sanity check a bluetooth address, such as "00:43:A8:23:10:F0" - * @hide */ - public static boolean checkBluetoothAddress(String address) { - if (address == null || address.length() != ADDRESS_LENGTH) { - return false; - } - for (int i = 0; i < ADDRESS_LENGTH; i++) { - char c = address.charAt(i); - switch (i % 3) { - case 0: - case 1: - if (Character.digit(c, 16) != -1) { - break; // hex character, OK - } - return false; - case 2: - if (c == ':') { - break; // OK - } - return false; - } - } - return true; - } } diff --git a/core/java/android/bluetooth/BluetoothDevicePicker.java b/core/java/android/bluetooth/BluetoothDevicePicker.java new file mode 100644 index 0000000..05eed0e --- /dev/null +++ b/core/java/android/bluetooth/BluetoothDevicePicker.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2009 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.annotation.SdkConstant; +import android.annotation.SdkConstant.SdkConstantType; + +/** + * A helper to show a system "Device Picker" activity to the user. + * + * @hide + */ +public interface BluetoothDevicePicker { + public static final String EXTRA_NEED_AUTH = + "android.bluetooth.devicepicker.extra.NEED_AUTH"; + public static final String EXTRA_FILTER_TYPE = + "android.bluetooth.devicepicker.extra.FILTER_TYPE"; + public static final String EXTRA_LAUNCH_PACKAGE = + "android.bluetooth.devicepicker.extra.LAUNCH_PACKAGE"; + public static final String EXTRA_LAUNCH_CLASS = + "android.bluetooth.devicepicker.extra.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 {@link BluetoothIntent} + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_DEVICE_SELECTED = + "android.bluetooth.devicepicker.action.DEVICE_SELECTED"; + + /** + * Broadcast when someone want to select one BT device from devices list. + * This intent contains below extra data: + * - {@link #EXTRA_NEED_AUTH} (boolean): if need authentication + * - {@link #EXTRA_FILTER_TYPE} (int): what kinds of device should be + * listed + * - {@link #EXTRA_LAUNCH_PACKAGE} (string): where(which package) this + * intent come from + * - {@link #EXTRA_LAUNCH_CLASS} (string): where(which class) this intent + * come from + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_LAUNCH = + "android.bluetooth.devicepicker.action.LAUNCH"; + + /** Ask device picker to show all kinds of BT devices */ + public static final int FILTER_TYPE_ALL = 0; + /** Ask device picker to show BT devices that support AUDIO profiles */ + public static final int FILTER_TYPE_AUDIO = 1; + /** Ask device picker to show BT devices that support Object Transfer */ + public static final int FILTER_TYPE_TRANSFER = 2; +} diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java index d31b6ae..90cff6b 100644 --- a/core/java/android/bluetooth/BluetoothHeadset.java +++ b/core/java/android/bluetooth/BluetoothHeadset.java @@ -16,6 +16,8 @@ package android.bluetooth; +import android.annotation.SdkConstant; +import android.annotation.SdkConstant.SdkConstantType; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -54,6 +56,27 @@ public final class BluetoothHeadset { private static final String TAG = "BluetoothHeadset"; private static final boolean DBG = false; + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_STATE_CHANGED = + "android.bluetooth.headset.action.STATE_CHANGED"; + /** + * TODO(API release): Consider incorporating as new state in + * HEADSET_STATE_CHANGED + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_AUDIO_STATE_CHANGED = + "android.bluetooth.headset.action.AUDIO_STATE_CHANGED"; + public static final String EXTRA_STATE = + "android.bluetooth.headset.extra.STATE"; + public static final String EXTRA_PREVIOUS_STATE = + "android.bluetooth.headset.extra.PREVIOUS_STATE"; + public static final String EXTRA_AUDIO_STATE = + "android.bluetooth.headset.extra.AUDIO_STATE"; + + /** + * TODO(API release): Consider incorporating as new state in + * HEADSET_STATE_CHANGED + */ private IBluetoothHeadset mService; private final Context mContext; private final ServiceListener mServiceListener; diff --git a/core/java/android/bluetooth/BluetoothIntent.java b/core/java/android/bluetooth/BluetoothIntent.java deleted file mode 100644 index 8de19f5..0000000 --- a/core/java/android/bluetooth/BluetoothIntent.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (C) 2008 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.annotation.SdkConstant; -import android.annotation.SdkConstant.SdkConstantType; - -/** - * Bluetooth API constants. - * - * TODO: Deprecate this class - * @hide - */ -public interface BluetoothIntent { - public static final String DEVICE = - "android.bluetooth.intent.DEVICE"; - public static final String NAME = - "android.bluetooth.intent.NAME"; - public static final String ALIAS = - "android.bluetooth.intent.ALIAS"; - public static final String RSSI = - "android.bluetooth.intent.RSSI"; - public static final String CLASS = - "android.bluetooth.intent.CLASS"; - public static final String HEADSET_STATE = - "android.bluetooth.intent.HEADSET_STATE"; - public static final String HEADSET_PREVIOUS_STATE = - "android.bluetooth.intent.HEADSET_PREVIOUS_STATE"; - public static final String HEADSET_AUDIO_STATE = - "android.bluetooth.intent.HEADSET_AUDIO_STATE"; - public static final String BOND_STATE = - "android.bluetooth.intent.BOND_STATE"; - public static final String BOND_PREVIOUS_STATE = - "android.bluetooth.intent.BOND_PREVIOUS_STATE"; - public static final String REASON = - "android.bluetooth.intent.REASON"; - public static final String PAIRING_VARIANT = - "android.bluetooth.intent.PAIRING_VARIANT"; - 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"; - - @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String NAME_CHANGED_ACTION = - "android.bluetooth.intent.action.NAME_CHANGED"; - - @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String DISCOVERY_STARTED_ACTION = - "android.bluetooth.intent.action.DISCOVERY_STARTED"; - @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String DISCOVERY_COMPLETED_ACTION = - "android.bluetooth.intent.action.DISCOVERY_COMPLETED"; - - @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String PAIRING_REQUEST_ACTION = - "android.bluetooth.intent.action.PAIRING_REQUEST"; - @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String PAIRING_CANCEL_ACTION = - "android.bluetooth.intent.action.PAIRING_CANCEL"; - - @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String REMOTE_DEVICE_FOUND_ACTION = - "android.bluetooth.intent.action.REMOTE_DEVICE_FOUND"; - @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String REMOTE_DEVICE_DISAPPEARED_ACTION = - "android.bluetooth.intent.action.REMOTE_DEVICE_DISAPPEARED"; - @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String REMOTE_DEVICE_CLASS_UPDATED_ACTION = - "android.bluetooth.intent.action.REMOTE_DEVICE_DISAPPEARED"; - @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String REMOTE_DEVICE_CONNECTED_ACTION = - "android.bluetooth.intent.action.REMOTE_DEVICE_CONNECTED"; - @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String REMOTE_DEVICE_DISCONNECT_REQUESTED_ACTION = - "android.bluetooth.intent.action.REMOTE_DEVICE_DISCONNECT_REQUESTED"; - @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String REMOTE_DEVICE_DISCONNECTED_ACTION = - "android.bluetooth.intent.action.REMOTE_DEVICE_DISCONNECTED"; - @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String REMOTE_NAME_UPDATED_ACTION = - "android.bluetooth.intent.action.REMOTE_NAME_UPDATED"; - @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String REMOTE_NAME_FAILED_ACTION = - "android.bluetooth.intent.action.REMOTE_NAME_FAILED"; - - /** - * Broadcast when the bond state of a remote device changes. - * Has string extra ADDRESS and int extras BOND_STATE and - * BOND_PREVIOUS_STATE. - * If BOND_STATE is BluetoothDevice.BOND_NOT_BONDED then will - * also have an int extra REASON with a value of: - * BluetoothDevice.BOND_RESULT_* - * */ - @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String BOND_STATE_CHANGED_ACTION = - "android.bluetooth.intent.action.BOND_STATE_CHANGED_ACTION"; - - /** - * TODO(API release): Move into BluetoothHeadset - */ - @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String HEADSET_STATE_CHANGED_ACTION = - "android.bluetooth.intent.action.HEADSET_STATE_CHANGED"; - - /** - * TODO(API release): Consider incorporating as new state in - * HEADSET_STATE_CHANGED - */ - @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String HEADSET_AUDIO_STATE_CHANGED_ACTION = - "android.bluetooth.intent.action.HEADSET_ADUIO_STATE_CHANGED"; -} diff --git a/core/java/android/bluetooth/BluetoothPbap.java b/core/java/android/bluetooth/BluetoothPbap.java index 645e241..b48f48e 100644 --- a/core/java/android/bluetooth/BluetoothPbap.java +++ b/core/java/android/bluetooth/BluetoothPbap.java @@ -221,9 +221,9 @@ public class BluetoothPbap { * devices. It tries to err on the side of false positives. * @return True if this device might support PBAP. */ - public static boolean doesClassMatchSink(int btClass) { + public static boolean doesClassMatchSink(BluetoothClass btClass) { // TODO optimize the rule - switch (BluetoothClass.Device.getDevice(btClass)) { + switch (btClass.getDeviceClass()) { case BluetoothClass.Device.COMPUTER_DESKTOP: case BluetoothClass.Device.COMPUTER_LAPTOP: case BluetoothClass.Device.COMPUTER_SERVER: diff --git a/core/java/android/server/BluetoothA2dpService.java b/core/java/android/server/BluetoothA2dpService.java index a24e0d2..9c687e2 100644 --- a/core/java/android/server/BluetoothA2dpService.java +++ b/core/java/android/server/BluetoothA2dpService.java @@ -25,7 +25,6 @@ package android.server; import android.bluetooth.BluetoothA2dp; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; -import android.bluetooth.BluetoothIntent; import android.bluetooth.BluetoothUuid; import android.bluetooth.IBluetoothA2dp; import android.content.BroadcastReceiver; @@ -79,7 +78,7 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); BluetoothDevice device = - intent.getParcelableExtra(BluetoothIntent.DEVICE); + intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) { int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR); @@ -91,19 +90,19 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub { onBluetoothDisable(); break; } - } else if (action.equals(BluetoothIntent.BOND_STATE_CHANGED_ACTION)) { - int bondState = intent.getIntExtra(BluetoothIntent.BOND_STATE, + } else if (action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) { + int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR); switch(bondState) { case BluetoothDevice.BOND_BONDED: setSinkPriority(device, BluetoothA2dp.PRIORITY_AUTO); break; case BluetoothDevice.BOND_BONDING: - case BluetoothDevice.BOND_NOT_BONDED: + case BluetoothDevice.BOND_NONE: setSinkPriority(device, BluetoothA2dp.PRIORITY_OFF); break; } - } else if (action.equals(BluetoothIntent.REMOTE_DEVICE_CONNECTED_ACTION)) { + } else if (action.equals(BluetoothDevice.ACTION_ACL_CONNECTED)) { if (getSinkPriority(device) > BluetoothA2dp.PRIORITY_OFF && isSinkDevice(device)) { // This device is a preferred sink. Make an A2DP connection @@ -134,8 +133,8 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub { mAdapter = (BluetoothAdapter) context.getSystemService(Context.BLUETOOTH_SERVICE); mIntentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED); - mIntentFilter.addAction(BluetoothIntent.BOND_STATE_CHANGED_ACTION); - mIntentFilter.addAction(BluetoothIntent.REMOTE_DEVICE_CONNECTED_ACTION); + mIntentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED); + mIntentFilter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED); mContext.registerReceiver(mReceiver, mIntentFilter); mAudioDevices = new HashMap<BluetoothDevice, Integer>(); @@ -361,7 +360,7 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub { public synchronized boolean setSinkPriority(BluetoothDevice device, int priority) { mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission"); - if (!BluetoothDevice.checkBluetoothAddress(device.getAddress())) { + if (!BluetoothAdapter.checkBluetoothAddress(device.getAddress())) { return false; } return Settings.Secure.putInt(mContext.getContentResolver(), @@ -411,10 +410,10 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub { } mAudioDevices.put(device, state); - Intent intent = new Intent(BluetoothA2dp.SINK_STATE_CHANGED_ACTION); - intent.putExtra(BluetoothIntent.DEVICE, device); - intent.putExtra(BluetoothA2dp.SINK_PREVIOUS_STATE, prevState); - intent.putExtra(BluetoothA2dp.SINK_STATE, state); + Intent intent = new Intent(BluetoothA2dp.ACTION_SINK_STATE_CHANGED); + intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); + intent.putExtra(BluetoothA2dp.EXTRA_PREVIOUS_SINK_STATE, prevState); + intent.putExtra(BluetoothA2dp.EXTRA_SINK_STATE, state); mContext.sendBroadcast(intent, BLUETOOTH_PERM); if (DBG) log("A2DP state : device: " + device + " State:" + prevState + "->" + state); diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java index b5eb9ac..4c24c50 100644 --- a/core/java/android/server/BluetoothEventLoop.java +++ b/core/java/android/server/BluetoothEventLoop.java @@ -20,7 +20,6 @@ import android.bluetooth.BluetoothA2dp; import android.bluetooth.BluetoothClass; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; -import android.bluetooth.BluetoothIntent; import android.bluetooth.BluetoothUuid; import android.content.Context; import android.content.Intent; @@ -140,11 +139,12 @@ class BluetoothEventLoop { rssiValue = Short.MIN_VALUE; } if (classValue != null) { - Intent intent = new Intent(BluetoothIntent.REMOTE_DEVICE_FOUND_ACTION); - intent.putExtra(BluetoothIntent.DEVICE, mAdapter.getRemoteDevice(address)); - intent.putExtra(BluetoothIntent.CLASS, Integer.valueOf(classValue)); - intent.putExtra(BluetoothIntent.RSSI, rssiValue); - intent.putExtra(BluetoothIntent.NAME, name); + Intent intent = new Intent(BluetoothDevice.ACTION_FOUND); + intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address)); + intent.putExtra(BluetoothDevice.EXTRA_CLASS, + new BluetoothClass(Integer.valueOf(classValue))); + intent.putExtra(BluetoothDevice.EXTRA_RSSI, rssiValue); + intent.putExtra(BluetoothDevice.EXTRA_NAME, name); mContext.sendBroadcast(intent, BLUETOOTH_PERM); } else { @@ -161,8 +161,8 @@ class BluetoothEventLoop { } private void onDeviceDisappeared(String address) { - Intent intent = new Intent(BluetoothIntent.REMOTE_DEVICE_DISAPPEARED_ACTION); - intent.putExtra(BluetoothIntent.DEVICE, mAdapter.getRemoteDevice(address)); + Intent intent = new Intent(BluetoothDevice.ACTION_DISAPPEARED); + intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address)); mContext.sendBroadcast(intent, BLUETOOTH_PERM); } @@ -182,7 +182,7 @@ class BluetoothEventLoop { pairingAttempt(address, result); } else { mBluetoothService.getBondState().setBondState(address, - BluetoothDevice.BOND_NOT_BONDED, result); + BluetoothDevice.BOND_NONE, result); if (mBluetoothService.getBondState().isAutoPairingAttemptsInProgress(address)) { mBluetoothService.getBondState().clearPinAttempts(address); } @@ -202,7 +202,7 @@ class BluetoothEventLoop { MAX_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY) { mBluetoothService.getBondState().clearPinAttempts(address); mBluetoothService.getBondState().setBondState(address, - BluetoothDevice.BOND_NOT_BONDED, result); + BluetoothDevice.BOND_NONE, result); return; } @@ -213,7 +213,7 @@ class BluetoothEventLoop { if (!postResult) { mBluetoothService.getBondState().clearPinAttempts(address); mBluetoothService.getBondState().setBondState(address, - BluetoothDevice.BOND_NOT_BONDED, result); + BluetoothDevice.BOND_NONE, result); return; } mBluetoothService.getBondState().attempt(address); @@ -235,7 +235,7 @@ class BluetoothEventLoop { String address = mBluetoothService.getAddressFromObjectPath(deviceObjectPath); if (address != null) mBluetoothService.getBondState().setBondState(address.toUpperCase(), - BluetoothDevice.BOND_NOT_BONDED, BluetoothDevice.UNBOND_REASON_REMOVED); + BluetoothDevice.BOND_NONE, BluetoothDevice.UNBOND_REASON_REMOVED); } /*package*/ void onPropertyChanged(String[] propValues) { @@ -246,8 +246,8 @@ class BluetoothEventLoop { } String name = propValues[0]; if (name.equals("Name")) { - Intent intent = new Intent(BluetoothIntent.NAME_CHANGED_ACTION); - intent.putExtra(BluetoothIntent.NAME, propValues[1]); + Intent intent = new Intent(BluetoothDevice.ACTION_NAME_CHANGED); + intent.putExtra(BluetoothDevice.EXTRA_NAME, propValues[1]); mContext.sendBroadcast(intent, BLUETOOTH_PERM); mBluetoothService.setProperty(name, propValues[1]); } else if (name.equals("Pairable") || name.equals("Discoverable")) { @@ -274,12 +274,12 @@ class BluetoothEventLoop { Intent intent; if (propValues[1].equals("true")) { mBluetoothService.setIsDiscovering(true); - intent = new Intent(BluetoothIntent.DISCOVERY_STARTED_ACTION); + intent = new Intent(BluetoothAdapter.ACTION_DISCOVERY_STARTED); } else { // Stop the discovery. mBluetoothService.cancelDiscovery(); mBluetoothService.setIsDiscovering(false); - intent = new Intent(BluetoothIntent.DISCOVERY_COMPLETED_ACTION); + intent = new Intent(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); } mContext.sendBroadcast(intent, BLUETOOTH_PERM); mBluetoothService.setProperty(name, propValues[1]); @@ -312,25 +312,26 @@ class BluetoothEventLoop { } BluetoothDevice device = mAdapter.getRemoteDevice(address); if (name.equals("Name")) { - Intent intent = new Intent(BluetoothIntent.REMOTE_NAME_UPDATED_ACTION); - intent.putExtra(BluetoothIntent.DEVICE, device); - intent.putExtra(BluetoothIntent.NAME, propValues[1]); + Intent intent = new Intent(BluetoothDevice.ACTION_NAME_CHANGED); + intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); + intent.putExtra(BluetoothDevice.EXTRA_NAME, propValues[1]); mContext.sendBroadcast(intent, BLUETOOTH_PERM); mBluetoothService.setRemoteDeviceProperty(address, name, propValues[1]); } else if (name.equals("Class")) { - Intent intent = new Intent(BluetoothIntent.REMOTE_DEVICE_CLASS_UPDATED_ACTION); - intent.putExtra(BluetoothIntent.DEVICE, device); - intent.putExtra(BluetoothIntent.CLASS, propValues[1]); + Intent intent = new Intent(BluetoothDevice.ACTION_CLASS_CHANGED); + intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); + intent.putExtra(BluetoothDevice.EXTRA_CLASS, + new BluetoothClass(Integer.valueOf(propValues[1]))); mContext.sendBroadcast(intent, BLUETOOTH_PERM); mBluetoothService.setRemoteDeviceProperty(address, name, propValues[1]); } else if (name.equals("Connected")) { Intent intent = null; if (propValues[1].equals("true")) { - intent = new Intent(BluetoothIntent.REMOTE_DEVICE_CONNECTED_ACTION); + intent = new Intent(BluetoothDevice.ACTION_ACL_CONNECTED); } else { - intent = new Intent(BluetoothIntent.REMOTE_DEVICE_DISCONNECTED_ACTION); + intent = new Intent(BluetoothDevice.ACTION_ACL_DISCONNECTED); } - intent.putExtra(BluetoothIntent.DEVICE, device); + intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); mContext.sendBroadcast(intent, BLUETOOTH_PERM); mBluetoothService.setRemoteDeviceProperty(address, name, propValues[1]); } else if (name.equals("UUIDs")) { @@ -350,7 +351,7 @@ class BluetoothEventLoop { mBluetoothService.getBondState().setBondState(address, BluetoothDevice.BOND_BONDED); } else { mBluetoothService.getBondState().setBondState(address, - BluetoothDevice.BOND_NOT_BONDED); + BluetoothDevice.BOND_NONE); mBluetoothService.setRemoteDeviceProperty(address, "Trusted", "false"); } } else if (name.equals("Trusted")) { @@ -382,10 +383,10 @@ class BluetoothEventLoop { String address = checkPairingRequestAndGetAddress(objectPath, nativeData); if (address == null) return; - Intent intent = new Intent(BluetoothIntent.PAIRING_REQUEST_ACTION); - intent.putExtra(BluetoothIntent.DEVICE, mAdapter.getRemoteDevice(address)); - intent.putExtra(BluetoothIntent.PASSKEY, passkey); - intent.putExtra(BluetoothIntent.PAIRING_VARIANT, + Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST); + intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address)); + intent.putExtra(BluetoothDevice.EXTRA_PASSKEY, passkey); + intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, BluetoothDevice.PAIRING_VARIANT_CONFIRMATION); mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM); return; @@ -395,9 +396,10 @@ class BluetoothEventLoop { String address = checkPairingRequestAndGetAddress(objectPath, nativeData); if (address == null) return; - Intent intent = new Intent(BluetoothIntent.PAIRING_REQUEST_ACTION); - intent.putExtra(BluetoothIntent.DEVICE, mAdapter.getRemoteDevice(address)); - intent.putExtra(BluetoothIntent.PAIRING_VARIANT, BluetoothDevice.PAIRING_VARIANT_PASSKEY); + Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST); + intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address)); + intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, + BluetoothDevice.PAIRING_VARIANT_PASSKEY); mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM); return; } @@ -409,10 +411,10 @@ class BluetoothEventLoop { if (mBluetoothService.getBondState().getBondState(address) == BluetoothDevice.BOND_BONDING) { // we initiated the bonding - int btClass = mBluetoothService.getRemoteClass(address); + BluetoothClass btClass = new BluetoothClass(mBluetoothService.getRemoteClass(address)); // try 0000 once if the device looks dumb - switch (BluetoothClass.Device.getDevice(btClass)) { + switch (btClass.getDeviceClass()) { case BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET: case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE: case BluetoothClass.Device.AUDIO_VIDEO_HEADPHONES: @@ -427,9 +429,9 @@ class BluetoothEventLoop { } } } - Intent intent = new Intent(BluetoothIntent.PAIRING_REQUEST_ACTION); - intent.putExtra(BluetoothIntent.DEVICE, mAdapter.getRemoteDevice(address)); - intent.putExtra(BluetoothIntent.PAIRING_VARIANT, BluetoothDevice.PAIRING_VARIANT_PIN); + Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST); + intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address)); + intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, BluetoothDevice.PAIRING_VARIANT_PIN); mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM); return; } @@ -464,7 +466,7 @@ class BluetoothEventLoop { } private void onAgentCancel() { - Intent intent = new Intent(BluetoothIntent.PAIRING_CANCEL_ACTION); + Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_CANCEL); mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM); return; } diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java index 6482c4c..53fb03c 100644 --- a/core/java/android/server/BluetoothService.java +++ b/core/java/android/server/BluetoothService.java @@ -28,7 +28,6 @@ import android.bluetooth.BluetoothClass; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHeadset; -import android.bluetooth.BluetoothIntent; import android.bluetooth.IBluetooth; import android.content.BroadcastReceiver; import android.content.ContentResolver; @@ -183,7 +182,7 @@ public class BluetoothService extends IBluetooth.Stub { // mark in progress bondings as cancelled for (String address : mBondState.listInState(BluetoothDevice.BOND_BONDING)) { - mBondState.setBondState(address, BluetoothDevice.BOND_NOT_BONDED, + mBondState.setBondState(address, BluetoothDevice.BOND_NONE, BluetoothDevice.UNBOND_REASON_AUTH_CANCELED); } @@ -441,17 +440,17 @@ public class BluetoothService extends IBluetooth.Stub { } if (DBG) log(address + " bond state " + oldState + " -> " + state + " (" + reason + ")"); - Intent intent = new Intent(BluetoothIntent.BOND_STATE_CHANGED_ACTION); - intent.putExtra(BluetoothIntent.DEVICE, mAdapter.getRemoteDevice(address)); - intent.putExtra(BluetoothIntent.BOND_STATE, state); - intent.putExtra(BluetoothIntent.BOND_PREVIOUS_STATE, oldState); - if (state == BluetoothDevice.BOND_NOT_BONDED) { + Intent intent = new Intent(BluetoothDevice.ACTION_BOND_STATE_CHANGED); + intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address)); + intent.putExtra(BluetoothDevice.EXTRA_BOND_STATE, state); + intent.putExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, oldState); + if (state == BluetoothDevice.BOND_NONE) { if (reason <= 0) { Log.w(TAG, "setBondState() called to unbond device, but reason code is " + "invalid. Overriding reason code with BOND_RESULT_REMOVED"); reason = BluetoothDevice.UNBOND_REASON_REMOVED; } - intent.putExtra(BluetoothIntent.REASON, reason); + intent.putExtra(BluetoothDevice.EXTRA_REASON, reason); mState.remove(address); } else { mState.put(address, state); @@ -470,7 +469,7 @@ public class BluetoothService extends IBluetooth.Stub { public synchronized int getBondState(String address) { Integer state = mState.get(address); if (state == null) { - return BluetoothDevice.BOND_NOT_BONDED; + return BluetoothDevice.BOND_NONE; } return state.intValue(); } @@ -526,7 +525,7 @@ public class BluetoothService extends IBluetooth.Stub { private static String toBondStateString(int bondState) { switch (bondState) { - case BluetoothDevice.BOND_NOT_BONDED: + case BluetoothDevice.BOND_NONE: return "not bonded"; case BluetoothDevice.BOND_BONDING: return "bonding"; @@ -642,9 +641,11 @@ public class BluetoothService extends IBluetooth.Stub { case BluetoothAdapter.SCAN_MODE_CONNECTABLE: pairable = true; discoverable = false; + break; case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE: pairable = true; discoverable = true; + break; default: Log.w(TAG, "Requested invalid scan mode " + mode); return false; @@ -685,7 +686,7 @@ public class BluetoothService extends IBluetooth.Stub { */ public synchronized String getRemoteName(String address) { mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); - if (!BluetoothDevice.checkBluetoothAddress(address)) { + if (!BluetoothAdapter.checkBluetoothAddress(address)) { return null; } Map <String, String> properties = mDeviceProperties.get(address); @@ -747,7 +748,7 @@ public class BluetoothService extends IBluetooth.Stub { public synchronized boolean createBond(String address) { mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission"); - if (!BluetoothDevice.checkBluetoothAddress(address)) { + if (!BluetoothAdapter.checkBluetoothAddress(address)) { return false; } address = address.toUpperCase(); @@ -762,7 +763,7 @@ public class BluetoothService extends IBluetooth.Stub { // Check for bond state only if we are not performing auto // pairing exponential back-off attempts. if (!mBondState.isAutoPairingAttemptsInProgress(address) && - mBondState.getBondState(address) != BluetoothDevice.BOND_NOT_BONDED) { + mBondState.getBondState(address) != BluetoothDevice.BOND_NONE) { log("Ignoring createBond(): this device is already bonding or bonded"); return false; } @@ -778,7 +779,7 @@ public class BluetoothService extends IBluetooth.Stub { public synchronized boolean cancelBondProcess(String address) { mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission"); - if (!BluetoothDevice.checkBluetoothAddress(address)) { + if (!BluetoothAdapter.checkBluetoothAddress(address)) { return false; } address = address.toUpperCase(); @@ -786,7 +787,7 @@ public class BluetoothService extends IBluetooth.Stub { return false; } - mBondState.setBondState(address, BluetoothDevice.BOND_NOT_BONDED, + mBondState.setBondState(address, BluetoothDevice.BOND_NONE, BluetoothDevice.UNBOND_REASON_AUTH_CANCELED); cancelDeviceCreationNative(address); return true; @@ -795,7 +796,7 @@ public class BluetoothService extends IBluetooth.Stub { public synchronized boolean removeBond(String address) { mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission"); - if (!BluetoothDevice.checkBluetoothAddress(address)) { + if (!BluetoothAdapter.checkBluetoothAddress(address)) { return false; } return removeDeviceNative(getObjectPathFromAddress(address)); @@ -808,7 +809,7 @@ public class BluetoothService extends IBluetooth.Stub { public synchronized int getBondState(String address) { mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); - if (!BluetoothDevice.checkBluetoothAddress(address)) { + if (!BluetoothAdapter.checkBluetoothAddress(address)) { return BluetoothDevice.ERROR; } return mBondState.getBondState(address.toUpperCase()); @@ -898,7 +899,7 @@ public class BluetoothService extends IBluetooth.Stub { * @return boolean to indicate operation success or fail */ public synchronized boolean setTrust(String address, boolean value) { - if (!BluetoothDevice.checkBluetoothAddress(address)) { + if (!BluetoothAdapter.checkBluetoothAddress(address)) { mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); return false; } @@ -915,7 +916,7 @@ public class BluetoothService extends IBluetooth.Stub { * @return boolean to indicate trust or untrust state */ public synchronized boolean getTrustState(String address) { - if (!BluetoothDevice.checkBluetoothAddress(address)) { + if (!BluetoothAdapter.checkBluetoothAddress(address)) { mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); return false; } @@ -939,7 +940,7 @@ public class BluetoothService extends IBluetooth.Stub { * classes. */ public synchronized int getRemoteClass(String address) { - if (!BluetoothDevice.checkBluetoothAddress(address)) { + if (!BluetoothAdapter.checkBluetoothAddress(address)) { mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); return BluetoothClass.ERROR; } @@ -961,7 +962,7 @@ public class BluetoothService extends IBluetooth.Stub { */ public synchronized String[] getRemoteUuids(String address) { mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); - if (!BluetoothDevice.checkBluetoothAddress(address)) { + if (!BluetoothAdapter.checkBluetoothAddress(address)) { return null; } String value = getRemoteDeviceProperty(address, "UUIDs"); @@ -982,7 +983,7 @@ public class BluetoothService extends IBluetooth.Stub { */ public int getRemoteServiceChannel(String address, String uuid) { mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); - if (!BluetoothDevice.checkBluetoothAddress(address)) { + if (!BluetoothAdapter.checkBluetoothAddress(address)) { return BluetoothDevice.ERROR; } return getDeviceServiceChannelNative(getObjectPathFromAddress(address), uuid, 0x0004); @@ -992,7 +993,7 @@ public class BluetoothService extends IBluetooth.Stub { mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission"); if (pin == null || pin.length <= 0 || pin.length > 16 || - !BluetoothDevice.checkBluetoothAddress(address)) { + !BluetoothAdapter.checkBluetoothAddress(address)) { return false; } address = address.toUpperCase(); @@ -1017,7 +1018,7 @@ public class BluetoothService extends IBluetooth.Stub { public synchronized boolean setPasskey(String address, int passkey) { mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission"); - if (passkey < 0 || passkey > 999999 || !BluetoothDevice.checkBluetoothAddress(address)) { + if (passkey < 0 || passkey > 999999 || !BluetoothAdapter.checkBluetoothAddress(address)) { return false; } address = address.toUpperCase(); @@ -1048,10 +1049,10 @@ public class BluetoothService extends IBluetooth.Stub { public synchronized boolean cancelPairingUserInput(String address) { mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission"); - if (!BluetoothDevice.checkBluetoothAddress(address)) { + if (!BluetoothAdapter.checkBluetoothAddress(address)) { return false; } - mBondState.setBondState(address, BluetoothDevice.BOND_NOT_BONDED, + mBondState.setBondState(address, BluetoothDevice.BOND_NONE, BluetoothDevice.UNBOND_REASON_AUTH_CANCELED); address = address.toUpperCase(); Integer data = mEventLoop.getPasskeyAgentRequestData().remove(address); |