19c6d7c21Sopenharmony_ci# samgr_lite 29c6d7c21Sopenharmony_ci 39c6d7c21Sopenharmony_ci## Introduction 49c6d7c21Sopenharmony_ci 59c6d7c21Sopenharmony_ciDue to limited platform resources, a unified system ability framework is provided to harmonize differences of hardware architectures (for example, RISC-V, Cortex-M, and Cortex-A), platform resources, and running modes. Two types of hardware platforms (M- and A-core) are defined. 69c6d7c21Sopenharmony_ci 79c6d7c21Sopenharmony_ci- M-core: hardware platforms with Cortex-M or equivalent processing capabilities. The system memory is generally less than 512 KB. There is only a lightweight file system that can be used in limited scenarios, or no file system at all. M-core platforms comply with the Cortex Microcontroller Software Interface Standard (CMSIS). 89c6d7c21Sopenharmony_ci- A-core: hardware platforms with Cortex-A or equivalent processing capabilities. The system memory is greater than 512 KB. There is a comprehensive file system for storing a large amount of data. A-core platforms comply with the Portable Operating System Interface (POSIX) specifications. 99c6d7c21Sopenharmony_ci 109c6d7c21Sopenharmony_ciThis service-oriented system ability framework enables you to develop services, features, and external APIs, and implement multi-service process sharing and service invoking for inter-process communication (IPC). Where: 119c6d7c21Sopenharmony_ci 129c6d7c21Sopenharmony_ci- M core provides services, features, external APIs, and multi-service process sharing development. 139c6d7c21Sopenharmony_ci- In addition to the capabilities provided by M-core, A-core provides capabilities such as IPC service invoking, permission control for IPC service invoking, and IPC service API development. 149c6d7c21Sopenharmony_ci 159c6d7c21Sopenharmony_ci## System Architecture 169c6d7c21Sopenharmony_ci 179c6d7c21Sopenharmony_ciFigure 1 Service-oriented architecture 189c6d7c21Sopenharmony_ci 199c6d7c21Sopenharmony_ci 209c6d7c21Sopenharmony_ci 219c6d7c21Sopenharmony_ci 229c6d7c21Sopenharmony_ci- Provider: a service provider that provides capabilities (external APIs) for the system. 239c6d7c21Sopenharmony_ci- Consumer: a service consumer that invokes the features (external APIs) provided by the service. 249c6d7c21Sopenharmony_ci- Samgr: an agency that manages capabilities provided by providers and helps consumers discover providers' capabilities. 259c6d7c21Sopenharmony_ci 269c6d7c21Sopenharmony_ci**Figure 2** Main objects of the system ability framework 279c6d7c21Sopenharmony_ci 289c6d7c21Sopenharmony_ci 299c6d7c21Sopenharmony_ci 309c6d7c21Sopenharmony_ci- SamgrLite: provides service registration and discovery. 319c6d7c21Sopenharmony_ci- Service: implements lifecycle APIs of the service during service development. 329c6d7c21Sopenharmony_ci- Feature: implements lifecycle APIs of the feature during feature development. 339c6d7c21Sopenharmony_ci- IUnknown: implements external APIs for services or features based on **IUnknown**. 349c6d7c21Sopenharmony_ci- IClientProxy: implements the consumer's proxy to send messages during IPC invoking. 359c6d7c21Sopenharmony_ci- IServerProxy: implements the provider's proxy during IPC invoking, which needs to be implemented by developers. 369c6d7c21Sopenharmony_ci 379c6d7c21Sopenharmony_ci## Directory Structure 389c6d7c21Sopenharmony_ci 399c6d7c21Sopenharmony_ci**Figure 1** Structure of the source code directory of the system ability framework 409c6d7c21Sopenharmony_ci 419c6d7c21Sopenharmony_ci| Name | Description | 429c6d7c21Sopenharmony_ci| -------------------------------------------------- | -------------------------------------------- | 439c6d7c21Sopenharmony_ci| interfaces/kits/samgr_lite/samgr | External APIs of the M- and A-core system ability frameworks. | 449c6d7c21Sopenharmony_ci| interfaces/kits/samgr_lite/registry | External APIs for service invocation between A-core processes. | 459c6d7c21Sopenharmony_ci| interfaces/kits/samgr_lite/communication/broadcast | External APIs of the event broadcast service within M- and A-core processes. | 469c6d7c21Sopenharmony_ci| services/samgr_lite/samgr/adapter | POSIX and CMSIS interface adaptation layer, which is used to harmonize the differences between the APIs of M- and A-core.| 479c6d7c21Sopenharmony_ci| services/samgr_lite/samgr/registry | Stub functions for M-core service registration and discovery. | 489c6d7c21Sopenharmony_ci| services/samgr_lite/samgr/source | Basic code for the M- and A-core system ability frameworks. | 499c6d7c21Sopenharmony_ci| services/samgr_lite/samgr_client | Registration and discovery for service invocation between A-core processes. | 509c6d7c21Sopenharmony_ci| services/samgr_lite/samgr_server | IPC address management and access control for service invocation between A-core processes. | 519c6d7c21Sopenharmony_ci| services/samgr_lite/samgr_endpoint | Packet Rx/Tx management for A-core IPC. | 529c6d7c21Sopenharmony_ci| services/samgr_lite/communication/broadcast | Event broadcast service for M- and A-core processes. | 539c6d7c21Sopenharmony_ci 549c6d7c21Sopenharmony_ci## Constraints 559c6d7c21Sopenharmony_ci 569c6d7c21Sopenharmony_ci- The system ability framework is developed using the C programming language. 579c6d7c21Sopenharmony_ci- Services in the same process use **IUnknown** for invoking. Messages are passed to the service through **IUnknown**. 589c6d7c21Sopenharmony_ci- The service name and feature name must be constant strings and the length must be less than 16 bytes. 599c6d7c21Sopenharmony_ci- More-core depends on the Bootstrap service and calls the **OHOS_SystemInit()** function in the system startup function. 609c6d7c21Sopenharmony_ci- A-core depends on the Samgr library and calls the **SAMGR_Bootstrap()** function in the **main** function. 619c6d7c21Sopenharmony_ci 629c6d7c21Sopenharmony_ci## Developing a Service 639c6d7c21Sopenharmony_ci 649c6d7c21Sopenharmony_ci- Inherit and redefine a service. 659c6d7c21Sopenharmony_ci 669c6d7c21Sopenharmony_ci ``` 679c6d7c21Sopenharmony_ci typedef struct ExampleService { 689c6d7c21Sopenharmony_ci INHERIT_SERVICE; 699c6d7c21Sopenharmony_ci INHERIT_IUNKNOWNENTRY(DefaultFeatureApi); 709c6d7c21Sopenharmony_ci Identity identity; 719c6d7c21Sopenharmony_ci } ExampleService; 729c6d7c21Sopenharmony_ci ``` 739c6d7c21Sopenharmony_ci 749c6d7c21Sopenharmony_ci- Implement the lifecycle function of the service. 759c6d7c21Sopenharmony_ci 769c6d7c21Sopenharmony_ci ``` 779c6d7c21Sopenharmony_ci static const char *GetName(Service *service) 789c6d7c21Sopenharmony_ci { 799c6d7c21Sopenharmony_ci return EXAMPLE_SERVICE; 809c6d7c21Sopenharmony_ci } 819c6d7c21Sopenharmony_ci 829c6d7c21Sopenharmony_ci static BOOL Initialize(Service *service, Identity identity) 839c6d7c21Sopenharmony_ci { 849c6d7c21Sopenharmony_ci ExampleService *example = (ExampleService *)service; 859c6d7c21Sopenharmony_ci // Save the unique ID of the service, which is used when IUnknown is used to send messages to the service. 869c6d7c21Sopenharmony_ci example->identity = identity; 879c6d7c21Sopenharmony_ci return TRUE; 889c6d7c21Sopenharmony_ci } 899c6d7c21Sopenharmony_ci static BOOL MessageHandle(Service *service, Request *msg) 909c6d7c21Sopenharmony_ci { 919c6d7c21Sopenharmony_ci ExampleService *example = (ExampleService *)service; 929c6d7c21Sopenharmony_ci switch (msg->msgId) { 939c6d7c21Sopenharmony_ci case MSG_SYNC: 949c6d7c21Sopenharmony_ci // Process the service. 959c6d7c21Sopenharmony_ci break; 969c6d7c21Sopenharmony_ci default:break; 979c6d7c21Sopenharmony_ci } 989c6d7c21Sopenharmony_ci return FALSE; 999c6d7c21Sopenharmony_ci } 1009c6d7c21Sopenharmony_ci static TaskConfig GetTaskConfig(Service *service) 1019c6d7c21Sopenharmony_ci { 1029c6d7c21Sopenharmony_ci TaskConfig config = {LEVEL_HIGH, PRI_BELOW_NORMAL, 1039c6d7c21Sopenharmony_ci 0x800, 20, SHARED_TASK}; 1049c6d7c21Sopenharmony_ci return config; 1059c6d7c21Sopenharmony_ci } 1069c6d7c21Sopenharmony_ci ``` 1079c6d7c21Sopenharmony_ci 1089c6d7c21Sopenharmony_ci- Create a service object. 1099c6d7c21Sopenharmony_ci 1109c6d7c21Sopenharmony_ci ``` 1119c6d7c21Sopenharmony_ci static ExampleService g_example = { 1129c6d7c21Sopenharmony_ci .GetName = GetName, 1139c6d7c21Sopenharmony_ci .Initialize = Initialize, 1149c6d7c21Sopenharmony_ci .MessageHandle = MessageHandle, 1159c6d7c21Sopenharmony_ci .GetTaskConfig = GetTaskConfig, 1169c6d7c21Sopenharmony_ci SERVER_IPROXY_IMPL_BEGIN, 1179c6d7c21Sopenharmony_ci .Invoke = NULL, 1189c6d7c21Sopenharmony_ci .SyncCall = SyncCall, 1199c6d7c21Sopenharmony_ci IPROXY_END, 1209c6d7c21Sopenharmony_ci }; 1219c6d7c21Sopenharmony_ci ``` 1229c6d7c21Sopenharmony_ci 1239c6d7c21Sopenharmony_ci- Register the service and API with Samgr. 1249c6d7c21Sopenharmony_ci 1259c6d7c21Sopenharmony_ci ``` 1269c6d7c21Sopenharmony_ci static void Init(void) 1279c6d7c21Sopenharmony_ci { 1289c6d7c21Sopenharmony_ci SAMGR_GetInstance()->RegisterService((Service *)&g_example); 1299c6d7c21Sopenharmony_ci SAMGR_GetInstance()->RegisterDefaultFeatureApi(EXAMPLE_SERVICE, GET_IUNKNOWN(g_example)); 1309c6d7c21Sopenharmony_ci } 1319c6d7c21Sopenharmony_ci ``` 1329c6d7c21Sopenharmony_ci 1339c6d7c21Sopenharmony_ci- Define the initializer of the service. 1349c6d7c21Sopenharmony_ci 1359c6d7c21Sopenharmony_ci ``` 1369c6d7c21Sopenharmony_ci SYSEX_SERVICE_INIT(Init); 1379c6d7c21Sopenharmony_ci 1389c6d7c21Sopenharmony_ci ``` 1399c6d7c21Sopenharmony_ci 1409c6d7c21Sopenharmony_ci 1419c6d7c21Sopenharmony_ci## Developing a Feature of a Service 1429c6d7c21Sopenharmony_ci 1439c6d7c21Sopenharmony_ci- Inherit and redefine a feature. 1449c6d7c21Sopenharmony_ci 1459c6d7c21Sopenharmony_ci ``` 1469c6d7c21Sopenharmony_ci typedef struct DemoFeature { 1479c6d7c21Sopenharmony_ci INHERIT_FEATURE; 1489c6d7c21Sopenharmony_ci INHERIT_IUNKNOWNENTRY(DemoApi); 1499c6d7c21Sopenharmony_ci Identity identity; 1509c6d7c21Sopenharmony_ci Service *parent; 1519c6d7c21Sopenharmony_ci } DemoFeature; 1529c6d7c21Sopenharmony_ci ``` 1539c6d7c21Sopenharmony_ci 1549c6d7c21Sopenharmony_ci- Implement the lifecycle function of the feature. 1559c6d7c21Sopenharmony_ci 1569c6d7c21Sopenharmony_ci ``` 1579c6d7c21Sopenharmony_ci static const char *FEATURE_GetName(Feature *feature) 1589c6d7c21Sopenharmony_ci { 1599c6d7c21Sopenharmony_ci return EXAMPLE_FEATURE; 1609c6d7c21Sopenharmony_ci } 1619c6d7c21Sopenharmony_ci 1629c6d7c21Sopenharmony_ci static void FEATURE_OnInitialize(Feature *feature, Service *parent, Identity identity) 1639c6d7c21Sopenharmony_ci { 1649c6d7c21Sopenharmony_ci DemoFeature *demoFeature = (DemoFeature *)feature; 1659c6d7c21Sopenharmony_ci demoFeature->identity = identity; 1669c6d7c21Sopenharmony_ci demoFeature->parent = parent; 1679c6d7c21Sopenharmony_ci } 1689c6d7c21Sopenharmony_ci 1699c6d7c21Sopenharmony_ci static void FEATURE_OnStop(Feature *feature, Identity identity) 1709c6d7c21Sopenharmony_ci { 1719c6d7c21Sopenharmony_ci g_example.identity.queueId = NULL; 1729c6d7c21Sopenharmony_ci g_example.identity.featureId = -1; 1739c6d7c21Sopenharmony_ci g_example.identity.serviceId = -1; 1749c6d7c21Sopenharmony_ci } 1759c6d7c21Sopenharmony_ci 1769c6d7c21Sopenharmony_ci static BOOL FEATURE_OnMessage(Feature *feature, Request *request) 1779c6d7c21Sopenharmony_ci { 1789c6d7c21Sopenharmony_ci if (request->msgId == MSG_PROC) { 1799c6d7c21Sopenharmony_ci Response response = {.data = "Yes, you did!", .len = 0}; 1809c6d7c21Sopenharmony_ci SAMGR_SendResponse(request, &response); 1819c6d7c21Sopenharmony_ci return TRUE; 1829c6d7c21Sopenharmony_ci } else { 1839c6d7c21Sopenharmony_ci if (request->msgId == MSG_TIME_PROC) { 1849c6d7c21Sopenharmony_ci LOS_Msleep(WAIT_FEATURE_PROC * 10); 1859c6d7c21Sopenharmony_ci if (request->msgValue) { 1869c6d7c21Sopenharmony_ci SAMGR_PrintServices(); 1879c6d7c21Sopenharmony_ci } else { 1889c6d7c21Sopenharmony_ci SAMGR_PrintOperations(); 1899c6d7c21Sopenharmony_ci } 1909c6d7c21Sopenharmony_ci AsyncTimeCall(GET_IUNKNOWN(g_example)); 1919c6d7c21Sopenharmony_ci return FALSE; 1929c6d7c21Sopenharmony_ci } 1939c6d7c21Sopenharmony_ci } 1949c6d7c21Sopenharmony_ci return FALSE; 1959c6d7c21Sopenharmony_ci } 1969c6d7c21Sopenharmony_ci ``` 1979c6d7c21Sopenharmony_ci 1989c6d7c21Sopenharmony_ci- Create a feature object. 1999c6d7c21Sopenharmony_ci 2009c6d7c21Sopenharmony_ci ``` 2019c6d7c21Sopenharmony_ci static DemoFeature g_example = { 2029c6d7c21Sopenharmony_ci .GetName = FEATURE_GetName, 2039c6d7c21Sopenharmony_ci .OnInitialize = FEATURE_OnInitialize, 2049c6d7c21Sopenharmony_ci .OnStop = FEATURE_OnStop, 2059c6d7c21Sopenharmony_ci .OnMessage = FEATURE_OnMessage, 2069c6d7c21Sopenharmony_ci DEFAULT_IUNKNOWN_ENTRY_BEGIN, 2079c6d7c21Sopenharmony_ci .AsyncCall = AsyncCall, 2089c6d7c21Sopenharmony_ci .AsyncTimeCall = AsyncTimeCall, 2099c6d7c21Sopenharmony_ci .SyncCall = SyncCall, 2109c6d7c21Sopenharmony_ci .AsyncCallBack = AsyncCallBack, 2119c6d7c21Sopenharmony_ci DEFAULT_IUNKNOWN_ENTRY_END, 2129c6d7c21Sopenharmony_ci .identity = {-1, -1, NULL}, 2139c6d7c21Sopenharmony_ci }; 2149c6d7c21Sopenharmony_ci ``` 2159c6d7c21Sopenharmony_ci 2169c6d7c21Sopenharmony_ci- Register the feature and API with Samgr. 2179c6d7c21Sopenharmony_ci 2189c6d7c21Sopenharmony_ci ``` 2199c6d7c21Sopenharmony_ci static void Init(void){ 2209c6d7c21Sopenharmony_ci SAMGR_GetInstance()->RegisterFeature(EXAMPLE_SERVICE, (Feature *)&g_example); 2219c6d7c21Sopenharmony_ci SAMGR_GetInstance()->RegisterFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE, GET_IUNKNOWN(g_example)); 2229c6d7c21Sopenharmony_ci } 2239c6d7c21Sopenharmony_ci ``` 2249c6d7c21Sopenharmony_ci 2259c6d7c21Sopenharmony_ci- Define the initializer of the feature. 2269c6d7c21Sopenharmony_ci 2279c6d7c21Sopenharmony_ci ``` 2289c6d7c21Sopenharmony_ci SYSEX_FEATURE_INIT(Init); 2299c6d7c21Sopenharmony_ci 2309c6d7c21Sopenharmony_ci ``` 2319c6d7c21Sopenharmony_ci 2329c6d7c21Sopenharmony_ci 2339c6d7c21Sopenharmony_ci## Developing an External API for Intra-Process Communication 2349c6d7c21Sopenharmony_ci 2359c6d7c21Sopenharmony_ci- Define the **IUnknown** API. 2369c6d7c21Sopenharmony_ci 2379c6d7c21Sopenharmony_ci ``` 2389c6d7c21Sopenharmony_ci typedef struct DemoApi { 2399c6d7c21Sopenharmony_ci INHERIT_IUNKNOWN; 2409c6d7c21Sopenharmony_ci BOOL (*AsyncCall)(IUnknown *iUnknown, const char *buff); 2419c6d7c21Sopenharmony_ci BOOL (*AsyncTimeCall)(IUnknown *iUnknown); 2429c6d7c21Sopenharmony_ci BOOL (*SyncCall)(IUnknown *iUnknown, struct Payload *payload); 2439c6d7c21Sopenharmony_ci BOOL (*AsyncCallBack)(IUnknown *iUnknown, const char *buff, Handler handler); 2449c6d7c21Sopenharmony_ci } DemoApi; 2459c6d7c21Sopenharmony_ci ``` 2469c6d7c21Sopenharmony_ci 2479c6d7c21Sopenharmony_ci- Define the reference object of **IUnknown**. 2489c6d7c21Sopenharmony_ci 2499c6d7c21Sopenharmony_ci ``` 2509c6d7c21Sopenharmony_ci typedef struct DemoRefApi { 2519c6d7c21Sopenharmony_ci INHERIT_IUNKNOWNENTRY(DemoApi); 2529c6d7c21Sopenharmony_ci } DemoRefApi; 2539c6d7c21Sopenharmony_ci ``` 2549c6d7c21Sopenharmony_ci 2559c6d7c21Sopenharmony_ci- Initialize the object of **IUnknown**. 2569c6d7c21Sopenharmony_ci 2579c6d7c21Sopenharmony_ci ``` 2589c6d7c21Sopenharmony_ci static DemoRefApi api = { 2599c6d7c21Sopenharmony_ci DEFAULT_IUNKNOWN_ENTRY_BEGIN, 2609c6d7c21Sopenharmony_ci .AsyncCall = AsyncCall, 2619c6d7c21Sopenharmony_ci .AsyncTimeCall = AsyncTimeCall, 2629c6d7c21Sopenharmony_ci .SyncCall = SyncCall, 2639c6d7c21Sopenharmony_ci .AsyncCallBack = AsyncCallBack, 2649c6d7c21Sopenharmony_ci DEFAULT_IUNKNOWN_ENTRY_END, 2659c6d7c21Sopenharmony_ci }; 2669c6d7c21Sopenharmony_ci ``` 2679c6d7c21Sopenharmony_ci 2689c6d7c21Sopenharmony_ci- Register the feature API. 2699c6d7c21Sopenharmony_ci 2709c6d7c21Sopenharmony_ci ``` 2719c6d7c21Sopenharmony_ci SAMGR_GetInstance()->RegisterFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE, GET_IUNKNOWN(api)); 2729c6d7c21Sopenharmony_ci 2739c6d7c21Sopenharmony_ci ``` 2749c6d7c21Sopenharmony_ci 2759c6d7c21Sopenharmony_ci 2769c6d7c21Sopenharmony_ci## Invoking a Service in the Same Process 2779c6d7c21Sopenharmony_ci 2789c6d7c21Sopenharmony_ci- Obtain the external API of the service. 2799c6d7c21Sopenharmony_ci 2809c6d7c21Sopenharmony_ci ``` 2819c6d7c21Sopenharmony_ci DemoApi *demoApi = NULL; 2829c6d7c21Sopenharmony_ci IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE); 2839c6d7c21Sopenharmony_ci if (iUnknown == NULL) { 2849c6d7c21Sopenharmony_ci return NULL; 2859c6d7c21Sopenharmony_ci } 2869c6d7c21Sopenharmony_ci int result = iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void **)&demoApi); 2879c6d7c21Sopenharmony_ci if (result != 0 || demoApi == NULL) { 2889c6d7c21Sopenharmony_ci return NULL; 2899c6d7c21Sopenharmony_ci } 2909c6d7c21Sopenharmony_ci ``` 2919c6d7c21Sopenharmony_ci 2929c6d7c21Sopenharmony_ci- Call the API. 2939c6d7c21Sopenharmony_ci 2949c6d7c21Sopenharmony_ci ``` 2959c6d7c21Sopenharmony_ci if (demoApi->AsyncCallBack == NULL) { 2969c6d7c21Sopenharmony_ci return NULL; 2979c6d7c21Sopenharmony_ci } 2989c6d7c21Sopenharmony_ci demoApi->AsyncCallBack((IUnknown *)demoApi, "I wanna async call callback good result!", AsyncHandler); 2999c6d7c21Sopenharmony_ci ``` 3009c6d7c21Sopenharmony_ci 3019c6d7c21Sopenharmony_ci- Release the API. 3029c6d7c21Sopenharmony_ci 3039c6d7c21Sopenharmony_ci ``` 3049c6d7c21Sopenharmony_ci int32 ref = demoApi->Release((IUnknown *)demoApi); 3059c6d7c21Sopenharmony_ci 3069c6d7c21Sopenharmony_ci ``` 3079c6d7c21Sopenharmony_ci 3089c6d7c21Sopenharmony_ci 3099c6d7c21Sopenharmony_ci## Developing an External API for IPC 3109c6d7c21Sopenharmony_ci 3119c6d7c21Sopenharmony_ci- Inherit **IServerProxy** to replace **IUnknown**: INHERIT\_SERVER\_IPROXY 3129c6d7c21Sopenharmony_ci 3139c6d7c21Sopenharmony_ci ``` 3149c6d7c21Sopenharmony_ci typedef struct DemoFeatureApi { 3159c6d7c21Sopenharmony_ci INHERIT_SERVER_IPROXY; 3169c6d7c21Sopenharmony_ci BOOL (*AsyncCall)(IUnknown *iUnknown, const char *buff); 3179c6d7c21Sopenharmony_ci BOOL (*AsyncTimeCall)(IUnknown *iUnknown); 3189c6d7c21Sopenharmony_ci BOOL (*SyncCall)(IUnknown *iUnknown, struct Payload *payload); 3199c6d7c21Sopenharmony_ci BOOL (*AsyncCallBack)(IUnknown *iUnknown, const char *buff, IOwner notify, INotifyFunc handler); 3209c6d7c21Sopenharmony_ci } DemoFeatureApi; 3219c6d7c21Sopenharmony_ci ``` 3229c6d7c21Sopenharmony_ci 3239c6d7c21Sopenharmony_ci- Initialize the **IServerProxy** object. 3249c6d7c21Sopenharmony_ci 3259c6d7c21Sopenharmony_ci ``` 3269c6d7c21Sopenharmony_ci static DemoFeature g_example = { 3279c6d7c21Sopenharmony_ci SERVER_IPROXY_IMPL_BEGIN, 3289c6d7c21Sopenharmony_ci .Invoke = Invoke, 3299c6d7c21Sopenharmony_ci .AsyncCall = AsyncCall, 3309c6d7c21Sopenharmony_ci .AsyncTimeCall = AsyncTimeCall, 3319c6d7c21Sopenharmony_ci .SyncCall = SyncCall, 3329c6d7c21Sopenharmony_ci .AsyncCallBack = AsyncCallBack, 3339c6d7c21Sopenharmony_ci IPROXY_END, 3349c6d7c21Sopenharmony_ci }; 3359c6d7c21Sopenharmony_ci ``` 3369c6d7c21Sopenharmony_ci 3379c6d7c21Sopenharmony_ci- Implement the **Invoke** function to process IPC messages. 3389c6d7c21Sopenharmony_ci 3399c6d7c21Sopenharmony_ci ``` 3409c6d7c21Sopenharmony_ci static int32 Invoke(IServerProxy *iProxy, int funcId, void *origin, IpcIo *req, IpcIo *reply) 3419c6d7c21Sopenharmony_ci { 3429c6d7c21Sopenharmony_ci DemoFeatureApi *api = (DemoFeatureApi *)iProxy; 3439c6d7c21Sopenharmony_ci BOOL ret; 3449c6d7c21Sopenharmony_ci size_t len = 0; 3459c6d7c21Sopenharmony_ci switch (funcId) { 3469c6d7c21Sopenharmony_ci case ID_ASYNCALL: 3479c6d7c21Sopenharmony_ci ret = api->AsyncCall((IUnknown *)iProxy, (char *)IpcIoPopString(req, &len)); 3489c6d7c21Sopenharmony_ci IpcIoPushBool(reply, ret); 3499c6d7c21Sopenharmony_ci break; 3509c6d7c21Sopenharmony_ci case ID_ASYNTIMECALL: 3519c6d7c21Sopenharmony_ci ret = api->AsyncTimeCall((IUnknown *)iProxy); 3529c6d7c21Sopenharmony_ci IpcIoPushBool(reply, ret); 3539c6d7c21Sopenharmony_ci break; 3549c6d7c21Sopenharmony_ci case ID_SYNCCALL: { 3559c6d7c21Sopenharmony_ci struct Payload payload; 3569c6d7c21Sopenharmony_ci payload.id = IpcIoPopInt32(req); 3579c6d7c21Sopenharmony_ci payload.value = IpcIoPopInt32(req); 3589c6d7c21Sopenharmony_ci payload.name = (char *)IpcIoPopString(req, &len); 3599c6d7c21Sopenharmony_ci ret = api->SyncCall((IUnknown *)iProxy, &payload); 3609c6d7c21Sopenharmony_ci IpcIoPushString(reply, ret ? "TRUE" : "FALSE"); 3619c6d7c21Sopenharmony_ci } 3629c6d7c21Sopenharmony_ci break; 3639c6d7c21Sopenharmony_ci case ID_ASYNCCALLBACK: { // convert to sync proxy 3649c6d7c21Sopenharmony_ci IpcIoPushString(reply, "Yes, you did!"); 3659c6d7c21Sopenharmony_ci IpcIoPushBool(reply, TRUE); 3669c6d7c21Sopenharmony_ci } 3679c6d7c21Sopenharmony_ci break; 3689c6d7c21Sopenharmony_ci default: 3699c6d7c21Sopenharmony_ci IpcIoPushBool(reply, FALSE); 3709c6d7c21Sopenharmony_ci break; 3719c6d7c21Sopenharmony_ci } 3729c6d7c21Sopenharmony_ci return EC_SUCCESS; 3739c6d7c21Sopenharmony_ci } 3749c6d7c21Sopenharmony_ci ``` 3759c6d7c21Sopenharmony_ci 3769c6d7c21Sopenharmony_ci- Register the API. This step is same as the API registration for intra-process communication. 3779c6d7c21Sopenharmony_ci 3789c6d7c21Sopenharmony_ci ``` 3799c6d7c21Sopenharmony_ci SAMGR_GetInstance()->RegisterFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE, GET_IUNKNOWN(g_example)); 3809c6d7c21Sopenharmony_ci 3819c6d7c21Sopenharmony_ci ``` 3829c6d7c21Sopenharmony_ci 3839c6d7c21Sopenharmony_ci 3849c6d7c21Sopenharmony_ci## Invoking a Service in Another Process 3859c6d7c21Sopenharmony_ci 3869c6d7c21Sopenharmony_ci- Obtain the external API of the service in another process. 3879c6d7c21Sopenharmony_ci 3889c6d7c21Sopenharmony_ci ``` 3899c6d7c21Sopenharmony_ci IClientProxy *demoApi = NULL; 3909c6d7c21Sopenharmony_ci IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE); 3919c6d7c21Sopenharmony_ci if (iUnknown == NULL) { 3929c6d7c21Sopenharmony_ci return NULL; 3939c6d7c21Sopenharmony_ci } 3949c6d7c21Sopenharmony_ci int result = iUnknown->QueryInterface(iUnknown, CLIENT_PROXY_VER, (void **)&demoApi); 3959c6d7c21Sopenharmony_ci if (result != 0 || demoApi == NULL) { 3969c6d7c21Sopenharmony_ci return NULL; 3979c6d7c21Sopenharmony_ci } 3989c6d7c21Sopenharmony_ci ``` 3999c6d7c21Sopenharmony_ci 4009c6d7c21Sopenharmony_ci- Invoke the API for sending IPC messages. 4019c6d7c21Sopenharmony_ci 4029c6d7c21Sopenharmony_ci ``` 4039c6d7c21Sopenharmony_ci IpcIo request;char data[250]; 4049c6d7c21Sopenharmony_ci IpcIoInit(&request, data, sizeof(data), 0); 4059c6d7c21Sopenharmony_ci demoApi->Invoke(demoApi, 0, &request, NULL, NULL); 4069c6d7c21Sopenharmony_ci ``` 4079c6d7c21Sopenharmony_ci 4089c6d7c21Sopenharmony_ci- Release the API. 4099c6d7c21Sopenharmony_ci 4109c6d7c21Sopenharmony_ci ``` 4119c6d7c21Sopenharmony_ci int32 ref = demoApi->Release((IUnknown *)demoApi); 4129c6d7c21Sopenharmony_ci 4139c6d7c21Sopenharmony_ci ``` 4149c6d7c21Sopenharmony_ci 4159c6d7c21Sopenharmony_ci 4169c6d7c21Sopenharmony_ci## Developing a Client Proxy for Inter-Process Service Invocation 4179c6d7c21Sopenharmony_ci 4189c6d7c21Sopenharmony_ci- Define a client proxy for the IPC API. 4199c6d7c21Sopenharmony_ci 4209c6d7c21Sopenharmony_ci ``` 4219c6d7c21Sopenharmony_ci typedef struct DemoClientProxy { 4229c6d7c21Sopenharmony_ci INHERIT_CLIENT_IPROXY; 4239c6d7c21Sopenharmony_ci BOOL (*AsyncCall)(IUnknown *iUnknown, const char *buff); 4249c6d7c21Sopenharmony_ci BOOL (*AsyncTimeCall)(IUnknown *iUnknown); 4259c6d7c21Sopenharmony_ci BOOL (*SyncCall)(IUnknown *iUnknown, struct Payload *payload); 4269c6d7c21Sopenharmony_ci BOOL (*AsyncCallBack)(IUnknown *iUnknown, const char *buff, IOwner notify, INotifyFunc handler); 4279c6d7c21Sopenharmony_ci } DemoClientProxy; 4289c6d7c21Sopenharmony_ci typedef struct DemoClientEntry { 4299c6d7c21Sopenharmony_ci INHERIT_IUNKNOWNENTRY(DemoClientProxy); 4309c6d7c21Sopenharmony_ci } DemoClientEntry; 4319c6d7c21Sopenharmony_ci ``` 4329c6d7c21Sopenharmony_ci 4339c6d7c21Sopenharmony_ci- Enable the client proxy to encapsulate the IPC message API. 4349c6d7c21Sopenharmony_ci 4359c6d7c21Sopenharmony_ci ``` 4369c6d7c21Sopenharmony_ci static BOOL AsyncCall(IUnknown *iUnknown, const char *buff) 4379c6d7c21Sopenharmony_ci { 4389c6d7c21Sopenharmony_ci DemoClientProxy *proxy = (DemoClientProxy *)iUnknown; 4399c6d7c21Sopenharmony_ci IpcIo request; 4409c6d7c21Sopenharmony_ci char data[MAX_DATA_LEN]; 4419c6d7c21Sopenharmony_ci IpcIoInit(&request, data, MAX_DATA_LEN, 0); 4429c6d7c21Sopenharmony_ci IpcIoPushString(&request, buff); 4439c6d7c21Sopenharmony_ci int ret = proxy->Invoke((IClientProxy *)proxy, ID_ASYNCALL, &request, NULL, NULL); 4449c6d7c21Sopenharmony_ci return ret == EC_SUCCESS; 4459c6d7c21Sopenharmony_ci } 4469c6d7c21Sopenharmony_ci 4479c6d7c21Sopenharmony_ci static BOOL AsyncTimeCall(IUnknown *iUnknown) 4489c6d7c21Sopenharmony_ci { 4499c6d7c21Sopenharmony_ci DemoClientProxy *proxy = (DemoClientProxy *)iUnknown; 4509c6d7c21Sopenharmony_ci IpcIo request; 4519c6d7c21Sopenharmony_ci char data[MAX_DATA_LEN]; 4529c6d7c21Sopenharmony_ci IpcIoInit(&request, data, MAX_DATA_LEN, 0); 4539c6d7c21Sopenharmony_ci int ret = proxy->Invoke((IClientProxy *)proxy, ID_ASYNTIMECALL, &request, NULL, NULL); 4549c6d7c21Sopenharmony_ci return ret == EC_SUCCESS; 4559c6d7c21Sopenharmony_ci } 4569c6d7c21Sopenharmony_ci 4579c6d7c21Sopenharmony_ci static int Callback(IOwner owner, int code, IpcIo *reply) 4589c6d7c21Sopenharmony_ci { 4599c6d7c21Sopenharmony_ci size_t len = 0; 4609c6d7c21Sopenharmony_ci return strcpy_s(owner, MAX_DATA_LEN, (char *)IpcIoPopString(reply, &len)); 4619c6d7c21Sopenharmony_ci } 4629c6d7c21Sopenharmony_ci 4639c6d7c21Sopenharmony_ci static BOOL SyncCall(IUnknown *iUnknown, struct Payload *payload) 4649c6d7c21Sopenharmony_ci { 4659c6d7c21Sopenharmony_ci DemoClientProxy *proxy = (DemoClientProxy *)iUnknown; 4669c6d7c21Sopenharmony_ci IpcIo request; 4679c6d7c21Sopenharmony_ci char data[MAX_DATA_LEN]; 4689c6d7c21Sopenharmony_ci IpcIoInit(&request, data, MAX_DATA_LEN, 0); 4699c6d7c21Sopenharmony_ci IpcIoPushInt32(&request, payload->id); 4709c6d7c21Sopenharmony_ci IpcIoPushInt32(&request, payload->value); 4719c6d7c21Sopenharmony_ci IpcIoPushString(&request, payload->name); 4729c6d7c21Sopenharmony_ci int ret = proxy->Invoke((IClientProxy *)proxy, ID_SYNCCALL, &request, data, Callback); 4739c6d7c21Sopenharmony_ci data[MAX_DATA_LEN - 1] = 0; 4749c6d7c21Sopenharmony_ci HILOG_INFO(HILOG_MODULE_APP, "[TID:0x%lx]Remote response is %s!", pthread_self(), data); 4759c6d7c21Sopenharmony_ci return ret == EC_SUCCESS; 4769c6d7c21Sopenharmony_ci } 4779c6d7c21Sopenharmony_ci 4789c6d7c21Sopenharmony_ci struct CurrentNotify { 4799c6d7c21Sopenharmony_ci IOwner notify; 4809c6d7c21Sopenharmony_ci INotifyFunc handler; 4819c6d7c21Sopenharmony_ci }; 4829c6d7c21Sopenharmony_ci 4839c6d7c21Sopenharmony_ci static int CurrentCallback(IOwner owner, int code, IpcIo *reply) 4849c6d7c21Sopenharmony_ci { 4859c6d7c21Sopenharmony_ci struct CurrentNotify *notify = (struct CurrentNotify *)owner; 4869c6d7c21Sopenharmony_ci size_t len = 0; 4879c6d7c21Sopenharmony_ci char *response = (char *)IpcIoPopString(reply, &len); 4889c6d7c21Sopenharmony_ci HILOG_INFO(HILOG_MODULE_APP, "[TID:0x%lx]Notify Remote response is %s!", pthread_self(), response); 4899c6d7c21Sopenharmony_ci notify->handler(notify->notify, response); 4909c6d7c21Sopenharmony_ci return EC_SUCCESS; 4919c6d7c21Sopenharmony_ci } 4929c6d7c21Sopenharmony_ci 4939c6d7c21Sopenharmony_ci static BOOL AsyncCallBack(IUnknown *iUnknown, const char *buff, IOwner notify, INotifyFunc handler) 4949c6d7c21Sopenharmony_ci { 4959c6d7c21Sopenharmony_ci struct CurrentNotify owner = {notify, handler}; 4969c6d7c21Sopenharmony_ci DemoClientProxy *proxy = (DemoClientProxy *)iUnknown; 4979c6d7c21Sopenharmony_ci IpcIo request; 4989c6d7c21Sopenharmony_ci char data[MAX_DATA_LEN]; 4999c6d7c21Sopenharmony_ci IpcIoInit(&request, data, MAX_DATA_LEN, 0); 5009c6d7c21Sopenharmony_ci IpcIoPushString(&request, buff); 5019c6d7c21Sopenharmony_ci int ret = proxy->Invoke((IClientProxy *)proxy, ID_ASYNCCALLBACK, &request, &owner, CurrentCallback); 5029c6d7c21Sopenharmony_ci return ret == EC_SUCCESS; 5039c6d7c21Sopenharmony_ci } 5049c6d7c21Sopenharmony_ci ``` 5059c6d7c21Sopenharmony_ci 5069c6d7c21Sopenharmony_ci- Implement the factory method for creating the client proxy. 5079c6d7c21Sopenharmony_ci 5089c6d7c21Sopenharmony_ci ``` 5099c6d7c21Sopenharmony_ci void *DEMO_CreatClient(const char *service, const char *feature, uint32 size) 5109c6d7c21Sopenharmony_ci { 5119c6d7c21Sopenharmony_ci (void)service; 5129c6d7c21Sopenharmony_ci (void)feature; 5139c6d7c21Sopenharmony_ci uint32 len = size + sizeof(DemoClientEntry); 5149c6d7c21Sopenharmony_ci uint8 *client = malloc(len); 5159c6d7c21Sopenharmony_ci (void)memset_s(client, len, 0, len); 5169c6d7c21Sopenharmony_ci DemoClientEntry *entry = (DemoClientEntry *)&client[size]; 5179c6d7c21Sopenharmony_ci entry->ver = ((uint16)CLIENT_PROXY_VER | (uint16)DEFAULT_VERSION); 5189c6d7c21Sopenharmony_ci entry->ref = 1; 5199c6d7c21Sopenharmony_ci entry->iUnknown.QueryInterface = IUNKNOWN_QueryInterface; 5209c6d7c21Sopenharmony_ci entry->iUnknown.AddRef = IUNKNOWN_AddRef; 5219c6d7c21Sopenharmony_ci entry->iUnknown.Release = IUNKNOWN_Release; 5229c6d7c21Sopenharmony_ci entry->iUnknown.Invoke = NULL; 5239c6d7c21Sopenharmony_ci entry->iUnknown.AsyncCall = AsyncCall; 5249c6d7c21Sopenharmony_ci entry->iUnknown.AsyncTimeCall = AsyncTimeCall; 5259c6d7c21Sopenharmony_ci entry->iUnknown.SyncCall = SyncCall; 5269c6d7c21Sopenharmony_ci entry->iUnknown.AsyncCallBack = AsyncCallBack; 5279c6d7c21Sopenharmony_ci return client; 5289c6d7c21Sopenharmony_ci } 5299c6d7c21Sopenharmony_ci void DEMO_DestroyClient(const char *service, const char *feature, void *iproxy) 5309c6d7c21Sopenharmony_ci { 5319c6d7c21Sopenharmony_ci free(iproxy); 5329c6d7c21Sopenharmony_ci } 5339c6d7c21Sopenharmony_ci ``` 5349c6d7c21Sopenharmony_ci 5359c6d7c21Sopenharmony_ci- Register the factory method of the client proxy with Samgr. 5369c6d7c21Sopenharmony_ci 5379c6d7c21Sopenharmony_ci ``` 5389c6d7c21Sopenharmony_ci SAMGR_RegisterFactory(EXAMPLE_SERVICE, EXAMPLE_FEATURE, DEMO_CreatClient, DEMO_DestroyClient); 5399c6d7c21Sopenharmony_ci ``` 5409c6d7c21Sopenharmony_ci 5419c6d7c21Sopenharmony_ci- Obtain the external API of the service in another process. 5429c6d7c21Sopenharmony_ci 5439c6d7c21Sopenharmony_ci ``` 5449c6d7c21Sopenharmony_ci DemoClientProxy *demoApi = NULL; 5459c6d7c21Sopenharmony_ci IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE); 5469c6d7c21Sopenharmony_ci if (iUnknown == NULL) { 5479c6d7c21Sopenharmony_ci return NULL; 5489c6d7c21Sopenharmony_ci } 5499c6d7c21Sopenharmony_ci int result = iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void **)&demoApi); 5509c6d7c21Sopenharmony_ci if (result != 0 || demoApi == NULL) { 5519c6d7c21Sopenharmony_ci return NULL; 5529c6d7c21Sopenharmony_ci } 5539c6d7c21Sopenharmony_ci ``` 5549c6d7c21Sopenharmony_ci 5559c6d7c21Sopenharmony_ci- Invoke the client proxy API of the service in another process. 5569c6d7c21Sopenharmony_ci 5579c6d7c21Sopenharmony_ci ``` 5589c6d7c21Sopenharmony_ci if (demoApi->AsyncCallBack == NULL) { 5599c6d7c21Sopenharmony_ci return NULL; 5609c6d7c21Sopenharmony_ci } 5619c6d7c21Sopenharmony_ci demoApi->AsyncCallBack((IUnknown *)demoApi, 5629c6d7c21Sopenharmony_ci "I wanna async call callback good result!", NULL, AsyncHandler); 5639c6d7c21Sopenharmony_ci ``` 5649c6d7c21Sopenharmony_ci 5659c6d7c21Sopenharmony_ci- Release the API. 5669c6d7c21Sopenharmony_ci 5679c6d7c21Sopenharmony_ci ``` 5689c6d7c21Sopenharmony_ci int32 ref = demoApi->Release((IUnknown *)demoApi); 5699c6d7c21Sopenharmony_ci ``` 5709c6d7c21Sopenharmony_ci 5719c6d7c21Sopenharmony_ci 5729c6d7c21Sopenharmony_ci## Repositories Involved 5739c6d7c21Sopenharmony_ci 5749c6d7c21Sopenharmony_ciSamgr 5759c6d7c21Sopenharmony_ci 5769c6d7c21Sopenharmony_ci[**systemabilitymgr\_samgr\_lite**](https://gitee.com/openharmony/systemabilitymgr_samgr_lite) 5779c6d7c21Sopenharmony_ci 5789c6d7c21Sopenharmony_ci[systemabilitymgr\_samgr](https://gitee.com/openharmony/systemabilitymgr_samgr) 5799c6d7c21Sopenharmony_ci 5809c6d7c21Sopenharmony_ci[systemabilitymgr\_safwk](https://gitee.com/openharmony/systemabilitymgr_safwk) 5819c6d7c21Sopenharmony_ci 5829c6d7c21Sopenharmony_ci[systemabilitymgr\_safwk\_lite](https://gitee.com/openharmony/systemabilitymgr_safwk_lite) 583