设备监控-回写
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
.cache/clangd/index/DeviceRegistry.cpp.D6392F292F1C203D.idx
Normal file
BIN
.cache/clangd/index/DeviceRegistry.cpp.D6392F292F1C203D.idx
Normal file
Binary file not shown.
BIN
.cache/clangd/index/DeviceRegistry.h.97F54B624D840DC0.idx
Normal file
BIN
.cache/clangd/index/DeviceRegistry.h.97F54B624D840DC0.idx
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -100,6 +100,8 @@ qt_add_executable(softbus_daemon
|
|||||||
|
|
||||||
# device bus: registry skeleton
|
# device bus: registry skeleton
|
||||||
src/device_bus/registry/IDeviceRegistry.h
|
src/device_bus/registry/IDeviceRegistry.h
|
||||||
|
src/device_bus/registry/DeviceRegistry.h
|
||||||
|
src/device_bus/registry/DeviceRegistry.cpp
|
||||||
|
|
||||||
# devices: base skeleton
|
# devices: base skeleton
|
||||||
src/devices/base/IDevice.h
|
src/devices/base/IDevice.h
|
||||||
|
|||||||
Binary file not shown.
7
main.cpp
7
main.cpp
@@ -10,6 +10,11 @@
|
|||||||
void signalHandler(int signal)
|
void signalHandler(int signal)
|
||||||
{
|
{
|
||||||
LOG_INFO() << "Received signal:" << signal;
|
LOG_INFO() << "Received signal:" << signal;
|
||||||
|
CoreService* coreService = CoreService::instance();
|
||||||
|
if (coreService) {
|
||||||
|
coreService->shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
QCoreApplication::quit();
|
QCoreApplication::quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,7 +73,7 @@ int main(int argc, char *argv[])
|
|||||||
LOG_ERROR() << "CoreService initialize failed";
|
LOG_ERROR() << "CoreService initialize failed";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
QObject::connect(&app, &QCoreApplication::aboutToQuit, coreService, &CoreService::shutdown);
|
// QObject::connect(&app, &QCoreApplication::aboutToQuit, coreService, &CoreService::shutdown);
|
||||||
|
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
// 创建并注册 D-Bus 服务(仅在 CoreRouter 角色中启用)
|
// 创建并注册 D-Bus 服务(仅在 CoreRouter 角色中启用)
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ CoreService::CoreService(QObject* parent)
|
|||||||
|
|
||||||
CoreService::~CoreService()
|
CoreService::~CoreService()
|
||||||
{
|
{
|
||||||
shutdown();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CoreService::initialize()
|
bool CoreService::initialize()
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include "device_bus/manager/DeviceBusManager.h"
|
#include "device_bus/manager/DeviceBusManager.h"
|
||||||
#include "device_bus/monitor/DeviceMonitorService.h"
|
#include "device_bus/monitor/DeviceMonitorService.h"
|
||||||
|
#include "device_bus/registry/DeviceRegistry.h"
|
||||||
#include "device_bus/tree/DeviceTreeModel.h"
|
#include "device_bus/tree/DeviceTreeModel.h"
|
||||||
#include "utils/logs/logging.h"
|
#include "utils/logs/logging.h"
|
||||||
|
|
||||||
@@ -14,11 +15,12 @@ namespace softbus::device_bus {
|
|||||||
|
|
||||||
class DeviceBus::Impl {
|
class DeviceBus::Impl {
|
||||||
public:
|
public:
|
||||||
DeviceBusManager manager;
|
std::unique_ptr<DeviceBusManager> manager;
|
||||||
std::unique_ptr<monitor::DeviceMonitorService> monitorService;
|
std::unique_ptr<monitor::DeviceMonitorService> monitorService;
|
||||||
|
std::unique_ptr<registry::DeviceRegistry> registry;
|
||||||
std::shared_ptr<DeviceTreeModel> treeModel;
|
std::shared_ptr<DeviceTreeModel> treeModel;
|
||||||
QString configPath;
|
QString configPath;
|
||||||
bool deviceTreeDirty{false};
|
bool deviceTreeDirty{false}; // 设备树是否脏了
|
||||||
};
|
};
|
||||||
|
|
||||||
DeviceBus &DeviceBus::instance() {
|
DeviceBus &DeviceBus::instance() {
|
||||||
@@ -34,37 +36,61 @@ DeviceBus::~DeviceBus() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool DeviceBus::initialize(const QJsonObject &rootConfig) {
|
bool DeviceBus::initialize(const QJsonObject &rootConfig) {
|
||||||
if (!d->monitorService) {
|
if (!d) {
|
||||||
d->monitorService = std::make_unique<monitor::DeviceMonitorService>(nullptr);
|
return false;
|
||||||
if (!d->monitorService->start()) {
|
|
||||||
LOG_WARNING() << "DeviceBus: device monitor service start failed";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!d->treeModel) {
|
if (!d->treeModel) {
|
||||||
d->treeModel = std::make_shared<DeviceTreeModel>();
|
d->treeModel = std::make_shared<DeviceTreeModel>();
|
||||||
}
|
}
|
||||||
d->manager.setDeviceTreeModel(d->treeModel);
|
if (!d->manager) {
|
||||||
return d->manager.initialize(rootConfig);
|
d->manager = std::make_unique<DeviceBusManager>();
|
||||||
|
}
|
||||||
|
if (!d->registry) {
|
||||||
|
d->registry = std::make_unique<registry::DeviceRegistry>(d->treeModel);
|
||||||
|
}
|
||||||
|
d->manager->setDeviceTreeModel(d->treeModel);
|
||||||
|
d->manager->setRegistry(d->registry.get());
|
||||||
|
|
||||||
|
if (!d->monitorService) {
|
||||||
|
d->monitorService = std::make_unique<monitor::DeviceMonitorService>(nullptr);
|
||||||
|
d->monitorService->setRegistry(d->registry.get());
|
||||||
|
d->monitorService->setDirtyCallback([this]() { this->markDeviceTreeDirty(); });
|
||||||
|
if (!d->monitorService->start()) {
|
||||||
|
LOG_WARNING() << "DeviceBus: device monitor service start failed";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return d->manager->initialize(rootConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceBus::shutdown() {
|
void DeviceBus::shutdown() {
|
||||||
|
if (!d) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (d->monitorService) {
|
if (d->monitorService) {
|
||||||
|
LOG_INFO() << "DeviceBus shutting down monitor service";
|
||||||
d->monitorService->stop();
|
d->monitorService->stop();
|
||||||
d->monitorService.reset();
|
d->monitorService.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
d->manager.shutdown();
|
if (d->manager) {
|
||||||
|
LOG_INFO() << "DeviceBus shutting down manager";
|
||||||
|
d->manager->shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
if (!d->deviceTreeDirty) {
|
if (!d->deviceTreeDirty) {
|
||||||
|
LOG_INFO() << "DeviceBus device tree dirty is false";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d->configPath.isEmpty() || !d->treeModel) {
|
if (d->configPath.isEmpty() || !d->treeModel) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QFileInfo fi(d->configPath);
|
const QFileInfo fi(d->configPath);
|
||||||
const QString dirPath = fi.dir().absolutePath();
|
const QString dirPath = fi.dir().absolutePath();
|
||||||
|
LOG_INFO() << "DeviceBus: saving config to" << dirPath;
|
||||||
if (!QDir().mkpath(dirPath)) {
|
if (!QDir().mkpath(dirPath)) {
|
||||||
LOG_ERROR() << "DeviceBus: failed to create config dir" << dirPath;
|
LOG_ERROR() << "DeviceBus: failed to create config dir" << dirPath;
|
||||||
return;
|
return;
|
||||||
@@ -92,18 +118,22 @@ void DeviceBus::shutdown() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DeviceBus::setConfigPath(const QString& path) {
|
void DeviceBus::setConfigPath(const QString& path) {
|
||||||
|
if (!d) return;
|
||||||
d->configPath = path;
|
d->configPath = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString DeviceBus::configPath() const {
|
QString DeviceBus::configPath() const {
|
||||||
|
if (!d) return {};
|
||||||
return d->configPath;
|
return d->configPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<DeviceTreeModel> DeviceBus::deviceTreeModel() const {
|
std::shared_ptr<DeviceTreeModel> DeviceBus::deviceTreeModel() const {
|
||||||
|
if (!d) return {};
|
||||||
return d->treeModel;
|
return d->treeModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceBus::markDeviceTreeDirty() {
|
void DeviceBus::markDeviceTreeDirty() {
|
||||||
|
if (!d) return;
|
||||||
d->deviceTreeDirty = true;
|
d->deviceTreeDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
#include <QSerialPort>
|
#include <QSerialPort>
|
||||||
#include <algorithm>
|
// #include <algorithm>
|
||||||
|
|
||||||
#include "hardware/drivers/serial/SerialQtDriver.h"
|
#include "hardware/drivers/serial/SerialQtDriver.h"
|
||||||
#include "hardware/drivers/serial/SerialCapabilities.h"
|
#include "hardware/drivers/serial/SerialCapabilities.h"
|
||||||
@@ -19,6 +19,11 @@ void DeviceBusManager::setDeviceTreeModel(std::shared_ptr<DeviceTreeModel> model
|
|||||||
m_treeModel = std::move(model);
|
m_treeModel = std::move(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DeviceBusManager::setRegistry(softbus::device_bus::registry::IDeviceRegistry* registry)
|
||||||
|
{
|
||||||
|
m_registry = registry;
|
||||||
|
}
|
||||||
|
|
||||||
bool DeviceBusManager::initialize(const QJsonObject& rootConfig)
|
bool DeviceBusManager::initialize(const QJsonObject& rootConfig)
|
||||||
{
|
{
|
||||||
if (!m_treeModel) {
|
if (!m_treeModel) {
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ class DeviceBusManager
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void setDeviceTreeModel(std::shared_ptr<DeviceTreeModel> model);
|
void setDeviceTreeModel(std::shared_ptr<DeviceTreeModel> model);
|
||||||
|
void setRegistry(softbus::device_bus::registry::IDeviceRegistry* registry);
|
||||||
|
|
||||||
bool initialize(const QJsonObject& rootConfig);
|
bool initialize(const QJsonObject& rootConfig);
|
||||||
void shutdown();
|
void shutdown();
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
|
|
||||||
|
#include "device_bus/registry/IDeviceRegistry.h"
|
||||||
#include "utils/logs/logging.h"
|
#include "utils/logs/logging.h"
|
||||||
|
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
@@ -57,6 +58,16 @@ void DeviceMonitorService::stop()
|
|||||||
m_started = false;
|
m_started = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DeviceMonitorService::setRegistry(softbus::device_bus::registry::IDeviceRegistry* registry)
|
||||||
|
{
|
||||||
|
m_registry = registry;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceMonitorService::setDirtyCallback(std::function<void()> cb)
|
||||||
|
{
|
||||||
|
m_dirtyCb = std::move(cb);
|
||||||
|
}
|
||||||
|
|
||||||
void DeviceMonitorService::onEvent(const DeviceEvent& ev)
|
void DeviceMonitorService::onEvent(const DeviceEvent& ev)
|
||||||
{
|
{
|
||||||
// De-dup (short window): suppress identical events bursts
|
// De-dup (short window): suppress identical events bursts
|
||||||
@@ -78,6 +89,18 @@ void DeviceMonitorService::onEvent(const DeviceEvent& ev)
|
|||||||
}
|
}
|
||||||
m_lastEventMsByKey.insert(key, nowMs);
|
m_lastEventMsByKey.insert(key, nowMs);
|
||||||
|
|
||||||
|
if (m_registry) {
|
||||||
|
bool changed = false;
|
||||||
|
if (ev.action == DeviceEventAction::Add || ev.action == DeviceEventAction::Change) {
|
||||||
|
changed = m_registry->upsertFromMonitorEvent(ev);
|
||||||
|
} else if (ev.action == DeviceEventAction::Remove) {
|
||||||
|
changed = m_registry->markOfflineFromMonitorEvent(ev);
|
||||||
|
}
|
||||||
|
if (changed && m_dirtyCb) {
|
||||||
|
m_dirtyCb();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 第一版:仅日志
|
// 第一版:仅日志
|
||||||
LOG_INFO() << "DeviceMonitor event"
|
LOG_INFO() << "DeviceMonitor event"
|
||||||
<< "type=" << toString(ev.type)
|
<< "type=" << toString(ev.type)
|
||||||
|
|||||||
@@ -5,9 +5,12 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
#include "device_bus/monitor/IDeviceMonitor.h"
|
#include "device_bus/monitor/IDeviceMonitor.h"
|
||||||
|
|
||||||
|
namespace softbus::device_bus::registry { class IDeviceRegistry; }
|
||||||
|
|
||||||
namespace softbus::device_bus::monitor
|
namespace softbus::device_bus::monitor
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -20,6 +23,8 @@ public:
|
|||||||
|
|
||||||
bool start();
|
bool start();
|
||||||
void stop();
|
void stop();
|
||||||
|
void setRegistry(softbus::device_bus::registry::IDeviceRegistry* registry);
|
||||||
|
void setDirtyCallback(std::function<void()> cb);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onEvent(const DeviceEvent& ev);
|
void onEvent(const DeviceEvent& ev);
|
||||||
@@ -27,6 +32,8 @@ private:
|
|||||||
private:
|
private:
|
||||||
std::vector<std::unique_ptr<IDeviceMonitor>> m_monitors;
|
std::vector<std::unique_ptr<IDeviceMonitor>> m_monitors;
|
||||||
bool m_started{false};
|
bool m_started{false};
|
||||||
|
softbus::device_bus::registry::IDeviceRegistry* m_registry{nullptr};
|
||||||
|
std::function<void()> m_dirtyCb;
|
||||||
|
|
||||||
// Lightweight de-dup: key -> last timestamp (ms)
|
// Lightweight de-dup: key -> last timestamp (ms)
|
||||||
QHash<QString, qint64> m_lastEventMsByKey;
|
QHash<QString, qint64> m_lastEventMsByKey;
|
||||||
|
|||||||
166
src/device_bus/registry/DeviceRegistry.cpp
Normal file
166
src/device_bus/registry/DeviceRegistry.cpp
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
#include "device_bus/registry/DeviceRegistry.h"
|
||||||
|
|
||||||
|
#include <QCryptographicHash>
|
||||||
|
#include <QDateTime>
|
||||||
|
|
||||||
|
#include "utils/logs/logging.h"
|
||||||
|
|
||||||
|
namespace softbus::device_bus::registry
|
||||||
|
{
|
||||||
|
|
||||||
|
DeviceRegistry::DeviceRegistry(std::shared_ptr<DeviceTreeModel> treeModel)
|
||||||
|
: m_treeModel(std::move(treeModel))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceRegistry::registerDevice(const softbus::devices::DeviceInfo& info)
|
||||||
|
{
|
||||||
|
m_devicesById.insert(info.id, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceRegistry::unregisterDevice(int id)
|
||||||
|
{
|
||||||
|
m_devicesById.remove(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<softbus::devices::DeviceInfo> DeviceRegistry::findById(int id) const
|
||||||
|
{
|
||||||
|
auto it = m_devicesById.constFind(id);
|
||||||
|
if (it == m_devicesById.constEnd()) {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
return it.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<softbus::devices::DeviceInfo> DeviceRegistry::listDevices() const
|
||||||
|
{
|
||||||
|
std::vector<softbus::devices::DeviceInfo> out;
|
||||||
|
out.reserve(m_devicesById.size());
|
||||||
|
for (auto it = m_devicesById.cbegin(); it != m_devicesById.cend(); ++it) {
|
||||||
|
out.push_back(it.value());
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DeviceRegistry::upsertFromMonitorEvent(const softbus::device_bus::monitor::DeviceEvent& ev)
|
||||||
|
{
|
||||||
|
if (!m_treeModel) return false;
|
||||||
|
|
||||||
|
const QString stableKey = buildStableKey(ev);
|
||||||
|
if (stableKey.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const QString preferredId = buildPreferredNodeId(ev, stableKey);
|
||||||
|
const QString now = QDateTime::currentDateTimeUtc().toString(Qt::ISODate);
|
||||||
|
|
||||||
|
const QString nodeId = m_treeModel->upsertNodeByStableKey(
|
||||||
|
stableKey,
|
||||||
|
preferredId,
|
||||||
|
inferType(ev),
|
||||||
|
inferEndpoint(ev),
|
||||||
|
inferName(ev),
|
||||||
|
buildParams(ev),
|
||||||
|
true,
|
||||||
|
now);
|
||||||
|
|
||||||
|
if (!nodeId.isEmpty()) {
|
||||||
|
m_stableKeyToNodeId.insert(stableKey, nodeId);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DeviceRegistry::markOfflineFromMonitorEvent(const softbus::device_bus::monitor::DeviceEvent& ev)
|
||||||
|
{
|
||||||
|
if (!m_treeModel) return false;
|
||||||
|
const QString stableKey = buildStableKey(ev);
|
||||||
|
if (stableKey.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const QString now = QDateTime::currentDateTimeUtc().toString(Qt::ISODate);
|
||||||
|
return m_treeModel->markOfflineByStableKey(stableKey, now);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString DeviceRegistry::buildStableKey(const softbus::device_bus::monitor::DeviceEvent& ev)
|
||||||
|
{
|
||||||
|
const QString type = inferType(ev);
|
||||||
|
|
||||||
|
if (!ev.serial.isEmpty()) {
|
||||||
|
return type + QStringLiteral("|serial|") + ev.serial;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ev.type == softbus::device_bus::monitor::DeviceEventType::NetInterface) {
|
||||||
|
if (!ev.ifname.isEmpty()) return type + QStringLiteral("|ifname|") + ev.ifname;
|
||||||
|
if (ev.ifindex >= 0) return type + QStringLiteral("|ifindex|") + QString::number(ev.ifindex);
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString path = !ev.props.value(QStringLiteral("SYSPATH")).isEmpty()
|
||||||
|
? ev.props.value(QStringLiteral("SYSPATH"))
|
||||||
|
: (!ev.devicePath.isEmpty() ? ev.devicePath : ev.devnode);
|
||||||
|
if (!ev.vid.isEmpty() || !ev.pid.isEmpty() || !path.isEmpty()) {
|
||||||
|
return type + QStringLiteral("|vpidpath|") + ev.vid + QStringLiteral(":") + ev.pid + QStringLiteral("|") + path;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ev.devnode.isEmpty()) {
|
||||||
|
return type + QStringLiteral("|devnode|") + ev.devnode;
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
QString DeviceRegistry::buildPreferredNodeId(const softbus::device_bus::monitor::DeviceEvent& ev, const QString& stableKey)
|
||||||
|
{
|
||||||
|
if (!ev.serial.isEmpty()) {
|
||||||
|
return QStringLiteral("dev_serial_") + ev.serial;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QByteArray hash = QCryptographicHash::hash(stableKey.toUtf8(), QCryptographicHash::Sha1).toHex();
|
||||||
|
return QStringLiteral("dev_") + QString::fromUtf8(hash.left(12));
|
||||||
|
}
|
||||||
|
|
||||||
|
QString DeviceRegistry::inferType(const softbus::device_bus::monitor::DeviceEvent& ev)
|
||||||
|
{
|
||||||
|
using softbus::device_bus::monitor::DeviceEventType;
|
||||||
|
switch (ev.type) {
|
||||||
|
case DeviceEventType::Serial: return QStringLiteral("serial");
|
||||||
|
case DeviceEventType::NetInterface: return QStringLiteral("network");
|
||||||
|
case DeviceEventType::Storage: return QStringLiteral("storage");
|
||||||
|
case DeviceEventType::Usb: return QStringLiteral("usb");
|
||||||
|
default: return QStringLiteral("unknown");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString DeviceRegistry::inferEndpoint(const softbus::device_bus::monitor::DeviceEvent& ev)
|
||||||
|
{
|
||||||
|
if (!ev.devnode.isEmpty()) return ev.devnode;
|
||||||
|
if (!ev.ifname.isEmpty()) return ev.ifname;
|
||||||
|
if (!ev.devicePath.isEmpty()) return ev.devicePath;
|
||||||
|
return ev.props.value(QStringLiteral("SYSPATH"));
|
||||||
|
}
|
||||||
|
|
||||||
|
QString DeviceRegistry::inferName(const softbus::device_bus::monitor::DeviceEvent& ev)
|
||||||
|
{
|
||||||
|
if (!ev.model.isEmpty()) return ev.model;
|
||||||
|
if (!ev.ifname.isEmpty()) return ev.ifname;
|
||||||
|
if (!ev.devnode.isEmpty()) return ev.devnode;
|
||||||
|
return inferType(ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject DeviceRegistry::buildParams(const softbus::device_bus::monitor::DeviceEvent& ev)
|
||||||
|
{
|
||||||
|
QJsonObject p;
|
||||||
|
p.insert(QStringLiteral("online"), true);
|
||||||
|
if (!ev.vid.isEmpty()) p.insert(QStringLiteral("vid"), ev.vid);
|
||||||
|
if (!ev.pid.isEmpty()) p.insert(QStringLiteral("pid"), ev.pid);
|
||||||
|
if (!ev.serial.isEmpty()) p.insert(QStringLiteral("serial"), ev.serial);
|
||||||
|
if (!ev.vendor.isEmpty()) p.insert(QStringLiteral("vendor"), ev.vendor);
|
||||||
|
if (!ev.model.isEmpty()) p.insert(QStringLiteral("model"), ev.model);
|
||||||
|
if (!ev.ifname.isEmpty()) p.insert(QStringLiteral("ifname"), ev.ifname);
|
||||||
|
if (ev.ifindex >= 0) p.insert(QStringLiteral("ifindex"), ev.ifindex);
|
||||||
|
if (!ev.subsystem.isEmpty()) p.insert(QStringLiteral("subsystem"), ev.subsystem);
|
||||||
|
if (!ev.devicePath.isEmpty()) p.insert(QStringLiteral("devicePath"), ev.devicePath);
|
||||||
|
if (!ev.devnode.isEmpty()) p.insert(QStringLiteral("devnode"), ev.devnode);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace softbus::device_bus::registry
|
||||||
|
|
||||||
44
src/device_bus/registry/DeviceRegistry.h
Normal file
44
src/device_bus/registry/DeviceRegistry.h
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QHash>
|
||||||
|
#include <memory>
|
||||||
|
#include <optional>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "device_bus/registry/IDeviceRegistry.h"
|
||||||
|
#include "device_bus/tree/DeviceTreeModel.h"
|
||||||
|
|
||||||
|
namespace softbus::device_bus::registry
|
||||||
|
{
|
||||||
|
|
||||||
|
class DeviceRegistry : public IDeviceRegistry
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit DeviceRegistry(std::shared_ptr<DeviceTreeModel> treeModel);
|
||||||
|
~DeviceRegistry() override = default;
|
||||||
|
|
||||||
|
void registerDevice(const softbus::devices::DeviceInfo& info) override;
|
||||||
|
void unregisterDevice(int id) override;
|
||||||
|
|
||||||
|
std::optional<softbus::devices::DeviceInfo> findById(int id) const override;
|
||||||
|
std::vector<softbus::devices::DeviceInfo> listDevices() const override;
|
||||||
|
|
||||||
|
bool upsertFromMonitorEvent(const softbus::device_bus::monitor::DeviceEvent& ev) override;
|
||||||
|
bool markOfflineFromMonitorEvent(const softbus::device_bus::monitor::DeviceEvent& ev) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static QString buildStableKey(const softbus::device_bus::monitor::DeviceEvent& ev);
|
||||||
|
static QString buildPreferredNodeId(const softbus::device_bus::monitor::DeviceEvent& ev, const QString& stableKey);
|
||||||
|
static QString inferType(const softbus::device_bus::monitor::DeviceEvent& ev);
|
||||||
|
static QString inferEndpoint(const softbus::device_bus::monitor::DeviceEvent& ev);
|
||||||
|
static QString inferName(const softbus::device_bus::monitor::DeviceEvent& ev);
|
||||||
|
static QJsonObject buildParams(const softbus::device_bus::monitor::DeviceEvent& ev);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr<DeviceTreeModel> m_treeModel;
|
||||||
|
QHash<int, softbus::devices::DeviceInfo> m_devicesById;
|
||||||
|
QHash<QString, QString> m_stableKeyToNodeId;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace softbus::device_bus::registry
|
||||||
|
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "devices/DeviceTypes.h"
|
#include "devices/DeviceTypes.h"
|
||||||
|
#include "device_bus/monitor/DeviceEvent.h"
|
||||||
|
|
||||||
namespace softbus::device_bus::registry
|
namespace softbus::device_bus::registry
|
||||||
{
|
{
|
||||||
@@ -18,6 +19,10 @@ public:
|
|||||||
|
|
||||||
virtual std::optional<softbus::devices::DeviceInfo> findById(int id) const = 0;
|
virtual std::optional<softbus::devices::DeviceInfo> findById(int id) const = 0;
|
||||||
virtual std::vector<softbus::devices::DeviceInfo> listDevices() const = 0;
|
virtual std::vector<softbus::devices::DeviceInfo> listDevices() const = 0;
|
||||||
|
|
||||||
|
// Monitor-driven registry APIs
|
||||||
|
virtual bool upsertFromMonitorEvent(const softbus::device_bus::monitor::DeviceEvent& ev) = 0;
|
||||||
|
virtual bool markOfflineFromMonitorEvent(const softbus::device_bus::monitor::DeviceEvent& ev) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace softbus::device_bus::registry
|
} // namespace softbus::device_bus::registry
|
||||||
|
|||||||
@@ -118,14 +118,96 @@ QJsonObject DeviceTreeModel::toDaemonConfigRoot() const
|
|||||||
|
|
||||||
const DeviceTreeNode* DeviceTreeModel::findById(const QString& id) const
|
const DeviceTreeNode* DeviceTreeModel::findById(const QString& id) const
|
||||||
{
|
{
|
||||||
const auto it = m_indexById.constFind(id);
|
const int index = findIndexById(id);
|
||||||
if (it == m_indexById.constEnd()) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
const int index = it.value();
|
|
||||||
if (index < 0 || index >= m_nodes.size()) {
|
if (index < 0 || index >= m_nodes.size()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return &m_nodes.at(index);
|
return &m_nodes.at(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int DeviceTreeModel::findIndexById(const QString& id) const
|
||||||
|
{
|
||||||
|
const auto it = m_indexById.constFind(id);
|
||||||
|
if (it == m_indexById.constEnd()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return it.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
int DeviceTreeModel::findIndexByStableKey(const QString& stableKey) const
|
||||||
|
{
|
||||||
|
if (stableKey.isEmpty()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < m_nodes.size(); ++i) {
|
||||||
|
const auto& n = m_nodes.at(i);
|
||||||
|
if (n.params.value(QStringLiteral("stableKey")).toString() == stableKey) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString DeviceTreeModel::upsertNodeByStableKey(const QString& stableKey,
|
||||||
|
const QString& preferredId,
|
||||||
|
const QString& type,
|
||||||
|
const QString& endpoint,
|
||||||
|
const QString& name,
|
||||||
|
const QJsonObject& extraParams,
|
||||||
|
bool online,
|
||||||
|
const QString& lastSeenTs)
|
||||||
|
{
|
||||||
|
int idx = findIndexByStableKey(stableKey);
|
||||||
|
if (idx < 0 && !preferredId.isEmpty()) {
|
||||||
|
idx = findIndexById(preferredId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idx < 0) {
|
||||||
|
DeviceTreeNode node;
|
||||||
|
node.id = preferredId;
|
||||||
|
node.type = type;
|
||||||
|
node.endpoint = endpoint;
|
||||||
|
node.name = name;
|
||||||
|
node.enabled = true;
|
||||||
|
node.params = extraParams;
|
||||||
|
node.params.insert(QStringLiteral("stableKey"), stableKey);
|
||||||
|
node.params.insert(QStringLiteral("online"), online);
|
||||||
|
if (!lastSeenTs.isEmpty()) {
|
||||||
|
node.params.insert(QStringLiteral("lastSeenTs"), lastSeenTs);
|
||||||
|
}
|
||||||
|
m_nodes.push_back(node);
|
||||||
|
rebuildIndex();
|
||||||
|
return node.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& node = m_nodes[idx];
|
||||||
|
if (!type.isEmpty()) node.type = type;
|
||||||
|
if (!endpoint.isEmpty()) node.endpoint = endpoint;
|
||||||
|
if (!name.isEmpty()) node.name = name;
|
||||||
|
node.enabled = true;
|
||||||
|
|
||||||
|
for (auto it = extraParams.begin(); it != extraParams.end(); ++it) {
|
||||||
|
node.params.insert(it.key(), it.value());
|
||||||
|
}
|
||||||
|
node.params.insert(QStringLiteral("stableKey"), stableKey);
|
||||||
|
node.params.insert(QStringLiteral("online"), online);
|
||||||
|
if (!lastSeenTs.isEmpty()) {
|
||||||
|
node.params.insert(QStringLiteral("lastSeenTs"), lastSeenTs);
|
||||||
|
}
|
||||||
|
return node.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DeviceTreeModel::markOfflineByStableKey(const QString& stableKey, const QString& lastSeenTs)
|
||||||
|
{
|
||||||
|
const int idx = findIndexByStableKey(stableKey);
|
||||||
|
if (idx < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto& node = m_nodes[idx];
|
||||||
|
node.params.insert(QStringLiteral("online"), false);
|
||||||
|
if (!lastSeenTs.isEmpty()) {
|
||||||
|
node.params.insert(QStringLiteral("lastSeenTs"), lastSeenTs);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,19 @@ public:
|
|||||||
QVector<DeviceTreeNode>& nodesMutable() { return m_nodes; }
|
QVector<DeviceTreeNode>& nodesMutable() { return m_nodes; }
|
||||||
|
|
||||||
const DeviceTreeNode* findById(const QString& id) const;
|
const DeviceTreeNode* findById(const QString& id) const;
|
||||||
|
int findIndexById(const QString& id) const;
|
||||||
|
int findIndexByStableKey(const QString& stableKey) const;
|
||||||
|
|
||||||
|
// Monitor/register path: upsert or mark online/offline
|
||||||
|
QString upsertNodeByStableKey(const QString& stableKey,
|
||||||
|
const QString& preferredId,
|
||||||
|
const QString& type,
|
||||||
|
const QString& endpoint,
|
||||||
|
const QString& name,
|
||||||
|
const QJsonObject& extraParams,
|
||||||
|
bool online,
|
||||||
|
const QString& lastSeenTs);
|
||||||
|
bool markOfflineByStableKey(const QString& stableKey, const QString& lastSeenTs);
|
||||||
|
|
||||||
// 序列化为 daemon_config.json 所需格式
|
// 序列化为 daemon_config.json 所需格式
|
||||||
QJsonArray toDeviceTreeJson() const;
|
QJsonArray toDeviceTreeJson() const;
|
||||||
|
|||||||
Reference in New Issue
Block a user