# 介绍 - [简介](#section11660541593) - [目录](#section1464106163817) - [约束](#section1718733212019) - [开发服务](#section159991817144514) - [开发服务的子功能](#section11510542164514) - [开发进程内对外接口](#section1685211117463) - [调用进程内服务](#section3690162916462) - [开发跨进程间对外接口](#section9220246194615) - [调用跨进程间服务](#section114372711475) - [开发跨进程间服务调用客户端代理](#section09341923114710) - [涉及仓](#section10365113863719) ## 简介 由于平台资源有限,且硬件平台多样,因此需要屏蔽不同硬件架构和平台资源的不同、以及运行形态的不同,提供统一化的系统服务开发框架。根据RISC-V、Cortex-M、Cortex-A不同硬件平台,分为两种硬件平台,以下简称M核、A核。 - M核:处理器架构为Cortex-M或同等处理能力的硬件平台,系统内存一般低于512KB,无文件系统或者仅提供一个可有限使用的轻量级文件系统,遵循CMSIS接口规范。 - A核:处理器架构为Cortex-A或同等处理能力的硬件平台,内存资源大于512KB,文件系统完善,可存储大量数据,遵循POSIX接口规范。 系统服务框架基于面向服务的架构,提供了服务开发、服务的子功能开发、对外接口的开发、以及多服务共进程、进程间服务调用等开发能力。其中: - M核:包含服务开发、服务的子功能开发、对外接口的开发以及多服务共进程的开发框架。 - A核:在M核能力基础之上,包含了进程间服务调用、进程间服务调用权限控制、进程间服务接口的开发等能力。 面向服务的架构: ![](figures/zh-cn_image_0000001128146921.png) - Provider:服务的提供者,为系统提供能力(对外接口)。 - Consumer:服务的消费者,调用服务提供的功能(对外接口)。 - Samgr:作为中介者,管理Provider提供的能力,同时帮助Consumer发现Provider的能力。 系统服务开发框架主体对象: ![](figures/zh-cn_image_0000001081285004.png) - SamgrLite:主要提供服务的注册与发现能力。 - Service:开发服务时,需要实现的服务的生命周期接口。 - Feature:开发功能时,需要实现的功能的生命周期接口。 - IUnknown:基于IUnknown开发服务或功能的对外接口。 - IClientProxy:IPC调用时,消费者的消息发送代理。 - IServerProxy:IPC调用时,开发者需要实现提供者的消息处理接口。 ## 目录 **表 1** 系统服务框架源代码目录结构

名称

描述

interfaces/kits/samgr_lite/samgr

M核和A核系统服务框架对外接口定义。

interfaces/kits/samgr_lite/registry

A核进程间服务调用的对外接口定义。

interfaces/kits/samgr_lite/communication/broadcast

M核和A核进程内事件广播服务的对外接口定义。

services/samgr_lite/samgr/adapter

POSIX和CMSIS接口适配层来屏蔽A核M核接口差异。

services/samgr_lite/samgr/registry

M核服务注册发现的桩函数。

services/samgr_lite/samgr/source

M核和A核系统服务开发框架基础代码。

services/samgr_lite/samgr_client

A核进程间服务调用的注册与发现。

services/samgr_lite/samgr_server

A核进程间服务调用的IPC地址管理和访问控制。

services/samgr_lite/samgr_endpoint

A核IPC通信消息收发包管理。

services/samgr_lite/communication/broadcast

M核和A核进程内事件广播服务。

