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 bundleManager from '@ohos.bundle.bundleManager';
17import { CheckEmptyUtils } from '../utils/CheckEmptyUtils';
18import osAccount from '@ohos.account.osAccount';
19import type Want from '@ohos.app.ability.Want';
20import { Log } from '../utils/Log';
21
22const TAG = 'CommonBundleManager';
23const DEFAULT_USER_ID = 100;
24
25/**
26 * 通用包管理(可以查询桌面包、原子化服务包)
27 */
28class CommonBundleManager {
29  private static mInstance: CommonBundleManager;
30  private mUserId: number = DEFAULT_USER_ID;
31
32  /**
33   * 获取通用包管理对象
34   *
35   * @return 通用包管理对象单一实例
36   */
37  static getInstance(): CommonBundleManager {
38    if (CommonBundleManager.mInstance == null) {
39      CommonBundleManager.mInstance = new CommonBundleManager();
40      globalThis.CommonBundleManagerInstance = CommonBundleManager.mInstance;
41    }
42    return CommonBundleManager.mInstance;
43  }
44
45  private constructor() {
46    const osAccountManager = osAccount.getAccountManager();
47    osAccountManager.getOsAccountLocalId((err, localId) => {
48      Log.showDebug(TAG, `getOsAccountLocalIdFromProcess localId ${localId}`);
49      this.mUserId = localId;
50    });
51  }
52
53  /**
54   * 获取userId.
55   *
56   * @returns
57   */
58  getUserId(): number {
59    return this.mUserId;
60  }
61
62  /**
63   * 获取所有ability信息
64   *
65   * @param bundleType 包类型:bundleManager.BundleType.APP:桌面app,  bundleManager.BundleType.ATOMIC_SERVICE:原子化服务
66   * @returns 所有ability信息
67   */
68  async getAllAbilityList(bundleType?: bundleManager.BundleType): Promise<bundleManager.AbilityInfo[]> {
69    let abilityList: Array<bundleManager.AbilityInfo> = [];
70    let want: Want = {
71      action : 'action.system.home',
72      entities : ['entity.system.home']
73    };
74    try {
75      await bundleManager.queryAbilityInfo(want, bundleManager.AbilityFlag.GET_ABILITY_INFO_WITH_APPLICATION, this.mUserId)
76        .then((res: Array<bundleManager.AbilityInfo>) => {
77          Log.showInfo(TAG, `getAllAbilityList res length: ${res.length}`);
78          abilityList = res;
79        })
80        .catch((err) => {
81          Log.showError(TAG, `getAllAbilityList error: ${JSON.stringify(err)}`);
82        });
83    } catch (err) {
84      Log.showError(TAG, `getAllAbilityList bundleManager.queryAbilityInfo error: ${JSON.stringify(err)}`);
85    }
86    if (CheckEmptyUtils.isEmptyArr(abilityList)) {
87      Log.showInfo(TAG, 'getAllAbilityList Empty');
88      return [];
89    }
90    if (CheckEmptyUtils.isEmpty(bundleType)) {
91      return abilityList;
92    }
93    return abilityList.filter(ability => ability.applicationInfo.bundleType === bundleType);
94  }
95
96  /**
97   * 根据bundleName获取包信息
98   *
99   * @param bundleName 包名
100   * @param bundleType 包类型:bundleManager.BundleType.APP:桌面app,  bundleManager.BundleType.ATOMIC_SERVICE:原子化服务
101   * @returns 包信息
102   */
103  async getBundleInfoByBundleName(bundleName: string, bundleType?: bundleManager.BundleType): Promise<bundleManager.BundleInfo | undefined> {
104    if (CheckEmptyUtils.checkStrIsEmpty(bundleName)) {
105      Log.showError(TAG, 'getBundleInfoByBundleName reqParam bundleName is empty');
106      return undefined;
107    }
108    let bundleInfo: bundleManager.BundleInfo = undefined;
109    try {
110      await bundleManager.getBundleInfo(bundleName,
111        bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION |
112        bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_HAP_MODULE |
113        bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_ABILITY,
114        this.mUserId)
115        .then((res: bundleManager.BundleInfo) => {
116          Log.showInfo(TAG, `getBundleInfoByBundleName res:${JSON.stringify(res.hapModulesInfo.length)}`);
117          bundleInfo = res;
118        })
119        .catch((err) => {
120          Log.showError(TAG, `getBundleInfoByBundleName error: ${JSON.stringify(err)}, bundleName:${bundleName}`);
121        });
122    } catch (err) {
123      Log.showError(TAG, `getBundleInfoByBundleName bundleManager.getBundleInfo error: ${JSON.stringify(err)}, bundleName:${bundleName}`);
124    }
125    if (CheckEmptyUtils.isEmpty(bundleInfo)) {
126      return undefined;
127    }
128    if (CheckEmptyUtils.isEmpty(bundleType)) {
129      return bundleInfo;
130    }
131    return bundleInfo.appInfo.bundleType === bundleType ? bundleInfo : undefined;
132  }
133
134  /**
135   * 根据abilityName获取ability信息
136   *
137   * @param bundleName 包名
138   * @param abilityName ability名
139   * @param bundleType 包类型:bundleManager.BundleType.APP:桌面app,  bundleManager.BundleType.ATOMIC_SERVICE:原子化服务
140   * @returns ability信息
141   */
142  async getAbilityInfoByAbilityName(bundleName: string, abilityName: string,
143                                    bundleType?: bundleManager.BundleType): Promise<bundleManager.AbilityInfo | undefined> {
144    if (CheckEmptyUtils.checkStrIsEmpty(bundleName) || CheckEmptyUtils.checkStrIsEmpty(abilityName)) {
145      Log.showError(TAG, 'getAbilityInfoByAbilityName reqParam bundleName or abilityName is empty');
146      return undefined;
147    }
148    // get from system
149    let abilityList = new Array<bundleManager.AbilityInfo>();
150    let want: Want = {
151      bundleName: bundleName,
152      abilityName: abilityName
153    };
154    try {
155      await bundleManager.queryAbilityInfo(want, bundleManager.AbilityFlag.GET_ABILITY_INFO_WITH_APPLICATION, this.mUserId)
156        .then((res: Array<bundleManager.AbilityInfo>)=>{
157          if (res !== undefined) {
158            Log.showInfo(TAG, `getAbilityInfoByAbilityName res length: ${res.length}`);
159            abilityList = res;
160          }
161        })
162        .catch((err)=>{
163          Log.showError(TAG, `getAbilityInfoByAbilityName error: ${JSON.stringify(err)}`);
164        });
165    } catch (err) {
166      Log.showError(TAG, `getAbilityInfoByAbilityName bundleManager.queryAbilityInfo error: ${JSON.stringify(err)}`);
167    }
168    if (CheckEmptyUtils.isEmptyArr(abilityList)) {
169      return undefined;
170    }
171    if (CheckEmptyUtils.isEmpty(bundleType)) {
172      return abilityList[0];
173    }
174    return abilityList[0].applicationInfo.bundleType === bundleType ? abilityList[0] : undefined;
175  }
176}
177
178const commonBundleManager = CommonBundleManager.getInstance();
179export default commonBundleManager;