您现在的位置是:亿华云 > 应用开发
OpenHarmony 源码解析之Sensor子系统(上)
亿华云2025-10-02 06:26:42【应用开发】8人已围观
简介想了解更多内容,请访问:和华为官方合作共建的鸿蒙技术社区https://harmonyos.51cto.com前言人类获取外界信息必须借助于感觉器官,而在研究自然现象和规律以及生产活动仅靠感官已经远远
想了解更多内容,码解请访问:
和华为官方合作共建的析之系统鸿蒙技术社区
https://harmonyos.51cto.com
前言
人类获取外界信息必须借助于感觉器官,而在研究自然现象和规律以及生产活动仅靠感官已经远远不够了,码解为了适应这种情况,析之系统出现了传感器。码解随着物联网,析之系统移动互联网的码解快速发展,在数字时代,析之系统传感器在智能交通,码解智能工业,析之系统智能穿戴等领域有着广阔的码解应用空间。
概述
传感器是析之系统检测到被测量信息,将非电量信息转换成电信号的码解检测装置。就像眼睛是析之系统人类心灵的窗户,传感器则是码解计算机感知世界万物的眼睛。
传感器用于侦测环境中所发生事件或变化,并将此消息发送至其他电子设备(如中央处理器)的设备,通常由敏感组件和转换组件组成。根据用途可分为以下六大类:
运动类:加速度、陀螺仪、重力、线性加速度传感器等; 姿态类:旋转矢量、方向传感器等; 环境类:磁力计、气压、云服务器湿度传感器等; 光线类:环境光、接近光、色温传感器等; 健康类:心率、心跳传感器等; 其它:霍尔传感器、手握传感器等;架构层级
OpenHarmony架构图:

传感器架构图如下所示:

应用层 :各种需要sensor的应用,例如运动健康,计步器,指南针等等。
框架层 :
SDK ,给应用提供标准接口,包括JS接口和C++接口。 Framework,向应用层提供稳定的基础能力,包括Sensor列表查询、Sensor启停、Sensor订阅及去订阅,Sensor参数配置,创建数据传递通道,sensor数据上传等功能。 Service, 提供Sensor设备管理,Sensor通用配置能力,Sensor通用数据解析能力,权限管理能力。HDF层 :HDF驱动框架,Sensor设备驱动的开发是基于该框架的基础上,结合操作系统适配层(OSAL)和平台驱动接口(比如I2C/SPI/UART总线等平台资源)能力,屏蔽不同操作系统和平台总线资源差异,实现Sensor驱动“一次开发,站群服务器多系统部署”的目标。
Hardware层 :各种传感器器件,例如加速度计,陀螺仪,温度,湿度等等。
Sensor子系统代码目录
/base/sensors/sensor ├── frameworks # 框架代码 │ └── native # sensor客户端代码 ├── interfaces # 对外接口存放目录 │ ├── native # sensor native实现 │ └── plugin # Js API ├── sa_profile # 服务名称和服务的动态库的配置文件 ├── services # 服务的代码目录 │ └── sensor # 传感器服务,包括加速度、陀螺仪等,上报传感器数据 └── utils # 公共代码,包括权限、通信等能力源码分析
本文先讲解框架层的代码,HDF的部分放在下一篇文章讲解。框架层主要包含两部分:
JS应用订阅、启动sensor。
JS应用收到订阅sensor的数据信息。
1. JS应用订阅、启动Sensor
我们从JS API开放的能力开始看源码,绿色部分看作client,黄色部分看作service。

