Advertising Filtering: send all filters in one batch (2/2)

Bug: 67371480
Test: sl4a FilteringTest
Change-Id: I93595b5ed4e7cf25cdb6a8b1f9413a7f05e61774
diff --git a/btif/include/btif_gatt_util.h b/btif/include/btif_gatt_util.h
index c2d91aa..284a45c 100644
--- a/btif/include/btif_gatt_util.h
+++ b/btif/include/btif_gatt_util.h
@@ -25,9 +25,6 @@
 #include "bta/include/bta_gatt_api.h"
 
 void btif_to_bta_response(tGATTS_RSP* p_dest, btgatt_response_t* p_src);
-void btif_to_bta_uuid_mask(tBTM_BLE_PF_COND_MASK* p_mask,
-                           const bluetooth::Uuid& p_src,
-                           const bluetooth::Uuid& svc_uuid);
 
 void btif_gatt_check_encrypted_link(RawAddress bd_addr,
                                     tGATT_TRANSPORT transport);
diff --git a/btif/src/btif_ble_scanner.cc b/btif/src/btif_ble_scanner.cc
index beb61cf..2511e2c 100644
--- a/btif/src/btif_ble_scanner.cc
+++ b/btif/src/btif_ble_scanner.cc
@@ -255,90 +255,18 @@
                                 jni_thread_wrapper(FROM_HERE, std::move(cb))));
   }
 
