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 Prompt from '@ohos.promptAction';
17import missionManager from '@ohos.app.ability.missionManager';
18import { CloseAppManager, LauncherDragItemInfo, windowManager } from '@ohos/common';
19import { Log } from '@ohos/common';
20import { CheckEmptyUtils } from '@ohos/common';
21import { EventConstants } from '@ohos/common';
22import { StyleConstants } from '@ohos/common';
23import { CommonConstants } from '@ohos/common';
24import { AppModel } from '@ohos/common';
25import { AppItemInfo } from '@ohos/common';
26import { DockItemInfo } from '@ohos/common';
27import { MissionInfo } from '@ohos/common';
28import { RecentBundleMissionInfo } from '@ohos/common';
29import { ResourceManager } from '@ohos/common';
30import { amsMissionManager } from '@ohos/common';
31import { localEventManager } from '@ohos/common';
32import { layoutConfigManager } from '@ohos/common';
33import { launcherAbilityManager } from '@ohos/common';
34import SmartDockCloseAppHandler from '../common/SmartDockCloseAppHandler';
35import { SmartDockStyleConfig } from '../config/SmartDockStyleConfig';
36import { SmartDockLayoutConfig } from '../config/SmartDockLayoutConfig';
37import SmartDockConstants from '../common/constants/SmartDockConstants';
38import { RecentMissionInfo } from '@ohos/common';
39import launcherBundleManager from '@ohos.bundle.launcherBundleManager';
40
41const TAG = 'SmartDockModel';
42
43/**
44 * SmartDock Model
45 */
46export default class SmartDockModel {
47  private readonly mSmartDockLayoutConfig: SmartDockLayoutConfig;
48  private readonly mSmartDockCloseAppHandler: SmartDockCloseAppHandler;
49  private readonly mSmartDockStyleConfig: SmartDockStyleConfig;
50  private mResidentList: DockItemInfo[] = new Array<DockItemInfo>();
51  private mRecentDataList: RecentBundleMissionInfo[] = new Array<RecentBundleMissionInfo>();
52  private readonly mCloseAppManager: CloseAppManager;
53  private readonly mDevice = CommonConstants.DEFAULT_DEVICE_TYPE;
54  private readonly mResourceManager: ResourceManager;
55  protected mAppModel: AppModel;
56  private KEY_NAME: string = 'name';
57
58  private constructor() {
59    this.mSmartDockLayoutConfig = layoutConfigManager.getFunctionConfig(SmartDockLayoutConfig.SMART_DOCK_LAYOUT_INFO);
60    this.mSmartDockStyleConfig = layoutConfigManager.getStyleConfig(SmartDockStyleConfig.APP_LIST_STYLE_CONFIG, SmartDockConstants.FEATURE_NAME);
61    this.mCloseAppManager = CloseAppManager.getInstance();
62    this.mSmartDockCloseAppHandler = new SmartDockCloseAppHandler();
63    this.mCloseAppManager.registerCloseAppHandler(this.mSmartDockCloseAppHandler);
64    this.mAppModel = AppModel.getInstance();
65    this.mResourceManager = ResourceManager.getInstance();
66    this.registerDockListener();
67    this.mDevice = AppStorage.get('deviceType');
68    Log.showDebug(TAG, `dockDevice: ${this.mDevice}`);
69    this.getResidentList().then(() => {}, () => {});
70    if (this.mDevice === CommonConstants.PAD_DEVICE_TYPE) {
71      this.getRecentDataList().then(() => {}, () => {});
72    }
73    this.registerMissionListener();
74    Log.showInfo(TAG, 'constructor!');
75  }
76
77  static getInstance(): SmartDockModel {
78    if (globalThis.SmartDockModel == null) {
79      globalThis.SmartDockModel = new SmartDockModel();
80      Log.showInfo(TAG, 'getInstance!');
81    }
82    return globalThis.SmartDockModel;
83  }
84
85  /**
86   * get resident dock list
87   */
88  async getResidentList(): Promise<void> {
89    let residentList = new Array<DockItemInfo>();
90
91    // query rdb data
92    let rdbResidentList: DockItemInfo[] = [];
93    rdbResidentList = await globalThis.RdbStoreManagerInstance.querySmartDock();
94
95    if (CheckEmptyUtils.isEmptyArr(rdbResidentList) && !this.mSmartDockLayoutConfig.isConfigExist()) {
96      // init preset dock data
97      const dockDataList = this.mSmartDockLayoutConfig.getDockLayoutInfo();
98      Log.showDebug(TAG, `getResidentList from config length: ${dockDataList.length}`);
99      for (let i = 0; i < dockDataList.length; i++) {
100        if (dockDataList[i].itemType == CommonConstants.TYPE_APP) {
101          Log.showDebug(TAG, `getResidentList dockDataList[i].bundleName: ${dockDataList[i].bundleName}`);
102          const appData = await launcherAbilityManager.getAppInfoByBundleName(dockDataList[i].bundleName);
103          if (appData == undefined) {
104            continue;
105          }
106          const dockItemInfo = new DockItemInfo();
107          dockItemInfo.itemType = dockDataList[i].itemType;
108          dockItemInfo.editable = dockDataList[i].editable;
109          dockItemInfo.appName = typeof (appData) === 'undefined' ? dockDataList[i].appName : appData.appName;
110          dockItemInfo.bundleName = typeof (appData) === 'undefined' ? dockDataList[i].bundleName : appData.bundleName;
111          dockItemInfo.moduleName = typeof (appData) === 'undefined' ? dockDataList[i].bundleName : appData.moduleName;
112          dockItemInfo.abilityName = typeof (appData) === 'undefined' ? dockItemInfo.abilityName : appData.abilityName;
113          dockItemInfo.keyName = `${dockItemInfo.bundleName}${dockItemInfo.abilityName}${dockItemInfo.moduleName}`;
114          dockItemInfo.appIconId = typeof (appData) === 'undefined' ? dockItemInfo.appIconId : appData.appIconId;
115          dockItemInfo.appLabelId = typeof (appData) === 'undefined' ? dockItemInfo.appLabelId : appData.appLabelId;
116          dockItemInfo.isSystemApp = typeof (appData) === 'undefined' ? dockItemInfo.isSystemApp : appData.isSystemApp;
117          dockItemInfo.isUninstallAble = typeof (appData) === 'undefined' ? dockItemInfo.isUninstallAble : appData.isUninstallAble;
118          dockItemInfo.installTime = typeof (appData) === 'undefined' ? dockItemInfo.installTime : appData.installTime;
119          dockItemInfo.badgeNumber = typeof (appData) === 'undefined' ? dockItemInfo.badgeNumber : appData.badgeNumber;
120          residentList.push(dockItemInfo);
121        } else if (dockDataList[i].itemType == CommonConstants.TYPE_CARD) {
122        } else {
123          const dockItemInfo = new DockItemInfo();
124          dockItemInfo.itemType = dockDataList[i].itemType;
125          dockItemInfo.editable = dockDataList[i].editable;
126          dockItemInfo.bundleName = dockDataList[i].bundleName;
127          dockItemInfo.abilityName = dockDataList[i].abilityName;
128          dockItemInfo.moduleName = dockDataList[i].moduleName;
129          dockItemInfo.keyName = `${dockItemInfo.bundleName}${dockItemInfo.abilityName}${dockItemInfo.moduleName}`;
130          dockItemInfo.appIconId = typeof (dockDataList[i].appIconId) != 'undefined' ? dockDataList[i].appIconId : dockDataList[i].iconId.id;
131          dockItemInfo.appLabelId = typeof (dockDataList[i].appLabelId) != 'undefined' ? dockDataList[i].appLabelId : dockDataList[i].labelId.id;
132          dockItemInfo.isSystemApp = typeof (dockDataList[i].isSystemApp) === 'undefined' ? true : dockDataList[i].isSystemApp;
133          dockItemInfo.isUninstallAble = typeof (dockDataList[i].isUninstallAble) === 'undefined' ? true : dockDataList[i].isUninstallAble;
134          dockItemInfo.badgeNumber = typeof (dockDataList[i].badgeNumber) === 'undefined' ?
135          CommonConstants.BADGE_DISPLAY_HIDE : dockDataList[i].badgeNumber;
136          const loadAppName = await this.mResourceManager
137            .getAppNameSync(dockItemInfo.appLabelId, dockItemInfo.bundleName, dockItemInfo.moduleName, '');
138          dockItemInfo.appName = loadAppName;
139          residentList.push(dockItemInfo);
140        }
141      }
142
143      // update persistent data
144      globalThis.RdbStoreManagerInstance.insertIntoSmartdock(residentList);
145      this.mSmartDockLayoutConfig.updateDockLayoutInfo(residentList);
146    } else {
147      residentList = rdbResidentList;
148      Log.showDebug(TAG, 'getResidentList from rdb!');
149    }
150
151    // trigger component update
152    AppStorage.setOrCreate('residentList', residentList);
153    if (this.mDevice) {
154      localEventManager.sendLocalEventSticky(EventConstants.EVENT_SMARTDOCK_INIT_FINISHED, residentList);
155    }
156    Log.showDebug(TAG, `getResidentList end residentList.length: ${residentList.length}`);
157  }
158
159  /**
160   * get recent dock list
161   */
162  async getRecentDataList(): Promise<void> {
163    Log.showDebug(TAG, 'getRecentDataList start!');
164    if (this.mDevice === CommonConstants.DEFAULT_DEVICE_TYPE) {
165      return;
166    }
167    const recentList = await amsMissionManager.getRecentBundleMissionsList();
168    if (CheckEmptyUtils.isEmptyArr(recentList)) {
169      Log.showDebug(TAG, 'getRecentDataList empty');
170      AppStorage.setOrCreate('recentList', recentList);
171      return;
172    }
173    let recents: RecentBundleMissionInfo[] = [];
174    let missionInfos: {
175      appName: string,
176      bundleName: string,
177      missionInfoList: MissionInfo[]
178    }[] = [];
179    recentList.forEach(item => {
180      missionInfos.push({
181        appName: item.appName,
182        bundleName: item.bundleName,
183        missionInfoList: item.missionInfoList
184      });
185      item.missionInfoList = [];
186      recents.push(item);
187    });
188    if (recents.length > this.mSmartDockStyleConfig.mMaxRecentNum) {
189      recents = recents.slice(0, this.mSmartDockStyleConfig.mMaxRecentNum);
190    }
191    AppStorage.setOrCreate('recentList', recents);
192
193    missionInfos = missionInfos.slice(0,20);
194
195    AppStorage.setOrCreate('missionInfoList', missionInfos);
196    Log.showDebug(TAG, `getRecentDataList end, recentList.length: ${recents.length}`);
197  }
198
199  /**
200   * delete app from smartdock
201   * @param dockItem
202   * @param dockType
203   */
204  deleteDockItem(dockItem: DockItemInfo, dockType: number): boolean {
205    if (SmartDockConstants.RESIDENT_DOCK_TYPE === dockType) {
206      return this.deleteResistDockItem(dockItem);
207    }
208    else if (SmartDockConstants.RECENT_DOCK_TYPE === dockType) {
209      return this.deleteRecentDockItem(dockItem);
210    }
211  }
212
213  /**
214   * add appItem to smartdock
215   *
216   * @param appInfo
217   * @param index
218   */
219  addToSmartdock(appInfo: LauncherDragItemInfo, index?: number): boolean {
220    if (appInfo.typeId != CommonConstants.TYPE_APP) {
221      return false;
222    }
223    this.mResidentList = AppStorage.get('residentList');
224    const dockItemCount = this.mResidentList.length;
225    if (this.checkDockNum(dockItemCount)) {
226      return false;
227    }
228    const flag = this.idDuplicate(this.mResidentList, appInfo as AppItemInfo);
229    if (flag) {
230      const dockItemInfo = new DockItemInfo();
231      dockItemInfo.itemType = CommonConstants.TYPE_APP;
232      dockItemInfo.editable = true;
233      dockItemInfo.appId = appInfo.appId;
234      dockItemInfo.appName = appInfo.appName;
235      dockItemInfo.bundleName = appInfo.bundleName;
236      dockItemInfo.abilityName = appInfo.abilityName;
237      dockItemInfo.moduleName = appInfo.moduleName;
238      dockItemInfo.keyName = appInfo.keyName;
239      dockItemInfo.appIconId = appInfo.appIconId;
240      dockItemInfo.appLabelId = appInfo.appLabelId;
241      dockItemInfo.isSystemApp = appInfo.isSystemApp;
242      dockItemInfo.isUninstallAble = appInfo.isUninstallAble;
243      dockItemInfo.badgeNumber = appInfo.badgeNumber;
244      if (dockItemCount == 0 || index == undefined || index >= dockItemCount || index < 0) {
245        this.mResidentList.push(dockItemInfo);
246      } else {
247        this.mResidentList.splice(index, 0, dockItemInfo);
248      }
249      AppStorage.setOrCreate('residentList', this.mResidentList);
250      globalThis.RdbStoreManagerInstance.insertIntoSmartdock(this.mResidentList);
251      Log.showDebug(TAG, `addToSmartdock appInfo: ${appInfo.keyName}`);
252      return true;
253    }
254    return false;
255  }
256
257  /**
258   * check docklist over max num or not
259   * @param dockItemCount
260   * @return true: over max
261   * @return false: editable
262   */
263  private checkDockNum(dockItemCount: number): boolean {
264    if (dockItemCount >= this.mSmartDockStyleConfig.mMaxDockNum) {
265      Prompt.showToast({
266        message: $r('app.string.no_space_for_add')
267      });
268      return true;
269    }
270    return false;
271  }
272
273  /**
274   * check app exist in list
275   * @param list
276   * @param appInfo
277   * @return true: not exit, editable
278   * @return false: exited
279   */
280  private idDuplicate(list: AppItemInfo[], appInfo: AppItemInfo): boolean {
281    for (let i = 0; i < list.length; i++) {
282      if (list[i].keyName === appInfo.keyName) {
283        Prompt.showToast({
284          message: $r('app.string.duplicate_add')
285        });
286        return false;
287      }
288    }
289    return true;
290  }
291
292  /**
293   * send requset to add appItem to pageDesktop
294   * @param appInfo
295   */
296  addToPageDesk(appInfo: DockItemInfo): void {
297    if (appInfo.itemType == CommonConstants.TYPE_APP) {
298      localEventManager.sendLocalEventSticky(EventConstants.EVENT_REQUEST_PAGEDESK_ITEM_ADD, appInfo).then(()=>{}, ()=>{});
299    } else {
300      Prompt.showToast({
301        message: $r('app.string.disable_add_to_dock')
302      });
303    }
304  }
305
306  /**
307   * move appItem from itemIndex to insertIndex
308   * @param insertIndex
309   * @param itemIndex
310   */
311  insertItemToIndex(insertIndex: number, itemIndex: number): void {
312    Log.showInfo(TAG, `insertItemToIndex insertIndex: ${insertIndex}, itemIndex: ${itemIndex}`);
313    if ((insertIndex == 0 || insertIndex == 1 || itemIndex == 0 || itemIndex == 1) && this.mDevice === CommonConstants.PAD_DEVICE_TYPE) {
314      Prompt.showToast({
315        message: $r('app.string.disable_to_move')
316      });
317      return;
318    }
319    this.mResidentList = AppStorage.get('residentList');
320    if (itemIndex < insertIndex) {
321      const selectItem = this.mResidentList[itemIndex];
322      this.mResidentList.splice(insertIndex, 0, selectItem);
323      this.mResidentList.splice(itemIndex, 1);
324    }
325    if (itemIndex > insertIndex) {
326      const selectItem = this.mResidentList[itemIndex];
327      this.mResidentList.splice(itemIndex, 1);
328      this.mResidentList.splice(insertIndex, 0, selectItem);
329    }
330    AppStorage.setOrCreate('residentList', this.mResidentList);
331    globalThis.RdbStoreManagerInstance.insertIntoSmartdock(this.mResidentList);
332  }
333
334  /**
335   * register residentList dock ADD ITEM Listener
336   * local listener for model to model send and receive msg
337   */
338  registerDockListener(): void {
339    localEventManager.registerEventListener(this.mAddToDockListener, [
340      EventConstants.EVENT_REQUEST_DOCK_ITEM_ADD,
341      EventConstants.EVENT_REQUEST_RESIDENT_DOCK_ITEM_DELETE,
342      EventConstants.EVENT_REQUEST_RECENT_DOCK_ITEM_DELETE,
343      EventConstants.EVENT_REQUEST_RESIDENT_DOCK_ITEM_UPDATE,
344      EventConstants.EVENT_BADGE_UPDATE
345    ]);
346    Log.showDebug(TAG, 'local listener on create');
347  }
348
349  /**
350   * unregister residentList dock ADD ITEM Listener
351   */
352  unregisterDockListener(): void {
353    localEventManager.unregisterEventListener(this.mAddToDockListener);
354    Log.showDebug(TAG, 'local listener on destroy');
355  }
356
357  /**
358   * resident local Listener
359   */
360  private readonly mAddToDockListener = {
361    onReceiveEvent: (event: string, params: any) => {
362      Log.showDebug(TAG, `receive event: ${event}, params: ${JSON.stringify(params)}`);
363      if (event === EventConstants.EVENT_REQUEST_DOCK_ITEM_ADD) {
364        this.addToSmartdock(params);
365      } else if (event === EventConstants.EVENT_REQUEST_RESIDENT_DOCK_ITEM_DELETE) {
366        this.deleteDockItem(params, SmartDockConstants.RESIDENT_DOCK_TYPE);
367      } else if (event === EventConstants.EVENT_REQUEST_RECENT_DOCK_ITEM_DELETE) {
368        this.deleteDockItem(params, SmartDockConstants.RECENT_DOCK_TYPE);
369      } else if (event === EventConstants.EVENT_REQUEST_RESIDENT_DOCK_ITEM_UPDATE) {
370        this.updateResistDockItem(params);
371      } else if (event === EventConstants.EVENT_BADGE_UPDATE) {
372        this.updateBadgeNum(params);
373      }
374    }
375  };
376
377  private updateBadgeNum(badgeInfo) {
378    Log.showInfo(TAG, `updateBadgeNum badgeInfo is ${JSON.stringify(badgeInfo)}`);
379    let residentListTemp: DockItemInfo[] = AppStorage.get('residentList');
380    if (!CheckEmptyUtils.isEmptyArr(residentListTemp)) {
381      for (var i = 0; i < residentListTemp.length; i++) {
382        if (badgeInfo.bundleName === residentListTemp[i].bundleName) {
383          let dockItemInfo = new DockItemInfo();
384          dockItemInfo.itemType = CommonConstants.TYPE_APP;
385          dockItemInfo.editable = true;
386          dockItemInfo.appId = residentListTemp[i].appId;
387          dockItemInfo.appName = residentListTemp[i].appName;
388          dockItemInfo.bundleName = residentListTemp[i].bundleName;
389          dockItemInfo.abilityName = residentListTemp[i].abilityName;
390          dockItemInfo.moduleName = residentListTemp[i].moduleName;
391          dockItemInfo.keyName = residentListTemp[i].keyName;
392          dockItemInfo.appIconId = residentListTemp[i].appIconId;
393          dockItemInfo.appLabelId = residentListTemp[i].appLabelId;
394          dockItemInfo.installTime = residentListTemp[i].installTime;
395          dockItemInfo.isSystemApp = residentListTemp[i].isSystemApp;
396          dockItemInfo.isUninstallAble = residentListTemp[i].isUninstallAble;
397          dockItemInfo.badgeNumber = badgeInfo.badgeNumber;
398          residentListTemp[i] = dockItemInfo;
399          Log.showDebug(TAG, `updateBadgeNum dockItemInfo is ${JSON.stringify(dockItemInfo)}`);
400          AppStorage.setOrCreate('residentList', residentListTemp);
401        }
402      }
403    }
404
405    if (this.mDevice === CommonConstants.PAD_DEVICE_TYPE) {
406      this.mRecentDataList = AppStorage.get('recentList');
407      Log.showDebug(TAG, 'updateBadgeNum recent ');
408      if (!CheckEmptyUtils.isEmptyArr(this.mRecentDataList)) {
409        for (var i = 0; i < this.mRecentDataList.length; i++) {
410          let curRecentData: RecentBundleMissionInfo = this.mRecentDataList[i];
411          Log.showDebug(TAG, `updateBadgeNum curRecentData is ${JSON.stringify(curRecentData)}`);
412          if (curRecentData.bundleName === badgeInfo.bundleName) {
413            let recentBundleMission: RecentBundleMissionInfo = new RecentBundleMissionInfo();
414            recentBundleMission.appId = curRecentData.appId;
415            recentBundleMission.appName = curRecentData.appName;
416            recentBundleMission.bundleName = curRecentData.bundleName;
417            recentBundleMission.abilityName = curRecentData.abilityName;
418            recentBundleMission.moduleName = curRecentData.moduleName;
419            recentBundleMission.keyName = curRecentData.keyName;
420            recentBundleMission.appIconId = curRecentData.appIconId;
421            recentBundleMission.appLabelId = curRecentData.appLabelId;
422            recentBundleMission.installTime = curRecentData.installTime;
423            recentBundleMission.isSystemApp = curRecentData.isSystemApp;
424            recentBundleMission.isUninstallAble = curRecentData.isUninstallAble;
425            recentBundleMission.badgeNumber = badgeInfo.badgeNumber;
426            this.mRecentDataList[i] = recentBundleMission;
427            Log.showDebug(TAG, `updateBadgeNum dockItemInfo is ${JSON.stringify(recentBundleMission)}`);
428            AppStorage.setOrCreate('recentList', this.mRecentDataList);
429          }
430        }
431      }
432    }
433  }
434
435  private registerMissionListener(): void {
436    Log.showDebug(TAG, 'registerMissionListener');
437    const listener: missionManager.MissionListener = {
438      onMissionCreated: this.onMissionCreatedCallback.bind(this),
439      onMissionDestroyed: this.onMissionDestroyedCallback.bind(this),
440      onMissionSnapshotChanged: this.onMissionSnapshotChangedCallback.bind(this),
441      onMissionMovedToFront: this.onMissionMovedToFrontCallback.bind(this),
442      onMissionIconUpdated: this.onMissionIconUpdatedCallback.bind(this),
443      onMissionClosed: this.onMissionClosedCallback.bind(this),
444      onMissionLabelUpdated: this.onMissionLabelUpdatedCallback.bind(this)
445    };
446    missionManager.on('mission', listener);
447  }
448
449  /**
450   * get recent view list
451   */
452  async getRecentViewDataList(missionId: number): Promise<void> {
453    let mRecentMissionsList = await amsMissionManager.getRecentMissionsList();
454    Log.showDebug(TAG, `getRecentMissionsList length: ${mRecentMissionsList.length}`);
455    const snapShotTime = new Date().toString();
456
457    let recentMissionInfoIndex = mRecentMissionsList.findIndex(item => {
458      return item.missionId === missionId;
459    })
460    if (recentMissionInfoIndex != -1) {
461      let recentMissionInfo: RecentMissionInfo = {
462        missionId: mRecentMissionsList[recentMissionInfoIndex].missionId,
463        appIconId: mRecentMissionsList[recentMissionInfoIndex].appIconId,
464        appLabelId: mRecentMissionsList[recentMissionInfoIndex].appLabelId,
465        appName: mRecentMissionsList[recentMissionInfoIndex].appName,
466        bundleName: mRecentMissionsList[recentMissionInfoIndex].bundleName,
467        moduleName: mRecentMissionsList[recentMissionInfoIndex].moduleName,
468        abilityName: mRecentMissionsList[recentMissionInfoIndex].abilityName,
469        lockedState: mRecentMissionsList[recentMissionInfoIndex].lockedState,
470        snapShotTime: snapShotTime
471      }
472      mRecentMissionsList[recentMissionInfoIndex] = recentMissionInfo;
473    }
474    if (globalThis.recentMode && windowManager.isSplitWindowMode(globalThis.recentMode)) {
475      mRecentMissionsList.forEach((item, index) => {
476        if (item.missionId == globalThis.splitMissionId) {
477          mRecentMissionsList.splice(index, 1);
478          return;
479        }
480      });
481    }
482    AppStorage.setOrCreate('recentMissionsList', mRecentMissionsList);
483  }
484
485  onMissionCreatedCallback(missionId: number): void {
486    Log.showInfo(TAG, 'onMissionCreatedCallback, missionId=' + missionId);
487  }
488
489  onMissionDestroyedCallback(missionId: number): void {
490    Log.showInfo(TAG, 'onMissionDestroyedCallback, missionId=' + missionId);
491    this.getRecentDataList().then(() => {}, ( )=> {});
492    this.getRecentViewDataList(missionId).then(() => {}, () => {});
493  }
494
495  onMissionSnapshotChangedCallback(missionId: number): void {
496    Log.showInfo(TAG, 'onMissionSnapshotChangedCallback, missionId=' + missionId);
497    this.getRecentDataList().then(() => {}, () => {});
498    this.getRecentViewDataList(missionId).then(() => {}, () => {});
499  }
500
501  onMissionMovedToFrontCallback(missionId: number): void {
502    Log.showInfo(TAG, 'onMissionMovedToFrontCallback, missionId=' + missionId);
503    this.getRecentDataList().then(() => {}, () => { });
504    this.getRecentViewDataList(missionId).then(() => {}, () => {});
505  }
506
507  onMissionIconUpdatedCallback(missionId: number): void {
508    Log.showInfo(TAG, 'onMissionIconUpdatedCallback, missionId=' + missionId);
509    this.getRecentDataList().then(() => {}, () => {});
510    this.getRecentViewDataList(missionId).then(() => {}, () => {});
511  }
512
513  onMissionClosedCallback(missionId: number): void {
514    Log.showInfo(TAG, 'onMissionClosedCallback, missionId=' + missionId);
515    this.getRecentDataList().then(() => {}, () => {});
516    this.getRecentViewDataList(missionId).then(() => {}, () => {});
517  }
518
519  onMissionLabelUpdatedCallback(missionId: number): void {
520    Log.showInfo(TAG, 'onMissionLabelUpdatedCallback, missionId=' + missionId);
521    this.getRecentDataList().then(() => {}, () => {});
522    this.getRecentViewDataList(missionId).then(() => {}, () => {});
523  }
524
525  /**
526   * get ShortcutInfo by bundleName
527   * @param bundleName
528   */
529  getShortcutInfo(bundleName: string): launcherBundleManager.ShortcutInfo[] | undefined {
530    return this.mAppModel.getShortcutInfo(bundleName);
531  }
532
533  /**
534   * @param cacheKey
535   *
536   * @return cache
537   */
538  getAppName(cacheKey: string): string {
539    return this.mResourceManager.getAppResourceCache(cacheKey, this.KEY_NAME);
540  }
541
542  async getSnapshot(missionIds: MissionInfo[], name: string): Promise<any> {
543    const snapshotList: {
544      name: string,
545      image: any,
546      missionId: number,
547      boxSize: number,
548      bundleName: string,
549      left?: number,
550      right?: number,
551    }[] = [];
552    if(this.mDevice === CommonConstants.PAD_DEVICE_TYPE){
553      let snapShotWidth = 0;
554      for (const item of missionIds) {
555        let pixelMap: {
556          name: string,
557          image: any,
558          missionId: number,
559          boxSize: number,
560          bundleName: string,
561          left?: number,
562          right?: number,
563        } = {
564          name: '',
565          left: StyleConstants.DEFAULT_12,
566          missionId: -1,
567          image: $r('app.media.icon'),
568          boxSize: StyleConstants.DEFAULT_SMART_DOCK_MISSION_IMAGE_HEIGHT,
569          bundleName: ''
570        };
571        const snapshotMap = await missionManager.getMissionSnapShot('', item.missionId);
572        pixelMap.image = snapshotMap.snapshot;
573        pixelMap.missionId = item.missionId;
574        pixelMap.bundleName = snapshotMap.ability.bundleName;
575        const imageInfo = await snapshotMap.snapshot.getImageInfo();
576        pixelMap.boxSize = Math.ceil(StyleConstants.DEFAULT_SMART_DOCK_MISSION_IMAGE_HEIGHT / imageInfo.size.height * imageInfo.size.width);
577        pixelMap.name = name;
578        pixelMap.left = StyleConstants.DEFAULT_12;
579        snapshotList.push(pixelMap);
580        snapShotWidth += pixelMap.boxSize + pixelMap.left;
581      }
582      AppStorage.setOrCreate('snapshotList', snapshotList);
583      AppStorage.setOrCreate('snapShotWidth', snapShotWidth);
584    }
585    Log.showDebug(TAG, 'getSnapshot update snapshotList');
586    return snapshotList;
587  }
588
589  private deleteResistDockItem(dockItem: {bundleName: string | undefined, keyName: string | undefined}): boolean {
590    this.mResidentList = AppStorage.get('residentList');
591    Log.showError(TAG, `deleteResistDockItem residentList length ${this.mResidentList.length}`);
592    if (!CheckEmptyUtils.isEmptyArr(this.mResidentList)) {
593      const findResidentList = this.mResidentList.find(item => {
594        return dockItem.bundleName == item.bundleName || dockItem.keyName == item.keyName;
595      })
596      // check right to delete
597      if (!findResidentList.editable) {
598        Prompt.showToast({
599          message: $r('app.string.disable_add_to_delete')
600        });
601        return false;
602      }
603      this.mResidentList = this.mResidentList.filter(item => {
604        if (dockItem.bundleName) {
605          return dockItem.bundleName != item.bundleName;
606        } else if (dockItem.keyName) {
607          return dockItem.keyName != item.keyName;
608        }
609      })
610      AppStorage.setOrCreate('residentList', this.mResidentList);
611      globalThis.RdbStoreManagerInstance.insertIntoSmartdock(this.mResidentList);
612      Log.showDebug(TAG, `deleteResistDockItem resist dockItem: ${JSON.stringify(dockItem)}`);
613    }
614    return true;
615  }
616
617  private deleteRecentDockItem(dockItem: {bundleName: string | undefined, keyName: string | undefined}): boolean {
618    let res = false;
619    this.mRecentDataList = AppStorage.get('recentList');
620    Log.showDebug(TAG, `deleteRecentDockItem recent dockItem: ${JSON.stringify(dockItem)}`);
621    if (!CheckEmptyUtils.isEmptyArr(this.mRecentDataList)) {
622      this.mRecentDataList = this.mRecentDataList.filter(item => {
623        if (dockItem.bundleName) {
624          return dockItem.bundleName != item.bundleName;
625        } else if (dockItem.keyName) {
626          return dockItem.keyName != item.keyName;
627        }
628      })
629      AppStorage.setOrCreate('recentList', this.mRecentDataList);
630      res = true;
631    }
632    return res;
633  }
634
635  updateResistDockItem(appInfo: AppItemInfo): void{
636    Log.showDebug(TAG, `updateResistDockItem appInfo: ${JSON.stringify(appInfo)}`);
637    let resistDockItem: DockItemInfo[] = AppStorage.get('residentList');
638    if (!CheckEmptyUtils.isEmptyArr(resistDockItem)) {
639      for (let i = 0; i < resistDockItem.length; i++) {
640        if (appInfo.bundleName === resistDockItem[i].bundleName) {
641          let dockItemInfo = new DockItemInfo();
642          dockItemInfo.itemType = CommonConstants.TYPE_APP;
643          dockItemInfo.editable = true;
644          dockItemInfo.appId = appInfo.appId;
645          dockItemInfo.appName = appInfo.appName;
646          dockItemInfo.bundleName = appInfo.bundleName;
647          dockItemInfo.abilityName = appInfo.abilityName;
648          dockItemInfo.moduleName = appInfo.moduleName;
649          dockItemInfo.keyName = appInfo.keyName;
650          dockItemInfo.appIconId = appInfo.appIconId;
651          dockItemInfo.appLabelId = appInfo.appLabelId;
652          dockItemInfo.installTime = appInfo.installTime;
653          dockItemInfo.isSystemApp = appInfo.isSystemApp;
654          dockItemInfo.isUninstallAble = appInfo.isUninstallAble;
655          dockItemInfo.badgeNumber = appInfo.badgeNumber;
656          resistDockItem[i] = dockItemInfo;
657          AppStorage.setOrCreate('residentList', resistDockItem);
658        }
659      }
660    }
661  }
662}