1 /*
2 * Copyright (c) 2022-2025 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 "hiappevent_ffrt.h"
24 #include "hilog/log.h"
25 #include "os_event_listener.h"
26
27 #undef LOG_DOMAIN
28 #define LOG_DOMAIN 0xD002D07
29
30 #undef LOG_TAG
31 #define LOG_TAG "ObserverMgr"
32
33 namespace OHOS {
34 namespace HiviewDFX {
35 using HiAppEvent::AppEventFilter;
36 using HiAppEvent::TriggerCondition;
37 namespace {
38 constexpr int ONE_MINUTE = 60 * 1000;
39 constexpr int REFRESH_FREE_SIZE_INTERVAL = 10 * ONE_MINUTE; // 10 minutes
40 constexpr int TIMEOUT_INTERVAL_MICRO = HiAppEvent::TIMEOUT_STEP * 1000 * 1000; // 30s
41 constexpr int MAX_SIZE_OF_INIT = 100;
42
StoreEventsToDb(std::vector<std::shared_ptr<AppEventPack>> & events)43 void StoreEventsToDb(std::vector<std::shared_ptr<AppEventPack>>& events)
44 {
45 for (auto& event : events) {
46 int64_t eventSeq = AppEventStore::GetInstance().InsertEvent(event);
47 if (eventSeq <= 0) {
48 HILOG_WARN(LOG_CORE, "failed to store event to db");
49 continue;
50 }
51 event->SetSeq(eventSeq);
52 AppEventStore::GetInstance().QueryCustomParamsAdd2EventPack(event);
53 }
54 }
55
StoreEventMappingToDb(const std::vector<std::shared_ptr<AppEventPack>> & events,std::shared_ptr<AppEventObserver> observer)56 void StoreEventMappingToDb(const std::vector<std::shared_ptr<AppEventPack>>& events,
57 std::shared_ptr<AppEventObserver> observer)
58 {
59 for (const auto& event : events) {
60 if (observer->VerifyEvent(event)) {
61 int64_t observerSeq = observer->GetSeq();
62 if (AppEventStore::GetInstance().InsertEventMapping(event->GetSeq(), observerSeq) < 0) {
63 HILOG_ERROR(LOG_CORE, "failed to add mapping record to db, seq=%{public}" PRId64, observerSeq);
64 }
65 }
66 }
67 }
68
SendEventsToObserver(const std::vector<std::shared_ptr<AppEventPack>> & events,std::shared_ptr<AppEventObserver> observer)69 void SendEventsToObserver(const std::vector<std::shared_ptr<AppEventPack>>& events,
70 std::shared_ptr<AppEventObserver> observer)
71 {
72 std::vector<std::shared_ptr<AppEventPack>> realTimeEvents;
73 for (const auto& event : events) {
74 if (!observer->VerifyEvent(event)) {
75 continue;
76 }
77 if (observer->IsRealTimeEvent(event)) {
78 realTimeEvents.emplace_back(event);
79 } else {
80 observer->ProcessEvent(event);
81 }
82 }
83 if (!realTimeEvents.empty()) {
84 observer->OnEvents(realTimeEvents);
85 }
86 }
87
InitObserverFromDb(std::shared_ptr<AppEventObserver> observer,const std::string & name,int64_t hashCode)88 int64_t InitObserverFromDb(std::shared_ptr<AppEventObserver> observer,
89 const std::string& name, int64_t hashCode)
90 {
91 std::string filters;
92 int64_t observerSeq = AppEventStore::GetInstance().QueryObserverSeqAndFilters(name, hashCode, filters);
93 if (observerSeq <= 0) {
94 HILOG_INFO(LOG_CORE, "the observer does not exist in database, name=%{public}s, hash=%{public}" PRId64,
95 name.c_str(), hashCode);
96 return -1;
97 }
98 std::string newFilters = observer->GetFiltersStr();
99 if (filters != newFilters && AppEventStore::GetInstance().UpdateObserver(observerSeq, newFilters) < 0) {
100 HILOG_ERROR(LOG_CORE, "failed to update observer=%{public}s to db", name.c_str());
101 }
102 std::vector<std::shared_ptr<AppEventPack>> events;
103 if (AppEventStore::GetInstance().QueryEvents(events, observerSeq, MAX_SIZE_OF_INIT) < 0) {
104 HILOG_ERROR(LOG_CORE, "failed to take events, seq=%{public}" PRId64, observerSeq);
105 return -1;
106 }
107 observer->SetSeq(observerSeq);
108 if (!events.empty()) {
109 if (hashCode == 0) {
110 // send old events to watcher where init
111 SendEventsToObserver(events, observer);
112 } else {
113 TriggerCondition triggerCond;
114 for (auto event : events) {
115 triggerCond.row++;
116 triggerCond.size += static_cast<int>(event->GetEventStr().size());
117 }
118 observer->SetCurrCondition(triggerCond);
119 }
120 }
121 return observerSeq;
122 }
123
InitObserver(std::shared_ptr<AppEventObserver> observer,bool & isExist)124 int64_t InitObserver(std::shared_ptr<AppEventObserver> observer, bool& isExist)
125 {
126 std::string observerName = observer->GetName();
127 int64_t observerHashCode = observer->GenerateHashCode();
128 int64_t observerSeq = InitObserverFromDb(observer, observerName, observerHashCode);
129 if (observerSeq <= 0) {
130 observerSeq = AppEventStore::GetInstance().InsertObserver(AppEventCacheCommon::Observer(observerName,
131 observerHashCode, observer->GetFiltersStr()));
132 if (observerSeq <= 0) {
133 HILOG_ERROR(LOG_CORE, "failed to insert observer=%{public}s to db", observerName.c_str());
134 return -1;
135 }
136 } else {
137 isExist = true;
138 }
139 observer->SetSeq(observerSeq);
140 return observerSeq;
141 }
142 }
143
GetInstance()144 AppEventObserverMgr& AppEventObserverMgr::GetInstance()
145 {
146 static AppEventObserverMgr instance;
147 return instance;
148 }
149
AppEventObserverMgr()150 AppEventObserverMgr::AppEventObserverMgr()
151 {
152 CreateEventHandler();
153 SendRefreshFreeSizeEvent();
154 RegisterAppStateCallback();
155 moduleLoader_ = std::make_unique<ModuleLoader>();
156 }
157
CreateEventHandler()158 void AppEventObserverMgr::CreateEventHandler()
159 {
160 auto runner = AppExecFwk::EventRunner::Create("OS_AppEvent_Hd", AppExecFwk::ThreadMode::FFRT);
161 if (runner == nullptr) {
162 HILOG_ERROR(LOG_CORE, "failed to create event runner");
163 return;
164 }
165 handler_ = std::make_shared<AppEventHandler>(runner);
166 }
167
RegisterAppStateCallback()168 void AppEventObserverMgr::RegisterAppStateCallback()
169 {
170 auto context = OHOS::AbilityRuntime::ApplicationContext::GetInstance();
171 if (context == nullptr) {
172 HILOG_WARN(LOG_CORE, "app context is null");
173 return;
174 }
175 appStateCallback_ = std::make_shared<AppStateCallback>();
176 context->RegisterAbilityLifecycleCallback(appStateCallback_);
177 HILOG_INFO(LOG_CORE, "succ to register application state callback");
178 }
179
~AppEventObserverMgr()180 AppEventObserverMgr::~AppEventObserverMgr()
181 {
182 DestroyEventHandler();
183 UnregisterAppStateCallback();
184 }
185
DestroyEventHandler()186 void AppEventObserverMgr::DestroyEventHandler()
187 {
188 if (handler_ != nullptr) {
189 HILOG_INFO(LOG_CORE, "start to TaskCancelAndWait");
190 // stop and wait task
191 handler_->TaskCancelAndWait();
192 }
193 std::lock_guard<std::mutex> lock(handlerMutex_);
194 handler_ = nullptr;
195 }
196
UnregisterAppStateCallback()197 void AppEventObserverMgr::UnregisterAppStateCallback()
198 {
199 if (appStateCallback_ == nullptr) {
200 return;
201 }
202
203 auto context = OHOS::AbilityRuntime::ApplicationContext::GetInstance();
204 if (context == nullptr) {
205 HILOG_WARN(LOG_CORE, "app context is null");
206 return;
207 }
208 context->UnregisterAbilityLifecycleCallback(appStateCallback_);
209 appStateCallback_ = nullptr;
210 HILOG_INFO(LOG_CORE, "succ to unregister application state callback");
211 }
212
InitWatchers()213 void AppEventObserverMgr::InitWatchers()
214 {
215 static std::once_flag onceFlag;
216 std::call_once(onceFlag, [&]() {
217 std::vector<AppEventCacheCommon::Observer> observers;
218 if (AppEventStore::GetInstance().QueryWatchers(observers) != 0) {
219 HILOG_WARN(LOG_CORE, "failed to query observers from db");
220 return;
221 }
222 std::lock_guard<std::mutex> lock(observerMutex_);
223 for (const auto& observer : observers) {
224 auto observerPtr = std::make_shared<AppEventObserver>(observer.name);
225 observerPtr->SetSeq(observer.seq);
226 observerPtr->SetFilters(observer.filters);
227 observers_[observer.seq] = observerPtr;
228 }
229 HILOG_INFO(LOG_CORE, "init watchers");
230 });
231 }
232
RegisterObserver(std::shared_ptr<AppEventObserver> observer)233 int64_t AppEventObserverMgr::RegisterObserver(std::shared_ptr<AppEventObserver> observer)
234 {
235 InitWatchers();
236 bool isExist = false;
237 int64_t observerSeq = InitObserver(observer, isExist);
238 if (observerSeq <= 0) {
239 return observerSeq;
240 }
241
242 std::lock_guard<std::mutex> lock(observerMutex_);
243 if (!InitObserverFromListener(observer, isExist)) {
244 return -1;
245 }
246 observers_[observerSeq] = observer;
247 HILOG_INFO(LOG_CORE, "register observer=%{public}" PRId64 " successfully", observerSeq);
248 return observerSeq;
249 }
250
RegisterObserver(const std::string & observerName,const ReportConfig & config)251 int64_t AppEventObserverMgr::RegisterObserver(const std::string& observerName, const ReportConfig& config)
252 {
253 if (observerName.empty()) {
254 HILOG_WARN(LOG_CORE, "observer name is empty");
255 return -1;
256 }
257
258 auto observer = moduleLoader_->CreateProcessorProxy(observerName);
259 if (observer == nullptr) {
260 HILOG_WARN(LOG_CORE, "observer is null");
261 return -1;
262 }
263 observer->SetReportConfig(config);
264
265 int64_t observerSeq = RegisterObserver(observer);
266 if (observerSeq <= 0) {
267 return -1;
268 }
269 observer->ProcessStartup();
270 return observerSeq;
271 }
272
UnregisterObserver(int64_t observerSeq)273 int AppEventObserverMgr::UnregisterObserver(int64_t observerSeq)
274 {
275 std::lock_guard<std::mutex> lock(observerMutex_);
276 if (observers_.find(observerSeq) == observers_.cend()) {
277 HILOG_WARN(LOG_CORE, "observer seq=%{public}" PRId64 " is not exist", observerSeq);
278 return 0;
279 }
280 if (int ret = AppEventStore::GetInstance().DeleteObserver(observerSeq); ret < 0) {
281 HILOG_ERROR(LOG_CORE, "failed to unregister observer seq=%{public}" PRId64, observerSeq);
282 return ret;
283 }
284 observers_.erase(observerSeq);
285 UnregisterOsEventListener();
286 HILOG_INFO(LOG_CORE, "unregister observer seq=%{public}" PRId64 " successfully", observerSeq);
287 return 0;
288 }
289
UnregisterObserver(const std::string & observerName)290 int AppEventObserverMgr::UnregisterObserver(const std::string& observerName)
291 {
292 std::vector<int64_t> deleteSeqs;
293 if (int ret = AppEventStore::GetInstance().QueryObserverSeqs(observerName, deleteSeqs); ret < 0) {
294 HILOG_ERROR(LOG_CORE, "failed to query observer=%{public}s seqs", observerName.c_str());
295 return ret;
296 }
297 int ret = 0;
298 for (auto deleteSeq : deleteSeqs) {
299 if (int tempRet = UnregisterObserver(deleteSeq); tempRet < 0) {
300 HILOG_ERROR(LOG_CORE, "failed to unregister observer seq=%{public}" PRId64, deleteSeq);
301 ret = tempRet;
302 }
303 }
304 return ret;
305 }
306
Load(const std::string & moduleName)307 int AppEventObserverMgr::Load(const std::string& moduleName)
308 {
309 return moduleLoader_->Load(moduleName);
310 }
311
RegisterProcessor(const std::string & name,std::shared_ptr<AppEventProcessor> processor)312 int AppEventObserverMgr::RegisterProcessor(const std::string& name, std::shared_ptr<AppEventProcessor> processor)
313 {
314 return moduleLoader_->RegisterProcessor(name, processor);
315 }
316
UnregisterProcessor(const std::string & name)317 int AppEventObserverMgr::UnregisterProcessor(const std::string& name)
318 {
319 return moduleLoader_->UnregisterProcessor(name);
320 }
321
HandleEvents(std::vector<std::shared_ptr<AppEventPack>> & events)322 void AppEventObserverMgr::HandleEvents(std::vector<std::shared_ptr<AppEventPack>>& events)
323 {
324 InitWatchers();
325 std::lock_guard<std::mutex> lock(observerMutex_);
326 if (observers_.empty() || events.empty()) {
327 return;
328 }
329 HILOG_DEBUG(LOG_CORE, "start to handle events size=%{public}zu", events.size());
330 StoreEventsToDb(events);
331 for (auto it = observers_.cbegin(); it != observers_.cend(); ++it) {
332 StoreEventMappingToDb(events, it->second);
333 }
334 bool needSend = false;
335 for (auto it = observers_.cbegin(); it != observers_.cend(); ++it) {
336 // send events to observer, and then delete events not in event mapping
337 SendEventsToObserver(events, it->second);
338 needSend |= it->second->HasTimeoutCondition();
339 }
340 if (needSend && !hasHandleTimeout_) {
341 SendEventToHandler();
342 hasHandleTimeout_ = true;
343 }
344 }
345
HandleTimeout()346 void AppEventObserverMgr::HandleTimeout()
347 {
348 std::lock_guard<std::mutex> lock(observerMutex_);
349 bool needSend = false;
350 for (auto it = observers_.cbegin(); it != observers_.cend(); ++it) {
351 it->second->ProcessTimeout();
352 needSend |= it->second->HasTimeoutCondition();
353 }
354 if (needSend) {
355 SendEventToHandler();
356 } else {
357 hasHandleTimeout_ = false;
358 }
359 }
360
SendEventToHandler()361 void AppEventObserverMgr::SendEventToHandler()
362 {
363 HiAppEvent::Submit([this] {
364 ffrt::this_task::sleep_for(std::chrono::microseconds(TIMEOUT_INTERVAL_MICRO));
365 HandleTimeout();
366 }, {}, {}, ffrt::task_attr().name("appevent_timeout"));
367 }
368
SendRefreshFreeSizeEvent()369 void AppEventObserverMgr::SendRefreshFreeSizeEvent()
370 {
371 std::lock_guard<std::mutex> lock(handlerMutex_);
372 if (handler_ == nullptr) {
373 HILOG_ERROR(LOG_CORE, "failed to SendRefreshFreeSizeEvent: handler is null");
374 return;
375 }
376 handler_->SendEvent(AppEventType::REFRESH_FREE_SIZE, 0, REFRESH_FREE_SIZE_INTERVAL);
377 }
378
HandleBackground()379 void AppEventObserverMgr::HandleBackground()
380 {
381 HILOG_INFO(LOG_CORE, "start to handle background");
382 HiAppEvent::Submit([this] {
383 std::lock_guard<std::mutex> lock(observerMutex_);
384 for (auto it = observers_.cbegin(); it != observers_.cend(); ++it) {
385 it->second->ProcessBackground();
386 }
387 }, {}, {}, ffrt::task_attr().name("app_background"));
388 }
389
HandleClearUp()390 void AppEventObserverMgr::HandleClearUp()
391 {
392 HILOG_INFO(LOG_CORE, "start to handle clear up");
393 std::lock_guard<std::mutex> lock(observerMutex_);
394 for (auto it = observers_.cbegin(); it != observers_.cend(); ++it) {
395 it->second->ResetCurrCondition();
396 }
397 }
398
SetReportConfig(int64_t observerSeq,const ReportConfig & config)399 int AppEventObserverMgr::SetReportConfig(int64_t observerSeq, const ReportConfig& config)
400 {
401 std::lock_guard<std::mutex> lock(observerMutex_);
402 if (observers_.find(observerSeq) == observers_.cend()) {
403 HILOG_WARN(LOG_CORE, "failed to set config, seq=%{public}" PRId64, observerSeq);
404 return -1;
405 }
406 observers_[observerSeq]->SetReportConfig(config);
407 return 0;
408 }
409
GetReportConfig(int64_t observerSeq,ReportConfig & config)410 int AppEventObserverMgr::GetReportConfig(int64_t observerSeq, ReportConfig& config)
411 {
412 std::lock_guard<std::mutex> lock(observerMutex_);
413 if (observers_.find(observerSeq) == observers_.cend()) {
414 HILOG_WARN(LOG_CORE, "failed to get config, seq=%{public}" PRId64, observerSeq);
415 return -1;
416 }
417 config = observers_[observerSeq]->GetReportConfig();
418 return 0;
419 }
420
InitObserverFromListener(std::shared_ptr<AppEventObserver> observer,bool isExist)421 bool AppEventObserverMgr::InitObserverFromListener(std::shared_ptr<AppEventObserver> observer, bool isExist)
422 {
423 uint64_t mask = observer->GetOsEventsMask();
424 if (mask == 0) {
425 return true;
426 }
427 if (listener_ == nullptr) {
428 listener_ = std::make_shared<OsEventListener>();
429 if (!listener_->StartListening()) {
430 return false;
431 }
432 }
433 if (!listener_->AddListenedEvents(mask)) {
434 return false;
435 }
436 if (isExist) {
437 std::vector<std::shared_ptr<AppEventPack>> events;
438 listener_->GetEvents(events);
439 StoreEventMappingToDb(events, observer);
440 SendEventsToObserver(events, observer);
441 }
442 return true;
443 }
444
UnregisterOsEventListener()445 void AppEventObserverMgr::UnregisterOsEventListener()
446 {
447 if (listener_ == nullptr) {
448 return;
449 }
450 uint64_t mask = 0;
451 for (auto it = observers_.begin(); it != observers_.end(); ++it) {
452 mask |= it->second->GetOsEventsMask();
453 }
454 if (mask > 0) {
455 listener_->SetListenedEvents(mask);
456 return;
457 }
458 listener_->RemoveOsEventDir();
459 listener_ = nullptr;
460 }
461 } // namespace HiviewDFX
462 } // namespace OHOS
463