16e80583aSopenharmony_ci/**
26e80583aSopenharmony_ci * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
36e80583aSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
46e80583aSopenharmony_ci * you may not use this file except in compliance with the License.
56e80583aSopenharmony_ci * You may obtain a copy of the License at
66e80583aSopenharmony_ci *
76e80583aSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
86e80583aSopenharmony_ci *
96e80583aSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
106e80583aSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
116e80583aSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
126e80583aSopenharmony_ci * See the License for the specific language governing permissions and
136e80583aSopenharmony_ci * limitations under the License.
146e80583aSopenharmony_ci */
156e80583aSopenharmony_ci
166e80583aSopenharmony_ciimport atomicServiceAbilityManager from '../manager/AtomicServiceAbilityManager';
176e80583aSopenharmony_ciimport SystemApplication from '../configs/SystemApplication';
186e80583aSopenharmony_ciimport { CheckEmptyUtils } from '../utils/CheckEmptyUtils';
196e80583aSopenharmony_ciimport { CommonConstants } from '../constants/CommonConstants';
206e80583aSopenharmony_ciimport type { AppItemInfo } from '../bean/AppItemInfo';
216e80583aSopenharmony_ciimport { FormModel } from './FormModel';
226e80583aSopenharmony_ciimport { Log } from '../utils/Log';
236e80583aSopenharmony_ci
246e80583aSopenharmony_ciconst TAG = 'AtomicServiceAppModel';
256e80583aSopenharmony_ci
266e80583aSopenharmony_ci/**
276e80583aSopenharmony_ci * Desktop application information data model.
286e80583aSopenharmony_ci */
296e80583aSopenharmony_ciexport class AtomicServiceAppModel {
306e80583aSopenharmony_ci  private mAtomicServiceBundleInfoList: AppItemInfo[] = [];
316e80583aSopenharmony_ci  private readonly mSystemApplicationName: string[] = [];
326e80583aSopenharmony_ci  private readonly mAppStateChangeListener = [];
336e80583aSopenharmony_ci  private readonly mFormModel: FormModel;
346e80583aSopenharmony_ci  private static mInstance: AtomicServiceAppModel;
356e80583aSopenharmony_ci
366e80583aSopenharmony_ci  private constructor() {
376e80583aSopenharmony_ci    Log.showInfo(TAG, 'constructor start');
386e80583aSopenharmony_ci    this.mSystemApplicationName = SystemApplication.SystemApplicationName.split(',');
396e80583aSopenharmony_ci    this.mFormModel = FormModel.getInstance();
406e80583aSopenharmony_ci  }
416e80583aSopenharmony_ci
426e80583aSopenharmony_ci  /**
436e80583aSopenharmony_ci   * Get the application data model object.
446e80583aSopenharmony_ci   *
456e80583aSopenharmony_ci   * @return {object} application data model singleton
466e80583aSopenharmony_ci   */
476e80583aSopenharmony_ci  static getInstance(): AtomicServiceAppModel {
486e80583aSopenharmony_ci    if (AtomicServiceAppModel.mInstance == null) {
496e80583aSopenharmony_ci      AtomicServiceAppModel.mInstance = new AtomicServiceAppModel();
506e80583aSopenharmony_ci      globalThis.AtomicServiceAppModel = AtomicServiceAppModel.mInstance;
516e80583aSopenharmony_ci    }
526e80583aSopenharmony_ci    return AtomicServiceAppModel.mInstance;
536e80583aSopenharmony_ci  }
546e80583aSopenharmony_ci
556e80583aSopenharmony_ci  /**
566e80583aSopenharmony_ci   * Get the list of apps displayed on the desktop.
576e80583aSopenharmony_ci   * (public function, reduce the frequency of method call)
586e80583aSopenharmony_ci   *
596e80583aSopenharmony_ci   * @return {array} bundleInfoList
606e80583aSopenharmony_ci   */
616e80583aSopenharmony_ci  async getAtomicServiceAppList(): Promise<AppItemInfo[]> {
626e80583aSopenharmony_ci    Log.showInfo(TAG, 'getAtomicServiceAppList start');
636e80583aSopenharmony_ci    if (!CheckEmptyUtils.isEmptyArr(this.mAtomicServiceBundleInfoList)) {
646e80583aSopenharmony_ci      Log.showInfo(TAG, `getAtomicServiceAppList bundleInfoList length: ${this.mAtomicServiceBundleInfoList.length}`);
656e80583aSopenharmony_ci      return this.mAtomicServiceBundleInfoList;
666e80583aSopenharmony_ci    }
676e80583aSopenharmony_ci    const bundleInfoList: AppItemInfo[] = await this.getAtomicServiceAppListAsync();
686e80583aSopenharmony_ci    Log.showInfo(TAG, `getAtomicServiceAppList bundleInfoList length: ${this.mAtomicServiceBundleInfoList.length}`);
696e80583aSopenharmony_ci    return bundleInfoList;
706e80583aSopenharmony_ci  }
716e80583aSopenharmony_ci
726e80583aSopenharmony_ci  /**
736e80583aSopenharmony_ci   * Get the list of apps displayed on the desktop (private function).
746e80583aSopenharmony_ci   *
756e80583aSopenharmony_ci   * @return {array} bundleInfoList, excluding system applications
766e80583aSopenharmony_ci   */
776e80583aSopenharmony_ci  async getAtomicServiceAppListAsync(): Promise<AppItemInfo[]> {
786e80583aSopenharmony_ci    let allAbilityList: AppItemInfo[] = await atomicServiceAbilityManager.getAtomicServiceAbilityList();
796e80583aSopenharmony_ci    let atomicServiceAbilityList: AppItemInfo[] = [];
806e80583aSopenharmony_ci    if (CheckEmptyUtils.isEmptyArr(allAbilityList)) {
816e80583aSopenharmony_ci      return atomicServiceAbilityList;
826e80583aSopenharmony_ci    }
836e80583aSopenharmony_ci    Log.showInfo(TAG, `getAtomicServiceAppListAsync allAbilityList length: ${allAbilityList.length}`);
846e80583aSopenharmony_ci    for (let ability of allAbilityList) {
856e80583aSopenharmony_ci      if (this.mSystemApplicationName.indexOf(ability.bundleName) === CommonConstants.INVALID_VALUE) {
866e80583aSopenharmony_ci        atomicServiceAbilityList.push(ability);
876e80583aSopenharmony_ci        await this.mFormModel.updateAtomicServiceAppItemFormInfo(ability.bundleName);
886e80583aSopenharmony_ci      }
896e80583aSopenharmony_ci    }
906e80583aSopenharmony_ci    this.mAtomicServiceBundleInfoList = atomicServiceAbilityList;
916e80583aSopenharmony_ci    Log.showInfo(TAG, `getAtomicServiceAppListAsync length: ${atomicServiceAbilityList.length}`);
926e80583aSopenharmony_ci    return atomicServiceAbilityList;
936e80583aSopenharmony_ci  }
946e80583aSopenharmony_ci
956e80583aSopenharmony_ci  /**
966e80583aSopenharmony_ci   * Register application list change event listener.
976e80583aSopenharmony_ci   *
986e80583aSopenharmony_ci   * @param listener
996e80583aSopenharmony_ci   */
1006e80583aSopenharmony_ci  registerStateChangeListener(listener): void {
1016e80583aSopenharmony_ci    if (this.mAppStateChangeListener.indexOf(listener) === CommonConstants.INVALID_VALUE) {
1026e80583aSopenharmony_ci      this.mAppStateChangeListener.push(listener);
1036e80583aSopenharmony_ci    }
1046e80583aSopenharmony_ci  }
1056e80583aSopenharmony_ci
1066e80583aSopenharmony_ci  /**
1076e80583aSopenharmony_ci   * Unregister application list change event listener.
1086e80583aSopenharmony_ci   *
1096e80583aSopenharmony_ci   * @param listener
1106e80583aSopenharmony_ci   */
1116e80583aSopenharmony_ci  unregisterAppStateChangeListener(listener): void {
1126e80583aSopenharmony_ci    let index: number = this.mAppStateChangeListener.indexOf(listener);
1136e80583aSopenharmony_ci    if (index !== CommonConstants.INVALID_VALUE) {
1146e80583aSopenharmony_ci      this.mAppStateChangeListener.splice(index, 1);
1156e80583aSopenharmony_ci    }
1166e80583aSopenharmony_ci  }
1176e80583aSopenharmony_ci
1186e80583aSopenharmony_ci  /**
1196e80583aSopenharmony_ci   * 获取userId.
1206e80583aSopenharmony_ci   */
1216e80583aSopenharmony_ci  getUserId(): number {
1226e80583aSopenharmony_ci    return atomicServiceAbilityManager.getUserId();
1236e80583aSopenharmony_ci  }
1246e80583aSopenharmony_ci
1256e80583aSopenharmony_ci  /**
1266e80583aSopenharmony_ci   * 获取并替换原子服务App
1276e80583aSopenharmony_ci   *
1286e80583aSopenharmony_ci   * @param bundleName 包名
1296e80583aSopenharmony_ci   */
1306e80583aSopenharmony_ci  async getAndReplaceAtomicAbility(bundleName: string): Promise<AppItemInfo> {
1316e80583aSopenharmony_ci    const abilityInfos: AppItemInfo[] = await atomicServiceAbilityManager.getAtomicServiceAbilityInfoAsync(bundleName);
1326e80583aSopenharmony_ci    if (CheckEmptyUtils.isEmptyArr(abilityInfos)) {
1336e80583aSopenharmony_ci      Log.showInfo(TAG, 'cannot get abilityInfo by bundleName:' + bundleName);
1346e80583aSopenharmony_ci      return undefined;
1356e80583aSopenharmony_ci    }
1366e80583aSopenharmony_ci    Log.showInfo(TAG, `atomic abilityInfos: ${JSON.stringify(abilityInfos)}`);
1376e80583aSopenharmony_ci    this.replaceAtomicServiceItem(bundleName, abilityInfos);
1386e80583aSopenharmony_ci    return abilityInfos[0];
1396e80583aSopenharmony_ci  }
1406e80583aSopenharmony_ci
1416e80583aSopenharmony_ci  notifyAppStateChangeEvent(): void {
1426e80583aSopenharmony_ci    for (let i = 0; i < this.mAppStateChangeListener.length; i++) {
1436e80583aSopenharmony_ci      this.mAppStateChangeListener[i](this.mAtomicServiceBundleInfoList);
1446e80583aSopenharmony_ci    }
1456e80583aSopenharmony_ci  }
1466e80583aSopenharmony_ci
1476e80583aSopenharmony_ci  private getAtomicServiceItemIndex(bundleName: string): number {
1486e80583aSopenharmony_ci    for (const listItem of this.mAtomicServiceBundleInfoList) {
1496e80583aSopenharmony_ci      if (listItem.bundleName === bundleName) {
1506e80583aSopenharmony_ci        return this.mAtomicServiceBundleInfoList.indexOf(listItem);
1516e80583aSopenharmony_ci      }
1526e80583aSopenharmony_ci    }
1536e80583aSopenharmony_ci    return CommonConstants.INVALID_VALUE;
1546e80583aSopenharmony_ci  }
1556e80583aSopenharmony_ci
1566e80583aSopenharmony_ci  private appendAtomicServiceItem(abilityInfos: AppItemInfo[]): void {
1576e80583aSopenharmony_ci    for (let index = 0; index < abilityInfos.length; index++) {
1586e80583aSopenharmony_ci      this.mAtomicServiceBundleInfoList.push(abilityInfos[index]);
1596e80583aSopenharmony_ci    }
1606e80583aSopenharmony_ci  }
1616e80583aSopenharmony_ci
1626e80583aSopenharmony_ci  /**
1636e80583aSopenharmony_ci   * 移除原子服务App
1646e80583aSopenharmony_ci   *
1656e80583aSopenharmony_ci   * @param bundleName 包名
1666e80583aSopenharmony_ci   */
1676e80583aSopenharmony_ci  removeAtomicServiceItem(bundleName: string): void {
1686e80583aSopenharmony_ci    Log.showDebug(TAG, `removeAtomicServiceItem bundleName: ${bundleName}`);
1696e80583aSopenharmony_ci    this.mFormModel.deleteAtomicServiceAppItemFormInfo(bundleName);
1706e80583aSopenharmony_ci    let originItemIndex: number = this.getAtomicServiceItemIndex(bundleName);
1716e80583aSopenharmony_ci    while (originItemIndex !== CommonConstants.INVALID_VALUE) {
1726e80583aSopenharmony_ci      this.removeItemCache(this.mAtomicServiceBundleInfoList[originItemIndex]);
1736e80583aSopenharmony_ci      this.mAtomicServiceBundleInfoList.splice(originItemIndex, 1);
1746e80583aSopenharmony_ci      originItemIndex = this.getAtomicServiceItemIndex(bundleName);
1756e80583aSopenharmony_ci    }
1766e80583aSopenharmony_ci  }
1776e80583aSopenharmony_ci
1786e80583aSopenharmony_ci  private removeItemCache(appItemInfo: AppItemInfo): void {
1796e80583aSopenharmony_ci    Log.showInfo(TAG, `removeItemCache bundleName: ${(appItemInfo.bundleName)}`);
1806e80583aSopenharmony_ci    let cacheKey: string = appItemInfo.appLabelId + appItemInfo.bundleName + appItemInfo.moduleName;
1816e80583aSopenharmony_ci    globalThis.ResourceManager.deleteAppResourceCache(cacheKey, 'name');
1826e80583aSopenharmony_ci    cacheKey = appItemInfo.appIconId + appItemInfo.bundleName + appItemInfo.moduleName;
1836e80583aSopenharmony_ci    globalThis.ResourceManager.deleteAppResourceCache(cacheKey, 'icon');
1846e80583aSopenharmony_ci  }
1856e80583aSopenharmony_ci
1866e80583aSopenharmony_ci  private replaceAtomicServiceItem(bundleName: string, abilityInfos: AppItemInfo[]): void {
1876e80583aSopenharmony_ci    Log.showDebug(TAG, `replaceAtomicServiceItem bundleName: ${bundleName}`);
1886e80583aSopenharmony_ci    this.removeAtomicServiceItem(bundleName);
1896e80583aSopenharmony_ci    this.appendAtomicServiceItem(abilityInfos);
1906e80583aSopenharmony_ci  }
1916e80583aSopenharmony_ci}
192