1/* 2 * Copyright (c) 2022-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 deviceManager from '@ohos.distributedHardware.deviceManager'; 16import UIExtensionContentSession from '@ohos.app.ability.UIExtensionContentSession'; 17import deviceInfo from '@ohos.deviceInfo'; 18import Constant from '../common/constant'; 19import common from '@ohos.app.ability.common'; 20import display from '@ohos.display'; 21import mediaQuery from '@ohos.mediaquery'; 22 23let dmClass: deviceManager.DeviceManager | null; 24let TAG = '[DeviceManagerUI:ConfirmDialog]==>'; 25const ACTION_ALLOW_AUTH_ONCE: number = 0; 26const ACTION_CANCEL_AUTH: number = 1; 27const ACTION_AUTH_CONFIRM_TIMEOUT: number = 2; 28const ACTION_ALLOW_AUTH_ALWAYS: number = 6; 29const MSG_CANCEL_CONFIRM_SHOW: number = 5; 30const DEVICE_TYPE_2IN1: number = 0xA2F; 31const DEVICE_TYPE_PC: number = 0x0C; 32const CAST_PKG_NAME: string = 'CastEngineService'; 33 34@CustomDialog 35struct ConfirmCustomDialog { 36 @State peerAppOperation: string = ''; 37 @State peerCustomDescription: string = ''; 38 @State peerDeviceName: string = ''; 39 @State peerDeviceType: number = 0; 40 @State secondsNum: number = 30; 41 @State times: number = 0; 42 @State isAvailableType: boolean = false; 43 @State btnColor: ResourceColor = Color.Transparent; 44 @State title: string = ''; 45 controller?: CustomDialogController; 46 isPC: boolean = false; 47 48 aboutToAppear() { 49 console.log(TAG + 'aboutToAppear execute PinCustomDialog') 50 let context = getContext() as common.UIAbilityContext; 51 52 if (AppStorage.get('deviceName') != null) { 53 this.peerDeviceName = AppStorage.get('deviceName') as string; 54 console.log('peerDeviceName is ' + this.peerDeviceName); 55 } 56 let hostPkgLabel: string = AppStorage.get('hostPkgLabel') as string; 57 if (hostPkgLabel === CAST_PKG_NAME) { 58 this.title = 59 context.resourceManager.getStringSync($r('app.string.dm_confirm_title_cast').id, this.peerDeviceName); 60 } else if (hostPkgLabel != null) { 61 this.title = context.resourceManager.getStringSync($r('app.string.dm_confirm_title_hap').id, hostPkgLabel, 62 this.peerDeviceName); 63 this.peerCustomDescription = context.resourceManager.getStringSync($r('app.string.dm_confirm_intention').id); 64 } else { 65 let titleFirst: string = 66 context.resourceManager.getStringSync($r('app.string.dm_connect_device').id, this.peerDeviceName); 67 this.title = 68 context.resourceManager.getStringSync($r('app.string.dm_is_trust_device').id, titleFirst); 69 this.peerCustomDescription = context.resourceManager.getStringSync($r('app.string.dm_confirm_intention').id); 70 } 71 72 if (AppStorage.get('deviceType') != null) { 73 this.peerDeviceType = AppStorage.get('deviceType') as number; 74 console.log('peerDeviceType is ' + this.peerDeviceType); 75 } 76 77 this.times = setInterval(() => { 78 console.info('devicemanagerui confirm dialog run seconds:' + this.secondsNum); 79 this.secondsNum--; 80 if (this.secondsNum === 0) { 81 clearInterval(this.times); 82 this.times = 0; 83 this.setUserOperation(ACTION_AUTH_CONFIRM_TIMEOUT); 84 this.destruction(); 85 console.info('click cancel times run out'); 86 } 87 }, 1000) 88 console.log(TAG + 'deviceInfo.deviceType:' + deviceInfo.deviceType); 89 this.isPC = Constant.isPC(); 90 } 91 92 onAllowOnce() { 93 console.log('allow once') 94 if (dmClass == null) { 95 console.log('createDeviceManager is null') 96 return 97 } 98 99 console.log('allow once' + ACTION_ALLOW_AUTH_ONCE) 100 this.setUserOperation(ACTION_ALLOW_AUTH_ONCE) 101 this.destruction() 102 } 103 104 onAllowAlways() { 105 console.log('allow always') 106 if (dmClass == null) { 107 console.log('createDeviceManager is null') 108 return 109 } 110 111 console.log('allow always' + ACTION_ALLOW_AUTH_ALWAYS) 112 this.setUserOperation(ACTION_ALLOW_AUTH_ALWAYS) 113 this.destruction() 114 } 115 116 onCancel() { 117 console.log('cancel') 118 if (dmClass == null) { 119 console.log('createDeviceManager is null') 120 return 121 } 122 123 console.log('cancel' + ACTION_CANCEL_AUTH) 124 this.setUserOperation(ACTION_CANCEL_AUTH) 125 this.destruction() 126 } 127 128 setUserOperation(operation: number) { 129 console.log(TAG + 'setUserOperation: ' + operation) 130 if (dmClass == null) { 131 console.log(TAG + 'setUserOperation: ' + 'dmClass null') 132 return; 133 } 134 try { 135 dmClass.setUserOperation(operation, 'extra'); 136 } catch (error) { 137 console.log(TAG + 'dmClass setUserOperation failed') 138 } 139 } 140 141 destruction() { 142 let session = AppStorage.get<UIExtensionContentSession>('ConfirmSession'); 143 if (session) { 144 session.terminateSelf(); 145 } 146 } 147 148 getImages(peerdeviceType: number): Resource { 149 console.info('peerdeviceType is ' + peerdeviceType); 150 if (peerdeviceType === deviceManager.DeviceType.SPEAKER) { 151 this.isAvailableType = true; 152 return $r('sys.symbol.soundai_fill'); 153 } else if (peerdeviceType === deviceManager.DeviceType.PHONE) { 154 this.isAvailableType = true; 155 return $r('sys.symbol.phone_fill_1'); 156 } else if (peerdeviceType === deviceManager.DeviceType.TABLET) { 157 this.isAvailableType = true; 158 return $r('sys.symbol.pad_fill'); 159 } else if (peerdeviceType === deviceManager.DeviceType.WEARABLE) { 160 this.isAvailableType = true; 161 return $r('sys.symbol.earphone_case_16896'); 162 } else if (peerdeviceType === deviceManager.DeviceType.CAR) { 163 this.isAvailableType = true; 164 return $r('sys.symbol.car_fill'); 165 } else if (peerdeviceType === deviceManager.DeviceType.TV) { 166 this.isAvailableType = true; 167 return $r('sys.symbol.smartscreen_fill'); 168 } else if (peerdeviceType === DEVICE_TYPE_PC) { 169 this.isAvailableType = true; 170 return $r('sys.symbol.matebook_fill'); 171 } else if (peerdeviceType === DEVICE_TYPE_2IN1) { 172 this.isAvailableType = true; 173 return $r('sys.symbol.matebook_fill'); 174 } else { 175 this.isAvailableType = false; 176 return $r('sys.symbol.unknown_device_fill'); 177 } 178 } 179 180 @Builder 181 Symbol() { 182 Shape() { 183 Circle() 184 .width(32) 185 .height(32) 186 .fill($r('sys.color.ohos_id_color_activated')) 187 Column() { 188 SymbolGlyph(this.getImages(this.peerDeviceType)) 189 .fontSize('20vp') 190 .renderingStrategy(SymbolRenderingStrategy.MULTIPLE_OPACITY) 191 .fontColor([$r('sys.color.ohos_id_color_primary_contrary')]) 192 .offset({ x: 6, y: 6 }) 193 } 194 } 195 .visibility(this.isAvailableType ? Visibility.Visible : Visibility.None) 196 .margin({ bottom: 16, top: 24 }) 197 } 198 199 build() { 200 GridRow({ 201 columns: { xs: 4, sm: 8, md: this.isPC ? 24 : 12 }, 202 gutter: { x: 4 }, 203 breakpoints: { value: ['600vp', '840vp'] } 204 }) { 205 GridCol({ span: { xs: 4, sm: 4, md: this.isPC ? 6 : 4 }, offset: { sm: 2, md: this.isPC ? 9 : 4 } }) { 206 Column() { 207 this.Symbol(); 208 Column() { 209 Text(this.title) 210 .textAlign(TextAlign.Center) 211 .fontSize($r('sys.float.ohos_id_text_size_dialog_tittle')) 212 .fontWeight(FontWeight.Bold) 213 .fontColor($r('sys.color.ohos_id_color_text_primary')) 214 .minFontSize(12) 215 .maxFontSize($r('sys.float.ohos_id_text_size_dialog_tittle')) 216 .heightAdaptivePolicy(TextHeightAdaptivePolicy.LAYOUT_CONSTRAINT_FIRST) 217 .textOverflow({ overflow: TextOverflow.Ellipsis }) 218 .width('auto') 219 .maxLines(2) 220 Text(this.peerCustomDescription) 221 .textAlign(TextAlign.Start) 222 .fontColor($r('sys.color.ohos_id_color_text_secondary')) 223 .fontWeight(FontWeight.Regular) 224 .textOverflow({ overflow: TextOverflow.Ellipsis }) 225 .fontSize($r('sys.float.ohos_id_text_size_body2')) 226 .maxLines(2) 227 .width('auto') 228 .margin({ top: 8 }) 229 .visibility(this.peerCustomDescription === '' ? Visibility.None : Visibility.Visible) 230 }.margin({ 231 top: this.isAvailableType ? 0 : 24, 232 bottom: 16, left: 24, right: 24 }) 233 234 Column() { 235 Button($r('app.string.dm_allow_always')) 236 .margin({ bottom: 4 }) 237 .onClick(() => { 238 this.onAllowAlways(); 239 }) 240 .fontColor($r('sys.color.ohos_id_color_text_primary_activated')) 241 .height(40) 242 .width(this.isPC ? 250 : '100%') 243 .backgroundColor(this.btnColor) 244 .onHover((isHover?: boolean, event?: HoverEvent): void => { 245 if (isHover) { 246 this.btnColor = $r('sys.color.ohos_id_color_hover'); 247 } else { 248 this.btnColor = this.isPC ? $r('sys.color.ohos_id_color_button_normal') : Color.Transparent; 249 } 250 }) 251 .stateStyles({ 252 pressed: { 253 .backgroundColor($r('sys.color.ohos_id_color_click_effect')) 254 }, 255 normal: { 256 .backgroundColor(this.isPC ? $r('sys.color.ohos_id_color_button_normal') : Color.Transparent) 257 } 258 }) 259 Button($r('app.string.dm_allow_temp')) 260 .margin({ bottom: 4 }) 261 .onClick(() => { 262 this.onAllowOnce(); 263 }) 264 .fontColor($r('sys.color.ohos_id_color_text_primary_activated')) 265 .height(40) 266 .width(this.isPC ? 250 : '100%') 267 .backgroundColor(this.btnColor) 268 .onHover((isHover?: boolean, event?: HoverEvent): void => { 269 if (isHover) { 270 this.btnColor = $r('sys.color.ohos_id_color_hover'); 271 } else { 272 this.btnColor = this.isPC ? $r('sys.color.ohos_id_color_button_normal') : Color.Transparent; 273 } 274 }) 275 .stateStyles({ 276 pressed: { 277 .backgroundColor($r('sys.color.ohos_id_color_click_effect')) 278 }, 279 normal: { 280 .backgroundColor(this.isPC ? $r('sys.color.ohos_id_color_button_normal') : Color.Transparent) 281 } 282 }) 283 Button($r('app.plural.dm_not_allow', this.secondsNum, this.secondsNum)) 284 .margin({ left: 16, right: 16 }) 285 .fontColor($r('sys.color.ohos_id_color_text_primary_activated')) 286 .onClick(() => { 287 this.onCancel(); 288 }) 289 .height(40) 290 .width(this.isPC ? 250 : '100%') 291 .backgroundColor(this.btnColor) 292 .onHover((isHover?: boolean, event?: HoverEvent): void => { 293 if (isHover) { 294 this.btnColor = $r('sys.color.ohos_id_color_hover'); 295 } else { 296 this.btnColor = this.isPC ? $r('sys.color.ohos_id_color_button_normal') : Color.Transparent; 297 } 298 }) 299 .stateStyles({ 300 pressed: { 301 .backgroundColor($r('sys.color.ohos_id_color_click_effect')) 302 }, 303 normal: { 304 .backgroundColor(this.isPC ? $r('sys.color.ohos_id_color_button_normal') : Color.Transparent) 305 } 306 }) 307 } 308 .margin({ 309 left: 16, 310 right: 16, 311 bottom: this.isPC ? 24 : 8 312 }) 313 } 314 .borderRadius($r('sys.float.ohos_id_corner_radius_dialog')) 315 .backgroundBlurStyle(BlurStyle.COMPONENT_ULTRA_THICK) 316 .margin({ left: $r('sys.float.ohos_id_dialog_margin_start'), right: $r('sys.float.ohos_id_dialog_margin_end') }) 317 } 318 }.constraintSize({ maxHeight: '90%' }) 319 } 320} 321 322@Entry 323@Component 324struct dialogPlusPage { 325 dialogController: CustomDialogController = new CustomDialogController({ 326 builder: ConfirmCustomDialog(), 327 autoCancel: false, 328 alignment: DialogAlignment.Center, 329 offset: { dx: 0, dy: -20 }, 330 customStyle: true, 331 maskColor: $r('sys.color.ohos_id_color_mask_thin') 332 }); 333 334 initStatue() { 335 if (dmClass) { 336 console.log(TAG + 'deviceManager exist') 337 return 338 } 339 deviceManager.createDeviceManager('com.ohos.devicemanagerui.confirm', 340 (err: Error, dm: deviceManager.DeviceManager) => { 341 if (err) { 342 console.log('createDeviceManager err:' + JSON.stringify(err) + ' --fail:' + JSON.stringify(dm)) 343 return 344 } 345 dmClass = dm 346 dmClass.on('uiStateChange', (data: Record<string, string>) => { 347 console.log('uiStateChange executed, dialog closed' + JSON.stringify(data)) 348 let tmpStr: Record<string, number> = JSON.parse(data.param) 349 let msg: number = tmpStr.uiStateMsg as number 350 if (msg === MSG_CANCEL_CONFIRM_SHOW) { 351 console.log('cancel confirm show.') 352 this.destruction() 353 return 354 } 355 }) 356 }) 357 } 358 359 onPageShow() { 360 console.log('onPageShow') 361 this.initStatue() 362 } 363 364 destruction() { 365 let session = AppStorage.get<UIExtensionContentSession>('ConfirmSession'); 366 if (session) { 367 session.terminateSelf(); 368 } 369 } 370 371 aboutToDisappear() { 372 console.log(TAG + 'aboutToDisappear aboutToDisappear') 373 if (dmClass != null) { 374 try { 375 dmClass.off('uiStateChange'); 376 dmClass.release(); 377 } catch (error) { 378 console.log('dmClass release failed') 379 } 380 dmClass = null 381 } 382 } 383 384 build() { 385 Column(this.dialogController.open()) 386 } 387}