• 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 isFirst: boolean[] = [];
76  @State applicationList: ApplicationObj[] = []; // application info array
77  @State searchResult: boolean = true; // search results
78  @State selectedIndex: number = 0;
79  @State permissionInfo: PermissionInfo = new PermissionInfo('', '', '', 0);
80  @State allBundleInfo: appInfo[] = GlobalContext.load('allBundleInfo');
81  scroller: Scroller = new Scroller();
82
83  @Builder ListItemLayout(item: ApplicationObj) {
84    ListItem() {
85      Row() {
86        Column() {
87          Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
88            Row() {
89              Image(item.icon)
90                .customizeImage(Constants.AUTHORITY_IMAGE_WIDTH, Constants.AUTHORITY_IMAGE_HEIGHT)
91                .margin({ right: Constants.AUTHORITY_IMAGE_MARGIN_RIGHT })
92              Column() {
93                Text(item.label)
94                  .width(Constants.MAXIMUM_HEADER_WIDTH)
95                  .maxLines(Constants.MAXIMUM_HEADER_LINES)
96                  .textOverflow({ overflow: TextOverflow.Ellipsis })
97                  .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE)
98                  .fontWeight(FontWeight.Medium)
99                  .fontColor($r('sys.color.ohos_id_color_text_primary'))
100                if (this.isRisk[item.index]) {
101                  Text($r('app.string.risk_warning'))
102                    .fontSize(Constants.TEXT_SMALL_FONT_SIZE)
103                    .fontColor($r('sys.color.ohos_id_color_text_secondary'))
104                }
105              }.flexGrow(Constants.FLEX_GROW)
106              .alignItems(HorizontalAlign.Start)
107              Toggle({ type: ToggleType.Switch, isOn: this.toggleIsOn[item.index] })
108                .selectedColor($r('sys.color.ohos_id_color_toolbar_icon_actived'))
109                .switchPointColor($r('sys.color.ohos_id_color_foreground_contrary'))
110                .padding({ right: 0 })
111                .width(Constants.AUTHORITY_TOGGLE_WIDTH)
112                .height(Constants.AUTHORITY_TOGGLE_HEIGHT)
113                .onChange((isOn: boolean) => {
114                  if (item.permission === undefined) {
115                    return;
116                  }
117                  if (this.isFirst[item.index] && isOn) {
118                    this.isFirst[item.index] = false;
119                    return;
120                  }
121                  this.isFirst[item.index] = false;
122                  if (isOn) {
123                    this.grantUserGrantedPermission(item.accessTokenId, item.permission, item.index);
124                  } else {
125                    this.revokeUserGrantedPermission(item.accessTokenId, item.permission, item.index);
126                  }
127                })
128            }
129            .width(Constants.FULL_WIDTH)
130            .height(Constants.AUTHORITY_ROW_HEIGHT)
131            .constraintSize({ minHeight: Constants.AUTHORITY_CONSTRAINTSIZE_MINHEIGHT })
132          }
133        }.onClick(() => {
134        })
135      }
136    }.padding({ left: Constants.DEFAULT_PADDING_START, right: Constants.DEFAULT_PADDING_END })
137    .enabled(!this.isRisk[item.index])
138    .opacity(this.isRisk[item.index] ? $r('sys.float.ohos_id_alpha_disabled') : 1)
139  }
140
141  /**
142   * Grant permissions to the app
143   * @param {Number} accessTokenId
144   * @param {String} permission permission name
145   * @param {Number} index Array index to modify permission status
146   */
147  grantUserGrantedPermission(accessTokenId: number, permission: Permissions, index: number) {
148    abilityAccessCtrl.createAtManager().grantUserGrantedPermission(
149      accessTokenId, permission, Constants.PERMISSION_FLAG).then(() => {
150      // result: 0 Authorization succeeded; result: -1 Authorization failed
151      this.toggleIsOn[index] = true;
152      let num = this.toggleIsOn.filter(item => item === true).length;
153      this.permissionNum = num;
154    }).catch((error: BusinessError) => {
155      this.toggleIsOn[index] = false;
156      console.error(TAG + 'abilityAccessCtrl.createAtManager.grantUserGrantedPermission failed. Cause: ' + JSON.stringify(error));
157    })
158  }
159
160  /**
161   * Deauthorize the app
162   * @param {Number} accessTokenId
163   * @param {String} permission permission name
164   * @param {Number} index Array index to modify permission status
165   */
166  revokeUserGrantedPermission(accessTokenId: number, permission: Permissions, index: number) {
167    abilityAccessCtrl.createAtManager().revokeUserGrantedPermission(
168      accessTokenId, permission, Constants.PERMISSION_FLAG).then(() => {
169      // result: 0 successfully cancel the authorization; result: -1 cancel the authorization failed
170      this.toggleIsOn[index] = false;
171      let num = this.toggleIsOn.filter(item => item === true).length;
172      this.permissionNum = num;
173    }).catch(() => {
174      this.toggleIsOn[index] = true;
175    })
176  }
177
178  /**
179   * Lifecycle function, executed when the page is initialized
180   */
181  aboutToAppear() {
182    let bundleNames = this.list.length > 0 ? this.list[0].bundleNames : this.list;
183    permissionGroups.forEach(permission => {
184      if (permission.permissionName === this.permissionName) {
185        this.permissionInfo = permission;
186      }
187    })
188
189    let atManager = abilityAccessCtrl.createAtManager();
190    for (let i = 0; i < bundleNames.length; i++) {
191      // Get BundleInfo based on bundle name
192      this.allBundleInfo.forEach(bundleInfo => {
193        if (bundleInfo.bundleName === bundleNames[i]) {
194          this.applicationList.push(
195            new ApplicationObj(
196              bundleInfo.label,
197              bundleInfo.icon,
198              i,
199              bundleInfo.tokenId,
200              this.list[0].permission,
201              bundleInfo.zhTag,
202              bundleInfo.indexTag,
203              bundleInfo.language) // Get the first letter in the returned initials array
204          );
205          verifyAccessToken(bundleInfo.tokenId, this.list[0].permission).then(data => {
206            // 0: have permission; -1: no permission
207            if (data === Constants.PERMISSION_INDEX) {
208              this.toggleIsOn[i] = true;
209              this.isFirst[i] = true;
210              this.permissionNum++;
211            } else {
212              this.toggleIsOn[i] = false;
213              this.isFirst[i] = false;
214            }
215          })
216          this.isRisk[i] = false;
217          try {
218            atManager.getPermissionFlags(bundleInfo.tokenId, this.list[0].permission).then(data => {
219              if (data == Constants.PERMISSION_POLICY_FIXED) {
220                this.isRisk[i] = true;
221              }
222            })
223          }
224          catch(err) {
225            console.log(TAG + 'getPermissionFlags error: ' + JSON.stringify(err));
226          }
227        }
228      })
229    }
230  }
231
232  build() {
233    Column() {
234      Row() {
235        textInput({
236          applicationItem: $applicationList,
237          searchResult: $searchResult
238        })
239      }.padding({
240        left: Constants.AUTHORITY_TEXTINPUT_PADDING_LEFT,
241        right: Constants.AUTHORITY_TEXTINPUT_PADDING_RIGHT
242      })
243      Flex({ alignItems:ItemAlign.Start, justifyContent: FlexAlign.Start }) {
244        Column() {
245          Flex({ justifyContent: FlexAlign.Start }) {
246            if (this.permissionNum > 0) {
247              Text() {
248                Span(this.permissionInfo.enable_description_start ? this.permissionInfo.enable_description_start : '')
249                Span(String(this.permissionNum))
250                Span(this.permissionInfo.enable_description_end ? this.permissionInfo.enable_description_end : '')
251              }
252                .fontSize(Constants.TEXT_SMALL_FONT_SIZE)
253                .fontColor($r('sys.color.ohos_id_color_text_secondary'))
254                .margin({ top: Constants.AUTHORITY_TEXT_MARGIN_TOP })
255            } else {
256              Text(this.permissionInfo.forbidden_description)
257                .fontSize(Constants.TEXT_SMALL_FONT_SIZE)
258                .fontColor($r('sys.color.ohos_id_color_text_secondary'))
259                .margin({ top: Constants.AUTHORITY_TEXT_MARGIN_TOP })
260            }
261          }.padding({ left: Constants.DEFAULT_PADDING_START, right: Constants.DEFAULT_PADDING_END })
262          .margin({ bottom: Constants.AUTHORITY_ROW_MARGIN_BOTTOM })
263          Row() {
264            Column() {
265              if (!this.applicationList.length) {
266                if (this.searchResult) {
267                  Row() {}
268                } else {
269                  Row() {
270                    Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
271                      Image($r('app.media.searchnoresult'))
272                        .customizeImage(Constants.SEARCHNORESULT_IMAGE_WIDTH, Constants.SEARCHNORESULT_IMAGE_HEIGHT)
273                    }
274                  }
275                }
276              } else {
277                Row() {
278                  List({ scroller: this.scroller }) {
279                    ForEach(sortByName(this.applicationList), (item: ApplicationObj) => {
280                      this.ListItemLayout(item)
281                    }, (item: ApplicationObj) => JSON.stringify(item))
282                  }
283                  .backgroundColor($r('sys.color.ohos_id_color_list_card_bg'))
284                  .borderRadius($r('sys.float.ohos_id_corner_radius_card'))
285                  .padding({ top: Constants.LIST_PADDING_TOP, bottom: Constants.LIST_PADDING_BOTTOM })
286                  .divider({
287                    strokeWidth: Constants.DIVIDER,
288                    color: $r('sys.color.ohos_id_color_list_separator'),
289                    startMargin: Constants.DIVIDER_MARGIN_RIGHT_APPLICATION,
290                    endMargin: Constants.DEFAULT_MARGIN_END
291                  })
292                  .onScrollIndex((start, end) => {
293                    GlobalContext.getContext().set('scroller', this.scroller);
294                    if (this.applicationList.length > 0) {
295                      let alphabeticalIndex = sortByName(this.applicationList)[start].indexTag;
296                      let index = indexValue.indexOf(alphabeticalIndex);
297                      this.selectedIndex = index >= 0 ? index : 0;
298                    }
299                  })
300                }
301              }
302            }.width(Constants.FULL_WIDTH)
303            .margin({ bottom: Constants.AUTHORITY_LIST_MARGIN_BOTTOM })
304          }
305        }.padding({ left: Constants.AUTHORITY_LISTITEM_PADDING_LEFT })
306        Column() {
307          alphabetIndexerComponent({ applicationItem: $applicationList, index: $selectedIndex })
308        }.width(Constants.AUTHORITY_ALPHABETINDEX_WIDTH)
309         .padding({ top: Constants.AUTHORITY_ALPHABETINDEX_PADDING_TOP })
310        .margin({ bottom: Constants.APPLICATION_LIST_MARGIN_BOTTOM })
311      }.flexGrow(Constants.FLEX_GROW)
312    }.height(Constants.FULL_HEIGHT)
313  }
314}
315