• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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