1/*
2 * Copyright (c) 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 display from '@ohos.display';
17import userAuth from '@ohos.userIAM.userAuth';
18import Constants, { CmdData, CmdType, FingerPosition, NumKeyBoardItem, WantParams } from '../../common/vm/Constants';
19import AuthUtils from '../utils/AuthUtils';
20import FuncUtils from '../utils/FuncUtils';
21import LogUtils from '../utils/LogUtils';
22import TimeUtils from '../utils/TimeUtils';
23import NumKeyBoard from './NumkeyBoard';
24import common from '@ohos.app.ability.common';
25import UIExtensionContentSession from '@ohos.app.ability.UIExtensionContentSession';
26
27const TAG = 'FullScreen';
28const INTERVAL = 1000;
29const THOUSANDTH = 1000;
30const DEL_PWD = -2;
31const CALL_PHONE = -1;
32const GO_BACK = -3;
33const FINGER_TEXT_POSITION = 120;
34const FINGER_HIGH = 80;
35const FINGER_Y_POSITION = 60;
36const MAX_LENGTH = 32;
37const SIX_MAX_LENGTH = 6;
38const AUTH_TYPE_FACE = 2;
39const AUTH_TYPE_FINGER = 4;
40const PASSWORD_LENGTH = 4;
41const PASSWORD_ARRAY_LENGTH = 6;
42const NOTICE_DELAY = 50;
43const FINGER_SENSOR_POSITION_LINE = 0.75;
44const RADIUS = 2;
45const PADDING_8 = 8;
46const CANCEL_HIGH = 40;
47const BOTTOM = 72;
48const MARGIN = 4;
49const NUM_KEY_BOTTOM = 0.63;
50const NUM_KEY_POSITION = 0.54;
51const TIPS_POSITION = 0.245;
52const LOCK_POSITION = 0.2675;
53
54interface ControlType {
55  isSixPassword?: boolean,
56  isLandscape: boolean,
57  jumpFinger: boolean,
58  isShowFace: boolean,
59  isShowFinger: boolean,
60}
61
62@Component
63export default struct FullScreen {
64  @Link pinSubType: string;
65  @Link textValue: string;
66  @Link authType: Array<userAuth.UserAuthType>;
67  @Link @Watch('onCmdDataChange') cmdData: Array<CmdType>;
68  @Link cancelImage: boolean;
69  @State pinLock: number = 0;
70  @State fingerPositionY: number = 0;
71  @State fingerTextPositionY: number = 0;
72  @State fingerTipsPositionY: number = 0;
73  @State fingerButtonPositionY: number = 0;
74  @State fingerPositionLine: number = 0;
75  @StorageLink('passwordArray') passwordArray: string[] = [];
76  @StorageLink('passwordArrayNumber') passwordArrayNumber: string[] = [];
77  @State passwordObj: string = '';
78  numKeyboard: NumKeyBoardItem[] = Constants.numKeyBoard;
79  @State prompt: string = (AppStorage.get("context") as common.ExtensionContext)?.resourceManager
80    .getStringSync($r('app.string.unified_authwidget_use_pwd').id);
81  @State fingerText: string = (AppStorage.get("context") as common.ExtensionContext)?.resourceManager
82    .getStringSync($r('app.string.unified_authwidget_hint_inscreen_fp').id);
83  @StorageLink('screenLockDirection') screenLockDirection: number = 1;
84  @StorageLink('SYSTEM_STATUS_BAR_HEIGHT') SYSTEM_STATUS_BAR_HEIGHT: number = 0;
85  @StorageLink('SYSTEM_NAVIGATION_BAR_HEIGHT') SYSTEM_NAVIGATION_BAR_HEIGHT: number = 0;
86  @State controlType: ControlType = {
87    jumpFinger: false,
88    isLandscape: false,
89    isSixPassword: true,
90    isShowFace: this.authType.includes(AUTH_TYPE_FACE),
91    isShowFinger: this.authType.includes(AUTH_TYPE_FINGER)
92  }
93  @State fingerPosition: FingerPosition = {
94    sensorType: ''
95  }
96  @State screen: number[] = [];
97  @State faceFingerLockArr: boolean[] = [false, false];
98  @StorageLink('IS_LANDSCAPE') IS_LANDSCAPE: boolean = false;
99  @Consume underFingerPrint: boolean;
100
101  onCmdDataChange(num?: string): void {
102    this.cmdData.length > 0 && this.cmdData.map((item) => {
103      const payload: CmdData = item.payload;
104      if (payload.type === Constants.noticeTypePin) {
105        this.clearPassword();
106        if (payload.remainAttempts) {
107          this.prompt = (AppStorage.get("context") as common.ExtensionContext)?.resourceManager
108            .getStringSync($r('app.string.unified_authwidget_hint_pwd_error').id);
109          if (num === 'first' && this.prompt !== (AppStorage.get("context") as common.ExtensionContext)?.resourceManager
110            .getStringSync($r('app.string.unified_authwidget_hint_recognition').id)) {
111            this.prompt = (AppStorage.get("context") as common.ExtensionContext)?.resourceManager
112              .getStringSync($r('app.string.unified_authwidget_use_pwd').id);
113          }
114          // 3: pin Residual number
115          if (payload.remainAttempts < 3 && num !== 'first') {
116            this.prompt = (AppStorage.get("context") as common.ExtensionContext)?.resourceManager
117              .getStringSync($r('app.string.unified_authwidget_pwd_error_can_try').id)
118              + payload.remainAttempts + (AppStorage.get("context") as common.ExtensionContext)?.resourceManager
119              .getStringSync($r('app.string.unified_authwidget_frequency').id);
120          }
121        }
122        if (payload.remainAttempts === 0 && payload.lockoutDuration) {
123          // 1: pin lock
124          this.pinLock = 1;
125          this.countdown(payload.lockoutDuration);
126        }
127
128        if (!payload.remainAttempts && !payload.lockoutDuration) {
129          // 1: pin lock
130          this.pinLock = 1;
131        }
132        if (payload.result === 0) {
133          (AppStorage.get("session") as UIExtensionContentSession)?.terminateSelf();
134        }
135      } else if (payload.type === Constants.noticeTypeFace) {
136        if (payload.remainAttempts < 5 && payload.remainAttempts > 0) {
137          if (this.pinLock !== 1) {
138            this.prompt = (AppStorage.get("context") as common.ExtensionContext)?.resourceManager
139              .getStringSync($r('app.string.unified_authwidget_hint_face_verify_fail_click_retry_s1').id);
140            this.faceFingerLockArr[0] = false;
141          }
142        }
143        if (num === 'first') {
144          if (payload.remainAttempts === 0) {
145            this.controlType.isShowFace = false;
146          } else {
147            if (this.pinLock !== 1) {
148              this.prompt = (AppStorage.get("context") as common.ExtensionContext)?.resourceManager
149                .getStringSync($r('app.string.unified_authwidget_hint_recognition').id);
150            }
151          }
152        }
153        if (payload.remainAttempts === 0) {
154          if (num !== 'first') {
155            this.prompt = (AppStorage.get("context") as common.ExtensionContext)?.resourceManager
156              .getStringSync($r('app.string.unified_authwidget_title_number_failed_face_forbidden').id);
157          }
158          this.faceFingerLockArr[0] = true;
159        }
160        if (payload.result === 0) {
161          (AppStorage.get("session") as UIExtensionContentSession)?.terminateSelf();
162        }
163      } else if (payload.type === Constants.noticeTypeFinger) {
164        let sensor: FingerPosition =  { sensorType: '' };
165        if (payload.sensorInfo && JSON.stringify(payload.sensorInfo) !== '{}') {
166          sensor = JSON.parse(payload.sensorInfo);
167          this.fingerPosition = sensor || { sensorType: '' };
168        }
169        if (payload.remainAttempts && payload.result !== 0) {
170          if (this.controlType.jumpFinger) {
171            this.fingerText = (AppStorage.get("context") as common.ExtensionContext)?.resourceManager
172              .getStringSync($r('app.string.unified_authwidget_hint_fp_retry_s2').id);
173          }
174          if (sensor && this.fingerPosition.udSensorCenterYInThousandth !== undefined &&
175            this.fingerPosition.udSensorRadiusInPx !== undefined) {
176            if (sensor.sensorType === 'UNDER_SCREEN_SENSOR' ||
177              sensor.sensorType === 'BOTH_SENSOR' ||
178              sensor.sensorType === 'SensorType1') {
179              if (num !== 'first' && payload.remainAttempts > 0 && payload.result != 0) {
180                setTimeout(() => {
181                  AuthUtils.getInstance().sendNotice('EVENT_AUTH_TYPE_READY', [Constants.noticeTypeFinger]);
182                }, NOTICE_DELAY);
183                this.prompt = (AppStorage.get("context") as common.ExtensionContext)?.resourceManager
184                  .getStringSync($r('app.string.unified_authwidget_hint_fp_retry_s2').id);
185              }
186
187              this.fingerButtonPositionY = px2vp(this.fingerPosition.udSensorCenterYInThousandth / THOUSANDTH * this.screen[1]);
188              FuncUtils.judgmentOverflow(this.fingerButtonPositionY);
189              this.fingerPositionY = this.fingerButtonPositionY - this.SYSTEM_STATUS_BAR_HEIGHT
190                - this.SYSTEM_STATUS_BAR_HEIGHT - px2vp(this.fingerPosition.udSensorRadiusInPx * RADIUS) - PADDING_8;
191              this.fingerPositionLine = this.fingerPositionY / px2vp(this.screen[1]);
192              FuncUtils.judgmentOverflow(this.fingerPositionLine);
193              if (num === 'first' && this.fingerPositionLine > FINGER_SENSOR_POSITION_LINE && payload.result != 0) {
194                AuthUtils.getInstance().sendNotice('EVENT_AUTH_TYPE_READY', [Constants.noticeTypeFinger]);
195              }
196            }
197          }
198        }
199        if (payload.remainAttempts === 0) {
200          if (num === 'first') {
201            this.controlType.isShowFinger = false;
202          } else {
203            this.prompt = (AppStorage.get("context") as common.ExtensionContext)?.resourceManager
204              .getStringSync($r('app.string.unified_authwidget_title_number_failed_fp_forbidden').id);
205            this.fingerText = (AppStorage.get("context") as common.ExtensionContext)?.resourceManager
206              .getStringSync($r('app.string.unified_authwidget_title_number_failed_fp_forbidden').id);
207          }
208          this.faceFingerLockArr[1] = true;
209          this.controlType.jumpFinger = false;
210          this.cancelImage = false;
211        }
212        if (payload.result === 0) {
213          (AppStorage.get("session") as UIExtensionContentSession)?.terminateSelf();
214        }
215      } else {
216        LogUtils.error(TAG, 'type: ' + payload.type);
217        (AppStorage.get("session") as UIExtensionContentSession)?.terminateSelf();
218      }
219    })
220  }
221
222  aboutToAppear(): void {
223    LogUtils.debug(TAG, 'aboutToAppear');
224    try {
225      const displayClass = display.getDefaultDisplaySync();
226      this.screen = [displayClass.width, displayClass.height];
227      AppStorage.SetOrCreate('passwordArray', [] as string[]);
228      if (this.cmdData && this.cmdData.length > 0) {
229        this.onCmdDataChange('first');
230      }
231
232      if (this.controlType.isShowFinger && this.fingerPosition.udSensorCenterYInThousandth !== undefined &&
233        this.fingerPosition.udSensorRadiusInPx !== undefined) {
234        let tempPosition = px2vp(this.fingerPosition.udSensorCenterYInThousandth * this.screen[1]);
235        FuncUtils.judgmentOverflow(tempPosition);
236        this.fingerButtonPositionY = tempPosition / THOUSANDTH;
237        FuncUtils.judgmentOverflow(this.fingerButtonPositionY);
238        this.fingerPositionY = this.fingerButtonPositionY - this.SYSTEM_STATUS_BAR_HEIGHT
239          - this.SYSTEM_STATUS_BAR_HEIGHT - px2vp(this.fingerPosition.udSensorRadiusInPx * RADIUS) - PADDING_8;
240        FuncUtils.judgmentOverflow(this.fingerPositionY);
241
242        this.fingerTipsPositionY = this.fingerButtonPositionY - px2vp(FINGER_Y_POSITION) - FINGER_HIGH
243          - this.SYSTEM_STATUS_BAR_HEIGHT - px2vp(this.fingerPosition.udSensorRadiusInPx * RADIUS) - PADDING_8;
244        FuncUtils.judgmentOverflow(this.fingerTipsPositionY);
245
246        this.fingerTextPositionY = this.fingerButtonPositionY - px2vp(FINGER_Y_POSITION) - FINGER_TEXT_POSITION
247          - this.SYSTEM_STATUS_BAR_HEIGHT - px2vp(this.fingerPosition.udSensorRadiusInPx * RADIUS) - PADDING_8;
248        FuncUtils.judgmentOverflow(this.fingerTextPositionY);
249      }
250
251      if (this.controlType.isShowFace && this.pinLock !== 1) {
252        AuthUtils.getInstance().sendNotice('EVENT_AUTH_TYPE_READY', [Constants.noticeTypeFace]);
253        return;
254      }
255    } catch (error) {
256      LogUtils.error(TAG, 'aboutToAppear catch error: ' + error?.code);
257      (AppStorage.get("session") as UIExtensionContentSession)?.terminateSelf();
258    }
259  }
260
261  clearPassword(): void {
262    this.passwordArray = [];
263    this.passwordArrayNumber = [];
264    this.passwordArray = ['', '', '', '', '', ''];
265    this.passwordObj = '';
266    this.numKeyboard[11].value = GO_BACK;
267    this.numKeyboard[11].row1 = (AppStorage.get("context") as common.ExtensionContext)?.resourceManager
268      .getStringSync($r('app.string.unified_authwidget_back').id);
269    this.updateStorage(() => {
270    })
271  }
272
273  aboutToDisappear(): void {
274    this.clearPassword();
275  }
276
277  countdown(freezingTime: number): void {
278    const TRY_AGAIN = (AppStorage.get("context") as common.ExtensionContext)?.resourceManager.getStringSync($r('app.string.unified_authwidget_postretry').id);
279    const PLEASE_TRY = (AppStorage.get("context") as common.ExtensionContext)?.resourceManager.getStringSync($r('app.string.unified_authwidget_pleaseretry').id);
280    let promptText: string = '';
281    let freezingMillisecond = freezingTime;
282    if (freezingMillisecond > 0) {
283      promptText = TimeUtils.getFreezingTimeNm(freezingMillisecond, (AppStorage.get("context") as common.ExtensionContext));
284      promptText =PLEASE_TRY + promptText + TRY_AGAIN;
285      setTimeout((t: number):void => this.countdown(t), INTERVAL, freezingTime - INTERVAL);
286    } else {
287      promptText = (AppStorage.get("context") as common.ExtensionContext)?.resourceManager.getStringSync($r('app.string.unified_authwidget_use_pwd').id);
288      this.clearPassword();
289      // 0: pin unlock
290      this.pinLock = 0;
291    }
292    this.prompt = promptText;
293  }
294
295  updateStorage(callback: Function): void {
296    AppStorage.SetOrCreate('passwordArray', this.passwordArray);
297    AppStorage.SetOrCreate('numKeyboard', this.numKeyboard);
298    callback();
299  }
300
301  build() {
302    if (!this.controlType.jumpFinger) {
303      Column() {
304
305        // 1: pin lock
306        if(this.pinLock === 1) {
307          Column() {
308            Text($r('app.string.unified_authwidget_locked'))
309              .draggable(false)
310              .margin({ bottom: $r('app.float.content_padding') })
311              .fontColor($r('sys.color.ohos_id_color_text_primary_contrary'))
312              .fontSize($r('sys.float.ohos_id_text_size_headline6'))
313              .fontWeight(FontWeight.Medium)
314            Text(this.prompt)
315              .draggable(false)
316              .id('cancelIconCustomPassword')
317              .fontSize($r('sys.float.ohos_id_text_size_body2'))
318              .fontWeight(FontWeight.Medium)
319              .fontColor($r('sys.color.ohos_id_color_text_secondary_contrary'))
320              .margin({ bottom: $r('app.float.margin_16') })
321              .textAlign(TextAlign.Center)
322              .textOverflow({ overflow: TextOverflow.None })
323              .height($r('app.float.size_24'))
324            Button(($r('app.string.unified_authwidget_forgotpwd')), {
325              stateEffect: false
326            })
327              .id('forgotBtnCustomPwd')
328              .height($r('app.float.text_high'))
329              .backgroundColor(Color.Transparent)
330              .fontColor($r('sys.color.ohos_id_color_text_primary_activated'))
331              .fontSize($r('sys.float.ohos_id_text_size_button1'))
332              .fontWeight(FontWeight.Medium)
333              .onClick(() => {
334                let str = this.passwordArrayNumber.toString()
335                this.textValue = str.replace(new RegExp(',', 'g'), '');
336              })
337              .visibility(Visibility.Hidden)
338          }
339          .position({ y: px2vp(this.screen[1] * LOCK_POSITION) - CANCEL_HIGH - this.SYSTEM_STATUS_BAR_HEIGHT})
340          .width(Constants.fullContainerWidth)
341        } else {
342          Column() {
343            if (this.controlType.isShowFace) {
344              Image($r('app.media.white_faceID'))
345                .draggable(false)
346                .id('faceImgCustomPwd')
347                .width($r('app.float.image_small'))
348                .height($r('app.float.image_small'))
349                .margin({ bottom: $r('app.float.content_padding') })
350                .onClick(() => {
351                  if (!this.faceFingerLockArr[0]) {
352                    this.prompt = (AppStorage.get("context") as common.ExtensionContext)?.resourceManager
353                      .getStringSync($r('app.string.unified_authwidget_hint_recognition').id);
354                    AuthUtils.getInstance().sendNotice('EVENT_AUTH_TYPE_READY', [Constants.noticeTypeFace]);
355                  } else {
356                    this.prompt = (AppStorage.get("context") as common.ExtensionContext)?.resourceManager
357                      .getStringSync($r('app.string.unified_authwidget_title_face_forbidden').id);
358                  }
359                })
360            }
361            if (!this.controlType.isShowFace) {
362              Text()
363                .draggable(false)
364                .width($r('app.float.image_small'))
365                .height($r('app.float.image_small'))
366                .margin({ bottom: $r('app.float.content_padding') })
367            }
368            Text(this.prompt)
369              .draggable(false)
370              .id('cancelIconCustomPassword')
371              .fontSize($r('sys.float.ohos_id_text_size_body1'))
372              .fontWeight(FontWeight.Medium)
373              .fontColor($r('sys.color.ohos_id_color_text_primary_contrary'))
374              .margin({ bottom: $r('app.float.margin_16') })
375              .textAlign(TextAlign.Center)
376              .textOverflow({ overflow: TextOverflow.None })
377              .height($r('app.float.size_24'))
378              .onClick(() => {
379                if (this.prompt === (AppStorage.get("context") as common.ExtensionContext)?.resourceManager
380                  .getStringSync($r('app.string.unified_authwidget_hint_face_verify_fail_click_retry_s1').id)) {
381                  this.prompt = (AppStorage.get("context") as common.ExtensionContext)?.resourceManager
382                    .getStringSync($r('app.string.unified_authwidget_hint_recognition').id);
383                  AuthUtils.getInstance().sendNotice('EVENT_AUTH_TYPE_READY', [Constants.noticeTypeFace]);
384                }
385              })
386
387            Flex({ alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
388              // 0: pin unlock
389              if (this.pinLock === 0) {
390                if (this.pinSubType === Constants.pinSix) {
391                  Stack() {
392                    List() {
393                      ForEach(this.passwordArray, (item: string) => {
394                        if ((!item || item === '') && item !== '0') {
395                          ListItem() {
396                            Button()
397                              .border({
398                                color: Color.White,
399                                style: BorderStyle.Solid,
400                                width: 1
401                              })
402                              .borderRadius($r('app.float.input_btn_size'))
403                              .width($r('app.float.input_btn_size'))
404                              .height($r('app.float.input_btn_size'))
405                              .type(ButtonType.Circle)
406                              .backgroundColor(Color.Transparent)
407                          }
408                          .margin({
409                            left: $r('app.float.margin_12'),
410                            right: $r('app.float.margin_12'),
411                            top: $r('app.float.margin_14')
412                          })
413                        } else {
414                          ListItem() {
415                            Button()
416                              .borderRadius($r('app.float.input_btn_size'))
417                              .width($r('app.float.input_btn_size'))
418                              .height($r('app.float.input_btn_size'))
419                              .type(ButtonType.Circle)
420                              .backgroundColor($r('sys.color.ohos_id_color_text_primary_contrary'))
421                          }
422                          .margin({
423                            left: $r('app.float.margin_12'),
424                            right: $r('app.float.margin_12'),
425                            top: $r('app.float.margin_14')
426                          })
427                        }
428                      })
429                    }
430                    .listDirection(Axis.Horizontal)
431                    .height($r('app.float.input_height'))
432
433                    if (this.IS_LANDSCAPE) {
434                      TextInput({ placeholder: '', text: this.passwordArray?.join('') })
435                        .draggable(false)
436                        .onChange(async (value: string) => {
437                          const arr = value.replace(new RegExp('[^\\d]', 'g'), '').split('');
438                          arr?.map((item, index) => {
439                            this.passwordArray[index] = item;
440                          });
441                          if (arr?.length === SIX_MAX_LENGTH) {
442                            this.textValue = arr?.join('');
443                            AuthUtils.getInstance().sendNotice('EVENT_AUTH_TYPE_READY', [Constants.noticeTypePin]);
444                          }
445                        })
446                        .maxLength(SIX_MAX_LENGTH)
447                        .visibility(Visibility.Visible)
448                        .opacity(0)
449                        .caretColor('transparent')
450                    }
451                  }
452
453                } else if (this.pinSubType === Constants.pinNumber) {
454                  Stack() {
455                    TextInput({ placeholder: '', text: this.passwordArrayNumber.join('') })
456                      .draggable(false)
457                      .onChange(async (value: string) => {
458                        // Removes non-numeric characters from a string
459                        this.passwordArrayNumber = value.replace(new RegExp('[^\\d]', 'g'), '').split('');
460                      })
461                      .id('pinInputNumber')
462                      .onSubmit(async (enterKey: EnterKeyType) => {
463                        let str = this.passwordArrayNumber.toString();
464                        this.textValue = str.replace(new RegExp(',', 'g'), '');
465                        if (this.passwordArrayNumber.length < PASSWORD_LENGTH) {
466                          return;
467                        }
468                        const strData = this.passwordArrayNumber.toString();
469                        this.textValue = strData.replace(new RegExp(',', 'g'), '');
470                        AuthUtils.getInstance().sendNotice('EVENT_AUTH_TYPE_READY', [Constants.noticeTypePin]);
471                      })
472                      .fontColor(Color.White)
473                      .height($r('app.float.btn_height'))
474                      .width($r('app.float.fullScreen_input_width'))
475                      .type(InputType.Password)
476                      .copyOption(CopyOptions.None)
477                      .fontSize($r('sys.float.ohos_id_text_size_body1'))
478                      .fontWeight(FontWeight.Regular)
479                      .maxLength(MAX_LENGTH)
480                      .backgroundColor('rgba(255,255,255,0.2)')
481                      .textAlign(TextAlign.Start)
482                      .margin({
483                        left: $r('app.float.custom_password_input_margin'),
484                        right: $r('app.float.custom_password_input_margin')
485                      })
486                  }
487                } else if (this.pinSubType === Constants.pinMixed) {
488                  TextInput({ text: this.passwordObj })
489                    .draggable(false)
490                    .fontColor(Color.White)
491                    .height($r('app.float.btn_height'))
492                    .width($r('app.float.fullScreen_input_width'))
493                    .type(InputType.Password)
494                    .copyOption(CopyOptions.None)
495                    .fontSize($r('sys.float.ohos_id_text_size_body1'))
496                    .fontWeight(FontWeight.Regular)
497                    .maxLength(MAX_LENGTH)
498                    .backgroundColor('rgba(255,255,255,0.2)')
499                    .textAlign(TextAlign.Start)
500                    .margin({
501                      left: $r('app.float.custom_password_input_margin'),
502                      right: $r('app.float.custom_password_input_margin')
503                    })
504                    .onSubmit(async (enterKey: EnterKeyType) => {
505                      // check callback
506                      if (this.passwordObj.length < PASSWORD_LENGTH) {
507                        return;
508                      }
509                      this.textValue = this.passwordObj;
510                      AuthUtils.getInstance().sendNotice('EVENT_AUTH_TYPE_READY', [Constants.noticeTypePin]);
511                    })
512                    .onChange((value: string) => {
513                      this.passwordObj = value;
514                    })
515                    .id('pinInput')
516                }
517              }
518            }
519            .height($r('app.float.text_high'))
520            Button(($r('app.string.unified_authwidget_forgotpwd')), {
521              stateEffect: false
522            })
523              .id('forgotBtnCustomPwd')
524              .height($r('app.float.text_high'))
525              .backgroundColor(Color.Transparent)
526              .fontColor($r('sys.color.ohos_id_color_text_primary_activated'))
527              .fontSize($r('sys.float.ohos_id_text_size_button1'))
528              .fontWeight(FontWeight.Medium)
529              .onClick(() => {
530                let str = this.passwordArrayNumber.toString()
531                this.textValue = str.replace(new RegExp(',', 'g'), '');
532              })
533              .visibility(Visibility.Hidden)
534          }
535          .width(Constants.fullContainerWidth)
536          .position({ y: px2vp(this.screen[1] * TIPS_POSITION) - CANCEL_HIGH - this.SYSTEM_STATUS_BAR_HEIGHT })
537        }
538
539        // 0: pin unlock
540        if (!this.IS_LANDSCAPE && this.pinLock === 0 && this.pinSubType === Constants.pinSix) {
541          if (this.controlType.isShowFinger && this.fingerPosition.sensorType !== 'OUT_OF_SCREEN_SENSOR'
542            && this.fingerPosition.sensorType !== 'NON_SENSOR') {
543            if (this.fingerPositionLine > FINGER_SENSOR_POSITION_LINE && this.fingerPosition.udSensorRadiusInPx !== undefined
544              && this.fingerPosition.udSensorCenterYInThousandth !== undefined) {
545              Column() {
546                NumKeyBoard({
547                  onKeyPress: (index , callback) => {
548                    let keyValue = this.numKeyboard[index].value;
549                    if (keyValue!= undefined && keyValue >= 0) {
550                      const index = this.passwordArray.map(item => item).indexOf('')
551                      if (index > -1) {
552                        this.passwordArray[index] = keyValue + '';
553                        this.numKeyboard[11].row1 = $r('app.string.unified_authwidget_delete');
554                        this.numKeyboard[11].value = DEL_PWD;
555                        if (index === 5) {
556                          this.passwordArray[index] = keyValue + '';
557                          if (this.passwordArray.join('').length < PASSWORD_ARRAY_LENGTH) {
558                            return;
559                          }
560                          let str = this.passwordArray.toString();
561                          this.textValue = str.replace(new RegExp(',', 'g'), '');
562                          AuthUtils.getInstance().sendNotice('EVENT_AUTH_TYPE_READY', [Constants.noticeTypePin]);
563                        }
564                        this.updateStorage(callback);
565                      }
566                    } else if (keyValue === DEL_PWD) {
567                      const index = this.passwordArray.map(item => item).indexOf('');
568                      if (index === -1) {
569                        this.passwordArray[5] = '';
570                      } else if (index === 1) {
571                        this.passwordArray[index - 1] = '';
572                        this.numKeyboard[11].value = GO_BACK;
573                        this.numKeyboard[11].row1 = (AppStorage.get("context") as common.ExtensionContext)?.resourceManager
574                          .getStringSync($r('app.string.unified_authwidget_back').id);
575                      } else {
576                        this.passwordArray[index - 1] = '';
577                      }
578                      this.updateStorage(callback);
579                    } else if (keyValue === GO_BACK) {
580                      // 0: pin unlock
581                      this.pinLock = 0;
582                      this.clearPassword();
583                      (AppStorage.get("session") as UIExtensionContentSession)?.terminateSelf();
584                      AuthUtils.getInstance().sendNotice(Constants.noticeEventCancel, [] ||
585                      (AppStorage.get("wantParams") as WantParams)?.type as string[]);
586                    } else if (keyValue === CALL_PHONE) {
587                      if (this.passwordArray.join('').length < PASSWORD_ARRAY_LENGTH) {
588                        return;
589                      }
590
591                      let str = this.passwordArray.toString();
592                      this.textValue = str.replace(new RegExp(',', 'g'), '');
593                      AuthUtils.getInstance().sendNotice('EVENT_AUTH_TYPE_READY', [Constants.noticeTypePin]);
594                    }
595                  }
596                })
597              }
598              .width(Constants.fullContainerWidth)
599              .height('37%')
600              .position({ y: px2vp(this.screen[1] * NUM_KEY_BOTTOM)
601                - CANCEL_HIGH - MARGIN - px2vp(this.fingerPosition.udSensorRadiusInPx * RADIUS)
602                - px2vp((THOUSANDTH - this.fingerPosition.udSensorCenterYInThousandth) / THOUSANDTH * this.screen[1])
603                - this.SYSTEM_STATUS_BAR_HEIGHT })
604            } else {
605              Column() {
606                NumKeyBoard({
607                  onKeyPress: (index, callback) => {
608                    let keyValue = this.numKeyboard[index].value;
609                    if (keyValue !== undefined && keyValue >= 0) {
610                      const index = this.passwordArray.map(item => item).indexOf('')
611                      if (index > -1) {
612                        this.passwordArray[index] = keyValue + '';
613                        this.numKeyboard[11].row1 = $r('app.string.unified_authwidget_delete');
614                        this.numKeyboard[11].value = DEL_PWD;
615                        if (index === 5) {
616                          this.passwordArray[index] = keyValue + '';
617                          if (this.passwordArray.join('').length < PASSWORD_ARRAY_LENGTH) {
618                            return;
619                          }
620                          let str = this.passwordArray.toString();
621                          this.textValue = str.replace(new RegExp(',', 'g'), '');
622                          AuthUtils.getInstance().sendNotice('EVENT_AUTH_TYPE_READY', [Constants.noticeTypePin]);
623                        }
624                        this.updateStorage(callback);
625                      }
626                    } else if (keyValue === DEL_PWD) {
627                      const index = this.passwordArray.map(item => item).indexOf('');
628                      if (index === -1) {
629                        this.passwordArray[5] = '';
630                      } else if (index === 1) {
631                        this.passwordArray[index - 1] = '';
632                        this.numKeyboard[11].value = GO_BACK;
633                        this.numKeyboard[11].row1 = (AppStorage.get("context") as common.ExtensionContext)?.resourceManager
634                          .getStringSync($r('app.string.unified_authwidget_back').id);
635                      } else {
636                        this.passwordArray[index - 1] = '';
637                      }
638                      this.updateStorage(callback);
639                    } else if (keyValue === GO_BACK) {
640                      // 0: pin unlock
641                      this.pinLock = 0;
642                      this.clearPassword();
643                      (AppStorage.get("session") as UIExtensionContentSession)?.terminateSelf();
644                      AuthUtils.getInstance().sendNotice(Constants.noticeEventCancel, [] ||
645                        (AppStorage.get("wantParams") as WantParams)?.type as string[]);
646                    } else if (keyValue === CALL_PHONE) {
647                      if (this.passwordArray.join('').length < PASSWORD_ARRAY_LENGTH) {
648                        return;
649                      }
650                      let str = this.passwordArray.toString();
651                      this.textValue = str.replace(new RegExp(',', 'g'), '');
652                      AuthUtils.getInstance().sendNotice('EVENT_AUTH_TYPE_READY', [Constants.noticeTypePin]);
653                    }
654                  }
655                })
656              }
657              .width(Constants.fullContainerWidth)
658              .height('37%')
659              .position({ y: px2vp(this.screen[1] * NUM_KEY_BOTTOM) - CANCEL_HIGH - BOTTOM
660                - this.SYSTEM_STATUS_BAR_HEIGHT - this.SYSTEM_NAVIGATION_BAR_HEIGHT })
661            }
662          } else {
663            Column() {
664              NumKeyBoard({
665                onKeyPress: (index, callback) => {
666                  let keyValue = this.numKeyboard[index].value;
667                  if (keyValue !== undefined && keyValue >= 0) {
668                    const index = this.passwordArray.map(item => item).indexOf('')
669                    if (index > -1) {
670                      this.passwordArray[index] = keyValue + '';
671                      this.numKeyboard[11].row1 = $r('app.string.unified_authwidget_delete');
672                      this.numKeyboard[11].value = DEL_PWD;
673                      if (index === 5) {
674                        this.passwordArray[index] = keyValue + '';
675                        if (this.passwordArray.join('').length < PASSWORD_ARRAY_LENGTH) {
676                          return;
677                        }
678                        let str = this.passwordArray.toString();
679                        this.textValue = str.replace(new RegExp(',', 'g'), '');
680                        AuthUtils.getInstance().sendNotice('EVENT_AUTH_TYPE_READY', [Constants.noticeTypePin]);
681                      }
682                      this.updateStorage(callback);
683                    }
684                  } else if (keyValue === DEL_PWD) {
685                    const index = this.passwordArray.map(item => item).indexOf('');
686                    if (index === -1) {
687                      this.passwordArray[5] = '';
688                    } else if (index === 1) {
689                      this.passwordArray[index - 1] = '';
690                      this.numKeyboard[11].value = GO_BACK;
691                      this.numKeyboard[11].row1 = (AppStorage.get("context") as common.ExtensionContext)?.resourceManager
692                        .getStringSync($r('app.string.unified_authwidget_back').id);
693                    } else {
694                      this.passwordArray[index - 1] = '';
695                    }
696                    this.updateStorage(callback);
697                  } else if (keyValue === GO_BACK) {
698                    // 0: pin unlock
699                    this.pinLock = 0;
700                    this.clearPassword();
701                    (AppStorage.get("session") as UIExtensionContentSession)?.terminateSelf();
702                    AuthUtils.getInstance().sendNotice(Constants.noticeEventCancel, [] ||
703                      (AppStorage.get("wantParams") as WantParams)?.type as string[]);
704                  } else if (keyValue === CALL_PHONE) {
705                    if (this.passwordArray.join('').length < PASSWORD_ARRAY_LENGTH) {
706                      return;
707                    }
708
709                    let str = this.passwordArray.toString();
710                    this.textValue = str.replace(new RegExp(',', 'g'), '');
711                    AuthUtils.getInstance().sendNotice('EVENT_AUTH_TYPE_READY', [Constants.noticeTypePin]);
712                  }
713                }
714              })
715            }
716            .width(Constants.fullContainerWidth)
717            .height('37%')
718            .position({ y: px2vp(this.screen[1] * NUM_KEY_POSITION) - CANCEL_HIGH
719              - this.SYSTEM_STATUS_BAR_HEIGHT })
720          }
721        }
722
723        // 1: pin lock
724        if (this.controlType.isShowFinger && this.pinLock !== 1 && !this.faceFingerLockArr[1]) {
725          if (this.fingerPosition.sensorType !== 'OUT_OF_SCREEN_SENSOR' &&
726          this.fingerPosition.sensorType !== 'NON_SENSOR') {
727            if (this.fingerPosition.sensorType === 'UNDER_SCREEN_SENSOR' ||
728            this.fingerPosition.sensorType === 'BOTH_SENSOR' ||
729            this.fingerPosition.sensorType === 'SensorType1') {
730              if (this.fingerPositionLine > FINGER_SENSOR_POSITION_LINE && !this.IS_LANDSCAPE && this.fingerPosition.udSensorRadiusInPx !== undefined
731                && this.fingerPosition.udSensorCenterYInThousandth !== undefined) {
732                Column() {
733                  Image($r('app.media.ic_unlock_fingerprint'))
734                    .draggable(false)
735                    .id('fingerprintImgCustomPassword')
736                    .width(px2vp(this.fingerPosition.udSensorRadiusInPx * RADIUS))
737                    .height(px2vp(this.fingerPosition.udSensorRadiusInPx * RADIUS))
738                    .onClick(() => {
739                      if (!this.faceFingerLockArr[1]) {
740                        AuthUtils.getInstance().sendNotice('EVENT_AUTH_TYPE_READY', [Constants.noticeTypeFinger]);
741                      }
742                    })
743                }
744                .position({ y: px2vp(this.fingerPosition.udSensorCenterYInThousandth / THOUSANDTH * this.screen[1])
745                  - px2vp(this.fingerPosition.udSensorRadiusInPx * RADIUS)
746                  - CANCEL_HIGH - this.SYSTEM_STATUS_BAR_HEIGHT })
747                .width(Constants.fullContainerWidth)
748                .height(this.controlType.isShowFinger ? $r('app.float.finger_high'): '9%')
749                .justifyContent(FlexAlign.Start)
750                .alignItems(HorizontalAlign.Center)
751              } else {
752                Column() {
753                  Image($r('app.media.finger_white'))
754                    .draggable(false)
755                    .id('fingerWhiteImgCustomPassword')
756                    .width($r('app.float.image_back_size'))
757                    .height($r('app.float.image_back_size'))
758                    .margin({ top: $r('app.float.input_btn_size') })
759                    .onClick(() => {
760                      if (this.IS_LANDSCAPE) {
761                        this.underFingerPrint = true;
762                      } else {
763                        this.controlType.jumpFinger = true;
764                        AuthUtils.getInstance().sendNotice('EVENT_AUTH_TYPE_READY', [Constants.noticeTypeFinger]);
765                        this.cancelImage = true;
766                      }
767                    })
768                }
769                .width(Constants.fullContainerWidth)
770                .height(this.controlType.isShowFinger ? $r('app.float.finger_high'): '9%')
771                .justifyContent(FlexAlign.Start)
772                .alignItems(HorizontalAlign.Center)
773                .position({ y: px2vp(this.screen[1]) - CANCEL_HIGH - BOTTOM
774                  - this.SYSTEM_STATUS_BAR_HEIGHT - this.SYSTEM_NAVIGATION_BAR_HEIGHT })
775              }
776            }
777          }
778        }
779      }
780      .alignItems(HorizontalAlign.Center)
781      .height(Constants.fullContainerHeight)
782      .width(Constants.fullContainerWidth)
783    } else if (!this.controlType.isLandscape && this.fingerPosition.udSensorRadiusInPx !== undefined) {
784      Column() {
785        if (AppStorage.Get('titleLength') as number < (AppStorage.get("wantParams") as WantParams)?.title.length) {
786          Scroll() {
787            Column() {
788              Text((AppStorage.get("wantParams") as WantParams)?.title)
789              .draggable(false)
790              .fontColor($r('sys.color.ohos_id_color_text_primary_contrary'))
791              .fontSize($r('sys.float.ohos_id_text_size_sub_title2'))
792              .fontWeight(FontWeight.Medium)
793              Text(this.fingerText)
794              .draggable(false)
795              .height($r('app.float.text_high'))
796              .fontColor($r('sys.color.ohos_id_color_text_primary_contrary'))
797              .fontSize($r('sys.float.ohos_id_text_size_body2'))
798              .fontWeight(FontWeight.Regular)
799              .textAlign(TextAlign.Center)
800              .margin({ top: $r('app.float.padding_8') })
801            }.margin({left: $r('app.float.margin_36'), right: $r('app.float.size_24')})
802          }
803          .width('96%')
804          .id('titleFullScreen')
805          .position({
806            y: this.fingerTextPositionY,
807          })
808          .height($r('app.float.scroll_height_72'))
809          .scrollable(ScrollDirection.Vertical)
810          .scrollBarColor('sys.color.ohos_id_color_foreground')
811        } else {
812          Text((AppStorage.get("wantParams") as WantParams)?.title)
813            .draggable(false)
814            .height($r('app.float.text_high'))
815            .fontColor($r('sys.color.ohos_id_color_text_primary_contrary'))
816            .fontSize($r('sys.float.ohos_id_text_size_sub_title2'))
817            .fontWeight(FontWeight.Medium)
818            .id('titleFullScreen')
819            .position({
820              y: this.fingerTextPositionY
821            })
822            .width('100%')
823            .textAlign(TextAlign.Center)
824          Text(this.fingerText)
825            .draggable(false)
826            .height($r('app.float.text_high'))
827            .fontColor($r('sys.color.ohos_id_color_text_secondary_contrary'))
828            .fontSize($r('sys.float.ohos_id_text_size_body2'))
829            .fontWeight(FontWeight.Regular)
830            .position({
831              y: this.fingerTipsPositionY
832            })
833            .width('100%')
834            .textAlign(TextAlign.Center)
835            .margin({ top: $r('app.float.padding_8') })
836        }
837
838        Column() {
839          Image($r('app.media.ic_unlock_fingerprint'))
840            .draggable(false)
841            .id('unlockFingerprintImgCustomPwd')
842              // radius
843            .width(px2vp(this.fingerPosition.udSensorRadiusInPx * RADIUS))
844            .height(px2vp(this.fingerPosition.udSensorRadiusInPx * RADIUS))
845        }.width('100%')
846        .position({ y: this.fingerPositionY })
847        .justifyContent(FlexAlign.Center)
848        .alignItems(HorizontalAlign.Center)
849
850        Button($r('app.string.unified_authwidget_cancel'), {
851          type: ButtonType.Normal,
852          stateEffect: true
853        })
854          .width('100%')
855          .position({
856            y: this.fingerButtonPositionY
857          })
858          .backgroundColor(Color.Transparent)
859          .fontColor($r('sys.color.ohos_id_color_text_primary_contrary'))
860          .onClick(() => {
861            this.controlType.jumpFinger = false;
862            this.cancelImage = false;
863            AuthUtils.getInstance().sendNotice(Constants.noticeEventCancel, [Constants.noticeTypeFinger]);
864            this.prompt = (AppStorage.get("context") as common.ExtensionContext)?.resourceManager
865              .getStringSync($r('app.string.unified_authwidget_use_pwd').id);
866          })
867      }
868      .justifyContent(FlexAlign.End)
869      .alignItems(HorizontalAlign.Center)
870      .height('100%')
871      .width('100%')
872    }
873  }
874}