• 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 Prompt from '@ohos.promptAction';
17import { Log } from '@ohos/common';
18import { Trace } from '@ohos/common';
19import { CheckEmptyUtils } from '@ohos/common';
20import { StyleConstants } from '@ohos/common';
21import { EventConstants } from '@ohos/common';
22import { CommonConstants } from '@ohos/common';
23import { FormManager } from '@ohos/common';
24import { BadgeManager } from '@ohos/common';
25import { windowManager } from '@ohos/common';
26import { layoutConfigManager } from '@ohos/common';
27import { BaseViewModel } from '@ohos/common';
28import { SettingsModelObserver } from '@ohos/common';
29import { FormListInfoCacheManager } from '@ohos/common';
30import { FormModel } from '@ohos/common';
31import { SettingsModel } from '@ohos/common';
32import { PageDesktopModel } from '@ohos/common';
33import { MenuInfo } from '@ohos/common';
34import { CardItemInfo } from '@ohos/common';
35import { BigFolderModel } from '@ohos/bigfolder';
36import { FormDetailLayoutConfig } from '@ohos/form';
37import { localEventManager } from '@ohos/common';
38import PageDesktopConstants from '../common/constants/PageDesktopConstants';
39import { PageDesktopGridStyleConfig } from '../common/PageDesktopGridStyleConfig';
40import formHost from '@ohos.app.form.formHost';
41
42const TAG = 'PageDesktopViewModel';
43const KEY_APP_LIST = 'appListInfo';
44const KEY_FORM_LIST = 'formListInfo';
45
46export default class PageDesktopViewModel extends BaseViewModel {
47  private readonly pageDesktopStyleConfig: PageDesktopGridStyleConfig = null;
48  private readonly formDetailLayoutConfig: FormDetailLayoutConfig = null;
49  private readonly mSettingsModel: SettingsModel;
50  private readonly mFolderModel: BigFolderModel;
51  private readonly mFormModel: FormModel;
52  private readonly mPageDesktopModel: PageDesktopModel;
53  private readonly mBadgeManager: BadgeManager;
54  private readonly mFormListInfoCacheManager: FormListInfoCacheManager;
55  private mBundleInfoList;
56  private mHideBundleInfoList = new Array<any>();
57  private mGridConfig;
58  private mGridAppsInfos;
59  private readonly mPageCoordinateData = {
60    gridXAxis: [],
61    gridYAxis: []
62  };
63  private isPad = false;
64  private isAddByDraggingFlag = false;
65  private desktopSwiperController: SwiperController;
66
67  async showFormManager(params) {
68    globalThis.createWindowWithName(windowManager.FORM_MANAGER_WINDOW_NAME, windowManager.RECENT_RANK);
69  }
70
71  setSwiperController(swiperController: SwiperController): void {
72    this.desktopSwiperController = swiperController;
73  }
74
75  showNext(): void {
76    this.desktopSwiperController?.showNext();
77  }
78
79  showPrevious(): void {
80    this.desktopSwiperController?.showPrevious();
81  }
82
83  private readonly mLocalEventListener = {
84    onReceiveEvent: (event, params) => {
85      Log.showDebug(TAG, `localEventListener receive event: ${event}, params: ${params}`);
86      switch (event) {
87        case EventConstants.EVENT_REQUEST_PAGEDESK_ITEM_ADD:
88          this.addToDesktop(params);
89          break;
90        case EventConstants.EVENT_REQUEST_PAGEDESK_ITEM_DELETE:
91          this.deleteAppItem(params);
92          break;
93        case EventConstants.EVENT_REQUEST_PAGEDESK_ITEM_UPDATE:
94          this.getGridList();
95          break;
96        case EventConstants.EVENT_BADGE_UPDATE:
97          this.updateBadgeNumber(params);
98          break;
99        case EventConstants.EVENT_REQUEST_PAGEDESK_FORM_ITEM_ADD:
100          this.createCardToDeskTop(params);
101          break;
102        case EventConstants.EVENT_SMARTDOCK_INIT_FINISHED:
103          this.getGridList();
104          break;
105        case EventConstants.EVENT_REQUEST_PAGEDESK_REFRESH:
106          this.pagingFiltering();
107          break;
108        case EventConstants.EVENT_REQUEST_FORM_ITEM_VISIBLE:
109          this.notifyVisibleForms();
110          break;
111        default:
112          if (!this.isPad) {
113            Log.showDebug(TAG, 'localEventListener hideBundleInfoList!')
114            this.mHideBundleInfoList = params;
115            this.getGridList();
116          }
117          break;
118      }
119    }
120  };
121
122  /**
123   * Notify forms on current page become visible.
124   */
125  notifyVisibleForms(): void {
126    let pageIndex = this.mPageDesktopModel.getPageIndex();
127    let formList = [];
128    let items = this.mGridAppsInfos[pageIndex];
129    for (let i = 0; i < items.length; i++) {
130      if (items[i].typeId == CommonConstants.TYPE_CARD) {
131        formList.push(String(items[i].cardId));
132      }
133    }
134    if (formList.length > 0) {
135      try {
136        formHost.notifyVisibleForms(formList).then(() => {
137          Log.showInfo(TAG, 'formHost notifyVisibleForms success');
138        }).catch((error) => {
139          Log.showInfo(TAG, 'formHost notifyVisibleForms, error:' + JSON.stringify(error));
140        });
141      } catch(error) {
142        Log.showInfo(TAG, `catch err->${JSON.stringify(error)}`);
143      }
144    }
145  }
146
147  private readonly mSettingsChangeObserver: SettingsModelObserver = (event: number)=> {
148    this.mGridConfig = this.getGridConfig();
149    this.pagingFiltering();
150  };
151
152  private constructor() {
153    super();
154    this.mPageDesktopModel = PageDesktopModel.getInstance();
155    this.mFolderModel = BigFolderModel.getInstance();
156    this.mFormModel = FormModel.getInstance();
157    this.mSettingsModel = SettingsModel.getInstance();
158    this.mBadgeManager = BadgeManager.getInstance();
159    this.mFormListInfoCacheManager = FormListInfoCacheManager.getInstance();
160    this.mSettingsModel.forceReloadConfig();
161    this.mSettingsModel.addObserver(this.mSettingsChangeObserver);
162    this.onPageDesktopCreate();
163    this.mGridConfig = this.getGridConfig();
164    this.pageDesktopStyleConfig = layoutConfigManager.getStyleConfig(PageDesktopGridStyleConfig.APP_GRID_STYLE_CONFIG, PageDesktopConstants.FEATURE_NAME);
165    this.formDetailLayoutConfig = layoutConfigManager.getStyleConfig(FormDetailLayoutConfig.FORM_LAYOUT_INFO, PageDesktopConstants.FEATURE_NAME);
166  }
167
168  /**
169   * Obtains the PageDesktopViewModel instance.
170   *
171   * @return PageDesktopViewModel
172   */
173  static getInstance(): PageDesktopViewModel {
174    if (globalThis.PageDesktopViewModel == null) {
175      globalThis.PageDesktopViewModel = new PageDesktopViewModel();
176    }
177    return globalThis.PageDesktopViewModel;
178  }
179
180  /**
181   * Registering Listening Events.
182   */
183  private onPageDesktopCreate(): void {
184    this.mAppModel.registerAppListEvent();
185    this.mPageDesktopModel.registerPageDesktopItemAddEvent(this.mLocalEventListener);
186    this.mPageDesktopModel.registerPageDesktopBadgeUpdateEvent(this.mLocalEventListener);
187  }
188
189  /**
190   * Unregistering Listening Events.
191   */
192  private onPageDesktopDestroy(): void {
193    this.mAppModel.unregisterAppListEvent();
194    this.mPageDesktopModel.unregisterEventListener(this.mLocalEventListener);
195  }
196
197  /**
198   * Obtains the application list displayed on the desktop.
199   */
200  async getGridList() {
201    const appInfoList = await this.getAppList();
202    const bundleInfoListTemp = [];
203    this.appendAppData(appInfoList, bundleInfoListTemp);
204    const folderInfoList = await this.mFolderModel.getFolderList();
205    Log.showDebug(TAG, 'getAppList folderInfoList length: ' + folderInfoList.length);
206    this.appendFolderData(folderInfoList, bundleInfoListTemp);
207    let formInfoList: any = this.mFormListInfoCacheManager.getCache(KEY_FORM_LIST);
208    if (formInfoList == CommonConstants.INVALID_VALUE) {
209      formInfoList = await this.mFormModel.getAllFormsInfoFromRdb();
210      if (formInfoList && formInfoList.length > 0) {
211        this.mFormListInfoCacheManager.setCache(KEY_FORM_LIST, formInfoList);
212      }
213    }
214    this.appendFormData(formInfoList, bundleInfoListTemp);
215    this.mBundleInfoList = bundleInfoListTemp;
216    this.pagingFiltering();
217  }
218
219  async updateDesktopInfo(): Promise<void> {
220    await this.mAppModel.getAppListAsync();
221    this.getGridList();
222    AppStorage.SetOrCreate('formRefresh', String(new Date()));
223  }
224
225  private async getAppList() {
226    Log.showInfo(TAG, 'getAppList start');
227
228    // get total app from system
229    const totalAppInfoList = await this.mAppModel.getAppList();
230
231    // get pageDesktop app from config
232    let pageDesktopInfo = this.mSettingsModel.getAppListInfo();
233
234    // get from config empty then init pageDesktop app
235    if (!this.mSettingsModel.isAppListInfoExist() && this.ifInfoIsNull(pageDesktopInfo)) {
236      for (const appInfo of totalAppInfoList) {
237        pageDesktopInfo.push(appInfo);
238      }
239    } else {
240      // remove uninstalled app
241      pageDesktopInfo = pageDesktopInfo.filter(item => {
242        for (const appInfo of totalAppInfoList) {
243          if (item.keyName == appInfo.keyName) {
244            item.appName = appInfo.appName;
245            return true;
246          }
247        }
248        return false;
249      });
250    }
251
252    // product phone logic
253    if (!this.isPad) {
254      this.addNewInstalledInfo(totalAppInfoList, pageDesktopInfo);
255      this.removeBottomBarInfo(pageDesktopInfo);
256    }
257    this.removeFolderInfo(pageDesktopInfo);
258
259    // update pageDesktop app config
260    this.mSettingsModel.setAppListInfo(pageDesktopInfo);
261    AppStorage.SetOrCreate('isDesktopLoadFinished', true);
262    return pageDesktopInfo;
263  }
264
265  /**
266   * delete app in pageDesktop
267   *
268   * @param abilityName
269   * @param bundleName
270   */
271  deleteAppItem(appItem: {bundleName: string | undefined, keyName: string | undefined}) {
272    this.mBundleInfoList = this.mSettingsModel.getAppListInfo();
273    Log.showDebug(TAG, `deleteAppItem appItem: ${JSON.stringify(appItem)}`);
274    if (appItem.bundleName) {
275      this.mBundleInfoList = this.mBundleInfoList.filter(item => item.bundleName !== appItem.bundleName);
276    } else if(appItem.keyName) {
277      this.mBundleInfoList = this.mBundleInfoList.filter(item => item.keyName !== appItem.keyName);
278    }
279    this.mSettingsModel.setAppListInfo(this.mBundleInfoList);
280
281    const gridLayoutInfo = this.mSettingsModel.getLayoutInfo();
282    const layoutInfo = gridLayoutInfo.layoutInfo;
283    for (let i = 0; i < layoutInfo.length; i++) {
284      if (layoutInfo[i].typeId == CommonConstants.TYPE_APP &&
285      (layoutInfo[i].bundleName == appItem.bundleName || layoutInfo[i].keyName == appItem.keyName)) {
286        const page = layoutInfo[i].page;
287        gridLayoutInfo.layoutInfo.splice(i, 1);
288        let ret: boolean = this.mPageDesktopModel.deleteBlankPageFromLayoutInfo(gridLayoutInfo, page);
289        this.mSettingsModel.setLayoutInfo(gridLayoutInfo);
290        if(ret){
291          const curPageIndex = this.mPageDesktopModel.getPageIndex();
292          Log.showInfo(TAG, 'deleteAppItem' + curPageIndex);
293          this.mPageDesktopModel.setPageIndex(curPageIndex - 1);
294        }
295        break;
296      }
297    }
298    this.getGridList();
299  }
300
301  /**
302   * add app to pageDesktop
303   *
304   * @param appInfo
305   */
306  addToDesktop(appInfo) {
307    this.mBundleInfoList = this.mSettingsModel.getAppListInfo();
308    Log.showDebug(TAG, `addToDesktop keyName: ${appInfo.keyName} mBundleInfoList length: ${this.mBundleInfoList.length}`);
309    for (let i = 0; i < this.mBundleInfoList.length; i++) {
310      if (this.mBundleInfoList[i].keyName === appInfo.keyName) {
311        Prompt.showToast({
312          message: $r('app.string.duplicate_add')
313        });
314        return;
315      }
316    }
317
318    const gridLayoutInfo = this.mSettingsModel.getLayoutInfo();
319
320    // Check if app is in folder
321    for (let i = 0; i < gridLayoutInfo.layoutInfo.length; i++) {
322      if (gridLayoutInfo.layoutInfo[i].typeId === CommonConstants.TYPE_FOLDER) {
323        const appIndex = gridLayoutInfo.layoutInfo[i].layoutInfo[0].findIndex(item => {
324          return item.keyName === appInfo.keyName;
325        })
326        if (appIndex != CommonConstants.INVALID_VALUE) {
327          Prompt.showToast({
328            message: $r('app.string.duplicate_add')
329          });
330          return;
331        }
332      }
333    }
334
335    this.mBundleInfoList.push(appInfo);
336    this.mSettingsModel.setAppListInfo(this.mBundleInfoList);
337    this.getGridList();
338  }
339
340  /**
341   * add form to pageDesktop
342   *
343   * @param appInfo
344   */
345  addFormToDesktop(formInfo) {
346    Log.showInfo(TAG, 'addFormToDesktop');
347    this.mBundleInfoList = this.mSettingsModel.getAppListInfo();
348    switch(formInfo.dimension) {
349      case FormDimension.Dimension_1_2:
350        formInfo.row = this.formDetailLayoutConfig.getFormLayoutInfo().formLayoutDimension1X2.row;
351        formInfo.column = this.formDetailLayoutConfig.getFormLayoutInfo().formLayoutDimension1X2.column;
352        formInfo.area = this.formDetailLayoutConfig.getFormLayoutInfo().formLayoutDimension1X2.area;
353        break;
354      case FormDimension.Dimension_2_2:
355        formInfo.row = this.formDetailLayoutConfig.getFormLayoutInfo().formLayoutDimension2X2.row;
356        formInfo.column = this.formDetailLayoutConfig.getFormLayoutInfo().formLayoutDimension2X2.column;
357        formInfo.area = this.formDetailLayoutConfig.getFormLayoutInfo().formLayoutDimension2X2.area;
358        break;
359      case FormDimension.Dimension_2_4:
360        formInfo.row = this.formDetailLayoutConfig.getFormLayoutInfo().formLayoutDimension2X4.row;
361        formInfo.column = this.formDetailLayoutConfig.getFormLayoutInfo().formLayoutDimension2X4.column;
362        formInfo.area = this.formDetailLayoutConfig.getFormLayoutInfo().formLayoutDimension2X4.area;
363        break;
364      case FormDimension.Dimension_4_4:
365        formInfo.row = this.formDetailLayoutConfig.getFormLayoutInfo().formLayoutDimension4X4.row;
366        formInfo.column = this.formDetailLayoutConfig.getFormLayoutInfo().formLayoutDimension4X4.column;
367        formInfo.area = this.formDetailLayoutConfig.getFormLayoutInfo().formLayoutDimension4X4.area;
368        break;
369      default:
370        break;
371    }
372    this.mBundleInfoList.push(formInfo);
373    this.mSettingsModel.setAppListInfo(this.mBundleInfoList);
374    this.getGridList();
375  }
376
377  /**
378   * update badge in desktop
379   *
380   * @param badgeInfo
381   */
382  updateBadgeNumber(badgeInfo) {
383    this.mBundleInfoList = this.mSettingsModel.getAppListInfo();
384
385    let appInfo = this.mBundleInfoList.find(item => {
386      return item.bundleName == badgeInfo.bundleName;
387    });
388    if (!this.ifInfoIsNull(appInfo)) {
389      Log.showDebug(TAG, `updateBadgeNumber bundleName: ${badgeInfo.bundleName}`);
390      appInfo.badgeNumber = badgeInfo.badgeNumber;
391      this.mSettingsModel.setAppListInfo(this.mBundleInfoList);
392      this.getGridList();
393    } else {
394      Log.showDebug(TAG, 'updateBadgeNumber appInfo is null ');
395      const gridLayoutInfo = this.mSettingsModel.getLayoutInfo();
396      const layoutInfo = gridLayoutInfo.layoutInfo;
397      let hasFound = false;
398      for (let i = 0; i < layoutInfo.length; i++) {
399        if (hasFound) {
400          break;
401        }
402        if (layoutInfo[i].typeId == CommonConstants.TYPE_FOLDER && !hasFound) {
403          for (let j = 0; j < layoutInfo[i].layoutInfo.length; j++) {
404            appInfo = layoutInfo[i].layoutInfo[j].find(item => {
405              return item.bundleName == badgeInfo.bundleName;
406            });
407
408            if (!this.ifInfoIsNull(appInfo)) {
409              hasFound = true;
410              appInfo.badgeNumber = badgeInfo.badgeNumber;
411              break;
412            }
413          }
414          layoutInfo[i].badgeNumber = this.getFolderBadgeNumber(layoutInfo[i]);
415        }
416      }
417      if (hasFound) {
418        this.mSettingsModel.setLayoutInfo(gridLayoutInfo);
419        this.getGridList();
420      }
421    }
422  }
423
424  private getFolderBadgeNumber(folderInfo) {
425    let bidfolderBadgeNumber: number = 0;
426    let layoutInfo: [[]] = folderInfo.layoutInfo;
427    for (var i = 0; i < layoutInfo.length; i++) {
428      layoutInfo[i].forEach((item: any) => {
429        if (item.badgeNumber && item.badgeNumber > 0) {
430          bidfolderBadgeNumber = bidfolderBadgeNumber + item.badgeNumber;
431        }
432      });
433    }
434    return bidfolderBadgeNumber;
435  }
436
437  /**
438   * add app to pageDesktop by dragging
439   *
440   * @param appInfo
441   */
442  addToDesktopByDraging(appInfo) {
443    Log.showDebug(TAG, `addToDesktopByDraging bundleName: ${appInfo.bundleName}`);
444    this.mGridConfig = this.mSettingsModel.getGridConfig();
445    for (let i = 0; i < this.mBundleInfoList.length; i++) {
446      if (this.mBundleInfoList[i].bundleName === appInfo.bundleName) {
447        Prompt.showToast({
448          message: $r('app.string.duplicate_add')
449        });
450        return;
451      }
452    }
453    this.mBundleInfoList.push(appInfo);
454    this.mSettingsModel.setAppListInfo(this.mBundleInfoList);
455    this.getGridList();
456  }
457
458  /**
459   * add app to dock
460   *
461   * @param appInfo
462   */
463  addToDock(appInfo) {
464    this.mPageDesktopModel.sendDockItemChangeEvent(appInfo);
465  }
466
467  private appendAppData(appInfoList, bundleInfoList) {
468    for (let i = 0; i < appInfoList.length; i++) {
469      if (this.isInHideAppList(appInfoList[i])) {
470        continue;
471      }
472      appInfoList[i].typeId = CommonConstants.TYPE_APP;
473      appInfoList[i].area = [1, 1];
474      bundleInfoList.push(appInfoList[i]);
475    }
476  }
477
478  private isInHideAppList(appInfo): boolean {
479    for (const hideInfo of this.mHideBundleInfoList) {
480      if (appInfo.keyName == hideInfo.keyName) {
481        return true;
482      }
483    }
484    return false;
485  }
486
487  private appendFolderData(folderInfoList, bundleInfoList) {
488    for (let i = 0; i < folderInfoList.length; i++) {
489      for (let j = 0; j < folderInfoList[i].layoutInfo.length; j++) {
490        for (let k = 0; k < folderInfoList[i].layoutInfo[j].length; k++) {
491          const appIndex = bundleInfoList.findIndex(item => {
492            return item.keyName === folderInfoList[i].layoutInfo[j][k].keyName;
493          });
494          if (appIndex != CommonConstants.INVALID_VALUE) {
495            bundleInfoList.splice(appIndex, 1);
496          }
497        }
498      }
499    }
500  }
501
502  private appendFormData(formInfoList, bundleInfoList) {
503    for (let i = 0; i < formInfoList.length; i++) {
504      formInfoList[i].typeId = CommonConstants.TYPE_CARD;
505      bundleInfoList.push(formInfoList[i]);
506    }
507  }
508
509  /**
510   * Obtains Grid Configuration.
511   */
512  getGridConfig() {
513    return this.mSettingsModel.getGridConfig();
514  }
515
516  /**
517   * refresh page
518   */
519  pagingFiltering() {
520    const appInfo = {
521      appGridInfo: []
522    };
523    const appListInfo = [];
524    const info = this.getAndSetLayoutInfo();
525    const layoutInfo = info.layoutInfo;
526    for (let i = 0; i < layoutInfo.length; i++) {
527      if (layoutInfo[i].typeId == CommonConstants.TYPE_APP) {
528        for (let j = 0; j < this.mBundleInfoList.length; j++) {
529          if (layoutInfo[i].keyName == this.mBundleInfoList[j].keyName
530          && layoutInfo[i].typeId == this.mBundleInfoList[j].typeId) {
531            this.mBundleInfoList[j].area = layoutInfo[i].area;
532            this.mBundleInfoList[j].page = layoutInfo[i].page;
533            this.mBundleInfoList[j].row = layoutInfo[i].row;
534            this.mBundleInfoList[j].column = layoutInfo[i].column;
535            this.mBundleInfoList[j].x = 0;
536            appListInfo.push(this.mBundleInfoList[j]);
537          }
538        }
539      } else if (layoutInfo[i].typeId == CommonConstants.TYPE_FOLDER) {
540        appListInfo.push(layoutInfo[i]);
541      } else if (layoutInfo[i].typeId == CommonConstants.TYPE_CARD) {
542        for (let j = 0; j < this.mBundleInfoList.length; j++) {
543          if (layoutInfo[i].cardId == this.mBundleInfoList[j].cardId
544          && layoutInfo[i].typeId == this.mBundleInfoList[j].typeId) {
545            this.mBundleInfoList[j].cardId = layoutInfo[i].cardId;
546            this.mBundleInfoList[j].area = layoutInfo[i].area;
547            this.mBundleInfoList[j].page = layoutInfo[i].page;
548            this.mBundleInfoList[j].row = layoutInfo[i].row;
549            this.mBundleInfoList[j].column = layoutInfo[i].column;
550            this.mBundleInfoList[j].x = 0;
551            appListInfo.push(this.mBundleInfoList[j]);
552          }
553        }
554      }
555    }
556    appInfo.appGridInfo = this.integrateSwiper(appListInfo);
557    Log.showInfo(TAG, 'pagingFiltering appListInfo length:' + appListInfo.length);
558    AppStorage.SetOrCreate('selectDesktopAppItem', '');
559    AppStorage.SetOrCreate(KEY_APP_LIST, appInfo);
560  }
561
562  private integrateSwiper(list) {
563    let gridAppsInfos = [];
564    const allPageCount = this.mSettingsModel.getLayoutInfo().layoutDescription.pageCount;
565    let max = allPageCount;
566    for (let i = 0;i < list.length; i++) {
567      if (max <= list[i].page + 1) {
568        max = list[i].page + 1;
569      }
570    }
571
572    for (let i = 0;i < max; i++) {
573      gridAppsInfos.push([]);
574    }
575
576    for (let i = 0;i < list.length; i++) {
577      gridAppsInfos[list[i].page].push(list[i]);
578    }
579
580    //If the workspace has no applications,
581    // it needs to be initialized to [].
582    if (gridAppsInfos.length == 0) {
583      gridAppsInfos.push([]);
584    }
585
586    this.mGridAppsInfos = gridAppsInfos;
587    return gridAppsInfos;
588  }
589
590  private getAndSetLayoutInfo() {
591    let info = this.mSettingsModel.getLayoutInfo();
592    const isLegal = this.ifLayoutRationality(info);
593    if (isLegal) {
594      info = this.updateLayoutInfo(info);
595    } else {
596      info = this.updateLayoutInfo(this.createNewLayoutInfo());
597    }
598    this.mSettingsModel.setLayoutInfo(info);
599    return info;
600  }
601
602  private ifLayoutRationality(info) {
603    //verify whether the info is null.
604    if (this.ifInfoIsNull(info)) {
605      return false;
606    }
607    const layoutDescription = info.layoutDescription;
608
609    //verify whether the layoutDescription is different.
610    this.mGridConfig = this.getGridConfig();
611    const column = this.mGridConfig.column;
612    const row = this.mGridConfig.row;
613    if (this.ifDescriptionIsDifferent(layoutDescription, row, column)) {
614      return false;
615    }
616
617    //verify whether the layoutInfo's row and column is more than standard.
618    if (this.ifColumnOrRowAreBigger(info.layoutInfo, row, column)) {
619      return false;
620    }
621
622    //verify whether the layoutInfo's position is duplicated.
623    if (this.ifDuplicatePosition(info.layoutInfo)) {
624      return false;
625    }
626    //verify whether the layoutInfo's keyName is duplicated.
627    if (this.ifDuplicateKeyName(info.layoutInfo)) {
628      return false;
629    }
630    return true;
631  };
632
633  private ifInfoIsNull(info) {
634    if (info == undefined || info == '' || info == {} || info == null) {
635      return true;
636    }
637    return false;
638  }
639
640  private ifDescriptionIsDifferent(layoutDescription, row, column) {
641    if (row != layoutDescription.row || column != layoutDescription.column) {
642      return true;
643    }
644    return false;
645  }
646
647  private ifColumnOrRowAreBigger(layoutInfo, row, column) {
648    for (let i = 0; i < layoutInfo.length; i++) {
649      //column or row are bigger than legal num
650      if (layoutInfo[i].column >= column || layoutInfo[i].row >= row) {
651        return true;
652      }
653    }
654    return false;
655  }
656
657  private ifDuplicatePosition(layoutInfo) {
658    const mPositionInfo = [];
659    for (let i = 0; i < layoutInfo.length; i++) {
660      for(let j = 0; j < layoutInfo[i].area[1]; j++){
661        for(let k = 0; k < layoutInfo[i].area[0]; k++){
662          const position = [];
663          position[0] = layoutInfo[i].page;
664          position[1] = layoutInfo[i].row + j;
665          position[2] = layoutInfo[i].column + k;
666          mPositionInfo.push(position);
667        }
668      }
669    }
670    for (let i = 0; i < mPositionInfo.length; i++) {
671      for (let j = mPositionInfo.length - 1; j > 0 && j > i; j--) {
672        if (mPositionInfo[i][0] == mPositionInfo[j][0] && mPositionInfo[i][1] == mPositionInfo[j][1] && mPositionInfo[i][2] == mPositionInfo[j][2]) {
673          return true;
674        }
675
676      }
677    }
678    return false;
679  }
680
681  private ifDuplicateKeyName(layoutInfo) {
682    const count = [];
683    for (let i = 0; i < layoutInfo.length; i++) {
684      if (CheckEmptyUtils.isEmpty(count[layoutInfo[i].keyName])) {
685        count[layoutInfo[i].keyName] = 0;
686      } else if (layoutInfo[i].typeId == CommonConstants.TYPE_APP) {
687        return true;
688      }
689    }
690    return false;
691  }
692
693  private updateLayoutInfo(info) {
694    let layoutInfo = info.layoutInfo;
695    this.mGridConfig = this.getGridConfig();
696    Log.showDebug(TAG, 'updateLayoutInfo mGridConfig:' + JSON.stringify(this.mGridConfig));
697    info.layoutDescription.row = this.mGridConfig.row;
698    info.layoutDescription.column = this.mGridConfig.column;
699    const newApp = [];
700    //Detect newly installed apps
701    for (const i in this.mBundleInfoList) {
702      let sign = false;
703      for (const j in layoutInfo) {
704        if (this.mBundleInfoList[i].typeId == layoutInfo[j].typeId
705        && this.mBundleInfoList[i].typeId == CommonConstants.TYPE_APP
706        && this.mBundleInfoList[i].keyName == layoutInfo[j].keyName) {
707          layoutInfo[j].badgeNumber = this.mBundleInfoList[i].badgeNumber;
708          sign = true;
709          break;
710        }
711      }
712      if (!sign) {
713        newApp.push(this.mBundleInfoList[i]);
714      }
715    }
716
717    //Detect uninstalled apps, remove all apps which have same bundleName when one app is uninstalled
718    layoutInfo = layoutInfo.filter(item => {
719      if (item.typeId == CommonConstants.TYPE_FOLDER || item.typeId == CommonConstants.TYPE_CARD) {
720        return true;
721      }
722      for (const bundleInfo of this.mBundleInfoList) {
723        if (item.keyName == bundleInfo.keyName) {
724          return true;
725        }
726      }
727      return false;
728    })
729    info.layoutInfo = layoutInfo;
730
731    // calculate the layout of new apps
732    for (let i = 0; i < newApp.length; i++) {
733      if (newApp[i].typeId == CommonConstants.TYPE_APP) {
734        this.mPageDesktopModel.updateAppItemLayoutInfo(info, newApp[i]);
735      }
736    }
737    let infoOld = this.mSettingsModel.getLayoutInfo();
738    for (const item of infoOld.layoutInfo) {
739      if (item.typeId == CommonConstants.TYPE_APP) {
740        for (const infoNew of info.layoutInfo) {
741          if (item.keyName == infoNew.keyName) {
742            infoNew.page = item.page;
743          }
744        }
745      }
746    }
747    return info;
748  }
749
750  private createNewInfo() {
751    this.mGridConfig = this.getGridConfig();
752    const column = this.mGridConfig.column;
753    const row = this.mGridConfig.row;
754    const layoutNum = this.mBundleInfoList.length;
755    const maxPerPage = column * row;
756    const pageNum = Math.ceil(layoutNum / maxPerPage);
757    const newLayoutInfo = {
758      layoutDescription: {},
759      layoutInfo: []
760    };
761    newLayoutInfo.layoutDescription = {
762      'pageCount': pageNum,
763      'row': row,
764      'column': column,
765    };
766    newLayoutInfo.layoutInfo = [];
767    return newLayoutInfo;
768  }
769
770  private createNewLayoutInfo() {
771    const info = this.mSettingsModel.getLayoutInfo();
772    this.mGridConfig = this.getGridConfig();
773    const column = this.mGridConfig.column;
774    const row = this.mGridConfig.row;
775    const layoutNum = info.layoutInfo.length;
776    const maxPerPage = column * row;
777    const pageNum = Math.ceil(layoutNum / maxPerPage);
778    const newLayoutInfo = {
779      layoutDescription: {},
780      layoutInfo: []
781    };
782    newLayoutInfo.layoutDescription = {
783      'pageCount': info.layoutDescription.pageCount,
784      'row': row,
785      'column': column
786    };
787    if (AppStorage.Has('isPortrait') && AppStorage.Get('isPortrait')) {
788      let cardInfoHorizontal: any[] = [];
789      for (let i = 0; i < info.layoutInfo.length; i++) {
790        if (info.layoutInfo[i].typeId == CommonConstants.TYPE_FOLDER) {
791          let tt = info.layoutInfo[i].column
792          info.layoutInfo[i].column = info.layoutInfo[i].row;
793          info.layoutInfo[i].row = tt;
794          newLayoutInfo.layoutInfo.push(info.layoutInfo[i]);
795        }
796      }
797
798      for (let i = 0; i < info.layoutInfo.length; i++) {
799        if (info.layoutInfo[i].typeId == CommonConstants.TYPE_CARD) {
800          if (info.layoutInfo[i].area[0] == info.layoutInfo[i].area[1]) {
801            let tt = info.layoutInfo[i].column
802            info.layoutInfo[i].column = info.layoutInfo[i].row;
803            info.layoutInfo[i].row = tt;
804            newLayoutInfo.layoutInfo.push(info.layoutInfo[i]);
805          } else {
806            cardInfoHorizontal.push(JSON.stringify(info.layoutInfo[i]));
807            this.mPageDesktopModel.updatePageDesktopLayoutInfo(newLayoutInfo, info.layoutInfo[i]);
808            newLayoutInfo.layoutInfo.push(info.layoutInfo[i]);
809          }
810        }
811      }
812      AppStorage.SetOrCreate('isPortraitCard', cardInfoHorizontal);
813    }
814
815    if (AppStorage.Has('isPortrait') && !AppStorage.Get('isPortrait')) {
816      for (let i = 0; i < info.layoutInfo.length; i++) {
817        if (info.layoutInfo[i].typeId == CommonConstants.TYPE_FOLDER) {
818          let tt = info.layoutInfo[i].column
819          info.layoutInfo[i].column = info.layoutInfo[i].row;
820          info.layoutInfo[i].row = tt;
821          newLayoutInfo.layoutInfo.push(info.layoutInfo[i]);
822        }
823      }
824
825      for (let i = 0; i < info.layoutInfo.length; i++) {
826        if (info.layoutInfo[i].typeId == CommonConstants.TYPE_CARD) {
827          if (info.layoutInfo[i].area[0] == info.layoutInfo[i].area[1]) {
828            let tt = info.layoutInfo[i].column
829            info.layoutInfo[i].column = info.layoutInfo[i].row;
830            info.layoutInfo[i].row = tt;
831            newLayoutInfo.layoutInfo.push(info.layoutInfo[i]);
832          } else {
833            let cardInfoOld: [] = AppStorage.Get('isPortraitCard');
834            Log.showInfo(TAG, 'cardInfoOld:' + JSON.stringify(cardInfoOld));
835            if (!cardInfoOld.find(item => JSON.parse(item).cardId === info.layoutInfo[i].cardId)) {
836              this.mPageDesktopModel.updatePageDesktopLayoutInfo(newLayoutInfo, info.layoutInfo[i]);
837              newLayoutInfo.layoutInfo.push(info.layoutInfo[i]);
838            }
839            for (let index = 0; index < cardInfoOld.length; index++) {
840              if (!newLayoutInfo.layoutInfo.find(item => item.cardId == JSON.parse(cardInfoOld[index]).cardId)) {
841                newLayoutInfo.layoutInfo.push(JSON.parse(cardInfoOld[index]));
842              }
843            }
844          }
845        }
846      }
847    }
848
849    if (!AppStorage.Has('isPortrait')) {
850      newLayoutInfo.layoutDescription = {
851        'pageCount': pageNum,
852        'row': row,
853        'column': column
854      };
855      newLayoutInfo.layoutInfo = [];
856    }
857
858    return newLayoutInfo;
859  }
860
861  regroupDataAppListChange(callbackList) {
862    this.getGridList();
863  }
864
865  /**
866   * Open the app.
867   *
868   * @param abilityName
869   * @param bundleName
870   */
871  openApplication(abilityName: string, bundleName: string, moduleName: string): void {
872    this.jumpTo(abilityName, bundleName, moduleName);
873  }
874
875  /**
876   * Open Settings.
877   */
878  intoSetting(): void {
879    Log.showInfo(TAG, 'intoSetting');
880    this.jumpToSetting();
881  }
882
883  /**
884   * Get strings for addBlankPageButton.
885   *
886   * @return {string} AddBlankPageButton Strings.
887   */
888  getBlankPageBtnStr() {
889    return this.isBlankPage() ? $r('app.string.delete_blank_page') : $r('app.string.add_blank_page');
890  }
891
892  /**
893   * Get strings for deleteBlankPageButton.
894   *
895   * @return {string} AddBlankPageButton Strings.
896   */
897  getBlankPageBtnIcon() {
898    return this.isBlankPage() ? '/common/pics/ic_public_delete.svg' : '/common/pics/ic_public_add_black.svg';
899  }
900
901  isBlankPage(): boolean {
902    const curPageIndex = this.mPageDesktopModel.getPageIndex();
903    // 当且仅当只有一个页面时,菜单项只允许添加
904    if (this.getGridPageCount() <= 1) {
905      return false;
906    }
907    if (CheckEmptyUtils.isEmpty(this.mGridAppsInfos) || CheckEmptyUtils.isEmpty(this.mGridAppsInfos[curPageIndex])
908    || CheckEmptyUtils.isEmpty(this.mGridAppsInfos[curPageIndex].length)) {
909      return true;
910    }
911    if (this.mGridAppsInfos[curPageIndex].length === 0) {
912      return true;
913    }
914    return false;
915  }
916
917  /**
918   * Add or delete the chosen blank page.
919   */
920  addOrDeleteBlankPage(): void {
921    if (this.isBlankPage()) {
922      this.deleteBlankPage();
923    } else {
924      this.addBlankPage(false);
925    }
926  }
927
928  /**
929   * Add a blank page.
930   *
931   * @param {boolean} isAddByDrag
932   */
933  addBlankPage(isAddByDrag: boolean): void {
934    this.mPageDesktopModel.setAddByDragging(isAddByDrag);
935    const allPageCount = this.mSettingsModel.getLayoutInfo().layoutDescription.pageCount + 1;
936    this.setGridPageCount(allPageCount);
937    this.pagingFiltering();
938    this.mPageDesktopModel.setPageIndex(allPageCount - 1);
939  }
940
941  /**
942   * Get pageCount.
943   *
944   * @return {number} PageCount.
945   */
946  /**
947   * Get pageCount.
948   *
949   * @return {number} PageCount.
950   */
951  getGridPageCount(): number {
952    return this.mSettingsModel.getLayoutInfo().layoutDescription.pageCount;
953  }
954
955  /**
956   * Set pageCount.
957   *
958   * @param {number} pageCount - PageCount.
959   */
960  private setGridPageCount(pageCount: number): void {
961    const gridLayoutInfo = this.mSettingsModel.getLayoutInfo();
962    gridLayoutInfo.layoutDescription.pageCount = pageCount;
963    this.mSettingsModel.setLayoutInfo(gridLayoutInfo);
964  }
965
966  /**
967   * Delete the chosen blank page.
968   */
969  private deleteBlankPage(): void {
970    const curPageIndex = this.mPageDesktopModel.getPageIndex();
971    this.deleteGridPage(curPageIndex);
972    if (curPageIndex === 0) {
973      this.mPageDesktopModel.setPageIndex(curPageIndex);
974    } else {
975      this.mPageDesktopModel.setPageIndex(curPageIndex - 1);
976    }
977    this.setGridPageCount(this.mSettingsModel.getLayoutInfo().layoutDescription.pageCount - 1);
978    this.pagingFiltering();
979  }
980
981  /**
982   * Delete blank page.
983   *
984   * @param {number} pageIndex - Index of the page which is to be deleted.
985   */
986  private deleteGridPage(pageIndex: number): void {
987    const info = this.mSettingsModel.getLayoutInfo();
988    const layoutInfo = info.layoutInfo;
989    for (const element of layoutInfo) {
990      if (element.page > pageIndex) {
991        element.page = element.page - 1;
992      }
993    }
994    info.layoutInfo = layoutInfo;
995    this.mSettingsModel.setLayoutInfo(info);
996  }
997
998  /**
999   * Set device type.
1000   *
1001   * @param EType: Device type
1002   */
1003  setDevice(EType): void {
1004    this.mSettingsModel.setDevice(EType);
1005    this.isPad = EType === CommonConstants.PAD_DEVICE_TYPE;
1006  }
1007
1008  /**
1009   * Get device type.
1010   */
1011  getDevice(): boolean {
1012    return this.isPad;
1013  }
1014
1015  buildMenuInfoList(appInfo, dialog, formDialog?, folderCallback?, openClickCallback?): MenuInfo[] {
1016    let menuInfoList = new Array<MenuInfo>();
1017    const shortcutInfo: any = this.mAppModel.getShortcutInfo(appInfo.bundleName);
1018    if (shortcutInfo) {
1019      let menu = null;
1020      shortcutInfo.forEach((value) => {
1021        menu = new MenuInfo();
1022        menu.menuType = CommonConstants.MENU_TYPE_DYNAMIC;
1023        menu.menuImgSrc = value.icon;
1024        menu.menuText = value.label;
1025        menu.shortcutIconId = value.iconId;
1026        menu.shortcutLabelId =  value.labelId;
1027        menu.bundleName = value.bundleName;
1028        menu.moduleName = value.moduleName;
1029        menu.onMenuClick = () => {
1030          Trace.start(Trace.CORE_METHOD_START_APP_ANIMATION);
1031          if (openClickCallback) {
1032            openClickCallback();
1033          }
1034          if (AppStorage.Get('openFolderStatus') != 0) {
1035            AppStorage.SetOrCreate('openFolderStatus', 0);
1036          }
1037          this.jumpTo(value.wants[0].targetClass, value.wants[0].targetBundle, value.wants[0].targetModule);
1038        };
1039        value.bundleName == appInfo.bundleName && value.moduleName == appInfo.moduleName && menuInfoList.push(menu);
1040      });
1041    }
1042
1043    let open = new MenuInfo();
1044    open.menuType = CommonConstants.MENU_TYPE_FIXED;
1045    open.menuImgSrc = '/common/pics/ic_public_add_norm.svg';
1046    open.menuText = $r('app.string.app_menu_open');
1047    open.onMenuClick = () => {
1048      if (AppStorage.Get('openFolderStatus') != 0 && AppStorage.Get('deviceType') === CommonConstants.PAD_DEVICE_TYPE) {
1049        AppStorage.SetOrCreate('openFolderStatus', 0);
1050      }
1051      this.setStartAppInfo()
1052      this.jumpTo(appInfo.abilityName, appInfo.bundleName, appInfo.moduleName);
1053    };
1054    menuInfoList.push(open);
1055
1056    const formInfoList = this.mFormModel.getAppItemFormInfo(appInfo.bundleName);
1057    if (!CheckEmptyUtils.isEmptyArr(formInfoList)) {
1058      let addFormToDeskTopMenu = new MenuInfo();
1059      addFormToDeskTopMenu.menuType = CommonConstants.MENU_TYPE_FIXED;
1060      addFormToDeskTopMenu.menuImgSrc = '/common/pics/ic_public_app.svg';
1061      addFormToDeskTopMenu.menuText = $r('app.string.add_form_to_desktop');
1062      addFormToDeskTopMenu.onMenuClick = () => {
1063        Log.showDebug(TAG, 'Launcher click menu item into add form to desktop view');
1064        const appName = this.getAppName(appInfo.appLabelId + appInfo.bundleName + appInfo.moduleName);
1065        if (appName != null) {
1066          appInfo.appName = appName;
1067        }
1068        AppStorage.SetOrCreate('formAppInfo', appInfo);
1069        if (!this.isPad) {
1070          this.showFormManager(appInfo);
1071        } else {
1072          formDialog.open();
1073        }
1074      };
1075      menuInfoList.push(addFormToDeskTopMenu);
1076    }
1077
1078    if (this.isPad) {
1079      const addToDockMenu = new MenuInfo();
1080      addToDockMenu.menuType = CommonConstants.MENU_TYPE_FIXED;
1081      addToDockMenu.menuImgSrc = '/common/pics/ic_public_copy.svg';
1082      addToDockMenu.menuText = $r('app.string.app_center_menu_add_dock');
1083      addToDockMenu.onMenuClick = () => {
1084        Log.showDebug(TAG, 'Launcher click menu item add to dock');
1085        const appName = this.getAppName(appInfo.appLabelId + appInfo.bundleName + appInfo.moduleName);
1086        if (appName != null) {
1087          appInfo.appName = appName;
1088        }
1089        this.addToDock(appInfo);
1090      };
1091      menuInfoList.push(addToDockMenu);
1092    }
1093
1094    if (folderCallback) {
1095      const moveOutMenu = new MenuInfo();
1096      moveOutMenu.menuType = CommonConstants.MENU_TYPE_FIXED;
1097      moveOutMenu.menuImgSrc = '/common/pics/ic_public_remove.svg';
1098      moveOutMenu.menuText = $r('app.string.remove_app_from_folder');
1099      moveOutMenu.onMenuClick = () => {
1100        Log.showDebug(TAG, 'Launcher click menu item remove app from folder');
1101        // remove app from folder
1102        folderCallback(appInfo);
1103      };
1104      menuInfoList.push(moveOutMenu);
1105    }
1106
1107    const uninstallMenu = new MenuInfo();
1108    uninstallMenu.menuType = CommonConstants.MENU_TYPE_FIXED;
1109    uninstallMenu.menuImgSrc = this.isPad ? '/common/pics/ic_public_remove.svg' : '/common/pics/ic_public_delete.svg';
1110    uninstallMenu.menuText = this.isPad ?  $r('app.string.delete_app') : $r('app.string.uninstall');
1111    uninstallMenu.onMenuClick = () => {
1112      Log.showDebug(TAG, 'Launcher click menu item uninstall');
1113      const appName = this.getAppName(appInfo.appLabelId + appInfo.bundleName + appInfo.moduleName);
1114      if (appName != null) {
1115        appInfo.appName = appName;
1116      }
1117      AppStorage.SetOrCreate('uninstallAppInfo', appInfo);
1118      dialog.open();
1119    };
1120    uninstallMenu.menuEnabled = appInfo.isUninstallAble;
1121    menuInfoList.push(uninstallMenu);
1122    return menuInfoList;
1123  }
1124
1125  buildCardMenuInfoList(formInfo, dialog, formDialog): MenuInfo[] {
1126    const menuInfoList = new Array<MenuInfo>();
1127    if (!this.ifStringIsNull(formInfo.formConfigAbility)
1128    && formInfo.formConfigAbility.startsWith(CommonConstants.FORM_CONFIG_ABILITY_PREFIX, 0)) {
1129      const editForm = new MenuInfo();
1130      editForm.menuType = CommonConstants.MENU_TYPE_FIXED;
1131      editForm.menuImgSrc = '/common/pics/ic_public_edit.svg';
1132      editForm.menuText = $r('app.string.form_edit');
1133      editForm.onMenuClick = () => {
1134        Log.showDebug(TAG, `Launcher click menu item into form edit view:${formInfo.formConfigAbility}`);
1135        const abilityName = formInfo.formConfigAbility.slice(CommonConstants.FORM_CONFIG_ABILITY_PREFIX.length);
1136        this.jumpToForm(abilityName, formInfo.bundleName, formInfo.moduleName, formInfo.cardId);
1137      };
1138      menuInfoList.push(editForm);
1139    }
1140    const addFormToDeskTopMenu = new MenuInfo();
1141    addFormToDeskTopMenu.menuType = CommonConstants.MENU_TYPE_FIXED;
1142    addFormToDeskTopMenu.menuImgSrc = '/common/pics/ic_public_app.svg';
1143    addFormToDeskTopMenu.menuText = $r('app.string.add_form_to_desktop');
1144    addFormToDeskTopMenu.onMenuClick = () => {
1145      Log.showDebug(TAG, 'Launcher click menu item into add form to desktop view');
1146      const appName = this.getAppName(formInfo.appLabelId + formInfo.bundleName + formInfo.moduleName);
1147      if (appName != null) {
1148        formInfo.appName = appName;
1149      }
1150      AppStorage.SetOrCreate('formAppInfo', formInfo);
1151      if (!this.isPad) {
1152        this.showFormManager(formInfo);
1153      } else {
1154        formDialog.open();
1155      }
1156    };
1157    menuInfoList.push(addFormToDeskTopMenu);
1158    const deleteFormFromDeskTop = new MenuInfo();
1159    deleteFormFromDeskTop.menuType = CommonConstants.MENU_TYPE_FIXED;
1160    deleteFormFromDeskTop.menuImgSrc = '/common/pics/ic_public_remove.svg';
1161    deleteFormFromDeskTop.menuText = $r('app.string.delete_form');
1162    deleteFormFromDeskTop.onMenuClick = () => {
1163      Log.showDebug(TAG, 'Launcher click menu item remove form to desktop view');
1164      const formAnimateData: {
1165        cardId: number,
1166        isOpenRemoveFormDialog: boolean,
1167      } = { cardId: formInfo.cardId, isOpenRemoveFormDialog: true };
1168      AppStorage.SetOrCreate('formAnimateData', formAnimateData);
1169      dialog.open();
1170    };
1171    menuInfoList.push(deleteFormFromDeskTop);
1172    return menuInfoList;
1173  }
1174
1175  buildRenameMenuInfoList(folderItemInfo, menuCallback): MenuInfo[] {
1176    const menuInfoList = new Array<MenuInfo>();
1177    const renameMenu = new MenuInfo();
1178    renameMenu.menuType = CommonConstants.MENU_TYPE_DYNAMIC;
1179    renameMenu.menuImgSrc = StyleConstants.DEFAULT_RENAME_IMAGE;
1180    renameMenu.menuText = $r('app.string.rename_folder');
1181    renameMenu.onMenuClick = () => {
1182      Log.showDebug(TAG, 'Launcher click menu to rename');
1183      menuCallback();
1184    };
1185    menuInfoList.push(renameMenu);
1186    return menuInfoList;
1187  }
1188
1189  /**
1190   * Get PageDesktopStyleConfig.
1191   */
1192  getPageDesktopStyleConfig() {
1193    return this.pageDesktopStyleConfig;
1194  }
1195
1196  /**
1197   * Get workSpaceWidth.
1198   */
1199  getWorkSpaceWidth() {
1200    return AppStorage.Get('workSpaceWidth');
1201  }
1202
1203  /**
1204   * Get workSpaceHeight.
1205   */
1206  getWorkSpaceHeight() {
1207    return AppStorage.Get('workSpaceHeight');
1208  }
1209
1210  /**
1211   * Get getAppPageStartConfig.
1212   */
1213  getAppPageStartConfig() {
1214    return this.mSettingsModel.getAppPageStartConfig();
1215  }
1216
1217  /**
1218   * click event
1219   *
1220   * @param abilityName ability name
1221   * @param bundleName bundle name
1222   */
1223  onAppClick(abilityName: string, bundleName: string, moduleName: string) {
1224    if (!this.isPad) {
1225      this.jumpTo(abilityName, bundleName, moduleName);
1226      return;
1227    }
1228    Log.showDebug(TAG, `onAppClick keyName ${bundleName + abilityName + moduleName}`);
1229    AppStorage.SetOrCreate('selectDesktopAppItem', bundleName + abilityName + moduleName);
1230  }
1231
1232  /**
1233   * double click event
1234   *
1235   * @param abilityName ability name
1236   * @param bundleName bundle name
1237   */
1238  onAppDoubleClick(abilityName: string, bundleName: string, moduleName: string): void {
1239    AppStorage.SetOrCreate('selectDesktopAppItem', '');
1240    this.jumpTo(abilityName, bundleName, moduleName);
1241  }
1242
1243  /**
1244   * other app publish card to pageDesktop
1245   *
1246   * @param parameters
1247   */
1248  async publishCardToDesktop(parameters:any) {
1249    Log.showDebug(TAG, 'publishCardToDesktop');
1250    const formItem = await FormManager.getInstance().getFormCardItemByWant(parameters);
1251    localEventManager.sendLocalEventSticky(EventConstants.EVENT_REQUEST_PAGEDESK_FORM_ITEM_ADD, formItem);
1252  }
1253
1254  /**
1255   * add card to pageDesktop
1256   *
1257   * @param appInfo
1258   */
1259  async createCardToDeskTop(formCardItem) {
1260    Log.showDebug(TAG, `createCardToDeskTop formCardItem id: ${formCardItem.id}`);
1261    const cardItemInfo = this.createNewCardItemInfo(formCardItem);
1262
1263    let formInfoList: any = this.mFormListInfoCacheManager.getCache(KEY_FORM_LIST);
1264    if (formInfoList == CommonConstants.INVALID_VALUE) {
1265      formInfoList = new Array<CardItemInfo>();
1266    }
1267    formInfoList.push(cardItemInfo);
1268    this.mFormListInfoCacheManager.setCache(KEY_FORM_LIST, formInfoList);
1269
1270    const result = await this.mFormModel.updateFormInfoById(cardItemInfo);
1271    if (result) {
1272      const gridLayoutInfo = this.mSettingsModel.getLayoutInfo();
1273      const cardItemLayoutInfo = {
1274        cardId: cardItemInfo.cardId,
1275        typeId: CommonConstants.TYPE_CARD,
1276        area: FormManager.getInstance().getCardSize(cardItemInfo.cardDimension),
1277        page: 0,
1278        row: 0,
1279        column: 0
1280      };
1281
1282      const needNewPage: boolean =this.mPageDesktopModel.updatePageDesktopLayoutInfo(gridLayoutInfo, cardItemLayoutInfo);
1283      const curPageIndex = this.mPageDesktopModel.getPageIndex();
1284      if (needNewPage) {
1285        gridLayoutInfo.layoutDescription.pageCount = gridLayoutInfo.layoutDescription.pageCount + 1;
1286        for (let index = 0; index < gridLayoutInfo.layoutInfo.length; index++) {
1287          if (gridLayoutInfo.layoutInfo[index].page > curPageIndex) {
1288            gridLayoutInfo.layoutInfo[index].page++;
1289          }
1290        }
1291      }
1292
1293      // Push card into the layoutInfo
1294      gridLayoutInfo.layoutInfo.push(cardItemLayoutInfo);
1295      this.mSettingsModel.setLayoutInfo(gridLayoutInfo);
1296      if (needNewPage) {
1297        this.mPageDesktopModel.setPageIndex(curPageIndex + 1);
1298      }
1299    }
1300    this.getGridList();
1301  }
1302
1303  /**
1304   * create new cardItemInfo by formItemInfo
1305   *
1306   * @param formCardItem
1307   */
1308  private createNewCardItemInfo(formCardItem): CardItemInfo {
1309    const cardItemInfo = new CardItemInfo();
1310    cardItemInfo.cardId = formCardItem.id;
1311    cardItemInfo.cardName = formCardItem.name;
1312    cardItemInfo.bundleName = formCardItem.bundleName;
1313    cardItemInfo.abilityName = formCardItem.abilityName;
1314    cardItemInfo.moduleName = formCardItem.moduleName;
1315    cardItemInfo.formConfigAbility = formCardItem.formConfigAbility;
1316    cardItemInfo.appLabelId = formCardItem.appLabelId;
1317    cardItemInfo.cardDimension = formCardItem.dimension;
1318    return cardItemInfo;
1319  }
1320
1321  private ifStringIsNull(str): boolean {
1322    if (str == undefined || str == '' || str == null) {
1323      return true;
1324    }
1325    return false;
1326  }
1327
1328  private addNewInstalledInfo(totalAppInfoList, pageDesktopInfo): void {
1329    for (const i in totalAppInfoList) {
1330      let hasInstalled = false;
1331      for (const j in pageDesktopInfo) {
1332        if (totalAppInfoList[i].keyName == pageDesktopInfo[j].keyName) {
1333          hasInstalled = true;
1334          break;
1335        }
1336      }
1337      if (!hasInstalled) {
1338        pageDesktopInfo.push(totalAppInfoList[i]);
1339      }
1340    }
1341  }
1342
1343  private removeBottomBarInfo(pageDesktopInfo) {
1344    let bottomAppList = [];
1345    bottomAppList = AppStorage.Get('residentList');
1346    Log.showDebug(TAG, `removeBottomBarInfo bottomAppList length: ${bottomAppList.length}`);
1347    if (!CheckEmptyUtils.isEmptyArr(bottomAppList)) {
1348      for (let i = 0; i < bottomAppList.length; i++) {
1349        Log.showDebug(TAG, `removeBottomBarInfo bottomAppList[${i}]: ${JSON.stringify(bottomAppList[i])}`);
1350        const appInfo = pageDesktopInfo.find(item => {
1351          if (item.keyName == bottomAppList[i].keyName) {
1352            return true;
1353          }
1354        });
1355        if (!this.ifInfoIsNull(appInfo)) {
1356          const index = pageDesktopInfo.indexOf(appInfo);
1357          pageDesktopInfo.splice(index, 1);
1358        }
1359      }
1360    }
1361  }
1362
1363  private removeFolderInfo(pageDesktopInfo): void {
1364    const gridLayoutInfo = this.mSettingsModel.getLayoutInfo();
1365    const layoutInfo = gridLayoutInfo.layoutInfo;
1366    for (let i = 0; i < layoutInfo.length; i++) {
1367      if (layoutInfo[i].typeId == CommonConstants.TYPE_FOLDER) {
1368        for (let j = 0; j < layoutInfo[i].layoutInfo.length; j++) {
1369          for (let k = 0; k < layoutInfo[i].layoutInfo[j].length; k++) {
1370            const appInfo = pageDesktopInfo.find(item => {
1371              if (item.keyName == layoutInfo[i].layoutInfo[j][k].keyName) {
1372                return true;
1373              }
1374            });
1375            if (!this.ifInfoIsNull(appInfo)) {
1376              const index = pageDesktopInfo.indexOf(appInfo);
1377              pageDesktopInfo.splice(index, 1);
1378              Log.showDebug(TAG, `removeFolderInfo keyName: ${appInfo.keyName}`);
1379            }
1380          }
1381        }
1382      }
1383    }
1384  }
1385
1386  /**
1387   * set start app info
1388   */
1389  private setStartAppInfo() {
1390    AppStorage.SetOrCreate('startAppIconInfo', {
1391      appIconSize: 0,
1392      appIconHeight: 0,
1393      appIconPositionX: 0,
1394      appIconPositionY: 0
1395    });
1396  }
1397}