Onfound onlost feature.

Change-Id: I5475cb21183abab8cf04af486ff7692396801b92
Signed-off-by: Prerepa Viswanadham <dham@google.com>
This commit is contained in:
Prerepa Viswanadham
2015-04-07 14:36:53 -07:00
parent 0326f585e1
commit e593d0aec6
6 changed files with 182 additions and 9 deletions

View File

@ -997,6 +997,24 @@ public final class BluetoothAdapter {
return false;
}
/**
* Return true if hardware has entries available for matching beacons
*
* @return true if there are hw entries available for matching beacons
* @hide
*/
public boolean isHardwareTrackingFiltersAvailable() {
if (getState() != STATE_ON) return false;
try {
synchronized(mManagerCallback) {
if(mService != null) return (mService.numOfHwTrackFiltersAvailable() != 0);
}
} catch (RemoteException e) {
Log.e(TAG, "", e);
}
return false;
}
/**
* Return the record of {@link BluetoothActivityEnergyInfo} object that
* has the activity and energy info. This can be used to ascertain what

View File

@ -98,6 +98,7 @@ interface IBluetooth
boolean isActivityAndEnergyReportingSupported();
void getActivityEnergyInfoFromController();
BluetoothActivityEnergyInfo reportActivityInfo();
int numOfHwTrackFiltersAvailable();
// for dumpsys support
String dump();

View File

@ -128,6 +128,16 @@ public final class BluetoothLeScanner {
ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED);
return;
}
if (!isHardwareResourcesAvailableForScan(settings)) {
postCallbackError(callback,
ScanCallback.SCAN_FAILED_OUT_OF_HARDWARE_RESOURCES);
return;
}
if (!isSettingsAndFilterComboAllowed(settings, filters)) {
postCallbackError(callback,
ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED);
return;
}
BleScanCallbackWrapper wrapper = new BleScanCallbackWrapper(gatt, filters,
settings, callback, resultStorages);
wrapper.startRegisteration();
@ -394,4 +404,33 @@ public final class BluetoothLeScanner {
}
return false;
}
private boolean isSettingsAndFilterComboAllowed(ScanSettings settings,
List <ScanFilter> filterList) {
final int callbackType = settings.getCallbackType();
// If onlost/onfound is requested, a non-empty filter is expected
if ((callbackType & ScanSettings.CALLBACK_TYPE_FIRST_MATCH
| ScanSettings.CALLBACK_TYPE_MATCH_LOST) != 0) {
if (filterList == null) {
return false;
}
for (ScanFilter filter : filterList) {
if (filter.isAllFieldsEmpty()) {
return false;
}
}
}
return true;
}
private boolean isHardwareResourcesAvailableForScan(ScanSettings settings) {
final int callbackType = settings.getCallbackType();
if ((callbackType & ScanSettings.CALLBACK_TYPE_FIRST_MATCH) != 0
|| (callbackType & ScanSettings.CALLBACK_TYPE_MATCH_LOST) != 0) {
// For onlost/onfound, we required hw support be available
return (mBluetoothAdapter.isOffloadedFilteringSupported() &&
mBluetoothAdapter.isHardwareTrackingFiltersAvailable());
}
return true;
}
}

View File

@ -44,11 +44,17 @@ public abstract class ScanCallback {
*/
public static final int SCAN_FAILED_FEATURE_UNSUPPORTED = 4;
/**
* Fails to start scan as it is out of hardware resources.
* @hide
*/
public static final int SCAN_FAILED_OUT_OF_HARDWARE_RESOURCES = 5;
/**
* Callback when a BLE advertisement has been found.
*
* @param callbackType Determines how this callback was triggered. Currently could only be
* {@link ScanSettings#CALLBACK_TYPE_ALL_MATCHES}.
* @param callbackType Determines how this callback was triggered. Could be of
* {@link ScanSettings#CALLBACK_TYPE_ALL_MATCHES}
* @param result A Bluetooth LE scan result.
*/
public void onScanResult(int callbackType, ScanResult result) {

View File

@ -67,6 +67,8 @@ public final class ScanFilter implements Parcelable {
private final byte[] mManufacturerData;
@Nullable
private final byte[] mManufacturerDataMask;
private static final ScanFilter EMPTY = new ScanFilter.Builder().build() ;
private ScanFilter(String name, String deviceAddress, ParcelUuid uuid,
ParcelUuid uuidMask, ParcelUuid serviceDataUuid,
@ -409,6 +411,14 @@ public final class ScanFilter implements Parcelable {
Objects.equals(mServiceUuidMask, other.mServiceUuidMask);
}
/**
* Checks if the scanfilter is empty
* @hide
*/
public boolean isAllFieldsEmpty() {
return EMPTY.equals(this);
}
/**
* Builder class for {@link ScanFilter}.
*/

View File

@ -59,7 +59,6 @@ public final class ScanSettings implements Parcelable {
/**
* A result callback is only triggered for the first advertisement packet received that matches
* the filter criteria.
*
* @hide
*/
@SystemApi
@ -68,15 +67,53 @@ public final class ScanSettings implements Parcelable {
/**
* Receive a callback when advertisements are no longer received from a device that has been
* previously reported by a first match callback.
*
* @hide
*/
@SystemApi
public static final int CALLBACK_TYPE_MATCH_LOST = 4;
/**
* Request full scan results which contain the device, rssi, advertising data, scan response as
* well as the scan timestamp.
* Determines how many advertisements to match per filter, as this is scarce hw resource
*/
/**
* Match one advertisement per filter
* @hide
*/
public static final int MATCH_NUM_ONE_ADVERTISEMENT = 1;
/**
* Match few advertisement per filter, depends on current capability and availibility of
* the resources in hw
* @hide
*/
public static final int MATCH_NUM_FEW_ADVERTISEMENT = 2;
/**
* Match as many advertisement per filter as hw could allow, depends on current
* capability and availibility of the resources in hw
* @hide
*/
public static final int MATCH_NUM_MAX_ADVERTISEMENT = 3;
/**
* In Aggressive mode, hw will determine a match sooner even with feeble signal strength
* and few number of sightings/match in a duration.
* @hide
*/
public static final int MATCH_MODE_AGGRESSIVE = 1;
/**
* For sticky mode, higher threshold of signal strength and sightings is required
* before reporting by hw
* @hide
*/
public static final int MATCH_MODE_STICKY = 2;
/**
* Request full scan results which contain the device, rssi, advertising data, scan response
* as well as the scan timestamp.
*
* @hide
*/
@ -106,6 +143,10 @@ public final class ScanSettings implements Parcelable {
// Time of delay for reporting the scan result
private long mReportDelayMillis;
private int mMatchMode;
private int mNumOfMatchesPerFilter;
public int getScanMode() {
return mScanMode;
}
@ -118,6 +159,20 @@ public final class ScanSettings implements Parcelable {
return mScanResultType;
}
/**
* @hide
*/
public int getMatchMode() {
return mMatchMode;
}
/**
* @hide
*/
public int getNumOfMatches() {
return mNumOfMatchesPerFilter;
}
/**
* Returns report delay timestamp based on the device clock.
*/
@ -126,11 +181,13 @@ public final class ScanSettings implements Parcelable {
}
private ScanSettings(int scanMode, int callbackType, int scanResultType,
long reportDelayMillis) {
long reportDelayMillis, int matchMode, int numOfMatchesPerFilter) {
mScanMode = scanMode;
mCallbackType = callbackType;
mScanResultType = scanResultType;
mReportDelayMillis = reportDelayMillis;
mNumOfMatchesPerFilter = numOfMatchesPerFilter;
mMatchMode = numOfMatchesPerFilter;
}
private ScanSettings(Parcel in) {
@ -138,6 +195,8 @@ public final class ScanSettings implements Parcelable {
mCallbackType = in.readInt();
mScanResultType = in.readInt();
mReportDelayMillis = in.readLong();
mMatchMode = in.readInt();
mNumOfMatchesPerFilter = in.readInt();
}
@Override
@ -146,6 +205,8 @@ public final class ScanSettings implements Parcelable {
dest.writeInt(mCallbackType);
dest.writeInt(mScanResultType);
dest.writeLong(mReportDelayMillis);
dest.writeInt(mMatchMode);
dest.writeInt(mNumOfMatchesPerFilter);
}
@Override
@ -174,7 +235,8 @@ public final class ScanSettings implements Parcelable {
private int mCallbackType = CALLBACK_TYPE_ALL_MATCHES;
private int mScanResultType = SCAN_RESULT_TYPE_FULL;
private long mReportDelayMillis = 0;
private int mMatchMode = MATCH_MODE_AGGRESSIVE;
private int mNumOfMatchesPerFilter = MATCH_NUM_ONE_ADVERTISEMENT;
/**
* Set scan mode for Bluetooth LE scan.
*
@ -254,12 +316,49 @@ public final class ScanSettings implements Parcelable {
return this;
}
/**
* Set the number of matches for Bluetooth LE scan filters hardware match
*
* @param numOfMatches The num of matches can be one of
* {@link ScanSettings#MATCH_NUM_ONE_ADVERTISEMENT} or
* {@link ScanSettings#MATCH_NUM_FEW_ADVERTISEMENT} or
* {@link ScanSettings#MATCH_NUM_MAX_ADVERTISEMENT}
* @throws IllegalArgumentException If the {@code matchMode} is invalid.
* @hide
*/
public Builder setNumOfMatches(int numOfMatches) {
if (numOfMatches < MATCH_NUM_ONE_ADVERTISEMENT
|| numOfMatches > MATCH_NUM_MAX_ADVERTISEMENT) {
throw new IllegalArgumentException("invalid numOfMatches " + numOfMatches);
}
mNumOfMatchesPerFilter = numOfMatches;
return this;
}
/**
* Set match mode for Bluetooth LE scan filters hardware match
*
* @param matchMode The match mode can be one of
* {@link ScanSettings#MATCH_MODE_AGGRESSIVE} or
* {@link ScanSettings#MATCH_MODE_STICKY}
* @throws IllegalArgumentException If the {@code matchMode} is invalid.
* @hide
*/
public Builder setMatchMode(int matchMode) {
if (matchMode < MATCH_MODE_AGGRESSIVE
|| matchMode > MATCH_MODE_STICKY) {
throw new IllegalArgumentException("invalid matchMode " + matchMode);
}
mMatchMode = matchMode;
return this;
}
/**
* Build {@link ScanSettings}.
*/
public ScanSettings build() {
return new ScanSettings(mScanMode, mCallbackType, mScanResultType,
mReportDelayMillis);
mReportDelayMillis, mMatchMode, mNumOfMatchesPerFilter);
}
}
}