【OpenHarmony】MSDP设备状态感知模块架构
MSDP设备状态感知模块架构
1. 模块概述
MSDP设备状态感知框架能够识别出目前设备的状态并传递给订阅者,整个框架是基于MSDP算法库和系统SensorHDI组件组成的,将其接收到的感知事件传递给订阅者。
源码:https://gitee.com/openharmony/msdp_device_status
1.1 功能与目标
主要功能:
- 绝对静止感知:利用加速度、陀螺仪等传感器信息识别设备处于绝对静止状态
- 水平/垂直姿态感知:基于传感器数据识别设备的水平或垂直姿态
- 皮套开合事件感知:基于霍尔传感器识别皮套的开合状态
- 拖拽交互管理:提供跨设备拖拽和协作功能
- 运动状态感知:支持多种运动场景的状态识别
- 屏幕协作:支持多设备间的屏幕协作和鼠标指针跨屏移动
目标:
- 为OpenHarmony系统提供智能设备状态感知能力
- 支持多模态交互和跨设备协作
- 提供高精度的传感器数据处理和状态识别
- 实现流畅的用户交互体验
使用场景:
- 智能设备状态监控和自动调节
- 跨设备拖拽和文件传输
- 多设备协作办公
- 运动健康监测
- 智能家居控制
1.2 系统位置
MSDP设备状态感知模块是OpenHarmonyOS系统中的核心感知服务模块,属于MSDP(Multi-Sensor Data Processing)子系统的重要组成部分。
系统位置:
- 位于系统服务层,为上层应用提供设备状态感知能力
- 作为MSDP子系统的核心模块,负责多传感器数据处理
- 与传感器管理、输入管理、窗口管理等系统模块紧密协作
模块关系:
- 依赖传感器管理模块获取传感器数据
- 依赖输入管理模块处理用户交互
- 依赖窗口管理模块实现跨屏协作
- 为上层应用框架提供设备状态感知接口
1.3 设计思路与模式
设计思路:
- 采用分层架构设计,将算法层、服务层、接口层分离
- 基于MSDP算法库实现高精度传感器数据处理
- 支持多种设备状态类型的统一管理和扩展
- 实现异步事件驱动和回调机制
设计模式:
- 单例模式:DeviceStatusClient、StationaryManager等核心管理器采用单例模式
- 观察者模式:设备状态变化通过回调机制通知订阅者
- 策略模式:不同设备状态类型采用不同的算法策略
- 代理模式:通过代理对象封装远程服务调用
- 工厂模式:算法管理器和数据管理器的创建
2. 模块结构
2.1 源文件与头文件
主要头文件:
devicestatus_client.h
- 设备状态客户端接口stationary_manager.h
- 静止状态管理器stationary_data.h
- 设备状态数据结构定义interaction_manager.h
- 交互管理器drag_data.h
- 拖拽数据结构i_devicestatus.h
- 设备状态服务接口devicestatus_service.h
- 设备状态服务实现devicestatus_manager.h
- 设备状态管理器
主要源文件:
devicestatus_service.cpp
- 设备状态服务实现devicestatus_manager.cpp
- 设备状态管理器实现drag_manager.cpp
- 拖拽管理器实现algo_absolute_still.cpp
- 绝对静止算法实现algo_horizontal.cpp
- 水平姿态算法实现algo_vertical.cpp
- 垂直姿态算法实现sensor_data_callback.cpp
- 传感器数据回调处理
2.2 类、结构体、函数与方法
核心类:
DeviceStatusService类
class DeviceStatusService final : public IContext,public StreamServer,public SystemAbility,public DeviceStatusSrvStub {
public:void OnStart() override;void OnStop() override;void Subscribe(Type type, ActivityEvent event, ReportLatencyNs latency,sptr<IRemoteDevStaCallback> callback) override;void Unsubscribe(Type type, ActivityEvent event, sptr<IRemoteDevStaCallback> callback) override;Data GetCache(const Type &type) override;int32_t AllocSocketFd(const std::string &programName, int32_t moduleType,int32_t &socketFd, int32_t &tokenType) override;
private:std::shared_ptr<DeviceStatusManager> devicestatusManager_;DragManager dragMgr_;SocketSessionManager socketSessionMgr_;std::unique_ptr<IDDMAdapter> ddm_;std::unique_ptr<IInputAdapter> input_;
};
DeviceStatusManager类
class DeviceStatusManager {
public:bool Init();bool Enable(Type type);bool Disable(Type type);void Subscribe(Type type, ActivityEvent event, ReportLatencyNs latency, sptr<IRemoteDevStaCallback> callback);void Unsubscribe(Type type, ActivityEvent event, sptr<IRemoteDevStaCallback> callback);Data GetLatestDeviceStatusData(Type type);int32_t NotifyDeviceStatusChange(const Data &devicestatusData);int32_t LoadAlgorithm();int32_t UnloadAlgorithm();
private:std::shared_ptr<DeviceStatusMsdpClientImpl> msdpImpl_;std::map<Type, OnChangedValue> msdpData_;std::map<Type, std::set<const sptr<IRemoteDevStaCallback>, classcomp>> listeners_;
};
StationaryManager类
class StationaryManager {
public:static StationaryManager& GetInstance();int32_t SubscribeCallback(Type type, ActivityEvent event, ReportLatencyNs latency,sptr<IRemoteDevStaCallback> callback);int32_t UnsubscribeCallback(Type type, ActivityEvent event, sptr<IRemoteDevStaCallback> callback);Data GetDeviceStatusData(const Type type);int32_t GetDevicePostureDataSync(DevicePostureData &data);
private:DISALLOW_COPY_AND_MOVE(StationaryManager);
};
InteractionManager类
class InteractionManager {
public:static std::shared_ptr<InteractionManager> GetInstance();int32_t RegisterCoordinationListener(std::shared_ptr<ICoordinationListener> listener);int32_t UnregisterCoordinationListener(std::shared_ptr<ICoordinationListener> listener);int32_t StartDrag(const DragData &dragData, std::shared_ptr<IStartDragListener> listener);int32_t StopDrag(const DragDropResult &dropResult);int32_t UpdateDragStyle(DragCursorStyle style, int32_t eventId = -1);int32_t SetDragWindowVisible(bool visible, bool isForce = false);int32_t GetDragData(DragData &dragData);
private:static std::shared_ptr<InteractionManager> instance_;static std::mutex mutex_;
};
核心结构体:
Data结构体
struct Data {Type type { TYPE_INVALID }; // 设备状态类型OnChangedValue value { VALUE_INVALID }; // 状态值Status status { STATUS_INVALID }; // 状态Action action { ACTION_INVALID }; // 动作double movement { 0.0 }; // 运动量bool operator !=(const Data &r) const;
};
DevicePostureData结构体
struct DevicePostureData {float rollRad = 0.0F; // 横滚角(弧度)float pitchRad = 0.0F; // 俯仰角(弧度)float yawRad = 0.0F; // 偏航角(弧度)
};
DragData结构体
struct DragData {std::string extraInfo; // 额外信息std::string summary; // 数据摘要int32_t dragNum; // 拖拽编号uint64_t displayId; // 显示IDMMI::PointerEvent::SourceType sourceType; // 输入源类型std::map<std::string, int64_t> summarys; // 详细摘要
};
算法基类:
AlgoBase类
class AlgoBase {
public:virtual bool Init(Type type) = 0;virtual bool StartAlgorithm(int32_t sensorTypeId, AccelData* sensorData) = 0;virtual void ExecuteOperation() = 0;void RegisterCallback(const std::shared_ptr<IMsdp::MsdpAlgoCallback> callback);void UpdateStateAndReport(OnChangedValue value, int32_t state, Type type);
protected:bool SetData(int32_t sensorTypeId, AccelData* sensorData);void Unsubscribe(int32_t sensorTypeId);
private:std::shared_ptr<IMsdp::MsdpAlgoCallback> callback_;SensorCallback algoCallback_;AlgoPara algoPara_;int32_t state_ { UNSTILL };int32_t counter_ { COUNTER_THRESHOLD };Data reportInfo_;
};
2.3 继承与多态
继承关系:
DeviceStatusService
继承自SystemAbility
和DeviceStatusSrvStub
AlgoAbsoluteStill
、AlgoHorizontal
、AlgoVertical
继承自AlgoBase
- 各种回调类继承自相应的接口基类
多态设计:
- 通过算法基类实现不同状态识别算法的统一管理
- 回调机制支持多种事件类型的统一处理
- 策略模式实现不同设备状态类型的动态切换
3. 模块间交互
3.1 交互描述
与系统模块的交互:
- 传感器管理:通过Sensor HDI获取加速度、陀螺仪、霍尔传感器数据
- 输入管理:通过InputManager处理鼠标、触摸等输入事件
- 窗口管理:通过WindowManager实现跨屏协作和窗口管理
- 设备管理:通过DeviceManager管理多设备连接
- 权限管理:通过AccessToken验证应用权限
外部库依赖:
- MSDP算法库:核心传感器数据处理算法
- 系统服务:SAMGR、SAFWK等系统框架
- 第三方库:cJSON、OpenSSL、jsoncpp等
异步处理机制:
- 使用epoll机制处理异步事件
- 通过回调机制处理传感器数据
- 支持多线程并发处理多个状态识别任务
3.2 事件驱动机制
事件类型:
- 传感器数据变化事件
- 设备状态变化事件
- 拖拽交互事件
- 跨设备协作事件
- 窗口状态变化事件
事件处理流程:
- 注册事件监听器
- 接收传感器或系统事件
- 算法处理和数据融合
- 状态判断和更新
- 通知相关回调
4. 状态机转换图
4.1 状态机模型
设备状态感知模块的状态机包含以下主要状态:
服务状态:
STATE_NOT_START
- 服务未启动STATE_RUNNING
- 服务运行中STATE_EXIT
- 服务退出
设备状态:
TYPE_ABSOLUTE_STILL
- 绝对静止TYPE_HORIZONTAL_POSITION
- 水平姿态TYPE_VERTICAL_POSITION
- 垂直姿态TYPE_STILL
- 静止状态TYPE_RELATIVE_STILL
- 相对静止TYPE_CAR_BLUETOOTH
- 车载蓝牙TYPE_LID_OPEN
- 皮套开启
拖拽状态:
DragState::STOP
- 停止状态DragState::START
- 开始状态DragState::MOTION_DRAGGING
- 拖拽中DragState::FINISH
- 完成状态
4.2 状态切换规则
服务启动流程:
- 系统启动时,服务处于
STATE_NOT_START
状态 - 收到启动事件后,进入
STATE_RUNNING
状态 - 初始化各个子模块和算法管理器
- 注册到系统能力管理器
设备状态转换:
- 传感器数据输入触发算法处理
- 算法判断设备状态类型
- 状态变化时触发回调通知
- 更新内部状态缓存
拖拽状态转换:
- 收到拖拽开始事件,进入
START
状态 - 拖拽过程中,进入
MOTION_DRAGGING
状态 - 拖拽结束,进入
FINISH
状态 - 清理资源后,回到
STOP
状态
事件触发条件:
- 传感器数据变化
- 用户交互事件
- 跨设备连接状态变化
- 窗口状态变化
- 系统配置更新
5. 接口设计
5.1 公共接口
设备状态管理接口:
订阅设备状态变化
int32_t SubscribeCallback(Type type, ActivityEvent event, ReportLatencyNs latency,sptr<IRemoteDevStaCallback> callback);
- 功能:订阅指定类型的设备状态变化
- 参数:
type
- 设备状态类型event
- 事件类型(进入、退出、进入退出)latency
- 报告延迟callback
- 回调接口
- 返回值:操作结果码
- 异常处理:参数无效时返回错误码
取消订阅
int32_t UnsubscribeCallback(Type type, ActivityEvent event, sptr<IRemoteDevStaCallback> callback);
- 功能:取消设备状态变化订阅
- 参数:与订阅接口相同
- 返回值:操作结果码
获取设备状态数据
Data GetDeviceStatusData(const Type type);
- 功能:获取指定类型的设备状态数据
- 参数:
type
- 设备状态类型 - 返回值:设备状态数据
拖拽交互接口:
开始拖拽
int32_t StartDrag(const DragData &dragData, std::shared_ptr<IStartDragListener> listener);
- 功能:开始拖拽操作
- 参数:
dragData
- 拖拽数据listener
- 拖拽监听器
- 返回值:操作结果码
停止拖拽
int32_t StopDrag(const DragDropResult &dropResult);
- 功能:停止拖拽操作
- 参数:
dropResult
- 拖拽结果 - 返回值:操作结果码
更新拖拽样式
int32_t UpdateDragStyle(DragCursorStyle style, int32_t eventId = -1);
- 功能:更新拖拽时的鼠标样式
- 参数:
style
- 鼠标样式eventId
- 事件ID
- 返回值:操作结果码
跨设备协作接口:
注册协作监听器
int32_t RegisterCoordinationListener(std::shared_ptr<ICoordinationListener> listener);
- 功能:注册跨设备协作监听器
- 参数:
listener
- 协作监听器 - 返回值:操作结果码
激活协作
int32_t ActivateCoordination(const std::string &remoteNetworkId, int32_t startDeviceId,std::function<void(const std::string&, const CoordinationMsgInfo&)> callback);
- 功能:激活跨设备协作
- 参数:
remoteNetworkId
- 远程设备网络IDstartDeviceId
- 起始设备IDcallback
- 结果回调
- 返回值:操作结果码
5.2 数据交换接口
设备状态数据结构:
enum Type {TYPE_INVALID = -1,TYPE_ABSOLUTE_STILL, // 绝对静止TYPE_HORIZONTAL_POSITION, // 水平姿态TYPE_VERTICAL_POSITION, // 垂直姿态TYPE_STILL, // 静止TYPE_RELATIVE_STILL, // 相对静止TYPE_CAR_BLUETOOTH, // 车载蓝牙TYPE_LID_OPEN, // 皮套开启TYPE_MAX
};enum ActivityEvent {EVENT_INVALID = 0,ENTER = 1, // 进入状态EXIT = 2, // 退出状态ENTER_EXIT = 3 // 进入退出
};enum ReportLatencyNs {Latency_INVALID = -1,SHORT = 1, // 短延迟MIDDLE = 2, // 中等延迟LONG = 3 // 长延迟
};
拖拽数据结构:
enum DragState {STOP = 0, // 停止START = 1, // 开始MOTION_DRAGGING = 2, // 拖拽中FINISH = 3 // 完成
};enum DragCursorStyle {DEFAULT = 0, // 默认样式CROSSHAIR = 1, // 十字线HAND = 2, // 手型FORBIDDEN = 3 // 禁止
};
回调接口定义:
class IRemoteDevStaCallback : public IRemoteBroker {
public:virtual void OnDeviceStatusChanged(const Data& data) = 0;DECLARE_INTERFACE_DESCRIPTOR(u"ohos.msdp.IRemoteDevStaCallback");
};class IStartDragListener {
public:virtual void OnDragStart() = 0;virtual void OnDragEnd(int32_t result) = 0;virtual void OnDragMove(float deltaX, float deltaY) = 0;
};
6. 系统架构图
6.1 整体系统架构
6.2 模块内部架构
6.3 类关系图
6.4 状态机转换图
6.5 接口调用时序图
7. 总结
MSDP设备状态感知模块是OpenHarmony系统中的核心感知服务,采用分层架构设计,支持多种设备状态识别和跨设备交互功能。模块通过MSDP算法库实现高精度传感器数据处理,为上层应用提供智能设备状态感知能力。
主要特点:
- 多传感器融合:支持加速度、陀螺仪、霍尔等多种传感器
- 智能状态识别:基于算法库实现高精度状态识别
- 跨设备协作:支持多设备间的拖拽和协作功能
- 异步事件驱动:基于epoll的异步事件处理机制
- 模块化设计:清晰的分层架构,易于维护和扩展
技术亮点:
- 采用单例模式管理核心组件
- 通过观察者模式实现事件通知
- 使用策略模式支持多种算法
- 基于代理模式封装远程调用
- 完善的错误处理和异常管理机制
应用场景:
- 智能设备状态监控
- 跨设备文件传输
- 多设备协作办公
- 运动健康监测
- 智能家居控制