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 abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl'; 17import bundleManager from '@ohos.bundle.bundleManager'; 18import rpc from '@ohos.rpc'; 19import window from '@ohos.window'; 20import common from '@ohos.app.ability.common'; 21import pasteboard from '@ohos.pasteboard'; 22import { BusinessError } from '@ohos.base'; 23import { CustomContentDialog } from '@ohos.arkui.advanced.Dialog'; 24import { 25 Log, 26 getPermissionGroup, 27 titleTrim, 28 getPermissionLabel, 29 getFontSizeScale, 30 supportPermission 31} from '../common/utils/utils'; 32import { Permission, ButtonStatus } from '../common/model/definition'; 33import { GroupInfo, WantInfo } from '../common/model/typedef'; 34import { GlobalContext } from '../common/utils/globalContext'; 35import Constants from '../common/utils/constant'; 36import { showSubPermissionsGroup, buttonResource } from '../common/model/permissionGroup'; 37import { LocationCanvas } from '../common/components/location'; 38import { MeasureText } from '@kit.ArkUI'; 39 40@Extend(Button)function customizeButton() { 41 .buttonStyle(ButtonStyleMode.TEXTUAL) 42 .fontColor($r('sys.color.font_emphasize')) 43 .width(Constants.HALF_LENGTH) 44} 45 46@Extend(Text)function titleText() { 47 .fontWeight(FontWeight.Bold) 48 .fontColor($r('sys.color.font_primary')) 49 .textAlign(TextAlign.Center) 50 .textOverflow({ overflow: TextOverflow.Ellipsis }) 51 .maxLines(Constants.SECURITY_HEADER_MAX_LINES) 52} 53 54const fuzzyMarks = [Constants.LOCATION_FUZZY, Constants.LOCATION_BOTH_FUZZY, Constants.LOCATION_BOTH_PRECISE]; 55const preciseMarks = [Constants.LOCATION_UPGRADE, Constants.LOCATION_BOTH_PRECISE]; 56let storage = LocalStorage.getShared(); 57 58@Entry(storage) 59@Component 60struct dialogPlusPage { 61 @LocalStorageLink('want') want: WantInfo = new WantInfo([]); 62 @LocalStorageLink('win') win: window.Window = {} as window.Window; 63 private context = getContext(this) as common.ServiceExtensionContext; 64 @State count: number = 0; 65 @State result: Array<number> = []; 66 @State accessTokenId: number = 0; 67 @State initStatus: number = Constants.INIT_NEED_TO_WAIT; 68 @State reqPerms: Array<Permission> = []; 69 @State grantGroups: Array<GroupInfo> = []; 70 @State userFixedFlag: number = 2; // means user fixed 71 @State grantStatus: number = -1; 72 @State appName: string = ''; 73 @State locationFlag: number = Constants.LOCATION_NONE; 74 @State reqPermissionDetails: bundleManager.ReqPermissionDetail[] = []; 75 @State refresh: number = 0; 76 @State pasteBoardName: string = ''; 77 @State isUpdate: number = -1; 78 79 dialogController: CustomDialogController | null = new CustomDialogController({ 80 builder: CustomContentDialog({ 81 contentBuilder: () => { 82 this.buildContent(); 83 }, 84 contentAreaPadding: { right: 0 } 85 }), 86 autoCancel: false 87 }); 88 89 @Builder 90 DialogTitle() { 91 Row() { 92 Column() { 93 if (getFontSizeScale()) { 94 Text($r(this.showTitle(), this.appName)) 95 .titleText() 96 .fontSize($r('sys.float.Title_S')) 97 } else { 98 Text($r(this.showTitle(), this.appName)) 99 .titleText() 100 .minFontSize(Constants.TEXT_MIDDLE_FONT_SIZE) 101 .maxFontSize($r('sys.float.Title_S')) 102 .heightAdaptivePolicy(TextHeightAdaptivePolicy.MAX_LINES_FIRST) 103 } 104 } 105 .constraintSize({ minHeight: Constants.HEADLINE_HEIGHT }) 106 .justifyContent(FlexAlign.Center) 107 .padding({ 108 top: Constants.DEFAULT_PADDING_TOP, 109 bottom: Constants.DEFAULT_PADDING_BOTTOM, 110 left: Constants.PADDING_24, 111 right: Constants.PADDING_24 112 }) 113 } 114 } 115 116 @Builder 117 buildContent(): void { 118 Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) { 119 Column() { 120 if ((this.initStatus != Constants.INIT_NEED_TO_WAIT) && this.verify()) { 121 Image(this.currentGroup().icon) 122 .width(Constants.DIALOG_ICON_WIDTH) 123 .height(Constants.DIALOG_ICON_HEIGHT) 124 .fillColor($r('sys.color.font_primary')) 125 .margin({ top: Constants.DIALOG_ICON_MARGIN_TOP }) 126 if (this.grantGroups.length > 1) { 127 Text(`${this.count + 1} / ${this.grantGroups.length}`) 128 .fontSize(Constants.DIALOG_LABEL_FONT_SIZE) 129 .fontColor($r('sys.color.font_secondary')) 130 .lineHeight(Constants.DIALOG_LABEL_LINE_HEIGHT) 131 .margin({ top: Constants.DIALOG_LABEL_MARGIN_TOP }) 132 } 133 Scroll() { 134 Column() { 135 this.DialogTitle(); 136 137 Row() { 138 Flex({ justifyContent: FlexAlign.Center }) { 139 Text() { 140 if ( 141 this.currentGroup().name === 'LOCATION' && 142 ((this.locationFlag == Constants.LOCATION_FUZZY) || 143 (this.locationFlag == Constants.LOCATION_BOTH_FUZZY)) 144 ) { 145 Span($r('app.string.close_exact_position')) 146 } else if (this.currentGroup().name === 'PASTEBOARD') { 147 if (this.pasteBoardName) { 148 Span($r('app.string.pasteBoard_app', this.pasteBoardName)) 149 } else { 150 Span($r('app.string.pasteBoard_desc')) 151 } 152 } else { 153 if (this.currentGroup().description.length > 0) { 154 ForEach(this.currentGroup().description, (item: ResourceStr) => { 155 Span(item) 156 }) 157 Span(this.currentGroup().reason ? $r('app.string.comma') : $r('app.string.period')) 158 } 159 Span(this.refresh >= 0 ? this.currentGroup().reason : '') 160 } 161 } 162 .textAlign(TextAlign.Start) 163 .fontColor($r('sys.color.font_primary')) 164 .fontSize($r('sys.float.Body_L')) 165 .maxFontScale(Constants.DIALOG_TEXT_MAX_SCALE) 166 .margin({ 167 left: Constants.DIALOG_DESP_MARGIN_LEFT, 168 right: Constants.DIALOG_DESP_MARGIN_RIGHT, 169 bottom: Constants.DIALOG_DESP_MARGIN_BOTTOM 170 }) 171 } 172 } 173 174 if (this.locationFlag > Constants.LOCATION_NONE && this.currentGroup().name === 'LOCATION') { 175 LocationCanvas({ locationFlag: $locationFlag }) 176 } 177 } 178 }.constraintSize({ maxHeight: Constants.MAXIMUM_HEADER_HEIGHT }) 179 if (this.currentGroup().buttons.length <= 2 && this.calculateButtonWidth(this.currentGroup().buttons)) { 180 //横向布局 181 Row() { 182 Flex({ justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) { 183 Button(buttonResource.get(this.currentGroup().buttons[0])) 184 .customizeButton() 185 .onClick(() => { 186 this.clickHandle(this.currentGroup().buttons[0]); 187 }) 188 Divider() 189 .color($r('sys.color.comp_divider')) 190 .vertical(true) 191 .strokeWidth(Constants.DIALOG_DIVIDER) 192 .height(Constants.DIVIDER_HEIGHT) 193 .opacity(0.2) 194 .margin({ left: Constants.MARGIN_8, right: Constants.MARGIN_8 }) 195 Button(buttonResource.get(this.currentGroup().buttons[1])) 196 .customizeButton() 197 .onClick(() => { 198 this.clickHandle(this.currentGroup().buttons[1]); 199 }) 200 }.margin({ 201 left: Constants.BUTTON_MARGIN_LEFT, 202 right: Constants.BUTTON_MARGIN_RIGHT, 203 bottom: Constants.MARGIN_8 204 }) 205 } 206 } else { 207 //纵向布局 208 Column() { 209 ForEach(this.currentGroup().buttons, (buttonStatus: ButtonStatus, idx: number) => { 210 Button(buttonResource.get(buttonStatus)) 211 .customizeButton() 212 .width(Constants.FULL_WIDTH) 213 .margin({ bottom: idx + 1 < this.currentGroup().buttons.length ? Constants.MARGIN_4 : 0 }) 214 .onClick(() => { 215 this.clickHandle(buttonStatus); 216 }) 217 }) 218 } 219 .padding({ left: Constants.PADDING_16, right: Constants.PADDING_16 }) 220 } 221 } 222 } 223 .padding({ bottom: Constants.PADDING_8 }) 224 .clip(true) 225 } 226 } 227 228 build() {} 229 230 showTitle(): string { 231 let index = this.count >= this.grantGroups.length ? this.grantGroups.length - 1 : this.count; 232 if (this.grantGroups[index].name == 'LOCATION') { 233 if (this.locationFlag == Constants.LOCATION_FUZZY) { 234 return 'app.string.access_general_location'; 235 } 236 if (this.locationFlag == Constants.LOCATION_UPGRADE) { 237 return 'app.string.fuzzy_to_exact'; 238 } 239 } 240 return this.grantGroups[index].label; 241 } 242 243 currentGroup(): GroupInfo { 244 let index = this.count >= this.grantGroups.length ? this.grantGroups.length - 1 : this.count; 245 return this.grantGroups[index]; 246 } 247 248 calculateButtonWidth(buttonStatus: ButtonStatus[]): boolean { 249 let denyText = buttonResource.get(buttonStatus[0]); 250 let allowText = buttonResource.get(buttonStatus[1]); 251 let maxButtonTextLength = Math.max( 252 MeasureText.measureText({ textContent: denyText }), 253 MeasureText.measureText({ textContent: allowText }) 254 ) 255 256 Log.info(`px2vp(maxButtonTextLength): ${px2vp(maxButtonTextLength)}`); 257 if (px2vp(maxButtonTextLength) > Constants.DIALOG_BUTTON_MAX_WIDTH) { 258 return false; 259 } 260 261 return true; 262 } 263 264 clickHandle(buttonStatus: ButtonStatus) { 265 switch (buttonStatus) { 266 case ButtonStatus.ALLOW: 267 this.privacyAccept(this.grantGroups[this.count], this.accessTokenId, this.reqPerms, this.userFixedFlag); 268 return; 269 case ButtonStatus.DENY: 270 this.privacyCancel(this.grantGroups[this.count], this.accessTokenId, this.reqPerms, this.userFixedFlag); 271 return; 272 case ButtonStatus.CANCEL: 273 this.count ++; 274 return; 275 case ButtonStatus.THIS_TIME_ONLY: 276 this.privacyAccept( 277 this.grantGroups[this.count], this.accessTokenId, this.reqPerms, Constants.PERMISSION_ALLOW_THIS_TIME 278 ); 279 return; 280 case ButtonStatus.ALLOW_THIS_TIME: 281 this.privacyAccept( 282 this.grantGroups[this.count], this.accessTokenId, this.reqPerms, Constants.PERMISSION_ALLOW_THIS_TIME 283 ); 284 return; 285 case ButtonStatus.ALLOW_ONLY_DURING_USE: 286 this.privacyAccept(this.grantGroups[this.count], this.accessTokenId, this.reqPerms, this.userFixedFlag); 287 return; 288 } 289 } 290 291 async privacyAccept(group: GroupInfo, accessTokenId: number, permissionList: string[], userFixedFlag: number) { 292 let num = 0; 293 group.permissions.forEach(async permission => { 294 this.grantStatus = -1; 295 if (showSubPermissionsGroup.indexOf(group.name) == -1) { 296 if (group.name == 'LOCATION') { 297 if (fuzzyMarks.includes(this.locationFlag) && permission === Permission.APPROXIMATELY_LOCATION) { 298 await this.operationPermission(true, accessTokenId, permission, userFixedFlag); 299 } 300 if (preciseMarks.includes(this.locationFlag) && permission === Permission.LOCATION) { 301 await this.operationPermission(true, accessTokenId, permission, userFixedFlag); 302 } 303 } else { 304 await this.operationPermission(true, accessTokenId, permission, userFixedFlag); 305 } 306 } else { 307 if (permissionList.includes(permission)) { 308 await this.operationPermission(true, accessTokenId, permission, userFixedFlag); 309 } 310 } 311 if (this.grantStatus == abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) { 312 permissionList.forEach((req, idx) => { 313 if (req == permission) { 314 this.result[idx] = abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED; 315 } 316 }) 317 } 318 num ++; 319 if (num == group.permissions.length) { 320 this.count ++; 321 } 322 }) 323 } 324 325 async privacyCancel(group: GroupInfo, accessTokenId: number, permissionList: string[], userFixedFlag: number) { 326 group.permissions.forEach(async permission => { 327 if (showSubPermissionsGroup.indexOf(group.name) == -1) { 328 await this.operationPermission(false, accessTokenId, permission, userFixedFlag); 329 } else { 330 if (permissionList.includes(permission)) { 331 await this.operationPermission(false, accessTokenId, permission, userFixedFlag); 332 } 333 } 334 }) 335 this.count ++; 336 } 337 338 async operationPermission(status: boolean, token: number, permission: Permissions, flag: number) { 339 if (status) { 340 try { 341 Log.info('grantUserGrantedPermission: ' + permission); 342 await abilityAccessCtrl.createAtManager().grantUserGrantedPermission(token, permission, flag).then(() => { 343 this.grantStatus = abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED; 344 }) 345 } catch (err) { 346 Log.error('failed to grant permission: ' + permission); 347 } 348 } else { 349 try { 350 Log.info('revokeUserGrantedPermission: ' + permission) 351 await abilityAccessCtrl.createAtManager().revokeUserGrantedPermission(token, permission, flag); 352 } catch (err) { 353 Log.error('failed to revoke permission:' + permission); 354 } 355 } 356 } 357 358 aboutToAppear() { 359 this.count = 0; 360 this.initStatus = Constants.INIT_NEED_TO_WAIT; 361 this.result = []; 362 this.reqPerms = this.want.parameters['ohos.user.grant.permission']; 363 this.accessTokenId = this.want.parameters['ohos.aafwk.param.callerToken']; 364 if (this.reqPerms == undefined || this.accessTokenId == undefined || this.reqPerms.length == 0) { 365 Log.info('invalid parameters'); 366 this.initStatus = Constants.INIT_NEED_TO_TERMINATED; 367 return; 368 } 369 Log.info(`request permission: ${JSON.stringify(this.reqPerms)}.`); 370 Log.info('permission state=' + JSON.stringify(this.want.parameters['ohos.user.grant.permission.state'])); 371 this.result = new Array(this.reqPerms.length).fill(-1); 372 this.getPasteBoardInfo(); 373 let bundleName: string = this.want.parameters['ohos.aafwk.param.callerBundleName']; 374 try { 375 bundleManager.getBundleInfo(bundleName, bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_REQUESTED_PERMISSION) 376 .then(bundleInfo => { 377 this.reqPermissionDetails = bundleInfo.reqPermissionDetails; 378 this.getGrantGroups(this.want.parameters['ohos.user.grant.permission.state']); 379 this.getApplicationName(bundleName); 380 this.dialogController?.open(); 381 }).catch((err: BusinessError) => { 382 Log.error('getBundleInfo error :' + JSON.stringify(err)); 383 this.initStatus = Constants.INIT_NEED_TO_TERMINATED; 384 }) 385 } catch (err) { 386 Log.error('getBundleInfo error :' + JSON.stringify(err)); 387 this.initStatus = Constants.INIT_NEED_TO_TERMINATED; 388 } 389 } 390 391 aboutToDisappear() { 392 this.dialogController = null; 393 } 394 395 onPageShow() { 396 if (this.isUpdate > 0) { 397 this.getApplicationName(this.want.parameters['ohos.aafwk.param.callerBundleName']) 398 } 399 this.isUpdate ++; 400 } 401 402 getPasteBoardInfo() { 403 if (this.reqPerms.includes(Permission.READ_PASTEBOARD)) { 404 let systemPasteboard: pasteboard.SystemPasteboard = pasteboard.getSystemPasteboard(); 405 this.pasteBoardName = systemPasteboard.getDataSource(); 406 } 407 } 408 409 getGrantGroups(stateGroup: number[]) { 410 if (this.reqPerms.includes(Permission.APPROXIMATELY_LOCATION)) { 411 this.locationFlag = Constants.LOCATION_FUZZY; 412 if (this.reqPerms.includes(Permission.LOCATION)) { 413 this.locationFlag = Constants.LOCATION_BOTH_PRECISE; 414 let fuzzyIndex = this.reqPerms.indexOf(Permission.APPROXIMATELY_LOCATION); 415 if (stateGroup[fuzzyIndex] == Constants.PASS_OPER) { 416 this.locationFlag = Constants.LOCATION_UPGRADE; 417 } 418 } 419 } else if (this.reqPerms.includes(Permission.LOCATION)) { 420 this.locationFlag = Constants.LOCATION_UPGRADE; 421 } 422 423 this.reqPerms.forEach(async (permission, idx) => { 424 if (permission === Permission.APP_TRACKING_CONSENT) { 425 let toggleStatus = await this.appTrackHandle(idx); 426 if (toggleStatus === abilityAccessCtrl.PermissionRequestToggleStatus.CLOSED) { 427 return; 428 } 429 } 430 if (stateGroup[idx] == Constants.PASS_OPER) { 431 Log.info('permission has been fixed:' + permission); 432 this.result[idx] = abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED; 433 } else if (stateGroup[idx] == Constants.DYNAMIC_OPER) { 434 let supportPermissions = supportPermission(); 435 if (!supportPermissions.includes(permission)) { 436 Log.info('The permission does not exist or is not supported by the current device: ' + permission); 437 } else { 438 this.addGroup(permission); 439 } 440 } 441 }) 442 this.initStatus = Constants.INIT_NEED_TO_VERIFY; 443 } 444 445 async appTrackHandle(index: number): Promise<abilityAccessCtrl.PermissionRequestToggleStatus> { 446 try { 447 let acManager = abilityAccessCtrl.createAtManager(); 448 let toggleStatus = await acManager.getPermissionRequestToggleStatus(Permission.APP_TRACKING_CONSENT); 449 Log.info(`APP_TRACKING_CONSENT toggleStatus: ${toggleStatus}.`); 450 if (toggleStatus === abilityAccessCtrl.PermissionRequestToggleStatus.CLOSED) { 451 await acManager.grantUserGrantedPermission( 452 this.accessTokenId, Permission.APP_TRACKING_CONSENT, this.userFixedFlag 453 ); 454 this.result[index] = abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED; 455 Log.info('APP_TRACKING_CONSENT grant success.'); 456 } 457 return toggleStatus; 458 } catch (err) { 459 Log.error(`APP_TRACKING_CONSENT getToggleStatus or grant fail: ${JSON.stringify(err)}`); 460 return abilityAccessCtrl.PermissionRequestToggleStatus.OPEN; 461 } 462 } 463 464 addGroup(permission: Permission) { 465 let group = getPermissionGroup(permission); 466 if (group.name === 'FOLDER') { 467 switch (permission) { 468 case Permission.READ_WRITE_DOWNLOAD_DIRECTORY: 469 let downloadGroup = new GroupInfo( 470 group.name, group.groupName, 'app.string.group_label_download_folder', group.icon, group.description, 471 group.reason, [Permission.READ_WRITE_DOWNLOAD_DIRECTORY], group.buttons, group.isShow 472 ) 473 this.grantGroups.push(downloadGroup); 474 break; 475 case Permission.READ_WRITE_DESKTOP_DIRECTORY: 476 let desktopGroup = new GroupInfo( 477 group.name, group.groupName, 'app.string.group_label_desktop_folder', group.icon, group.description, 478 group.reason, [Permission.READ_WRITE_DESKTOP_DIRECTORY], group.buttons, group.isShow 479 ) 480 this.grantGroups.push(desktopGroup); 481 break; 482 case Permission.READ_WRITE_DOCUMENTS_DIRECTORY: 483 let documentGroup = new GroupInfo( 484 group.name, group.groupName, 'app.string.group_label_document_folder', group.icon, group.description, 485 group.reason, [Permission.READ_WRITE_DOCUMENTS_DIRECTORY], group.buttons, group.isShow 486 ) 487 this.grantGroups.push(documentGroup); 488 break; 489 } 490 return 491 } 492 let exist = this.grantGroups.find(grantGroup => grantGroup.name == group.name); 493 if (showSubPermissionsGroup.indexOf(group.name) != -1) { 494 let label = getPermissionLabel(permission) 495 if (!exist) { 496 group.description.push(label); 497 this.grantGroups.push(group); 498 } else { 499 if (exist.description.indexOf(label) == -1) { 500 exist.description.push($r('app.string.and')); 501 exist.description.push(label); 502 } 503 } 504 } else { 505 if (!exist) { 506 this.grantGroups.push(group); 507 } 508 } 509 } 510 511 getApplicationName(bundleName: string) { 512 Log.info('getApplicationName bundleName:' + bundleName); 513 bundleManager.getApplicationInfo(bundleName, bundleManager.ApplicationFlag.GET_APPLICATION_INFO_DEFAULT) 514 .then(applicationInfo => { 515 let context = this.context.createBundleContext(bundleName); 516 context.resourceManager.getStringValue(applicationInfo.labelId, (err, value) => { 517 if (value == undefined) { 518 this.appName = titleTrim(applicationInfo.label); 519 } else { 520 this.appName = titleTrim(value); 521 } 522 Log.info('hap label:' + applicationInfo.label + ', value:' + this.appName); 523 }) 524 }).catch((err: BusinessError) => { 525 Log.error('applicationInfo error :' + err); 526 this.initStatus = Constants.INIT_NEED_TO_TERMINATED; 527 }) 528 this.grantGroups.forEach((group) => { 529 group.reason = ''; 530 this.getReason(group, bundleName); 531 }) 532 } 533 534 getReason(group: GroupInfo, bundleName: string) { 535 group.permissions.forEach(permission => { 536 if (this.reqPerms.indexOf(permission) != -1) { 537 this.reqPermissionDetails.forEach(reqPermissionDetail => { 538 if (reqPermissionDetail.name == permission) { 539 Log.info('reqPermissionDetail: ' + JSON.stringify(reqPermissionDetail)); 540 let context = this.context.createModuleContext(bundleName, reqPermissionDetail.moduleName); 541 context.resourceManager.getStringValue(reqPermissionDetail.reasonId, (err, value) => { 542 if (value !== undefined && group.reason === '') { 543 group.reason = value.slice(Constants.START_SUBSCRIPT, Constants.END_SUBSCRIPT); 544 this.refresh ++; 545 } 546 this.initStatus = Constants.INIT_NEED_TO_REFRESH; 547 }) 548 } 549 }) 550 } 551 }) 552 } 553 554 verify() { 555 if ((this.initStatus == Constants.INIT_NEED_TO_TERMINATED) || (this.count >= this.grantGroups.length)) { 556 this.answerRequest(); 557 this.initStatus = Constants.INIT_NEED_TO_WAIT; 558 return false; 559 } 560 return true; 561 } 562 563 answerRequest() { 564 let ret: number = Constants.RESULT_SUCCESS; 565 if (this.initStatus == Constants.INIT_NEED_TO_TERMINATED) { 566 ret = Constants.RESULT_FAILURE; 567 } 568 this.answer(ret, this.reqPerms); 569 } 570 571 answer(ret: number, reqPerms: string[]) { 572 Log.info('code:' + ret + ', perms=' + JSON.stringify(reqPerms) + ', result=' + JSON.stringify(this.result)); 573 let perms: string[] = []; 574 let results: number[] = []; 575 reqPerms.forEach(perm => { 576 perms.push(perm); 577 }) 578 this.result.forEach(result => { 579 results.push(result); 580 }) 581 let option = new rpc.MessageOption(); 582 let data = new rpc.MessageSequence(); 583 let setDialogData = new rpc.MessageSequence(); 584 let reply = new rpc.MessageSequence(); 585 Promise.all([ 586 data.writeInterfaceToken(Constants.ACCESS_TOKEN), 587 data.writeStringArray(perms), 588 data.writeIntArray(results), 589 setDialogData.writeInterfaceToken(Constants.ACCESS_TOKEN), 590 ]).then(() => { 591 let proxy = this.want.parameters['ohos.ability.params.callback'].value as rpc.RemoteObject; 592 proxy.sendMessageRequest(Constants.RESULT_CODE, data, reply, option); 593 proxy.sendMessageRequest(Constants.RESULT_CODE_1, setDialogData, reply, option); 594 }).catch(() => { 595 Log.error('write result failed!'); 596 }).finally(() => { 597 data.reclaim(); 598 reply.reclaim(); 599 setDialogData.reclaim(); 600 this.destruction(); 601 }) 602 } 603 604 destruction() { 605 let windowNum: number = GlobalContext.load('windowNum'); 606 windowNum --; 607 Log.info('windowNum:' + windowNum); 608 GlobalContext.store('windowNum', windowNum); 609 this.win.destroyWindow(); 610 if (windowNum == 0) { 611 this.context.terminateSelf(); 612 } 613 } 614}