• 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 "bundle_active_core.h"
16 #include "accesstoken_kit.h"
17 #include "time_service_client.h"
18 
19 #include "bundle_active_log.h"
20 #include "bundle_active_event.h"
21 #include "bundle_active_event_stats.h"
22 #include "bundle_active_report_handler.h"
23 #include "bundle_active_group_common.h"
24 #include "bundle_active_bundle_mgr_helper.h"
25 #include "bundle_active_constant.h"
26 #include "bundle_active_util.h"
27 #include "ffrt_inner.h"
28 #include "bundle_constants.h"
29 #include "hisysevent.h"
30 #include "bundle_active_high_frequency_period.h"
31 #include "bundle_active_report_controller.h"
32 #include "bundle_active_event_reporter.h"
33 #include "os_account_constants.h"
34 
35 namespace OHOS {
36 namespace DeviceUsageStats {
37 #ifndef OS_ACCOUNT_PART_ENABLED
38 const int32_t DEFAULT_OS_ACCOUNT_ID = 0; // 0 is the default id when there is no os_account part
39 #endif // OS_ACCOUNT_PART_ENABLED
40 constexpr int32_t BUNDLE_UNINSTALL_DELAY_TIME = 5 * 1000 * 1000;
41 constexpr int32_t MIN_USER_ID = -1;
42 constexpr int32_t MAX_DELETE_EVENT_DALIYS = 6;
43 constexpr int32_t INDEX_USE_TIME = 1;
44 constexpr int32_t INDEX_HOUR = 0;
45 constexpr double DEFAULT_PERCENT_USER_SPACE_LIMIT = 0.1;
46 static constexpr char RSS[] = "RSS";
47 static constexpr char FILEMANAGEMENT[] = "FILEMANAGEMENT";
48 static constexpr char DATA_PATH[] = "/data";
49 
50 // 用于根据使用次数对时段进行降序的数据结构
51 struct ElementWithIndex {
52     int32_t useTimes;
53     int32_t originlIndex;
54 };
55 
BundleActiveReportHandlerObject()56 BundleActiveReportHandlerObject::BundleActiveReportHandlerObject()
57 {
58     userId_ = -1;
59     bundleName_ = "";
60 }
61 
BundleActiveReportHandlerObject(const int32_t userId,const std::string bundleName)62 BundleActiveReportHandlerObject::BundleActiveReportHandlerObject(const int32_t userId, const std::string bundleName)
63 {
64     userId_ = userId;
65     bundleName_ = bundleName;
66 }
67 
BundleActiveReportHandlerObject(const BundleActiveReportHandlerObject & orig)68 BundleActiveReportHandlerObject::BundleActiveReportHandlerObject(const BundleActiveReportHandlerObject& orig)
69 {
70     event_ = orig.event_;
71     userId_ = orig.userId_;
72     bundleName_ = orig.bundleName_;
73     uid_ = orig.uid_;
74     appIndex_ = orig.appIndex_;
75 }
76 
BundleActiveCore()77 BundleActiveCore::BundleActiveCore()
78 {
79     systemTimeShot_ = -1;
80     realTimeShot_ = -1;
81     currentUsedUser_ = -1;
82     if (DEBUG_ON) {
83         flushInterval_ = TWO_MINUTE;
84         debugCore_ = true;
85     } else {
86         flushInterval_ = THIRTY_MINUTE;
87         debugCore_ = false;
88     }
89     percentUserSpaceLimit_ = DEFAULT_PERCENT_USER_SPACE_LIMIT;
90 }
91 
~BundleActiveCore()92 BundleActiveCore::~BundleActiveCore()
93 {
94 }
95 
DeInit()96 void BundleActiveCore::DeInit()
97 {
98     BundleActiveGroupController::GetInstance().DeInit();
99     BundleActiveReportController::GetInstance().DeInit();
100 }
101 
OnReceiveEvent(const CommonEventData & data)102 void BundleActiveCommonEventSubscriber::OnReceiveEvent(const CommonEventData &data)
103 {
104     std::lock_guard<ffrt::mutex> lock(mutex_);
105     std::string action = data.GetWant().GetAction();
106     if (action == CommonEventSupport::COMMON_EVENT_SCREEN_OFF ||
107         action == CommonEventSupport::COMMON_EVENT_SCREEN_ON) {
108         HandleScreenEvent();
109     } else if (action == CommonEventSupport::COMMON_EVENT_USER_REMOVED) {
110         HandleUserRemoveEvent(data);
111     } else if (action == CommonEventSupport::COMMON_EVENT_USER_SWITCHED) {
112         HandleUserSwitchEvent(data);
113     } else if (action == CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED ||
114         action == CommonEventSupport::COMMON_EVENT_PACKAGE_FULLY_REMOVED) {
115         HandlePackageRemoveEvent(data);
116     } else if (action == COMMON_EVENT_UNLOCK_SCREEN || action == COMMON_EVENT_LOCK_SCREEN) {
117         HandleLockEvent(data);
118     } else if (action == CommonEventSupport::COMMON_EVENT_PACKAGE_ADDED) {
119         HandlePackageAddEvent(data);
120     }
121 }
122 
HandleScreenEvent()123 void BundleActiveCommonEventSubscriber::HandleScreenEvent()
124 {
125     auto groupHandler = BundleActiveGroupController::GetInstance().GetBundleGroupHandler();
126     if (groupHandler != nullptr) {
127         sptr<MiscServices::TimeServiceClient> timer = MiscServices::TimeServiceClient::GetInstance();
128         bool isScreenOn = BundleActiveGroupController::GetInstance().IsScreenOn();
129         BUNDLE_ACTIVE_LOGI("screen state change to %{public}d", isScreenOn);
130         BundleActiveGroupController::GetInstance().OnScreenChanged(isScreenOn, timer->GetBootTimeMs());
131     }
132 }
133 
HandleUserRemoveEvent(const CommonEventData & data)134 void BundleActiveCommonEventSubscriber::HandleUserRemoveEvent(const CommonEventData &data)
135 {
136     int32_t userId = data.GetCode();
137     BUNDLE_ACTIVE_LOGI("remove user id %{public}d", userId);
138     BundleActiveReportHandlerObject tmpHandlerObject(userId, "");
139     std::shared_ptr<BundleActiveReportHandlerObject> handlerobjToPtr =
140         std::make_shared<BundleActiveReportHandlerObject>(tmpHandlerObject);
141     auto bundleActiveReportHandler = BundleActiveReportController::GetInstance().GetBundleReportHandler();
142     if (bundleActiveReportHandler == nullptr) {
143         return;
144     }
145     bundleActiveReportHandler->SendEvent(BundleActiveReportHandler::MSG_REMOVE_USER, handlerobjToPtr);
146 }
147 
HandleUserSwitchEvent(const CommonEventData & data)148 void BundleActiveCommonEventSubscriber::HandleUserSwitchEvent(const CommonEventData &data)
149 {
150     auto bundleActiveReportHandler = BundleActiveReportController::GetInstance().GetBundleReportHandler();
151     if (bundleActiveReportHandler == nullptr) {
152         return;
153     }
154     int32_t userId = data.GetCode();
155     BUNDLE_ACTIVE_LOGI("OnReceiveEvent receive switched user event, user id is %{public}d", userId);
156     BundleActiveReportHandlerObject tmpHandlerObject(userId, "");
157     std::shared_ptr<BundleActiveReportHandlerObject> handlerobjToPtr =
158         std::make_shared<BundleActiveReportHandlerObject>(tmpHandlerObject);
159     bundleActiveReportHandler->SendEvent(BundleActiveReportHandler::MSG_SWITCH_USER, handlerobjToPtr);
160 }
161 
HandlePackageRemoveEvent(const CommonEventData & data)162 void BundleActiveCommonEventSubscriber::HandlePackageRemoveEvent(const CommonEventData &data)
163 {
164     std::string action = data.GetWant().GetAction();
165     int32_t userId = data.GetWant().GetIntParam("userId", 0);
166     std::string bundleName = data.GetWant().GetElement().GetBundleName();
167     BUNDLE_ACTIVE_LOGI("action is %{public}s, userID is %{public}d, bundlename is %{public}s",
168         action.c_str(), userId, bundleName.c_str());
169     BundleActiveReportHandlerObject tmpHandlerObject(userId, bundleName);
170     tmpHandlerObject.uid_ = data.GetWant().GetIntParam("uid", -1);
171     tmpHandlerObject.appIndex_ = data.GetWant().GetIntParam("appIndex", -1);
172     std::shared_ptr<BundleActiveReportHandlerObject> handlerobjToPtr =
173         std::make_shared<BundleActiveReportHandlerObject>(tmpHandlerObject);
174     auto bundleActiveReportHandler = BundleActiveReportController::GetInstance().GetBundleReportHandler();
175     if (bundleActiveReportHandler == nullptr) {
176         return;
177     }
178     bundleActiveReportHandler->SendEvent(BundleActiveReportHandler::MSG_BUNDLE_UNINSTALLED,
179         handlerobjToPtr);
180 }
181 
HandlePackageAddEvent(const CommonEventData & data)182 void BundleActiveCommonEventSubscriber::HandlePackageAddEvent(const CommonEventData &data)
183 {
184     std::string action = data.GetWant().GetAction();
185     int32_t userId = data.GetWant().GetIntParam("userId", 0);
186     std::string bundleName = data.GetWant().GetElement().GetBundleName();
187     BUNDLE_ACTIVE_LOGI("action is %{public}s, userID is %{public}d, bundlename is %{public}s",
188         action.c_str(), userId, bundleName.c_str());
189     BundleActiveReportHandlerObject tmpHandlerObject(userId, bundleName);
190     tmpHandlerObject.uid_ = data.GetWant().GetIntParam("uid", -1);
191     tmpHandlerObject.appIndex_ = data.GetWant().GetIntParam("appIndex", -1);
192     std::shared_ptr<BundleActiveReportHandlerObject> handlerobjToPtr =
193         std::make_shared<BundleActiveReportHandlerObject>(tmpHandlerObject);
194     auto bundleActiveReportHandler = BundleActiveReportController::GetInstance().GetBundleReportHandler();
195     if (bundleActiveReportHandler == nullptr) {
196         return;
197     }
198     bundleActiveReportHandler->SendEvent(BundleActiveReportHandler::MSG_BUNDLE_INSTALLED,
199         handlerobjToPtr);
200 }
201 
HandleLockEvent(const CommonEventData & data)202 void BundleActiveCommonEventSubscriber::HandleLockEvent(const CommonEventData &data)
203 {
204     std::string action = data.GetWant().GetAction();
205     int32_t userId = data.GetWant().GetIntParam("userId", 0);
206     BUNDLE_ACTIVE_LOGI("action is %{public}s, userID is %{public}d", action.c_str(), userId);
207     BundleActiveReportHandlerObject tmpHandlerObject(-1, "");
208     BundleActiveEvent newEvent;
209     tmpHandlerObject.event_ = newEvent;
210     if (action == COMMON_EVENT_UNLOCK_SCREEN) {
211         tmpHandlerObject.event_.eventId_ = BundleActiveEvent::SYSTEM_UNLOCK;
212     } else {
213         tmpHandlerObject.event_.eventId_ = BundleActiveEvent::SYSTEM_LOCK;
214     }
215     tmpHandlerObject.userId_ = userId;
216     sptr<MiscServices::TimeServiceClient> timer = MiscServices::TimeServiceClient::GetInstance();
217     tmpHandlerObject.event_.timeStamp_ = timer->GetBootTimeMs();
218     auto handlerobjToPtr = std::make_shared<BundleActiveReportHandlerObject>(tmpHandlerObject);
219     auto bundleActiveReportHandler = BundleActiveReportController::GetInstance().GetBundleReportHandler();
220     if (bundleActiveReportHandler == nullptr) {
221         return;
222     }
223     bundleActiveReportHandler->SendEvent(BundleActiveReportHandler::MSG_REPORT_EVENT, handlerobjToPtr);
224 }
225 
RegisterSubscriber()226 void BundleActiveCore::RegisterSubscriber()
227 {
228     MatchingSkills matchingSkills;
229     matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_SCREEN_OFF);
230     matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_SCREEN_ON);
231     matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_USER_REMOVED);
232     matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_USER_SWITCHED);
233     matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED);
234     matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_BUNDLE_REMOVED);
235     matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_PACKAGE_FULLY_REMOVED);
236     matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_PACKAGE_ADDED);
237     CommonEventSubscribeInfo subscriberInfo(matchingSkills);
238     commonEventSubscriber_ = std::make_shared<BundleActiveCommonEventSubscriber>(subscriberInfo);
239     bool subscribeResult = CommonEventManager::SubscribeCommonEvent(commonEventSubscriber_);
240     SubscriberLockScreenCommonEvent();
241     BUNDLE_ACTIVE_LOGD("Register for events result is %{public}d", subscribeResult);
242 }
243 
SubscriberLockScreenCommonEvent()244 void BundleActiveCore::SubscriberLockScreenCommonEvent()
245 {
246     MatchingSkills matchingSkills;
247     matchingSkills.AddEvent(COMMON_EVENT_UNLOCK_SCREEN);
248     matchingSkills.AddEvent(COMMON_EVENT_LOCK_SCREEN);
249     CommonEventSubscribeInfo subscriberInfo(matchingSkills);
250     subscriberInfo.SetPublisherBundleName(AppExecFwk::Constants::SCENE_BOARD_BUNDLE_NAME);
251     lockScreenSubscriber_ = std::make_shared<BundleActiveCommonEventSubscriber>(subscriberInfo);
252     CommonEventManager::SubscribeCommonEvent(lockScreenSubscriber_);
253 }
254 
UnRegisterSubscriber()255 void BundleActiveCore::UnRegisterSubscriber()
256 {
257     CommonEventManager::UnSubscribeCommonEvent(commonEventSubscriber_);
258     CommonEventManager::UnSubscribeCommonEvent(lockScreenSubscriber_);
259 }
260 
Init()261 void BundleActiveCore::Init()
262 {
263     sptr<MiscServices::TimeServiceClient> timer = MiscServices::TimeServiceClient::GetInstance();
264     do {
265         realTimeShot_ = timer->GetBootTimeMs();
266         systemTimeShot_ = BundleActiveUtil::GetSystemTimeMs();
267     } while (realTimeShot_ == -1 && systemTimeShot_ == -1);
268     realTimeShot_ = timer->GetBootTimeMs();
269     systemTimeShot_ = BundleActiveUtil::GetSystemTimeMs();
270     BUNDLE_ACTIVE_LOGD("system time shot is %{public}lld", (long long)systemTimeShot_);
271     bundleActiveConfigReader_ = std::make_shared<BundleActiveConfigReader>();
272     bundleActiveConfigReader_->LoadConfig();
273     BundleActiveEventReporter::GetInstance().ReportFileSizeEvent();
274 }
275 
InitBundleGroupController()276 void BundleActiveCore::InitBundleGroupController()
277 {
278     BUNDLE_ACTIVE_LOGD("InitBundleGroupController called");
279     BundleActiveGroupController::GetInstance().Init(debugCore_);
280     BundleActiveGroupController::GetInstance().CreateUserHistory(realTimeShot_, shared_from_this());
281     RegisterSubscriber();
282     std::vector<int32_t> activatedOsAccountIds;
283     BundleActiveGroupController::GetInstance().SetBundleGroupEnable(true);
284     GetAllActiveUser(activatedOsAccountIds);
285     if (activatedOsAccountIds.size() == 0) {
286         BUNDLE_ACTIVE_LOGI("query activated account failed, no account activated");
287         return;
288     }
289     for (uint32_t i = 0; i < activatedOsAccountIds.size(); i++) {
290         BundleActiveGroupController::GetInstance().PeriodCheckBundleState(activatedOsAccountIds[i]);
291     }
292 }
293 
GetUserDataAndInitializeIfNeeded(const int32_t userId,const int64_t timeStamp,const bool debug)294 std::shared_ptr<BundleActiveUserService> WEAK_FUNC BundleActiveCore::GetUserDataAndInitializeIfNeeded(
295     const int32_t userId, const int64_t timeStamp, const bool debug)
296 {
297     BUNDLE_ACTIVE_LOGD("GetUserDataAndInitializeIfNeeded called");
298     std::map<int, std::shared_ptr<BundleActiveUserService>>::iterator it = userStatServices_.find(userId);
299     if (it == userStatServices_.end()) {
300         BUNDLE_ACTIVE_LOGI("first initialize user service");
301         std::shared_ptr<BundleActiveUserService> service = std::make_shared<BundleActiveUserService>(userId, *this,
302             debug);
303         service->Init(timeStamp);
304         userStatServices_[userId] = service;
305         BUNDLE_ACTIVE_LOGI("service is not null");
306         return service;
307     }
308     return it->second;
309 }
310 
OnBundleUninstalled(const int32_t userId,const std::string & bundleName,const int32_t uid,const int32_t appIndex)311 void BundleActiveCore::OnBundleUninstalled(const int32_t userId, const std::string& bundleName,
312     const int32_t uid, const int32_t appIndex)
313 {
314     BUNDLE_ACTIVE_LOGD("OnBundleUninstalled CALLED");
315     std::lock_guard<ffrt::mutex> lock(mutex_);
316     int64_t timeNow = CheckTimeChangeAndGetWallTime(userId);
317     if (timeNow == ERR_TIME_OPERATION_FAILED) {
318         return;
319     }
320     auto service = GetUserDataAndInitializeIfNeeded(userId, timeNow, debugCore_);
321     if (service == nullptr) {
322         return;
323     }
324     AddbundleUninstalledUid(uid);
325     DelayRemoveBundleUninstalledUid(uid);
326     service->DeleteUninstalledBundleStats(bundleName, uid, appIndex);
327     BundleActiveGroupController::GetInstance().OnBundleUninstalled(userId, bundleName, uid, appIndex);
328 }
329 
OnBundleInstalled(const int32_t userId,const std::string & bundleName,const int32_t uid,const int32_t appIndex)330 void BundleActiveCore::OnBundleInstalled(const int32_t userId, const std::string& bundleName,
331     const int32_t uid, const int32_t appIndex)
332 {
333     BUNDLE_ACTIVE_LOGD("OnBundleInstalled CALLED");
334     std::lock_guard<ffrt::mutex> lock(bundleUninstalledMutex_);
335     if (bundleUninstalledSet_.find(uid) == bundleUninstalledSet_.end()) {
336         return;
337     }
338     bundleUninstalledSet_.erase(uid);
339     if (taskMap_.find(uid) == taskMap_.end()) {
340         return;
341     }
342     ffrt::skip(taskMap_[uid]);
343     taskMap_.erase(uid);
344 }
345 
AddbundleUninstalledUid(const int32_t uid)346 void BundleActiveCore::AddbundleUninstalledUid(const int32_t uid)
347 {
348     std::lock_guard<ffrt::mutex> lock(bundleUninstalledMutex_);
349     bundleUninstalledSet_.insert(uid);
350 }
351 
DelayRemoveBundleUninstalledUid(const int32_t uid)352 void BundleActiveCore::DelayRemoveBundleUninstalledUid(const int32_t uid)
353 {
354     auto bundleActiveCore = shared_from_this();
355     auto task = ffrt::submit_h([bundleActiveCore, uid]() {
356         std::lock_guard<ffrt::mutex> lock(bundleActiveCore->bundleUninstalledMutex_);
357         bundleActiveCore->bundleUninstalledSet_.erase(uid);
358         if (bundleActiveCore->taskMap_.find(uid) == bundleActiveCore->taskMap_.end()) {
359             return;
360         }
361         bundleActiveCore->taskMap_.erase(uid);
362         }, {}, {}, ffrt::task_attr().delay(BUNDLE_UNINSTALL_DELAY_TIME));
363     taskMap_[uid] = std::move(task);
364 }
365 
isUninstalledApp(const int32_t uid)366 bool BundleActiveCore::isUninstalledApp(const int32_t uid)
367 {
368     std::lock_guard<ffrt::mutex> lock(bundleUninstalledMutex_);
369     if (bundleUninstalledSet_.find(uid) != bundleUninstalledSet_.end()) {
370         return true;
371     }
372     return false;
373 }
374 
OnStatsChanged(const int32_t userId)375 void BundleActiveCore::OnStatsChanged(const int32_t userId)
376 {
377     auto bundleActiveReportHandler = BundleActiveReportController::GetInstance().GetBundleReportHandler();
378     if (bundleActiveReportHandler == nullptr) {
379         return;
380     }
381     BundleActiveReportHandlerObject tmpHandlerObject;
382     tmpHandlerObject.userId_ = userId;
383     std::shared_ptr<BundleActiveReportHandlerObject> handlerobjToPtr =
384         std::make_shared<BundleActiveReportHandlerObject>(tmpHandlerObject);
385     if (bundleActiveReportHandler->HasEvent(BundleActiveReportHandler::MSG_FLUSH_TO_DISK) == false) {
386         BUNDLE_ACTIVE_LOGI("OnStatsChanged send flush to disk event for user %{public}d", userId);
387         bundleActiveReportHandler->SendEvent(BundleActiveReportHandler::MSG_FLUSH_TO_DISK,
388             handlerobjToPtr, flushInterval_);
389     }
390 }
391 
RestoreAllData()392 void BundleActiveCore::RestoreAllData()
393 {
394     for (const auto& it : userStatServices_) {
395         std::shared_ptr<BundleActiveUserService> service = it.second;
396         if (service == nullptr) {
397             BUNDLE_ACTIVE_LOGI("service in BundleActiveCore::RestoreToDatabaseLocked() is null");
398             return;
399         }
400         BUNDLE_ACTIVE_LOGI("userid is %{public}d ", service->userId_);
401         service->RestoreStats(true);
402         if (BundleActiveGroupController::GetInstance().bundleUserHistory_ != nullptr) {
403             BundleActiveGroupController::GetInstance().RestoreToDatabase(it.first);
404         }
405     }
406     BundleActiveGroupController::GetInstance().RestoreDurationToDatabase();
407     auto bundleActiveReportHandler = BundleActiveReportController::GetInstance().GetBundleReportHandler();
408     if (bundleActiveReportHandler == nullptr) {
409         return;
410     }
411     BUNDLE_ACTIVE_LOGI("RestoreAllData remove flush to disk event");
412     bundleActiveReportHandler->RemoveEvent(BundleActiveReportHandler::MSG_FLUSH_TO_DISK);
413 }
414 
RestoreToDatabase(const int32_t userId)415 void BundleActiveCore::RestoreToDatabase(const int32_t userId)
416 {
417     if (IsUserSpaceMemoryLimit()) {
418         BUNDLE_ACTIVE_LOGE("The available memory in user space is too low and is not on the disk");
419         return;
420     }
421     BUNDLE_ACTIVE_LOGD("RestoreToDatabase called");
422     BundleActiveEvent event;
423     event.eventId_ = BundleActiveEvent::FLUSH;
424     event.timeStamp_ = BundleActiveUtil::GetSystemTimeMs();
425     event.abilityId_ = "";
426     auto it = userStatServices_.find(userId);
427     if (it != userStatServices_.end()) {
428         it->second->ReportEvent(event);
429     }
430     RestoreToDatabaseLocked(userId);
431     std::shared_ptr<BundleActiveCore> bundleActiveCore = shared_from_this();
432     ffrt::submit([bundleActiveCore]() {
433         if (bundleActiveCore == nullptr) {
434             return;
435         }
436         bundleActiveCore->ProcessDataSize();
437         });
438 }
439 
RestoreToDatabaseLocked(const int32_t userId)440 void BundleActiveCore::RestoreToDatabaseLocked(const int32_t userId)
441 {
442     BUNDLE_ACTIVE_LOGD("RestoreToDatabaseLocked called");
443     auto it = userStatServices_.find(userId);
444     if (it != userStatServices_.end()) {
445         it->second->RestoreStats(false);
446     }
447     BundleActiveGroupController::GetInstance().RestoreDurationToDatabase();
448     auto bundleActiveReportHandler = BundleActiveReportController::GetInstance().GetBundleReportHandler();
449     if (bundleActiveReportHandler == nullptr) {
450         return;
451     }
452     BUNDLE_ACTIVE_LOGI("RestoreToDatabaseLocked remove flush to disk event");
453     bundleActiveReportHandler->RemoveEvent(BundleActiveReportHandler::MSG_FLUSH_TO_DISK);
454 }
455 
PreservePowerStateInfo(const int32_t eventId)456 void BundleActiveCore::PreservePowerStateInfo(const int32_t eventId)
457 {
458     auto bundleActiveReportHandler = BundleActiveReportController::GetInstance().GetBundleReportHandler();
459     if (bundleActiveReportHandler == nullptr) {
460         return;
461     }
462     int32_t userId = -1;
463     std::vector<int32_t> currentActiveUser;
464     BundleActiveCore::GetAllActiveUser(currentActiveUser);
465     if (currentActiveUser.size() == 1) {
466         userId = currentActiveUser.front();
467     }
468     BundleActiveReportHandlerObject tmpHandlerObject(userId, "");
469     BundleActiveEvent newEvent;
470     tmpHandlerObject.event_ = newEvent;
471     tmpHandlerObject.event_.eventId_ = eventId;
472     sptr<MiscServices::TimeServiceClient> timer = MiscServices::TimeServiceClient::GetInstance();
473     tmpHandlerObject.event_.timeStamp_ = timer->GetBootTimeMs();
474     std::shared_ptr<BundleActiveReportHandlerObject> handlerobjToPtr =
475         std::make_shared<BundleActiveReportHandlerObject>(tmpHandlerObject);
476     bundleActiveReportHandler->SendEvent(BundleActiveReportHandler::MSG_REPORT_EVENT, handlerobjToPtr);
477 }
478 
ShutDown()479 void BundleActiveCore::ShutDown()
480 {
481     std::lock_guard<ffrt::mutex> lock(mutex_);
482     BUNDLE_ACTIVE_LOGD("ShutDown called");
483     sptr<MiscServices::TimeServiceClient> timer = MiscServices::TimeServiceClient::GetInstance();
484     int64_t timeStamp = timer->GetBootTimeMs();
485     BundleActiveEvent event(BundleActiveEvent::SHUTDOWN, timeStamp);
486     event.bundleName_ = BundleActiveEvent::DEVICE_EVENT_PACKAGE_NAME;
487     std::vector<int32_t> activatedOsAccountIds;
488     GetAllActiveUser(activatedOsAccountIds);
489     if (activatedOsAccountIds.size() == 0) {
490         BUNDLE_ACTIVE_LOGI("query activated account failed, no account activated");
491         return;
492     }
493     for (uint32_t i = 0; i < activatedOsAccountIds.size(); i++) {
494         BundleActiveGroupController::GetInstance().ShutDown(timeStamp, activatedOsAccountIds[i]);
495     }
496     ReportEventToAllUserId(event);
497     RestoreAllData();
498 }
499 
OnStatsReload()500 void BundleActiveCore::OnStatsReload()
501 {
502     BUNDLE_ACTIVE_LOGD("OnStatsReload called");
503     BundleActiveGroupController::GetInstance().CheckIdleStatsOneTime();
504 }
505 
OnSystemUpdate(int32_t userId)506 void BundleActiveCore::OnSystemUpdate(int32_t userId)
507 {
508 }
509 
CheckTimeChangeAndGetWallTime(int32_t userId)510 int64_t WEAK_FUNC BundleActiveCore::CheckTimeChangeAndGetWallTime(int32_t userId)
511 {
512     BUNDLE_ACTIVE_LOGD("CheckTimeChangeAndGetWallTime called, userId is %{public}d", userId);
513     sptr<MiscServices::TimeServiceClient> timer = MiscServices::TimeServiceClient::GetInstance();
514     int64_t actualSystemTime = BundleActiveUtil::GetSystemTimeMs();
515     int64_t actualRealTime = timer->GetBootTimeMs();
516     int64_t expectedSystemTime = (actualRealTime - realTimeShot_) + systemTimeShot_;
517     int64_t diffSystemTime = actualSystemTime - expectedSystemTime;
518     if (actualSystemTime == -1 || actualRealTime == -1) {
519         return ERR_TIME_OPERATION_FAILED;
520     }
521     BUNDLE_ACTIVE_LOGD("asystime is %{public}lld, artime is %{public}lld, esystime is %{public}lld, "
522         "diff is %{public}lld", (long long)actualSystemTime,
523         (long long)actualRealTime, (long long)expectedSystemTime, (long long)diffSystemTime);
524     if (std::abs(diffSystemTime) < TIME_CHANGE_THRESHOLD_MILLIS) {
525         //系统时间同步后,需要更新记录的开机时间戳
526         if (std::abs(diffSystemTime) > TWO_SECONDS) {
527             realTimeShot_ = actualRealTime;
528             systemTimeShot_ = actualSystemTime;
529         }
530         return actualSystemTime;
531     }
532 
533     // 时区变换逻辑
534     auto it = userStatServices_.find(userId);
535     if (it != userStatServices_.end()) {
536         BundleActiveEvent event;
537         event.eventId_ = BundleActiveEvent::FLUSH;
538         event.timeStamp_ = expectedSystemTime;
539         event.abilityId_ = "";
540         it->second->ReportEvent(event);
541         it->second->RestoreStats(true);
542         it->second->RenewTableTime(expectedSystemTime, actualSystemTime);
543         it->second->LoadActiveStats(actualSystemTime, true, true);
544         it->second->LoadModuleAndFormStats();
545         auto bundleActiveReportHandler = BundleActiveReportController::GetInstance().GetBundleReportHandler();
546         if (bundleActiveReportHandler == nullptr) {
547             return actualSystemTime;
548         }
549         BUNDLE_ACTIVE_LOGI("CheckTimeChangeAndGetWallTime remove flush to disk event");
550         bundleActiveReportHandler->RemoveEvent(BundleActiveReportHandler::MSG_FLUSH_TO_DISK);
551     }
552     realTimeShot_ = actualRealTime;
553     systemTimeShot_ = actualSystemTime;
554     return actualSystemTime;
555 }
556 
ConvertToSystemTimeLocked(BundleActiveEvent & event)557 void BundleActiveCore::ConvertToSystemTimeLocked(BundleActiveEvent& event)
558 {
559     BUNDLE_ACTIVE_LOGD("ConvertToSystemTimeLocked called");
560     event.timeStamp_ = std::max((int64_t)0, event.timeStamp_ - realTimeShot_) + systemTimeShot_;
561 }
562 
OnUserRemoved(const int32_t userId)563 void BundleActiveCore::OnUserRemoved(const int32_t userId)
564 {
565     BUNDLE_ACTIVE_LOGD("OnUserRemoved called");
566     std::lock_guard<ffrt::mutex> lock(mutex_);
567     if (MIN_USER_ID > userId || userId > AccountSA::Constants::MAX_USER_ID) {
568         return;
569     }
570     auto it = userStatServices_.find(userId);
571     if (it == userStatServices_.end()) {
572         return;
573     }
574     userStatServices_[userId]->OnUserRemoved();
575     userStatServices_[userId].reset();
576     userStatServices_.erase(userId);
577     BundleActiveGroupController::GetInstance().OnUserRemoved(userId);
578 }
579 
OnUserSwitched(const int32_t userId)580 void BundleActiveCore::OnUserSwitched(const int32_t userId)
581 {
582     sptr<MiscServices::TimeServiceClient> timer = MiscServices::TimeServiceClient::GetInstance();
583     auto it = userStatServices_.find(currentUsedUser_);
584     if (it != userStatServices_.end()) {
585         BUNDLE_ACTIVE_LOGI("restore old user id %{public}d data when switch user", currentUsedUser_);
586         BundleActiveEvent event;
587         event.eventId_ = BundleActiveEvent::FLUSH;
588         int64_t actualRealTime = timer->GetBootTimeMs();
589         event.timeStamp_ = (actualRealTime - realTimeShot_) + systemTimeShot_;
590         event.abilityId_ = "";
591         it->second->ReportEvent(event);
592         it->second->RestoreStats(true);
593     }
594     std::vector<int32_t> activatedOsAccountIds;
595     GetAllActiveUser(activatedOsAccountIds);
596     if (activatedOsAccountIds.size() == 0) {
597         BUNDLE_ACTIVE_LOGI("query activated account failed, no account activated");
598         return;
599     }
600     for (uint32_t i = 0; i < activatedOsAccountIds.size(); i++) {
601         BUNDLE_ACTIVE_LOGI("start to period check for userId %{public}d", activatedOsAccountIds[i]);
602         BundleActiveGroupController::GetInstance().OnUserSwitched(activatedOsAccountIds[i], currentUsedUser_);
603     }
604     currentUsedUser_ = userId;
605     OnStatsChanged(userId);
606 }
607 
ReportEvent(BundleActiveEvent & event,int32_t userId)608 int32_t BundleActiveCore::ReportEvent(BundleActiveEvent& event, int32_t userId)
609 {
610     BUNDLE_ACTIVE_LOGD("FLUSH interval is %{public}lld, debug is %{public}d", (long long)flushInterval_, debugCore_);
611     ObtainSystemEventName(event);
612     event.PrintEvent(debugCore_);
613     std::lock_guard<ffrt::mutex> lock(mutex_);
614     if (userId == 0 || userId == -1) {
615         return -1;
616     }
617     if (currentUsedUser_ == -1) {
618         currentUsedUser_ = userId;
619         BUNDLE_ACTIVE_LOGI("last used id change to %{public}d", currentUsedUser_);
620     }
621     sptr<MiscServices::TimeServiceClient> timer = MiscServices::TimeServiceClient::GetInstance();
622     int64_t bootBasedTimeStamp = timer->GetBootTimeMs();
623     if (BundleActiveBundleMgrHelper::GetInstance()->IsLauncherApp(event.bundleName_, userId)) {
624         BUNDLE_ACTIVE_LOGI("launcher event, only update app group");
625         BundleActiveGroupController::GetInstance().ReportEvent(event, bootBasedTimeStamp, userId);
626         return 0;
627     }
628     BUNDLE_ACTIVE_LOGD("report event called, bundle name %{public}s time %{public}lld userId %{public}d, "
629         "eventid %{public}d, in lock range", event.bundleName_.c_str(),
630         (long long)event.timeStamp_, userId, event.eventId_);
631     int64_t timeNow = CheckTimeChangeAndGetWallTime(userId);
632     if (timeNow == ERR_TIME_OPERATION_FAILED) {
633         return -1;
634     }
635     ConvertToSystemTimeLocked(event);
636     std::shared_ptr<BundleActiveUserService> service = GetUserDataAndInitializeIfNeeded(userId, timeNow, debugCore_);
637     if (service == nullptr) {
638         BUNDLE_ACTIVE_LOGE("get user data service failed!");
639         return -1;
640     }
641     if (event.eventId_ == BundleActiveEvent::FORM_IS_CLICKED ||
642         event.eventId_ == BundleActiveEvent::FORM_IS_REMOVED) {
643         service->ReportFormEvent(event);
644         return 0;
645     }
646     service->ReportModuleEvent(event);
647     service->ReportEvent(event);
648     BundleActiveGroupController::GetInstance().ReportEvent(event, bootBasedTimeStamp, userId);
649     return 0;
650 }
651 
ObtainSystemEventName(BundleActiveEvent & event)652 void BundleActiveCore::ObtainSystemEventName(BundleActiveEvent& event)
653 {
654     switch (event.eventId_) {
655         case BundleActiveEvent::SYSTEM_LOCK:
656             event.bundleName_ = OPERATION_SYSTEM_LOCK;
657             break;
658         case BundleActiveEvent::SYSTEM_UNLOCK:
659             event.bundleName_ = OPERATION_SYSTEM_UNLOCK;
660             break;
661         case BundleActiveEvent::SYSTEM_SLEEP:
662             event.bundleName_ = OPERATION_SYSTEM_SLEEP;
663             break;
664         case BundleActiveEvent::SYSTEM_WAKEUP:
665             event.bundleName_ = OPERATION_SYSTEM_WAKEUP;
666             break;
667         default:
668             break;
669     }
670 }
671 
ReportEventToAllUserId(BundleActiveEvent & event)672 int32_t BundleActiveCore::ReportEventToAllUserId(BundleActiveEvent& event)
673 {
674     BUNDLE_ACTIVE_LOGD("ReportEventToAllUserId called");
675     int64_t timeNow = CheckTimeChangeAndGetWallTime();
676     if (timeNow == ERR_TIME_OPERATION_FAILED) {
677         return -1;
678     }
679     if (userStatServices_.empty()) {
680         return DEFAULT_USER_ID;
681     }
682     for (const auto& it : userStatServices_) {
683         ConvertToSystemTimeLocked(event);
684         std::shared_ptr<BundleActiveUserService> service = GetUserDataAndInitializeIfNeeded(it.first, timeNow,
685             debugCore_);
686         if (service == nullptr) {
687             BUNDLE_ACTIVE_LOGE("get user data service failed!");
688             return -1;
689         }
690         BUNDLE_ACTIVE_LOGI("ReportEventToAllUserId SERVICE user ID IS userId %{public}d", service->userId_);
691         service->ReportForShutdown(event);
692         return 0;
693     }
694     return 0;
695 }
696 
QueryBundleStatsInfos(std::vector<BundleActivePackageStats> & packageStats,const int32_t userId,const int32_t intervalType,const int64_t beginTime,const int64_t endTime,std::string bundleName)697 ErrCode BundleActiveCore::QueryBundleStatsInfos(std::vector<BundleActivePackageStats>& packageStats,
698     const int32_t userId, const int32_t intervalType, const int64_t beginTime, const int64_t endTime,
699     std::string bundleName)
700 {
701     BUNDLE_ACTIVE_LOGD("QueryBundleStatsInfos called");
702     std::lock_guard<ffrt::mutex> lock(mutex_);
703     int64_t timeNow = CheckTimeChangeAndGetWallTime(userId);
704     if (timeNow == ERR_TIME_OPERATION_FAILED) {
705         return ERR_TIME_OPERATION_FAILED;
706     }
707 
708     BUNDLE_ACTIVE_LOGD("QueryBundleStatsInfos begin time is %{public}lld, end time is %{public}lld, "
709         "intervaltype is %{public}d", (long long)beginTime, (long long)endTime, intervalType);
710     if (beginTime > timeNow || beginTime >= endTime) {
711         BUNDLE_ACTIVE_LOGI("QueryBundleStatsInfos time span illegal");
712         return ERR_QUERY_TIME_OUT_OF_RANGE;
713     }
714 
715     std::shared_ptr<BundleActiveUserService> service = GetUserDataAndInitializeIfNeeded(userId, timeNow, debugCore_);
716     if (service == nullptr) {
717         BUNDLE_ACTIVE_LOGI("QueryBundleStatsInfos service is null, failed");
718         return ERR_MEMORY_OPERATION_FAILED;
719     }
720     return service->QueryBundleStatsInfos(packageStats, intervalType, beginTime, endTime, userId, bundleName);
721 }
722 
QueryBundleEvents(std::vector<BundleActiveEvent> & bundleActiveEvent,const int32_t userId,const int64_t beginTime,const int64_t endTime,std::string bundleName)723 ErrCode BundleActiveCore::QueryBundleEvents(std::vector<BundleActiveEvent>& bundleActiveEvent, const int32_t userId,
724     const int64_t beginTime, const int64_t endTime, std::string bundleName)
725 {
726     BUNDLE_ACTIVE_LOGD("QueryBundleEvents called");
727     std::lock_guard<ffrt::mutex> lock(mutex_);
728     int64_t timeNow = CheckTimeChangeAndGetWallTime(userId);
729     if (timeNow == ERR_TIME_OPERATION_FAILED) {
730         return ERR_TIME_OPERATION_FAILED;
731     }
732     if (beginTime > timeNow || beginTime >= endTime) {
733         return ERR_QUERY_TIME_OUT_OF_RANGE;
734     }
735     std::shared_ptr<BundleActiveUserService> service = GetUserDataAndInitializeIfNeeded(userId, timeNow, debugCore_);
736     if (service == nullptr) {
737         return ERR_MEMORY_OPERATION_FAILED;
738     }
739     auto item = service->QueryBundleEvents(bundleActiveEvent, beginTime, endTime, userId, bundleName);
740     return item;
741 }
742 
QueryModuleUsageRecords(int32_t maxNum,std::vector<BundleActiveModuleRecord> & results,int32_t userId)743 ErrCode BundleActiveCore::QueryModuleUsageRecords(int32_t maxNum, std::vector<BundleActiveModuleRecord>& results,
744     int32_t userId)
745 {
746     std::lock_guard<ffrt::mutex> lock(mutex_);
747     int64_t timeNow = CheckTimeChangeAndGetWallTime(userId);
748     if (timeNow == ERR_TIME_OPERATION_FAILED) {
749         return ERR_TIME_OPERATION_FAILED;
750     }
751     std::shared_ptr<BundleActiveUserService> service = GetUserDataAndInitializeIfNeeded(userId, timeNow, debugCore_);
752     if (!service) {
753         return ERR_MEMORY_OPERATION_FAILED;
754     }
755     return service->QueryModuleUsageRecords(maxNum, results);
756 }
757 
QueryDeviceEventStats(int64_t beginTime,int64_t endTime,std::vector<BundleActiveEventStats> & eventStats,int32_t userId)758 ErrCode BundleActiveCore::QueryDeviceEventStats(int64_t beginTime, int64_t endTime,
759     std::vector<BundleActiveEventStats>& eventStats, int32_t userId)
760 {
761     std::lock_guard<ffrt::mutex> lock(mutex_);
762     int64_t timeNow = CheckTimeChangeAndGetWallTime(userId);
763     if (timeNow == ERR_TIME_OPERATION_FAILED) {
764         return ERR_TIME_OPERATION_FAILED;
765     }
766     std::shared_ptr<BundleActiveUserService> service = GetUserDataAndInitializeIfNeeded(userId, timeNow, debugCore_);
767     if (!service) {
768         return ERR_MEMORY_OPERATION_FAILED;
769     }
770     return service->QueryDeviceEventStats(beginTime, endTime, eventStats, userId);
771 }
772 
QueryNotificationEventStats(int64_t beginTime,int64_t endTime,std::vector<BundleActiveEventStats> & eventStats,int32_t userId)773 ErrCode BundleActiveCore::QueryNotificationEventStats(int64_t beginTime, int64_t endTime,
774     std::vector<BundleActiveEventStats>& eventStats, int32_t userId)
775 {
776     std::lock_guard<ffrt::mutex> lock(mutex_);
777     int64_t timeNow = CheckTimeChangeAndGetWallTime(userId);
778     if (timeNow == ERR_TIME_OPERATION_FAILED) {
779         return ERR_TIME_OPERATION_FAILED;
780     }
781     std::shared_ptr<BundleActiveUserService> service = GetUserDataAndInitializeIfNeeded(userId, timeNow, debugCore_);
782     if (!service) {
783         return ERR_MEMORY_OPERATION_FAILED;
784     }
785     return service->QueryNotificationEventStats(beginTime, endTime, eventStats, userId);
786 }
787 
SetAppGroup(const std::string & bundleName,const int32_t newGroup,const int32_t userId,const bool isFlush)788 ErrCode BundleActiveCore::SetAppGroup(
789     const std::string& bundleName, const int32_t newGroup, const int32_t userId, const bool isFlush)
790 {
791     int32_t newReason = GROUP_CONTROL_REASON_FORCED;
792     sptr<MiscServices::TimeServiceClient> timer = MiscServices::TimeServiceClient::GetInstance();
793     int64_t bootBasedTimeStamp = timer->GetBootTimeMs();
794     return BundleActiveGroupController::GetInstance().SetAppGroup(
795         bundleName, userId, newGroup, newReason, bootBasedTimeStamp, isFlush);
796 }
797 
QueryAppGroup(int32_t & appGroup,const std::string & bundleName,const int32_t userId)798 ErrCode BundleActiveCore::QueryAppGroup(int32_t& appGroup, const std::string& bundleName, const int32_t userId)
799 {
800     return BundleActiveGroupController::GetInstance().QueryAppGroup(appGroup, bundleName, userId);
801 }
802 
IsBundleIdle(const std::string & bundleName,const int32_t userId)803 int32_t BundleActiveCore::IsBundleIdle(const std::string& bundleName, const int32_t userId)
804 {
805     return BundleActiveGroupController::GetInstance().IsBundleIdle(bundleName, userId);
806 }
807 
IsBundleUsePeriod(const std::string & bundleName,const int32_t userId)808 bool BundleActiveCore::IsBundleUsePeriod(const std::string& bundleName, const int32_t userId)
809 {
810     if (!BundleActiveGroupController::GetInstance().IsBundleInstalled(bundleName, userId)) {
811         BUNDLE_ACTIVE_LOGI("IsBundleUsePeriod is not bundleInstalled");
812         return false;
813     }
814     if (BundleActiveGroupController::GetInstance().IsUsedOverOneWeek(bundleName, userId)) {
815         return true;
816     }
817     int64_t currentSystemTime = BundleActiveUtil::GetSystemTimeMs();
818     int64_t aWeekAgo = currentSystemTime - ONE_WEEK_TIME;
819     int64_t startTime = BundleActiveUtil::GetIntervalTypeStartTime(aWeekAgo, BundleActiveUtil::PERIOD_DAILY);
820     std::vector<BundleActivePackageStats> packageStats;
821     QueryBundleStatsInfos(packageStats, userId, BundleActivePeriodStats::PERIOD_DAILY, startTime,
822         currentSystemTime, bundleName);
823     int32_t useDayPeriod = 0;
824     for (auto& item : packageStats) {
825         if (item.startCount_ >= bundleActiveConfigReader_->GetApplicationUsePeriodicallyConfig().minUseTimes
826             && item.startCount_ <= bundleActiveConfigReader_->GetApplicationUsePeriodicallyConfig().maxUseTimes) {
827             useDayPeriod ++;
828         }
829     }
830     return useDayPeriod >= bundleActiveConfigReader_->GetApplicationUsePeriodicallyConfig().minUseDays;
831 }
832 
GetAllActiveUser(std::vector<int32_t> & activatedOsAccountIds)833 void BundleActiveCore::GetAllActiveUser(std::vector<int32_t>& activatedOsAccountIds)
834 {
835 #ifdef OS_ACCOUNT_PART_ENABLED
836     if (AccountSA::OsAccountManager::QueryActiveOsAccountIds(activatedOsAccountIds) != ERR_OK) {
837         BUNDLE_ACTIVE_LOGI("query activated account failed");
838         return;
839     }
840 #else // OS_ACCOUNT_PART_ENABLED
841     activatedOsAccountIds.clear();
842     activatedOsAccountIds.push_back(DEFAULT_OS_ACCOUNT_ID);
843     BUNDLE_ACTIVE_LOGI("os account part is not enabled, use default id.");
844 #endif // OS_ACCOUNT_PART_ENABLED
845     if (activatedOsAccountIds.size() == 0) {
846         BUNDLE_ACTIVE_LOGI("GetAllActiveUser size is 0");
847         return;
848     }
849 }
850 
OnAppGroupChanged(const AppGroupCallbackInfo & callbackInfo)851 void BundleActiveCore::OnAppGroupChanged(const AppGroupCallbackInfo& callbackInfo)
852 {
853     std::shared_ptr<BundleActiveCore> bundleActiveCore = shared_from_this();
854     AccessToken::HapTokenInfo tokenInfo = AccessToken::HapTokenInfo();
855     auto bundleGroupHandler = BundleActiveGroupController::GetInstance().GetBundleGroupHandler();
856     if (bundleGroupHandler != nullptr) {
857         bundleGroupHandler->PostTask([bundleActiveCore, callbackInfo, tokenInfo]() {
858             bundleActiveCore->NotifOberserverGroupChanged(callbackInfo, tokenInfo);
859         });
860     }
861 
862     HiSysEventWrite(RSS,
863         "UPDATE_GROUP_SCENE", HiviewDFX::HiSysEvent::EventType::STATISTIC,
864         "UPDATE_GROUP_BUNDLENAME", callbackInfo.GetBundleName(),
865         "UPDATE_GROUP_USERID", callbackInfo.GetUserId(),
866         "UPDATE_GROUP_REASON", callbackInfo.GetChangeReason(),
867         "UPDATE_GROUP_TIME", BundleActiveUtil::GetSystemTimeMs(),
868         "UPDATE_GROUP_OLD_GROUP", callbackInfo.GetOldGroup(),
869         "UPDATE_GROUP_NEW_GROUP", callbackInfo.GetNewGroup());
870 }
871 
NotifOberserverGroupChanged(const AppGroupCallbackInfo & callbackInfo,AccessToken::HapTokenInfo tokenInfo)872 void BundleActiveCore::NotifOberserverGroupChanged(const AppGroupCallbackInfo& callbackInfo,
873     AccessToken::HapTokenInfo tokenInfo)
874 {
875     std::lock_guard<ffrt::recursive_mutex> lock(callbackMutex_);
876     for (const auto &item : groupChangeObservers_) {
877         auto observer = item.second;
878         if (!observer) {
879             continue;
880         }
881         BUNDLE_ACTIVE_LOGI(
882             "RegisterAppGroupCallBack will OnAppGroupChanged!,oldGroup is %{public}d, newGroup is %{public}d",
883             callbackInfo.GetOldGroup(), callbackInfo.GetNewGroup());
884         if (AccessToken::AccessTokenKit::GetTokenType(item.first) == AccessToken::ATokenTypeEnum::TOKEN_NATIVE) {
885             observer->OnAppGroupChanged(callbackInfo);
886         } else if (AccessToken::AccessTokenKit::GetTokenType(item.first) ==
887                     AccessToken::ATokenTypeEnum::TOKEN_HAP) {
888             AccessToken::AccessTokenKit::GetHapTokenInfo(item.first, tokenInfo);
889             if (tokenInfo.userID == callbackInfo.GetUserId()) {
890                 observer->OnAppGroupChanged(callbackInfo);
891             }
892         }
893     }
894 }
895 
RegisterAppGroupCallBack(const AccessToken::AccessTokenID & tokenId,const sptr<IAppGroupCallback> & observer)896 ErrCode BundleActiveCore::RegisterAppGroupCallBack(const AccessToken::AccessTokenID& tokenId,
897     const sptr<IAppGroupCallback> &observer)
898 {
899     std::lock_guard<ffrt::recursive_mutex> lock(callbackMutex_);
900     if (!observer) {
901         return ERR_MEMORY_OPERATION_FAILED;
902     }
903     auto item = groupChangeObservers_.find(tokenId);
904     if (item != groupChangeObservers_.end()) {
905         return ERR_REPEAT_REGISTER_OR_DEREGISTER_GROUP_CALLBACK;
906     }
907     groupChangeObservers_.emplace(tokenId, observer);
908     AddObserverDeathRecipient(observer);
909     BUNDLE_ACTIVE_LOGD("RegisterAppGroupCallBack number is %{public}d", static_cast<int>(groupChangeObservers_.size()));
910     return ERR_OK;
911 }
912 
UnRegisterAppGroupCallBack(const AccessToken::AccessTokenID & tokenId,const sptr<IAppGroupCallback> & observer)913 ErrCode BundleActiveCore::UnRegisterAppGroupCallBack(const AccessToken::AccessTokenID& tokenId,
914     const sptr<IAppGroupCallback> &observer)
915 {
916     std::lock_guard<ffrt::recursive_mutex> lock(callbackMutex_);
917     auto item = groupChangeObservers_.find(tokenId);
918     if (item == groupChangeObservers_.end()) {
919         BUNDLE_ACTIVE_LOGI("UnRegisterAppGroupCallBack observer is not exist, return");
920         return ERR_REPEAT_REGISTER_OR_DEREGISTER_GROUP_CALLBACK;
921     }
922     RemoveObserverDeathRecipient(item->second);
923     groupChangeObservers_.erase(tokenId);
924     return ERR_OK;
925 }
926 
AddObserverDeathRecipient(const sptr<IAppGroupCallback> & observer)927 void BundleActiveCore::AddObserverDeathRecipient(const sptr<IAppGroupCallback> &observer)
928 {
929     std::lock_guard<ffrt::recursive_mutex> lock(callbackMutex_);
930     if (!observer) {
931         BUNDLE_ACTIVE_LOGI("observer nullptr.");
932         return;
933     }
934     auto object = observer->AsObject();
935     if (!object) {
936         BUNDLE_ACTIVE_LOGI("observer->AsObject() nullptr.");
937         return;
938     }
939     auto it = recipientMap_.find(observer->AsObject());
940     if (it != recipientMap_.end()) {
941         BUNDLE_ACTIVE_LOGI("This death recipient has been added.");
942         return;
943     }
944     sptr<RemoteDeathRecipient> deathRecipient = new (std::nothrow) RemoteDeathRecipient(
945         [this](const wptr<IRemoteObject> &remote) { this->OnObserverDied(remote); });
946     if (!deathRecipient) {
947         BUNDLE_ACTIVE_LOGI("create death recipient failed");
948         return ;
949     }
950     observer->AsObject()->AddDeathRecipient(deathRecipient);
951     recipientMap_.emplace(observer->AsObject(), deathRecipient);
952 }
RemoveObserverDeathRecipient(const sptr<IAppGroupCallback> & observer)953 void BundleActiveCore::RemoveObserverDeathRecipient(const sptr<IAppGroupCallback> &observer)
954 {
955     std::lock_guard<ffrt::recursive_mutex> lock(callbackMutex_);
956     if (!observer) {
957         return;
958     }
959     auto object = observer->AsObject();
960     if (!object) {
961         return ;
962     }
963     auto iter = recipientMap_.find(observer->AsObject());
964     if (iter != recipientMap_.end()) {
965         iter->first->RemoveDeathRecipient(iter->second);
966         recipientMap_.erase(iter);
967     }
968 }
969 
OnObserverDied(const wptr<IRemoteObject> & remote)970 void BundleActiveCore::OnObserverDied(const wptr<IRemoteObject> &remote)
971 {
972     if (remote == nullptr) {
973         BUNDLE_ACTIVE_LOGE("remote object is null.");
974         return;
975     }
976     std::shared_ptr<BundleActiveCore> bundleActiveCore = shared_from_this();
977     auto bundleGroupHandler = BundleActiveGroupController::GetInstance().GetBundleGroupHandler();
978     if (bundleGroupHandler == nullptr) {
979         return;
980     }
981     bundleGroupHandler->PostSyncTask([bundleActiveCore, &remote]() {
982         bundleActiveCore->OnObserverDiedInner(remote);
983     });
984 }
985 
OnObserverDiedInner(const wptr<IRemoteObject> & remote)986 void BundleActiveCore::OnObserverDiedInner(const wptr<IRemoteObject> &remote)
987 {
988     sptr<IRemoteObject> objectProxy = remote.promote();
989     if (remote == nullptr || !objectProxy) {
990         BUNDLE_ACTIVE_LOGE("get remote object failed");
991         return;
992     }
993     std::lock_guard<ffrt::recursive_mutex> lock(callbackMutex_);
994     for (const auto& item : groupChangeObservers_) {
995         if (!(item.second)) {
996             continue;
997         }
998         auto object = (item.second)->AsObject();
999         if (!object) {
1000             continue;
1001         }
1002         if (object == objectProxy) {
1003             groupChangeObservers_.erase(item.first);
1004             break;
1005         }
1006     }
1007     recipientMap_.erase(objectProxy);
1008 }
1009 
IsUserSpaceMemoryLimit()1010 bool BundleActiveCore::IsUserSpaceMemoryLimit()
1011 {
1012     return BundleActiveUtil::GetPercentOfAvailableUserSpace(DATA_PATH) <= percentUserSpaceLimit_;
1013 }
1014 
ProcessDataSize()1015 void BundleActiveCore::ProcessDataSize()
1016 {
1017     if (!bundleActiveConfigReader_ || !IsFolderSizeLimit()) {
1018         return;
1019     }
1020     DeleteExcessiveTableData();
1021 }
1022 
IsFolderSizeLimit()1023 bool BundleActiveCore::IsFolderSizeLimit()
1024 {
1025     return BundleActiveUtil::GetFolderOrFileSize(BUNDLE_ACTIVE_DATABASE_DIR) >=
1026         bundleActiveConfigReader_->GetMaxDataSize();
1027 }
1028 
DeleteExcessiveTableData()1029 void BundleActiveCore::DeleteExcessiveTableData()
1030 {
1031     std::lock_guard<ffrt::mutex> lock(mutex_);
1032     auto it = userStatServices_.find(currentUsedUser_);
1033     if (it == userStatServices_.end()) {
1034         BUNDLE_ACTIVE_LOGE("currentUsedUser_ is not exit, delete exceeive table data failed");
1035         return;
1036     }
1037     for (int32_t deleteDays = DEFAULT_DELETE_EVENT_DALIYS; deleteDays <= MAX_DELETE_EVENT_DALIYS; deleteDays++) {
1038         it->second->DeleteExcessiveEventTableData(deleteDays);
1039         if (!IsFolderSizeLimit()) {
1040             return;
1041         }
1042     }
1043 }
1044 
QueryHighFrequencyPeriodBundle(std::vector<BundleActiveHighFrequencyPeriod> & appFreqHours,int32_t userId)1045 ErrCode BundleActiveCore::QueryHighFrequencyPeriodBundle(
1046     std::vector<BundleActiveHighFrequencyPeriod>& appFreqHours, int32_t userId)
1047 {
1048     BUNDLE_ACTIVE_LOGD("QueryHighFrequencyPeriodBundle called");
1049     std::lock_guard<ffrt::mutex> lock(mutex_);
1050     int64_t timeNow = CheckTimeChangeAndGetWallTime(userId);
1051     if (timeNow == ERR_TIME_OPERATION_FAILED) {
1052         return ERR_TIME_OPERATION_FAILED;
1053     }
1054     std::shared_ptr<BundleActiveUserService> service = GetUserDataAndInitializeIfNeeded(userId, timeNow, debugCore_);
1055     if (service == nullptr) {
1056         return ERR_MEMORY_OPERATION_FAILED;
1057     }
1058     int64_t currentSystemTime = BundleActiveUtil::GetSystemTimeMs();
1059     int64_t aWeekAgo = currentSystemTime - ONE_WEEK_TIME;
1060     std::vector<BundleActiveEvent> bundleActiveEvents;
1061     auto res = service->QueryBundleEvents(bundleActiveEvents, aWeekAgo, currentSystemTime, userId, "");
1062     if (res != ERR_OK) {
1063         BUNDLE_ACTIVE_LOGE("QueryHighFrequencyPeriodBundle QueryBundleEvents fail");
1064         return res;
1065     }
1066     std::unordered_map<std::string, BundleActiveCore::AppUsage> appUsages;
1067     // 解析前台事件,记录应用使用时段数据
1068     ProcessEvents(appUsages, bundleActiveEvents);
1069     // 获取高频时段使用应用信息
1070     GetFreqBundleHours(appFreqHours, appUsages);
1071     return res;
1072 }
1073 
GetFreqBundleHours(std::vector<BundleActiveHighFrequencyPeriod> & appFreqHours,std::unordered_map<std::string,BundleActiveCore::AppUsage> & appUsages)1074 void BundleActiveCore::GetFreqBundleHours(std::vector<BundleActiveHighFrequencyPeriod>& appFreqHours,
1075     std::unordered_map<std::string, BundleActiveCore::AppUsage>& appUsages)
1076 {
1077     BUNDLE_ACTIVE_LOGD("BundleActiveCore GetFreqBundleHours appUsages size: %{public}zu", appUsages.size());
1078     for (auto& [appName, usage] : appUsages) {
1079         // 统计应用一周内的使用天数
1080         int32_t totalDayUse = 0;
1081         for (int32_t i = 0; i < NUM_DAY_ONE_WEEK; i++) {
1082             if (usage.dayUsage[i] != 0) {
1083                 totalDayUse++;
1084             }
1085         }
1086         // 若一周内的使用天数不满足阈值minTotalUseDays, 则判断为非周期性使用应用
1087         if (totalDayUse < bundleActiveConfigReader_->GetAppHighFrequencyPeriodThresholdConfig().minTotalUseDays) {
1088             continue;
1089         }
1090         // 统计应用每个时段 一周内的使用天数,只取满足使用天数限制的时段信息
1091         std::vector<std::vector<int32_t>> topHoursUsage;
1092         GetTopHourUsage(topHoursUsage, usage);
1093         if (topHoursUsage.size() > 0) {
1094             // 按使用天数降序排序
1095             std::sort(topHoursUsage.begin(),
1096                 topHoursUsage.end(),
1097                 [](const std::vector<int32_t>& hourUsageA, const std::vector<int32_t> &hourUsageB) {
1098                     return hourUsageA[INDEX_USE_TIME] > hourUsageB[INDEX_USE_TIME];
1099                 });
1100             uint64_t maxHighFreqHourNum = static_cast<uint64_t>(
1101                 bundleActiveConfigReader_->GetAppHighFrequencyPeriodThresholdConfig().maxHighFreqHourNum);
1102             // 只取使用天数最多的前TOPN个时段
1103             if (topHoursUsage.size() > maxHighFreqHourNum) {
1104                 topHoursUsage.erase(topHoursUsage.begin() + maxHighFreqHourNum, topHoursUsage.end());
1105             }
1106             std::vector<int32_t> hourColumn;
1107             for (const auto& hourUsage : topHoursUsage) {
1108                 hourColumn.push_back(hourUsage[INDEX_HOUR]);
1109             }
1110             appFreqHours.emplace_back(appName, hourColumn);
1111         }
1112     }
1113 }
1114 
GetTopHourUsage(std::vector<std::vector<int32_t>> & topHoursUsage,BundleActiveCore::AppUsage & usage)1115 void BundleActiveCore::GetTopHourUsage(
1116     std::vector<std::vector<int32_t>>& topHoursUsage, BundleActiveCore::AppUsage& usage)
1117 {
1118     std::vector<ElementWithIndex> elementsWithIndices(NUM_HOUR_ONE_DAY);
1119     for (int32_t i = 0; i < NUM_HOUR_ONE_DAY; i++) {
1120         elementsWithIndices[i] = {usage.hourTotalUse[i], i};
1121     }
1122     sort(elementsWithIndices.begin(),
1123         elementsWithIndices.end(),
1124         [](const ElementWithIndex& hourUseTimeA, const ElementWithIndex& hourUseTimeB) {
1125             return hourUseTimeA.useTimes > hourUseTimeB.useTimes;
1126         });
1127     int32_t minTopUseHoursLimit =
1128         bundleActiveConfigReader_->GetAppHighFrequencyPeriodThresholdConfig().minTopUseHoursLimit;
1129     for (int32_t i = 0; i < minTopUseHoursLimit; i++) {
1130         int32_t hour = elementsWithIndices[i].originlIndex;
1131         int32_t hourUseDays = 0;
1132         for (int32_t weekDay = 0; weekDay < NUM_DAY_ONE_WEEK; weekDay++) {
1133             if (usage.hourUsage[weekDay][hour] > 0) {
1134                 hourUseDays++;
1135             }
1136         }
1137         if (hourUseDays >= bundleActiveConfigReader_->GetAppHighFrequencyPeriodThresholdConfig().minHourUseDays) {
1138             topHoursUsage.emplace_back(std::vector<int32_t>{hour, hourUseDays});
1139         }
1140     }
1141 }
1142 
ProcessEvents(std::unordered_map<std::string,AppUsage> & appUsages,std::vector<BundleActiveEvent> & events)1143 void BundleActiveCore::ProcessEvents(
1144     std::unordered_map<std::string, AppUsage>& appUsages, std::vector<BundleActiveEvent>& events)
1145 {
1146     BUNDLE_ACTIVE_LOGD("BundleActiveCore ProcessEvent events size: %{public}zu", events.size());
1147     for (size_t i = 0; i < events.size(); ++i) {
1148         std::string bundleName = events[i].bundleName_;
1149         if (events[i].eventId_ == BundleActiveEvent::ABILITY_FOREGROUND) {
1150             auto [it, inserted] = appUsages.emplace(bundleName, BundleActiveCore::AppUsage());
1151             if (it->second.startTime == DEFAULT_INVALID_VALUE) {
1152                 it->second.startTime = events[i].timeStamp_;
1153             }
1154         } else if (events[i].eventId_ == BundleActiveEvent::ABILITY_BACKGROUND ||
1155                    events[i].eventId_ == BundleActiveEvent::ABILITY_STOP) {
1156             auto it = appUsages.find(bundleName);
1157             if (it == appUsages.end() || it->second.startTime == DEFAULT_INVALID_VALUE) {
1158                 continue;
1159             }
1160             // 转换成以秒为单位
1161             const time_t timestampSeconds = it->second.startTime / 1000;
1162             // 转换为tm结构体以获取详细信息
1163             std::tm* startTimeTm = std::localtime(&timestampSeconds);
1164             if (startTimeTm == nullptr) {
1165                 it->second.startTime = DEFAULT_INVALID_VALUE;
1166                 continue;
1167             }
1168             // 获取星期几(0=周日, 6=周六)
1169             int32_t weekDay = startTimeTm->tm_wday;
1170             int32_t hour = startTimeTm->tm_hour;
1171             it->second.dayUsage[weekDay]++;
1172             it->second.hourUsage[weekDay][hour]++;
1173             it->second.hourTotalUse[hour]++;
1174             it->second.startTime = DEFAULT_INVALID_VALUE;
1175         }
1176     }
1177 }
1178 }  // namespace DeviceUsageStats
1179 }  // namespace OHOS
1180 
1181