1 /*
2 * Copyright (c) 2021 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_listener.h"
17 #include "event_log_wrapper.h"
18 #include "hitrace_meter_adapter.h"
19 #include "ffrt.h"
20
21 namespace OHOS {
22 namespace EventFwk {
23 std::shared_ptr<AppExecFwk::EventRunner> CommonEventListener::commonRunner_ = nullptr;
24 std::atomic<int> ffrtIndex = 0;
25
CommonEventListener(const std::shared_ptr<CommonEventSubscriber> & commonEventSubscriber)26 CommonEventListener::CommonEventListener(const std::shared_ptr<CommonEventSubscriber> &commonEventSubscriber)
27 : commonEventSubscriber_(commonEventSubscriber)
28 {
29 Init();
30 }
31
~CommonEventListener()32 CommonEventListener::~CommonEventListener()
33 {}
34
NotifyEvent(const CommonEventData & commonEventData,const bool & ordered,const bool & sticky)35 void CommonEventListener::NotifyEvent(const CommonEventData &commonEventData, const bool &ordered, const bool &sticky)
36 {
37 HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
38 EVENT_LOGD("enter");
39
40 std::lock_guard<std::mutex> lock(mutex_);
41 if (!IsReady()) {
42 EVENT_LOGE("not ready");
43 return;
44 }
45
46 wptr<CommonEventListener> wp = this;
47 std::function<void()> onReceiveEventFunc = [wp, commonEventData, ordered, sticky] () {
48 sptr<CommonEventListener> sThis = wp.promote();
49 if (sThis == nullptr) {
50 EVENT_LOGE("invalid listener");
51 return;
52 }
53 sThis->OnReceiveEvent(commonEventData, ordered, sticky);
54 };
55
56 if (handler_) {
57 handler_->PostTask(onReceiveEventFunc, "CommonEvent" + commonEventData.GetWant().GetAction());
58 }
59
60 if (listenerQueue_) {
61 static_cast<ffrt::queue*>(listenerQueue_)->submit(onReceiveEventFunc);
62 }
63 }
64
Init()65 __attribute__((no_sanitize("cfi"))) ErrCode CommonEventListener::Init()
66 {
67 EVENT_LOGD("ready to init");
68 std::lock_guard<std::mutex> lock(mutex_);
69 if (!commonEventSubscriber_) {
70 EVENT_LOGE("Failed to init with CommonEventSubscriber nullptr");
71 return ERR_INVALID_OPERATION;
72 }
73 auto threadMode = commonEventSubscriber_->GetSubscribeInfo().GetThreadMode();
74 EVENT_LOGD("thread mode: %{public}d", threadMode);
75 if (threadMode == CommonEventSubscribeInfo::HANDLER) {
76 if (!runner_) {
77 runner_ = EventRunner::GetMainEventRunner();
78 if (!runner_) {
79 EVENT_LOGE("Failed to init due to create runner error");
80 return ERR_INVALID_OPERATION;
81 }
82 }
83 if (!handler_) {
84 handler_ = std::make_shared<EventHandler>(runner_);
85 if (!handler_) {
86 EVENT_LOGE("Failed to init due to create handler error");
87 return ERR_INVALID_OPERATION;
88 }
89 }
90 } else {
91 InitListenerQueue();
92 if (listenerQueue_ == nullptr) {
93 EVENT_LOGE("Failed to init due to create ffrt queue error");
94 return ERR_INVALID_OPERATION;
95 }
96 }
97 return ERR_OK;
98 }
99
GetCommonRunner()100 std::shared_ptr<AppExecFwk::EventRunner> CommonEventListener::GetCommonRunner()
101 {
102 if (CommonEventListener::commonRunner_ == nullptr) {
103 CommonEventListener::commonRunner_ = EventRunner::Create("OS_cesComLstnr");
104 }
105
106 return CommonEventListener::commonRunner_;
107 }
108
InitListenerQueue()109 void CommonEventListener::InitListenerQueue()
110 {
111 if (listenerQueue_ == nullptr) {
112 ffrtIndex.fetch_add(1);
113 std::string id = "ces_queue_" + std::to_string(ffrtIndex.load());
114 listenerQueue_ = static_cast<void*>(new ffrt::queue(id.c_str()));
115 }
116 return;
117 }
118
IsReady()119 bool CommonEventListener::IsReady()
120 {
121 if (!listenerQueue_ && !handler_) {
122 EVENT_LOGE("ffrt queue is not ready");
123 return false;
124 }
125 return true;
126 }
127
OnReceiveEvent(const CommonEventData & commonEventData,const bool & ordered,const bool & sticky)128 __attribute__((no_sanitize("cfi"))) void CommonEventListener::OnReceiveEvent(
129 const CommonEventData &commonEventData, const bool &ordered, const bool &sticky)
130 {
131 HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
132 EVENT_LOGD("enter %{public}s", commonEventData.GetWant().GetAction().c_str());
133
134 int32_t code = commonEventData.GetCode();
135 std::string data = commonEventData.GetData();
136
137 std::shared_ptr<AsyncCommonEventResult> result =
138 std::make_shared<AsyncCommonEventResult>(code, data, ordered, sticky, this);
139 if (result == nullptr) {
140 EVENT_LOGE("Failed to create AsyncCommonEventResult");
141 return;
142 }
143
144 if (!commonEventSubscriber_) {
145 EVENT_LOGE("CommonEventSubscriber ptr is nullptr");
146 return;
147 }
148 commonEventSubscriber_->SetAsyncCommonEventResult(result);
149
150 commonEventSubscriber_->OnReceiveEvent(commonEventData);
151
152 if ((commonEventSubscriber_->GetAsyncCommonEventResult() != nullptr) && ordered) {
153 commonEventSubscriber_->GetAsyncCommonEventResult()->FinishCommonEvent();
154 }
155 EVENT_LOGD("end");
156 }
157
Stop()158 void CommonEventListener::Stop()
159 {
160 EVENT_LOGD("enter");
161 void *queue = nullptr;
162 {
163 std::lock_guard<std::mutex> lock(mutex_);
164 if (listenerQueue_) {
165 queue = listenerQueue_;
166 listenerQueue_ = nullptr;
167 }
168
169 if (handler_) {
170 handler_.reset();
171 }
172
173 if (commonEventSubscriber_ == nullptr) {
174 EVENT_LOGE("commonEventSubscriber_ == nullptr");
175 return;
176 }
177 EVENT_LOGD("event size: %{public}zu",
178 commonEventSubscriber_->GetSubscribeInfo().GetMatchingSkills().CountEvent());
179 if (CommonEventSubscribeInfo::HANDLER == commonEventSubscriber_->GetSubscribeInfo().GetThreadMode()) {
180 EVENT_LOGD("stop listener in HANDLER mode");
181 return;
182 }
183
184 if (runner_) {
185 runner_.reset();
186 }
187 }
188 if (queue) {
189 delete static_cast<ffrt::queue*>(queue);
190 }
191 }
192 } // namespace EventFwk
193 } // namespace OHOS
194