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 bundleManager from "@ohos.bundle.bundleManager"; 21import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl'; 22import { BusinessError } from '@ohos.base'; 23import audio from '@ohos.multimedia.audio' 24import camera from '@ohos.multimedia.camera' 25import common from '@ohos.app.ability.common'; 26import { verifyAccessToken, indexValue, sortByName } from "../common/utils/utils"; 27import { ApplicationObj, GroupInfo, routerParams_1, permissionApplications, appInfo } from "../common/utils/typedef"; 28import { GlobalContext } from "../common/utils/globalContext"; 29import { globalDialog } from "../common/components/dialog"; 30import Constants from '../common/utils/constant'; 31import { polymorphismGroup, globalGroup, groups } from "../common/model/permissionGroup"; 32 33const TAG = 'PermissionManager_MainAbility:'; 34const FUZZY_LOCATION_PERMISSION = 'ohos.permission.APPROXIMATELY_LOCATION'; 35const PRECISE_LOCATION_PERMISSION = 'ohos.permission.LOCATION'; 36const BACKGROUND_LOCATION_PERMISSION = 'ohos.permission.LOCATION_IN_BACKGROUND'; 37const DOWNLOAD_PERMISSION = 'ohos.permission.READ_WRITE_DOWNLOAD_DIRECTORY'; 38const DESKTOP_PERMISSION = 'ohos.permission.READ_WRITE_DESKTOP_DIRECTORY'; 39const DOCUMENTS_PERMISSION = 'ohos.permission.READ_WRITE_DOCUMENTS_DIRECTORY'; 40let globalIsOn: boolean = (router.getParams() as routerParams_1).globalIsOn; // return title name 41 42@Extend(Image) function customizeImage(width: number, height: number) { 43 .objectFit(ImageFit.Contain) 44 .width(width) 45 .height(height) 46 .draggable(false) 47} 48 49@Entry 50@Component 51struct locationInfoPage { 52 private backTitle: ResourceStr = (router.getParams() as routerParams_1).backTitle; 53 private list: permissionApplications[] = (router.getParams() as routerParams_1).list; 54 @State currentGroup: string = GlobalContext.load('currentPermissionGroup'); 55 @State polymorphismIsOn: Array<boolean> = []; 56 @State folderStatusArray: Array<Array<boolean>> = [[]]; 57 58 build() { 59 GridRow({ gutter: Constants.GUTTER, columns: { 60 xs: Constants.XS_COLUMNS, sm: Constants.SM_COLUMNS, md: Constants.MD_COLUMNS, lg: Constants.LG_COLUMNS } }) { 61 GridCol({ span: { xs: Constants.XS_SPAN, sm: Constants.SM_SPAN, md: Constants.MD_SPAN, lg: Constants.LG_SPAN }, 62 offset: { xs: Constants.XS_OFFSET, sm: Constants.SM_OFFSET, md: Constants.MD_OFFSET, lg: Constants.LG_OFFSET } }) { 63 Row() { 64 Column() { 65 Row() { 66 backBar({ title: JSON.stringify(this.backTitle), recordable: false }) 67 } 68 Row() { 69 Column() { 70 applicationItem({ polymorphismIsOn: $polymorphismIsOn, folderStatusArray: $folderStatusArray }) 71 72 }.width(Constants.FULL_WIDTH) 73 } 74 .layoutWeight(Constants.LAYOUT_WEIGHT) 75 } 76 } 77 .height(Constants.FULL_HEIGHT) 78 .width(Constants.FULL_WIDTH) 79 .backgroundColor($r("sys.color.ohos_id_color_sub_background")) 80 } 81 }.backgroundColor($r("sys.color.ohos_id_color_sub_background")) 82 } 83 84 onPageShow() { 85 console.log(TAG + "onPageShow"); 86 if (polymorphismGroup.indexOf(this.currentGroup) !== -1) { 87 let bundleNames: string[] = []; 88 let atManager = abilityAccessCtrl.createAtManager(); 89 this.list.forEach(permissionmanager => { 90 permissionmanager.bundleNames.forEach(bundleName => { 91 if (bundleNames.indexOf(bundleName) == -1) { 92 bundleNames.push(bundleName); 93 } 94 }) 95 }) 96 97 bundleNames.forEach((bundleName, index) => { 98 bundleManager.getBundleInfo(bundleName, bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION | bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_REQUESTED_PERMISSION).then(res => { 99 // 0: have permission; -1: no permission 100 this.polymorphismIsOn[index] = true; 101 this.folderStatusArray[index] = [false, false, false]; 102 let reqPermissions: Array<string> = []; 103 res.reqPermissionDetails.forEach(item => { 104 reqPermissions.push(item.name); 105 }) 106 if (this.currentGroup === 'LOCATION') { 107 if (!reqPermissions.includes(FUZZY_LOCATION_PERMISSION) && res.targetVersion >= Constants.API_VERSION_SUPPORT_STAGE) { 108 this.polymorphismIsOn[index] = false; 109 } 110 for (let j = 0; j < this.list.length; j++) { 111 if ((this.list[j].permission == PRECISE_LOCATION_PERMISSION) && (res.targetVersion >= Constants.API_VERSION_SUPPORT_STAGE)) { 112 continue; 113 } 114 if ((this.list[j].permission == FUZZY_LOCATION_PERMISSION) && (res.targetVersion < Constants.API_VERSION_SUPPORT_STAGE)) { 115 continue; 116 } 117 if (this.list[j].permission == BACKGROUND_LOCATION_PERMISSION) { 118 continue; 119 } 120 if (reqPermissions.indexOf(this.list[j].permission) == -1) { 121 continue; 122 } 123 verifyAccessToken(res.appInfo.accessTokenId, this.list[j].permission).then((access) => { 124 if (Number(access) === abilityAccessCtrl.GrantStatus.PERMISSION_DENIED) { 125 this.polymorphismIsOn[index] = false; 126 } 127 }); 128 } 129 } 130 if (this.currentGroup === 'FOLDER') { 131 for (let j = 0; j < this.list.length; j++) { 132 if (reqPermissions.indexOf(this.list[j].permission) == -1) { 133 continue; 134 } 135 let access = atManager.verifyAccessTokenSync(res.appInfo.accessTokenId, this.list[j].permission); 136 if (Number(access) === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) { 137 switch (this.list[j].permission) { 138 case DOWNLOAD_PERMISSION: 139 this.folderStatusArray[index][0] = true; 140 break; 141 case DESKTOP_PERMISSION: 142 this.folderStatusArray[index][1] = true; 143 break; 144 case DOCUMENTS_PERMISSION: 145 this.folderStatusArray[index][2] = true; 146 break; 147 } 148 } 149 } 150 } 151 }).catch((error: BusinessError) => { 152 console.log(TAG + bundleName + "onPageShow getBundleInfo failed, cause: " + JSON.stringify(error)); 153 }) 154 }) 155 } 156 } 157} 158 159@Component 160struct applicationItem { 161 private context = getContext(this) as common.UIAbilityContext; 162 private backTitle: ResourceStr = (router.getParams() as routerParams_1).backTitle; 163 private list: permissionApplications[] = (router.getParams() as routerParams_1).list; 164 @State permissionNum: number = Constants.PERMISSION_NUM; // permission num 165 @State toggleIsOn: boolean[] = []; // toggle switch state array 166 @State isRisk: boolean[] = []; 167 @State isFirst: boolean[] = []; 168 @State applicationList: ApplicationObj[] = []; // application info array 169 @State searchResult: boolean = true; // search results 170 @Link polymorphismIsOn: Array<boolean>; 171 @Link folderStatusArray: Array<Array<boolean>>; 172 @State globalIsOn: boolean = true; 173 @State selectedIndex: number = 0; 174 @State isTouch: string = ''; 175 @State groupInfo: GroupInfo = new GroupInfo('', '', '', '', [], '', [], false); 176 @State currentGroup: string = GlobalContext.load('currentPermissionGroup'); 177 @State isMuteSupported: boolean = GlobalContext.load('isMuteSupported'); 178 @State allBundleInfo: appInfo[] = GlobalContext.load('allBundleInfo'); 179 scroller: Scroller = new Scroller(); 180 181 privacyDialogController: CustomDialogController | null = new CustomDialogController({ 182 builder: globalDialog({ globalIsOn: $globalIsOn }), 183 autoCancel: false, 184 alignment: DialogAlignment.Center, 185 customStyle: true 186 }) 187 188 @Builder ListItemLayout(item: ApplicationObj) { 189 ListItem() { 190 Row() { 191 Column() { 192 Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) { 193 Row() { 194 Image(item.icon) 195 .customizeImage(Constants.AUTHORITY_IMAGE_WIDTH, Constants.AUTHORITY_IMAGE_HEIGHT) 196 .margin({ right: Constants.AUTHORITY_IMAGE_MARGIN_RIGHT }) 197 Column() { 198 Text(item.label) 199 .width(Constants.MAXIMUM_HEADER_WIDTH) 200 .maxLines(Constants.MAXIMUM_HEADER_LINES) 201 .textOverflow({ overflow: TextOverflow.Ellipsis }) 202 .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE) 203 .fontWeight(FontWeight.Medium) 204 .fontColor($r('sys.color.ohos_id_color_text_primary')) 205 if (this.isRisk[item.index]) { 206 Text($r('app.string.risk_warning')) 207 .fontSize(Constants.TEXT_SMALL_FONT_SIZE) 208 .fontColor($r('sys.color.ohos_id_color_text_secondary')) 209 } 210 }.flexGrow(Constants.FLEX_GROW) 211 .alignItems(HorizontalAlign.Start) 212 if (polymorphismGroup.indexOf(this.currentGroup) == -1) { 213 Toggle({ type: ToggleType.Switch, isOn: this.toggleIsOn[item.index] }) 214 .selectedColor($r('sys.color.ohos_id_color_toolbar_icon_actived')) 215 .switchPointColor($r('sys.color.ohos_id_color_foreground_contrary')) 216 .padding({ right: 0 }) 217 .width(Constants.AUTHORITY_TOGGLE_WIDTH) 218 .height(Constants.AUTHORITY_TOGGLE_HEIGHT) 219 .onChange((isOn: boolean) => { 220 if (item.permission === undefined) { 221 return; 222 } 223 if (this.isFirst[item.index] && isOn) { 224 this.isFirst[item.index] = false; 225 return; 226 } 227 this.isFirst[item.index] = false; 228 let _this = this; 229 if (isOn) { 230 let promises = this.list.map(it => new Promise<number>((resolve) => { 231 _this.grantUserGrantedPermission(item.accessTokenId, it.permission, resolve); 232 })); 233 Promise.all(promises).then(() => { 234 _this.toggleIsOn[item.index] = true; 235 let num = _this.toggleIsOn.filter(item => item === true).length; 236 _this.permissionNum = num; 237 }); 238 } else { 239 let promises = this.list.map(it => new Promise<number>((resolve) => { 240 _this.revokeUserGrantedPermission(item.accessTokenId, it.permission, resolve); 241 })); 242 Promise.all(promises).then(() => { 243 _this.toggleIsOn[item.index] = false; 244 let num = _this.toggleIsOn.filter(item => item === true).length; 245 _this.permissionNum = num; 246 }); 247 } 248 }) 249 } else { 250 if (this.currentGroup === 'FOLDER') { 251 Text() { 252 if (this.folderStatusArray[item.index].includes(true)) { 253 ForEach(this.folderStatusArray[item.index], (status: boolean, index) =>{ 254 if (status) { 255 if (index !== this.folderStatusArray[item.index].indexOf(true)) { 256 Span($r('app.string.separator')) 257 } 258 Span(index === 0 ? $r('app.string.Download') : index === 1 ? $r('app.string.Desktop') : $r('app.string.Document')) 259 } 260 }) 261 } else { 262 Span($r('app.string.ban')) 263 } 264 } 265 .fontSize(Constants.TEXT_SMALL_FONT_SIZE) 266 .fontColor($r('sys.color.ohos_id_color_text_secondary')) 267 .margin({ right: Constants.AUTHORITY_IMAGE_MARGIN_RIGHT }) 268 } else { 269 Text(this.polymorphismIsOn[item.index] ? $r('app.string.allow') : $r('app.string.ban')) 270 .fontSize(Constants.TEXT_SMALL_FONT_SIZE) 271 .fontColor($r('sys.color.ohos_id_color_text_secondary')) 272 .margin({ right: Constants.AUTHORITY_IMAGE_MARGIN_RIGHT }) 273 } 274 Image($r('app.media.ic_public_arrow_right')) 275 .fillColor($r('sys.color.ohos_id_color_tertiary')) 276 .customizeImage(Constants.IMAGE_WIDTH, Constants.IMAGE_HEIGHT) 277 } 278 } 279 .width(Constants.FULL_WIDTH) 280 .height(Constants.AUTHORITY_ROW_HEIGHT) 281 .constraintSize({ minHeight: Constants.AUTHORITY_CONSTRAINTSIZE_MINHEIGHT }) 282 } 283 }.onClick(() => { 284 if (polymorphismGroup.indexOf(this.currentGroup) !== -1) { 285 let permissions: string[] = []; 286 this.list.forEach(data => { 287 if (data.bundleNames.includes(item.bundleName as string)) { 288 permissions.push(data.permission); 289 } 290 }) 291 this.allBundleInfo.forEach(bundleInfo => { 292 if (bundleInfo.bundleName === item.bundleName) { 293 GlobalContext.store('applicationInfo', bundleInfo); 294 } 295 }) 296 GlobalContext.store('folderStatus', this.folderStatusArray[item.index]); 297 router.pushUrl({ 298 url: 'pages/application-tertiary', 299 params: { 300 bundleName: item.bundleName, 301 backTitle: this.backTitle, 302 permission: permissions, 303 status: this.polymorphismIsOn[item.index] ? Constants.RADIO_ALLOW_INDEX : Constants.RADIO_BAN_INDEX, 304 tokenId: item.accessTokenId 305 } 306 }); 307 } 308 }) 309 } 310 }.padding({ left: $r('sys.float.ohos_id_card_margin_start'), right: $r('sys.float.ohos_id_card_margin_end') }) 311 .enabled(!this.isRisk[item.index]) 312 .opacity(this.isRisk[item.index] ? $r('sys.float.ohos_id_alpha_disabled') : 1) 313 .borderRadius($r("sys.float.ohos_id_corner_radius_default_l")) 314 .linearGradient((this.isTouch === item.bundleName) ? { 315 angle: 90, 316 direction: GradientDirection.Right, 317 colors: [['#DCEAF9', 0.0], ['#FAFAFA', 1.0]] 318 } : { 319 angle: 90, 320 direction: GradientDirection.Right, 321 colors: [[$r("sys.color.ohos_id_color_list_card_bg"), 1], [$r("sys.color.ohos_id_color_list_card_bg"), 1]] 322 }) 323 .onTouch(event => { 324 if (event === undefined) { 325 return; 326 } 327 if (event.type === TouchType.Down && polymorphismGroup.indexOf(this.currentGroup) !== -1) { 328 this.isTouch = item.bundleName ? item.bundleName : ''; 329 } 330 if (event.type === TouchType.Up) { 331 this.isTouch = ''; 332 } 333 }) 334 } 335 336 /** 337 * Take the total number of access applications 338 */ 339 getGrantApplicationNumber() { 340 if (polymorphismGroup.indexOf(this.currentGroup) !== -1) { 341 if (this.currentGroup === 'FOLDER') { 342 let sum = this.folderStatusArray.filter(item => item.includes(true)); 343 return sum.length; 344 } else { 345 let sum = this.polymorphismIsOn.filter(item => item == true); 346 return sum.length; 347 } 348 } else { 349 return this.permissionNum; 350 } 351 } 352 353 /** 354 * Grant permissions to the app 355 * @param {Number} accessTokenId 356 * @param {String} permission permission name 357 * @param {Number} index Array index to modify permission status 358 */ 359 grantUserGrantedPermission(accessTokenId: number, permission: Permissions, resolve: (value: number) => void) { 360 abilityAccessCtrl.createAtManager().grantUserGrantedPermission(accessTokenId, permission, Constants.PERMISSION_FLAG).then(() => { 361 resolve(0); 362 }).catch((error: BusinessError) => { 363 resolve(-1); 364 console.error(TAG + 'abilityAccessCtrl.createAtManager.grantUserGrantedPermission failed. Cause: ' + JSON.stringify(error)); 365 }) 366 } 367 368 /** 369 * Deauthorize the app 370 * @param {Number} accessTokenId 371 * @param {String} permission permission name 372 * @param {Number} index Array index to modify permission status 373 */ 374 revokeUserGrantedPermission(accessTokenId: number, permission: Permissions, resolve: (value: number) => void) { 375 abilityAccessCtrl.createAtManager().revokeUserGrantedPermission(accessTokenId, permission, Constants.PERMISSION_FLAG).then(() => { 376 resolve(0); 377 }).catch((error: BusinessError) => { 378 resolve(-1); 379 console.error(TAG + 'abilityAccessCtrl.createAtManager.revokeUserGrantedPermission failed. Cause: ' + JSON.stringify(error)); 380 }) 381 } 382 383 /** 384 * Lifecycle function, executed when the page is initialized 385 */ 386 aboutToAppear() { 387 let bundleNames: string[] = []; 388 this.applicationList = []; 389 this.list.forEach(permissionmanager => { 390 permissionmanager.bundleNames.forEach(bundleName => { 391 if (bundleNames.indexOf(bundleName) == -1) { 392 bundleNames.push(bundleName); 393 } 394 }) 395 }) 396 groups.forEach(group => { 397 if (group.name === this.currentGroup) { 398 this.groupInfo = group; 399 } 400 }) 401 402 let atManager = abilityAccessCtrl.createAtManager(); 403 for (let i = 0; i < bundleNames.length; i++) { 404 // Get BundleInfo based on bundle name 405 this.allBundleInfo.forEach(bundleInfo => { 406 if (bundleInfo.bundleName === bundleNames[i]) { 407 this.applicationList.push( 408 new ApplicationObj( 409 bundleInfo.label, 410 bundleInfo.icon, 411 i, 412 bundleInfo.tokenId, 413 this.list[0].permission, 414 bundleInfo.zhTag, 415 bundleInfo.indexTag, 416 bundleInfo.language, 417 bundleInfo.bundleName) // Get the first letter in the returned initials array 418 ); 419 this.isRisk[i] = false; 420 try { 421 atManager.getPermissionFlags(bundleInfo.tokenId, this.list[0].permission).then(data => { 422 if (data == Constants.PERMISSION_POLICY_FIXED) { 423 this.isRisk[i] = true; 424 } 425 }) 426 } 427 catch(err) { 428 console.log(TAG + 'getPermissionFlags error: ' + JSON.stringify(err)); 429 } 430 // 0: have permission; -1: no permission 431 let boole = true; 432 this.permissionNum++; 433 for (let j = 0; j < this.list.length; j++) { 434 if (bundleInfo.permissions.indexOf(this.list[j].permission) == -1) { 435 continue; 436 } 437 verifyAccessToken(bundleInfo.tokenId, this.list[j].permission).then((access) => { 438 if (Number(access) === Constants.PERMISSION_INDEX) { 439 if (boole) { 440 this.toggleIsOn[i] = true; 441 this.isFirst[i] = true; 442 } 443 } else { 444 if (boole) { 445 this.permissionNum--; 446 } 447 boole = false; 448 this.toggleIsOn[i] = false; 449 this.isFirst[i] = false; 450 } 451 }); 452 } 453 } 454 }) 455 } 456 if (globalGroup.indexOf(this.currentGroup) !== -1) { 457 this.globalIsOn = globalIsOn; 458 if (this.currentGroup == "CAMERA") { 459 let cameraManager = camera.getCameraManager(GlobalContext.load('context')); 460 cameraManager.on('cameraMute', (err, curMuted) => { 461 console.log(TAG + 'curMuted: ' + JSON.stringify(curMuted) + ' err: ' + JSON.stringify(err)); 462 this.globalIsOn = !curMuted; 463 }) 464 } else { 465 let audioManager = audio.getAudioManager(); 466 let audioVolumeManager = audioManager.getVolumeManager(); 467 let groupid = audio.DEFAULT_VOLUME_GROUP_ID; 468 audioVolumeManager.getVolumeGroupManager(groupid).then(audioVolumeGroupManager => { 469 audioVolumeGroupManager.on('micStateChange', micStateChange => { 470 this.globalIsOn = !micStateChange.mute; 471 }) 472 }) 473 } 474 } 475 } 476 477 aboutToDisappear() { 478 this.privacyDialogController = null; 479 } 480 481 build() { 482 Column() { 483 Row() { 484 textInput({ 485 applicationItem: $applicationList, 486 searchResult: $searchResult 487 }) 488 }.padding({ 489 left: Constants.AUTHORITY_TEXTINPUT_PADDING_LEFT, 490 right: Constants.AUTHORITY_TEXTINPUT_PADDING_RIGHT 491 }) 492 Flex({ alignItems:ItemAlign.Start, justifyContent: FlexAlign.Start }) { 493 Column() { 494 if (globalGroup.indexOf(this.currentGroup) !== -1 && this.isMuteSupported === true) { 495 Row() { 496 Flex({ justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) { 497 Text(this.currentGroup == "CAMERA" ? $r('app.string.camera') : $r('app.string.microphone')) 498 .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE).fontColor($r('sys.color.ohos_id_color_text_primary')) 499 .fontWeight(FontWeight.Medium) 500 Row() { 501 Toggle({ type: ToggleType.Switch, isOn: this.globalIsOn }) 502 .selectedColor($r('sys.color.ohos_id_color_toolbar_icon_actived')) 503 .switchPointColor($r('sys.color.ohos_id_color_foreground_contrary')) 504 .padding({ right: 0 }) 505 .onChange((isOn: boolean) => { 506 if (isOn) { 507 if (this.currentGroup == "CAMERA") { 508 let cameraManager = camera.getCameraManager(GlobalContext.load('context')); 509 cameraManager.muteCamera(false); 510 } else { 511 let audioManager = audio.getAudioManager(); 512 let audioVolumeManager = audioManager.getVolumeManager(); 513 let groupid = audio.DEFAULT_VOLUME_GROUP_ID; 514 audioVolumeManager.getVolumeGroupManager(groupid).then(audioVolumeGroupManager => { 515 audioVolumeGroupManager.setMicrophoneMute(false) 516 }) 517 } 518 } 519 }) 520 Row().onClick(() => { 521 if (this.privacyDialogController !== null) { 522 this.privacyDialogController.open() 523 } 524 }) 525 .width(Constants.DEFAULT_SLIDER_WIDTH).height(Constants.DEFAULT_SLIDER_HEIGHT) 526 .position({ x: this.globalIsOn ? 0 : Constants.OFFSET, y: 0 }) 527 }.clip(true) 528 }.height(Constants.LISTITEM_ROW_HEIGHT) 529 .padding({ left: Constants.DEFAULT_PADDING_START, right: Constants.DEFAULT_PADDING_END }) 530 }.padding({ top: Constants.LIST_PADDING_TOP, bottom: Constants.LIST_PADDING_BOTTOM }) 531 .backgroundColor($r('sys.color.ohos_id_color_list_card_bg')) 532 .borderRadius($r('sys.float.ohos_id_corner_radius_card')) 533 .margin({ top: Constants.TERTIARY_ROW_MARGIN_TOP }) 534 } 535 Flex({ justifyContent: FlexAlign.Start }) { 536 if (this.globalIsOn) { 537 if (this.getGrantApplicationNumber() > 0) { 538 Text() { 539 Span(this.groupInfo.enable_description_start ? this.groupInfo.enable_description_start : '') 540 Span(String(this.getGrantApplicationNumber())) 541 Span(this.groupInfo.enable_description_end ? this.groupInfo.enable_description_end : '') 542 } 543 .fontSize(Constants.TEXT_SMALL_FONT_SIZE) 544 .fontColor($r('sys.color.ohos_id_color_text_secondary')) 545 .margin({ top: Constants.AUTHORITY_TEXT_MARGIN_TOP }) 546 } else { 547 Text(this.groupInfo.forbidden_description) 548 .fontSize(Constants.TEXT_SMALL_FONT_SIZE) 549 .fontColor($r('sys.color.ohos_id_color_text_secondary')) 550 .margin({ top: Constants.AUTHORITY_TEXT_MARGIN_TOP }) 551 } 552 } else { 553 Text(this.currentGroup == "CAMERA" ? $r('app.string.camera_is_off') : $r('app.string.microphone_is_off')) 554 .fontSize(Constants.TEXT_SMALL_FONT_SIZE) 555 .fontColor($r('sys.color.ohos_id_color_text_secondary')) 556 .margin({ top: Constants.AUTHORITY_TEXT_MARGIN_TOP }) 557 } 558 }.padding({ left: Constants.DEFAULT_PADDING_START, right: Constants.DEFAULT_PADDING_END }) 559 .margin({ bottom: Constants.AUTHORITY_ROW_MARGIN_BOTTOM }) 560 Row() { 561 Column() { 562 if (!this.applicationList.length) { 563 if (this.searchResult) { 564 Row() {} 565 } else { 566 Row() { 567 Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) { 568 Image($r('app.media.searchnoresult')) 569 .customizeImage(Constants.SEARCHNORESULT_IMAGE_WIDTH, Constants.SEARCHNORESULT_IMAGE_HEIGHT) 570 } 571 } 572 } 573 } else { 574 Row() { 575 List({ scroller: this.scroller }) { 576 ForEach(sortByName(this.applicationList), (item: ApplicationObj) => { 577 this.ListItemLayout(item) 578 }, (item: ApplicationObj) => JSON.stringify(item)) 579 } 580 .backgroundColor($r('sys.color.ohos_id_color_list_card_bg')) 581 .borderRadius($r('sys.float.ohos_id_corner_radius_card')) 582 .padding(Constants.LIST_PADDING_TOP) 583 .divider({ 584 strokeWidth: Constants.DIVIDER, 585 color: $r('sys.color.ohos_id_color_list_separator'), 586 startMargin: Constants.DIVIDER_MARGIN_RIGHT_APPLICATION, 587 endMargin: Constants.DEFAULT_MARGIN_END 588 }) 589 .onScrollIndex((start, end) => { 590 GlobalContext.getContext().set('scroller', this.scroller); 591 if (this.applicationList.length > 0) { 592 let alphabeticalIndex: string = sortByName(this.applicationList)[start].indexTag; 593 let index = indexValue.indexOf(alphabeticalIndex); 594 this.selectedIndex = index >= 0 ? index : 0; 595 } 596 }) 597 } 598 } 599 }.width(Constants.FULL_WIDTH) 600 .margin({ bottom: globalGroup.includes(this.currentGroup) && this.isMuteSupported === true ? Constants.AUTHORITY_LIST_MARGIN_BOTTOM_GLOBAL : Constants.AUTHORITY_LIST_MARGIN_BOTTOM }) 601 } 602 }.padding({ left: Constants.AUTHORITY_LISTITEM_PADDING_LEFT }) 603 Column() { 604 alphabetIndexerComponent({ applicationItem: $applicationList, index: $selectedIndex }) 605 }.width(Constants.AUTHORITY_ALPHABETINDEX_WIDTH) 606 .padding({ top: Constants.AUTHORITY_ALPHABETINDEX_PADDING_TOP }) 607 .margin({ bottom: Constants.APPLICATION_LIST_MARGIN_BOTTOM }) 608 }.flexGrow(Constants.FLEX_GROW) 609 }.height(Constants.FULL_HEIGHT) 610 } 611} 612