1/* 2 * Copyright (c) 2024 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 UIExtensionContentSession from '@ohos.app.ability.UIExtensionContentSession'; 17import { EditableLeftIconType } from '@ohos.arkui.advanced.EditableTitleBar'; 18import { EditableTitleBar } from '@ohos.arkui.advanced.EditableTitleBar'; 19import ConnectService from '../common/share/ConnectService'; 20import { LengthMetrics } from '@ohos.arkui.node'; 21import dlpPermission from '@ohos.dlpPermission'; 22import promptAction from '@ohos.promptAction'; 23import { BusinessError } from '@ohos.base'; 24import Want from '@ohos.app.ability.Want'; 25import fs from '@ohos.file.fs'; 26import emitter from '@ohos.events.emitter'; 27import { HiLog } from '../common/HiLog'; 28import Constants from '../common/constant'; 29import FileUtils, { FileMsg } from '../common/FileUtils'; 30import { 31 getFileUriByPath, 32 getFileFd, 33 sendDlpFileCreateProperties, 34 getFileSizeByUri, 35 sendDlpManagerAccountLogin, 36 getAppId, 37 getOsAccountInfo, 38 checkNetworkStatus 39} from '../common/utils'; 40import { SystemUtils } from '../common/systemUtils'; 41 42const TAG = 'Share'; 43 44class Test { 45 public '0': number = 0; 46 public '1': number = 0; 47 public '4': string = ''; 48} 49 50class AuthUserList { 51 public authAccount: string = ''; 52 public authAccountType: number = 0; 53 public dlpFileAccess: number = 0; 54 public permExpiryTime: number = 0; 55} 56 57let defaultDlpProperty: dlpPermission.DLPProperty = { 58 ownerAccount: '', 59 ownerAccountType: dlpPermission.AccountType.CLOUD_ACCOUNT, 60 authUserList: [], 61 contactAccount: '', 62 offlineAccess: true, 63 ownerAccountID: '', 64 everyoneAccessList: [] 65}; 66 67let storage = LocalStorage.getShared(); 68 69@Entry(storage) 70@Component 71struct encryptedSharing { 72 private connectService: ConnectService = new ConnectService(getContext(this)); 73 @State titlebarMargin: LocalizedMargin = { 74 start: LengthMetrics.vp(Constants.SHARE_TITLE_HEAD_MARGIN_RIGHT), 75 end: LengthMetrics.vp(Constants.SHARE_TITLE_HEAD_MARGIN_RIGHT), 76 }; 77 @LocalStorageLink('commandSearchUserInfo') @Watch('beginToGenerateDLPFile') isInputInvalid: string = ''; 78 @LocalStorageLink('commandGetAccountInfo') @Watch('changeAccountInfo') commandGetAccountInfo: string = ''; 79 @State commandGetAccountInfoFlag: boolean = false; 80 @State dlpProperty: dlpPermission.DLPProperty = defaultDlpProperty; 81 @State enabledFocus: boolean = true; 82 @State isConfirmButtonEnabled: boolean = false; 83 @State isShowSheet: boolean = false; 84 @State showUIExtensionForAccountLogin: boolean = false; 85 @State actionWant: Want | undefined = storage.get<Want>('actionWant'); 86 @State inputValue: string = ''; 87 @State phoneFormatTips: boolean = false; 88 @State ownerAccount: string = ''; 89 @State ownerAccountID: string = ''; 90 @State contactExists: boolean = true; 91 @State credentialCallBackMsg: string | Resource = ''; 92 @State session: UIExtensionContentSession | undefined = 93 storage === undefined ? undefined : storage.get<UIExtensionContentSession>('session'); 94 @State placeHolderStr: ResourceStr = ''; 95 @State contactPerson: string = ''; 96 @State recordHashUid: string = ''; 97 @State osVersion: ResourceStr = ''; 98 @State isTextInputFocus: boolean = false; 99 @State generalType: string = 'general.file'; 100 101 @Builder 102 contactsPicker() { 103 Column() { 104 UIExtensionComponent({ 105 bundleName: 'com.ohos.contacts', 106 abilityName: 'ContactUiExtentionAbility', 107 parameters: { 108 'ability.want.params.uiExtensionType': 'sys/commonUI', 109 'targetUrl': 'BatchSelectContactsPage', 110 'isContactMultiSelect': false, 111 } 112 }) 113 .onRelease((code) => { 114 }) 115 .onResult((data) => { 116 }) 117 .onReceive((data) => { 118 let params: [] = JSON.parse((data.want as Want)?.parameters?.contactObjects as string); 119 for (let i = 0; i < params.length; i++) { 120 this.inputValue = (params[i] as Record<string, string>)?.telephone; 121 } 122 this.isShowSheet = false; 123 }) 124 .width(Constants.CONTACTS_PICKER_WIDTH) 125 .height(Constants.CONTACTS_PICKER_HEIGHT) 126 .hitTestBehavior(HitTestMode.Block) 127 } 128 .width(Constants.CONTACTS_PICKER_WIDTH) 129 .height(Constants.CONTACTS_PICKER_HEIGHT) 130 } 131 132 private async beginShareEncrypt() { 133 HiLog.info(TAG, `begin Share Encrypt start`); 134 if (this.checkCloudPhone(this.inputValue)) { 135 this.enabledFocus = false; 136 this.isConfirmButtonEnabled = false; 137 this.getAccountInfo(); 138 } 139 } 140 141 changeAccountInfo() { 142 HiLog.info(TAG, `changeAccountInfo start`); 143 if (!this.checkCloudPhone(this.inputValue)) { 144 return; 145 } 146 if (!this.commandGetAccountInfo) { 147 this.enabledFocus = true; 148 this.isConfirmButtonEnabled = true; 149 this.showToast($r('app.string.Share_File_Encrypted_Failed')); 150 } 151 let commandGetAccountInfoCallBack = JSON.parse(this.commandGetAccountInfo) as Record<string, object>; 152 HiLog.info(TAG, `commandGetAccountInfo Call Back errorCode: ${commandGetAccountInfoCallBack.errorCode}`); 153 let res = commandGetAccountInfoCallBack.result as Record<string, string>; 154 if (Number(commandGetAccountInfoCallBack.errorCode) === Constants.ERR_CODE_SUCCESS && res?.uid) { 155 this.ownerAccount = res?.uid; 156 this.ownerAccountID = res?.uid; 157 this.connectService.connectServiceShareAbility(Constants.COMMAND_SEARCH_USER_INFO); 158 } else { 159 this.enabledFocus = true; 160 this.isConfirmButtonEnabled = true; 161 this.recordHashUid = ''; 162 storage.setOrCreate('commandGetAccountInfo', ''); 163 if ([ 164 Constants.ERR_CODE_NETWORK_ERROR, 165 Constants.ERR_CODE_CONNECTION_FAIL, 166 Constants.ERR_CODE_CONNECTION_TIME_OUT 167 ].includes(Number(commandGetAccountInfoCallBack.errorCode))) { 168 this.showToast($r('app.string.network_invalid')); 169 return; 170 } 171 this.showToast($r('app.string.Share_File_Encrypted_Failed')); 172 } 173 } 174 175 checkCloudPhone(phone: string): boolean { 176 if (!phone) { 177 return false; 178 } 179 let reg = /^(?:(?:\+|00)86)?1[3456789]\d{9}$/; 180 if (!(reg.test(phone))) { 181 HiLog.info(TAG, `Please enter the phone.`); 182 this.phoneFormatTips = true; 183 this.credentialCallBackMsg = $r('app.string.Share_Tips_Phone_Format'); 184 HiLog.info(TAG, `phoneFormatTips: ${this.phoneFormatTips}`); 185 return false; 186 } 187 reg = /^(0086|\+86)/; 188 let formatPhone = this.inputValue.replace(reg, ''); 189 let cloudPhone = `${Constants.INTERNATIONAL_DIALING_CODE}${formatPhone}`; 190 AppStorage.setOrCreate('cloudPhone', cloudPhone); 191 return true; 192 } 193 194 async beginToGenerateDLPFile() { 195 HiLog.info(TAG, `beginToGenerateDLPFile start`); 196 if (!this.isInputValid()) { 197 this.enabledFocus = true; 198 this.isConfirmButtonEnabled = true; 199 this.textInputGetFocus(); 200 return; 201 } 202 let parameters = this.actionWant?.parameters as Record<string, Array<string>>; 203 let inputUri: string = parameters['ability.params.stream'][0]; 204 let inputFileName: string = this.getFileName(parameters, inputUri); 205 let dlpFileName = decodeURIComponent(inputFileName) + '.dlp'; 206 let inFileFd = getFileFd(inputUri); 207 let srcFileSize: number = await getFileSizeByUri(inputUri); 208 AppStorage.setOrCreate('hiFileSize', srcFileSize); 209 let filePath = getContext(this).filesDir + `/Share/${new Date().getTime()}/`; 210 try { 211 await fs.mkdir(filePath, true); 212 } catch (error) { 213 HiLog.error(TAG, `mkdir failed: ${JSON.stringify(error)}`); 214 } 215 let newFilePath = filePath + dlpFileName; 216 let file: fs.File | undefined; 217 let filePathUri = getFileUriByPath(newFilePath); 218 try { 219 file = fs.openSync(newFilePath, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE); 220 await dlpPermission.generateDLPFile(inFileFd, file.fd, this.dlpProperty); 221 this.showToast($r('app.string.Share_File_Encrypted_Success')); 222 let dstFileSize: number = await getFileSizeByUri(filePathUri); 223 AppStorage.setOrCreate('hiPolicySizeEnc', dstFileSize); 224 AppStorage.setOrCreate('hiCode', 201); 225 sendDlpFileCreateProperties(dlpPermission.AccountType.CLOUD_ACCOUNT); // 201: DLP_2C_FILE_CREATE_EVENT 226 this.backToPages(filePathUri, dlpFileName); 227 HiLog.info(TAG, `beginToGenerateDLPFile success`); 228 } catch (err) { 229 HiLog.error(TAG, `open temp failed: ${JSON.stringify(err)}`); 230 HiLog.info(TAG, `generateDLPFile file failed: ${JSON.stringify(err)}`); 231 storage.setOrCreate('commandSearchUserInfo', ''); 232 if (err.code === Constants.SHARE_FILE_NAME_TOO_LONG) { 233 this.showToast($r('app.string.Share_File_Name_Too_Long')); 234 return; 235 } 236 this.showToast($r('app.string.Share_File_Encrypted_Failed')); 237 this.enabledFocus = true; 238 this.isConfirmButtonEnabled = true; 239 } finally { 240 if (file) { 241 fs.closeSync(file); 242 } 243 } 244 } 245 246 getFileName(parameters: Record<string, Array<string>>, inputUri: string): string { 247 let abilityPickerRecords = parameters['ability.picker.records']; 248 let srcFileMsg: FileMsg = FileUtils.getSuffixFileMsgByUri(inputUri); 249 AppStorage.setOrCreate('hiFileType', srcFileMsg.fileType); 250 let res: string = ''; 251 Object.keys(abilityPickerRecords).forEach(key => { 252 this.generalType = key; 253 res = abilityPickerRecords[key][0]?.['4']; 254 }); 255 if (res === undefined) { 256 res = srcFileMsg.fileName + srcFileMsg.fileType; 257 } 258 return res; 259 } 260 261 showToast(msg: Resource) { 262 promptAction.showToast({ 263 message: msg, 264 duration: Constants.SHARE_SET_TIMEOUT 265 }); 266 } 267 268 backToPages(filePathUri: string, dlpFileName: string) { 269 HiLog.info(TAG, `backToPages start: ${dlpFileName}`); 270 if (this.actionWant && this.actionWant.parameters) { 271 this.actionWant.parameters['ability.params.stream'] = [filePathUri]; 272 let arr: Test[] = [ 273 { 274 '0': 0, 275 '1': 0, 276 '4': dlpFileName 277 } 278 ]; 279 let generalFile: Record<string, Test[]> = {}; 280 generalFile[this.generalType] = arr; 281 this.actionWant.parameters['ability.picker.records'] = generalFile; 282 setTimeout(() => { 283 this.session!.terminateSelfWithResult({ 284 resultCode: 2, 285 want: this.actionWant 286 }); 287 }, Constants.SHARE_SET_TIMEOUT) 288 } 289 } 290 291 isInputValid(): boolean { 292 if (!this.isInputInvalid) { 293 return false; 294 } 295 let credentialCallBack = JSON.parse(this.isInputInvalid) as Record<string, string>; 296 HiLog.info(TAG, `credential Call Back errorCode: ${credentialCallBack.errorCode}`); 297 if (!credentialCallBack.status && Number(credentialCallBack.errorCode) === Constants.ERR_CODE_SUCCESS) { 298 HiLog.info(TAG, `credentialCallBack msg`); 299 let str = this.getExternalResourceString(Constants.DLP_CREDMGR_BUNDLE_NAME, 'entry', 'no_user'); 300 this.credentialCallBackMsg = str.length > 0 ? str : credentialCallBack.msg; 301 this.phoneFormatTips = true; 302 storage.setOrCreate('commandSearchUserInfo', ''); 303 return false; 304 } 305 if (!credentialCallBack.status && [ 306 Constants.ERR_CODE_NETWORK_ERROR, 307 Constants.ERR_CODE_CONNECTION_FAIL, 308 Constants.ERR_CODE_CONNECTION_TIME_OUT 309 ].includes(Number(credentialCallBack.errorCode))) { 310 this.showToast($r('app.string.network_invalid')); 311 storage.setOrCreate('commandSearchUserInfo', ''); 312 return false; 313 } 314 if (!credentialCallBack.status && Number(credentialCallBack.errorCode) !== Constants.ERR_CODE_SUCCESS) { 315 this.showToast($r('app.string.Share_File_Encrypted_Failed')); 316 storage.setOrCreate('commandSearchUserInfo', ''); 317 return false; 318 } 319 let authUserList: AuthUserList[] = [ 320 { 321 'authAccount': credentialCallBack.userIdCipher, 322 'authAccountType': 1, 323 'dlpFileAccess': 1, 324 'permExpiryTime': Date.UTC(9999, 1, 1), 325 } 326 ]; 327 this.dlpProperty = { 328 'ownerAccount': this.ownerAccount, 329 'ownerAccountID': this.ownerAccountID, 330 'ownerAccountType': 1, 331 'authUserList': authUserList, 332 'contactAccount': this.ownerAccount, 333 'offlineAccess': true, 334 } 335 return true; 336 } 337 338 async checkContacts() { 339 let callerBundleName = 'com.ohos.contacts'; 340 try { 341 await getAppId(callerBundleName); 342 this.contactExists = true; 343 } catch { 344 this.contactExists = false; 345 } 346 } 347 348 async getLoginStatus() { 349 HiLog.info(TAG, `get login status start.`); 350 try { 351 await checkNetworkStatus(); 352 } catch { 353 this.showToast($r('app.string.network_invalid')); 354 this.enabledFocus = true; 355 this.isConfirmButtonEnabled = this.inputValue.length > 0; 356 this.isTextInputFocus = true; 357 this.textInputGetFocus(); 358 return 359 } 360 try { 361 let accountInfo = await getOsAccountInfo(); 362 if (accountInfo.distributedInfo.name === 'ohosAnonymousName' && 363 accountInfo.distributedInfo.id === 'ohosAnonymousUid') { 364 this.showUIExtensionForAccountLogin = true; 365 } else { 366 this.isTextInputFocus = true; 367 this.textInputGetFocus(); 368 } 369 } catch (err) { 370 HiLog.error(TAG, `getOsAccountInfo failed: ${JSON.stringify(err)}`); 371 } 372 } 373 374 async getAccountInfo() { 375 HiLog.info(TAG, `get Account Info start`); 376 try { 377 await checkNetworkStatus(); 378 } catch { 379 this.showToast($r('app.string.network_invalid')); 380 this.enabledFocus = true; 381 this.isConfirmButtonEnabled = this.inputValue.length > 0; 382 this.isTextInputFocus = true; 383 this.textInputGetFocus(); 384 return; 385 } 386 try { 387 let accountInfo = await getOsAccountInfo(); 388 if (accountInfo.distributedInfo.name === 'ohosAnonymousName' && 389 accountInfo.distributedInfo.id === 'ohosAnonymousUid') { 390 this.showUIExtensionForAccountLogin = true; 391 return; 392 } 393 if (accountInfo.distributedInfo.id !== this.recordHashUid) { 394 HiLog.info(TAG, `COMMAND_GET_ACCOUNT_INFO start`); 395 this.connectService.connectServiceShareAbility(Constants.COMMAND_GET_ACCOUNT_INFO); 396 this.commandGetAccountInfoFlag = true; 397 this.recordHashUid = accountInfo.distributedInfo.id; 398 return; 399 } else { 400 this.changeAccountInfo(); 401 } 402 } catch (err) { 403 HiLog.error(TAG, `getOsAccountInfo failed: ${JSON.stringify(err)}`); 404 this.showToast($r('app.string.Share_File_Encrypted_Failed')); 405 this.enabledFocus = true; 406 this.isConfirmButtonEnabled = this.inputValue.length > 0; 407 } 408 } 409 410 onLanguageChange() { 411 let str = this.getExternalResourceString(Constants.DLP_CREDMGR_BUNDLE_NAME, 'entry', 'add_users_hint'); 412 if (str.length > 0) { 413 this.placeHolderStr = str; 414 } 415 str = this.getExternalResourceString(Constants.DLP_CREDMGR_BUNDLE_NAME, 'entry', 'no_user'); 416 if (str.length > 0) { 417 this.credentialCallBackMsg = str; 418 } 419 str = this.getExternalResourceString(Constants.DLP_CREDMGR_BUNDLE_NAME, 'entry', 'hmos_version_label'); 420 if (str.length > 0) { 421 this.osVersion = str; 422 } 423 this.getContactPersonString(); 424 } 425 426 subscribeLanguageChange() { 427 emitter.on('onConfigurationUpdate', () => { 428 this.onLanguageChange(); 429 }) 430 } 431 432 getExternalResourceString(bundle: string, module: string, resourceName: string): string { 433 try { 434 let ctx = getContext().createModuleContext(bundle, module); 435 HiLog.info(TAG, 'getExternalResourceString get context from: ' + ctx.applicationInfo.name); 436 let str = ctx.resourceManager.getStringByNameSync(resourceName); 437 return str; 438 } catch (e) { 439 let error = e as BusinessError; 440 HiLog.error(TAG, 'getExternalResourceString error: ' + error.code + ' ' + error.message); 441 return ''; 442 } 443 } 444 445 getContactPersonString() { 446 try { 447 getContext().resourceManager.getStringValue($r('app.string.Share_Contact_Person').id, 448 (error: BusinessError, value: string) => { 449 if (error === undefined || error === null) { 450 this.contactPerson = value; 451 } else { 452 HiLog.error(TAG, `error is ${JSON.stringify(error)}`); 453 } 454 }); 455 } catch (error) { 456 HiLog.error(TAG, `callback getStringValue failed, error ${JSON.stringify(error)}`); 457 } 458 } 459 460 clearHistoryDLPFile() { 461 let pathDir = getContext(this).filesDir + '/Share'; 462 fs.listFile(pathDir).then((filenames: Array<string>) => { 463 HiLog.info(TAG, `listFile succeed`); 464 let filenamesLists = filenames.sort((a, b) => Number(a) - Number(b)); 465 if (filenamesLists.length > Constants.SHARE_TEMP_SAVE_FILE_NUMBER) { 466 let deleteArray = filenamesLists.slice(0, filenamesLists.length - Constants.SHARE_TEMP_SAVE_FILE_NUMBER); 467 deleteArray.forEach((item) => { 468 fs.rmdirSync(pathDir + `/${item}`); 469 }) 470 } 471 }).catch((err: BusinessError) => { 472 HiLog.error(TAG, `list file failed with error message: ${JSON.stringify(err)}`); 473 }); 474 } 475 476 textInputGetFocus() { 477 setTimeout(() => { 478 try { 479 HiLog.info(TAG, `delay requestFocus start`); 480 this.getUIContext().getFocusController().requestFocus('phoneInput'); 481 } catch (error) { 482 HiLog.error(TAG, `requestFocus failed. Cause: ${JSON.stringify(error)}`); 483 } 484 }, Constants.ENCRYPTION_SET_TIMEOUT_TIME); 485 } 486 487 aboutToAppear() { 488 HiLog.info(TAG, `aboutToAppear enter: ${this.showUIExtensionForAccountLogin}`); 489 this.getLoginStatus(); 490 AppStorage.setOrCreate('hiAccountType', dlpPermission.AccountType.CLOUD_ACCOUNT); 491 sendDlpManagerAccountLogin(-1); 492 this.checkContacts(); 493 this.clearHistoryDLPFile(); 494 this.subscribeLanguageChange(); 495 let str = this.getExternalResourceString(Constants.DLP_CREDMGR_BUNDLE_NAME, 'entry', 'add_users_hint'); 496 this.placeHolderStr = str.length > 0 ? str : ''; 497 str = this.getExternalResourceString(Constants.DLP_CREDMGR_BUNDLE_NAME, 'entry', 'hmos_version_label'); 498 this.osVersion = str.length > 0 ? str : ''; 499 this.getContactPersonString(); 500 } 501 502 build() { 503 Stack() { 504 Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Start }) { 505 EditableTitleBar({ 506 leftIconStyle: EditableLeftIconType.Back, 507 title: $r('app.string.Share_Add_Viewable_Users'), 508 contentMargin: this.titlebarMargin, 509 menuItems: [ 510 { 511 value: $r('sys.media.ohos_ic_public_cancel'), 512 isEnabled: true, 513 label: $r('app.string.ban'), 514 action: () => { 515 if (this.session !== undefined) { 516 this.session.terminateSelfWithResult({ 517 'resultCode': 1, 518 }); 519 } 520 } 521 } 522 ], 523 isSaveIconRequired: false, 524 onCancel: () => { 525 if (this.session !== undefined) { 526 this.session.terminateSelfWithResult({ 527 'resultCode': 0, 528 }); 529 } 530 }, 531 }) 532 .constraintSize({ minHeight: Constants.SHARE_TITLE_HEAD_HEIGHT }) 533 .margin({ 534 top: Constants.SHARE_TITLE_HEAD_MARGIN_TOP, 535 }) 536 Scroll() { 537 Column() { 538 Row() { 539 TextInput({ placeholder: this.placeHolderStr, text: this.inputValue }) 540 .id('phoneInput') 541 .padding({ 542 left: SystemUtils.isRTL() ? 543 Constants.SHARE_TEXT_INPUT_CONTENT_PADDING_RIGHT : Constants.SHARE_TEXT_INPUT_CONTENT_PADDING_LEFT, 544 right: SystemUtils.isRTL() ? 545 Constants.SHARE_TEXT_INPUT_CONTENT_PADDING_LEFT : Constants.SHARE_TEXT_INPUT_CONTENT_PADDING_RIGHT 546 }) 547 .enabled(this.enabledFocus) 548 .constraintSize({ minHeight: Constants.SHARE_TEXT_INPUT_HEIGHT }) 549 .focusable(this.isTextInputFocus) 550 .defaultFocus(false) 551 .direction(SystemUtils.isRTL() ? Direction.Rtl : Direction.Ltr) 552 .type(InputType.PhoneNumber) 553 .contentType(ContentType.PHONE_COUNTRY_CODE) 554 .enterKeyType(EnterKeyType.NEW_LINE) 555 .border(this.phoneFormatTips ? 556 { width: Constants.DIALOG_MD_OFFSET, color: $r('sys.color.ohos_id_color_warning') } : { width: 0 }) 557 .onChange((value: string) => { 558 HiLog.info(TAG, `input length: ${value.length}`); 559 this.inputValue = value; 560 this.phoneFormatTips = false; 561 this.isConfirmButtonEnabled = value.length > 0; 562 }) 563 if (this.contactExists) { 564 Column() { 565 SymbolGlyph($r('sys.symbol.person_2')) 566 .fontSize(`${Constants.SYMBOL_GLYPH_FONT_SIZE}vp`) 567 .fontColor(this.enabledFocus ? [$r('sys.color.icon_primary')] : [$r('sys.color.icon_tertiary')]) 568 } 569 .accessibilityText(this.contactPerson) 570 .enabled(this.enabledFocus) 571 .offset({ 572 x: SystemUtils.isRTL() 573 ? Constants.SHARE_CONTACTS_GROUP_OFFSET_X_RTL : Constants.SHARE_CONTACTS_GROUP_OFFSET_X, 574 y: Constants.SHARE_CONTACTS_GROUP_OFFSET_Y 575 }) 576 .onClick(() => { 577 this.isShowSheet = !this.isShowSheet; 578 }) 579 .bindSheet(this.isShowSheet, this.contactsPicker(), { 580 height: SheetSize.LARGE, 581 dragBar: false, 582 showClose: true, 583 onWillDisappear: () => { 584 this.isShowSheet = false; 585 }, 586 backgroundColor: Color.Transparent, 587 blurStyle: BlurStyle.COMPONENT_ULTRA_THICK 588 }) 589 } 590 } 591 592 Text(this.phoneFormatTips ? 593 this.credentialCallBackMsg : $r('app.string.Share_Enter_Mobile_Number', this.osVersion)) 594 .fontColor(this.phoneFormatTips ? 595 $r('sys.color.ohos_id_color_warning') : $r('sys.color.ohos_id_color_text_secondary')) 596 .fontSize($r('sys.float.ohos_id_text_size_body3')) 597 .fontWeight(FontWeight.Regular) 598 .margin({ top: Constants.ENCRYPTION_ADD_STAFF_BORDER_MARGIN_TOP }) 599 .backgroundColor(Color.Transparent) 600 .width(Constants.CONTACTS_PICKER_WIDTH) 601 .padding({ left: Constants.SHARE_TITLE_HEAD_PADDING_LEFT }) 602 } 603 .margin({ left: Constants.SHARE_TEXT_INPUT_MARGIN_LEFT, right: Constants.SHARE_TEXT_INPUT_MARGIN_RIGHT }) 604 } 605 .align(Alignment.TopStart) 606 .constraintSize({ 607 minHeight: `${Constants.SHARE_TEXTAREA_MAX_HEIGHT}vp` 608 }) 609 .padding({ 610 top: Constants.SHARE_TITLE_HEAD_MARGIN_BOTTOM 611 }) 612 613 Column() { 614 Button($r('app.string.Share_Confirms'), { type: ButtonType.Capsule, stateEffect: true }) 615 .enabled(this.isConfirmButtonEnabled) 616 .backgroundColor($r('sys.color.ohos_id_color_text_primary_activated')) 617 .width(Constants.SHARE_BUTTON_WIDTH) 618 .controlSize(ControlSize.NORMAL) 619 .onClick(async () => { 620 this.beginShareEncrypt(); 621 }) 622 } 623 .justifyContent(FlexAlign.Center) 624 .margin({ 625 top: Constants.SHARE_BUTTON_MARGIN_TOP, 626 left: Constants.SHARE_BUTTON_MARGIN_LEFT, 627 right: Constants.SHARE_BUTTON_MARGIN_RIGHT, 628 bottom: Constants.SHARE_BUTTON_PADDING_BOTTOM 629 }) 630 } 631 .width(Constants.SHARE_PAGES_COLUMN_WIDTH) 632 .height(Constants.SHARE_PAGES_COLUMN_HEIGHT) 633 634 if (this.showUIExtensionForAccountLogin) { 635 UIExtensionComponent({ 636 bundleName: 'com.huawei.hmos.dlpcredmgr', 637 abilityName: 'DlpCredAccountAbility', 638 parameters: { 639 'ability.want.params.uiExtensionType': 'sys/commonUI' 640 } 641 }) 642 .id('cloudAccountLoginUI') 643 .onRemoteReady(() => { 644 try { 645 HiLog.info(TAG, `cloudAccountLoginUI requestFocus start`); 646 this.getUIContext().getFocusController().requestFocus('cloudAccountLoginUI'); 647 } catch (error) { 648 HiLog.error(TAG, `requestFocus failed. Cause: ${JSON.stringify(error)}`) 649 } 650 }) 651 .onReceive((data) => { 652 HiLog.info(TAG, `data.status: ${JSON.stringify(data.status)}`); 653 let res = data.result as Record<string, string>; 654 HiLog.info(TAG, `res.code: ${JSON.stringify(res.code)}`); 655 if (data.status) { 656 this.ownerAccount = res?.uid; 657 this.ownerAccountID = res?.uid; 658 let checkCloudPhone = this.checkCloudPhone(this.inputValue); 659 HiLog.info(TAG, `checkCloudPhone: ${checkCloudPhone}`); 660 if (checkCloudPhone) { 661 this.enabledFocus = false; 662 this.isConfirmButtonEnabled = false; 663 this.connectService.connectServiceShareAbility(Constants.COMMAND_SEARCH_USER_INFO); 664 } 665 } else { 666 this.enabledFocus = true; 667 this.isConfirmButtonEnabled = this.inputValue.length > 0; 668 if (['12300001', '1001502005', '1001502009'].includes(res.code.toString())) { 669 this.showToast($r('app.string.network_invalid')); 670 } 671 } 672 this.isTextInputFocus = true; 673 this.textInputGetFocus(); 674 this.showUIExtensionForAccountLogin = false; 675 }) 676 .size({ 677 width: Constants.SHARE_PAGES_COLUMN_WIDTH, height: Constants.SHARE_PAGES_COLUMN_HEIGHT 678 }) 679 } 680 } 681 } 682}