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 */ 15import common from '@ohos.app.ability.common'; 16import display from '@ohos.display'; 17import settings from '@ohos.settings'; 18import UIExtensionContentSession from '@ohos.app.ability.UIExtensionContentSession'; 19import deviceInfo from '@ohos.deviceInfo'; 20import { BusinessError } from '@ohos.base'; 21import { EditableLeftIconType, EditableTitleBar } from '@ohos.arkui.advanced.EditableTitleBar'; 22import mediaQuery from '@ohos.mediaquery'; 23import ConfigurationConstant from '@ohos.app.ability.ConfigurationConstant'; 24import CommonConstants, { FontSizeScale } from '../common/constants/CommonConstants'; 25import { logger } from '../utils/Logger'; 26import { TipsJumpUtils } from '../utils/TipsJumpUtils'; 27import osAccount from '@ohos.account.osAccount'; 28import systemParameterEnhance from '@ohos.systemParameterEnhance'; 29import i18n from '@ohos.i18n'; 30 31const TAG = '[ContinueSwitch_Page] : '; 32let context = getContext(this) as common.UIAbilityContext; 33let localStorage = LocalStorage.getShared(); 34 35interface switchStatus { 36 open: string; 37 close: string; 38} 39 40let switchState: switchStatus = { 41 open: CommonConstants.SWITCH_STATUS_OPEN, 42 close: CommonConstants.SWITCH_STATUS_CLOSE 43} 44 45@Entry 46@Component 47struct ContinueSwitch { 48 @StorageLink('isSwitchOn') isSwitchOn: boolean | undefined = true; 49 @StorageLink('continueSession') continueSession: UIExtensionContentSession | undefined = undefined; 50 @State title: string = ''; 51 @State screenHeight: number = 0; 52 @State screenWidth: number = 0; 53 @State shortSideSize: number = 0; 54 @State imageAnimatorHeight: number = this.getImageAnimatorHeight(); 55 @State imageAnimatorWidth: number = this.getImageAnimatorWidth(); 56 @State textWidth: number = 0; 57 @State gapLength: number = 0; 58 @State isShow: boolean = false; 59 @State is2in1: boolean = false; 60 @State portraitFunc: mediaQuery.MediaQueryResult | void | null = null; 61 @State isVideoVisible: Visibility = Visibility.Hidden; 62 @State contentHeight: number = 0; 63 @State imageArray: Array<ImageFrameInfo> = []; 64 @State animationState: AnimationStatus = AnimationStatus.Running; 65 @State reverse: boolean = false; 66 @State iterations: number = -1; 67 @State isEnabled: boolean = true; 68 @State isShowBack: boolean = true; 69 @State isAnimatorDone: boolean = false; 70 @StorageProp('currentFontSizeScale') @Watch('onFontSizeScaleChange') fontSizeScale: number = 1; 71 @State phoneSwitchTextTopMargin: string = '17vp'; 72 @State phoneSwitchTextBottomMargin: string = '18vp'; 73 private listener: mediaQuery.MediaQueryListener = mediaQuery.matchMediaSync('(dark-mode:true)'); 74 private extContext?: common.UIExtensionContext; 75 private scroller: Scroller = new Scroller(); 76 private learnMore: ResourceStr = $r('app.string.learn_more'); 77 private continueDesc: ResourceStr = $r('app.string.continue_desc_text', ''); 78 private accountManager: osAccount.AccountManager = osAccount.getAccountManager(); 79 private startReason?: string = ''; 80 81 onPortrait(mediaQueryResult: mediaQuery.MediaQueryResult): void { 82 logger.info(`${TAG} 'onPortrait in`); 83 if (mediaQueryResult.matches as boolean) { 84 this.extContext?.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_DARK); 85 } else { 86 this.extContext?.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT); 87 } 88 } 89 90 onFontSizeScaleChange(): void { 91 logger.info(`${TAG} onFontSizeScaleChange`); 92 this.phoneSwitchTextTopMargin = this.UpdateMarginBasedOnFontSize(17, this.fontSizeScale); 93 this.phoneSwitchTextBottomMargin = this.UpdateMarginBasedOnFontSize(18, this.fontSizeScale); 94 } 95 96 /** 97 * Update the margins of the switch list according to the font size. 98 */ 99 public UpdateMarginBasedOnFontSize(fontFp: number, fontSizeScale: number): string { 100 logger.info(`${TAG} getlistSpace, fontSizeScale: ${fontSizeScale} ; fontFp: ${fontFp}`); 101 switch (fontSizeScale) { 102 case FontSizeScale.XXL1: 103 return '16vp'; 104 case FontSizeScale.XXL2: 105 return '20vp'; 106 case FontSizeScale.XXL3: 107 return '24vp'; 108 default: 109 return `${fontFp}vp`; 110 } 111 } 112 113 /** 114 * Initialize the switch list spacing size 115 */ 116 public phoneSwitchTextMarginInit(): void { 117 let fontSizeScale = parseFloat(systemParameterEnhance.getSync(CommonConstants.FONT_SIZE_SCALE_PARAM, '1')); 118 this.phoneSwitchTextTopMargin = this.UpdateMarginBasedOnFontSize(17, fontSizeScale); 119 this.phoneSwitchTextBottomMargin = this.UpdateMarginBasedOnFontSize(18, fontSizeScale); 120 } 121 122 getStringSync(): void { 123 logger.info(`${TAG} getStringSync in`); 124 try { 125 context.resourceManager.getStringValue($r('app.string.continue_title') 126 .id, (error: BusinessError, value: string) => { 127 if (error != null) { 128 logger.error(TAG + 'error is ' + error); 129 } else { 130 this.title = value; 131 logger.info(`${TAG} <aboutToAppear> this.title : ${this.title}`); 132 } 133 }) 134 } catch (error) { 135 let code: number = (error as BusinessError).code; 136 let message: string = (error as BusinessError).message; 137 logger.error(`${TAG} callback getStringValue failed,error code: ${code},message: ${message}.`); 138 } 139 } 140 141 getImageArray(): void { 142 logger.info(`${TAG} getImageArray in`); 143 for (let i = 0; i <= CommonConstants.IMAGE_COUNT; ++i) { 144 this.imageArray.push({ 145 src: $r(`app.media.continue_${i}`), 146 duration: (i == CommonConstants.IMAGE_COUNT) ? CommonConstants.IMG_ANIMATOR_OVER_DURATION 147 : CommonConstants.IMG_ANIMATOR_NORMAL_DURATION 148 }) 149 } 150 } 151 152 getGapLength(): void { 153 logger.info(`${TAG} getGapLength in, deviceInfo.deviceType : ${deviceInfo.deviceType}`); 154 if (deviceInfo.deviceType == 'phone') { 155 this.gapLength = CommonConstants.GENERAL_PHONE_GAP_LENGTH; 156 } else if (deviceInfo.deviceType == '2in1' || deviceInfo.deviceType == 'tablet') { 157 this.gapLength = CommonConstants.PC_PAD_GAP_LENGTH; 158 } 159 logger.info(`${TAG} this.gapLength : ${this.gapLength}`); 160 } 161 162 getForegroundOsAccountLocalId(): void { 163 logger.info(`${TAG} getForegroundOsAccountLocalId in`); 164 try { 165 this.accountManager.getForegroundOsAccountLocalId().then((localId: number) => { 166 logger.info(`${TAG} getForegroundOsAccountLocalId, localId: ${localId}`); 167 this.getAccountInfo(localId); 168 }).catch((err: BusinessError) => { 169 logger.error(`${TAG} getForegroundOsAccountLocalId errCode: ${err?.code}`); 170 }); 171 } catch (err) { 172 logger.error(`${TAG} getForegroundOsAccountLocalId exception: ${err?.message}`); 173 } 174 } 175 176 getAccountInfo(localId: number): void { 177 logger.info(`${TAG} getAccountInfo in`); 178 try { 179 this.accountManager.queryOsAccountById(localId).then((accountInfo: osAccount.OsAccountInfo) => { 180 logger.info(`${TAG} queryOsAccountById, accountInfo.type: ${accountInfo.type}`); 181 if (accountInfo.type === osAccount.OsAccountType.PRIVATE) { 182 let status: boolean = settings.setValueSync(context, CommonConstants.CONTINUE_SWITCH_KEY, switchState.close, 183 settings.domainName.USER_SECURITY); 184 this.isSwitchOn = false; 185 this.isEnabled = false; 186 logger.info(`${TAG} set value isSuccess : status = ${status}; set:Continue_Switch_Status is 0`); 187 } 188 }).catch((err: BusinessError) => { 189 logger.error(`${TAG} queryOsAccountById errCode: ${err?.code}`); 190 }); 191 } catch (err) { 192 logger.error(`${TAG} queryOsAccountById exception: ${err?.message}`); 193 } 194 } 195 196 onPageShow() { 197 logger.info(`${TAG} onPageShow in`); 198 this.getGapLength(); 199 display.getAllDisplays((err, data) => { 200 this.screenWidth = px2vp(data[0].width); 201 this.screenHeight = px2vp(data[0].height); 202 this.contentHeight = this.screenHeight; 203 logger.info(`${TAG} screenWidth = ${this.screenWidth}; screenHeight = ${this.screenHeight}`); 204 }) 205 this.is2in1 = deviceInfo.deviceType === '2in1' ? true : false; 206 } 207 208 aboutToAppear() { 209 logger.info(`${TAG} aboutToAppear in`); 210 // Switch State Initialization 211 let value = settings.getValueSync(context, CommonConstants.CONTINUE_SWITCH_KEY, switchState.open, 212 settings.domainName.USER_SECURITY); 213 this.isSwitchOn = value != switchState.close ? true : false; 214 logger.info(`${TAG} <aboutToAppear> this.isSwitchOn : ${this.isSwitchOn}; value: ${value}`); 215 216 AppStorage.setOrCreate('isSwitchOn', this.isSwitchOn); 217 logger.info(`${TAG} AppStorage.get<boolean>(isSwitchOn) : ${AppStorage.get<boolean>('isSwitchOn')}`); 218 219 if (this.isSwitchOn) { 220 let status: boolean = settings.setValueSync(context, CommonConstants.CONTINUE_SWITCH_KEY, switchState.open, 221 settings.domainName.USER_SECURITY); 222 logger.info(`${TAG} set value success :${status}; set:Continue_Switch_Status is 1`); 223 } 224 225 this.getStringSync(); 226 this.getImageArray(); 227 this.getForegroundOsAccountLocalId(); 228 this.listener.on('change', (mediaQueryResult: mediaQuery.MediaQueryResult) => { 229 this.onPortrait(mediaQueryResult); 230 }) 231 this.extContext = localStorage.get<common.UIExtensionContext>('context'); 232 this.startReason = AppStorage.get<string>('startReason'); 233 this.isShowBack = AppStorage.get<boolean>('isShowBack') ?? true; 234 logger.info(`${TAG} aboutToAppear: startReason is ${this.startReason}, isShowBack: ${this.isShowBack}`); 235 if (this.isPhone()) { 236 this.checkFoldBackButton(); 237 } 238 this.checkPcPadBackButton(); 239 this.phoneSwitchTextMarginInit(); 240 setTimeout(() => { 241 this.isAnimatorDone = true; 242 }, 20) 243 } 244 245 aboutToDisappear() { 246 logger.info(`${TAG} aboutToDisappear in`); 247 } 248 249 onBackPress() { 250 logger.info(`${TAG} onBackPress in`); 251 } 252 253 @Builder 254 NormalRootContent() { 255 this.titleBar(); 256 this.ContentBuilder(); 257 } 258 259 @Builder 260 SearchRootContent() { 261 NavDestination() { 262 this.ContentBuilder(); 263 } 264 .hideTitleBar(false) 265 .title(this.title) 266 .backgroundColor($r('sys.color.ohos_id_color_titlebar_sub_bg')) 267 } 268 269 @Builder 270 titleBar() { 271 Column() { 272 EditableTitleBar({ 273 leftIconStyle: EditableLeftIconType.Back, 274 title: $r('app.string.continue_title'), 275 isSaveIconRequired: false, 276 onCancel: () => { 277 if (this.continueSession) { 278 this.continueSession.sendData({ 'action': 'pop' }) 279 } else { 280 logger.error(`${TAG} continueSession is undefined`); 281 } 282 } 283 }) 284 } 285 } 286 287 @Builder 288 ContentBuilder() { 289 Scroll(this.scroller) { 290 Column() { 291 ImageAnimator() 292 .images(this.imageArray) 293 .state(this.animationState) 294 .reverse(this.reverse) 295 .fillMode(this.iterations) 296 .iterations(this.iterations) 297 .width(this.imageAnimatorWidth) 298 .height(this.imageAnimatorHeight) 299 .onStart(() => { 300 logger.info(`${TAG} ImageAnimator Start`); 301 }) 302 .onFinish(() => { 303 logger.info(`${TAG} ImageAnimator Finish`); 304 }) 305 306 Text() { 307 Span(this.continueDesc) 308 .fontFamily('HarmonyHeiTi') 309 .fontSize($r('sys.float.ohos_id_text_size_body2')) 310 .fontColor($r('sys.color.ohos_id_color_text_secondary')) 311 .fontWeight(FontWeight.Regular) 312 Span(this.learnMore) 313 .fontFamily('HarmonyHeiTi') 314 .fontSize($r('sys.float.ohos_id_text_size_body2')) 315 .fontColor($r('sys.color.ohos_id_color_text_primary_activated')) 316 .fontWeight(FontWeight.Medium) 317 .onClick(() => { 318 TipsJumpUtils.jumpTips(getContext(this) as common.UIAbilityContext, CommonConstants.FUN_NUM, 319 CommonConstants.TIPS_TYPE); 320 }) 321 } 322 .margin({ 323 bottom: CommonConstants.CONTINUE_DESC_TEXT_MARGIN_BOTTOM, 324 top: CommonConstants.CONTINUE_DESC_TEXT_MARGIN_TOP 325 }) 326 .textAlign(TextAlign.Center) 327 .width('100%') 328 329 Column() { 330 Flex({ 331 direction: FlexDirection.Row, 332 justifyContent: FlexAlign.SpaceBetween, 333 alignItems: ItemAlign.Center 334 }) { 335 Text($r('app.string.continue_title')) 336 .fontSize($r('sys.float.ohos_id_text_size_sub_title2')) 337 .fontWeight(FontWeight.Medium) 338 .fontColor($r('sys.color.ohos_id_color_text_primary')) 339 .accessibilityLevel('no') 340 .padding({ 341 top: this.is2in1 ? CommonConstants.ITEM_LIST_PADDING_TOP_PC : this.phoneSwitchTextTopMargin, 342 bottom: this.is2in1 ? CommonConstants.ITEM_LIST_PADDING_BOTTOM_PC : this.phoneSwitchTextBottomMargin 343 }) 344 345 Toggle({ type: ToggleType.Switch, isOn: this.isSwitchOn }) 346 .width(CommonConstants.CONTINUE_SWITCH_WIDTH) 347 .height(CommonConstants.CONTINUE_SWITCH_HEIGHT) 348 .hoverEffect(HoverEffect.None) 349 .enabled(this.isEnabled) 350 .onChange((isOn: boolean) => { 351 logger.info(`${TAG} isOn: ${isOn}`); 352 this.isSwitchOn = isOn; 353 AppStorage.setAndLink('isSwitchOn', isOn); 354 if (isOn) { 355 let status: boolean = settings.setValueSync(context, CommonConstants.CONTINUE_SWITCH_KEY, 356 switchState.open, settings.domainName.USER_SECURITY); 357 logger.info(`${TAG} is set success :${status}; set:Continue_Switch_Status is open`); 358 } else { 359 let status: boolean = settings.setValueSync(context, CommonConstants.CONTINUE_SWITCH_KEY, 360 switchState.close, settings.domainName.USER_SECURITY); 361 logger.info(`${TAG} is set success :${status}; set:Continue_Switch_Status is close`); 362 } 363 }) 364 } 365 .width('100%') 366 .padding({ 367 left: CommonConstants.TEXT_LIST_ALIGN_DISTANCE, 368 right: CommonConstants.TEXT_LIST_ALIGN_DISTANCE 369 }) 370 .backgroundColor($r('sys.color.ohos_id_color_list_card_bg')) 371 .borderRadius(this.is2in1 ? CommonConstants.PC_BORDER_RADIUS : CommonConstants.NON_PC_BORDER_RADIUS) 372 .accessibilityText(this.title) 373 } 374 .width('100%') 375 .constraintSize({ 376 minHeight: CommonConstants.PC_LIST_HEIGHT 377 }) 378 379 Column() { 380 Flex({ 381 direction: FlexDirection.Row, 382 justifyContent: FlexAlign.Start, 383 alignItems: ItemAlign.Center 384 }) { 385 SymbolGlyph($r('sys.symbol.info_circle_fill')) 386 .fontWeight(FontWeight.Medium) 387 .fontSize(CommonConstants.SYMBOL_INFO_CIRCLE) 388 .fontColor([$r('sys.color.ohos_id_color_activated')]) 389 .margin(this.isMirrorLanguages() ? { left: CommonConstants.SYMBOL_MARGIN_RIGHT } : 390 { right: CommonConstants.SYMBOL_MARGIN_RIGHT }) 391 .width(CommonConstants.SYMBOL_INFO_CIRCLE) 392 .height(CommonConstants.SYMBOL_INFO_CIRCLE) 393 .accessibilityLevel('no') 394 395 Text($r('app.string.update_version_prompt')) 396 .fontSize($r('sys.float.ohos_id_text_size_body3')) 397 .fontWeight(FontWeight.Medium) 398 .fontColor($r('sys.color.ohos_id_color_text_primary')) 399 .textAlign(TextAlign.Start) 400 .lineHeight(-1) 401 } 402 .margin({ top: CommonConstants.UPDATE_PROMPT_MARGIN_TOP }) 403 } 404 .padding({ 405 left: CommonConstants.TEXT_LIST_ALIGN_DISTANCE, 406 right: CommonConstants.TEXT_LIST_ALIGN_DISTANCE 407 }) 408 409 Column() { 410 Row() { 411 Text($r('app.string.continue_privacy_text')) 412 .fontSize($r('sys.float.ohos_id_text_size_body3')) 413 .fontWeight(FontWeight.Regular) 414 .margin({ top: CommonConstants.CONTINUE_PRIVACY_TEXT_MARGIN_TOP }) 415 .fontColor($r('sys.color.ohos_id_color_text_secondary')) 416 .textAlign(TextAlign.Start) 417 .width('100%') 418 .lineHeight(this.isTibetanLanguages() ? 19 : 0) 419 } 420 .padding({ 421 left: CommonConstants.TEXT_LIST_ALIGN_DISTANCE, 422 right: CommonConstants.TEXT_LIST_ALIGN_DISTANCE 423 }) 424 }.width('100%') 425 426 } 427 .width('100%') 428 .padding({ left: this.gapLength, right: this.gapLength }) 429 .margin({ bottom: this.contentHeight * 0.09 }) 430 .backgroundColor($r('sys.color.ohos_id_color_sub_background')) 431 .visibility(this.getContentVisibility()) 432 } 433 .width('100%') 434 .height(this.screenHeight) 435 .scrollable(ScrollDirection.Vertical) 436 .scrollBar(BarState.Off) 437 .align(Alignment.TopStart) 438 .friction(0.6) 439 .edgeEffect(EdgeEffect.Spring) 440 .onScrollEdge(() => { 441 logger.info('To the edge'); 442 }) 443 .onScrollStop(() => { 444 logger.info('Scroll Stop'); 445 }) 446 .onAreaChange((oldArea: Area, newArea: Area) => { 447 logger.info(`${TAG} Scroll, oldArea.height = ${oldArea.height}, newArea.height = ${newArea.height}`); 448 }) 449 } 450 451 build() { 452 Column() { 453 if (this.isShowBack) { 454 this.NormalRootContent(); 455 } else { 456 this.SearchRootContent(); 457 } 458 } 459 .width('100%') 460 .height('100%') 461 .backgroundColor($r('sys.color.ohos_id_color_sub_background')) 462 .onAreaChange((oldArea: Area, newArea: Area) => { 463 logger.info(`${TAG} build column , oldArea.height = ${oldArea.height}, newArea.height = ${newArea.height}`); 464 logger.info(`${TAG} this.shortSideSize = ${this.shortSideSize}, this.imageAnimatorWidth = 465 ${this.imageAnimatorWidth}, this.imageAnimatorHeight = ${this.imageAnimatorHeight}`); 466 }) 467 } 468 469 private getContentVisibility(): Visibility { 470 return (this.imageAnimatorWidth !== 0 && this.isAnimatorDone) ? Visibility.Visible : Visibility.Hidden; 471 } 472 473 private getImageAnimatorHeight(): number { 474 if (deviceInfo.deviceType === 'phone') { 475 return CommonConstants.ANIMATOR_HEIGHT_PHONE; 476 } else if (deviceInfo.deviceType === '2in1') { 477 return CommonConstants.ANIMATOR_HEIGHT_PC; 478 } else if (deviceInfo.deviceType === 'tablet') { 479 return CommonConstants.ANIMATOR_HEIGHT_PAD; 480 } 481 return CommonConstants.ANIMATOR_HEIGHT_PHONE; 482 } 483 484 private getImageAnimatorWidth(): number { 485 if (deviceInfo.deviceType === 'phone') { 486 return CommonConstants.ANIMATOR_WIDTH_PHONE; 487 } else if (deviceInfo.deviceType === '2in1') { 488 return CommonConstants.ANIMATOR_WIDTH_PC; 489 } else if (deviceInfo.deviceType === 'tablet') { 490 return CommonConstants.ANIMATOR_WIDTH_PAD; 491 } 492 return CommonConstants.ANIMATOR_WIDTH_PHONE; 493 } 494 495 private checkPcPadBackButton(): void { 496 logger.info(`${TAG} checkPcPadBackButton in`); 497 if (this.startReason === 'from_search') { 498 if (deviceInfo.deviceType === '2in1' || deviceInfo.deviceType === 'tablet') { 499 this.isShowBack = false; 500 } 501 } 502 } 503 504 private isPhone(): boolean { 505 logger.info(`${TAG} isPhone in`); 506 return (deviceInfo.deviceType === 'phone' || deviceInfo.deviceType === 'default'); 507 } 508 509 private refreshFoldStatus(foldStatus: display.FoldStatus): void { 510 logger.info(`${TAG} refreshFoldStatus in. foldStatus: ${foldStatus}. startReason: ${this.startReason}`); 511 if (this.startReason === 'from_search') { 512 if (foldStatus === display.FoldStatus.FOLD_STATUS_FOLDED) { 513 this.isShowBack = true; 514 logger.info(`${TAG} foldStatus: ${foldStatus}. this.isShowBack: ${this.isShowBack}`); 515 } else { 516 this.isShowBack = false; 517 logger.info(`${TAG} foldStatus: ${foldStatus}. this.isShowBack: ${this.isShowBack}`); 518 } 519 } else { 520 this.isShowBack = true; 521 logger.info(`${TAG} startReason: ${this.startReason}. this.isShowBack: ${this.isShowBack}`); 522 } 523 } 524 525 private checkFoldBackButton(): void { 526 logger.info(`${TAG} checkFoldBackButton in`); 527 if (display.isFoldable()) { 528 try { 529 display.on('foldStatusChange', (foldStatus: display.FoldStatus) => { 530 let foldStatusValue = foldStatus.valueOf(); 531 logger.info(`${TAG} checkFoldBackButton: foldStatusValue is ${foldStatusValue}`); 532 this.refreshFoldStatus(foldStatusValue); 533 }) 534 let data: display.FoldStatus = display.getFoldStatus(); 535 this.refreshFoldStatus(data); 536 } catch (err) { 537 logger.error(`${TAG} Register failed. exception: ${err.message}`); 538 } 539 } 540 } 541 542 private isMirrorLanguages(): boolean { 543 logger.info(`${TAG} isMirrorLanguages in`); 544 let locale = new Intl.Locale(i18n.System.getSystemLanguage()).toString(); 545 return CommonConstants.MIRROR_LANGUAGES.includes(locale); 546 } 547 548 private isTibetanLanguages(): boolean { 549 logger.info(`${TAG} isTibetanLanguages in`); 550 let locale = new Intl.Locale(i18n.System.getSystemLanguage()).toString(); 551 logger.info(`${TAG} isTibetanLanguages: ${locale}`); 552 return CommonConstants.TIBETAN_LANGUAGES.includes(locale); 553 } 554}