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