Loading android/app/jni/com_android_bluetooth_gatt.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -2483,7 +2483,7 @@ static JNINativeMethod sPeriodicScanMethods[] = { (void*)transferSetInfoNative}, }; // JNI functions defined in ScanManager class. // JNI functions defined in ScanNativeInterface class. static JNINativeMethod sScanMethods[] = { {"registerScannerNative", "(JJ)V", (void*)registerScannerNative}, {"unregisterScannerNative", "(I)V", (void*)unregisterScannerNative}, Loading Loading @@ -2592,7 +2592,7 @@ static JNINativeMethod sMethods[] = { int register_com_android_bluetooth_gatt(JNIEnv* env) { int register_success = jniRegisterNativeMethods( env, "com/android/bluetooth/gatt/ScanManager$ScanNative", sScanMethods, env, "com/android/bluetooth/gatt/ScanNativeInterface", sScanMethods, NELEM(sScanMethods)); register_success &= jniRegisterNativeMethods( env, "com/android/bluetooth/gatt/AdvertiseManager", sAdvertiseMethods, Loading android/app/src/com/android/bluetooth/gatt/GattObjectsFactory.java +4 −0 Original line number Diff line number Diff line Loading @@ -60,4 +60,8 @@ public class GattObjectsFactory { public GattNativeInterface getNativeInterface() { return GattNativeInterface.getInstance(); } public ScanNativeInterface getScanNativeInterface() { return ScanNativeInterface.getInstance(); } } android/app/src/com/android/bluetooth/gatt/ScanManager.java +47 −73 Original line number Diff line number Diff line Loading @@ -64,8 +64,6 @@ import java.util.Map; import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; /** * Class that handles Bluetooth LE scan related operations. Loading Loading @@ -136,8 +134,6 @@ public class ScanManager { private Set<ScanClient> mSuspendedScanClients; private SparseIntArray mPriorityMap = new SparseIntArray(); private CountDownLatch mLatch; private DisplayManager mDm; private ActivityManager mActivityManager; Loading Loading @@ -249,12 +245,12 @@ public class ScanManager { } void registerScanner(UUID uuid) { mScanNative.registerScannerNative(uuid.getLeastSignificantBits(), mScanNative.registerScanner(uuid.getLeastSignificantBits(), uuid.getMostSignificantBits()); } void unregisterScanner(int scannerId) { mScanNative.unregisterScannerNative(scannerId); mScanNative.unregisterScanner(scannerId); } /** Loading Loading @@ -316,13 +312,7 @@ public class ScanManager { } void callbackDone(int scannerId, int status) { if (DBG) { Log.d(TAG, "callback done for scannerId - " + scannerId + " status - " + status); } if (status == 0) { mLatch.countDown(); } // TODO: add a callback for scan failure. mScanNative.callbackDone(scannerId, status); } void onConnectingState(boolean isConnecting) { Loading Loading @@ -898,8 +888,10 @@ public class ScanManager { private AlarmManager mAlarmManager; private PendingIntent mBatchScanIntervalIntent; private ScanNativeInterface mNativeInterface; ScanNative() { mNativeInterface = GattObjectsFactory.getInstance().getScanNativeInterface(); mFilterIndexStack = new ArrayDeque<Integer>(); mClientFilterIndexMap = new HashMap<Integer, Deque<Integer>>(); Loading Loading @@ -930,17 +922,22 @@ public class ScanManager { mBatchAlarmReceiverRegistered = true; } private void callbackDone(int scannerId, int status) { if (DBG) { Log.d(TAG, "callback done for scannerId - " + scannerId + " status - " + status); } if (status == 0) { mNativeInterface.callbackDone(); } // TODO: add a callback for scan failure. } private void resetCountDownLatch() { mLatch = new CountDownLatch(1); mNativeInterface.resetCountDownLatch(); } // Returns true if mLatch reaches 0, false if timeout or interrupted. private boolean waitForCallback() { try { return mLatch.await(OPERATION_TIME_OUT_MILLIS, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { return false; } return mNativeInterface.waitForCallback(OPERATION_TIME_OUT_MILLIS); } void configureRegularScanParams() { Loading @@ -962,7 +959,7 @@ public class ScanManager { // convert scanWindow and scanInterval from ms to LE scan units(0.625ms) int scanWindow = Utils.millsToUnit(scanWindowMs); int scanInterval = Utils.millsToUnit(scanIntervalMs); gattClientScanNative(false); mNativeInterface.gattClientScan(false); if (DBG) { Log.d(TAG, "Start gattClientScanNative with" + " old scanMode " + mLastConfiguredScanSetting Loading @@ -971,8 +968,9 @@ public class ScanManager { + ", in scan unit: " + scanInterval + " / " + scanWindow + " )" + client); } gattSetScanParametersNative(client.scannerId, scanInterval, scanWindow); gattClientScanNative(true); mNativeInterface.gattSetScanParameters(client.scannerId, scanInterval, scanWindow); mNativeInterface.gattClientScan(true); mLastConfiguredScanSetting = curScanSetting; } } else { Loading Loading @@ -1011,7 +1009,7 @@ public class ScanManager { if (DBG) { Log.d(TAG, "start gattClientScanNative from startRegularScan()"); } gattClientScanNative(true); mNativeInterface.gattClientScan(true); } } Loading Loading @@ -1071,7 +1069,7 @@ public class ScanManager { Log.d(TAG, "stopping BLe Batch"); } resetCountDownLatch(); gattClientStopBatchScanNative(scannerId); mNativeInterface.gattClientStopBatchScan(scannerId); waitForCallback(); // Clear pending results as it's illegal to config storage if there are still // pending results. Loading @@ -1089,7 +1087,7 @@ public class ScanManager { if (DBG) { Log.d(TAG, "configuring batch scan storage, appIf " + client.scannerId); } gattClientConfigBatchScanStorageNative(client.scannerId, fullScanPercent, mNativeInterface.gattClientConfigBatchScanStorage(client.scannerId, fullScanPercent, 100 - fullScanPercent, notifyThreshold); waitForCallback(); resetCountDownLatch(); Loading @@ -1097,8 +1095,8 @@ public class ScanManager { Utils.millsToUnit(getBatchScanIntervalMillis(batchScanParams.scanMode)); int scanWindow = Utils.millsToUnit(getBatchScanWindowMillis(batchScanParams.scanMode)); gattClientStartBatchScanNative(scannerId, resultType, scanInterval, scanWindow, 0, DISCARD_OLDEST_WHEN_BUFFER_FULL); mNativeInterface.gattClientStartBatchScan(scannerId, resultType, scanInterval, scanWindow, 0, DISCARD_OLDEST_WHEN_BUFFER_FULL); waitForCallback(); } mBatchScanParms = batchScanParams; Loading Loading @@ -1217,7 +1215,7 @@ public class ScanManager { if (DBG) { Log.d(TAG, "stop gattClientScanNative"); } gattClientScanNative(false); mNativeInterface.gattClientScan(false); } removeScanFilters(client.scannerId); } Loading Loading @@ -1249,7 +1247,7 @@ public class ScanManager { if (DBG) { Log.d(TAG, "stop gattClientScanNative"); } gattClientScanNative(false); mNativeInterface.gattClientScan(false); } } Loading Loading @@ -1299,13 +1297,13 @@ public class ScanManager { } if (mBatchScanParms.fullScanscannerId != -1) { resetCountDownLatch(); gattClientReadScanReportsNative(mBatchScanParms.fullScanscannerId, mNativeInterface.gattClientReadScanReports(mBatchScanParms.fullScanscannerId, SCAN_RESULT_TYPE_FULL); waitForCallback(); } if (mBatchScanParms.truncatedScanscannerId != -1) { resetCountDownLatch(); gattClientReadScanReportsNative(mBatchScanParms.truncatedScanscannerId, mNativeInterface.gattClientReadScanReports(mBatchScanParms.truncatedScanscannerId, SCAN_RESULT_TYPE_TRUNCATED); waitForCallback(); } Loading Loading @@ -1350,7 +1348,7 @@ public class ScanManager { } resetCountDownLatch(); gattClientScanFilterEnableNative(scannerId, true); mNativeInterface.gattClientScanFilterEnable(scannerId, true); waitForCallback(); if (shouldUseAllPassFilter(client)) { Loading @@ -1371,7 +1369,8 @@ public class ScanManager { int filterIndex = mFilterIndexStack.pop(); resetCountDownLatch(); gattClientScanFilterAddNative(scannerId, queue.toArray(), filterIndex); mNativeInterface.gattClientScanFilterAdd(scannerId, queue.toArray(), filterIndex); waitForCallback(); resetCountDownLatch(); Loading Loading @@ -1420,7 +1419,7 @@ public class ScanManager { mFilterIndexStack.addAll(filterIndices); for (Integer filterIndex : filterIndices) { resetCountDownLatch(); gattClientScanFilterParamDeleteNative(scannerId, filterIndex); mNativeInterface.gattClientScanFilterParamDelete(scannerId, filterIndex); waitForCallback(); } } Loading @@ -1439,7 +1438,7 @@ public class ScanManager { // Remove ALL_PASS filter iff no app is using it. if (clients.isEmpty()) { resetCountDownLatch(); gattClientScanFilterParamDeleteNative(scannerId, filterIndex); mNativeInterface.gattClientScanFilterParamDelete(scannerId, filterIndex); waitForCallback(); } } Loading Loading @@ -1510,7 +1509,7 @@ public class ScanManager { new FilterParams(scannerId, filterIndex, featureSelection, LIST_LOGIC_TYPE, FILTER_LOGIC_TYPE, rssiThreshold, rssiThreshold, deliveryMode, onFoundTimeout, onLostTimeout, onFoundCount, numOfTrackingEntries); gattClientScanFilterParamAddNative(filtValue); mNativeInterface.gattClientScanFilterParamAdd(filtValue); } // Get delivery mode based on scan settings. Loading Loading @@ -1687,43 +1686,13 @@ public class ScanManager { } } private void registerScanner(long appUuidLsb, long appUuidMsb) { mNativeInterface.registerScanner(appUuidLsb, appUuidMsb); } /************************** Regular scan related native methods **************************/ private native void registerScannerNative(long appUuidLsb, long appUuidMsb); private native void unregisterScannerNative(int scannerId); private native void gattClientScanNative(boolean start); private native void gattSetScanParametersNative(int clientIf, int scanInterval, int scanWindow); /************************** Filter related native methods ********************************/ private native void gattClientScanFilterAddNative(int clientId, ScanFilterQueue.Entry[] entries, int filterIndex); private native void gattClientScanFilterParamAddNative(FilterParams filtValue); // Note this effectively remove scan filters for ALL clients. private native void gattClientScanFilterParamClearAllNative(int clientIf); private native void gattClientScanFilterParamDeleteNative(int clientIf, int filtIndex); private native void gattClientScanFilterClearNative(int clientIf, int filterIndex); private native void gattClientScanFilterEnableNative(int clientIf, boolean enable); /************************** Batch related native methods *********************************/ private native void gattClientConfigBatchScanStorageNative(int clientIf, int maxFullReportsPercent, int maxTruncatedReportsPercent, int notifyThresholdPercent); private native void gattClientStartBatchScanNative(int clientIf, int scanMode, int scanIntervalUnit, int scanWindowUnit, int addressType, int discardRule); private native void gattClientStopBatchScanNative(int clientIf); private native void gattClientReadScanReportsNative(int clientIf, int scanType); private void unregisterScanner(int scannerId) { mNativeInterface.unregisterScanner(scannerId); } } @VisibleForTesting Loading @@ -1731,6 +1700,11 @@ public class ScanManager { return mHandler; } @VisibleForTesting BatchScanParams getBatchScanParams() { return mBatchScanParms; } private boolean isScreenOn() { Display[] displays = mDm.getDisplays(); Loading android/app/src/com/android/bluetooth/gatt/ScanNativeInterface.java 0 → 100644 +195 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.bluetooth.gatt; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; /** * BLE Scan Native Interface to/from JNI. */ public class ScanNativeInterface { private static final String TAG = ScanNativeInterface.class.getSimpleName(); private static ScanNativeInterface sInterface; private static final Object INSTANCE_LOCK = new Object(); private CountDownLatch mLatch; private ScanNativeInterface() {} /** * This class is a singleton because native library should only be loaded once * * @return default instance */ public static ScanNativeInterface getInstance() { synchronized (INSTANCE_LOCK) { if (sInterface == null) { sInterface = new ScanNativeInterface(); } } return sInterface; } /* Native methods */ /************************** Regular scan related native methods **************************/ private native void registerScannerNative(long appUuidLsb, long appUuidMsb); private native void unregisterScannerNative(int scannerId); private native void gattClientScanNative(boolean start); private native void gattSetScanParametersNative(int clientIf, int scanInterval, int scanWindow); /************************** Filter related native methods ********************************/ private native void gattClientScanFilterAddNative(int clientId, ScanFilterQueue.Entry[] entries, int filterIndex); private native void gattClientScanFilterParamAddNative(FilterParams filtValue); // Note this effectively remove scan filters for ALL clients. private native void gattClientScanFilterParamClearAllNative(int clientIf); private native void gattClientScanFilterParamDeleteNative(int clientIf, int filtIndex); private native void gattClientScanFilterClearNative(int clientIf, int filterIndex); private native void gattClientScanFilterEnableNative(int clientIf, boolean enable); /************************** Batch related native methods *********************************/ private native void gattClientConfigBatchScanStorageNative(int clientIf, int maxFullReportsPercent, int maxTruncatedReportsPercent, int notifyThresholdPercent); private native void gattClientStartBatchScanNative(int clientIf, int scanMode, int scanIntervalUnit, int scanWindowUnit, int addressType, int discardRule); private native void gattClientStopBatchScanNative(int clientIf); private native void gattClientReadScanReportsNative(int clientIf, int scanType); /** * Register BLE scanner */ public void registerScanner(long appUuidLsb, long appUuidMsb) { registerScannerNative(appUuidLsb, appUuidMsb); } /** * Unregister BLE scanner */ public void unregisterScanner(int scannerId) { unregisterScannerNative(scannerId); } /** * Enable/disable BLE scan */ public void gattClientScan(boolean start) { gattClientScanNative(start); } /** * Configure BLE scan parameters */ public void gattSetScanParameters(int clientIf, int scanInterval, int scanWindow) { gattSetScanParametersNative(clientIf, scanInterval, scanWindow); } /** * Add BLE scan filter */ public void gattClientScanFilterAdd(int clientId, ScanFilterQueue.Entry[] entries, int filterIndex) { gattClientScanFilterAddNative(clientId, entries, filterIndex); } /** * Add BLE scan filter parameters */ public void gattClientScanFilterParamAdd(FilterParams filtValue) { gattClientScanFilterParamAddNative(filtValue); } /** * Clear all BLE scan filter parameters */ // Note this effectively remove scan filters for ALL clients. public void gattClientScanFilterParamClearAll(int clientIf) { gattClientScanFilterParamClearAllNative(clientIf); } /** * Delete BLE scan filter parameters */ public void gattClientScanFilterParamDelete(int clientIf, int filtIndex) { gattClientScanFilterParamDeleteNative(clientIf, filtIndex); } /** * Clear BLE scan filter */ public void gattClientScanFilterClear(int clientIf, int filterIndex) { gattClientScanFilterClearNative(clientIf, filterIndex); } /** * Enable/disable BLE scan filter */ public void gattClientScanFilterEnable(int clientIf, boolean enable) { gattClientScanFilterEnableNative(clientIf, enable); } /** * Configure BLE batch scan storage */ public void gattClientConfigBatchScanStorage(int clientIf, int maxFullReportsPercent, int maxTruncatedReportsPercent, int notifyThresholdPercent) { gattClientConfigBatchScanStorageNative(clientIf, maxFullReportsPercent, maxTruncatedReportsPercent, notifyThresholdPercent); } /** * Enable BLE batch scan with the parameters */ public void gattClientStartBatchScan(int clientIf, int scanMode, int scanIntervalUnit, int scanWindowUnit, int addressType, int discardRule) { gattClientStartBatchScanNative(clientIf, scanMode, scanIntervalUnit, scanWindowUnit, addressType, discardRule); } /** * Disable BLE batch scan */ public void gattClientStopBatchScan(int clientIf) { gattClientStopBatchScanNative(clientIf); } /** * Read BLE batch scan reports */ public void gattClientReadScanReports(int clientIf, int scanType) { gattClientReadScanReportsNative(clientIf, scanType); } void callbackDone() { mLatch.countDown(); } void resetCountDownLatch() { mLatch = new CountDownLatch(1); } // Returns true if mLatch reaches 0, false if timeout or interrupted. boolean waitForCallback(int timeoutMs) { try { return mLatch.await(timeoutMs, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { return false; } } } android/app/tests/unit/src/com/android/bluetooth/gatt/ScanManagerTest.java +96 −12 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
android/app/jni/com_android_bluetooth_gatt.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -2483,7 +2483,7 @@ static JNINativeMethod sPeriodicScanMethods[] = { (void*)transferSetInfoNative}, }; // JNI functions defined in ScanManager class. // JNI functions defined in ScanNativeInterface class. static JNINativeMethod sScanMethods[] = { {"registerScannerNative", "(JJ)V", (void*)registerScannerNative}, {"unregisterScannerNative", "(I)V", (void*)unregisterScannerNative}, Loading Loading @@ -2592,7 +2592,7 @@ static JNINativeMethod sMethods[] = { int register_com_android_bluetooth_gatt(JNIEnv* env) { int register_success = jniRegisterNativeMethods( env, "com/android/bluetooth/gatt/ScanManager$ScanNative", sScanMethods, env, "com/android/bluetooth/gatt/ScanNativeInterface", sScanMethods, NELEM(sScanMethods)); register_success &= jniRegisterNativeMethods( env, "com/android/bluetooth/gatt/AdvertiseManager", sAdvertiseMethods, Loading
android/app/src/com/android/bluetooth/gatt/GattObjectsFactory.java +4 −0 Original line number Diff line number Diff line Loading @@ -60,4 +60,8 @@ public class GattObjectsFactory { public GattNativeInterface getNativeInterface() { return GattNativeInterface.getInstance(); } public ScanNativeInterface getScanNativeInterface() { return ScanNativeInterface.getInstance(); } }
android/app/src/com/android/bluetooth/gatt/ScanManager.java +47 −73 Original line number Diff line number Diff line Loading @@ -64,8 +64,6 @@ import java.util.Map; import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; /** * Class that handles Bluetooth LE scan related operations. Loading Loading @@ -136,8 +134,6 @@ public class ScanManager { private Set<ScanClient> mSuspendedScanClients; private SparseIntArray mPriorityMap = new SparseIntArray(); private CountDownLatch mLatch; private DisplayManager mDm; private ActivityManager mActivityManager; Loading Loading @@ -249,12 +245,12 @@ public class ScanManager { } void registerScanner(UUID uuid) { mScanNative.registerScannerNative(uuid.getLeastSignificantBits(), mScanNative.registerScanner(uuid.getLeastSignificantBits(), uuid.getMostSignificantBits()); } void unregisterScanner(int scannerId) { mScanNative.unregisterScannerNative(scannerId); mScanNative.unregisterScanner(scannerId); } /** Loading Loading @@ -316,13 +312,7 @@ public class ScanManager { } void callbackDone(int scannerId, int status) { if (DBG) { Log.d(TAG, "callback done for scannerId - " + scannerId + " status - " + status); } if (status == 0) { mLatch.countDown(); } // TODO: add a callback for scan failure. mScanNative.callbackDone(scannerId, status); } void onConnectingState(boolean isConnecting) { Loading Loading @@ -898,8 +888,10 @@ public class ScanManager { private AlarmManager mAlarmManager; private PendingIntent mBatchScanIntervalIntent; private ScanNativeInterface mNativeInterface; ScanNative() { mNativeInterface = GattObjectsFactory.getInstance().getScanNativeInterface(); mFilterIndexStack = new ArrayDeque<Integer>(); mClientFilterIndexMap = new HashMap<Integer, Deque<Integer>>(); Loading Loading @@ -930,17 +922,22 @@ public class ScanManager { mBatchAlarmReceiverRegistered = true; } private void callbackDone(int scannerId, int status) { if (DBG) { Log.d(TAG, "callback done for scannerId - " + scannerId + " status - " + status); } if (status == 0) { mNativeInterface.callbackDone(); } // TODO: add a callback for scan failure. } private void resetCountDownLatch() { mLatch = new CountDownLatch(1); mNativeInterface.resetCountDownLatch(); } // Returns true if mLatch reaches 0, false if timeout or interrupted. private boolean waitForCallback() { try { return mLatch.await(OPERATION_TIME_OUT_MILLIS, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { return false; } return mNativeInterface.waitForCallback(OPERATION_TIME_OUT_MILLIS); } void configureRegularScanParams() { Loading @@ -962,7 +959,7 @@ public class ScanManager { // convert scanWindow and scanInterval from ms to LE scan units(0.625ms) int scanWindow = Utils.millsToUnit(scanWindowMs); int scanInterval = Utils.millsToUnit(scanIntervalMs); gattClientScanNative(false); mNativeInterface.gattClientScan(false); if (DBG) { Log.d(TAG, "Start gattClientScanNative with" + " old scanMode " + mLastConfiguredScanSetting Loading @@ -971,8 +968,9 @@ public class ScanManager { + ", in scan unit: " + scanInterval + " / " + scanWindow + " )" + client); } gattSetScanParametersNative(client.scannerId, scanInterval, scanWindow); gattClientScanNative(true); mNativeInterface.gattSetScanParameters(client.scannerId, scanInterval, scanWindow); mNativeInterface.gattClientScan(true); mLastConfiguredScanSetting = curScanSetting; } } else { Loading Loading @@ -1011,7 +1009,7 @@ public class ScanManager { if (DBG) { Log.d(TAG, "start gattClientScanNative from startRegularScan()"); } gattClientScanNative(true); mNativeInterface.gattClientScan(true); } } Loading Loading @@ -1071,7 +1069,7 @@ public class ScanManager { Log.d(TAG, "stopping BLe Batch"); } resetCountDownLatch(); gattClientStopBatchScanNative(scannerId); mNativeInterface.gattClientStopBatchScan(scannerId); waitForCallback(); // Clear pending results as it's illegal to config storage if there are still // pending results. Loading @@ -1089,7 +1087,7 @@ public class ScanManager { if (DBG) { Log.d(TAG, "configuring batch scan storage, appIf " + client.scannerId); } gattClientConfigBatchScanStorageNative(client.scannerId, fullScanPercent, mNativeInterface.gattClientConfigBatchScanStorage(client.scannerId, fullScanPercent, 100 - fullScanPercent, notifyThreshold); waitForCallback(); resetCountDownLatch(); Loading @@ -1097,8 +1095,8 @@ public class ScanManager { Utils.millsToUnit(getBatchScanIntervalMillis(batchScanParams.scanMode)); int scanWindow = Utils.millsToUnit(getBatchScanWindowMillis(batchScanParams.scanMode)); gattClientStartBatchScanNative(scannerId, resultType, scanInterval, scanWindow, 0, DISCARD_OLDEST_WHEN_BUFFER_FULL); mNativeInterface.gattClientStartBatchScan(scannerId, resultType, scanInterval, scanWindow, 0, DISCARD_OLDEST_WHEN_BUFFER_FULL); waitForCallback(); } mBatchScanParms = batchScanParams; Loading Loading @@ -1217,7 +1215,7 @@ public class ScanManager { if (DBG) { Log.d(TAG, "stop gattClientScanNative"); } gattClientScanNative(false); mNativeInterface.gattClientScan(false); } removeScanFilters(client.scannerId); } Loading Loading @@ -1249,7 +1247,7 @@ public class ScanManager { if (DBG) { Log.d(TAG, "stop gattClientScanNative"); } gattClientScanNative(false); mNativeInterface.gattClientScan(false); } } Loading Loading @@ -1299,13 +1297,13 @@ public class ScanManager { } if (mBatchScanParms.fullScanscannerId != -1) { resetCountDownLatch(); gattClientReadScanReportsNative(mBatchScanParms.fullScanscannerId, mNativeInterface.gattClientReadScanReports(mBatchScanParms.fullScanscannerId, SCAN_RESULT_TYPE_FULL); waitForCallback(); } if (mBatchScanParms.truncatedScanscannerId != -1) { resetCountDownLatch(); gattClientReadScanReportsNative(mBatchScanParms.truncatedScanscannerId, mNativeInterface.gattClientReadScanReports(mBatchScanParms.truncatedScanscannerId, SCAN_RESULT_TYPE_TRUNCATED); waitForCallback(); } Loading Loading @@ -1350,7 +1348,7 @@ public class ScanManager { } resetCountDownLatch(); gattClientScanFilterEnableNative(scannerId, true); mNativeInterface.gattClientScanFilterEnable(scannerId, true); waitForCallback(); if (shouldUseAllPassFilter(client)) { Loading @@ -1371,7 +1369,8 @@ public class ScanManager { int filterIndex = mFilterIndexStack.pop(); resetCountDownLatch(); gattClientScanFilterAddNative(scannerId, queue.toArray(), filterIndex); mNativeInterface.gattClientScanFilterAdd(scannerId, queue.toArray(), filterIndex); waitForCallback(); resetCountDownLatch(); Loading Loading @@ -1420,7 +1419,7 @@ public class ScanManager { mFilterIndexStack.addAll(filterIndices); for (Integer filterIndex : filterIndices) { resetCountDownLatch(); gattClientScanFilterParamDeleteNative(scannerId, filterIndex); mNativeInterface.gattClientScanFilterParamDelete(scannerId, filterIndex); waitForCallback(); } } Loading @@ -1439,7 +1438,7 @@ public class ScanManager { // Remove ALL_PASS filter iff no app is using it. if (clients.isEmpty()) { resetCountDownLatch(); gattClientScanFilterParamDeleteNative(scannerId, filterIndex); mNativeInterface.gattClientScanFilterParamDelete(scannerId, filterIndex); waitForCallback(); } } Loading Loading @@ -1510,7 +1509,7 @@ public class ScanManager { new FilterParams(scannerId, filterIndex, featureSelection, LIST_LOGIC_TYPE, FILTER_LOGIC_TYPE, rssiThreshold, rssiThreshold, deliveryMode, onFoundTimeout, onLostTimeout, onFoundCount, numOfTrackingEntries); gattClientScanFilterParamAddNative(filtValue); mNativeInterface.gattClientScanFilterParamAdd(filtValue); } // Get delivery mode based on scan settings. Loading Loading @@ -1687,43 +1686,13 @@ public class ScanManager { } } private void registerScanner(long appUuidLsb, long appUuidMsb) { mNativeInterface.registerScanner(appUuidLsb, appUuidMsb); } /************************** Regular scan related native methods **************************/ private native void registerScannerNative(long appUuidLsb, long appUuidMsb); private native void unregisterScannerNative(int scannerId); private native void gattClientScanNative(boolean start); private native void gattSetScanParametersNative(int clientIf, int scanInterval, int scanWindow); /************************** Filter related native methods ********************************/ private native void gattClientScanFilterAddNative(int clientId, ScanFilterQueue.Entry[] entries, int filterIndex); private native void gattClientScanFilterParamAddNative(FilterParams filtValue); // Note this effectively remove scan filters for ALL clients. private native void gattClientScanFilterParamClearAllNative(int clientIf); private native void gattClientScanFilterParamDeleteNative(int clientIf, int filtIndex); private native void gattClientScanFilterClearNative(int clientIf, int filterIndex); private native void gattClientScanFilterEnableNative(int clientIf, boolean enable); /************************** Batch related native methods *********************************/ private native void gattClientConfigBatchScanStorageNative(int clientIf, int maxFullReportsPercent, int maxTruncatedReportsPercent, int notifyThresholdPercent); private native void gattClientStartBatchScanNative(int clientIf, int scanMode, int scanIntervalUnit, int scanWindowUnit, int addressType, int discardRule); private native void gattClientStopBatchScanNative(int clientIf); private native void gattClientReadScanReportsNative(int clientIf, int scanType); private void unregisterScanner(int scannerId) { mNativeInterface.unregisterScanner(scannerId); } } @VisibleForTesting Loading @@ -1731,6 +1700,11 @@ public class ScanManager { return mHandler; } @VisibleForTesting BatchScanParams getBatchScanParams() { return mBatchScanParms; } private boolean isScreenOn() { Display[] displays = mDm.getDisplays(); Loading
android/app/src/com/android/bluetooth/gatt/ScanNativeInterface.java 0 → 100644 +195 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.bluetooth.gatt; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; /** * BLE Scan Native Interface to/from JNI. */ public class ScanNativeInterface { private static final String TAG = ScanNativeInterface.class.getSimpleName(); private static ScanNativeInterface sInterface; private static final Object INSTANCE_LOCK = new Object(); private CountDownLatch mLatch; private ScanNativeInterface() {} /** * This class is a singleton because native library should only be loaded once * * @return default instance */ public static ScanNativeInterface getInstance() { synchronized (INSTANCE_LOCK) { if (sInterface == null) { sInterface = new ScanNativeInterface(); } } return sInterface; } /* Native methods */ /************************** Regular scan related native methods **************************/ private native void registerScannerNative(long appUuidLsb, long appUuidMsb); private native void unregisterScannerNative(int scannerId); private native void gattClientScanNative(boolean start); private native void gattSetScanParametersNative(int clientIf, int scanInterval, int scanWindow); /************************** Filter related native methods ********************************/ private native void gattClientScanFilterAddNative(int clientId, ScanFilterQueue.Entry[] entries, int filterIndex); private native void gattClientScanFilterParamAddNative(FilterParams filtValue); // Note this effectively remove scan filters for ALL clients. private native void gattClientScanFilterParamClearAllNative(int clientIf); private native void gattClientScanFilterParamDeleteNative(int clientIf, int filtIndex); private native void gattClientScanFilterClearNative(int clientIf, int filterIndex); private native void gattClientScanFilterEnableNative(int clientIf, boolean enable); /************************** Batch related native methods *********************************/ private native void gattClientConfigBatchScanStorageNative(int clientIf, int maxFullReportsPercent, int maxTruncatedReportsPercent, int notifyThresholdPercent); private native void gattClientStartBatchScanNative(int clientIf, int scanMode, int scanIntervalUnit, int scanWindowUnit, int addressType, int discardRule); private native void gattClientStopBatchScanNative(int clientIf); private native void gattClientReadScanReportsNative(int clientIf, int scanType); /** * Register BLE scanner */ public void registerScanner(long appUuidLsb, long appUuidMsb) { registerScannerNative(appUuidLsb, appUuidMsb); } /** * Unregister BLE scanner */ public void unregisterScanner(int scannerId) { unregisterScannerNative(scannerId); } /** * Enable/disable BLE scan */ public void gattClientScan(boolean start) { gattClientScanNative(start); } /** * Configure BLE scan parameters */ public void gattSetScanParameters(int clientIf, int scanInterval, int scanWindow) { gattSetScanParametersNative(clientIf, scanInterval, scanWindow); } /** * Add BLE scan filter */ public void gattClientScanFilterAdd(int clientId, ScanFilterQueue.Entry[] entries, int filterIndex) { gattClientScanFilterAddNative(clientId, entries, filterIndex); } /** * Add BLE scan filter parameters */ public void gattClientScanFilterParamAdd(FilterParams filtValue) { gattClientScanFilterParamAddNative(filtValue); } /** * Clear all BLE scan filter parameters */ // Note this effectively remove scan filters for ALL clients. public void gattClientScanFilterParamClearAll(int clientIf) { gattClientScanFilterParamClearAllNative(clientIf); } /** * Delete BLE scan filter parameters */ public void gattClientScanFilterParamDelete(int clientIf, int filtIndex) { gattClientScanFilterParamDeleteNative(clientIf, filtIndex); } /** * Clear BLE scan filter */ public void gattClientScanFilterClear(int clientIf, int filterIndex) { gattClientScanFilterClearNative(clientIf, filterIndex); } /** * Enable/disable BLE scan filter */ public void gattClientScanFilterEnable(int clientIf, boolean enable) { gattClientScanFilterEnableNative(clientIf, enable); } /** * Configure BLE batch scan storage */ public void gattClientConfigBatchScanStorage(int clientIf, int maxFullReportsPercent, int maxTruncatedReportsPercent, int notifyThresholdPercent) { gattClientConfigBatchScanStorageNative(clientIf, maxFullReportsPercent, maxTruncatedReportsPercent, notifyThresholdPercent); } /** * Enable BLE batch scan with the parameters */ public void gattClientStartBatchScan(int clientIf, int scanMode, int scanIntervalUnit, int scanWindowUnit, int addressType, int discardRule) { gattClientStartBatchScanNative(clientIf, scanMode, scanIntervalUnit, scanWindowUnit, addressType, discardRule); } /** * Disable BLE batch scan */ public void gattClientStopBatchScan(int clientIf) { gattClientStopBatchScanNative(clientIf); } /** * Read BLE batch scan reports */ public void gattClientReadScanReports(int clientIf, int scanType) { gattClientReadScanReportsNative(clientIf, scanType); } void callbackDone() { mLatch.countDown(); } void resetCountDownLatch() { mLatch = new CountDownLatch(1); } // Returns true if mLatch reaches 0, false if timeout or interrupted. boolean waitForCallback(int timeoutMs) { try { return mLatch.await(timeoutMs, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { return false; } } }
android/app/tests/unit/src/com/android/bluetooth/gatt/ScanManagerTest.java +96 −12 File changed.Preview size limit exceeded, changes collapsed. Show changes