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