鸿蒙OS 系统服务框架子系统


系统服务框架子系统

简介

这个仓库用于存放系统服务框架的代码。由于平台资源有限,且硬件平台多样,因此需要屏蔽不同硬件架构和资源的不同、以及运行形态的不同,提供统一化的系统服务开发框架。根据RISC-V、Cortex-M、Cortex-A不同硬件平台,分为两种硬件平台,以下简称M核、A核。

M核:处理器架构为Cortex-M或同等处理能力的硬件平台,系统内存一般低于512KB,无文件系统或者仅提供一个可有限使用的轻量级文件系统,遵循CMSIS接口规范。

A核:处理器架构为Cortex-A或同等处理能力的硬件平台,内存资源大于512KB,文件系统完善,可存储大量数据,遵循POSIX接口规范。

系统服务框架基于面向服务的架构,提供了服务开发、服务的子功能开发、对外接口的开发、以及多服务共进程、进程间服务调用等开发能力。其中:

M核:包含服务开发、服务的子功能开发、对外接口的开发以及多服务共进程的开发框架。

A核:在M核能力基础之上,包含了进程间服务调用、进程间服务调用权限控制、进程间服务接口的开发等能力。

面向服务的架构:

Provider:服务的提供者,为系统提供能力(对外接口)。

Consumer:服务的消费者,调用服务提供的功能(对外接口)。

Samgr:做为中介者,管理Provider提供的能力,同时帮助Consumer发现Provider的能力。

系统服务开发框架主体对象:

SamgrLite:主要提供服务的注册与发现能力。

Service:开发服务时,需要实现的服务的生命周期接口。

Feature:开发功能时,需要实现的功能的生命周期接口。

IUnknown:基于IUnknown开发服务或功能的对外接口。

IClientProxy:IPC调用时,消费者的消息发送代理。

IServerProxy:IPC调用时,开发者需要实现的,生产者的消息处理代理。

目录

表 1 系统服务框架源代码目录结构

名称描述

interfaces/kits/samgr_lite/samgrM核和A核系统服务框架对外接口定义。

interfaces/kits/samgr_lite/registryA核进程间服务调用的对外接口定义。

interfaces/kits/samgr_lite/communication/broadcastM核和A核进程内事件广播服务的对外接口定义。

services/samgr_lite/samgr/adapterPOSIX和CMSIS接口适配层来屏蔽A核M核接口差异。

services/samgr_lite/samgr/registryM核服务注册发现的桩函数。

services/samgr_lite/samgr/sourceM核和A核系统服务开发框架基础代码。

services/samgr_lite/samgr_clientA核进程间服务调用的注册与发现。

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

services/samgr_lite/samgr_endpointA核IPC通信消息收发包管理。

services/samgr_lite/communication/broadcastM核和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的Invoke函数:

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);

涉及仓

distributedschedule_interfaces_kits_samgr_lite

distributedschedule_services_samgr_lite

你可能感兴趣的:(鸿蒙OS 系统服务框架子系统)