• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 
16 #include "bundle_cache_mgr.h"
17 
18 #include <cinttypes>
19 #include "bundle_mgr_service.h"
20 
21 namespace OHOS {
22 namespace AppExecFwk {
23 namespace {
24 constexpr size_t INDEX_BUNDLE_NAME = 0;
25 constexpr size_t INDEX_MODULE_NAMES = 1;
26 constexpr size_t INDEX_CLONE_APP_INDEX = 2;
27 }
28 
GetBundleCachePath(const std::string & bundleName,const int32_t userId,const int32_t appIndex,const std::vector<std::string> & moduleNameList)29 std::vector<std::string> BundleCacheMgr::GetBundleCachePath(const std::string &bundleName,
30     const int32_t userId, const int32_t appIndex, const std::vector<std::string> &moduleNameList)
31 {
32     std::string bundleNameDir = bundleName;
33     if (appIndex > 0) {
34         bundleNameDir = BundleCloneCommonHelper::GetCloneDataDir(bundleName, appIndex);
35     }
36     std::vector<std::string> cachePaths;
37     std::string elBase;
38     for (const auto &el : ServiceConstants::FULL_BUNDLE_EL) {
39         elBase = std::string(ServiceConstants::BUNDLE_APP_DATA_BASE_DIR) + el + ServiceConstants::PATH_SEPARATOR +
40             std::to_string(userId) + ServiceConstants::BASE + bundleNameDir + ServiceConstants::PATH_SEPARATOR;
41         std::string baseCachePath = elBase + Constants::CACHE_DIR;
42         cachePaths.emplace_back(baseCachePath);
43         for (const auto &moduleName : moduleNameList) {
44             std::string moduleCachePath = elBase + ServiceConstants::HAPS + moduleName +
45                 ServiceConstants::PATH_SEPARATOR + Constants::CACHE_DIR;
46             cachePaths.emplace_back(moduleCachePath);
47         }
48     }
49     return cachePaths;
50 }
51 
GetBundleCacheSize(const std::vector<std::tuple<std::string,std::vector<std::string>,std::vector<int32_t>>> & validBundles,const int32_t userId,uint64_t & cacheStat)52 void BundleCacheMgr::GetBundleCacheSize(const std::vector<std::tuple<std::string,
53     std::vector<std::string>, std::vector<int32_t>>> &validBundles, const int32_t userId,
54     uint64_t &cacheStat)
55 {
56     for (const auto &item : validBundles) {
57         // get cache path for every bundle(contains clone and module)
58         std::string bundleName = std::get<INDEX_BUNDLE_NAME>(item);
59         std::vector<std::string> moduleNames = std::get<INDEX_MODULE_NAMES>(item);
60         std::vector<int32_t> allCloneAppIndex = std::get<INDEX_CLONE_APP_INDEX>(item);
61         for (const auto &appIndex : allCloneAppIndex) {
62             std::vector<std::string> cachePaths = GetBundleCachePath(bundleName, userId, appIndex, moduleNames);
63             int64_t cacheSize = 0;
64             ErrCode ret = InstalldClient::GetInstance()->GetDiskUsageFromPath(cachePaths, cacheSize);
65             if (ret != ERR_OK) {
66                 APP_LOGW("BundleCache GetDiskUsageFromPath  failed for %{public}s", bundleName.c_str());
67                 continue;
68             }
69             APP_LOGD("BundleCache stat: %{public}" PRId64 " bundlename: %{public}s",
70                 cacheSize, bundleName.c_str());
71             cacheStat += static_cast<uint64_t>(cacheSize);
72         }
73     }
74     return;
75 }
76 
GetAllBundleCacheStat(const sptr<IProcessCacheCallback> processCacheCallback)77 ErrCode BundleCacheMgr::GetAllBundleCacheStat(const sptr<IProcessCacheCallback> processCacheCallback)
78 {
79     APP_LOGI("start");
80     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
81     if (dataMgr == nullptr) {
82         return ERR_BUNDLE_MANAGER_INTERNAL_ERROR;
83     }
84 
85     auto userId = AccountHelper::GetCurrentActiveUserId();
86     if (userId <= Constants::DEFAULT_USERID) {
87         APP_LOGE("Invalid userid: %{public}d", userId);
88         return ERR_BUNDLE_MANAGER_INVALID_PARAMETER;
89     }
90     std::vector<std::tuple<std::string, std::vector<std::string>, std::vector<int32_t>>> validBundles;
91     dataMgr->GetBundleCacheInfos(userId, validBundles, false);
92     if (!validBundles.empty()) {
93         auto getAllBundleCache = [validBundles, userId, processCacheCallback]() {
94             uint64_t cacheStat = 0;
95             APP_LOGI("thread for GetBundleCacheSize start");
96             GetBundleCacheSize(validBundles, userId, cacheStat);
97             processCacheCallback->OnGetAllBundleCacheFinished(cacheStat);
98         };
99         std::thread(getAllBundleCache).detach();
100     }
101     return ERR_OK;
102 }
103 
CleanBundleCloneCache(const std::string & bundleName,int32_t userId,int32_t appCloneIndex,const std::vector<std::string> & moduleNames)104 ErrCode BundleCacheMgr::CleanBundleCloneCache(const std::string &bundleName, int32_t userId,
105     int32_t appCloneIndex, const std::vector<std::string> &moduleNames)
106 {
107     std::vector<std::string> cachePaths = GetBundleCachePath(bundleName, userId, appCloneIndex, moduleNames);
108     int32_t result = ERR_OK;
109     for (const auto& cache : cachePaths) {
110         int32_t ret = InstalldClient::GetInstance()->CleanBundleDataDir(cache);
111         if (ret != ERR_OK) {
112             result = ret;
113             APP_LOGW("Clean BundleCache dir failed, path: %{private}s", cache.c_str());
114         }
115     }
116     return result;
117 }
118 
CleanBundleCache(const std::vector<std::tuple<std::string,std::vector<std::string>,std::vector<int32_t>>> & validBundles,int32_t userId)119 ErrCode BundleCacheMgr::CleanBundleCache(const std::vector<std::tuple<std::string,
120     std::vector<std::string>, std::vector<int32_t>>> &validBundles, int32_t userId)
121 {
122     int32_t result = ERR_OK;
123     for (const auto &item : validBundles) {
124         // get cache path for every bundle(contains clone and module)
125         std::string bundleName = std::get<INDEX_BUNDLE_NAME>(item);
126         std::vector<std::string> moduleNames = std::get<INDEX_MODULE_NAMES>(item);
127         std::vector<int32_t> allCloneAppIndex = std::get<INDEX_CLONE_APP_INDEX>(item);
128         for (const auto &appIndex : allCloneAppIndex) {
129             int32_t ret = CleanBundleCloneCache(bundleName, userId, appIndex, moduleNames);
130             if (ERR_OK != ret) {
131                 result = ret;
132                 APP_LOGW("Clean BundleCache %{public}s failed, userId: %{public}d, appIndex: %{public}d",
133                     bundleName.c_str(), userId, appIndex);
134             }
135         }
136     }
137     return result;
138 }
139 
CleanAllBundleCache(const sptr<IProcessCacheCallback> processCacheCallback)140 ErrCode BundleCacheMgr::CleanAllBundleCache(const sptr<IProcessCacheCallback> processCacheCallback)
141 {
142     APP_LOGI("start");
143     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
144     if (dataMgr == nullptr) {
145         return ERR_BUNDLE_MANAGER_INTERNAL_ERROR;
146     }
147     auto userId = AccountHelper::GetCurrentActiveUserId();
148     if (userId <= Constants::DEFAULT_USERID) {
149         APP_LOGE("Invalid userid: %{public}d", userId);
150         return ERR_BUNDLE_MANAGER_INVALID_PARAMETER;
151     }
152     std::vector<std::tuple<std::string, std::vector<std::string>, std::vector<int32_t>>> validBundles;
153     dataMgr->GetBundleCacheInfos(userId, validBundles, true);
154     if (!validBundles.empty()) {
155         auto CleanAllBundleCache = [validBundles, userId, processCacheCallback]() {
156             int32_t result = ERR_OK;
157             APP_LOGI("thread for CleanBundleCache start");
158             result = CleanBundleCache(validBundles, userId);
159             processCacheCallback->OnCleanAllBundleCacheFinished(result);
160         };
161         std::thread(CleanAllBundleCache).detach();
162     }
163     return ERR_OK;
164 }
165 }  // namespace AppExecFwk
166 }  // namespace OHOS
167