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