• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 "storage/storage_status_service.h"
17 #include "accesstoken_kit.h"
18 #include "ipc_skeleton.h"
19 #include "hitrace_meter.h"
20 #include "storage_daemon_communication/storage_daemon_communication.h"
21 #include "storage_service_constant.h"
22 #include "storage_service_errno.h"
23 #include "storage_service_log.h"
24 #include "storage/bundle_manager_connector.h"
25 #include "storage/storage_total_status_service.h"
26 #include "iservice_registry.h"
27 #include "system_ability_definition.h"
28 #include "utils/storage_radar.h"
29 #ifdef STORAGE_SERVICE_GRAPHIC
30 #include "datashare_abs_result_set.h"
31 #include "datashare_helper.h"
32 #include "datashare_predicates.h"
33 #endif
34 
35 using namespace std;
36 using namespace OHOS::StorageService;
37 namespace OHOS {
38 namespace StorageManager {
39 using namespace OHOS::StorageService;
40 
41 namespace {
42 const string MEDIA_TYPE = "media";
43 const string FILE_TYPE = "file";
44 const string MEDIALIBRARY_DATA_URI = "datashare:///media";
45 const string MEDIA_QUERYOPRN_QUERYVOLUME = "query_media_volume";
46 #ifdef STORAGE_SERVICE_GRAPHIC
47 const int MEDIA_TYPE_IMAGE = 1;
48 const int MEDIA_TYPE_AUDIO = 3;
49 const int MEDIA_TYPE_VIDEO = 2;
50 const int32_t GET_DATA_SHARE_HELPER_TIMES = 5;
51 #endif
52 } // namespace
53 
StorageStatusService()54 StorageStatusService::StorageStatusService() {}
~StorageStatusService()55 StorageStatusService::~StorageStatusService() {}
56 
57 #ifdef STORAGE_SERVICE_GRAPHIC
GetMediaTypeAndSize(const std::shared_ptr<DataShare::DataShareResultSet> & resultSet,StorageStats & storageStats)58 void GetMediaTypeAndSize(const std::shared_ptr<DataShare::DataShareResultSet> &resultSet, StorageStats &storageStats)
59 {
60     if (resultSet == nullptr) {
61         LOGE("StorageStatusService::GetMediaTypeAndSize, input resultSet is nullptr.");
62         return;
63     }
64     int thumbnailType = -1;
65     while (resultSet->GoToNextRow() == E_OK) {
66         int32_t index = 0;
67         int mediatype = 0;
68         int64_t size = 0;
69         if (resultSet->GetColumnIndex("media_type", index) || resultSet->GetInt(index, mediatype)) {
70             LOGE("get media_type column index or int value err.");
71             continue;
72         }
73         if (resultSet->GetColumnIndex("size", index) || resultSet->GetLong(index, size)) {
74             LOGE("get size column index or long value err.");
75             continue;
76         }
77         LOGI("media type: %{public}d, size: %{public}lld", mediatype, static_cast<long long>(size));
78         if (mediatype == MEDIA_TYPE_IMAGE || mediatype == thumbnailType) {
79             storageStats.image_ += size;
80         } else if (mediatype == MEDIA_TYPE_AUDIO) {
81             storageStats.audio_ = size;
82         } else if (mediatype == MEDIA_TYPE_VIDEO) {
83             storageStats.video_ = size;
84         } else {
85             LOGD("unsupprted media_type: %{public}d", mediatype);
86         }
87     }
88 }
89 #endif
90 
GetMediaStorageStats(StorageStats & storageStats)91 int32_t GetMediaStorageStats(StorageStats &storageStats)
92 {
93     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
94     LOGE("GetMediaStorageStats start");
95 #ifdef STORAGE_SERVICE_GRAPHIC
96     auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
97     if (sam == nullptr) {
98         LOGE("StorageStatusService::GetMediaStorageStats samgr == nullptr");
99         return E_SA_IS_NULLPTR;
100     }
101     auto remoteObj = sam->GetSystemAbility(STORAGE_MANAGER_MANAGER_ID);
102     if (remoteObj == nullptr) {
103         LOGE("StorageStatusService::GetMediaStorageStats remoteObj == nullptr");
104         return E_REMOTE_IS_NULLPTR;
105     }
106     int32_t tryCount = 1;
107     LOGE("GetMediaStorageStats start Creator");
108     auto dataShareHelper = DataShare::DataShareHelper::Creator(remoteObj, MEDIALIBRARY_DATA_URI);
109     while (dataShareHelper == nullptr && tryCount < GET_DATA_SHARE_HELPER_TIMES) {
110         LOGW("dataShareHelper is retrying, attempt %{public}d", tryCount);
111         dataShareHelper = DataShare::DataShareHelper::Creator(remoteObj, MEDIALIBRARY_DATA_URI);
112         tryCount++;
113     }
114     if (dataShareHelper == nullptr) {
115         LOGE("dataShareHelper is null!");
116         return E_MEDIALIBRARY_ERROR;
117     }
118     vector<string> columns;
119     Uri uri(MEDIALIBRARY_DATA_URI + "/" + MEDIA_QUERYOPRN_QUERYVOLUME + "/" + MEDIA_QUERYOPRN_QUERYVOLUME);
120     DataShare::DataSharePredicates predicates;
121     LOGE("GetMediaStorageStats start Query");
122     auto queryResultSet = dataShareHelper->Query(uri, predicates, columns);
123     if (queryResultSet == nullptr) {
124         LOGE("queryResultSet is null!");
125         return E_QUERY;
126     }
127     auto count = 0;
128     auto ret = queryResultSet->GetRowCount(count);
129     if ((ret != E_OK) || (count < 0)) {
130         LOGE("get row count from rdb failed");
131         return E_GETROWCOUNT;
132     }
133     GetMediaTypeAndSize(queryResultSet, storageStats);
134     dataShareHelper->Release();
135 #endif
136     LOGE("GetMediaStorageStats end");
137     return E_OK;
138 }
139 
GetFileStorageStats(int32_t userId,StorageStats & storageStats)140 int32_t GetFileStorageStats(int32_t userId, StorageStats &storageStats)
141 {
142     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
143     LOGE("GetFileStorageStats start");
144     int32_t err = E_OK;
145     int32_t prjId = userId * USER_ID_BASE + UID_FILE_MANAGER;
146     std::shared_ptr<StorageDaemonCommunication> sdCommunication;
147     sdCommunication = DelayedSingleton<StorageDaemonCommunication>::GetInstance();
148     err = sdCommunication->GetOccupiedSpace(StorageDaemon::USRID, prjId, storageStats.file_);
149     LOGE("GetFileStorageStats end");
150     return err;
151 }
152 
GetCurrentUserId()153 int StorageStatusService::GetCurrentUserId()
154 {
155     int uid = -1;
156     uid = IPCSkeleton::GetCallingUid();
157     int userId = uid / 200000;
158     return userId;
159 }
160 
GetCallingPkgName()161 std::string StorageStatusService::GetCallingPkgName()
162 {
163     uint32_t pid = IPCSkeleton::GetCallingTokenID();
164     Security::AccessToken::HapTokenInfo tokenInfo = Security::AccessToken::HapTokenInfo();
165     Security::AccessToken::AccessTokenKit::GetHapTokenInfo(pid, tokenInfo);
166     return tokenInfo.bundleName;
167 }
168 
GetBundleStats(const std::string & pkgName,BundleStats & bundleStats,int32_t appIndex,uint32_t statFlag)169 int32_t StorageStatusService::GetBundleStats(const std::string &pkgName,
170     BundleStats &bundleStats, int32_t appIndex, uint32_t statFlag)
171 {
172     int userId = GetCurrentUserId();
173     LOGD("StorageStatusService::userId is:%d, appIndex is: %d", userId, appIndex);
174     return GetBundleStats(pkgName, userId, bundleStats, appIndex, statFlag);
175 }
176 
GetUserStorageStats(StorageStats & storageStats)177 int32_t StorageStatusService::GetUserStorageStats(StorageStats &storageStats)
178 {
179     int userId = GetCurrentUserId();
180     return GetUserStorageStats(userId, storageStats);
181 }
182 
GetUserStorageStats(int32_t userId,StorageStats & storageStats)183 int32_t StorageStatusService::GetUserStorageStats(int32_t userId, StorageStats &storageStats)
184 {
185     bool isCeEncrypt = false;
186     std::shared_ptr<StorageDaemonCommunication> sdCommunication;
187     sdCommunication = DelayedSingleton<StorageDaemonCommunication>::GetInstance();
188     int ret = sdCommunication->GetFileEncryptStatus(userId, isCeEncrypt, true);
189     if (ret != E_OK || isCeEncrypt) {
190         LOGE("User %{public}d de has not decrypt.", userId);
191         return ret;
192     }
193     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
194     // totalSize
195     int64_t totalSize = 0;
196     int32_t err = DelayedSingleton<StorageTotalStatusService>::GetInstance()->GetTotalSize(totalSize);
197     if (err != E_OK) {
198         LOGE("StorageStatusService::GetUserStorageStats getTotalSize failed");
199         StorageRadar::ReportGetStorageStatus("GetUserStorageStats::GetTotalSize", userId, ret, GetCallingPkgName());
200         return err;
201     }
202     // appSize
203     LOGD("StorageStatusService::GetUserStorageStats userId is %{public}d", userId);
204     int64_t appSize = 0;
205     err = GetAppSize(userId, appSize);
206     if (err != E_OK) {
207         LOGE("StorageStatusService::GetUserStorageStats getAppSize failed");
208         StorageRadar::ReportGetStorageStatus("GetUserStorageStats::GetAppSize", userId, ret, GetCallingPkgName());
209         return err;
210     }
211 
212     storageStats.total_ = totalSize;
213     storageStats.app_ = appSize;
214 
215     // mediaSize
216     err = GetMediaStorageStats(storageStats);
217     if (err != E_OK) {
218         LOGE("StorageStatusService::GetUserStorageStats GetMediaStorageStats failed");
219         StorageRadar::ReportGetStorageStatus("GetUserStorageStats::GetMediaStorageStats", userId, ret,
220             GetCallingPkgName());
221         return err;
222     }
223     // fileSize
224     err = GetFileStorageStats(userId, storageStats);
225     if (err != E_OK) {
226         LOGE("StorageStatusService::GetUserStorageStats GetFileStorageStats failed");
227         StorageRadar::ReportGetStorageStatus("GetUserStorageStats::GetFileStorageStats", userId, ret,
228             GetCallingPkgName());
229     }
230 
231     LOGE("StorageStatusService::GetUserStorageStats success for userId=%{public}d, "
232         "totalSize=%{public}lld, appSize=%{public}lld, videoSize=%{public}lld, audioSize=%{public}lld, "
233         "imageSize=%{public}lld, fileSize=%{public}lld",
234         userId, static_cast<long long>(storageStats.total_), static_cast<long long>(storageStats.app_),
235         static_cast<long long>(storageStats.video_), static_cast<long long>(storageStats.audio_),
236         static_cast<long long>(storageStats.image_), static_cast<long long>(storageStats.file_));
237     return err;
238 }
239 
GetBundleStatsForIncrease(uint32_t userId,const std::vector<std::string> & bundleNames,const std::vector<int64_t> & incrementalBackTimes,std::vector<int64_t> & pkgFileSizes,std::vector<int64_t> & incPkgFileSizes)240 int32_t StorageStatusService::GetBundleStatsForIncrease(uint32_t userId, const std::vector<std::string> &bundleNames,
241     const std::vector<int64_t> &incrementalBackTimes, std::vector<int64_t> &pkgFileSizes,
242     std::vector<int64_t> &incPkgFileSizes)
243 {
244     std::shared_ptr<StorageDaemonCommunication> sdCommunication;
245     sdCommunication = DelayedSingleton<StorageDaemonCommunication>::GetInstance();
246     int32_t err = sdCommunication->GetBundleStatsForIncrease(userId, bundleNames, incrementalBackTimes,
247         pkgFileSizes, incPkgFileSizes);
248     LOGI("StorageStatusService::GetBundleStatsForIncrease err is %{public}d", err);
249     return err;
250 }
251 
GetCurrentBundleStats(BundleStats & bundleStats,uint32_t statFlag)252 int32_t StorageStatusService::GetCurrentBundleStats(BundleStats &bundleStats, uint32_t statFlag)
253 {
254     int userId = GetCurrentUserId();
255     std::string pkgName = GetCallingPkgName();
256     int32_t ret = GetBundleStats(pkgName, userId, bundleStats, DEFAULT_APP_INDEX, statFlag);
257     if (ret != E_OK) {
258         LOGE("storage status service GetBundleStats failed, please check");
259         std::string extraData = "pkgName=" + pkgName + ",statFlag=" + std::to_string(statFlag);
260         StorageRadar::ReportBundleMgrResult("GetCurrentBundleStats::GetBundleStats", ret, userId, extraData);
261     }
262     return ret;
263 }
264 
GetBundleStats(const std::string & pkgName,int32_t userId,BundleStats & pkgStats,int32_t appIndex,uint32_t statFlag)265 int32_t StorageStatusService::GetBundleStats(const std::string &pkgName, int32_t userId,
266     BundleStats &pkgStats, int32_t appIndex, uint32_t statFlag)
267 {
268     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
269     auto bundleMgr = DelayedSingleton<BundleMgrConnector>::GetInstance()->GetBundleMgrProxy();
270     if (bundleMgr == nullptr) {
271         LOGE("StorageStatusService::GetBundleStats connect bundlemgr failed");
272         return E_SERVICE_IS_NULLPTR;
273     }
274 
275     if (userId < 0 || userId > StorageService::MAX_USER_ID) {
276         LOGE("StorageStatusService::Invaild userId.");
277         return E_USERID_RANGE;
278     }
279 
280     if (appIndex < 0 || appIndex > StorageService::MAX_APP_INDEX) {
281         LOGE("StorageStatusService::Invalid appIndex: %{public}d", appIndex);
282         return E_APPINDEX_RANGE;
283     }
284     vector<int64_t> bundleStats;
285     bool res = bundleMgr->GetBundleStats(pkgName, userId, bundleStats, appIndex, statFlag);
286     if (!res || bundleStats.size() != dataDir.size()) {
287         LOGE("StorageStatusService::An error occurred in querying bundle stats.");
288         std::string extraData = "bundleStats size=" + std::to_string(bundleStats.size())
289             + ", dataDir size=" + std::to_string(dataDir.size());
290         StorageRadar::ReportBundleMgrResult("GetBundleStats", res, userId, extraData);
291         return E_BUNDLEMGR_ERROR;
292     }
293     for (uint i = 0; i < bundleStats.size(); i++) {
294         if (bundleStats[i] == E_ERR) {
295             LOGE("StorageStatusService::Failed to query %{public}s data.", dataDir[i].c_str());
296             bundleStats[i] = 0;
297         }
298     }
299     pkgStats.appSize_ = bundleStats[APP];
300     pkgStats.cacheSize_ = bundleStats[CACHE];
301     pkgStats.dataSize_ = bundleStats[LOCAL] + bundleStats[DISTRIBUTED] + bundleStats[DATABASE];
302     LOGE("StorageStatusService::GetBundleStats success for pkgName=%{public}s, userId=%{public}d, appIndex=%{public}d"
303         ", appSize=%{public}lld, cacheSize=%{public}lld, dataSize=%{public}lld",
304         pkgName.c_str(), userId, appIndex, static_cast<long long>(pkgStats.appSize_),
305         static_cast<long long>(pkgStats.cacheSize_), static_cast<long long>(pkgStats.dataSize_));
306     return E_OK;
307 }
308 
GetAppSize(int32_t userId,int64_t & appSize)309 int32_t StorageStatusService::GetAppSize(int32_t userId, int64_t &appSize)
310 {
311     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
312     LOGD("StorageStatusService::GetAppSize start");
313     auto bundleMgr = DelayedSingleton<BundleMgrConnector>::GetInstance()->GetBundleMgrProxy();
314     if (bundleMgr == nullptr) {
315         LOGE("StorageStatusService::GetUserStorageStats connect bundlemgr failed");
316         return E_SERVICE_IS_NULLPTR;
317     }
318 
319     vector<int64_t> bundleStats;
320     bool res = bundleMgr->GetAllBundleStats(userId, bundleStats);
321     if (!res || bundleStats.size() != dataDir.size()) {
322         LOGE("StorageStatusService::GetAllBundleStats fail. res %{public}d, bundleStats.size %{public}zu",
323              res, bundleStats.size());
324         std::string extraData = "bundleStats size=" + std::to_string(bundleStats.size())
325             + ", dataDir size=" + std::to_string(dataDir.size());
326         StorageRadar::ReportBundleMgrResult("GetAppSize::GetAllBundleStats", res, userId, extraData);
327         return E_BUNDLEMGR_ERROR;
328     }
329 
330     for (uint i = 0; i < bundleStats.size(); i++) {
331         appSize += bundleStats[i];
332     }
333     LOGD("StorageStatusService::GetAppSize end");
334     return E_OK;
335 }
336 
GetUserStorageStatsByType(int32_t userId,StorageStats & storageStats,std::string type)337 int32_t StorageStatusService::GetUserStorageStatsByType(int32_t userId, StorageStats &storageStats, std::string type)
338 {
339     storageStats.video_ = 0;
340     storageStats.image_ = 0;
341     storageStats.file_ = 0;
342     int32_t err = E_OK;
343     if (type == MEDIA_TYPE) {
344         LOGI("GetUserStorageStatsByType media");
345         err = GetMediaStorageStats(storageStats);
346         if (err != E_OK) {
347             StorageRadar::ReportGetStorageStatus("GetMediaStorageStats", userId, err, "setting");
348         }
349     } else if (type == FILE_TYPE) {
350         LOGI("GetUserStorageStatsByType file");
351         err = GetFileStorageStats(userId, storageStats);
352         if (err != E_OK) {
353             StorageRadar::ReportGetStorageStatus("GetFileStorageStats", userId, err, "setting");
354         }
355     } else {
356         LOGI("GetUserStorageStatsByType type: %{public}s", type.c_str());
357     }
358 
359     return err;
360 }
361 } // StorageManager
362 } // OHOS
363