• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import { backBar } from "../common/components/backBar";
17import router from '@ohos.router';
18import bundle from "@ohos.bundle";
19import bundleManager from '@ohos.bundle.bundleManager';
20import { getAppLabel, getAppIcon } from "../common/utils/utils";
21import abilityAccessCtrl from '@ohos.abilityAccessCtrl';
22import { authorizeDialog } from "../common/components/dialog";
23import { showSubpermissionsGrop } from "../common/model/permissionGroup";
24import Constants from '../common/utils/constant';
25
26var TAG = 'PermissionManager_MainAbility:'
27
28let routerData: any = router.getParams()['routerData']; // Routing jump data
29let backTitle: any = router.getParams()['backTitle']; // return title name
30let status = router.getParams()['status']; // Status: Allowed, Forbidden
31let permissions: any = router.getParams()['permission']; // permissions name
32let nowGrantResult = Constants.PERMISSION_NUM; // Authorization results now
33let nowRevokeResult = Constants.PERMISSION_NUM; // Now deauthorize results
34let GrantResultFlag = []; // Authorization result Flag
35let RevokeResultFlag = []; // Cancel authorization result Flag
36let reason = null  // Authorized reason
37let bundleInfo: any = {}
38const PRECISE_LOCATION_PERMISSION = 'ohos.permission.LOCATION'
39class MeidaDocObj {
40  name: Resource
41  index: number
42  groupName: string
43  accessTokenId: number
44  permissions: []
45  constructor(
46    name: Resource,
47    index: number,
48    groupName: string,
49    accessTokenId: number,
50    permissions: []
51  ) {
52    this.name = name
53    this.index = index
54    this.groupName = groupName
55    this.accessTokenId = accessTokenId
56    this.permissions = permissions
57  }
58}; // permission information class
59class MediaListObj {
60  labelId: string
61  iconId: string
62  versionName: string
63  constructor(labelId: string, iconId: string, versionName: string,) {
64    this.labelId = labelId
65    this.iconId = iconId
66    this.versionName = versionName
67  }
68}; // Permission application information class
69
70class ResourceObj {
71  period: string
72  comma: string
73  constructor(period: string, comma: string) {
74    this.period = period
75    this.comma = comma
76  }
77}
78
79@Entry
80@Component
81struct mediaDocumentPage {
82  build() {
83    Column() {
84      GridContainer({ gutter: Constants.GUTTER, margin: Constants.GRID_MARGIN }) {
85        Row() {
86          Row()
87            .useSizeType({
88              xs: { span: Constants.LEFT_XS_SPAN, offset: Constants.LEFT_XS_OFFSET },
89              sm: { span: Constants.LEFT_SM_SPAN, offset: Constants.LEFT_SM_OFFSET },
90              md: { span: Constants.LEFT_MD_SPAN, offset: Constants.LEFT_MD_OFFSET },
91              lg: { span: Constants.LEFT_LG_SPAN, offset: Constants.LEFT_LG_OFFSET }
92            })
93            .height(Constants.FULL_HEIGHT)
94          Row() {
95            Column() {
96              Row() {
97                backBar({ title: JSON.stringify(backTitle), recordable: false })
98              }
99              Row() {
100                Column() {
101                  mediaDocumentItem()
102                }.width(Constants.FULL_WIDTH)
103              }
104              .margin({ top: Constants.TITLE_MARGIN_BOTTOM })
105              .layoutWeight(Constants.LAYOUT_WEIGHT)
106            }
107          }
108          .useSizeType({
109            xs: { span: Constants.MIDDLE_XS_SPAN, offset: Constants.MIDDLE_XS_OFFSET },
110            sm: { span: Constants.MIDDLE_SM_SPAN, offset: Constants.MIDDLE_SM_OFFSET },
111            md: { span: Constants.MIDDLE_MD_SPAN, offset: Constants.MIDDLE_MD_OFFSET },
112            lg: { span: Constants.MIDDLE_LG_SPAN, offset: Constants.MIDDLE_LG_OFFSET }
113          })
114          .height(Constants.FULL_HEIGHT)
115          Row()
116            .useSizeType({
117              xs: { span: Constants.RIGHT_XS_SPAN, offset: Constants.RIGHT_XS_OFFSET },
118              sm: { span: Constants.RIGHT_SM_SPAN, offset: Constants.RIGHT_SM_OFFSET },
119              md: { span: Constants.RIGHT_MD_SPAN, offset: Constants.RIGHT_MD_OFFSET },
120              lg: { span: Constants.RIGHT_LG_SPAN, offset: Constants.RIGHT_LG_OFFSET }
121            })
122            .height(Constants.FULL_HEIGHT)
123        }
124        .height(Constants.FULL_HEIGHT)
125        .width(Constants.FULL_WIDTH)
126        .backgroundColor($r("sys.color.ohos_id_color_sub_background"))
127      }
128    }
129  }
130}
131
132@Component
133struct mediaDocumentItem {
134  @State mediaDocListItem: MeidaDocObj[] = []; // Permission information array
135  @State mediaListItem: MediaListObj = {
136    labelId: '',
137    iconId: '',
138    versionName: '',
139  }; // application info array
140  @State isCheckList: boolean[] = []; // Permission status array
141  @State accurateIsOn: boolean = true;
142  @State api: number = 0;
143  @State resource: ResourceObj = new ResourceObj('', '')
144
145  authorizeDialogController: CustomDialogController = new CustomDialogController({
146    builder: authorizeDialog({ }),
147    autoCancel: true,
148    alignment: DialogAlignment.Center
149  });
150
151  /**
152   * Grant permissions to the app
153   * @param {Number} accessTokenId
154   * @param {String} permission permission name
155   */
156  grantUserGrantedPermission(accessTokenId, permission) {
157    abilityAccessCtrl.createAtManager().grantUserGrantedPermission(
158      accessTokenId, permission, Constants.PERMISSION_FLAG).then(() => {
159      nowGrantResult = Constants.PERMISSION_INDEX;
160    })
161    .catch((error) => {
162      console.error(TAG + 'grantUserGrantedPermission failed. Cause: ' + JSON.stringify(error));
163    })
164  }
165
166  /**
167   * Deauthorize the app
168   * @param {Number} accessTokenId
169   * @param {String} permission permission name
170   */
171  revokeUserGrantedPermission(accessTokenId, permission) {
172    abilityAccessCtrl.createAtManager().revokeUserGrantedPermission(
173      accessTokenId, permission, Constants.PERMISSION_FLAG).then(() => {
174      nowRevokeResult = Constants.PERMISSION_INDEX;
175    })
176      .catch((error) => {
177        console.error(TAG + 'revokeUserGrantedPermission failed. Cause: ' + JSON.stringify(error));
178      })
179  }
180
181  /**
182   * Lifecycle function, executed when the page is initialized
183   */
184  aboutToAppear() {
185    if(showSubpermissionsGrop.indexOf(globalThis.currentPermissionGroup) != -1) {
186      reason = []
187      permissions.forEach(permission => {
188        reason.push(globalThis.permissionLabels[permission])
189      })
190      Promise.all([globalThis.context.resourceManager.getString($r("app.string.separator").id),
191      globalThis.context.resourceManager.getString($r("app.string.reason_suffix").id),
192      globalThis.context.resourceManager.getString($r("app.string.and").id),
193      globalThis.context.resourceManager.getString($r("app.string.period").id),
194      globalThis.context.resourceManager.getString($r("app.string.comma").id)])
195        .then(values => {
196          this.resource.period = values[3]
197          this.resource.comma = values[4]
198          reason = globalThis.currentPermissionGroup == 'SMS' ? (reason.join(values[0]) + values[1]) : (reason.join(values[2]) + values[3])
199        })
200    }else {
201      reason = ''
202    }
203    let hasReason = false
204    bundleManager.getBundleInfo(routerData, Constants.PARMETER_BUNDLE_FLAG).then(info => {
205      permissions.forEach(permission => {
206        info.reqPermissionDetails.forEach(reqPermissionDetail => {
207          if(reqPermissionDetail.name == permission) {
208            let context = globalThis.context.createBundleContext(routerData)
209            context.resourceManager.getString(reqPermissionDetail.reasonId).then(value => {
210              if (value !== undefined && !hasReason) {
211                reason = reason.replace(this.resource.period, this.resource.comma)
212                reason += value.slice(Constants.START_SUBSCRIPT, Constants.END_SUBSCRIPT)
213                hasReason = true
214              }
215            })
216          }
217        })
218      })
219    })
220    bundle.getBundleInfo(routerData, Constants.PARMETER_BUNDLE_FLAG).then(res => {
221      this.api = res.targetVersion
222      bundleInfo = res
223      var acManager = abilityAccessCtrl.createAtManager()
224      acManager.verifyAccessToken(res.appInfo.accessTokenId, PRECISE_LOCATION_PERMISSION).then(accurateStatus => {
225        accurateStatus == abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED ? this.accurateIsOn = true : this.accurateIsOn = false
226      })
227      Promise.all([getAppLabel(res.appInfo.labelId, res.name),
228      getAppIcon(res.appInfo.iconId, res.name)])
229        .then((values) => {
230          this.mediaListItem = new MediaListObj(
231            String(values[0]), String(values[1]), res.versionName);
232        })
233      this.mediaDocListItem.push(
234        new MeidaDocObj(
235          $r('app.string.allow'),
236          Constants.RADIO_ALLOW_INDEX,
237          Constants.RADIO_ALLOW_GROUP_NAME,
238          res.appInfo.accessTokenId,
239          permissions
240        )
241      );
242      this.mediaDocListItem.push(
243        new MeidaDocObj(
244          $r('app.string.ban'),
245          Constants.RADIO_BAN_INDEX,
246          Constants.RADIO_BAN_GROUP_NAME,
247          res.appInfo.accessTokenId,
248          permissions
249        )
250      );
251    }).catch((error) => {
252      console.error(TAG + 'bundle.getBundleInfo failed. Cause: ' + JSON.stringify(error));
253      this.mediaListItem = new MediaListObj('', '', '');
254      this.mediaDocListItem.push(
255        new MeidaDocObj($r('app.string.allow'), Constants.RADIO_ALLOW_INDEX,
256          Constants.RADIO_ALLOW_GROUP_NAME, 0, permissions)
257      );
258      this.mediaDocListItem.push(
259        new MeidaDocObj($r('app.string.ban'), Constants.RADIO_BAN_INDEX,
260          Constants.RADIO_BAN_GROUP_NAME, 0, permissions)
261      );
262    })
263    // Get permission status
264    if (!status) {
265      this.isCheckList = [true, false];
266    } else {
267      this.isCheckList = [false, true];
268    }
269  }
270
271  build(){
272    Column() {
273      Row() {
274        Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
275          Image(this.mediaListItem.iconId)
276            .width(Constants.TERTIARY_IMAGE_WIDTH)
277            .height(Constants.TERTIARY_IMAGE_HEIGHT)
278            .margin({ left: Constants.TERTIARY_IMAGE_MARGIN_LEFT, right: Constants.TERTIARY_IMAGE_MARGIN_RIGHT })
279          Column() {
280            Row() {
281              Text(this.mediaListItem.labelId)
282                .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE)
283                .fontColor($r('app.color.label_color'))
284                .fontWeight(FontWeight.Bold)
285                .textAlign(TextAlign.Start)
286            }
287            .width(Constants.TERTIARY_HALF_WIDTH)
288            .margin({ bottom: Constants.TERTIARY_LABEL_MARGIN_BOTTOM })
289            Row() {
290              Text(this.mediaListItem.versionName)
291                .fontSize(Constants.TEXT_SMAL_FONT_SIZE)
292                .fontColor($r('app.color.label_color_light'))
293                .textAlign(TextAlign.Start)
294            }
295            .width(Constants.TERTIARY_HALF_WIDTH)
296          }
297        }.margin({ left: Constants.TERTIARY_MARGIN_LEFT })
298      }
299      if(reason) {
300        Row() {
301          Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
302            Row() {
303              Text(reason)
304                .fontSize(Constants.TEXT_SMAL_FONT_SIZE)
305                .fontColor($r('app.color.label_color_light'))
306                .textAlign(TextAlign.Start)
307            }.margin({ left: Constants.TERTIARY_IMAGE_MARGIN_LEFT, right: Constants.TERTIARY_IMAGE_MARGIN_RIGHT })
308          }
309        }
310        .margin({ top: Constants.TERTIARY_ROW_MARGIN_TOP, left: Constants.TERTIARY_MARGIN_LEFT })
311      }
312      Row() {
313        Text(backTitle)
314          .fontSize(Constants.TEXT_SMAL_FONT_SIZE)
315          .fontColor($r('app.color.label_color_light'))
316          .fontWeight(FontWeight.Medium)
317          .textAlign(TextAlign.Start)
318          .lineHeight(Constants.SUBTITLE_LINE_HEIGHT)
319        Text($r('app.string.access_permission'))
320          .fontSize(Constants.TEXT_SMAL_FONT_SIZE)
321          .fontColor($r('app.color.label_color_light'))
322          .fontWeight(FontWeight.Medium)
323          .textAlign(TextAlign.Start)
324          .lineHeight(Constants.SUBTITLE_LINE_HEIGHT)
325      }.width(Constants.FULL_WIDTH)
326      .constraintSize({ minHeight: Constants.SUBTITLE_MIN_HEIGHT })
327      .padding({ top: Constants.SUBTITLE_PADDING_TOP, bottom: Constants.SUBTITLE_PADDING_BOTTOM,
328        left: Constants.TERTIARY_TEXT_MARGIN_LEFT, right: Constants.TERTIARY_IMAGE_MARGIN_RIGHT})
329      .margin({ top: Constants.TERTIARY_PERMISSION_ROW_MARGIN_TOP })
330      Column() {
331        List() {
332          ForEach(this.mediaDocListItem, (item) => {
333            ListItem() {
334              Column() {
335                Row() {
336                  Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
337                    Row() {
338                      Text(item.name)
339                        .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE)
340                        .fontColor($r('app.color.label_color'))
341                        .fontWeight(FontWeight.Medium)
342                        .flexGrow(Constants.FLEX_GROW)
343                      if (this.isCheckList[item.index] === true) {
344                        Shape() {
345                          Circle().width(Constants.SHAPE_DIA).height(Constants.SHAPE_DIA)
346                            .fill($r("app.color.shape_allow_color")).offset({ x: 0, y: 0 })
347                          Circle().width(Constants.SHAPE_ALLOW_DIA).height(Constants.SHAPE_ALLOW_DIA)
348                            .fill($r("app.color.default_background_color"))
349                            .offset({ x: Constants.SHAPE_ALLOW_OFFSET, y: Constants.SHAPE_ALLOW_OFFSET })
350                        }
351                      } else if (this.isCheckList[item.index] === false) {
352                        Shape() {
353                          Circle().width(Constants.SHAPE_DIA).height(Constants.SHAPE_DIA)
354                            .fill($r("app.color.shape_ban_color")).offset({ x: 0, y: 0 })
355                          Circle().width(Constants.SHAPE_BAN_DIA).height(Constants.SHAPE_BAN_DIA)
356                            .fill($r("app.color.default_background_color"))
357                            .offset({ x: Constants.SHAPE_BAN_OFFSET, y: Constants.SHAPE_BAN_OFFSET })
358                        }
359                      }
360                    }
361                    .width(Constants.FULL_WIDTH)
362                    .height(Constants.LISTITEM_ROW_HEIGHT)
363                    .onClick(() => {
364                        item.permissions.forEach((permission) => {
365                          if (!item.index) {
366                            if((this.api >= Constants.API_VERSION_SUPPORT_STAGE) && (permission == PRECISE_LOCATION_PERMISSION)) {
367                              return false
368                            }
369                            this.grantUserGrantedPermission(item.accessTokenId, permission)
370                            if (nowGrantResult != Constants.PERMISSION_INDEX) {
371                              GrantResultFlag.push(-1)
372                            }else{
373                              GrantResultFlag.push(0)
374                            }
375                          } else {
376                            if((permission == PRECISE_LOCATION_PERMISSION) && (this.api >= Constants.API_VERSION_SUPPORT_STAGE)) {
377                              if(this.accurateIsOn) {
378                                this.revokeUserGrantedPermission(item.accessTokenId, permission)
379                                this.accurateIsOn = false
380                              }
381                            }else {
382                              this.revokeUserGrantedPermission(item.accessTokenId, permission)
383                            }
384
385                            if (nowRevokeResult != Constants.PERMISSION_INDEX) {
386                              RevokeResultFlag.push(-1)
387                              this.authorizeDialogController.open();
388                              setTimeout(()=> {
389                                this.authorizeDialogController.close();
390                              }, Constants.DELAY_TIME)
391                            }else{
392                              RevokeResultFlag.push(0)
393                            }
394                          }
395                        })
396                        if (!item.index) {
397                          if(GrantResultFlag.indexOf(-1) > -1){
398                            this.authorizeDialogController.open();
399                            setTimeout(()=> {
400                              this.authorizeDialogController.close();
401                            }, Constants.DELAY_TIME)
402                          }else{
403                            this.isCheckList = [true, false];
404                          }
405                        }else{
406                          if (RevokeResultFlag.indexOf(-1) > -1){
407                            this.authorizeDialogController.open();
408                            setTimeout(()=> {
409                              this.authorizeDialogController.close();
410                            }, Constants.DELAY_TIME)
411                          }else{
412                            this.isCheckList = [false, true];
413                          }
414                        }
415                    })
416                  }
417                }
418                if (!item.index) {
419                  Row() {
420                    Column()
421                      .backgroundColor($r('app.color.text_decoration_color'))
422                      .width(Constants.FULL_WIDTH)
423                      .height(Constants.TEXT_DECORATION_HEIGHT)
424                  }
425                }
426              }
427              .onClick(() => {
428              })
429            }
430            .padding({
431              left: Constants.DEFAULT_PADDING_START,
432              right: Constants.DEFAULT_PADDING_END
433            })
434            .margin({ top: Constants.TERTIARY_LISTITEM_MARGIN_TOP })
435          }, item => item.toString())
436        }
437        .borderRadius(Constants.BORDER_RADIUS)
438        .backgroundColor($r('app.color.default_background_color'))
439        .padding({
440          top: Constants.TERTIARY_LIST_PADDING_TOP, bottom: Constants.TERTIARY_LIST_PADDING_BOTTOM
441        })
442
443        if ((this.api >= Constants.API_VERSION_SUPPORT_STAGE) && (permissions.includes(PRECISE_LOCATION_PERMISSION))) {
444          Column() {
445            Row() {
446              Text($r('app.string.precise_location'))
447                .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE)
448                .fontColor($r('app.color.label_color'))
449                .fontWeight(FontWeight.Medium)
450                .flexGrow(Constants.FLEX_GROW)
451              Toggle({ type: ToggleType.Switch, isOn: this.accurateIsOn })
452                .selectedColor($r('app.color.button_color'))
453                .switchPointColor($r('app.color.selected_Color'))
454                .onChange((isOn: boolean) => {
455                  var acManager = abilityAccessCtrl.createAtManager()
456                  if (isOn) {
457                    acManager.grantUserGrantedPermission(bundleInfo.appInfo.accessTokenId, PRECISE_LOCATION_PERMISSION, Constants.PERMISSION_FLAG)
458                      .then(() => { this.accurateIsOn = true })
459                  } else {
460                    acManager.revokeUserGrantedPermission(bundleInfo.appInfo.accessTokenId, PRECISE_LOCATION_PERMISSION, Constants.PERMISSION_FLAG)
461                      .then(() => { this.accurateIsOn = false })
462                  }
463                })
464                .padding({ right: 0 })
465                .enabled(this.isCheckList[0])
466            }.width(Constants.FULL_WIDTH)
467            .height(Constants.LISTITEM_ROW_HEIGHT)
468          }.margin({ top: Constants.LOCATION_MARGIN_TOP, bottom: Constants.LOCATION_MARGIN_BOTTOM })
469          .padding({
470            left: Constants.DEFAULT_PADDING_START,
471            right: Constants.DEFAULT_PADDING_END,
472            top: Constants.TERTIARY_LIST_PADDING_TOP,
473            bottom: Constants.TERTIARY_LIST_PADDING_BOTTOM
474          })
475          .borderRadius(Constants.BORDER_RADIUS)
476          .backgroundColor($r('app.color.default_background_color'))
477
478          Row() {
479            Text($r('app.string.get_the_exact_position'))
480              .fontSize(Constants.TEXT_SMAL_FONT_SIZE)
481              .fontColor($r('app.color.label_color_light'))
482              .lineHeight(Constants.TEXT_SMALL_LINE_HEIGHT)
483          }.width(Constants.FULL_WIDTH)
484          .padding({
485            left: Constants.DEFAULT_PADDING_START,
486            right: Constants.DEFAULT_PADDING_END,
487          })
488        }
489      }
490      .padding({
491        left: Constants.LIST_PADDING_LEFT,
492        right: Constants.LIST_PADDING_LEFT
493      })
494      .width(Constants.FULL_WIDTH)
495      .height(Constants.FULL_HEIGHT)
496    }
497    .width(Constants.FULL_WIDTH)
498  }
499}
500