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