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.h"
17 #include "native_log.h"
18 #include "parameter_parse.h"
19 
20 namespace OHOS::CommonEventManager {
21     const int8_t STR_PTR_TYPE = 5;
22     std::atomic_ullong SubscriberImpl::subscriberID_ = 0;
23 
SubscriberImpl(std::shared_ptr<CommonEventSubscribeInfo> sp,int64_t infoId)24     SubscriberImpl::SubscriberImpl(std::shared_ptr<CommonEventSubscribeInfo> sp, int64_t infoId)
25         : CommonEventSubscriber(*sp)
26     {
27         id_ = ++subscriberID_;
28         LOGI("constructor SubscriberImpl");
29         valid_ = std::make_shared<bool>(false);
30         infoId_ = infoId;
31     }
32 
~SubscriberImpl()33     SubscriberImpl::~SubscriberImpl()
34     {
35         LOGI("destructor SubscriberImpl[%{public}llu]", id_.load());
36         *valid_ = false;
37     }
38 
FreeCCommonEventData(CCommonEventData & cData)39     static void FreeCCommonEventData(CCommonEventData &cData)
40     {
41         FreeCCommonEventDataCharPtr(cData);
42         for (int i = 0; i < cData.parameters.size; i++) {
43             auto ptr = cData.parameters.head[i];
44             free(ptr.key);
45             ptr.key = nullptr;
46             if (ptr.valueType == STR_PTR_TYPE) {
47                 char **value = reinterpret_cast<char **>(ptr.value);
48                 for (int j = 0; j < ptr.size; j++) {
49                     free(value[j]);
50                     value[j] = nullptr;
51                 }
52             }
53             free(ptr.value);
54             ptr.value = nullptr;
55         }
56         free(cData.parameters.head);
57         cData.parameters.head = nullptr;
58     }
59 
OnReceiveEvent(const CommonEventData & data)60     void SubscriberImpl::OnReceiveEvent(const CommonEventData &data)
61     {
62         LOGI("Receive event.")
63         if (valid_ == nullptr || *(valid_) == false) {
64             LOGE("OnReceiveEvent commonEventDataWorkerData or ref is invalid which may be freed before");
65             return;
66         }
67         if (this->IsOrderedCommonEvent()) {
68             LOGI("IsOrderedCommonEvent is true");
69             SetPublishResult(this);
70         }
71         LOGI("Subscribe callback start to run.")
72         CCommonEventData cData;
73         int32_t code = GetCommonEventData(data, cData);
74         if (code == ERR_NO_MEMORY || code == ERR_CES_FAILED) {
75             LOGE("Failed to excute callback: out of memory.");
76             return;
77         }
78         callback_(cData);
79         FreeCCommonEventData(cData);
80     }
81 
GetID()82     unsigned long long SubscriberImpl::GetID()
83     {
84         return id_.load();
85     }
86 
GetSubscribeInfoId()87     int64_t SubscriberImpl::GetSubscribeInfoId()
88     {
89         return infoId_;
90     }
91 
SetSubscriberManagerId(int64_t id)92     void SubscriberImpl::SetSubscriberManagerId(int64_t id)
93     {
94         managerId_ = id;
95     }
96 
GetSubscriberManagerId()97     int64_t SubscriberImpl::GetSubscriberManagerId()
98     {
99         return managerId_;
100     }
101 
SetCallback(const std::function<void (CCommonEventData)> & callback)102     void SubscriberImpl::SetCallback(const std::function<void(CCommonEventData)> &callback)
103     {
104         callback_ = callback;
105         *valid_ = true;
106     }
107 
SubscriberManager(std::shared_ptr<CommonEventSubscribeInfo> info,int64_t infoId)108     SubscriberManager::SubscriberManager(std::shared_ptr<CommonEventSubscribeInfo> info, int64_t infoId)
109     {
110         auto objectInfo = new (std::nothrow) SubscriberImpl(info, infoId);
111         subscriber = std::shared_ptr<SubscriberImpl>(objectInfo);
112     }
113 
~SubscriberManager()114     SubscriberManager::~SubscriberManager()
115     {
116     }
117 
GetSubscriber()118     std::shared_ptr<SubscriberImpl> SubscriberManager::GetSubscriber()
119     {
120         return subscriber;
121     }
122 
GetSubscribeInfoId()123     int64_t SubscriberManager::GetSubscribeInfoId()
124     {
125         return subscriber->GetSubscribeInfoId();
126     }
127 } // namespace OHOS::CommonEventManager