summaryrefslogtreecommitdiff
path: root/framework/java
diff options
context:
space:
mode:
Diffstat (limited to 'framework/java')
-rw-r--r--framework/java/android/bluetooth/BluetoothA2dp.java26
-rwxr-xr-xframework/java/android/bluetooth/BluetoothA2dpSink.java2
-rw-r--r--framework/java/android/bluetooth/BluetoothAdapter.java234
-rwxr-xr-xframework/java/android/bluetooth/BluetoothClass.java7
-rw-r--r--framework/java/android/bluetooth/BluetoothCodecConfig.java36
-rw-r--r--framework/java/android/bluetooth/BluetoothCodecStatus.java5
-rw-r--r--framework/java/android/bluetooth/BluetoothDevice.java90
-rw-r--r--framework/java/android/bluetooth/BluetoothGatt.java11
-rw-r--r--framework/java/android/bluetooth/BluetoothGattCharacteristic.java5
-rw-r--r--framework/java/android/bluetooth/BluetoothGattDescriptor.java4
-rw-r--r--framework/java/android/bluetooth/BluetoothGattService.java4
-rw-r--r--framework/java/android/bluetooth/BluetoothHeadset.java13
-rw-r--r--framework/java/android/bluetooth/BluetoothHeadsetClient.java6
-rw-r--r--framework/java/android/bluetooth/BluetoothHeadsetClientCall.java6
-rw-r--r--framework/java/android/bluetooth/BluetoothHearingAid.java4
-rw-r--r--framework/java/android/bluetooth/BluetoothMap.java2
-rw-r--r--framework/java/android/bluetooth/BluetoothMapClient.java21
-rw-r--r--framework/java/android/bluetooth/BluetoothPan.java11
-rw-r--r--framework/java/android/bluetooth/BluetoothPbap.java2
-rw-r--r--framework/java/android/bluetooth/BluetoothProfile.java6
-rw-r--r--framework/java/android/bluetooth/BluetoothSap.java2
-rw-r--r--framework/java/android/bluetooth/BluetoothServerSocket.java7
-rw-r--r--framework/java/android/bluetooth/BluetoothSocket.java10
-rw-r--r--framework/java/android/bluetooth/BluetoothUuid.java17
-rw-r--r--framework/java/android/bluetooth/le/BluetoothLeAdvertiser.java9
-rw-r--r--framework/java/android/bluetooth/le/ScanFilter.java130
-rw-r--r--framework/java/android/bluetooth/le/ScanRecord.java57
27 files changed, 670 insertions, 57 deletions
diff --git a/framework/java/android/bluetooth/BluetoothA2dp.java b/framework/java/android/bluetooth/BluetoothA2dp.java
index 94fd138ca6..d21f76d435 100644
--- a/framework/java/android/bluetooth/BluetoothA2dp.java
+++ b/framework/java/android/bluetooth/BluetoothA2dp.java
@@ -21,6 +21,7 @@ import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -29,6 +30,7 @@ import android.os.Binder;
import android.os.IBinder;
import android.os.ParcelUuid;
import android.os.RemoteException;
+import android.os.UserHandle;
import android.util.Log;
import com.android.internal.annotations.GuardedBy;
@@ -117,6 +119,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
* @hide
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ @UnsupportedAppUsage
public static final String ACTION_ACTIVE_DEVICE_CHANGED =
"android.bluetooth.a2dp.profile.action.ACTIVE_DEVICE_CHANGED";
@@ -137,6 +140,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
* @hide
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ @UnsupportedAppUsage
public static final String ACTION_CODEC_CONFIG_CHANGED =
"android.bluetooth.a2dp.profile.action.CODEC_CONFIG_CHANGED";
@@ -160,6 +164,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
*
* @hide
*/
+ @UnsupportedAppUsage
public static final int OPTIONAL_CODECS_SUPPORT_UNKNOWN = -1;
/**
@@ -167,6 +172,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
*
* @hide
*/
+ @UnsupportedAppUsage
public static final int OPTIONAL_CODECS_NOT_SUPPORTED = 0;
/**
@@ -174,6 +180,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
*
* @hide
*/
+ @UnsupportedAppUsage
public static final int OPTIONAL_CODECS_SUPPORTED = 1;
/**
@@ -182,6 +189,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
*
* @hide
*/
+ @UnsupportedAppUsage
public static final int OPTIONAL_CODECS_PREF_UNKNOWN = -1;
/**
@@ -189,6 +197,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
*
* @hide
*/
+ @UnsupportedAppUsage
public static final int OPTIONAL_CODECS_PREF_DISABLED = 0;
/**
@@ -196,6 +205,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
*
* @hide
*/
+ @UnsupportedAppUsage
public static final int OPTIONAL_CODECS_PREF_ENABLED = 1;
private Context mContext;
@@ -261,13 +271,14 @@ public final class BluetoothA2dp implements BluetoothProfile {
ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
intent.setComponent(comp);
if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
- mContext.getUser())) {
+ UserHandle.CURRENT_OR_SELF)) {
Log.e(TAG, "Could not bind to Bluetooth A2DP Service with " + intent);
return false;
}
return true;
}
+ @UnsupportedAppUsage
/*package*/ void close() {
mServiceListener = null;
IBluetoothManager mgr = mAdapter.getBluetoothManager();
@@ -315,6 +326,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
* @return false on immediate error, true otherwise
* @hide
*/
+ @UnsupportedAppUsage
public boolean connect(BluetoothDevice device) {
if (DBG) log("connect(" + device + ")");
try {
@@ -357,6 +369,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
* @return false on immediate error, true otherwise
* @hide
*/
+ @UnsupportedAppUsage
public boolean disconnect(BluetoothDevice device) {
if (DBG) log("disconnect(" + device + ")");
try {
@@ -460,6 +473,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
* @return false on immediate error, true otherwise
* @hide
*/
+ @UnsupportedAppUsage
public boolean setActiveDevice(@Nullable BluetoothDevice device) {
if (DBG) log("setActiveDevice(" + device + ")");
try {
@@ -490,6 +504,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
*/
@RequiresPermission(Manifest.permission.BLUETOOTH)
@Nullable
+ @UnsupportedAppUsage
public BluetoothDevice getActiveDevice() {
if (VDBG) log("getActiveDevice()");
try {
@@ -556,6 +571,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
* @hide
*/
@RequiresPermission(Manifest.permission.BLUETOOTH)
+ @UnsupportedAppUsage
public int getPriority(BluetoothDevice device) {
if (VDBG) log("getPriority(" + device + ")");
try {
@@ -671,6 +687,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
* @return the current codec status
* @hide
*/
+ @UnsupportedAppUsage
public BluetoothCodecStatus getCodecStatus(BluetoothDevice device) {
if (DBG) Log.d(TAG, "getCodecStatus(" + device + ")");
try {
@@ -698,6 +715,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
* @param codecConfig the codec configuration preference
* @hide
*/
+ @UnsupportedAppUsage
public void setCodecConfigPreference(BluetoothDevice device,
BluetoothCodecConfig codecConfig) {
if (DBG) Log.d(TAG, "setCodecConfigPreference(" + device + ")");
@@ -723,6 +741,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
* active A2DP Bluetooth device.
* @hide
*/
+ @UnsupportedAppUsage
public void enableOptionalCodecs(BluetoothDevice device) {
if (DBG) Log.d(TAG, "enableOptionalCodecs(" + device + ")");
enableDisableOptionalCodecs(device, true);
@@ -735,6 +754,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
* active A2DP Bluetooth device.
* @hide
*/
+ @UnsupportedAppUsage
public void disableOptionalCodecs(BluetoothDevice device) {
if (DBG) Log.d(TAG, "disableOptionalCodecs(" + device + ")");
enableDisableOptionalCodecs(device, false);
@@ -775,6 +795,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
* OPTIONAL_CODECS_SUPPORTED.
* @hide
*/
+ @UnsupportedAppUsage
public int supportsOptionalCodecs(BluetoothDevice device) {
try {
mServiceLock.readLock().lock();
@@ -799,6 +820,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
* OPTIONAL_CODECS_PREF_DISABLED.
* @hide
*/
+ @UnsupportedAppUsage
public int getOptionalCodecsEnabled(BluetoothDevice device) {
try {
mServiceLock.readLock().lock();
@@ -824,6 +846,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
* OPTIONAL_CODECS_PREF_DISABLED.
* @hide
*/
+ @UnsupportedAppUsage
public void setOptionalCodecsEnabled(BluetoothDevice device, int value) {
try {
if (value != BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN
@@ -854,6 +877,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
*
* @hide
*/
+ @UnsupportedAppUsage
public static String stateToString(int state) {
switch (state) {
case STATE_DISCONNECTED:
diff --git a/framework/java/android/bluetooth/BluetoothA2dpSink.java b/framework/java/android/bluetooth/BluetoothA2dpSink.java
index 13f0aaf47f..fda2f89275 100755
--- a/framework/java/android/bluetooth/BluetoothA2dpSink.java
+++ b/framework/java/android/bluetooth/BluetoothA2dpSink.java
@@ -16,6 +16,7 @@
package android.bluetooth;
+import android.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -278,6 +279,7 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
* @return false on immediate error, true otherwise
* @hide
*/
+ @UnsupportedAppUsage
public boolean disconnect(BluetoothDevice device) {
if (DBG) log("disconnect(" + device + ")");
final IBluetoothA2dpSink service = mService;
diff --git a/framework/java/android/bluetooth/BluetoothAdapter.java b/framework/java/android/bluetooth/BluetoothAdapter.java
index 44051081b5..8e6a3856d5 100644
--- a/framework/java/android/bluetooth/BluetoothAdapter.java
+++ b/framework/java/android/bluetooth/BluetoothAdapter.java
@@ -23,6 +23,7 @@ import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
+import android.annotation.UnsupportedAppUsage;
import android.app.ActivityThread;
import android.bluetooth.le.BluetoothLeAdvertiser;
import android.bluetooth.le.BluetoothLeScanner;
@@ -80,7 +81,8 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
* {@link #getBondedDevices()}; start device discovery with
* {@link #startDiscovery()}; or create a {@link BluetoothServerSocket} to
* listen for incoming RFComm connection requests with {@link
- * #listenUsingRfcommWithServiceRecord(String, UUID)}; or start a scan for
+ * #listenUsingRfcommWithServiceRecord(String, UUID)}; listen for incoming L2CAP Connection-oriented
+ * Channels (CoC) connection requests with {@link #listenUsingL2capChannel()}; or start a scan for
* Bluetooth LE devices with {@link #startLeScan(LeScanCallback callback)}.
* </p>
* <p>This class is thread safe.</p>
@@ -394,6 +396,64 @@ public final class BluetoothAdapter {
public static final int SCAN_MODE_CONNECTABLE_DISCOVERABLE = 23;
/**
+ * Device only has a display.
+ *
+ * @hide
+ */
+ public static final int IO_CAPABILITY_OUT = 0;
+
+ /**
+ * Device has a display and the ability to input Yes/No.
+ *
+ * @hide
+ */
+ public static final int IO_CAPABILITY_IO = 1;
+
+ /**
+ * Device only has a keyboard for entry but no display.
+ *
+ * @hide
+ */
+ public static final int IO_CAPABILITY_IN = 2;
+
+ /**
+ * Device has no Input or Output capability.
+ *
+ * @hide
+ */
+ public static final int IO_CAPABILITY_NONE = 3;
+
+ /**
+ * Device has a display and a full keyboard.
+ *
+ * @hide
+ */
+ public static final int IO_CAPABILITY_KBDISP = 4;
+
+ /**
+ * Maximum range value for Input/Output capabilities.
+ *
+ * <p>This should be updated when adding a new Input/Output capability. Other code
+ * like validation depends on this being accurate.
+ *
+ * @hide
+ */
+ public static final int IO_CAPABILITY_MAX = 5;
+
+ /**
+ * The Input/Output capability of the device is unknown.
+ *
+ * @hide
+ */
+ public static final int IO_CAPABILITY_UNKNOWN = 255;
+
+ /** @hide */
+ @IntDef({IO_CAPABILITY_OUT, IO_CAPABILITY_IO, IO_CAPABILITY_IN, IO_CAPABILITY_NONE,
+ IO_CAPABILITY_KBDISP})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface IoCapability {}
+
+ /**
* 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
@@ -581,6 +641,7 @@ public final class BluetoothAdapter {
private static PeriodicAdvertisingManager sPeriodicAdvertisingManager;
private final IBluetoothManager mManagerService;
+ @UnsupportedAppUsage
private IBluetooth mService;
private final ReentrantReadWriteLock mServiceLock = new ReentrantReadWriteLock();
@@ -936,6 +997,7 @@ public final class BluetoothAdapter {
*/
@RequiresPermission(Manifest.permission.BLUETOOTH)
@AdapterState
+ @UnsupportedAppUsage
public int getLeState() {
int state = BluetoothAdapter.STATE_OFF;
@@ -1046,6 +1108,7 @@ public final class BluetoothAdapter {
* @return true to indicate adapter shutdown has begun, or false on immediate error
* @hide
*/
+ @UnsupportedAppUsage
public boolean disable(boolean persist) {
try {
@@ -1097,6 +1160,7 @@ public final class BluetoothAdapter {
* @return true to indicate that the config file was successfully cleared
* @hide
*/
+ @UnsupportedAppUsage
public boolean factoryReset() {
try {
mServiceLock.readLock().lock();
@@ -1120,6 +1184,7 @@ public final class BluetoothAdapter {
* @return the UUIDs supported by the local Bluetooth Adapter.
* @hide
*/
+ @UnsupportedAppUsage
public ParcelUuid[] getUuids() {
if (getState() != STATE_ON) {
return null;
@@ -1225,6 +1290,108 @@ public final class BluetoothAdapter {
}
/**
+ * Returns the Input/Output capability of the device for classic Bluetooth.
+ *
+ * @return Input/Output capability of the device. One of {@link #IO_CAPABILITY_OUT},
+ * {@link #IO_CAPABILITY_IO}, {@link #IO_CAPABILITY_IN}, {@link #IO_CAPABILITY_NONE},
+ * {@link #IO_CAPABILITY_KBDISP} or {@link #IO_CAPABILITY_UNKNOWN}.
+ *
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+ @IoCapability
+ public int getIoCapability() {
+ if (getState() != STATE_ON) return BluetoothAdapter.IO_CAPABILITY_UNKNOWN;
+ try {
+ mServiceLock.readLock().lock();
+ if (mService != null) return mService.getIoCapability();
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getMessage(), e);
+ } finally {
+ mServiceLock.readLock().unlock();
+ }
+ return BluetoothAdapter.IO_CAPABILITY_UNKNOWN;
+ }
+
+ /**
+ * Sets the Input/Output capability of the device for classic Bluetooth.
+ *
+ * <p>Changing the Input/Output capability of a device only takes effect on restarting the
+ * Bluetooth stack. You would need to restart the stack using {@link BluetoothAdapter#disable()}
+ * and {@link BluetoothAdapter#enable()} to see the changes.
+ *
+ * @param capability Input/Output capability of the device. One of {@link #IO_CAPABILITY_OUT},
+ * {@link #IO_CAPABILITY_IO}, {@link #IO_CAPABILITY_IN},
+ * {@link #IO_CAPABILITY_NONE} or {@link #IO_CAPABILITY_KBDISP}.
+ *
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+ public boolean setIoCapability(@IoCapability int capability) {
+ if (getState() != STATE_ON) return false;
+ try {
+ mServiceLock.readLock().lock();
+ if (mService != null) return mService.setIoCapability(capability);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getMessage(), e);
+ } finally {
+ mServiceLock.readLock().unlock();
+ }
+ return false;
+ }
+
+ /**
+ * Returns the Input/Output capability of the device for BLE operations.
+ *
+ * @return Input/Output capability of the device. One of {@link #IO_CAPABILITY_OUT},
+ * {@link #IO_CAPABILITY_IO}, {@link #IO_CAPABILITY_IN}, {@link #IO_CAPABILITY_NONE},
+ * {@link #IO_CAPABILITY_KBDISP} or {@link #IO_CAPABILITY_UNKNOWN}.
+ *
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+ @IoCapability
+ public int getLeIoCapability() {
+ if (getState() != STATE_ON) return BluetoothAdapter.IO_CAPABILITY_UNKNOWN;
+ try {
+ mServiceLock.readLock().lock();
+ if (mService != null) return mService.getLeIoCapability();
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getMessage(), e);
+ } finally {
+ mServiceLock.readLock().unlock();
+ }
+ return BluetoothAdapter.IO_CAPABILITY_UNKNOWN;
+ }
+
+ /**
+ * Sets the Input/Output capability of the device for BLE operations.
+ *
+ * <p>Changing the Input/Output capability of a device only takes effect on restarting the
+ * Bluetooth stack. You would need to restart the stack using {@link BluetoothAdapter#disable()}
+ * and {@link BluetoothAdapter#enable()} to see the changes.
+ *
+ * @param capability Input/Output capability of the device. One of {@link #IO_CAPABILITY_OUT},
+ * {@link #IO_CAPABILITY_IO}, {@link #IO_CAPABILITY_IN},
+ * {@link #IO_CAPABILITY_NONE} or {@link #IO_CAPABILITY_KBDISP}.
+ *
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+ public boolean setLeIoCapability(@IoCapability int capability) {
+ if (getState() != STATE_ON) return false;
+ try {
+ mServiceLock.readLock().lock();
+ if (mService != null) return mService.setLeIoCapability(capability);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getMessage(), e);
+ } finally {
+ mServiceLock.readLock().unlock();
+ }
+ return false;
+ }
+
+ /**
* Get the current Bluetooth scan mode of the local Bluetooth adapter.
* <p>The Bluetooth scan mode determines if the local adapter is
* connectable and/or discoverable from remote Bluetooth devices.
@@ -1286,6 +1453,7 @@ public final class BluetoothAdapter {
* @return true if the scan mode was set, false otherwise
* @hide
*/
+ @UnsupportedAppUsage
public boolean setScanMode(@ScanMode int mode, int duration) {
if (getState() != STATE_ON) {
return false;
@@ -1304,6 +1472,7 @@ public final class BluetoothAdapter {
}
/** @hide */
+ @UnsupportedAppUsage
public boolean setScanMode(int mode) {
if (getState() != STATE_ON) {
return false;
@@ -1313,6 +1482,7 @@ public final class BluetoothAdapter {
}
/** @hide */
+ @UnsupportedAppUsage
public int getDiscoverableTimeout() {
if (getState() != STATE_ON) {
return -1;
@@ -1331,6 +1501,7 @@ public final class BluetoothAdapter {
}
/** @hide */
+ @UnsupportedAppUsage
public void setDiscoverableTimeout(int timeout) {
if (getState() != STATE_ON) {
return;
@@ -1855,6 +2026,7 @@ public final class BluetoothAdapter {
* #STATE_CONNECTING} or {@link #STATE_DISCONNECTED}
* @hide
*/
+ @UnsupportedAppUsage
public int getConnectionState() {
if (getState() != STATE_ON) {
return BluetoothAdapter.STATE_DISCONNECTED;
@@ -1942,6 +2114,7 @@ public final class BluetoothAdapter {
* permissions, or channel in use.
* @hide
*/
+ @UnsupportedAppUsage
public BluetoothServerSocket listenUsingRfcommOn(int channel, boolean mitm,
boolean min16DigitPin) throws IOException {
BluetoothServerSocket socket =
@@ -2054,6 +2227,7 @@ public final class BluetoothAdapter {
* permissions, or channel in use.
* @hide
*/
+ @UnsupportedAppUsage
public BluetoothServerSocket listenUsingEncryptedRfcommWithServiceRecord(String name, UUID uuid)
throws IOException {
return createNewRfcommSocketAndRecord(name, uuid, false, true);
@@ -2597,6 +2771,7 @@ public final class BluetoothAdapter {
return true;
}
+ @UnsupportedAppUsage
/*package*/ IBluetoothManager getBluetoothManager() {
return mManagerService;
}
@@ -2604,6 +2779,7 @@ public final class BluetoothAdapter {
private final ArrayList<IBluetoothManagerCallback> mProxyServiceStateCallbacks =
new ArrayList<IBluetoothManagerCallback>();
+ @UnsupportedAppUsage
/*package*/ IBluetooth getBluetoothService(IBluetoothManagerCallback cb) {
synchronized (mProxyServiceStateCallbacks) {
if (cb == null) {
@@ -2792,7 +2968,7 @@ public final class BluetoothAdapter {
/**
* Create a secure L2CAP Connection-oriented Channel (CoC) {@link BluetoothServerSocket} and
* assign a dynamic protocol/service multiplexer (PSM) value. This socket can be used to listen
- * for incoming connections.
+ * for incoming connections. The supported Bluetooth transport is LE only.
* <p>A remote device connecting to this socket will be authenticated and communication on this
* socket will be encrypted.
* <p>Use {@link BluetoothServerSocket#accept} to retrieve incoming connections from a listening
@@ -2802,21 +2978,16 @@ public final class BluetoothAdapter {
* closed, Bluetooth is turned off, or the application exits unexpectedly.
* <p>The mechanism of disclosing the assigned dynamic PSM value to the initiating peer is
* defined and performed by the application.
- * <p>Use {@link BluetoothDevice#createL2capCocSocket(int, int)} to connect to this server
+ * <p>Use {@link BluetoothDevice#createL2capChannel(int)} to connect to this server
* socket from another Android device that is given the PSM value.
*
- * @param transport Bluetooth transport to use, must be {@link BluetoothDevice#TRANSPORT_LE}
* @return an L2CAP CoC BluetoothServerSocket
* @throws IOException on error, for example Bluetooth not available, or insufficient
* permissions, or unable to start this CoC
- * @hide
*/
@RequiresPermission(Manifest.permission.BLUETOOTH)
- public BluetoothServerSocket listenUsingL2capCoc(int transport)
+ public BluetoothServerSocket listenUsingL2capChannel()
throws IOException {
- if (transport != BluetoothDevice.TRANSPORT_LE) {
- throw new IllegalArgumentException("Unsupported transport: " + transport);
- }
BluetoothServerSocket socket =
new BluetoothServerSocket(BluetoothSocket.TYPE_L2CAP_LE, true, true,
SOCKET_CHANNEL_AUTO_STATIC_NO_SDP, false, false);
@@ -2830,7 +3001,7 @@ public final class BluetoothAdapter {
throw new IOException("Error: Unable to assign PSM value");
}
if (DBG) {
- Log.d(TAG, "listenUsingL2capCoc: set assigned PSM to "
+ Log.d(TAG, "listenUsingL2capChannel: set assigned PSM to "
+ assignedPsm);
}
socket.setChannel(assignedPsm);
@@ -2839,10 +3010,23 @@ public final class BluetoothAdapter {
}
/**
+ * TODO: Remove this hidden method once all the SL4A and other tests are updated to use the new
+ * API name, listenUsingL2capChannel.
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
+ public BluetoothServerSocket listenUsingL2capCoc(int transport)
+ throws IOException {
+ Log.e(TAG, "listenUsingL2capCoc: PLEASE USE THE OFFICIAL API, listenUsingL2capChannel");
+ return listenUsingL2capChannel();
+ }
+
+ /**
* Create an insecure L2CAP Connection-oriented Channel (CoC) {@link BluetoothServerSocket} and
- * assign a dynamic PSM value. This socket can be used to listen for incoming connections.
+ * assign a dynamic PSM value. This socket can be used to listen for incoming connections. The
+ * supported Bluetooth transport is LE only.
* <p>The link key is not required to be authenticated, i.e the communication may be vulnerable
- * to man-in-the-middle attacks. Use {@link #listenUsingL2capCoc}, if an encrypted and
+ * to man-in-the-middle attacks. Use {@link #listenUsingL2capChannel}, if an encrypted and
* authenticated communication channel is desired.
* <p>Use {@link BluetoothServerSocket#accept} to retrieve incoming connections from a listening
* {@link BluetoothServerSocket}.
@@ -2852,21 +3036,16 @@ public final class BluetoothAdapter {
* unexpectedly.
* <p>The mechanism of disclosing the assigned dynamic PSM value to the initiating peer is
* defined and performed by the application.
- * <p>Use {@link BluetoothDevice#createInsecureL2capCocSocket(int, int)} to connect to this
- * server socket from another Android device that is given the PSM value.
+ * <p>Use {@link BluetoothDevice#createInsecureL2capChannel(int)} to connect to this server
+ * socket from another Android device that is given the PSM value.
*
- * @param transport Bluetooth transport to use, must be {@link BluetoothDevice#TRANSPORT_LE}
* @return an L2CAP CoC BluetoothServerSocket
* @throws IOException on error, for example Bluetooth not available, or insufficient
* permissions, or unable to start this CoC
- * @hide
*/
@RequiresPermission(Manifest.permission.BLUETOOTH)
- public BluetoothServerSocket listenUsingInsecureL2capCoc(int transport)
+ public BluetoothServerSocket listenUsingInsecureL2capChannel()
throws IOException {
- if (transport != BluetoothDevice.TRANSPORT_LE) {
- throw new IllegalArgumentException("Unsupported transport: " + transport);
- }
BluetoothServerSocket socket =
new BluetoothServerSocket(BluetoothSocket.TYPE_L2CAP_LE, false, false,
SOCKET_CHANNEL_AUTO_STATIC_NO_SDP, false, false);
@@ -2880,11 +3059,24 @@ public final class BluetoothAdapter {
throw new IOException("Error: Unable to assign PSM value");
}
if (DBG) {
- Log.d(TAG, "listenUsingInsecureL2capOn: set assigned PSM to "
+ Log.d(TAG, "listenUsingInsecureL2capChannel: set assigned PSM to "
+ assignedPsm);
}
socket.setChannel(assignedPsm);
return socket;
}
+
+ /**
+ * TODO: Remove this hidden method once all the SL4A and other tests are updated to use the new
+ * API name, listenUsingInsecureL2capChannel.
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
+ public BluetoothServerSocket listenUsingInsecureL2capCoc(int transport)
+ throws IOException {
+ Log.e(TAG, "listenUsingInsecureL2capCoc: PLEASE USE THE OFFICIAL API, "
+ + "listenUsingInsecureL2capChannel");
+ return listenUsingInsecureL2capChannel();
+ }
}
diff --git a/framework/java/android/bluetooth/BluetoothClass.java b/framework/java/android/bluetooth/BluetoothClass.java
index f22ea6e88e..3a78cbdd4d 100755
--- a/framework/java/android/bluetooth/BluetoothClass.java
+++ b/framework/java/android/bluetooth/BluetoothClass.java
@@ -16,6 +16,8 @@
package android.bluetooth;
+import android.annotation.TestApi;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -63,6 +65,7 @@ public final class BluetoothClass implements Parcelable {
private final int mClass;
/** @hide */
+ @UnsupportedAppUsage
public BluetoothClass(int classInt) {
mClass = classInt;
}
@@ -291,6 +294,7 @@ public final class BluetoothClass implements Parcelable {
*
* @hide
*/
+ @TestApi
public int getClassOfDevice() {
return mClass;
}
@@ -322,8 +326,10 @@ public final class BluetoothClass implements Parcelable {
}
/** @hide */
+ @UnsupportedAppUsage
public static final int PROFILE_HEADSET = 0;
/** @hide */
+ @UnsupportedAppUsage
public static final int PROFILE_A2DP = 1;
/** @hide */
public static final int PROFILE_OPP = 2;
@@ -346,6 +352,7 @@ public final class BluetoothClass implements Parcelable {
* @return True if this device might support specified profile.
* @hide
*/
+ @UnsupportedAppUsage
public boolean doesClassMatch(int profile) {
if (profile == PROFILE_A2DP) {
if (hasService(Service.RENDER)) {
diff --git a/framework/java/android/bluetooth/BluetoothCodecConfig.java b/framework/java/android/bluetooth/BluetoothCodecConfig.java
index e3a6e06472..79c0a3a207 100644
--- a/framework/java/android/bluetooth/BluetoothCodecConfig.java
+++ b/framework/java/android/bluetooth/BluetoothCodecConfig.java
@@ -16,6 +16,7 @@
package android.bluetooth;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -32,34 +33,58 @@ public final class BluetoothCodecConfig implements Parcelable {
// Add an entry for each source codec here.
// NOTE: The values should be same as those listed in the following file:
// hardware/libhardware/include/hardware/bt_av.h
+ @UnsupportedAppUsage
public static final int SOURCE_CODEC_TYPE_SBC = 0;
+ @UnsupportedAppUsage
public static final int SOURCE_CODEC_TYPE_AAC = 1;
+ @UnsupportedAppUsage
public static final int SOURCE_CODEC_TYPE_APTX = 2;
+ @UnsupportedAppUsage
public static final int SOURCE_CODEC_TYPE_APTX_HD = 3;
+ @UnsupportedAppUsage
public static final int SOURCE_CODEC_TYPE_LDAC = 4;
+ @UnsupportedAppUsage
public static final int SOURCE_CODEC_TYPE_MAX = 5;
+ @UnsupportedAppUsage
public static final int SOURCE_CODEC_TYPE_INVALID = 1000 * 1000;
+ @UnsupportedAppUsage
public static final int CODEC_PRIORITY_DISABLED = -1;
+ @UnsupportedAppUsage
public static final int CODEC_PRIORITY_DEFAULT = 0;
+ @UnsupportedAppUsage
public static final int CODEC_PRIORITY_HIGHEST = 1000 * 1000;
+ @UnsupportedAppUsage
public static final int SAMPLE_RATE_NONE = 0;
+ @UnsupportedAppUsage
public static final int SAMPLE_RATE_44100 = 0x1 << 0;
+ @UnsupportedAppUsage
public static final int SAMPLE_RATE_48000 = 0x1 << 1;
+ @UnsupportedAppUsage
public static final int SAMPLE_RATE_88200 = 0x1 << 2;
+ @UnsupportedAppUsage
public static final int SAMPLE_RATE_96000 = 0x1 << 3;
+ @UnsupportedAppUsage
public static final int SAMPLE_RATE_176400 = 0x1 << 4;
+ @UnsupportedAppUsage
public static final int SAMPLE_RATE_192000 = 0x1 << 5;
+ @UnsupportedAppUsage
public static final int BITS_PER_SAMPLE_NONE = 0;
+ @UnsupportedAppUsage
public static final int BITS_PER_SAMPLE_16 = 0x1 << 0;
+ @UnsupportedAppUsage
public static final int BITS_PER_SAMPLE_24 = 0x1 << 1;
+ @UnsupportedAppUsage
public static final int BITS_PER_SAMPLE_32 = 0x1 << 2;
+ @UnsupportedAppUsage
public static final int CHANNEL_MODE_NONE = 0;
+ @UnsupportedAppUsage
public static final int CHANNEL_MODE_MONO = 0x1 << 0;
+ @UnsupportedAppUsage
public static final int CHANNEL_MODE_STEREO = 0x1 << 1;
private final int mCodecType;
@@ -72,6 +97,7 @@ public final class BluetoothCodecConfig implements Parcelable {
private final long mCodecSpecific3;
private final long mCodecSpecific4;
+ @UnsupportedAppUsage
public BluetoothCodecConfig(int codecType, int codecPriority,
int sampleRate, int bitsPerSample,
int channelMode, long codecSpecific1,
@@ -276,6 +302,7 @@ public final class BluetoothCodecConfig implements Parcelable {
*
* @return the codec type
*/
+ @UnsupportedAppUsage
public int getCodecType() {
return mCodecType;
}
@@ -296,6 +323,7 @@ public final class BluetoothCodecConfig implements Parcelable {
*
* @return the codec priority
*/
+ @UnsupportedAppUsage
public int getCodecPriority() {
return mCodecPriority;
}
@@ -307,6 +335,7 @@ public final class BluetoothCodecConfig implements Parcelable {
*
* @param codecPriority the codec priority
*/
+ @UnsupportedAppUsage
public void setCodecPriority(int codecPriority) {
mCodecPriority = codecPriority;
}
@@ -324,6 +353,7 @@ public final class BluetoothCodecConfig implements Parcelable {
*
* @return the codec sample rate
*/
+ @UnsupportedAppUsage
public int getSampleRate() {
return mSampleRate;
}
@@ -338,6 +368,7 @@ public final class BluetoothCodecConfig implements Parcelable {
*
* @return the codec bits per sample
*/
+ @UnsupportedAppUsage
public int getBitsPerSample() {
return mBitsPerSample;
}
@@ -351,6 +382,7 @@ public final class BluetoothCodecConfig implements Parcelable {
*
* @return the codec channel mode
*/
+ @UnsupportedAppUsage
public int getChannelMode() {
return mChannelMode;
}
@@ -360,6 +392,7 @@ public final class BluetoothCodecConfig implements Parcelable {
*
* @return a codec specific value1.
*/
+ @UnsupportedAppUsage
public long getCodecSpecific1() {
return mCodecSpecific1;
}
@@ -369,6 +402,7 @@ public final class BluetoothCodecConfig implements Parcelable {
*
* @return a codec specific value2
*/
+ @UnsupportedAppUsage
public long getCodecSpecific2() {
return mCodecSpecific2;
}
@@ -378,6 +412,7 @@ public final class BluetoothCodecConfig implements Parcelable {
*
* @return a codec specific value3
*/
+ @UnsupportedAppUsage
public long getCodecSpecific3() {
return mCodecSpecific3;
}
@@ -387,6 +422,7 @@ public final class BluetoothCodecConfig implements Parcelable {
*
* @return a codec specific value4
*/
+ @UnsupportedAppUsage
public long getCodecSpecific4() {
return mCodecSpecific4;
}
diff --git a/framework/java/android/bluetooth/BluetoothCodecStatus.java b/framework/java/android/bluetooth/BluetoothCodecStatus.java
index 3a05e7093d..78560d2de4 100644
--- a/framework/java/android/bluetooth/BluetoothCodecStatus.java
+++ b/framework/java/android/bluetooth/BluetoothCodecStatus.java
@@ -16,6 +16,7 @@
package android.bluetooth;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -37,6 +38,7 @@ public final class BluetoothCodecStatus implements Parcelable {
* This extra represents the current codec status of the A2DP
* profile.
*/
+ @UnsupportedAppUsage
public static final String EXTRA_CODEC_STATUS =
"android.bluetooth.codec.extra.CODEC_STATUS";
@@ -137,6 +139,7 @@ public final class BluetoothCodecStatus implements Parcelable {
*
* @return the current codec configuration
*/
+ @UnsupportedAppUsage
public BluetoothCodecConfig getCodecConfig() {
return mCodecConfig;
}
@@ -146,6 +149,7 @@ public final class BluetoothCodecStatus implements Parcelable {
*
* @return an array with the codecs local capabilities
*/
+ @UnsupportedAppUsage
public BluetoothCodecConfig[] getCodecsLocalCapabilities() {
return mCodecsLocalCapabilities;
}
@@ -155,6 +159,7 @@ public final class BluetoothCodecStatus implements Parcelable {
*
* @return an array with the codecs selectable capabilities
*/
+ @UnsupportedAppUsage
public BluetoothCodecConfig[] getCodecsSelectableCapabilities() {
return mCodecsSelectableCapabilities;
}
diff --git a/framework/java/android/bluetooth/BluetoothDevice.java b/framework/java/android/bluetooth/BluetoothDevice.java
index 3cf8074665..fc0c1dc438 100644
--- a/framework/java/android/bluetooth/BluetoothDevice.java
+++ b/framework/java/android/bluetooth/BluetoothDevice.java
@@ -21,6 +21,7 @@ import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.os.Handler;
import android.os.Parcel;
@@ -115,6 +116,7 @@ public final class BluetoothDevice implements Parcelable {
* @hide
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ @UnsupportedAppUsage
public static final String ACTION_DISAPPEARED =
"android.bluetooth.device.action.DISAPPEARED";
@@ -186,6 +188,7 @@ public final class BluetoothDevice implements Parcelable {
* @hide
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ @UnsupportedAppUsage
public static final String ACTION_ALIAS_CHANGED =
"android.bluetooth.device.action.ALIAS_CHANGED";
@@ -306,6 +309,7 @@ public final class BluetoothDevice implements Parcelable {
*
* @hide
*/
+ @UnsupportedAppUsage
public static final String EXTRA_REASON = "android.bluetooth.device.extra.REASON";
/**
@@ -346,6 +350,7 @@ public final class BluetoothDevice implements Parcelable {
/** @hide */
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ @UnsupportedAppUsage
public static final String ACTION_SDP_RECORD =
"android.bluetooth.device.action.SDP_RECORD";
@@ -390,6 +395,7 @@ public final class BluetoothDevice implements Parcelable {
"android.bluetooth.device.action.PAIRING_REQUEST";
/** @hide */
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ @UnsupportedAppUsage
public static final String ACTION_PAIRING_CANCEL =
"android.bluetooth.device.action.PAIRING_CANCEL";
@@ -481,6 +487,7 @@ public final class BluetoothDevice implements Parcelable {
*
* @hide
*/
+ @UnsupportedAppUsage
public static final int UNBOND_REASON_AUTH_FAILED = 1;
/**
@@ -489,6 +496,7 @@ public final class BluetoothDevice implements Parcelable {
*
* @hide
*/
+ @UnsupportedAppUsage
public static final int UNBOND_REASON_AUTH_REJECTED = 2;
/**
@@ -503,6 +511,7 @@ public final class BluetoothDevice implements Parcelable {
*
* @hide
*/
+ @UnsupportedAppUsage
public static final int UNBOND_REASON_REMOTE_DEVICE_DOWN = 4;
/**
@@ -510,6 +519,7 @@ public final class BluetoothDevice implements Parcelable {
*
* @hide
*/
+ @UnsupportedAppUsage
public static final int UNBOND_REASON_DISCOVERY_IN_PROGRESS = 5;
/**
@@ -517,6 +527,7 @@ public final class BluetoothDevice implements Parcelable {
*
* @hide
*/
+ @UnsupportedAppUsage
public static final int UNBOND_REASON_AUTH_TIMEOUT = 6;
/**
@@ -524,6 +535,7 @@ public final class BluetoothDevice implements Parcelable {
*
* @hide
*/
+ @UnsupportedAppUsage
public static final int UNBOND_REASON_REPEATED_ATTEMPTS = 7;
/**
@@ -532,6 +544,7 @@ public final class BluetoothDevice implements Parcelable {
*
* @hide
*/
+ @UnsupportedAppUsage
public static final int UNBOND_REASON_REMOTE_AUTH_CANCELED = 8;
/**
@@ -610,6 +623,7 @@ public final class BluetoothDevice implements Parcelable {
"android.bluetooth.device.extra.SDP_RECORD";
/** @hide */
+ @UnsupportedAppUsage
public static final String EXTRA_SDP_SEARCH_STATUS =
"android.bluetooth.device.extra.SDP_SEARCH_STATUS";
/**
@@ -720,6 +734,7 @@ public final class BluetoothDevice implements Parcelable {
private final String mAddress;
/*package*/
+ @UnsupportedAppUsage
static IBluetooth getService() {
synchronized (BluetoothDevice.class) {
if (sService == null) {
@@ -763,6 +778,7 @@ public final class BluetoothDevice implements Parcelable {
* @throws IllegalArgumentException address is invalid
* @hide
*/
+ @UnsupportedAppUsage
/*package*/ BluetoothDevice(String address) {
getService(); // ensures sService is initialized
if (!BluetoothAdapter.checkBluetoothAddress(address)) {
@@ -887,6 +903,7 @@ public final class BluetoothDevice implements Parcelable {
* @return the Bluetooth alias, or null if no alias or there was a problem
* @hide
*/
+ @UnsupportedAppUsage
public String getAlias() {
final IBluetooth service = sService;
if (service == null) {
@@ -911,6 +928,7 @@ public final class BluetoothDevice implements Parcelable {
* @return true on success, false on error
* @hide
*/
+ @UnsupportedAppUsage
public boolean setAlias(String alias) {
final IBluetooth service = sService;
if (service == null) {
@@ -934,6 +952,7 @@ public final class BluetoothDevice implements Parcelable {
* @see #getAlias()
* @see #getName()
*/
+ @UnsupportedAppUsage
public String getAliasName() {
String name = getAlias();
if (name == null) {
@@ -952,6 +971,7 @@ public final class BluetoothDevice implements Parcelable {
* @hide
*/
@RequiresPermission(Manifest.permission.BLUETOOTH)
+ @UnsupportedAppUsage
public int getBatteryLevel() {
final IBluetooth service = sService;
if (service == null) {
@@ -1010,6 +1030,7 @@ public final class BluetoothDevice implements Parcelable {
* @throws IllegalArgumentException if an invalid transport was specified
* @hide
*/
+ @UnsupportedAppUsage
public boolean createBond(int transport) {
final IBluetooth service = sService;
if (service == null) {
@@ -1063,6 +1084,7 @@ public final class BluetoothDevice implements Parcelable {
}
/** @hide */
+ @UnsupportedAppUsage
public boolean isBondingInitiatedLocally() {
final IBluetooth service = sService;
if (service == null) {
@@ -1355,6 +1377,7 @@ public final class BluetoothDevice implements Parcelable {
}
/** @hide */
+ @UnsupportedAppUsage
public boolean setPasskey(int passkey) {
//TODO(BT)
/*
@@ -1395,6 +1418,7 @@ public final class BluetoothDevice implements Parcelable {
}
/** @hide */
+ @UnsupportedAppUsage
public boolean cancelPairingUserInput() {
final IBluetooth service = sService;
if (service == null) {
@@ -1410,6 +1434,7 @@ public final class BluetoothDevice implements Parcelable {
}
/** @hide */
+ @UnsupportedAppUsage
public boolean isBluetoothDock() {
// TODO(BT)
/*
@@ -1435,6 +1460,7 @@ public final class BluetoothDevice implements Parcelable {
* #ACCESS_UNKNOWN}, {@link #ACCESS_ALLOWED} or {@link #ACCESS_REJECTED}.
* @hide
*/
+ @UnsupportedAppUsage
public int getPhonebookAccessPermission() {
final IBluetooth service = sService;
if (service == null) {
@@ -1479,6 +1505,7 @@ public final class BluetoothDevice implements Parcelable {
* {@link #ACCESS_ALLOWED} or {@link #ACCESS_REJECTED}.
* @hide
*/
+ @UnsupportedAppUsage
public int getMessageAccessPermission() {
final IBluetooth service = sService;
if (service == null) {
@@ -1501,6 +1528,7 @@ public final class BluetoothDevice implements Parcelable {
* @return Whether the value has been successfully set.
* @hide
*/
+ @UnsupportedAppUsage
public boolean setMessageAccessPermission(int value) {
final IBluetooth service = sService;
if (service == null) {
@@ -1543,6 +1571,7 @@ public final class BluetoothDevice implements Parcelable {
* @return Whether the value has been successfully set.
* @hide
*/
+ @UnsupportedAppUsage
public boolean setSimAccessPermission(int value) {
final IBluetooth service = sService;
if (service == null) {
@@ -1581,6 +1610,7 @@ public final class BluetoothDevice implements Parcelable {
* permissions
* @hide
*/
+ @UnsupportedAppUsage
public BluetoothSocket createRfcommSocket(int channel) throws IOException {
if (!isBluetoothEnabled()) {
Log.e(TAG, "Bluetooth is not enabled");
@@ -1733,6 +1763,7 @@ public final class BluetoothDevice implements Parcelable {
* permissions.
* @hide
*/
+ @UnsupportedAppUsage
public BluetoothSocket createInsecureRfcommSocket(int port) throws IOException {
if (!isBluetoothEnabled()) {
Log.e(TAG, "Bluetooth is not enabled");
@@ -1752,6 +1783,7 @@ public final class BluetoothDevice implements Parcelable {
* permissions.
* @hide
*/
+ @UnsupportedAppUsage
public BluetoothSocket createScoSocket() throws IOException {
if (!isBluetoothEnabled()) {
Log.e(TAG, "Bluetooth is not enabled");
@@ -1769,6 +1801,7 @@ public final class BluetoothDevice implements Parcelable {
* @return the pin code as a UTF-8 byte array, or null if it is an invalid Bluetooth pin.
* @hide
*/
+ @UnsupportedAppUsage
public static byte[] convertPinToBytes(String pin) {
if (pin == null) {
return null;
@@ -1900,6 +1933,7 @@ public final class BluetoothDevice implements Parcelable {
* operations.
* @hide
*/
+ @UnsupportedAppUsage
public BluetoothGatt connectGatt(Context context, boolean autoConnect,
BluetoothGattCallback callback, int transport,
boolean opportunistic, int phy, Handler handler) {
@@ -1929,8 +1963,8 @@ public final class BluetoothDevice implements Parcelable {
/**
* Create a Bluetooth L2CAP Connection-oriented Channel (CoC) {@link BluetoothSocket} that can
* be used to start a secure outgoing connection to the remote device with the same dynamic
- * protocol/service multiplexer (PSM) value.
- * <p>This is designed to be used with {@link BluetoothAdapter#listenUsingL2capCoc(int)} for
+ * protocol/service multiplexer (PSM) value. The supported Bluetooth transport is LE only.
+ * <p>This is designed to be used with {@link BluetoothAdapter#listenUsingL2capChannel()} for
* peer-peer Bluetooth applications.
* <p>Use {@link BluetoothSocket#connect} to initiate the outgoing connection.
* <p>Application using this API is responsible for obtaining PSM value from remote device.
@@ -1941,59 +1975,71 @@ public final class BluetoothDevice implements Parcelable {
* secure socket connection is not possible, use {@link createInsecureLeL2capCocSocket(int,
* int)}.
*
- * @param transport Bluetooth transport to use, must be {@link #TRANSPORT_LE}
* @param psm dynamic PSM value from remote device
* @return a CoC #BluetoothSocket ready for an outgoing connection
* @throws IOException on error, for example Bluetooth not available, or insufficient
* permissions
- * @hide
*/
@RequiresPermission(Manifest.permission.BLUETOOTH)
- public BluetoothSocket createL2capCocSocket(int transport, int psm) throws IOException {
+ public BluetoothSocket createL2capChannel(int psm) throws IOException {
if (!isBluetoothEnabled()) {
- Log.e(TAG, "createL2capCocSocket: Bluetooth is not enabled");
+ Log.e(TAG, "createL2capChannel: Bluetooth is not enabled");
throw new IOException();
}
- if (transport != BluetoothDevice.TRANSPORT_LE) {
- throw new IllegalArgumentException("Unsupported transport: " + transport);
- }
- if (DBG) Log.d(TAG, "createL2capCocSocket: transport=" + transport + ", psm=" + psm);
+ if (DBG) Log.d(TAG, "createL2capChannel: psm=" + psm);
return new BluetoothSocket(BluetoothSocket.TYPE_L2CAP_LE, -1, true, true, this, psm,
null);
}
/**
+ * TODO: Remove this hidden method once all the SL4A and other tests are updated to use the new
+ * API name, createL2capChannel.
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
+ public BluetoothSocket createL2capCocSocket(int transport, int psm) throws IOException {
+ Log.e(TAG, "createL2capCocSocket: PLEASE USE THE OFFICIAL API, createL2capChannel");
+ return createL2capChannel(psm);
+ }
+
+ /**
* Create a Bluetooth L2CAP Connection-oriented Channel (CoC) {@link BluetoothSocket} that can
* be used to start a secure outgoing connection to the remote device with the same dynamic
- * protocol/service multiplexer (PSM) value.
- * <p>This is designed to be used with {@link BluetoothAdapter#listenUsingInsecureL2capCoc(int)}
- * for peer-peer Bluetooth applications.
+ * protocol/service multiplexer (PSM) value. The supported Bluetooth transport is LE only.
+ * <p>This is designed to be used with {@link
+ * BluetoothAdapter#listenUsingInsecureL2capChannel()} for peer-peer Bluetooth applications.
* <p>Use {@link BluetoothSocket#connect} to initiate the outgoing connection.
* <p>Application using this API is responsible for obtaining PSM value from remote device.
* <p> The communication channel may not have an authenticated link key, i.e. it may be subject
- * to man-in-the-middle attacks. Use {@link #createL2capCocSocket(int, int)} if an encrypted and
+ * to man-in-the-middle attacks. Use {@link #createL2capChannel(int)} if an encrypted and
* authenticated communication channel is possible.
*
- * @param transport Bluetooth transport to use, must be {@link #TRANSPORT_LE}
* @param psm dynamic PSM value from remote device
* @return a CoC #BluetoothSocket ready for an outgoing connection
* @throws IOException on error, for example Bluetooth not available, or insufficient
* permissions
- * @hide
*/
@RequiresPermission(Manifest.permission.BLUETOOTH)
- public BluetoothSocket createInsecureL2capCocSocket(int transport, int psm) throws IOException {
+ public BluetoothSocket createInsecureL2capChannel(int psm) throws IOException {
if (!isBluetoothEnabled()) {
- Log.e(TAG, "createInsecureL2capCocSocket: Bluetooth is not enabled");
+ Log.e(TAG, "createInsecureL2capChannel: Bluetooth is not enabled");
throw new IOException();
}
- if (transport != BluetoothDevice.TRANSPORT_LE) {
- throw new IllegalArgumentException("Unsupported transport: " + transport);
- }
if (DBG) {
- Log.d(TAG, "createInsecureL2capCocSocket: transport=" + transport + ", psm=" + psm);
+ Log.d(TAG, "createInsecureL2capChannel: psm=" + psm);
}
return new BluetoothSocket(BluetoothSocket.TYPE_L2CAP_LE, -1, false, false, this, psm,
null);
}
+
+ /**
+ * TODO: Remove this hidden method once all the SL4A and other tests are updated to use the new
+ * API name, createInsecureL2capChannel.
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
+ public BluetoothSocket createInsecureL2capCocSocket(int transport, int psm) throws IOException {
+ Log.e(TAG, "createL2capCocSocket: PLEASE USE THE OFFICIAL API, createInsecureL2capChannel");
+ return createInsecureL2capChannel(psm);
+ }
}
diff --git a/framework/java/android/bluetooth/BluetoothGatt.java b/framework/java/android/bluetooth/BluetoothGatt.java
index 77b65f0d1b..43f68f7e3d 100644
--- a/framework/java/android/bluetooth/BluetoothGatt.java
+++ b/framework/java/android/bluetooth/BluetoothGatt.java
@@ -16,6 +16,7 @@
package android.bluetooth;
+import android.annotation.UnsupportedAppUsage;
import android.os.Handler;
import android.os.ParcelUuid;
import android.os.RemoteException;
@@ -41,16 +42,23 @@ public final class BluetoothGatt implements BluetoothProfile {
private static final boolean DBG = true;
private static final boolean VDBG = false;
+ @UnsupportedAppUsage
private IBluetoothGatt mService;
+ @UnsupportedAppUsage
private volatile BluetoothGattCallback mCallback;
private Handler mHandler;
+ @UnsupportedAppUsage
private int mClientIf;
private BluetoothDevice mDevice;
+ @UnsupportedAppUsage
private boolean mAutoConnect;
+ @UnsupportedAppUsage
private int mAuthRetryState;
private int mConnState;
private final Object mStateLock = new Object();
+ @UnsupportedAppUsage
private Boolean mDeviceBusy = false;
+ @UnsupportedAppUsage
private int mTransport;
private int mPhy;
private boolean mOpportunistic;
@@ -810,6 +818,7 @@ public final class BluetoothGatt implements BluetoothProfile {
/**
* Unregister the current application and callbacks.
*/
+ @UnsupportedAppUsage
private void unregisterApp() {
if (DBG) Log.d(TAG, "unregisterApp() - mClientIf=" + mClientIf);
if (mService == null || mClientIf == 0) return;
@@ -845,6 +854,7 @@ public final class BluetoothGatt implements BluetoothProfile {
* automatically connect as soon as the remote device becomes available (true).
* @return true, if the connection attempt was initiated successfully
*/
+ @UnsupportedAppUsage
/*package*/ boolean connect(Boolean autoConnect, BluetoothGattCallback callback,
Handler handler) {
if (DBG) {
@@ -1407,6 +1417,7 @@ public final class BluetoothGatt implements BluetoothProfile {
*
* @hide
*/
+ @UnsupportedAppUsage
public boolean refresh() {
if (DBG) Log.d(TAG, "refresh() - device: " + mDevice.getAddress());
if (mService == null || mClientIf == 0) return false;
diff --git a/framework/java/android/bluetooth/BluetoothGattCharacteristic.java b/framework/java/android/bluetooth/BluetoothGattCharacteristic.java
index 243ad359a4..6d46b3a418 100644
--- a/framework/java/android/bluetooth/BluetoothGattCharacteristic.java
+++ b/framework/java/android/bluetooth/BluetoothGattCharacteristic.java
@@ -15,6 +15,7 @@
*/
package android.bluetooth;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.ParcelUuid;
import android.os.Parcelable;
@@ -182,6 +183,7 @@ public class BluetoothGattCharacteristic implements Parcelable {
*
* @hide
*/
+ @UnsupportedAppUsage
protected int mInstance;
/**
@@ -218,6 +220,7 @@ public class BluetoothGattCharacteristic implements Parcelable {
*
* @hide
*/
+ @UnsupportedAppUsage
protected BluetoothGattService mService;
/**
@@ -381,6 +384,7 @@ public class BluetoothGattCharacteristic implements Parcelable {
*
* @hide
*/
+ @UnsupportedAppUsage
/*package*/ void setService(BluetoothGattService service) {
mService = service;
}
@@ -464,6 +468,7 @@ public class BluetoothGattCharacteristic implements Parcelable {
*
* @hide
*/
+ @UnsupportedAppUsage
public void setKeySize(int keySize) {
mKeySize = keySize;
}
diff --git a/framework/java/android/bluetooth/BluetoothGattDescriptor.java b/framework/java/android/bluetooth/BluetoothGattDescriptor.java
index 217a5abf1f..3ffbb9e0c0 100644
--- a/framework/java/android/bluetooth/BluetoothGattDescriptor.java
+++ b/framework/java/android/bluetooth/BluetoothGattDescriptor.java
@@ -16,6 +16,7 @@
package android.bluetooth;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.ParcelUuid;
import android.os.Parcelable;
@@ -100,6 +101,7 @@ public class BluetoothGattDescriptor implements Parcelable {
*
* @hide
*/
+ @UnsupportedAppUsage
protected int mInstance;
/**
@@ -114,6 +116,7 @@ public class BluetoothGattDescriptor implements Parcelable {
*
* @hide
*/
+ @UnsupportedAppUsage
protected BluetoothGattCharacteristic mCharacteristic;
/**
@@ -205,6 +208,7 @@ public class BluetoothGattDescriptor implements Parcelable {
*
* @hide
*/
+ @UnsupportedAppUsage
/*package*/ void setCharacteristic(BluetoothGattCharacteristic characteristic) {
mCharacteristic = characteristic;
}
diff --git a/framework/java/android/bluetooth/BluetoothGattService.java b/framework/java/android/bluetooth/BluetoothGattService.java
index ce1dc1ce63..8e740ee387 100644
--- a/framework/java/android/bluetooth/BluetoothGattService.java
+++ b/framework/java/android/bluetooth/BluetoothGattService.java
@@ -15,6 +15,7 @@
*/
package android.bluetooth;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.ParcelUuid;
import android.os.Parcelable;
@@ -48,6 +49,7 @@ public class BluetoothGattService implements Parcelable {
*
* @hide
*/
+ @UnsupportedAppUsage
protected BluetoothDevice mDevice;
/**
@@ -265,6 +267,7 @@ public class BluetoothGattService implements Parcelable {
*
* @hide
*/
+ @UnsupportedAppUsage
public void setInstanceId(int instanceId) {
mInstanceId = instanceId;
}
@@ -382,6 +385,7 @@ public class BluetoothGattService implements Parcelable {
*
* @hide
*/
+ @UnsupportedAppUsage
public void setAdvertisePreferred(boolean advertisePreferred) {
mAdvertisePreferred = advertisePreferred;
}
diff --git a/framework/java/android/bluetooth/BluetoothHeadset.java b/framework/java/android/bluetooth/BluetoothHeadset.java
index 0c91a2054b..636b1b9b13 100644
--- a/framework/java/android/bluetooth/BluetoothHeadset.java
+++ b/framework/java/android/bluetooth/BluetoothHeadset.java
@@ -22,6 +22,7 @@ import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
+import android.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Context;
import android.os.Binder;
@@ -110,6 +111,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
* @hide
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ @UnsupportedAppUsage
public static final String ACTION_ACTIVE_DEVICE_CHANGED =
"android.bluetooth.headset.profile.action.ACTIVE_DEVICE_CHANGED";
@@ -401,6 +403,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
* results once close() has been called. Multiple invocations of close()
* are ok.
*/
+ @UnsupportedAppUsage
/*package*/ void close() {
if (VDBG) log("close()");
@@ -602,6 +605,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
* @return priority of the device
* @hide
*/
+ @UnsupportedAppUsage
public int getPriority(BluetoothDevice device) {
if (VDBG) log("getPriority(" + device + ")");
final IBluetoothHeadset service = mService;
@@ -719,6 +723,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
*
* @hide
*/
+ @UnsupportedAppUsage
public int getAudioState(BluetoothDevice device) {
if (VDBG) log("getAudioState");
final IBluetoothHeadset service = mService;
@@ -846,6 +851,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
* @return false if there was some error such as there is no active headset
* @hide
*/
+ @UnsupportedAppUsage
public boolean connectAudio() {
final IBluetoothHeadset service = mService;
if (service != null && isEnabled()) {
@@ -872,6 +878,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
* @return false if audio is not connected, or on error, true otherwise
* @hide
*/
+ @UnsupportedAppUsage
public boolean disconnectAudio() {
final IBluetoothHeadset service = mService;
if (service != null && isEnabled()) {
@@ -909,6 +916,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
* @hide
*/
@RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+ @UnsupportedAppUsage
public boolean startScoUsingVirtualVoiceCall() {
if (DBG) log("startScoUsingVirtualVoiceCall()");
final IBluetoothHeadset service = mService;
@@ -938,6 +946,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
* @hide
*/
@RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+ @UnsupportedAppUsage
public boolean stopScoUsingVirtualVoiceCall() {
if (DBG) log("stopScoUsingVirtualVoiceCall()");
final IBluetoothHeadset service = mService;
@@ -962,6 +971,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
*
* @hide
*/
+ @UnsupportedAppUsage
public void phoneStateChanged(int numActive, int numHeld, int callState, String number,
int type) {
final IBluetoothHeadset service = mService;
@@ -1060,6 +1070,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
* @hide
*/
@RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN)
+ @UnsupportedAppUsage
public boolean setActiveDevice(@Nullable BluetoothDevice device) {
if (DBG) {
Log.d(TAG, "setActiveDevice: " + device);
@@ -1089,6 +1100,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
* @hide
*/
@RequiresPermission(android.Manifest.permission.BLUETOOTH)
+ @UnsupportedAppUsage
public BluetoothDevice getActiveDevice() {
if (VDBG) {
Log.d(TAG, "getActiveDevice");
@@ -1163,6 +1175,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
}
};
+ @UnsupportedAppUsage
private boolean isEnabled() {
return mAdapter.getState() == BluetoothAdapter.STATE_ON;
}
diff --git a/framework/java/android/bluetooth/BluetoothHeadsetClient.java b/framework/java/android/bluetooth/BluetoothHeadsetClient.java
index 397b90656f..ec18d42698 100644
--- a/framework/java/android/bluetooth/BluetoothHeadsetClient.java
+++ b/framework/java/android/bluetooth/BluetoothHeadsetClient.java
@@ -16,6 +16,7 @@
package android.bluetooth;
+import android.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -476,6 +477,7 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
* @return <code>true</code> if command has been issued successfully; <code>false</code>
* otherwise; upon completion HFP sends {@link #ACTION_CONNECTION_STATE_CHANGED} intent.
*/
+ @UnsupportedAppUsage
public boolean connect(BluetoothDevice device) {
if (DBG) log("connect(" + device + ")");
final IBluetoothHeadsetClient service = mService;
@@ -498,6 +500,7 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
* @return <code>true</code> if command has been issued successfully; <code>false</code>
* otherwise; upon completion HFP sends {@link #ACTION_CONNECTION_STATE_CHANGED} intent.
*/
+ @UnsupportedAppUsage
public boolean disconnect(BluetoothDevice device) {
if (DBG) log("disconnect(" + device + ")");
final IBluetoothHeadsetClient service = mService;
@@ -720,6 +723,7 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
* @return <code>true</code> if command has been issued successfully; <code>false</code>
* otherwise; upon completion HFP sends {@link #ACTION_CALL_CHANGED} intent.
*/
+ @UnsupportedAppUsage
public boolean acceptCall(BluetoothDevice device, int flag) {
if (DBG) log("acceptCall()");
final IBluetoothHeadsetClient service = mService;
@@ -766,6 +770,7 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
* #EXTRA_AG_FEATURE_REJECT_CALL}. This method invocation will fail silently when feature is not
* supported.</p>
*/
+ @UnsupportedAppUsage
public boolean rejectCall(BluetoothDevice device) {
if (DBG) log("rejectCall()");
final IBluetoothHeadsetClient service = mService;
@@ -943,6 +948,7 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
*
* Note: This is an internal function and shouldn't be exposed
*/
+ @UnsupportedAppUsage
public int getAudioState(BluetoothDevice device) {
if (VDBG) log("getAudioState");
final IBluetoothHeadsetClient service = mService;
diff --git a/framework/java/android/bluetooth/BluetoothHeadsetClientCall.java b/framework/java/android/bluetooth/BluetoothHeadsetClientCall.java
index d46b2e3746..e02a2f4ae5 100644
--- a/framework/java/android/bluetooth/BluetoothHeadsetClientCall.java
+++ b/framework/java/android/bluetooth/BluetoothHeadsetClientCall.java
@@ -16,6 +16,7 @@
package android.bluetooth;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.SystemClock;
@@ -143,6 +144,7 @@ public final class BluetoothHeadsetClientCall implements Parcelable {
*
* @return call id.
*/
+ @UnsupportedAppUsage
public int getId() {
return mId;
}
@@ -162,6 +164,7 @@ public final class BluetoothHeadsetClientCall implements Parcelable {
*
* @return state of this particular phone call.
*/
+ @UnsupportedAppUsage
public int getState() {
return mState;
}
@@ -171,6 +174,7 @@ public final class BluetoothHeadsetClientCall implements Parcelable {
*
* @return string representing phone number.
*/
+ @UnsupportedAppUsage
public String getNumber() {
return mNumber;
}
@@ -189,6 +193,7 @@ public final class BluetoothHeadsetClientCall implements Parcelable {
*
* @return <code>true</code> if call is a multi party call, <code>false</code> otherwise.
*/
+ @UnsupportedAppUsage
public boolean isMultiParty() {
return mMultiParty;
}
@@ -198,6 +203,7 @@ public final class BluetoothHeadsetClientCall implements Parcelable {
*
* @return <code>true</code> if its outgoing call, <code>false</code> otherwise.
*/
+ @UnsupportedAppUsage
public boolean isOutgoing() {
return mOutgoing;
}
diff --git a/framework/java/android/bluetooth/BluetoothHearingAid.java b/framework/java/android/bluetooth/BluetoothHearingAid.java
index 159e165d59..606f00a823 100644
--- a/framework/java/android/bluetooth/BluetoothHearingAid.java
+++ b/framework/java/android/bluetooth/BluetoothHearingAid.java
@@ -21,6 +21,7 @@ import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -108,6 +109,7 @@ public final class BluetoothHearingAid implements BluetoothProfile {
* receive.
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ @UnsupportedAppUsage
public static final String ACTION_ACTIVE_DEVICE_CHANGED =
"android.bluetooth.hearingaid.profile.action.ACTIVE_DEVICE_CHANGED";
@@ -401,6 +403,7 @@ public final class BluetoothHearingAid implements BluetoothProfile {
* @return false on immediate error, true otherwise
* @hide
*/
+ @UnsupportedAppUsage
public boolean setActiveDevice(@Nullable BluetoothDevice device) {
if (DBG) log("setActiveDevice(" + device + ")");
try {
@@ -432,6 +435,7 @@ public final class BluetoothHearingAid implements BluetoothProfile {
* @hide
*/
@RequiresPermission(Manifest.permission.BLUETOOTH)
+ @UnsupportedAppUsage
public List<BluetoothDevice> getActiveDevices() {
if (VDBG) log("getActiveDevices()");
try {
diff --git a/framework/java/android/bluetooth/BluetoothMap.java b/framework/java/android/bluetooth/BluetoothMap.java
index 0fa1d5d629..98c23c600f 100644
--- a/framework/java/android/bluetooth/BluetoothMap.java
+++ b/framework/java/android/bluetooth/BluetoothMap.java
@@ -16,6 +16,7 @@
package android.bluetooth;
+import android.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -233,6 +234,7 @@ public final class BluetoothMap implements BluetoothProfile {
* @param device Remote Bluetooth Device
* @return false on error, true otherwise
*/
+ @UnsupportedAppUsage
public boolean disconnect(BluetoothDevice device) {
if (DBG) log("disconnect(" + device + ")");
final IBluetoothMap service = mService;
diff --git a/framework/java/android/bluetooth/BluetoothMapClient.java b/framework/java/android/bluetooth/BluetoothMapClient.java
index 4f21d936e5..559a59b68b 100644
--- a/framework/java/android/bluetooth/BluetoothMapClient.java
+++ b/framework/java/android/bluetooth/BluetoothMapClient.java
@@ -16,6 +16,7 @@
package android.bluetooth;
+import android.annotation.UnsupportedAppUsage;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
@@ -72,6 +73,8 @@ public final class BluetoothMapClient implements BluetoothProfile {
/** Connection canceled before completion. */
public static final int RESULT_CANCELED = 2;
+ private static final int UPLOADING_FEATURE_BITMASK = 0x08;
+
private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
new IBluetoothStateChangeCallback.Stub() {
public void onBluetoothStateChange(boolean up) {
@@ -358,6 +361,7 @@ public final class BluetoothMapClient implements BluetoothProfile {
* @param deliveredIntent intent issued when message is delivered
* @return true if the message is enqueued, false on error
*/
+ @UnsupportedAppUsage
public boolean sendMessage(BluetoothDevice device, Uri[] contacts, String message,
PendingIntent sentIntent, PendingIntent deliveredIntent) {
if (DBG) Log.d(TAG, "sendMessage(" + device + ", " + contacts + ", " + message);
@@ -393,6 +397,23 @@ public final class BluetoothMapClient implements BluetoothProfile {
return false;
}
+ /**
+ * Returns the "Uploading" feature bit value from the SDP record's
+ * MapSupportedFeatures field (see Bluetooth MAP 1.4 spec, page 114).
+ * @param device The Bluetooth device to get this value for.
+ * @return Returns true if the Uploading bit value in SDP record's
+ * MapSupportedFeatures field is set. False is returned otherwise.
+ */
+ public boolean isUploadingSupported(BluetoothDevice device) {
+ try {
+ return (mService != null && isEnabled() && isValidDevice(device))
+ && ((mService.getSupportedFeatures(device) & UPLOADING_FEATURE_BITMASK) > 0);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getMessage());
+ }
+ return false;
+ }
+
private final ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
if (DBG) Log.d(TAG, "Proxy object connected");
diff --git a/framework/java/android/bluetooth/BluetoothPan.java b/framework/java/android/bluetooth/BluetoothPan.java
index 9f401eb3ce..58be732960 100644
--- a/framework/java/android/bluetooth/BluetoothPan.java
+++ b/framework/java/android/bluetooth/BluetoothPan.java
@@ -18,6 +18,7 @@ package android.bluetooth;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -129,6 +130,7 @@ public final class BluetoothPan implements BluetoothProfile {
* Create a BluetoothPan proxy object for interacting with the local
* Bluetooth Service which handles the Pan profile
*/
+ @UnsupportedAppUsage
/*package*/ BluetoothPan(Context context, ServiceListener l) {
mContext = context;
mServiceListener = l;
@@ -142,6 +144,7 @@ public final class BluetoothPan implements BluetoothProfile {
doBind();
}
+ @UnsupportedAppUsage
boolean doBind() {
Intent intent = new Intent(IBluetoothPan.class.getName());
ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
@@ -154,6 +157,7 @@ public final class BluetoothPan implements BluetoothProfile {
return true;
}
+ @UnsupportedAppUsage
/*package*/ void close() {
if (VDBG) log("close()");
@@ -236,6 +240,7 @@ public final class BluetoothPan implements BluetoothProfile {
* @return false on immediate error, true otherwise
* @hide
*/
+ @UnsupportedAppUsage
public boolean connect(BluetoothDevice device) {
if (DBG) log("connect(" + device + ")");
final IBluetoothPan service = mPanService;
@@ -276,6 +281,7 @@ public final class BluetoothPan implements BluetoothProfile {
* @return false on immediate error, true otherwise
* @hide
*/
+ @UnsupportedAppUsage
public boolean disconnect(BluetoothDevice device) {
if (DBG) log("disconnect(" + device + ")");
final IBluetoothPan service = mPanService;
@@ -348,6 +354,7 @@ public final class BluetoothPan implements BluetoothProfile {
return BluetoothProfile.STATE_DISCONNECTED;
}
+ @UnsupportedAppUsage
public void setBluetoothTethering(boolean value) {
if (DBG) log("setBluetoothTethering(" + value + ")");
final IBluetoothPan service = mPanService;
@@ -360,6 +367,7 @@ public final class BluetoothPan implements BluetoothProfile {
}
}
+ @UnsupportedAppUsage
public boolean isTetheringOn() {
if (VDBG) log("isTetheringOn()");
final IBluetoothPan service = mPanService;
@@ -392,14 +400,17 @@ public final class BluetoothPan implements BluetoothProfile {
}
};
+ @UnsupportedAppUsage
private boolean isEnabled() {
return mAdapter.getState() == BluetoothAdapter.STATE_ON;
}
+ @UnsupportedAppUsage
private static boolean isValidDevice(BluetoothDevice device) {
return device != null && BluetoothAdapter.checkBluetoothAddress(device.getAddress());
}
+ @UnsupportedAppUsage
private static void log(String msg) {
Log.d(TAG, msg);
}
diff --git a/framework/java/android/bluetooth/BluetoothPbap.java b/framework/java/android/bluetooth/BluetoothPbap.java
index c60e9e075c..ae264e19bb 100644
--- a/framework/java/android/bluetooth/BluetoothPbap.java
+++ b/framework/java/android/bluetooth/BluetoothPbap.java
@@ -17,6 +17,7 @@
package android.bluetooth;
import android.annotation.SdkConstant;
+import android.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -281,6 +282,7 @@ public class BluetoothPbap implements BluetoothProfile {
*/
// TODO: This is currently being used by SettingsLib and will be used in the future.
// TODO: Must specify target device. Implement this in the service.
+ @UnsupportedAppUsage
public boolean disconnect(BluetoothDevice device) {
log("disconnect()");
final IBluetoothPbap service = mService;
diff --git a/framework/java/android/bluetooth/BluetoothProfile.java b/framework/java/android/bluetooth/BluetoothProfile.java
index 6aeb94da11..9777b5cc6c 100644
--- a/framework/java/android/bluetooth/BluetoothProfile.java
+++ b/framework/java/android/bluetooth/BluetoothProfile.java
@@ -20,6 +20,7 @@ package android.bluetooth;
import android.Manifest;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
+import android.annotation.UnsupportedAppUsage;
import java.util.List;
@@ -85,6 +86,7 @@ public interface BluetoothProfile {
*
* @hide
*/
+ @UnsupportedAppUsage
int PAN = 5;
/**
@@ -122,6 +124,7 @@ public interface BluetoothProfile {
*
* @hide
*/
+ @UnsupportedAppUsage
int A2DP_SINK = 11;
/**
@@ -129,6 +132,7 @@ public interface BluetoothProfile {
*
* @hide
*/
+ @UnsupportedAppUsage
int AVRCP_CONTROLLER = 12;
/**
@@ -192,6 +196,7 @@ public interface BluetoothProfile {
*
* @hide
**/
+ @UnsupportedAppUsage
int PRIORITY_AUTO_CONNECT = 1000;
/**
@@ -217,6 +222,7 @@ public interface BluetoothProfile {
*
* @hide
*/
+ @UnsupportedAppUsage
int PRIORITY_UNDEFINED = -1;
/**
diff --git a/framework/java/android/bluetooth/BluetoothSap.java b/framework/java/android/bluetooth/BluetoothSap.java
index c51e39a741..1b732062f6 100644
--- a/framework/java/android/bluetooth/BluetoothSap.java
+++ b/framework/java/android/bluetooth/BluetoothSap.java
@@ -16,6 +16,7 @@
package android.bluetooth;
+import android.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -280,6 +281,7 @@ public final class BluetoothSap implements BluetoothProfile {
* @return false on error, true otherwise
* @hide
*/
+ @UnsupportedAppUsage
public boolean disconnect(BluetoothDevice device) {
if (DBG) log("disconnect(" + device + ")");
final IBluetoothSap service = mService;
diff --git a/framework/java/android/bluetooth/BluetoothServerSocket.java b/framework/java/android/bluetooth/BluetoothServerSocket.java
index ca29ef37a2..758c68db1c 100644
--- a/framework/java/android/bluetooth/BluetoothServerSocket.java
+++ b/framework/java/android/bluetooth/BluetoothServerSocket.java
@@ -16,6 +16,7 @@
package android.bluetooth;
+import android.annotation.UnsupportedAppUsage;
import android.os.Handler;
import android.os.ParcelUuid;
import android.util.Log;
@@ -69,6 +70,7 @@ public final class BluetoothServerSocket implements Closeable {
private static final String TAG = "BluetoothServerSocket";
private static final boolean DBG = false;
+ @UnsupportedAppUsage
/*package*/ final BluetoothSocket mSocket;
private Handler mHandler;
private int mMessage;
@@ -201,12 +203,11 @@ public final class BluetoothServerSocket implements Closeable {
/**
* Returns the assigned dynamic protocol/service multiplexer (PSM) value for the listening L2CAP
* Connection-oriented Channel (CoC) server socket. This server socket must be returned by the
- * {@link BluetoothAdapter.listenUsingL2capCoc(int)} or {@link
- * BluetoothAdapter.listenUsingInsecureL2capCoc(int)}. The returned value is undefined if this
+ * {@link BluetoothAdapter.listenUsingL2capChannel()} or {@link
+ * BluetoothAdapter.listenUsingInsecureL2capChannel()}. The returned value is undefined if this
* method is called on non-L2CAP server sockets.
*
* @return the assigned PSM or LE_PSM value depending on transport
- * @hide
*/
public int getPsm() {
return mChannel;
diff --git a/framework/java/android/bluetooth/BluetoothSocket.java b/framework/java/android/bluetooth/BluetoothSocket.java
index 09a5b593e5..3a1e2f58c9 100644
--- a/framework/java/android/bluetooth/BluetoothSocket.java
+++ b/framework/java/android/bluetooth/BluetoothSocket.java
@@ -16,6 +16,7 @@
package android.bluetooth;
+import android.annotation.UnsupportedAppUsage;
import android.net.LocalSocket;
import android.os.ParcelFileDescriptor;
import android.os.ParcelUuid;
@@ -110,6 +111,7 @@ public final class BluetoothSocket implements Closeable {
public static final int TYPE_L2CAP_LE = 4;
/*package*/ static final int EBADFD = 77;
+ @UnsupportedAppUsage
/*package*/ static final int EADDRINUSE = 98;
/*package*/ static final int SEC_FLAG_ENCRYPT = 1;
@@ -129,10 +131,13 @@ public final class BluetoothSocket implements Closeable {
private boolean mExcludeSdp = false; /* when true no SPP SDP record will be created */
private boolean mAuthMitm = false; /* when true Man-in-the-middle protection will be enabled*/
private boolean mMin16DigitPin = false; /* Minimum 16 digit pin for sec mode 2 connections */
+ @UnsupportedAppUsage
private ParcelFileDescriptor mPfd;
+ @UnsupportedAppUsage
private LocalSocket mSocket;
private InputStream mSocketIS;
private OutputStream mSocketOS;
+ @UnsupportedAppUsage
private int mPort; /* RFCOMM channel or L2CAP psm */
private int mFd;
private String mServiceName;
@@ -517,6 +522,7 @@ public final class BluetoothSocket implements Closeable {
*
* @throws IOException if an i/o error occurs.
*/
+ @UnsupportedAppUsage
/*package*/ void flush() throws IOException {
if (mSocketOS == null) throw new IOException("flush is called on null OutputStream");
if (VDBG) Log.d(TAG, "flush: " + mSocketOS);
@@ -661,6 +667,10 @@ public final class BluetoothSocket implements Closeable {
* @return one of {@link #TYPE_RFCOMM}, {@link #TYPE_SCO} or {@link #TYPE_L2CAP}
*/
public int getConnectionType() {
+ if (mType == TYPE_L2CAP_LE) {
+ // Treat the LE CoC to be the same type as L2CAP.
+ return TYPE_L2CAP;
+ }
return mType;
}
diff --git a/framework/java/android/bluetooth/BluetoothUuid.java b/framework/java/android/bluetooth/BluetoothUuid.java
index 605dbd2199..fdbfec00e6 100644
--- a/framework/java/android/bluetooth/BluetoothUuid.java
+++ b/framework/java/android/bluetooth/BluetoothUuid.java
@@ -16,6 +16,7 @@
package android.bluetooth;
+import android.annotation.UnsupportedAppUsage;
import android.os.ParcelUuid;
import java.nio.ByteBuffer;
@@ -37,16 +38,20 @@ public final class BluetoothUuid {
* The following 128 bit values are calculated as:
* uuid * 2^96 + BASE_UUID
*/
+ @UnsupportedAppUsage
public static final ParcelUuid AudioSink =
ParcelUuid.fromString("0000110B-0000-1000-8000-00805F9B34FB");
public static final ParcelUuid AudioSource =
ParcelUuid.fromString("0000110A-0000-1000-8000-00805F9B34FB");
+ @UnsupportedAppUsage
public static final ParcelUuid AdvAudioDist =
ParcelUuid.fromString("0000110D-0000-1000-8000-00805F9B34FB");
+ @UnsupportedAppUsage
public static final ParcelUuid HSP =
ParcelUuid.fromString("00001108-0000-1000-8000-00805F9B34FB");
public static final ParcelUuid HSP_AG =
ParcelUuid.fromString("00001112-0000-1000-8000-00805F9B34FB");
+ @UnsupportedAppUsage
public static final ParcelUuid Handsfree =
ParcelUuid.fromString("0000111E-0000-1000-8000-00805F9B34FB");
public static final ParcelUuid Handsfree_AG =
@@ -55,20 +60,24 @@ public final class BluetoothUuid {
ParcelUuid.fromString("0000110E-0000-1000-8000-00805F9B34FB");
public static final ParcelUuid AvrcpTarget =
ParcelUuid.fromString("0000110C-0000-1000-8000-00805F9B34FB");
+ @UnsupportedAppUsage
public static final ParcelUuid ObexObjectPush =
ParcelUuid.fromString("00001105-0000-1000-8000-00805f9b34fb");
public static final ParcelUuid Hid =
ParcelUuid.fromString("00001124-0000-1000-8000-00805f9b34fb");
+ @UnsupportedAppUsage
public static final ParcelUuid Hogp =
ParcelUuid.fromString("00001812-0000-1000-8000-00805f9b34fb");
public static final ParcelUuid PANU =
ParcelUuid.fromString("00001115-0000-1000-8000-00805F9B34FB");
+ @UnsupportedAppUsage
public static final ParcelUuid NAP =
ParcelUuid.fromString("00001116-0000-1000-8000-00805F9B34FB");
public static final ParcelUuid BNEP =
ParcelUuid.fromString("0000000f-0000-1000-8000-00805F9B34FB");
public static final ParcelUuid PBAP_PCE =
ParcelUuid.fromString("0000112e-0000-1000-8000-00805F9B34FB");
+ @UnsupportedAppUsage
public static final ParcelUuid PBAP_PSE =
ParcelUuid.fromString("0000112f-0000-1000-8000-00805F9B34FB");
public static final ParcelUuid MAP =
@@ -92,10 +101,12 @@ public final class BluetoothUuid {
/** Length of bytes for 128 bit UUID */
public static final int UUID_BYTES_128_BIT = 16;
+ @UnsupportedAppUsage
public static final ParcelUuid[] RESERVED_UUIDS = {
AudioSink, AudioSource, AdvAudioDist, HSP, Handsfree, AvrcpController, AvrcpTarget,
ObexObjectPush, PANU, NAP, MAP, MNS, MAS, SAP};
+ @UnsupportedAppUsage
public static boolean isAudioSource(ParcelUuid uuid) {
return uuid.equals(AudioSource);
}
@@ -104,6 +115,7 @@ public final class BluetoothUuid {
return uuid.equals(AudioSink);
}
+ @UnsupportedAppUsage
public static boolean isAdvAudioDist(ParcelUuid uuid) {
return uuid.equals(AdvAudioDist);
}
@@ -120,6 +132,7 @@ public final class BluetoothUuid {
return uuid.equals(AvrcpController);
}
+ @UnsupportedAppUsage
public static boolean isAvrcpTarget(ParcelUuid uuid) {
return uuid.equals(AvrcpTarget);
}
@@ -162,6 +175,7 @@ public final class BluetoothUuid {
* @param uuidArray - Array of ParcelUuids
* @param uuid
*/
+ @UnsupportedAppUsage
public static boolean isUuidPresent(ParcelUuid[] uuidArray, ParcelUuid uuid) {
if ((uuidArray == null || uuidArray.length == 0) && uuid == null) {
return true;
@@ -183,6 +197,7 @@ public final class BluetoothUuid {
* @param uuidA - List of ParcelUuids
* @param uuidB - List of ParcelUuids
*/
+ @UnsupportedAppUsage
public static boolean containsAnyUuid(ParcelUuid[] uuidA, ParcelUuid[] uuidB) {
if (uuidA == null && uuidB == null) return true;
@@ -330,6 +345,7 @@ public final class BluetoothUuid {
* @param parcelUuid
* @return true if the parcelUuid can be converted to 16 bit uuid, false otherwise.
*/
+ @UnsupportedAppUsage
public static boolean is16BitUuid(ParcelUuid parcelUuid) {
UUID uuid = parcelUuid.getUuid();
if (uuid.getLeastSignificantBits() != BASE_UUID.getUuid().getLeastSignificantBits()) {
@@ -345,6 +361,7 @@ public final class BluetoothUuid {
* @param parcelUuid
* @return true if the parcelUuid can be converted to 32 bit uuid, false otherwise.
*/
+ @UnsupportedAppUsage
public static boolean is32BitUuid(ParcelUuid parcelUuid) {
UUID uuid = parcelUuid.getUuid();
if (uuid.getLeastSignificantBits() != BASE_UUID.getUuid().getLeastSignificantBits()) {
diff --git a/framework/java/android/bluetooth/le/BluetoothLeAdvertiser.java b/framework/java/android/bluetooth/le/BluetoothLeAdvertiser.java
index 0fb4ba1a87..13c5ff6909 100644
--- a/framework/java/android/bluetooth/le/BluetoothLeAdvertiser.java
+++ b/framework/java/android/bluetooth/le/BluetoothLeAdvertiser.java
@@ -411,7 +411,14 @@ public final class BluetoothLeAdvertiser {
try {
gatt = mBluetoothManager.getBluetoothGatt();
} catch (RemoteException e) {
- Log.e(TAG, "Failed to get Bluetooth gatt - ", e);
+ Log.e(TAG, "Failed to get Bluetooth GATT - ", e);
+ postStartSetFailure(handler, callback,
+ AdvertiseCallback.ADVERTISE_FAILED_INTERNAL_ERROR);
+ return;
+ }
+
+ if (gatt == null) {
+ Log.e(TAG, "Bluetooth GATT is null");
postStartSetFailure(handler, callback,
AdvertiseCallback.ADVERTISE_FAILED_INTERNAL_ERROR);
return;
diff --git a/framework/java/android/bluetooth/le/ScanFilter.java b/framework/java/android/bluetooth/le/ScanFilter.java
index c3fae7d470..c5d435b761 100644
--- a/framework/java/android/bluetooth/le/ScanFilter.java
+++ b/framework/java/android/bluetooth/le/ScanFilter.java
@@ -58,6 +58,11 @@ public final class ScanFilter implements Parcelable {
private final ParcelUuid mServiceUuidMask;
@Nullable
+ private final ParcelUuid mServiceSolicitationUuid;
+ @Nullable
+ private final ParcelUuid mServiceSolicitationUuidMask;
+
+ @Nullable
private final ParcelUuid mServiceDataUuid;
@Nullable
private final byte[] mServiceData;
@@ -75,12 +80,15 @@ public final class ScanFilter implements Parcelable {
private ScanFilter(String name, String deviceAddress, ParcelUuid uuid,
- ParcelUuid uuidMask, ParcelUuid serviceDataUuid,
+ ParcelUuid uuidMask, ParcelUuid solicitationUuid,
+ ParcelUuid solicitationUuidMask, ParcelUuid serviceDataUuid,
byte[] serviceData, byte[] serviceDataMask,
int manufacturerId, byte[] manufacturerData, byte[] manufacturerDataMask) {
mDeviceName = name;
mServiceUuid = uuid;
mServiceUuidMask = uuidMask;
+ mServiceSolicitationUuid = solicitationUuid;
+ mServiceSolicitationUuidMask = solicitationUuidMask;
mDeviceAddress = deviceAddress;
mServiceDataUuid = serviceDataUuid;
mServiceData = serviceData;
@@ -113,6 +121,14 @@ public final class ScanFilter implements Parcelable {
dest.writeParcelable(mServiceUuidMask, flags);
}
}
+ dest.writeInt(mServiceSolicitationUuid == null ? 0 : 1);
+ if (mServiceSolicitationUuid != null) {
+ dest.writeParcelable(mServiceSolicitationUuid, flags);
+ dest.writeInt(mServiceSolicitationUuidMask == null ? 0 : 1);
+ if (mServiceSolicitationUuidMask != null) {
+ dest.writeParcelable(mServiceSolicitationUuidMask, flags);
+ }
+ }
dest.writeInt(mServiceDataUuid == null ? 0 : 1);
if (mServiceDataUuid != null) {
dest.writeParcelable(mServiceDataUuid, flags);
@@ -172,6 +188,17 @@ public final class ScanFilter implements Parcelable {
}
}
if (in.readInt() == 1) {
+ ParcelUuid solicitationUuid = in.readParcelable(
+ ParcelUuid.class.getClassLoader());
+ builder.setServiceSolicitationUuid(solicitationUuid);
+ if (in.readInt() == 1) {
+ ParcelUuid solicitationUuidMask = in.readParcelable(
+ ParcelUuid.class.getClassLoader());
+ builder.setServiceSolicitationUuid(solicitationUuid,
+ solicitationUuidMask);
+ }
+ }
+ if (in.readInt() == 1) {
ParcelUuid servcieDataUuid =
in.readParcelable(ParcelUuid.class.getClassLoader());
if (in.readInt() == 1) {
@@ -231,6 +258,22 @@ public final class ScanFilter implements Parcelable {
return mServiceUuidMask;
}
+ /**
+ * Returns the filter set on the service Solicitation uuid.
+ */
+ @Nullable
+ public ParcelUuid getServiceSolicitationUuid() {
+ return mServiceSolicitationUuid;
+ }
+
+ /**
+ * Returns the filter set on the service Solicitation uuid mask.
+ */
+ @Nullable
+ public ParcelUuid getServiceSolicitationUuidMask() {
+ return mServiceSolicitationUuidMask;
+ }
+
@Nullable
public String getDeviceAddress() {
return mDeviceAddress;
@@ -288,7 +331,7 @@ public final class ScanFilter implements Parcelable {
// Scan record is null but there exist filters on it.
if (scanRecord == null
&& (mDeviceName != null || mServiceUuid != null || mManufacturerData != null
- || mServiceData != null)) {
+ || mServiceData != null || mServiceSolicitationUuid != null)) {
return false;
}
@@ -303,6 +346,13 @@ public final class ScanFilter implements Parcelable {
return false;
}
+ // solicitation UUID match.
+ if (mServiceSolicitationUuid != null && !matchesServiceSolicitationUuids(
+ mServiceSolicitationUuid, mServiceSolicitationUuidMask,
+ scanRecord.getServiceSolicitationUuids())) {
+ return false;
+ }
+
// Service data match
if (mServiceDataUuid != null) {
if (!matchesPartialData(mServiceData, mServiceDataMask,
@@ -350,6 +400,36 @@ public final class ScanFilter implements Parcelable {
return BitUtils.maskedEquals(data, uuid, mask);
}
+ /**
+ * Check if the solicitation uuid pattern is contained in a list of parcel uuids.
+ *
+ */
+ private static boolean matchesServiceSolicitationUuids(ParcelUuid solicitationUuid,
+ ParcelUuid parcelSolicitationUuidMask, List<ParcelUuid> solicitationUuids) {
+ if (solicitationUuid == null) {
+ return true;
+ }
+ if (solicitationUuids == null) {
+ return false;
+ }
+
+ for (ParcelUuid parcelSolicitationUuid : solicitationUuids) {
+ UUID solicitationUuidMask = parcelSolicitationUuidMask == null
+ ? null : parcelSolicitationUuidMask.getUuid();
+ if (matchesServiceUuid(solicitationUuid.getUuid(), solicitationUuidMask,
+ parcelSolicitationUuid.getUuid())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // Check if the solicitation uuid pattern matches the particular service solicitation uuid.
+ private static boolean matchesServiceSolicitationUuid(UUID solicitationUuid,
+ UUID solicitationUuidMask, UUID data) {
+ return BitUtils.maskedEquals(data, solicitationUuid, solicitationUuidMask);
+ }
+
// Check whether the data pattern matches the parsed data.
private boolean matchesPartialData(byte[] data, byte[] dataMask, byte[] parsedData) {
if (parsedData == null || parsedData.length < data.length) {
@@ -376,6 +456,8 @@ public final class ScanFilter implements Parcelable {
return "BluetoothLeScanFilter [mDeviceName=" + mDeviceName + ", mDeviceAddress="
+ mDeviceAddress
+ ", mUuid=" + mServiceUuid + ", mUuidMask=" + mServiceUuidMask
+ + ", mServiceSolicitationUuid=" + mServiceSolicitationUuid
+ + ", mServiceSolicitationUuidMask=" + mServiceSolicitationUuidMask
+ ", mServiceDataUuid=" + Objects.toString(mServiceDataUuid) + ", mServiceData="
+ Arrays.toString(mServiceData) + ", mServiceDataMask="
+ Arrays.toString(mServiceDataMask) + ", mManufacturerId=" + mManufacturerId
@@ -391,7 +473,8 @@ public final class ScanFilter implements Parcelable {
mServiceDataUuid,
Arrays.hashCode(mServiceData),
Arrays.hashCode(mServiceDataMask),
- mServiceUuid, mServiceUuidMask);
+ mServiceUuid, mServiceUuidMask,
+ mServiceSolicitationUuid, mServiceSolicitationUuidMask);
}
@Override
@@ -412,7 +495,10 @@ public final class ScanFilter implements Parcelable {
&& Objects.deepEquals(mServiceData, other.mServiceData)
&& Objects.deepEquals(mServiceDataMask, other.mServiceDataMask)
&& Objects.equals(mServiceUuid, other.mServiceUuid)
- && Objects.equals(mServiceUuidMask, other.mServiceUuidMask);
+ && Objects.equals(mServiceUuidMask, other.mServiceUuidMask)
+ && Objects.equals(mServiceSolicitationUuid, other.mServiceSolicitationUuid)
+ && Objects.equals(mServiceSolicitationUuidMask,
+ other.mServiceSolicitationUuidMask);
}
/**
@@ -435,6 +521,9 @@ public final class ScanFilter implements Parcelable {
private ParcelUuid mServiceUuid;
private ParcelUuid mUuidMask;
+ private ParcelUuid mServiceSolicitationUuid;
+ private ParcelUuid mServiceSolicitationUuidMask;
+
private ParcelUuid mServiceDataUuid;
private byte[] mServiceData;
private byte[] mServiceDataMask;
@@ -493,6 +582,36 @@ public final class ScanFilter implements Parcelable {
return this;
}
+
+ /**
+ * Set filter on service solicitation uuid.
+ */
+ public Builder setServiceSolicitationUuid(ParcelUuid serviceSolicitationUuid) {
+ mServiceSolicitationUuid = serviceSolicitationUuid;
+ return this;
+ }
+
+
+ /**
+ * Set filter on partial service Solicitation uuid. The {@code SolicitationUuidMask} is the
+ * bit mask for the {@code serviceSolicitationUuid}. Set any bit in the mask to 1 to
+ * indicate a match is needed for the bit in {@code serviceSolicitationUuid}, and 0 to
+ * ignore that bit.
+ *
+ * @throws IllegalArgumentException If {@code serviceSolicitationUuid} is {@code null} but
+ * {@code serviceSolicitationUuidMask} is not {@code null}.
+ */
+ public Builder setServiceSolicitationUuid(ParcelUuid serviceSolicitationUuid,
+ ParcelUuid solicitationUuidMask) {
+ if (mServiceSolicitationUuidMask != null && mServiceSolicitationUuid == null) {
+ throw new IllegalArgumentException(
+ "SolicitationUuid is null while SolicitationUuidMask is not null!");
+ }
+ mServiceSolicitationUuid = serviceSolicitationUuid;
+ mServiceSolicitationUuidMask = solicitationUuidMask;
+ return this;
+ }
+
/**
* Set filtering on service data.
*
@@ -598,7 +717,8 @@ public final class ScanFilter implements Parcelable {
*/
public ScanFilter build() {
return new ScanFilter(mDeviceName, mDeviceAddress,
- mServiceUuid, mUuidMask,
+ mServiceUuid, mUuidMask, mServiceSolicitationUuid,
+ mServiceSolicitationUuidMask,
mServiceDataUuid, mServiceData, mServiceDataMask,
mManufacturerId, mManufacturerData, mManufacturerDataMask);
}
diff --git a/framework/java/android/bluetooth/le/ScanRecord.java b/framework/java/android/bluetooth/le/ScanRecord.java
index f8aaba910b..7988008f03 100644
--- a/framework/java/android/bluetooth/le/ScanRecord.java
+++ b/framework/java/android/bluetooth/le/ScanRecord.java
@@ -17,6 +17,7 @@
package android.bluetooth.le;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.bluetooth.BluetoothUuid;
import android.os.ParcelUuid;
import android.util.ArrayMap;
@@ -50,6 +51,9 @@ public final class ScanRecord {
private static final int DATA_TYPE_SERVICE_DATA_16_BIT = 0x16;
private static final int DATA_TYPE_SERVICE_DATA_32_BIT = 0x20;
private static final int DATA_TYPE_SERVICE_DATA_128_BIT = 0x21;
+ private static final int DATA_TYPE_SERVICE_SOLICITATION_UUIDS_16_BIT = 0x14;
+ private static final int DATA_TYPE_SERVICE_SOLICITATION_UUIDS_32_BIT = 0x1F;
+ private static final int DATA_TYPE_SERVICE_SOLICITATION_UUIDS_128_BIT = 0x15;
private static final int DATA_TYPE_MANUFACTURER_SPECIFIC_DATA = 0xFF;
// Flags of the advertising data.
@@ -57,6 +61,8 @@ public final class ScanRecord {
@Nullable
private final List<ParcelUuid> mServiceUuids;
+ @Nullable
+ private final List<ParcelUuid> mServiceSolicitationUuids;
private final SparseArray<byte[]> mManufacturerSpecificData;
@@ -88,6 +94,15 @@ public final class ScanRecord {
}
/**
+ * Returns a list of service solicitation UUIDs within the advertisement that are used to
+ * identify the Bluetooth GATT services.
+ */
+ @Nullable
+ public List<ParcelUuid> getServiceSolicitationUuids() {
+ return mServiceSolicitationUuids;
+ }
+
+ /**
* Returns a sparse array of manufacturer identifier and its corresponding manufacturer specific
* data.
*/
@@ -117,7 +132,7 @@ public final class ScanRecord {
*/
@Nullable
public byte[] getServiceData(ParcelUuid serviceDataUuid) {
- if (serviceDataUuid == null) {
+ if (serviceDataUuid == null || mServiceData == null) {
return null;
}
return mServiceData.get(serviceDataUuid);
@@ -150,10 +165,12 @@ public final class ScanRecord {
}
private ScanRecord(List<ParcelUuid> serviceUuids,
+ List<ParcelUuid> serviceSolicitationUuids,
SparseArray<byte[]> manufacturerData,
Map<ParcelUuid, byte[]> serviceData,
int advertiseFlags, int txPowerLevel,
String localName, byte[] bytes) {
+ mServiceSolicitationUuids = serviceSolicitationUuids;
mServiceUuids = serviceUuids;
mManufacturerSpecificData = manufacturerData;
mServiceData = serviceData;
@@ -174,6 +191,7 @@ public final class ScanRecord {
* @param scanRecord The scan record of Bluetooth LE advertisement and/or scan response.
* @hide
*/
+ @UnsupportedAppUsage
public static ScanRecord parseFromBytes(byte[] scanRecord) {
if (scanRecord == null) {
return null;
@@ -182,6 +200,7 @@ public final class ScanRecord {
int currentPos = 0;
int advertiseFlag = -1;
List<ParcelUuid> serviceUuids = new ArrayList<ParcelUuid>();
+ List<ParcelUuid> serviceSolicitationUuids = new ArrayList<ParcelUuid>();
String localName = null;
int txPowerLevel = Integer.MIN_VALUE;
@@ -218,6 +237,18 @@ public final class ScanRecord {
parseServiceUuid(scanRecord, currentPos, dataLength,
BluetoothUuid.UUID_BYTES_128_BIT, serviceUuids);
break;
+ case DATA_TYPE_SERVICE_SOLICITATION_UUIDS_16_BIT:
+ parseServiceSolicitationUuid(scanRecord, currentPos, dataLength,
+ BluetoothUuid.UUID_BYTES_16_BIT, serviceSolicitationUuids);
+ break;
+ case DATA_TYPE_SERVICE_SOLICITATION_UUIDS_32_BIT:
+ parseServiceSolicitationUuid(scanRecord, currentPos, dataLength,
+ BluetoothUuid.UUID_BYTES_32_BIT, serviceSolicitationUuids);
+ break;
+ case DATA_TYPE_SERVICE_SOLICITATION_UUIDS_128_BIT:
+ parseServiceSolicitationUuid(scanRecord, currentPos, dataLength,
+ BluetoothUuid.UUID_BYTES_128_BIT, serviceSolicitationUuids);
+ break;
case DATA_TYPE_LOCAL_NAME_SHORT:
case DATA_TYPE_LOCAL_NAME_COMPLETE:
localName = new String(
@@ -263,19 +294,23 @@ public final class ScanRecord {
if (serviceUuids.isEmpty()) {
serviceUuids = null;
}
- return new ScanRecord(serviceUuids, manufacturerData, serviceData,
- advertiseFlag, txPowerLevel, localName, scanRecord);
+ if (serviceSolicitationUuids.isEmpty()) {
+ serviceSolicitationUuids = null;
+ }
+ return new ScanRecord(serviceUuids, serviceSolicitationUuids, manufacturerData,
+ serviceData, advertiseFlag, txPowerLevel, localName, scanRecord);
} catch (Exception e) {
Log.e(TAG, "unable to parse scan record: " + Arrays.toString(scanRecord));
// As the record is invalid, ignore all the parsed results for this packet
// and return an empty record with raw scanRecord bytes in results
- return new ScanRecord(null, null, null, -1, Integer.MIN_VALUE, null, scanRecord);
+ return new ScanRecord(null, null, null, null, -1, Integer.MIN_VALUE, null, scanRecord);
}
}
@Override
public String toString() {
return "ScanRecord [mAdvertiseFlags=" + mAdvertiseFlags + ", mServiceUuids=" + mServiceUuids
+ + ", mServiceSolicitationUuids=" + mServiceSolicitationUuids
+ ", mManufacturerSpecificData=" + BluetoothLeUtils.toString(
mManufacturerSpecificData)
+ ", mServiceData=" + BluetoothLeUtils.toString(mServiceData)
@@ -295,6 +330,20 @@ public final class ScanRecord {
return currentPos;
}
+ /**
+ * Parse service Solicitation UUIDs.
+ */
+ private static int parseServiceSolicitationUuid(byte[] scanRecord, int currentPos,
+ int dataLength, int uuidLength, List<ParcelUuid> serviceSolicitationUuids) {
+ while (dataLength > 0) {
+ byte[] uuidBytes = extractBytes(scanRecord, currentPos, uuidLength);
+ serviceSolicitationUuids.add(BluetoothUuid.parseUuidFrom(uuidBytes));
+ dataLength -= uuidLength;
+ currentPos += uuidLength;
+ }
+ return currentPos;
+ }
+
// Helper method to extract bytes from byte array.
private static byte[] extractBytes(byte[] scanRecord, int start, int length) {
byte[] bytes = new byte[length];