1/*
2 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import Log from '../utils/log';
17import router from '@system.router';
18import Config from '../config/config';
19import UserIdmModel from '../model/userIdmModel';
20
21class CommonController {
22  private readonly TAG: string = 'CommonController';
23
24  async routeBack(): Promise<void> {
25    Log.info(this.TAG, 'router getLength: ' + router.getLength());
26    if (parseInt(router.getLength()) > 1) {
27      Log.info(this.TAG, 'router back: back+');
28      router.back();
29      Log.info(this.TAG, 'router back: back-');
30    } else {
31      Log.info(this.TAG, 'router back: terminate ability+');
32      this.terminateAbility();
33      Log.info(this.TAG, 'router back: terminate ability-');
34    }
35  }
36
37  async terminateAbility(): Promise<void> {
38    Log.info(this.TAG, 'terminate ability+');
39    UserIdmModel.destroy();
40    globalThis.abilityContext.terminateSelf()
41      .then(data => Log.info(this.TAG, 'terminateSelf promise then ' + data))
42      .catch(error => Log.error(this.TAG, 'terminateSelf promise catch ' + error));
43    Log.info(this.TAG, 'terminate ability-');
44  }
45
46  async sleepMS(ms): Promise<void> {
47    return new Promise(resolve => setTimeout(resolve, ms));
48  }
49
50  getDialogAlignment():DialogAlignment {
51    if (Config.getDeviceType() === 'phone') {
52      return DialogAlignment.Bottom;
53    } else {
54      return DialogAlignment.Center;
55    }
56  }
57
58  getDialogYOffset():string {
59    if (Config.getDeviceType() === 'phone') {
60      return '-12vp';
61    } else {
62      return '0vp';
63    }
64  }
65
66  getShelterHeightPercentageBegin(width: number, height: number) :string {
67    const HALF = 0.5;
68    let a = width * HALF;
69    let b = height * HALF;
70    let R = Math.sqrt(a * a + b * b);
71    const R_H_RATIO = 0.3;
72    let H = R / R_H_RATIO;
73    const H_WEIGHT = 166;
74    let hPercentage = '' + Math.trunc(H * H_WEIGHT / height) + '%';
75    return hPercentage;
76  }
77
78  setNonAppBarDisplaySize(nonAppBarDisplayWidth: number, nonAppBarDisplayHeight: number): void {
79    const HALF = 0.5;
80    if (Config.getDeviceType() !== 'phone') {
81      return;
82    }
83    nonAppBarDisplayHeight = nonAppBarDisplayHeight + AppStorage.Get<number>('SYSTEM_NAVIGATION_BAR_HEIGHT');
84    Log.info(this.TAG, 'update nonAppBarDisplayHeight to ' + nonAppBarDisplayHeight);
85    let sideLength = Math.floor(nonAppBarDisplayHeight * HALF);
86    AppStorage.SetOrCreate('enrollImageHeight', sideLength);
87    AppStorage.SetOrCreate('enrollImageWidth', nonAppBarDisplayWidth);
88    // when percentage is 166%, circular diameter == height
89    AppStorage.SetOrCreate('stackShelterHeightBegin',
90      this.getShelterHeightPercentageBegin(nonAppBarDisplayWidth, nonAppBarDisplayHeight * HALF));
91    AppStorage.SetOrCreate('stackShelterHeightEnd', '132.8%'); // 166 * 0.8
92    const STACK_SHELTER_HEIGHT_END_RATIO = 1.328;
93    const SCALE = 0.6;
94    const STACKRINGRADIUS_OFFSET = 21;
95    AppStorage.SetOrCreate('stackRingRadius', (sideLength * STACK_SHELTER_HEIGHT_END_RATIO * SCALE +
96      STACKRINGRADIUS_OFFSET) * HALF);
97  }
98
99  setDisplaySize(displayWidth: number, displayHeight: number): void {
100    this.setGridWidth(displayWidth);
101    if (Config.getDeviceType() !== 'tablet') {
102      return;
103    }
104    displayHeight = displayHeight + AppStorage.Get<number>('SYSTEM_NAVIGATION_BAR_HEIGHT') +
105      AppStorage.Get<number>('SYSTEM_STATUS_BAR_HEIGHT');
106    Log.info(this.TAG, 'update displayHeight to ' + displayHeight);
107    const HALF = 0.5;
108    const DISPLAY_SIDE_LENGTH_RATIO = 0.8;
109    let sideLength = Math.floor(Math.min(displayWidth, displayHeight * HALF) * DISPLAY_SIDE_LENGTH_RATIO * HALF) / HALF;
110    Log.info(this.TAG, 'sideLength ' + sideLength);
111    AppStorage.SetOrCreate('enrollImageHeight', sideLength);
112    AppStorage.SetOrCreate('enrollImageWidth', sideLength);
113    // when percentage is 166%, circular diameter == height
114    AppStorage.SetOrCreate('stackShelterHeightBegin',
115      this.getShelterHeightPercentageBegin(sideLength, sideLength));
116    AppStorage.SetOrCreate('stackShelterHeightEnd', '146%'); // 166 * 0.88
117    const STACK_SHELTER_HEIGHT_END_RATIO = 1.46;
118    const SCALE = 0.6;
119    const STACKRINGRADIUS_OFFSET = 21;
120    AppStorage.SetOrCreate('stackRingRadius', Math.floor((sideLength * STACK_SHELTER_HEIGHT_END_RATIO * SCALE +
121      STACKRINGRADIUS_OFFSET) * HALF));
122  }
123
124  setGridWidth(displayWidth: number): void {
125    if (Config.getDeviceType() === 'tablet') {
126      this.setGridWidthForTablet(displayWidth);
127      return;
128    }
129    this.setGridWidthForPhone(displayWidth);
130  }
131
132  setGridWidthForTablet(displayWidth: number): void {
133    const COLUMN_NUM = 12;
134    const MARGIN = 24;
135    const GUTTER_WIDTH = 24;
136    const MARGIN_WEIGHT = 2;
137    let columnWidth = (displayWidth - MARGIN * MARGIN_WEIGHT - (COLUMN_NUM - 1) * GUTTER_WIDTH) / COLUMN_NUM;
138    const CONTENT_COLUMN_WIDTH_WEIGHT = 8;
139    const CONTENT_GUTTER_WIDTH_WEIGHT = 7;
140    AppStorage.SetOrCreate('CONTENT_TYPE_WIDTH', CONTENT_COLUMN_WIDTH_WEIGHT * columnWidth + CONTENT_GUTTER_WIDTH_WEIGHT * GUTTER_WIDTH);
141    const BUTTON_COLUMN_WIDTH_WEIGHT = 4;
142    const BUTTON_GUTTER_WIDTH_WEIGHT = 3;
143    AppStorage.SetOrCreate('BUTTON_TYPE_WIDTH', BUTTON_COLUMN_WIDTH_WEIGHT * columnWidth + BUTTON_GUTTER_WIDTH_WEIGHT * GUTTER_WIDTH);
144    const POP_COLUMN_WIDTH_WEIGHT = 6;
145    const POP_GUTTER_WIDTH_WEIGHT = 5;
146    AppStorage.SetOrCreate('POP_TYPE_WIDTH', POP_COLUMN_WIDTH_WEIGHT * columnWidth + POP_GUTTER_WIDTH_WEIGHT * GUTTER_WIDTH);
147    const CARD_MARGIN = 12;
148    const CARD_GUTTER_WIDTH = 12;
149    const CARD_COLUMN_WIDTH_WEIGHT = 8;
150    const CARD_GUTTER_WIDTH_WEIGHT = 7;
151    columnWidth = (displayWidth - CARD_MARGIN * MARGIN_WEIGHT - (COLUMN_NUM - 1) * CARD_GUTTER_WIDTH) / COLUMN_NUM;
152    AppStorage.SetOrCreate('CARD_TYPE_WIDTH', CARD_COLUMN_WIDTH_WEIGHT * columnWidth + CARD_GUTTER_WIDTH_WEIGHT * CARD_GUTTER_WIDTH);
153  }
154
155  setGridWidthForPhone(displayWidth: number): void {
156    const COLUMN_NUM = 4;
157    const MARGIN = 24;
158    const GUTTER_WIDTH = 24;
159    const MARGIN_WEIGHT = 2;
160    let columnWidth = (displayWidth - MARGIN * MARGIN_WEIGHT - (COLUMN_NUM - 1) * GUTTER_WIDTH) / COLUMN_NUM;
161    const CONTENT_COLUMN_WIDTH_WEIGHT = 4;
162    const CONTENT_GUTTER_WIDTH_WEIGHT = 3;
163    AppStorage.SetOrCreate('CONTENT_TYPE_WIDTH', CONTENT_COLUMN_WIDTH_WEIGHT * columnWidth + CONTENT_GUTTER_WIDTH_WEIGHT * GUTTER_WIDTH);
164    const BUTTON_COLUMN_WIDTH_WEIGHT = 2;
165    const BUTTON_GUTTER_WIDTH_WEIGHT = 3;
166    AppStorage.SetOrCreate('BUTTON_TYPE_WIDTH', BUTTON_COLUMN_WIDTH_WEIGHT * columnWidth + BUTTON_GUTTER_WIDTH_WEIGHT * GUTTER_WIDTH);
167    const POP_COLUMN_WIDTH_WEIGHT = 4;
168    const POP_GUTTER_WIDTH_WEIGHT = 3;
169    AppStorage.SetOrCreate('POP_TYPE_WIDTH', POP_COLUMN_WIDTH_WEIGHT * columnWidth + POP_GUTTER_WIDTH_WEIGHT * GUTTER_WIDTH);
170    const CARD_MARGIN = 12;
171    const CARD_GUTTER_WIDTH = 12;
172    const CARD_COLUMN_WIDTH_WEIGHT = 4;
173    const CARD_GUTTER_WIDTH_WEIGHT = 3;
174    columnWidth = (displayWidth - CARD_MARGIN * MARGIN_WEIGHT - (COLUMN_NUM - 1) * CARD_GUTTER_WIDTH) / COLUMN_NUM;
175    AppStorage.SetOrCreate('CARD_TYPE_WIDTH', CARD_COLUMN_WIDTH_WEIGHT * columnWidth + CARD_GUTTER_WIDTH_WEIGHT * CARD_GUTTER_WIDTH);
176  }
177
178  uin8Array2JsonString(inArray: Uint8Array): string {
179    return JSON.stringify(inArray);
180  }
181
182  jsonString2Uint8Array(inString: string): Uint8Array {
183    let buffer = [];
184    let parsed : object = JSON.parse(inString);
185    for (const key of Object.keys(parsed)) {
186      buffer.push(parsed[key]);
187    }
188    return new Uint8Array(buffer);
189  }
190
191  string2Uint8Array(inString: string): Uint8Array {
192    let buffer = [];
193    for (let i = 0; i < inString.length; i++) {
194      buffer.push(inString.charCodeAt(i));
195    }
196    buffer.push(0);
197    return new Uint8Array(buffer);
198  }
199
200  getStartViewImage() : Resource {
201    if (Config.getDeviceType() === 'tablet') {
202      return $r('app.media.face_start_view_pad');
203    }
204    return $r('app.media.face_start_view');
205  }
206}
207
208let commonController = new CommonController();
209export default commonController as CommonController;