• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 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_memory_guard.h"
21 #include "bundle_mgr_service.h"
22 #include "bundle_util.h"
23 #include "display_power_mgr_client.h"
24 #include "ffrt.h"
25 #include "parameter.h"
26 
27 namespace OHOS {
28 namespace AppExecFwk {
29 namespace {
30 const int32_t PERIOD_ANNUALLY = 4;
31 const std::string SYSTEM_PARAM_AGING_TIMER_INTERVAL = "persist.sys.bms.aging.policy.timer.interval";
32 const std::string SYSTEM_PARAM_AGING_BATTER_THRESHOLD = "persist.sys.bms.aging.policy.battery.threshold";
33 const std::string AGING_TASK = "AgingTask";
34 
StatisticsUsageStats(const std::vector<DeviceUsageStats::BundleActivePackageStats> & useStats,std::vector<DeviceUsageStats::BundleActivePackageStats> & results)35 void StatisticsUsageStats(
36     const std::vector<DeviceUsageStats::BundleActivePackageStats> &useStats,
37     std::vector<DeviceUsageStats::BundleActivePackageStats> &results)
38 {
39     for (const auto &useStat : useStats) {
40         auto ret = std::any_of(results.begin(), results.end(),
41             [&useStat](auto &result) {
42                 if (useStat.bundleName_ == result.bundleName_) {
43                     result.startCount_ += useStat.startCount_;
44                     if (result.lastTimeUsed_ < useStat.lastTimeUsed_) {
45                         result.lastTimeUsed_ = useStat.lastTimeUsed_;
46                     }
47 
48                     return true;
49                 }
50 
51                 return false;
52             });
53         if (!ret) {
54             results.emplace_back(useStat);
55         }
56     }
57 }
58 }
59 
BundleAgingMgr()60 BundleAgingMgr::BundleAgingMgr()
61 {
62     InitAgingHandlerChain();
63     APP_LOGI("BundleAgingMgr is created.");
64 }
65 
~BundleAgingMgr()66 BundleAgingMgr::~BundleAgingMgr()
67 {
68     APP_LOGI("BundleAgingMgr is destroyed");
69 }
70 
InitAgingTimerInterval()71 void BundleAgingMgr::InitAgingTimerInterval()
72 {
73     char szTimerThresold[AgingConstants::THRESHOLD_VAL_LEN] = {0};
74     int32_t ret = GetParameter(SYSTEM_PARAM_AGING_TIMER_INTERVAL.c_str(), "", szTimerThresold,
75         AgingConstants::THRESHOLD_VAL_LEN);
76     APP_LOGD("ret is %{public}d, szTimerThresold is %{public}d", ret, atoi(szTimerThresold));
77     if (ret <= 0) {
78         APP_LOGD("GetParameter failed");
79         return;
80     }
81 
82     if (strcmp(szTimerThresold, "") != 0) {
83         agingTimerInterval_ = atoi(szTimerThresold);
84         APP_LOGD("BundleAgingMgr init aging timer success");
85     }
86 }
87 
InitAgingBatteryThresold()88 void BundleAgingMgr::InitAgingBatteryThresold()
89 {
90     char szBatteryThresold[AgingConstants::THRESHOLD_VAL_LEN] = {0};
91     int32_t ret = GetParameter(SYSTEM_PARAM_AGING_BATTER_THRESHOLD.c_str(), "", szBatteryThresold,
92         AgingConstants::THRESHOLD_VAL_LEN);
93     APP_LOGD("ret is %{public}d, szBatteryThresold is %{public}d", ret, atoi(szBatteryThresold));
94     if (ret <= 0) {
95         APP_LOGD("GetParameter failed");
96         return;
97     }
98 
99     if (strcmp(szBatteryThresold, "") != 0) {
100         agingBatteryThresold_ = atoi(szBatteryThresold);
101         APP_LOGD("BundleAgingMgr init battery threshold success");
102     }
103 }
104 
InitAgingtTimer()105 void BundleAgingMgr::InitAgingtTimer()
106 {
107     InitAgingBatteryThresold();
108     InitAgingTimerInterval();
109     ScheduleLoopTask();
110 }
111 
ScheduleLoopTask()112 void BundleAgingMgr::ScheduleLoopTask()
113 {
114     std::weak_ptr<BundleAgingMgr> weakPtr = shared_from_this();
115     auto task = [weakPtr]() {
116         BundleMemoryGuard memoryGuard;
117         while (true) {
118             auto sharedPtr = weakPtr.lock();
119             if (sharedPtr == nullptr) {
120                 APP_LOGD("stop aging task");
121                 break;
122             }
123             ffrt::this_task::sleep_for(std::chrono::milliseconds(sharedPtr->agingTimerInterval_));
124             APP_LOGD("begin to run aging task");
125             sharedPtr->Start(AgingTriggertype::PREIOD);
126         }
127         APP_LOGD("aging task done");
128     };
129     if (agingTimerInterval_ >= 0) {
130         APP_LOGD("submit aging task");
131         ffrt::submit(task, {}, {}, ffrt::task_attr().name(AGING_TASK.c_str()));
132     }
133 }
134 
ResetRequest()135 bool BundleAgingMgr::ResetRequest()
136 {
137     auto dataMgr = OHOS::DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
138     if (dataMgr == nullptr) {
139         APP_LOGE("dataMgr is null");
140         return false;
141     }
142 
143     request_.ResetRequest();
144     request_.SetTotalDataBytes(dataMgr->GetAllFreeInstallBundleSpaceSize());
145     return true;
146 }
147 
IsReachStartAgingThreshold()148 bool BundleAgingMgr::IsReachStartAgingThreshold()
149 {
150     return request_.IsReachStartAgingThreshold();
151 }
152 
QueryBundleStatsInfoByInterval(std::vector<DeviceUsageStats::BundleActivePackageStats> & results)153 bool BundleAgingMgr::QueryBundleStatsInfoByInterval(
154     std::vector<DeviceUsageStats::BundleActivePackageStats> &results)
155 {
156     auto dataMgr = OHOS::DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
157     if (dataMgr == nullptr) {
158         APP_LOGE("dataMgr is null");
159         return false;
160     }
161 
162     int64_t startTime = 0;
163     int64_t endTime = AgingUtil::GetNowSysTimeMs();
164     std::vector<DeviceUsageStats::BundleActivePackageStats> useStats;
165     for (const auto &userId : dataMgr->GetAllUser()) {
166         DeviceUsageStats::BundleActiveClient::GetInstance().QueryBundleStatsInfoByInterval(
167             useStats, PERIOD_ANNUALLY, startTime, endTime, userId);
168         StatisticsUsageStats(useStats, results);
169         useStats.clear();
170     }
171 
172     APP_LOGD("activeBundleRecord size %{public}zu", results.size());
173     return !results.empty();
174 }
175 
InitAgingRequest()176 bool BundleAgingMgr::InitAgingRequest()
177 {
178     auto dataMgr = OHOS::DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
179     if (dataMgr == nullptr) {
180         APP_LOGE("dataMgr is null");
181         return false;
182     }
183 
184     if (!ResetRequest()) {
185         APP_LOGE("Reset Request failed");
186         return false;
187     }
188 
189     if (!IsReachStartAgingThreshold()) {
190         APP_LOGI("Not reach agingThreshold and not need aging.");
191         return false;
192     }
193 
194     std::vector<DeviceUsageStats::BundleActivePackageStats> activeBundleRecord;
195     if (!QueryBundleStatsInfoByInterval(activeBundleRecord)) {
196         APP_LOGE("InitAgingRequest: can not get bundle active bundle record");
197         return false;
198     }
199     auto bundleInfos = dataMgr->GetAllInnerBundleInfos();
200     for (const auto &item : bundleInfos) {
201         if (!item.second.IsBundleRemovable()) {
202             continue;
203         }
204 
205         int64_t installTime = item.second.GetLastInstallationTime();
206         auto bundleName = item.first;
207         DeviceUsageStats::BundleActivePackageStats bundleRecord;
208         bundleRecord.bundleName_ = bundleName;
209         bundleRecord.lastTimeUsed_ = installTime;
210         std::any_of(activeBundleRecord.begin(), activeBundleRecord.end(),
211             [&bundleRecord](const auto &record) {
212                 if (record.bundleName_ == bundleRecord.bundleName_) {
213                     bundleRecord = record;
214                     return true;
215                 }
216 
217                 return false;
218             });
219         AgingBundleInfo agingBundleInfo(bundleName, bundleRecord.lastTimeUsed_, bundleRecord.startCount_);
220         request_.AddAgingBundle(agingBundleInfo);
221     }
222 
223     bool ret = request_.SortAgingBundles() > 0;
224     request_.Dump();
225     return ret;
226 }
227 
Process(const std::shared_ptr<BundleDataMgr> & dataMgr)228 void BundleAgingMgr::Process(const std::shared_ptr<BundleDataMgr> &dataMgr)
229 {
230     APP_LOGD("BundleAging begin to process.");
231     if (InitAgingRequest()) {
232         chain_.Process(request_);
233     }
234 
235     {
236         std::lock_guard<std::mutex> lock(mutex_);
237         running_ = false;
238     }
239 
240     APP_LOGD("BundleAgingMgr Process done");
241 }
242 
Start(AgingTriggertype type)243 void BundleAgingMgr::Start(AgingTriggertype type)
244 {
245     APP_LOGD("aging start, AgingTriggertype: %{public}d", type);
246     if (!CheckPrerequisite(type)) {
247         APP_LOGE("BundleAgingMgr aging Prerequisite is not satisfied");
248         return;
249     }
250 
251     auto dataMgr = OHOS::DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
252     if (dataMgr == nullptr) {
253         APP_LOGE("dataMgr is null");
254         return;
255     }
256 
257     {
258         std::lock_guard<std::mutex> lock(mutex_);
259         if (running_) {
260             APP_LOGD("BundleAgingMgr is running, no need to start is again");
261             return;
262         }
263         running_ = true;
264     }
265 
266     auto task = [&, dataMgr]() {
267         BundleMemoryGuard memoryGuard;
268         Process(dataMgr);
269     };
270     ffrt::task_handle task_handle = ffrt::submit_h(task);
271     if (task_handle == nullptr) {
272         APP_LOGE("submit_h return null, execute Process failed");
273         std::lock_guard<std::mutex> lock(mutex_);
274         running_ = false;
275     }
276 }
277 
CheckPrerequisite(AgingTriggertype type) const278 bool BundleAgingMgr::CheckPrerequisite(AgingTriggertype type) const
279 {
280     if (type != AgingTriggertype::PREIOD) {
281         return true;
282     }
283 
284     DisplayPowerMgr::DisplayState state = DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().GetDisplayState();
285     if (state == DisplayPowerMgr::DisplayState::DISPLAY_ON) {
286         APP_LOGD("current Displaystate is DisplayState::DISPLAY_ON");
287         return false;
288     }
289 
290     int32_t currentBatteryCap = OHOS::PowerMgr::BatterySrvClient::GetInstance().GetCapacity();
291     APP_LOGD("current GetCapacity is %{public}d agingBatteryThresold: %{public}" PRId64,
292         currentBatteryCap, agingBatteryThresold_);
293     return currentBatteryCap > agingBatteryThresold_;
294 }
295 
InitAgingHandlerChain()296 void BundleAgingMgr::InitAgingHandlerChain()
297 {
298     chain_ = AgingHandlerChain();
299     chain_.AddHandler(std::make_shared<RecentlyUnuseBundleAgingHandler>());
300 }
301 }  //  namespace AppExecFwk
302 }  //  namespace OHOS
303