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
44 if (ServiceConstants::BUNDLE_EL[1] == el) {
45 baseCachePath = std::string(ServiceConstants::BUNDLE_APP_DATA_BASE_DIR) + el +
46 ServiceConstants::PATH_SEPARATOR + std::to_string(userId) + ServiceConstants::SHAREFILES +
47 bundleNameDir + ServiceConstants::PATH_SEPARATOR + Constants::CACHE_DIR;
48 cachePaths.emplace_back(baseCachePath);
49 }
50 for (const auto &moduleName : moduleNameList) {
51 std::string moduleCachePath = elBase + ServiceConstants::HAPS + moduleName +
52 ServiceConstants::PATH_SEPARATOR + Constants::CACHE_DIR;
53 cachePaths.emplace_back(moduleCachePath);
54 if (ServiceConstants::BUNDLE_EL[1] == el) {
55 moduleCachePath = std::string(ServiceConstants::BUNDLE_APP_DATA_BASE_DIR) + el +
56 ServiceConstants::PATH_SEPARATOR + std::to_string(userId) + ServiceConstants::SHAREFILES +
57 bundleNameDir + ServiceConstants::HAPS + moduleName + ServiceConstants::PATH_SEPARATOR +
58 Constants::CACHE_DIR;
59 cachePaths.emplace_back(moduleCachePath);
60 }
61 }
62 }
63 return cachePaths;
64 }
65
GetBundleCacheSize(const std::vector<std::tuple<std::string,std::vector<std::string>,std::vector<int32_t>>> & validBundles,const int32_t userId,uint64_t & cacheStat)66 void BundleCacheMgr::GetBundleCacheSize(const std::vector<std::tuple<std::string,
67 std::vector<std::string>, std::vector<int32_t>>> &validBundles, const int32_t userId,
68 uint64_t &cacheStat)
69 {
70 for (const auto &item : validBundles) {
71 // get cache path for every bundle(contains clone and module)
72 std::string bundleName = std::get<INDEX_BUNDLE_NAME>(item);
73 std::vector<std::string> moduleNames = std::get<INDEX_MODULE_NAMES>(item);
74 std::vector<int32_t> allCloneAppIndex = std::get<INDEX_CLONE_APP_INDEX>(item);
75 for (const auto &appIndex : allCloneAppIndex) {
76 std::vector<std::string> cachePaths = GetBundleCachePath(bundleName, userId, appIndex, moduleNames);
77 int64_t cacheSize = 0;
78 ErrCode ret = InstalldClient::GetInstance()->GetDiskUsageFromPath(cachePaths, cacheSize);
79 if (ret != ERR_OK) {
80 APP_LOGW("BundleCache GetDiskUsageFromPath failed for %{public}s", bundleName.c_str());
81 continue;
82 }
83 APP_LOGD("BundleCache stat: %{public}" PRId64 " bundlename: %{public}s",
84 cacheSize, bundleName.c_str());
85 cacheStat += static_cast<uint64_t>(cacheSize);
86 }
87 }
88 return;
89 }
90
GetAllBundleCacheStat(const sptr<IProcessCacheCallback> processCacheCallback)91 ErrCode BundleCacheMgr::GetAllBundleCacheStat(const sptr<IProcessCacheCallback> processCacheCallback)
92 {
93 APP_LOGI("start");
94 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
95 if (dataMgr == nullptr) {
96 return ERR_BUNDLE_MANAGER_INTERNAL_ERROR;
97 }
98
99 auto userId = AccountHelper::GetCurrentActiveUserId();
100 if (userId <= Constants::DEFAULT_USERID) {
101 APP_LOGE("Invalid userid: %{public}d", userId);
102 return ERR_BUNDLE_MANAGER_INVALID_PARAMETER;
103 }
104 std::vector<std::tuple<std::string, std::vector<std::string>, std::vector<int32_t>>> validBundles;
105 dataMgr->GetBundleCacheInfos(userId, validBundles, false);
106 if (!validBundles.empty()) {
107 auto getAllBundleCache = [validBundles, userId, processCacheCallback]() {
108 uint64_t cacheStat = 0;
109 APP_LOGI("thread for GetBundleCacheSize start");
110 GetBundleCacheSize(validBundles, userId, cacheStat);
111 processCacheCallback->OnGetAllBundleCacheFinished(cacheStat);
112 };
113 std::thread(getAllBundleCache).detach();
114 }
115 return ERR_OK;
116 }
117
CleanBundleCloneCache(const std::string & bundleName,int32_t userId,int32_t appCloneIndex,const std::vector<std::string> & moduleNames)118 ErrCode BundleCacheMgr::CleanBundleCloneCache(const std::string &bundleName, int32_t userId,
119 int32_t appCloneIndex, const std::vector<std::string> &moduleNames)
120 {
121 std::vector<std::string> cachePaths = GetBundleCachePath(bundleName, userId, appCloneIndex, moduleNames);
122 int32_t result = ERR_OK;
123 for (const auto& cache : cachePaths) {
124 int32_t ret = InstalldClient::GetInstance()->CleanBundleDataDir(cache);
125 if (ret != ERR_OK) {
126 result = ret;
127 APP_LOGW("CleanBundleDataDir failed, path: %{private}s", cache.c_str());
128 }
129 }
130 return result;
131 }
132
CleanBundleCache(const std::vector<std::tuple<std::string,std::vector<std::string>,std::vector<int32_t>>> & validBundles,int32_t userId)133 ErrCode BundleCacheMgr::CleanBundleCache(const std::vector<std::tuple<std::string,
134 std::vector<std::string>, std::vector<int32_t>>> &validBundles, int32_t userId)
135 {
136 int32_t result = ERR_OK;
137 for (const auto &item : validBundles) {
138 // get cache path for every bundle(contains clone and module)
139 std::string bundleName = std::get<INDEX_BUNDLE_NAME>(item);
140 std::vector<std::string> moduleNames = std::get<INDEX_MODULE_NAMES>(item);
141 std::vector<int32_t> allCloneAppIndex = std::get<INDEX_CLONE_APP_INDEX>(item);
142 for (const auto &appIndex : allCloneAppIndex) {
143 int32_t ret = CleanBundleCloneCache(bundleName, userId, appIndex, moduleNames);
144 if (ret != ERR_OK) {
145 result = ret;
146 APP_LOGW("CleanBundleCloneCache %{public}s failed, userId: %{public}d, appIndex: %{public}d",
147 bundleName.c_str(), userId, appIndex);
148 }
149 }
150 }
151 return result;
152 }
153
CleanAllBundleCache(const sptr<IProcessCacheCallback> processCacheCallback)154 ErrCode BundleCacheMgr::CleanAllBundleCache(const sptr<IProcessCacheCallback> processCacheCallback)
155 {
156 APP_LOGI("start");
157 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
158 if (dataMgr == nullptr) {
159 return ERR_BUNDLE_MANAGER_INTERNAL_ERROR;
160 }
161 auto userId = AccountHelper::GetCurrentActiveUserId();
162 if (userId <= Constants::DEFAULT_USERID) {
163 APP_LOGE("Invalid userid: %{public}d", userId);
164 return ERR_BUNDLE_MANAGER_INVALID_PARAMETER;
165 }
166
167 std::vector<std::tuple<std::string, std::vector<std::string>, std::vector<int32_t>>> validBundles;
168 dataMgr->GetBundleCacheInfos(userId, validBundles, true);
169 if (!validBundles.empty()) {
170 auto CleanAllBundleCache = [validBundles, userId, processCacheCallback]() {
171 ErrCode result = ERR_OK;
172 APP_LOGI("thread for CleanBundleCache start");
173 result = CleanBundleCache(validBundles, userId);
174 processCacheCallback->OnCleanAllBundleCacheFinished(result);
175 };
176 std::thread(CleanAllBundleCache).detach();
177 }
178 return ERR_OK;
179 }
180 } // namespace AppExecFwk
181 } // namespace OHOS
182