• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/**
2 * Copyright (c) 2024-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 i18n from '@ohos.i18n';
17import bundleManager from '@ohos.bundle.bundleManager';
18import { BundleInfoBean } from '../../common/bean/BundleInfoBean';
19import common from '@ohos.app.ability.common';
20import Want from '@ohos.app.ability.Want';
21import Logger from '../../common/utils/Logger';
22import { StringUtil } from '../../common/utils/StringUtil';
23import resourceManager from '@ohos.resourceManager';
24
25const USER_ID = 100;
26const TAG = 'BundleInfoModel';
27const ACTION = 'action.access.privacy.center';
28
29class BundleInfoModel {
30  private context = getContext(this) as common.UIAbilityContext;
31
32  getAllBundleLabelAndIcon(allBundleInfo: bundleManager.ApplicationInfo[]) {
33    let bundleInfoList: BundleInfoBean[] = []
34    return new Promise<BundleInfoBean[]>(async (resolve, reject) => {
35      try {
36        allBundleInfo = allBundleInfo.filter((item, index, arr) => {
37          return arr.findIndex(t => t.name === item.name) === index;
38        });
39        for (let index = 0; index < allBundleInfo.length; index++) {
40          const info = allBundleInfo[index];
41          let bundleInfo: BundleInfoBean = {
42            bundleName: info.name,
43            icon: '',
44            iconId: info.iconId,
45            label: '',
46            labelId: info.labelId,
47            permissionName: '',
48            permissionLabel: '',
49            checkedState: '',
50            checkedStateLabel: '',
51            zhTag: '',
52            indexTag: '',
53            language: '',
54            labelResource: info.labelResource,
55            iconResource: info.iconResource,
56          }
57          await this.updateAppLabelAndIcon(bundleInfo);
58          if (bundleInfo.label && bundleInfo.icon) {
59            bundleInfoList.push(bundleInfo)
60          }
61        }
62      } catch (error) {
63        Logger.error(TAG, `getAllBundleLabelAndIcon error: ${JSON.stringify(error)}`)
64      }
65      resolve(bundleInfoList);
66    })
67  }
68
69  queryExtensionAbilityInfo(bundleName: string) {
70    Logger.info(TAG, `queryExtensionAbilityInfo bundleName: ${bundleName}`);
71    let extensionAbilityType = bundleManager.ExtensionAbilityType.UNSPECIFIED;
72    let extensionFlags = bundleManager.ExtensionAbilityFlag.GET_EXTENSION_ABILITY_INFO_WITH_METADATA;
73    let userId = USER_ID;
74    let want: Want = {
75      bundleName: bundleName,
76      action: ACTION,
77    }
78
79    return new Promise<bundleManager.ExtensionAbilityInfo[]>((resolve) => {
80      bundleManager.queryExtensionAbilityInfo(want, extensionAbilityType, extensionFlags, userId, (err, data) => {
81        if (err) {
82          Logger.error(TAG, `queryExtensionAbilityInfo failed: ${err.message}`)
83        } else {
84          resolve(data);
85          Logger.info(TAG, `queryExtensionAbilityInfo successfully: ${JSON.stringify(data)}`)
86        }
87      })
88    })
89  }
90
91  async queryExtensionAbilityInfoOther() {
92    Logger.info(TAG, 'queryExtensionAbilityInfoOther');
93    let extensionAbilityType = bundleManager.ExtensionAbilityType.UNSPECIFIED;
94    let extensionFlags = bundleManager.ExtensionAbilityFlag.GET_EXTENSION_ABILITY_INFO_WITH_METADATA |
95    bundleManager.ExtensionAbilityFlag.GET_EXTENSION_ABILITY_INFO_WITH_APPLICATION;
96    let userId = USER_ID;
97    let want: Want = {
98      action: ACTION,
99    };
100    let result: bundleManager.ExtensionAbilityInfo[] = [];
101    try {
102      result = await bundleManager.queryExtensionAbilityInfo(want, extensionAbilityType, extensionFlags, userId)
103    } catch (err) {
104      Logger.error(TAG, `queryExtensionAbilityInfoOther fail: ${JSON.stringify(err)}`);
105    }
106    return result;
107  }
108
109  async queryAbilityInfoOther() {
110    Logger.info(TAG, 'queryAbilityInfoOther');
111    let extensionFlags = bundleManager.ExtensionAbilityFlag.GET_EXTENSION_ABILITY_INFO_WITH_METADATA |
112    bundleManager.ExtensionAbilityFlag.GET_EXTENSION_ABILITY_INFO_WITH_APPLICATION;
113    let userId = USER_ID;
114    let want: Want = {
115      action: ACTION,
116    };
117    let result: bundleManager.AbilityInfo[] = [];
118    try {
119      result = await bundleManager.queryAbilityInfo(want, extensionFlags, userId)
120    } catch (err) {
121      Logger.error(TAG, `queryExtensionAbilityInfoOther fail: ${JSON.stringify(err)}`);
122    }
123    return result;
124  }
125
126  //   Get all application information about feature access
127  getAllBundleInfoByFunctionAccess() {
128    let modelFlags = bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_METADATA |
129    bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION |
130    bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_HAP_MODULE |
131    bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_ABILITY |
132    bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_ABILITY;
133    return new Promise<bundleManager.BundleInfo[]>((resolve) => {
134      bundleManager.getAllBundleInfo(modelFlags).then((data) => {
135        resolve(data)
136      }).catch((error: Error) => {
137        resolve([])
138        Logger.error(TAG, `getAllBundleInfo error: ${JSON.stringify(error)}`)
139      })
140    })
141  }
142
143  /**
144   * Get app label and icon resources
145   * @param {Number} index index of all app permissions array
146   * @param {String} bundleName Package names
147   */
148  async updateAppLabelAndIcon(info: BundleInfoBean): Promise<void> {
149    let resourceManager: resourceManager.ResourceManager = this.context.createBundleContext(info.bundleName)
150      .resourceManager;
151    return new Promise<void>(async (resolve, reject) => {
152      try {
153        await resourceManager.getStringValue(info.labelId).then(value => {
154          info.label = value;
155        }).catch((error: Error) => {
156          Logger.error(TAG, `${info.bundleName} getStringValue by ${info.labelId} error=${JSON.stringify(error)}`);
157        })
158        try {
159          let iconDescriptor = resourceManager.getDrawableDescriptor(info.iconId);
160          info.icon = iconDescriptor?.getPixelMap();
161        } catch (exception) {
162          Logger.warn(TAG, `get adaptive icon exception: ${JSON.stringify(exception)}`)
163        }
164        if (!info.icon) {
165          info.icon = await resourceManager.getMediaContentBase64(info.iconId) || $r('app.media.icon');
166        }
167      } catch (error) {
168        Logger.error(TAG, `updateAppLabelAndIcon error: ${JSON.stringify(error)}`)
169      }
170      resolve();
171    })
172  }
173
174  public static readonly zh: string = '';
175  public static readonly en: string = '';
176  public indexValue: string[] = []
177
178  getStringZh(input: string): string {
179    let result: string = '';
180    let upperCaseStr = input.toLocaleUpperCase();
181    let regex: RegExp = new RegExp('[A-Z]');
182    for (let i = 0; i < input.length; i++) {
183      if (upperCaseStr[i].match(regex)) {
184        let index = upperCaseStr.charCodeAt(i) - 'A'.charCodeAt(0);
185        let ch = BundleInfoModel.zh.charAt(index);
186        result += ch;
187      } else {
188        result += upperCaseStr[i];
189      }
190    }
191    return result;
192  }
193
194  findZhIndex(zhCharacter: string): string {
195    if (StringUtil.isEmpty(zhCharacter) || zhCharacter.localeCompare(BundleInfoModel.zh[0], 'zh') < 0) {
196      return '#';
197    }
198    for (let left = 0; left < BundleInfoModel.zh.length - 1; left++) {
199      let next = left + 1;
200      if (zhCharacter.localeCompare(BundleInfoModel.zh[left], 'zh') >= 0 && zhCharacter.localeCompare(BundleInfoModel.zh[next], 'zh') < 0) {
201        return BundleInfoModel.en[left];
202      }
203      if (next === BundleInfoModel.zh.length - 1 && zhCharacter.localeCompare(BundleInfoModel.zh[next], 'zh') >= 0) {
204        return BundleInfoModel.en[next];
205      }
206    }
207    return '';
208  }
209
210  sortByName(appArray: BundleInfoBean[]): BundleInfoBean[] {
211    let enComparator = new Intl.Collator('en');
212    let zhComparator = new Intl.Collator('zh-Hans-CN');
213    try {
214      return appArray.sort((item1: BundleInfoBean, item2: BundleInfoBean) => {
215        if (item1.indexTag !== item2.indexTag) {
216          return enComparator.compare(item1.indexTag, item2.indexTag);
217        }
218        let isEn1 = item1.language === 'EN';
219        let isEn2 = item2.language === 'EN';
220        if (isEn1 && isEn2) {
221          return enComparator.compare(item1.label, item2.label)
222        } else if (isEn1 && !isEn2) {
223          return 1;
224        } else if (!isEn1 && isEn2) {
225          return -1;
226        } else {
227          return zhComparator.compare(item1.zhTag, item2.zhTag);
228        }
229      })
230    } catch (error) {
231      Logger.error(TAG, `sortByName error: ${JSON.stringify(error)}`)
232      return [];
233    }
234  }
235
236  addLocalTag(info: BundleInfoBean) {
237    let isZh = i18n.System.getSystemLanguage().indexOf('zh') >= 0;
238    let appName: string = info.label;
239    let upperCase = StringUtil.isEmpty(appName) ? '' : appName[0].toLocaleUpperCase();
240    let regexEn: RegExp = new RegExp('[A-Z]');
241    let regexNm: RegExp = new RegExp('[0-9]');
242
243    if (isZh) {
244      if (upperCase.match(regexEn)) {
245        info.zhTag = this.getStringZh(appName);
246        info.indexTag = upperCase;
247        info.language = 'EN';
248      } else {
249        info.zhTag = appName;
250        info.language = 'CN';
251        if (upperCase.match(regexNm)) {
252          info.indexTag = '#';
253        } else {
254          info.indexTag = this.findZhIndex(upperCase);
255        }
256      }
257    } else {
258      if (upperCase.match(regexEn)) {
259        info.zhTag = appName;
260        info.indexTag = upperCase;
261        info.language = 'EN';
262      } else {
263        info.zhTag = appName;
264        info.indexTag = '#';
265        info.language = 'CN';
266      }
267    }
268  }
269}
270
271let bundleInfoModel = new BundleInfoModel();
272
273export default bundleInfoModel as BundleInfoModel;
274