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 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 * Return the record of {@link BluetoothActivityEnergyInfo} object that
* has the activity and energy info. This can be used to ascertain what * has the activity and energy info. This can be used to ascertain what

View File

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

View File

@ -128,6 +128,16 @@ public final class BluetoothLeScanner {
ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED); ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED);
return; 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, BleScanCallbackWrapper wrapper = new BleScanCallbackWrapper(gatt, filters,
settings, callback, resultStorages); settings, callback, resultStorages);
wrapper.startRegisteration(); wrapper.startRegisteration();
@ -394,4 +404,33 @@ public final class BluetoothLeScanner {
} }
return false; 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; 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. * Callback when a BLE advertisement has been found.
* *
* @param callbackType Determines how this callback was triggered. Currently could only be * @param callbackType Determines how this callback was triggered. Could be of
* {@link ScanSettings#CALLBACK_TYPE_ALL_MATCHES}. * {@link ScanSettings#CALLBACK_TYPE_ALL_MATCHES}
* @param result A Bluetooth LE scan result. * @param result A Bluetooth LE scan result.
*/ */
public void onScanResult(int callbackType, ScanResult result) { public void onScanResult(int callbackType, ScanResult result) {

View File

@ -67,6 +67,8 @@ public final class ScanFilter implements Parcelable {
private final byte[] mManufacturerData; private final byte[] mManufacturerData;
@Nullable @Nullable
private final byte[] mManufacturerDataMask; private final byte[] mManufacturerDataMask;
private static final ScanFilter EMPTY = new ScanFilter.Builder().build() ;
private ScanFilter(String name, String deviceAddress, ParcelUuid uuid, private ScanFilter(String name, String deviceAddress, ParcelUuid uuid,
ParcelUuid uuidMask, ParcelUuid serviceDataUuid, ParcelUuid uuidMask, ParcelUuid serviceDataUuid,
@ -409,6 +411,14 @@ public final class ScanFilter implements Parcelable {
Objects.equals(mServiceUuidMask, other.mServiceUuidMask); Objects.equals(mServiceUuidMask, other.mServiceUuidMask);
} }
/**
* Checks if the scanfilter is empty
* @hide
*/
public boolean isAllFieldsEmpty() {
return EMPTY.equals(this);
}
/** /**
* Builder class for {@link ScanFilter}. * 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 * A result callback is only triggered for the first advertisement packet received that matches
* the filter criteria. * the filter criteria.
*
* @hide * @hide
*/ */
@SystemApi @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 * Receive a callback when advertisements are no longer received from a device that has been
* previously reported by a first match callback. * previously reported by a first match callback.
*
* @hide * @hide
*/ */
@SystemApi @SystemApi
public static final int CALLBACK_TYPE_MATCH_LOST = 4; public static final int CALLBACK_TYPE_MATCH_LOST = 4;
/** /**
* Request full scan results which contain the device, rssi, advertising data, scan response as * Determines how many advertisements to match per filter, as this is scarce hw resource
* well as the scan timestamp. */
/**
* 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 * @hide
*/ */
@ -106,6 +143,10 @@ public final class ScanSettings implements Parcelable {
// Time of delay for reporting the scan result // Time of delay for reporting the scan result
private long mReportDelayMillis; private long mReportDelayMillis;
private int mMatchMode;
private int mNumOfMatchesPerFilter;
public int getScanMode() { public int getScanMode() {
return mScanMode; return mScanMode;
} }
@ -118,6 +159,20 @@ public final class ScanSettings implements Parcelable {
return mScanResultType; return mScanResultType;
} }
/**
* @hide
*/
public int getMatchMode() {
return mMatchMode;
}
/**
* @hide
*/
public int getNumOfMatches() {
return mNumOfMatchesPerFilter;
}
/** /**
* Returns report delay timestamp based on the device clock. * 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, private ScanSettings(int scanMode, int callbackType, int scanResultType,
long reportDelayMillis) { long reportDelayMillis, int matchMode, int numOfMatchesPerFilter) {
mScanMode = scanMode; mScanMode = scanMode;
mCallbackType = callbackType; mCallbackType = callbackType;
mScanResultType = scanResultType; mScanResultType = scanResultType;
mReportDelayMillis = reportDelayMillis; mReportDelayMillis = reportDelayMillis;
mNumOfMatchesPerFilter = numOfMatchesPerFilter;
mMatchMode = numOfMatchesPerFilter;
} }
private ScanSettings(Parcel in) { private ScanSettings(Parcel in) {
@ -138,6 +195,8 @@ public final class ScanSettings implements Parcelable {
mCallbackType = in.readInt(); mCallbackType = in.readInt();
mScanResultType = in.readInt(); mScanResultType = in.readInt();
mReportDelayMillis = in.readLong(); mReportDelayMillis = in.readLong();
mMatchMode = in.readInt();
mNumOfMatchesPerFilter = in.readInt();
} }
@Override @Override
@ -146,6 +205,8 @@ public final class ScanSettings implements Parcelable {
dest.writeInt(mCallbackType); dest.writeInt(mCallbackType);
dest.writeInt(mScanResultType); dest.writeInt(mScanResultType);
dest.writeLong(mReportDelayMillis); dest.writeLong(mReportDelayMillis);
dest.writeInt(mMatchMode);
dest.writeInt(mNumOfMatchesPerFilter);
} }
@Override @Override
@ -174,7 +235,8 @@ public final class ScanSettings implements Parcelable {
private int mCallbackType = CALLBACK_TYPE_ALL_MATCHES; private int mCallbackType = CALLBACK_TYPE_ALL_MATCHES;
private int mScanResultType = SCAN_RESULT_TYPE_FULL; private int mScanResultType = SCAN_RESULT_TYPE_FULL;
private long mReportDelayMillis = 0; private long mReportDelayMillis = 0;
private int mMatchMode = MATCH_MODE_AGGRESSIVE;
private int mNumOfMatchesPerFilter = MATCH_NUM_ONE_ADVERTISEMENT;
/** /**
* Set scan mode for Bluetooth LE scan. * Set scan mode for Bluetooth LE scan.
* *
@ -254,12 +316,49 @@ public final class ScanSettings implements Parcelable {
return this; 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}. * Build {@link ScanSettings}.
*/ */
public ScanSettings build() { public ScanSettings build() {
return new ScanSettings(mScanMode, mCallbackType, mScanResultType, return new ScanSettings(mScanMode, mCallbackType, mScanResultType,
mReportDelayMillis); mReportDelayMillis, mMatchMode, mNumOfMatchesPerFilter);
} }
} }
} }