1 /*
2 * Copyright (c) 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 #include "app_event_watcher_mgr.h"
16
17 #include "app_event_cache.h"
18 #include "app_event_handler.h"
19 #include "hilog/log.h"
20
21 namespace OHOS {
22 namespace HiviewDFX {
23 namespace {
24 const HiLogLabel LABEL = { LOG_CORE, 0xD002D07, "HiAppEvent_WatcherMgr" };
25 constexpr int TIMEOUT_INTERVAL = 30000; // 30s
26 }
27 std::shared_mutex AppEventWatcherMgr::mutex_;
28 std::shared_ptr<AppEventWatcherMgr> AppEventWatcherMgr::instance_ = nullptr;
29
GetInstance()30 std::shared_ptr<AppEventWatcherMgr> AppEventWatcherMgr::GetInstance()
31 {
32 if (instance_ == nullptr) {
33 std::unique_lock<std::shared_mutex> lock(mutex_);
34 if (instance_ == nullptr) {
35 instance_ = std::make_shared<AppEventWatcherMgr>();
36 }
37 }
38 return instance_;
39 }
40
AddWatcher(const std::shared_ptr<AppEventWatcher> & watcher)41 void AppEventWatcherMgr::AddWatcher(const std::shared_ptr<AppEventWatcher>& watcher)
42 {
43 // if already exists, need to delete the old watcher first
44 std::string name = watcher->GetName();
45 if (watchers_.find(name) != watchers_.end()) {
46 RemoveWatcher(name);
47 }
48
49 // need to create a block for the watcher
50 std::unique_lock<std::shared_mutex> lock(mutex_);
51 if (AppEventCache::GetInstance()->CreateBlock(name) != 0) {
52 HiLog::Error(LABEL, "addWatcher: failed to create block");
53 return;
54 }
55 watchers_[name] = watcher;
56
57 // if the timeOut condition is set, need to create the event handler
58 if (watcher->GetCond().timeOut > 0 && handler_ == nullptr) {
59 if (CreateEventHandler() == nullptr) {
60 HiLog::Error(LABEL, "addWatcher: failed to create handler");
61 }
62 handler_->SendEvent(AppEventType::WATCHER_TIMEOUT, 0, TIMEOUT_INTERVAL);
63 }
64 HiLog::Info(LABEL, "add watcher=%{public}s successfully", name.c_str());
65 }
66
RemoveWatcher(const std::string & name)67 void AppEventWatcherMgr::RemoveWatcher(const std::string& name)
68 {
69 if (watchers_.find(name) == watchers_.end()) {
70 return;
71 }
72 std::unique_lock<std::shared_mutex> lock(mutex_);
73 if (AppEventCache::GetInstance()->DestroyBlock(name) != 0) {
74 HiLog::Error(LABEL, "failed to remove watcher: failed to destroy block");
75 }
76 watchers_.erase(name);
77
78 // if the remaining watchers do not need to be triggered timely, the handler is destroyed
79 auto it = std::find_if(watchers_.begin(), watchers_.end(),
80 [&] (const std::map<std::string, std::shared_ptr<AppEventWatcher>>::value_type& watcher) {
81 return watcher.second->GetCond().timeOut > 0;
82 });
83 if (it == watchers_.end()) {
84 DestroyEventHandler();
85 }
86 HiLog::Info(LABEL, "remove watcher=%{public}s successfully", name.c_str());
87 }
88
HandleEvent(const std::string & domain,int type,const std::string & event)89 void AppEventWatcherMgr::HandleEvent(const std::string& domain, int type, const std::string& event)
90 {
91 HiLog::Debug(LABEL, "watcherMgr start to handle event");
92 std::shared_lock<std::shared_mutex> lock(mutex_);
93 for (auto it = watchers_.begin(); it != watchers_.end(); ++it) {
94 it->second->ProcessEvent(domain, type, event);
95 }
96 }
97
HandleTimeOut()98 void AppEventWatcherMgr::HandleTimeOut()
99 {
100 HiLog::Debug(LABEL, "watcherMgr start to handle timeout");
101 if (handler_ == nullptr) {
102 HiLog::Error(LABEL, "failed to handle timeOut: handler is null");
103 return;
104 }
105 handler_->SendEvent(AppEventType::WATCHER_TIMEOUT, 0, TIMEOUT_INTERVAL);
106 std::shared_lock<std::shared_mutex> lock(mutex_);
107 for (auto it = watchers_.begin(); it != watchers_.end(); ++it) {
108 it->second->ProcessTimeOut();
109 }
110 }
111
CreateEventHandler()112 std::shared_ptr<AppEventHandler> AppEventWatcherMgr::CreateEventHandler()
113 {
114 if (handler_ != nullptr) {
115 return handler_;
116 }
117 auto runner = AppExecFwk::EventRunner::Create("AppEventHandler");
118 if (runner == nullptr) {
119 HiLog::Error(LABEL, "failed to create event runner");
120 return nullptr;
121 }
122 handler_ = std::make_shared<AppEventHandler>(runner);
123 return handler_;
124 }
125
DestroyEventHandler()126 void AppEventWatcherMgr::DestroyEventHandler()
127 {
128 handler_= nullptr;
129 }
130 } // namespace HiviewDFX
131 } // namespace OHOS
132