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