-  void ScanFilterAddRemove(int action, int filt_type, int filt_index,
-                           int company_id, int company_id_mask,
-                           const bluetooth::Uuid* p_uuid,
-                           const bluetooth::Uuid* p_uuid_mask,
-                           const RawAddress* bd_addr, char addr_type,
-                           vector<uint8_t> data, vector<uint8_t> mask,
-                           FilterConfigCallback cb) override {
-    BTIF_TRACE_DEBUG("%s, %d, %d", __func__, action, filt_type);
+  void ScanFilterAdd(int filter_index, std::vector<ApcfCommand> filters,
+                     FilterConfigCallback cb) override {
+    BTIF_TRACE_DEBUG("%s: %d", __func__, filter_index);
 
-    /* If data is passed, both mask and data have to be the same length */
-    if (data.size() != mask.size() && data.size() != 0 && mask.size() != 0)
-      return;
-
-    switch (filt_type) {
-      case BTM_BLE_PF_ADDR_FILTER: {
-        tBLE_BD_ADDR target_addr;
-        target_addr.bda = *bd_addr;
-        target_addr.type = addr_type;
-
-        do_in_bta_thread(
-            FROM_HERE,
-            base::Bind(&BTM_LE_PF_addr_filter, action, filt_index,
-                       std::move(target_addr),
-                       jni_thread_wrapper(FROM_HERE, Bind(cb, filt_type))));
-        return;
-      }
-
-      case BTM_BLE_PF_SRVC_DATA:
-        do_in_bta_thread(FROM_HERE,
-                         base::Bind(&BTM_LE_PF_srvc_data, action, filt_index));
-        return;
-
-      case BTM_BLE_PF_SRVC_UUID:
-      case BTM_BLE_PF_SRVC_SOL_UUID: {
-        if (p_uuid_mask == NULL) {
-          do_in_bta_thread(
-              FROM_HERE,
-              base::Bind(&BTM_LE_PF_uuid_filter, action, filt_index, filt_type,
-                         *p_uuid, BTM_BLE_PF_LOGIC_AND, nullptr,
-                         jni_thread_wrapper(FROM_HERE, Bind(cb, filt_type))));
-          return;
-        }
-
-        tBTM_BLE_PF_COND_MASK* mask = new tBTM_BLE_PF_COND_MASK;
-        btif_to_bta_uuid_mask(mask, *p_uuid_mask, *p_uuid);
-        do_in_bta_thread(
-            FROM_HERE,
-            base::Bind(&BTM_LE_PF_uuid_filter, action, filt_index, filt_type,
-                       *p_uuid, BTM_BLE_PF_LOGIC_AND, base::Owned(mask),
-                       jni_thread_wrapper(FROM_HERE, Bind(cb, filt_type))));
-        return;
-      }
-
-      case BTM_BLE_PF_LOCAL_NAME: {
-        do_in_bta_thread(
-            FROM_HERE,
-            base::Bind(&BTM_LE_PF_local_name, action, filt_index,
-                       std::move(data),
-                       jni_thread_wrapper(FROM_HERE, Bind(cb, filt_type))));
-        return;
-      }
-
-      case BTM_BLE_PF_MANU_DATA: {
-        do_in_bta_thread(
-            FROM_HERE,
-            base::Bind(&BTM_LE_PF_manu_data, action, filt_index, company_id,
-                       company_id_mask, std::move(data), std::move(mask),
-                       jni_thread_wrapper(FROM_HERE, Bind(cb, filt_type))));
-        return;
-      }
-
-      case BTM_BLE_PF_SRVC_DATA_PATTERN: {
-        do_in_bta_thread(
-            FROM_HERE,
-            base::Bind(&BTM_LE_PF_srvc_data_pattern, action, filt_index,
-                       std::move(data), std::move(mask),
-                       jni_thread_wrapper(FROM_HERE, Bind(cb, filt_type))));
-        return;
-      }
-
-      default:
-        LOG_ERROR(LOG_TAG, "%s: Unknown filter type (%d)!", __func__, action);
-        return;
-    }
+    do_in_bta_thread(
+        FROM_HERE,
+        base::Bind(
+            &BTM_LE_PF_set, filter_index, std::move(filters),
+            jni_thread_wrapper(
+                FROM_HERE,
+                Bind(std::move(cb),
+                     0 /*TODO: this used to be filter type, unused ?*/))));
   }
 
   void ScanFilterClear(int filter_index, FilterConfigCallback cb) override {
diff --git a/btif/src/btif_gatt_util.cc b/btif/src/btif_gatt_util.cc
index 8c7971f..16f2275 100644
--- a/btif/src/btif_gatt_util.cc
+++ b/btif/src/btif_gatt_util.cc
@@ -53,31 +53,6 @@
   memcpy(p_dest->attr_value.value, p_src->attr_value.value, GATT_MAX_ATTR_LEN);
 }
 
-void btif_to_bta_uuid_mask(tBTM_BLE_PF_COND_MASK* p_mask,
-                           const bluetooth::Uuid& uuid_mask,
-                           const bluetooth::Uuid& svc_uuid) {
-  // we use svc_uuid for uuid_mask length picking ?
-  int uuid_len = svc_uuid.GetShortestRepresentationSize();
-
-  switch (uuid_len) {
-    case Uuid::kNumBytes16:
-      p_mask->uuid16_mask = uuid_mask.As16Bit();
-      break;
-
-    case Uuid::kNumBytes32:
-      p_mask->uuid32_mask = uuid_mask.As32Bit();
-      break;
-
-    case Uuid::kNumBytes128:
-      memcpy(p_mask->uuid128_mask, uuid_mask.To128BitLE().data(),
-             Uuid::kNumBytes128);
-      break;
-
-    default:
-      break;
-  }
-}
-
 /*******************************************************************************
  * Encrypted link map handling
  ******************************************************************************/
diff --git a/include/hardware/ble_scanner.h b/include/hardware/ble_scanner.h
index 17ffd29..efa9662 100644
--- a/include/hardware/ble_scanner.h
+++ b/include/hardware/ble_scanner.h
@@ -86,14 +86,8 @@
       FilterParamSetupCallback cb) = 0;
 
   /** Configure a scan filter condition  */
-  virtual void ScanFilterAddRemove(int action, int filt_type, int filt_index,
-                                   int company_id, int company_id_mask,
-                                   const bluetooth::Uuid* p_uuid,
-                                   const bluetooth::Uuid* p_uuid_mask,
-                                   const RawAddress* bd_addr, char addr_type,
-                                   std::vector<uint8_t> data,
-                                   std::vector<uint8_t> p_mask,
-                                   FilterConfigCallback cb) = 0;
+  virtual void ScanFilterAdd(int filter_index, std::vector<ApcfCommand> filters,
+                             FilterConfigCallback cb) = 0;
 
   /** Clear all scan filter conditions for specific filter index*/
   virtual void ScanFilterClear(int filt_index, FilterConfigCallback cb) = 0;
