1c5c2eed7Sopenharmony_ci/*
2c5c2eed7Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
3c5c2eed7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4c5c2eed7Sopenharmony_ci * you may not use this file except in compliance with the License.
5c5c2eed7Sopenharmony_ci * You may obtain a copy of the License at
6c5c2eed7Sopenharmony_ci *
7c5c2eed7Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8c5c2eed7Sopenharmony_ci *
9c5c2eed7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10c5c2eed7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11c5c2eed7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12c5c2eed7Sopenharmony_ci * See the License for the specific language governing permissions and
13c5c2eed7Sopenharmony_ci * limitations under the License.
14c5c2eed7Sopenharmony_ci */
15c5c2eed7Sopenharmony_ciimport bundleManager from '@ohos.bundle.bundleManager';
16c5c2eed7Sopenharmony_ciimport Constants from '../common/utils/constant';
17c5c2eed7Sopenharmony_ciimport common from '@ohos.app.ability.common';
18c5c2eed7Sopenharmony_ciimport { BusinessError } from '@ohos.base';
19c5c2eed7Sopenharmony_ciimport {
20c5c2eed7Sopenharmony_ci  checkPermissionGroup,
21c5c2eed7Sopenharmony_ci  getGroupIdByPermission, getPermissionLabel, Log,
22c5c2eed7Sopenharmony_ci  PermissionDialogException,
23c5c2eed7Sopenharmony_ci  PermissionDialogReturn,
24c5c2eed7Sopenharmony_ci  verifyAccessToken } from '../common/utils/utils';
25c5c2eed7Sopenharmony_ciimport { AppInfo, CallerBundleInfo,
26c5c2eed7Sopenharmony_ci  CheckboxInfo,
27c5c2eed7Sopenharmony_ci  MediaDocObj,
28c5c2eed7Sopenharmony_ci  WantInfo } from '../common/model/typedef';
29c5c2eed7Sopenharmony_ciimport { GlobalContext } from '../common/utils/globalContext';
30c5c2eed7Sopenharmony_ciimport abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl';
31c5c2eed7Sopenharmony_ciimport { groups, showSubPermissionsGroup } from '../common/model/permissionGroup';
32c5c2eed7Sopenharmony_ciimport UIExtensionContentSession from '@ohos.app.ability.UIExtensionContentSession';
33c5c2eed7Sopenharmony_ciimport { CustomContentDialog } from '@ohos.arkui.advanced.Dialog'
34c5c2eed7Sopenharmony_ci
35c5c2eed7Sopenharmony_ciconst FUZZY_LOCATION_PERMISSION = 'ohos.permission.APPROXIMATELY_LOCATION';
36c5c2eed7Sopenharmony_ciconst PRECISE_LOCATION_PERMISSION = 'ohos.permission.LOCATION';
37c5c2eed7Sopenharmony_ciconst BACKGROUND_LOCATION_PERMISSION = 'ohos.permission.LOCATION_IN_BACKGROUND';
38c5c2eed7Sopenharmony_ciconst DOWNLOAD_PERMISSION = 'ohos.permission.READ_WRITE_DOWNLOAD_DIRECTORY';
39c5c2eed7Sopenharmony_ciconst DESKTOP_PERMISSION = 'ohos.permission.READ_WRITE_DESKTOP_DIRECTORY';
40c5c2eed7Sopenharmony_ciconst DOCUMENTS_PERMISSION = 'ohos.permission.READ_WRITE_DOCUMENTS_DIRECTORY';
41c5c2eed7Sopenharmony_ciconst PASTE = 'ohos.permission.READ_PASTEBOARD';
42c5c2eed7Sopenharmony_ci
43c5c2eed7Sopenharmony_cilet storage = LocalStorage.getShared();
44c5c2eed7Sopenharmony_cilet accessTokenId: number = 0;
45c5c2eed7Sopenharmony_cilet session: UIExtensionContentSession;
46c5c2eed7Sopenharmony_cilet results: Map<string, number> = new Map();
47c5c2eed7Sopenharmony_cilet terminating: boolean = false;
48c5c2eed7Sopenharmony_ci
49c5c2eed7Sopenharmony_ciexport function ReportDialogResult(wantPermissions: Permissions[]) {
50c5c2eed7Sopenharmony_ci  let resultArray: number[] = [];
51c5c2eed7Sopenharmony_ci  Log.info('processed result:' + JSON.stringify(results));
52c5c2eed7Sopenharmony_ci  for (const permission of wantPermissions) {
53c5c2eed7Sopenharmony_ci    // check if corresponding result is set
54c5c2eed7Sopenharmony_ci    if (results.has(permission)) {
55c5c2eed7Sopenharmony_ci      resultArray.push(results.get(permission)!);
56c5c2eed7Sopenharmony_ci    } else {
57c5c2eed7Sopenharmony_ci      Log.error(permission + ' is not processed!');
58c5c2eed7Sopenharmony_ci      resultArray.push(Constants.ERR_PERMISSION_GRANT_EXCEPTION);
59c5c2eed7Sopenharmony_ci    }
60c5c2eed7Sopenharmony_ci  }
61c5c2eed7Sopenharmony_ci  Log.info('terminating session with return array ' + JSON.stringify(resultArray));
62c5c2eed7Sopenharmony_ci  PermissionDialogReturn(resultArray, session);
63c5c2eed7Sopenharmony_ci}
64c5c2eed7Sopenharmony_ci
65c5c2eed7Sopenharmony_ciexport function getCallerBundleInfo(want: WantInfo): CallerBundleInfo {
66c5c2eed7Sopenharmony_ci  let bundleName: string = want.parameters['ohos.aafwk.param.callerBundleName'];
67c5c2eed7Sopenharmony_ci  let uId: number = want.parameters['ohos.aafwk.param.callerUid'] ?? 0;
68c5c2eed7Sopenharmony_ci  let token: number = want.parameters['ohos.aafwk.param.callerToken'] ?? 0;
69c5c2eed7Sopenharmony_ci  let permissions: Permissions[] = want.parameters['ohos.user.setting.permission'];
70c5c2eed7Sopenharmony_ci  let globSwitch: number = want.parameters['ohos.user.setting.global_switch'];
71c5c2eed7Sopenharmony_ci
72c5c2eed7Sopenharmony_ci  const callerBundle: CallerBundleInfo = {
73c5c2eed7Sopenharmony_ci    bundleName: bundleName,
74c5c2eed7Sopenharmony_ci    uId: uId,
75c5c2eed7Sopenharmony_ci    permissionGroup: permissions,
76c5c2eed7Sopenharmony_ci    token: token,
77c5c2eed7Sopenharmony_ci    globSwitch: globSwitch
78c5c2eed7Sopenharmony_ci  }
79c5c2eed7Sopenharmony_ci
80c5c2eed7Sopenharmony_ci  return callerBundle;
81c5c2eed7Sopenharmony_ci}
82c5c2eed7Sopenharmony_ci
83c5c2eed7Sopenharmony_ci@Entry(storage)
84c5c2eed7Sopenharmony_ci@Component
85c5c2eed7Sopenharmony_cistruct PermissionStateSheetDialog {
86c5c2eed7Sopenharmony_ci  private context = getContext(this) as common.ServiceExtensionContext;
87c5c2eed7Sopenharmony_ci  @LocalStorageLink('want') want: Want | null = storage.get<Want>('want') || null;
88c5c2eed7Sopenharmony_ci  @LocalStorageLink('session') session: UIExtensionContentSession =
89c5c2eed7Sopenharmony_ci    storage.get<UIExtensionContentSession>('session') as UIExtensionContentSession;
90c5c2eed7Sopenharmony_ci  @State applicationInfo: AppInfo | undefined = undefined;
91c5c2eed7Sopenharmony_ci  @State folderStatus: boolean[] = [false, false, false];
92c5c2eed7Sopenharmony_ci  @State reqUserPermissions: Permissions[] = [];
93c5c2eed7Sopenharmony_ci  @State bundleName: string = '';
94c5c2eed7Sopenharmony_ci  @State isGranted: number = Constants.PERMISSION_ALLOW;
95c5c2eed7Sopenharmony_ci  @State groupName: ResourceStr = '';
96c5c2eed7Sopenharmony_ci  @State currentGroup: string = '';
97c5c2eed7Sopenharmony_ci
98c5c2eed7Sopenharmony_ci  dialogController: CustomDialogController | null = new CustomDialogController({
99c5c2eed7Sopenharmony_ci    builder: CustomContentDialog({
100c5c2eed7Sopenharmony_ci      contentBuilder: () => {
101c5c2eed7Sopenharmony_ci        this.buildDialog();
102c5c2eed7Sopenharmony_ci      },
103c5c2eed7Sopenharmony_ci      contentAreaPadding: {left: 0, right: 0}
104c5c2eed7Sopenharmony_ci    }),
105c5c2eed7Sopenharmony_ci    offset: { dx: 0, dy: `-${GlobalContext.load('avoidAreaHeight') as string}` }, // unit included in globalContext
106c5c2eed7Sopenharmony_ci    alignment: DialogAlignment.Bottom,
107c5c2eed7Sopenharmony_ci    customStyle: false,
108c5c2eed7Sopenharmony_ci    isModal: true,
109c5c2eed7Sopenharmony_ci    width: '100%',
110c5c2eed7Sopenharmony_ci    autoCancel: false,
111c5c2eed7Sopenharmony_ci    cornerRadius: {topLeft: 32, topRight: 32, bottomLeft: 0, bottomRight: 0},
112c5c2eed7Sopenharmony_ci    cancel: () => {
113c5c2eed7Sopenharmony_ci      ReportDialogResult(this.reqUserPermissions);
114c5c2eed7Sopenharmony_ci      this.context.terminateSelf();
115c5c2eed7Sopenharmony_ci      this.dialogController?.close();
116c5c2eed7Sopenharmony_ci    }
117c5c2eed7Sopenharmony_ci  });
118c5c2eed7Sopenharmony_ci
119c5c2eed7Sopenharmony_ci  @Builder
120c5c2eed7Sopenharmony_ci  buildDialog() {
121c5c2eed7Sopenharmony_ci    mediaDocumentItem({
122c5c2eed7Sopenharmony_ci      bundleName: this.bundleName,
123c5c2eed7Sopenharmony_ci      backTitle: this.groupName,
124c5c2eed7Sopenharmony_ci      permissions: this.reqUserPermissions,
125c5c2eed7Sopenharmony_ci      status: this.isGranted,
126c5c2eed7Sopenharmony_ci      tokenId: this.applicationInfo?.tokenId,
127c5c2eed7Sopenharmony_ci      applicationInfo: this.applicationInfo,
128c5c2eed7Sopenharmony_ci      currentGroup: this.currentGroup
129c5c2eed7Sopenharmony_ci    })
130c5c2eed7Sopenharmony_ci  }
131c5c2eed7Sopenharmony_ci
132c5c2eed7Sopenharmony_ci  build() {
133c5c2eed7Sopenharmony_ci
134c5c2eed7Sopenharmony_ci  }
135c5c2eed7Sopenharmony_ci
136c5c2eed7Sopenharmony_ci  async aboutToAppear() {
137c5c2eed7Sopenharmony_ci    session = this.session;
138c5c2eed7Sopenharmony_ci    await this.GetAppInfo();
139c5c2eed7Sopenharmony_ci
140c5c2eed7Sopenharmony_ci    if (!this.applicationInfo) {
141c5c2eed7Sopenharmony_ci      this.context.terminateSelf();
142c5c2eed7Sopenharmony_ci    }
143c5c2eed7Sopenharmony_ci
144c5c2eed7Sopenharmony_ci    if (this.dialogController !== null && terminating == false) {
145c5c2eed7Sopenharmony_ci      this.dialogController.open();
146c5c2eed7Sopenharmony_ci    }
147c5c2eed7Sopenharmony_ci  }
148c5c2eed7Sopenharmony_ci
149c5c2eed7Sopenharmony_ci  async getSpecifiedApplication(bundleName: string): Promise<AppInfo | undefined> {
150c5c2eed7Sopenharmony_ci    const flag =
151c5c2eed7Sopenharmony_ci      bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION |
152c5c2eed7Sopenharmony_ci      bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_REQUESTED_PERMISSION;
153c5c2eed7Sopenharmony_ci    let promise = new Promise<AppInfo | undefined>(async (resolve, reject) => {
154c5c2eed7Sopenharmony_ci      try {
155c5c2eed7Sopenharmony_ci        let info = await this.getBundleInfo(bundleName, flag);
156c5c2eed7Sopenharmony_ci        resolve(info);
157c5c2eed7Sopenharmony_ci      } catch (e) {
158c5c2eed7Sopenharmony_ci        resolve(undefined);
159c5c2eed7Sopenharmony_ci      }
160c5c2eed7Sopenharmony_ci    })
161c5c2eed7Sopenharmony_ci    return promise;
162c5c2eed7Sopenharmony_ci  }
163c5c2eed7Sopenharmony_ci
164c5c2eed7Sopenharmony_ci  async getBundleInfo(bundleName: string, flag: number): Promise<AppInfo | undefined> {
165c5c2eed7Sopenharmony_ci    return new Promise<AppInfo | undefined>(async (resolve, reject) => {
166c5c2eed7Sopenharmony_ci      let info: AppInfo | undefined = undefined;
167c5c2eed7Sopenharmony_ci      let permissionGrantMap: Map<string, number> = new Map();
168c5c2eed7Sopenharmony_ci      let bundleInfo = await bundleManager.getBundleInfo(bundleName, flag);
169c5c2eed7Sopenharmony_ci      let appPermissions = bundleInfo.reqPermissionDetails;
170c5c2eed7Sopenharmony_ci      let granted = bundleInfo.permissionGrantStates;
171c5c2eed7Sopenharmony_ci      info = new AppInfo(bundleInfo.name, bundleInfo.targetVersion,
172c5c2eed7Sopenharmony_ci        bundleInfo.appInfo.accessTokenId, '', bundleInfo.appInfo.iconId, bundleInfo.appInfo.iconResource,
173c5c2eed7Sopenharmony_ci        '', bundleInfo.appInfo.labelId, bundleInfo.appInfo.labelResource, [], [], '', '', ''
174c5c2eed7Sopenharmony_ci      );
175c5c2eed7Sopenharmony_ci      resolve(info);
176c5c2eed7Sopenharmony_ci      // check if all permissions passed from want has been claimed by app config
177c5c2eed7Sopenharmony_ci      for (const wantPermission of this.reqUserPermissions) {
178c5c2eed7Sopenharmony_ci        if (terminating) {
179c5c2eed7Sopenharmony_ci          continue;
180c5c2eed7Sopenharmony_ci        }
181c5c2eed7Sopenharmony_ci        let idx = appPermissions.findIndex((item) => {
182c5c2eed7Sopenharmony_ci          return item.name == wantPermission;
183c5c2eed7Sopenharmony_ci        });
184c5c2eed7Sopenharmony_ci        if (idx == -1) {
185c5c2eed7Sopenharmony_ci          Log.error('permission ' + wantPermission + ' not claimed by ' + this.bundleName + ' in module.json');
186c5c2eed7Sopenharmony_ci          PermissionDialogException(Constants.ERR_PERMISSIONS_NOT_IN_CONFIG, session);
187c5c2eed7Sopenharmony_ci          terminating = true;
188c5c2eed7Sopenharmony_ci          this.context.terminateSelf();
189c5c2eed7Sopenharmony_ci          return;
190c5c2eed7Sopenharmony_ci        }
191c5c2eed7Sopenharmony_ci        permissionGrantMap.set(appPermissions[idx].name, granted[idx]);
192c5c2eed7Sopenharmony_ci      }
193c5c2eed7Sopenharmony_ci      // check if all permissions are already granted
194c5c2eed7Sopenharmony_ci      let permissionsAllGranted = true;
195c5c2eed7Sopenharmony_ci      for (const key of permissionGrantMap.keys()) {
196c5c2eed7Sopenharmony_ci        if (permissionGrantMap.get(key) === -1) { // -1 means not granted
197c5c2eed7Sopenharmony_ci          permissionsAllGranted = false;
198c5c2eed7Sopenharmony_ci        }
199c5c2eed7Sopenharmony_ci      }
200c5c2eed7Sopenharmony_ci      // check if all permissions are already granted
201c5c2eed7Sopenharmony_ci      if (permissionsAllGranted) {
202c5c2eed7Sopenharmony_ci        Log.error('terminating : ' + terminating + ' requested permissions are all already granted');
203c5c2eed7Sopenharmony_ci        if (terminating == false) {
204c5c2eed7Sopenharmony_ci          PermissionDialogException(Constants.ERR_PERMISSIONS_ALL_GRANTED, session);
205c5c2eed7Sopenharmony_ci          terminating = true;
206c5c2eed7Sopenharmony_ci          this.context.terminateSelf();
207c5c2eed7Sopenharmony_ci        }
208c5c2eed7Sopenharmony_ci      }
209c5c2eed7Sopenharmony_ci    })
210c5c2eed7Sopenharmony_ci  }
211c5c2eed7Sopenharmony_ci
212c5c2eed7Sopenharmony_ci  aboutToDisappear() {
213c5c2eed7Sopenharmony_ci    Log.info('permission dialog about to disappear');
214c5c2eed7Sopenharmony_ci    this.dialogController = null;
215c5c2eed7Sopenharmony_ci  }
216c5c2eed7Sopenharmony_ci
217c5c2eed7Sopenharmony_ci  async GetAppInfo() {
218c5c2eed7Sopenharmony_ci    let callerBundle: CallerBundleInfo = getCallerBundleInfo(this.want as Object as WantInfo);
219c5c2eed7Sopenharmony_ci    this.bundleName = callerBundle.bundleName;
220c5c2eed7Sopenharmony_ci    this.reqUserPermissions = callerBundle.permissionGroup as Permissions[]; // user permission is passed from wantInfo
221c5c2eed7Sopenharmony_ci    // check if wanted permissions are in the same permission group
222c5c2eed7Sopenharmony_ci    let groupName = checkPermissionGroup(this.reqUserPermissions);
223c5c2eed7Sopenharmony_ci    if (groupName == null) {
224c5c2eed7Sopenharmony_ci      terminating = true;
225c5c2eed7Sopenharmony_ci      PermissionDialogException(Constants.ERR_PERMISSIONS_NOT_SAME_GROUP, session);
226c5c2eed7Sopenharmony_ci      this.context.terminateSelf();
227c5c2eed7Sopenharmony_ci    }
228c5c2eed7Sopenharmony_ci    this.currentGroup = groupName!;
229c5c2eed7Sopenharmony_ci    // check app infos, check if permissions are claimed , check if permissions are granted
230c5c2eed7Sopenharmony_ci    this.applicationInfo = await this.getSpecifiedApplication(callerBundle.bundleName);
231c5c2eed7Sopenharmony_ci    if (this.applicationInfo === undefined) {
232c5c2eed7Sopenharmony_ci      Log.error('application info is undefined');
233c5c2eed7Sopenharmony_ci    }
234c5c2eed7Sopenharmony_ci    // get application detailed info
235c5c2eed7Sopenharmony_ci    await this.initApplicationInfo(this.applicationInfo!);
236c5c2eed7Sopenharmony_ci    // initialize permission states
237c5c2eed7Sopenharmony_ci    await this.initialPermissions();
238c5c2eed7Sopenharmony_ci    // store application info after initialization is done
239c5c2eed7Sopenharmony_ci    GlobalContext.store('applicationInfo', this.applicationInfo);
240c5c2eed7Sopenharmony_ci  }
241c5c2eed7Sopenharmony_ci
242c5c2eed7Sopenharmony_ci  async initApplicationInfo(info: AppInfo) {
243c5c2eed7Sopenharmony_ci    Log.info('labelResource: ' + JSON.stringify(info.labelResource));
244c5c2eed7Sopenharmony_ci    let resourceManager = this.context.createBundleContext(info.bundleName).resourceManager;
245c5c2eed7Sopenharmony_ci
246c5c2eed7Sopenharmony_ci    if (info.labelResource.id !== 0) {
247c5c2eed7Sopenharmony_ci      info.label = await this.context.resourceManager.getStringValue(info.labelResource);
248c5c2eed7Sopenharmony_ci    } else {
249c5c2eed7Sopenharmony_ci      info.label = await resourceManager.getStringValue(info.labelId);
250c5c2eed7Sopenharmony_ci    }
251c5c2eed7Sopenharmony_ci
252c5c2eed7Sopenharmony_ci    try {
253c5c2eed7Sopenharmony_ci      if (info.iconResource.id !== 0) {
254c5c2eed7Sopenharmony_ci        let iconDescriptor = this.context.resourceManager.getDrawableDescriptor(info.iconResource);
255c5c2eed7Sopenharmony_ci        info.icon = iconDescriptor?.getPixelMap();
256c5c2eed7Sopenharmony_ci      } else {
257c5c2eed7Sopenharmony_ci        let iconDescriptor = resourceManager.getDrawableDescriptor(info.iconId);
258c5c2eed7Sopenharmony_ci        info.icon = iconDescriptor?.getPixelMap();
259c5c2eed7Sopenharmony_ci      }
260c5c2eed7Sopenharmony_ci    } catch (error) {
261c5c2eed7Sopenharmony_ci      Log.error(`getDrawableDescriptor failed, error code: ${error.code}, message: ${error.message}.`);
262c5c2eed7Sopenharmony_ci    }
263c5c2eed7Sopenharmony_ci
264c5c2eed7Sopenharmony_ci    if (!info.icon) {
265c5c2eed7Sopenharmony_ci      info.icon = $r('app.media.icon');
266c5c2eed7Sopenharmony_ci    }
267c5c2eed7Sopenharmony_ci
268c5c2eed7Sopenharmony_ci    let groupIds: number[] = [];
269c5c2eed7Sopenharmony_ci    for (let i = 0; i < this.reqUserPermissions.length; i++) {
270c5c2eed7Sopenharmony_ci      let groupId = getGroupIdByPermission(this.reqUserPermissions[i]);
271c5c2eed7Sopenharmony_ci      if (groupIds.indexOf(groupId) == -1) {
272c5c2eed7Sopenharmony_ci        groupIds.push(groupId);
273c5c2eed7Sopenharmony_ci      }
274c5c2eed7Sopenharmony_ci    }
275c5c2eed7Sopenharmony_ci    info.permissions = this.reqUserPermissions;
276c5c2eed7Sopenharmony_ci    info.groupId = groupIds;
277c5c2eed7Sopenharmony_ci  }
278c5c2eed7Sopenharmony_ci
279c5c2eed7Sopenharmony_ci  async getStatus(groupReqPermissions: Permissions[], group: string) {
280c5c2eed7Sopenharmony_ci    if (group === 'LOCATION') {
281c5c2eed7Sopenharmony_ci      try {
282c5c2eed7Sopenharmony_ci        let acManager = abilityAccessCtrl.createAtManager();
283c5c2eed7Sopenharmony_ci        let fuzzyState = acManager.verifyAccessTokenSync(this.applicationInfo?.tokenId, FUZZY_LOCATION_PERMISSION);
284c5c2eed7Sopenharmony_ci        fuzzyState === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED ?
285c5c2eed7Sopenharmony_ci          this.isGranted = Constants.PERMISSION_ALLOWED_ONLY_DURING_USE : null;
286c5c2eed7Sopenharmony_ci        let backgroundState =
287c5c2eed7Sopenharmony_ci          acManager.verifyAccessTokenSync(this.applicationInfo?.tokenId, BACKGROUND_LOCATION_PERMISSION);
288c5c2eed7Sopenharmony_ci        backgroundState === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED ?
289c5c2eed7Sopenharmony_ci          this.isGranted = Constants.PERMISSION_ALLOW : null;
290c5c2eed7Sopenharmony_ci        await acManager.getPermissionFlags(this.applicationInfo?.tokenId, FUZZY_LOCATION_PERMISSION ).then(flag => {
291c5c2eed7Sopenharmony_ci          flag === Constants.PERMISSION_ALLOW_THIS_TIME ? this.isGranted = Constants.PERMISSION_ONLY_THIS_TIME : null;
292c5c2eed7Sopenharmony_ci        })
293c5c2eed7Sopenharmony_ci      } catch (err) {
294c5c2eed7Sopenharmony_ci        Log.error('change location status error: ' + JSON.stringify(err));
295c5c2eed7Sopenharmony_ci      }
296c5c2eed7Sopenharmony_ci      GlobalContext.store('locationStatus', this.isGranted);
297c5c2eed7Sopenharmony_ci      return true;
298c5c2eed7Sopenharmony_ci    }
299c5c2eed7Sopenharmony_ci    for (let i = 0; i < groupReqPermissions.length; i++) {
300c5c2eed7Sopenharmony_ci      let permission = groupReqPermissions[i];
301c5c2eed7Sopenharmony_ci      let res = await verifyAccessToken(this.applicationInfo!.tokenId, permission);
302c5c2eed7Sopenharmony_ci      if (res != abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
303c5c2eed7Sopenharmony_ci        this.isGranted = Constants.PERMISSION_BAN;
304c5c2eed7Sopenharmony_ci      }
305c5c2eed7Sopenharmony_ci      if (group === 'FOLDER' && res === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
306c5c2eed7Sopenharmony_ci        switch (permission) {
307c5c2eed7Sopenharmony_ci          case DOWNLOAD_PERMISSION:
308c5c2eed7Sopenharmony_ci            this.folderStatus[0] = true;
309c5c2eed7Sopenharmony_ci            break;
310c5c2eed7Sopenharmony_ci          case DESKTOP_PERMISSION:
311c5c2eed7Sopenharmony_ci            this.folderStatus[1] = true;
312c5c2eed7Sopenharmony_ci            break;
313c5c2eed7Sopenharmony_ci          case DOCUMENTS_PERMISSION:
314c5c2eed7Sopenharmony_ci            this.folderStatus[2] = true;
315c5c2eed7Sopenharmony_ci            break;
316c5c2eed7Sopenharmony_ci        }
317c5c2eed7Sopenharmony_ci      }
318c5c2eed7Sopenharmony_ci    }
319c5c2eed7Sopenharmony_ci    return true;
320c5c2eed7Sopenharmony_ci  }
321c5c2eed7Sopenharmony_ci
322c5c2eed7Sopenharmony_ci  /**
323c5c2eed7Sopenharmony_ci   * Initialize permission status information and group permission information
324c5c2eed7Sopenharmony_ci   */
325c5c2eed7Sopenharmony_ci  async initialPermissions() {
326c5c2eed7Sopenharmony_ci    if (this.bundleName && !this.applicationInfo?.groupId.length) {
327c5c2eed7Sopenharmony_ci      await this.initApplicationInfo(this.applicationInfo!);
328c5c2eed7Sopenharmony_ci    }
329c5c2eed7Sopenharmony_ci    let reqPermissions = this.applicationInfo!.permissions;
330c5c2eed7Sopenharmony_ci    let reqGroupIds = this.applicationInfo!.groupId;
331c5c2eed7Sopenharmony_ci
332c5c2eed7Sopenharmony_ci    for (let i = 0; i < reqGroupIds.length; i++) {
333c5c2eed7Sopenharmony_ci      let id = reqGroupIds[i];
334c5c2eed7Sopenharmony_ci      let groupName = groups[id].groupName;
335c5c2eed7Sopenharmony_ci      let group = groups[id].name;
336c5c2eed7Sopenharmony_ci      let groupReqPermissions: Permissions[] = [];
337c5c2eed7Sopenharmony_ci
338c5c2eed7Sopenharmony_ci      for (let j = 0; j < reqPermissions.length; j++) {
339c5c2eed7Sopenharmony_ci        let permission = reqPermissions[j];
340c5c2eed7Sopenharmony_ci        if (groups[id].permissions.indexOf(permission) != -1) {
341c5c2eed7Sopenharmony_ci          groupReqPermissions.push(permission);
342c5c2eed7Sopenharmony_ci          this.groupName = groupName;
343c5c2eed7Sopenharmony_ci        }
344c5c2eed7Sopenharmony_ci      }
345c5c2eed7Sopenharmony_ci      this.isGranted = group === 'LOCATION' ? Constants.PERMISSION_BAN : Constants.PERMISSION_ALLOW;
346c5c2eed7Sopenharmony_ci      this.folderStatus = [false, false, false];
347c5c2eed7Sopenharmony_ci      await this.getStatus(groupReqPermissions, group);
348c5c2eed7Sopenharmony_ci
349c5c2eed7Sopenharmony_ci      GlobalContext.store('folderStatus', this.folderStatus);
350c5c2eed7Sopenharmony_ci    }
351c5c2eed7Sopenharmony_ci  }
352c5c2eed7Sopenharmony_ci}
353c5c2eed7Sopenharmony_ci
354c5c2eed7Sopenharmony_ci@CustomDialog
355c5c2eed7Sopenharmony_cistruct mediaDocumentItem {
356c5c2eed7Sopenharmony_ci  private context = getContext(this) as common.UIAbilityContext;
357c5c2eed7Sopenharmony_ci  private backTitle: ResourceStr = '';
358c5c2eed7Sopenharmony_ci  private bundleName: string = '';
359c5c2eed7Sopenharmony_ci  private permissions: Permissions[] = [];
360c5c2eed7Sopenharmony_ci  private status: number = 0;
361c5c2eed7Sopenharmony_ci  private tokenId: number = 0;
362c5c2eed7Sopenharmony_ci  private controller: CustomDialogController;
363c5c2eed7Sopenharmony_ci  @State hidden: boolean = false;
364c5c2eed7Sopenharmony_ci  @State currentGroup: string = '';
365c5c2eed7Sopenharmony_ci  @State applicationInfo: AppInfo = GlobalContext.load('applicationInfo');
366c5c2eed7Sopenharmony_ci  @State folderStatus: boolean[] = [];
367c5c2eed7Sopenharmony_ci  @State mediaDocListItem: MediaDocObj[] = []; // Permission information array
368c5c2eed7Sopenharmony_ci  @State selected: number = 0;
369c5c2eed7Sopenharmony_ci  @State accurateIsOn: boolean = true;
370c5c2eed7Sopenharmony_ci  @State api: number = 0;
371c5c2eed7Sopenharmony_ci  @State isRisk: boolean = false; // Whether it is a risky application
372c5c2eed7Sopenharmony_ci  @State noForeground: boolean = false;
373c5c2eed7Sopenharmony_ci  @State isTouch: number = -1;
374c5c2eed7Sopenharmony_ci  @State isCheck: string = '';
375c5c2eed7Sopenharmony_ci  @State reason: string = '';
376c5c2eed7Sopenharmony_ci  @State label: string = '';
377c5c2eed7Sopenharmony_ci  @State version: string = '';
378c5c2eed7Sopenharmony_ci  @State permissionLabels: Array<ResourceStr> = [];
379c5c2eed7Sopenharmony_ci  @LocalStorageLink('bundleInfo') bundleInfo: Want = {} as Want;
380c5c2eed7Sopenharmony_ci
381c5c2eed7Sopenharmony_ci  /**
382c5c2eed7Sopenharmony_ci   * Grant permissions to the app
383c5c2eed7Sopenharmony_ci   * @param {Number} accessTokenId
384c5c2eed7Sopenharmony_ci   * @param {String} permission permission name
385c5c2eed7Sopenharmony_ci   */
386c5c2eed7Sopenharmony_ci  async grantUserGrantedPermission(accessTokenId: number, permission: Permissions) {
387c5c2eed7Sopenharmony_ci    Log.info('granting permission ' + permission);
388c5c2eed7Sopenharmony_ci    try {
389c5c2eed7Sopenharmony_ci      await abilityAccessCtrl.createAtManager()
390c5c2eed7Sopenharmony_ci        .grantUserGrantedPermission(accessTokenId, permission, Constants.PERMISSION_FLAG);
391c5c2eed7Sopenharmony_ci        Log.info('grantUserGrantedPermission ' + permission + ' success.');
392c5c2eed7Sopenharmony_ci        results.set(permission, Constants.PERMISSION_DIALOG_SUCCESS);
393c5c2eed7Sopenharmony_ci    } catch (e) {
394c5c2eed7Sopenharmony_ci        results.set(permission, Constants.ERR_PERMISSION_GRANT_EXCEPTION);
395c5c2eed7Sopenharmony_ci        Log.error('grantUserGrantedPermission failed. Cause: ' + JSON.stringify(e));
396c5c2eed7Sopenharmony_ci    }
397c5c2eed7Sopenharmony_ci  }
398c5c2eed7Sopenharmony_ci
399c5c2eed7Sopenharmony_ci  /**
400c5c2eed7Sopenharmony_ci   * Deauthorize the app
401c5c2eed7Sopenharmony_ci   * @param {Number} accessTokenId
402c5c2eed7Sopenharmony_ci   * @param {String} permission permission name
403c5c2eed7Sopenharmony_ci   */
404c5c2eed7Sopenharmony_ci  async revokeUserGrantedPermission(accessTokenId: number, permission: Permissions, flag: number) {
405c5c2eed7Sopenharmony_ci    abilityAccessCtrl.createAtManager().revokeUserGrantedPermission(accessTokenId, permission, flag)
406c5c2eed7Sopenharmony_ci      .then(() => {
407c5c2eed7Sopenharmony_ci        Log.error('revokeUserGrantedPermission ' + permission + ' success');
408c5c2eed7Sopenharmony_ci      })
409c5c2eed7Sopenharmony_ci      .catch((error: BusinessError) => {
410c5c2eed7Sopenharmony_ci        Log.error('revokeUserGrantedPermission failed. Cause: ' + JSON.stringify(error));
411c5c2eed7Sopenharmony_ci      })
412c5c2eed7Sopenharmony_ci  }
413c5c2eed7Sopenharmony_ci
414c5c2eed7Sopenharmony_ci  onPageShow(): void {
415c5c2eed7Sopenharmony_ci    this.refreshStatus();
416c5c2eed7Sopenharmony_ci  }
417c5c2eed7Sopenharmony_ci
418c5c2eed7Sopenharmony_ci  async refreshStatus() {
419c5c2eed7Sopenharmony_ci    Log.info('Refresh permission status');
420c5c2eed7Sopenharmony_ci    let isGranted = this.currentGroup === 'LOCATION' ? Constants.PERMISSION_BAN : Constants.PERMISSION_ALLOW;
421c5c2eed7Sopenharmony_ci    let folderStatus = [false, false, false];
422c5c2eed7Sopenharmony_ci    let atManager = abilityAccessCtrl.createAtManager();
423c5c2eed7Sopenharmony_ci    for (let i = 0; i < this.permissions.length; i++) {
424c5c2eed7Sopenharmony_ci      let permission = this.permissions[i];
425c5c2eed7Sopenharmony_ci      if (this.currentGroup === 'LOCATION') {
426c5c2eed7Sopenharmony_ci        continue;
427c5c2eed7Sopenharmony_ci      }
428c5c2eed7Sopenharmony_ci      let res = atManager.verifyAccessTokenSync(this.tokenId, permission);
429c5c2eed7Sopenharmony_ci      if (res != abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
430c5c2eed7Sopenharmony_ci        isGranted = Constants.PERMISSION_BAN;
431c5c2eed7Sopenharmony_ci      }
432c5c2eed7Sopenharmony_ci      if (this.currentGroup === 'FOLDER' && res === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
433c5c2eed7Sopenharmony_ci        switch (permission) {
434c5c2eed7Sopenharmony_ci          case DOWNLOAD_PERMISSION:
435c5c2eed7Sopenharmony_ci            folderStatus[0] = true;
436c5c2eed7Sopenharmony_ci            break;
437c5c2eed7Sopenharmony_ci          case DESKTOP_PERMISSION:
438c5c2eed7Sopenharmony_ci            folderStatus[1] = true;
439c5c2eed7Sopenharmony_ci            break;
440c5c2eed7Sopenharmony_ci          case DOCUMENTS_PERMISSION:
441c5c2eed7Sopenharmony_ci            folderStatus[2] = true;
442c5c2eed7Sopenharmony_ci            break;
443c5c2eed7Sopenharmony_ci        }
444c5c2eed7Sopenharmony_ci        results.set(permission, Constants.PERMISSION_DIALOG_SUCCESS);
445c5c2eed7Sopenharmony_ci      }
446c5c2eed7Sopenharmony_ci    }
447c5c2eed7Sopenharmony_ci    this.folderStatus = folderStatus;
448c5c2eed7Sopenharmony_ci    await this.refreshSelected(isGranted);
449c5c2eed7Sopenharmony_ci  }
450c5c2eed7Sopenharmony_ci
451c5c2eed7Sopenharmony_ci  async refreshSelected(isGranted: number) {
452c5c2eed7Sopenharmony_ci    this.selected = isGranted;
453c5c2eed7Sopenharmony_ci    if (this.currentGroup === 'PASTEBOARD') {
454c5c2eed7Sopenharmony_ci      try {
455c5c2eed7Sopenharmony_ci        let acManager = abilityAccessCtrl.createAtManager();
456c5c2eed7Sopenharmony_ci        acManager.getPermissionFlags(this.tokenId, PASTE).then(flag => {
457c5c2eed7Sopenharmony_ci          flag === Constants.PERMISSION_ALLOW_THIS_TIME ? this.selected = Constants.PERMISSION_ONLY_THIS_TIME : null;
458c5c2eed7Sopenharmony_ci        });
459c5c2eed7Sopenharmony_ci      } catch (err) {
460c5c2eed7Sopenharmony_ci        Log.error('getPermissionFlags error: ' + JSON.stringify(err));
461c5c2eed7Sopenharmony_ci      }
462c5c2eed7Sopenharmony_ci    } else if (this.currentGroup === 'LOCATION') {
463c5c2eed7Sopenharmony_ci      try {
464c5c2eed7Sopenharmony_ci        let acManager = abilityAccessCtrl.createAtManager();
465c5c2eed7Sopenharmony_ci        let fuzzyState = acManager.verifyAccessTokenSync(this.tokenId, FUZZY_LOCATION_PERMISSION);
466c5c2eed7Sopenharmony_ci        fuzzyState === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED ?
467c5c2eed7Sopenharmony_ci          this.selected = Constants.PERMISSION_ALLOWED_ONLY_DURING_USE : null;
468c5c2eed7Sopenharmony_ci        let accurateStatus = acManager.verifyAccessTokenSync(this.tokenId, PRECISE_LOCATION_PERMISSION);
469c5c2eed7Sopenharmony_ci        this.accurateIsOn = (accurateStatus == abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) ? true : false;
470c5c2eed7Sopenharmony_ci        let backgroundState = acManager.verifyAccessTokenSync(this.tokenId, BACKGROUND_LOCATION_PERMISSION);
471c5c2eed7Sopenharmony_ci        backgroundState === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED ?
472c5c2eed7Sopenharmony_ci          this.selected = Constants.PERMISSION_ALLOW : null;
473c5c2eed7Sopenharmony_ci        acManager.getPermissionFlags(this.tokenId, FUZZY_LOCATION_PERMISSION).then(flag => {
474c5c2eed7Sopenharmony_ci          flag === Constants.PERMISSION_ALLOW_THIS_TIME ? this.selected = Constants.PERMISSION_ONLY_THIS_TIME : null;
475c5c2eed7Sopenharmony_ci        })
476c5c2eed7Sopenharmony_ci      } catch (err) {
477c5c2eed7Sopenharmony_ci        Log.error('change location status error: ' + JSON.stringify(err));
478c5c2eed7Sopenharmony_ci      }
479c5c2eed7Sopenharmony_ci    } else {
480c5c2eed7Sopenharmony_ci      await this.checkPermissionFlag();
481c5c2eed7Sopenharmony_ci    }
482c5c2eed7Sopenharmony_ci  }
483c5c2eed7Sopenharmony_ci
484c5c2eed7Sopenharmony_ci  async checkPermissionFlag() {
485c5c2eed7Sopenharmony_ci    try {
486c5c2eed7Sopenharmony_ci      for (const permission of this.permissions) {
487c5c2eed7Sopenharmony_ci        let acManager = abilityAccessCtrl.createAtManager();
488c5c2eed7Sopenharmony_ci        let flag = await acManager.getPermissionFlags(this.tokenId, permission);
489c5c2eed7Sopenharmony_ci        Log.error('permission Flag is ' + flag);
490c5c2eed7Sopenharmony_ci        if (flag === Constants.PERMISSION_DEFAULT && terminating == false) {
491c5c2eed7Sopenharmony_ci          PermissionDialogException(Constants.ERR_PERMISSIONS_FLAG_DEFAULT, session);
492c5c2eed7Sopenharmony_ci          terminating = true;
493c5c2eed7Sopenharmony_ci          this.context.terminateSelf();
494c5c2eed7Sopenharmony_ci          return;
495c5c2eed7Sopenharmony_ci        }
496c5c2eed7Sopenharmony_ci      }
497c5c2eed7Sopenharmony_ci    } catch (err) {
498c5c2eed7Sopenharmony_ci      Log.error('getPermissionFlags error: ' + JSON.stringify(err));
499c5c2eed7Sopenharmony_ci    }
500c5c2eed7Sopenharmony_ci  }
501c5c2eed7Sopenharmony_ci
502c5c2eed7Sopenharmony_ci  getCheckboxInfo(permission: Permissions): CheckboxInfo {
503c5c2eed7Sopenharmony_ci    switch (permission) {
504c5c2eed7Sopenharmony_ci      case DOWNLOAD_PERMISSION:
505c5c2eed7Sopenharmony_ci        return new CheckboxInfo($r('app.string.Download_folder'), 0);
506c5c2eed7Sopenharmony_ci      case DESKTOP_PERMISSION:
507c5c2eed7Sopenharmony_ci        return new CheckboxInfo($r('app.string.Desktop_folder'), 1);
508c5c2eed7Sopenharmony_ci      case DOCUMENTS_PERMISSION:
509c5c2eed7Sopenharmony_ci        return new CheckboxInfo($r('app.string.Document_folder'), 2);
510c5c2eed7Sopenharmony_ci      default:
511c5c2eed7Sopenharmony_ci        return new CheckboxInfo($r('app.string.Download_folder'), 0);
512c5c2eed7Sopenharmony_ci    }
513c5c2eed7Sopenharmony_ci  }
514c5c2eed7Sopenharmony_ci
515c5c2eed7Sopenharmony_ci  getMediaDocList() {
516c5c2eed7Sopenharmony_ci    Log.info('current group ' + this.currentGroup);
517c5c2eed7Sopenharmony_ci    Log.info('current permissions ' + this.permissions);
518c5c2eed7Sopenharmony_ci
519c5c2eed7Sopenharmony_ci    if (this.currentGroup == 'PASTEBOARD') {
520c5c2eed7Sopenharmony_ci      this.mediaDocListItem.push(
521c5c2eed7Sopenharmony_ci        new MediaDocObj($r('app.string.per_use_query'), this.permissions, Constants.PERMISSION_ONLY_THIS_TIME)
522c5c2eed7Sopenharmony_ci      );
523c5c2eed7Sopenharmony_ci      this.mediaDocListItem.push(
524c5c2eed7Sopenharmony_ci        new MediaDocObj($r('app.string.always_allow'), this.permissions, Constants.PERMISSION_ALLOW)
525c5c2eed7Sopenharmony_ci      );
526c5c2eed7Sopenharmony_ci    } else if (this.currentGroup == 'LOCATION') {
527c5c2eed7Sopenharmony_ci      this.selected = GlobalContext.load('locationStatus');
528c5c2eed7Sopenharmony_ci      this.mediaDocListItem.push(
529c5c2eed7Sopenharmony_ci        new MediaDocObj($r('app.string.per_inquiry'), this.permissions, Constants.PERMISSION_ONLY_THIS_TIME)
530c5c2eed7Sopenharmony_ci      );
531c5c2eed7Sopenharmony_ci      if (this.permissions.includes(BACKGROUND_LOCATION_PERMISSION)) {
532c5c2eed7Sopenharmony_ci        this.mediaDocListItem.push(
533c5c2eed7Sopenharmony_ci          new MediaDocObj($r('app.string.always_allow'), this.permissions, Constants.PERMISSION_ALLOW)
534c5c2eed7Sopenharmony_ci        );
535c5c2eed7Sopenharmony_ci      }
536c5c2eed7Sopenharmony_ci      if (this.permissions.includes(FUZZY_LOCATION_PERMISSION)) {
537c5c2eed7Sopenharmony_ci        this.mediaDocListItem.push(
538c5c2eed7Sopenharmony_ci          new MediaDocObj(
539c5c2eed7Sopenharmony_ci            $r('app.string.allowed_only_during_use'),
540c5c2eed7Sopenharmony_ci            [FUZZY_LOCATION_PERMISSION],
541c5c2eed7Sopenharmony_ci            Constants.PERMISSION_ALLOWED_ONLY_DURING_USE
542c5c2eed7Sopenharmony_ci          )
543c5c2eed7Sopenharmony_ci        );
544c5c2eed7Sopenharmony_ci      } else {
545c5c2eed7Sopenharmony_ci        this.noForeground = true;
546c5c2eed7Sopenharmony_ci      }
547c5c2eed7Sopenharmony_ci    } else {
548c5c2eed7Sopenharmony_ci      this.mediaDocListItem.push(
549c5c2eed7Sopenharmony_ci        new MediaDocObj($r('app.string.allow'), this.permissions, Constants.PERMISSION_ALLOW)
550c5c2eed7Sopenharmony_ci      );
551c5c2eed7Sopenharmony_ci    }
552c5c2eed7Sopenharmony_ci    this.mediaDocListItem.push(
553c5c2eed7Sopenharmony_ci      new MediaDocObj($r('app.string.ban'), this.permissions, Constants.PERMISSION_BAN)
554c5c2eed7Sopenharmony_ci    );
555c5c2eed7Sopenharmony_ci  }
556c5c2eed7Sopenharmony_ci
557c5c2eed7Sopenharmony_ci  async getReason() {
558c5c2eed7Sopenharmony_ci    this.label = this.applicationInfo.label;
559c5c2eed7Sopenharmony_ci    if (showSubPermissionsGroup.indexOf(this.currentGroup) != -1) {
560c5c2eed7Sopenharmony_ci      this.permissions.forEach((permission, idx) => {
561c5c2eed7Sopenharmony_ci        if (idx > 0) {
562c5c2eed7Sopenharmony_ci          this.permissionLabels.push($r('app.string.and'));
563c5c2eed7Sopenharmony_ci        }
564c5c2eed7Sopenharmony_ci        let label = getPermissionLabel(permission);
565c5c2eed7Sopenharmony_ci        this.permissionLabels.push(label);
566c5c2eed7Sopenharmony_ci      });
567c5c2eed7Sopenharmony_ci    }
568c5c2eed7Sopenharmony_ci    let hasReason = false;
569c5c2eed7Sopenharmony_ci    let info = await
570c5c2eed7Sopenharmony_ci      bundleManager.getBundleInfo(this.bundleName, bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_REQUESTED_PERMISSION)
571c5c2eed7Sopenharmony_ci    for (const permission of this.permissions) {
572c5c2eed7Sopenharmony_ci      for (const reqPermissionDetail of info.reqPermissionDetails) {
573c5c2eed7Sopenharmony_ci        if (reqPermissionDetail.name != permission) {
574c5c2eed7Sopenharmony_ci          continue;
575c5c2eed7Sopenharmony_ci        }
576c5c2eed7Sopenharmony_ci        Log.info('reqPermissionDetail: ' + JSON.stringify(reqPermissionDetail));
577c5c2eed7Sopenharmony_ci        let context = this.context.createModuleContext(this.bundleName, reqPermissionDetail.moduleName);
578c5c2eed7Sopenharmony_ci        let reason = await context.resourceManager.getStringValue(reqPermissionDetail.reasonId);
579c5c2eed7Sopenharmony_ci        if (reason !== undefined && !hasReason) {
580c5c2eed7Sopenharmony_ci          this.reason = reason.slice(Constants.START_SUBSCRIPT, Constants.END_SUBSCRIPT);
581c5c2eed7Sopenharmony_ci          hasReason = true;
582c5c2eed7Sopenharmony_ci        }
583c5c2eed7Sopenharmony_ci      }
584c5c2eed7Sopenharmony_ci    }
585c5c2eed7Sopenharmony_ci  }
586c5c2eed7Sopenharmony_ci
587c5c2eed7Sopenharmony_ci  aboutToAppear() {
588c5c2eed7Sopenharmony_ci    this.refreshStatus();
589c5c2eed7Sopenharmony_ci    this.getMediaDocList();
590c5c2eed7Sopenharmony_ci    this.getReason();
591c5c2eed7Sopenharmony_ci    this.setState();
592c5c2eed7Sopenharmony_ci  }
593c5c2eed7Sopenharmony_ci
594c5c2eed7Sopenharmony_ci  setState() {
595c5c2eed7Sopenharmony_ci    this.hidden = false;
596c5c2eed7Sopenharmony_ci    this.selected = this.status;
597c5c2eed7Sopenharmony_ci    bundleManager.getBundleInfo(this.bundleName, bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION)
598c5c2eed7Sopenharmony_ci    .then(async res => {
599c5c2eed7Sopenharmony_ci        this.api = res.targetVersion;
600c5c2eed7Sopenharmony_ci        this.version = res.versionName;
601c5c2eed7Sopenharmony_ci        accessTokenId = res.appInfo.accessTokenId;
602c5c2eed7Sopenharmony_ci        let acManager = abilityAccessCtrl.createAtManager();
603c5c2eed7Sopenharmony_ci        let accurateStatus = acManager.verifyAccessTokenSync(res.appInfo.accessTokenId, PRECISE_LOCATION_PERMISSION);
604c5c2eed7Sopenharmony_ci        this.accurateIsOn = (accurateStatus == abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) ? true : false;
605c5c2eed7Sopenharmony_ci        try {
606c5c2eed7Sopenharmony_ci          let getFlagPermission = this.currentGroup === 'LOCATION' ? FUZZY_LOCATION_PERMISSION : this.permissions[0];
607c5c2eed7Sopenharmony_ci          let flag = await acManager.getPermissionFlags(res.appInfo.accessTokenId, getFlagPermission);
608c5c2eed7Sopenharmony_ci          Log.info(`getPermissionFlags success, data->${JSON.stringify(flag)}`);
609c5c2eed7Sopenharmony_ci          this.isRisk = (flag == Constants.PERMISSION_POLICY_FIXED) ? true : false;
610c5c2eed7Sopenharmony_ci          if (flag === Constants.PERMISSION_ALLOW_THIS_TIME) {
611c5c2eed7Sopenharmony_ci            this.selected = Constants.PERMISSION_ONLY_THIS_TIME;
612c5c2eed7Sopenharmony_ci          }
613c5c2eed7Sopenharmony_ci        } catch (err) {
614c5c2eed7Sopenharmony_ci          Log.error('acManager.getPermissionFlags failed. Cause: ' + JSON.stringify(err));
615c5c2eed7Sopenharmony_ci        }
616c5c2eed7Sopenharmony_ci      }).catch((error: BusinessError) => {
617c5c2eed7Sopenharmony_ci      Log.error('bundle.getBundleInfo failed. Cause: ' + JSON.stringify(error));
618c5c2eed7Sopenharmony_ci    });
619c5c2eed7Sopenharmony_ci  }
620c5c2eed7Sopenharmony_ci
621c5c2eed7Sopenharmony_ci  async grantFolderPermission(permission: Permissions) {
622c5c2eed7Sopenharmony_ci    if (this.folderStatus[this.getCheckboxInfo(permission).index]) {
623c5c2eed7Sopenharmony_ci      this.revokeUserGrantedPermission(accessTokenId, permission, Constants.PERMISSION_FLAG);
624c5c2eed7Sopenharmony_ci      this.folderStatus[this.getCheckboxInfo(permission).index] = false;
625c5c2eed7Sopenharmony_ci      results.set(permission, Constants.ERR_PERMISSION_GRANT_EXCEPTION);
626c5c2eed7Sopenharmony_ci    } else {
627c5c2eed7Sopenharmony_ci      await this.grantUserGrantedPermission(accessTokenId, permission);
628c5c2eed7Sopenharmony_ci      this.folderStatus[this.getCheckboxInfo(permission).index] = true;
629c5c2eed7Sopenharmony_ci    }
630c5c2eed7Sopenharmony_ci    // check if every permission has been granted
631c5c2eed7Sopenharmony_ci    let allGranted = true;
632c5c2eed7Sopenharmony_ci    for (const permission of this.permissions) {
633c5c2eed7Sopenharmony_ci      if (!results.has(permission)) {
634c5c2eed7Sopenharmony_ci        Log.info('permission ' + permission + ' not granted, continue');
635c5c2eed7Sopenharmony_ci        return;
636c5c2eed7Sopenharmony_ci      }
637c5c2eed7Sopenharmony_ci      if (results.get(permission) !== Constants.PERMISSION_DIALOG_SUCCESS) {
638c5c2eed7Sopenharmony_ci        allGranted = false;
639c5c2eed7Sopenharmony_ci      }
640c5c2eed7Sopenharmony_ci    }
641c5c2eed7Sopenharmony_ci    // if all granted , return status
642c5c2eed7Sopenharmony_ci    if (allGranted) {
643c5c2eed7Sopenharmony_ci      ReportDialogResult(this.permissions);
644c5c2eed7Sopenharmony_ci    }
645c5c2eed7Sopenharmony_ci  }
646c5c2eed7Sopenharmony_ci
647c5c2eed7Sopenharmony_ci  async grantOtherPermissions(item: MediaDocObj) {
648c5c2eed7Sopenharmony_ci    this.selected = item.index;
649c5c2eed7Sopenharmony_ci    for (const permission of item.permissions) {
650c5c2eed7Sopenharmony_ci      Log.info('item click index:' + item.index);
651c5c2eed7Sopenharmony_ci      if (item.index === Constants.PERMISSION_ALLOW) {
652c5c2eed7Sopenharmony_ci        if (permission !== PRECISE_LOCATION_PERMISSION) {
653c5c2eed7Sopenharmony_ci          await this.grantUserGrantedPermission(accessTokenId, permission);
654c5c2eed7Sopenharmony_ci        }
655c5c2eed7Sopenharmony_ci      } else if (item.index === Constants.PERMISSION_BAN) {
656c5c2eed7Sopenharmony_ci        if (permission == PRECISE_LOCATION_PERMISSION && this.accurateIsOn) {
657c5c2eed7Sopenharmony_ci          this.revokeUserGrantedPermission(accessTokenId, permission, Constants.PERMISSION_FLAG);
658c5c2eed7Sopenharmony_ci          this.accurateIsOn = false;
659c5c2eed7Sopenharmony_ci        } else {
660c5c2eed7Sopenharmony_ci          this.revokeUserGrantedPermission(accessTokenId, permission, Constants.PERMISSION_FLAG);
661c5c2eed7Sopenharmony_ci        }
662c5c2eed7Sopenharmony_ci      } else if (item.index === Constants.PERMISSION_ONLY_THIS_TIME) {
663c5c2eed7Sopenharmony_ci        if (permission !== PRECISE_LOCATION_PERMISSION) {
664c5c2eed7Sopenharmony_ci          await this.revokeUserGrantedPermission(
665c5c2eed7Sopenharmony_ci            accessTokenId, permission, Constants.PERMISSION_ALLOW_THIS_TIME
666c5c2eed7Sopenharmony_ci          );
667c5c2eed7Sopenharmony_ci        }
668c5c2eed7Sopenharmony_ci      } else if (item.index === Constants.PERMISSION_ALLOWED_ONLY_DURING_USE) {
669c5c2eed7Sopenharmony_ci        await this.grantUserGrantedPermission(accessTokenId, permission);
670c5c2eed7Sopenharmony_ci        await this.revokeUserGrantedPermission(
671c5c2eed7Sopenharmony_ci          accessTokenId, BACKGROUND_LOCATION_PERMISSION, Constants.PERMISSION_FLAG
672c5c2eed7Sopenharmony_ci        );
673c5c2eed7Sopenharmony_ci      }
674c5c2eed7Sopenharmony_ci    }
675c5c2eed7Sopenharmony_ci    ReportDialogResult(this.permissions);
676c5c2eed7Sopenharmony_ci    return true;
677c5c2eed7Sopenharmony_ci  }
678c5c2eed7Sopenharmony_ci
679c5c2eed7Sopenharmony_ci  build() {
680c5c2eed7Sopenharmony_ci    Column() {
681c5c2eed7Sopenharmony_ci      Row() {
682c5c2eed7Sopenharmony_ci        Column() {
683c5c2eed7Sopenharmony_ci          Row() {
684c5c2eed7Sopenharmony_ci            Text(this.backTitle)
685c5c2eed7Sopenharmony_ci              .align(Alignment.Start)
686c5c2eed7Sopenharmony_ci              .fontColor($r('sys.color.font_primary'))
687c5c2eed7Sopenharmony_ci              .maxLines(Constants.MAXIMUM_HEADER_LINES)
688c5c2eed7Sopenharmony_ci              .textOverflow({ overflow: TextOverflow.Ellipsis })
689c5c2eed7Sopenharmony_ci              .fontSize(Constants.TEXT_BIG_FONT_SIZE)
690c5c2eed7Sopenharmony_ci              .flexGrow(Constants.FLEX_GROW)
691c5c2eed7Sopenharmony_ci              .fontWeight(FontWeight.Bold)
692c5c2eed7Sopenharmony_ci              .padding({ left: Constants.PADDING_24, top: Constants.PADDING_20, bottom: Constants.PADDING_20 })
693c5c2eed7Sopenharmony_ci              .width('80%')
694c5c2eed7Sopenharmony_ci          }.width(Constants.FULL_WIDTH)
695c5c2eed7Sopenharmony_ci        }
696c5c2eed7Sopenharmony_ci        .alignItems(HorizontalAlign.Start)
697c5c2eed7Sopenharmony_ci        .width(Constants.FULL_WIDTH)
698c5c2eed7Sopenharmony_ci      }
699c5c2eed7Sopenharmony_ci      Row() {
700c5c2eed7Sopenharmony_ci        Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
701c5c2eed7Sopenharmony_ci          Image(this.applicationInfo.icon)
702c5c2eed7Sopenharmony_ci            .width(Constants.TERTIARY_IMAGE_WIDTH)
703c5c2eed7Sopenharmony_ci            .height(Constants.TERTIARY_IMAGE_HEIGHT)
704c5c2eed7Sopenharmony_ci            .margin({ left: Constants.TERTIARY_IMAGE_MARGIN_LEFT, right: Constants.TERTIARY_IMAGE_MARGIN_RIGHT })
705c5c2eed7Sopenharmony_ci          Column() {
706c5c2eed7Sopenharmony_ci            Row() {
707c5c2eed7Sopenharmony_ci              Text(this.label)
708c5c2eed7Sopenharmony_ci                .maxLines(Constants.MAXIMUM_HEADER_LINES)
709c5c2eed7Sopenharmony_ci                .textOverflow({ overflow: TextOverflow.Ellipsis })
710c5c2eed7Sopenharmony_ci                .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE)
711c5c2eed7Sopenharmony_ci                .fontColor($r('sys.color.font_primary'))
712c5c2eed7Sopenharmony_ci                .fontWeight(FontWeight.Bold)
713c5c2eed7Sopenharmony_ci                .textAlign(TextAlign.Start)
714c5c2eed7Sopenharmony_ci            }
715c5c2eed7Sopenharmony_ci            .width(Constants.TERTIARY_HALF_WIDTH)
716c5c2eed7Sopenharmony_ci            .margin({ bottom: Constants.TERTIARY_LABEL_MARGIN_BOTTOM })
717c5c2eed7Sopenharmony_ci
718c5c2eed7Sopenharmony_ci            Row() {
719c5c2eed7Sopenharmony_ci              Text($r('app.string.version'))
720c5c2eed7Sopenharmony_ci                .fontSize(Constants.TEXT_SMALL_FONT_SIZE)
721c5c2eed7Sopenharmony_ci                .fontColor($r('sys.color.font_secondary'))
722c5c2eed7Sopenharmony_ci                .textAlign(TextAlign.Start)
723c5c2eed7Sopenharmony_ci              Text(this.version)
724c5c2eed7Sopenharmony_ci                .fontSize(Constants.TEXT_SMALL_FONT_SIZE)
725c5c2eed7Sopenharmony_ci                .fontColor($r('sys.color.font_secondary'))
726c5c2eed7Sopenharmony_ci                .textAlign(TextAlign.Start)
727c5c2eed7Sopenharmony_ci            }
728c5c2eed7Sopenharmony_ci            .width(Constants.TERTIARY_HALF_WIDTH)
729c5c2eed7Sopenharmony_ci          }
730c5c2eed7Sopenharmony_ci        }.margin({ left: Constants.TERTIARY_MARGIN_LEFT })
731c5c2eed7Sopenharmony_ci      }
732c5c2eed7Sopenharmony_ci      if (this.isRisk) {
733c5c2eed7Sopenharmony_ci        Row() {
734c5c2eed7Sopenharmony_ci          Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
735c5c2eed7Sopenharmony_ci            Row() {
736c5c2eed7Sopenharmony_ci              Image($r('app.media.ic_public_fail'))
737c5c2eed7Sopenharmony_ci                .fillColor($r('sys.color.icon_secondary'))
738c5c2eed7Sopenharmony_ci                .width(Constants.TERTIARY_RADIO_IMAGE_WIDTH)
739c5c2eed7Sopenharmony_ci                .height(Constants.TERTIARY_RADIO_IMAGE_HEIGHT)
740c5c2eed7Sopenharmony_ci                .margin({ right: Constants.TERTIARY_IMAGE_MARGIN_RIGHT })
741c5c2eed7Sopenharmony_ci              Text($r('app.string.risk_warning'))
742c5c2eed7Sopenharmony_ci                .fontColor($r('sys.color.font_primary'))
743c5c2eed7Sopenharmony_ci                .fontSize($r('sys.float.ohos_id_text_size_body1'))
744c5c2eed7Sopenharmony_ci                .fontWeight(FontWeight.Regular)
745c5c2eed7Sopenharmony_ci            }.margin({ left: Constants.DEFAULT_PADDING_START, right: Constants.DEFAULT_PADDING_END })
746c5c2eed7Sopenharmony_ci          }
747c5c2eed7Sopenharmony_ci        }.backgroundColor($r('sys.color.interactive_click'))
748c5c2eed7Sopenharmony_ci        .borderRadius($r('sys.float.ohos_id_corner_radius_default_l'))
749c5c2eed7Sopenharmony_ci        .padding({ top: Constants.DEFAULT_PADDING_TOP, bottom: Constants.DEFAULT_PADDING_BOTTOM })
750c5c2eed7Sopenharmony_ci        .margin({ left: Constants.DEFAULT_MARGIN_START, right: Constants.DEFAULT_MARGIN_END })
751c5c2eed7Sopenharmony_ci      }
752c5c2eed7Sopenharmony_ci      Row() {
753c5c2eed7Sopenharmony_ci        Text() {
754c5c2eed7Sopenharmony_ci          Span(this.backTitle)
755c5c2eed7Sopenharmony_ci          Span($r('app.string.access_permission'))
756c5c2eed7Sopenharmony_ci        }
757c5c2eed7Sopenharmony_ci        .fontSize(Constants.TEXT_SMALL_FONT_SIZE)
758c5c2eed7Sopenharmony_ci        .fontColor($r('sys.color.icon_secondary'))
759c5c2eed7Sopenharmony_ci        .fontWeight(FontWeight.Medium)
760c5c2eed7Sopenharmony_ci        .textAlign(TextAlign.Start)
761c5c2eed7Sopenharmony_ci        .lineHeight(Constants.SUBTITLE_LINE_HEIGHT)
762c5c2eed7Sopenharmony_ci      }.width(Constants.FULL_WIDTH)
763c5c2eed7Sopenharmony_ci      .constraintSize({ minHeight: Constants.SUBTITLE_MIN_HEIGHT })
764c5c2eed7Sopenharmony_ci      .padding({ top: Constants.SUBTITLE_PADDING_TOP, bottom: Constants.SUBTITLE_PADDING_BOTTOM,
765c5c2eed7Sopenharmony_ci        left: Constants.TERTIARY_TEXT_MARGIN_LEFT, right: Constants.TERTIARY_IMAGE_MARGIN_RIGHT })
766c5c2eed7Sopenharmony_ci
767c5c2eed7Sopenharmony_ci      Column() {
768c5c2eed7Sopenharmony_ci        List() {
769c5c2eed7Sopenharmony_ci          if (this.currentGroup === 'FOLDER') {
770c5c2eed7Sopenharmony_ci            ForEach(this.permissions, (permission: Permissions) => {
771c5c2eed7Sopenharmony_ci              ListItem() {
772c5c2eed7Sopenharmony_ci                Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
773c5c2eed7Sopenharmony_ci                  Row() {
774c5c2eed7Sopenharmony_ci                    Text(this.getCheckboxInfo(permission).label)
775c5c2eed7Sopenharmony_ci                      .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE)
776c5c2eed7Sopenharmony_ci                      .fontColor($r('sys.color.font_primary'))
777c5c2eed7Sopenharmony_ci                      .fontWeight(FontWeight.Medium)
778c5c2eed7Sopenharmony_ci                      .flexGrow(Constants.FLEX_GROW)
779c5c2eed7Sopenharmony_ci                    Checkbox()
780c5c2eed7Sopenharmony_ci                      .select(this.folderStatus[this.getCheckboxInfo(permission).index])
781c5c2eed7Sopenharmony_ci                      .hitTestBehavior(HitTestMode.None)
782c5c2eed7Sopenharmony_ci                  }
783c5c2eed7Sopenharmony_ci                  .width(Constants.FULL_WIDTH)
784c5c2eed7Sopenharmony_ci                  .height(Constants.LISTITEM_ROW_HEIGHT)
785c5c2eed7Sopenharmony_ci                  .onClick(async () => {
786c5c2eed7Sopenharmony_ci                      await this.grantFolderPermission(permission)
787c5c2eed7Sopenharmony_ci                  })
788c5c2eed7Sopenharmony_ci                }
789c5c2eed7Sopenharmony_ci              }
790c5c2eed7Sopenharmony_ci              .padding({
791c5c2eed7Sopenharmony_ci                left: $r('sys.float.ohos_id_card_margin_start'),
792c5c2eed7Sopenharmony_ci                right: $r('sys.float.ohos_id_card_margin_end')
793c5c2eed7Sopenharmony_ci              })
794c5c2eed7Sopenharmony_ci              .borderRadius($r('sys.float.ohos_id_corner_radius_default_l'))
795c5c2eed7Sopenharmony_ci              .margin({ top: Constants.TERTIARY_LISTITEM_MARGIN_TOP })
796c5c2eed7Sopenharmony_ci              .linearGradient((this.isCheck === permission) ? {
797c5c2eed7Sopenharmony_ci                angle: 90,
798c5c2eed7Sopenharmony_ci                direction: GradientDirection.Right,
799c5c2eed7Sopenharmony_ci                colors: [['#DCEAF9', 0.0], ['#FAFAFA', 1.0]]
800c5c2eed7Sopenharmony_ci              } : {
801c5c2eed7Sopenharmony_ci                angle: 90,
802c5c2eed7Sopenharmony_ci                direction: GradientDirection.Right,
803c5c2eed7Sopenharmony_ci                colors: []
804c5c2eed7Sopenharmony_ci              })
805c5c2eed7Sopenharmony_ci              .onTouch(event => {
806c5c2eed7Sopenharmony_ci                if (event === undefined) {
807c5c2eed7Sopenharmony_ci                  return;
808c5c2eed7Sopenharmony_ci                }
809c5c2eed7Sopenharmony_ci                if (event.type === TouchType.Down) {
810c5c2eed7Sopenharmony_ci                  this.isCheck = permission;
811c5c2eed7Sopenharmony_ci                }
812c5c2eed7Sopenharmony_ci                if (event.type === TouchType.Up) {
813c5c2eed7Sopenharmony_ci                  this.isCheck = '';
814c5c2eed7Sopenharmony_ci                }
815c5c2eed7Sopenharmony_ci              })
816c5c2eed7Sopenharmony_ci            }, (permission: Permissions) => JSON.stringify(permission))
817c5c2eed7Sopenharmony_ci          } else {
818c5c2eed7Sopenharmony_ci            ForEach(this.mediaDocListItem, (item: MediaDocObj) => {
819c5c2eed7Sopenharmony_ci              ListItem() {
820c5c2eed7Sopenharmony_ci                Column() {
821c5c2eed7Sopenharmony_ci                  Row() {
822c5c2eed7Sopenharmony_ci                    Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
823c5c2eed7Sopenharmony_ci                      Row() {
824c5c2eed7Sopenharmony_ci                        Text(item.name)
825c5c2eed7Sopenharmony_ci                          .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE)
826c5c2eed7Sopenharmony_ci                          .fontColor($r('sys.color.font_primary'))
827c5c2eed7Sopenharmony_ci                          .fontWeight(FontWeight.Medium)
828c5c2eed7Sopenharmony_ci                          .flexGrow(Constants.FLEX_GROW)
829c5c2eed7Sopenharmony_ci                        Radio({ value: 'Radio', group: 'radioGroup' })
830c5c2eed7Sopenharmony_ci                          .checked(item.index === this.selected)
831c5c2eed7Sopenharmony_ci                          .hitTestBehavior(HitTestMode.None)
832c5c2eed7Sopenharmony_ci                          .height(Constants.SHAPE_DIA)
833c5c2eed7Sopenharmony_ci                          .width(Constants.SHAPE_DIA)
834c5c2eed7Sopenharmony_ci                      }
835c5c2eed7Sopenharmony_ci                      .width(Constants.FULL_WIDTH)
836c5c2eed7Sopenharmony_ci                      .height(Constants.LISTITEM_ROW_HEIGHT)
837c5c2eed7Sopenharmony_ci                      .onClick(async () => {
838c5c2eed7Sopenharmony_ci                        await this.grantOtherPermissions(item);
839c5c2eed7Sopenharmony_ci                      })
840c5c2eed7Sopenharmony_ci                    }
841c5c2eed7Sopenharmony_ci                  }
842c5c2eed7Sopenharmony_ci                }
843c5c2eed7Sopenharmony_ci              }
844c5c2eed7Sopenharmony_ci              .padding({
845c5c2eed7Sopenharmony_ci                left: $r('sys.float.ohos_id_card_margin_start'),
846c5c2eed7Sopenharmony_ci                right: $r('sys.float.ohos_id_card_margin_end')
847c5c2eed7Sopenharmony_ci              })
848c5c2eed7Sopenharmony_ci              .borderRadius($r('sys.float.ohos_id_corner_radius_default_l'))
849c5c2eed7Sopenharmony_ci              .linearGradient((this.isTouch === item.index) ? {
850c5c2eed7Sopenharmony_ci                angle: 90,
851c5c2eed7Sopenharmony_ci                direction: GradientDirection.Right,
852c5c2eed7Sopenharmony_ci                colors: [['#DCEAF9', 0.0], ['#FAFAFA', 1.0]]
853c5c2eed7Sopenharmony_ci              } : {
854c5c2eed7Sopenharmony_ci                angle: 90,
855c5c2eed7Sopenharmony_ci                direction: GradientDirection.Right,
856c5c2eed7Sopenharmony_ci                colors: []
857c5c2eed7Sopenharmony_ci              })
858c5c2eed7Sopenharmony_ci              .onTouch(event => {
859c5c2eed7Sopenharmony_ci                if (event === undefined) {
860c5c2eed7Sopenharmony_ci                  return;
861c5c2eed7Sopenharmony_ci                }
862c5c2eed7Sopenharmony_ci                if (event.type === TouchType.Down) {
863c5c2eed7Sopenharmony_ci                  this.isTouch = item.index;
864c5c2eed7Sopenharmony_ci                }
865c5c2eed7Sopenharmony_ci                if (event.type === TouchType.Up) {
866c5c2eed7Sopenharmony_ci                  this.isTouch = -1;
867c5c2eed7Sopenharmony_ci                }
868c5c2eed7Sopenharmony_ci              })
869c5c2eed7Sopenharmony_ci              .margin({ top: Constants.TERTIARY_LISTITEM_MARGIN_TOP })
870c5c2eed7Sopenharmony_ci            }, (item: MediaDocObj) => JSON.stringify(item))
871c5c2eed7Sopenharmony_ci          }
872c5c2eed7Sopenharmony_ci        }
873c5c2eed7Sopenharmony_ci        .borderRadius($r('sys.float.ohos_id_corner_radius_card'))
874c5c2eed7Sopenharmony_ci        .backgroundColor($r('sys.color.comp_background_list_card'))
875c5c2eed7Sopenharmony_ci        .padding(Constants.LIST_PADDING_TOP)
876c5c2eed7Sopenharmony_ci        .divider({
877c5c2eed7Sopenharmony_ci          strokeWidth: Constants.DIVIDER,
878c5c2eed7Sopenharmony_ci          color: $r('sys.color.comp_divider'),
879c5c2eed7Sopenharmony_ci          startMargin: Constants.DEFAULT_MARGIN_START,
880c5c2eed7Sopenharmony_ci          endMargin: Constants.DEFAULT_MARGIN_END
881c5c2eed7Sopenharmony_ci        })
882c5c2eed7Sopenharmony_ci
883c5c2eed7Sopenharmony_ci        if (this.permissions.includes(PRECISE_LOCATION_PERMISSION)) {
884c5c2eed7Sopenharmony_ci          Column() {
885c5c2eed7Sopenharmony_ci            Row() {
886c5c2eed7Sopenharmony_ci              Text($r('app.string.precise_location'))
887c5c2eed7Sopenharmony_ci                .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE)
888c5c2eed7Sopenharmony_ci                .fontColor($r('sys.color.font_primary'))
889c5c2eed7Sopenharmony_ci                .fontWeight(FontWeight.Medium)
890c5c2eed7Sopenharmony_ci                .flexGrow(Constants.FLEX_GROW)
891c5c2eed7Sopenharmony_ci              Toggle({ type: ToggleType.Switch, isOn: this.accurateIsOn })
892c5c2eed7Sopenharmony_ci                .selectedColor($r('sys.color.icon_emphasize'))
893c5c2eed7Sopenharmony_ci                .switchPointColor($r('sys.color.comp_background_primary_contrary'))
894c5c2eed7Sopenharmony_ci                .onChange((isOn: boolean) => {
895c5c2eed7Sopenharmony_ci                  let acManager = abilityAccessCtrl.createAtManager()
896c5c2eed7Sopenharmony_ci                  if (isOn) {
897c5c2eed7Sopenharmony_ci                    acManager.grantUserGrantedPermission(
898c5c2eed7Sopenharmony_ci                      accessTokenId, PRECISE_LOCATION_PERMISSION, Constants.PERMISSION_FLAG
899c5c2eed7Sopenharmony_ci                    ).then(() => {
900c5c2eed7Sopenharmony_ci                      this.accurateIsOn = true
901c5c2eed7Sopenharmony_ci                    })
902c5c2eed7Sopenharmony_ci                  } else {
903c5c2eed7Sopenharmony_ci                    acManager.revokeUserGrantedPermission(
904c5c2eed7Sopenharmony_ci                      accessTokenId, PRECISE_LOCATION_PERMISSION, Constants.PERMISSION_FLAG
905c5c2eed7Sopenharmony_ci                    ).then(() => {
906c5c2eed7Sopenharmony_ci                      this.accurateIsOn = false
907c5c2eed7Sopenharmony_ci                    })
908c5c2eed7Sopenharmony_ci                  }
909c5c2eed7Sopenharmony_ci                })
910c5c2eed7Sopenharmony_ci                .padding({ right: 0 })
911c5c2eed7Sopenharmony_ci                .enabled(this.selected !== Constants.PERMISSION_BAN)
912c5c2eed7Sopenharmony_ci            }.width(Constants.FULL_WIDTH)
913c5c2eed7Sopenharmony_ci            .height(Constants.LISTITEM_ROW_HEIGHT)
914c5c2eed7Sopenharmony_ci          }.margin({ top: Constants.LOCATION_MARGIN_TOP, bottom: Constants.LOCATION_MARGIN_BOTTOM })
915c5c2eed7Sopenharmony_ci          .padding({
916c5c2eed7Sopenharmony_ci            left: Constants.DEFAULT_PADDING_START,
917c5c2eed7Sopenharmony_ci            right: Constants.DEFAULT_PADDING_END,
918c5c2eed7Sopenharmony_ci            top: Constants.TERTIARY_LIST_PADDING_TOP,
919c5c2eed7Sopenharmony_ci            bottom: Constants.TERTIARY_LIST_PADDING_BOTTOM
920c5c2eed7Sopenharmony_ci          })
921c5c2eed7Sopenharmony_ci          .borderRadius($r('sys.float.ohos_id_corner_radius_card'))
922c5c2eed7Sopenharmony_ci          .backgroundColor($r('sys.color.comp_background_list_card'))
923c5c2eed7Sopenharmony_ci
924c5c2eed7Sopenharmony_ci          Row() {
925c5c2eed7Sopenharmony_ci            Text($r('app.string.get_the_exact_position'))
926c5c2eed7Sopenharmony_ci              .fontSize(Constants.TEXT_SMALL_FONT_SIZE)
927c5c2eed7Sopenharmony_ci              .fontColor($r('sys.color.font_secondary'))
928c5c2eed7Sopenharmony_ci              .lineHeight(Constants.TEXT_SMALL_LINE_HEIGHT)
929c5c2eed7Sopenharmony_ci          }.width(Constants.FULL_WIDTH)
930c5c2eed7Sopenharmony_ci          .padding({
931c5c2eed7Sopenharmony_ci            left: Constants.DEFAULT_PADDING_START,
932c5c2eed7Sopenharmony_ci            right: Constants.DEFAULT_PADDING_END,
933c5c2eed7Sopenharmony_ci          })
934c5c2eed7Sopenharmony_ci        }
935c5c2eed7Sopenharmony_ci      }
936c5c2eed7Sopenharmony_ci      .padding({
937c5c2eed7Sopenharmony_ci        left: Constants.LIST_PADDING_LEFT,
938c5c2eed7Sopenharmony_ci        right: Constants.LIST_PADDING_LEFT
939c5c2eed7Sopenharmony_ci      })
940c5c2eed7Sopenharmony_ci      .width(Constants.FULL_WIDTH)
941c5c2eed7Sopenharmony_ci      .enabled(!this.isRisk && !this.noForeground)
942c5c2eed7Sopenharmony_ci      .opacity((!this.isRisk && !this.noForeground) ? 1 : $r('sys.float.ohos_id_alpha_disabled'))
943c5c2eed7Sopenharmony_ci    }
944c5c2eed7Sopenharmony_ci    .visibility(this.hidden ? Visibility.None : Visibility.Visible)
945c5c2eed7Sopenharmony_ci    .width(Constants.FULL_WIDTH)
946c5c2eed7Sopenharmony_ci  }
947c5c2eed7Sopenharmony_ci}
948