1 /*
2 * Copyright (c) 2022-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 #include "app_event_observer_mgr.h"
16
17 #include "app_state_callback.h"
18 #include "app_event_handler.h"
19 #include "app_event_processor_proxy.h"
20 #include "app_event_store.h"
21 #include "application_context.h"
22 #include "hiappevent_base.h"
23 #include "hilog/log.h"
24 #include "module_loader.h"
25 #include "os_event_listener.h"
26
27 namespace OHOS {
28 namespace HiviewDFX {
29 using HiAppEvent::AppEventFilter;
30 using HiAppEvent::TriggerCondition;
31 namespace {
32 const HiLogLabel LABEL = { LOG_CORE, HIAPPEVENT_DOMAIN, "HiAppEvent_ObserverMgr" };
33 constexpr int TIMEOUT_INTERVAL = 1000; // 1s
34
StoreEventsToDb(std::vector<std::shared_ptr<AppEventPack>> & events)35 void StoreEventsToDb(std::vector<std::shared_ptr<AppEventPack>>& events)
36 {
37 for (auto& event : events) {
38 int64_t eventSeq = AppEventStore::GetInstance().InsertEvent(event);
39 if (eventSeq <= 0) {
40 HiLog::Warn(LABEL, "failed to store event to db");
41 continue;
42 }
43 event->SetSeq(eventSeq);
44 }
45 }
46
StoreEventMappingToDb(int64_t eventSeq,int64_t observerSeq)47 int64_t StoreEventMappingToDb(int64_t eventSeq, int64_t observerSeq)
48 {
49 return AppEventStore::GetInstance().InsertEventMapping(eventSeq, observerSeq);
50 }
51
InitObserverFromDb(std::shared_ptr<AppEventObserver> observer,const std::string & name,int64_t hashCode)52 int64_t InitObserverFromDb(std::shared_ptr<AppEventObserver> observer,
53 const std::string& name, int64_t hashCode)
54 {
55 int64_t observerSeq = AppEventStore::GetInstance().QueryObserverSeq(name, hashCode);
56 if (observerSeq <= 0) {
57 HiLog::Info(LABEL, "the observer does not exist in database, name=%{public}s, hash=%{public}" PRId64,
58 name.c_str(), hashCode);
59 return -1;
60 }
61 std::vector<std::shared_ptr<AppEventPack>> events;
62 if (AppEventStore::GetInstance().QueryEvents(events, observerSeq) < 0) {
63 HiLog::Error(LABEL, "failed to take events, seq=%{public}" PRId64, observerSeq);
64 return -1;
65 }
66 if (!events.empty()) {
67 TriggerCondition triggerCond;
68 for (auto event : events) {
69 triggerCond.row++;
70 triggerCond.size += static_cast<int>(event->GetEventStr().size());
71 }
72 observer->SetCurrCondition(triggerCond);
73 }
74 return observerSeq;
75 }
76
SendEventsToObserver(const std::vector<std::shared_ptr<AppEventPack>> & events,std::shared_ptr<AppEventObserver> observer)77 void SendEventsToObserver(const std::vector<std::shared_ptr<AppEventPack>>& events,
78 std::shared_ptr<AppEventObserver> observer)
79 {
80 std::vector<std::shared_ptr<AppEventPack>> realTimeEvents;
81 for (const auto& event : events) {
82 if (!observer->VerifyEvent(event)) {
83 continue;
84 }
85 if (observer->IsRealTimeEvent(event)) {
86 realTimeEvents.emplace_back(event);
87 } else {
88 int64_t observerSeq = observer->GetSeq();
89 if (StoreEventMappingToDb(event->GetSeq(), observerSeq) < 0) {
90 HiLog::Warn(LABEL, "failed to add mapping record to db, seq=%{public}" PRId64, observerSeq);
91 return;
92 }
93 observer->ProcessEvent(event);
94 }
95 }
96 if (!realTimeEvents.empty()) {
97 observer->OnEvents(realTimeEvents);
98 }
99 }
100 }
101 std::mutex AppEventObserverMgr::instanceMutex_;
102
GetInstance()103 AppEventObserverMgr& AppEventObserverMgr::GetInstance()
104 {
105 std::lock_guard<std::mutex> lock(instanceMutex_);
106 static AppEventObserverMgr instance;
107 return instance;
108 }
109
AppEventObserverMgr()110 AppEventObserverMgr::AppEventObserverMgr()
111 {
112 CreateEventHandler();
113 RegisterAppStateCallback();
114 }
115
CreateEventHandler()116 void AppEventObserverMgr::CreateEventHandler()
117 {
118 auto runner = AppExecFwk::EventRunner::Create("AppEventHandler");
119 if (runner == nullptr) {
120 HiLog::Error(LABEL, "failed to create event runner");
121 return;
122 }
123 handler_ = std::make_shared<AppEventHandler>(runner);
124 handler_->SendEvent(AppEventType::WATCHER_TIMEOUT, 0, TIMEOUT_INTERVAL);
125 }
126
RegisterAppStateCallback()127 void AppEventObserverMgr::RegisterAppStateCallback()
128 {
129 auto context = OHOS::AbilityRuntime::ApplicationContext::GetInstance();
130 if (context == nullptr) {
131 HiLog::Warn(LABEL, "app context is null");
132 return;
133 }
134 appStateCallback_ = std::make_shared<AppStateCallback>();
135 context->RegisterAbilityLifecycleCallback(appStateCallback_);
136 HiLog::Info(LABEL, "succ to register application state callback");
137 }
138
~AppEventObserverMgr()139 AppEventObserverMgr::~AppEventObserverMgr()
140 {
141 DestroyEventHandler();
142 UnregisterAppStateCallback();
143 }
144
DestroyEventHandler()145 void AppEventObserverMgr::DestroyEventHandler()
146 {
147 handler_= nullptr;
148 }
149
UnregisterAppStateCallback()150 void AppEventObserverMgr::UnregisterAppStateCallback()
151 {
152 if (appStateCallback_ == nullptr) {
153 return;
154 }
155
156 auto context = OHOS::AbilityRuntime::ApplicationContext::GetInstance();
157 if (context == nullptr) {
158 HiLog::Warn(LABEL, "app context is null");
159 return;
160 }
161 context->UnregisterAbilityLifecycleCallback(appStateCallback_);
162 appStateCallback_ = nullptr;
163 HiLog::Info(LABEL, "succ to unregister application state callback");
164 }
165
RegisterObserver(std::shared_ptr<AppEventObserver> observer)166 int64_t AppEventObserverMgr::RegisterObserver(std::shared_ptr<AppEventObserver> observer)
167 {
168 int64_t observerSeq = InitObserver(observer);
169 if (observerSeq <= 0) {
170 return observerSeq;
171 }
172
173 std::lock_guard<std::mutex> lock(observerMutex_);
174 observers_[observerSeq] = observer;
175 HiLog::Info(LABEL, "register observer=%{public}" PRId64 " successfully", observerSeq);
176 return observerSeq;
177 }
178
RegisterObserver(const std::string & observerName,const ReportConfig & config)179 int64_t AppEventObserverMgr::RegisterObserver(const std::string& observerName, const ReportConfig& config)
180 {
181 if (observerName.empty()) {
182 HiLog::Warn(LABEL, "observer name is empty");
183 return -1;
184 }
185
186 auto observer = HiAppEvent::ModuleLoader::GetInstance().CreateProcessorProxy(observerName);
187 if (observer == nullptr) {
188 HiLog::Warn(LABEL, "observer is null");
189 return -1;
190 }
191 observer->SetReportConfig(config);
192
193 int64_t observerSeq = RegisterObserver(observer);
194 if (observerSeq <= 0) {
195 return -1;
196 }
197 observer->ProcessStartup();
198 return observerSeq;
199 }
200
UnregisterObserver(int64_t observerSeq)201 int AppEventObserverMgr::UnregisterObserver(int64_t observerSeq)
202 {
203 std::lock_guard<std::mutex> lock(observerMutex_);
204 if (observers_.find(observerSeq) == observers_.cend()) {
205 HiLog::Warn(LABEL, "observer seq=%{public}" PRId64 " is not exist", observerSeq);
206 return 0;
207 }
208 if (int ret = AppEventStore::GetInstance().DeleteObserver(observerSeq); ret < 0) {
209 HiLog::Error(LABEL, "failed to unregister observer seq=%{public}" PRId64, observerSeq);
210 return ret;
211 }
212 observers_.erase(observerSeq);
213 UnregisterOsEventListener();
214 HiLog::Info(LABEL, "unregister observer seq=%{public}" PRId64 " successfully", observerSeq);
215 return 0;
216 }
217
UnregisterObserver(const std::string & observerName)218 int AppEventObserverMgr::UnregisterObserver(const std::string& observerName)
219 {
220 std::vector<int64_t> deleteSeqs;
221 if (int ret = AppEventStore::GetInstance().QueryObserverSeqs(observerName, deleteSeqs); ret < 0) {
222 HiLog::Error(LABEL, "failed to query observer=%{public}s seqs", observerName.c_str());
223 return ret;
224 }
225 int ret = 0;
226 for (auto deleteSeq : deleteSeqs) {
227 if (int tempRet = UnregisterObserver(deleteSeq); tempRet < 0) {
228 HiLog::Error(LABEL, "failed to unregister observer seq=%{public}" PRId64, deleteSeq);
229 ret = tempRet;
230 }
231 }
232 return ret;
233 }
234
InitObserver(std::shared_ptr<AppEventObserver> observer)235 int64_t AppEventObserverMgr::InitObserver(std::shared_ptr<AppEventObserver> observer)
236 {
237 std::string observerName = observer->GetName();
238 int64_t observerHashCode = observer->GenerateHashCode();
239 int64_t observerSeq = InitObserverFromDb(observer, observerName, observerHashCode);
240 bool sendFlag = false;
241 if (observerSeq <= 0) {
242 observerSeq = AppEventStore::GetInstance().InsertObserver(observerName, observerHashCode);
243 if (observerSeq <= 0) {
244 HiLog::Error(LABEL, "failed to insert observer=%{public}s to db", observerName.c_str());
245 return -1;
246 }
247 } else {
248 sendFlag = true;
249 }
250 observer->SetSeq(observerSeq);
251
252 if (!InitObserverFromListener(observer, sendFlag)) {
253 return -1;
254 }
255 return observerSeq;
256 }
257
HandleEvents(std::vector<std::shared_ptr<AppEventPack>> & events)258 void AppEventObserverMgr::HandleEvents(std::vector<std::shared_ptr<AppEventPack>>& events)
259 {
260 std::lock_guard<std::mutex> lock(observerMutex_);
261 if (observers_.empty()) {
262 return;
263 }
264 HiLog::Info(LABEL, "start to handle events");
265 StoreEventsToDb(events);
266 for (auto it = observers_.cbegin(); it != observers_.cend(); ++it) {
267 SendEventsToObserver(events, it->second);
268 }
269 }
270
HandleTimeout()271 void AppEventObserverMgr::HandleTimeout()
272 {
273 if (handler_ == nullptr) {
274 HiLog::Error(LABEL, "failed to handle timeOut: handler is null");
275 return;
276 }
277 handler_->SendEvent(AppEventType::WATCHER_TIMEOUT, 0, TIMEOUT_INTERVAL);
278 std::lock_guard<std::mutex> lock(observerMutex_);
279 for (auto it = observers_.cbegin(); it != observers_.cend(); ++it) {
280 it->second->ProcessTimeout();
281 }
282 }
283
HandleBackground()284 void AppEventObserverMgr::HandleBackground()
285 {
286 HiLog::Info(LABEL, "start to handle background");
287 std::lock_guard<std::mutex> lock(observerMutex_);
288 for (auto it = observers_.cbegin(); it != observers_.cend(); ++it) {
289 it->second->ProcessBackground();
290 }
291 }
292
HandleClearUp()293 void AppEventObserverMgr::HandleClearUp()
294 {
295 HiLog::Info(LABEL, "start to handle clear up");
296 std::lock_guard<std::mutex> lock(observerMutex_);
297 for (auto it = observers_.cbegin(); it != observers_.cend(); ++it) {
298 it->second->ResetCurrCondition();
299 }
300 }
301
SetReportConfig(int64_t observerSeq,const ReportConfig & config)302 int AppEventObserverMgr::SetReportConfig(int64_t observerSeq, const ReportConfig& config)
303 {
304 if (observers_.find(observerSeq) == observers_.cend()) {
305 HiLog::Warn(LABEL, "failed to set config, seq=%{public}" PRId64, observerSeq);
306 return -1;
307 }
308 observers_[observerSeq]->SetReportConfig(config);
309 return 0;
310 }
311
GetReportConfig(int64_t observerSeq,ReportConfig & config)312 int AppEventObserverMgr::GetReportConfig(int64_t observerSeq, ReportConfig& config)
313 {
314 if (observers_.find(observerSeq) == observers_.cend()) {
315 HiLog::Warn(LABEL, "failed to get config, seq=%{public}" PRId64, observerSeq);
316 return -1;
317 }
318 config = observers_[observerSeq]->GetReportConfig();
319 return 0;
320 }
321
InitObserverFromListener(std::shared_ptr<AppEventObserver> observer,bool sendFlag)322 bool AppEventObserverMgr::InitObserverFromListener(std::shared_ptr<AppEventObserver> observer, bool sendFlag)
323 {
324 if (!observer->HasOsDomain()) {
325 return true;
326 }
327 if (listener_ == nullptr) {
328 listener_ = std::make_shared<OsEventListener>();
329 if (!listener_->StartListening()) {
330 return false;
331 }
332 }
333 if (sendFlag) {
334 std::vector<std::shared_ptr<AppEventPack>> events;
335 listener_->GetEvents(events);
336 SendEventsToObserver(events, observer);
337 }
338 return true;
339 }
340
UnregisterOsEventListener()341 void AppEventObserverMgr::UnregisterOsEventListener()
342 {
343 for (auto it = observers_.begin(); it != observers_.end(); ++it) {
344 if (it->second->HasOsDomain()) {
345 return;
346 }
347 }
348 if (listener_ != nullptr) {
349 listener_->RemoveOsEventDir();
350 listener_ = nullptr;
351 }
352 }
353 } // namespace HiviewDFX
354 } // namespace OHOS
355