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