系统服务框架子系统

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

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

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

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

    面向服务的架构:

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

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

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

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

    系统服务框架子系统 - 图1

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

    目录

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

    约束

    系统服务开发框架统一使用C开发。

    同进程内服务间调用统一使用IUnknown接口对外象,消息接口统一由IUnknown接口传递给本服务。

    服务名和功能名必需使用常量字符串且长度小于16个字节。

    M核:系统依赖上bootstrap服务,在系统启动函数中调用HOS_SystemInit()函数。

    A核:系统依赖samgr库,在main函数中调用SAMGR_Bootstrap()函数。

    • 继承并重新定义服务:

    • 实现服务的生命周期函数:

      1. {
      2. return EXAMPLE_SERVICE;
      3. }
      4. static BOOL Initialize(Service *service, Identity identity)
      5. {
      6. ExampleService *example = (ExampleService *)service;
      7. // 保存服务的唯一身份标识,用来自己的IUnknown接口对服务发消息时使用。
      8. example->identity = identity;
      9. return TRUE;
      10. }
      11. static BOOL MessageHandle(Service *service, Request *msg)
      12. {
      13. ExampleService *example = (ExampleService *)service;
      14. switch (msg->msgId) {
      15. case MSG_SYNC:
      16. // 业务处理
      17. break;
      18. default:break;
      19. }
      20. return FALSE;
      21. }
      22. static TaskConfig GetTaskConfig(Service *service)
      23. {
      24. TaskConfig config = {LEVEL_HIGH, PRI_BELOW_NORMAL,
      25. 0x800, 20, SHARED_TASK};
      26. return config;
      27. }
    • 创建服务对象:

      1. static ExampleService g_example = {
      2. .GetName = GetName,
      3. .Initialize = Initialize,
      4. .MessageHandle = MessageHandle,
      5. .GetTaskConfig = GetTaskConfig,
      6. SERVER_IPROXY_IMPL_BEGIN,
      7. .Invoke = NULL,
      8. .SyncCall = SyncCall,
      9. IPROXY_END,
      10. };
    • 向SAMGR注册服务及接口:

      1. static void Init(void)
      2. {
      3. SAMGR_GetInstance()->RegisterService((Service *)&g_example);
      4. SAMGR_GetInstance()->RegisterDefaultFeatureApi(EXAMPLE_SERVICE, GET_IUNKNOWN(g_example));
      5. }
    • 定义服务的初始化入口:

      1. SYSEX_SERVICE_INIT(Init);

    开发服务的子功能

    • 继承并重新定义功能:

      1. typedef struct DemoFeature {
      2. INHERIT_FEATURE;
      3. INHERIT_IUNKNOWNENTRY(DemoApi);
      4. Identity identity;
      5. Service *parent;
      6. } DemoFeature;
    • 实现功能的生命周期函数:

      1. static const char *FEATURE_GetName(Feature *feature)
      2. {
      3. return EXAMPLE_FEATURE;
      4. }
      5. static void FEATURE_OnInitialize(Feature *feature, Service *parent, Identity identity)
      6. {
      7. DemoFeature *demoFeature = (DemoFeature *)feature;
      8. demoFeature->identity = identity;
      9. demoFeature->parent = parent;
      10. }
      11. static void FEATURE_OnStop(Feature *feature, Identity identity)
      12. {
      13. g_example.identity.queueId = NULL;
      14. g_example.identity.featureId = -1;
      15. g_example.identity.serviceId = -1;
      16. }
      17. static BOOL FEATURE_OnMessage(Feature *feature, Request *request)
      18. {
      19. if (request->msgId == MSG_PROC) {
      20. Response response = {.data = "Yes, you did!", .len = 0};
      21. SAMGR_SendResponse(request, &response);
      22. return TRUE;
      23. } else {
      24. if (request->msgId == MSG_TIME_PROC) {
      25. LOS_Msleep(WAIT_FEATURE_PROC * 10);
      26. if (request->msgValue) {
      27. SAMGR_PrintServices();
      28. } else {
      29. SAMGR_PrintOperations();
      30. }
      31. AsyncTimeCall(GET_IUNKNOWN(g_example));
      32. return FALSE;
      33. }
      34. }
      35. return FALSE;
      36. }
    • 创建功能对象:

      1. static DemoFeature g_example = {
      2. .GetName = FEATURE_GetName,
      3. .OnInitialize = FEATURE_OnInitialize,
      4. .OnMessage = FEATURE_OnMessage,
      5. DEFAULT_IUNKNOWN_ENTRY_BEGIN,
      6. .AsyncCall = AsyncCall,
      7. .AsyncTimeCall = AsyncTimeCall,
      8. .SyncCall = SyncCall,
      9. .AsyncCallBack = AsyncCallBack,
      10. DEFAULT_IUNKNOWN_ENTRY_END,
      11. .identity = {-1, -1, NULL},
      12. };
      1. static void Init(void){
      2. SAMGR_GetInstance()->RegisterFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE, GET_IUNKNOWN(g_example));
      3. }
    • 定义功能的初始化入口:

      1. SYSEX_FEATURE_INIT(Init);

    开发进程内对外接口

    • 定义IUnknown接口:

    • 定义IUnknown的引用对象:

      1. typedef struct DemoRefApi {
      2. INHERIT_IUNKNOWNENTRY(DemoApi);
      3. } DemoRefApi;
    • 初始化接口对象:

      1. static DemoRefApi api = {
      2. DEFAULT_IUNKNOWN_ENTRY_BEGIN,
      3. .AsyncCall = AsyncCall,
      4. .AsyncTimeCall = AsyncTimeCall,
      5. .SyncCall = SyncCall,
      6. .AsyncCallBack = AsyncCallBack,
      7. DEFAULT_IUNKNOWN_ENTRY_END,
      8. };
    • 注册服务接口:

      1. SAMGR_GetInstance()->RegisterFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE, GET_IUNKNOWN(api));
    • 获取服务的对外接口:

      1. DemoApi *demoApi = NULL;
      2. IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE);
      3. if (iUnknown == NULL) {
      4. return NULL;
      5. }
      6. int result = iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void **)&demoApi);
      7. if (result != 0 || demoApi == NULL) {
      8. return NULL;
      9. }
    • 接口调用:

      1. if (demoApi->AsyncCallBack == NULL) {
      2. return NULL;
      3. }
      4. demoApi->AsyncCallBack((IUnknown *)demoApi, "I wanna async call callback good result!", AsyncHandler);
    • 释放接口:

      1. int32 ref = demoApi->Release((IUnknown *)demoApi);

    开发跨进程间对外接口

    • 继承IServerProxy替代继承IUnknown:INHERIT_SERVER_IPROXY

      1. typedef struct DemoFeatureApi {
      2. INHERIT_SERVER_IPROXY;
      3. BOOL (*AsyncCall)(IUnknown *iUnknown, const char *buff);
      4. BOOL (*AsyncTimeCall)(IUnknown *iUnknown);
      5. BOOL (*SyncCall)(IUnknown *iUnknown, struct Payload *payload);
      6. BOOL (*AsyncCallBack)(IUnknown *iUnknown, const char *buff, IOwner notify, INotifyFunc handler);
      7. } DemoFeatureApi;
    • 初始化IServerProxy的Invoke函数:

      1. static DemoFeature g_example = {
      2. SERVER_IPROXY_IMPL_BEGIN,
      3. .Invoke = Invoke,
      4. .AsyncCall = AsyncCall,
      5. .AsyncTimeCall = AsyncTimeCall,
      6. .SyncCall = SyncCall,
      7. .AsyncCallBack = AsyncCallBack,
      8. IPROXY_END,
      9. };
    • 实现Invoke函数来处理Ipc消息:

      1. static int32 Invoke(IServerProxy *iProxy, int funcId, void *origin, IpcIo *req, IpcIo *reply)
      2. {
      3. DemoFeatureApi *api = (DemoFeatureApi *)iProxy;
      4. BOOL ret;
      5. size_t len = 0;
      6. switch (funcId) {
      7. case ID_ASYNCALL:
      8. ret = api->AsyncCall((IUnknown *)iProxy, (char *)IpcIoPopString(req, &len));
      9. IpcIoPushBool(reply, ret);
      10. break;
      11. case ID_ASYNTIMECALL:
      12. ret = api->AsyncTimeCall((IUnknown *)iProxy);
      13. IpcIoPushBool(reply, ret);
      14. break;
      15. case ID_SYNCCALL: {
      16. struct Payload payload;
      17. payload.id = IpcIoPopInt32(req);
      18. payload.value = IpcIoPopInt32(req);
      19. payload.name = (char *)IpcIoPopString(req, &len);
      20. ret = api->SyncCall((IUnknown *)iProxy, &payload);
      21. IpcIoPushString(reply, ret ? "TRUE" : "FALSE");
      22. }
      23. break;
      24. case ID_ASYNCCALLBACK: { // convert to sync proxy
      25. IpcIoPushString(reply, "Yes, you did!");
      26. IpcIoPushBool(reply, TRUE);
      27. }
      28. break;
      29. default:
      30. IpcIoPushBool(reply, FALSE);
      31. break;
      32. }
      33. return EC_SUCCESS;
      34. }
    • 注册接口:与进程内接口注册一致

    调用跨进程间服务

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

      1. IClientProxy *demoApi = NULL;
      2. IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE);
      3. if (iUnknown == NULL) {
      4. return NULL;
      5. }
      6. int result = iUnknown->QueryInterface(iUnknown, CLIENT_PROXY_VER, (void **)&demoApi);
      7. if (result != 0 || demoApi == NULL) {
      8. return NULL;
      9. }
    • 调用Ipc消息接口:

      1. IpcIo request;char data[250];
      2. IpcIoInit(&request, data, sizeof(data), 0);
      3. demoApi->Invoke(demoApi, 0, &request, NULL, NULL);
    • 释放接口:

      1. int32 ref = demoApi->Release((IUnknown *)demoApi);
    • 定义IPC接口客户端代理:

      1. INHERIT_CLIENT_IPROXY;
      2. BOOL (*AsyncCall)(IUnknown *iUnknown, const char *buff);
      3. BOOL (*AsyncTimeCall)(IUnknown *iUnknown);
      4. BOOL (*SyncCall)(IUnknown *iUnknown, struct Payload *payload);
      5. BOOL (*AsyncCallBack)(IUnknown *iUnknown, const char *buff, IOwner notify, INotifyFunc handler);
      6. } DemoClientProxy;
      7. typedef struct DemoClientEntry {
      8. INHERIT_IUNKNOWNENTRY(DemoClientProxy);
      9. } DemoClientEntry;
    • 实现客户端代理封装Ipc消息接口:

      1. static BOOL AsyncCall(IUnknown *iUnknown, const char *buff)
      2. DemoClientProxy *proxy = (DemoClientProxy *)iUnknown;
      3. IpcIo request;
      4. char data[MAX_DATA_LEN];
      5. IpcIoInit(&request, data, MAX_DATA_LEN, 0);
      6. IpcIoPushString(&request, buff);
      7. int ret = proxy->Invoke((IClientProxy *)proxy, ID_ASYNCALL, &request, NULL, NULL);
      8. return ret == EC_SUCCESS;
      9. }
      10. static BOOL AsyncTimeCall(IUnknown *iUnknown)
      11. {
      12. DemoClientProxy *proxy = (DemoClientProxy *)iUnknown;
      13. IpcIo request;
      14. char data[MAX_DATA_LEN];
      15. IpcIoInit(&request, data, MAX_DATA_LEN, 0);
      16. int ret = proxy->Invoke((IClientProxy *)proxy, ID_ASYNTIMECALL, &request, NULL, NULL);
      17. return ret == EC_SUCCESS;
      18. }
      19. static int Callback(IOwner owner, int code, IpcIo *reply)
      20. {
      21. size_t len = 0;
      22. return strcpy_s(owner, MAX_DATA_LEN, (char *)IpcIoPopString(reply, &len));
      23. }
      24. static BOOL SyncCall(IUnknown *iUnknown, struct Payload *payload)
      25. {
      26. DemoClientProxy *proxy = (DemoClientProxy *)iUnknown;
      27. IpcIo request;
      28. char data[MAX_DATA_LEN];
      29. IpcIoInit(&request, data, MAX_DATA_LEN, 0);
      30. IpcIoPushInt32(&request, payload->id);
      31. IpcIoPushInt32(&request, payload->value);
      32. IpcIoPushString(&request, payload->name);
      33. int ret = proxy->Invoke((IClientProxy *)proxy, ID_SYNCCALL, &request, data, Callback);
      34. data[MAX_DATA_LEN - 1] = 0;
      35. HILOG_INFO(HILOG_MODULE_APP, "[TID:0x%lx]Remote response is %s!", pthread_self(), data);
      36. return ret == EC_SUCCESS;
      37. }
      38. struct CurrentNotify {
      39. IOwner notify;
      40. INotifyFunc handler;
      41. };
      42. static int CurrentCallback(IOwner owner, int code, IpcIo *reply)
      43. {
      44. struct CurrentNotify *notify = (struct CurrentNotify *)owner;
      45. size_t len = 0;
      46. char *response = (char *)IpcIoPopString(reply, &len);
      47. HILOG_INFO(HILOG_MODULE_APP, "[TID:0x%lx]Notify Remote response is %s!", pthread_self(), response);
      48. notify->handler(notify->notify, response);
      49. return EC_SUCCESS;
      50. }
      51. static BOOL AsyncCallBack(IUnknown *iUnknown, const char *buff, IOwner notify, INotifyFunc handler)
      52. {
      53. struct CurrentNotify owner = {notify, handler};
      54. DemoClientProxy *proxy = (DemoClientProxy *)iUnknown;
      55. IpcIo request;
      56. char data[MAX_DATA_LEN];
      57. IpcIoInit(&request, data, MAX_DATA_LEN, 0);
      58. IpcIoPushString(&request, buff);
      59. int ret = proxy->Invoke((IClientProxy *)proxy, ID_ASYNCCALLBACK, &request, &owner, CurrentCallback);
      60. return ret == EC_SUCCESS;
      61. }
    • 实现客户端代理的工厂方法:

      1. void *DEMO_CreatClient(const char *service, const char *feature, uint32 size)
      2. {
      3. (void)service;
      4. (void)feature;
      5. uint32 len = size + sizeof(DemoClientEntry);
      6. uint8 *client = malloc(len);
      7. (void)memset_s(client, len, 0, len);
      8. DemoClientEntry *entry = (DemoClientEntry *)&client[size];
      9. entry->ver = ((uint16)CLIENT_PROXY_VER | (uint16)DEFAULT_VERSION);
      10. entry->ref = 1;
      11. entry->iUnknown.QueryInterface = IUNKNOWN_QueryInterface;
      12. entry->iUnknown.AddRef = IUNKNOWN_AddRef;
      13. entry->iUnknown.Release = IUNKNOWN_Release;
      14. entry->iUnknown.Invoke = NULL;
      15. entry->iUnknown.AsyncCall = AsyncCall;
      16. entry->iUnknown.AsyncTimeCall = AsyncTimeCall;
      17. entry->iUnknown.SyncCall = SyncCall;
      18. entry->iUnknown.AsyncCallBack = AsyncCallBack;
      19. return client;
      20. }
      21. void DEMO_DestroyClient(const char *service, const char *feature, void *iproxy)
      22. {
      23. free(iproxy);
      24. }
    • 将客户端代理的工厂方法注册到SAMGR:

      1. SAMGR_RegisterFactory(EXAMPLE_SERVICE, EXAMPLE_FEATURE, DEMO_CreatClient, DEMO_DestroyClient);
    • 获取跨进程服务的对外接口:

      1. DemoClientProxy *demoApi = NULL;
      2. IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE);
      3. if (iUnknown == NULL) {
      4. return NULL;
      5. }
      6. int result = iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void **)&demoApi);
      7. if (result != 0 || demoApi == NULL) {
      8. return NULL;
      9. }
    • 调用跨进程服务的客户端代理接口:

      1. if (demoApi->AsyncCallBack == NULL) {
      2. return NULL;
      3. }
    • 释放接口:

    涉及仓

    distributedschedule_interfaces_innerkits_samgr_lite