• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2021-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 { backBar } from '../common/components/backBar';
17import common from '@ohos.app.ability.common';
18import bundleManager from '@ohos.bundle.bundleManager';
19import abilityAccessCtrl from '@ohos.abilityAccessCtrl';
20import { BusinessError } from '@ohos.base';
21import { showSubPermissionsGroup } from '../common/model/permissionGroup';
22import { Log, getPermissionLabel } from '../common/utils/utils';
23import Constants from '../common/utils/constant';
24import { MediaDocObj, RouterParams3, AppInfo, CheckboxInfo } from '../common/model/typedef';
25import { GlobalContext } from '../common/utils/globalContext';
26import { Permission, PermissionGroup } from '../common/model/definition';
27import { PermissionUtils } from '../common/utils/permissionUtils';
28
29const showPrecise: number[] = [Constants.PERMISSION_ALLOW, Constants.PERMISSION_ALLOWED_ONLY_DURING_USE];
30let accessTokenId: number = 0;
31let reqPermissionInfo: bundleManager.ReqPermissionDetail;
32
33@Entry
34@Component
35struct mediaDocumentPage {
36  private backTitle: ResourceStr = (this.getUIContext().getRouter().getParams() as RouterParams3).backTitle;
37  private permissions: Permission[] = (this.getUIContext().getRouter().getParams() as RouterParams3).permission;
38  private tokenId: number = (this.getUIContext().getRouter().getParams() as RouterParams3).tokenId;
39  @State currentGroup: string = GlobalContext.load('currentPermissionGroup');
40  @State folderStatus: boolean[] = GlobalContext.load('folderStatus');
41  @State refresh: boolean = false;
42  @State selected: number = 0; // Permission status array
43  @State accurateIsOn: boolean = false;
44  @State isRefreshReason: number = 0;
45
46  build() {
47    Column() {
48      GridRow({ gutter: Constants.GUTTER, columns: {
49        xs: Constants.XS_COLUMNS, sm: Constants.SM_COLUMNS, md: Constants.MD_COLUMNS, lg: Constants.LG_COLUMNS } }) {
50        GridCol({
51          span: { xs: Constants.XS_SPAN, sm: Constants.SM_SPAN, md: Constants.MD_SPAN, lg: Constants.LG_SPAN },
52          offset: { xs: Constants.XS_OFFSET, sm: Constants.SM_OFFSET, md: Constants.MD_OFFSET, lg: Constants.LG_OFFSET }
53        }) {
54          Row() {
55            Column() {
56              Row() {
57                backBar({ title: JSON.stringify(this.backTitle), recordable: false })
58              }
59              Row() {
60                Column() {
61                  mediaDocumentItem({
62                    selected: $selected,
63                    accurateIsOn: $accurateIsOn,
64                    isRefreshReason: $isRefreshReason,
65                    folderStatus: $folderStatus
66                  })
67                }.width(Constants.FULL_WIDTH)
68              }
69              .margin({ top: Constants.TITLE_MARGIN_BOTTOM })
70              .layoutWeight(Constants.LAYOUT_WEIGHT)
71            }
72          }
73          .height(Constants.FULL_HEIGHT)
74          .width(Constants.FULL_WIDTH)
75          .backgroundColor($r('sys.color.background_secondary'))
76        }
77      }.backgroundColor($r('sys.color.background_secondary'))
78    }
79  }
80
81  onPageShow() {
82    if (this.refresh) {
83      this.refreshStatus();
84    }
85    this.refresh = true;
86  }
87
88  refreshStatus() {
89    if (reqPermissionInfo) {
90      this.isRefreshReason ++;
91    }
92    Log.info('Refresh permission status');
93    let isGranted = this.currentGroup === 'LOCATION' ? Constants.PERMISSION_BAN : Constants.PERMISSION_ALLOW;
94    let folderStatus = [false, false, false];
95    let atManager = abilityAccessCtrl.createAtManager();
96    for (let i = 0; i < this.permissions.length; i++) {
97      let permission = this.permissions[i];
98      if (this.currentGroup === 'LOCATION') {
99        continue;
100      }
101      let res = atManager.verifyAccessTokenSync(this.tokenId, permission);
102      if (res != abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
103        isGranted = Constants.PERMISSION_BAN;
104      }
105      if (this.currentGroup === 'FOLDER' && res === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
106        switch (permission) {
107          case Permission.READ_WRITE_DOWNLOAD_DIRECTORY:
108            folderStatus[0] = true;
109            break;
110          case Permission.READ_WRITE_DESKTOP_DIRECTORY:
111            folderStatus[1] = true;
112            break;
113          case Permission.READ_WRITE_DOCUMENTS_DIRECTORY:
114            folderStatus[2] = true;
115            break;
116        }
117      }
118    }
119    Log.info('isGranted: ' + JSON.stringify(isGranted));
120    this.folderStatus = folderStatus;
121
122    this.refreshSelected(isGranted);
123  }
124
125  refreshSelected(isGranted: number) {
126    this.selected = isGranted;
127    if (this.currentGroup === 'PASTEBOARD') {
128      try {
129        let acManager = abilityAccessCtrl.createAtManager();
130        acManager.getPermissionFlags(this.tokenId, Permission.READ_PASTEBOARD).then(flag => {
131          flag === Constants.PERMISSION_ALLOW_THIS_TIME ? this.selected = Constants.PERMISSION_ONLY_THIS_TIME : null;
132        })
133      } catch (err) {
134        Log.error('getPermissionFlags error: ' + JSON.stringify(err));
135      }
136    }
137    if (this.currentGroup === 'LOCATION') {
138      try {
139        let acManager = abilityAccessCtrl.createAtManager();
140        let fuzzyState = acManager.verifyAccessTokenSync(this.tokenId, Permission.APPROXIMATELY_LOCATION);
141        fuzzyState === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED ?
142          this.selected = Constants.PERMISSION_ALLOWED_ONLY_DURING_USE : null;
143        let accurateStatus = acManager.verifyAccessTokenSync(this.tokenId, Permission.LOCATION);
144        this.accurateIsOn = (accurateStatus == abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) ? true : false;
145        let backgroundState = acManager.verifyAccessTokenSync(this.tokenId, Permission.LOCATION_IN_BACKGROUND);
146        backgroundState === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED ?
147          this.selected = Constants.PERMISSION_ALLOW : null;
148        acManager.getPermissionFlags(this.tokenId, Permission.APPROXIMATELY_LOCATION ).then(flag => {
149          flag === Constants.PERMISSION_ALLOW_THIS_TIME ? this.selected = Constants.PERMISSION_ONLY_THIS_TIME : null;
150        })
151      } catch (err) {
152        Log.error('change location status error: ' + JSON.stringify(err));
153      }
154    }
155  }
156}
157
158@Component
159struct mediaDocumentItem {
160  private context = this.getUIContext().getHostContext() as common.UIAbilityContext;
161  private backTitle: ResourceStr = (this.getUIContext().getRouter().getParams() as RouterParams3).backTitle;
162  private bundleName: string = (this.getUIContext().getRouter().getParams() as RouterParams3).bundleName;
163  private permissions: Permission[] = (this.getUIContext().getRouter().getParams() as RouterParams3).permission;
164  private status: number = (this.getUIContext().getRouter().getParams() as RouterParams3).status;
165  @State currentGroup: PermissionGroup = GlobalContext.load('currentPermissionGroup');
166  @State applicationInfo: AppInfo = GlobalContext.load('applicationInfo');
167  @Link folderStatus: boolean[];
168  @State mediaDocListItem: MediaDocObj[] = []; // Permission information array
169  @Link selected: number;
170  @Link accurateIsOn: boolean;
171  @State isRisk: boolean = false; // Whether it is a risky application
172  @State noForeground: boolean = false;
173  @State isTouch: number = -1;
174  @State isCheck: string = '';
175  @State reason: string = '';
176  @State label: string = '';
177  @State version: string = '';
178  @State permissionLabels: Array<ResourceStr> = [];
179  @Link @Watch('updateReason') isRefreshReason: number;
180
181  /**
182   * Update reason
183   */
184  updateReason() {
185    bundleManager.getApplicationInfo(
186      this.applicationInfo.bundleName, bundleManager.ApplicationFlag.GET_APPLICATION_INFO_DEFAULT
187    ).then(appInfo => {
188      let bundleContext = this.context.createBundleContext(this.bundleName)
189      bundleContext.resourceManager.getStringValue(appInfo.labelId, (error, value) => {
190        if (value) {
191          this.applicationInfo.label = value;
192          GlobalContext.store('applicationInfo', this.applicationInfo);
193          this.label = value
194        }
195      })
196    }).catch((error: BusinessError) => {
197      Log.error('getApplicationInfo error: ' + JSON.stringify(error));
198    })
199    let context = this.context.createModuleContext(this.bundleName, reqPermissionInfo.moduleName);
200    context.resourceManager.getStringValue(reqPermissionInfo.reasonId).then(value => {
201      if (value !== undefined) {
202        this.reason = value.slice(Constants.START_SUBSCRIPT, Constants.END_SUBSCRIPT);
203      }
204    })
205  }
206
207  getCheckboxInfo(permission: Permission): CheckboxInfo {
208    switch (permission) {
209      case Permission.READ_WRITE_DOWNLOAD_DIRECTORY:
210        return new CheckboxInfo($r('app.string.Download_folder'), 0);
211      case Permission.READ_WRITE_DESKTOP_DIRECTORY:
212        return new CheckboxInfo($r('app.string.Desktop_folder'), 1);
213      case Permission.READ_WRITE_DOCUMENTS_DIRECTORY:
214        return new CheckboxInfo($r('app.string.Document_folder'), 2);
215      default:
216        return new CheckboxInfo($r('app.string.Download_folder'), 0);
217    }
218  }
219
220  getMediaDocList() {
221    if (this.currentGroup == 'PASTEBOARD') {
222      this.mediaDocListItem.push(
223        new MediaDocObj($r('app.string.per_use_query'), this.permissions, Constants.PERMISSION_ONLY_THIS_TIME)
224      );
225      this.mediaDocListItem.push(
226        new MediaDocObj($r('app.string.always_allow'), this.permissions, Constants.PERMISSION_ALLOW)
227      );
228    } else if (this.currentGroup == 'LOCATION') {
229      this.selected = GlobalContext.load('locationStatus');
230      this.mediaDocListItem.push(
231        new MediaDocObj($r('app.string.per_inquiry'), this.permissions, Constants.PERMISSION_ONLY_THIS_TIME)
232      );
233      if (this.permissions.includes(Permission.LOCATION_IN_BACKGROUND)) {
234        this.mediaDocListItem.push(
235          new MediaDocObj($r('app.string.always_allow'), this.permissions, Constants.PERMISSION_ALLOW)
236        );
237      }
238      if (this.permissions.includes(Permission.APPROXIMATELY_LOCATION)) {
239        this.mediaDocListItem.push(
240          new MediaDocObj(
241            $r('app.string.allowed_only_during_use'),
242            [Permission.APPROXIMATELY_LOCATION],
243            Constants.PERMISSION_ALLOWED_ONLY_DURING_USE
244          )
245        );
246      } else {
247        this.noForeground = true;
248      }
249    } else {
250      this.mediaDocListItem.push(
251        new MediaDocObj($r('app.string.allow'), this.permissions, Constants.PERMISSION_ALLOW)
252      );
253    }
254    this.mediaDocListItem.push(
255      new MediaDocObj($r('app.string.ban'), this.permissions, Constants.PERMISSION_BAN)
256    );
257  }
258
259  getReason() {
260    this.label = this.applicationInfo.label;
261    if (showSubPermissionsGroup.indexOf(this.currentGroup) != -1) {
262      this.permissions.forEach((permission, idx) => {
263        if (idx > 0) {
264          this.permissionLabels.push($r('app.string.and'))
265        }
266        let label = getPermissionLabel(permission)
267        this.permissionLabels.push(label);
268      })
269    }
270    let hasReason = false;
271    bundleManager.getBundleInfo(this.bundleName, bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_REQUESTED_PERMISSION)
272      .then(info => {
273        this.permissions.forEach(permission => {
274          info.reqPermissionDetails.forEach(reqPermissionDetail => {
275            if (reqPermissionDetail.name == permission) {
276              Log.info('reqPermissionDetail: ' + JSON.stringify(reqPermissionDetail));
277              let context = this.context.createModuleContext(this.bundleName, reqPermissionDetail.moduleName);
278              context.resourceManager.getStringValue(reqPermissionDetail.reasonId).then(value => {
279                if (value !== undefined && !hasReason) {
280                  this.reason = value.slice(Constants.START_SUBSCRIPT, Constants.END_SUBSCRIPT);
281                  reqPermissionInfo = reqPermissionDetail;
282                  hasReason = true;
283                }
284              })
285            }
286          })
287        })
288      })
289  }
290
291  /**
292   * Lifecycle function, executed when the page is initialized
293   */
294  aboutToAppear() {
295    this.selected = this.status;
296    this.getMediaDocList();
297    this.getReason();
298
299    try {
300      bundleManager.getBundleInfo(this.bundleName, bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION)
301        .then(res => {
302          this.version = res.versionName;
303          accessTokenId = res.appInfo.accessTokenId;
304          let acManager = abilityAccessCtrl.createAtManager();
305          let accurateStatus = acManager.verifyAccessTokenSync(res.appInfo.accessTokenId, Permission.LOCATION);
306          this.accurateIsOn = (accurateStatus == abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) ? true : false;
307          let getFlagPermission =
308            this.currentGroup === 'LOCATION' ? Permission.APPROXIMATELY_LOCATION : this.permissions[0];
309          acManager.getPermissionFlags(res.appInfo.accessTokenId, getFlagPermission).then((flag) => {
310            Log.info(`getPermissionFlags success, data->${JSON.stringify(flag)}`);
311            this.isRisk = (flag == Constants.PERMISSION_POLICY_FIXED) ? true : false;
312            flag === Constants.PERMISSION_ALLOW_THIS_TIME ? this.selected = Constants.PERMISSION_ONLY_THIS_TIME : null;
313          })
314        }).catch((error: BusinessError) => {
315          Log.error('bundle.getBundleInfo failed. Cause: ' + JSON.stringify(error));
316        })
317    } catch (err) {
318      Log.error('bundle.getBundleInfo failed. Cause: ' + JSON.stringify(err));
319    }
320  }
321
322  build() {
323    Column() {
324      Row() {
325        Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
326          Image(this.applicationInfo.icon)
327            .width(Constants.TERTIARY_IMAGE_WIDTH)
328            .height(Constants.TERTIARY_IMAGE_HEIGHT)
329            .margin({ left: Constants.TERTIARY_IMAGE_MARGIN_LEFT, right: Constants.TERTIARY_IMAGE_MARGIN_RIGHT })
330          Column() {
331            Row() {
332              Text(this.label)
333                .maxLines(Constants.MAXIMUM_HEADER_LINES)
334                .textOverflow({ overflow: TextOverflow.Ellipsis })
335                .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE)
336                .fontColor($r('sys.color.font_primary'))
337                .fontWeight(FontWeight.Bold)
338                .textAlign(TextAlign.Start)
339            }
340            .width(Constants.TERTIARY_HALF_WIDTH)
341            .margin({ bottom: Constants.TERTIARY_LABEL_MARGIN_BOTTOM })
342            Row() {
343              Text($r('app.string.version'))
344                .fontSize(Constants.TEXT_SMALL_FONT_SIZE)
345                .fontColor($r('sys.color.font_secondary'))
346                .textAlign(TextAlign.Start)
347              Text(this.version)
348                .fontSize(Constants.TEXT_SMALL_FONT_SIZE)
349                .fontColor($r('sys.color.font_secondary'))
350                .textAlign(TextAlign.Start)
351            }
352            .width(Constants.TERTIARY_HALF_WIDTH)
353          }
354        }.margin({ left: Constants.TERTIARY_MARGIN_LEFT })
355      }
356      if (this.reason || this.permissionLabels.length > 0) {
357        Row() {
358          Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
359            Row() {
360              Text() {
361                if (this.permissionLabels.length > 0) {
362                  ForEach(this.permissionLabels, (item: ResourceStr) => {
363                    Span(item)
364                  })
365                  Span(this.reason ? $r('app.string.comma') : $r('app.string.period'))
366                }
367                Span(this.reason)
368              }
369                .fontSize(Constants.TEXT_SMALL_FONT_SIZE)
370                .fontColor($r('sys.color.icon_secondary'))
371                .textAlign(TextAlign.Start)
372            }.margin({ left: Constants.TERTIARY_IMAGE_MARGIN_LEFT, right: Constants.TERTIARY_IMAGE_MARGIN_RIGHT })
373          }
374        }
375        .margin({
376          top: Constants.TERTIARY_ROW_MARGIN_TOP,
377          left: Constants.DEFAULT_MARGIN_START,
378          bottom: Constants.DEFAULT_MARGIN_BOTTOM
379        })
380      }
381      if (this.isRisk) {
382        Row() {
383          Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
384            Row() {
385              Image($r('app.media.ic_public_fail'))
386                .fillColor($r('sys.color.icon_secondary'))
387                .width(Constants.TERTIARY_RADIO_IMAGE_WIDTH)
388                .height(Constants.TERTIARY_RADIO_IMAGE_HEIGHT)
389                .margin({ right: Constants.TERTIARY_IMAGE_MARGIN_RIGHT })
390              Text($r('app.string.risk_warning'))
391                .fontColor($r('sys.color.font_primary'))
392                .fontSize($r('sys.float.ohos_id_text_size_body1'))
393                .fontWeight(FontWeight.Regular)
394            }.margin({ left: Constants.DEFAULT_PADDING_START, right: Constants.DEFAULT_PADDING_END })
395          }
396        }.backgroundColor($r('sys.color.interactive_click'))
397        .borderRadius($r('sys.float.ohos_id_corner_radius_default_l'))
398        .padding({ top: Constants.DEFAULT_PADDING_TOP, bottom: Constants.DEFAULT_PADDING_BOTTOM })
399        .margin({ left: Constants.DEFAULT_MARGIN_START, right: Constants.DEFAULT_MARGIN_END })
400      }
401      Row() {
402        Text() {
403          Span(this.backTitle)
404          Span($r('app.string.access_permission'))
405        }
406          .fontSize(Constants.TEXT_SMALL_FONT_SIZE)
407          .fontColor($r('sys.color.icon_secondary'))
408          .fontWeight(FontWeight.Medium)
409          .textAlign(TextAlign.Start)
410          .lineHeight(Constants.SUBTITLE_LINE_HEIGHT)
411      }.width(Constants.FULL_WIDTH)
412      .constraintSize({ minHeight: Constants.SUBTITLE_MIN_HEIGHT })
413      .padding({ top: Constants.SUBTITLE_PADDING_TOP, bottom: Constants.SUBTITLE_PADDING_BOTTOM,
414        left: Constants.TERTIARY_TEXT_MARGIN_LEFT, right: Constants.TERTIARY_IMAGE_MARGIN_RIGHT})
415      Column() {
416        List() {
417          if (this.currentGroup === 'FOLDER') {
418            ForEach(this.permissions, (permission: Permission) => {
419              ListItem() {
420                Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
421                  Row() {
422                    Text(this.getCheckboxInfo(permission).label)
423                      .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE)
424                      .fontColor($r('sys.color.font_primary'))
425                      .fontWeight(FontWeight.Medium)
426                      .flexGrow(Constants.FLEX_GROW)
427                    Checkbox()
428                      .select(this.folderStatus[this.getCheckboxInfo(permission).index])
429                      .hitTestBehavior(HitTestMode.None)
430                  }
431                  .width(Constants.FULL_WIDTH)
432                  .height(Constants.LISTITEM_ROW_HEIGHT)
433                  .onClick(() => {
434                    if (this.folderStatus[this.getCheckboxInfo(permission).index]) {
435                      PermissionUtils.revokePermissionWithResult(permission, Constants.PERMISSION_FLAG, accessTokenId);
436                      this.folderStatus[this.getCheckboxInfo(permission).index] = false;
437                    } else {
438                      PermissionUtils.grantPermissionWithResult(permission, Constants.PERMISSION_FLAG, accessTokenId);
439                      this.folderStatus[this.getCheckboxInfo(permission).index] = true;
440                    }
441                  })
442                }
443              }
444              .padding({
445                left: $r('sys.float.ohos_id_card_margin_start'),
446                right: $r('sys.float.ohos_id_card_margin_end')
447              })
448              .borderRadius($r('sys.float.ohos_id_corner_radius_default_l'))
449              .margin({ top: Constants.TERTIARY_LISTITEM_MARGIN_TOP })
450              .linearGradient((this.isCheck === permission) ? {
451                angle: 90,
452                direction: GradientDirection.Right,
453                colors: [['#DCEAF9', 0.0], ['#FAFAFA', 1.0]]
454              } : {
455                angle: 90,
456                direction: GradientDirection.Right,
457                colors: []
458              })
459              .onTouch(event => {
460                if (event === undefined) {
461                  return;
462                }
463                if (event.type === TouchType.Down) {
464                  this.isCheck = permission;
465                }
466                if (event.type === TouchType.Up) {
467                  this.isCheck = '';
468                }
469              })
470            }, (permission: Permission) => JSON.stringify(permission))
471          } else {
472            ForEach(this.mediaDocListItem, (item: MediaDocObj) => {
473              ListItem() {
474                Column() {
475                  Row() {
476                    Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
477                      Row() {
478                        Text(item.name)
479                          .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE)
480                          .fontColor($r('sys.color.font_primary'))
481                          .fontWeight(FontWeight.Medium)
482                          .flexGrow(Constants.FLEX_GROW)
483                        Radio({ value: 'Radio', group: 'radioGroup' })
484                          .checked(item.index === this.selected)
485                          .hitTestBehavior(HitTestMode.None)
486                          .height(Constants.SHAPE_DIA)
487                          .width(Constants.SHAPE_DIA)
488                      }
489                      .width(Constants.FULL_WIDTH)
490                      .height(Constants.LISTITEM_ROW_HEIGHT)
491                      .onClick(() => {
492                        this.selected = item.index;
493                        item.permissions.forEach((permission): boolean => {
494                          if (item.index === Constants.PERMISSION_ALLOW) {
495                            if (permission === Permission.LOCATION) {
496                              return false;
497                            }
498                            PermissionUtils.grantPermissionWithResult(
499                              permission, Constants.PERMISSION_FLAG, accessTokenId
500                            );
501                          } else if (item.index === Constants.PERMISSION_BAN) {
502                            if (permission == Permission.LOCATION && this.accurateIsOn) {
503                              PermissionUtils.revokePermissionWithResult(
504                                permission, Constants.PERMISSION_FLAG, accessTokenId
505                              );
506                              this.accurateIsOn = false;
507                            } else {
508                              PermissionUtils.revokePermissionWithResult(
509                                permission, Constants.PERMISSION_FLAG, accessTokenId
510                              );
511                            }
512                          } else if (item.index === Constants.PERMISSION_ONLY_THIS_TIME) {
513                            if (permission === Permission.LOCATION) {
514                              return false;
515                            }
516                            PermissionUtils.revokePermissionWithResult(
517                              permission, Constants.PERMISSION_ALLOW_THIS_TIME, accessTokenId
518                            );
519                          } else if (item.index === Constants.PERMISSION_ALLOWED_ONLY_DURING_USE) {
520                            PermissionUtils.grantPermissionWithResult(
521                              permission, Constants.PERMISSION_FLAG, accessTokenId
522                            );
523                            PermissionUtils.revokePermissionWithResult(
524                              Permission.LOCATION_IN_BACKGROUND, Constants.PERMISSION_FLAG, accessTokenId
525                            );
526                          }
527                          return true;
528                        })
529                      })
530                    }
531                  }
532                }
533              }
534              .padding({
535                left: $r('sys.float.ohos_id_card_margin_start'),
536                right: $r('sys.float.ohos_id_card_margin_end')
537              })
538              .borderRadius($r('sys.float.ohos_id_corner_radius_default_l'))
539              .linearGradient((this.isTouch === item.index) ? {
540                  angle: 90,
541                  direction: GradientDirection.Right,
542                  colors: [['#DCEAF9', 0.0], ['#FAFAFA', 1.0]]
543                } : {
544                  angle: 90,
545                  direction: GradientDirection.Right,
546                  colors: []
547                })
548              .onTouch(event => {
549                if (event === undefined) {
550                  return;
551                }
552                if (event.type === TouchType.Down) {
553                  this.isTouch = item.index;
554                }
555                if (event.type === TouchType.Up) {
556                  this.isTouch = -1;
557                }
558              })
559              .margin({ top: Constants.TERTIARY_LISTITEM_MARGIN_TOP })
560            }, (item: MediaDocObj) => JSON.stringify(item))
561          }
562        }
563        .borderRadius($r('sys.float.ohos_id_corner_radius_card'))
564        .backgroundColor($r('sys.color.comp_background_list_card'))
565        .padding(Constants.LIST_PADDING_TOP)
566        .divider({
567          strokeWidth: Constants.DIVIDER,
568          color: $r('sys.color.comp_divider'),
569          startMargin: Constants.DEFAULT_MARGIN_START,
570          endMargin: Constants.DEFAULT_MARGIN_END
571        })
572
573        if (this.permissions.includes(Permission.LOCATION) && showPrecise.includes(this.selected)) {
574          Column() {
575            Row() {
576              Text($r('app.string.precise_location'))
577                .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE)
578                .fontColor($r('sys.color.font_primary'))
579                .fontWeight(FontWeight.Medium)
580                .flexGrow(Constants.FLEX_GROW)
581              Toggle({ type: ToggleType.Switch, isOn: this.accurateIsOn })
582                .selectedColor($r('sys.color.icon_emphasize'))
583                .switchPointColor($r('sys.color.comp_background_primary_contrary'))
584                .onChange((isOn: boolean) => {
585                  if (isOn) {
586                    PermissionUtils.grantPermissionWithResult(
587                      Permission.LOCATION, Constants.PERMISSION_FLAG, accessTokenId
588                    );
589                    this.accurateIsOn = true;
590                  } else {
591                    PermissionUtils.revokePermissionWithResult(
592                      Permission.LOCATION, Constants.PERMISSION_FLAG, accessTokenId
593                    );
594                    this.accurateIsOn = false;
595                  }
596                })
597                .padding({ right: 0 })
598            }.width(Constants.FULL_WIDTH)
599            .height(Constants.LISTITEM_ROW_HEIGHT)
600          }.margin({ top: Constants.LOCATION_MARGIN_TOP, bottom: Constants.LOCATION_MARGIN_BOTTOM })
601          .padding({
602            left: Constants.DEFAULT_PADDING_START,
603            right: Constants.DEFAULT_PADDING_END,
604            top: Constants.TERTIARY_LIST_PADDING_TOP,
605            bottom: Constants.TERTIARY_LIST_PADDING_BOTTOM
606          })
607          .borderRadius($r('sys.float.ohos_id_corner_radius_card'))
608          .backgroundColor($r('sys.color.comp_background_list_card'))
609
610          Row() {
611            Text($r('app.string.get_the_exact_position'))
612              .fontSize(Constants.TEXT_SMALL_FONT_SIZE)
613              .fontColor($r('sys.color.font_secondary'))
614              .lineHeight(Constants.TEXT_SMALL_LINE_HEIGHT)
615          }.width(Constants.FULL_WIDTH)
616          .padding({
617            left: Constants.DEFAULT_PADDING_START,
618            right: Constants.DEFAULT_PADDING_END,
619          })
620        }
621      }
622      .padding({
623        left: Constants.LIST_PADDING_LEFT,
624        right: Constants.LIST_PADDING_LEFT
625      })
626      .width(Constants.FULL_WIDTH)
627      .height(Constants.FULL_HEIGHT)
628      .enabled(!this.isRisk && !this.noForeground)
629      .opacity((!this.isRisk && !this.noForeground) ? 1 : $r('sys.float.ohos_id_alpha_disabled'))
630    }
631    .width(Constants.FULL_WIDTH)
632  }
633}
634