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

Commit 00c3520d authored by Myles Watson's avatar Myles Watson
Browse files

RootCanal: Schedule device and phy deletions

Actions that are scheduled on the same thread as the
timer tick won't conflict.

Bug: 154020729
Bug: 161919939
Bug: 159847796
Test: cert/run --host
Tag: #stability
Change-Id: I4b0ed942a5b95d818acaf352e5183e523a74e595
parent 84e3cb66
Loading
Loading
Loading
Loading
+36 −26
Original line number Diff line number Diff line
@@ -37,9 +37,6 @@
#include "base/values.h"

#include "os/log.h"
#include "osi/include/osi.h"

#include "device_boutique.h"
#include "include/phy.h"
#include "model/devices/hci_socket_device.h"
#include "model/devices/link_layer_socket_device.h"
@@ -103,7 +100,7 @@ void TestModel::StopTimer() {
}

size_t TestModel::Add(std::shared_ptr<Device> new_dev) {
  devices_.push_back(new_dev);
  devices_.push_back(std::move(new_dev));
  return devices_.size() - 1;
}

@@ -112,8 +109,11 @@ void TestModel::Del(size_t dev_index) {
    LOG_WARN("Unknown device %zu", dev_index);
    return;
  }
  schedule_task_(model_user_id_, std::chrono::milliseconds(0),
                 [this, dev_index]() {
                   devices_[dev_index]->UnregisterPhyLayers();
                   devices_[dev_index] = nullptr;
                 });
}

size_t TestModel::AddPhy(Phy::Type phy_type) {
@@ -127,7 +127,9 @@ void TestModel::DelPhy(size_t phy_index) {
    LOG_WARN("Unknown phy at index %zu", phy_index);
    return;
  }
  phys_[phy_index].UnregisterAllPhyLayers();
  schedule_task_(
      model_user_id_, std::chrono::milliseconds(0),
      [this, phy_index]() { phys_[phy_index].UnregisterAllPhyLayers(); });
}

void TestModel::AddDeviceToPhy(size_t dev_index, size_t phy_index) {
@@ -142,7 +144,7 @@ void TestModel::AddDeviceToPhy(size_t dev_index, size_t phy_index) {
  auto dev = devices_[dev_index];
  dev->RegisterPhyLayer(phys_[phy_index].GetPhyLayer(
      [dev](model::packets::LinkLayerPacketView packet) {
        dev->IncomingPacket(packet);
        dev->IncomingPacket(std::move(packet));
      },
      dev_index));
}
@@ -156,8 +158,12 @@ void TestModel::DelDeviceFromPhy(size_t dev_index, size_t phy_index) {
    LOG_WARN("Can't find phy %zu", phy_index);
    return;
  }
  devices_[dev_index]->UnregisterPhyLayer(phys_[phy_index].GetType(),
  schedule_task_(model_user_id_, std::chrono::milliseconds(0),
                 [this, dev_index, phy_index]() {
                   devices_[dev_index]->UnregisterPhyLayer(
                       phys_[phy_index].GetType(),
                       phys_[phy_index].GetFactoryId());
                 });
}

void TestModel::AddLinkLayerConnection(int socket_fd, Phy::Type phy_type) {
@@ -197,15 +203,17 @@ void TestModel::IncomingHciConnection(int socket_fd) {
    AddDeviceToPhy(index, i);
  }
  AsyncUserId user_id = get_user_id_();
  dev->RegisterTaskScheduler(
      [user_id, this](std::chrono::milliseconds delay,
                      const TaskCallback& task_callback) {
  dev->RegisterTaskScheduler([user_id, this](std::chrono::milliseconds delay,
                                             TaskCallback task_callback) {
    return schedule_task_(user_id, delay, std::move(task_callback));
  });
  dev->RegisterTaskCancel(cancel_task_);
  dev->RegisterCloseCallback([this, socket_fd, index, user_id] {
    schedule_task_(user_id, std::chrono::milliseconds(0),
                   [this, socket_fd, index, user_id]() {
                     OnHciConnectionClosed(socket_fd, index, user_id);
                   });
  });
}

void TestModel::OnHciConnectionClosed(int socket_fd, size_t index,
@@ -227,7 +235,7 @@ void TestModel::SetDeviceAddress(size_t index, Address address) {
    LOG_WARN("Can't find device %zu", index);
    return;
  }
  devices_[index]->SetAddress(address);
  devices_[index]->SetAddress(std::move(address));
}

const std::string& TestModel::List() {
@@ -250,22 +258,24 @@ const std::string& TestModel::List() {
}

void TestModel::TimerTick() {
  for (const auto& dev : devices_) {
    if (dev != nullptr) {
      dev->TimerTick();
  for (size_t i = 0; i < devices_.size(); i++) {
    if (devices_[i] != nullptr) {
      devices_[i]->TimerTick();
    }
  }
}

void TestModel::Reset() {
  StopTimer();
  for (const auto& dev : devices_) {
    if (dev != nullptr) {
      dev->UnregisterPhyLayers();
  schedule_task_(model_user_id_, std::chrono::milliseconds(0), [this]() {
    LOG_INFO("Running Reset task");
    for (size_t i = 0; i < devices_.size(); i++) {
      if (devices_[i] != nullptr) {
        devices_[i]->UnregisterPhyLayers();
      }
    }
    devices_.clear();
  phys_.clear();
  });
}

}  // namespace test_vendor_lib