• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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