180922886Sopenharmony_ci/* 280922886Sopenharmony_ci * Copyright (c) 2023-2024 Huawei Device Co., Ltd. 380922886Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 480922886Sopenharmony_ci * you may not use this file except in compliance with the License. 580922886Sopenharmony_ci * You may obtain a copy of the License at 680922886Sopenharmony_ci * 780922886Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 880922886Sopenharmony_ci * 980922886Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1080922886Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1180922886Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1280922886Sopenharmony_ci * See the License for the specific language governing permissions and 1380922886Sopenharmony_ci * limitations under the License. 1480922886Sopenharmony_ci */ 1580922886Sopenharmony_ci 1680922886Sopenharmony_ciconst TAG = 'avcastpicker_component '; 1780922886Sopenharmony_ci 1880922886Sopenharmony_ci/** 1980922886Sopenharmony_ci * Definition of av cast picker state. 2080922886Sopenharmony_ci */ 2180922886Sopenharmony_ciexport enum AVCastPickerState { 2280922886Sopenharmony_ci /** 2380922886Sopenharmony_ci * The picker starts showing. 2480922886Sopenharmony_ci */ 2580922886Sopenharmony_ci STATE_APPEARING, 2680922886Sopenharmony_ci 2780922886Sopenharmony_ci /** 2880922886Sopenharmony_ci * The picker finishes presenting. 2980922886Sopenharmony_ci */ 3080922886Sopenharmony_ci STATE_DISAPPEARING 3180922886Sopenharmony_ci} 3280922886Sopenharmony_ci 3380922886Sopenharmony_ci/** 3480922886Sopenharmony_ci * Definition of av cast picker state. 3580922886Sopenharmony_ci */ 3680922886Sopenharmony_ciexport enum AVCastPickerStyle { 3780922886Sopenharmony_ci /** 3880922886Sopenharmony_ci * The picker shows in a panel style. 3980922886Sopenharmony_ci */ 4080922886Sopenharmony_ci STYLE_PANEL, 4180922886Sopenharmony_ci 4280922886Sopenharmony_ci /** 4380922886Sopenharmony_ci * The picker shows in a menu style. 4480922886Sopenharmony_ci */ 4580922886Sopenharmony_ci STYLE_MENU 4680922886Sopenharmony_ci} 4780922886Sopenharmony_ci 4880922886Sopenharmony_cienum DeviceSource { 4980922886Sopenharmony_ci /** 5080922886Sopenharmony_ci * local device 5180922886Sopenharmony_ci */ 5280922886Sopenharmony_ci LOCAL, 5380922886Sopenharmony_ci 5480922886Sopenharmony_ci /** 5580922886Sopenharmony_ci * cast device 5680922886Sopenharmony_ci */ 5780922886Sopenharmony_ci CAST 5880922886Sopenharmony_ci} 5980922886Sopenharmony_ci 6080922886Sopenharmony_cienum ConfigurationColorMode { 6180922886Sopenharmony_ci /** 6280922886Sopenharmony_ci * the color mode is not set. 6380922886Sopenharmony_ci */ 6480922886Sopenharmony_ci COLOR_MODE_NOT_SET = -1, 6580922886Sopenharmony_ci 6680922886Sopenharmony_ci /** 6780922886Sopenharmony_ci * Dark mode. 6880922886Sopenharmony_ci */ 6980922886Sopenharmony_ci COLOR_MODE_DARK = 0, 7080922886Sopenharmony_ci 7180922886Sopenharmony_ci /** 7280922886Sopenharmony_ci * Light mode. 7380922886Sopenharmony_ci */ 7480922886Sopenharmony_ci COLOR_MODE_LIGHT = 1 7580922886Sopenharmony_ci} 7680922886Sopenharmony_ci 7780922886Sopenharmony_cienum AVCastPickerColorMode { 7880922886Sopenharmony_ci /** 7980922886Sopenharmony_ci * the color mode of picker is not set. 8080922886Sopenharmony_ci */ 8180922886Sopenharmony_ci AUTO = 0, 8280922886Sopenharmony_ci 8380922886Sopenharmony_ci /** 8480922886Sopenharmony_ci * Dark mode of picker. 8580922886Sopenharmony_ci */ 8680922886Sopenharmony_ci DARK = 1, 8780922886Sopenharmony_ci 8880922886Sopenharmony_ci /** 8980922886Sopenharmony_ci * Light mode of picker. 9080922886Sopenharmony_ci */ 9180922886Sopenharmony_ci LIGHT = 2 9280922886Sopenharmony_ci} 9380922886Sopenharmony_ci 9480922886Sopenharmony_ci/** 9580922886Sopenharmony_ci * menuItem device info 9680922886Sopenharmony_ci */ 9780922886Sopenharmony_ciexport interface AVCastPickerDeviceInfo { 9880922886Sopenharmony_ci deviceId: number | String, 9980922886Sopenharmony_ci deviceType: number, 10080922886Sopenharmony_ci deviceName: string, 10180922886Sopenharmony_ci deviceIconName: string, 10280922886Sopenharmony_ci isConnected: boolean, 10380922886Sopenharmony_ci selectedIconName: string, 10480922886Sopenharmony_ci deviceSource: DeviceSource 10580922886Sopenharmony_ci} 10680922886Sopenharmony_ci 10780922886Sopenharmony_ci@Component 10880922886Sopenharmony_ciexport struct AVCastPicker { 10980922886Sopenharmony_ci /** 11080922886Sopenharmony_ci * Assigns the color of picker component at normal state. 11180922886Sopenharmony_ci */ 11280922886Sopenharmony_ci @State normalColor: Color | number | string | undefined = undefined; 11380922886Sopenharmony_ci 11480922886Sopenharmony_ci /** 11580922886Sopenharmony_ci * Assigns the color of picker component at active state. 11680922886Sopenharmony_ci */ 11780922886Sopenharmony_ci @State activeColor: Color | number | string | undefined = undefined; 11880922886Sopenharmony_ci 11980922886Sopenharmony_ci /** 12080922886Sopenharmony_ci * Definition of color mode of picker. 12180922886Sopenharmony_ci */ 12280922886Sopenharmony_ci @State colorMode: AVCastPickerColorMode = AVCastPickerColorMode.AUTO; 12380922886Sopenharmony_ci 12480922886Sopenharmony_ci /** 12580922886Sopenharmony_ci * The device that is displayed in the menu. 12680922886Sopenharmony_ci */ 12780922886Sopenharmony_ci @State deviceList: Array<AVCastPickerDeviceInfo> = []; 12880922886Sopenharmony_ci 12980922886Sopenharmony_ci /** 13080922886Sopenharmony_ci * Session type transferred by the application. 13180922886Sopenharmony_ci */ 13280922886Sopenharmony_ci @State sessionType: string = 'audio'; 13380922886Sopenharmony_ci 13480922886Sopenharmony_ci /** 13580922886Sopenharmony_ci * Display form of application transfer. 13680922886Sopenharmony_ci */ 13780922886Sopenharmony_ci @State pickerStyle: AVCastPickerStyle = AVCastPickerStyle.STYLE_PANEL; 13880922886Sopenharmony_ci 13980922886Sopenharmony_ci /** 14080922886Sopenharmony_ci * Display form mediaController. 14180922886Sopenharmony_ci */ 14280922886Sopenharmony_ci @State pickerStyleFromMediaController: AVCastPickerStyle = AVCastPickerStyle.STYLE_PANEL; 14380922886Sopenharmony_ci 14480922886Sopenharmony_ci /** 14580922886Sopenharmony_ci * Whether to display the menu. 14680922886Sopenharmony_ci */ 14780922886Sopenharmony_ci @State@Watch('MenuStateChange') isMenuShow: boolean = false; 14880922886Sopenharmony_ci 14980922886Sopenharmony_ci /** 15080922886Sopenharmony_ci * Touch item index. 15180922886Sopenharmony_ci */ 15280922886Sopenharmony_ci @State touchMenuItemIndex: number = -1; 15380922886Sopenharmony_ci 15480922886Sopenharmony_ci /** 15580922886Sopenharmony_ci * Picker state change callback. 15680922886Sopenharmony_ci */ 15780922886Sopenharmony_ci private onStateChange?: (state: AVCastPickerState) => void; 15880922886Sopenharmony_ci 15980922886Sopenharmony_ci /** 16080922886Sopenharmony_ci * UIExtensionProxy. 16180922886Sopenharmony_ci */ 16280922886Sopenharmony_ci private extensionProxy: UIExtensionProxy | null = null; 16380922886Sopenharmony_ci 16480922886Sopenharmony_ci private pickerClickTime: number = -1; 16580922886Sopenharmony_ci 16680922886Sopenharmony_ci /** 16780922886Sopenharmony_ci * Custom builder from application. 16880922886Sopenharmony_ci */ 16980922886Sopenharmony_ci @BuilderParam customPicker: (() => void) 17080922886Sopenharmony_ci 17180922886Sopenharmony_ci /** 17280922886Sopenharmony_ci * Configuration color mode. 17380922886Sopenharmony_ci */ 17480922886Sopenharmony_ci @State configurationColorMode: number = ConfigurationColorMode.COLOR_MODE_NOT_SET; 17580922886Sopenharmony_ci 17680922886Sopenharmony_ci @State deviceInfoType: string = ''; 17780922886Sopenharmony_ci 17880922886Sopenharmony_ci /** 17980922886Sopenharmony_ci * Max Font and graphic magnification. 18080922886Sopenharmony_ci */ 18180922886Sopenharmony_ci private maxFonSizeScale: number = 2; 18280922886Sopenharmony_ci 18380922886Sopenharmony_ci /** 18480922886Sopenharmony_ci * Accessibility Strings 18580922886Sopenharmony_ci */ 18680922886Sopenharmony_ci @State accessibilityConnectedStr: string = '已连接'; 18780922886Sopenharmony_ci @State accessibilityAudioControlStr: string = '音视频投播'; 18880922886Sopenharmony_ci 18980922886Sopenharmony_ci MenuStateChange() { 19080922886Sopenharmony_ci if (this.extensionProxy != null) { 19180922886Sopenharmony_ci this.extensionProxy.send({ 'isMenuShow': this.isMenuShow }); 19280922886Sopenharmony_ci } 19380922886Sopenharmony_ci } 19480922886Sopenharmony_ci 19580922886Sopenharmony_ci build() { 19680922886Sopenharmony_ci Column() { 19780922886Sopenharmony_ci if (this.customPicker === undefined) { 19880922886Sopenharmony_ci this.buildDefaultPicker(false); 19980922886Sopenharmony_ci } else { 20080922886Sopenharmony_ci this.buildCustomPicker(); 20180922886Sopenharmony_ci } 20280922886Sopenharmony_ci }.size({width: '100%', height: '100%'}) 20380922886Sopenharmony_ci } 20480922886Sopenharmony_ci 20580922886Sopenharmony_ci @Builder 20680922886Sopenharmony_ci buildIcon(item: AVCastPickerDeviceInfo, isSelected: boolean): void { 20780922886Sopenharmony_ci if (this.deviceInfoType === 'true') { 20880922886Sopenharmony_ci SymbolGlyph(!isSelected ? $r(item.deviceIconName) : $r(item.selectedIconName)) 20980922886Sopenharmony_ci .fontSize('24vp') 21080922886Sopenharmony_ci .fontColor((isSelected && this.configurationColorMode !== ConfigurationColorMode.COLOR_MODE_DARK) ? 21180922886Sopenharmony_ci [$r('sys.color.comp_background_emphasize')] : [$r('sys.color.icon_primary')]) 21280922886Sopenharmony_ci .renderingStrategy(2) 21380922886Sopenharmony_ci } else { 21480922886Sopenharmony_ci Image(!isSelected ? $r(item.deviceIconName) : $r(item.selectedIconName)) 21580922886Sopenharmony_ci .width(24) 21680922886Sopenharmony_ci .height(24) 21780922886Sopenharmony_ci .fillColor((isSelected && this.configurationColorMode !== ConfigurationColorMode.COLOR_MODE_DARK) ? 21880922886Sopenharmony_ci $r('sys.color.comp_background_emphasize') : $r('sys.color.icon_primary')) 21980922886Sopenharmony_ci } 22080922886Sopenharmony_ci } 22180922886Sopenharmony_ci 22280922886Sopenharmony_ci @Builder 22380922886Sopenharmony_ci deviceMenu() { 22480922886Sopenharmony_ci Column() { 22580922886Sopenharmony_ci ForEach(this.deviceList, (item: AVCastPickerDeviceInfo, index) => { 22680922886Sopenharmony_ci Flex({ 22780922886Sopenharmony_ci direction: FlexDirection.Column, 22880922886Sopenharmony_ci justifyContent: FlexAlign.SpaceBetween, 22980922886Sopenharmony_ci alignItems: ItemAlign.End 23080922886Sopenharmony_ci }) { 23180922886Sopenharmony_ci Flex({ 23280922886Sopenharmony_ci direction: FlexDirection.Row, 23380922886Sopenharmony_ci justifyContent: FlexAlign.SpaceBetween, 23480922886Sopenharmony_ci alignItems: ItemAlign.Center 23580922886Sopenharmony_ci }) { 23680922886Sopenharmony_ci Row() { 23780922886Sopenharmony_ci this.buildIcon(item, false) 23880922886Sopenharmony_ci 23980922886Sopenharmony_ci Text(item.deviceName) 24080922886Sopenharmony_ci .fontSize($r('sys.float.ohos_id_text_size_body2')) 24180922886Sopenharmony_ci .fontColor(item.isConnected ? 24280922886Sopenharmony_ci (this.configurationColorMode !== ConfigurationColorMode.COLOR_MODE_DARK ? 24380922886Sopenharmony_ci $r('sys.color.font_emphasize') : $r('sys.color.font_primary')) : 24480922886Sopenharmony_ci (this.configurationColorMode !== ConfigurationColorMode.COLOR_MODE_DARK ? 24580922886Sopenharmony_ci $r('sys.color.font_primary') : $r('sys.color.font_secondary'))) 24680922886Sopenharmony_ci .width(144) 24780922886Sopenharmony_ci .padding({ 24880922886Sopenharmony_ci left: 8, 24980922886Sopenharmony_ci top: 12, 25080922886Sopenharmony_ci right: 8, 25180922886Sopenharmony_ci bottom: 12 25280922886Sopenharmony_ci }) 25380922886Sopenharmony_ci .textOverflow({ overflow: TextOverflow.Ellipsis }) 25480922886Sopenharmony_ci .maxLines(2) 25580922886Sopenharmony_ci .wordBreak(WordBreak.BREAK_ALL) 25680922886Sopenharmony_ci .maxFontScale(this.maxFonSizeScale) 25780922886Sopenharmony_ci } 25880922886Sopenharmony_ci .justifyContent(FlexAlign.Start) 25980922886Sopenharmony_ci .alignItems(VerticalAlign.Center) 26080922886Sopenharmony_ci 26180922886Sopenharmony_ci if (item.isConnected && item.selectedIconName !== null && item.selectedIconName !== undefined) { 26280922886Sopenharmony_ci Row() { 26380922886Sopenharmony_ci this.buildIcon(item, true) 26480922886Sopenharmony_ci } 26580922886Sopenharmony_ci .justifyContent(FlexAlign.Start) 26680922886Sopenharmony_ci .alignItems(VerticalAlign.Center) 26780922886Sopenharmony_ci .accessibilityLevel('yes') 26880922886Sopenharmony_ci .accessibilityText(this.accessibilityConnectedStr) 26980922886Sopenharmony_ci } 27080922886Sopenharmony_ci } 27180922886Sopenharmony_ci .constraintSize({ minHeight: 48 }) 27280922886Sopenharmony_ci .padding({ left: 12, right: 12 }) 27380922886Sopenharmony_ci .onTouch((event) => { 27480922886Sopenharmony_ci if (event.type === TouchType.Down) { 27580922886Sopenharmony_ci this.touchMenuItemIndex = index; 27680922886Sopenharmony_ci } else if (event.type === TouchType.Up) { 27780922886Sopenharmony_ci this.touchMenuItemIndex = -1; 27880922886Sopenharmony_ci } 27980922886Sopenharmony_ci }) 28080922886Sopenharmony_ci .backgroundColor(this.touchMenuItemIndex === index 28180922886Sopenharmony_ci ? $r('sys.color.interactive_click') : '#00FFFFFF') 28280922886Sopenharmony_ci .borderRadius(this.touchMenuItemIndex === index 28380922886Sopenharmony_ci ? $r('sys.float.corner_radius_level8') : 0) 28480922886Sopenharmony_ci 28580922886Sopenharmony_ci if (index != this.deviceList.length - 1) { 28680922886Sopenharmony_ci Divider() 28780922886Sopenharmony_ci .height(1) 28880922886Sopenharmony_ci .width(172) 28980922886Sopenharmony_ci .color($r('sys.color.comp_divider')) 29080922886Sopenharmony_ci .padding({ right: 12 }) 29180922886Sopenharmony_ci } 29280922886Sopenharmony_ci } 29380922886Sopenharmony_ci .width('100%') 29480922886Sopenharmony_ci .onClick(() => { 29580922886Sopenharmony_ci if (this.extensionProxy != null && !item.isConnected) { 29680922886Sopenharmony_ci this.extensionProxy.send({ 'selectedDeviceInfo': item }) 29780922886Sopenharmony_ci } 29880922886Sopenharmony_ci }) 29980922886Sopenharmony_ci }) 30080922886Sopenharmony_ci } 30180922886Sopenharmony_ci .width(216) 30280922886Sopenharmony_ci } 30380922886Sopenharmony_ci 30480922886Sopenharmony_ci @Builder 30580922886Sopenharmony_ci private buildDefaultPicker(isCustomPicker: boolean) { 30680922886Sopenharmony_ci UIExtensionComponent( 30780922886Sopenharmony_ci { 30880922886Sopenharmony_ci abilityName: 'UIExtAbility', 30980922886Sopenharmony_ci bundleName: 'com.hmos.mediacontroller', 31080922886Sopenharmony_ci parameters: { 31180922886Sopenharmony_ci 'normalColor': this.normalColor, 31280922886Sopenharmony_ci 'activeColor': this.activeColor, 31380922886Sopenharmony_ci 'pickerColorMode': this.colorMode, 31480922886Sopenharmony_ci 'avCastPickerStyle': this.pickerStyle, 31580922886Sopenharmony_ci 'ability.want.params.uiExtensionType': 'sysPicker/mediaControl', 31680922886Sopenharmony_ci 'isCustomPicker': isCustomPicker, 31780922886Sopenharmony_ci } 31880922886Sopenharmony_ci }) 31980922886Sopenharmony_ci .onRemoteReady((proxy: UIExtensionProxy) => { 32080922886Sopenharmony_ci console.info(TAG, 'onRemoteReady'); 32180922886Sopenharmony_ci this.extensionProxy = proxy; 32280922886Sopenharmony_ci }) 32380922886Sopenharmony_ci .onReceive((data) => { 32480922886Sopenharmony_ci if (JSON.stringify(data['deviceInfoType']) !== undefined) { 32580922886Sopenharmony_ci console.info(TAG, `deviceInfoType : ${JSON.stringify(data['deviceInfoType'])}`); 32680922886Sopenharmony_ci this.deviceInfoType = data['deviceInfoType'] as string; 32780922886Sopenharmony_ci } 32880922886Sopenharmony_ci 32980922886Sopenharmony_ci if (JSON.stringify(data['pickerStyle']) !== undefined) { 33080922886Sopenharmony_ci console.info(TAG, `picker style : ${JSON.stringify(data['pickerStyle'])}`); 33180922886Sopenharmony_ci this.pickerStyleFromMediaController = data['pickerStyle'] as AVCastPickerStyle; 33280922886Sopenharmony_ci } 33380922886Sopenharmony_ci 33480922886Sopenharmony_ci if (JSON.stringify(data['deviceList']) !== undefined) { 33580922886Sopenharmony_ci console.info(TAG, `picker device list : ${JSON.stringify(data['deviceList'])}`); 33680922886Sopenharmony_ci this.deviceList = JSON.parse(JSON.stringify(data['deviceList'])); 33780922886Sopenharmony_ci let hasOnlySpeakerAndEarpiece: boolean = this.deviceList.length === 2 && !this.hasExtDevice(this.deviceList); 33880922886Sopenharmony_ci let hasNoDevices: boolean = this.deviceList === null || this.deviceList.length === 0; 33980922886Sopenharmony_ci let isCalling: boolean = this.sessionType === 'voice_call' || this.sessionType === 'video_call'; 34080922886Sopenharmony_ci let isExtMenuScene = isCalling && (hasNoDevices || hasOnlySpeakerAndEarpiece); 34180922886Sopenharmony_ci let isPanelForMedia: boolean = !isCalling && 34280922886Sopenharmony_ci (this.pickerStyle === AVCastPickerStyle.STYLE_PANEL && 34380922886Sopenharmony_ci this.pickerStyleFromMediaController === AVCastPickerStyle.STYLE_PANEL); 34480922886Sopenharmony_ci if (isExtMenuScene || isPanelForMedia) { 34580922886Sopenharmony_ci this.isMenuShow = false; 34680922886Sopenharmony_ci this.touchMenuItemIndex = -1; 34780922886Sopenharmony_ci } 34880922886Sopenharmony_ci } 34980922886Sopenharmony_ci 35080922886Sopenharmony_ci if (JSON.stringify(data['state']) !== undefined) { 35180922886Sopenharmony_ci console.info(TAG, `picker state change : ${JSON.stringify(data['state'])}`); 35280922886Sopenharmony_ci let isCalling: boolean = (this.sessionType === 'voice_call' || this.sessionType === 'video_call'); 35380922886Sopenharmony_ci let isPanelForMedia: boolean = !isCalling && 35480922886Sopenharmony_ci (this.pickerStyle === AVCastPickerStyle.STYLE_PANEL && 35580922886Sopenharmony_ci this.pickerStyleFromMediaController === AVCastPickerStyle.STYLE_PANEL); 35680922886Sopenharmony_ci if (this.onStateChange != null && isPanelForMedia) { 35780922886Sopenharmony_ci if (parseInt(JSON.stringify(data['state'])) === AVCastPickerState.STATE_APPEARING) { 35880922886Sopenharmony_ci this.onStateChange(AVCastPickerState.STATE_APPEARING); 35980922886Sopenharmony_ci } else { 36080922886Sopenharmony_ci this.onStateChange(AVCastPickerState.STATE_DISAPPEARING); 36180922886Sopenharmony_ci } 36280922886Sopenharmony_ci } 36380922886Sopenharmony_ci } 36480922886Sopenharmony_ci 36580922886Sopenharmony_ci if (JSON.stringify(data['sessionType']) !== undefined) { 36680922886Sopenharmony_ci console.info(TAG, `session type : ${JSON.stringify(data['sessionType'])}`); 36780922886Sopenharmony_ci this.sessionType = data['sessionType'] as string; 36880922886Sopenharmony_ci } 36980922886Sopenharmony_ci 37080922886Sopenharmony_ci if (JSON.stringify(data['isShowMenu']) !== undefined) { 37180922886Sopenharmony_ci console.info(TAG, `isShowMenu : ${JSON.stringify(data['isShowMenu'])}`); 37280922886Sopenharmony_ci this.isMenuShow = data['isShowMenu'] as boolean; 37380922886Sopenharmony_ci if (!this.isMenuShow) { 37480922886Sopenharmony_ci this.touchMenuItemIndex = -1; 37580922886Sopenharmony_ci } 37680922886Sopenharmony_ci } 37780922886Sopenharmony_ci 37880922886Sopenharmony_ci if (JSON.stringify(data['configurationColorMode']) !== undefined) { 37980922886Sopenharmony_ci console.info(TAG, `configurationColorMode : ${JSON.stringify(data['configurationColorMode'])}`); 38080922886Sopenharmony_ci this.configurationColorMode = data['configurationColorMode'] as number; 38180922886Sopenharmony_ci } 38280922886Sopenharmony_ci 38380922886Sopenharmony_ci if (JSON.stringify(data['accessConnected']) !== undefined) { 38480922886Sopenharmony_ci console.info(TAG, `accessConnected : ${JSON.stringify(data['accessConnected'])}`); 38580922886Sopenharmony_ci this.accessibilityConnectedStr = data['accessConnected'] as string; 38680922886Sopenharmony_ci } 38780922886Sopenharmony_ci 38880922886Sopenharmony_ci if (JSON.stringify(data['accessAudioControl']) !== undefined) { 38980922886Sopenharmony_ci console.info(TAG, `accessAudioControl : ${JSON.stringify(data['accessAudioControl'])}`); 39080922886Sopenharmony_ci this.accessibilityAudioControlStr = data['accessAudioControl'] as string; 39180922886Sopenharmony_ci } 39280922886Sopenharmony_ci }) 39380922886Sopenharmony_ci .size({ width: '100%', height: '100%' }) 39480922886Sopenharmony_ci .bindMenu(this.isMenuShow, this.deviceMenu(), { 39580922886Sopenharmony_ci placement: Placement.TopRight, 39680922886Sopenharmony_ci onDisappear: () => { 39780922886Sopenharmony_ci this.isMenuShow = false; 39880922886Sopenharmony_ci this.touchMenuItemIndex = -1; 39980922886Sopenharmony_ci this.menuShowStateCallback(this.isMenuShow); 40080922886Sopenharmony_ci }, 40180922886Sopenharmony_ci onAppear: () => { 40280922886Sopenharmony_ci if (this.extensionProxy != null && this.pickerClickTime !== -1) { 40380922886Sopenharmony_ci this.extensionProxy.send({ 'timeCost': new Date().getTime() - this.pickerClickTime}); 40480922886Sopenharmony_ci this.pickerClickTime = -1; 40580922886Sopenharmony_ci } 40680922886Sopenharmony_ci this.menuShowStateCallback(this.isMenuShow); 40780922886Sopenharmony_ci } 40880922886Sopenharmony_ci }) 40980922886Sopenharmony_ci .onClick(() => { 41080922886Sopenharmony_ci let hasOnlySpeakerAndEarpiece: boolean = this.deviceList.length === 2 && !this.hasExtDevice(this.deviceList); 41180922886Sopenharmony_ci let hasNoDevices: boolean = this.deviceList === null || this.deviceList.length === 0; 41280922886Sopenharmony_ci let isCalling: boolean = this.sessionType === 'voice_call' || this.sessionType === 'video_call'; 41380922886Sopenharmony_ci let isExtMenuScene: boolean = isCalling && (hasNoDevices || hasOnlySpeakerAndEarpiece); 41480922886Sopenharmony_ci let isPanelForMedia: boolean = !isCalling && 41580922886Sopenharmony_ci (this.pickerStyle === AVCastPickerStyle.STYLE_PANEL && 41680922886Sopenharmony_ci this.pickerStyleFromMediaController === AVCastPickerStyle.STYLE_PANEL); 41780922886Sopenharmony_ci if (isExtMenuScene || isPanelForMedia) { 41880922886Sopenharmony_ci if (this.extensionProxy != null) { 41980922886Sopenharmony_ci this.extensionProxy.send({'clickEvent': true}); 42080922886Sopenharmony_ci } 42180922886Sopenharmony_ci this.isMenuShow = false; 42280922886Sopenharmony_ci this.touchMenuItemIndex = -1; 42380922886Sopenharmony_ci } else { 42480922886Sopenharmony_ci this.isMenuShow = !this.isMenuShow; 42580922886Sopenharmony_ci if (this.isMenuShow) { 42680922886Sopenharmony_ci this.pickerClickTime = new Date().getTime(); 42780922886Sopenharmony_ci } else { 42880922886Sopenharmony_ci this.touchMenuItemIndex = -1; 42980922886Sopenharmony_ci } 43080922886Sopenharmony_ci } 43180922886Sopenharmony_ci }) 43280922886Sopenharmony_ci .accessibilityLevel('yes') 43380922886Sopenharmony_ci .accessibilityText(this.accessibilityAudioControlStr) 43480922886Sopenharmony_ci } 43580922886Sopenharmony_ci 43680922886Sopenharmony_ci private hasExtDevice(allDevice: Array<AVCastPickerDeviceInfo>): boolean { 43780922886Sopenharmony_ci for (let i = 0; i < allDevice.length; i++) { 43880922886Sopenharmony_ci if (allDevice[i].deviceType !== 1 && // 1 is audio.DeviceType.EARPIECE 43980922886Sopenharmony_ci allDevice[i].deviceType !== 2) { // 2 is audio.DeviceType.SPEAKER 44080922886Sopenharmony_ci return true; 44180922886Sopenharmony_ci } 44280922886Sopenharmony_ci } 44380922886Sopenharmony_ci return false; 44480922886Sopenharmony_ci } 44580922886Sopenharmony_ci 44680922886Sopenharmony_ci private menuShowStateCallback(isMenuShow: boolean): void { 44780922886Sopenharmony_ci if (this.onStateChange != null && 44880922886Sopenharmony_ci (this.pickerStyle === AVCastPickerStyle.STYLE_MENU || 44980922886Sopenharmony_ci this.pickerStyleFromMediaController === AVCastPickerStyle.STYLE_MENU)) { 45080922886Sopenharmony_ci let menuShowState: AVCastPickerState = isMenuShow ? 45180922886Sopenharmony_ci AVCastPickerState.STATE_APPEARING : AVCastPickerState.STATE_DISAPPEARING; 45280922886Sopenharmony_ci this.onStateChange(menuShowState); 45380922886Sopenharmony_ci } 45480922886Sopenharmony_ci } 45580922886Sopenharmony_ci 45680922886Sopenharmony_ci @Builder 45780922886Sopenharmony_ci private buildCustomPicker() { 45880922886Sopenharmony_ci Stack({ alignContent: Alignment.Center}) { 45980922886Sopenharmony_ci Column() { 46080922886Sopenharmony_ci this.customPicker(); 46180922886Sopenharmony_ci } 46280922886Sopenharmony_ci .alignItems(HorizontalAlign.Center) 46380922886Sopenharmony_ci .justifyContent(FlexAlign.Center) 46480922886Sopenharmony_ci .size({ width: '100%', height: '100%' }) 46580922886Sopenharmony_ci .zIndex(0) 46680922886Sopenharmony_ci 46780922886Sopenharmony_ci Column() { 46880922886Sopenharmony_ci this.buildDefaultPicker(true); 46980922886Sopenharmony_ci } 47080922886Sopenharmony_ci .alignItems(HorizontalAlign.Center) 47180922886Sopenharmony_ci .justifyContent(FlexAlign.Center) 47280922886Sopenharmony_ci .size({ width: '100%', height: '100%' }) 47380922886Sopenharmony_ci .zIndex(1) 47480922886Sopenharmony_ci } 47580922886Sopenharmony_ci .size({ width: '100%', height: '100%' }) 47680922886Sopenharmony_ci } 47780922886Sopenharmony_ci} 478