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 deviceInfo from '@ohos.deviceInfo'; 17import BaseSettingsController from '../../../../../../../common/component/src/main/ets/default/controller/BaseSettingsController'; 18import BluetoothModel, { BondState, ProfileConnectionState } from '../../model/bluetoothImpl/BluetoothModel'; 19import BluetoothDevice from '../../model/bluetoothImpl/BluetoothDevice'; 20import Log from '../../../../../../../common/utils/src/main/ets/default/baseUtil/LogDecorator'; 21import ConfigData from '../../../../../../../common/utils/src/main/ets/default/baseUtil/ConfigData'; 22import ISettingsController from '../../../../../../../common/component/src/main/ets/default/controller/ISettingsController'; 23import LogUtil from '../../../../../../../common/utils/src/main/ets/default/baseUtil/LogUtil'; 24import AboutDeviceModel from '../../model/aboutDeviceImpl/AboutDeviceModel' 25import { emitter } from '@kit.BasicServicesKit'; 26import constant from '@ohos.bluetooth.constant'; 27 28const deviceTypeInfo = deviceInfo.deviceType; 29const DISCOVERY_DURING_TIME: number = 30000; // 30' 30const DISCOVERY_INTERVAL_TIME: number = 3000; // 3' 31const DISCOVERY_DEBOUNCE_TIME: number = 500; 32 33export default class BluetoothDeviceController extends BaseSettingsController { 34 private TAG = ConfigData.TAG + 'BluetoothDeviceController ' 35 36 //state 37 private isOn: boolean = false; 38 private enabled: boolean = false; 39 40 // paired devices 41 private pairedDevices: BluetoothDevice[] = []; 42 43 // available devices 44 private isDeviceDiscovering: boolean = false; 45 private availableDevices: BluetoothDevice[] = []; 46 private pairPinCode: string = ''; 47 private discoveryStartTimeoutId: number = 0; 48 private discoveryStopTimeoutId: number = 0; 49 private debounceTimer: number = 0; 50 private eventData: emitter.EventData = {}; 51 52 initData(): ISettingsController { 53 LogUtil.log(this.TAG + 'start to initData bluetooth'); 54 super.initData(); 55 let isOn = BluetoothModel.isStateOn(); 56 LogUtil.log(this.TAG + 'initData bluetooth state isOn ' + isOn + ', typeof isOn = ' + typeof (isOn)) 57 if (isOn) { 58 this.refreshPairedDevices(); 59 } 60 61 LogUtil.log(this.TAG + 'initData save value to app storage. ') 62 this.isOn = new Boolean(isOn).valueOf() 63 this.enabled = true 64 65 AppStorage.SetOrCreate('bluetoothIsOn', this.isOn); 66 AppStorage.SetOrCreate('bluetoothToggleEnabled', this.enabled); 67 AppStorage.SetOrCreate('bluetoothAvailableDevices', this.availableDevices); 68 69 return this; 70 } 71 72 subscribe(): ISettingsController { 73 LogUtil.log(this.TAG + 'subscribe bluetooth state isOn ' + this.isOn) 74 this.subscribeStateChange(); 75 this.subscribeBluetoothDeviceFind(); 76 this.subscribeBondStateChange(); 77 this.subscribeDeviceConnectStateChange(); 78 BluetoothModel.subscribePinRequired((pinRequiredParam: { 79 deviceId: string; 80 pinCode: string; 81 }) => { 82 LogUtil.log(this.TAG + 'bluetooth subscribePinRequired callback'); 83 let pairData = this.getAvailableDevice(pinRequiredParam.deviceId); 84 this.pairPinCode = pinRequiredParam.pinCode; 85 AppStorage.SetOrCreate('pairData', pairData); 86 AppStorage.SetOrCreate('pinRequiredParam', pinRequiredParam); 87 }); 88 return this; 89 } 90 91 unsubscribe(): ISettingsController { 92 LogUtil.log(this.TAG + 'start to unsubscribe bluetooth'); 93 this.stopBluetoothDiscovery(); 94 95 if (this.discoveryStartTimeoutId) { 96 clearTimeout(this.discoveryStartTimeoutId); 97 this.discoveryStartTimeoutId = 0; 98 } 99 100 if (this.discoveryStopTimeoutId) { 101 clearTimeout(this.discoveryStopTimeoutId); 102 this.discoveryStopTimeoutId = 0; 103 } 104 105 BluetoothModel.unsubscribeBluetoothDeviceFind(); 106 BluetoothModel.unsubscribeBondStateChange(); 107 BluetoothModel.unsubscribeDeviceStateChange(); 108 BluetoothModel.unsubscribePinRequired(); 109 AppStorage.Delete('BluetoothFailedDialogFlag'); 110 return this; 111 } 112 113 /** 114 * Set toggle value 115 */ 116 toggleValue(isOn: boolean) { 117 if(this.discoveryStartTimeoutId) { 118 clearTimeout(this.discoveryStartTimeoutId); 119 this.discoveryStartTimeoutId = 0; 120 } 121 if(this.discoveryStopTimeoutId) { 122 clearTimeout(this.discoveryStopTimeoutId); 123 this.discoveryStopTimeoutId = 0; 124 } 125 if(this.debounceTimer) { 126 clearTimeout(this.debounceTimer); 127 this.debounceTimer = 0; 128 } 129 130 this.debounceTimer = setTimeout(() => { 131 let curState = BluetoothModel.getState(); 132 if ((curState === 2) === isOn) { 133 clearTimeout(this.debounceTimer); 134 this.debounceTimer = 0; 135 return; 136 } 137 this.enabled = false 138 AppStorage.SetOrCreate('bluetoothToggleEnabled', this.enabled); 139 LogUtil.log(this.TAG + 'afterCurrentValueChanged bluetooth state isOn = ' + this.isOn) 140 if (isOn) { 141 BluetoothModel.enableBluetooth(); 142 } else { 143 BluetoothModel.disableBluetooth(); 144 clearTimeout(this.debounceTimer); 145 this.debounceTimer = 0; 146 // remove all elements from availableDevices array 147 this.availableDevices.splice(0, this.availableDevices.length); 148 } 149 }, DISCOVERY_DEBOUNCE_TIME); 150 } 151 152 /** 153 * Get Local Name 154 */ 155 getLocalName() { 156 AppStorage.SetOrCreate('bluetoothLocalName', AboutDeviceModel.getSystemName()); 157 } 158 159 /** 160 * Pair device. 161 * 162 * @param deviceId device id 163 * @param success success callback 164 * @param error error callback 165 */ 166 pair(deviceId: string, success?: (pinCode: string) => void, error?: () => void): void { 167 const device: BluetoothDevice = this.getAvailableDevice(deviceId); 168 if (device && device.connectionState === BondState.BOND_STATE_BONDING) { 169 LogUtil.log(this.TAG + `bluetooth no Aavailable device or device is already pairing.`) 170 return; 171 } 172 // start pairing 173 BluetoothModel.pairDevice(deviceId); 174 } 175 176 /** 177 * Confirm pairing. 178 * 179 * @param deviceId device id 180 * @param accept accept or not 181 * @param success success callback 182 * @param error error callback 183 */ 184 confirmPairing(deviceId: string, accept: boolean): void { 185 if (accept) { 186 try { 187 this.getAvailableDevice(deviceId).connectionState = BondState.BOND_STATE_BONDING; 188 } catch (err) { 189 LogUtil.error(this.TAG + 'confirmPairing =' + JSON.stringify(err)); 190 } 191 } 192 // set paring confirmation 193 BluetoothModel.setDevicePairingConfirmation(deviceId, accept); 194 195 } 196 197 /** 198 * Connect device. 199 * @param deviceId device id 200 */ 201 connect(deviceId: string): Array<{ 202 profileId: number; 203 connectRet: boolean; 204 }> { 205 return BluetoothModel.connectDevice(deviceId); 206 } 207 208 /** 209 * disconnect device. 210 * @param deviceId device id 211 */ 212 disconnect(deviceId: string): Array<{ 213 profileId: number; 214 disconnectRet: boolean; 215 }> { 216 return BluetoothModel.disconnectDevice(deviceId); 217 } 218 219 /** 220 * get Profile State 221 * @param deviceId device id 222 * @param profileId profile id 223 */ 224 getProfileState(deviceId: string, profileId: number): { 225 isOn: boolean, 226 isEnable: boolean, 227 description: string | ResourceStr 228 } { 229 return BluetoothModel.getProfileState(deviceId, profileId); 230 } 231 232 /** 233 * Connect profile. 234 * @param deviceId device id 235 * @param profileId profile id 236 */ 237 connectProfile(deviceId: string, profileId: number): void { 238 BluetoothModel.connectProfile(deviceId, profileId); 239 } 240 /** 241 * disconnect profile. 242 * @param deviceId device id 243 * @param profileId profile id 244 */ 245 disconnectProfile(deviceId: string, profileId: number): void { 246 BluetoothModel.disconnectProfile(deviceId, profileId); 247 } 248 249 /** 250 * Unpair device. 251 * @param deviceId device id 252 */ 253 unpair(deviceId: string): boolean { 254 AppStorage.SetOrCreate('BluetoothFailedDialogFlag', false); 255 const result = BluetoothModel.unpairDevice(deviceId); 256 LogUtil.log(this.TAG + 'bluetooth paired device unpair. result = ' + result) 257 this.refreshPairedDevices() 258 return result; 259 } 260 261 /** 262 * Refresh paired devices. 263 */ 264 refreshPairedDevices() { 265 let deviceIds: string[] = BluetoothModel.getPairedDeviceIds(); 266 let list: BluetoothDevice[] = [] 267 deviceIds.forEach(deviceId => { 268 list.push(this.getDevice(deviceId)); 269 }); 270 this.pairedDevices = list; 271 this.sortPairedDevices(); 272 AppStorage.SetOrCreate('bluetoothPairedDevices', this.pairedDevices); 273 LogUtil.log(this.TAG + 'bluetooth paired devices. list length = ' + JSON.stringify(list.length)) 274 } 275 276 /** 277 * Paired device should be shown on top of the list. 278 */ 279 private sortPairedDevices() { 280 LogUtil.log(this.TAG + 'sortPairedDevices in.') 281 this.pairedDevices.sort((a: BluetoothDevice, b: BluetoothDevice) => { 282 if (a.connectionState == ProfileConnectionState.STATE_DISCONNECTED && b.connectionState == ProfileConnectionState.STATE_DISCONNECTED) { 283 return 0 284 } else if (b.connectionState == ProfileConnectionState.STATE_DISCONNECTED) { 285 return -1 286 } else if (a.connectionState == ProfileConnectionState.STATE_DISCONNECTED) { 287 return 1 288 } else { 289 return 0 290 } 291 }) 292 LogUtil.log(this.TAG + 'sortPairedDevices out.') 293 } 294 295 //---------------------- subscribe ---------------------- 296 /** 297 * Subscribe bluetooth state change 298 */ 299 private subscribeStateChange() { 300 BluetoothModel.subscribeStateChange((isOn: boolean) => { 301 LogUtil.log(this.TAG + 'bluetooth state changed. isOn = ' + isOn) 302 this.isOn = new Boolean(isOn).valueOf(); 303 this.enabled = true; 304 305 LogUtil.log(this.TAG + 'bluetooth state changed. save value.') 306 this.getLocalName() 307 AppStorage.SetOrCreate('bluetoothIsOn', this.isOn); 308 AppStorage.SetOrCreate('bluetoothToggleEnabled', this.enabled); 309 310 if (isOn) { 311 LogUtil.log(this.TAG + 'bluetooth state changed. unsubscribe') 312 this.startBluetoothDiscovery(); 313 } else { 314 LogUtil.log(this.TAG + 'bluetooth state changed. subscribe') 315 this.mStopBluetoothDiscovery(); 316 } 317 }); 318 } 319 320 /** 321 * Subscribe device find 322 */ 323 private subscribeBluetoothDeviceFind() { 324 BluetoothModel.subscribeBluetoothDeviceFind((deviceIds: Array<string>) => { 325 LogUtil.log(ConfigData.TAG + 'available bluetooth devices changed.'); 326 327 deviceIds?.forEach(deviceId => { 328 let device = this.availableDevices.find((availableDevice) => { 329 return availableDevice.deviceId === deviceId 330 }) 331 LogUtil.log(this.TAG + 'available bluetooth find'); 332 if (!device) { 333 let pairedDevice = this.pairedDevices.find((pairedDevice) => { 334 return pairedDevice.deviceId === deviceId 335 }) 336 if (pairedDevice) { 337 LogUtil.log(this.TAG + `available bluetooth is paried.`); 338 let indexDeviceID = 0; 339 for (let i = 0; i < this.pairedDevices.length; i++) { 340 if (this.pairedDevices[i].deviceId === deviceId) { 341 indexDeviceID = i; 342 break; 343 } 344 } 345 let existDevice = this.getDevice(deviceId); 346 if(existDevice.deviceName !== this.pairedDevices[indexDeviceID].deviceName){ 347 this.pairedDevices.splice(indexDeviceID,1,existDevice); 348 AppStorage.setOrCreate('bluetoothPairedDevices', this.pairedDevices); 349 } 350 } else { 351 LogUtil.log(this.TAG + 'available bluetooth new device found. availableDevices length = ' + this.availableDevices.length); 352 let newDevice = this.getDevice(deviceId); 353 if (!!newDevice.deviceName) { 354 this.availableDevices.push(newDevice); 355 } 356 357 LogUtil.log(this.TAG + 'available bluetooth new device pushed. availableDevices length = ' + this.availableDevices.length); 358 } 359 } else { 360 LogUtil.log(this.TAG + 'bluetooth already exist!'); 361 let indexDeviceID = 0; 362 for (let i = 0; i < this.availableDevices.length; i++) { 363 if (this.availableDevices[i].deviceId === deviceId) { 364 indexDeviceID = i; 365 break; 366 } 367 } 368 let existDevice = this.getDevice(deviceId); 369 if(existDevice.deviceName !== this.availableDevices[indexDeviceID].deviceName){ 370 this.availableDevices.splice(indexDeviceID,1,existDevice); 371 } 372 } 373 }) 374 AppStorage.SetOrCreate('bluetoothAvailableDevices', this.availableDevices); 375 }); 376 } 377 378 /** 379 * Subscribe bond state change 380 */ 381 private subscribeBondStateChange() { 382 BluetoothModel.subscribeBondStateChange((data: { 383 deviceId: string; 384 bondState: number; 385 }) => { 386 LogUtil.info(this.TAG + "data.bondState" + JSON.stringify(data.bondState)) 387 //paired devices 388 if (data.bondState !== BondState.BOND_STATE_BONDING) { 389 AppStorage.SetOrCreate("controlPairing", true) 390 this.refreshPairedDevices(); 391 } 392 393 //available devices 394 if (data.bondState == BondState.BOND_STATE_BONDING) { 395 AppStorage.SetOrCreate("controlPairing", false) 396 // case bonding 397 // do nothing and still listening 398 LogUtil.log(this.TAG + 'bluetooth continue listening bondStateChange.'); 399 if (this.getAvailableDevice(data.deviceId) != null) { 400 this.getAvailableDevice(data.deviceId).connectionState = ProfileConnectionState.STATE_CONNECTING; 401 } 402 403 } else if (data.bondState == BondState.BOND_STATE_INVALID) { 404 AppStorage.SetOrCreate("controlPairing", true) 405 // case failed 406 if (this.getAvailableDevice(data.deviceId) != null) { 407 this.getAvailableDevice(data.deviceId).connectionState = ProfileConnectionState.STATE_DISCONNECTED; 408 } 409 this.forceRefresh(this.availableDevices); 410 AppStorage.SetOrCreate('bluetoothAvailableDevices', this.availableDevices); 411 let showFlag = AppStorage.Get('BluetoothFailedDialogFlag'); 412 if (showFlag == false) { 413 AppStorage.SetOrCreate('BluetoothFailedDialogFlag', true); 414 return; 415 } 416 this.showConnectFailedDialog(this.getDevice(data.deviceId).deviceName); 417 } else if (data.bondState == BondState.BOND_STATE_BONDED) { 418 // case success 419 LogUtil.log(this.TAG + 'bluetooth bonded : remove device.'); 420 this.removeAvailableDevice(data.deviceId); 421 BluetoothModel.connectDevice(data.deviceId); 422 } 423 424 }); 425 } 426 427 /** 428 * Subscribe device connect state change 429 */ 430 private subscribeDeviceConnectStateChange() { 431 BluetoothModel.subscribeDeviceStateChange((data: { 432 profileId: number; 433 deviceId: string; 434 profileConnectionState: number; 435 }) => { 436 LogUtil.log(this.TAG + 'device connection state changed. profileId:' + JSON.stringify(data.profileId) 437 + ' profileConnectionState: ' + JSON.stringify(data.profileConnectionState)); 438 for (let device of this.pairedDevices) { 439 if (device.deviceId === data.deviceId) { 440 device.setProfile(data); 441 this.sortPairedDevices(); 442 AppStorage.SetOrCreate('bluetoothPairedDevices', this.pairedDevices); 443 if (data.profileId === constant.ProfileId.PROFILE_A2DP_SOURCE) { 444 let innerEvent: emitter.InnerEvent = { 445 eventId: constant.ProfileId.PROFILE_A2DP_SOURCE 446 }; 447 LogUtil.info('constant.ProfileId.PROFILE_A2DP_SOURCE,data.profileConnectionState,eventData') 448 this.setProfileEventData(data.profileConnectionState); 449 emitter.emit(innerEvent, this.eventData) 450 } 451 else if (data.profileId === constant.ProfileId.PROFILE_HANDSFREE_AUDIO_GATEWAY) { 452 let innerEvent: emitter.InnerEvent = { 453 eventId: constant.ProfileId.PROFILE_HANDSFREE_AUDIO_GATEWAY 454 }; 455 this.setProfileEventData(data.profileConnectionState); 456 LogUtil.info('constant.ProfileId.PROFILE_A2DP_SOURCE,data.profileConnectionState,eventData') 457 emitter.emit(innerEvent, this.eventData) 458 } 459 else if (data.profileId === constant.ProfileId.PROFILE_HID_HOST) { 460 let innerEvent: emitter.InnerEvent = { 461 eventId: constant.ProfileId.PROFILE_HID_HOST 462 }; 463 this.setProfileEventData(data.profileConnectionState); 464 emitter.emit(innerEvent, this.eventData) 465 } else { 466 // Do nothing 467 } 468 break; 469 } 470 }; 471 LogUtil.log(this.TAG + 'device connection state changed. pairedDevices length = ' 472 + JSON.stringify(this.pairedDevices.length)) 473 LogUtil.log(this.TAG + 'device connection state changed. availableDevices length = ' 474 + JSON.stringify(this.availableDevices.length)) 475 this.removeAvailableDevice(data.deviceId); 476 }); 477 } 478 479 //---------------------- private ---------------------- 480 /** 481 * Get device by device id. 482 * @param deviceId device id 483 */ 484 protected getDevice(deviceId: string): BluetoothDevice { 485 let device = new BluetoothDevice(); 486 device.deviceId = deviceId; 487 device.deviceName = BluetoothModel.getDeviceName(deviceId); 488 device.deviceType = BluetoothModel.getDeviceType(deviceId); 489 device.setProfiles(BluetoothModel.getDeviceState(deviceId)); 490 return device; 491 } 492 493 /** 494 * Force refresh array. 495 * Note: the purpose of this function is just trying to fix page (ets) level's bug below, 496 * and should be useless if fixed by the future sdk. 497 * Bug Details: 498 * @State is not supported well for Array<CustomClass> type. 499 * In the case that the array item's field value changed, while not its length, 500 * the build method on page will not be triggered! 501 */ 502 protected forceRefresh(arr: BluetoothDevice[]): void { 503 arr.push(new BluetoothDevice()) 504 arr.pop(); 505 } 506 507 /** 508 * Start bluetooth discovery. 509 */ 510 @Log 511 public startBluetoothDiscovery() { 512 this.isDeviceDiscovering = true; 513 BluetoothModel.startBluetoothDiscovery(); 514 if(this.discoveryStopTimeoutId) { 515 clearTimeout(this.discoveryStopTimeoutId); 516 this.discoveryStopTimeoutId = 0; 517 } 518 this.discoveryStopTimeoutId = setTimeout(() => { 519 this.stopBluetoothDiscovery(); 520 clearTimeout(this.discoveryStopTimeoutId); 521 this.discoveryStopTimeoutId = 0; 522 }, DISCOVERY_DURING_TIME); 523 } 524 525 /** 526 * Stop bluetooth discovery. 527 */ 528 @Log 529 private stopBluetoothDiscovery() { 530 this.isDeviceDiscovering = false; 531 BluetoothModel.stopBluetoothDiscovery(); 532 if(this.discoveryStartTimeoutId) { 533 clearTimeout(this.discoveryStartTimeoutId); 534 this.discoveryStartTimeoutId = 0; 535 } 536 this.discoveryStartTimeoutId = setTimeout(() => { 537 this.startBluetoothDiscovery(); 538 clearTimeout(this.discoveryStartTimeoutId); 539 this.discoveryStartTimeoutId = 0; 540 }, DISCOVERY_INTERVAL_TIME); 541 } 542 543 /** 544 * Stop bluetooth discovery. 545 */ 546 private mStopBluetoothDiscovery() { 547 this.isDeviceDiscovering = false; 548 BluetoothModel.stopBluetoothDiscovery(); 549 if (this.discoveryStartTimeoutId) { 550 clearTimeout(this.discoveryStartTimeoutId); 551 this.discoveryStartTimeoutId = 0; 552 } 553 554 if (this.discoveryStopTimeoutId) { 555 clearTimeout(this.discoveryStopTimeoutId); 556 this.discoveryStopTimeoutId = 0; 557 } 558 } 559 560 561 /** 562 * Get available device. 563 * 564 * @param deviceId device id 565 */ 566 private getAvailableDevice(deviceIds: string): BluetoothDevice { 567 LogUtil.log(this.TAG + 'getAvailableDevice length = ' + this.availableDevices.length); 568 let temp = this.availableDevices; 569 for (let i = 0; i < temp.length; i++) { 570 if (temp[i].deviceId === deviceIds) { 571 return temp[i]; 572 } 573 } 574 return null; 575 } 576 577 /** 578 * Remove available device. 579 * 580 * @param deviceId device id 581 */ 582 private removeAvailableDevice(deviceId: string): void { 583 LogUtil.log(this.TAG + 'removeAvailableDevice : before : availableDevices length = ' + this.availableDevices.length); 584 this.availableDevices = this.availableDevices.filter((device) => device.deviceId !== deviceId) 585 AppStorage.SetOrCreate('bluetoothAvailableDevices', this.availableDevices); 586 LogUtil.log(this.TAG + 'removeAvailableDevice : after : availableDevices length = ' + this.availableDevices.length); 587 } 588 589 /** 590 * Connect Failed Dialog 591 */ 592 private showConnectFailedDialog(deviceName: string) { 593 AlertDialog.show({ 594 title: $r("app.string.bluetooth_connect_failed"), 595 message: $r("app.string.bluetooth_connect_failed_msg", deviceName), 596 confirm: { 597 value: $r("app.string.bluetooth_know_button"), 598 action: () => { 599 LogUtil.info('Button-clicking callback') 600 } 601 }, 602 cancel: () => { 603 LogUtil.info('Closed callbacks') 604 }, 605 alignment: deviceTypeInfo === 'phone' || deviceTypeInfo === 'default' ? DialogAlignment.Bottom : DialogAlignment.Center, 606 offset: ({ 607 dx: 0, dy: deviceTypeInfo === 'phone' || deviceTypeInfo === 'default' ? '-24dp' : 0 608 }) 609 }) 610 611 } 612 613 private setProfileEventData(state: number) { 614 switch (state) { 615 case ProfileConnectionState.STATE_DISCONNECTED: 616 this.eventData = { 617 data: { 618 'State': false, 619 'Enable': true, 620 'Description': '' 621 } 622 } 623 break; 624 case ProfileConnectionState.STATE_CONNECTING: 625 this.eventData = { 626 data: { 627 'State': true, 628 'Enable': false, 629 'Description': $r('app.string.bt_state_connecting') 630 } 631 } 632 break; 633 case ProfileConnectionState.STATE_CONNECTED: 634 this.eventData = { 635 data: { 636 'State': true, 637 'Enable': true, 638 'Description': $r('app.string.bt_state_connected') 639 } 640 } 641 break; 642 case ProfileConnectionState.STATE_DISCONNECTING: 643 this.eventData = { 644 data: { 645 'State': false, 646 'Enable': false, 647 'Description': $r('app.string.bt_state_connected') 648 } 649 } 650 break; 651 default: 652 LogUtil.info('eventData has no value') 653 } 654 } 655}