1/* 2 * Copyright (c) 2022-2023 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 16import bundle from '@ohos.bundle.bundleManager' 17import storageStatistics from '@ohos.file.storageStatistics' 18import { AppData } from '../model/AppData' 19import CheckEmptyUtils from '../utils/CheckEmptyUtils' 20import Logger from '../utils/Logger' 21import ParseData from '../common/ParseData' 22import { StorageData } from '../model/StorageData' 23 24const TAG: string = 'QueryStorageData' 25 26export class QueryStorageData { 27 // Size data may get 0, so set -1 as default value 28 public totalSize: number = -1 29 public freeSize: number = -1 30 public itemSizeList: number[] = [] 31 public appDataList: AppData[] = [] 32 public classifiedDataList: StorageData[] = [] 33 private context: Context = getContext(this) as Context 34 35 private async initClassifiedDataList() { 36 this.classifiedDataList = [] 37 let storageStats: storageStatistics.StorageStats = await storageStatistics.getUserStorageStats() 38 this.classifiedDataList.push({ 39 name: $r('app.string.query_data_application'), 40 size: storageStats.app, 41 color: '#F9A20F', 42 }) 43 this.classifiedDataList.push({ 44 name: $r('app.string.query_data_audio'), 45 size: storageStats.audio, 46 color: '#F2400A' 47 }) 48 this.classifiedDataList.push({ 49 name: $r('app.string.query_data_video'), 50 size: storageStats.video, 51 color: '#E65392' 52 }) 53 this.classifiedDataList.push({ 54 name: $r('app.string.query_data_image'), 55 size: storageStats.image, 56 color: '#A12DF7' }) 57 this.classifiedDataList.push({ 58 name: $r('app.string.query_data_file'), 59 size: storageStats.file, 60 color: '#4B48F7' 61 }) 62 this.classifiedDataList.push({ 63 name: $r('app.string.query_data_system'), 64 size: await storageStatistics.getSystemSize(), 65 color: '#007DFF' 66 }) 67 Logger.info(TAG, `classifiedDataList: ${JSON.stringify(this.classifiedDataList)}`) 68 } 69 70 private async initAppDataList() { 71 this.appDataList = [] 72 let bundleFlags = bundle.ApplicationFlag.GET_APPLICATION_INFO_DEFAULT | bundle.ApplicationFlag.GET_APPLICATION_INFO_WITH_PERMISSION | bundle.ApplicationFlag.GET_APPLICATION_INFO_WITH_METADATA | bundle.ApplicationFlag.GET_APPLICATION_INFO_WITH_DISABLE; 73 let applicationInfo: bundle.ApplicationInfo[] = 74 await bundle.getAllApplicationInfo(bundleFlags) 75 for (let i = 0; i < applicationInfo.length; i++) { 76 let info: bundle.ApplicationInfo = applicationInfo[i] 77 let appName: string = await this.getAppNameSync(info.labelId, info.name, info.label) 78 this.appDataList.push({ 79 appName: appName, 80 bundleName: info.name, 81 bundleStats: await storageStatistics.getBundleStats(info.name), 82 hasLabel: this.isAppHasAvailableLabel(appName) 83 }) 84 } 85 Logger.info(TAG, `appDataList: ${JSON.stringify(this.appDataList)}`) 86 } 87 88 private async initItemSizeList() { 89 this.itemSizeList = [] 90 for (let i = 0; i < this.classifiedDataList.length; i++) { 91 this.itemSizeList.push(ParseData.parseSize(this.classifiedDataList[i].size)) 92 } 93 Logger.info(TAG, `itemSizeList: ${JSON.stringify(this.itemSizeList)}`) 94 } 95 96 public async initData(callback?: (hasInit: boolean) => void) { 97 if(callback === undefined){ 98 return 99 } 100 101 try { 102 await this.initClassifiedDataList() 103 await this.initAppDataList() 104 await this.initItemSizeList() 105 this.totalSize = await storageStatistics.getTotalSize() 106 this.freeSize = await storageStatistics.getFreeSize() 107 } catch (error) { 108 Logger.error(TAG, `Init data failed ! error: ${error}`) 109 callback(false) 110 return 111 } 112 callback(true) 113 return 114 } 115 116 public async getUsedSize(callback: (usedSize: number) => void) { 117 if (this.totalSize > -1 && this.freeSize > -1) { 118 callback(this.totalSize - this.freeSize) 119 return 120 } 121 Logger.info(TAG, `totalSize or freeSize is -1, init data`) 122 await this.initData() 123 callback(this.totalSize - this.freeSize) 124 return 125 } 126 127 private async getAppNameSync(labelId: number, bundleName: string, appName: string): Promise<string> { 128 if (CheckEmptyUtils.isEmpty(labelId) || labelId <= 0 || CheckEmptyUtils.checkStrIsEmpty(bundleName)) { 129 Logger.info(TAG, `getAppNameSync param empty! appName: ${appName}`) 130 return appName 131 } else { 132 let cacheKey = labelId + bundleName 133 Logger.info(TAG, `getAppNameSync getResourceManager cacheKey: ${cacheKey}`) 134 if (this.isResourceManagerEmpty()) { 135 Logger.info(TAG, 'getAppNameSync resourceManager is empty') 136 return appName 137 } 138 let bundleContext: Context = this.context.createBundleContext(bundleName) 139 let resMgrName: string = await bundleContext.resourceManager.getString(labelId) 140 Logger.info(TAG, `getAppNameSync resMgrName: ${resMgrName}`) 141 if (resMgrName != null) { 142 return resMgrName 143 } else { 144 return appName 145 } 146 } 147 } 148 149 private isResourceManagerEmpty(): boolean { 150 return CheckEmptyUtils.isEmpty(this.context) 151 || CheckEmptyUtils.isEmpty(this.context.resourceManager) 152 } 153 154 private isAppHasAvailableLabel(appName: string): boolean { 155 if (CheckEmptyUtils.checkStrIsEmpty(appName) || appName === 'label') { 156 return false 157 } 158 159 return true 160 } 161} 162 163export default new QueryStorageData()