• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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