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