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