OpenHarmony鸿蒙开发( Beta5.0)轻量型系统服务管理部件详解

149 篇文章 1 订阅
149 篇文章 0 订阅

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

  • M核:包含服务开发、服务的子功能开发、对外接口的开发以及多服务共进程的开发框架。
  • A核:在M核能力基础之上,包含了进程间服务调用、进程间服务调用权限控制、进程间服务接口的开发等能力。

开发跨进程间服务调用客户端代理

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

调用跨进程间服务

获取跨进程服务的对外接口:

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

开发跨进程间对外接口

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

调用进程内服务

获取服务的对外接口:

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

开发进程内对外接口

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

开发服务的子功能

继承并重新定义功能:

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

开发服务

继承并重新定义服务:

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

目录

表 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函数。

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

 

SamgrLite:主要提供服务的注册与发现能力。 Service:开发服务时,需要实现的服务的生命周期接口。 Feature:开发功能时,需要实现的功能的生命周期接口。 IUnknown:基于IUnknown开发服务或功能的对外接口。 IClientProxy:IPC调用时,消费者的消息发送代理。 IServerProxy:IPC调用时,开发者需要实现提供者的消息处理接口。

系统架构

图 1 面向服务的架构

 

Provider:服务的提供者,为系统提供能力(对外接口)。 Consumer:服务的消费者,调用服务提供的功能(对外接口)。 Samgr:作为中介者,管理Provider提供的能力,同时帮助Consumer发现Provider的能力。

最后

小编在之前的鸿蒙系统扫盲中,有很多朋友给我留言,有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以有一份实用的鸿蒙(HarmonyOS NEXT)文档用来跟着学习是非常有必要的。 

为了确保高效学习,建议规划清晰的学习路线,涵盖以下关键阶段:

GitCode - 全球开发者的开源社区,开源代码托管平台  希望这一份鸿蒙学习文档能够给大家带来帮助~


鸿蒙(HarmonyOS NEXT)最新学习路线

该路线图包含基础技能、就业必备技能、多媒体技术、六大电商APP、进阶高级技能、实战就业级设备开发,不仅补充了华为官网未涉及的解决方案

路线图适合人群:

IT开发人员:想要拓展职业边界
零基础小白:鸿蒙爱好者,希望从0到1学习,增加一项技能。
技术提升/进阶跳槽:发展瓶颈期,提升职场竞争力,快速掌握鸿蒙技术

2.视频学习教程+学习PDF文档

HarmonyOS Next 最新全套视频教程

  纯血版鸿蒙全套学习文档(面试、文档、全套视频等)       

​​

总结

参与鸿蒙开发,你要先认清适合你的方向,如果是想从事鸿蒙应用开发方向的话,可以参考本文的学习路径,简单来说就是:为了确保高效学习,建议规划清晰的学习路线

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值