1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "common_event_manager_ffi.h"
17 #include "common_event_constant.h"
18 #include "common_event_manager_impl.h"
19 #include "common_event.h"
20 
21 #include "native_log.h"
22 #include "cj_lambda.h"
23 #include "securec.h"
24 using namespace OHOS::FFI;
25 using CommonEventManagerImpl = OHOS::CommonEventManager::CommonEventManagerImpl;
26 
27 namespace OHOS::CommonEventManager {
28     const int32_t ERR_INVALID_INSTANCE_ID = -1;
29 
30     extern "C"
31     {
CJ_PublishEvent(char * event,int32_t userId)32         int32_t CJ_PublishEvent(char *event, int32_t userId)
33         {
34             return CommonEventManagerImpl::PublishEvent(event, userId);
35         }
36 
CJ_PublishEventWithData(char * event,int32_t userId,CommonEventPublishDataBycj options)37         int32_t CJ_PublishEventWithData(char *event, int32_t userId, CommonEventPublishDataBycj options)
38         {
39             return CommonEventManagerImpl::PublishEventWithData(event, userId, options);
40         }
41 
CJ_SetStaticSubscriberState(bool enable)42         int32_t CJ_SetStaticSubscriberState(bool enable)
43         {
44             return CommonEventManagerImpl::SetStaticSubscriberState(enable);
45         }
46 
CJ_RemoveStickyCommonEvent(char * event)47         int32_t CJ_RemoveStickyCommonEvent(char *event)
48         {
49             return CommonEventManagerImpl::RemoveStickyCommonEvent(event);
50         }
51 
CJ_CreateCommonEventSubscribeInfo(CArrString events)52         int64_t CJ_CreateCommonEventSubscribeInfo(CArrString events)
53         {
54             auto infoPtr = CommonEventManagerImpl::CreateCommonEventSubscribeInfo(events.head, events.size);
55             auto ptr = FFIData::Create<CommonEventSubscribeInfoImpl>(infoPtr);
56             if (!ptr) {
57                 return static_cast<int64_t>(ERR_INVALID_INSTANCE_ID);
58             }
59             return ptr->GetID();
60         }
61 
CJ_CreateSubscriber(int64_t id)62         int64_t CJ_CreateSubscriber(int64_t id)
63         {
64             bool haveId = false;
65             int64_t managerId = GetManagerId(id, haveId);
66             if (haveId) {
67                 return managerId;
68             }
69             auto instance = FFIData::GetData<CommonEventSubscribeInfoImpl>(id);
70             if (!instance) {
71                 LOGE("CommonEventSubscribeInfoImpl instance not exist %{public}" PRId64, id);
72                 return static_cast<int64_t>(ERR_INVALID_INSTANCE_ID);
73             }
74             auto info = instance->GetInfoPtr();
75             auto ptr = FFIData::Create<SubscriberManager>(info, id);
76             if (!ptr) {
77                 return static_cast<int64_t>(ERR_INVALID_INSTANCE_ID);
78             }
79             ptr->GetSubscriber()->SetSubscriberManagerId(ptr->GetID());
80             return ptr->GetID();
81         }
82 
CJ_Subscribe(int64_t id,void (* callbackRef)(const CCommonEventData data))83         int32_t CJ_Subscribe(int64_t id, void (*callbackRef)(const CCommonEventData data))
84         {
85             auto instance = FFIData::GetData<SubscriberManager>(id);
86             if (!instance) {
87                 LOGE("SubscriberManager instance not exist %{public}" PRId64, id);
88                 return ERR_INVALID_INSTANCE_CODE;
89             }
90             auto subscriber = instance->GetSubscriber();
91             auto onChange = [lambda = CJLambda::Create(callbackRef)](const CCommonEventData data) -> void {
92                 lambda(data);
93             };
94             return CommonEventManagerImpl::Subscribe(subscriber, onChange);
95         }
96 
CJ_Unsubscribe(int64_t id)97         int32_t CJ_Unsubscribe(int64_t id)
98         {
99             auto instance = FFIData::GetData<SubscriberManager>(id);
100             if (!instance) {
101                 LOGE("SubscriberManager instance not exist %{public}" PRId64, id);
102                 return ERR_INVALID_INSTANCE_CODE;
103             }
104             return CommonEventManagerImpl::Unsubscribe(instance->GetSubscriber());
105         }
106 
CJ_GetCode(int64_t id)107         RetDataI64 CJ_GetCode(int64_t id)
108         {
109             RetDataI64 ret = {.code = ERR_INVALID_INSTANCE_CODE, .data = 0};
110             auto instance = FFIData::GetData<SubscriberManager>(id);
111             if (!instance) {
112                 LOGE("SubscriberManager instance not exist %{public}" PRId64, id);
113                 return ret;
114             }
115             auto subscriber = instance->GetSubscriber();
116             GetSubscriberCode(subscriber, ret.data);
117             ret.code = NO_ERROR;
118             return ret;
119         }
120 
CJ_SetCode(int64_t id,int32_t code)121         int32_t CJ_SetCode(int64_t id, int32_t code)
122         {
123             auto instance = FFIData::GetData<SubscriberManager>(id);
124             if (!instance) {
125                 LOGE("SubscriberManager instance not exist %{public}" PRId64, id);
126                 return ERR_INVALID_INSTANCE_CODE;
127             }
128             auto subscriber = instance->GetSubscriber();
129             return SetSubscriberCode(subscriber, code);
130         }
131 
CJ_GetData(int64_t id)132         RetDataCString CJ_GetData(int64_t id)
133         {
134             RetDataCString ret = {.code = ERR_INVALID_INSTANCE_CODE, .data = nullptr};
135             auto instance = FFIData::GetData<SubscriberManager>(id);
136             if (!instance) {
137                 LOGE("SubscriberManager instance not exist %{public}" PRId64, id);
138                 return ret;
139             }
140             auto subscriber = instance->GetSubscriber();
141             ret.data = MallocCString(GetSubscriberData(subscriber));
142             if (ret.data == nullptr) {
143                 LOGE("CJ_GetData failed: out of memory.")
144                 ret.code = ERR_NO_MEMORY;
145             } else {
146                 ret.code = NO_ERROR;
147             }
148             return ret;
149         }
150 
CJ_SetData(int64_t id,char * data)151         int32_t CJ_SetData(int64_t id, char *data)
152         {
153             auto instance = FFIData::GetData<SubscriberManager>(id);
154             if (!instance) {
155                 LOGE("SubscriberManager instance not exist %{public}" PRId64, id);
156                 return ERR_INVALID_INSTANCE_CODE;
157             }
158             auto subscriber = instance->GetSubscriber();
159             return SetSubscriberData(subscriber, data);
160         }
161 
CJ_SetCodeAndData(int64_t id,int32_t code,char * data)162         int32_t CJ_SetCodeAndData(int64_t id, int32_t code, char *data)
163         {
164             auto instance = FFIData::GetData<SubscriberManager>(id);
165             if (!instance) {
166                 LOGE("SubscriberManager instance not exist %{public}" PRId64, id);
167                 return ERR_INVALID_INSTANCE_CODE;
168             }
169             auto subscriber = instance->GetSubscriber();
170             return SetSubscriberCodeAndData(subscriber, code, data);
171         }
172 
CJ_IsOrderedCommonEvent(int64_t id)173         RetDataBool CJ_IsOrderedCommonEvent(int64_t id)
174         {
175             RetDataBool ret = {.code = ERR_INVALID_INSTANCE_CODE, .data = false};
176             auto instance = FFIData::GetData<SubscriberManager>(id);
177             if (!instance) {
178                 LOGE("SubscriberManager instance not exist %{public}" PRId64, id);
179                 return ret;
180             }
181             auto subscriber = instance->GetSubscriber();
182             IsCommonEventOrdered(subscriber, ret.data);
183             ret.code = NO_ERROR;
184             return ret;
185         }
186 
CJ_IsStickyCommonEvent(int64_t id)187         RetDataBool CJ_IsStickyCommonEvent(int64_t id)
188         {
189             RetDataBool ret = {.code = ERR_INVALID_INSTANCE_CODE, .data = false};
190             auto instance = FFIData::GetData<SubscriberManager>(id);
191             if (!instance) {
192                 LOGE("SubscriberManager instance not exist %{public}" PRId64, id);
193                 return ret;
194             }
195             auto subscriber = instance->GetSubscriber();
196             IsCommonEventSticky(subscriber, ret.data);
197             ret.code = NO_ERROR;
198             return ret;
199         }
200 
CJ_AbortCommonEvent(int64_t id)201         int32_t CJ_AbortCommonEvent(int64_t id)
202         {
203             auto instance = FFIData::GetData<SubscriberManager>(id);
204             if (!instance) {
205                 LOGE("SubscriberManager instance not exist %{public}" PRId64, id);
206                 return ERR_INVALID_INSTANCE_CODE;
207             }
208             if (!instance->GetSubscriber()->AbortCommonEvent()) {
209                 return ERR_CES_FAILED;
210             }
211             return SUCCESS_CODE;
212         }
213 
CJ_ClearAbortCommonEvent(int64_t id)214         int32_t CJ_ClearAbortCommonEvent(int64_t id)
215         {
216             auto instance = FFIData::GetData<SubscriberManager>(id);
217             if (!instance) {
218                 LOGE("SubscriberManager instance not exist %{public}" PRId64, id);
219                 return ERR_INVALID_INSTANCE_CODE;
220             }
221             if (!instance->GetSubscriber()->ClearAbortCommonEvent()) {
222                 return ERR_CES_FAILED;
223             }
224             return SUCCESS_CODE;
225         }
226 
CJ_GetAbortCommonEvent(int64_t id)227         RetDataBool CJ_GetAbortCommonEvent(int64_t id)
228         {
229             RetDataBool ret = {.code = ERR_INVALID_INSTANCE_CODE, .data = false};
230             auto instance = FFIData::GetData<SubscriberManager>(id);
231             if (!instance) {
232                 LOGE("SubscriberManager instance not exist %{public}" PRId64, id);
233                 return ret;
234             }
235             ret.code = SUCCESS_CODE;
236             ret.data = instance->GetSubscriber()->GetAbortCommonEvent();
237             return ret;
238         }
239 
CJ_GetSubscribeInfo(int64_t id)240         RetDataI64 CJ_GetSubscribeInfo(int64_t id)
241         {
242             RetDataI64 ret = {.code = ERR_INVALID_INSTANCE_ID, .data = 0};
243             auto instance = FFIData::GetData<SubscriberManager>(id);
244             if (!instance) {
245                 LOGE("SubscriberManager instance not exist %{public}" PRId64, id);
246                 return ret;
247             }
248             ret.code = SUCCESS_CODE;
249             ret.data = instance->GetSubscribeInfoId();
250             return ret;
251         }
252 
CJ_FinishCommonEvent(int64_t id)253         int32_t CJ_FinishCommonEvent(int64_t id)
254         {
255             int32_t errorCode = ERR_CES_FAILED;
256             auto instance = FFIData::GetData<SubscriberManager>(id);
257             if (!instance) {
258                 LOGE("SubscriberManager instance not exist %{public}" PRId64, id);
259                 return ERR_INVALID_INSTANCE_ID;
260             }
261             auto subscriber = instance->GetSubscriber();
262             std::shared_ptr<AsyncCommonEventResult> result = GetAsyncResult(subscriber.get());
263             if (result) {
264                 errorCode = result->FinishCommonEvent() ? NO_ERROR : ERR_CES_FAILED;
265             }
266             return errorCode;
267         }
268 
CJ_SetPermission(int64_t id,char * value)269         void CJ_SetPermission(int64_t id, char *value)
270         {
271             auto instance = FFIData::GetData<CommonEventSubscribeInfoImpl>(id);
272             if (!instance) {
273                 LOGE("CommonEventSubscribeInfoImpl instance not exist %{public}" PRId64, id);
274                 return;
275             }
276 
277             return instance->SetPermission(std::string(value));
278         }
279 
CJ_SetDeviceId(int64_t id,const char * value)280         void CJ_SetDeviceId(int64_t id, const char *value)
281         {
282             auto instance = FFIData::GetData<CommonEventSubscribeInfoImpl>(id);
283             if (!instance) {
284                 LOGE("CommonEventSubscribeInfoImpl instance not exist %{public}" PRId64, id);
285                 return;
286             }
287             return instance->SetDeviceId(std::string(value));
288         }
289 
CJ_SetUserId(int64_t id,int32_t value)290         void CJ_SetUserId(int64_t id, int32_t value)
291         {
292             auto instance = FFIData::GetData<CommonEventSubscribeInfoImpl>(id);
293             if (!instance) {
294                 LOGE("CommonEventSubscribeInfoImpl instance not exist %{public}" PRId64, id);
295                 return;
296             }
297             return instance->SetUserId(value);
298         }
299 
CJ_SetPriority(int64_t id,int32_t value)300         void CJ_SetPriority(int64_t id, int32_t value)
301         {
302             auto instance = FFIData::GetData<CommonEventSubscribeInfoImpl>(id);
303             if (!instance) {
304                 LOGE("CommonEventSubscribeInfoImpl instance not exist %{public}" PRId64, id);
305                 return;
306             }
307             return instance->SetPriority(value);
308         }
309 
CJ_SetBundleName(int64_t id,const char * value)310         void CJ_SetBundleName(int64_t id, const char *value)
311         {
312             auto instance = FFIData::GetData<CommonEventSubscribeInfoImpl>(id);
313             if (!instance) {
314                 LOGE("CommonEventSubscribeInfoImpl instance not exist %{public}" PRId64, id);
315                 return;
316             }
317             return instance->SetPublisherBundleName(std::string(value));
318         }
319 
CJ_GetPermission(int64_t id)320         const char *CJ_GetPermission(int64_t id)
321         {
322             auto instance = FFIData::GetData<CommonEventSubscribeInfoImpl>(id);
323             if (!instance) {
324                 LOGE("CJ_GetPermission instance not exist %{public}" PRId64, id);
325                 return nullptr;
326             }
327             auto str = instance->GetPermission();
328             auto ret = MallocCString(str);
329             return ret;
330         }
331 
CJ_GetDeviceId(int64_t id)332         const char *CJ_GetDeviceId(int64_t id)
333         {
334             auto instance = FFIData::GetData<CommonEventSubscribeInfoImpl>(id);
335             if (!instance) {
336                 LOGE("CJ_GetDeviceId instance not exist %{public}" PRId64, id);
337                 return nullptr;
338             }
339             auto str = instance->GetDeviceId();
340             auto ret = MallocCString(str);
341             return ret;
342         }
343 
CJ_GetUserId(int64_t id)344         int32_t CJ_GetUserId(int64_t id)
345         {
346             auto instance = FFIData::GetData<CommonEventSubscribeInfoImpl>(id);
347             if (!instance) {
348                 LOGE("CJ_GetUserId instance not exist %{public}" PRId64, id);
349                 return 0;
350             }
351             return instance->GetUserId();
352         }
353 
CJ_GetPriority(int64_t id)354         int32_t CJ_GetPriority(int64_t id)
355         {
356             auto instance = FFIData::GetData<CommonEventSubscribeInfoImpl>(id);
357             if (!instance) {
358                 LOGE("CJ_GetPriority instance not exist %{public}" PRId64, id);
359                 return 0;
360             }
361             return instance->GetPriority();
362         }
363 
CJ_GetBundleName(int64_t id)364         const char *CJ_GetBundleName(int64_t id)
365         {
366             auto instance = FFIData::GetData<CommonEventSubscribeInfoImpl>(id);
367             if (!instance) {
368                 LOGE("CJ_GetBundleName instance not exist %{public}" PRId64, id);
369                 return nullptr;
370             }
371             auto str = instance->GetPublisherBundleName();
372             auto ret = MallocCString(str);
373             return ret;
374         }
375 
ClearCharPointer(char ** ptr,int count)376         void ClearCharPointer(char** ptr, int count)
377         {
378             for (int i = 0; i < count; i++) {
379                 free(ptr[i]);
380                 ptr[i] = nullptr;
381             }
382         }
383 
VectorToCharPointer(std::vector<std::string> & vec)384         char **VectorToCharPointer(std::vector<std::string> &vec)
385         {
386             char** result = static_cast<char**>(malloc(sizeof(char*) * vec.size()));
387             if (result == nullptr) {
388                 return nullptr;
389             }
390             for (size_t i = 0; i < vec.size(); i++) {
391                 result[i] = MallocCString(vec[i]);
392                 if (result[i] == nullptr) {
393                     ClearCharPointer(result, i);
394                     free(result);
395                     return nullptr;
396                 }
397             }
398             return result;
399         }
400 
CJ_GetEvents(int64_t id)401         CArrString CJ_GetEvents(int64_t id)
402         {
403             auto instance = FFIData::GetData<CommonEventSubscribeInfoImpl>(id);
404             CArrString ret = {.head = nullptr, .size = 0};
405             if (!instance) {
406                 LOGE("CJ_GetEvents instance not exist %{public}" PRId64, id);
407                 return ret;
408             }
409             auto vStr = instance->GetEvents();
410             if (vStr.size() == 0) {
411                 return ret;
412             }
413             ret.head = VectorToCharPointer(vStr);
414             ret.size = static_cast<int64_t>(vStr.size());
415             if (ret.head == nullptr) {
416                 LOGE("Failed to malloc.");
417                 ret.size = 0;
418             }
419             return ret;
420         }
421     }
422 }