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