• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 bundleMgr from '@ohos.bundle';
17import osaccount from '@ohos.account.osAccount';
18import hiSysEvent from '@ohos.hiSysEvent';
19import launcherBundleMgr from '@ohos.bundle.innerBundleManager';
20import { LauncherAbilityInfo } from 'bundle/launcherAbilityInfo';
21import { Log } from '../utils/Log';
22import { Trace } from '../utils/Trace';
23import { CheckEmptyUtils } from '../utils/CheckEmptyUtils';
24import { AppItemInfo } from '../bean/AppItemInfo';
25import { CommonConstants } from '../constants/CommonConstants';
26import { ResourceManager } from './ResourceManager';
27import { EventConstants } from '../constants/EventConstants';
28import { BadgeManager } from '../manager/BadgeManager';
29
30const TAG = 'LauncherAbilityManager';
31
32/**
33 * Wrapper class for innerBundleManager and formManager interfaces.
34 */
35class LauncherAbilityManager {
36  private static readonly CURRENT_USER_ID = -2;
37  private static readonly BUNDLE_STATUS_CHANGE_KEY = 'BundleStatusChange';
38  private readonly mAppMap = new Map<string, AppItemInfo>();
39  private mUserId: number = 100;
40
41  private readonly mBundleStatusCallback: any = {
42    add: (bundleName, userId) => {
43      Log.showDebug(TAG, `mBundleStatusCallback add bundleName: ${bundleName}, userId: ${userId}, mUserId ${this.mUserId}`);
44      this.mUserId == userId && this.notifyLauncherAbilityChange(EventConstants.EVENT_PACKAGE_ADDED, bundleName, userId);
45    },
46    remove: (bundleName, userId) => {
47      Log.showDebug(TAG, `mBundleStatusCallback remove bundleName: ${bundleName}, userId: ${userId}, mUserId ${this.mUserId}`);
48      this.mUserId == userId && this.notifyLauncherAbilityChange(EventConstants.EVENT_PACKAGE_REMOVED, bundleName, userId);
49    },
50    update: (bundleName, userId) => {
51      Log.showDebug(TAG, `mBundleStatusCallback update bundleName: ${bundleName}, userId: ${userId}, mUserId ${this.mUserId}`);
52      this.mUserId == userId && this.notifyLauncherAbilityChange(EventConstants.EVENT_PACKAGE_CHANGED, bundleName, userId);
53    }
54  };
55
56  private readonly mLauncherAbilityChangeListeners: any[] = [];
57
58  /**
59   * Get desktop application information management object
60   *
61   * @return Desktop application information management object instance
62   */
63  static getInstance(): LauncherAbilityManager {
64    if (globalThis.LauncherAbilityManagerInstance == null) {
65      globalThis.LauncherAbilityManagerInstance = new LauncherAbilityManager();
66    }
67    return globalThis.LauncherAbilityManagerInstance;
68  }
69
70  private constructor() {
71    const osAccountManager = osaccount.getAccountManager();
72    osAccountManager.getOsAccountLocalIdFromProcess((err, localId) => {
73      Log.showDebug(TAG, `getOsAccountLocalIdFromProcess localId ${localId}`);
74      this.mUserId = localId;
75    });
76  }
77
78  getUserId(): number {
79    return this.mUserId;
80  }
81
82  /**
83   * Monitor system application status.
84   *
85   * @params listener: listening object
86   */
87  registerLauncherAbilityChangeListener(listener: any): void {
88    if (listener != null) {
89      if (this.mLauncherAbilityChangeListeners.length == 0) {
90        launcherBundleMgr.on(LauncherAbilityManager.BUNDLE_STATUS_CHANGE_KEY, this.mBundleStatusCallback).then(data => {
91          Log.showDebug(TAG, `registerCallback success: ${JSON.stringify(data)}`);
92        }).catch(err => {
93          Log.showError(TAG, `registerCallback fail: ${JSON.stringify(err)}`);
94        });
95      }
96      const index = this.mLauncherAbilityChangeListeners.indexOf(listener);
97      if (index == CommonConstants.INVALID_VALUE) {
98        this.mLauncherAbilityChangeListeners.push(listener);
99      }
100    }
101  }
102
103  /**
104   * Cancel monitoring system application status.
105   *
106   * @params listener: listening object
107   */
108  unregisterLauncherAbilityChangeListener(listener: any): void {
109    if (listener != null) {
110      const index = this.mLauncherAbilityChangeListeners.indexOf(listener);
111      if (index != CommonConstants.INVALID_VALUE) {
112        this.mLauncherAbilityChangeListeners.splice(index, 1);
113      }
114      if (this.mLauncherAbilityChangeListeners.length == 0) {
115        launcherBundleMgr.off(LauncherAbilityManager.BUNDLE_STATUS_CHANGE_KEY).then(data => {
116          Log.showDebug(TAG, 'unregisterCallback success');
117        }).catch(err => {
118          Log.showError(TAG, `unregisterCallback fail: ${JSON.stringify(err)}`);
119        });
120      }
121    }
122  }
123
124  private notifyLauncherAbilityChange(event, bundleName: string, userId): void {
125    for (let index = 0; index < this.mLauncherAbilityChangeListeners.length; index++) {
126      this.mLauncherAbilityChangeListeners[index](event, bundleName, userId);
127    }
128  }
129
130  /**
131   * get all app List info from BMS
132   */
133  async getLauncherAbilityList(): Promise<AppItemInfo[]> {
134    let abilityList = null;
135    await launcherBundleMgr.getAllLauncherAbilityInfos(LauncherAbilityManager.CURRENT_USER_ID)
136      .then((res) => {
137        abilityList = res;
138      })
139      .catch((err) => {
140        Log.showError(TAG, `getLauncherAbilityList error: ${JSON.stringify(err)}`);
141      });
142    const appItemInfoList = new Array<AppItemInfo>();
143    if (CheckEmptyUtils.isEmpty(abilityList)) {
144      Log.showDebug(TAG, 'getLauncherAbilityList Empty');
145      return appItemInfoList;
146    }
147    for (let i = 0; i < abilityList.length; i++) {
148      let appItem = await this.convertToAppItemInfo(abilityList[i]);
149      appItemInfoList.push(appItem);
150    }
151    return appItemInfoList;
152  }
153
154  /**
155   * get AbilityInfos by bundleName from BMS
156   *
157   * @params bundleName Application package name
158   * @return List of entry capabilities information of the target application
159   */
160  async getLauncherAbilityInfo(bundleName: string): Promise<AppItemInfo[]> {
161    let abilityInfos: LauncherAbilityInfo[];
162    await launcherBundleMgr.getLauncherAbilityInfos(bundleName, this.mUserId)
163      .then((res) => {
164        abilityInfos = res;
165      })
166      .catch((err) => {
167        Log.showError(TAG, `getLauncherAbilityInfo error: ${JSON.stringify(err)}`);
168      });
169    const appItemInfoList = new Array<AppItemInfo>();
170    if (CheckEmptyUtils.isEmpty(abilityInfos)) {
171      Log.showDebug(TAG, 'getLauncherAbilityInfo Empty');
172      return appItemInfoList;
173    }
174    for (let i = 0; i < abilityInfos.length; i++) {
175      let appItem = await this.convertToAppItemInfo(abilityInfos[i]);
176      appItemInfoList.push(appItem);
177    }
178    return appItemInfoList;
179  }
180
181  /**
182   * get AppItemInfo from BMS with bundleName
183   * @params bundleName
184   * @return AppItemInfo
185   */
186  async getAppInfoByBundleName(bundleName: string, abilityName?: string): Promise<AppItemInfo | undefined> {
187    let appItemInfo: AppItemInfo | undefined = undefined;
188    // get from cache
189    if (this.mAppMap != null && this.mAppMap.has(bundleName)) {
190      appItemInfo = this.mAppMap.get(bundleName);
191    }
192    if (appItemInfo != undefined) {
193      return appItemInfo;
194    }
195    // get from system
196    let abilityInfos = new Array<LauncherAbilityInfo>();
197    await launcherBundleMgr.getLauncherAbilityInfos(bundleName, LauncherAbilityManager.CURRENT_USER_ID)
198      .then((res)=>{
199        if (res != undefined) {
200          abilityInfos = res;
201        }
202      })
203      .catch((err)=>{
204        Log.showError(TAG, `getAppInfoByBundleName launcherBundleMgr getLauncherAbilityInfos error: ${JSON.stringify(err)}`);
205      });
206
207    if (abilityInfos == undefined || abilityInfos.length == 0) {
208      Log.showDebug(TAG, `${bundleName} has no launcher ability`);
209      return undefined;
210    }
211    let appInfo = abilityInfos[0];
212    if (abilityName != undefined) {
213      appInfo = abilityInfos.find(item => {
214        return item.elementName.abilityName === abilityName;
215      });
216    }
217    const data = await this.convertToAppItemInfo(appInfo);
218    return data;
219  }
220
221  private async convertToAppItemInfo(info): Promise<AppItemInfo> {
222    const appItemInfo = new AppItemInfo();
223    appItemInfo.appName = await ResourceManager.getInstance().getAppNameSync(
224      info.labelId, info.elementName.bundleName, info.elementName.moduleName, info.applicationInfo.label
225    );
226    appItemInfo.isSystemApp = info.applicationInfo.systemApp;
227    appItemInfo.isUninstallAble = info.applicationInfo.removable;
228    appItemInfo.appIconId = info.iconId;
229    appItemInfo.appLabelId = info.labelId;
230    appItemInfo.bundleName = info.elementName.bundleName;
231    appItemInfo.abilityName = info.elementName.abilityName;
232    appItemInfo.moduleName = info.elementName.moduleName;
233    appItemInfo.keyName = info.elementName.bundleName + info.elementName.abilityName + info.elementName.moduleName;
234    appItemInfo.typeId = CommonConstants.TYPE_APP;
235    appItemInfo.installTime = String(new Date());
236    appItemInfo.badgeNumber = await BadgeManager.getInstance().getBadgeByBundleSync(info.elementName.bundleName);
237    await ResourceManager.getInstance().updateIconCache(appItemInfo.appIconId, appItemInfo.bundleName, appItemInfo.moduleName);
238    this.mAppMap.set(appItemInfo.bundleName, appItemInfo);
239    return appItemInfo;
240  }
241
242  /**
243   * uninstall application, notice the userId need to be the login user
244   *
245   * @params bundleName application bundleName
246   * @params callback to get result
247   */
248  async uninstallLauncherAbility(bundleName: string, callback): Promise<void> {
249    Log.showInfo(TAG, `uninstallLauncherAbility bundleName: ${bundleName}`);
250    const bundlerInstaller = await bundleMgr.getBundleInstaller();
251    bundlerInstaller.uninstall(bundleName, {
252      userId: this.mUserId,
253      installFlag: 0,
254      isKeepData: false
255    }, (result) => {
256      Log.showDebug(TAG, `uninstallLauncherAbility result => ${JSON.stringify(result)}`);
257      callback(result);
258    });
259  }
260
261  /**
262   * start the app
263   *
264   * @params paramAbilityName: Ability name
265   * @params paramBundleName: Application package name
266   */
267  startLauncherAbility(paramAbilityName: string, paramBundleName: string, paramModuleName: string) {
268    Log.showDebug(TAG, `startApplication abilityName: ${paramAbilityName}, bundleName: ${paramBundleName}, moduleName ${paramModuleName}`);
269    globalThis.desktopContext.startAbility({
270      bundleName: paramBundleName,
271      abilityName: paramAbilityName,
272      moduleName: paramModuleName
273    }).then(() => {
274      Log.showDebug(TAG, 'startApplication promise success');
275    }, (err) => {
276      Log.showError(TAG, `startApplication promise error: ${JSON.stringify(err)}`);
277    });
278
279    const sysEventInfo = {
280      domain: 'LAUNCHER_APP',
281      name: 'START_ABILITY',
282      eventType: hiSysEvent.EventType.BEHAVIOR,
283      params: {
284        'BUNDLE_NAME': paramBundleName,
285        'ABILITY_NAME': paramAbilityName,
286        'MODULE_NAME': paramModuleName
287      }
288    };
289    hiSysEvent.write(sysEventInfo,
290      (err, value) => {
291        if (err) {
292          Log.showError(TAG, `startApplication hiSysEvent write error: ${err.code}`);
293        } else {
294          Log.showDebug(TAG, `startApplication hiSysEvent write success: ${value}`);
295        }
296    })
297  }
298
299  /**
300   * start form config ability
301   *
302   * @params paramAbilityName
303   * @params paramBundleName
304   */
305  startAbilityFormEdit(paramAbilityName: string, paramBundleName: string, paramModuleName: string, paramCardId: number) {
306    Log.showDebug(TAG, `startAbility abilityName: ${paramAbilityName},bundleName: ${paramBundleName}, moduleName: ${paramModuleName} ,paramCardId: ${paramCardId}`);
307    globalThis.desktopContext.startAbility({
308      bundleName: paramBundleName,
309      abilityName: paramAbilityName,
310      moduleName: paramModuleName,
311      parameters:
312        {
313          formId: paramCardId.toString()
314        }
315    }).then((ret) => {
316      Log.showDebug(TAG, `startAbility ret: ${JSON.stringify(ret)}`);
317    }, (err) => {
318      Log.showError(TAG, `startAbility catch error: ${JSON.stringify(err)}`);
319    });
320  }
321
322  async getShortcutInfo(paramBundleName, callback) {
323    Log.showDebug(TAG, `getShortcutInfo bundleName: ${paramBundleName}`);
324    await launcherBundleMgr.getShortcutInfos(paramBundleName)
325      .then(shortcutInfo => {
326        callback(paramBundleName, shortcutInfo);
327      })
328      .catch(err => {
329      });
330  }
331
332  /**
333   * start application by uri
334   *
335   * @params paramBundleName application bundle name
336   * @params paramAbilityName application abilit uri
337   */
338  startLauncherAbilityByUri(paramBundleName, abilityUri) {
339    Log.showInfo(TAG, `startLauncherAbilityByUri bundleName:${paramBundleName} abilityUri:${abilityUri}`);
340    const result = globalThis.desktopContext.startAbility({
341      bundleName: paramBundleName,
342      uri: abilityUri
343    }).then(() => {
344      Log.showDebug(TAG, 'startLauncherAbilityByUri promise success');
345    }, (err) => {
346      Log.showError(TAG, `startLauncherAbilityByUri promise error: ${JSON.stringify(err)}`);
347    });
348    Log.showDebug(TAG, `startLauncherAbilityByUri AceApplication : startAbility : ${result}`);
349  }
350}
351
352export const launcherAbilityManager = LauncherAbilityManager.getInstance();
353