1 /*
2 * Copyright (c) 2021 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 "hap_token_info.h"
20 #include "hitrace_meter.h"
21 #include "storage_service_constant.h"
22 #include "storage_service_errno.h"
23 #include "storage_service_log.h"
24 #include "storage/storage_total_status_service.h"
25 #include "installd_client.h"
26 #include "bundle_mgr_interface.h"
27 #include "bundle_mgr_proxy.h"
28 #include "application_info.h"
29 #include "iservice_registry.h"
30 #include "system_ability_definition.h"
31 #include "utils/storage_utils.h"
32 #ifdef STORAGE_SERVICE_GRAPHIC
33 #include "media_library_manager.h"
34 #include "media_volume.h"
35 #endif
36
37 using namespace std;
38
39 namespace OHOS {
40 namespace StorageManager {
StorageStatusService()41 StorageStatusService::StorageStatusService() {}
~StorageStatusService()42 StorageStatusService::~StorageStatusService() {}
43
GetCurrentUserId()44 int StorageStatusService::GetCurrentUserId()
45 {
46 int uid = -1;
47 uid = IPCSkeleton::GetCallingUid();
48 int userId = uid / 200000;
49 return userId;
50 }
51
GetCallingPkgName()52 std::string StorageStatusService::GetCallingPkgName()
53 {
54 uint32_t pid = IPCSkeleton::GetCallingTokenID();
55 Security::AccessToken::HapTokenInfo tokenInfo = Security::AccessToken::HapTokenInfo();
56 Security::AccessToken::AccessTokenKit::GetHapTokenInfo(pid, tokenInfo);
57 return tokenInfo.bundleName;
58 }
59
GetBundleStats(const std::string & pkgName,BundleStats & bundleStats)60 int32_t StorageStatusService::GetBundleStats(const std::string &pkgName, BundleStats &bundleStats)
61 {
62 int userId = GetCurrentUserId();
63 LOGD("StorageStatusService::userId is:%d", userId);
64 return GetBundleStats(pkgName, userId, bundleStats);
65 }
66
GetUserStorageStats(StorageStats & storageStats)67 int32_t StorageStatusService::GetUserStorageStats(StorageStats &storageStats)
68 {
69 int userId = GetCurrentUserId();
70 return GetUserStorageStats(userId, storageStats);
71 }
72
GetUserStorageStats(int32_t userId,StorageStats & storageStats)73 int32_t StorageStatusService::GetUserStorageStats(int32_t userId, StorageStats &storageStats)
74 {
75 // totalSize
76 int64_t totalSize = 0;
77 int32_t err = DelayedSingleton<StorageTotalStatusService>::GetInstance()->GetTotalSize(totalSize);
78 if (err != E_OK) {
79 LOGE("StorageStatusService::GetUserStorageStats getTotalSize failed");
80 return err;
81 }
82 // appSize
83 LOGI("StorageStatusService::GetUserStorageStats userId is %{public}d", userId);
84 err = ConnectBundleMgr();
85 if (err != E_OK) {
86 LOGE("StorageStatusService::GetUserStorageStats connect bundlemgr failed");
87 return err;
88 }
89 vector<AppExecFwk::ApplicationInfo> appInfos;
90 bool res = bundleMgr_->GetApplicationInfos(
91 AppExecFwk::ApplicationFlag::GET_BASIC_APPLICATION_INFO, userId, appInfos);
92 if (!res) {
93 LOGE("StorageStatusService::GetUserStorageStats an error occured in querying appInfos");
94 return E_BUNDLEMGR_ERROR;
95 }
96 int64_t appSize = 0;
97 for (const auto& appInfo : appInfos) {
98 int64_t bundleSize = 0;
99 LOGD("StorageStatusService::GetCurUserStorageStats pkgname is %{public}s", appInfo.name.c_str());
100 vector<int64_t> bundleStats;
101 res = bundleMgr_->GetBundleStats(appInfo.name, userId, bundleStats);
102 if (!res || bundleStats.size() != dataDir.size()) {
103 LOGE("StorageStatusService::An error occurred in querying bundle stats.");
104 return E_BUNDLEMGR_ERROR;
105 }
106 for (uint i = 0; i < bundleStats.size(); i++) {
107 bundleSize += bundleStats[i];
108 }
109 appSize += bundleSize;
110 }
111 // mediaSize
112 #ifdef STORAGE_SERVICE_GRAPHIC
113 Media::MediaLibraryManager mgr;
114 Media::MediaVolume mediaVol;
115 auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
116 if (sam == nullptr) {
117 LOGE("StorageStatusService::GetUserStorageStats samgr == nullptr");
118 return E_SA_IS_NULLPTR;
119 }
120 auto remoteObj = sam->GetSystemAbility(STORAGE_MANAGER_MANAGER_ID);
121 if (remoteObj == nullptr) {
122 LOGE("StorageStatusService::GetUserStorageStats remoteObj == nullptr");
123 return E_REMOTE_IS_NULLPTR;
124 }
125 mgr.InitMediaLibraryManager(remoteObj);
126 if (mgr.QueryTotalSize(mediaVol)) {
127 LOGE("StorageStatusService::GetUserStorageStats an error occured in querying mediaSize");
128 return E_MEDIALIBRARY_ERROR;
129 }
130 #endif
131 storageStats.total_ = totalSize;
132 storageStats.app_ = appSize;
133 #ifdef STORAGE_SERVICE_GRAPHIC
134 storageStats.audio_ = mediaVol.GetAudiosSize();
135 storageStats.video_ = mediaVol.GetVideosSize();
136 storageStats.image_ = mediaVol.GetImagesSize();
137 storageStats.file_ = mediaVol.GetFilesSize();
138 #endif
139 return E_OK;
140 }
141
GetCurrentBundleStats(BundleStats & bundleStats)142 int32_t StorageStatusService::GetCurrentBundleStats(BundleStats &bundleStats)
143 {
144 int userId = GetCurrentUserId();
145 LOGD("StorageStatusService::userId is:%d", userId);
146 std::string pkgName = GetCallingPkgName();
147 return GetBundleStats(pkgName, userId, bundleStats);
148 }
149
GetBundleStats(const std::string & pkgName,int32_t userId,BundleStats & pkgStats)150 int32_t StorageStatusService::GetBundleStats(const std::string &pkgName, int32_t userId, BundleStats &pkgStats)
151 {
152 HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
153 int32_t err = ConnectBundleMgr();
154 if (err != E_OK) {
155 LOGE("StorageStatusService::GetBundleStats connect bundlemgr failed");
156 return err;
157 }
158
159 if (userId < 0 || userId > StorageService::MAX_USER_ID) {
160 LOGE("StorageStatusService::Invaild userId.");
161 return E_USERID_RANGE;
162 }
163
164 vector<int64_t> bundleStats;
165 bool res = bundleMgr_->GetBundleStats(pkgName, userId, bundleStats);
166 if (!res || bundleStats.size() != dataDir.size()) {
167 LOGE("StorageStatusService::An error occurred in querying bundle stats.");
168 return E_BUNDLEMGR_ERROR;
169 }
170 for (uint i = 0; i < bundleStats.size(); i++) {
171 if (bundleStats[i] == E_ERR) {
172 LOGE("StorageStatusService::Failed to query %s data.", dataDir[i].c_str());
173 bundleStats[i] = 0;
174 }
175 }
176 pkgStats.appSize_ = bundleStats[APP];
177 pkgStats.cacheSize_ = bundleStats[CACHE];
178 pkgStats.dataSize_ = bundleStats[LOCAL] + bundleStats[DISTRIBUTED] + bundleStats[DATABASE];
179 return E_OK;
180 }
181
ConnectBundleMgr()182 int32_t StorageStatusService::ConnectBundleMgr()
183 {
184 LOGI("connect begin");
185 std::lock_guard<std::mutex> lock(mutex_);
186 if (bundleMgr_ == nullptr) {
187 auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
188 if (sam == nullptr) {
189 LOGE("StorageStatusService::ConnectBundleMgr samgr == nullptr");
190 return E_SA_IS_NULLPTR;
191 }
192
193 sptr<IRemoteObject> remoteObject = sam->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
194 if (!remoteObject) {
195 LOGE("StorageStatusService::ConnectBundleMgr remoteObj == nullptr");
196 return E_REMOTE_IS_NULLPTR;
197 }
198
199 bundleMgr_ = iface_cast<AppExecFwk::IBundleMgr>(remoteObject);
200 if (bundleMgr_ == nullptr) {
201 LOGE("StorageStatusService::ConnectBundleMgr bundleMgr == nullptr");
202 return E_SERVICE_IS_NULLPTR;
203 }
204
205 deathRecipient_ = new (std::nothrow) BundleMgrDeathRecipient();
206 if (!deathRecipient_) {
207 LOGE("StorageStatusService::ConnectBundleMgr failed to create death recipient");
208 return E_DEATH_RECIPIENT_IS_NULLPTR;
209 }
210
211 bundleMgr_->AsObject()->AddDeathRecipient(deathRecipient_);
212 }
213 LOGI("connect end");
214 return E_OK;
215 }
216
ResetBundleMgrProxy()217 int32_t StorageStatusService::ResetBundleMgrProxy()
218 {
219 LOGD("enter");
220 std::lock_guard<std::mutex> lock(mutex_);
221 if ((bundleMgr_ != nullptr) && (bundleMgr_->AsObject() != nullptr)) {
222 bundleMgr_->AsObject()->RemoveDeathRecipient(deathRecipient_);
223 }
224 bundleMgr_ = nullptr;
225
226 return E_OK;
227 }
228
OnRemoteDied(const wptr<IRemoteObject> & remote)229 void BundleMgrDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
230 {
231 DelayedSingleton<StorageStatusService>::GetInstance()->ResetBundleMgrProxy();
232 }
233 } // StorageManager
234 } // OHOS
235