OSDN Git Service

Onfound onlost feature.
authorPrerepa Viswanadham <dham@google.com>
Tue, 7 Apr 2015 21:36:53 +0000 (14:36 -0700)
committerPrerepa Viswanadham <dham@google.com>
Tue, 7 Apr 2015 22:32:41 +0000 (22:32 +0000)
Change-Id: I5475cb21183abab8cf04af486ff7692396801b92
Signed-off-by: Prerepa Viswanadham <dham@google.com>
core/java/android/bluetooth/BluetoothAdapter.java
core/java/android/bluetooth/IBluetooth.aidl
core/java/android/bluetooth/le/BluetoothLeScanner.java
core/java/android/bluetooth/le/ScanCallback.java
core/java/android/bluetooth/le/ScanFilter.java
core/java/android/bluetooth/le/ScanSettings.java

index ee055a5..0442d09 100644 (file)
@@ -998,6 +998,24 @@ public final class BluetoothAdapter {
     }
 
     /**
+     * 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
      * the controller has been up to, since the last sample.
index dabb1ce..299f4c8 100644 (file)
@@ -98,6 +98,7 @@ interface IBluetooth
     boolean isActivityAndEnergyReportingSupported();
     void getActivityEnergyInfoFromController();
     BluetoothActivityEnergyInfo reportActivityInfo();
+    int numOfHwTrackFiltersAvailable();
 
     // for dumpsys support
     String dump();
index 93ea299..73a1907 100644 (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;
+    }
 }
index 05782a8..27b96bd 100644 (file)
@@ -45,10 +45,16 @@ 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) {
index 5025218..92a3817 100644 (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,
@@ -410,6 +412,14 @@ public final class ScanFilter implements Parcelable {
     }
 
     /**
+     * Checks if the scanfilter is empty
+     * @hide
+     */
+    public boolean isAllFieldsEmpty() {
+        return EMPTY.equals(this);
+    }
+
+    /**
      * Builder class for {@link ScanFilter}.
      */
     public static final class Builder {
index 0106686..f103cae 100644 (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;
 
+
+    /**
+     * 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;
+
     /**
-     * Request full scan results which contain the device, rssi, advertising data, scan response as
-     * well as the scan timestamp.
+     * 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;
     }
@@ -119,6 +160,20 @@ public final class ScanSettings implements Parcelable {
     }
 
     /**
+     * @hide
+     */
+    public int getMatchMode() {
+        return mMatchMode;
+    }
+
+    /**
+     * @hide
+     */
+    public int getNumOfMatches() {
+        return mNumOfMatchesPerFilter;
+    }
+
+    /**
      * Returns report delay timestamp based on the device clock.
      */
     public long getReportDelayMillis() {
@@ -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.
          *
@@ -255,11 +317,48 @@ public final class ScanSettings implements Parcelable {
         }
 
         /**
+         * 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);
         }
     }
 }