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