Phase 1: 硬件探针与能力分级详细设计文档¶
文档信息¶
| 项目 | 内容 |
|---|---|
| 文档版本 | v1.0 |
| 创建日期 | 2026-02-20 |
| 阶段代号 | Phase 1 - 硬件探针与能力分级 |
| 预计周期 | 2~3 周 |
| 依赖阶段 | Phase 0 |
一、阶段目标¶
1.1 核心目标¶
实现开机自动硬件检测,输出能力档位枚举,作为后续所有模块的行为裁剪依据。
1.2 具体交付物¶
- [ ]
HardwareProbe模块及其单元测试 - [ ]
CapabilityPolicy策略引擎 - [ ]
HWTier枚举定义及查询接口 - [ ] 设备配置文件
/etc/CFDesktop/device.conf - [ ] Mock 数据集用于单元测试
二、模块架构设计¶
2.1 整体架构图¶
┌─────────────────────────────────────────────────────────┐
│ Application Layer │
│ (使用 HWTier 查询) │
├─────────────────────────────────────────────────────────┤
│ CapabilityPolicy (策略引擎) │
│ ┌────────────────────────────────────────────┐ │
│ │ getAnimationPolicy() │ │
│ │ getRenderingBackend() │ │
│ │ getVideoDecoderPolicy() │ │
│ │ getMemoryPolicy() │ │
│ └────────────────────────────────────────────┘ │
├─────────────────────────────────────────────────────────┤
│ HardwareProbe (硬件探针) │
│ ┌────────────────────────────────────────────┐ │
│ │ detectCPU() │ │
│ │ detectGPU() │ │
│ │ detectMemory() │ │
│ │ detectNetwork() │ │
│ │ calculateTier() │ │
│ └────────────────────────────────────────────┘ │
├─────────────────────────────────────────────────────────┤
│ Platform Abstraction (平台抽象) │
│ /proc/cpuinfo /sys/class/ /dev/dri/ evdev │
└─────────────────────────────────────────────────────────┘
2.2 文件结构¶
src/base/
├── include/CFDesktop/Base/HardwareProbe/
│ ├── HWTier.h # 档位枚举定义
│ ├── HardwareInfo.h # 硬件信息结构体
│ ├── HardwareProbe.h # 探针主类
│ ├── CapabilityPolicy.h # 策略引擎
│ └── DeviceConfig.h # 配置文件读取
│
└── src/hardware/
├── HardwareProbe.cpp
├── CapabilityPolicy.cpp
├── DeviceConfig.cpp
├── detectors/ # 各检测器实现
│ ├── CPUDetector.cpp
│ ├── GPUDetector.cpp
│ ├── MemoryDetector.cpp
│ └── NetworkDetector.cpp
└── platform/ # 平台特定实现
├── LinuxDetector.cpp
└── WindowsDetector.cpp
三、数据结构定义¶
3.1 HWTier 枚举¶
文件: include/CFDesktop/Base/HardwareProbe/HWTier.h
#pragma once
#include <QtGlobal>
namespace CFDesktop::Base {
/**
* @brief 硬件能力档位枚举
*
* 定义三个标准档位,每个档位对应不同的硬件配置和性能等级。
* 后续所有模块根据此枚举决定行为策略。
*/
enum class HWTier {
/**
* @brief 低端档位
*
* 典型硬件:IMX6ULL (528MHz Cortex-A7, 无GPU/软GPU)
* - 禁用所有动画
* - 使用 linuxfb 渲染后端
* - 软件视频解码
* - 限制内存使用 < 64MB
*/
Low,
/**
* @brief 中端档位
*
* 典型硬件:RK3568 (4xCortex-A55, Mali-G52)
* - 部分动画(淡入淡出、位移)
* - eglfs 可选
* - 硬件视频解码(H.264/H.265 部分)
* - 内存使用 < 256MB
*/
Mid,
/**
* @brief 高端档位
*
* 典型硬件:RK3588 (8xCortex-A76/A55, Mali-G610)
* - 全动画支持(包括缩放、旋转、复杂效果)
* - 强制 eglfs + OpenGL ES 3.2+
* - 全格式硬件视频解码
* - 内存使用 < 1GB
*/
High
};
/**
* @brief 获取档位字符串描述
*/
QString tierToString(HWTier tier);
/**
* @brief 从字符串解析档位
*/
HWTier tierFromString(const QString& str);
} // namespace CFDesktop::Base
3.2 HardwareInfo 结构体¶
文件: include/CFDesktop/Base/HardwareProbe/HardwareInfo.h
#pragma once
#include <QString>
#include <QList>
#include <QPair>
#include "HWTier.h"
namespace CFDesktop::Base {
/**
* @brief CPU 信息
*/
struct CPUInfo {
QString model; // CPU 型号名称
int cores = 0; // 逻辑核心数
int frequencyMHz = 0; // 主频 (MHz)
QString architecture; // 架构 (armv7l, aarch64, x86_64)
QStringList features; // CPU 特性 (neon, vfpv4, etc.)
};
/**
* @brief GPU 信息
*/
struct GPUInfo {
QString renderer; // 渲染器名称
QString vendor; // 供应商
QString version; // 驱动版本
bool hasHardwareAcceleration = false; // 是否有硬件加速
QString driverPath; // 驱动设备路径 (/dev/dri/card0)
int maxTextureSize = 0; // 最大纹理尺寸
QStringList extensions; // OpenGL 扩展列表
};
/**
* @brief 内存信息
*/
struct MemoryInfo {
quint64 totalBytes = 0; // 总内存 (字节)
quint64 availableBytes = 0; // 可用内存 (字节)
quint64 totalSwap = 0; // 总交换空间
quint64 freeSwap = 0; // 可用交换空间
QString lowMemoryBehavior; // 低内存行为 (oom, compress, etc.)
};
/**
* @brief 网络接口信息
*/
struct NetworkInterface {
QString name; // 接口名称 (eth0, wlan0)
bool isUp = false; // 是否启用
bool isWireless = false; // 是否无线
QString macAddress; // MAC 地址
QStringList ipAddresses; // IP 地址列表
};
/**
* @brief 完整硬件信息
*/
struct HardwareInfo {
HWTier tier = HWTier::Low; // 计算得出的档位
CPUInfo cpu; // CPU 信息
GPUInfo gpu; // GPU 信息
MemoryInfo memory; // 内存信息
QList<NetworkInterface> networkInterfaces; // 网络接口
QString deviceTreeCompatible; // 设备树 compatible 字符串
QString boardName; // 板载名称
bool isUserOverridden = false; // 是否用户手动覆盖
};
} // namespace CFDesktop::Base
3.3 CapabilityPolicy 配置结构¶
文件: include/CFDesktop/Base/HardwareProbe/CapabilityPolicy.h
#pragma once
#include "HWTier.h"
#include <QString>
namespace CFDesktop::Base {
/**
* @brief 动画策略
*/
struct AnimationPolicy {
bool enabled = false; // 是否启用动画
int defaultDurationMs = 0; // 默认动画时长 (毫秒)
int maxConcurrentAnimations = 0; // 最大并发动画数
bool allowComplexEffects = false; // 是否允许复杂效果 (模糊、阴影等)
};
/**
* @brief 渲染后端策略
*/
struct RenderingPolicy {
QString qtPlatform; // Qt 平台插件 (linuxfb, eglfs, xcb)
bool useOpenGL = false; // 是否使用 OpenGL
QString openGLVersion; // OpenGL 版本要求
bool useVSync = false; // 是否垂直同步
int maxFPS = 60; // 最大帧率
};
/**
* @brief 视频解码策略
*/
struct VideoDecoderPolicy {
bool useHardwareDecoder = false; // 是否使用硬件解码
QStringList supportedCodecs; // 支持的编解码器
int maxResolution = 0; // 最大分辨率 (宽)
int maxBitrate = 0; // 最大码率 (bps)
bool allowSimultaneousPlayback = false; // 是否允许同时播放多个
};
/**
* @brief 内存策略
*/
struct MemoryPolicy {
int maxImageCacheBytes = 0; // 图片缓存大小
int maxFontCacheBytes = 0; // 字体缓存大小
bool enableTextureCompression = false; // 是否启用纹理压缩
int maxWindowSurfaces = 0; // 最大窗口表面数
};
} // namespace CFDesktop::Base
四、类接口设计¶
4.1 HardwareProbe 主类¶
文件: include/CFDesktop/Base/HardwareProbe/HardwareProbe.h
#pragma once
#include "HardwareInfo.h"
#include <QObject>
#include <QSharedPointer>
#include <QStringList>
namespace CFDesktop::Base {
/**
* @brief 硬件探针主类
*
* 负责检测系统硬件能力,输出 HardwareInfo 结构。
* 单例模式,进程内唯一实例。
*/
class HardwareProbe : public QObject {
Q_OBJECT
public:
/**
* @brief 获取单例实例
*/
static HardwareProbe* instance();
/**
* @brief 执行硬件检测
* @return 检测结果
*
* 首次调用会执行完整检测,后续调用返回缓存结果。
* 可通过 forceRedetect() 强制重新检测。
*/
HardwareInfo probe();
/**
* @brief 强制重新检测
*/
HardwareInfo forceRedetect();
/**
* @brief 获取当前硬件档位
*/
HWTier currentTier() const;
/**
* @brief 获取完整硬件信息
*/
const HardwareInfo& hardwareInfo() const;
/**
* @brief 设置 Mock 数据(仅用于测试)
*/
void setMockData(const HardwareInfo& mockInfo);
/**
* @brief 检查特定功能是否可用
*/
bool hasFeature(const QString& feature) const;
signals:
/**
* @brief 硬件检测完成信号
*/
void probeCompleted(const HardwareInfo& info);
/**
* @brief 档位变化信号(热插拔设备等情况)
*/
void tierChanged(HWTier newTier);
private:
HardwareProbe(QObject* parent = nullptr);
~HardwareProbe() = default;
// 禁用拷贝和移动
HardwareProbe(const HardwareProbe&) = delete;
HardwareProbe& operator=(const HardwareProbe&) = delete;
// 内部检测方法
void detectCPU(HardwareInfo& info);
void detectGPU(HardwareInfo& info);
void detectMemory(HardwareInfo& info);
void detectNetwork(HardwareInfo& info);
void calculateTier(HardwareInfo& info);
// 平台特定实现
void probeLinux(HardwareInfo& info);
void probeWindows(HardwareInfo& info);
private:
static HardwareProbe* s_instance;
HardwareInfo m_cachedInfo;
bool m_isProbed = false;
bool m_useMockData = false;
HardwareInfo m_mockInfo;
};
} // namespace CFDesktop::Base
4.2 CapabilityPolicy 策略引擎¶
文件: include/CFDesktop/Base/HardwareProbe/CapabilityPolicy.h
#pragma once
#include "HWTier.h"
#include <QObject>
namespace CFDesktop::Base {
// 前向声明
struct AnimationPolicy;
struct RenderingPolicy;
struct VideoDecoderPolicy;
struct MemoryPolicy;
/**
* @brief 能力策略引擎
*
* 根据 HWTier 提供各模块的能力配置。
* 单例模式,根据当前硬件档位返回对应策略。
*/
class CapabilityPolicy : public QObject {
Q_OBJECT
public:
static CapabilityPolicy* instance();
/**
* @brief 获取动画策略
*/
AnimationPolicy getAnimationPolicy() const;
/**
* @brief 获取渲染策略
*/
RenderingPolicy getRenderingPolicy() const;
/**
* @brief 获取视频解码策略
*/
VideoDecoderPolicy getVideoDecoderPolicy() const;
/**
* @brief 获取内存策略
*/
MemoryPolicy getMemoryPolicy() const;
/**
* @brief 获取当前档位
*/
HWTier currentTier() const;
/**
* @brief 强制设置档位(用于测试或用户覆盖)
*/
void overrideTier(HWTier tier);
signals:
void policyChanged(HWTier newTier);
private:
CapabilityPolicy(QObject* parent = nullptr);
~CapabilityPolicy() = default;
// 档位特定策略配置
AnimationPolicy getAnimationPolicyForLow() const;
AnimationPolicy getAnimationPolicyForMid() const;
AnimationPolicy getAnimationPolicyForHigh() const;
RenderingPolicy getRenderingPolicyForLow() const;
RenderingPolicy getRenderingPolicyForMid() const;
RenderingPolicy getRenderingPolicyForHigh() const;
VideoDecoderPolicy getVideoPolicyForLow() const;
VideoDecoderPolicy getVideoPolicyForMid() const;
VideoDecoderPolicy getVideoPolicyForHigh() const;
MemoryPolicy getMemoryPolicyForLow() const;
MemoryPolicy getMemoryPolicyForMid() const;
MemoryPolicy getMemoryPolicyForHigh() const;
private:
static CapabilityPolicy* s_instance;
HWTier m_currentTier = HWTier::Low;
bool m_isOverridden = false;
};
} // namespace CFDesktop::Base
4.3 DeviceConfig 配置文件¶
文件: include/CFDesktop/Base/HardwareProbe/DeviceConfig.h
#pragma once
#include "HWTier.h"
#include <QString>
#include <QVariantMap>
namespace CFDesktop::Base {
/**
* @brief 设备配置文件读取器
*
* 读取 /etc/CFDesktop/device.conf,允许用户手动覆盖硬件检测。
*
* 配置文件格式:
* [Device]
* Tier=auto|low|mid|high
* CustomScript=/path/to/detection/script
*
* [Overrides]
* EnableAnimations=true|false
* ForceOpenGL=true|false
*/
class DeviceConfig {
public:
struct Config {
bool tierAutoDetect = true;
HWTier forcedTier = HWTier::Low;
QString customScriptPath;
QVariantMap overrides;
};
/**
* @brief 加载配置文件
*/
static Config load(const QString& path = "/etc/CFDesktop/device.conf");
/**
* @brief 保存配置文件
*/
static bool save(const Config& config,
const QString& path = "/etc/CFDesktop/device.conf");
/**
* @brief 执行自定义检测脚本
*
* 脚本输出格式: JSON
* {
* "tier": "low|mid|high",
* "properties": {...}
* }
*/
static QVariantMap executeCustomScript(const QString& scriptPath);
};
} // namespace CFDesktop::Base
五、检测逻辑详细设计¶
5.1 CPU 检测¶
5.1.1 Linux 平台¶
检测文件: src/hardware/detectors/CPUDetector.cpp
CPUInfo CPUDetector::detectCPU() {
CPUInfo info;
// 1. 读取 /proc/cpuinfo
QFile cpuInfo("/proc/cpuinfo");
if (cpuInfo.open(QIODevice::ReadOnly)) {
QTextStream in(&cpuInfo);
QSet<QString> uniqueProcessors;
while (!in.atEnd()) {
QString line = in.readLine();
if (line.startsWith("Hardware")) {
info.model = line.section(':', 1).trimmed();
} else if (line.startsWith("Processor")) {
uniqueProcessors.insert(line);
} else if (line.startsWith("CPU implementer")) {
info.architecture = detectArchitecture(line);
} else if (line.startsWith("Features")) {
info.features = line.section(':', 1).trimmed().split(' ');
} else if (line.startsWith("BogoMIPS")) {
info.frequencyMHz = static_cast<int>(
line.section(':', 1).trimmed().toDouble() * 2);
}
}
info.cores = uniqueProcessors.size();
}
// 2. 通过 uname 确认架构
QProcess uname;
uname.start("uname", QStringList() << "-m");
if (uname.waitForStarted() && uname.waitForFinished()) {
info.architecture = uname.readAllStandardOutput().trimmed();
}
// 3. 读取设备树 (如果存在)
QFile compatible("/sys/firmware/devicetree/base/compatible");
if (compatible.open(QIODevice::ReadOnly)) {
QByteArray data = compatible.readAll();
// 设备树字符串以 null 结尾,可能有多项
QList<QByteArray> compatList = data.split('\0');
if (!compatList.isEmpty() && !compatList.first().isEmpty()) {
info.model = compatList.first();
}
}
return info;
}
QString CPUDetector::detectArchitecture(const QString& cpuInfoLine) {
// CPU implementer 值映射
QHash<QString, QString> implementerMap = {
{"0x41", "ARM"},
{"0x42", "Broadcom"},
{"0x43", "Cavium"},
{"0x44", "DEC"},
{"0x49", "Infineon"},
{"0x4d", "Motorola/Freescale"},
{"0x4e", "NVIDIA"},
{"0x50", "APM"},
{"0x51", "Qualcomm"},
{"0x56", "Marvell"},
{"0x69", "Intel"},
};
QString implementer = /* 从 cpuinfo 提取 */;
return implementerMap.value(implementer, "Unknown");
}
5.1.2 Windows 平台¶
CPUInfo CPUDetector::detectCPUWindows() {
CPUInfo info;
// 使用 WMI 查询
QProcess wmic;
wmic.start("wmic", QStringList()
<< "cpu" << "get" << "Name,NumberOfCores,MaxClockSpeed");
// 解析输出...
return info;
}
5.2 GPU 检测¶
GPUInfo GPUDetector::detectGPU() {
GPUInfo info;
// 1. 检查 DRM 设备
QDir dri("/dev/dri");
if (dri.exists()) {
QStringList devices = dri.entryList(QStringList() << "card*", QDir::Files);
if (!devices.isEmpty()) {
info.hasHardwareAcceleration = true;
info.driverPath = "/dev/dri/" + devices.first();
}
}
// 2. 尝试创建 OpenGL 上下文
QOffscreenSurface surface;
QOpenGLContext context;
if (context.create()) {
context.makeCurrent(&surface);
auto* functions = context.functions();
info.vendor = reinterpret_cast<const char*>(
functions->glGetString(GL_VENDOR));
info.renderer = reinterpret_cast<const char*>(
functions->glGetString(GL_RENDERER));
info.version = reinterpret_cast<const char*>(
functions->glGetString(GL_VERSION));
// 获取扩展列表
auto* extraFunctions = context.extraFunctions();
GLint numExtensions = 0;
functions->glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions);
for (int i = 0; i < numExtensions; ++i) {
const char* ext = reinterpret_cast<const char*>(
functions->glGetStringi(GL_EXTENSIONS, i));
info.extensions.append(ext);
}
context.doneCurrent();
}
// 3. 检查特定 SoC 的 GPU 型号
detectSoCGPU(info);
return info;
}
5.3 内存检测¶
MemoryInfo MemoryDetector::detectMemory() {
MemoryInfo info;
// Linux: 读取 /proc/meminfo
QFile memInfo("/proc/meminfo");
if (memInfo.open(QIODevice::ReadOnly)) {
QTextStream in(&memInfo);
QHash<QString, quint64> memData;
while (!in.atEnd()) {
QString line = in.readLine();
QString key = line.section(':', 0, 0);
QString value = line.section(':', 1).section(' ', 0, 0);
memData[key] = value.toULongLong() * 1024; // kB to bytes
}
info.totalBytes = memData["MemTotal"];
info.availableBytes = memData["MemAvailable"];
info.totalSwap = memData["SwapTotal"];
info.freeSwap = memData["SwapFree"];
}
return info;
}
5.4 网络检测¶
QList<NetworkInterface> NetworkDetector::detectNetwork() {
QList<NetworkInterface> interfaces;
// 读取 /sys/class/net
QDir netDir("/sys/class/net");
QStringList devices = netDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
for (const QString& device : devices) {
NetworkInterface iface;
iface.name = device;
// 检查是否启用
QFile operstate(QString("/sys/class/net/%1/operstate").arg(device));
if (operstate.open(QIODevice::ReadOnly)) {
iface.isUp = operstate.readAll().trimmed() == "up";
}
// 检查是否无线
QDir wireless("/sys/class/net/" + device + "/wireless");
iface.isWireless = wireless.exists();
// 读取 MAC 地址
QFile address(QString("/sys/class/net/%1/address").arg(device));
if (address.open(QIODevice::ReadOnly)) {
iface.macAddress = address.readAll().trimmed();
}
// 通过 Socket ioctl 获取 IP 地址
iface.ipAddresses = getIPAddresses(device);
interfaces.append(iface);
}
return interfaces;
}
5.5 档位计算逻辑¶
void HardwareProbe::calculateTier(HardwareInfo& info) {
// 默认为 Low 档
HWTier calculatedTier = HWTier::Low;
int score = 0;
// CPU 评分
score += std::min(info.cpu.cores, 8) * 10; // 最多 80 分
if (info.cpu.frequencyMHz > 1000) score += 20;
if (info.cpu.features.contains("neon")) score += 10;
// GPU 评分
if (info.gpu.hasHardwareAcceleration) score += 50;
if (!info.gpu.driverPath.isEmpty()) score += 20;
// 内存评分
int memoryMB = info.memory.totalBytes / (1024 * 1024);
if (memoryMB >= 512) score += 20;
if (memoryMB >= 1024) score += 20;
if (memoryMB >= 2048) score += 10;
// 根据评分决定档位
// Low: 0-60, Mid: 61-120, High: 121+
if (score >= 121) {
calculatedTier = HWTier::High;
} else if (score >= 61) {
calculatedTier = HWTier::Mid;
} else {
calculatedTier = HWTier::Low;
}
info.tier = calculatedTier;
}
六、设备配置文件格式¶
6.1 配置文件模板¶
文件: configs/device.conf.template
# CFDesktop 设备配置文件
# 部署位置: /etc/CFDesktop/device.conf
[Device]
# 档位设置: auto(自动检测) | low | mid | high
Tier=auto
# 自定义检测脚本路径(可选)
# 脚本应输出 JSON 格式到 stdout
CustomScript=/opt/cfdesktop/detect-hardware.sh
# 板载名称(可选,用于日志)
BoardName=Generic-Board
[Overrides]
# 强制覆盖特定能力(可选)
# 动画设置
EnableAnimations=true
AnimationDuration=200
# 渲染后端: auto | linuxfb | eglfs | xcb
RenderingBackend=auto
# OpenGL 设置
ForceOpenGL=false
# 视频解码: auto | software | hardware
VideoDecoder=auto
[Logging]
# 硬件检测日志级别
LogLevel=Info
6.2 自定义检测脚本示例¶
#!/bin/bash
# /opt/cfdesktop/detect-hardware.sh
# 检测是否连接了特定扩展硬件
if [ -e /sys/bus/i2c/devices/0-0050 ]; then
# 检测到扩展显示屏,提升档位
echo '{"tier": "mid", "properties": {"externalDisplay": true}}'
else
echo '{"tier": "low"}'
fi
七、单元测试设计¶
7.1 Mock 数据目录结构¶
tests/mock/
└── proc/
├── cpuinfo_imx6ull # IMX6ULL CPU 信息
├── cpuinfo_rk3568 # RK3568 CPU 信息
├── cpuinfo_rk3588 # RK3588 CPU 信息
├── meminfo_512mb # 512MB 内存
├── meminfo_1gb # 1GB 内存
├── meminfo_4gb # 4GB 内存
└── devices/ # 模拟设备文件
└── dri/
└── card0 # 模拟 GPU 设备
7.2 测试用例清单¶
文件: tests/unit/base/hardware/test_hardware_probe.cpp
class TestHardwareProbe : public QObject {
Q_OBJECT
private slots:
// ========== CPU 检测测试 ==========
void testDetectCPU_IMX6ULL();
void testDetectCPU_RK3568();
void testDetectCPU_RK3588();
void testDetectCPU_X86_64();
// ========== GPU 检测测试 ==========
void testDetectGPU_WithDRM();
void testDetectGPU_NoDRM();
void testDetectGPU_OpenGLContext();
// ========== 内存检测测试 ==========
void testDetectMemory_512MB();
void testDetectMemory_1GB();
void testDetectMemory_4GB();
// ========== 档位计算测试 ==========
void testCalculateTier_IMX6ULL_returnsLow();
void testCalculateTier_RK3568_returnsMid();
void testCalculateTier_RK3588_returnsHigh();
// ========== 配置文件测试 ==========
void testDeviceConfig_LoadDefault();
void testDeviceConfig_OverrideTier();
void testDeviceConfig_CustomScript();
// ========== 策略引擎测试 ==========
void testCapabilityPolicy_LowTier();
void testCapabilityPolicy_MidTier();
void testCapabilityPolicy_HighTier();
void testCapabilityPolicy_AnimationDisabledOnLow();
// ========== 边界情况 ==========
void testEmptyProcFiles();
void testMalformedConfig();
void testTierOverride();
};
7.3 示例测试用例¶
void TestHardwareProbe::testDetectCPU_IMX6ULL() {
// 1. 设置 Mock 环境变量
qputenv("CFDESKTOP_MOCK_PROC", "/path/to/mock/proc/cpuinfo_imx6ull");
// 2. 创建探针实例
HardwareProbe probe;
HardwareInfo info = probe.probe();
// 3. 验证结果
QCOMPARE(info.cpu.model, "Freescale i.MX6 UltraLite");
QCOMPARE(info.cpu.cores, 1);
QVERIFY(info.cpu.features.contains("neon"));
QCOMPARE(info.cpu.architecture, "armv7l");
// 4. 验证档位
QCOMPARE(info.tier, HWTier::Low);
}
八、详细任务清单¶
8.1 Week 1: 基础检测器实现¶
Day 1-2: CPU 检测器¶
- [ ] 创建
CPUDetector类框架 - [ ] 实现
/proc/cpuinfo解析 - [ ] 实现设备树 compatible 读取
- [ ] 实现
uname架构检测 - [ ] 编写 CPU 检测单元测试
Day 3: GPU 检测器¶
- [ ] 创建
GPUDetector类框架 - [ ] 实现 DRM 设备检测
- [ ] 实现 OpenGL 上下文创建
- [ ] 实现 GPU 能力查询
- [ ] 编写 GPU 检测单元测试
Day 4: 内存与网络检测器¶
- [ ] 实现
/proc/meminfo解析 - [ ] 实现网络接口枚举
- [ ] 实现 IP 地址获取
- [ ] 编写相应单元测试
Day 5: 档位计算逻辑¶
- [ ] 实现评分算法
- [ ] 定义档位阈值
- [ ] 实现
calculateTier()方法 - [ ] 验证各板卡档位判定
8.2 Week 2: 策略引擎与配置¶
Day 1-2: CapabilityPolicy 实现¶
- [ ] 定义各策略结构体
- [ ] 实现档位特定策略配置
- [ ] 实现
getAnimationPolicy() - [ ] 实现
getRenderingPolicy() - [ ] 实现
getVideoDecoderPolicy() - [ ] 实现
getMemoryPolicy()
Day 3: DeviceConfig 实现¶
- [ ] 实现配置文件解析
- [ ] 实现配置文件写入
- [ ] 实现自定义脚本执行
- [ ] 编写配置测试
Day 4: 集成测试¶
- [ ] 创建端到端测试用例
- [ ] 测试 IMX6ULL 真机
- [ ] 测试 RK3568 真机
- [ ] 验证自动档位判定
Day 5: 文档与优化¶
- [ ] 编写 API 文档
- [ ] 优化检测性能
- [ ] 添加性能日志
- [ ] Code Review
8.3 Week 3: 完善与验证¶
Day 1-2: 跨平台支持¶
- [ ] 实现 Windows 平台检测
- [ ] 实现模拟器平台适配
- [ ] 编写平台特定测试
Day 3-4: 真机验证¶
- [ ] 在 IMX6ULL 上完整测试
- [ ] 在 RK3568 上完整测试
- [ ] 在 RK3588 上完整测试
- [ ] 收集性能数据
Day 5: 发布准备¶
- [ ] 最终测试
- [ ] 更新文档
- [ ] 准备演示
- [ ] 合并主分支
九、验收标准¶
9.1 功能验收¶
- [ ] 在 IMX6ULL 上正确识别为 Low 档
- [ ] 在 RK3568 上正确识别为 Mid 档
- [ ] 在 RK3588 上正确识别为 High 档
- [ ] 所有单元测试通过(覆盖率 > 90%)
- [ ] 配置文件覆盖功能正常
- [ ] 自定义脚本执行正常
9.2 性能验收¶
- [ ] 硬件检测耗时 < 500ms
- [ ] 内存占用 < 5MB
- [ ] 不影响系统启动时间
9.3 代码质量¶
- [ ] 符合代码规范
- [ ] 通过 clang-tidy 检查
- [ ] API 文档完整
- [ ] 代码审查通过
十、已知问题与风险¶
| 问题 | 风险 | 缓解措施 |
|---|---|---|
| 某些板卡没有设备树 | 档位误判 | 提供 CPU 特性回退检测 |
| GPU 驱动不稳定 | 检测失败 | 添加异常处理,设置超时 |
| 交叉编译测试困难 | 覆盖不足 | 使用 QEMU 用户模式模拟 |
十一、下一步行动¶
完成 Phase 1 后,进入 Phase 2: Base 库核心。