1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.bluetooth.gatt; 18 19 import java.util.concurrent.CountDownLatch; 20 import java.util.concurrent.TimeUnit; 21 22 /** 23 * BLE Scan Native Interface to/from JNI. 24 */ 25 public class ScanNativeInterface { 26 private static final String TAG = ScanNativeInterface.class.getSimpleName(); 27 28 private static ScanNativeInterface sInterface; 29 private static final Object INSTANCE_LOCK = new Object(); 30 31 private CountDownLatch mLatch; 32 ScanNativeInterface()33 private ScanNativeInterface() {} 34 35 /** 36 * This class is a singleton because native library should only be loaded once 37 * 38 * @return default instance 39 */ getInstance()40 public static ScanNativeInterface getInstance() { 41 synchronized (INSTANCE_LOCK) { 42 if (sInterface == null) { 43 sInterface = new ScanNativeInterface(); 44 } 45 } 46 return sInterface; 47 } 48 49 /* Native methods */ 50 /************************** Regular scan related native methods **************************/ registerScannerNative(long appUuidLsb, long appUuidMsb)51 private native void registerScannerNative(long appUuidLsb, long appUuidMsb); unregisterScannerNative(int scannerId)52 private native void unregisterScannerNative(int scannerId); gattClientScanNative(boolean start)53 private native void gattClientScanNative(boolean start); gattSetScanParametersNative(int clientIf, int scanInterval, int scanWindow)54 private native void gattSetScanParametersNative(int clientIf, int scanInterval, 55 int scanWindow); 56 /************************** Filter related native methods ********************************/ gattClientScanFilterAddNative(int clientId, ScanFilterQueue.Entry[] entries, int filterIndex)57 private native void gattClientScanFilterAddNative(int clientId, 58 ScanFilterQueue.Entry[] entries, int filterIndex); gattClientScanFilterParamAddNative(FilterParams filtValue)59 private native void gattClientScanFilterParamAddNative(FilterParams filtValue); 60 // Note this effectively remove scan filters for ALL clients. gattClientScanFilterParamClearAllNative(int clientIf)61 private native void gattClientScanFilterParamClearAllNative(int clientIf); gattClientScanFilterParamDeleteNative(int clientIf, int filtIndex)62 private native void gattClientScanFilterParamDeleteNative(int clientIf, int filtIndex); gattClientScanFilterClearNative(int clientIf, int filterIndex)63 private native void gattClientScanFilterClearNative(int clientIf, int filterIndex); gattClientScanFilterEnableNative(int clientIf, boolean enable)64 private native void gattClientScanFilterEnableNative(int clientIf, boolean enable); 65 /************************** Batch related native methods *********************************/ gattClientConfigBatchScanStorageNative(int clientIf, int maxFullReportsPercent, int maxTruncatedReportsPercent, int notifyThresholdPercent)66 private native void gattClientConfigBatchScanStorageNative(int clientIf, 67 int maxFullReportsPercent, int maxTruncatedReportsPercent, 68 int notifyThresholdPercent); gattClientStartBatchScanNative(int clientIf, int scanMode, int scanIntervalUnit, int scanWindowUnit, int addressType, int discardRule)69 private native void gattClientStartBatchScanNative(int clientIf, int scanMode, 70 int scanIntervalUnit, int scanWindowUnit, int addressType, int discardRule); gattClientStopBatchScanNative(int clientIf)71 private native void gattClientStopBatchScanNative(int clientIf); gattClientReadScanReportsNative(int clientIf, int scanType)72 private native void gattClientReadScanReportsNative(int clientIf, int scanType); 73 74 /** 75 * Register BLE scanner 76 */ registerScanner(long appUuidLsb, long appUuidMsb)77 public void registerScanner(long appUuidLsb, long appUuidMsb) { 78 registerScannerNative(appUuidLsb, appUuidMsb); 79 } 80 81 /** 82 * Unregister BLE scanner 83 */ unregisterScanner(int scannerId)84 public void unregisterScanner(int scannerId) { 85 unregisterScannerNative(scannerId); 86 } 87 88 /** 89 * Enable/disable BLE scan 90 */ gattClientScan(boolean start)91 public void gattClientScan(boolean start) { 92 gattClientScanNative(start); 93 } 94 95 /** 96 * Configure BLE scan parameters 97 */ gattSetScanParameters(int clientIf, int scanInterval, int scanWindow)98 public void gattSetScanParameters(int clientIf, int scanInterval, int scanWindow) { 99 gattSetScanParametersNative(clientIf, scanInterval, scanWindow); 100 } 101 102 /** 103 * Add BLE scan filter 104 */ gattClientScanFilterAdd(int clientId, ScanFilterQueue.Entry[] entries, int filterIndex)105 public void gattClientScanFilterAdd(int clientId, ScanFilterQueue.Entry[] entries, 106 int filterIndex) { 107 gattClientScanFilterAddNative(clientId, entries, filterIndex); 108 } 109 110 /** 111 * Add BLE scan filter parameters 112 */ gattClientScanFilterParamAdd(FilterParams filtValue)113 public void gattClientScanFilterParamAdd(FilterParams filtValue) { 114 gattClientScanFilterParamAddNative(filtValue); 115 } 116 117 /** 118 * Clear all BLE scan filter parameters 119 */ 120 // Note this effectively remove scan filters for ALL clients. gattClientScanFilterParamClearAll(int clientIf)121 public void gattClientScanFilterParamClearAll(int clientIf) { 122 gattClientScanFilterParamClearAllNative(clientIf); 123 } 124 125 /** 126 * Delete BLE scan filter parameters 127 */ gattClientScanFilterParamDelete(int clientIf, int filtIndex)128 public void gattClientScanFilterParamDelete(int clientIf, int filtIndex) { 129 gattClientScanFilterParamDeleteNative(clientIf, filtIndex); 130 } 131 132 /** 133 * Clear BLE scan filter 134 */ gattClientScanFilterClear(int clientIf, int filterIndex)135 public void gattClientScanFilterClear(int clientIf, int filterIndex) { 136 gattClientScanFilterClearNative(clientIf, filterIndex); 137 } 138 139 /** 140 * Enable/disable BLE scan filter 141 */ gattClientScanFilterEnable(int clientIf, boolean enable)142 public void gattClientScanFilterEnable(int clientIf, boolean enable) { 143 gattClientScanFilterEnableNative(clientIf, enable); 144 } 145 146 /** 147 * Configure BLE batch scan storage 148 */ gattClientConfigBatchScanStorage(int clientIf, int maxFullReportsPercent, int maxTruncatedReportsPercent, int notifyThresholdPercent)149 public void gattClientConfigBatchScanStorage(int clientIf, 150 int maxFullReportsPercent, int maxTruncatedReportsPercent, 151 int notifyThresholdPercent) { 152 gattClientConfigBatchScanStorageNative(clientIf, maxFullReportsPercent, 153 maxTruncatedReportsPercent, notifyThresholdPercent); 154 } 155 156 /** 157 * Enable BLE batch scan with the parameters 158 */ gattClientStartBatchScan(int clientIf, int scanMode, int scanIntervalUnit, int scanWindowUnit, int addressType, int discardRule)159 public void gattClientStartBatchScan(int clientIf, int scanMode, 160 int scanIntervalUnit, int scanWindowUnit, int addressType, int discardRule) { 161 gattClientStartBatchScanNative(clientIf, scanMode, scanIntervalUnit, scanWindowUnit, 162 addressType, discardRule); 163 } 164 165 /** 166 * Disable BLE batch scan 167 */ gattClientStopBatchScan(int clientIf)168 public void gattClientStopBatchScan(int clientIf) { 169 gattClientStopBatchScanNative(clientIf); 170 } 171 172 /** 173 * Read BLE batch scan reports 174 */ gattClientReadScanReports(int clientIf, int scanType)175 public void gattClientReadScanReports(int clientIf, int scanType) { 176 gattClientReadScanReportsNative(clientIf, scanType); 177 } 178 callbackDone()179 void callbackDone() { 180 mLatch.countDown(); 181 } 182 resetCountDownLatch()183 void resetCountDownLatch() { 184 mLatch = new CountDownLatch(1); 185 } 186 187 // Returns true if mLatch reaches 0, false if timeout or interrupted. waitForCallback(int timeoutMs)188 boolean waitForCallback(int timeoutMs) { 189 try { 190 return mLatch.await(timeoutMs, TimeUnit.MILLISECONDS); 191 } catch (InterruptedException e) { 192 return false; 193 } 194 } 195 } 196