• 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 { Log } from '../utils/Log';
17import { EventConstants } from '../constants/EventConstants';
18import { CommonConstants } from '../constants/CommonConstants';
19import { CardItemInfo } from '../bean/CardItemInfo';
20import { SettingsModel } from './SettingsModel';
21import { FormManager } from '../manager/FormManager';
22import { RdbStoreManager } from '../manager/RdbStoreManager';
23import { FormListInfoCacheManager } from '../cache/FormListInfoCacheManager';
24import {PageDesktopModel} from './PageDesktopModel';
25import { GridLayoutInfo } from '../interface';
26
27
28const TAG = 'FormModel';
29
30/**
31 * form model.
32 */
33export class FormModel {
34  private readonly mRdbStoreManager: RdbStoreManager;
35  private readonly mFormManager: FormManager;
36  private readonly mFormListInfoCacheManager: FormListInfoCacheManager;
37  private readonly mAppItemFormInfoMap = new Map<string, CardItemInfo[]>();
38  private readonly mPageDesktopModel: PageDesktopModel;
39  private readonly mAtomicServiceAppItemFormInfoMap = new Map<string, CardItemInfo[]>();
40  private readonly KEY_FORM_LIST: string = 'formListInfo';
41
42  private constructor() {
43    this.mRdbStoreManager = RdbStoreManager.getInstance();
44    this.mFormManager = FormManager.getInstance();
45    this.mFormListInfoCacheManager = FormListInfoCacheManager.getInstance();
46    this.mPageDesktopModel = PageDesktopModel.getInstance();
47  }
48
49  /**
50   * Get the form model object.
51   *
52   * @return {object} form model singleton
53   */
54  static getInstance(): FormModel {
55    if (globalThis.FormModelInstance == null) {
56      globalThis.FormModelInstance = new FormModel();
57    }
58    return globalThis.FormModelInstance;
59  }
60
61  /**
62   * Get the form info list of all ohos applications on the device.
63   *
64   * @return {array} allFormList
65   */
66  async getAllFormsInfo() {
67    Log.showDebug(TAG, 'getAllFormsInfo start');
68    const allFormList = await this.mFormManager.getAllFormsInfo();
69    return allFormList;
70  }
71
72  getAllAppItemFormInfoMap(): Map<string, CardItemInfo[]> {
73    return this.mAppItemFormInfoMap;
74  }
75
76  /**
77   * Get the form info list of all ohos applications on the device by bundle name.
78   *
79   * @param {array} bundleName
80   * @param {function | undefined} callback
81   *
82   * @return {array} currentBundleFormsInfo
83   */
84  async getFormsInfoByBundleName(bundleName: string, callback?) {
85    Log.showDebug(TAG, `getFormsInfoByBundleName bundleName: ${bundleName}`);
86    let currentBundleFormsInfo: any;
87    await this.mFormManager.getFormsInfoByApp(bundleName)
88      .then(bundleFormsInfo => {
89        currentBundleFormsInfo = bundleFormsInfo;
90        if (callback != undefined) {
91          callback(bundleName, bundleFormsInfo);
92        }
93      })
94      .catch(err => {
95        Log.showError(TAG, `getFormsInfoByBundleName err: ${JSON.stringify(err)}`);
96      });
97    AppStorage.setOrCreate('formMgrItem', currentBundleFormsInfo);
98    return currentBundleFormsInfo;
99  }
100
101  /**
102   * Get the form info list of all ohos applications on the device by module name.
103   *
104   * @param {string} bundleName
105   * @param {string} moduleName
106   *
107   * @return {array} currentModuleFormsInfo
108   */
109  async getFormsInfoByModuleName(bundleName: string, moduleName: string) {
110    Log.showDebug(TAG, `getFormsInfoByModuleName bundleName: ${bundleName}, moduleName: ${moduleName}`);
111    const currentModuleFormsInfo = await this.mFormManager.getFormsInfoByModule(bundleName, moduleName);
112    return currentModuleFormsInfo;
113  }
114
115  /**
116   * Get the form info list from rdb.
117   *
118   * @return {array} allFormList
119   */
120  async getAllFormsInfoFromRdb() {
121    Log.showDebug(TAG, 'getAllFormsInfoFromRdb start');
122    const allFormList = await this.mRdbStoreManager.getAllFormInfos();
123    return allFormList;
124  }
125
126  /**
127   * Update the form info in rdb by id.
128   *
129   * @param {object} cardItemInfo
130   *
131   * @return {boolean} result
132   */
133  async updateFormInfoById(cardItemInfo) {
134    return await this.mRdbStoreManager.updateFormInfoById(cardItemInfo);
135  }
136
137  /**
138   * Delete form in rdb and fms by id.
139   *
140   * @param {number} cardId
141   */
142  async deleteFormById(cardId: number): Promise<boolean> {
143    try{
144      await this.mRdbStoreManager.deleteFormInfoById(cardId);
145      await this.mFormManager.deleteCard(cardId.toString());
146    } catch(error){
147      Log.showError(TAG, `deleteFormById err: ${JSON.stringify(error)}`);
148      return false;
149    }
150    return true;
151
152  }
153
154  /**
155   * Delete form in fms by formId.
156   *
157   * @param {number} formId
158   */
159  deleteFormByFormID(formId: number) {
160    this.mFormManager.deleteCard(formId.toString());
161  }
162
163  /**
164   * Set app item form info into map.
165   *
166   * @param {string} bundleName
167   * @param {array} appItemFormInfo
168   */
169  setAppItemFormInfo(bundleName: string, appItemFormInfo: CardItemInfo[]): void {
170    this.mAppItemFormInfoMap.set(bundleName, appItemFormInfo);
171  }
172
173  /**
174   * Get app item form info from map.
175   *
176   * @param {string} bundleName
177   *
178   * @return {array | undefined} mAppItemFormInfoMap
179   */
180  getAppItemFormInfo(bundleName: string, moduleName?: string): CardItemInfo[] | undefined {
181    Log.showDebug(TAG, `getAppItemFormInfo bundleName: ${bundleName},
182      appItemFormInfo: ${JSON.stringify(this.mAppItemFormInfoMap.get(bundleName))}`);
183    let formList = this.mAppItemFormInfoMap.get(bundleName);
184    if (formList && formList.length && moduleName) {
185      formList = formList.filter(item => item.moduleName === moduleName);
186    }
187    return formList;
188  }
189
190  /**
191   * Update app item form info into map.
192   *
193   * @param {string} bundleName
194   * @param {string | undefined} eventType
195   */
196  async updateAppItemFormInfo(bundleName: string, eventType?: string): Promise<void> {
197    if (eventType && eventType === EventConstants.EVENT_PACKAGE_REMOVED) {
198      this.mAppItemFormInfoMap.delete(bundleName);
199      return;
200    }
201    const formsInfoList = this.getFormsInfoByBundleName(bundleName, this.setAppItemFormInfo.bind(this));
202  }
203
204  /**
205   * Delete form by bundleName and update layout info.
206   *
207   * @param {string} bundleName
208   */
209  deleteFormByBundleName(bundleName: string): void {
210    const settingsModel = SettingsModel.getInstance();
211    this.mRdbStoreManager.deleteFormInfoByBundle(bundleName);
212    const formInfoList: any = this.mFormListInfoCacheManager.getCache(this.KEY_FORM_LIST);
213    if (formInfoList === CommonConstants.INVALID_VALUE) {
214      return;
215    }
216    const layoutInfo = settingsModel.getLayoutInfo();
217    const tempFormInfoList = JSON.parse(JSON.stringify(formInfoList));
218    const pageItemMap = new Map<string, number>();
219    for (let i = 0; i < layoutInfo.layoutInfo.length; i++) {
220      const tmpPage = layoutInfo.layoutInfo[i].page.toString();
221      if (pageItemMap.has(tmpPage)) {
222        pageItemMap.set(tmpPage, pageItemMap.get(tmpPage) + 1);
223      } else {
224        pageItemMap.set(tmpPage, 1);
225      }
226    }
227    for(let i = formInfoList.length - 1; i >= 0; i--) {
228      const formInfo = formInfoList[i];
229      if (formInfo.bundleName === bundleName) {
230        tempFormInfoList.splice(i, 1);
231        for(let j = layoutInfo.layoutInfo.length - 1; j >= 0; j--) {
232          if (layoutInfo.layoutInfo[j].typeId === CommonConstants.TYPE_CARD && formInfo.cardId == layoutInfo.layoutInfo[j].cardId) {
233            const tmpPage = layoutInfo.layoutInfo[j].page.toString();
234            pageItemMap.set(tmpPage, pageItemMap.get(tmpPage) - 1);
235            layoutInfo.layoutInfo.splice(j, 1);
236            break;
237          }
238        }
239      }
240    }
241    if (tempFormInfoList.length === 0) {
242      this.mFormListInfoCacheManager.setCache(this.KEY_FORM_LIST, null);
243    } else {
244      this.mFormListInfoCacheManager.setCache(this.KEY_FORM_LIST, tempFormInfoList);
245    }
246
247    this.updateBlankPage(pageItemMap, layoutInfo);
248    settingsModel.setLayoutInfo(layoutInfo);
249  }
250
251  /**
252   * Delete form by cardId.
253   *
254   * @param {number} cardId.
255   */
256  async deleteForm(cardId) {
257    Log.showDebug(TAG, 'deleteForm start');
258    let gridLayoutInfo: GridLayoutInfo = {
259      layoutDescription: undefined,
260      layoutInfo: []
261    };
262    gridLayoutInfo = SettingsModel.getInstance().getLayoutInfo();
263    const cardIndex = gridLayoutInfo.layoutInfo.findIndex(item => {
264      return item.typeId === CommonConstants.TYPE_CARD && item.cardId === cardId;
265    });
266    if (cardIndex != CommonConstants.INVALID_VALUE) {
267      this.deleteFormById(cardId);
268      const page = gridLayoutInfo.layoutInfo[cardIndex].page;
269      gridLayoutInfo.layoutInfo.splice(cardIndex, 1);
270      let ret: boolean = this.mPageDesktopModel.deleteBlankPageFromLayoutInfo(gridLayoutInfo, page);
271      SettingsModel.getInstance().setLayoutInfo(gridLayoutInfo);
272      if(ret){
273        const curPageIndex = this.mPageDesktopModel.getPageIndex();
274        Log.showInfo(TAG, 'deleteForm' + curPageIndex);
275        this.mPageDesktopModel.setPageIndex(curPageIndex - 1);
276      }
277    }
278    const formInfoList: any = this.mFormListInfoCacheManager.getCache(this.KEY_FORM_LIST);
279    if (formInfoList === CommonConstants.INVALID_VALUE) {
280      return;
281    }
282    for(let i = 0; i < formInfoList.length; i++) {
283      if (formInfoList[i].cardId === cardId){
284        formInfoList.splice(i, 1);
285        break;
286      }
287    }
288    if (formInfoList.length === 0) {
289      this.mFormListInfoCacheManager.setCache(this.KEY_FORM_LIST, null);
290    } else {
291      this.mFormListInfoCacheManager.setCache(this.KEY_FORM_LIST, formInfoList);
292    }
293  }
294
295  /**
296   * update page number if blank page is exist
297   *
298   * @param pageItemMap
299   * @param layoutInfo
300   */
301  private updateBlankPage(pageItemMap, layoutInfo): void {
302    const blankPages = [];
303    for (let [page, count] of pageItemMap) {
304      if (count === 0) {
305        layoutInfo.layoutDescription.pageCount--;
306        blankPages.push(page);
307      }
308    }
309    for (let m = 0; m < layoutInfo.layoutInfo.length; m++) {
310      let pageMinus = 0;
311      for (let n = 0; n < blankPages.length; n++) {
312        if (layoutInfo.layoutInfo[m].page > blankPages[n]) {
313          pageMinus++;
314        }
315      }
316      if (pageMinus != 0) {
317        layoutInfo.layoutInfo[m].page = layoutInfo.layoutInfo[m].page - pageMinus;
318      }
319    }
320  }
321
322  private setAtomicServiceAppItemFormInfo(bundleName: string, appItemFormInfo: CardItemInfo[]): void {
323    this.mAtomicServiceAppItemFormInfoMap.set(bundleName, appItemFormInfo);
324  }
325
326  /**
327   * 获取所有原服务app 卡片信息
328   *
329   * @returns {Map<string, CardItemInfo[]>} mAtomicServiceAppItemFormInfoMap
330   */
331  getAllAtomicServiceAppItemFormInfoMap(): Map<string, CardItemInfo[]> {
332    return this.mAtomicServiceAppItemFormInfoMap;
333  }
334
335  /**
336   * 先从缓存中获取原服务卡片信息,没有的话,再从卡片管理器获取
337   *
338   * @param bundleName bundleName
339   * @returns {Promise<CardItemInfo[]>}
340   */
341  async getAtomicServiceFormsInfoFromMapAndManager(bundleName: string): Promise<CardItemInfo[]> {
342    let cardInfo: CardItemInfo[] = this.mAtomicServiceAppItemFormInfoMap.get(bundleName);
343    if (typeof cardInfo === 'undefined') {
344      return this.mFormManager.getFormsInfoByApp(bundleName)
345        .then(bundleFormsInfo => {
346          Log.showInfo(TAG, `getAtomicServiceFormsInfoFromMapAndManager bundleFormsInfo: ${JSON.stringify(bundleFormsInfo)}`);
347          return bundleFormsInfo;
348        })
349        .catch(err => {
350          Log.showError(TAG, `getAtomicServiceFormsInfoFromMapAndManager err: ${JSON.stringify(err)}`);
351          return [];
352        });
353    }
354    return cardInfo;
355  }
356
357  /**
358   * 更新原服务应用的卡片信息
359   *
360   * @param bundleName {string} bundleName
361   * @param eventType {string | undefined} eventType
362   * @returns {Promise<void>}
363   */
364  async updateAtomicServiceAppItemFormInfo(bundleName: string, eventType?: string): Promise<void> {
365    if (eventType && eventType === EventConstants.EVENT_PACKAGE_REMOVED) {
366      this.mAtomicServiceAppItemFormInfoMap.delete(bundleName);
367      return;
368    }
369    await this.getFormsInfoByBundleName(bundleName, this.setAtomicServiceAppItemFormInfo.bind(this));
370  }
371
372  /**
373   * 从缓存中获取原服务app 卡片信息
374   *
375   * @param bundleName bundleName
376   * @returns CardItemInfo[]
377   */
378  getAtomicServiceAppItemFormInfo(bundleName: string): CardItemInfo[] | undefined {
379    Log.showInfo(TAG, `getAtomicServiceAppItemFormInfo bundleName: ${bundleName}, ` +
380      `appItemFormInfo: ${JSON.stringify(this.mAtomicServiceAppItemFormInfoMap.get(bundleName))}`);
381    return this.mAtomicServiceAppItemFormInfoMap.get(bundleName);
382  }
383
384  /**
385   * 删除原服务卡片信息
386   *
387   * @param bundleName 包名
388   */
389  deleteAtomicServiceAppItemFormInfo(bundleName: string): void {
390    this.mAtomicServiceAppItemFormInfoMap.delete(bundleName);
391  }
392
393  getRealForm(cardItemInfos: CardItemInfo[]): CardItemInfo[] {
394    if (cardItemInfos.length <= 0) {
395      return null;
396    }
397    let result: CardItemInfo[] = [];
398    for (let j: number = 0; j < cardItemInfos.length; j++) {
399      let dimensions: number[] = cardItemInfos[j].supportDimensions;
400      for (let i: number = 0; i < dimensions.length; i++) {
401        const tempCard = new CardItemInfo();
402        this.copyCardItemInfo(tempCard, cardItemInfos[j]);
403        let tempDimensions: number[] = [];
404        tempDimensions.push(dimensions[i]);
405        tempCard.supportDimensions = tempDimensions;
406        tempCard.cardDimension = dimensions[i];
407        result.push(tempCard);
408      }
409    }
410    return result;
411  }
412
413  copyCardItemInfo(newCard: CardItemInfo, oldCard: CardItemInfo): void {
414    newCard.description = oldCard.description;
415    newCard.bundleName = oldCard.bundleName;
416    newCard.abilityName = oldCard.abilityName;
417    newCard.moduleName = oldCard.moduleName;
418    newCard.cardName = oldCard.cardName;
419    newCard.area = oldCard.area;
420    newCard.formConfigAbility = oldCard.formConfigAbility;
421  }
422
423  async getFullFormsInfoByBundleName(bundleName: string, callback?): Promise<CardItemInfo[]> {
424    let currentBundleFormsInfo: CardItemInfo[] = [];
425    currentBundleFormsInfo = await this.getFormsInfoByBundleName(bundleName, callback);
426    currentBundleFormsInfo = this.getRealForm(currentBundleFormsInfo);
427    AppStorage.setOrCreate('formMgrItem', currentBundleFormsInfo);
428    return currentBundleFormsInfo;
429  }
430
431  async doBeforeJumpToFormManager(formBundleName : string): Promise<void> {
432    const formItem = await this.getFullFormsInfoByBundleName(formBundleName);
433    AppStorage.setOrCreate('formItem', formItem);
434  }
435}