Merge "Bluetooth 5 enhanced scanning API"

This commit is contained in:
Jakub Pawlowski
2017-03-08 19:02:57 +00:00
committed by Gerrit Code Review
5 changed files with 350 additions and 16 deletions

View File

@@ -7544,19 +7544,37 @@ package android.bluetooth.le {
}
public final class ScanResult implements android.os.Parcelable {
ctor public ScanResult(android.bluetooth.BluetoothDevice, android.bluetooth.le.ScanRecord, int, long);
ctor public deprecated ScanResult(android.bluetooth.BluetoothDevice, android.bluetooth.le.ScanRecord, int, long);
ctor public ScanResult(android.bluetooth.BluetoothDevice, int, int, int, int, int, int, int, android.bluetooth.le.ScanRecord, long);
method public int describeContents();
method public int getAdvertisingSid();
method public int getDataStatus();
method public android.bluetooth.BluetoothDevice getDevice();
method public int getPeriodicAdvertisingInterval();
method public int getPrimaryPhy();
method public int getRssi();
method public android.bluetooth.le.ScanRecord getScanRecord();
method public int getSecondaryPhy();
method public long getTimestampNanos();
method public int getTxPower();
method public boolean isConnectable();
method public boolean isLegacy();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.bluetooth.le.ScanResult> CREATOR;
field public static final int DATA_COMPLETE = 0; // 0x0
field public static final int DATA_TRUNCATED = 2; // 0x2
field public static final int PHY_LE_1M = 1; // 0x1
field public static final int PHY_LE_2M = 2; // 0x2
field public static final int PHY_LE_CODED = 3; // 0x3
field public static final int PHY_UNUSED = 0; // 0x0
field public static final int SID_NOT_PRESENT = 255; // 0xff
}
public final class ScanSettings implements android.os.Parcelable {
method public int describeContents();
method public int getCallbackType();
method public boolean getLegacy();
method public int getPhy();
method public long getReportDelayMillis();
method public int getScanMode();
method public int getScanResultType();
@@ -7570,6 +7588,9 @@ package android.bluetooth.le {
field public static final int MATCH_NUM_FEW_ADVERTISEMENT = 2; // 0x2
field public static final int MATCH_NUM_MAX_ADVERTISEMENT = 3; // 0x3
field public static final int MATCH_NUM_ONE_ADVERTISEMENT = 1; // 0x1
field public static final int PHY_LE_1M = 1; // 0x1
field public static final int PHY_LE_ALL_SUPPORTED = 255; // 0xff
field public static final int PHY_LE_CODED = 3; // 0x3
field public static final int SCAN_MODE_BALANCED = 1; // 0x1
field public static final int SCAN_MODE_LOW_LATENCY = 2; // 0x2
field public static final int SCAN_MODE_LOW_POWER = 0; // 0x0
@@ -7580,8 +7601,10 @@ package android.bluetooth.le {
ctor public ScanSettings.Builder();
method public android.bluetooth.le.ScanSettings build();
method public android.bluetooth.le.ScanSettings.Builder setCallbackType(int);
method public android.bluetooth.le.ScanSettings.Builder setLegacy(boolean);
method public android.bluetooth.le.ScanSettings.Builder setMatchMode(int);
method public android.bluetooth.le.ScanSettings.Builder setNumOfMatches(int);
method public android.bluetooth.le.ScanSettings.Builder setPhy(int);
method public android.bluetooth.le.ScanSettings.Builder setReportDelay(long);
method public android.bluetooth.le.ScanSettings.Builder setScanMode(int);
}

View File

@@ -7861,19 +7861,37 @@ package android.bluetooth.le {
}
public final class ScanResult implements android.os.Parcelable {
ctor public ScanResult(android.bluetooth.BluetoothDevice, android.bluetooth.le.ScanRecord, int, long);
ctor public deprecated ScanResult(android.bluetooth.BluetoothDevice, android.bluetooth.le.ScanRecord, int, long);
ctor public ScanResult(android.bluetooth.BluetoothDevice, int, int, int, int, int, int, int, android.bluetooth.le.ScanRecord, long);
method public int describeContents();
method public int getAdvertisingSid();
method public int getDataStatus();
method public android.bluetooth.BluetoothDevice getDevice();
method public int getPeriodicAdvertisingInterval();
method public int getPrimaryPhy();
method public int getRssi();
method public android.bluetooth.le.ScanRecord getScanRecord();
method public int getSecondaryPhy();
method public long getTimestampNanos();
method public int getTxPower();
method public boolean isConnectable();
method public boolean isLegacy();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.bluetooth.le.ScanResult> CREATOR;
field public static final int DATA_COMPLETE = 0; // 0x0
field public static final int DATA_TRUNCATED = 2; // 0x2
field public static final int PHY_LE_1M = 1; // 0x1
field public static final int PHY_LE_2M = 2; // 0x2
field public static final int PHY_LE_CODED = 3; // 0x3
field public static final int PHY_UNUSED = 0; // 0x0
field public static final int SID_NOT_PRESENT = 255; // 0xff
}
public final class ScanSettings implements android.os.Parcelable {
method public int describeContents();
method public int getCallbackType();
method public boolean getLegacy();
method public int getPhy();
method public long getReportDelayMillis();
method public int getScanMode();
method public int getScanResultType();
@@ -7887,6 +7905,9 @@ package android.bluetooth.le {
field public static final int MATCH_NUM_FEW_ADVERTISEMENT = 2; // 0x2
field public static final int MATCH_NUM_MAX_ADVERTISEMENT = 3; // 0x3
field public static final int MATCH_NUM_ONE_ADVERTISEMENT = 1; // 0x1
field public static final int PHY_LE_1M = 1; // 0x1
field public static final int PHY_LE_ALL_SUPPORTED = 255; // 0xff
field public static final int PHY_LE_CODED = 3; // 0x3
field public static final int SCAN_MODE_BALANCED = 1; // 0x1
field public static final int SCAN_MODE_LOW_LATENCY = 2; // 0x2
field public static final int SCAN_MODE_LOW_POWER = 0; // 0x0
@@ -7899,8 +7920,10 @@ package android.bluetooth.le {
ctor public ScanSettings.Builder();
method public android.bluetooth.le.ScanSettings build();
method public android.bluetooth.le.ScanSettings.Builder setCallbackType(int);
method public android.bluetooth.le.ScanSettings.Builder setLegacy(boolean);
method public android.bluetooth.le.ScanSettings.Builder setMatchMode(int);
method public android.bluetooth.le.ScanSettings.Builder setNumOfMatches(int);
method public android.bluetooth.le.ScanSettings.Builder setPhy(int);
method public android.bluetooth.le.ScanSettings.Builder setReportDelay(long);
method public android.bluetooth.le.ScanSettings.Builder setScanMode(int);
method public android.bluetooth.le.ScanSettings.Builder setScanResultType(int);

View File

@@ -7553,19 +7553,37 @@ package android.bluetooth.le {
}
public final class ScanResult implements android.os.Parcelable {
ctor public ScanResult(android.bluetooth.BluetoothDevice, android.bluetooth.le.ScanRecord, int, long);
ctor public deprecated ScanResult(android.bluetooth.BluetoothDevice, android.bluetooth.le.ScanRecord, int, long);
ctor public ScanResult(android.bluetooth.BluetoothDevice, int, int, int, int, int, int, int, android.bluetooth.le.ScanRecord, long);
method public int describeContents();
method public int getAdvertisingSid();
method public int getDataStatus();
method public android.bluetooth.BluetoothDevice getDevice();
method public int getPeriodicAdvertisingInterval();
method public int getPrimaryPhy();
method public int getRssi();
method public android.bluetooth.le.ScanRecord getScanRecord();
method public int getSecondaryPhy();
method public long getTimestampNanos();
method public int getTxPower();
method public boolean isConnectable();
method public boolean isLegacy();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.bluetooth.le.ScanResult> CREATOR;
field public static final int DATA_COMPLETE = 0; // 0x0
field public static final int DATA_TRUNCATED = 2; // 0x2
field public static final int PHY_LE_1M = 1; // 0x1
field public static final int PHY_LE_2M = 2; // 0x2
field public static final int PHY_LE_CODED = 3; // 0x3
field public static final int PHY_UNUSED = 0; // 0x0
field public static final int SID_NOT_PRESENT = 255; // 0xff
}
public final class ScanSettings implements android.os.Parcelable {
method public int describeContents();
method public int getCallbackType();
method public boolean getLegacy();
method public int getPhy();
method public long getReportDelayMillis();
method public int getScanMode();
method public int getScanResultType();
@@ -7579,6 +7597,9 @@ package android.bluetooth.le {
field public static final int MATCH_NUM_FEW_ADVERTISEMENT = 2; // 0x2
field public static final int MATCH_NUM_MAX_ADVERTISEMENT = 3; // 0x3
field public static final int MATCH_NUM_ONE_ADVERTISEMENT = 1; // 0x1
field public static final int PHY_LE_1M = 1; // 0x1
field public static final int PHY_LE_ALL_SUPPORTED = 255; // 0xff
field public static final int PHY_LE_CODED = 3; // 0x3
field public static final int SCAN_MODE_BALANCED = 1; // 0x1
field public static final int SCAN_MODE_LOW_LATENCY = 2; // 0x2
field public static final int SCAN_MODE_LOW_POWER = 0; // 0x0
@@ -7589,8 +7610,10 @@ package android.bluetooth.le {
ctor public ScanSettings.Builder();
method public android.bluetooth.le.ScanSettings build();
method public android.bluetooth.le.ScanSettings.Builder setCallbackType(int);
method public android.bluetooth.le.ScanSettings.Builder setLegacy(boolean);
method public android.bluetooth.le.ScanSettings.Builder setMatchMode(int);
method public android.bluetooth.le.ScanSettings.Builder setNumOfMatches(int);
method public android.bluetooth.le.ScanSettings.Builder setPhy(int);
method public android.bluetooth.le.ScanSettings.Builder setReportDelay(long);
method public android.bluetooth.le.ScanSettings.Builder setScanMode(int);
}

View File

@@ -27,7 +27,56 @@ import java.util.Objects;
* ScanResult for Bluetooth LE scan.
*/
public final class ScanResult implements Parcelable {
// Remote bluetooth device.
/**
* For chained advertisements, inidcates tha the data contained in this
* scan result is complete.
*/
public static final int DATA_COMPLETE = 0x00;
/**
* For chained advertisements, indicates that the controller was
* unable to receive all chained packets and the scan result contains
* incomplete truncated data.
*/
public static final int DATA_TRUNCATED = 0x02;
/**
* Indicates that the secondary physical layer was not used.
*/
public static final int PHY_UNUSED = 0x00;
/**
* Bluetooth LE 1Mbit advertiser PHY.
*/
public static final int PHY_LE_1M = 0x01;
/**
* Bluetooth LE 2Mbit advertiser PHY.
*/
public static final int PHY_LE_2M = 0x02;
/**
* Bluetooth LE Coded advertiser PHY.
*/
public static final int PHY_LE_CODED = 0x03;
/**
* Advertising Set ID is not present in the packet.
*/
public static final int SID_NOT_PRESENT = 0xFF;
/**
* Mask for checking wether event type represents legacy advertisement.
*/
private static final int ET_LEGACY_MASK = 0x10;
/**
* Mask for checking wether event type represents connectable advertisement.
*/
private static final int ET_CONNECTABLE_MASK = 0x01;
// Remote Bluetooth device.
private BluetoothDevice mDevice;
// Scan record, including advertising data and scan response data.
@@ -40,13 +89,21 @@ public final class ScanResult implements Parcelable {
// Device timestamp when the result was last seen.
private long mTimestampNanos;
private int mEventType;
private int mPrimaryPhy;
private int mSecondaryPhy;
private int mAdvertisingSid;
private int mTxPower;
private int mPeriodicAdvertisingInterval;
/**
* Constructor of scan result.
* Constructs a new ScanResult.
*
* @param device Remote bluetooth device that is found.
* @param device Remote Bluetooth device found.
* @param scanRecord Scan record including both advertising data and scan response data.
* @param rssi Received signal strength.
* @param timestampNanos Device timestamp when the scan result was observed.
* @param timestampNanos Timestamp at which the scan result was observed.
* @deprecated use {@link #ScanResult(BluetoothDevice, int, int, int, int, int, int, int, ScanRecord, long)}
*/
public ScanResult(BluetoothDevice device, ScanRecord scanRecord, int rssi,
long timestampNanos) {
@@ -54,6 +111,41 @@ public final class ScanResult implements Parcelable {
mScanRecord = scanRecord;
mRssi = rssi;
mTimestampNanos = timestampNanos;
mEventType = (DATA_COMPLETE << 5) | ET_LEGACY_MASK | ET_CONNECTABLE_MASK;
mPrimaryPhy = PHY_LE_1M;
mSecondaryPhy = PHY_UNUSED;
mAdvertisingSid = SID_NOT_PRESENT;
mTxPower = 127;
mPeriodicAdvertisingInterval = 0;
}
/**
* Constructs a new ScanResult.
*
* @param device Remote Bluetooth device found.
* @param eventType Event type.
* @param primaryPhy Primary advertising phy.
* @param secondaryPhy Secondary advertising phy.
* @param advertisingSid Advertising set ID.
* @param txPower Transmit power.
* @param rssi Received signal strength.
* @param periodicAdvertisingInterval Periodic advertising interval.
* @param scanRecord Scan record including both advertising data and scan response data.
* @param timestampNanos Timestamp at which the scan result was observed.
*/
public ScanResult(BluetoothDevice device, int eventType, int primaryPhy, int secondaryPhy,
int advertisingSid, int txPower, int rssi, int periodicAdvertisingInterval,
ScanRecord scanRecord, long timestampNanos) {
mDevice = device;
mEventType = eventType;
mPrimaryPhy = primaryPhy;
mSecondaryPhy = secondaryPhy;
mAdvertisingSid = advertisingSid;
mTxPower = txPower;
mRssi = rssi;
mPeriodicAdvertisingInterval = periodicAdvertisingInterval;
mScanRecord = scanRecord;
mTimestampNanos = timestampNanos;
}
private ScanResult(Parcel in) {
@@ -76,6 +168,12 @@ public final class ScanResult implements Parcelable {
}
dest.writeInt(mRssi);
dest.writeLong(mTimestampNanos);
dest.writeInt(mEventType);
dest.writeInt(mPrimaryPhy);
dest.writeInt(mSecondaryPhy);
dest.writeInt(mAdvertisingSid);
dest.writeInt(mTxPower);
dest.writeInt(mPeriodicAdvertisingInterval);
}
private void readFromParcel(Parcel in) {
@@ -87,6 +185,12 @@ public final class ScanResult implements Parcelable {
}
mRssi = in.readInt();
mTimestampNanos = in.readLong();
mEventType = in.readInt();
mPrimaryPhy = in.readInt();
mSecondaryPhy = in.readInt();
mAdvertisingSid = in.readInt();
mTxPower = in.readInt();
mPeriodicAdvertisingInterval = in.readInt();
}
@Override
@@ -95,7 +199,7 @@ public final class ScanResult implements Parcelable {
}
/**
* Returns the remote bluetooth device identified by the bluetooth device address.
* Returns the remote Bluetooth device identified by the Bluetooth device address.
*/
public BluetoothDevice getDevice() {
return mDevice;
@@ -123,9 +227,79 @@ public final class ScanResult implements Parcelable {
return mTimestampNanos;
}
/**
* Returns true if this object represents legacy scan result.
* Legacy scan results do not contain advanced advertising information
* as specified in the Bluetooth Core Specification v5.
*/
public boolean isLegacy() {
return (mEventType & ET_LEGACY_MASK) != 0;
}
/**
* Returns true if this object represents connectable scan result.
*/
public boolean isConnectable() {
return (mEventType & ET_CONNECTABLE_MASK) != 0;
}
/**
* Returns the data status.
* Can be one of {@link ScanResult#DATA_COMPLETE} or
* {@link ScanResult#DATA_TRUNCATED}.
*/
public int getDataStatus() {
// return bit 5 and 6
return (mEventType >> 5) & 0x03;
}
/**
* Returns the primary Physical Layer
* on which this advertisment was received.
* Can be one of {@link ScanResult#PHY_LE_1M} or
* {@link ScanResult#PHY_LE_CODED}.
*/
public int getPrimaryPhy() { return mPrimaryPhy; }
/**
* Returns the secondary Physical Layer
* on which this advertisment was received.
* Can be one of {@link ScanResult#PHY_LE_1M},
* {@link ScanResult#PHY_LE_2M}, {@link ScanResult#PHY_LE_CODED}
* or {@link ScanResult#PHY_UNUSED} - if the advertisement
* was not received on a secondary physical channel.
*/
public int getSecondaryPhy() { return mSecondaryPhy; }
/**
* Returns the advertising set id.
* May return {@link ScanResult#SID_NOT_PRESENT} if
* no set id was is present.
*/
public int getAdvertisingSid() { return mAdvertisingSid; }
/**
* Returns the transmit power in dBm.
* Valid range is [-127, 126]. A value of 127 indicates that the
* advertisement did not indicate TX power.
*/
public int getTxPower() { return mTxPower; }
/**
* Returns the periodic advertising interval in units of 1.25ms.
* Valid range is 6 (7.5ms) to 65536 (81918.75ms). A value of 0 means
* periodic advertising is not used for this scan result.
*/
public int getPeriodicAdvertisingInterval() {
return mPeriodicAdvertisingInterval;
}
@Override
public int hashCode() {
return Objects.hash(mDevice, mRssi, mScanRecord, mTimestampNanos);
return Objects.hash(mDevice, mRssi, mScanRecord, mTimestampNanos,
mEventType, mPrimaryPhy, mSecondaryPhy,
mAdvertisingSid, mTxPower,
mPeriodicAdvertisingInterval);
}
@Override
@@ -138,15 +312,24 @@ public final class ScanResult implements Parcelable {
}
ScanResult other = (ScanResult) obj;
return Objects.equals(mDevice, other.mDevice) && (mRssi == other.mRssi) &&
Objects.equals(mScanRecord, other.mScanRecord)
&& (mTimestampNanos == other.mTimestampNanos);
Objects.equals(mScanRecord, other.mScanRecord) &&
(mTimestampNanos == other.mTimestampNanos) &&
mEventType == other.mEventType &&
mPrimaryPhy == other.mPrimaryPhy &&
mSecondaryPhy == other.mSecondaryPhy &&
mAdvertisingSid == other.mAdvertisingSid &&
mTxPower == other.mTxPower &&
mPeriodicAdvertisingInterval == other.mPeriodicAdvertisingInterval;
}
@Override
public String toString() {
return "ScanResult{" + "mDevice=" + mDevice + ", mScanRecord="
+ Objects.toString(mScanRecord) + ", mRssi=" + mRssi + ", mTimestampNanos="
+ mTimestampNanos + '}';
return "ScanResult{" + "device=" + mDevice + ", scanRecord=" +
Objects.toString(mScanRecord) + ", rssi=" + mRssi +
", timestampNanos=" + mTimestampNanos + ", eventType=" + mEventType +
", primaryPhy=" + mPrimaryPhy + ", secondaryPhy=" + mSecondaryPhy +
", advertisingSid=" + mAdvertisingSid + ", txPower=" + mTxPower +
", periodicAdvertisingInterval=" + mPeriodicAdvertisingInterval + '}';
}
public static final Parcelable.Creator<ScanResult> CREATOR = new Creator<ScanResult>() {

View File

@@ -122,6 +122,24 @@ public final class ScanSettings implements Parcelable {
@SystemApi
public static final int SCAN_RESULT_TYPE_ABBREVIATED = 1;
/**
* Use the Bluetooth LE 1Mbit PHY for scanning.
*/
public static final int PHY_LE_1M = 1;
/**
* Use Bluetooth LE Coded PHY for scanning.
*/
public static final int PHY_LE_CODED = 3;
/**
* Use all supported PHYs for scanning.
* This will check the controller capabilities, and start
* the scan on 1Mbit and LE Coded PHYs if supported, or on
* the 1Mbit PHY only.
*/
public static final int PHY_LE_ALL_SUPPORTED = 255;
// Bluetooth LE scan mode.
private int mScanMode;
@@ -138,6 +156,11 @@ public final class ScanSettings implements Parcelable {
private int mNumOfMatchesPerFilter;
// Include only legacy advertising results
private boolean mLegacy;
private int mPhy;
public int getScanMode() {
return mScanMode;
}
@@ -164,6 +187,22 @@ public final class ScanSettings implements Parcelable {
return mNumOfMatchesPerFilter;
}
/**
* Returns whether only legacy advertisements will be returned.
* Legacy advertisements include advertisements as specified
* by the Bluetooth core specification 4.2 and below.
*/
public boolean getLegacy() {
return mLegacy;
}
/**
* Returns the physical layer used during a scan.
*/
public int getPhy() {
return mPhy;
}
/**
* Returns report delay timestamp based on the device clock.
*/
@@ -172,13 +211,16 @@ public final class ScanSettings implements Parcelable {
}
private ScanSettings(int scanMode, int callbackType, int scanResultType,
long reportDelayMillis, int matchMode, int numOfMatchesPerFilter) {
long reportDelayMillis, int matchMode,
int numOfMatchesPerFilter, boolean legacy, int phy) {
mScanMode = scanMode;
mCallbackType = callbackType;
mScanResultType = scanResultType;
mReportDelayMillis = reportDelayMillis;
mNumOfMatchesPerFilter = numOfMatchesPerFilter;
mMatchMode = matchMode;
mLegacy = legacy;
mPhy = phy;
}
private ScanSettings(Parcel in) {
@@ -188,6 +230,8 @@ public final class ScanSettings implements Parcelable {
mReportDelayMillis = in.readLong();
mMatchMode = in.readInt();
mNumOfMatchesPerFilter = in.readInt();
mLegacy = in.readInt() != 0 ? true : false;
mPhy = in.readInt();
}
@Override
@@ -198,6 +242,8 @@ public final class ScanSettings implements Parcelable {
dest.writeLong(mReportDelayMillis);
dest.writeInt(mMatchMode);
dest.writeInt(mNumOfMatchesPerFilter);
dest.writeInt(mLegacy ? 1 : 0);
dest.writeInt(mPhy);
}
@Override
@@ -228,6 +274,9 @@ public final class ScanSettings implements Parcelable {
private long mReportDelayMillis = 0;
private int mMatchMode = MATCH_MODE_AGGRESSIVE;
private int mNumOfMatchesPerFilter = MATCH_NUM_MAX_ADVERTISEMENT;
private boolean mLegacy = true;
private int mPhy = PHY_LE_ALL_SUPPORTED;
/**
* Set scan mode for Bluetooth LE scan.
*
@@ -340,12 +389,45 @@ public final class ScanSettings implements Parcelable {
return this;
}
/**
* Set whether only legacy advertisments should be returned in scan results.
* Legacy advertisements include advertisements as specified by the
* Bluetooth core specification 4.2 and below. This is true by default
* for compatibility with older apps.
*
* @param legacy true if only legacy advertisements will be returned
*/
public Builder setLegacy(boolean legacy) {
mLegacy = legacy;
return this;
}
/**
* Set the Physical Layer to use during this scan.
* This is used only if {@link ScanSettings.Builder#setLegacy}
* is set to false.
* {@link android.bluetooth.BluetoothAdapter#isLeCodedPhySupported}
* may be used to check whether LE Coded phy is supported by calling
* {@link android.bluetooth.BluetoothAdapter#isLeCodedPhySupported}.
* Selecting an unsupported phy will result in failure to start scan.
*
* @param phy Can be one of
* {@link ScanSettings#PHY_LE_1M},
* {@link ScanSettings#PHY_LE_CODED} or
* {@link ScanSettings#PHY_LE_ALL_SUPPORTED}
*/
public Builder setPhy(int phy) {
mPhy = phy;
return this;
}
/**
* Build {@link ScanSettings}.
*/
public ScanSettings build() {
return new ScanSettings(mScanMode, mCallbackType, mScanResultType,
mReportDelayMillis, mMatchMode, mNumOfMatchesPerFilter);
mReportDelayMillis, mMatchMode,
mNumOfMatchesPerFilter, mLegacy, mPhy);
}
}
}