diff --git a/include/hardware/bt_common_types.h b/include/hardware/bt_common_types.h
index d39370f..0a315fe 100644
--- a/include/hardware/bt_common_types.h
+++ b/include/hardware/bt_common_types.h
@@ -26,6 +26,7 @@
 #include "bluetooth.h"
 
 #include <bluetooth/uuid.h>
+#include <vector>
 
 typedef struct {
   uint8_t client_if;
@@ -86,4 +87,18 @@
   uint16_t num_of_tracking_entries;
 } btgatt_filt_param_setup_t;
 
+// Advertising Packet Content Filter
+struct ApcfCommand {
+  uint8_t type;
+  RawAddress address;
+  uint8_t addr_type;
+  bluetooth::Uuid uuid;
+  bluetooth::Uuid uuid_mask;
+  std::vector<uint8_t> name;
+  uint16_t company;
+  uint16_t company_mask;
+  std::vector<uint8_t> data;
+  std::vector<uint8_t> data_mask;
+};
+
 #endif /* ANDROID_INCLUDE_BT_COMMON_TYPES_H */
diff --git a/service/test/low_energy_scanner_unittest.cc b/service/test/low_energy_scanner_unittest.cc
index efb1092..c8b16f3 100644
--- a/service/test/low_energy_scanner_unittest.cc
+++ b/service/test/low_energy_scanner_unittest.cc
@@ -71,14 +71,8 @@
                                StartSyncCb, SyncReportCb, SyncLostCb));
   MOCK_METHOD1(StopSync, void(uint16_t));
 
-  void ScanFilterAddRemove(int action, int filt_type, int filt_index,
-                           int company_id, int company_id_mask,
-                           const bluetooth::Uuid* p_uuid,
-                           const bluetooth::Uuid* p_uuid_mask,
-                           const RawAddress* bd_addr, char addr_type,
-                           std::vector<uint8_t> data,
-                           std::vector<uint8_t> p_mask,
-                           FilterConfigCallback cb){};
+  void ScanFilterAdd(int filter_index, std::vector<ApcfCommand> filters,
+                     FilterConfigCallback cb){};
 
   void ScanFilterParamSetup(
       uint8_t client_if, uint8_t action, uint8_t filt_index,
diff --git a/stack/btm/btm_ble_adv_filter.cc b/stack/btm/btm_ble_adv_filter.cc
index d63c40d..4787abf 100644
--- a/stack/btm/btm_ble_adv_filter.cc
+++ b/stack/btm/btm_ble_adv_filter.cc
@@ -34,6 +34,7 @@
 #include "hcidefs.h"
 #include "hcimsgs.h"
 
+using base::Bind;
 using bluetooth::Uuid;
 
 #define BTM_BLE_ADV_FILT_META_HDR_LENGTH 3
@@ -542,7 +543,7 @@
                            tBTM_BLE_PF_COND_TYPE filter_type,
                            const bluetooth::Uuid& uuid,
                            tBTM_BLE_PF_LOGIC_TYPE cond_logic,
-                           tBTM_BLE_PF_COND_MASK* p_uuid_mask,
+                           const bluetooth::Uuid& uuid_mask,
                            tBTM_BLE_PF_CFG_CBACK cb) {
   uint8_t evt_type;
 
@@ -580,15 +581,16 @@
       return;
     }
 
