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