第五章 插件:OpenHarmony设备插件实现分析
目录
-
插件结构概述 -
插件接口实现分析 -
设备通信机制 -
镜像服务器部署 -
截图功能实现 -
实现特点与优化建议 -
总结
1. 插件结构概述
OpenHarmony设备插件由两个主要类组成:
-
OHOSDevicePlugin: 实现了IDevicePlugin接口,负责插件的注册、信息提供和设备代理创建。 -
OHOSDevice: 实现了DeviceProxy接口,负责与OpenHarmony设备通信、镜像服务器管理和事件处理。
这两个类共同构成了完整的OpenHarmony设备支持功能,通过HDC(HarmonyOS Device Connector)工具与设备进行交互。
2. 插件接口实现分析
2.1 OHOSDevicePlugin类
核心功能
OHOSDevicePlugin类是插件的入口点,继承自QObject和IDevicePlugin接口,主要负责:
-
提供插件基本信息(名称、版本) -
创建OHOSDevice设备代理实例 -
检查HDC驱动可用性 -
管理HDC工具路径
关键代码实现
classOHOSDevicePlugin :public QObject, public IDevicePlugin
{
Q_OBJECT
Q_INTERFACES(IDevicePlugin)
Q_PLUGIN_METADATA(IID "com.screencast.deviceplugin.ohos" FILE "ohosdeviceplugin.json")
public:
OHOSDevicePlugin(QObject* parent = nullptr);
~OHOSDevicePlugin() override;
// 插件基本信息
QString pluginName()constoverride;
QString pluginVersion()constoverride;
DeviceType deviceType()constoverride;
// 设备代理创建
DeviceProxy* createDeviceProxy(QObject* parent)constoverride;
// HDC驱动管理
boolcheckDriverAvailable()constoverride;
QString getDriverPath()constoverride;
};
主要方法实现
-
pluginName(): 返回插件名称”OpenHarmony” -
pluginVersion(): 返回插件版本”1.0.0″ -
deviceType(): 返回设备类型DeviceType::OHOS -
createDeviceProxy(): 创建并返回OHOSDevice实例 -
checkDriverAvailable(): 通过执行”hdc list targets”命令检查HDC驱动是否可用 -
getDriverPath(): 在多个路径下查找HDC工具,包括环境变量、应用目录和系统标准路径
2.2 OHOSDevice类
核心功能
OHOSDevice类是实际与OpenHarmony设备交互的组件,继承自DeviceProxy,主要负责:
-
设备列表获取与信息查询 -
镜像服务器部署与管理 -
设备事件发送(触摸、滑动、按键等) -
屏幕截图功能
关键代码实现
classOHOSDevice :public DeviceProxy
{
Q_OBJECT
public:
OHOSDevice(QObject* parent = nullptr);
~OHOSDevice() override;
// 设备管理
QVector<DeviceInfo> listDevices()override;
boolqueryDeviceInfo(const QString& serial, DeviceInfo& info)override;
DeviceType deviceType()constoverride;
// 设备信息查询
QString deviceModel(const QString& serial)override;
QString deviceName(const QString& serial)override;
QSize deviceResolution(const QString& serial)override;
intdeviceRotation(const QString& serial)override;
// 镜像服务器管理
boolsetupMirrorServer(const QString& serial, int forwardPort)override;
boolstartMirrorServer(const QString& serial)override;
boolstopMirrorServer(const QString& serial)override;
QString getMirrorServerIp(const QString& serial)override;
// 事件发送
boolsendEvent(const DeviceInfo& dev, DeviceEvent event)override;
boolsendTouchEvent(const DeviceInfo& dev, QPoint pos)override;
boolsendTextEvent(const DeviceInfo& dev, const QString& text)override;
boolsendSwipeEvent(const DeviceInfo& dev, QPoint start, QPoint end, int duration)override;
// 其他功能
boolscreenshot(const QString& serial, QByteArray& imageData)override;
boolsupportEvent(DeviceEvent event)constoverride;
private:
boolpushResourceToDevice(const QString& serial, const QString& resourcePath, const QString& devicePath);
boolisScreenOn(const QString& serial);
private:
bool m_running{false};
QMutex m_mutex;
};
3. 设备通信机制
OpenHarmony插件通过HDC(HarmonyOS Device Connector)工具与设备进行通信,实现了以下核心功能:
3.1 设备列表获取
使用hdc list targets命令获取已连接的OpenHarmony设备列表:
QVector<DeviceInfo> OHOSDevice::listDevices()
{
QMutexLocker locker(&m_mutex);
QVector<DeviceInfo> devices;
QString output;
if (!Shell::executeQuiet("hdc list targets", &output))
{
return devices;
}
QStringList lines = output.split('\n', Qt::SkipEmptyParts);
for (const QString& line : lines)
{
QString serial = line.trimmed();
if (!serial.isEmpty() && serial != "[Empty]")
{
DeviceInfo info;
info.type = DeviceType::OHOS;
info.serial = serial;
devices.append(info);
}
}
return devices;
}
3.2 设备信息查询
通过HDC命令获取设备的各种信息:
-
设备型号: hdc -t <serial> shell param get const.product.model -
设备名称: hdc -t <serial> shell param get const.product.name -
设备分辨率: hdc -t <serial> shell hidumper -s RenderService -a screen -
设备旋转角度: hdc -t <serial> shell hidumper -s RenderService -a screen
3.3 事件发送
实现了丰富的设备事件发送功能,包括:
-
标准按键事件: 主页、返回、菜单、唤醒、休眠等 -
触摸事件: 单点触控 -
滑动事件: 多点滑动 -
文本输入事件: 文本发送
事件处理采用映射表设计,使代码结构清晰:
// 定义事件与命令的映射
staticconststd::map<DeviceEvent, QString> eventMap = {
{DeviceEvent::HOME, "uinput -K -d 1 -u 1"},
{DeviceEvent::BACK, "uinput -K -d 2 -u 2"},
{DeviceEvent::MENU, "uinput -K -d 2078 -u 2078"},
{DeviceEvent::WAKEUP, "power-shell wakeup"},
// ... 其他事件映射
};
4. 镜像服务器部署
OpenHarmony插件实现了完整的镜像服务器部署和管理流程:
4.1 资源推送
将镜像服务器程序推送到设备:
boolOHOSDevice::pushResourceToDevice(const QString& serial, const QString& resourcePath, const QString& devicePath)
{
// 读取资源文件
QFile file(resourcePath);
if (!file.open(QIODevice::ReadOnly))
{
returnfalse;
}
// 创建临时文件
QTemporaryFile tempFile;
if (!tempFile.open())
{
returnfalse;
}
tempFile.write(file.readAll());
tempFile.close();
// 推送文件到设备
QString command = QString("hdc -t %1 file send %2 %3").arg(serial, QDir::toNativeSeparators(tempFile.fileName()), devicePath);
// ...
// 设置执行权限
command = QString("hdc -t %1 shell chmod 755 %2").arg(serial, devicePath);
// ...
returntrue;
}
4.2 端口转发
设置本地端口与设备端口之间的转发:
QString forwardCommand = QString("hdc -t %1 fport tcp:%2 tcp:12345").arg(serial).arg(forwardPort);
4.3 异步启动与监控
使用QtConcurrent实现镜像服务器的异步启动和状态监控:
// 启动服务器进程
[[maybe_unused]] auto future1 = QtConcurrent::run([=]() {
QStringList args = {"-t", serial, "shell", "/data/local/tmp/mirror_server"};
QProcess process;
process.start("hdc", args);
while (m_running && !process.waitForFinished(1000))
{
// Keep running
}
process.kill();
});
// 检查服务器状态
[[maybe_unused]] auto future2 = QtConcurrent::run([=]() {
QString command = QString("hdc -t %1 shell netstat -ltn | grep ':12345'").arg(serial);
for (int i = 0; i < 30 && m_running; ++i)
{
QString output;
if (Shell::executeQuiet(command, &output) && output.contains(":12345"))
{
emit serverStarted(serial);
return;
}
QThread::sleep(1);
}
});
5. 截图功能实现
截图功能实现了从设备获取屏幕截图并传输到本地:
-
在设备上截取屏幕并保存为临时文件 -
将临时文件拉取到本地 -
读取图像数据并清理临时文件
boolOHOSDevice::screenshot(const QString& serial, QByteArray& imageData)
{
QMutexLocker locker(&m_mutex);
const QString timestamp = QDateTime::currentDateTime().toString("yyyyMMddhhmmss");
const QString tempPath = QString("/data/local/tmp/screenshot_%1.jpeg").arg(timestamp);
const QString localPath = QDir::toNativeSeparators(QDir::tempPath() + QDir::separator() + QString("screenshot_%1.jpeg").arg(timestamp));
// 截取屏幕截图
QString command = QString("hdc -t %1 shell snapshot_display -f %2").arg(serial, tempPath);
if (!Shell::execute(command))
{
returnfalse;
}
// 拉取截图到本地
command = QString("hdc -t %1 file recv %2 %3").arg(serial, tempPath, localPath);
if (!Shell::execute(command))
{
returnfalse;
}
// 读取图像数据并清理
QFile tempFile(localPath);
if (tempFile.open(QIODevice::ReadOnly))
{
imageData = tempFile.readAll();
tempFile.close();
QFile::remove(localPath);
returntrue;
}
returnfalse;
}
6. 实现特点与优化建议
6.1 实现特点
-
多平台支持: 通过HDC工具实现跨平台支持 -
异步处理: 使用QtConcurrent实现异步任务处理 -
线程安全: 使用QMutex确保多线程安全操作 -
错误处理: 完善的错误日志记录和异常处理 -
可扩展性: 模块化设计便于功能扩展
6.2 优化建议
-
错误处理增强: 增加更详细的错误信息和恢复机制 -
缓存机制: 对设备信息查询结果进行缓存,减少重复查询 -
内存优化: 优化大文件传输和处理逻辑 -
超时控制: 为HDC命令添加超时控制机制 -
并行处理: 对设备列表扫描和信息查询进行并行优化
7. 总结
OpenHarmony设备插件通过HDC工具实现了与OpenHarmony设备的全面交互,包括设备发现、信息查询、事件发送、镜像服务和截图等功能。插件采用了模块化设计和异步处理机制,确保了良好的性能和用户体验。
与Android插件类似,OpenHarmony插件也遵循了相同的接口规范,但针对OpenHarmony平台的特点进行了专门优化,使用了适合OpenHarmony系统的HDC工具和命令集。
通过这些实现,ScreenCast项目成功支持了OpenHarmony设备的屏幕投影和远程控制功能,为用户提供了统一的多平台投影解决方案。
夜雨聆风
