1 /*
2 * Copyright (c) 2021-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 "common_event_constant.h"
18 #include "common_event_death_recipient.h"
19 #include "event_log_wrapper.h"
20 #include "hitrace_meter_adapter.h"
21 #include "icommon_event.h"
22 #include "iservice_registry.h"
23 #include "refbase.h"
24 #include "system_ability_definition.h"
25 #include "ces_inner_error_code.h"
26 #include <memory>
27 #include <mutex>
28
29 namespace OHOS {
30 namespace EventFwk {
31 namespace {
32 const int32_t MAX_RETRY_TIME = 30;
33 const int32_t SLEEP_TIME = 1000;
34 }
35
36 std::mutex CommonEvent::instanceMutex_;
37 std::shared_ptr<CommonEvent> CommonEvent::instance_;
38
39 using namespace OHOS::Notification;
40
GetInstance()41 std::shared_ptr<CommonEvent> CommonEvent::GetInstance()
42 {
43 if (instance_ == nullptr) {
44 std::lock_guard<std::mutex> lock(instanceMutex_);
45 if (instance_ == nullptr) {
46 instance_ = std::make_shared<CommonEvent>();
47 }
48 }
49 return instance_;
50 }
51
PublishCommonEvent(const CommonEventData & data,const CommonEventPublishInfo & publishInfo,const std::shared_ptr<CommonEventSubscriber> & subscriber)52 bool CommonEvent::PublishCommonEvent(const CommonEventData &data, const CommonEventPublishInfo &publishInfo,
53 const std::shared_ptr<CommonEventSubscriber> &subscriber)
54 {
55 HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
56 EVENT_LOGD("enter");
57 sptr<IRemoteObject> commonEventListener = nullptr;
58 if (!PublishParameterCheck(data, publishInfo, subscriber, commonEventListener)) {
59 EVENT_LOGE("failed to check publish parameter");
60 return false;
61 }
62 sptr<ICommonEvent> proxy = GetCommonEventProxy();
63 if (!proxy) {
64 EVENT_LOGE("the commonEventProxy is null");
65 return false;
66 }
67 return proxy->PublishCommonEvent(
68 data, publishInfo, commonEventListener, UNDEFINED_USER) == ERR_OK ? true : false;
69 }
70
PublishCommonEventAsUser(const CommonEventData & data,const CommonEventPublishInfo & publishInfo,const std::shared_ptr<CommonEventSubscriber> & subscriber,const int32_t & userId)71 int32_t CommonEvent::PublishCommonEventAsUser(const CommonEventData &data, const CommonEventPublishInfo &publishInfo,
72 const std::shared_ptr<CommonEventSubscriber> &subscriber, const int32_t &userId)
73 {
74 HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
75 EVENT_LOGD("enter");
76 sptr<IRemoteObject> commonEventListener = nullptr;
77 if (!PublishParameterCheck(data, publishInfo, subscriber, commonEventListener)) {
78 EVENT_LOGE("failed to check publish parameter");
79 return ERR_NOTIFICATION_CES_COMMON_PARAM_INVALID;
80 }
81 sptr<ICommonEvent> proxy = GetCommonEventProxy();
82 if (!proxy) {
83 EVENT_LOGE("the commonEventProxy is null");
84 return ERR_NOTIFICATION_CES_COMMON_PARAM_INVALID;
85 }
86 return proxy->PublishCommonEvent(data, publishInfo, commonEventListener, userId);
87 }
88
PublishCommonEvent(const CommonEventData & data,const CommonEventPublishInfo & publishInfo,const std::shared_ptr<CommonEventSubscriber> & subscriber,const uid_t & uid,const int32_t & callerToken)89 bool CommonEvent::PublishCommonEvent(const CommonEventData &data, const CommonEventPublishInfo &publishInfo,
90 const std::shared_ptr<CommonEventSubscriber> &subscriber, const uid_t &uid, const int32_t &callerToken)
91 {
92 HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
93 EVENT_LOGD("enter");
94 sptr<IRemoteObject> commonEventListener = nullptr;
95 if (!PublishParameterCheck(data, publishInfo, subscriber, commonEventListener)) {
96 EVENT_LOGE("failed to check publish parameter");
97 return false;
98 }
99 sptr<ICommonEvent> proxy = GetCommonEventProxy();
100 if (!proxy) {
101 EVENT_LOGE("the commonEventProxy is null");
102 return false;
103 }
104 return proxy->PublishCommonEvent(data, publishInfo, commonEventListener, uid, callerToken, UNDEFINED_USER);
105 }
106
PublishCommonEventAsUser(const CommonEventData & data,const CommonEventPublishInfo & publishInfo,const std::shared_ptr<CommonEventSubscriber> & subscriber,const uid_t & uid,const int32_t & callerToken,const int32_t & userId)107 bool CommonEvent::PublishCommonEventAsUser(const CommonEventData &data, const CommonEventPublishInfo &publishInfo,
108 const std::shared_ptr<CommonEventSubscriber> &subscriber, const uid_t &uid,
109 const int32_t &callerToken, const int32_t &userId)
110 {
111 HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
112 EVENT_LOGD("enter");
113 sptr<IRemoteObject> commonEventListener = nullptr;
114 if (!PublishParameterCheck(data, publishInfo, subscriber, commonEventListener)) {
115 EVENT_LOGE("failed to check publish parameter");
116 return false;
117 }
118 sptr<ICommonEvent> proxy = GetCommonEventProxy();
119 if (!proxy) {
120 EVENT_LOGE("the commonEventProxy is null");
121 return false;
122 }
123 return proxy->PublishCommonEvent(data, publishInfo, commonEventListener, uid, callerToken, userId);
124 }
125
PublishParameterCheck(const CommonEventData & data,const CommonEventPublishInfo & publishInfo,const std::shared_ptr<CommonEventSubscriber> & subscriber,sptr<IRemoteObject> & commonEventListener)126 __attribute__((no_sanitize("cfi"))) bool CommonEvent::PublishParameterCheck(const CommonEventData &data,
127 const CommonEventPublishInfo &publishInfo, const std::shared_ptr<CommonEventSubscriber> &subscriber,
128 sptr<IRemoteObject> &commonEventListener)
129 {
130 EVENT_LOGD("enter");
131 if (data.GetWant().GetAction() == std::string()) {
132 EVENT_LOGE("the commonEventdata action is null");
133 return false;
134 }
135
136 if (!publishInfo.IsOrdered() && (subscriber != nullptr)) {
137 EVENT_LOGE("When publishing unordered events, the subscriber object is not required.");
138 return false;
139 }
140
141 if (subscriber) {
142 if (CreateCommonEventListener(subscriber, commonEventListener) == SUBSCRIBE_FAILED) {
143 EVENT_LOGE("failed to CreateCommonEventListener");
144 return false;
145 }
146 }
147
148 return true;
149 }
150
SubscribeCommonEvent(const std::shared_ptr<CommonEventSubscriber> & subscriber)151 __attribute__((no_sanitize("cfi"))) int32_t CommonEvent::SubscribeCommonEvent(
152 const std::shared_ptr<CommonEventSubscriber> &subscriber)
153 {
154 HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
155 EVENT_LOGD("enter");
156
157 if (subscriber == nullptr) {
158 EVENT_LOGE("the subscriber is null");
159 return ERR_NOTIFICATION_CES_COMMON_PARAM_INVALID;
160 }
161
162 if (subscriber->GetSubscribeInfo().GetMatchingSkills().CountEvent() == 0) {
163 EVENT_LOGE("the subscriber has no event");
164 return ERR_NOTIFICATION_CES_COMMON_PARAM_INVALID;
165 }
166 sptr<ICommonEvent> proxy = GetCommonEventProxy();
167 if (!proxy) {
168 EVENT_LOGE("the commonEventProxy is null");
169 return ERR_NOTIFICATION_CESM_ERROR;
170 }
171 DelayedSingleton<CommonEventDeathRecipient>::GetInstance()->SubscribeSAManager();
172 sptr<IRemoteObject> commonEventListener = nullptr;
173 uint8_t subscribeState = CreateCommonEventListener(subscriber, commonEventListener);
174 if (subscribeState == INITIAL_SUBSCRIPTION) {
175 auto res = proxy->SubscribeCommonEvent(subscriber->GetSubscribeInfo(),
176 commonEventListener, UNDEFINED_INSTANCE_KEY);
177 if (res != ERR_OK) {
178 EVENT_LOGD("subscribe common event failed, remove event listener");
179 std::lock_guard<std::mutex> lock(eventListenersMutex_);
180 auto eventListener = eventListeners_.find(subscriber);
181 if (eventListener != eventListeners_.end()) {
182 eventListeners_.erase(eventListener);
183 }
184 }
185 return res;
186 } else if (subscribeState == ALREADY_SUBSCRIBED) {
187 return ERR_OK;
188 } else {
189 return ERR_NOTIFICATION_CES_COMMON_SYSTEMCAP_NOT_SUPPORT;
190 }
191 }
192
UnSubscribeCommonEvent(const std::shared_ptr<CommonEventSubscriber> & subscriber)193 __attribute__((no_sanitize("cfi"))) int32_t CommonEvent::UnSubscribeCommonEvent(
194 const std::shared_ptr<CommonEventSubscriber> &subscriber)
195 {
196 HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
197 EVENT_LOGD("enter");
198
199 if (subscriber == nullptr) {
200 EVENT_LOGE("the subscriber is null");
201 return ERR_NOTIFICATION_CES_COMMON_PARAM_INVALID;
202 }
203 sptr<ICommonEvent> proxy = GetCommonEventProxy();
204 if (!proxy) {
205 EVENT_LOGE("the commonEventProxy is null");
206 return ERR_NOTIFICATION_CESM_ERROR;
207 }
208 std::lock_guard<std::mutex> lock(eventListenersMutex_);
209 auto eventListener = eventListeners_.find(subscriber);
210 if (eventListener != eventListeners_.end()) {
211 EVENT_LOGD("before UnsubscribeCommonEvent listeners size is %{public}zu", eventListeners_.size());
212 if (proxy->UnsubscribeCommonEvent(eventListener->second->AsObject()) == ERR_OK) {
213 eventListener->second->Stop();
214 eventListeners_.erase(eventListener);
215 return ERR_OK;
216 }
217 return ERR_NOTIFICATION_SEND_ERROR;
218 } else {
219 EVENT_LOGW("No specified subscriber has been registered");
220 }
221
222 return ERR_OK;
223 }
224
GetStickyCommonEvent(const std::string & event,CommonEventData & eventData)225 bool CommonEvent::GetStickyCommonEvent(const std::string &event, CommonEventData &eventData)
226 {
227 EVENT_LOGD("enter");
228
229 if (event.empty()) {
230 EVENT_LOGE("event is empty");
231 return false;
232 }
233 sptr<ICommonEvent> proxy = GetCommonEventProxy();
234 if (!proxy) {
235 EVENT_LOGE("the commonEventProxy is null");
236 return false;
237 }
238 return proxy->GetStickyCommonEvent(event, eventData);
239 }
240
FinishReceiver(const sptr<IRemoteObject> & proxy,const int32_t & code,const std::string & data,const bool & abortEvent)241 bool CommonEvent::FinishReceiver(
242 const sptr<IRemoteObject> &proxy, const int32_t &code, const std::string &data, const bool &abortEvent)
243 {
244 EVENT_LOGD("enter");
245
246 if (proxy == nullptr) {
247 EVENT_LOGE("the proxy is null");
248 return false;
249 }
250 sptr<ICommonEvent> cesProxy = GetCommonEventProxy();
251 if (!cesProxy) {
252 EVENT_LOGE("the commonEventProxy is null");
253 return false;
254 }
255 return cesProxy->FinishReceiver(proxy, code, data, abortEvent);
256 }
257
DumpState(const uint8_t & dumpType,const std::string & event,const int32_t & userId,std::vector<std::string> & state)258 bool CommonEvent::DumpState(const uint8_t &dumpType, const std::string &event, const int32_t &userId,
259 std::vector<std::string> &state)
260 {
261 EVENT_LOGD("enter");
262
263 sptr<ICommonEvent> proxy = GetCommonEventProxy();
264 if (!proxy) {
265 EVENT_LOGE("the commonEventProxy is null");
266 return false;
267 }
268 return proxy->DumpState(dumpType, event, userId, state);
269 }
270
Freeze(const uid_t & uid)271 bool CommonEvent::Freeze(const uid_t &uid)
272 {
273 EVENT_LOGD("enter");
274
275 sptr<ICommonEvent> proxy = GetCommonEventProxy();
276 if (!proxy) {
277 EVENT_LOGE("the commonEventProxy is null");
278 return false;
279 }
280 return proxy->Freeze(uid);
281 }
282
Unfreeze(const uid_t & uid)283 bool CommonEvent::Unfreeze(const uid_t &uid)
284 {
285 EVENT_LOGD("enter");
286
287 sptr<ICommonEvent> proxy = GetCommonEventProxy();
288 if (!proxy) {
289 EVENT_LOGE("the commonEventProxy is null");
290 return false;
291 }
292 return proxy->Unfreeze(uid);
293 }
294
UnfreezeAll()295 bool CommonEvent::UnfreezeAll()
296 {
297 EVENT_LOGD("enter");
298
299 sptr<ICommonEvent> proxy = GetCommonEventProxy();
300 if (!proxy) {
301 EVENT_LOGE("the commonEventProxy is null");
302 return false;
303 }
304 return proxy->UnfreezeAll();
305 }
306
RemoveStickyCommonEvent(const std::string & event)307 int32_t CommonEvent::RemoveStickyCommonEvent(const std::string &event)
308 {
309 EVENT_LOGD("enter");
310
311 sptr<ICommonEvent> proxy = GetCommonEventProxy();
312 if (!proxy) {
313 EVENT_LOGE("the commonEventProxy is null");
314 return ERR_NOTIFICATION_CES_COMMON_PARAM_INVALID;
315 }
316 return proxy->RemoveStickyCommonEvent(event);
317 }
318
SetStaticSubscriberState(bool enable)319 int32_t CommonEvent::SetStaticSubscriberState(bool enable)
320 {
321 EVENT_LOGD("enter");
322 sptr<ICommonEvent> proxy_ = GetCommonEventProxy();
323 if (!proxy_) {
324 EVENT_LOGE("failed to get commonEventProxy");
325 return ERR_NOTIFICATION_CES_COMMON_PARAM_INVALID;
326 }
327 return proxy_->SetStaticSubscriberState(enable);
328 }
329
SetStaticSubscriberState(const std::vector<std::string> & events,bool enable)330 int32_t CommonEvent::SetStaticSubscriberState(const std::vector<std::string> &events, bool enable)
331 {
332 EVENT_LOGD("Called.");
333 sptr<ICommonEvent> proxy_ = GetCommonEventProxy();
334 if (!proxy_) {
335 EVENT_LOGE("Failed to get common event proxy.");
336 return ERR_NOTIFICATION_CES_COMMON_PARAM_INVALID;
337 }
338 return proxy_->SetStaticSubscriberState(events, enable);
339 }
340
SetFreezeStatus(std::set<int> pidList,bool isFreeze)341 bool CommonEvent::SetFreezeStatus(std::set<int> pidList, bool isFreeze)
342 {
343 EVENT_LOGD("enter");
344 sptr<ICommonEvent> proxy_ = GetCommonEventProxy();
345 if (!proxy_) {
346 EVENT_LOGE("failed to get commonEventProxy");
347 return ERR_NOTIFICATION_CES_COMMON_PARAM_INVALID;
348 }
349 return proxy_->SetFreezeStatus(pidList, isFreeze);
350 }
351
GetCommonEventProxy()352 sptr<ICommonEvent> CommonEvent::GetCommonEventProxy()
353 {
354 EVENT_LOGD("enter");
355 sptr<ISystemAbilityManager> systemAbilityManager =
356 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
357 if (!systemAbilityManager) {
358 EVENT_LOGE("Failed to get system ability mgr.");
359 return nullptr;
360 }
361
362 sptr<IRemoteObject> remoteObject = systemAbilityManager->GetSystemAbility(COMMON_EVENT_SERVICE_ID);
363 if (!remoteObject) {
364 EVENT_LOGE("Failed to get COMMON Event Manager.");
365 return nullptr;
366 }
367
368 auto proxy = iface_cast<ICommonEvent>(remoteObject);
369 if (!proxy || !proxy->AsObject()) {
370 EVENT_LOGE("Failed to get COMMON Event Manager's proxy");
371 return nullptr;
372 }
373 return proxy;
374 }
375
CreateCommonEventListener(const std::shared_ptr<CommonEventSubscriber> & subscriber,sptr<IRemoteObject> & commonEventListener)376 uint8_t CommonEvent::CreateCommonEventListener(
377 const std::shared_ptr<CommonEventSubscriber> &subscriber, sptr<IRemoteObject> &commonEventListener)
378 {
379 if (subscriber == nullptr) {
380 EVENT_LOGE("subscriber is null");
381 return SUBSCRIBE_FAILED;
382 }
383
384 std::lock_guard<std::mutex> lock(eventListenersMutex_);
385
386 auto eventListener = eventListeners_.find(subscriber);
387 if (eventListener != eventListeners_.end()) {
388 commonEventListener = eventListener->second->AsObject();
389 EVENT_LOGW("subscriber has common event listener");
390 return ALREADY_SUBSCRIBED;
391 } else {
392 if (eventListeners_.size() == SUBSCRIBER_MAX_SIZE) {
393 EVENT_LOGE("the maximum number of subscriptions has been reached");
394 return SUBSCRIBE_FAILED;
395 }
396
397 sptr<CommonEventListener> listener = new (std::nothrow) CommonEventListener(subscriber);
398 if (!listener) {
399 EVENT_LOGE("the common event listener is null");
400 return SUBSCRIBE_FAILED;
401 }
402 commonEventListener = listener->AsObject();
403 eventListeners_[subscriber] = listener;
404 }
405
406 return INITIAL_SUBSCRIPTION;
407 }
408
Reconnect()409 bool CommonEvent::Reconnect()
410 {
411 EVENT_LOGD("enter");
412 for (int32_t i = 0; i < MAX_RETRY_TIME; i++) {
413 // try to connect ces
414 if (!GetCommonEventProxy()) {
415 // Sleep 1000 milliseconds before reconnect.
416 std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME));
417 EVENT_LOGE("Resubscribe failed, try again.");
418 continue;
419 }
420 return true;
421 }
422
423 return false;
424 }
425
Resubscribe()426 __attribute__((no_sanitize("cfi"))) bool CommonEvent::Resubscribe()
427 {
428 EVENT_LOGD("enter");
429 sptr<ICommonEvent> proxy = GetCommonEventProxy();
430 if (!proxy) {
431 EVENT_LOGE("failed to get commonEventProxy");
432 return false;
433 }
434
435 std::lock_guard<std::mutex> lock(eventListenersMutex_);
436 for (auto it = eventListeners_.begin(); it != eventListeners_.end();) {
437 auto subscriber = it->first;
438 auto listener = it->second;
439 int32_t res = proxy->SubscribeCommonEvent(subscriber->GetSubscribeInfo(),
440 listener, UNDEFINED_INSTANCE_KEY);
441 if (res != ERR_OK) {
442 EVENT_LOGW("subscribe common event failed, remove event listener");
443 it = eventListeners_.erase(it);
444 } else {
445 it++;
446 }
447 }
448 return true;
449 }
450 } // namespace EventFwk
451 } // namespace OHOS
452