-    if (p_uuid_mask) {
+    if (!uuid_mask.IsEmpty()) {
       if (uuid_len == Uuid::kNumBytes16) {
-        UINT16_TO_STREAM(p, p_uuid_mask->uuid16_mask);
+        UINT16_TO_STREAM(p, uuid_mask.As16Bit());
         len += Uuid::kNumBytes16;
       } else if (uuid_len == Uuid::kNumBytes32) {
-        UINT32_TO_STREAM(p, p_uuid_mask->uuid32_mask);
+        UINT32_TO_STREAM(p, uuid_mask.As32Bit());
         len += Uuid::kNumBytes32;
       } else if (uuid_len == Uuid::kNumBytes128) {
-        ARRAY_TO_STREAM(p, p_uuid_mask->uuid128_mask, (int)Uuid::kNumBytes128);
+        const auto& tmp = uuid.To128BitLE();
+        ARRAY_TO_STREAM(p, tmp.data(), (int)Uuid::kNumBytes128);
         len += Uuid::kNumBytes128;
       }
     } else {
@@ -603,6 +605,69 @@
   memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR));
 }
 
+void DoNothing(uint8_t a, uint8_t b, uint8_t c) {}
+
+void BTM_LE_PF_set(tBTM_BLE_PF_FILT_INDEX filt_index,
+                   std::vector<ApcfCommand> commands,
+                   tBTM_BLE_PF_CFG_CBACK cb) {
+  int action = BTM_BLE_SCAN_COND_ADD;
+
+  for (const ApcfCommand& cmd : commands) {
+    /* If data is passed, both mask and data have to be the same length */
+    if (cmd.data.size() != cmd.data_mask.size() && cmd.data.size() != 0 &&
+        cmd.data_mask.size() != 0) {
+      LOG(ERROR) << __func__ << " data(" << cmd.data.size() << ") and mask("
+                 << cmd.data_mask.size() << ") are of different size";
+      continue;
+    }
+
+    switch (cmd.type) {
+      case BTM_BLE_PF_ADDR_FILTER: {
+        tBLE_BD_ADDR target_addr;
+        target_addr.bda = cmd.address;
+        target_addr.type = cmd.addr_type;
+
+        BTM_LE_PF_addr_filter(action, filt_index, target_addr, Bind(DoNothing));
+        break;
+      }
+
+      case BTM_BLE_PF_SRVC_DATA:
+        BTM_LE_PF_srvc_data(action, filt_index);
+        break;
+
+      case BTM_BLE_PF_SRVC_UUID:
+      case BTM_BLE_PF_SRVC_SOL_UUID: {
+        BTM_LE_PF_uuid_filter(action, filt_index, cmd.type, cmd.uuid,
+                              BTM_BLE_PF_LOGIC_AND, cmd.uuid_mask,
+                              Bind(DoNothing));
+        break;
+      }
+
+      case BTM_BLE_PF_LOCAL_NAME: {
+        BTM_LE_PF_local_name(action, filt_index, cmd.name, Bind(DoNothing));
+        break;
+      }
+
+      case BTM_BLE_PF_MANU_DATA: {
+        BTM_LE_PF_manu_data(action, filt_index, cmd.company, cmd.company_mask,
+                            cmd.data, cmd.data_mask, Bind(DoNothing));
+        break;
+      }
+
+      case BTM_BLE_PF_SRVC_DATA_PATTERN: {
+        BTM_LE_PF_srvc_data_pattern(action, filt_index, cmd.data, cmd.data_mask,
+                                    Bind(DoNothing));
+        break;
+      }
+
+      default:
+        LOG(ERROR) << __func__ << ": Unknown filter type: " << +cmd.type;
+        break;
+    }
+  }
+  cb.Run(0, 0, 0);
+}
+
 /**
  * all adv payload filter by de-selecting all the adv pf feature bits
  */
