1 /*
2 * Copyright (c) 2021-2022 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_manager_service.h"
17
18 #include "access_token_helper.h"
19 #include "accesstoken_kit.h"
20 #include "bundle_manager_helper.h"
21 #include "common_event_constant.h"
22 #include "datetime_ex.h"
23 #include "event_log_wrapper.h"
24 #include "hitrace_meter.h"
25 #include "ipc_skeleton.h"
26 #include "publish_manager.h"
27 #include "system_ability_definition.h"
28 #include "xcollie/watchdog.h"
29 #include "ces_inner_error_code.h"
30
31 namespace OHOS {
32 namespace EventFwk {
33 using namespace OHOS::Notification;
34
CommonEventManagerService()35 CommonEventManagerService::CommonEventManagerService()
36 : serviceRunningState_(ServiceRunningState::STATE_NOT_START),
37 runner_(nullptr),
38 handler_(nullptr)
39 {
40 EVENT_LOGI("instance created");
41 }
42
~CommonEventManagerService()43 CommonEventManagerService::~CommonEventManagerService()
44 {
45 EVENT_LOGI("instance destroyed");
46 }
47
Init()48 ErrCode CommonEventManagerService::Init()
49 {
50 EVENT_LOGI("ready to init");
51 innerCommonEventManager_ = std::make_shared<InnerCommonEventManager>();
52 if (!innerCommonEventManager_) {
53 EVENT_LOGE("Failed to init without inner service");
54 return ERR_INVALID_OPERATION;
55 }
56
57 runner_ = EventRunner::Create("CesSrvMain");
58 if (!runner_) {
59 EVENT_LOGE("Failed to init due to create runner error");
60 return ERR_INVALID_OPERATION;
61 }
62 handler_ = std::make_shared<EventHandler>(runner_);
63 if (!handler_) {
64 EVENT_LOGE("Failed to init due to create handler error");
65 return ERR_INVALID_OPERATION;
66 }
67 if (handler_->GetEventRunner() != nullptr) {
68 std::string threadName = handler_->GetEventRunner()->GetRunnerThreadName();
69 if (HiviewDFX::Watchdog::GetInstance().AddThread(threadName, handler_) != 0) {
70 EVENT_LOGE("Failed to Add main Thread");
71 }
72 }
73
74 serviceRunningState_ = ServiceRunningState::STATE_RUNNING;
75
76 return ERR_OK;
77 }
78
IsReady() const79 bool CommonEventManagerService::IsReady() const
80 {
81 if (!innerCommonEventManager_) {
82 EVENT_LOGE("innerCommonEventManager is null");
83 return false;
84 }
85
86 if (!handler_) {
87 EVENT_LOGE("handler is null");
88 return false;
89 }
90
91 return true;
92 }
93
PublishCommonEvent(const CommonEventData & event,const CommonEventPublishInfo & publishinfo,const sptr<IRemoteObject> & commonEventListener,const int32_t & userId)94 int32_t CommonEventManagerService::PublishCommonEvent(const CommonEventData &event,
95 const CommonEventPublishInfo &publishinfo, const sptr<IRemoteObject> &commonEventListener,
96 const int32_t &userId)
97 {
98 EVENT_LOGI("enter");
99
100 if (!IsReady()) {
101 EVENT_LOGE("CommonEventManagerService not ready");
102 return ERR_NOTIFICATION_CESM_ERROR;
103 }
104
105 return PublishCommonEventDetailed(event,
106 publishinfo,
107 commonEventListener,
108 IPCSkeleton::GetCallingPid(),
109 IPCSkeleton::GetCallingUid(),
110 IPCSkeleton::GetCallingTokenID(),
111 userId);
112 }
113
PublishCommonEvent(const CommonEventData & event,const CommonEventPublishInfo & publishinfo,const sptr<IRemoteObject> & commonEventListener,const uid_t & uid,const int32_t & callerToken,const int32_t & userId)114 bool CommonEventManagerService::PublishCommonEvent(const CommonEventData &event,
115 const CommonEventPublishInfo &publishinfo, const sptr<IRemoteObject> &commonEventListener, const uid_t &uid,
116 const int32_t &callerToken, const int32_t &userId)
117 {
118 EVENT_LOGI("enter");
119
120 if (!IsReady()) {
121 EVENT_LOGE("CommonEventManagerService not ready");
122 return false;
123 }
124
125 if (!AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID())) {
126 EVENT_LOGE("Only sa can publish common event as proxy.");
127 return false;
128 }
129
130 return PublishCommonEventDetailed(
131 event, publishinfo, commonEventListener, UNDEFINED_PID, uid, callerToken, userId) == ERR_OK ? true : false;
132 }
133
PublishCommonEventDetailed(const CommonEventData & event,const CommonEventPublishInfo & publishinfo,const sptr<IRemoteObject> & commonEventListener,const pid_t & pid,const uid_t & uid,const int32_t & clientToken,const int32_t & userId)134 int32_t CommonEventManagerService::PublishCommonEventDetailed(const CommonEventData &event,
135 const CommonEventPublishInfo &publishinfo, const sptr<IRemoteObject> &commonEventListener, const pid_t &pid,
136 const uid_t &uid, const int32_t &clientToken, const int32_t &userId)
137 {
138 HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
139 EVENT_LOGI("enter");
140
141 EVENT_LOGI("clientToken = %{public}d", clientToken);
142 if (AccessTokenHelper::IsDlpHap(clientToken)) {
143 EVENT_LOGE("DLP hap not allowed to send common event");
144 return ERR_NOTIFICATION_CES_NOT_SA_SYSTEM_APP;
145 }
146 struct tm recordTime = {0};
147 if (!GetSystemCurrentTime(&recordTime)) {
148 EVENT_LOGE("Failed to GetSystemCurrentTime");
149 return ERR_NOTIFICATION_SYS_ERROR;
150 }
151
152 std::string bundleName = DelayedSingleton<BundleManagerHelper>::GetInstance()->GetBundleName(uid);
153
154 if (DelayedSingleton<PublishManager>::GetInstance()->CheckIsFloodAttack(uid)) {
155 EVENT_LOGE("Too many common events have been sent in a short period from %{public}s (pid = %{public}d, uid = "
156 "%{public}d, userId = %{public}d)",
157 bundleName.c_str(),
158 pid,
159 uid,
160 userId);
161 return ERR_NOTIFICATION_CES_COMMON_PARAM_INVALID;
162 }
163
164 std::weak_ptr<InnerCommonEventManager> wp = innerCommonEventManager_;
165 wptr<CommonEventManagerService> weakThis = this;
166 std::function<void()> publishCommonEventFunc = [wp,
167 event,
168 publishinfo,
169 commonEventListener,
170 recordTime,
171 pid,
172 uid,
173 clientToken,
174 userId,
175 bundleName,
176 weakThis] () {
177 std::shared_ptr<InnerCommonEventManager> innerCommonEventManager = wp.lock();
178 if (innerCommonEventManager == nullptr) {
179 EVENT_LOGE("innerCommonEventManager not exist");
180 return;
181 }
182 sptr<CommonEventManagerService> commonEventManagerService = weakThis.promote();
183 if (commonEventManagerService == nullptr) {
184 EVENT_LOGE("CommonEventManager not exist");
185 return;
186 }
187 bool ret = innerCommonEventManager->PublishCommonEvent(event,
188 publishinfo,
189 commonEventListener,
190 recordTime,
191 pid,
192 uid,
193 clientToken,
194 userId,
195 bundleName,
196 commonEventManagerService);
197 if (!ret) {
198 EVENT_LOGE("failed to publish event %{public}s", event.GetWant().GetAction().c_str());
199 }
200 };
201 return handler_->PostTask(publishCommonEventFunc) ? ERR_OK : ERR_NOTIFICATION_CESM_ERROR;
202 }
203
SubscribeCommonEvent(const CommonEventSubscribeInfo & subscribeInfo,const sptr<IRemoteObject> & commonEventListener)204 int32_t CommonEventManagerService::SubscribeCommonEvent(
205 const CommonEventSubscribeInfo &subscribeInfo, const sptr<IRemoteObject> &commonEventListener)
206 {
207 HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
208 EVENT_LOGI("enter");
209
210 if (!IsReady()) {
211 EVENT_LOGE("CommonEventManagerService not ready");
212 return ERR_NOTIFICATION_CES_COMMON_PARAM_INVALID;
213 }
214
215 struct tm recordTime = {0};
216 if (!GetSystemCurrentTime(&recordTime)) {
217 EVENT_LOGE("Failed to GetSystemCurrentTime");
218 return ERR_NOTIFICATION_CES_COMMON_PARAM_INVALID;
219 }
220
221 auto callingUid = IPCSkeleton::GetCallingUid();
222 auto callingPid = IPCSkeleton::GetCallingPid();
223 std::string bundleName = DelayedSingleton<BundleManagerHelper>::GetInstance()->GetBundleName(callingUid);
224 Security::AccessToken::AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID();
225 std::weak_ptr<InnerCommonEventManager> wp = innerCommonEventManager_;
226 std::function<void()> subscribeCommonEventFunc = [wp,
227 subscribeInfo,
228 commonEventListener,
229 recordTime,
230 callingPid,
231 callingUid,
232 callerToken,
233 bundleName] () {
234 std::shared_ptr<InnerCommonEventManager> innerCommonEventManager = wp.lock();
235 if (innerCommonEventManager == nullptr) {
236 EVENT_LOGE("innerCommonEventManager not exist");
237 return;
238 }
239 bool ret = innerCommonEventManager->SubscribeCommonEvent(subscribeInfo,
240 commonEventListener,
241 recordTime,
242 callingPid,
243 callingUid,
244 callerToken,
245 bundleName);
246 if (!ret) {
247 EVENT_LOGE("failed to subscribe event");
248 }
249 };
250 return handler_->PostTask(subscribeCommonEventFunc) ? ERR_OK : ERR_NOTIFICATION_CESM_ERROR;
251 }
252
UnsubscribeCommonEvent(const sptr<IRemoteObject> & commonEventListener)253 int32_t CommonEventManagerService::UnsubscribeCommonEvent(const sptr<IRemoteObject> &commonEventListener)
254 {
255 HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
256 EVENT_LOGI("enter");
257
258 if (!IsReady()) {
259 EVENT_LOGE("CommonEventManagerService not ready");
260 return ERR_NOTIFICATION_CES_COMMON_PARAM_INVALID;
261 }
262
263 std::weak_ptr<InnerCommonEventManager> wp = innerCommonEventManager_;
264 std::function<void()> unsubscribeCommonEventFunc = [wp, commonEventListener] () {
265 std::shared_ptr<InnerCommonEventManager> innerCommonEventManager = wp.lock();
266 if (innerCommonEventManager == nullptr) {
267 EVENT_LOGE("innerCommonEventManager not exist");
268 return;
269 }
270 bool ret = innerCommonEventManager->UnsubscribeCommonEvent(commonEventListener);
271 if (!ret) {
272 EVENT_LOGE("failed to unsubscribe event");
273 }
274 };
275
276 return handler_->PostTask(unsubscribeCommonEventFunc) ? ERR_OK : ERR_NOTIFICATION_CESM_ERROR;
277 }
278
GetStickyCommonEvent(const std::string & event,CommonEventData & eventData)279 bool CommonEventManagerService::GetStickyCommonEvent(const std::string &event, CommonEventData &eventData)
280 {
281 EVENT_LOGI("enter");
282
283 if (!IsReady()) {
284 EVENT_LOGE("CommonEventManagerService not ready");
285 return false;
286 }
287
288 if (event.empty()) {
289 EVENT_LOGE("event is empty");
290 return false;
291 }
292
293 auto callingUid = IPCSkeleton::GetCallingUid();
294 std::string bundleName = DelayedSingleton<BundleManagerHelper>::GetInstance()->GetBundleName(callingUid);
295 const std::string permission = "ohos.permission.COMMONEVENT_STICKY";
296 bool ret = AccessTokenHelper::VerifyAccessToken(IPCSkeleton::GetCallingTokenID(), permission);
297 if (!ret) {
298 EVENT_LOGE("No permission to get a sticky common event from %{public}s (uid = %{public}d)",
299 bundleName.c_str(),
300 callingUid);
301 return false;
302 }
303
304 return innerCommonEventManager_->GetStickyCommonEvent(event, eventData);
305 }
306
DumpState(const uint8_t & dumpType,const std::string & event,const int32_t & userId,std::vector<std::string> & state)307 bool CommonEventManagerService::DumpState(const uint8_t &dumpType, const std::string &event, const int32_t &userId,
308 std::vector<std::string> &state)
309 {
310 EVENT_LOGI("enter");
311
312 if (!AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID())) {
313 EVENT_LOGE("Not subsystem or shell request");
314 return false;
315 }
316 if (!IsReady()) {
317 EVENT_LOGE("CommonEventManagerService not ready");
318 return false;
319 }
320
321 innerCommonEventManager_->DumpState(dumpType, event, userId, state);
322
323 return true;
324 }
325
FinishReceiver(const sptr<IRemoteObject> & proxy,const int32_t & code,const std::string & receiverData,const bool & abortEvent)326 bool CommonEventManagerService::FinishReceiver(
327 const sptr<IRemoteObject> &proxy, const int32_t &code, const std::string &receiverData, const bool &abortEvent)
328 {
329 EVENT_LOGI("enter");
330
331 if (!IsReady()) {
332 EVENT_LOGE("CommonEventManagerService not ready");
333 return false;
334 }
335 std::weak_ptr<InnerCommonEventManager> wp = innerCommonEventManager_;
336 std::function<void()> finishReceiverFunc = [wp, proxy, code, receiverData, abortEvent] () {
337 std::shared_ptr<InnerCommonEventManager> innerCommonEventManager = wp.lock();
338 if (innerCommonEventManager == nullptr) {
339 EVENT_LOGE("innerCommonEventManager not exist");
340 return;
341 }
342 innerCommonEventManager->FinishReceiver(proxy, code, receiverData, abortEvent);
343 };
344
345 return handler_->PostTask(finishReceiverFunc);
346 }
347
Freeze(const uid_t & uid)348 bool CommonEventManagerService::Freeze(const uid_t &uid)
349 {
350 EVENT_LOGI("enter");
351
352 if (!AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID())) {
353 EVENT_LOGE("Not subsystem request");
354 return false;
355 }
356 if (!IsReady()) {
357 EVENT_LOGE("CommonEventManagerService not ready");
358 return false;
359 }
360 std::weak_ptr<InnerCommonEventManager> wp = innerCommonEventManager_;
361 std::function<void()> freezeFunc = [wp, uid] () {
362 std::shared_ptr<InnerCommonEventManager> innerCommonEventManager = wp.lock();
363 if (innerCommonEventManager == nullptr) {
364 EVENT_LOGE("innerCommonEventManager not exist");
365 return;
366 }
367 innerCommonEventManager->Freeze(uid);
368 };
369 return handler_->PostImmediateTask(freezeFunc);
370 }
371
Unfreeze(const uid_t & uid)372 bool CommonEventManagerService::Unfreeze(const uid_t &uid)
373 {
374 EVENT_LOGI("enter");
375
376 if (!AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID())) {
377 EVENT_LOGE("Not subsystem request");
378 return false;
379 }
380 if (!IsReady()) {
381 EVENT_LOGE("CommonEventManagerService not ready");
382 return false;
383 }
384
385 std::weak_ptr<InnerCommonEventManager> wp = innerCommonEventManager_;
386 std::function<void()> unfreezeFunc = [wp, uid] () {
387 std::shared_ptr<InnerCommonEventManager> innerCommonEventManager = wp.lock();
388 if (innerCommonEventManager == nullptr) {
389 EVENT_LOGE("innerCommonEventManager not exist");
390 return;
391 }
392 innerCommonEventManager->Unfreeze(uid);
393 };
394
395 return handler_->PostImmediateTask(unfreezeFunc);
396 }
397
UnfreezeAll()398 bool CommonEventManagerService::UnfreezeAll()
399 {
400 EVENT_LOGI("enter");
401
402 if (!AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID())) {
403 EVENT_LOGE("Not subsystem request");
404 return false;
405 }
406 if (!IsReady()) {
407 EVENT_LOGE("CommonEventManagerService not ready");
408 return false;
409 }
410
411 std::weak_ptr<InnerCommonEventManager> wp = innerCommonEventManager_;
412 std::function<void()> unfreezeAllFunc = [wp] () {
413 std::shared_ptr<InnerCommonEventManager> innerCommonEventManager = wp.lock();
414 if (innerCommonEventManager == nullptr) {
415 EVENT_LOGE("innerCommonEventManager not exist");
416 return;
417 }
418 innerCommonEventManager->UnfreezeAll();
419 };
420
421 return handler_->PostImmediateTask(unfreezeAllFunc);
422 }
423
Dump(int fd,const std::vector<std::u16string> & args)424 int CommonEventManagerService::Dump(int fd, const std::vector<std::u16string> &args)
425 {
426 EVENT_LOGI("enter");
427
428 if (!AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID())) {
429 EVENT_LOGE("Not subsystem or shell request");
430 return false;
431 }
432 if (!IsReady()) {
433 EVENT_LOGE("CommonEventManagerService not ready");
434 return ERR_INVALID_VALUE;
435 }
436 std::string result;
437 innerCommonEventManager_->HiDump(args, result);
438 int ret = dprintf(fd, "%s\n", result.c_str());
439 if (ret < 0) {
440 EVENT_LOGE("dprintf error");
441 return ERR_INVALID_VALUE;
442 }
443 return ERR_OK;
444 }
445 } // namespace EventFwk
446 } // namespace OHOS
447