1/** 2 * Copyright (c) 2023-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 atomicServiceAbilityManager from '../manager/AtomicServiceAbilityManager'; 17import SystemApplication from '../configs/SystemApplication'; 18import { CheckEmptyUtils } from '../utils/CheckEmptyUtils'; 19import { CommonConstants } from '../constants/CommonConstants'; 20import type { AppItemInfo } from '../bean/AppItemInfo'; 21import { FormModel } from './FormModel'; 22import { Log } from '../utils/Log'; 23 24const TAG = 'AtomicServiceAppModel'; 25 26/** 27 * Desktop application information data model. 28 */ 29export class AtomicServiceAppModel { 30 private mAtomicServiceBundleInfoList: AppItemInfo[] = []; 31 private readonly mSystemApplicationName: string[] = []; 32 private readonly mAppStateChangeListener = []; 33 private readonly mFormModel: FormModel; 34 private static mInstance: AtomicServiceAppModel; 35 36 private constructor() { 37 Log.showInfo(TAG, 'constructor start'); 38 this.mSystemApplicationName = SystemApplication.SystemApplicationName.split(','); 39 this.mFormModel = FormModel.getInstance(); 40 } 41 42 /** 43 * Get the application data model object. 44 * 45 * @return {object} application data model singleton 46 */ 47 static getInstance(): AtomicServiceAppModel { 48 if (AtomicServiceAppModel.mInstance == null) { 49 AtomicServiceAppModel.mInstance = new AtomicServiceAppModel(); 50 globalThis.AtomicServiceAppModel = AtomicServiceAppModel.mInstance; 51 } 52 return AtomicServiceAppModel.mInstance; 53 } 54 55 /** 56 * Get the list of apps displayed on the desktop. 57 * (public function, reduce the frequency of method call) 58 * 59 * @return {array} bundleInfoList 60 */ 61 async getAtomicServiceAppList(): Promise<AppItemInfo[]> { 62 Log.showInfo(TAG, 'getAtomicServiceAppList start'); 63 if (!CheckEmptyUtils.isEmptyArr(this.mAtomicServiceBundleInfoList)) { 64 Log.showInfo(TAG, `getAtomicServiceAppList bundleInfoList length: ${this.mAtomicServiceBundleInfoList.length}`); 65 return this.mAtomicServiceBundleInfoList; 66 } 67 const bundleInfoList: AppItemInfo[] = await this.getAtomicServiceAppListAsync(); 68 Log.showInfo(TAG, `getAtomicServiceAppList bundleInfoList length: ${this.mAtomicServiceBundleInfoList.length}`); 69 return bundleInfoList; 70 } 71 72 /** 73 * Get the list of apps displayed on the desktop (private function). 74 * 75 * @return {array} bundleInfoList, excluding system applications 76 */ 77 async getAtomicServiceAppListAsync(): Promise<AppItemInfo[]> { 78 let allAbilityList: AppItemInfo[] = await atomicServiceAbilityManager.getAtomicServiceAbilityList(); 79 let atomicServiceAbilityList: AppItemInfo[] = []; 80 if (CheckEmptyUtils.isEmptyArr(allAbilityList)) { 81 return atomicServiceAbilityList; 82 } 83 Log.showInfo(TAG, `getAtomicServiceAppListAsync allAbilityList length: ${allAbilityList.length}`); 84 for (let ability of allAbilityList) { 85 if (this.mSystemApplicationName.indexOf(ability.bundleName) === CommonConstants.INVALID_VALUE) { 86 atomicServiceAbilityList.push(ability); 87 await this.mFormModel.updateAtomicServiceAppItemFormInfo(ability.bundleName); 88 } 89 } 90 this.mAtomicServiceBundleInfoList = atomicServiceAbilityList; 91 Log.showInfo(TAG, `getAtomicServiceAppListAsync length: ${atomicServiceAbilityList.length}`); 92 return atomicServiceAbilityList; 93 } 94 95 /** 96 * Register application list change event listener. 97 * 98 * @param listener 99 */ 100 registerStateChangeListener(listener): void { 101 if (this.mAppStateChangeListener.indexOf(listener) === CommonConstants.INVALID_VALUE) { 102 this.mAppStateChangeListener.push(listener); 103 } 104 } 105 106 /** 107 * Unregister application list change event listener. 108 * 109 * @param listener 110 */ 111 unregisterAppStateChangeListener(listener): void { 112 let index: number = this.mAppStateChangeListener.indexOf(listener); 113 if (index !== CommonConstants.INVALID_VALUE) { 114 this.mAppStateChangeListener.splice(index, 1); 115 } 116 } 117 118 /** 119 * 获取userId. 120 */ 121 getUserId(): number { 122 return atomicServiceAbilityManager.getUserId(); 123 } 124 125 /** 126 * 获取并替换原子服务App 127 * 128 * @param bundleName 包名 129 */ 130 async getAndReplaceAtomicAbility(bundleName: string): Promise<AppItemInfo> { 131 const abilityInfos: AppItemInfo[] = await atomicServiceAbilityManager.getAtomicServiceAbilityInfoAsync(bundleName); 132 if (CheckEmptyUtils.isEmptyArr(abilityInfos)) { 133 Log.showInfo(TAG, 'cannot get abilityInfo by bundleName:' + bundleName); 134 return undefined; 135 } 136 Log.showInfo(TAG, `atomic abilityInfos: ${JSON.stringify(abilityInfos)}`); 137 this.replaceAtomicServiceItem(bundleName, abilityInfos); 138 return abilityInfos[0]; 139 } 140 141 notifyAppStateChangeEvent(): void { 142 for (let i = 0; i < this.mAppStateChangeListener.length; i++) { 143 this.mAppStateChangeListener[i](this.mAtomicServiceBundleInfoList); 144 } 145 } 146 147 private getAtomicServiceItemIndex(bundleName: string): number { 148 for (const listItem of this.mAtomicServiceBundleInfoList) { 149 if (listItem.bundleName === bundleName) { 150 return this.mAtomicServiceBundleInfoList.indexOf(listItem); 151 } 152 } 153 return CommonConstants.INVALID_VALUE; 154 } 155 156 private appendAtomicServiceItem(abilityInfos: AppItemInfo[]): void { 157 for (let index = 0; index < abilityInfos.length; index++) { 158 this.mAtomicServiceBundleInfoList.push(abilityInfos[index]); 159 } 160 } 161 162 /** 163 * 移除原子服务App 164 * 165 * @param bundleName 包名 166 */ 167 removeAtomicServiceItem(bundleName: string): void { 168 Log.showDebug(TAG, `removeAtomicServiceItem bundleName: ${bundleName}`); 169 this.mFormModel.deleteAtomicServiceAppItemFormInfo(bundleName); 170 let originItemIndex: number = this.getAtomicServiceItemIndex(bundleName); 171 while (originItemIndex !== CommonConstants.INVALID_VALUE) { 172 this.removeItemCache(this.mAtomicServiceBundleInfoList[originItemIndex]); 173 this.mAtomicServiceBundleInfoList.splice(originItemIndex, 1); 174 originItemIndex = this.getAtomicServiceItemIndex(bundleName); 175 } 176 } 177 178 private removeItemCache(appItemInfo: AppItemInfo): void { 179 Log.showInfo(TAG, `removeItemCache bundleName: ${(appItemInfo.bundleName)}`); 180 let cacheKey: string = appItemInfo.appLabelId + appItemInfo.bundleName + appItemInfo.moduleName; 181 globalThis.ResourceManager.deleteAppResourceCache(cacheKey, 'name'); 182 cacheKey = appItemInfo.appIconId + appItemInfo.bundleName + appItemInfo.moduleName; 183 globalThis.ResourceManager.deleteAppResourceCache(cacheKey, 'icon'); 184 } 185 186 private replaceAtomicServiceItem(bundleName: string, abilityInfos: AppItemInfo[]): void { 187 Log.showDebug(TAG, `replaceAtomicServiceItem bundleName: ${bundleName}`); 188 this.removeAtomicServiceItem(bundleName); 189 this.appendAtomicServiceItem(abilityInfos); 190 } 191} 192