Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 38a6e1b6 authored by Patrick Chang's avatar Patrick Chang Committed by Gerrit Code Review
Browse files

Merge "Avoid active scanning if device is discovered but not connected" into main

parents 354c5007 91585a75
Loading
Loading
Loading
Loading
+17 −1
Original line number Diff line number Diff line
@@ -902,7 +902,15 @@ class CsisClientImpl : public CsisClient {
        auto g = FindCsisGroup(group_id_to_discover);
        LOG_DEBUG("Group size  %d  target size %d", g->GetDesiredSize(),
                  g->GetCurrentSize());
        if (g->GetDesiredSize() > g->GetCurrentSize()) {

        auto dev_waiting_for_bonding_cnt =
            GetNumOfKnownExpectedDevicesWaitingForBonding(g->GetGroupId());
        LOG_DEBUG("Group size: %d, desired size: %d, waiting for bonding: %d",
                  g->GetCurrentSize(), g->GetDesiredSize(),
                  dev_waiting_for_bonding_cnt);

        if (g->GetDesiredSize() >
            g->GetCurrentSize() + dev_waiting_for_bonding_cnt) {
          CsisActiveDiscovery(g);
        }
      }
@@ -1304,6 +1312,14 @@ class CsisClientImpl : public CsisClient {
    return std::move(devices);
  }

  int GetNumOfKnownExpectedDevicesWaitingForBonding(int group_id) {
    return std::count_if(
        devices_.begin(), devices_.end(), [group_id](const auto& device) {
          return device->GetExpectedGroupIdMember() == group_id &&
                 !device->GetCsisInstanceByGroupId(group_id);
        });
  }

  void CacheAndAdvertiseExpectedMember(const RawAddress& address,
                                       int group_id) {
    auto device = FindDeviceByAddress(address);
+94 −0
Original line number Diff line number Diff line
@@ -1089,6 +1089,100 @@ TEST_F(CsisClientTest, test_get_set_sirk) {
  ASSERT_EQ(g_1->GetSirk(), sirk);
}

TEST_F(CsisClientTest,
       test_not_open_duplicate_active_scan_while_bonding_set_member) {
  uint16_t conn_id = 0x0001;
  EXPECT_CALL(dm_interface, BTA_DmBleCsisObserve(true, _)).Times(1);
  SetSampleDatabaseCsis(conn_id, 1, 1);
  TestAppRegister();

  // Here we handle background scan request
  Mock::VerifyAndClearExpectations(&dm_interface);

  TestConnect(test_address);
  InjectConnectedEvent(test_address, 1);

  auto ReadCharacteristicCbGenerator = []() {
    return [](uint16_t conn_id, uint16_t handle, GATT_READ_OP_CB cb,
              void* cb_data) -> void {
      std::vector<uint8_t> value;
      switch (handle) {
        case 0x0003:
          // device name
          value.resize(20);
          break;
        case 0x0021:
          // plain sirk
          value.resize(17);
          value.assign(17, 1);
          break;
        case 0x0024:
          // size
          value.resize(1);
          value.assign(1, 2);
          break;
        case 0x0027:
          // lock
          value.resize(2);
          break;
        case 0x0030:
          // rank
          value.resize(1);
          value.assign(1, 1);
          break;
        default:
          FAIL();
          return;
      }
      if (cb) {
        cb(conn_id, GATT_SUCCESS, handle, value.size(), value.data(), cb_data);
      }
    };
  };

  // We should read 4 times for sirk, rank, size, and lock characteristics
  EXPECT_CALL(gatt_queue, ReadCharacteristic(conn_id, _, _, _))
      .Times(4)
      .WillOnce(Invoke(ReadCharacteristicCbGenerator()))
      .WillOnce(Invoke(ReadCharacteristicCbGenerator()))
      .WillOnce(Invoke(ReadCharacteristicCbGenerator()))
      .WillOnce(Invoke(ReadCharacteristicCbGenerator()));

  // Here is actual active scan request for the first device
  tBTA_DM_SEARCH_CBACK* p_results_cb = nullptr;
  EXPECT_CALL(dm_interface, BTA_DmBleCsisObserve(true, _))
      .Times(1)
      .WillOnce(DoAll(SaveArg<1>(&p_results_cb)));

  GetSearchCompleteEvent(conn_id);

  Mock::VerifyAndClearExpectations(&dm_interface);

  // Simulate we find the set member
  tBTA_DM_SEARCH result;
  result.inq_res.include_rsi = true;
  std::vector<uint8_t> rsi = {0x07, 0x2e, 0x00, 0xed, 0x1a, 0x00, 0x00, 0x00};
  result.inq_res.p_eir = rsi.data();
  result.inq_res.eir_len = 8;
  result.inq_res.bd_addr = test_address2;

  // CSIS client should process set member event to JNI
  EXPECT_CALL(*callbacks, OnSetMemberAvailable(test_address2, 1));

  p_results_cb(BTA_DM_INQ_RES_EVT, &result);

  Mock::VerifyAndClearExpectations(&dm_interface);

  EXPECT_CALL(dm_interface, BTA_DmBleCsisObserve(true, _)).Times(0);

  // Simulate getting duplicate response from remote for the first device
  // At this momoment we should not open second active scan because the set
  // member is already cached and waiting for bonding
  GetSearchCompleteEvent(conn_id);

  Mock::VerifyAndClearExpectations(&dm_interface);
}

TEST_F(CsisClientTest, test_csis_member_not_found) {
  EXPECT_CALL(dm_interface, BTA_DmBleCsisObserve(true, _)).Times(1);
  SetSampleDatabaseDoubleCsis(0x001, 1, 2);