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 '@system.prompt';
17import router from '@system.router';
18import deviceInfo from '@ohos.deviceInfo';
19import WifiModel, {
20  ApScanResult,
21  WiFiEncryptMethodMap,
22  WiFiIntensityMap,
23  WifiScanInfo,
24  WiFiSummaryMap
25} from '../model/wifiImpl/WifiModel';
26import LogUtil from '../../../../../../common/utils/src/main/ets/default/baseUtil/LogUtil';
27import ConfigData from '../../../../../../common/utils/src/main/ets/default/baseUtil/ConfigData';
28import HeadComponent from '../../../../../../common/component/src/main/ets/default/headComponent';
29import ResourceUtil from '../../../../../../common/search/src/main/ets/default/common/ResourceUtil';
30import ImageAnimatorComponent from '../../../../../../common/component/src/main/ets/default/imageAnimatorComponent';
31import wifi from '@ohos.wifi';
32
33const MODULE_TAG = ConfigData.TAG + 'WifiModel.wifi -> ';
34const deviceTypeInfo = deviceInfo.deviceType;
35
36function genWiFiIntensity(intensityEnum: number) {
37  if (intensityEnum === WiFiIntensityMap.GOOD) {
38    return $r("app.string.wifiSigIntensityStrong");
39  }
40
41  if (intensityEnum === WiFiIntensityMap.WELL) {
42    return $r("app.string.wifiSigIntensityWell");
43  }
44
45  if (intensityEnum === WiFiIntensityMap.NORMAL) {
46    return $r("app.string.wifiSigIntensityNormal");
47  }
48
49  if (intensityEnum === WiFiIntensityMap.BAD) {
50    return $r("app.string.wifiSigIntensityBad");
51  }
52  return $r("app.string.wifiSigIntensityBad");
53}
54
55function genWiFiEncryptMethod(encryptEnum: number) {
56  if (encryptEnum === WiFiEncryptMethodMap.OPEN) {
57    return $r("app.string.wifiEncryptMethodOpen");
58  }
59
60  if (encryptEnum === WiFiEncryptMethodMap.WEP) {
61    return $r("app.string.wifiEncryptMethodWEP");
62  }
63
64  if (encryptEnum === WiFiEncryptMethodMap.WPA) {
65    return $r("app.string.wifiEncryptMethodWPA");
66  }
67
68  if (encryptEnum === WiFiEncryptMethodMap.WPA2) {
69    return $r("app.string.wifiEncryptMethodWPA2");
70  }
71
72  return $r("app.string.wifiEncryptMethodOpen");
73}
74
75function genWiFiStatusSummary(statusEnum: number) {
76  if (statusEnum === WiFiSummaryMap.CONNECTED) {
77    return $r("app.string.wifiSummaryConnected");
78  }
79
80  if (statusEnum === WiFiSummaryMap.CONNECTING) {
81    return $r("app.string.wifiSummaryConnecting");
82  }
83
84  if (statusEnum === WiFiSummaryMap.OBTAINING_IP) {
85    return $r("app.string.wifiSummaryObtainingIP");
86  }
87
88  if (statusEnum === WiFiSummaryMap.SAVE_ENCRYPTED) {
89    return $r("app.string.wifiSummarySaveEncrypted");
90  }
91
92  if (statusEnum === WiFiSummaryMap.SAVE_OPEN) {
93    return $r("app.string.wifiSummarySaveOpen");
94  }
95
96  if (statusEnum === WiFiSummaryMap.ENCRYPTED) {
97    return $r("app.string.wifiSummaryEncrypted");
98  }
99
100  if (statusEnum === WiFiSummaryMap.OPEN) {
101    return $r("app.string.wifiSummaryOpen");
102  }
103  return $r("app.string.wifiSummaryConnected");
104}
105
106export interface WiFiMenuModel {
107  settingIcon: string;
108  settingSummary: number;
109  settingTitle: string;
110  settingValue: string;
111  settingArrow: string;
112  settingArrowStyle: string;
113  settingUri: string;
114  apInfo: WifiScanInfo;
115}
116
117export class apParam {
118  apInfo: WifiScanInfo;
119  isConnected: Boolean;
120
121  constructor(apInfo: WifiScanInfo, isConnected: boolean) {
122    this.apInfo = apInfo;
123    this.isConnected = isConnected;
124  }
125}
126
127@Entry
128@Component
129struct Index {
130  scroller: Scroller = new Scroller();
131  @StorageLink('slWiFiLists') scanWiFiResults: WiFiMenuModel[] = [];
132  @StorageLink('slConnectedWifi') connectedWiFi: WiFiMenuModel = {
133    settingIcon: '',
134    settingSummary: 0,
135    settingTitle: '',
136    settingValue: '',
137    settingArrow: '',
138    settingArrowStyle: '',
139    settingUri: '',
140    apInfo: {
141      ssid: '',
142      bssid: '',
143      rssi: -100,
144      band: 0,
145      frequency: 0,
146      timestamp: 0,
147      securityType: 1,
148    },
149  };
150  @State isWiFiEnabled: boolean = false;
151  @State isPhoneOrRK: boolean = false;
152  @State userSelectedApInfo: WifiScanInfo = {
153    ssid: '',
154    bssid: '',
155    rssi: -100,
156    band: 0,
157    frequency: 0,
158    timestamp: 0,
159    securityType: 1,
160  };
161  private switchDebounceFlag: number | undefined = undefined;
162  private timerId: number = -1;
163  private errorMessage: string = "";
164  private clickApInfoDialog: CustomDialogController | null = new CustomDialogController({
165    builder: apInfoDialog({
166      apInfo: this.userSelectedApInfo,
167    }),
168    alignment: deviceTypeInfo === 'phone' || deviceTypeInfo === 'default' ? DialogAlignment.Bottom : DialogAlignment.Center,
169    offset: ({ dx: 0, dy: deviceTypeInfo === 'phone' || deviceTypeInfo === 'default' ? '-24dp' : 0 }),
170    autoCancel: true,
171    customStyle: true
172  });
173  private clickApInfoDetailsDialog: CustomDialogController | null = new CustomDialogController({
174    builder: apInfoDetailsDialog({
175      apInfo: this.userSelectedApInfo,
176      disconnectAction: () => {
177        WifiModel.disconnectWiFi();
178        WifiModel.refreshApScanResults();
179      }
180    }),
181    alignment: deviceTypeInfo === 'phone' || deviceTypeInfo === 'default' ? DialogAlignment.Bottom : DialogAlignment.Center,
182    offset: ({ dx: 0, dy: deviceTypeInfo === 'phone' || deviceTypeInfo === 'default' ? '-24dp' : 0 }),
183    autoCancel: true,
184    customStyle: true
185  });
186
187  build() {
188    Column() {
189      GridContainer({ gutter: ConfigData.GRID_CONTAINER_GUTTER_24, margin: ConfigData.GRID_CONTAINER_MARGIN_24 }) {
190        Column() {
191          HeadComponent({ headName: $r('app.string.wifiTab'), isActive: true });
192
193          Row() {
194            Text($r('app.string.wifiTab'))
195              .fontSize($r('sys.float.ohos_id_text_size_body1'))
196              .fontColor($r('sys.color.ohos_id_color_text_primary'))
197              .fontWeight(FontWeight.Medium)
198              .textAlign(TextAlign.Start)
199
200            Blank()
201
202            Toggle({ type: ToggleType.Switch, isOn: this.isWiFiEnabled })
203              .width('36vp')
204              .height('20vp')
205              .selectedColor('#007DFF')
206              .onChange((isOn: boolean) => {
207                this.switchWiFiActiveStatus(isOn);
208              });
209          }
210          .height($r('app.float.wh_value_56'))
211          .width(ConfigData.WH_100_100)
212          .alignItems(VerticalAlign.Center)
213          .margin({ top: $r("app.float.distance_8") })
214          .padding({ left: $r("app.float.wh_value_12"), right: $r('app.float.wh_value_6') })
215          .backgroundColor($r("app.color.white_bg_color"))
216          .borderRadius($r('app.float.radius_24'));
217
218          Scroll(this.scroller) {
219            Column() {
220              Column() {
221                Row() {
222                  Text($r("app.string.wifiTipConnectedWLAN"))
223                    .fontSize($r('sys.float.ohos_id_text_size_body2'))
224                    .fontColor($r('sys.color.ohos_id_color_text_secondary'))
225                    .fontWeight(FontWeight.Medium)
226                    .textAlign(TextAlign.Start)
227                    .height($r('app.float.distance_19'));
228                }
229                .height($r("app.float.wh_value_48"))
230                .width(ConfigData.WH_100_100)
231                .padding({
232                  left: $r('app.float.wh_value_12'),
233                  top: $r('app.float.distance_19_5'),
234                  bottom: $r('app.float.distance_9_5')
235                })
236                .justifyContent(FlexAlign.Start);
237
238                Column() {
239                  ConnectedWiFiEntryComponent({
240                    connectedWiFi: $connectedWiFi,
241                    titleFontColor: "activated"
242                  })
243                }
244                .height($r("app.float.wh_value_64"))
245                .borderRadius($r("app.float.radius_24"))
246                .backgroundColor($r("app.color.white_bg_color"))
247                .margin({ top: $r("app.float.wh_value_4"), bottom: $r("app.float.wh_value_4") })
248                .onClick(() => {
249                  LogUtil.info(MODULE_TAG + 'clicked connected wifi item');
250                  this.userSelectedApInfo = this.connectedWiFi.apInfo;
251                  this.clickApInfoDetailsDialog?.open();
252                  LogUtil.info(MODULE_TAG + 'end!!!');
253                });
254              }
255              .visibility(this.isNeedRenderConnectedWiFi() && WifiModel.isWiFiConnected() ?
256              Visibility.Visible : Visibility.None);
257
258              Column() {
259                Row() {
260                  Text($r("app.string.wifiTipValidWLAN"))
261                    .fontSize($r('sys.float.ohos_id_text_size_body2'))
262                    .fontColor($r('sys.color.ohos_id_color_text_secondary'))
263                    .fontWeight(FontWeight.Medium)
264                    .height($r('app.float.wh_value_19'))
265                    .margin({ top: $r('app.float.distance_19_5'), bottom: $r('app.float.distance_9_5') });
266
267                  Blank()
268
269                  ImageAnimatorComponent({
270                    imageWidth: $r('app.float.wh_value_24'),
271                    imageHeight: $r('app.float.wh_value_24')
272                  })
273                    .visibility(this.scanWiFiResults.length === 0 ? Visibility.Visible : Visibility.None)
274                }
275                .height($r("app.float.wh_value_48"))
276                .width(ConfigData.WH_100_100)
277                .padding({ left: $r('app.float.wh_value_12'), right: $r('app.float.wh_value_12') })
278                .alignItems(VerticalAlign.Center);
279
280                Column() {
281                  List() {
282                    ForEach(this.scanWiFiResults, (item: WiFiMenuModel) => {
283                      ListItem() {
284                        WiFiEntryComponent({
285                          settingIcon: item.settingIcon,
286                          settingTitle: item.settingTitle,
287                          settingSummary: genWiFiStatusSummary(item.settingSummary),
288                          settingValue: item.settingValue,
289                          settingArrow: item.settingArrow,
290                          settingUri: item.settingUri,
291                          titleFontColor: "inactivated"
292                        });
293                      }
294                      .onClick(() => {
295                        if (WifiModel.isSavedAp(item.settingTitle)) {
296                          this.userSelectedApInfo = item.apInfo;
297                          this.clickApInfoDialog?.open();
298                        } else {
299                          this.jumpToConnectApPage(item.apInfo);
300                        }
301                      })
302                    });
303                  }
304                  .margin({ top: $r('app.float.wh_value_4'), bottom: $r('app.float.wh_value_4') })
305                  .divider({
306                    strokeWidth: $r('app.float.divider_wh'),
307                    color: $r('app.color.color_E3E3E3_grey'),
308                    startMargin: $r("app.float.wh_value_12"),
309                    endMargin: $r("app.float.wh_value_12"),
310                  });
311                }
312                .borderRadius($r("app.float.radius_24"))
313                .backgroundColor($r("app.color.white_bg_color"))
314                .visibility(this.scanWiFiResults.length !== 0 ? Visibility.Visible : Visibility.None)
315              }
316              .visibility(this.isWiFiEnabled ? Visibility.Visible : Visibility.None);
317            }
318          }
319          .width(ConfigData.WH_100_100)
320          .borderRadius($r("app.float.radius_24"))
321          .scrollable(ScrollDirection.Vertical)
322          .scrollBar(BarState.Off)
323          .layoutWeight(ConfigData.LAYOUT_WEIGHT_1)
324          .align(Alignment.Top);
325        }
326        .useSizeType({
327          sm: { span: 4, offset: 0 },
328          md: { span: 6, offset: 1 },
329          lg: { span: 8, offset: 2 }
330        });
331      }
332      .width(ConfigData.WH_100_100)
333      .height(ConfigData.WH_100_100)
334    }
335    .backgroundColor($r("sys.color.ohos_id_color_sub_background"))
336    .width(ConfigData.WH_100_100)
337    .height(ConfigData.WH_100_100);
338  }
339
340  isNeedRenderConnectedWiFi() {
341    if (this.isWiFiEnabled !== true) {
342      return false;
343    }
344
345    if (typeof this.connectedWiFi.settingTitle === 'undefined') {
346      return false;
347    }
348    // as the ConnectionStateChange event is diff with the getLinkInfo callback,
349    // we always get the diff status between them
350    let titleSign: boolean = (!!this.connectedWiFi.settingTitle) && (this.connectedWiFi.settingTitle.length > 0);
351    let arrowSign: boolean = (!!this.connectedWiFi.settingArrow) && (this.connectedWiFi.settingArrow.length > 0);
352    if (titleSign && arrowSign) {
353      return true;
354    }
355    return false;
356  }
357
358  jumpToConnectApPage(apInfo: WifiScanInfo) {
359    WifiModel.setUserSelectedAp(apInfo);
360    // direct connect to wifi in security type 1(Open)
361    if (apInfo.securityType === 1) {
362      WifiModel.connectWiFi('');
363      return;
364    }
365    let params: apParam = new apParam(apInfo, false);
366    router.push({
367      uri: 'pages/wifiPsd',
368      params: params,
369    });
370  }
371
372  timeLimits() {
373    this.timerId = setTimeout(() => {
374      if (this.isWiFiEnabled == WifiModel.isWiFiActive()) {
375        this.timerId = -1;
376        return;
377      }
378      this.isWiFiEnabled = WifiModel.isWiFiActive();
379      LogUtil.error(MODULE_TAG + 'wifi timeLimits active status : ' + this.isWiFiEnabled);
380      this.timerId = -1;
381      prompt.showToast({
382        message: this.errorMessage,
383        duration: 1000,
384      });
385    }, 5000)
386  }
387
388  switchWiFiActiveStatus(isOn: boolean) {
389    // make the ui change quickly
390    this.isWiFiEnabled = isOn;
391    LogUtil.info(MODULE_TAG + 'curr enable status : ' + this.isWiFiEnabled);
392
393    // delay the wifi status change event
394    if (this.switchDebounceFlag) {
395      clearTimeout(this.switchDebounceFlag);
396    }
397
398    if (this.timerId != -1) {
399      clearTimeout(this.timerId);
400    }
401
402    this.switchDebounceFlag = setTimeout(() => {
403      if (this.isWiFiEnabled) {
404        LogUtil.info(MODULE_TAG + 'enable wifi');
405        WifiModel.enableWiFi();
406      } else {
407        LogUtil.info(MODULE_TAG + 'disable wifi');
408        WifiModel.disableWifi();
409      }
410      this.switchDebounceFlag = undefined;
411      this.timeLimits();
412    }, 500);
413  }
414
415  aboutToAppear(): void {
416    LogUtil.info(MODULE_TAG + 'about to appear wifi page');
417    try {
418      ResourceUtil.getString($r('app.string.ERROR_WIFI_CHANGE')).then((data) => {
419        this.errorMessage = data;
420      })
421    } catch (error) {
422      LogUtil.error(MODULE_TAG + 'get errorMessage String error:' + JSON.stringify(error));
423    }
424    WifiModel.registerWiFiStatusObserver((code: number) => {
425      LogUtil.info(MODULE_TAG + 'wifi status code : ' + code + ' taskId : ' + this.switchDebounceFlag);
426      if ((!this.switchDebounceFlag) && (code == 0 || code == 1)) {
427        this.isWiFiEnabled = Boolean(code);
428        LogUtil.info(MODULE_TAG + 'wifi active status code : ' + code + " isWiFiEnabled" + this.isWiFiEnabled);
429        if (this.timerId != -1) {
430          clearTimeout(this.timerId);
431          this.timerId = -1;
432        }
433      }
434    });
435    // init wifi active status
436    this.isWiFiEnabled = WifiModel.isWiFiActive();
437    let wifiDefaultModel: WiFiMenuModel = (new ApScanResult()).renderToListModel();
438    AppStorage.SetOrCreate('slConnectedWifi', wifiDefaultModel);
439  }
440
441  aboutToDisappear(): void {
442    LogUtil.info(MODULE_TAG + 'about to disappear');
443    if (this.timerId != -1) {
444      clearTimeout(this.timerId);
445    }
446    if (this.switchDebounceFlag) {
447      clearTimeout(this.switchDebounceFlag);
448    }
449    WifiModel.destroyWiFiModelData();
450    WifiModel.unregisterWiFiStatusObserver();
451    this.clickApInfoDialog = null;
452    this.clickApInfoDetailsDialog = null;
453  }
454
455  onPageShow() {
456    LogUtil.info(MODULE_TAG + 'on page show');
457    WifiModel.registerWiFiConnectionObserver((code: number) => {
458      LogUtil.info(MODULE_TAG + 'wifi connection code : ' + code);
459      WifiModel.refreshApScanResults();
460    });
461    WifiModel.startScanTask();
462  }
463
464  onPageHide(): void {
465    LogUtil.info(MODULE_TAG + 'on page hide');
466    WifiModel.unregisterWiFiConnectionObserver();
467    WifiModel.stopScanTask();
468  }
469
470  onBackPress() {
471    LogUtil.info('settings Wifi onBackPress');
472  }
473}
474
475@Component
476export default struct ApInfoComponent {
477  @State label: string = "";
478  @State value: string = "";
479
480  build() {
481    Row() {
482      Text(this.label)
483        .fontSize($r('sys.float.ohos_id_text_size_body1'))
484        .fontColor($r('sys.color.ohos_id_color_text_primary'))
485        .fontWeight(FontWeight.Medium)
486        .textAlign(TextAlign.Start);
487
488      Blank();
489
490      Text(this.value)
491        .fontSize($r('sys.float.ohos_id_text_size_body2'))
492        .fontColor($r('sys.color.ohos_id_color_text_secondary'))
493        .fontWeight(FontWeight.Regular)
494        .textAlign(TextAlign.End);
495    }
496    .height($r('app.float.wh_value_48'))
497    .width(ConfigData.WH_100_100)
498    .backgroundColor($r("app.color.white_bg_color"))
499    .alignItems(VerticalAlign.Center);
500  }
501}
502
503export interface WifiDialogData {
504  key: ResourceStr;
505  value: ResourceStr;
506}
507
508export interface WifiButton {
509  summary: ResourceStr;
510  opType: number;
511}
512
513/**
514 * Choose Unlock Method Dialog
515 */
516@CustomDialog
517struct apInfoDialog {
518  controller?: CustomDialogController;
519  @State dataList: WifiDialogData[] = [
520    { key: $r('app.string.wifiInfoTitleIntensity'), value: $r('app.string.wifiSigIntensityBad') },
521    { key: $r('app.string.wifiInfoTitleEncryptMethod'), value: $r('app.string.wifiEncryptMethodOpen') }
522  ];
523  private apInfo: WifiScanInfo | null = null;
524  // 0 is cancel, 1 is delete, 2 is connect
525  private buttons: WifiButton[] = [
526    { summary: $r('app.string.wifiButtonCancel'), opType: 0 },
527    { summary: $r('app.string.wifiButtonDelete'), opType: 1 },
528    { summary: $r('app.string.wifiButtonConnect'), opType: 2 }
529  ];
530
531  build() {
532    Column() {
533      Column() {
534        Row() {
535          Text(this.apInfo?.ssid)
536            .fontSize($r('app.float.font_20'))
537            .fontColor($r('sys.color.ohos_id_color_text_primary'))
538            .fontWeight(FontWeight.Medium)
539            .align(Alignment.Start)
540        }
541        .height($r("app.float.wh_value_56"))
542        .width(ConfigData.WH_100_100)
543        .padding({ left: $r("app.float.wh_value_24"), right: $r("app.float.wh_value_24") })
544
545        List() {
546          ForEach(this.dataList, (item: WifiDialogData) => {
547            ListItem() {
548              ApInfoComponent({
549                label: item.key as string,
550                value: item.value as string,
551              });
552            }
553            .height($r('app.float.wh_value_48'))
554            .onClick(() => {
555              LogUtil.info(MODULE_TAG + 'clicked ap info item');
556            })
557          })
558        }
559        .margin({ left: $r("app.float.wh_value_24"), right: $r("app.float.wh_value_24") })
560        .divider({
561          strokeWidth: $r('app.float.divider_wh'),
562          color: $r('app.color.color_E3E3E3_grey'),
563        })
564
565        List() {
566          ForEach(this.buttons, (item: WifiButton) => {
567            ListItem() {
568              Row() {
569                Text(item.summary)
570                  .fontSize($r('sys.float.ohos_id_text_size_body1'))
571                  .fontColor($r('sys.color.ohos_id_color_text_primary_activated'))
572                  .fontWeight(FontWeight.Medium)
573                  .width(ConfigData.WH_100_100)
574                  .textAlign(TextAlign.Center)
575              }
576              .width($r("app.float.dialog_118"))
577              .height($r("app.float.wh_value_40"))
578              .alignItems(VerticalAlign.Center)
579            }
580            .margin({ left: $r("app.float.wh_value_4"), right: $r("app.float.wh_value_4") })
581            .onClick(() => {
582              // 0 is cancel, 1 is delete, 2 is connect
583              if (item.opType === 0) {
584                LogUtil.info(MODULE_TAG + 'clicked ap info cancel');
585              }
586
587              if (item.opType === 1) {
588                LogUtil.info(MODULE_TAG + 'clicked ap info delete');
589                if (this.apInfo) {
590                  WifiModel.removeDeviceConfig(this.apInfo);
591                }
592                WifiModel.refreshApScanResults();
593              }
594
595              if (item.opType === 2) {
596                LogUtil.info(MODULE_TAG + 'clicked ap info connect');
597                WifiModel.disconnectWiFi();
598                if (this.apInfo) {
599                  WifiModel.connectByDeviceConfig(this.apInfo);
600                }
601                WifiModel.refreshApScanResults();
602              }
603              this.controller?.close();
604            })
605          })
606        }
607        .scrollBar(BarState.Off)
608        .margin({
609          top: $r('app.float.wh_value_8'),
610          left: $r("app.float.wh_value_16"),
611          right: $r("app.float.wh_value_16"),
612          bottom: $r("app.float.wh_value_16")
613        })
614        .height($r('app.float.wh_value_40'))
615        .listDirection(Axis.Horizontal)
616        .divider({
617          strokeWidth: $r('app.float.divider_wh'),
618          color: $r('app.color.color_E3E3E3_grey'),
619          startMargin: $r('app.float.wh_value_8'),
620          endMargin: $r('app.float.wh_value_8')
621        })
622      }
623      .height($r("app.float.wh_value_216"))
624      .borderRadius($r("app.float.radius_32"))
625      .backgroundColor($r("app.color.white_bg_color"))
626    }
627    .width(deviceTypeInfo === 'phone' || deviceTypeInfo === 'default' ? ConfigData.WH_100_100 : $r("app.float.wh_value_410"))
628    .padding(deviceTypeInfo === 'phone' || deviceTypeInfo === 'default' ? {
629      left: $r("app.float.wh_value_12"),
630      right: $r("app.float.wh_value_12")
631    } : {})
632  }
633
634  aboutToAppear(): void {
635    // gen wifi signal level
636    let intensity = this.apInfo ? WifiModel.getSignalIntensity(this.apInfo) : WiFiIntensityMap.BAD;
637    let encryptType = this.apInfo ? WifiModel.getEncryptMethod(this.apInfo) : WiFiEncryptMethodMap.OPEN;
638    this.dataList = [
639      { key: $r('app.string.wifiInfoTitleIntensity'),
640        value: genWiFiIntensity(intensity) },
641      { key: $r('app.string.wifiInfoTitleEncryptMethod'),
642        value: genWiFiEncryptMethod(encryptType) }
643    ];
644  }
645}
646
647@CustomDialog
648struct apInfoDetailsDialog {
649  controller?: CustomDialogController;
650  private apInfo: WifiScanInfo | null = null;
651  private value: string = '';
652  private frequency: string = '2.4GHz';
653  private speed: string = '144Mbps';
654  @State dataList: WifiDialogData[] = [
655    { key: $r('app.string.wifiInfoTitleStatus'),
656      value: $r('app.string.wifiSummaryConnected') },
657    { key: $r('app.string.wifiInfoTitleIntensity'),
658      value: $r('app.string.wifiSigIntensityBad') },
659    { key: $r('app.string.wifiInfoTitleSpeed'),
660      value: this.speed },
661    { key: $r('app.string.wifiInfoTitleFrequency'),
662      value: this.frequency },
663    { key: $r('app.string.wifiInfoTitleEncryptMethod'),
664      value: $r("app.string.wifiEncryptMethodOpen") }
665  ];
666  private buttons: WifiButton[] = [
667    { summary: $r('app.string.wifiButtonCancel'), opType: 0 },
668    { summary: $r('app.string.wifiButtonDelete'), opType: 2 }
669  ];
670
671  build() {
672    Column() {
673      Column() {
674        Column() {
675          QRCode(this.value)
676            .width(160)
677            .height(160)
678        }
679        .width(ConfigData.WH_100_100)
680        .margin({ top: $r("app.float.wh_48") })
681        .alignItems(HorizontalAlign.Center);
682
683        Row() {
684          Text(this.apInfo?.ssid)
685            .width(ConfigData.WH_100_100)
686            .fontSize($r('app.float.font_24'))
687            .fontColor($r('sys.color.ohos_id_color_text_primary'))
688            .fontWeight(FontWeight.Medium)
689            .textAlign(TextAlign.Center);
690        }
691        .width($r("app.float.wh_value_288"))
692        .height($r("app.float.wh_value_32"))
693        .margin({ top: $r("app.float.wh_value_28") });
694
695        Row() {
696          Text($r("app.string.wifiTipsScanInfo"))
697            .width(ConfigData.WH_100_100)
698            .fontSize($r('sys.float.ohos_id_text_size_body2'))
699            .fontColor($r('sys.color.ohos_id_color_text_secondary'))
700            .fontWeight(FontWeight.Medium)
701            .textAlign(TextAlign.Start);
702        }
703        .width($r("app.float.wh_value_250"))
704        .height($r("app.float.wh_value_19"))
705        .margin({ top: $r("app.float.wh_value_6") });
706
707        List() {
708          ForEach(this.dataList, (item: WifiDialogData) => {
709            ListItem() {
710              ApInfoComponent({
711                label: item.key as string,
712                value: item.value as string
713              });
714            }
715            .height($r('app.float.wh_value_48'))
716            .onClick(() => {
717              LogUtil.info(MODULE_TAG + 'clicked ap detail info item');
718            })
719          })
720        }
721        .margin({
722          top: $r("app.float.wh_value_16"),
723          left: $r("app.float.wh_value_24"),
724          right: $r("app.float.wh_value_24")
725        })
726        .divider({
727          strokeWidth: $r('app.float.divider_wh'),
728          color: $r('app.color.color_E3E3E3_grey'),
729        })
730
731        List() {
732          ForEach(this.buttons, (item: WifiButton) => {
733            ListItem() {
734              Row() {
735                Text(item.summary)
736                  .fontSize($r('sys.float.ohos_id_text_size_body1'))
737                  .fontColor($r('sys.color.ohos_id_color_text_primary_activated'))
738                  .fontWeight(FontWeight.Medium)
739                  .width(ConfigData.WH_100_100)
740                  .textAlign(TextAlign.Center)
741              }
742              .width($r("app.float.wh_value_160"))
743              .height($r("app.float.wh_value_40"))
744              .alignItems(VerticalAlign.Center)
745            }
746            .margin({ left: $r("app.float.wh_value_4"), right: $r("app.float.wh_value_4") })
747            .onClick(() => {
748              if (item.opType === 0) {
749                LogUtil.info(MODULE_TAG + 'clicked ap info cancel');
750              }
751
752              if (item.opType === 2) {
753                LogUtil.info(MODULE_TAG + 'clicked ap info to disconnect');
754                WifiModel.disconnectWiFi();
755                if (this.apInfo) {
756                  WifiModel.removeDeviceConfig(this.apInfo);
757                }
758                WifiModel.refreshApScanResults();
759              }
760              this.controller?.close();
761            })
762          })
763        }
764        .scrollBar(BarState.Off)
765        .margin({
766          top: $r('app.float.wh_value_8'),
767          bottom: $r('app.float.wh_value_16'),
768          left: $r("app.float.wh_value_4"),
769          right: $r("app.float.wh_value_4")
770        })
771        .height($r('app.float.wh_value_40'))
772        .listDirection(Axis.Horizontal)
773        .divider({
774          strokeWidth: $r('app.float.divider_wh'),
775          color: $r('app.color.color_E3E3E3_grey'),
776          startMargin: $r('app.float.wh_value_8'),
777          endMargin: $r('app.float.wh_value_8')
778        });
779      }
780      .alignItems(HorizontalAlign.Center)
781      .height($r("app.float.wh_value_620"))
782      .padding({ top: $r('app.float.wh_value_6') })
783      .borderRadius($r("app.float.radius_32"))
784      .backgroundColor($r("app.color.white_bg_color"))
785    }
786    .width(deviceInfo.deviceType === 'phone' ? ConfigData.WH_100_100 : $r("app.float.wh_value_410"))
787    .padding(deviceInfo.deviceType === 'phone' ? {
788      left: $r("app.float.wh_value_12"),
789      right: $r("app.float.wh_value_12")
790    } : {})
791  }
792
793  async getScanInfo() {
794    if(this.apInfo?.ssid) {
795      const deviceConfigsInfo = WifiModel.getDeviceConfigsInfo(this.apInfo.ssid)
796      if(deviceConfigsInfo) {
797        this.value = `ssid:${deviceConfigsInfo.ssid},preSharedKey:${deviceConfigsInfo.preSharedKey}`
798      }
799    }
800  }
801
802  aboutToAppear(): void {
803    // gen wifi signal level
804    let intensity = this.apInfo ? WifiModel.getSignalIntensity(this.apInfo) : WiFiIntensityMap.BAD;
805    let encryptType = this.apInfo ? WifiModel.getEncryptMethod(this.apInfo) : WiFiEncryptMethodMap.OPEN;
806    let linkInfo: wifi.WifiLinkedInfo = WifiModel.getLinkInfo();
807    if (linkInfo != undefined) {
808      this.speed = linkInfo.linkSpeed + 'Mbps';
809      //5.0GHz limit:[5180MHz,5825MHz],2.4GHz limit:[2412MHz,2484MHz]
810      LogUtil.info(MODULE_TAG + 'get frequency: ' + linkInfo.frequency);
811      this.frequency = linkInfo.frequency > 3500 ? "5GHz" : "2.4GHz";
812    }
813    this.dataList = [
814      { key: $r('app.string.wifiInfoTitleStatus'),
815        value: $r('app.string.wifiSummaryConnected') },
816      { key: $r('app.string.wifiInfoTitleIntensity'),
817        value: genWiFiIntensity(intensity) },
818      { key: $r('app.string.wifiInfoTitleSpeed'),
819        value: this.speed },
820      { key: $r('app.string.wifiInfoTitleFrequency'),
821        value: this.frequency },
822      { key: $r('app.string.wifiInfoTitleEncryptMethod'),
823        value: genWiFiEncryptMethod(encryptType) }
824    ];
825
826    this.getScanInfo()
827  }
828
829  private disconnectAction: () => void = () => {
830  };
831}
832
833@Component
834struct WiFiEntryComponent {
835  @State settingIcon: string = "";
836  @State settingTitle: string = "";
837  @State settingValue: string = "";
838  @State settingArrow: string = "";
839  @State settingUri: string = "";
840  @State titleFontColor: string = "";
841  @State isTouched: boolean = false;
842  private settingSummary: string | Resource = ''; // 状态描述
843
844  build() {
845    Row() {
846      Column() {
847        Text(this.settingTitle)
848          .fontSize($r('sys.float.ohos_id_text_size_body1'))
849          .fontColor(this.titleFontColor === "activated" ?
850          $r('sys.color.ohos_id_color_text_primary_activated') : $r('sys.color.ohos_id_color_text_primary'))
851          .fontWeight(FontWeight.Medium);
852
853        Text(this.settingSummary)
854          .fontSize($r('sys.float.ohos_id_text_size_body2'))
855          .fontColor(this.titleFontColor === "activated" ?
856          $r('sys.color.ohos_id_color_text_primary') : $r('sys.color.ohos_id_color_text_secondary'))
857          .fontWeight(FontWeight.Regular)
858          .margin({ top: $r('app.float.wh_value_8') });
859      }
860      .margin({ left: $r("app.float.wh_value_12") })
861      .alignItems(HorizontalAlign.Start)
862
863      Blank()
864
865      Image(this.settingArrow)
866        .fillColor($r("sys.color.ohos_id_color_primary"))
867        .width($r('app.float.wh_value_24'))
868        .height($r('app.float.wh_value_24'))
869        .margin({ right: $r("app.float.wh_value_12") });
870    }
871    .height($r('app.float.wh_value_64'))
872    .width(ConfigData.WH_100_100)
873    .borderRadius($r("app.float.radius_24"))
874    .alignItems(VerticalAlign.Center)
875    .backgroundColor(this.isTouched ? $r("app.color.color_D8D8D8_grey") : $r("sys.color.ohos_id_color_foreground_contrary"))
876    .onTouch((event?: TouchEvent | undefined) => {
877      if (event?.type === TouchType.Down) {
878        this.isTouched = true;
879      }
880
881      if (event?.type === TouchType.Up) {
882        this.isTouched = false;
883      }
884    })
885  }
886}
887
888@Component
889struct ConnectedWiFiEntryComponent {
890  @Link connectedWiFi: WiFiMenuModel;
891  @State titleFontColor: string = "";
892  @State isTouched: boolean = false;
893
894  build() {
895    Row() {
896      Column() {
897        Text(this.connectedWiFi.settingTitle)
898          .fontSize($r('sys.float.ohos_id_text_size_body1'))
899          .fontColor(this.titleFontColor === "activated" ?
900          $r('sys.color.ohos_id_color_text_primary_activated') : $r('sys.color.ohos_id_color_text_primary'))
901          .fontWeight(FontWeight.Medium);
902
903        Text(genWiFiStatusSummary(this.connectedWiFi.settingSummary))
904          .fontSize($r('sys.float.ohos_id_text_size_body2'))
905          .fontColor(this.titleFontColor === "activated" ?
906          $r('sys.color.ohos_id_color_text_primary') : $r('sys.color.ohos_id_color_text_secondary'))
907          .fontWeight(FontWeight.Regular)
908          .margin({ top: $r('app.float.wh_value_8') });
909      }
910      .margin({ left: $r("app.float.wh_value_12") })
911      .alignItems(HorizontalAlign.Start)
912
913      Blank()
914
915      Image(this.connectedWiFi.settingArrow)
916        .fillColor($r("sys.color.ohos_id_color_primary"))
917        .width($r('app.float.wh_value_24'))
918        .height($r('app.float.wh_value_24'))
919        .margin({ right: $r("app.float.wh_value_12") });
920    }
921    .height($r('app.float.wh_value_64'))
922    .width(ConfigData.WH_100_100)
923    .borderRadius($r("app.float.radius_24"))
924    .alignItems(VerticalAlign.Center)
925    .backgroundColor(this.isTouched ? $r("app.color.color_D8D8D8_grey") : $r("sys.color.ohos_id_color_foreground_contrary"))
926    .onTouch((event?: TouchEvent | undefined) => {
927      if (event?.type === TouchType.Down) {
928        this.isTouched = true;
929      }
930      if (event?.type === TouchType.Up) {
931        this.isTouched = false;
932      }
933    })
934  }
935}
936