• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2022-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 bundleMgr from '@ohos.bundle'
17import launcherBundleManager from '@ohos.bundle.launcherBundleManager';
18import bundleMonitor from '@ohos.bundle.bundleMonitor';
19import osAccount from '@ohos.account.osAccount'
20import { AppItemInfo } from '../bean/AppItemInfo'
21import { CheckEmptyUtils } from '../utils/CheckEmptyUtils'
22import { CommonConstants } from '../constants/CommonConstants'
23import { EventConstants } from '../constants/EventConstants'
24import { ResourceManager } from './ResourceManager'
25import { Logger } from '../utils/Logger'
26
27const TAG: string = 'LauncherAbilityManager'
28
29/**
30 * Wrapper class for innerBundleManager and formManager interfaces.
31 */
32export class LauncherAbilityManager {
33  private static readonly BUNDLE_STATUS_CHANGE_KEY_REMOVE = 'remove'
34  private static readonly BUNDLE_STATUS_CHANGE_KEY_ADD = 'add'
35  private static launcherAbilityManager: LauncherAbilityManager = undefined
36  private readonly mAppMap = new Map<string, AppItemInfo>()
37  private mResourceManager: ResourceManager = undefined
38  private readonly mLauncherAbilityChangeListeners: any[] = []
39  private mUserId: number = 100
40  private context: any = undefined
41
42  constructor(context) {
43    this.context = context
44    this.mResourceManager = ResourceManager.getInstance(context)
45    const osAccountManager = osAccount.getAccountManager()
46    osAccountManager.getOsAccountLocalIdFromProcess((err, localId) => {
47      Logger.debug(TAG, `getOsAccountLocalIdFromProcess localId ${localId}`)
48      this.mUserId = localId
49    })
50  }
51
52  /**
53   * Get the application data model object.
54   *
55   * @return {object} application data model singleton
56   */
57  static getInstance(context): LauncherAbilityManager {
58    if (this.launcherAbilityManager === null || this.launcherAbilityManager === undefined) {
59      this.launcherAbilityManager = new LauncherAbilityManager(context)
60    }
61    return this.launcherAbilityManager
62  }
63
64  /**
65   * get all app List info from BMS
66   *
67   * @return 应用的入口Ability信息列表
68   */
69  async getLauncherAbilityList(): Promise<AppItemInfo[]> {
70    Logger.info(TAG, 'getLauncherAbilityList begin')
71    let abilityList = await launcherBundleManager.getAllLauncherAbilityInfo(this.mUserId)
72    const appItemInfoList = new Array<AppItemInfo>()
73    if (CheckEmptyUtils.isEmpty(abilityList)) {
74      Logger.info(TAG, 'getLauncherAbilityList Empty')
75      return appItemInfoList
76    }
77    for (let i = 0; i < abilityList.length; i++) {
78      let appItem = await this.transToAppItemInfo(abilityList[i])
79      appItemInfoList.push(appItem)
80    }
81    return appItemInfoList
82  }
83
84  /**
85   * get AppItemInfo from BMS with bundleName
86   * @params bundleName
87   * @return AppItemInfo
88   */
89  async getAppInfoByBundleName(bundleName: string): Promise<AppItemInfo | undefined> {
90    let appItemInfo: AppItemInfo | undefined = undefined
91    // get from cache
92    if (this.mAppMap != null && this.mAppMap.has(bundleName)) {
93      appItemInfo = this.mAppMap.get(bundleName)
94    }
95    if (appItemInfo != undefined) {
96      Logger.info(TAG, `getAppInfoByBundleName from cache: ${JSON.stringify(appItemInfo)}`)
97      return appItemInfo
98    }
99    // get from system
100    let abilityInfos = await launcherBundleManager.getLauncherAbilityInfo(bundleName, this.mUserId)
101    if (abilityInfos == undefined || abilityInfos.length == 0) {
102      Logger.info(TAG, `${bundleName} has no launcher ability`)
103      return undefined
104    }
105    let appInfo = abilityInfos[0]
106    const data = await this.transToAppItemInfo(appInfo)
107    Logger.info(TAG, `getAppInfoByBundleName from BMS: ${JSON.stringify(data)}`)
108    return data
109  }
110
111  private async transToAppItemInfo(info): Promise<AppItemInfo> {
112    const appItemInfo = new AppItemInfo()
113    appItemInfo.appName = await this.mResourceManager.getAppNameSync(
114    info.labelId, info.elementName.bundleName, info.applicationInfo.label
115    )
116    appItemInfo.isSystemApp = info.applicationInfo.systemApp
117    appItemInfo.isUninstallAble = info.applicationInfo.removable
118    appItemInfo.appIconId = info.iconId
119    appItemInfo.appLabelId = info.labelId
120    appItemInfo.bundleName = info.elementName.bundleName
121    appItemInfo.abilityName = info.elementName.abilityName
122    await this.mResourceManager.updateIconCache(appItemInfo.appIconId, appItemInfo.bundleName)
123    this.mAppMap.set(appItemInfo.bundleName, appItemInfo)
124    return appItemInfo
125  }
126
127
128  /**
129   * 启动应用
130   *
131   * @params paramAbilityName Ability名
132   * @params paramBundleName 应用包名
133   */
134  startLauncherAbility(paramAbilityName, paramBundleName) {
135    Logger.info(TAG, `startApplication abilityName: ${paramAbilityName}, bundleName: ${paramBundleName}`)
136    this.context.startAbility({
137      bundleName: paramBundleName,
138      abilityName: paramAbilityName
139    }).then(() => {
140      Logger.info(TAG, 'startApplication promise success')
141    }, (err) => {
142      Logger.error(TAG, `startApplication promise error: ${JSON.stringify(err)}`)
143    })
144  }
145
146  /**
147   * 通过桌面图标启动应用
148   *
149   * @params paramAbilityName Ability名
150   * @params paramBundleName 应用包名
151   */
152  startLauncherAbilityFromRecent(paramAbilityName, paramBundleName): void {
153    Logger.info(TAG, `startApplication abilityName: ${paramAbilityName}, bundleName: ${paramBundleName}`);
154    this.context.startRecentAbility({
155      bundleName: paramBundleName,
156      abilityName: paramAbilityName
157    }).then(() => {
158      Logger.info(TAG, 'startApplication promise success');
159    }, (err) => {
160      Logger.error(TAG, `startApplication promise error: ${JSON.stringify(err)}`);
161    });
162  }
163
164  /**
165   * 卸载应用
166   *
167   * @params bundleName 应用包名
168   * @params callback 卸载回调
169   */
170  async uninstallLauncherAbility(bundleName: string, callback): Promise<void> {
171    Logger.info(TAG, `uninstallLauncherAbility bundleName: ${bundleName}`)
172    const bundlerInstaller = await bundleMgr.getBundleInstaller()
173    bundlerInstaller.uninstall(bundleName, {
174      userId: this.mUserId,
175      installFlag: 0,
176      isKeepData: false
177    }, (result) => {
178      Logger.info(TAG, `uninstallLauncherAbility result => ${JSON.stringify(result)}`)
179      callback(result)
180    })
181  }
182
183  /**
184   * 开始监听系统应用状态.
185   *
186   * @params listener 监听对象
187   */
188  registerLauncherAbilityChangeListener(listener: any): void {
189    if (!CheckEmptyUtils.isEmpty(listener)) {
190      if (this.mLauncherAbilityChangeListeners.length == 0) {
191        bundleMonitor.on(LauncherAbilityManager.BUNDLE_STATUS_CHANGE_KEY_ADD, (bundleChangeInfo) => {
192          Logger.debug(TAG, `mBundleStatusCallback add bundleName: ${bundleChangeInfo.bundleName},
193            userId: ${bundleChangeInfo.userId}, mUserId ${this.mUserId}`)
194          if (this.mUserId === bundleChangeInfo.userId) {
195            this.notifyLauncherAbilityChange(EventConstants.EVENT_PACKAGE_ADDED,
196              bundleChangeInfo.bundleName, bundleChangeInfo.userId)
197          }
198        })
199        bundleMonitor.on(LauncherAbilityManager.BUNDLE_STATUS_CHANGE_KEY_REMOVE, (bundleChangeInfo) => {
200          Logger.debug(TAG, `mBundleStatusCallback remove bundleName: ${bundleChangeInfo.bundleName},
201            userId: ${bundleChangeInfo.userId}, mUserId ${this.mUserId}`)
202          if (this.mUserId === bundleChangeInfo.userId) {
203            this.notifyLauncherAbilityChange(EventConstants.EVENT_PACKAGE_REMOVED,
204              bundleChangeInfo.bundleName, bundleChangeInfo.userId)
205          }
206          AppStorage.Set('isRefresh', true)
207        })
208      }
209      const index = this.mLauncherAbilityChangeListeners.indexOf(listener)
210      if (index == CommonConstants.INVALID_VALUE) {
211        this.mLauncherAbilityChangeListeners.push(listener)
212      }
213    }
214  }
215
216  /**
217   * 取消监听系统应用状态.
218   *
219   * @params listener 监听对象
220   */
221  unregisterLauncherAbilityChangeListener(listener: any): void {
222    if (!CheckEmptyUtils.isEmpty(listener)) {
223      const index = this.mLauncherAbilityChangeListeners.indexOf(listener)
224      if (index != CommonConstants.INVALID_VALUE) {
225        this.mLauncherAbilityChangeListeners.splice(index, 1)
226      }
227      if (this.mLauncherAbilityChangeListeners.length == 0) {
228        bundleMonitor.off(LauncherAbilityManager.BUNDLE_STATUS_CHANGE_KEY_ADD)
229        bundleMonitor.off(LauncherAbilityManager.BUNDLE_STATUS_CHANGE_KEY_REMOVE)
230      }
231    }
232  }
233
234  private notifyLauncherAbilityChange(event: string, bundleName: string, userId: number): void {
235    for (let index = 0; index < this.mLauncherAbilityChangeListeners.length; index++) {
236      this.mLauncherAbilityChangeListeners[index](event, bundleName, userId)
237    }
238  }
239}