## 约束 - 系统服务开发框架统一使用C开发。 - 同进程内服务间调用统一使用IUnknown接口对外象,消息接口统一由IUnknown接口传递给本服务。 - 服务名和功能名必需使用常量字符串且长度小于16个字节。 - M核:系统依赖上bootstrap服务,在系统启动函数中调用OHOS\_SystemInit\(\)函数。 - A核:系统依赖samgr库,在main函数中调用SAMGR\_Bootstrap\(\)函数。 ## 开发服务 - 继承并重新定义服务: ``` typedef struct ExampleService { INHERIT_SERVICE; INHERIT_IUNKNOWNENTRY(DefaultFeatureApi); Identity identity; } ExampleService; ``` - 实现服务的生命周期函数: ``` static const char *GetName(Service *service) { return EXAMPLE_SERVICE; } static BOOL Initialize(Service *service, Identity identity) { ExampleService *example = (ExampleService *)service; // 保存服务的唯一身份标识,用来自己的IUnknown接口对服务发消息时使用。 example->identity = identity; return TRUE; } static BOOL MessageHandle(Service *service, Request *msg) { ExampleService *example = (ExampleService *)service; switch (msg->msgId) { case MSG_SYNC: // 业务处理 break; default:break; } return FALSE; } static TaskConfig GetTaskConfig(Service *service) { TaskConfig config = {LEVEL_HIGH, PRI_BELOW_NORMAL, 0x800, 20, SHARED_TASK}; return config; } ``` - 创建服务对象: ``` static ExampleService g_example = { .GetName = GetName, .Initialize = Initialize, .MessageHandle = MessageHandle, .GetTaskConfig = GetTaskConfig, SERVER_IPROXY_IMPL_BEGIN, .Invoke = NULL, .SyncCall = SyncCall, IPROXY_END, }; ``` - 向SAMGR注册服务及接口: ``` static void Init(void) { SAMGR_GetInstance()->RegisterService((Service *)&g_example); SAMGR_GetInstance()->RegisterDefaultFeatureApi(EXAMPLE_SERVICE, GET_IUNKNOWN(g_example)); } ``` - 定义服务的初始化入口: ``` SYSEX_SERVICE_INIT(Init); ``` ## 开发服务的子功能 - 继承并重新定义功能: ``` typedef struct DemoFeature { INHERIT_FEATURE; INHERIT_IUNKNOWNENTRY(DemoApi); Identity identity; Service *parent; } DemoFeature; ``` - 实现功能的生命周期函数: ``` static const char *FEATURE_GetName(Feature *feature) { return EXAMPLE_FEATURE; } static void FEATURE_OnInitialize(Feature *feature, Service *parent, Identity identity) { DemoFeature *demoFeature = (DemoFeature *)feature; demoFeature->identity = identity; demoFeature->parent = parent; } static void FEATURE_OnStop(Feature *feature, Identity identity) { g_example.identity.queueId = NULL; g_example.identity.featureId = -1; g_example.identity.serviceId = -1; } static BOOL FEATURE_OnMessage(Feature *feature, Request *request) { if (request->msgId == MSG_PROC) { Response response = {.data = "Yes, you did!", .len = 0}; SAMGR_SendResponse(request, &response); return TRUE; } else { if (request->msgId == MSG_TIME_PROC) { LOS_Msleep(WAIT_FEATURE_PROC * 10); if (request->msgValue) { SAMGR_PrintServices(); } else { SAMGR_PrintOperations(); } AsyncTimeCall(GET_IUNKNOWN(g_example)); return FALSE; } } return FALSE; } ``` - 创建功能对象: ``` static DemoFeature g_example = { .GetName = FEATURE_GetName, .OnInitialize = FEATURE_OnInitialize, .OnStop = FEATURE_OnStop, .OnMessage = FEATURE_OnMessage, DEFAULT_IUNKNOWN_ENTRY_BEGIN, .AsyncCall = AsyncCall, .AsyncTimeCall = AsyncTimeCall, .SyncCall = SyncCall, .AsyncCallBack = AsyncCallBack, DEFAULT_IUNKNOWN_ENTRY_END, .identity = {-1, -1, NULL}, }; ``` - 向SAMGR注册功能及接口: ``` static void Init(void){ SAMGR_GetInstance()->RegisterFeature(EXAMPLE_SERVICE, (Feature *)&g_example); SAMGR_GetInstance()->RegisterFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE, GET_IUNKNOWN(g_example)); } ``` - 定义功能的初始化入口: ``` SYSEX_FEATURE_INIT(Init); ``` ## 开发进程内对外接口 - 定义IUnknown接口: ``` typedef struct DemoApi { INHERIT_IUNKNOWN; BOOL (*AsyncCall)(IUnknown *iUnknown, const char *buff); BOOL (*AsyncTimeCall)(IUnknown *iUnknown); BOOL (*SyncCall)(IUnknown *iUnknown, struct Payload *payload); BOOL (*AsyncCallBack)(IUnknown *iUnknown, const char *buff, Handler handler); } DemoApi; ``` - 定义IUnknown的引用对象: ``` typedef struct DemoRefApi { INHERIT_IUNKNOWNENTRY(DemoApi); } DemoRefApi; ``` - 初始化接口对象: ``` static DemoRefApi api = { DEFAULT_IUNKNOWN_ENTRY_BEGIN, .AsyncCall = AsyncCall, .AsyncTimeCall = AsyncTimeCall, .SyncCall = SyncCall, .AsyncCallBack = AsyncCallBack, DEFAULT_IUNKNOWN_ENTRY_END, }; ``` - 注册服务接口: ``` SAMGR_GetInstance()->RegisterFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE, GET_IUNKNOWN(api)); ``` ## 调用进程内服务 - 获取服务的对外接口: ``` DemoApi *demoApi = NULL; IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE); if (iUnknown == NULL) { return NULL; } int result = iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void **)&demoApi); if (result != 0 || demoApi == NULL) { return NULL; } ``` - 接口调用: ``` if (demoApi->AsyncCallBack == NULL) { return NULL; } demoApi->AsyncCallBack((IUnknown *)demoApi, "I wanna async call callback good result!", AsyncHandler); ``` - 释放接口: ``` int32 ref = demoApi->Release((IUnknown *)demoApi); ``` ## 开发跨进程间对外接口 - 继承IServerProxy替代继承IUnknown:INHERIT\_SERVER\_IPROXY ``` typedef struct DemoFeatureApi { INHERIT_SERVER_IPROXY; BOOL (*AsyncCall)(IUnknown *iUnknown, const char *buff); BOOL (*AsyncTimeCall)(IUnknown *iUnknown); BOOL (*SyncCall)(IUnknown *iUnknown, struct Payload *payload); BOOL (*AsyncCallBack)(IUnknown *iUnknown, const char *buff, IOwner notify, INotifyFunc handler); } DemoFeatureApi; ``` - 初始化IServerProxy对象: ``` static DemoFeature g_example = { SERVER_IPROXY_IMPL_BEGIN, .Invoke = Invoke, .AsyncCall = AsyncCall, .AsyncTimeCall = AsyncTimeCall, .SyncCall = SyncCall, .AsyncCallBack = AsyncCallBack, IPROXY_END, }; ``` - 实现Invoke函数来处理Ipc消息: ``` static int32 Invoke(IServerProxy *iProxy, int funcId, void *origin, IpcIo *req, IpcIo *reply) { DemoFeatureApi *api = (DemoFeatureApi *)iProxy; BOOL ret; size_t len = 0; switch (funcId) { case ID_ASYNCALL: ret = api->AsyncCall((IUnknown *)iProxy, (char *)IpcIoPopString(req, &len)); IpcIoPushBool(reply, ret); break; case ID_ASYNTIMECALL: ret = api->AsyncTimeCall((IUnknown *)iProxy); IpcIoPushBool(reply, ret); break; case ID_SYNCCALL: { struct Payload payload; payload.id = IpcIoPopInt32(req); payload.value = IpcIoPopInt32(req); payload.name = (char *)IpcIoPopString(req, &len); ret = api->SyncCall((IUnknown *)iProxy, &payload); IpcIoPushString(reply, ret ? "TRUE" : "FALSE"); } break; case ID_ASYNCCALLBACK: { // convert to sync proxy IpcIoPushString(reply, "Yes, you did!"); IpcIoPushBool(reply, TRUE); } break; default: IpcIoPushBool(reply, FALSE); break; } return EC_SUCCESS; } ``` - 注册接口:与进程内接口注册一致 ``` SAMGR_GetInstance()->RegisterFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE, GET_IUNKNOWN(g_example)); ``` ## 调用跨进程间服务 - 获取跨进程服务的对外接口: ``` IClientProxy *demoApi = NULL; IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE); if (iUnknown == NULL) { return NULL; } int result = iUnknown->QueryInterface(iUnknown, CLIENT_PROXY_VER, (void **)&demoApi); if (result != 0 || demoApi == NULL) { return NULL; } ``` - 调用Ipc消息接口: ``` IpcIo request;char data[250]; IpcIoInit(&request, data, sizeof(data), 0); demoApi->Invoke(demoApi, 0, &request, NULL, NULL); ``` - 释放接口: ``` int32 ref = demoApi->Release((IUnknown *)demoApi); ``` ## 开发跨进程间服务调用客户端代理 - 定义IPC接口客户端代理: ``` typedef struct DemoClientProxy { INHERIT_CLIENT_IPROXY; BOOL (*AsyncCall)(IUnknown *iUnknown, const char *buff); BOOL (*AsyncTimeCall)(IUnknown *iUnknown); BOOL (*SyncCall)(IUnknown *iUnknown, struct Payload *payload); BOOL (*AsyncCallBack)(IUnknown *iUnknown, const char *buff, IOwner notify, INotifyFunc handler); } DemoClientProxy; typedef struct DemoClientEntry { INHERIT_IUNKNOWNENTRY(DemoClientProxy); } DemoClientEntry; ``` - 实现客户端代理封装Ipc消息接口: ``` static BOOL AsyncCall(IUnknown *iUnknown, const char *buff) { DemoClientProxy *proxy = (DemoClientProxy *)iUnknown; IpcIo request; char data[MAX_DATA_LEN]; IpcIoInit(&request, data, MAX_DATA_LEN, 0); IpcIoPushString(&request, buff); int ret = proxy->Invoke((IClientProxy *)proxy, ID_ASYNCALL, &request, NULL, NULL); return ret == EC_SUCCESS; } static BOOL AsyncTimeCall(IUnknown *iUnknown) { DemoClientProxy *proxy = (DemoClientProxy *)iUnknown; IpcIo request; char data[MAX_DATA_LEN]; IpcIoInit(&request, data, MAX_DATA_LEN, 0); int ret = proxy->Invoke((IClientProxy *)proxy, ID_ASYNTIMECALL, &request, NULL, NULL); return ret == EC_SUCCESS; } static int Callback(IOwner owner, int code, IpcIo *reply) { size_t len = 0; return strcpy_s(owner, MAX_DATA_LEN, (char *)IpcIoPopString(reply, &len)); } static BOOL SyncCall(IUnknown *iUnknown, struct Payload *payload) { DemoClientProxy *proxy = (DemoClientProxy *)iUnknown; IpcIo request; char data[MAX_DATA_LEN]; IpcIoInit(&request, data, MAX_DATA_LEN, 0); IpcIoPushInt32(&request, payload->id); IpcIoPushInt32(&request, payload->value); IpcIoPushString(&request, payload->name); int ret = proxy->Invoke((IClientProxy *)proxy, ID_SYNCCALL, &request, data, Callback); data[MAX_DATA_LEN - 1] = 0; HILOG_INFO(HILOG_MODULE_APP, "[TID:0x%lx]Remote response is %s!", pthread_self(), data); return ret == EC_SUCCESS; } struct CurrentNotify { IOwner notify; INotifyFunc handler; }; static int CurrentCallback(IOwner owner, int code, IpcIo *reply) { struct CurrentNotify *notify = (struct CurrentNotify *)owner; size_t len = 0; char *response = (char *)IpcIoPopString(reply, &len); HILOG_INFO(HILOG_MODULE_APP, "[TID:0x%lx]Notify Remote response is %s!", pthread_self(), response); notify->handler(notify->notify, response); return EC_SUCCESS; } static BOOL AsyncCallBack(IUnknown *iUnknown, const char *buff, IOwner notify, INotifyFunc handler) { struct CurrentNotify owner = {notify, handler}; DemoClientProxy *proxy = (DemoClientProxy *)iUnknown; IpcIo request; char data[MAX_DATA_LEN]; IpcIoInit(&request, data, MAX_DATA_LEN, 0); IpcIoPushString(&request, buff); int ret = proxy->Invoke((IClientProxy *)proxy, ID_ASYNCCALLBACK, &request, &owner, CurrentCallback); return ret == EC_SUCCESS; } ``` - 实现客户端代理的工厂方法: ``` void *DEMO_CreatClient(const char *service, const char *feature, uint32 size) { (void)service; (void)feature; uint32 len = size + sizeof(DemoClientEntry); uint8 *client = malloc(len); (void)memset_s(client, len, 0, len); DemoClientEntry *entry = (DemoClientEntry *)&client[size]; entry->ver = ((uint16)CLIENT_PROXY_VER | (uint16)DEFAULT_VERSION); entry->ref = 1; entry->iUnknown.QueryInterface = IUNKNOWN_QueryInterface; entry->iUnknown.AddRef = IUNKNOWN_AddRef; entry->iUnknown.Release = IUNKNOWN_Release; entry->iUnknown.Invoke = NULL; entry->iUnknown.AsyncCall = AsyncCall; entry->iUnknown.AsyncTimeCall = AsyncTimeCall; entry->iUnknown.SyncCall = SyncCall; entry->iUnknown.AsyncCallBack = AsyncCallBack; return client; } void DEMO_DestroyClient(const char *service, const char *feature, void *iproxy) { free(iproxy); } ``` - 将客户端代理的工厂方法注册到SAMGR: ``` SAMGR_RegisterFactory(EXAMPLE_SERVICE, EXAMPLE_FEATURE, DEMO_CreatClient, DEMO_DestroyClient); ``` - 获取跨进程服务的对外接口: ``` DemoClientProxy *demoApi = NULL; IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE); if (iUnknown == NULL) { return NULL; } int result = iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void **)&demoApi); if (result != 0 || demoApi == NULL) { return NULL; } ``` - 调用跨进程服务的客户端代理接口: ``` if (demoApi->AsyncCallBack == NULL) { return NULL; } demoApi->AsyncCallBack((IUnknown *)demoApi, "I wanna async call callback good result!", NULL, AsyncHandler); ``` - 释放接口: ``` int32 ref = demoApi->Release((IUnknown *)demoApi); ``` ## 涉及仓 **[分布式任务调度子系统](zh-cn_topic_0000001115719369.md)** [samgr\_lite](https://gitee.com/openharmony/distributedschedule_services_samgr_lite)