• 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 { alphabetIndexerComponent } from "../common/components/alphabeticalIndex";
18import { textInput } from "../common/components/search";
19import router from '@ohos.router';
20import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl';
21import { BusinessError } from '@ohos.base';
22import { verifyAccessToken, indexValue, sortByName } from "../common/utils/utils";
23import { ApplicationObj, PermissionInfo, routerParams_2, permissionApplications, appInfo } from "../common/utils/typedef";
24import { GlobalContext } from "../common/utils/globalContext";
25import Constants from '../common/utils/constant';
26import { permissionGroups } from "../common/model/permissionGroup";
27
28const TAG = 'PermissionManager_MainAbility:';
29
30@Extend(Image) function customizeImage(width: number, height: number) {
31  .objectFit(ImageFit.Contain)
32  .width(width)
33  .height(height)
34}
35
36@Entry
37@Component
38struct locationInfoPage {
39  private backTitle: ResourceStr = (router.getParams() as routerParams_2).backTitle;
40
41  build() {
42    GridRow({ gutter: Constants.GUTTER, columns: {
43      xs: Constants.XS_COLUMNS, sm: Constants.SM_COLUMNS, md: Constants.MD_COLUMNS, lg: Constants.LG_COLUMNS } }) {
44      GridCol({ span: { xs: Constants.XS_SPAN, sm: Constants.SM_SPAN, md: Constants.MD_SPAN, lg: Constants.LG_SPAN },
45        offset: { xs: Constants.XS_OFFSET, sm: Constants.SM_OFFSET, md: Constants.MD_OFFSET, lg: Constants.LG_OFFSET } }) {
46        Row() {
47          Column() {
48            Row() {
49              backBar({ title: JSON.stringify(this.backTitle), recordable: false })
50            }
51            Row() {
52              Column() {
53                applicationItem()
54
55              }.width(Constants.FULL_WIDTH)
56            }
57            .layoutWeight(Constants.LAYOUT_WEIGHT)
58          }
59        }
60        .height(Constants.FULL_HEIGHT)
61        .width(Constants.FULL_WIDTH)
62        .backgroundColor($r("sys.color.ohos_id_color_sub_background"))
63      }
64    }.backgroundColor($r("sys.color.ohos_id_color_sub_background"))
65  }
66}
67
68@Component
69struct applicationItem {
70  private list: permissionApplications[] = (router.getParams() as routerParams_2).list;
71  private permissionName: string = (router.getParams() as routerParams_2).permissionName;
72  @State permissionNum: number = Constants.PERMISSION_NUM; // permission num
73  @State toggleIsOn: boolean[] = []; // toggle switch state array
74  @State isRisk: boolean[] = [];
75  @State applicationList: ApplicationObj[] = []; // application info array
76  @State searchResult: boolean = true; // search results
77  @State selectedIndex: number = 0;
78  @State permissionInfo: PermissionInfo = new PermissionInfo('', '', '', 0);
79  @State allBundleInfo: appInfo[] = GlobalContext.load('allBundleInfo');
80  scroller: Scroller = new Scroller();
81
82  @Builder ListItemLayout(item: ApplicationObj) {
83    ListItem() {
84      Row() {
85        Column() {
86          Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
87            Row() {
88              Image(item.icon)
89                .customizeImage(Constants.AUTHORITY_IMAGE_WIDTH, Constants.AUTHORITY_IMAGE_HEIGHT)
90                .margin({ right: Constants.AUTHORITY_IMAGE_MARGIN_RIGHT })
91              Column() {
92                Text(item.label)
93                  .width(Constants.MAXIMUM_HEADER_WIDTH)
94                  .maxLines(Constants.MAXIMUM_HEADER_LINES)
95                  .textOverflow({ overflow: TextOverflow.Ellipsis })
96                  .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE)
97                  .fontWeight(FontWeight.Medium)
98                  .fontColor($r('sys.color.ohos_id_color_text_primary'))
99                if (this.isRisk[item.index]) {
100                  Text($r('app.string.risk_warning'))
101                    .fontSize(Constants.TEXT_SMALL_FONT_SIZE)
102                    .fontColor($r('sys.color.ohos_id_color_text_secondary'))
103                }
104              }.flexGrow(Constants.FLEX_GROW)
105              .alignItems(HorizontalAlign.Start)
106              Toggle({ type: ToggleType.Switch, isOn: this.toggleIsOn[item.index] })
107                .selectedColor($r('sys.color.ohos_id_color_toolbar_icon_actived'))
108                .switchPointColor($r('sys.color.ohos_id_color_foreground_contrary'))
109                .padding({ right: 0 })
110                .width(Constants.AUTHORITY_TOGGLE_WIDTH)
111                .height(Constants.AUTHORITY_TOGGLE_HEIGHT)
112                .onChange((isOn: boolean) => {
113                  if (item.permission === undefined) {
114                    return;
115                  }
116                  if (isOn) {
117                    this.grantUserGrantedPermission(item.accessTokenId, item.permission, item.index);
118                  } else {
119                    this.revokeUserGrantedPermission(item.accessTokenId, item.permission, item.index);
120                  }
121                })
122            }
123            .width(Constants.FULL_WIDTH)
124            .height(Constants.AUTHORITY_ROW_HEIGHT)
125            .constraintSize({ minHeight: Constants.AUTHORITY_CONSTRAINTSIZE_MINHEIGHT })
126          }
127        }.onClick(() => {
128        })
129      }
130    }.padding({ left: Constants.DEFAULT_PADDING_START, right: Constants.DEFAULT_PADDING_END })
131    .enabled(!this.isRisk[item.index])
132    .opacity(this.isRisk[item.index] ? $r('sys.float.ohos_id_alpha_disabled') : 1)
133  }
134
135  /**
136   * Grant permissions to the app
137   * @param {Number} accessTokenId
138   * @param {String} permission permission name
139   * @param {Number} index Array index to modify permission status
140   */
141  grantUserGrantedPermission(accessTokenId: number, permission: Permissions, index: number) {
142    abilityAccessCtrl.createAtManager().grantUserGrantedPermission(
143      accessTokenId, permission, Constants.PERMISSION_FLAG).then(() => {
144      // result: 0 Authorization succeeded; result: -1 Authorization failed
145      this.toggleIsOn[index] = true;
146      let num = this.toggleIsOn.filter(item => item === true).length;
147      this.permissionNum = num;
148    }).catch((error: BusinessError) => {
149      this.toggleIsOn[index] = false;
150      console.error(TAG + 'abilityAccessCtrl.createAtManager.grantUserGrantedPermission failed. Cause: ' + JSON.stringify(error));
151    })
152  }
153
154  /**
155   * Deauthorize the app
156   * @param {Number} accessTokenId
157   * @param {String} permission permission name
158   * @param {Number} index Array index to modify permission status
159   */
160  revokeUserGrantedPermission(accessTokenId: number, permission: Permissions, index: number) {
161    abilityAccessCtrl.createAtManager().revokeUserGrantedPermission(
162      accessTokenId, permission, Constants.PERMISSION_FLAG).then(() => {
163      // result: 0 successfully cancel the authorization; result: -1 cancel the authorization failed
164      this.toggleIsOn[index] = false;
165      let num = this.toggleIsOn.filter(item => item === true).length;
166      this.permissionNum = num;
167    }).catch(() => {
168      this.toggleIsOn[index] = true;
169    })
170  }
171
172  /**
173   * Lifecycle function, executed when the page is initialized
174   */
175  aboutToAppear() {
176    let bundleNames = this.list.length > 0 ? this.list[0].bundleNames : this.list;
177    permissionGroups.forEach(permission => {
178      if (permission.permissionName === this.permissionName) {
179        this.permissionInfo = permission;
180      }
181    })
182
183    let atManager = abilityAccessCtrl.createAtManager();
184    for (let i = 0; i < bundleNames.length; i++) {
185      // Get BundleInfo based on bundle name
186      this.allBundleInfo.forEach(bundleInfo => {
187        if (bundleInfo.bundleName === bundleNames[i]) {
188          this.applicationList.push(
189            new ApplicationObj(
190              bundleInfo.label,
191              bundleInfo.icon,
192              i,
193              bundleInfo.tokenId,
194              this.list[0].permission,
195              bundleInfo.zhTag,
196              bundleInfo.indexTag,
197              bundleInfo.language) // Get the first letter in the returned initials array
198          );
199          verifyAccessToken(bundleInfo.tokenId, this.list[0].permission).then(data => {
200            // 0: have permission; -1: no permission
201            if (data === Constants.PERMISSION_INDEX) {
202              this.toggleIsOn[i] = true;
203              this.permissionNum++;
204            } else {
205              this.toggleIsOn[i] = false;
206            }
207          })
208          this.isRisk[i] = false;
209          try {
210            atManager.getPermissionFlags(bundleInfo.tokenId, this.list[0].permission).then(data => {
211              if (data == Constants.PERMISSION_POLICY_FIXED) {
212                this.isRisk[i] = true;
213              }
214            })
215          }
216          catch(err) {
217            console.log(TAG + 'getPermissionFlags error: ' + JSON.stringify(err));
218          }
219        }
220      })
221    }
222  }
223
224  build() {
225    Column() {
226      Row() {
227        textInput({
228          applicationItem: $applicationList,
229          searchResult: $searchResult
230        })
231      }.padding({
232        left: Constants.AUTHORITY_TEXTINPUT_PADDING_LEFT,
233        right: Constants.AUTHORITY_TEXTINPUT_PADDING_RIGHT
234      })
235      Flex({ alignItems:ItemAlign.Start, justifyContent: FlexAlign.Start }) {
236        Column() {
237          Flex({ justifyContent: FlexAlign.Start }) {
238            if (this.permissionNum > 0) {
239              Text() {
240                Span(this.permissionInfo.enable_description_start ? this.permissionInfo.enable_description_start : '')
241                Span(String(this.permissionNum))
242                Span(this.permissionInfo.enable_description_end ? this.permissionInfo.enable_description_end : '')
243              }
244                .fontSize(Constants.TEXT_SMALL_FONT_SIZE)
245                .fontColor($r('sys.color.ohos_id_color_text_secondary'))
246                .margin({ top: Constants.AUTHORITY_TEXT_MARGIN_TOP })
247            } else {
248              Text(this.permissionInfo.forbidden_description)
249                .fontSize(Constants.TEXT_SMALL_FONT_SIZE)
250                .fontColor($r('sys.color.ohos_id_color_text_secondary'))
251                .margin({ top: Constants.AUTHORITY_TEXT_MARGIN_TOP })
252            }
253          }.padding({ left: Constants.DEFAULT_PADDING_START, right: Constants.DEFAULT_PADDING_END })
254          .margin({ bottom: Constants.AUTHORITY_ROW_MARGIN_BOTTOM })
255          Row() {
256            Column() {
257              if (!this.applicationList.length) {
258                if (this.searchResult) {
259                  Row() {}
260                } else {
261                  Row() {
262                    Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
263                      Image($r('app.media.searchnoresult'))
264                        .customizeImage(Constants.SEARCHNORESULT_IMAGE_WIDTH, Constants.SEARCHNORESULT_IMAGE_HEIGHT)
265                    }
266                  }
267                }
268              } else {
269                Row() {
270                  List({ scroller: this.scroller }) {
271                    ForEach(sortByName(this.applicationList), (item: ApplicationObj) => {
272                      this.ListItemLayout(item)
273                    }, (item: ApplicationObj) => JSON.stringify(item))
274                  }
275                  .backgroundColor($r('sys.color.ohos_id_color_list_card_bg'))
276                  .borderRadius($r('sys.float.ohos_id_corner_radius_card'))
277                  .padding({ top: Constants.LIST_PADDING_TOP, bottom: Constants.LIST_PADDING_BOTTOM })
278                  .divider({
279                    strokeWidth: Constants.DIVIDER,
280                    color: $r('sys.color.ohos_id_color_list_separator'),
281                    startMargin: Constants.DIVIDER_MARGIN_RIGHT_APPLICATION,
282                    endMargin: Constants.DEFAULT_MARGIN_END
283                  })
284                  .onScrollIndex((start, end) => {
285                    GlobalContext.getContext().set('scroller', this.scroller);
286                    if (this.applicationList.length > 0) {
287                      let alphabeticalIndex = sortByName(this.applicationList)[start].indexTag;
288                      let index = indexValue.indexOf(alphabeticalIndex);
289                      this.selectedIndex = index >= 0 ? index : 0;
290                    }
291                  })
292                }
293              }
294            }.width(Constants.FULL_WIDTH)
295            .margin({ bottom: Constants.AUTHORITY_LIST_MARGIN_BOTTOM })
296          }
297        }.padding({ left: Constants.AUTHORITY_LISTITEM_PADDING_LEFT })
298        Column() {
299          alphabetIndexerComponent({ applicationItem: $applicationList, index: $selectedIndex })
300        }.width(Constants.AUTHORITY_ALPHABETINDEX_WIDTH)
301         .padding({ top: Constants.AUTHORITY_ALPHABETINDEX_PADDING_TOP })
302        .margin({ bottom: Constants.APPLICATION_LIST_MARGIN_BOTTOM })
303      }.flexGrow(Constants.FLEX_GROW)
304    }.height(Constants.FULL_HEIGHT)
305  }
306}
307