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