• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2022-2024 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 bundleName;
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 bundleName;
137      }
138      let resMgrName: string = '';
139      try {
140        let bundleContext: Context = this.context.createBundleContext(bundleName);
141        resMgrName = bundleContext.resourceManager.getStringSync(labelId);
142      } catch (err) {
143        Logger.error(TAG, `getAppNameSync error: ${JSON.stringify(err)}`);
144      }
145
146      Logger.info(TAG, `getAppNameSync resMgrName: ${resMgrName}`);
147      if (resMgrName != '') {
148        return resMgrName;
149      } else {
150        return bundleName;
151      }
152    }
153  }
154
155  private isResourceManagerEmpty(): boolean {
156    return CheckEmptyUtils.isEmpty(this.context)
157    || CheckEmptyUtils.isEmpty(this.context.resourceManager)
158  }
159
160  private isAppHasAvailableLabel(appName: string): boolean {
161    if (CheckEmptyUtils.checkStrIsEmpty(appName) || appName === 'label') {
162      return false
163    }
164
165    return true
166  }
167}
168
169export default new QueryStorageData()