JS API的主要接口:
给JS应用提供接口的实现文件是sensor_js.cpp,我们从init开始看接口的云南idc服务商实现:
static napi_value Init(napi_env env, napi_value exports) { // 这里定义了三个接口,on、once、off。 napi_property_descriptor desc[] = { DECLARE_NAPI_FUNCTION("on", On), DECLARE_NAPI_FUNCTION("once", Once), DECLARE_NAPI_FUNCTION("off", Off) }; NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(napi_property_descriptor), desc)); return exports; } static napi_value On(napi_env env, napi_callback_info info) { ...... // 获取JS应用传递的sensorTypeId,例如加速度计,陀螺仪等等 int32_t sensorTypeId = GetCppInt32(args[0], env); ...... AsyncCallbackInfo *asyncCallbackInfo = new AsyncCallbackInfo { .env = env, .asyncWork = nullptr, .deferred = nullptr, }; napi_create_reference(env, args[1], 1, &asyncCallbackInfo->callback[0]); g_onCallbackInfos[sensorTypeId] = asyncCallbackInfo; // 调用SubscribeSensor函数订阅该sensor,指定sensor类型,上报频率,数据返回通过DataCallbackImpl。 int32_t ret = SubscribeSensor(sensorTypeId, interval, DataCallbackImpl); ...... HiLog::Info(LABEL, "%{ public}s out", __func__); return nullptr; } static int32_t SubscribeSensor(int32_t sensorTypeId, int64_t interval, RecordSensorCallback callback) { HiLog::Info(LABEL, "%{ public}s in, sensorTypeId: %{ public}d", __func__, sensorTypeId); // 注一:订阅指定sensorId的传感器数据,通过user,系统将向应用上报获得的传感器数据,user实际就是callback。 int32_t ret = SubscribeSensor(sensorTypeId, &user); if (ret < 0) { HiLog::Error(LABEL, "%{ public}s subscribeSensor failed", __func__); return ret; } // 设置采样频率和上报频率 ret = SetBatch(sensorTypeId, &user, interval, 0); if (ret < 0) { HiLog::Error(LABEL, "%{ public}s set batch failed", __func__); return ret; } //注二: 启用已订阅的传感器。只有在启用传感器后,应用才能获取传感器数据。 ret = ActivateSensor(sensorTypeId, &user); if (ret < 0) { HiLog::Error(LABEL, "%{ public}s activateSensor failed", __func__); return ret; } return 0; }注一:SubscribeSensor,订阅sensor,建立sensor数据传递频道。
int32_t SensorAgentProxy::SubscribeSensor(int32_t sensorId, const SensorUser *user) const { HiLog::Info(LABEL, "%{ public}s in, sensorId: %{ public}d", __func__, sensorId); if (user == nullptr || sensorId < 0 || user->callback == nullptr) { HiLog::Error(LABEL, "%{ public}s user is null or sensorId is invalid", __func__); return OHOS::Sensors::ERROR; } if (!g_isChannelCreated) { HiLog::Info(LABEL, "%{ public}s channel created", __func__); g_isChannelCreated = true; // 创建sensor数据频道,通过此channel实现client和service的数据传递。 CreateSensorDataChannel(user); } // 指定sensorId对应的callback g_subscribeMap[sensorId] = user; return OHOS::Sensors::SUCCESS; } int32_t SensorAgentProxy::CreateSensorDataChannel(const SensorUser *user) const { HiLog::Debug(LABEL, "%{ public}s", __func__); if (dataChannel_ == nullptr) { HiLog::Error(LABEL, "%{ public}s data channel cannot be null", __func__); return INVALID_POINTER; } // 注1 ,创建sensor数据传递频道,sendFd和recvFd auto ret = dataChannel_->CreateSensorDataChannel(HandleSensorData, nullptr); if (ret != ERR_OK) { HiLog::Error(LABEL, "%{ public}s create data channel failed, ret : %{ public}d", __func__, ret); return ret; } auto &client = SensorServiceClient::GetInstance(); // 注2 , 将client创建的数据频道,sendFd转移到service,使得service和client可以通讯。 ret = client.TransferDataChannel(dataChannel_); if (ret != ERR_OK) { auto destoryRet = dataChannel_->DestroySensorDataChannel(); HiLog::Error(LABEL, "%{ public}s transfer data channel failed, ret : %{ public}d, destoryRet : %{ public}d",__func__, ret, destoryRet); return ret; } return ERR_OK; }先看注1,创建sensor数据传递频道,sendFd和receiveFd,由调用关系找到,调用SensorDataChannel::InnerSensorDataChannel(),我们来看下这个函数。
int32_t SensorDataChannel::InnerSensorDataChannel() { std::lock_guard<std::mutex> threadLock(treadMutex_); // create basic data channel,通过socketpair()函数用于创建一对套接字sendFd_和receiveFd_ int32_t ret = CreateSensorBasicChannel(SENSOR_READ_DATA_SIZE,SENSOR_READ_DATA_SIZE); if (ret != ERR_OK) { HiLog::Error(LABEL, "%{ public}s create basic channel failed, ret : %{ public}d", __func__, ret); return ret; } auto listener = std::make_shared<MyFileDescriptorListener>(); listener->SetChannel(this); auto myRunner = AppExecFwk::EventRunner::Create(true); if (myRunner == nullptr) { HiLog::Error(LABEL, "%{ public}s myRunner is null", __func__); return -1; } auto handler = std::make_shared<MyEventHandler>(myRunner); if (handler == nullptr) { HiLog::Error(LABEL, "%{ public}s handler is null", __func__); return -1; } // receiveFd_绑定到MyFileDescriptorListener,MyFileDescriptorListener用于接收sensor数据 receiveFd_ = GetReceiveDataFd(); auto inResult = handler->AddFileDescriptorListener(receiveFd_, AppExecFwk::FILE_DESCRIPTOR_INPUT_EVENT, listener); …… }再看注2,如何将sendFd_转移给service,作为sensor数据的发送端?
ErrCode SensorServiceProxy::TransferDataChannel(const sptr<SensorBasicDataChannel> &sensorBasicDataChannel, const sptr<IRemoteObject> &sensorClient) { HiLog::Debug(LABEL, "%{ public}s sendFd: %{ public}d", __func__, sensorBasicDataChannel->GetSendDataFd()); if (sensorBasicDataChannel == nullptr || sensorClient == nullptr) { HiLog::Error(LABEL, "%{ public}s sensorBasicDataChannel or sensorClient cannot be null", __func__); return OBJECT_NULL; } MessageParcel data; MessageParcel reply; MessageOption option; if (!data.WriteInterfaceToken(SensorServiceProxy::GetDescriptor())) { HiLog::Error(LABEL, "%{ public}s write descriptor failed", __func__); return WRITE_MSG_ERR; } // 将sendFd_写入parcel,会通过SendRequest,传递给service sensorBasicDataChannel->SendToBinder(data); if (!data.WriteRemoteObject(sensorClient)) { HiLog::Error(LABEL, "%{ public}s write sensorClient failed", __func__); return WRITE_MSG_ERR; } // IPC通讯机制,执行此处会调用service的CreateDataChannelInner int32_t ret = Remote()->SendRequest(ISensorService::TRANSFER_DATA_CHANNEL, data, reply, option); if (ret != NO_ERROR) { DmdReport::ReportException(SENSOR_SERVICE_IPC_EXCEPTION, "TransferDataChannel", ret); HiLog::Error(LABEL, "%{ public}s failed, ret : %{ public}d", __func__, ret); } sensorBasicDataChannel->CloseSendFd(); return static_cast<ErrCode>(ret); }由SendRequest,指定ISensorService::TRANSFER_DATA_CHANNEL会调用到CreateDataChannelInner,这个函数主要的作用是CreateSensorBasicChannel,service端获取到sendFd_。
ErrCode SensorServiceStub::CreateDataChannelInner(MessageParcel &data, MessageParcel &reply) { (void)reply; sptr<SensorBasicDataChannel> sensorChannel = new (std::nothrow)SensorBasicDataChannel(); if (sensorChannel == nullptr) { HiLog::Error(LABEL, "%{ public}s sensorChannel cannot be null", __func__); return OBJECT_NULL; } auto ret = sensorChannel->CreateSensorBasicChannel(data); if (ret != ERR_OK) { HiLog::Error(LABEL, "%{ public}s CreateSensorBasicChannel ret : %{ public}d",__func__, ret); return OBJECT_NULL; } sptr<IRemoteObject> sensorClient = data.ReadRemoteObject(); if (sensorClient == nullptr) { HiLog::Error(LABEL, "%{ public}s sensorClient cannot be null", __func__); return OBJECT_NULL; } return TransferDataChannel(sensorChannel, sensorClient); } int32_t SensorBasicDataChannel::CreateSensorBasicChannel(MessageParcel &data) { HiLog::Debug(LABEL, "%{ public}s begin", __func__); if ((sendFd_ != INVALID_FD) || (receiveFd_ != INVALID_FD)) { HiLog::Debug(LABEL, "%{ public}s already create socketpair", __func__); return ERR_OK; } int32_t tmpFd = data.ReadFileDescriptor(); if (tmpFd < 0) { HiLog::Error(LABEL, "%{ public}s ReadFileDescriptor failed", __func__); sendFd_ = INVALID_FD; return SENSOR_CHANNEL_DUP_ERR; } // service的sendFd,和前面的receiveFd对应,用于传递sensor数据。 sendFd_ = dup(tmpFd); HiLog::Error(LABEL, "%{ public}s sendFd: %{ public}d", __func__, sendFd_); if (sendFd_ < 0) { HiLog::Error(LABEL, "%{ public}s dup FileDescriptor failed", __func__); sendFd_ = INVALID_FD; return SENSOR_CHANNEL_DUP_ERR; } return ERR_OK; }至此client和service跨进程传递Sensor数据的通道建立完成了。
注二: 启用已订阅的传感器。
int32_t ActivateSensor(int32_t sensorId, const SensorUser *user) { HiLog::Info(LABEL, "%{ public}s begin", __func__); const SensorAgentProxy *proxy = GetInstance(); if (proxy == NULL) { HiLog::Error(LABEL, "%s proxy is null", __func__); return OHOS::Sensors::ERROR; } // 调用SensorAgentProxy的ActivateSensor函数,指定sendorId和user,开启sensor return proxy->ActivateSensor(sensorId, user); } int32_t SensorAgentProxy::ActivateSensor(int32_t sensorId, const SensorUser *user) const { if (user == NULL || sensorId < 0) { HiLog::Error(LABEL, "%{ public}s user is null or sensorId is invalid",__func__); return OHOS::Sensors::ERROR; } if (g_samplingInterval < 0 || g_reportInterval < 0) { HiLog::Error(LABEL, "%{ public}s samplingPeroid or g_reportInterval is invalid", __func__); return OHOS::Sensors::ERROR; } if ((g_subscribeMap.find(sensorId) == g_subscribeMap.end()) || (g_subscribeMap.at(sensorId) != user)) { HiLog::Error(LABEL, "%{ public}s subscribe sensorId first", __func__); return OHOS::Sensors::ERROR; } SensorServiceClient &client = SensorServiceClient::GetInstance(); // 调用SensorServiceClient的 EnableSensor,指定sensorId,采样频率设上报频率。 int32_t ret = client.EnableSensor(sensorId, g_samplingInterval, g_reportInterval); g_samplingInterval = -1; g_reportInterval = -1; if (ret != 0) { HiLog::Error(LABEL, "%{ public}s enable sensor failed, ret: %{ public}d",__func__, ret); return OHOS::Sensors::ERROR; } return OHOS::Sensors::SUCCESS; }最终会调用到SensorServiceImpl::EnableSensor,这里主要是调用HDF提供的标准接口,打开sensor,下一篇文章会讲述HDF的内容。
ErrCode SensorServiceImpl::EnableSensor(uint32_t sensorId) const { HiLog::Info(LABEL, "%{ public}s begin", __func__); int32_t ret = sensorInterface_->Enable(sensorId); if (ret < 0) { HiLog::Error(LABEL, "%{ public}s is failed", __func__); return -1; } HiLog::Info(LABEL, "%{ public}s end", __func__); return ERR_OK; }2. JS应用接收订阅的sensor数据

Sensor打开之后,就会有sensor数据按照上报频率上报给应用。我们下面看下,数据是如何上报的?
前面看到传递的数据通道在订阅时已经创建好了,SensorService::EnableSensor时,在其内部还调用了SaveSubscriber。
ErrCode SensorService::EnableSensor(uint32_t sensorId, int64_t samplingPeriodNs, int64_t maxReportDelayNs) { ...... auto ret = SaveSubscriber(sensorId, samplingPeriodNs, maxReportDelayNs); if (ret != ERR_OK) { HiLog::Error(LABEL, "%{ public}s SaveSubscriber failed", __func__); return ret; } ret = sensorServiceImpl_.EnableSensor(sensorId); if (ret != ERR_OK) { HiLog::Error(LABEL, "%{ public}s EnableSensor failed", __func__); clientInfo_.RemoveSubscriber(sensorId, this->GetCallingPid()); return ENABLE_SENSOR_ERR; } return ret; }SaveSubscriber 做了两件事情:
1、调用SensorManager::SaveSubscriber管理sensor订阅信息。
2、开启sensor数据上报的线程。
ErrCode SensorService::SaveSubscriber(uint32_t sensorId, int64_t samplingPeriodNs, int64_t maxReportDelayNs) { auto ret = sensorManager_.SaveSubscriber(sensorId, this->GetCallingPid(), samplingPeriodNs, maxReportDelayNs); if (ret != ERR_OK) { HiLog::Error(LABEL, "%{ public}s SaveSubscriber failed", __func__); return ret; } sensorManager_.StartDataReportThread(); if (!sensorManager_.SetBestSensorParams(sensorId, samplingPeriodNs, maxReportDelayNs)) { HiLog::Error(LABEL, "%{ public}s SetBestSensorParams failed", __func__); clientInfo_.RemoveSubscriber(sensorId, this->GetCallingPid()); return ENABLE_SENSOR_ERR; } return ret; } void SensorManager::StartDataReportThread() { HiLog::Debug(LABEL, "%{ public}s begin", __func__); if (!dataThread_.joinable()) { HiLog::Warn(LABEL, "%{ public}s dataThread_ started", __func__); std::thread senocdDataThread(SensorDataProcesser::DataThread, sensorDataProcesser_, reportDataCallback_); dataThread_ = std::move(senocdDataThread); } HiLog::Debug(LABEL, "%{ public}s end", __func__); } int32_t SensorDataProcesser::DataThread(sptr<SensorDataProcesser>dataProcesser, sptr<ReportDataCallback> dataCallback) { HiLog::Debug(LABEL, "%{ public}s begin", __func__); do { if (dataProcesser->ProcessEvents(dataCallback) == INVALID_POINTER) { HiLog::Error(LABEL, "%{ public}s callback cannot be null", __func__); return INVALID_POINTER; } } while (1); } int32_t SensorDataProcesser::ProcessEvents(sptr<ReportDataCallback>dataCallback) { if (dataCallback == nullptr) { HiLog::Error(LABEL, "%{ public}s dataCallback cannot be null", __func__); return INVALID_POINTER; } std::unique_lock<std::mutex> lk(SensorServiceImpl::dataMutex_); // 使用std::condition_variable::wait(),处于阻塞状态, // 当其它线程调用notify_one()或者notify_all()函数,wait()会结束阻塞。 SensorServiceImpl::dataCondition_.wait(lk); ...... return SUCCESS; }看到这里,我们发现SaveSubscriber创建了sensor数据处理的线程,并使用SensorServiceImpl::dataCondition_.wait(lk)进入阻塞状态,我们看下何时使用notify_one()来激活该线程上报数据的?
系统开机启动时,hsensors进程启动,也就是SensorService启动。
on post-fs-data start hsensors service hsensors /system/bin/sa_main /system/profile/hsensors.xml class hsensors user system group system shell seclabel u:r:foundation:s0SensorService启动后,会将ZReportDataCallback 注册到HDF,看下面的代码:
void SensorService::OnStart() { if (state_ == SensorServiceState::STATE_RUNNING) { HiLog::Warn(LABEL, "%{ public}s SensorService has already started", __func__); return; } // 调用HDF标准接口,初始化 if (!InitInterface()) { HiLog::Error(LABEL, "%{ public}s Init interface error", __func__); return; } // 注册数据返回的callback,初始化 if (!InitDataCallback()) { HiLog::Error(LABEL, "%{ public}s Init data callback error", __func__); return; } ...... } bool SensorService::InitDataCallback() { reportDataCallback_ = new (std::nothrow) ReportDataCallback(); if (reportDataCallback_ == nullptr) { HiLog::Error(LABEL, "%{ public}s failed, reportDataCallback_ cannot be null",__func__); return false; } // 将ZReportDataCallback通过RegisteDataReport赋值给reportDataCb_,sensor数据上报会触发ZReportDataCallback // new ReportDataCallback传递到sensorServiceImpl_,为了调用reportDataCb_ ZReportDataCb cb = &ReportDataCallback::ZReportDataCallback; auto ret = sensorServiceImpl_.RegisteDataReport(cb, reportDataCallback_); if (ret != ERR_OK) { HiLog::Error(LABEL, "%{ public}s RegisterDataReport failed", __func__); return false; } return true; } ErrCode SensorServiceImpl::RegisteDataReport(ZReportDataCb cb, sptr<ReportDataCallback> reportDataCallback) { HiLog::Info(LABEL, "%{ public}s begin", __func__); if (reportDataCallback == nullptr) { HiLog::Error(LABEL, "%{ public}s failed, reportDataCallback cannot be null",__func__); return ERR_NO_INIT; } // 注册callback到HDF Register(SensorDataCallback); reportDataCb_ = cb; reportDataCallback_ = reportDataCallback; HiLog::Info(LABEL, "%{ public}s end", __func__); return ERR_OK; } ErrCode SensorServiceImpl::Register(RecordDataCallback cb) const { HiLog::Info(LABEL, "%{ public}s begin", __func__); if (sensorInterface_ == nullptr) { HiLog::Error(LABEL, " %{ public}s,", "test sensorHdi get Module instance failed\n\r"); return ERR_INVALID_VALUE; } // 通过HDF提供的标准接口,注册到HDF int32_t ret = sensorInterface_->Register(cb); if (ret < 0) { HiLog::Error(LABEL, "%{ public}s failed", __func__); return ERR_INVALID_VALUE; } HiLog::Info(LABEL, "%{ public}s end", __func__); return ERR_OK; }当JS应用订阅了传感器,并且启用了传感器,传感器数据就从SensorServiceImpl::SensorDataCallback向上传递,我们看下这函数的实现,主要做了两件事情:
1、调用ReportDataCallback::ZreportDataCallback将sensor数据写入cb->eventsBuf_。
2、调用dataCondition_.notify_one()激活数据上报的线程。
int32_t SensorServiceImpl::SensorDataCallback(const struct SensorEvents *event) { HiLog::Debug(LABEL, "%{ public}s begin", __func__); const int32_t SENSOR_AXISZ = 2; if ((event == nullptr) || (event->dataLen == 0)) { HiLog::Error(LABEL, "%{ public}s event is NULL", __func__); return ERR_INVALID_VALUE; } float *data = (float*)event->data; if (reportDataCb_ == nullptr) { HiLog::Error(LABEL, "%{ public}s reportDataCb_ cannot be null", __func__); return ERR_INVALID_VALUE; } // 调用ReportDataCallback::ZReportDataCallback方法,存入eventsBuf_ (void)(reportDataCallback_->*reportDataCb_)(reinterpret_cast<const structSensorEvent*>(event), reportDataCallback_); // 激活sensor数据上报线程 dataCondition_.notify_one(); return ERR_OK; } int32_t ReportDataCallback::ZReportDataCallback(const struct SensorEvent *event, sptr<ReportDataCallback> cb) { float *data = (float*)event->data; if (cb == nullptr || cb->eventsBuf_.circularBuf == nullptr || event == nullptr) { HiLog::Error(LABEL, "%{ public}s callback or circularBuf or event cannot be null", __func__); return ERROR; } struct SensorEvent eventCopy = { .sensorTypeId = event->sensorTypeId, .version = event->version, .timestamp = event->timestamp, .option = event->option, .mode = event->mode, .dataLen = event->dataLen }; eventCopy.data = new uint8_t[SENSOR_DATA_LENGHT]; if (memcpy_s(eventCopy.data, event->dataLen, event->data, event->dataLen) != EOK) { HiLog::Error(LABEL, "%{ public}s copy data failed", __func__); return COPY_ERR; } // 将SensorEvent的数据存入到ReportDataCallback的变量eventsBuf_里面 int32_t leftSize = CIRCULAR_BUF_LEN - cb->eventsBuf_.eventNum; int32_t toEndLen = CIRCULAR_BUF_LEN - cb->eventsBuf_.writePosition; if (toEndLen == 0) { cb->eventsBuf_.circularBuf[0] = eventCopy; cb->eventsBuf_.writePosition = 1 - toEndLen; } else { cb->eventsBuf_.circularBuf[cb->eventsBuf_.writePosition] = eventCopy; cb->eventsBuf_.writePosition += 1; } …… }至此,回过头来再看SensorDataProcesser::ProcessEvents,lock锁激活后,获取到eventsBuf_。
int32_t SensorDataProcesser::ProcessEvents(sptr<ReportDataCallback>dataCallback) { if (dataCallback == nullptr) { HiLog::Error(LABEL, "%{ public}s dataCallback cannot be null", __func__); return INVALID_POINTER; } std::unique_lock<std::mutex> lk(SensorServiceImpl::dataMutex_); SensorServiceImpl::dataCondition_.wait(lk); auto &eventsBuf = dataCallback->GetEventData(); if (eventsBuf.eventNum <= 0) { HiLog::Error(LABEL, "%{ public}s data cannot be empty", __func__); return NO_EVENT; } int32_t eventNum = eventsBuf.eventNum; for (int32_t i = 0; i < eventNum; i++) { // 通过EventFilter report eventsBuf数据 EventFilter(eventsBuf); delete eventsBuf.circularBuf[eventsBuf.readPosition].data; eventsBuf.circularBuf[eventsBuf.readPosition].data = nullptr; eventsBuf.readPosition++; if (eventsBuf.readPosition == CIRCULAR_BUF_LEN) { eventsBuf.readPosition = 0; } eventsBuf.eventNum--; } return SUCCESS; }EventFilter最终会调用SendRawData,通过该函数的channel->SendData,调用Socket send函数发送sensor数据。这里的sendFd_就是前面创建的。(中间的调用过程请看前面的时序图)
int32_t SensorBasicDataChannel::SendData(const void *vaddr, size_t size) { if (vaddr == nullptr || sendFd_ < 0) { HiLog::Error(LABEL, "%{ public}s failed, param is invalid", __func__); return SENSOR_CHANNEL_SEND_ADDR_ERR; } ssize_t length; do { length = send(sendFd_, vaddr, size, MSG_DONTWAIT | MSG_NOSIGNAL); } while (errno == EINTR); if (length < 0) { HiLog::Error(LABEL, "%{ public}s send fail : %{ public}d, length = %{ public}d", __func__, errno, (int32_t)length); return SENSOR_CHANNEL_SEND_DATA_ERR; } return ERR_OK; } void MyFileDescriptorListener::OnReadable(int32_t fileDescriptor) { if (fileDescriptor < 0) { HiLog::Error(LABEL, "%{ public}s fileDescriptor: %{ public}d", __func__, fileDescriptor); return; } FileDescriptorListener::OnReadable(fileDescriptor); struct TransferSensorEvents *receiveDataBuff_ = new (std::nothrow) TransferSensorEvents[sizeof(struct TransferSensorEvents) * RECEIVE_DATA_SIZE]; // 接收sensor数据,这里的fileDescriptor就是receiveFd_ int32_t len = recv(fileDescriptor, receiveDataBuff_, sizeof(struct TransferSensorEvents) * RECEIVE_DATA_SIZE, NULL); while (len > 0) { int32_t eventSize = sizeof(struct TransferSensorEvents); int32_t num = len / eventSize; for (int i = 0; i < num; i++) { SensorEvent event = { .sensorTypeId = receiveDataBuff_[i].sensorTypeId, .version = receiveDataBuff_[i].version, .timestamp = receiveDataBuff_[i].timestamp, .option = receiveDataBuff_[i].option, .mode = receiveDataBuff_[i].mode, .dataLen = receiveDataBuff_[i].dataLen, .data = receiveDataBuff_[i].data }; float *data = (float *)(event.data); // 通过dataCB_将数据再往上层传递,dataCB_即SensorAgentProxy::HandleSensorData channel_->dataCB_(&event, 1, channel_->privateData_); } len = recv(fileDescriptor, receiveDataBuff_, sizeof(struct TransferSensorEvents) * RECEIVE_DATA_SIZE, NULL); } } void SensorAgentProxy::HandleSensorData(struct SensorEvent *events, int32_t num, void *data) { if (events == nullptr || num <= 0) { HiLog::Error(LABEL, "%{ public}s events is null or num is invalid", __func__); return; } struct SensorEvent eventStream; for (int32_t i = 0; i < num; ++i) { eventStream = events[i]; if (eventStream.data == nullptr || g_subscribeMap[eventStream.sensorTypeId] == nullptr) { HiLog::Error(LABEL, "%{ public}s data or sensorUser is nullptr", __func__); return; } if (g_subscribeMap.find(eventStream.sensorTypeId) == g_subscribeMap.end()) { HiLog::Error(LABEL, "%{ public}s sensorTypeId not in g_subscribeMap", __func__); return; } // 这里的callback调用的是sensor_js.cpp DataCallbackImpl函数 g_subscribeMap[eventStream.sensorTypeId]->callback(&eventStream); } }通过DataCallbackImpl将数据上报给JS应用。以加速度计为例,会出现下面的log打印。
sensor.on(sensor.SensorType.SENSOR_TYPE_ID_ACCELEROMETER, (error, data) => { if (error) { console.error("Failed to subscribe to acceleration data. Error code: " + error.code + "; message: " + error.message); return; } console.info("Acceleration data obtained. x: " + data.x + "; y: " + data.y + ";z: " + data.z); }, { interval:200000000});总结
本文主要和大家分享传感器应用到框架层的实现,重点分析了传感器订阅、启动以及接收订阅传感器数据,做了较为详细的代码说明,希望通过本文您能初步掌握JS应用开发到框架层开发的步骤与流程。关于传感器HDF框架和驱动的分析,请关注后续文章。
想了解更多内容,请访问:
和华为官方合作共建的鸿蒙技术社区
https://harmonyos.51cto.com
很赞哦!(6654)