@@ -624,10 +689,12 @@
 
     /* clear UUID filter */
     BTM_LE_PF_uuid_filter(BTM_BLE_SCAN_COND_CLEAR, filt_index,
-                          BTM_BLE_PF_SRVC_UUID, {}, 0, nullptr, fDoNothing);
+                          BTM_BLE_PF_SRVC_UUID, {}, 0, Uuid::kEmpty,
+                          fDoNothing);
 
     BTM_LE_PF_uuid_filter(BTM_BLE_SCAN_COND_CLEAR, filt_index,
-                          BTM_BLE_PF_SRVC_SOL_UUID, {}, 0, nullptr, fDoNothing);
+                          BTM_BLE_PF_SRVC_SOL_UUID, {}, 0, Uuid::kEmpty,
+                          fDoNothing);
 
     /* clear service data filter */
     BTM_LE_PF_srvc_data_pattern(BTM_BLE_SCAN_COND_CLEAR, filt_index, {}, {},
diff --git a/stack/include/btm_ble_api.h b/stack/include/btm_ble_api.h
index f7e8a94..f0fb9e6 100644
--- a/stack/include/btm_ble_api.h
+++ b/stack/include/btm_ble_api.h
@@ -763,33 +763,9 @@
 /**
  * This functions are called to configure the adv data payload filter condition
  */
-extern void BTM_LE_PF_srvc_data(tBTM_BLE_SCAN_COND_OP action,
-                                tBTM_BLE_PF_FILT_INDEX filt_index);
-extern void BTM_LE_PF_addr_filter(tBTM_BLE_SCAN_COND_OP action,
-                                  tBTM_BLE_PF_FILT_INDEX filt_index,
-                                  tBLE_BD_ADDR addr, tBTM_BLE_PF_CFG_CBACK cb);
-extern void BTM_LE_PF_local_name(tBTM_BLE_SCAN_COND_OP action,
-                                 tBTM_BLE_PF_FILT_INDEX filt_index,
-                                 std::vector<uint8_t> name,
-                                 tBTM_BLE_PF_CFG_CBACK cb);
-extern void BTM_LE_PF_uuid_filter(tBTM_BLE_SCAN_COND_OP action,
-                                  tBTM_BLE_PF_FILT_INDEX filt_index,
-                                  tBTM_BLE_PF_COND_TYPE filter_type,
-                                  const bluetooth::Uuid& uuid,
-                                  tBTM_BLE_PF_LOGIC_TYPE cond_logic,
-                                  tBTM_BLE_PF_COND_MASK* p_uuid_mask,
-                                  tBTM_BLE_PF_CFG_CBACK cb);
-extern void BTM_LE_PF_manu_data(tBTM_BLE_SCAN_COND_OP action,
-                                tBTM_BLE_PF_FILT_INDEX filt_index,
-                                uint16_t company_id, uint16_t company_id_mask,
-                                std::vector<uint8_t> data,
-                                std::vector<uint8_t> data_mask,
-                                tBTM_BLE_PF_CFG_CBACK cb);
-extern void BTM_LE_PF_srvc_data_pattern(tBTM_BLE_SCAN_COND_OP action,
-                                        tBTM_BLE_PF_FILT_INDEX filt_index,
-                                        std::vector<uint8_t> data,
-                                        std::vector<uint8_t> data_mask,
-                                        tBTM_BLE_PF_CFG_CBACK cb);
+extern void BTM_LE_PF_set(tBTM_BLE_PF_FILT_INDEX filt_index,
+                          std::vector<ApcfCommand> commands,
+                          tBTM_BLE_PF_CFG_CBACK cb);
 extern void BTM_LE_PF_clear(tBTM_BLE_PF_FILT_INDEX filt_index,
                             tBTM_BLE_PF_CFG_CBACK cb);
 
diff --git a/stack/include/btm_ble_api_types.h b/stack/include/btm_ble_api_types.h
index 625b316..36b24af 100644
--- a/stack/include/btm_ble_api_types.h
+++ b/stack/include/btm_ble_api_types.h
@@ -451,12 +451,6 @@
 using tBTM_BLE_PF_PARAM_CB = base::Callback<void(
     uint8_t /* avbl_space */, uint8_t /* action */, uint8_t /* status */)>;
 
-typedef union {
-  uint16_t uuid16_mask;
-  uint32_t uuid32_mask;
-  uint8_t uuid128_mask[bluetooth::Uuid::kNumBytes128];
-} tBTM_BLE_PF_COND_MASK;
-
 /* per device filter + one generic filter indexed by 0 */
 #define BTM_BLE_MAX_FILTER_COUNTER (BTM_BLE_MAX_ADDR_FILTER + 1)