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