1/** 2 * Copyright (c) 2021-2022 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 resourceManager from '@ohos.resourceManager'; 17import { Log } from '../utils/Log'; 18import { CheckEmptyUtils } from '../utils/CheckEmptyUtils'; 19import AppResourceCacheManager from '../cache/AppResourceCacheManager'; 20import { DrawableDescriptor, LayeredDrawableDescriptor } from '@ohos.arkui.drawableDescriptor'; 21import image from '@ohos.multimedia.image'; 22 23const KEY_ICON = 'icon'; 24const KEY_NAME = 'name'; 25const TAG = 'ResourceManager'; 26 27/** 28 * Wrapper class for resourceManager interfaces. 29 */ 30export class ResourceManager { 31 private fontWeightRegular: string; 32 private fontWeightMedium: string; 33 34 private constructor() { 35 this.getStringByIdSync($r('sys.string.ohos_id_text_font_family_regular').id).then(value => { 36 this.fontWeightRegular = value; 37 }); 38 this.getStringByIdSync($r('sys.string.ohos_id_text_font_family_medium').id).then(value => { 39 this.fontWeightMedium = value; 40 }); 41 } 42 43 static getInstance(): ResourceManager { 44 if (globalThis.ResourceManager == null) { 45 globalThis.ResourceManager = new ResourceManager(); 46 } 47 return globalThis.ResourceManager; 48 } 49 50 private getAppResourceCacheManager(): AppResourceCacheManager { 51 if (globalThis.AppResourceCacheManager == null) { 52 globalThis.AppResourceCacheManager = new AppResourceCacheManager(); 53 } 54 return globalThis.AppResourceCacheManager; 55 } 56 57 getCachedAppIcon(iconId, bundleName: string, moduleName: string) { 58 const cacheKey = `${iconId}${bundleName}${moduleName}`; 59 return this.getAppResourceCacheManager().getCache(cacheKey, KEY_ICON); 60 } 61 62 setAppResourceCache(cacheKey: string, cacheType: string, value: object | string): void { 63 this.getAppResourceCacheManager().setCache(cacheKey, cacheType, value); 64 } 65 66 deleteAppResourceCache(cacheKey: string, cacheType: string): void { 67 this.getAppResourceCacheManager().deleteCache(cacheKey, cacheType); 68 } 69 70 async updateIconCache(iconId, bundleName: string, moduleName: string): Promise<void> { 71 let cacheKey = `${iconId}${bundleName}${moduleName}`; 72 const iconBase64 = this.getAppResourceCache(cacheKey, KEY_ICON); 73 if (!CheckEmptyUtils.isEmpty(iconBase64)) { 74 return; 75 } 76 Log.showDebug(TAG, `updateIconCache bundleName:${bundleName}, moduleName:${moduleName}, iconId: ${iconId}`); 77 try { 78 // 先拿分层图标,拿不到再取普通图标 79 let resMgr: resourceManager.ResourceManager = globalThis.desktopContext.createModuleResourceManager(bundleName, moduleName); 80 let imageDescriptor: DrawableDescriptor = (resMgr.getDrawableDescriptor(Number(iconId), undefined)); 81 let value: image.PixelMap = imageDescriptor.getPixelMap(); 82 if (imageDescriptor instanceof LayeredDrawableDescriptor) { 83 Log.showDebug(TAG, 'updateIconCache layered icon'); 84 this.setAppResourceCache(cacheKey, KEY_ICON, value); 85 } else { 86 let moduleContext = globalThis.desktopContext.createModuleContext(bundleName, moduleName); 87 if (moduleContext == null) { 88 return; 89 } 90 await moduleContext.resourceManager 91 .getMediaBase64(iconId) 92 .then((value) => { 93 Log.showDebug(TAG, 'updateIconCache normal icon'); 94 if (value != null) { 95 this.setAppResourceCache(cacheKey, KEY_ICON, value); 96 } 97 }).finally(() => { 98 moduleContext = null; 99 }); 100 } 101 } catch (error) { 102 Log.showError(TAG, `updateIconCache error ${error}`); 103 } 104 } 105 106 getAppIconWithCache(iconId, bundleName: string, moduleName: string, callback, defaultAppIcon) { 107 if (CheckEmptyUtils.isEmpty(iconId) || iconId <= 0) { 108 Log.showDebug(TAG, 'getAppIconWithCache defaultAppIcon'); 109 callback(defaultAppIcon); 110 } else { 111 const cacheKey = `${iconId}${bundleName}${moduleName}`; 112 const iconBase64 = this.getAppResourceCache(cacheKey, KEY_ICON); 113 if (CheckEmptyUtils.isEmpty(iconBase64)) { 114 if (this.isResourceManagerEmpty()) { 115 Log.showError(TAG, 'getAppIconWithCache resourceManager is empty'); 116 callback(defaultAppIcon); 117 return; 118 } 119 try { 120 Log.showDebug(TAG, `getAppIconWithCache bundleName:${bundleName}, moduleName:${moduleName}, iconId:${iconId}`); 121 let moduleContext = globalThis.desktopContext.createModuleContext(bundleName, moduleName); 122 moduleContext.resourceManager 123 .getMediaBase64(iconId) 124 .then((value: string)=> { 125 if (value != null) { 126 this.setAppResourceCache(cacheKey, KEY_ICON, value); 127 callback(value); 128 } 129 else { 130 callback(defaultAppIcon); 131 } 132 }) 133 .finally(() => { 134 moduleContext = null; 135 }); 136 } catch (error) { 137 Log.showError(TAG, `getAppIconWithCache error ${error}`); 138 callback(defaultAppIcon); 139 } 140 } else { 141 callback(iconBase64); 142 } 143 } 144 } 145 146 async getAppNameSync(labelId, bundleName: string, moduleName:string, appName: string): Promise<string> { 147 if (CheckEmptyUtils.isEmpty(labelId) || labelId <= 0 || 148 CheckEmptyUtils.checkStrIsEmpty(bundleName) || this.isResourceManagerEmpty()) { 149 Log.showDebug(TAG, `getAppNameSync param empty! appName: ${appName}`); 150 return appName; 151 } 152 const cacheKey = `${labelId}${bundleName}${moduleName}`; 153 let resMgrName = null; 154 let moduleContext = null; 155 Log.showDebug(TAG, `getAppNameSync bundleName:${bundleName}, moduleName:${moduleName}, iconId:${labelId}`); 156 try { 157 moduleContext = globalThis.desktopContext.createModuleContext(bundleName, moduleName); 158 resMgrName = await moduleContext.resourceManager.getString(labelId); 159 } catch (error) { 160 resMgrName = null; 161 Log.showError(TAG, `getAppNameSync getString error: ${JSON.stringify(error)}`); 162 } finally { 163 moduleContext = null; 164 }; 165 if (resMgrName != null) { 166 this.setAppResourceCache(cacheKey, KEY_NAME, resMgrName); 167 return resMgrName; 168 } else { 169 return appName; 170 } 171 } 172 173 getAppNameWithCache(labelId: number, bundleName: string, moduleName: string, appName: string, callback) { 174 if (CheckEmptyUtils.isEmpty(labelId) || labelId <= 0) { 175 Log.showDebug(TAG, `getAppNameWithCache ResourceManager getAppName callback: ${appName}`); 176 callback(appName); 177 } else { 178 const cacheKey = `${labelId}${bundleName}${moduleName}`; 179 const name = this.getAppResourceCache(cacheKey, KEY_NAME); 180 if (CheckEmptyUtils.isEmpty(name)) { 181 if (this.isResourceManagerEmpty()) { 182 return appName; 183 } 184 try { 185 Log.showDebug(TAG, `getAppNameWithCache bundleName:${bundleName}, moduleName:${moduleName}, iconId:${labelId}`); 186 let moduleContext = globalThis.desktopContext.createModuleContext(bundleName, moduleName); 187 moduleContext.resourceManager 188 .getString(labelId) 189 .then((value) => { 190 if (CheckEmptyUtils.checkStrIsEmpty(value)) { 191 Log.showDebug(TAG, `getAppNameWithCache getAppName getString ERROR! value is empty id ${labelId}`); 192 callback(appName); 193 } else { 194 this.setAppResourceCache(cacheKey, KEY_NAME, value); 195 callback(value); 196 } 197 }) 198 .finally(() => { 199 moduleContext = null; 200 }); 201 } catch (err) { 202 Log.showError(TAG, `getAppNameWithCache error: ${JSON.stringify(err)}`); 203 callback(appName); 204 } 205 } else { 206 callback(name); 207 } 208 } 209 } 210 211 /** 212 * Get app resource cache. 213 * 214 * @param {string} cacheKey 215 * @param {string} cacheType 216 */ 217 getAppResourceCache(cacheKey, cacheType) { 218 return this.getAppResourceCacheManager().getCache(cacheKey, cacheType); 219 } 220 221 /** 222 * get string by resource.id. 223 * 224 * @param {number} resource.id 225 * @param {function} callback(value) 226 */ 227 getStringById(resId: number, callback: (value: string) => void): void { 228 if (this.isResourceManagerEmpty()) { 229 Log.showDebug(TAG, 'resourceManager is empty'); 230 callback(''); 231 return; 232 } 233 try { 234 globalThis.desktopContext.resourceManager.getString(resId).then((value) => { 235 callback(value); 236 }); 237 } catch (err) { 238 Log.showError(TAG, `getStringById error: ${JSON.stringify(err)}`); 239 callback(''); 240 } 241 } 242 243 private isResourceManagerEmpty(): boolean { 244 return CheckEmptyUtils.isEmpty(globalThis.desktopContext) 245 || CheckEmptyUtils.isEmpty(globalThis.desktopContext.resourceManager); 246 } 247 248 async getStringByResource(res: resourceManager.Resource): Promise<string>{ 249 const json = JSON.parse(JSON.stringify(res)); 250 const id = json.id; 251 return await this.getStringByIdSync(id); 252 } 253 254 /** 255 * get string by resource.id. 256 * 257 * @param {number} resource.id 258 * @return {string} resource name 259 */ 260 async getStringByIdSync(resId: number): Promise<string> { 261 let resMgrName = ''; 262 if (resId <= 0) { 263 return resMgrName; 264 } else { 265 if (this.isResourceManagerEmpty()) { 266 return resMgrName; 267 } 268 try { 269 resMgrName = await globalThis.desktopContext.resourceManager.getString(resId); 270 } catch (err) { 271 Log.showError(TAG, `getStringByIdSync error: ${JSON.stringify(err)}`); 272 } 273 return resMgrName; 274 } 275 } 276 277 clearAppResourceCache(): void { 278 this.getAppResourceCacheManager().clearCache(); 279 } 280 281 /** 282 * get number by resource 283 * 284 * @param {Resource} resource 285 * @return {number} resource name 286 */ 287 getNumberByResource(res: Resource): number { 288 const json = JSON.parse(JSON.stringify(res)); 289 const id: number = json.id; 290 return this.getNumberById(id); 291 } 292 293 /** 294 * get number by resource.id. 295 * 296 * @param {number} resource.id 297 * @return {number} resource name 298 */ 299 getNumberById(resId: number): number { 300 let resMgrName = 0; 301 if (resId <= 0) { 302 Log.showInfo(TAG, `getNumberById resId: ${resId}`); 303 return resMgrName; 304 } else { 305 if (this.isResourceManagerEmpty()) { 306 Log.showInfo(TAG, 'getNumberById resourceManager is empty'); 307 return resMgrName; 308 } 309 try { 310 resMgrName = globalThis.desktopContext.resourceManager.getNumber(resId); 311 } catch (err) { 312 Log.showError(TAG, `getNumberById error: ${JSON.stringify(err)}`); 313 } 314 Log.showInfo(TAG, `getNumberById resMgrName: ${resMgrName}`); 315 return resMgrName; 316 } 317 } 318 319 getFontWeightRegular(): string { 320 return this.fontWeightRegular; 321 } 322 323 getFontWeightMedium(): string { 324 return this.fontWeightMedium; 325 } 326}