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