1/*
2 * Copyright (c) 2022-2024 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 */
15import deviceManager from '@ohos.distributedHardware.deviceManager';
16import { BusinessError } from '@ohos.base';
17import UIExtensionContentSession from '@ohos.app.ability.UIExtensionContentSession';
18import deviceInfo from '@ohos.deviceInfo';
19import Constant from '../common/constant';
20
21let dmClass: deviceManager.DeviceManager | null;
22let TAG = '[DeviceManagerUI:PinDialog]==>';
23const ACTION_CANCEL_PINCODE_DISPLAY: number = 3;
24const MSG_CANCEL_PIN_CODE_SHOW: number = 2;
25
26@CustomDialog
27struct PinCustomDialog {
28  @State pinCode: string = '';
29  @State pinCodeArr: Array<string> = [];
30  @State btnColor: ResourceColor = Color.Transparent;
31  @State isPC: boolean = false;
32  controller?: CustomDialogController
33
34  cancel() {
35    console.log(TAG + 'destruction()');
36    try {
37      console.log(TAG + 'pin dialog terminateSelf');
38      let session = AppStorage.get<UIExtensionContentSession>('pinSession');
39      if (session) {
40        session.terminateSelf();
41      }
42    } catch (err) {
43      console.log(TAG + 'dialog cancel failed: ' + JSON.stringify(err));
44    }
45  }
46
47  aboutToAppear() {
48    console.log(TAG + 'aboutToAppear execute PinCustomDialog');
49    this.isPC = Constant.isPC();
50    // 获取pinCode
51    this.pinCode = AppStorage.get('pinCode') as string;
52    this.pinCodeArr = this.pinCode.split('');
53    console.log(TAG + 'this.pinCodeArr' + this.pinCodeArr);
54  }
55
56  setUserOperation(operation: number) {
57    console.log(TAG + 'setUserOperation: ' + operation);
58    if (dmClass == null) {
59      console.log(TAG + 'setUserOperation: ' + 'dmClass null');
60      return;
61    }
62    try {
63      dmClass.setUserOperation(operation, 'extra');
64    } catch (error) {
65      console.log(TAG + 'dmClass setUserOperation failed');
66    }
67  }
68
69  build() {
70    GridRow({
71      columns: { xs: 4, sm: 8, md: this.isPC ? 24 : 12 },
72      gutter: { x: 4 },
73      breakpoints: { value: ['600vp', '840vp'] }
74    }) {
75      GridCol({ span: { xs: 4, sm: 4, md: this.isPC ? 6 : 4 }, offset: { sm: 2, md: this.isPC ? 9 : 4 } }) {
76        Column() {
77          Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
78            Text($r('app.string.dm_connect_code'))
79              .fontSize($r('sys.float.ohos_id_text_size_dialog_tittle'))
80              .fontColor($r('sys.color.ohos_id_color_text_primary'))
81              .fontWeight(FontWeight.Bold)
82              .margin({
83                left: 24,
84                right: 24
85              })
86          }
87          .constraintSize({ minHeight: 56 })
88          .margin({ bottom: this.isPC ? 16 : 8 })
89
90          Row() {
91            Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
92              ForEach(this.pinCodeArr, (item: string) => {
93                Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
94                  Text(item)
95                    .fontSize($r('sys.float.ohos_id_text_size_headline7'))
96                    .fontColor($r('sys.color.ohos_id_color_text_primary'))
97                    .fontWeight(FontWeight.Medium)
98                    .height(26)
99                }.width('10%')
100                .height('100%')
101              })
102            }.height(48)
103          }
104          .margin({ bottom: this.isPC ? 16 : 8 })
105
106          Flex({ justifyContent: FlexAlign.Center }) {
107            Button($r('app.string.dm_cancel'))
108              .fontSize($r('sys.float.ohos_id_text_size_button1'))
109              .fontColor($r('sys.color.ohos_id_color_text_primary_activated'))
110              .constraintSize({ minHeight: 40 })
111              .width('100%')
112              .backgroundColor(this.btnColor)
113              .onClick(() => {
114                if (this.controller) {
115                  this.controller.close();
116                }
117                this.cancel();
118                this.setUserOperation(ACTION_CANCEL_PINCODE_DISPLAY);
119              })
120              .onHover((isHover?: boolean, event?: HoverEvent): void => {
121                if (isHover) {
122                  this.btnColor = $r('sys.color.ohos_id_color_hover');
123                } else {
124                  this.btnColor = this.isPC ? $r('sys.color.ohos_id_color_button_normal') : Color.Transparent;
125                }
126              })
127              .stateStyles({
128                pressed: {
129                  .backgroundColor($r('sys.color.ohos_id_color_click_effect'))
130                },
131                normal: {
132                  .backgroundColor(this.isPC ? $r('sys.color.ohos_id_color_button_normal') : Color.Transparent)
133                }
134              })
135          }.margin({
136            left: this.isPC ? 72 : 16,
137            right: this.isPC ? 72 : 16,
138            bottom: this.isPC ? 24 : 16 })
139        }
140        .constraintSize({ maxHeight: `${300}` })
141        .borderRadius($r('sys.float.ohos_id_corner_radius_dialog'))
142        .backgroundBlurStyle(BlurStyle.COMPONENT_ULTRA_THICK)
143        .margin({ left: $r('sys.float.ohos_id_dialog_margin_start'), right: $r('sys.float.ohos_id_dialog_margin_end') })
144      }
145    }
146  }
147}
148
149@Entry
150@Component
151struct dialogPlusPage {
152  dialogController: CustomDialogController = new CustomDialogController({
153    builder: PinCustomDialog(),
154    cancel: this.onCancel,
155    autoCancel: false,
156    alignment: DialogAlignment.Center,
157    offset: { dx: 0, dy: -20 },
158    customStyle: true,
159    maskColor: $r('sys.color.ohos_id_color_mask_thin')
160  });
161
162  onCancel() {
163    this.destruction();
164  }
165
166  aboutToAppear() {
167    this.initStatue();
168    console.log(TAG + 'aboutToAppear execute')
169  }
170
171  aboutToDisappear() {
172    console.log(TAG + 'aboutToDisappear executed')
173    if (dmClass != null) {
174      try {
175        dmClass.off('uiStateChange')
176        try {
177          dmClass.release();
178        } catch (err) {
179          let e: BusinessError = err as BusinessError;
180          console.error(TAG + 'release device manager errCode:' + e.code + ',errMessage:' + e.message);
181        }
182      } catch (error) {
183        console.log(TAG + 'dmClass release failed')
184      }
185      dmClass = null
186    }
187  }
188
189  initStatue() {
190    if (dmClass) {
191      console.log(TAG + 'deviceManager exist');
192      return;
193    }
194    deviceManager.createDeviceManager('com.ohos.devicemanagerui.pin',
195      (err: Error, dm: deviceManager.DeviceManager) => {
196        if (err) {
197          console.log('createDeviceManager err:' + JSON.stringify(err) + ' --fail:' + JSON.stringify(dm))
198          return
199        }
200        dmClass = dm
201        dmClass.on('uiStateChange', (data: Record<string, string>) => {
202          console.log('uiStateChange executed, dialog closed' + JSON.stringify(data))
203          let tmpStr: Record<string, number> = JSON.parse(data.param)
204          let msg: number = tmpStr.uiStateMsg as number
205          if (msg === MSG_CANCEL_PIN_CODE_SHOW) {
206            this.destruction()
207          }
208        })
209      });
210  }
211
212  setUserOperation(operation: number) {
213    console.log(TAG + 'setUserOperation: ' + operation)
214    if (dmClass == null) {
215      console.log(TAG + 'setUserOperation: ' + 'dmClass null')
216      return;
217    }
218    try {
219      dmClass.setUserOperation(operation, 'extra');
220    } catch (error) {
221      console.log(TAG + 'dmClass setUserOperation failed')
222    }
223  }
224
225  destruction() {
226    console.log(TAG + 'destruction()');
227    try {
228      console.log(TAG + 'pin dialog terminateSelf');
229      let session = AppStorage.get<UIExtensionContentSession>('pinSession');
230      if (session) {
231        session.terminateSelf();
232      }
233    } catch (err) {
234      console.log(TAG + 'dialog cancel failed: ' + JSON.stringify(err));
235    }
236  }
237
238  build() {
239    Column(this.dialogController.open())
240  }
241}