diff options
author | Wei Wang <weiwa@google.com> | 2014-07-09 14:03:42 -0700 |
---|---|---|
committer | Andre Eisenbach <eisenbach@google.com> | 2014-07-11 11:06:10 -0700 |
commit | af74e66e29a518157cb78fcef4b4fc532b7f60b0 (patch) | |
tree | 7e16f5bc451845f48381679b7c3bcd48e1f2067a /core/java | |
parent | 3c58775a126c9c9b2f86bc22bd82cedbdcb06024 (diff) | |
download | frameworks_base-af74e66e29a518157cb78fcef4b4fc532b7f60b0.zip frameworks_base-af74e66e29a518157cb78fcef4b4fc532b7f60b0.tar.gz frameworks_base-af74e66e29a518157cb78fcef4b4fc532b7f60b0.tar.bz2 |
Unhide Bluetooth batch APIs. Deprecate BluetoothAdpater scan APIs. (1/2)
Change-Id: Ib0c4ea6c8372a15473269660355fb5ccf4284457
Diffstat (limited to 'core/java')
-rw-r--r-- | core/java/android/bluetooth/BluetoothAdapter.java | 10 | ||||
-rw-r--r-- | core/java/android/bluetooth/IBluetoothGatt.aidl | 6 | ||||
-rw-r--r-- | core/java/android/bluetooth/le/AdvertiseCallback.java | 50 | ||||
-rw-r--r-- | core/java/android/bluetooth/le/AdvertiseData.aidl (renamed from core/java/android/bluetooth/le/AdvertisementData.aidl) | 2 | ||||
-rw-r--r-- | core/java/android/bluetooth/le/AdvertiseData.java (renamed from core/java/android/bluetooth/le/AdvertisementData.java) | 69 | ||||
-rw-r--r-- | core/java/android/bluetooth/le/AdvertiseSettings.java | 108 | ||||
-rw-r--r-- | core/java/android/bluetooth/le/BluetoothLeAdvertiser.java | 72 | ||||
-rw-r--r-- | core/java/android/bluetooth/le/BluetoothLeScanner.java | 72 | ||||
-rw-r--r-- | core/java/android/bluetooth/le/ScanCallback.java | 49 | ||||
-rw-r--r-- | core/java/android/bluetooth/le/ScanFilter.java | 82 | ||||
-rw-r--r-- | core/java/android/bluetooth/le/ScanRecord.java | 23 | ||||
-rw-r--r-- | core/java/android/bluetooth/le/ScanSettings.java | 93 |
12 files changed, 329 insertions, 307 deletions
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java index be14504..97e3fc5 100644 --- a/core/java/android/bluetooth/BluetoothAdapter.java +++ b/core/java/android/bluetooth/BluetoothAdapter.java @@ -20,7 +20,9 @@ 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.Handler; import android.os.IBinder; @@ -1734,7 +1736,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); } @@ -1751,7 +1756,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); @@ -1794,7 +1802,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; diff --git a/core/java/android/bluetooth/IBluetoothGatt.aidl b/core/java/android/bluetooth/IBluetoothGatt.aidl index 5ed10a6..0f0eee6 100644 --- a/core/java/android/bluetooth/IBluetoothGatt.aidl +++ b/core/java/android/bluetooth/IBluetoothGatt.aidl @@ -18,7 +18,7 @@ package android.bluetooth; import android.bluetooth.BluetoothDevice; import android.bluetooth.le.AdvertiseSettings; -import android.bluetooth.le.AdvertisementData; +import android.bluetooth.le.AdvertiseData; import android.bluetooth.le.ScanFilter; import android.bluetooth.le.ScanSettings; import android.os.ParcelUuid; @@ -40,8 +40,8 @@ interface IBluetoothGatt { void stopScan(in int appIf, in boolean isServer); void flushPendingBatchResults(in int appIf, in boolean isServer); void startMultiAdvertising(in int appIf, - in AdvertisementData advertiseData, - in AdvertisementData scanResponse, + in AdvertiseData advertiseData, + in AdvertiseData scanResponse, in AdvertiseSettings settings); void stopMultiAdvertising(in int appIf); void registerClient(in ParcelUuid appId, in IBluetoothGattCallback callback); diff --git a/core/java/android/bluetooth/le/AdvertiseCallback.java b/core/java/android/bluetooth/le/AdvertiseCallback.java index 1d26ef9..2afbadf 100644 --- a/core/java/android/bluetooth/le/AdvertiseCallback.java +++ b/core/java/android/bluetooth/le/AdvertiseCallback.java @@ -17,64 +17,58 @@ package android.bluetooth.le; /** - * Callback of Bluetooth LE advertising, which is used to deliver advertising operation status. + * Bluetooth LE advertising callbacks, used to deliver advertising operation status. */ public abstract class AdvertiseCallback { /** - * The operation is success. - * + * The requested operation was successful. * @hide */ - public static final int SUCCESS = 0; + public static final int ADVERTISE_SUCCESS = 0; + /** - * Fails to start advertising as the advertisement data contains services that are not added to - * the local bluetooth GATT server. + * Failed to start advertising as the advertisement data contains services that are not + * added to the local Bluetooth GATT server. */ public static final int ADVERTISE_FAILED_SERVICE_UNKNOWN = 1; + /** - * Fails to start advertising as system runs out of quota for advertisers. + * Failed to start advertising because no advertising instance is available. */ public static final int ADVERTISE_FAILED_TOO_MANY_ADVERTISERS = 2; /** - * Fails to start advertising as the advertising is already started. + * Failed to start advertising as the advertising is already started. */ public static final int ADVERTISE_FAILED_ALREADY_STARTED = 3; - /** - * Fails to stop advertising as the advertising is not started. - */ - public static final int ADVERTISE_FAILED_NOT_STARTED = 4; /** - * Operation fails due to bluetooth controller failure. - */ - public static final int ADVERTISE_FAILED_CONTROLLER_FAILURE = 5; - - /** - * Operation fails due to GATT service failure. - * @hide + * Operation failed due to an internal error. */ - public static final int ADVERTISE_FAILED_GATT_SERVICE_FAILURE = 6; + public static final int ADVERTISE_FAILED_INTERNAL_ERROR = 4; /** - * Operation fails as this feature is not supported + * This feature is not supported on this platform. */ - public static final int ADVERTISE_FAILED_FEATURE_UNSUPPORTED = 7; + public static final int ADVERTISE_FAILED_FEATURE_UNSUPPORTED = 5; /** - * Callback when advertising operation succeeds. + * Callback triggered in response to {@link BluetoothLeAdvertiser#startAdvertising} indicating + * that the advertising has been started successfully. * * @param settingsInEffect The actual settings used for advertising, which may be different from - * what the app asks. + * what has been requested. */ - public abstract void onSuccess(AdvertiseSettings settingsInEffect); + public void onStartSuccess(AdvertiseSettings settingsInEffect) { + } /** - * Callback when advertising operation fails. + * Callback when advertising could not be started. * - * @param errorCode Error code for failures. + * @param errorCode Error code (see ADVERTISE_FAILED_* constants) for */ - public abstract void onFailure(int errorCode); + public void onStartFailure(int errorCode) { + } } diff --git a/core/java/android/bluetooth/le/AdvertisementData.aidl b/core/java/android/bluetooth/le/AdvertiseData.aidl index 3da1321..bcbf224 100644 --- a/core/java/android/bluetooth/le/AdvertisementData.aidl +++ b/core/java/android/bluetooth/le/AdvertiseData.aidl @@ -16,4 +16,4 @@ package android.bluetooth.le; -parcelable AdvertisementData;
\ No newline at end of file +parcelable AdvertiseData; diff --git a/core/java/android/bluetooth/le/AdvertisementData.java b/core/java/android/bluetooth/le/AdvertiseData.java index c587204..d0f52b2 100644 --- a/core/java/android/bluetooth/le/AdvertisementData.java +++ b/core/java/android/bluetooth/le/AdvertiseData.java @@ -27,16 +27,16 @@ import java.util.Arrays; import java.util.List; /** - * Advertisement data packet for Bluetooth LE advertising. This represents the data to be - * broadcasted in Bluetooth LE advertising as well as the scan response for active scan. - * <p> - * Use {@link AdvertisementData.Builder} to create an instance of {@link AdvertisementData} to be + * Advertisement data packet container for Bluetooth LE advertising. This represents the data to be + * advertised as well as the scan response data for active scans. + * + * <p>Use {@link AdvertiseData.Builder} to create an instance of {@link AdvertiseData} to be * advertised. * * @see BluetoothLeAdvertiser * @see ScanRecord */ -public final class AdvertisementData implements Parcelable { +public final class AdvertiseData implements Parcelable { @Nullable private final List<ParcelUuid> mServiceUuids; @@ -52,7 +52,7 @@ public final class AdvertisementData implements Parcelable { private boolean mIncludeTxPowerLevel; - private AdvertisementData(List<ParcelUuid> serviceUuids, + private AdvertiseData(List<ParcelUuid> serviceUuids, ParcelUuid serviceDataUuid, byte[] serviceData, int manufacturerId, byte[] manufacturerSpecificData, boolean includeTxPowerLevel) { @@ -65,8 +65,8 @@ public final class AdvertisementData implements Parcelable { } /** - * Returns a list of service uuids within the advertisement that are used to identify the - * bluetooth GATT services. + * Returns a list of service UUIDs within the advertisement that are used to identify the + * Bluetooth GATT services. */ public List<ParcelUuid> getServiceUuids() { return mServiceUuids; @@ -89,15 +89,14 @@ public final class AdvertisementData implements Parcelable { } /** - * Returns a 16 bit uuid of the service that the service data is associated with. + * Returns a 16-bit UUID of the service that the service data is associated with. */ public ParcelUuid getServiceDataUuid() { return mServiceDataUuid; } /** - * Returns service data. The first two bytes should be a 16 bit service uuid associated with the - * service data. + * Returns service data. */ public byte[] getServiceData() { return mServiceData; @@ -112,7 +111,7 @@ public final class AdvertisementData implements Parcelable { @Override public String toString() { - return "AdvertisementData [mServiceUuids=" + mServiceUuids + ", mManufacturerId=" + return "AdvertiseData [mServiceUuids=" + mServiceUuids + ", mManufacturerId=" + mManufacturerId + ", mManufacturerSpecificData=" + Arrays.toString(mManufacturerSpecificData) + ", mServiceDataUuid=" + mServiceDataUuid + ", mServiceData=" + Arrays.toString(mServiceData) @@ -156,15 +155,15 @@ public final class AdvertisementData implements Parcelable { dest.writeByte((byte) (getIncludeTxPowerLevel() ? 1 : 0)); } - public static final Parcelable.Creator<AdvertisementData> CREATOR = - new Creator<AdvertisementData>() { + public static final Parcelable.Creator<AdvertiseData> CREATOR = + new Creator<AdvertiseData>() { @Override - public AdvertisementData[] newArray(int size) { - return new AdvertisementData[size]; + public AdvertiseData[] newArray(int size) { + return new AdvertiseData[size]; } @Override - public AdvertisementData createFromParcel(Parcel in) { + public AdvertiseData createFromParcel(Parcel in) { Builder builder = new Builder(); if (in.readInt() > 0) { List<ParcelUuid> uuids = new ArrayList<ParcelUuid>(); @@ -194,7 +193,7 @@ public final class AdvertisementData implements Parcelable { }; /** - * Builder for {@link AdvertisementData}. + * Builder for {@link AdvertiseData}. */ public static final class Builder { private static final int MAX_ADVERTISING_DATA_BYTES = 31; @@ -215,11 +214,13 @@ public final class AdvertisementData implements Parcelable { private byte[] mServiceData; /** - * Set the service uuids. Note the corresponding bluetooth Gatt services need to be already - * added on the device before start BLE advertising. + * Set the service UUIDs. + * + * <p><b>Note:</b> The corresponding Bluetooth Gatt services need to already + * be added on the device (using {@link android.bluetooth.BluetoothGattServer#addService}) prior + * to advertising them. * - * @param serviceUuids Service uuids to be advertised, could be 16-bit, 32-bit or 128-bit - * uuids. + * @param serviceUuids Service UUIDs to be advertised. * @throws IllegalArgumentException If the {@code serviceUuids} are null. */ public Builder setServiceUuids(List<ParcelUuid> serviceUuids) { @@ -233,9 +234,8 @@ public final class AdvertisementData implements Parcelable { /** * Add service data to advertisement. * - * @param serviceDataUuid A 16 bit uuid of the service data - * @param serviceData Service data - the first two bytes of the service data are the service - * data uuid. + * @param serviceDataUuid 16-bit UUID of the service the data is associated with + * @param serviceData Service data * @throws IllegalArgumentException If the {@code serviceDataUuid} or {@code serviceData} is * empty. */ @@ -250,13 +250,14 @@ public final class AdvertisementData implements Parcelable { } /** - * Set manufacturer id and data. See <a - * href="https://www.bluetooth.org/en-us/specification/assigned-numbers/company-identifiers">assigned - * manufacturer identifies</a> for the existing company identifiers. + * Set manufacturer specific data. + * + * <p>Please refer to the Bluetooth Assigned Numbers document provided by the + * <a href="https://www.bluetooth.org">Bluetooth SIG</a> for a list of existing + * company identifiers. * - * @param manufacturerId Manufacturer id assigned by Bluetooth SIG. - * @param manufacturerSpecificData Manufacturer specific data - the first two bytes of the - * manufacturer specific data are the manufacturer id. + * @param manufacturerId Manufacturer ID assigned by Bluetooth SIG. + * @param manufacturerSpecificData Manufacturer specific data * @throws IllegalArgumentException If the {@code manufacturerId} is negative or * {@code manufacturerSpecificData} is null. */ @@ -282,16 +283,16 @@ public final class AdvertisementData implements Parcelable { } /** - * Build the {@link AdvertisementData}. + * Build the {@link AdvertiseData}. * * @throws IllegalArgumentException If the data size is larger than 31 bytes. */ - public AdvertisementData build() { + public AdvertiseData build() { if (totalBytes() > MAX_ADVERTISING_DATA_BYTES) { throw new IllegalArgumentException( "advertisement data size is larger than 31 bytes"); } - return new AdvertisementData(mServiceUuids, + return new AdvertiseData(mServiceUuids, mServiceDataUuid, mServiceData, mManufacturerId, mManufacturerSpecificData, mIncludeTxPowerLevel); diff --git a/core/java/android/bluetooth/le/AdvertiseSettings.java b/core/java/android/bluetooth/le/AdvertiseSettings.java index 87d0346..02b4a5b 100644 --- a/core/java/android/bluetooth/le/AdvertiseSettings.java +++ b/core/java/android/bluetooth/le/AdvertiseSettings.java @@ -21,7 +21,8 @@ import android.os.Parcelable; /** * The {@link AdvertiseSettings} provide a way to adjust advertising preferences for each - * individual advertisement. Use {@link AdvertiseSettings.Builder} to create an instance. + * Bluetooth LE advertisement instance. Use {@link AdvertiseSettings.Builder} to create an + * instance of this class. */ public final class AdvertiseSettings implements Parcelable { /** @@ -29,68 +30,64 @@ public final class AdvertiseSettings implements Parcelable { * advertising mode as it consumes the least power. */ public static final int ADVERTISE_MODE_LOW_POWER = 0; + /** * Perform Bluetooth LE advertising in balanced power mode. This is balanced between advertising * frequency and power consumption. */ public static final int ADVERTISE_MODE_BALANCED = 1; + /** * Perform Bluetooth LE advertising in low latency, high power mode. This has the highest power - * consumption and should not be used for background continuous advertising. + * consumption and should not be used for continuous background advertising. */ public static final int ADVERTISE_MODE_LOW_LATENCY = 2; /** - * Advertise using the lowest transmission(tx) power level. An app can use low transmission - * power to restrict the visibility range of its advertising packet. + * Advertise using the lowest transmission (TX) power level. Low transmission power can be used + * to restrict the visibility range of advertising packets. */ public static final int ADVERTISE_TX_POWER_ULTRA_LOW = 0; + /** - * Advertise using low tx power level. + * Advertise using low TX power level. */ public static final int ADVERTISE_TX_POWER_LOW = 1; + /** - * Advertise using medium tx power level. + * Advertise using medium TX power level. */ public static final int ADVERTISE_TX_POWER_MEDIUM = 2; + /** - * Advertise using high tx power level. This is corresponding to largest visibility range of the + * Advertise using high TX power level. This corresponds to largest visibility range of the * advertising packet. */ public static final int ADVERTISE_TX_POWER_HIGH = 3; /** - * Non-connectable undirected advertising event, as defined in Bluetooth Specification V4.1 - * vol6, part B, section 4.4.2 - Advertising state. - */ - public static final int ADVERTISE_TYPE_NON_CONNECTABLE = 0; - /** - * Scannable undirected advertise type, as defined in same spec mentioned above. This event type - * allows a scanner to send a scan request asking additional information about the advertiser. - */ - public static final int ADVERTISE_TYPE_SCANNABLE = 1; - /** - * Connectable undirected advertising type, as defined in same spec mentioned above. This event - * type allows a scanner to send scan request asking additional information about the - * advertiser. It also allows an initiator to send a connect request for connection. + * The maximimum limited advertisement duration as specified by the Bluetooth SIG */ - public static final int ADVERTISE_TYPE_CONNECTABLE = 2; + private static final int LIMITED_ADVERTISING_MAX_DURATION = 180; private final int mAdvertiseMode; private final int mAdvertiseTxPowerLevel; - private final int mAdvertiseEventType; + private final int mAdvertiseTimeoutSeconds; + private final boolean mAdvertiseConnectable; private AdvertiseSettings(int advertiseMode, int advertiseTxPowerLevel, - int advertiseEventType) { + boolean advertiseConnectable, int advertiseTimeout) { mAdvertiseMode = advertiseMode; mAdvertiseTxPowerLevel = advertiseTxPowerLevel; - mAdvertiseEventType = advertiseEventType; + mAdvertiseConnectable = advertiseConnectable; + mAdvertiseTimeoutSeconds = advertiseTimeout; } private AdvertiseSettings(Parcel in) { mAdvertiseMode = in.readInt(); mAdvertiseTxPowerLevel = in.readInt(); - mAdvertiseEventType = in.readInt(); + mAdvertiseConnectable = in.readInt() != 0 ? true : false; + mAdvertiseTimeoutSeconds = in.readInt(); } /** @@ -101,23 +98,32 @@ public final class AdvertiseSettings implements Parcelable { } /** - * Returns the tx power level for advertising. + * Returns the TX power level for advertising. */ public int getTxPowerLevel() { return mAdvertiseTxPowerLevel; } /** - * Returns the advertise event type. + * Returns whether the advertisement will indicate connectable. */ - public int getType() { - return mAdvertiseEventType; + public boolean getIsConnectable() { + return mAdvertiseConnectable; + } + + /** + * Returns the advertising time limit in seconds. + */ + public int getTimeout() { + return mAdvertiseTimeoutSeconds; } @Override public String toString() { - return "Settings [mAdvertiseMode=" + mAdvertiseMode + ", mAdvertiseTxPowerLevel=" - + mAdvertiseTxPowerLevel + ", mAdvertiseEventType=" + mAdvertiseEventType + "]"; + return "Settings [mAdvertiseMode=" + mAdvertiseMode + + ", mAdvertiseTxPowerLevel=" + mAdvertiseTxPowerLevel + + ", mAdvertiseConnectable=" + mAdvertiseConnectable + + ", mAdvertiseTimeoutSeconds=" + mAdvertiseTimeoutSeconds + "]"; } @Override @@ -129,7 +135,8 @@ public final class AdvertiseSettings implements Parcelable { public void writeToParcel(Parcel dest, int flags) { dest.writeInt(mAdvertiseMode); dest.writeInt(mAdvertiseTxPowerLevel); - dest.writeInt(mAdvertiseEventType); + dest.writeInt(mAdvertiseConnectable ? 1 : 0); + dest.writeInt(mAdvertiseTimeoutSeconds); } public static final Parcelable.Creator<AdvertiseSettings> CREATOR = @@ -151,7 +158,8 @@ public final class AdvertiseSettings implements Parcelable { public static final class Builder { private int mMode = ADVERTISE_MODE_LOW_POWER; private int mTxPowerLevel = ADVERTISE_TX_POWER_MEDIUM; - private int mType = ADVERTISE_TYPE_NON_CONNECTABLE; + private int mTimeoutSeconds = 0; + private boolean mConnectable = true; /** * Set advertise mode to control the advertising power and latency. @@ -172,7 +180,7 @@ public final class AdvertiseSettings implements Parcelable { } /** - * Set advertise tx power level to control the transmission power level for the advertising. + * Set advertise TX power level to control the transmission power level for the advertising. * * @param txPowerLevel Transmission power of Bluetooth LE Advertising, can only be one of * {@link AdvertiseSettings#ADVERTISE_TX_POWER_ULTRA_LOW}, @@ -191,20 +199,28 @@ public final class AdvertiseSettings implements Parcelable { } /** - * Set advertise type to control the event type of advertising. + * Set whether the advertisement type should be connectable or non-connectable. * - * @param type Bluetooth LE Advertising type, can be either - * {@link AdvertiseSettings#ADVERTISE_TYPE_NON_CONNECTABLE}, - * {@link AdvertiseSettings#ADVERTISE_TYPE_SCANNABLE} or - * {@link AdvertiseSettings#ADVERTISE_TYPE_CONNECTABLE}. - * @throws IllegalArgumentException If the {@code type} is invalid. + * @param isConnectable Controls whether the advertisment type will be connectable (true) + * or non-connectable (false). + */ + public Builder setIsConnectable(boolean isConnectable) { + mConnectable = isConnectable; + return this; + } + + /** + * Limit advertising to a given amount of time. + * @param timeoutSeconds Advertising time limit. May not exceed 180 seconds. + * A value of 0 will disable the time limit. + * @throws IllegalArgumentException If the provided timeout is over 180s. */ - public Builder setType(int type) { - if (type < ADVERTISE_TYPE_NON_CONNECTABLE - || type > ADVERTISE_TYPE_CONNECTABLE) { - throw new IllegalArgumentException("unknown advertise type " + type); + public Builder setTimeout(int timeoutSeconds) { + if (timeoutSeconds < 0 || timeoutSeconds > LIMITED_ADVERTISING_MAX_DURATION) { + throw new IllegalArgumentException("timeoutSeconds invalid (must be 0-" + + LIMITED_ADVERTISING_MAX_DURATION + " seconds)"); } - mType = type; + mTimeoutSeconds = timeoutSeconds; return this; } @@ -212,7 +228,7 @@ public final class AdvertiseSettings implements Parcelable { * Build the {@link AdvertiseSettings} object. */ public AdvertiseSettings build() { - return new AdvertiseSettings(mMode, mTxPowerLevel, mType); + return new AdvertiseSettings(mMode, mTxPowerLevel, mConnectable, mTimeoutSeconds); } } } diff --git a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java index d395d43..e232512 100644 --- a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java +++ b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java @@ -33,17 +33,17 @@ import java.util.Map; import java.util.UUID; /** - * This class provides a way to perform Bluetooth LE advertise operations, such as start and stop - * advertising. An advertiser can broadcast up to 31 bytes of advertisement data represented by - * {@link AdvertisementData}. + * This class provides a way to perform Bluetooth LE advertise operations, such as starting and + * stopping advertising. An advertiser can broadcast up to 31 bytes of advertisement data + * represented by {@link AdvertiseData}. * <p> * To get an instance of {@link BluetoothLeAdvertiser}, call the * {@link BluetoothAdapter#getBluetoothLeAdvertiser()} method. * <p> - * Note most of the methods here require {@link android.Manifest.permission#BLUETOOTH_ADMIN} + * <b>Note:</b> Most of the methods here require {@link android.Manifest.permission#BLUETOOTH_ADMIN} * permission. * - * @see AdvertisementData + * @see AdvertiseData */ public final class BluetoothLeAdvertiser { @@ -57,8 +57,6 @@ public final class BluetoothLeAdvertiser { /** * Use BluetoothAdapter.getLeAdvertiser() instead. - * - * @param bluetoothManager * @hide */ public BluetoothLeAdvertiser(IBluetoothManager bluetoothManager) { @@ -68,8 +66,8 @@ public final class BluetoothLeAdvertiser { } /** - * Start Bluetooth LE Advertising. The {@code advertiseData} would be broadcasted after the - * operation succeeds. Returns immediately, the operation status are delivered through + * Start Bluetooth LE Advertising. On success, the {@code advertiseData} will be + * broadcasted. Returns immediately, the operation status is delivered through * {@code callback}. * <p> * Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission. @@ -79,15 +77,15 @@ public final class BluetoothLeAdvertiser { * @param callback Callback for advertising status. */ public void startAdvertising(AdvertiseSettings settings, - AdvertisementData advertiseData, final AdvertiseCallback callback) { + AdvertiseData advertiseData, final AdvertiseCallback callback) { startAdvertising(settings, advertiseData, null, callback); } /** - * Start Bluetooth LE Advertising. The {@code advertiseData} would be broadcasted after the - * operation succeeds. The {@code scanResponse} would be returned when the scanning device sends - * active scan request. Method returns immediately, the operation status are delivered through - * {@code callback}. + * Start Bluetooth LE Advertising. The {@code advertiseData} will be broadcasted if the + * operation succeeds. The {@code scanResponse} is returned when a scanning device sends + * an active scan request. This method returns immediately, the operation status is + * delivered through {@code callback}. * <p> * Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} * @@ -97,7 +95,7 @@ public final class BluetoothLeAdvertiser { * @param callback Callback for advertising status. */ public void startAdvertising(AdvertiseSettings settings, - AdvertisementData advertiseData, AdvertisementData scanResponse, + AdvertiseData advertiseData, AdvertiseData scanResponse, final AdvertiseCallback callback) { if (callback == null) { throw new IllegalArgumentException("callback cannot be null"); @@ -110,8 +108,8 @@ public final class BluetoothLeAdvertiser { try { gatt = mBluetoothManager.getBluetoothGatt(); } catch (RemoteException e) { - Log.e(TAG, "failed to get bluetooth gatt - ", e); - postCallbackFailure(callback, AdvertiseCallback.ADVERTISE_FAILED_CONTROLLER_FAILURE); + Log.e(TAG, "Failed to get Bluetooth gatt - ", e); + postCallbackFailure(callback, AdvertiseCallback.ADVERTISE_FAILED_INTERNAL_ERROR); return; } if (!mBluetoothAdapter.isMultipleAdvertisementSupported()) { @@ -127,7 +125,7 @@ public final class BluetoothLeAdvertiser { mLeAdvertisers.put(callback, wrapper); } } catch (RemoteException e) { - Log.e(TAG, "failed to stop advertising", e); + Log.e(TAG, "Failed to stop advertising", e); } } @@ -137,31 +135,24 @@ public final class BluetoothLeAdvertiser { * <p> * Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission. * - * @param callback {@link AdvertiseCallback} for delivering stopping advertising status. + * @param callback {@link AdvertiseCallback} identifies the advertising instance to stop. */ public void stopAdvertising(final AdvertiseCallback callback) { if (callback == null) { throw new IllegalArgumentException("callback cannot be null"); } AdvertiseCallbackWrapper wrapper = mLeAdvertisers.get(callback); - if (wrapper == null) { - postCallbackFailure(callback, AdvertiseCallback.ADVERTISE_FAILED_NOT_STARTED); - return; - } + if (wrapper == null) return; + try { IBluetoothGatt gatt = mBluetoothManager.getBluetoothGatt(); - if (gatt == null) { - postCallbackFailure(callback, - AdvertiseCallback.ADVERTISE_FAILED_GATT_SERVICE_FAILURE); - } - gatt.stopMultiAdvertising(wrapper.mLeHandle); + if (gatt != null) gatt.stopMultiAdvertising(wrapper.mLeHandle); + if (wrapper.advertiseStopped()) { mLeAdvertisers.remove(callback); } } catch (RemoteException e) { - Log.e(TAG, "failed to stop advertising", e); - postCallbackFailure(callback, - AdvertiseCallback.ADVERTISE_FAILED_GATT_SERVICE_FAILURE); + Log.e(TAG, "Failed to stop advertising", e); } } @@ -171,8 +162,8 @@ public final class BluetoothLeAdvertiser { private static class AdvertiseCallbackWrapper extends IBluetoothGattCallback.Stub { private static final int LE_CALLBACK_TIMEOUT_MILLIS = 2000; private final AdvertiseCallback mAdvertiseCallback; - private final AdvertisementData mAdvertisement; - private final AdvertisementData mScanResponse; + private final AdvertiseData mAdvertisement; + private final AdvertiseData mScanResponse; private final AdvertiseSettings mSettings; private final IBluetoothGatt mBluetoothGatt; @@ -183,7 +174,7 @@ public final class BluetoothLeAdvertiser { private boolean isAdvertising = false; public AdvertiseCallbackWrapper(AdvertiseCallback advertiseCallback, - AdvertisementData advertiseData, AdvertisementData scanResponse, + AdvertiseData advertiseData, AdvertiseData scanResponse, AdvertiseSettings settings, IBluetoothGatt bluetoothGatt) { mAdvertiseCallback = advertiseCallback; @@ -347,8 +338,12 @@ public final class BluetoothLeAdvertiser { @Override public void onMultiAdvertiseCallback(int status) { + // TODO: This logic needs to be re-visited to account + // for whether the scan has actually been started + // or not. Toggling the isAdvertising does not seem + // correct. synchronized (this) { - if (status == 0) { + if (status == AdvertiseCallback.ADVERTISE_SUCCESS) { isAdvertising = !isAdvertising; if (!isAdvertising) { try { @@ -357,10 +352,11 @@ public final class BluetoothLeAdvertiser { } catch (RemoteException e) { Log.e(TAG, "remote exception when unregistering", e); } + } else { + mAdvertiseCallback.onStartSuccess(null); } - mAdvertiseCallback.onSuccess(null); } else { - mAdvertiseCallback.onFailure(status); + if (!isAdvertising) mAdvertiseCallback.onStartFailure(status); } notifyAll(); } @@ -398,7 +394,7 @@ public final class BluetoothLeAdvertiser { mHandler.post(new Runnable() { @Override public void run() { - callback.onFailure(error); + callback.onStartFailure(error); } }); } diff --git a/core/java/android/bluetooth/le/BluetoothLeScanner.java b/core/java/android/bluetooth/le/BluetoothLeScanner.java index d5a4728..7e87edc 100644 --- a/core/java/android/bluetooth/le/BluetoothLeScanner.java +++ b/core/java/android/bluetooth/le/BluetoothLeScanner.java @@ -36,14 +36,14 @@ import java.util.UUID; /** * This class provides methods to perform scan related operations for Bluetooth LE devices. An - * application can scan for a particular type of BLE devices using {@link ScanFilter}. It can also - * request different types of callbacks for delivering the result. + * application can scan for a particular type of Bluetotoh LE devices using {@link ScanFilter}. + * It can also request different types of callbacks for delivering the result. * <p> * Use {@link BluetoothAdapter#getBluetoothLeScanner()} to get an instance of * {@link BluetoothLeScanner}. * <p> - * Note most of the scan methods here require {@link android.Manifest.permission#BLUETOOTH_ADMIN} - * permission. + * <b>Note:</b> Most of the scan methods here require + * {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission. * * @see ScanFilter */ @@ -58,6 +58,8 @@ public final class BluetoothLeScanner { private final Map<ScanCallback, BleScanCallbackWrapper> mLeScanClients; /** + * Use {@link BluetoothAdapter#getBluetoothLeScanner()} instead. + * @param bluetoothManager BluetoothManager that conducts overall Bluetooth Management * @hide */ public BluetoothLeScanner(IBluetoothManager bluetoothManager) { @@ -68,13 +70,29 @@ public final class BluetoothLeScanner { } /** + * Start Bluetooth LE scan with default parameters and no filters. + * The scan results will be delivered through {@code callback}. + * <p> + * Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission. + * + * @param callback Callback used to deliver scan results. + * @throws IllegalArgumentException If {@code callback} is null. + */ + public void startScan(final ScanCallback callback) { + if (callback == null) { + throw new IllegalArgumentException("callback is null"); + } + this.startScan(null, new ScanSettings.Builder().build(), callback); + } + + /** * Start Bluetooth LE scan. The scan results will be delivered through {@code callback}. * <p> * Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission. * * @param filters {@link ScanFilter}s for finding exact BLE devices. - * @param settings Settings for ble scan. - * @param callback Callback when scan results are delivered. + * @param settings Settings for the scan. + * @param callback Callback used to deliver scan results. * @throws IllegalArgumentException If {@code settings} or {@code callback} is null. */ public void startScan(List<ScanFilter> filters, ScanSettings settings, @@ -94,7 +112,7 @@ public final class BluetoothLeScanner { gatt = null; } if (gatt == null) { - postCallbackError(callback, ScanCallback.SCAN_FAILED_GATT_SERVICE_FAILURE); + postCallbackError(callback, ScanCallback.SCAN_FAILED_INTERNAL_ERROR); return; } if (!isSettingsConfigAllowedForScan(settings)) { @@ -116,7 +134,7 @@ public final class BluetoothLeScanner { } } catch (RemoteException e) { Log.e(TAG, "GATT service exception when starting scan", e); - postCallbackError(callback, ScanCallback.SCAN_FAILED_GATT_SERVICE_FAILURE); + postCallbackError(callback, ScanCallback.SCAN_FAILED_INTERNAL_ERROR); } } } @@ -139,24 +157,12 @@ public final class BluetoothLeScanner { } /** - * Returns available storage size for batch scan results. It's recommended not to use batch scan - * if available storage size is small (less than 1k bytes, for instance). - * - * @hide TODO: unhide when batching is supported in stack. - */ - public int getAvailableBatchStorageSizeBytes() { - throw new UnsupportedOperationException("not impelemented"); - } - - /** * Flush pending batch scan results stored in Bluetooth controller. This will return Bluetooth * LE scan results batched on bluetooth controller. Returns immediately, batch scan results data * will be delivered through the {@code callback}. * * @param callback Callback of the Bluetooth LE Scan, it has to be the same instance as the one * used to start scan. - * - * @hide */ public void flushPendingScanResults(ScanCallback callback) { if (callback == null) { @@ -302,7 +308,7 @@ public final class BluetoothLeScanner { handler.post(new Runnable() { @Override public void run() { - mScanCallback.onAdvertisementUpdate(result); + mScanCallback.onScanResult(ScanSettings.CALLBACK_TYPE_ALL_MATCHES, result); } }); @@ -435,9 +441,9 @@ public final class BluetoothLeScanner { ScanResult result = new ScanResult(device, advData, rssi, scanNanos); if (onFound) { - mScanCallback.onAdvertisementFound(result); + mScanCallback.onScanResult(ScanSettings.CALLBACK_TYPE_FIRST_MATCH, result); } else { - mScanCallback.onAdvertisementLost(result); + mScanCallback.onScanResult(ScanSettings.CALLBACK_TYPE_MATCH_LOST, result); } } } @@ -452,17 +458,13 @@ public final class BluetoothLeScanner { } private boolean isSettingsConfigAllowedForScan(ScanSettings settings) { - boolean ret = true; - int callbackType; - - callbackType = settings.getCallbackType(); - if (((callbackType == ScanSettings.CALLBACK_TYPE_ON_LOST) || - (callbackType == ScanSettings.CALLBACK_TYPE_ON_FOUND) || - (callbackType == ScanSettings.CALLBACK_TYPE_ON_UPDATE && - settings.getReportDelayNanos() > 0) && - (!mBluetoothAdapter.isOffloadedFilteringSupported()))) { - ret = false; - } - return ret; + final int callbackType = settings.getCallbackType(); + if (( callbackType != ScanSettings.CALLBACK_TYPE_ALL_MATCHES + || (callbackType == ScanSettings.CALLBACK_TYPE_ALL_MATCHES + && settings.getReportDelaySeconds() > 0)) + && !mBluetoothAdapter.isOffloadedFilteringSupported()) { + return false; + } + return true; } } diff --git a/core/java/android/bluetooth/le/ScanCallback.java b/core/java/android/bluetooth/le/ScanCallback.java index 593f7f8..b4c1e17 100644 --- a/core/java/android/bluetooth/le/ScanCallback.java +++ b/core/java/android/bluetooth/le/ScanCallback.java @@ -19,64 +19,53 @@ package android.bluetooth.le; import java.util.List; /** - * Callback of Bluetooth LE scans. The results of the scans will be delivered through the callbacks. + * Bluetooth LE scan callbacks. + * Scan results are reported using these callbacks. + * + * {@see BluetoothLeScanner#startScan} */ public abstract class ScanCallback { - /** * Fails to start scan as BLE scan with the same settings is already started by the app. */ public static final int SCAN_FAILED_ALREADY_STARTED = 1; + /** * Fails to start scan as app cannot be registered. */ public static final int SCAN_FAILED_APPLICATION_REGISTRATION_FAILED = 2; + /** - * Fails to start scan due to gatt service failure. - */ - public static final int SCAN_FAILED_GATT_SERVICE_FAILURE = 3; - /** - * Fails to start scan due to controller failure. + * Fails to start scan due an internal error */ - public static final int SCAN_FAILED_CONTROLLER_FAILURE = 4; + public static final int SCAN_FAILED_INTERNAL_ERROR = 3; /** * Fails to start power optimized scan as this feature is not supported. */ - public static final int SCAN_FAILED_FEATURE_UNSUPPORTED = 5; + public static final int SCAN_FAILED_FEATURE_UNSUPPORTED = 4; /** - * Callback when a BLE advertisement is found. + * Callback when a BLE advertisement has been found. * + * @param callbackType Determines if this callback was triggered because of first match, + * a lost match indication or a regular scan result. * @param result A Bluetooth LE scan result. */ - public abstract void onAdvertisementUpdate(ScanResult result); - - /** - * Callback when the BLE advertisement is found for the first time. - * - * @param result The Bluetooth LE scan result when the onFound event is triggered. - */ - public abstract void onAdvertisementFound(ScanResult result); - - /** - * Callback when the BLE advertisement was lost. Note a device has to be "found" before it's - * lost. - * - * @param result The Bluetooth scan result that was last found. - */ - public abstract void onAdvertisementLost(ScanResult result); + public void onScanResult(int callbackType, ScanResult result) { + } /** * Callback when batch results are delivered. * * @param results List of scan results that are previously scanned. - * @hide */ - public abstract void onBatchScanResults(List<ScanResult> results); + public void onBatchScanResults(List<ScanResult> results) { + } /** - * Callback when scan failed. + * Callback when scan could not be started. */ - public abstract void onScanFailed(int errorCode); + public void onScanFailed(int errorCode) { + } } diff --git a/core/java/android/bluetooth/le/ScanFilter.java b/core/java/android/bluetooth/le/ScanFilter.java index c2e316b..e8a91b8 100644 --- a/core/java/android/bluetooth/le/ScanFilter.java +++ b/core/java/android/bluetooth/le/ScanFilter.java @@ -45,10 +45,10 @@ import java.util.UUID; public final class ScanFilter implements Parcelable { @Nullable - private final String mLocalName; + private final String mDeviceName; @Nullable - private final String mMacAddress; + private final String mDeviceAddress; @Nullable private final ParcelUuid mServiceUuid; @@ -69,14 +69,14 @@ public final class ScanFilter implements Parcelable { private final int mMinRssi; private final int mMaxRssi; - private ScanFilter(String name, String macAddress, ParcelUuid uuid, + private ScanFilter(String name, String deviceAddress, ParcelUuid uuid, ParcelUuid uuidMask, byte[] serviceData, byte[] serviceDataMask, int manufacturerId, byte[] manufacturerData, byte[] manufacturerDataMask, int minRssi, int maxRssi) { - mLocalName = name; + mDeviceName = name; mServiceUuid = uuid; mServiceUuidMask = uuidMask; - mMacAddress = macAddress; + mDeviceAddress = deviceAddress; mServiceData = serviceData; mServiceDataMask = serviceDataMask; mManufacturerId = manufacturerId; @@ -93,13 +93,13 @@ public final class ScanFilter implements Parcelable { @Override public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(mLocalName == null ? 0 : 1); - if (mLocalName != null) { - dest.writeString(mLocalName); + dest.writeInt(mDeviceName == null ? 0 : 1); + if (mDeviceName != null) { + dest.writeString(mDeviceName); } - dest.writeInt(mMacAddress == null ? 0 : 1); - if (mMacAddress != null) { - dest.writeString(mMacAddress); + dest.writeInt(mDeviceAddress == null ? 0 : 1); + if (mDeviceAddress != null) { + dest.writeString(mDeviceAddress); } dest.writeInt(mServiceUuid == null ? 0 : 1); if (mServiceUuid != null) { @@ -145,10 +145,10 @@ public final class ScanFilter implements Parcelable { public ScanFilter createFromParcel(Parcel in) { Builder builder = new Builder(); if (in.readInt() == 1) { - builder.setName(in.readString()); + builder.setDeviceName(in.readString()); } if (in.readInt() == 1) { - builder.setMacAddress(in.readString()); + builder.setDeviceAddress(in.readString()); } if (in.readInt() == 1) { ParcelUuid uuid = in.readParcelable(ParcelUuid.class.getClassLoader()); @@ -196,11 +196,11 @@ public final class ScanFilter implements Parcelable { }; /** - * Returns the filter set the local name field of Bluetooth advertisement data. + * Returns the filter set the device name field of Bluetooth advertisement data. */ @Nullable - public String getLocalName() { - return mLocalName; + public String getDeviceName() { + return mDeviceName; } /** @@ -218,7 +218,7 @@ public final class ScanFilter implements Parcelable { @Nullable public String getDeviceAddress() { - return mMacAddress; + return mDeviceAddress; } @Nullable @@ -249,14 +249,14 @@ public final class ScanFilter implements Parcelable { } /** - * Returns minimum value of rssi for the scan filter. {@link Integer#MIN_VALUE} if not set. + * Returns minimum value of RSSI for the scan filter. {@link Integer#MIN_VALUE} if not set. */ public int getMinRssi() { return mMinRssi; } /** - * Returns maximum value of the rssi for the scan filter. {@link Integer#MAX_VALUE} if not set. + * Returns maximum value of the RSSI for the scan filter. {@link Integer#MAX_VALUE} if not set. */ public int getMaxRssi() { return mMaxRssi; @@ -272,7 +272,7 @@ public final class ScanFilter implements Parcelable { } BluetoothDevice device = scanResult.getDevice(); // Device match. - if (mMacAddress != null && (device == null || !mMacAddress.equals(device.getAddress()))) { + if (mDeviceAddress != null && (device == null || !mDeviceAddress.equals(device.getAddress()))) { return false; } @@ -286,13 +286,13 @@ public final class ScanFilter implements Parcelable { // Scan record is null but there exist filters on it. if (scanRecord == null - && (mLocalName != null || mServiceUuid != null || mManufacturerData != null + && (mDeviceName != null || mServiceUuid != null || mManufacturerData != null || mServiceData != null)) { return false; } // Local name match. - if (mLocalName != null && !mLocalName.equals(scanRecord.getLocalName())) { + if (mDeviceName != null && !mDeviceName.equals(scanRecord.getDeviceName())) { return false; } @@ -367,7 +367,7 @@ public final class ScanFilter implements Parcelable { @Override public String toString() { - return "BluetoothLeScanFilter [mLocalName=" + mLocalName + ", mMacAddress=" + mMacAddress + return "BluetoothLeScanFilter [mDeviceName=" + mDeviceName + ", mDeviceAddress=" + mDeviceAddress + ", mUuid=" + mServiceUuid + ", mUuidMask=" + mServiceUuidMask + ", mServiceData=" + Arrays.toString(mServiceData) + ", mServiceDataMask=" + Arrays.toString(mServiceDataMask) + ", mManufacturerId=" + mManufacturerId @@ -378,7 +378,7 @@ public final class ScanFilter implements Parcelable { @Override public int hashCode() { - return Objects.hash(mLocalName, mMacAddress, mManufacturerId, mManufacturerData, + return Objects.hash(mDeviceName, mDeviceAddress, mManufacturerId, mManufacturerData, mManufacturerDataMask, mMaxRssi, mMinRssi, mServiceData, mServiceDataMask, mServiceUuid, mServiceUuidMask); } @@ -392,8 +392,8 @@ public final class ScanFilter implements Parcelable { return false; } ScanFilter other = (ScanFilter) obj; - return Objects.equals(mLocalName, other.mLocalName) && - Objects.equals(mMacAddress, other.mMacAddress) && + return Objects.equals(mDeviceName, other.mDeviceName) && + Objects.equals(mDeviceAddress, other.mDeviceAddress) && mManufacturerId == other.mManufacturerId && Objects.deepEquals(mManufacturerData, other.mManufacturerData) && Objects.deepEquals(mManufacturerDataMask, other.mManufacturerDataMask) && @@ -409,8 +409,8 @@ public final class ScanFilter implements Parcelable { */ public static final class Builder { - private String mLocalName; - private String mMacAddress; + private String mDeviceName; + private String mDeviceAddress; private ParcelUuid mServiceUuid; private ParcelUuid mUuidMask; @@ -426,26 +426,26 @@ public final class ScanFilter implements Parcelable { private int mMaxRssi = Integer.MAX_VALUE; /** - * Set filter on local name. + * Set filter on device name. */ - public Builder setName(String localName) { - mLocalName = localName; + public Builder setDeviceName(String deviceName) { + mDeviceName = deviceName; return this; } /** - * Set filter on device mac address. + * Set filter on device address. * - * @param macAddress The device mac address for the filter. It needs to be in the format of - * "01:02:03:AB:CD:EF". The mac address can be validated using + * @param deviceAddress The device Bluetooth address for the filter. It needs to be in + * the format of "01:02:03:AB:CD:EF". The device address can be validated using * {@link BluetoothAdapter#checkBluetoothAddress}. - * @throws IllegalArgumentException If the {@code macAddress} is invalid. + * @throws IllegalArgumentException If the {@code deviceAddress} is invalid. */ - public Builder setMacAddress(String macAddress) { - if (macAddress != null && !BluetoothAdapter.checkBluetoothAddress(macAddress)) { - throw new IllegalArgumentException("invalid mac address " + macAddress); + public Builder setDeviceAddress(String deviceAddress) { + if (deviceAddress != null && !BluetoothAdapter.checkBluetoothAddress(deviceAddress)) { + throw new IllegalArgumentException("invalid device address " + deviceAddress); } - mMacAddress = macAddress; + mDeviceAddress = deviceAddress; return this; } @@ -564,7 +564,7 @@ public final class ScanFilter implements Parcelable { } /** - * Set the desired rssi range for the filter. A scan result with rssi in the range of + * Set the desired RSSI range for the filter. A scan result with RSSI in the range of * [minRssi, maxRssi] will be consider as a match. */ public Builder setRssiRange(int minRssi, int maxRssi) { @@ -579,7 +579,7 @@ public final class ScanFilter implements Parcelable { * @throws IllegalArgumentException If the filter cannot be built. */ public ScanFilter build() { - return new ScanFilter(mLocalName, mMacAddress, + return new ScanFilter(mDeviceName, mDeviceAddress, mServiceUuid, mUuidMask, mServiceData, mServiceDataMask, mManufacturerId, mManufacturerData, mManufacturerDataMask, mMinRssi, mMaxRssi); diff --git a/core/java/android/bluetooth/le/ScanRecord.java b/core/java/android/bluetooth/le/ScanRecord.java index bd7304b..fc46e76 100644 --- a/core/java/android/bluetooth/le/ScanRecord.java +++ b/core/java/android/bluetooth/le/ScanRecord.java @@ -66,7 +66,7 @@ public final class ScanRecord { private final int mTxPowerLevel; // Local name of the Bluetooth LE device. - private final String mLocalName; + private final String mDeviceName; /** * Returns the advertising flags indicating the discoverable mode and capability of the device. @@ -77,7 +77,7 @@ public final class ScanRecord { } /** - * Returns a list of service uuids within the advertisement that are used to identify the + * Returns a list of service UUIDs within the advertisement that are used to identify the * bluetooth gatt services. */ public List<ParcelUuid> getServiceUuids() { @@ -94,22 +94,21 @@ public final class ScanRecord { /** * Returns the manufacturer specific data which is the content of manufacturer specific data - * field. The first 2 bytes of the data contain the company id. + * field. */ public byte[] getManufacturerSpecificData() { return mManufacturerSpecificData; } /** - * Returns a 16 bit uuid of the service that the service data is associated with. + * Returns a 16-bit UUID of the service that the service data is associated with. */ public ParcelUuid getServiceDataUuid() { return mServiceDataUuid; } /** - * Returns service data. The first two bytes should be a 16 bit service uuid associated with the - * service data. + * Returns service data. */ public byte[] getServiceData() { return mServiceData; @@ -130,8 +129,8 @@ public final class ScanRecord { * Returns the local name of the BLE device. The is a UTF-8 encoded string. */ @Nullable - public String getLocalName() { - return mLocalName; + public String getDeviceName() { + return mDeviceName; } private ScanRecord(List<ParcelUuid> serviceUuids, @@ -144,7 +143,7 @@ public final class ScanRecord { mManufacturerSpecificData = manufacturerSpecificData; mServiceDataUuid = serviceDataUuid; mServiceData = serviceData; - mLocalName = localName; + mDeviceName = localName; mAdvertiseFlags = advertiseFlags; mTxPowerLevel = txPowerLevel; } @@ -155,7 +154,7 @@ public final class ScanRecord { + ", mManufacturerId=" + mManufacturerId + ", mManufacturerSpecificData=" + Arrays.toString(mManufacturerSpecificData) + ", mServiceDataUuid=" + mServiceDataUuid + ", mServiceData=" + Arrays.toString(mServiceData) - + ", mTxPowerLevel=" + mTxPowerLevel + ", mLocalName=" + mLocalName + "]"; + + ", mTxPowerLevel=" + mTxPowerLevel + ", mDeviceName=" + mDeviceName + "]"; } /** @@ -223,7 +222,7 @@ public final class ScanRecord { break; case DATA_TYPE_SERVICE_DATA: serviceData = extractBytes(scanRecord, currentPos, dataLength); - // The first two bytes of the service data are service data uuid. + // The first two bytes of the service data are service data UUID. int serviceUuidLength = BluetoothUuid.UUID_BYTES_16_BIT; byte[] serviceDataUuidBytes = extractBytes(scanRecord, currentPos, serviceUuidLength); @@ -256,7 +255,7 @@ public final class ScanRecord { } } - // Parse service uuids. + // Parse service UUIDs. private static int parseServiceUuid(byte[] scanRecord, int currentPos, int dataLength, int uuidLength, List<ParcelUuid> serviceUuids) { while (dataLength > 0) { diff --git a/core/java/android/bluetooth/le/ScanSettings.java b/core/java/android/bluetooth/le/ScanSettings.java index 7c0f9e1..2097702 100644 --- a/core/java/android/bluetooth/le/ScanSettings.java +++ b/core/java/android/bluetooth/le/ScanSettings.java @@ -16,54 +16,66 @@ package android.bluetooth.le; +import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; /** - * Settings for Bluetooth LE scan. + * Bluetooth LE scan settings are passed to {@link BluetoothLeScanner#startScan} + * to define the parameters for the scan. */ public final class ScanSettings implements Parcelable { /** - * Perform Bluetooth LE scan in low power mode. This is the default scan mode as it consumes the - * least power. + * Perform Bluetooth LE scan in low power mode. + * This is the default scan mode as it consumes the least power. */ public static final int SCAN_MODE_LOW_POWER = 0; + /** * Perform Bluetooth LE scan in balanced power mode. + * Scan results are returned at a rate that provides a good trade-off between scan + * frequency and power consumption. */ public static final int SCAN_MODE_BALANCED = 1; + /** - * Scan using highest duty cycle. It's recommended only using this mode when the application is - * running in foreground. + * Scan using highest duty cycle. + * It's recommended to only use this mode when the application is running in the foreground. */ public static final int SCAN_MODE_LOW_LATENCY = 2; /** - * Callback each time when a bluetooth advertisement is found. + * Triggger a callback for every Bluetooth advertisement found that matches the + * filter criteria. If no filter is active, all advertisement packets are reported. */ - public static final int CALLBACK_TYPE_ON_UPDATE = 0; + public static final int CALLBACK_TYPE_ALL_MATCHES = 1; + /** - * Callback when a bluetooth advertisement is found for the first time. + * A result callback is only triggered for the first advertisement packet received that + * matches the filter criteria. */ - public static final int CALLBACK_TYPE_ON_FOUND = 1; + public static final int CALLBACK_TYPE_FIRST_MATCH = 2; + /** - * Callback when a bluetooth advertisement is found for the first time, then lost. + * Receive a callback when advertisements are no longer received from a device that has been + * previously reported by a first match callback. */ - public static final int CALLBACK_TYPE_ON_LOST = 2; + public static final int CALLBACK_TYPE_MATCH_LOST = 4; /** - * Full scan result which contains device mac address, rssi, advertising and scan response and - * scan timestamp. + * Request full scan results which contain the device, rssi, advertising data, scan response + * as well as the scan timestamp. */ public static final int SCAN_RESULT_TYPE_FULL = 0; + /** - * Truncated scan result which contains device mac address, rssi and scan timestamp. Note it's - * possible for an app to get more scan results that it asks if there are multiple apps using - * this type. TODO: decide whether we could unhide this setting. - * + * Request abbreviated scan results which contain the device, rssi and scan timestamp. + * <p><b>Note:</b> It is possible for an application to get more scan results than + * it asked for, if there are multiple apps using this type. * @hide */ - public static final int SCAN_RESULT_TYPE_TRUNCATED = 1; + @SystemApi + public static final int SCAN_RESULT_TYPE_ABBREVIATED = 1; // Bluetooth LE scan mode. private int mScanMode; @@ -75,7 +87,7 @@ public final class ScanSettings implements Parcelable { private int mScanResultType; // Time of delay for reporting the scan result - private long mReportDelayNanos; + private long mReportDelaySeconds; public int getScanMode() { return mScanMode; @@ -92,23 +104,23 @@ public final class ScanSettings implements Parcelable { /** * Returns report delay timestamp based on the device clock. */ - public long getReportDelayNanos() { - return mReportDelayNanos; + public long getReportDelaySeconds() { + return mReportDelaySeconds; } private ScanSettings(int scanMode, int callbackType, int scanResultType, - long reportDelayNanos) { + long reportDelaySeconds) { mScanMode = scanMode; mCallbackType = callbackType; mScanResultType = scanResultType; - mReportDelayNanos = reportDelayNanos; + mReportDelaySeconds = reportDelaySeconds; } private ScanSettings(Parcel in) { mScanMode = in.readInt(); mCallbackType = in.readInt(); mScanResultType = in.readInt(); - mReportDelayNanos = in.readLong(); + mReportDelaySeconds = in.readLong(); } @Override @@ -116,7 +128,7 @@ public final class ScanSettings implements Parcelable { dest.writeInt(mScanMode); dest.writeInt(mCallbackType); dest.writeInt(mScanResultType); - dest.writeLong(mReportDelayNanos); + dest.writeLong(mReportDelaySeconds); } @Override @@ -142,15 +154,14 @@ public final class ScanSettings implements Parcelable { */ public static final class Builder { private int mScanMode = SCAN_MODE_LOW_POWER; - private int mCallbackType = CALLBACK_TYPE_ON_UPDATE; + private int mCallbackType = CALLBACK_TYPE_ALL_MATCHES; private int mScanResultType = SCAN_RESULT_TYPE_FULL; - private long mReportDelayNanos = 0; + private long mReportDelaySeconds = 0; /** * Set scan mode for Bluetooth LE scan. * - * @param scanMode The scan mode can be one of - * {@link ScanSettings#SCAN_MODE_LOW_POWER}, + * @param scanMode The scan mode can be one of {@link ScanSettings#SCAN_MODE_LOW_POWER}, * {@link ScanSettings#SCAN_MODE_BALANCED} or * {@link ScanSettings#SCAN_MODE_LOW_LATENCY}. * @throws IllegalArgumentException If the {@code scanMode} is invalid. @@ -166,13 +177,13 @@ public final class ScanSettings implements Parcelable { /** * Set callback type for Bluetooth LE scan. * - * @param callbackType The callback type for the scan. Can only be - * {@link ScanSettings#CALLBACK_TYPE_ON_UPDATE}. + * @param callbackType The callback type flags for the scan. * @throws IllegalArgumentException If the {@code callbackType} is invalid. */ public Builder setCallbackType(int callbackType) { - if (callbackType < CALLBACK_TYPE_ON_UPDATE - || callbackType > CALLBACK_TYPE_ON_LOST) { + if (callbackType < CALLBACK_TYPE_ALL_MATCHES + || callbackType > (CALLBACK_TYPE_FIRST_MATCH | CALLBACK_TYPE_MATCH_LOST) + || (callbackType & CALLBACK_TYPE_ALL_MATCHES) != CALLBACK_TYPE_ALL_MATCHES) { throw new IllegalArgumentException("invalid callback type - " + callbackType); } mCallbackType = callbackType; @@ -184,14 +195,14 @@ public final class ScanSettings implements Parcelable { * * @param scanResultType Type for scan result, could be either * {@link ScanSettings#SCAN_RESULT_TYPE_FULL} or - * {@link ScanSettings#SCAN_RESULT_TYPE_TRUNCATED}. + * {@link ScanSettings#SCAN_RESULT_TYPE_ABBREVIATED}. * @throws IllegalArgumentException If the {@code scanResultType} is invalid. - * * @hide */ + @SystemApi public Builder setScanResultType(int scanResultType) { if (scanResultType < SCAN_RESULT_TYPE_FULL - || scanResultType > SCAN_RESULT_TYPE_TRUNCATED) { + || scanResultType > SCAN_RESULT_TYPE_ABBREVIATED) { throw new IllegalArgumentException( "invalid scanResultType - " + scanResultType); } @@ -201,9 +212,13 @@ public final class ScanSettings implements Parcelable { /** * Set report delay timestamp for Bluetooth LE scan. + * @param reportDelaySeconds Set to 0 to be notified of results immediately. + * Values >0 causes the scan results to be queued + * up and delivered after the requested delay or when + * the internal buffers fill up. */ - public Builder setReportDelayNanos(long reportDelayNanos) { - mReportDelayNanos = reportDelayNanos; + public Builder setReportDelaySeconds(long reportDelaySeconds) { + mReportDelaySeconds = reportDelaySeconds; return this; } @@ -212,7 +227,7 @@ public final class ScanSettings implements Parcelable { */ public ScanSettings build() { return new ScanSettings(mScanMode, mCallbackType, mScanResultType, - mReportDelayNanos); + mReportDelaySeconds); } } } |