1 /*
2 * Copyright (c) 2022 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 "aging/bundle_aging_mgr.h"
16
17 #include "account_helper.h"
18 #include "battery_srv_client.h"
19 #include "bundle_active_period_stats.h"
20 #include "bundle_mgr_service.h"
21 #include "bundle_util.h"
22 #include "display_power_mgr_client.h"
23 #include "parameter.h"
24
25 namespace OHOS {
26 namespace AppExecFwk {
BundleAgingMgr()27 BundleAgingMgr::BundleAgingMgr()
28 {
29 InitAgingHandlerChain();
30 APP_LOGI("BundleAgingMgr is created.");
31 }
32
~BundleAgingMgr()33 BundleAgingMgr::~BundleAgingMgr()
34 {
35 APP_LOGI("BundleAgingMgr is destroyed");
36 }
37
InitAgingRunner()38 void BundleAgingMgr::InitAgingRunner()
39 {
40 auto agingRunner = EventRunner::Create(AgingConstants::AGING_THREAD);
41 if (agingRunner == nullptr) {
42 APP_LOGE("create aging runner failed");
43 return;
44 }
45 SetEventRunner(agingRunner);
46 }
InitAgingTimerInterval()47 void BundleAgingMgr::InitAgingTimerInterval()
48 {
49 char szTimerThresold[AgingConstants::THRESHOLD_VAL_LEN] = {0};
50 int32_t ret = GetParameter(AgingConstants::SYSTEM_PARAM_AGING_TIMER_INTERVAL.c_str(), "", szTimerThresold,
51 AgingConstants::THRESHOLD_VAL_LEN);
52 APP_LOGD("ret is %{public}d, szTimerThresold is %{public}d", ret, atoi(szTimerThresold));
53 if (ret <= 0) {
54 APP_LOGD("GetParameter failed");
55 return;
56 }
57 if (strcmp(szTimerThresold, "") != 0) {
58 agingTimerInterval = atoi(szTimerThresold);
59 APP_LOGD("BundleAgingMgr init aging timer success");
60 }
61 }
62
InitAgingBatteryThresold()63 void BundleAgingMgr::InitAgingBatteryThresold()
64 {
65 char szBatteryThresold[AgingConstants::THRESHOLD_VAL_LEN] = {0};
66 int32_t ret = GetParameter(AgingConstants::SYSTEM_PARAM_AGING_BATTER_THRESHOLD.c_str(), "", szBatteryThresold,
67 AgingConstants::THRESHOLD_VAL_LEN);
68 APP_LOGD("ret is %{public}d, szBatteryThresold is %{public}d", ret, atoi(szBatteryThresold));
69 if (ret <= 0) {
70 APP_LOGD("GetParameter failed");
71 return;
72 }
73 if (strcmp(szBatteryThresold, "") != 0) {
74 agingBatteryThresold = atoi(szBatteryThresold);
75 APP_LOGD("BundleAgingMgr init battery threshold success");
76 }
77 }
78
InitAgingtTimer()79 void BundleAgingMgr::InitAgingtTimer()
80 {
81 InitAgingBatteryThresold();
82 InitAgingTimerInterval();
83 bool isEventStarted = SendEvent(InnerEvent::Get(EVENT_AGING_NOW), agingTimerInterval);
84 if (!isEventStarted) {
85 APP_LOGE("faild to send event is not started");
86 {
87 std::lock_guard<std::mutex> lock(mutex_);
88 running = false;
89 }
90 }
91 }
92
AgingQueryFormStatistics(std::vector<DeviceUsageStats::BundleActiveModuleRecord> & results,const std::shared_ptr<BundleDataMgr> & dataMgr)93 int BundleAgingMgr::AgingQueryFormStatistics(std::vector<DeviceUsageStats::BundleActiveModuleRecord>& results,
94 const std::shared_ptr<BundleDataMgr> &dataMgr)
95 {
96 int32_t userId = AccountHelper::GetCurrentActiveUserId();
97 int ret = DeviceUsageStats::BundleActiveClient::GetInstance().QueryModuleUsageRecords(
98 AgingConstants::COUNT_MODULE_RECODES_GET, results, userId);
99 APP_LOGD("activeModuleRecord size %{public}zu, ret:%{public}d", results.size(), ret);
100 return ret;
101 }
102
ReInitAgingRequest(const std::shared_ptr<BundleDataMgr> & dataMgr)103 bool BundleAgingMgr::ReInitAgingRequest(const std::shared_ptr<BundleDataMgr> &dataMgr)
104 {
105 if (dataMgr == nullptr) {
106 APP_LOGE("ReInitAgingRequest: dataMgr is null");
107 return false;
108 }
109 request.RequestReset();
110 std::map<std::string, int> bundleNamesAndUid;
111 dataMgr->GetRemovableBundleNameVec(bundleNamesAndUid);
112 if (bundleNamesAndUid.empty()) {
113 APP_LOGE("ReInitAgingRequest: no removable bundles");
114 return false;
115 }
116 APP_LOGD("ReInitAgingRequest: removable bundles size %{public}zu", bundleNamesAndUid.size());
117
118 std::vector<DeviceUsageStats::BundleActiveModuleRecord> activeModuleRecord;
119 int ret = AgingQueryFormStatistics(activeModuleRecord, dataMgr);
120 if (ret != 0) {
121 APP_LOGE("ReInitAgingRequest: can not get bundle active module record");
122 return false;
123 }
124 int64_t lastLaunchTimesMs = AgingUtil::GetNowSysTimeMs();
125 APP_LOGD("now: %{public}" PRId64, lastLaunchTimesMs);
126 for (auto iter : bundleNamesAndUid) {
127 int64_t dataBytes = dataMgr->GetBundleSpaceSize(iter.first);
128 // the value of lastLaunchTimesMs get from lastLaunchTimesMs interface
129 int64_t lastBundleUsedTime = 0;
130 for (const auto &moduleRecord : activeModuleRecord) {
131 APP_LOGD("%{public}s: %{public}" PRId64, moduleRecord.bundleName_.c_str(),
132 moduleRecord.lastModuleUsedTime_);
133 if (moduleRecord.bundleName_ == iter.first && lastBundleUsedTime < moduleRecord.lastModuleUsedTime_) {
134 lastBundleUsedTime = moduleRecord.lastModuleUsedTime_;
135 }
136 }
137 if (lastBundleUsedTime) {
138 APP_LOGD("%{public}s: %{public}" PRId64, iter.first.c_str(), lastBundleUsedTime);
139 AgingBundleInfo agingBundleInfo(iter.first, lastBundleUsedTime, dataBytes, iter.second);
140 request.AddAgingBundle(agingBundleInfo);
141 } else {
142 APP_LOGD("%{public}s: %{public}" PRId64, iter.first.c_str(), lastLaunchTimesMs);
143 AgingBundleInfo agingBundleInfo(iter.first, lastLaunchTimesMs, dataBytes, iter.second);
144 request.AddAgingBundle(agingBundleInfo);
145 }
146 }
147 request.SetTotalDataBytes(dataMgr->GetAllFreeInstallBundleSpaceSize());
148 return request.SortAgingBundles() > 0;
149 }
150
Process(const std::shared_ptr<BundleDataMgr> & dataMgr)151 void BundleAgingMgr::Process(const std::shared_ptr<BundleDataMgr> &dataMgr)
152 {
153 APP_LOGD("BundleAging begin to process.");
154 if (ReInitAgingRequest(dataMgr)) {
155 if (request.IsReachStartAgingThreshold()) {
156 chain.Process(request);
157 }
158 }
159 {
160 std::lock_guard<std::mutex> lock(mutex_);
161 running = false;
162 }
163 APP_LOGD("BundleAgingMgr Process done");
164 }
165
Start(AgingTriggertype type)166 void BundleAgingMgr::Start(AgingTriggertype type)
167 {
168 APP_LOGD("aging start, AgingTriggertype: %{public}d", type);
169 if (!CheckPrerequisite(type)) {
170 APP_LOGE("BundleAgingMgr aging Prerequisite is not satisfied");
171 return;
172 }
173
174 auto dataMgr = OHOS::DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
175 if (dataMgr == nullptr) {
176 APP_LOGE("dataMgr is null");
177 return;
178 }
179 {
180 std::lock_guard<std::mutex> lock(mutex_);
181 if (running) {
182 APP_LOGD("BundleAgingMgr is running, no need to start is again");
183 return;
184 }
185 running = true;
186 }
187
188 auto task = [&, dataMgr]() { Process(dataMgr); };
189 bool isEventStarted = SendEvent(InnerEvent::Get(task));
190 if (!isEventStarted) {
191 APP_LOGE("BundleAgingMgr event is not started.");
192 {
193 std::lock_guard<std::mutex> lock(mutex_);
194 running = false;
195 }
196 } else {
197 APP_LOGD("BundleAgingMgr schedule process done");
198 }
199 }
200
CheckPrerequisite(AgingTriggertype type) const201 bool BundleAgingMgr::CheckPrerequisite(AgingTriggertype type) const
202 {
203 if (type != AgingTriggertype::PREIOD) {
204 return true;
205 }
206 DisplayPowerMgr::DisplayState state = DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().GetDisplayState();
207 if (state == DisplayPowerMgr::DisplayState::DISPLAY_ON) {
208 APP_LOGD("current Displaystate is DisplayState::DISPLAY_ON");
209 return false;
210 }
211 int32_t currentBatteryCap = OHOS::PowerMgr::BatterySrvClient::GetInstance().GetCapacity();
212 APP_LOGD("current GetCapacity is %{public}d agingBatteryThresold: %{public}" PRId64,
213 currentBatteryCap, agingBatteryThresold);
214 return currentBatteryCap > agingBatteryThresold;
215 }
216
ProcessEvent(const InnerEvent::Pointer & event)217 void BundleAgingMgr::ProcessEvent(const InnerEvent::Pointer &event)
218 {
219 uint32_t eventId = event->GetInnerEventId();
220 APP_LOGD("BundleAgingMgr process event : %{public}u", eventId);
221 switch (eventId) {
222 case EVENT_AGING_NOW:
223 APP_LOGD("BundleAgingMgr timer expire, run aging now.");
224 Start(AgingTriggertype::PREIOD);
225 SendEvent(eventId, 0, agingTimerInterval);
226 APP_LOGD("BundleAginMgr reschedule time.");
227 break;
228
229 default:
230 APP_LOGD("BundleAgingMgr invalid Event %{public}d.", eventId);
231 break;
232 }
233 }
234
InitAgingHandlerChain()235 void BundleAgingMgr::InitAgingHandlerChain()
236 {
237 chain = AgingHandlerChain();
238 chain.AddHandler(std::make_shared<Over30DaysUnusedBundleAgingHandler>());
239 chain.AddHandler(std::make_shared<Over20DaysUnusedBundleAgingHandler>());
240 chain.AddHandler(std::make_shared<Over10DaysUnusedBundleAgingHandler>());
241 chain.AddHandler(std::make_shared<BundleDataSizeAgingHandler>());
242 APP_LOGD("InitAgingHandleChain is finished.");
243 }
244 } // namespace AppExecFwk
245 } // namespace OHOS
246