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(×tampSeconds);
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