• 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 router from '@ohos.router';
18import common from '@ohos.app.ability.common';
19import bundleManager from '@ohos.bundle.bundleManager';
20import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl';
21import { BusinessError } from '@ohos.base';
22import { showSubPermissionsGroup } from '../common/model/permissionGroup';
23import { Log, getPermissionLabel } from '../common/utils/utils';
24import Constants from '../common/utils/constant';
25import { MediaDocObj, RouterParams3, AppInfo, CheckboxInfo } from '../common/model/typedef';
26import { GlobalContext } from '../common/utils/globalContext';
27import { Permission, PermissionGroup } from '../common/model/definition';
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 = (router.getParams() as RouterParams3).backTitle;
37  private permissions: Permissions[] = (router.getParams() as RouterParams3).permission;
38  private tokenId: number = (router.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 = true;
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 = getContext(this) as common.UIAbilityContext;
161  private backTitle: ResourceStr = (router.getParams() as RouterParams3).backTitle;
162  private bundleName: string = (router.getParams() as RouterParams3).bundleName;
163  private permissions: Permission[] = (router.getParams() as RouterParams3).permission;
164  private status: number = (router.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   * Grant permissions to the app
183   * @param {Number} accessTokenId
184   * @param {String} permission permission name
185   */
186  grantUserGrantedPermission(accessTokenId: number, permission: Permissions) {
187    abilityAccessCtrl.createAtManager().grantUserGrantedPermission(accessTokenId, permission, Constants.PERMISSION_FLAG)
188      .then(() => {})
189      .catch((error: BusinessError) => {
190        Log.error('grantUserGrantedPermission failed. Cause: ' + JSON.stringify(error));
191      })
192  }
193
194  /**
195   * Deauthorize the app
196   * @param {Number} accessTokenId
197   * @param {String} permission permission name
198   */
199  revokeUserGrantedPermission(accessTokenId: number, permission: Permissions, flag: number) {
200    abilityAccessCtrl.createAtManager().revokeUserGrantedPermission(accessTokenId, permission, flag)
201      .then(() => {})
202      .catch((error: BusinessError) => {
203        Log.error('revokeUserGrantedPermission failed. Cause: ' + JSON.stringify(error));
204      })
205  }
206
207  /**
208   * Update reason
209   */
210  updateReason() {
211    bundleManager.getApplicationInfo(
212      this.applicationInfo.bundleName, bundleManager.ApplicationFlag.GET_APPLICATION_INFO_DEFAULT
213    ).then(appInfo => {
214      let bundleContext = this.context.createBundleContext(this.bundleName)
215      bundleContext.resourceManager.getStringValue(appInfo.labelId, (error, value) => {
216        if (value) {
217          this.applicationInfo.label = value;
218          GlobalContext.store('applicationInfo', this.applicationInfo);
219          this.label = value
220        }
221      })
222    }).catch((error: BusinessError) => {
223      Log.error('getApplicationInfo error: ' + JSON.stringify(error));
224    })
225    let context = this.context.createModuleContext(this.bundleName, reqPermissionInfo.moduleName);
226    context.resourceManager.getStringValue(reqPermissionInfo.reasonId).then(value => {
227      if (value !== undefined) {
228        this.reason = value.slice(Constants.START_SUBSCRIPT, Constants.END_SUBSCRIPT);
229      }
230    })
231  }
232
233  getCheckboxInfo(permission: Permissions): CheckboxInfo {
234    switch (permission) {
235      case Permission.READ_WRITE_DOWNLOAD_DIRECTORY:
236        return new CheckboxInfo($r('app.string.Download_folder'), 0);
237      case Permission.READ_WRITE_DESKTOP_DIRECTORY:
238        return new CheckboxInfo($r('app.string.Desktop_folder'), 1);
239      case Permission.READ_WRITE_DOCUMENTS_DIRECTORY:
240        return new CheckboxInfo($r('app.string.Document_folder'), 2);
241      default:
242        return new CheckboxInfo($r('app.string.Download_folder'), 0);
243    }
244  }
245
246  getMediaDocList() {
247    if (this.currentGroup == 'PASTEBOARD') {
248      this.mediaDocListItem.push(
249        new MediaDocObj($r('app.string.per_use_query'), this.permissions, Constants.PERMISSION_ONLY_THIS_TIME)
250      );
251      this.mediaDocListItem.push(
252        new MediaDocObj($r('app.string.always_allow'), this.permissions, Constants.PERMISSION_ALLOW)
253      );
254    } else if (this.currentGroup == 'LOCATION') {
255      this.selected = GlobalContext.load('locationStatus');
256      this.mediaDocListItem.push(
257        new MediaDocObj($r('app.string.per_inquiry'), this.permissions, Constants.PERMISSION_ONLY_THIS_TIME)
258      );
259      if (this.permissions.includes(Permission.LOCATION_IN_BACKGROUND)) {
260        this.mediaDocListItem.push(
261          new MediaDocObj($r('app.string.always_allow'), this.permissions, Constants.PERMISSION_ALLOW)
262        );
263      }
264      if (this.permissions.includes(Permission.APPROXIMATELY_LOCATION)) {
265        this.mediaDocListItem.push(
266          new MediaDocObj(
267            $r('app.string.allowed_only_during_use'),
268            [Permission.APPROXIMATELY_LOCATION],
269            Constants.PERMISSION_ALLOWED_ONLY_DURING_USE
270          )
271        );
272      } else {
273        this.noForeground = true;
274      }
275    } else {
276      this.mediaDocListItem.push(
277        new MediaDocObj($r('app.string.allow'), this.permissions, Constants.PERMISSION_ALLOW)
278      );
279    }
280    this.mediaDocListItem.push(
281      new MediaDocObj($r('app.string.ban'), this.permissions, Constants.PERMISSION_BAN)
282    );
283  }
284
285  getReason() {
286    this.label = this.applicationInfo.label;
287    if (showSubPermissionsGroup.indexOf(this.currentGroup) != -1) {
288      this.permissions.forEach((permission, idx) => {
289        if (idx > 0) {
290          this.permissionLabels.push($r('app.string.and'))
291        }
292        let label = getPermissionLabel(permission)
293        this.permissionLabels.push(label);
294      })
295    }
296    let hasReason = false;
297    bundleManager.getBundleInfo(this.bundleName, bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_REQUESTED_PERMISSION)
298      .then(info => {
299        this.permissions.forEach(permission => {
300          info.reqPermissionDetails.forEach(reqPermissionDetail => {
301            if (reqPermissionDetail.name == permission) {
302              Log.info('reqPermissionDetail: ' + JSON.stringify(reqPermissionDetail));
303              let context = this.context.createModuleContext(this.bundleName, reqPermissionDetail.moduleName);
304              context.resourceManager.getStringValue(reqPermissionDetail.reasonId).then(value => {
305                if (value !== undefined && !hasReason) {
306                  this.reason = value.slice(Constants.START_SUBSCRIPT, Constants.END_SUBSCRIPT);
307                  reqPermissionInfo = reqPermissionDetail;
308                  hasReason = true;
309                }
310              })
311            }
312          })
313        })
314      })
315  }
316
317  /**
318   * Lifecycle function, executed when the page is initialized
319   */
320  aboutToAppear() {
321    this.selected = this.status;
322    this.getMediaDocList();
323    this.getReason();
324
325    try {
326      bundleManager.getBundleInfo(this.bundleName, bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION)
327        .then(res => {
328          this.version = res.versionName;
329          accessTokenId = res.appInfo.accessTokenId;
330          let acManager = abilityAccessCtrl.createAtManager();
331          let accurateStatus = acManager.verifyAccessTokenSync(res.appInfo.accessTokenId, Permission.LOCATION);
332          this.accurateIsOn = (accurateStatus == abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) ? true : false;
333          let getFlagPermission =
334            this.currentGroup === 'LOCATION' ? Permission.APPROXIMATELY_LOCATION : this.permissions[0];
335          acManager.getPermissionFlags(res.appInfo.accessTokenId, getFlagPermission).then((flag) => {
336            Log.info(`getPermissionFlags success, data->${JSON.stringify(flag)}`);
337            this.isRisk = (flag == Constants.PERMISSION_POLICY_FIXED) ? true : false;
338            flag === Constants.PERMISSION_ALLOW_THIS_TIME ? this.selected = Constants.PERMISSION_ONLY_THIS_TIME : null;
339          })
340        }).catch((error: BusinessError) => {
341          Log.error('bundle.getBundleInfo failed. Cause: ' + JSON.stringify(error));
342        })
343    } catch (err) {
344      Log.error('bundle.getBundleInfo failed. Cause: ' + JSON.stringify(err));
345    }
346  }
347
348  build() {
349    Column() {
350      Row() {
351        Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
352          Image(this.applicationInfo.icon)
353            .width(Constants.TERTIARY_IMAGE_WIDTH)
354            .height(Constants.TERTIARY_IMAGE_HEIGHT)
355            .margin({ left: Constants.TERTIARY_IMAGE_MARGIN_LEFT, right: Constants.TERTIARY_IMAGE_MARGIN_RIGHT })
356          Column() {
357            Row() {
358              Text(this.label)
359                .maxLines(Constants.MAXIMUM_HEADER_LINES)
360                .textOverflow({ overflow: TextOverflow.Ellipsis })
361                .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE)
362                .fontColor($r('sys.color.font_primary'))
363                .fontWeight(FontWeight.Bold)
364                .textAlign(TextAlign.Start)
365            }
366            .width(Constants.TERTIARY_HALF_WIDTH)
367            .margin({ bottom: Constants.TERTIARY_LABEL_MARGIN_BOTTOM })
368            Row() {
369              Text($r('app.string.version'))
370                .fontSize(Constants.TEXT_SMALL_FONT_SIZE)
371                .fontColor($r('sys.color.font_secondary'))
372                .textAlign(TextAlign.Start)
373              Text(this.version)
374                .fontSize(Constants.TEXT_SMALL_FONT_SIZE)
375                .fontColor($r('sys.color.font_secondary'))
376                .textAlign(TextAlign.Start)
377            }
378            .width(Constants.TERTIARY_HALF_WIDTH)
379          }
380        }.margin({ left: Constants.TERTIARY_MARGIN_LEFT })
381      }
382      if (this.reason || this.permissionLabels.length > 0) {
383        Row() {
384          Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
385            Row() {
386              Text() {
387                if (this.permissionLabels.length > 0) {
388                  ForEach(this.permissionLabels, (item: ResourceStr) => {
389                    Span(item)
390                  })
391                  Span(this.reason ? $r('app.string.comma') : $r('app.string.period'))
392                }
393                Span(this.reason)
394              }
395                .fontSize(Constants.TEXT_SMALL_FONT_SIZE)
396                .fontColor($r('sys.color.icon_secondary'))
397                .textAlign(TextAlign.Start)
398            }.margin({ left: Constants.TERTIARY_IMAGE_MARGIN_LEFT, right: Constants.TERTIARY_IMAGE_MARGIN_RIGHT })
399          }
400        }
401        .margin({
402          top: Constants.TERTIARY_ROW_MARGIN_TOP,
403          left: Constants.DEFAULT_MARGIN_START,
404          bottom: Constants.DEFAULT_MARGIN_BOTTOM
405        })
406      }
407      if (this.isRisk) {
408        Row() {
409          Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
410            Row() {
411              Image($r('app.media.ic_public_fail'))
412                .fillColor($r('sys.color.icon_secondary'))
413                .width(Constants.TERTIARY_RADIO_IMAGE_WIDTH)
414                .height(Constants.TERTIARY_RADIO_IMAGE_HEIGHT)
415                .margin({ right: Constants.TERTIARY_IMAGE_MARGIN_RIGHT })
416              Text($r('app.string.risk_warning'))
417                .fontColor($r('sys.color.font_primary'))
418                .fontSize($r('sys.float.ohos_id_text_size_body1'))
419                .fontWeight(FontWeight.Regular)
420            }.margin({ left: Constants.DEFAULT_PADDING_START, right: Constants.DEFAULT_PADDING_END })
421          }
422        }.backgroundColor($r('sys.color.interactive_click'))
423        .borderRadius($r('sys.float.ohos_id_corner_radius_default_l'))
424        .padding({ top: Constants.DEFAULT_PADDING_TOP, bottom: Constants.DEFAULT_PADDING_BOTTOM })
425        .margin({ left: Constants.DEFAULT_MARGIN_START, right: Constants.DEFAULT_MARGIN_END })
426      }
427      Row() {
428        Text() {
429          Span(this.backTitle)
430          Span($r('app.string.access_permission'))
431        }
432          .fontSize(Constants.TEXT_SMALL_FONT_SIZE)
433          .fontColor($r('sys.color.icon_secondary'))
434          .fontWeight(FontWeight.Medium)
435          .textAlign(TextAlign.Start)
436          .lineHeight(Constants.SUBTITLE_LINE_HEIGHT)
437      }.width(Constants.FULL_WIDTH)
438      .constraintSize({ minHeight: Constants.SUBTITLE_MIN_HEIGHT })
439      .padding({ top: Constants.SUBTITLE_PADDING_TOP, bottom: Constants.SUBTITLE_PADDING_BOTTOM,
440        left: Constants.TERTIARY_TEXT_MARGIN_LEFT, right: Constants.TERTIARY_IMAGE_MARGIN_RIGHT})
441      Column() {
442        List() {
443          if (this.currentGroup === 'FOLDER') {
444            ForEach(this.permissions, (permission: Permissions) => {
445              ListItem() {
446                Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
447                  Row() {
448                    Text(this.getCheckboxInfo(permission).label)
449                      .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE)
450                      .fontColor($r('sys.color.font_primary'))
451                      .fontWeight(FontWeight.Medium)
452                      .flexGrow(Constants.FLEX_GROW)
453                    Checkbox()
454                      .select(this.folderStatus[this.getCheckboxInfo(permission).index])
455                      .hitTestBehavior(HitTestMode.None)
456                  }
457                  .width(Constants.FULL_WIDTH)
458                  .height(Constants.LISTITEM_ROW_HEIGHT)
459                  .onClick(() => {
460                    if (this.folderStatus[this.getCheckboxInfo(permission).index]) {
461                      this.revokeUserGrantedPermission(accessTokenId, permission, Constants.PERMISSION_FLAG);
462                      this.folderStatus[this.getCheckboxInfo(permission).index] = false;
463                    } else {
464                      this.grantUserGrantedPermission(accessTokenId, permission);
465                      this.folderStatus[this.getCheckboxInfo(permission).index] = true;
466                    }
467                  })
468                }
469              }
470              .padding({
471                left: $r('sys.float.ohos_id_card_margin_start'),
472                right: $r('sys.float.ohos_id_card_margin_end')
473              })
474              .borderRadius($r('sys.float.ohos_id_corner_radius_default_l'))
475              .margin({ top: Constants.TERTIARY_LISTITEM_MARGIN_TOP })
476              .linearGradient((this.isCheck === permission) ? {
477                angle: 90,
478                direction: GradientDirection.Right,
479                colors: [['#DCEAF9', 0.0], ['#FAFAFA', 1.0]]
480              } : {
481                angle: 90,
482                direction: GradientDirection.Right,
483                colors: []
484              })
485              .onTouch(event => {
486                if (event === undefined) {
487                  return;
488                }
489                if (event.type === TouchType.Down) {
490                  this.isCheck = permission;
491                }
492                if (event.type === TouchType.Up) {
493                  this.isCheck = '';
494                }
495              })
496            }, (permission: Permissions) => JSON.stringify(permission))
497          } else {
498            ForEach(this.mediaDocListItem, (item: MediaDocObj) => {
499              ListItem() {
500                Column() {
501                  Row() {
502                    Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
503                      Row() {
504                        Text(item.name)
505                          .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE)
506                          .fontColor($r('sys.color.font_primary'))
507                          .fontWeight(FontWeight.Medium)
508                          .flexGrow(Constants.FLEX_GROW)
509                        Radio({ value: 'Radio', group: 'radioGroup' })
510                          .checked(item.index === this.selected)
511                          .hitTestBehavior(HitTestMode.None)
512                          .height(Constants.SHAPE_DIA)
513                          .width(Constants.SHAPE_DIA)
514                      }
515                      .width(Constants.FULL_WIDTH)
516                      .height(Constants.LISTITEM_ROW_HEIGHT)
517                      .onClick(() => {
518                        this.selected = item.index;
519                        item.permissions.forEach((permission): boolean => {
520                          if (item.index === Constants.PERMISSION_ALLOW) {
521                            if (permission === Permission.LOCATION) {
522                              return false;
523                            }
524                            this.grantUserGrantedPermission(accessTokenId, permission);
525                          } else if (item.index === Constants.PERMISSION_BAN) {
526                            if (permission == Permission.LOCATION && this.accurateIsOn) {
527                              this.revokeUserGrantedPermission(accessTokenId, permission, Constants.PERMISSION_FLAG);
528                              this.accurateIsOn = false;
529                            } else {
530                              this.revokeUserGrantedPermission(accessTokenId, permission, Constants.PERMISSION_FLAG);
531                            }
532                          } else if (item.index === Constants.PERMISSION_ONLY_THIS_TIME) {
533                            if (permission === Permission.LOCATION) {
534                              return false;
535                            }
536                            this.revokeUserGrantedPermission(
537                              accessTokenId, permission, Constants.PERMISSION_ALLOW_THIS_TIME
538                            );
539                          } else if (item.index === Constants.PERMISSION_ALLOWED_ONLY_DURING_USE) {
540                            this.grantUserGrantedPermission(accessTokenId, permission);
541                            this.revokeUserGrantedPermission(
542                              accessTokenId, Permission.LOCATION_IN_BACKGROUND, Constants.PERMISSION_FLAG
543                            );
544                          }
545                          return true;
546                        })
547                      })
548                    }
549                  }
550                }
551              }
552              .padding({
553                left: $r('sys.float.ohos_id_card_margin_start'),
554                right: $r('sys.float.ohos_id_card_margin_end')
555              })
556              .borderRadius($r('sys.float.ohos_id_corner_radius_default_l'))
557              .linearGradient((this.isTouch === item.index) ? {
558                  angle: 90,
559                  direction: GradientDirection.Right,
560                  colors: [['#DCEAF9', 0.0], ['#FAFAFA', 1.0]]
561                } : {
562                  angle: 90,
563                  direction: GradientDirection.Right,
564                  colors: []
565                })
566              .onTouch(event => {
567                if (event === undefined) {
568                  return;
569                }
570                if (event.type === TouchType.Down) {
571                  this.isTouch = item.index;
572                }
573                if (event.type === TouchType.Up) {
574                  this.isTouch = -1;
575                }
576              })
577              .margin({ top: Constants.TERTIARY_LISTITEM_MARGIN_TOP })
578            }, (item: MediaDocObj) => JSON.stringify(item))
579          }
580        }
581        .borderRadius($r('sys.float.ohos_id_corner_radius_card'))
582        .backgroundColor($r('sys.color.comp_background_list_card'))
583        .padding(Constants.LIST_PADDING_TOP)
584        .divider({
585          strokeWidth: Constants.DIVIDER,
586          color: $r('sys.color.comp_divider'),
587          startMargin: Constants.DEFAULT_MARGIN_START,
588          endMargin: Constants.DEFAULT_MARGIN_END
589        })
590
591        if (this.permissions.includes(Permission.LOCATION) && showPrecise.includes(this.selected)) {
592          Column() {
593            Row() {
594              Text($r('app.string.precise_location'))
595                .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE)
596                .fontColor($r('sys.color.font_primary'))
597                .fontWeight(FontWeight.Medium)
598                .flexGrow(Constants.FLEX_GROW)
599              Toggle({ type: ToggleType.Switch, isOn: this.accurateIsOn })
600                .selectedColor($r('sys.color.icon_emphasize'))
601                .switchPointColor($r('sys.color.comp_background_primary_contrary'))
602                .onChange((isOn: boolean) => {
603                  let acManager = abilityAccessCtrl.createAtManager();
604                  if (isOn) {
605                    acManager.grantUserGrantedPermission(accessTokenId, Permission.LOCATION, Constants.PERMISSION_FLAG)
606                      .then(() => {
607                        this.accurateIsOn = true;
608                      })
609                  } else {
610                    acManager.revokeUserGrantedPermission(accessTokenId, Permission.LOCATION, Constants.PERMISSION_FLAG)
611                      .then(() => {
612                        this.accurateIsOn = false;
613                      })
614                  }
615                })
616                .padding({ right: 0 })
617            }.width(Constants.FULL_WIDTH)
618            .height(Constants.LISTITEM_ROW_HEIGHT)
619          }.margin({ top: Constants.LOCATION_MARGIN_TOP, bottom: Constants.LOCATION_MARGIN_BOTTOM })
620          .padding({
621            left: Constants.DEFAULT_PADDING_START,
622            right: Constants.DEFAULT_PADDING_END,
623            top: Constants.TERTIARY_LIST_PADDING_TOP,
624            bottom: Constants.TERTIARY_LIST_PADDING_BOTTOM
625          })
626          .borderRadius($r('sys.float.ohos_id_corner_radius_card'))
627          .backgroundColor($r('sys.color.comp_background_list_card'))
628
629          Row() {
630            Text($r('app.string.get_the_exact_position'))
631              .fontSize(Constants.TEXT_SMALL_FONT_SIZE)
632              .fontColor($r('sys.color.font_secondary'))
633              .lineHeight(Constants.TEXT_SMALL_LINE_HEIGHT)
634          }.width(Constants.FULL_WIDTH)
635          .padding({
636            left: Constants.DEFAULT_PADDING_START,
637            right: Constants.DEFAULT_PADDING_END,
638          })
639        }
640      }
641      .padding({
642        left: Constants.LIST_PADDING_LEFT,
643        right: Constants.LIST_PADDING_LEFT
644      })
645      .width(Constants.FULL_WIDTH)
646      .height(Constants.FULL_HEIGHT)
647      .enabled(!this.isRisk && !this.noForeground)
648      .opacity((!this.isRisk && !this.noForeground) ? 1 : $r('sys.float.ohos_id_alpha_disabled'))
649    }
650    .width(Constants.FULL_WIDTH)
651  }
652}
653