• 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 "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