aboutsummaryrefslogtreecommitdiff
path: root/framework/java/android/bluetooth/BluetoothAdapter.java
diff options
context:
space:
mode:
Diffstat (limited to 'framework/java/android/bluetooth/BluetoothAdapter.java')
-rw-r--r--framework/java/android/bluetooth/BluetoothAdapter.java344
1 files changed, 108 insertions, 236 deletions
diff --git a/framework/java/android/bluetooth/BluetoothAdapter.java b/framework/java/android/bluetooth/BluetoothAdapter.java
index 646be0666f..faf864550d 100644
--- a/framework/java/android/bluetooth/BluetoothAdapter.java
+++ b/framework/java/android/bluetooth/BluetoothAdapter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2009-2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,12 +18,15 @@ package android.bluetooth;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
+import android.bluetooth.le.BluetoothLeAdvertiser;
+import android.bluetooth.le.BluetoothLeScanner;
+import android.bluetooth.le.ScanCallback;
+import android.bluetooth.le.ScanResult;
+import android.bluetooth.le.ScanSettings;
import android.content.Context;
-import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
-import android.os.Message;
import android.os.ParcelUuid;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -37,9 +40,9 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Locale;
import java.util.Map;
-import java.util.Random;
import java.util.Set;
import java.util.UUID;
@@ -216,22 +219,6 @@ public final class BluetoothAdapter {
"android.bluetooth.adapter.action.SCAN_MODE_CHANGED";
/**
- * Broadcast Action: Indicate BLE Advertising is started.
- * @hide
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_BLUETOOTH_ADVERTISING_STARTED =
- "android.bluetooth.adapter.action.ADVERTISING_STARTED";
-
- /**
- * Broadcast Action: Indicated BLE Advertising is stopped.
- * @hide
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_BLUETOOTH_ADVERTISING_STOPPED =
- "android.bluetooth.adapter.action.ADVERTISING_STOPPED";
-
- /**
* Used as an int extra field in {@link #ACTION_SCAN_MODE_CHANGED}
* intents to request the current scan mode. Possible values are:
* {@link #SCAN_MODE_NONE},
@@ -400,8 +387,6 @@ public final class BluetoothAdapter {
private IBluetooth mService;
private final Map<LeScanCallback, GattCallbackWrapper> mLeScanClients;
- private BluetoothAdvScanData mBluetoothAdvScanData = null;
- private GattCallbackWrapper mAdvertisingGattCallback;
private final Handler mHandler; // Handler to post the advertise callback to run on main thread.
private final Object mLock = new Object();
@@ -478,126 +463,19 @@ public final class BluetoothAdapter {
}
/**
- * Returns a {@link BluetoothAdvScanData} object representing advertising data.
- * Data will be reset when bluetooth service is turned off.
- * @hide
+ * Returns a {@link BluetoothLeAdvertiser} object for Bluetooth LE Advertising operations.
*/
- public BluetoothAdvScanData getAdvScanData() {
- try {
- IBluetoothGatt iGatt = mManagerService.getBluetoothGatt();
- if (iGatt == null) {
- // BLE is not supported
- Log.e(TAG, "failed to start, iGatt null");
- return null;
- }
- if (mBluetoothAdvScanData == null) {
- mBluetoothAdvScanData = new BluetoothAdvScanData(iGatt, BluetoothAdvScanData.AD);
- }
- return mBluetoothAdvScanData;
- } catch (RemoteException e) {
- Log.e(TAG, "failed to get advScanData, error: " + e);
- return null;
- }
- }
-
- /**
- * Interface for BLE advertising callback.
- *
- * @hide
- */
- public interface AdvertiseCallback {
- /**
- * Callback when advertise starts.
- * @param status - {@link #ADVERTISE_CALLBACK_SUCCESS} for success, others for failure.
- */
- void onAdvertiseStart(int status);
- /**
- * Callback when advertise stops.
- * @param status - {@link #ADVERTISE_CALLBACK_SUCCESS} for success, others for failure.
- */
- void onAdvertiseStop(int status);
- }
-
- /**
- * Start BLE advertising using current {@link BluetoothAdvScanData}.
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED}
- *
- * @param callback - {@link AdvertiseCallback}
- * @return true if BLE advertising succeeds, false otherwise.
- * @hide
- */
- public boolean startAdvertising(final AdvertiseCallback callback) {
- if (getState() != STATE_ON) return false;
- try {
- IBluetoothGatt iGatt = mManagerService.getBluetoothGatt();
- if (iGatt == null) {
- // BLE is not supported.
- return false;
- }
- // Restart/reset advertising packets if advertising is in progress.
- if (isAdvertising()) {
- // Invalid advertising callback.
- if (mAdvertisingGattCallback == null || mAdvertisingGattCallback.mLeHandle == -1) {
- Log.e(TAG, "failed to restart advertising, invalid callback");
- return false;
- }
- iGatt.startAdvertising(mAdvertisingGattCallback.mLeHandle);
- // Run the callback from main thread.
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- // callback with status success.
- callback.onAdvertiseStart(ADVERTISE_CALLBACK_SUCCESS);
- }
- });
- return true;
- }
- UUID uuid = UUID.randomUUID();
- GattCallbackWrapper wrapper =
- new GattCallbackWrapper(this, null, null, callback);
- iGatt.registerClient(new ParcelUuid(uuid), wrapper);
- if (!wrapper.advertiseStarted()) {
- return false;
- }
- synchronized (mLock) {
- mAdvertisingGattCallback = wrapper;
- }
- return true;
- } catch (RemoteException e) {
- Log.e(TAG, "", e);
- return false;
- }
+ public BluetoothLeAdvertiser getBluetoothLeAdvertiser() {
+ // TODO: Return null if this feature is not supported by hardware.
+ return new BluetoothLeAdvertiser(mManagerService);
}
/**
- * Stop BLE advertising. The callback has to be the same one used for start advertising.
- *
- * @param callback - {@link AdvertiseCallback}
- * @return true if BLE advertising stops, false otherwise.
- * @hide
+ * Returns a {@link BluetoothLeScanner} object for Bluetooth LE scan operations.
*/
- public boolean stopAdvertising(AdvertiseCallback callback) {
- try {
- IBluetoothGatt iGatt = mManagerService.getBluetoothGatt();
- if (iGatt == null) {
- // BLE is not supported
- return false;
- }
- if (mAdvertisingGattCallback == null) {
- // no callback.
- return false;
- }
- // Make sure same callback is used for start and stop advertising.
- if (callback != mAdvertisingGattCallback.mAdvertiseCallback) {
- Log.e(TAG, "must use the same callback for star/stop advertising");
- return false;
- }
- mAdvertisingGattCallback.stopAdvertising();
- return true;
- } catch (RemoteException e) {
- Log.e(TAG, "", e);
- return false;
- }
+ public BluetoothLeScanner getBluetoothLeScanner() {
+ // TODO: Return null if BLE scan is not supported by hardware.
+ return new BluetoothLeScanner(mManagerService);
}
/**
@@ -1012,18 +890,46 @@ public final class BluetoothAdapter {
}
/**
- * Returns whether BLE is currently advertising.
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED}.
+ * Return true if the multi advertisement is supported by the chipset
*
- * @hide
+ * @return true if Multiple Advertisement feature is supported
*/
- public boolean isAdvertising() {
+ public boolean isMultipleAdvertisementSupported() {
if (getState() != STATE_ON) return false;
try {
- IBluetoothGatt iGatt = mManagerService.getBluetoothGatt();
- return iGatt.isAdvertising();
+ return mService.isMultiAdvertisementSupported();
} catch (RemoteException e) {
- Log.e(TAG, "", e);
+ Log.e(TAG, "failed to get isMultipleAdvertisementSupported, error: ", e);
+ }
+ return false;
+ }
+
+ /**
+ * Return true if offloaded filters are supported
+ *
+ * @return true if chipset supports on-chip filtering
+ */
+ public boolean isOffloadedFilteringSupported() {
+ if (getState() != STATE_ON) return false;
+ try {
+ return mService.isOffloadedFilteringSupported();
+ } catch (RemoteException e) {
+ Log.e(TAG, "failed to get isOffloadedFilteringSupported, error: ", e);
+ }
+ return false;
+ }
+
+ /**
+ * Return true if offloaded scan batching is supported
+ *
+ * @return true if chipset supports on-chip scan batching
+ */
+ public boolean isOffloadedScanBatchingSupported() {
+ if (getState() != STATE_ON) return false;
+ try {
+ return mService.isOffloadedScanBatchingSupported();
+ } catch (RemoteException e) {
+ Log.e(TAG, "failed to get isOffloadedScanBatchingSupported, error: ", e);
}
return false;
}
@@ -1363,6 +1269,12 @@ public final class BluetoothAdapter {
} else if (profile == BluetoothProfile.A2DP) {
BluetoothA2dp a2dp = new BluetoothA2dp(context, listener);
return true;
+ } else if (profile == BluetoothProfile.A2DP_SINK) {
+ BluetoothA2dpSink a2dpSink = new BluetoothA2dpSink(context, listener);
+ return true;
+ } else if (profile == BluetoothProfile.AVRCP_CONTROLLER) {
+ BluetoothAvrcpController avrcp = new BluetoothAvrcpController(context, listener);
+ return true;
} else if (profile == BluetoothProfile.INPUT_DEVICE) {
BluetoothInputDevice iDev = new BluetoothInputDevice(context, listener);
return true;
@@ -1375,6 +1287,9 @@ public final class BluetoothAdapter {
} else if (profile == BluetoothProfile.MAP) {
BluetoothMap map = new BluetoothMap(context, listener);
return true;
+ } else if (profile == BluetoothProfile.HEADSET_CLIENT) {
+ BluetoothHeadsetClient headsetClient = new BluetoothHeadsetClient(context, listener);
+ return true;
} else {
return false;
}
@@ -1403,6 +1318,14 @@ public final class BluetoothAdapter {
BluetoothA2dp a2dp = (BluetoothA2dp)proxy;
a2dp.close();
break;
+ case BluetoothProfile.A2DP_SINK:
+ BluetoothA2dpSink a2dpSink = (BluetoothA2dpSink)proxy;
+ a2dpSink.close();
+ break;
+ case BluetoothProfile.AVRCP_CONTROLLER:
+ BluetoothAvrcpController avrcp = (BluetoothAvrcpController)proxy;
+ avrcp.close();
+ break;
case BluetoothProfile.INPUT_DEVICE:
BluetoothInputDevice iDev = (BluetoothInputDevice)proxy;
iDev.close();
@@ -1427,6 +1350,10 @@ public final class BluetoothAdapter {
BluetoothMap map = (BluetoothMap)proxy;
map.close();
break;
+ case BluetoothProfile.HEADSET_CLIENT:
+ BluetoothHeadsetClient headsetClient = (BluetoothHeadsetClient)proxy;
+ headsetClient.close();
+ break;
}
}
@@ -1452,8 +1379,6 @@ public final class BluetoothAdapter {
if (VDBG) Log.d(TAG, "onBluetoothServiceDown: " + mService);
synchronized (mManagerCallback) {
mService = null;
- // Reset bluetooth adv scan data when Gatt service is down.
- mBluetoothAdvScanData = null;
for (IBluetoothManagerCallback cb : mProxyServiceStateCallbacks ){
try {
if (cb != null) {
@@ -1651,7 +1576,10 @@ public final class BluetoothAdapter {
*
* @param callback the callback LE scan results are delivered
* @return true, if the scan was started successfully
+ * @deprecated use {@link BluetoothLeScanner#startScan(List, ScanSettings, ScanCallback)}
+ * instead.
*/
+ @Deprecated
public boolean startLeScan(LeScanCallback callback) {
return startLeScan(null, callback);
}
@@ -1668,7 +1596,10 @@ public final class BluetoothAdapter {
* @param serviceUuids Array of services to look for
* @param callback the callback LE scan results are delivered
* @return true, if the scan was started successfully
+ * @deprecated use {@link BluetoothLeScanner#startScan(List, ScanSettings, ScanCallback)}
+ * instead.
*/
+ @Deprecated
public boolean startLeScan(UUID[] serviceUuids, LeScanCallback callback) {
if (DBG) Log.d(TAG, "startLeScan(): " + serviceUuids);
@@ -1711,7 +1642,9 @@ public final class BluetoothAdapter {
*
* @param callback used to identify which scan to stop
* must be the same handle used to start the scan
+ * @deprecated Use {@link BluetoothLeScanner#stopScan(ScanCallback)} instead.
*/
+ @Deprecated
public void stopLeScan(LeScanCallback callback) {
if (DBG) Log.d(TAG, "stopLeScan()");
GattCallbackWrapper wrapper;
@@ -1729,7 +1662,6 @@ public final class BluetoothAdapter {
private static final int LE_CALLBACK_REG_TIMEOUT = 2000;
private static final int LE_CALLBACK_REG_WAIT_COUNT = 5;
- private final AdvertiseCallback mAdvertiseCallback;
private final LeScanCallback mLeScanCb;
// mLeHandle 0: not registered
@@ -1745,27 +1677,12 @@ public final class BluetoothAdapter {
mLeScanCb = leScanCb;
mScanFilter = uuid;
mLeHandle = 0;
- mAdvertiseCallback = null;
- }
-
- public GattCallbackWrapper(BluetoothAdapter bluetoothAdapter, LeScanCallback leScanCb,
- UUID[] uuid, AdvertiseCallback callback) {
- mBluetoothAdapter = new WeakReference<BluetoothAdapter>(bluetoothAdapter);
- mLeScanCb = leScanCb;
- mScanFilter = uuid;
- mLeHandle = 0;
- mAdvertiseCallback = callback;
}
public boolean scanStarted() {
return waitForRegisteration(LE_CALLBACK_REG_WAIT_COUNT);
}
- public boolean advertiseStarted() {
- // Wait for registeration callback.
- return waitForRegisteration(1);
- }
-
private boolean waitForRegisteration(int maxWaitCount) {
boolean started = false;
synchronized(this) {
@@ -1785,27 +1702,6 @@ public final class BluetoothAdapter {
return started;
}
- public void stopAdvertising() {
- synchronized (this) {
- if (mLeHandle <= 0) {
- Log.e(TAG, "Error state, mLeHandle: " + mLeHandle);
- return;
- }
- BluetoothAdapter adapter = mBluetoothAdapter.get();
- if (adapter != null) {
- try {
- IBluetoothGatt iGatt = adapter.getBluetoothManager().getBluetoothGatt();
- iGatt.stopAdvertising();
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to stop advertising" + e);
- }
- } else {
- Log.e(TAG, "stopAdvertising, BluetoothAdapter is null");
- }
- notifyAll();
- }
- }
-
public void stopLeScan() {
synchronized(this) {
if (mLeHandle <= 0) {
@@ -1847,18 +1743,14 @@ public final class BluetoothAdapter {
BluetoothAdapter adapter = mBluetoothAdapter.get();
if (adapter != null) {
iGatt = adapter.getBluetoothManager().getBluetoothGatt();
- if (mAdvertiseCallback != null) {
- iGatt.startAdvertising(mLeHandle);
+ if (mScanFilter == null) {
+ iGatt.startScan(mLeHandle, false);
} else {
- if (mScanFilter == null) {
- iGatt.startScan(mLeHandle, false);
- } else {
- ParcelUuid[] uuids = new ParcelUuid[mScanFilter.length];
- for(int i = 0; i != uuids.length; ++i) {
- uuids[i] = new ParcelUuid(mScanFilter[i]);
- }
- iGatt.startScanWithUuids(mLeHandle, false, uuids);
- }
+ ParcelUuid[] uuids = new ParcelUuid[mScanFilter.length];
+ for(int i = 0; i != uuids.length; ++i) {
+ uuids[i] = new ParcelUuid(mScanFilter[i]);
+ }
+ iGatt.startScanWithUuids(mLeHandle, false, uuids);
}
} else {
Log.e(TAG, "onClientRegistered, BluetoothAdapter null");
@@ -1987,52 +1879,32 @@ public final class BluetoothAdapter {
}
public void onAdvertiseStateChange(int advertiseState, int status) {
- Log.d(TAG, "on advertise call back, state: " + advertiseState + " status: " + status);
- if (advertiseState == STATE_ADVERTISE_STARTED) {
- if (status == ADVERTISE_CALLBACK_SUCCESS) {
- mAdvertiseCallback.onAdvertiseStart(status);
- } else {
- // If status is unsuccessful and advertise state is started, it means stop
- // advertising fails.
- mAdvertiseCallback.onAdvertiseStop(status);
- }
- } else {
- synchronized (this) {
- if (status == ADVERTISE_CALLBACK_SUCCESS) {
- BluetoothAdapter adapter = mBluetoothAdapter.get();
- if (adapter != null) {
- try {
- IBluetoothGatt iGatt =
- adapter.getBluetoothManager().getBluetoothGatt();
- Log.d(TAG, "unregistering client " + mLeHandle);
- iGatt.unregisterClient(mLeHandle);
- // Reset advertise app handle.
- mLeHandle = -1;
- adapter.mAdvertisingGattCallback = null;
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to unregister client" + e);
- }
- } else {
- Log.e(TAG, "cannot unregister client, BluetoothAdapter is null");
- }
- }
- }
- if (status == ADVERTISE_CALLBACK_SUCCESS) {
- mAdvertiseCallback.onAdvertiseStop(status);
- } else{
- // If status is unsuccesful and advertise state is stopped, it means start
- // advertising fails.
- mAdvertiseCallback.onAdvertiseStart(status);
- }
- }
}
- /**
- * Callback reporting LE ATT MTU.
- * @hide
- */
+ @Override
+ public void onMultiAdvertiseCallback(int status) {
+ // no op
+ }
+
+ @Override
public void onConfigureMTU(String address, int mtu, int status) {
// no op
}
+
+ @Override
+ public void onConnectionCongested(String address, boolean congested) {
+ // no op
+ }
+
+ @Override
+ public void onBatchScanResults(List<ScanResult> results) {
+ // no op
+ }
+
+ @Override
+ public void onFoundOrLost(boolean onFound, String address,int rssi,
+ byte[] advData) {
+ // no op
+ }
}
}