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