OpenHarmony子系统数据上报功能
一. 简介
有些子系统能为上层提供可订阅的数据,如传感器子系统等。应用端通过on、off函数订阅或取消订阅某些事件,当订阅时能接收xx子系统底层过来的数据/事件。应用端可展示这些数据或进展这些数据、事件进行某些操作(下面的代码,功能已可用但不完善)。
上图展示了代码的大概的层级结构和数据上报模块的大体工作流程,详细见下面两部分
二. 注册数据接收
- frameworks/js/napi/display/src/display_setting.cpp 中定义观察者:
namespace {
std::shared_ptr<DisplayAccessObserver> g_displayAccessObserver = std::make_shared<DisplayAccessObserver>();
}
初始化DisplaySetting::Init() 时调用RegisterAccessObserverToHost(),将g_displayAccessObserver传到services/client/src/xxmw_client_manager.cpp中,通过DisplayHostObserverImp中Register函数保存到观察者对象列表中
void DisplaySetting::RegisterAccessObserverToHost()
{
XXMW_DEBUG_LOG("DisplaySetting::RegisterAccessObserverToHost in");
XXMWClientManager *host = &XxMWClientManager::GetInstance();
host->RegisterObserver(g_displayAccessObserver);
}
void XxMWClientManager::RegisterObserver(std::shared_ptr<DisplayHostObserver> observer)
{
XXMW_DEBUG_LOG("RegisterObserver enter");
if (pimpl == nullptr) {
XXMW_ERR_LOG("pimpl is null.");
return;
}
pimpl->observers_.Register(observer);
}
DisplayObserverList<DisplayHostObserver> observers_;
- hap应用种调用on/off接口,注册/注销事件
由@ohos.xxservice.displaySetting.d.ts对上层应用提供事件订阅接口,如:
function off(type: 'sourcePlugIn', callback?: Callback<number>): void;
function on(type: 'sourcePlugIn', callback: Callback<number>): void;
function off(type: 'sourcePlugOut', callback?: Callback<number>): void;
function on(type: 'sourcePlugOut', callback: Callback<number>): void;
... ...
sourcePlugIn, sourcePlugOut代表事件名称, on(订阅)函数必须要由callback参数,用以接收返回的数据,off的callback参数可有可无
- display_setting.cpp 中定义观察者g_displayAccessObserver, 定义on/off函数,对应RegisterObserver/DeregisterObserver函数:
// on/off state observer
BindNativeFunction(env, exportObj, "on", moduleName, DisplaySetting::RegisterObserver);
BindNativeFunction(env, exportObj, "off", moduleName, DisplaySetting::DeregisterObserver);
napi_value DisplaySetting::RegisterObserver(napi_env env, napi_callback_info info)
{
XXMW_DEBUG_LOG("DisplaySetting::RegisterObserver in");
if (g_displayAccessObserver) {
// 通过观察者中的事件订阅模块,注册订阅的事件和对应的callback到事件订阅模块
auto status = g_displayAccessObserver->eventSubscribe_.Register(env, info);
if (status != napi_ok) {
NError(ERR_PARAM_NUMBER).ThrowErr(env, "Register error!");
return nullptr;
}
}
return NapiGetUndefined(env);
}
napi_value DisplaySetting::DeregisterObserver(napi_env env, napi_callback_info info)
{
XXMW_DEBUG_LOG("DisplaySetting::DeregisterObserver in");
if (g_displayAccessObserver) {
// 注销事件订阅模块中的某个事件和对应的callback
auto status = g_displayAccessObserver->eventSubscribe_.Deregister(env, info);
if (status != napi_ok) {
NError(ERR_PARAM_NUMBER).ThrowErr(env, "Deregister error!");
return nullptr;
}
}
return NapiGetUndefined(env);
}
观察者对象中有事件订阅模块(class EventSubscribeModule, interfaces/kits/js/napi/event_subscribe_module.h),通过display_setting.cpp : RegisterObserver()函数调用订阅模块的Register()可将应用层的订阅事件和对应callback保存到事件订阅模块中,备后续使用
- 连接服务端(services/client/src/xxmw_client_manager.cpp : Connect()),连接服务端时将xxmw_client_manager.cpp中,将DisplayHostObserverImp对象(保存有观察者对象列表)送到服务端stub
int32_t XxMWClientManager::Connect()
{
if (g_sProxy != nullptr) {
return SUS;
}
... ...
g_sProxy = iface_cast<IXxMWAbility>(object);
RETURN_IF_WITH_RET_WITH_LOG(g_sProxy == nullptr, FAIL, "Convert Proxy is Failed");
g_sProxy->RegisterObserver(pimpl->observerImp_);
XXMW_DEBUG_LOG("Connect Success");
return SUS;
}
- 服务端stub(services/server/src/xxmw_ability_stub.cpp)接收到注册观察者函数调用时保存传过来的DisplayHostObserverImp对象,然后调用services/server/src/xxmw_system_ability.cpp中的RegisterObserver()函数注册保存
stubFuncMap_[REGISTER_OBSERVER] = &XxMWAbilityStub::RegisterObserverInternal;
stubFuncMap_[DEREGISTER_OBSERVER] = &XxMWAbilityStub::DeregisterObserverInternal;
void XxMWAbilityStub::RegisterObserverInternal(MessageParcel &data, MessageParcel &reply)
{
XXMW_DEBUG_LOG("RegisterObserverInternal entered");
sptr<IRemoteObject> remote = data.ReadRemoteObject();
const sptr<IXxMWObserver> observer = OHOS::iface_cast<IXxMWObserver>(remote);
RegisterObserver(observer);
}
void XxMWAbilityStub::DeregisterObserverInternal(MessageParcel &data, MessageParcel &reply)
{
XXMW_DEBUG_LOG("DeregisterObserverInternal entered");
sptr<IRemoteObject> remote = data.ReadRemoteObject();
const sptr<IXxMWObserver> observer = OHOS::iface_cast<IXxMWObserver>(remote);
DeregisterObserver(observer);
}
三. 数据上报及接口调用
- services/server/src/xxmw_system_ability.cpp 接收到hdi传上来的数据
- 如SetBootCompletedSaturation等函数可收到hdi返回的数据,可在services/server/src/xxmw_system_ability.cpp中收到数据后调用mAdapterManager->OnAdapterSourcePlugIn()等函数,将事件传递上去
- 调用mAdapterManager->OnAdapterSourcePlugIn()等事件上报函数时,会遍历各个注册过的观察者,然后调用xxmw_system_ability.cpp中的AdapterObserver对象中的OnSourcePlugIn()等函数
// services/server/src/xxmw_adapter_manager.cpp
void XxMWAdapterManager::OnAdapterSourcePlugIn(int32_t sourcePlugIn)
{
XXMW_DEBUG_LOG("OnAdapterSourcePlugIn sourcePlugIn is %{public}d", sourcePlugIn);
std::lock_guard<std::recursive_mutex> lock(pimpl->syncMutex_);
pimpl->adapterObservers_.ForEach(
[sourcePlugIn](IAdapterObserver &observer) { observer.OnSourcePlugIn(sourcePlugIn); });
}
// services/server/src/xxmw_system_ability.cpp
void OnSourcePlugIn(int32_t sourcePlugIn) override
{
if (!impl_) {
XXMW_ERR_LOG("OnSourcePlugIn err");
return;
}
impl_->observers_.ForEach([this, sourcePlugIn](sptr<IXxMWObserver> observer) {
int32_t pid = this->impl_->observersPid_.ReadVal(observer->AsObject());
uint32_t tokenId = this->impl_->observersToken_.ReadVal(observer->AsObject());
XXMW_INFO_LOG("OnSourcePlugIn pid:%d, tokenId:%d", pid, tokenId);
observer->OnSourcePlugIn(sourcePlugIn);
});
}
- 然后调用代理对象的函数如:services/server/src/display_host_observer_proxy.cpp:OnSourcePlugIn(),通过ipc发送数据到xxservice客户端
void DisplayHostObserverProxy::OnSourcePlugIn(int32_t sourcePlugIn)
{
MessageParcel data;
if (!data.WriteInterfaceToken(DisplayHostObserverProxy::GetDescriptor())) {
XXMW_ERR_LOG("DisplayHostObserverProxy::OnSourcePlugIn WriteInterfaceToken error");
return;
}
if (!data.WriteInt32(sourcePlugIn)) {
XXMW_ERR_LOG("DisplayHostObserverProxy::OnSourcePlugIn write sourcePlugIn type error");
return;
}
MessageParcel reply;
MessageOption option = {MessageOption::TF_ASYNC};
ErrCode result = InnerTransact(OBSERVER_SOURCE_PLUG_IN, option, data, reply);
if (result != ERR_NONE) {
XXMW_ERR_LOG("DisplayHostObserverProxy::OnSourcePlugIn done fail, error: %{public}d", result);
return;
}
}
- 客户端通过services/client/src/display_host_observer_stub.cpp接收服务端事件上报,
void DisplayHostObserverStub::OnSourcePlugInInner(MessageParcel &data, MessageParcel &reply)
{
XXMW_DEBUG_LOG("OnSourcePlugInInner entered");
int32_t value = data.ReadInt32();
XXMW_DEBUG_LOG("OnSourcePlugInInner value = %{public}d", value);
OnSourcePlugIn(value);
XXMW_DEBUG_LOG("DisplayHostObserverStub:OnSourcePlugInInner internal exit");
}
再调用到xxmw_client_manager.cpp中XxMWClientManager::impl::DisplayHostObserverImp下OnSourcePlugIn()函数, 然后遍历注册的对应事件和回调函数,传递数据到上层应用中的on函数
void OnSourcePlugIn(int32_t sourcePlugIn) override
{
host_.observers_.ForEach([sourcePlugIn](std::shared_ptr<DisplayHostObserver> observer) {
observer->OnSourcePlugIn(sourcePlugIn);
});
}
-
服务端(services/server/src/xxmw_system_ability.cpp)收到数据后上报方法:根据事件对应的函数调用mAdapterManager->OnAdapterSourcePlugIn()等函数,其他函数见xxmw_adapter_manager.h中声明;
如果在其他模块或文件中调用数据上报,可通过XxMWAdapterManager::GetInstance()获取mAdapterManager(mAdapterManager是XxMWAdapterManager对象,变量名可自行定义)后续还要解耦优化,如:将数据上报的接口从xxmw_adapter_manager.h中拆出来,使用更方便
-
大体的目录结构参考(不通的子系统通常有所不同)
更多推荐
所有评论(0)