/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2024-2025. All rights reserved.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* instrument ignore file */
// import hearingAid from '@hms.bluetooth.hearingAid';
import { ArrayList } from '@kit.ArkTS';
import { BusinessError, Callback } from '@ohos.base';
import bluetooth from '@ohos.bluetooth';
import a2dp from '@ohos.bluetooth.a2dp';
import baseProfile from '@ohos.bluetooth.baseProfile';
import connection from '@ohos.bluetooth.connection';
import constant from '@ohos.bluetooth.constant';
import hfp from '@ohos.bluetooth.hfp';
import hid from '@ohos.bluetooth.hid';
import map from '@ohos.bluetooth.map';
import pbap from '@ohos.bluetooth.pbap';
import bluetoothManager from '@ohos.bluetoothManager';
import CommonEvent from '@ohos.commonEvent';
import commonEventManager from '@ohos.commonEventManager';
import { DeviceNameUtil } from '@ohos/settings.common';
import { Controller, PushParam } from '@ohos/settings.common/src/main/ets/core/controller/Controller';
import { SwitchMenuController } from '@ohos/settings.common/src/main/ets/core/controller/MenuController';
import { SwitchMenuStyle } from '@ohos/settings.common/src/main/ets/core/model/menu/BaseMenu';
import { ContainerStyle, TextStyle } from '@ohos/settings.common/src/main/ets/core/model/menu/ComponetStyle';
import { SettingsBaseMenu } from '@ohos/settings.common/src/main/ets/core/model/menu/SettingsMenu';
import { EventBus } from '@ohos/settings.common/src/main/ets/framework/common/EventBus';
import {
  HiSysAboutBluetoothEventGroup,
  HiSysBluetoothEventGroup
} from '@ohos/settings.common/src/main/ets/systemEvent/BehaviorEventConsts';
import { HiSysEventUtil } from '@ohos/settings.common/src/main/ets/systemEvent/HiSysEventUtil';
import { BluetoothUtils, DisconnectCause } from '@ohos/settings.common/src/main/ets/utils/BluetoothUtils';
import { CheckEmptyUtils } from '@ohos/settings.common/src/main/ets/utils/CheckEmptyUtils';
import { CommonEventHelper } from '@ohos/settings.common/src/main/ets/utils/CommonEventHelper';
import { LogMaskUtil, LogUtil } from '@ohos/settings.common/src/main/ets/utils/LogUtil';
import { BluetoothSwitchToggleStyle } from '@ohos/settings.uikit/src/main/ets/menus/Menu';
import {
  BluetoothDevice,
  BondState,
  BondStateParam,
  PinRequiredParam,
  ProfileConnectionState,
  ProfileId,
  StateChangeParam,
  VolumeSyncParam
} from './model/BluetoothModel';
import { isPairOnlyDevice as checkPairOnlyDevice } from './utils/BluetoothPairOnlyUtil';
import { Utils } from './utils/Utils';

const TAG: string = 'BluetoothAdapter : ';
const DELAY_DISCOVERY_STATE_TIME: number = 200;
const DELAY_DISCOVERY_START_TIME_PAIR_FINISH: number = 1000;
const DELAY_DISCOVERY_START_DISCOVERY_TIME: number = 2000;
const DELAY_DISCOVERY_STATE_RETRY_TIME: number = 3000;
const DISCOVERY_RETRY_COUNT: number = 5;
const PROFILE_A2DP_SOURCE: number = 1;
const PROFILE_HANDS_FREE_AUDIO_GATEWAY: number = 4;
const PROFILE_HID_HOST: number = 6;
const PROFILE_HEARING_AID: number = 21;
const CONNECT_RESULT_SUCCESS: number = 1;
const CONNECT_RESULT_FAILED: number = -1;
const A2DP_DEVICE_KEY: string = 'a2dp_device_key';
const HID_DEVICE_KEY: string = 'hid_device_key';
const HFP_DEVICE_KEY: string = 'hfp_device_key';
const HEIGHT_64: string = '64vp';
const HEIGHT_48: string = '48vp';
const FRESH_TITLE_TIME_OUT: number = 200;
const FRESH_PROFILE_TIME_OUT: number = 1000;
const CONNECT_TASK_TIME_OUT: number = 3000;
const HEARINGAID_CONNECT_TASK_TIME_OUT: number = 15000;

export type ConnectionProfile = a2dp.A2dpSourceProfile | hfp.HandsFreeAudioGatewayProfile | hid.HidHostProfile;

export type PbapServerProfile = pbap.PbapServerProfile

export type MapMseProfile = map.MapMseProfile

export enum ConnectionStrategy {
  CONNECTION_STRATEGY_UNSUPPORTED = 0,
  CONNECTION_STRATEGY_ALLOWED = 1,
  CONNECTION_STRATEGY_FORBIDDEN = 2,
}

export enum BluetoothPinRequiredConfirmType {
  DevicePinCode = 1,
  DevicePairingConfirmation = 2,
  DefaultConfirm = 3
}

enum SummaryStatus {
  OPERATING = 'operating',
  DONE = 'done',
}

/**
 * 蓝牙开关状态监听接口
 *
 * @since 2022-05-20
 */
export interface BluetoothStateChangeListener {

  getListenKey(): string;

  /**
   * 蓝牙开关状态变化回调
   */
  onBluetoothStateChange(state: number): void;
}

export interface BluetoothRemoveSummaryListener {

  getListenKey(): string;

  /**
   * 蓝牙开关状态变化回调
   */
  onRemoveSummary(deviceId: string): void;
}

/**
 * 蓝牙远端设备状态监听接口
 *
 * @since 2022-05-20
 */
export interface BluetoothDeviceChangeListener {

  getListenKey(): string;

  /**
   * 设备新增回调
   */
  onDeviceAdded(device: BluetoothDevice): void;

  /**
   * 设备属性刷新回调
   */
  onDeviceAttributesChanged(device: BluetoothDevice): void;

  /**
   * 设备删除回调
   */
  onDeviceDeleted(device: BluetoothDevice): void;

  /**
   * 可用设备刷新回调
   */
  onAvailableDevicesRefresh(): void;

  /**
   * 清空可用设备回调
   */
  onAvailableDeviceClear(): void;
}

/**
 * 已配对设备变化监听
 * @since 2025-07-15
 */
export interface BluetoothBondedDeviceChangeListener {

  getListenKey(): string;

  /**
   * 已配对的设备合并
   *
   * @param device 被合并的设备(指被删除)
   */
  onBondedDeviceMerged(device: BluetoothDevice): void;
}

export interface BluetoothDeviceNameUpdateListener {

  getListenKey(): string;

  /**
   * 设备名称更新回调
   */
  onDeviceNameUpdate(device: BluetoothDevice): void;
}

/**
 * 蓝牙设备配对状态监听接口
 *
 * @since 2022-05-20
 */
export interface BluetoothBondChangeListener {

  getListenKey(): string;

  /**
   * 蓝牙配对状态变化回调
   */
  onBluetoothBondStateChange(stateParam: BondStateParam): void;

  /**
   * 配对请求回退
   */
  onBluetoothPinRequired(pinRequiredParam: PinRequiredParam): void;

  /**
   * 配对结果回退
   */
  onPairResult(deviceId: string, result: number, isSuccess: boolean): void;
}

export interface BluetoothLoadStateChangeListener {

  getListenKey(): string;

  /**
   * 加载动画状态回调
   */
  onChangeLoadingStatus(status: boolean): void;
}

/**
 * 蓝牙设备协议连接状态监听接口
 *
 * @since 2022-05-20
 */
export interface BluetoothProfileStateChangeListener {

  getListenKey(): string;

  /**
   * 协议连接状态变化回退
   */
  onBluetoothProfileStateChange(profileId: ProfileId, stateChangeParam: StateChangeParam): void;

  /**
   * 连接结果回退
   */
  onConnectResult(deviceId: string, result: number, isSuccess: boolean): void;
}

/**
 * 蓝牙设备缓存管理
 *
 * @since 2022-05-20
 */
export class CachedBluetoothDeviceManager {
  private cachedDevices: Map<string, BluetoothDevice> = new Map();

  getCachedDevices(): IterableIterator<BluetoothDevice> {
    return this.cachedDevices.values();
  }

  findDevice(deviceId: string): BluetoothDevice {
    return this.cachedDevices.get(deviceId) as BluetoothDevice;
  }

  /**
   * 添加设备到缓存,是个新设备则返回true,附属设备返回false
   *
   * @param device 要添加的网络
   */
  addDevice(device: BluetoothDevice): boolean {
    if (device && device.deviceId) {
      this.cachedDevices.set(device.deviceId, device);
    }
    return true;
  }

  /**
   * 获取缓存列表的个数
   *
   * @returns 缓存列表的个数
   */
  getDeviceCount(): number {
    return this.cachedDevices.size;
  }

  removeDevice(deviceId: string): boolean {
    return this.cachedDevices.delete(deviceId);
  }

  clear(): void {
    this.cachedDevices.clear();
  }
}

/**
 * 标记设置主动配对的蓝牙外设
 *
 * @since 2024-10-09
 */
export class ConnectTimestampManager {
  private bondedFromLocalMap: Map<string, boolean> = new Map();
  private connectTimestampMap: Map<string, number> = new Map();

  getDeviceBondedFromLocalDevices(): IterableIterator<string> {
    return this.bondedFromLocalMap.keys();
  }

  setDeviceBondedFromLocal(deviceId: string): void {
    this.bondedFromLocalMap.set(deviceId, true);
  }

  checkIsBondedFromLocal(deviceId: string): boolean {
    return this.bondedFromLocalMap.has(deviceId);
  }

  resetDeviceBondedFromLocal(deviceId: string): void {
    this.bondedFromLocalMap.delete(deviceId);
  }

  setDeviceConnectTimestamp(deviceId: string, timestamp: number): void {
    this.connectTimestampMap.set(deviceId, timestamp);
  }

  getDeviceConnectTimestamp(deviceId: string): number {
    return this.connectTimestampMap.get(deviceId) ?? 0;
  }

  resetDeviceConnectTimestamp(deviceId: string): void {
    this.connectTimestampMap.delete(deviceId);
  }

  checkDeviceConnectTimestampValid(deviceId: string, checkedTimeout: number): boolean {
    if (!this.connectTimestampMap.has(deviceId)) {
      return false;
    }

    return new Date().getTime() - (this.connectTimestampMap.get(deviceId) ?? 0) <= checkedTimeout;
  }
}

/**
 * 蓝牙配对监听接口
 *
 * @since 2022-05-20
 */
export interface BluetoothPairListener {
  /**
   * 配对结果回退
   */
  onPairResult(deviceId: string, result: number, isSuccess: boolean): void;
}

/**
 * 蓝牙连接监听接口
 *
 * @since 2022-05-20
 */
export interface BluetoothConnectListener {
  /**
   * 连接结果回退
   */
  onConnectResult(deviceId: string, result: number, isSuccess: boolean): void;
}

/**
 * 蓝牙协议基类
 *
 * @since 2022-05-20
 */
export class BluetoothProfile {
  public lastState: ProfileConnectionState | null = null;
  public listener: BluetoothProfileStateChangeListener;
  public profile?: bluetoothManager.A2dpSourceProfile | bluetoothManager.HandsFreeAudioGatewayProfile |
  bluetoothManager.HidHostProfile | bluetoothManager.PanProfile;
  public tag: string = 'BluetoothProfile';
  public connectionStrategyProfile: ConnectionProfile | null = null;

  constructor(listener: BluetoothProfileStateChangeListener) {
    this.listener = listener;
    try {
      if (BluetoothUtils.isBluetoothStateOn(BluetoothAdapter.getInstance().currentState)) {
        this.lastState = bluetoothManager.getProfileConnectionState(this.getProfileId());
      }
    } catch (err) {
      LogUtil.error(`${TAG} getProfileConnectionState failed, err is code: ${err?.code} message: ${err?.message}`);
    }
    try {
      this.profile = bluetoothManager.getProfileInstance(this.getProfileId());
    } catch (err) {
      LogUtil.error(`${TAG} getProfileInstance failed, err is code: ${err?.code} message: ${err?.message}`);
    }
  }

  setLastState(): void {
    try {
      LogUtil.info(`${TAG} get lastState profileId : ${this.getProfileId()}`);
      this.lastState = bluetoothManager.getProfileConnectionState(this.getProfileId());
    } catch (err) {
      LogUtil.error(`${TAG} getProfileConnectionState failed, err is code: ${err?.code} message: ${err?.message}`);
    }
  }


  initConnectionProfile(): void {
    LogUtil.info(`${this.tag} default initConnectionProfile`);
    try {
      this.connectionStrategyProfile = a2dp.createA2dpSrcProfile();
    } catch (err) {
      LogUtil.error(`${TAG} createA2dpSrcProfile failed, err is code: ${err?.code} message: ${err?.message}`);
    }
  }

  public onProfileStateChange = (state: StateChangeParam) => {
    if (!state) {
      return;
    }
    LogUtil.info(`${this.tag} onProfileStateChange, deviceId: ${BluetoothUtils.getLogMAC(state?.deviceId)}, state : ${state?.state}`);
    this.listener.onBluetoothProfileStateChange(this.getProfileId(), state);
    this.lastState = state.state;
  }

  getProfileId(): number {
    return 0;
  }

  start(): void {
    try {
      if (!this.connectionStrategyProfile) {
        this.connectionStrategyProfile = a2dp.createA2dpSrcProfile();
      }
      this.connectionStrategyProfile.on('connectionStateChange',
        this.onProfileStateChange as Callback<baseProfile.StateChangeParam>);
    } catch (err) {
      LogUtil.error(`${TAG} start failed, err is code: ${err?.code} message: ${err?.message}`);
    }
  }

  stop(): void {
    try {
      if (!this.connectionStrategyProfile) {
        this.connectionStrategyProfile = a2dp.createA2dpSrcProfile();
      }
      this.connectionStrategyProfile.off('connectionStateChange',
        this.onProfileStateChange as Callback<baseProfile.StateChangeParam>);
    } catch (err) {
      LogUtil.error(`${TAG} stop failed, err is code: ${err?.code} message: ${err?.message}`);
    }
  }

  connect(deviceId: string): boolean {
    try {
      (this.profile as bluetoothManager.A2dpSourceProfile | bluetoothManager.HandsFreeAudioGatewayProfile |
      bluetoothManager.HidHostProfile)?.connect(deviceId);
      return true;
    } catch (err) {
      LogUtil.error(`${TAG} connect failed, err is code: ${err?.code} message: ${err?.message}`);
      return false;
    }
  }

  disconnect(deviceId: string): boolean {
    try {
      this.profile?.disconnect(deviceId);
      return true;
    } catch (err) {
      LogUtil.error(`${TAG} connect failed, code: ${err?.code} message: ${err?.message}`);
      return false;
    }
  }

  getDeviceState(deviceId: string): ProfileConnectionState {
    let deviceState: ProfileConnectionState = ProfileConnectionState.STATE_DISCONNECTED;
    try {
      if (this.profile) {
        deviceState = this.profile?.getDeviceState(deviceId);
      }
    } catch (err) {
      LogUtil.error(`${TAG} getDeviceState failed, code: ${err?.code} message: ${err?.message}`);
    }
    return deviceState;
  }

  getConnectionState(deviceId: string): ProfileConnectionState {
    let connectionState: ProfileConnectionState = ProfileConnectionState.STATE_DISCONNECTED;
    try {
      if (this.connectionStrategyProfile) {
        connectionState = this.connectionStrategyProfile?.getConnectionState(deviceId);
      }
    } catch (err) {
      LogUtil.error(`${TAG} getConnectionState failed, code: ${err?.code} message: ${err?.message}`);
    }
    return connectionState;
  }

  async getConnectionStrategy(deviceId: string): Promise<ConnectionStrategy> {
    let connectionStrategy: ConnectionStrategy = ConnectionStrategy.CONNECTION_STRATEGY_UNSUPPORTED;
    try {
      if (this.connectionStrategyProfile) {
        let status = this.getDeviceState(deviceId)
        if (status === 2) {
          return Promise.resolve(ConnectionStrategy.CONNECTION_STRATEGY_ALLOWED)
        } else {
          connectionStrategy = await this.connectionStrategyProfile?.getConnectionStrategy(deviceId);
        }
      }
    } catch (err) {
      LogUtil.error(`${TAG} getConnectionStrategy failed, code: ${err?.code} message: ${err?.message}`);
    }
    return connectionStrategy;
  }

  async setConnectionStrategy(deviceId: string, strategy: ConnectionStrategy): Promise<void> {
    if (this.connectionStrategyProfile) {
      return this.connectionStrategyProfile.setConnectionStrategy(deviceId, strategy);
    }
  }
}

/**
 * 助听器蓝牙协议类
 *
 * @since 2025-07-01
 */
// export class HearingAidProfile extends BluetoothProfile {
//   public tag: string = 'HearingAidProfile';
//   // public hearingAidProfile: hearingAid.HearingAidSourceProfile | null = null;
//   // public onHearingAidProfileChange = (hearingAidState: hearingAid.HearingAidStateChangeParam) => {
//   //   if (!hearingAidState) {
//   //     return;
//   //   }
//   //   LogUtil.info(`${this.tag} onProfileStateChange, deviceId: ${BluetoothUtils.getLogMAC(hearingAidState?.deviceId)}, state : ${hearingAidState?.state}`);
//   //   let profileState: ProfileConnectionState = this.convertFromHearingAidState(hearingAidState?.state);
//   //   let stateParam: StateChangeParam = {
//   //     deviceId: hearingAidState?.deviceId,
//   //     state: profileState,
//   //     cause: DisconnectCause.USER_DISCONNECT
//   //   }
//   //   this.listener.onBluetoothProfileStateChange(this.getProfileId(), stateParam);
//   //   this.lastState = profileState;
//   // }
//
//   constructor(listener: BluetoothProfileStateChangeListener) {
//     super(listener);
//   }
//
//   initConnectionProfile(): void {
//     LogUtil.info(`${this.tag} default initConnectionProfile`);
//     try {
//       // this.hearingAidProfile = hearingAid.createHearingAidSrcProfile();
//     } catch (err) {
//       LogUtil.error(`${TAG} createHearingAidSrcProfile failed, err is code: ${err?.code} message: ${err?.message}`);
//     }
//   }
//
//   getProfileId(): ProfileId {
//     return PROFILE_HEARING_AID;
//   }
//
//   // private convertFromHearingAidState(state: hearingAid.HearingAidConnectionState): ProfileConnectionState {
//   //   switch (state) {
//   //     case hearingAid.HearingAidConnectionState.STATE_DISCONNECTED:
//   //       return ProfileConnectionState.STATE_DISCONNECTED;
//   //     case hearingAid.HearingAidConnectionState.STATE_CONNECTING:
//   //       return ProfileConnectionState.STATE_CONNECTING;
//   //     case hearingAid.HearingAidConnectionState.STATE_CONNECTED:
//   //       return ProfileConnectionState.STATE_CONNECTED;
//   //     case hearingAid.HearingAidConnectionState.STATE_DISCONNECTING:
//   //       return ProfileConnectionState.STATE_DISCONNECTING;
//   //     default:
//   //       return ProfileConnectionState.STATE_DISCONNECTED;
//   //   }
//   // }
//
//   // private convertFromHearingAidStrategy(strategy: hearingAid.HearingAidConnectionStrategy): ConnectionStrategy {
//   //   switch (strategy) {
//   //     case hearingAid.HearingAidConnectionStrategy.CONNECTION_STRATEGY_UNSUPPORTED:
//   //       return ConnectionStrategy.CONNECTION_STRATEGY_UNSUPPORTED;
//   //     case hearingAid.HearingAidConnectionStrategy.CONNECTION_STRATEGY_ALLOWED:
//   //       return ConnectionStrategy.CONNECTION_STRATEGY_ALLOWED;
//   //     case hearingAid.HearingAidConnectionStrategy.CONNECTION_STRATEGY_FORBIDDEN:
//   //       return ConnectionStrategy.CONNECTION_STRATEGY_FORBIDDEN;
//   //     default:
//   //       return ConnectionStrategy.CONNECTION_STRATEGY_UNSUPPORTED;
//   //   }
//   // }
//
//   // private convertToHearingAidStrategy(strategy: ConnectionStrategy): hearingAid.HearingAidConnectionStrategy {
//   //   switch (strategy) {
//   //     case ConnectionStrategy.CONNECTION_STRATEGY_UNSUPPORTED:
//   //       return hearingAid.HearingAidConnectionStrategy.CONNECTION_STRATEGY_UNSUPPORTED;
//   //     case ConnectionStrategy.CONNECTION_STRATEGY_ALLOWED:
//   //       return hearingAid.HearingAidConnectionStrategy.CONNECTION_STRATEGY_ALLOWED;
//   //     case ConnectionStrategy.CONNECTION_STRATEGY_FORBIDDEN:
//   //       return hearingAid.HearingAidConnectionStrategy.CONNECTION_STRATEGY_FORBIDDEN;
//   //     default:
//   //       return hearingAid.HearingAidConnectionStrategy.CONNECTION_STRATEGY_UNSUPPORTED;
//   //   }
//   // }
//
//   start(): void {
//     // try {
//     //   if (!this.hearingAidProfile) {
//     //     this.hearingAidProfile = hearingAid.createHearingAidSrcProfile();
//     //   }
//     //   this.hearingAidProfile.on('connectionStateChange', this.onHearingAidProfileChange);
//     // } catch (err) {
//     //   LogUtil.error(`${TAG} start failed, err is code: ${err?.code} message: ${err?.message}`);
//     // }
//   }
//
//   stop(): void {
//     // try {
//     //   if (!this.hearingAidProfile) {
//     //     // this.hearingAidProfile = hearingAid.createHearingAidSrcProfile();
//     //   }
//     //   this.hearingAidProfile.off('connectionStateChange', this.onHearingAidProfileChange);
//     // } catch (err) {
//     //   LogUtil.error(`${TAG} stop failed, err is code: ${err?.code} message: ${err?.message}`);
//     // }
//   }
//
//   connect(deviceId: string): boolean {
//     try {
//       // this.hearingAidProfile?.connect(deviceId);
//       return true;
//     } catch (err) {
//       LogUtil.error(`${TAG} connect failed, err is code: ${err?.code} message: ${err?.message}`);
//       return false;
//     }
//   }
//
//   disconnect(deviceId: string): boolean {
//     try {
//       // this.hearingAidProfile?.disconnect(deviceId);
//       return true;
//     } catch (err) {
//       LogUtil.error(`${TAG} connect failed, code: ${err?.code} message: ${err?.message}`);
//       return false;
//     }
//   }
//
//   getDeviceState(deviceId: string): ProfileConnectionState {
//     let deviceState: ProfileConnectionState = ProfileConnectionState.STATE_DISCONNECTED;
//     try {
//       // if (this.hearingAidProfile) {
//       //   deviceState = this.convertFromHearingAidState(this.hearingAidProfile.getConnectionState(deviceId));
//       // }
//     } catch (err) {
//       LogUtil.error(`${TAG} getDeviceState failed, code: ${err?.code} message: ${err?.message}`);
//     }
//     return deviceState;
//   }
//
//   getConnectionState(deviceId: string): ProfileConnectionState {
//     let connectionState: ProfileConnectionState = ProfileConnectionState.STATE_DISCONNECTED;
//     try {
//       // if (this.hearingAidProfile) {
//       //   connectionState = this.convertFromHearingAidState(this.hearingAidProfile.getConnectionState(deviceId));
//       // }
//     } catch (err) {
//       LogUtil.error(`${TAG} getConnectionState failed, code: ${err?.code} message: ${err?.message}`);
//     }
//     return connectionState;
//   }
//
//   async getConnectionStrategy(deviceId: string): Promise<ConnectionStrategy> {
//     let connectionStrategy: ConnectionStrategy = ConnectionStrategy.CONNECTION_STRATEGY_UNSUPPORTED;
//     try {
//       // if (this.hearingAidProfile) {
//       //   connectionStrategy =
//       //     this.convertFromHearingAidStrategy(await this.hearingAidProfile.getConnectionStrategy(deviceId));
//       // }
//     } catch (err) {
//       LogUtil.error(`${TAG} getConnectionStrategy failed, code: ${err?.code} message: ${err?.message}`);
//     }
//     return connectionStrategy;
//   }
//
//   async setConnectionStrategy(deviceId: string, strategy: ConnectionStrategy): Promise<void> {
//     // if (this.hearingAidProfile) {
//     //   return this.hearingAidProfile.setConnectionStrategy(deviceId, this.convertToHearingAidStrategy(strategy));
//     // }
//   }
//
//   /**
//    * 设置助听器音量
//    *
//    * @param deviceId 设备mac地址
//    * @param volume 音量值
//    */
//   public setVolume(deviceId: string, volume: number): void {
//     try {
//       // this.hearingAidProfile?.setVolume(deviceId, volume);
//     } catch (err) {
//       LogUtil.error(`${TAG} setVolume failed, err is code: ${err?.code} message: ${err?.message}`);
//     }
//   }
//
//   /**
//    * 获取助听器设备信息
//    *
//    * @param deviceId 设备mac地址
//    * @returns 助听器设备信息
//    */
//   // public getHearingAidDeviceInfo(deviceId: string): hearingAid.HearingAidDeviceInfo | undefined {
//   //   let deviceInfo: hearingAid.HearingAidDeviceInfo | undefined = undefined;
//   //   try {
//   //     deviceInfo = this.hearingAidProfile?.getHearingAidDeviceInfo(deviceId);
//   //   } catch (err) {
//   //     LogUtil.error(`${TAG} setVolume failed, err is code: ${err?.code} message: ${err?.message}`);
//   //   }
//   //   return deviceInfo;
//   // }
//
//   /**
//    * 获取助听器左右耳
//    *
//    * @param deviceId 设备mac地址
//    * @returns 左耳或右耳
//    */
//   // public getHearingAidSide(deviceId: string): hearingAid.DeviceSide | undefined {
//   //   let deviceSide: hearingAid.DeviceSide | undefined = undefined;
//   //   try {
//   //     let deviceInfo: hearingAid.HearingAidDeviceInfo | undefined = this.getHearingAidDeviceInfo(deviceId);
//   //     if (deviceInfo) {
//   //       deviceSide = deviceInfo.deviceSide;
//   //     }
//   //   } catch (err) {
//   //     LogUtil.error(`${TAG} getHearingAidSide failed, err is code: ${err?.code} message: ${err?.message}`);
//   //   }
//   //   return deviceSide;
//   // }
//
//   /**
//    * 获取HearingAidId,用于判断两个设备是否为同一套
//    *
//    * @param deviceId 设备mac地址
//    * @returns 设备HearingAidId
//    */
//   public getHearingAidId(deviceId: string): number | undefined {
//     let hearingAidId: number | undefined = undefined;
//     try {
//       // let deviceInfo: hearingAid.HearingAidDeviceInfo | undefined = this.getHearingAidDeviceInfo(deviceId);
//       // if (deviceInfo) {
//       //   hearingAidId = deviceInfo.hearingAidId;
//       // }
//     } catch (err) {
//       LogUtil.error(`${TAG} getHearingAidSide failed, err is code: ${err?.code} message: ${err?.message}`);
//     }
//     return hearingAidId;
//   }
//
//   /**
//    * 本地设备是否支持助听器
//    *
//    * @returns 是否支持助听器
//    */
//   public isLocalDeviceSupportHearingAid(): boolean {
//     if (this.hearingAidProfile) {
//       return this.hearingAidProfile.isLocalDeviceSupportHearingAid()
//     }
//     return false;
//   }
// }

/**
 * A2dp蓝牙协议类
 *
 * @since 2022-05-20
 */
export class A2dpProfile extends BluetoothProfile {
  public tag: string = 'A2dpProfile';

  constructor(listener: BluetoothProfileStateChangeListener) {
    super(listener);
  }

  getProfileId(): ProfileId {
    return PROFILE_A2DP_SOURCE;
  }

  initConnectionProfile(): void {
    LogUtil.info(`${this.tag} initConnectionProfile`);
    try {
      this.connectionStrategyProfile = a2dp.createA2dpSrcProfile();
    } catch (err) {
      LogUtil.error(`${TAG} createA2dpSrcProfile failed, code: ${err?.code} message: ${err?.message}`);
    }
  }
}

/**
 * Hfp蓝牙协议类
 *
 * @since 2022-05-20
 */
export class HfpProfile extends BluetoothProfile {
  public tag: string = 'HfpProfile';

  constructor(listener: BluetoothProfileStateChangeListener) {
    super(listener);
  }

  getProfileId(): ProfileId {
    return PROFILE_HANDS_FREE_AUDIO_GATEWAY;
  }

  initConnectionProfile(): void {
    LogUtil.info(`${this.tag} default initConnectionProfile`);
    try {
      this.connectionStrategyProfile = hfp.createHfpAgProfile();
    } catch (err) {
      LogUtil.error(`${TAG} createHfpAgProfile failed, code: ${err?.code} message: ${err?.message}`);
    }
  }
}

/**
 * Hid蓝牙协议类
 *
 * @since 2022-06-06
 */
export class HidProfile extends BluetoothProfile {
  public tag: string = 'HidProfile';

  constructor(listener: BluetoothProfileStateChangeListener) {
    super(listener);
  }

  getProfileId(): ProfileId {
    return PROFILE_HID_HOST;
  }

  initConnectionProfile(): void {
    LogUtil.info(`${this.tag} default initConnectionProfile`);
    try {
      this.connectionStrategyProfile = hid.createHidHostProfile();
    } catch (err) {
      LogUtil.error(`${TAG} createHidHostProfile failed, code: ${err?.code} message: ${err?.message}`);
    }
  }
}

/**
 * 蓝牙协议管理类
 *
 * @since 2022-05-20
 */
export class BluetoothProfileManager implements BluetoothProfileStateChangeListener {
  public static readonly CONNECT_TIMEOUT: number = 60000; // 60秒
  public readonly tag: string = 'BluetoothProfileManager : ';
  public isStart: boolean = false;
  public profiles: Map<ProfileId, BluetoothProfile> = new Map();
  public pbapProfile: pbap.PbapServerProfile | null = null;
  public mapProfile: map.MapMseProfile | null = null;
  public listener: BluetoothProfileStateChangeListener | null = null;
  // 连接管理使用变量
  public connectDeviceId: ArrayList<string> = new ArrayList();
  public connectListener: BluetoothConnectListener | null = null;
  public timerId: number | null = null;

  /**
   * 发起连接
   *
   * @param deviceId 连接的设备ID
   * @param listener 连接结果回调
   */
  startConnect(deviceId: string, listener?: BluetoothConnectListener, subDeviceId?: string): boolean {
    LogUtil.info(`${this.tag} startConnect. deviceId:${BluetoothUtils.getLogMAC(deviceId)}`);
    if (!deviceId) {
      LogUtil.error(`${this.tag} startConnect empty param`);
      return false;
    }
    if (checkPairOnlyDevice(deviceId) || (subDeviceId && checkPairOnlyDevice(subDeviceId))) {
      LogUtil.info(`${this.tag} pair only device, skip profileManager.startConnect`);
      return true;
    }
    this.finishConnect();
    this.connectDeviceId.add(deviceId);
    if (subDeviceId) {
      this.connectDeviceId.add(subDeviceId);
    }
    this.connectListener = listener as BluetoothConnectListener;

    this.timerId = setTimeout(() => {
      LogUtil.info(`${this.tag} connect timeout`);
      this.timerId = null;
      this.handleConnectTimeout();
    }, BluetoothPairManager.PAIR_TIMEOUT);

    let result = this.connectToDeviceId(deviceId);
    if (!result) {
      this.dispatchConnectResult(deviceId, false, CONNECT_RESULT_FAILED);
    }
    if (subDeviceId) {
      let subResult = this.connectToDeviceId(subDeviceId);
      if (!subResult) {
        this.dispatchConnectResult(subDeviceId, false, CONNECT_RESULT_FAILED);
      }
      result = result || subResult;
    }
    return result;
  }

  getListenKey(): string {
    return this.tag;
  }

  private handleConnectTimeout() {
    this.connectDeviceId.forEach(connectId => {
      this.dispatchConnectResult(connectId, false, CONNECT_RESULT_FAILED);
    });
  }

  private dispatchConnectResult(deviceId: string, isSuccess: boolean, result: number): void {
    this.connectListener?.onConnectResult(deviceId, result, isSuccess);
    this.connectDeviceId.remove(deviceId);
    if (this.connectDeviceId.isEmpty()) {
      this.finishConnect();
    }
  }

  finishConnect(): void {
    if (this.timerId != null) {
      clearTimeout(this.timerId);
      this.timerId = null;
    }
    this.connectDeviceId.clear();
    this.connectListener = null;
  }

  getProfileState(profileId: ProfileId, deviceId: string): ProfileConnectionState {
    let deviceState = ProfileConnectionState.STATE_DISCONNECTED;
    try {
      deviceState =
        this.profiles.get(profileId)?.getConnectionState(deviceId) as ProfileConnectionState;
      LogUtil.info(`${this.tag} profileId ${profileId} deviceState ${deviceState}`);
    } catch (err) {
      LogUtil.error(`${this.tag} getDeviceState failed, code: ${err?.code} message: ${err?.message}`);
    }
    return deviceState;
  }

  isDeviceConnected(deviceId: string): boolean {
    LogUtil.info(`${this.tag} isDeviceConnected`);
    if (!deviceId) {
      LogUtil.error(`${this.tag} isDeviceConnected empty param`);
      return false;
    }
    let flag: boolean = false;
    this.profiles.forEach((bluetoothProfile: BluetoothProfile, key: ProfileId) => {
      if (bluetoothProfile.getDeviceState(deviceId) === ProfileConnectionState.STATE_CONNECTED) {
        flag = true
        return;
      }
    })
    LogUtil.info(`${this.tag} isDeviceConnected. flag:${flag}`);
    return flag;
  }

  isDeviceConnecting(deviceId: string): boolean {
    if (!deviceId) {
      LogUtil.error(`${this.tag} isDeviceConnecting empty param`);
      return false;
    }
    let flag: boolean = false;
    this.profiles.forEach((bluetoothProfile: BluetoothProfile, key: ProfileId) => {
      if (bluetoothProfile.getDeviceState(deviceId) === ProfileConnectionState.STATE_CONNECTING) {
        flag = true
      }
    })
    return flag;
  }

  isDeviceConnectedOrConnecting(deviceId: string): boolean {
    if (!deviceId) {
      LogUtil.error(`${this.tag} isDeviceConnectedOrConnecting empty param`);
      return false;
    }
    let flag: boolean = false;
    this.profiles.forEach((bluetoothProfile: BluetoothProfile, key: ProfileId) => {
      let state = bluetoothProfile.getDeviceState(deviceId);
      if (state === ProfileConnectionState.STATE_CONNECTED || state === ProfileConnectionState.STATE_CONNECTING) {
        flag = true
      }
    })
    return flag;
  }

  /**
   * 是否所有profile都断连
   *
   * @param deviceId deviceId
   * @returns true:全部断连
   */
  isAllProfileDisconnected(deviceId: string): boolean {
    let isAllDisconnected = true;
    this.profiles.forEach((bluetoothProfile: BluetoothProfile, key: ProfileId) => {
      if (bluetoothProfile.getDeviceState(deviceId) != ProfileConnectionState.STATE_DISCONNECTED) {
        isAllDisconnected = false;
      }
    })
    return isAllDisconnected;
  }

  private connectToDeviceId(deviceId: string): boolean {
    LogUtil.info(`${this.tag} connectToDeviceId, deviceId:${BluetoothUtils.getLogMAC(deviceId)}`);
    let result = false;
    try {
      // connection.connectAllowedProfiles(deviceId);
      this.profiles.forEach((profile, key) => {
        if (profile) {
          let profileConnectionState = profile.getDeviceState(deviceId);
          LogUtil.info(` connectToDeviceId , connectionState = ${profileConnectionState}`);
          try {
            profile.connect(deviceId);
          } catch (BusinessError) {
            LogUtil.info(` connectToDeviceId failed. BusinessError is  ` + JSON.stringify(BusinessError));
          }
        }
      })
      result = true;
    } catch (err) {
      LogUtil.error(`${this.tag} connectToDeviceId. connectAllowedProfiles failed. code:${err?.code} message:${err?.message}`);
    }
    LogUtil.info(`${TAG} connectToDeviceId. result:${result}`);
    return result;
  }

  /**
   * 断开连接
   *
   * @param deviceId 要断开的设备ID
   */
  disconnectDevice(deviceId: string): boolean {
    if (!deviceId) {
      LogUtil.error(`${this.tag} disconnectDevice empty param`);
      return false;
    }
    let result = false;
    try {
      LogUtil.info(`${this.tag} disconnectDevice. deviceId:${BluetoothUtils.getLogMAC(deviceId)}`);
      // connection.disconnectAllowedProfiles(deviceId);
      this.profiles.forEach((profile, key) => {
        if (profile) {
          let profileConnectionState = profile.getDeviceState(deviceId);
          LogUtil.info(` disconnectDevice , connectionState = ${profileConnectionState}`);
          if (profileConnectionState === 2 || profileConnectionState === 1) {
            try {
              profile.disconnect(deviceId);
            } catch (BusinessError) {
              LogUtil.info(` disconnect failed. BusinessError is  ` + JSON.stringify(BusinessError));
            }
          }
        }
      })
      result = true;
    } catch (err) {
      LogUtil.error(`${this.tag} disconnectDevice disconnectAllowedProfiles failed. code:${err?.code} message:${err?.message}`);
    }
    return result;
  }

  /**
   * disconnect profile.
   * @param deviceId device id
   * @param profileId profile id
   */
  disconnectProfile(deviceId: string | undefined, profileId: number): void {
    const profile = this.profiles.get(profileId)
    if (profile) {
      let profileConnectionState = profile.getDeviceState(deviceId!);
      LogUtil.info(` disconnectProfile , connectionState = ${profileConnectionState}`);
      if (profileConnectionState === 2 || profileConnectionState === 1) {
        try {
          profile.disconnect(deviceId!);
        } catch (BusinessError) {
          LogUtil.info(` disconnectProfile failed. BusinessError is  ` + JSON.stringify(BusinessError));
        }
      }
    }
  }

  connectProfile(deviceId: string, profileId: number): void {
    if (checkPairOnlyDevice(deviceId)) {
      LogUtil.info(`${this.tag} pair only device, skip connectProfile profileId:${profileId}`);
      return;
    }
    const profile = this.profiles.get(profileId)
    if (profile) {
      let profileConnectionState = profile.getDeviceState(deviceId!);
      LogUtil.info(` connectProfile , connectionState = ${profileConnectionState}`);
      try {
        if (profileConnectionState === ProfileConnectionState.STATE_DISCONNECTED || profileConnectionState === ProfileConnectionState.STATE_DISCONNECTING) {
          profile.connect(deviceId)
        }
      } catch (BusinessError) {
        LogUtil.info(` connectProfile failed. BusinessError is  ` + JSON.stringify(BusinessError));
      }
    }
  }


  onBluetoothProfileStateChange(profileId: ProfileId, stateChangeParam: StateChangeParam): void {
    if (!stateChangeParam) {
      return;
    }
    LogUtil.info(`${this.tag} onBluetoothProfileStateChange. deviceId:${BluetoothUtils.getLogMAC(stateChangeParam.deviceId)} profileId:${profileId} state:${stateChangeParam.state} cause:${stateChangeParam.cause}`);
    this.listener?.onBluetoothProfileStateChange(profileId, stateChangeParam);
    if (!this.connectDeviceId.has(stateChangeParam.deviceId)) {
      return;
    }
    if (stateChangeParam.state === ProfileConnectionState.STATE_CONNECTED) {
      this.dispatchConnectResult(stateChangeParam.deviceId, true, CONNECT_RESULT_SUCCESS);
      return;
    }
    if (stateChangeParam.cause === DisconnectCause.TOO_MANY_CONNECTED_DEVICES &&
      stateChangeParam.state === ProfileConnectionState.STATE_DISCONNECTED) {
      this.dispatchConnectResult(stateChangeParam.deviceId, false, DisconnectCause.TOO_MANY_CONNECTED_DEVICES);
      return;
    }
    let profile: BluetoothProfile = this.profiles.get(profileId) as BluetoothProfile;
    if (this.connectDeviceId.has(stateChangeParam.deviceId) &&
      stateChangeParam.state === ProfileConnectionState.STATE_DISCONNECTED) {
      if (this.isAllProfileDisconnected(stateChangeParam.deviceId)) {
        // 连接失败
        this.dispatchConnectResult(stateChangeParam.deviceId, false, stateChangeParam.cause);
      }
    }
  }

  onConnectResult(deviceId: string, result: number, isSuccess: boolean): void {
  }

  /**
   * 开始生命周期
   *
   * @param listener 连接结果监听者
   */
  start(listener: BluetoothProfileStateChangeListener): void {
    if (!this.isStart) {
      this.isStart = true;
      LogUtil.info(`${this.tag} start`);
      this.listener = listener;

      // 在此处添加HfpProfile或者其他协议;
      this.profiles.set(PROFILE_HANDS_FREE_AUDIO_GATEWAY, new HfpProfile(this));
      this.profiles.set(PROFILE_HID_HOST, new HidProfile(this));
      this.profiles.set(PROFILE_A2DP_SOURCE, new A2dpProfile(this));
      // this.profiles.set(PROFILE_HEARING_AID, new HearingAidProfile(this));

      this.profiles.forEach((bluetoothProfile: BluetoothProfile, key: ProfileId) => {
        try {
          bluetoothProfile.initConnectionProfile();
          bluetoothProfile?.start();
        } catch (errData) {
          LogUtil.error(`${this.tag} bluetoothProfile.start failed. code:${errData?.code} message:${errData?.message}`);
        }
      })
      try {
        this.pbapProfile = pbap.createPbapServerProfile();
        LogUtil.error(`${this.tag} createPbapServerProfile successed.`);
        this.mapProfile = map.createMapMseProfile();
        LogUtil.error(`${this.tag} createMapMseProfile successed.`);
      } catch (errData) {
        LogUtil.error(`${this.tag} createProfile failed. code:${errData?.code} message:${errData?.message}`);
      }
      LogUtil.info(`${this.tag} start end`);
    }
  }

  /**
   * 停止生命周期
   */
  stop(): void {
    if (this.isStart) {
      LogUtil.info(`${this.tag} BluetoothProfileManager stop`);
      this.listener = null;
      this.profiles.forEach((bluetoothProfile: BluetoothProfile, key: ProfileId) => {
        try {
          bluetoothProfile?.stop();
        } catch (errData) {
          LogUtil.error(`${this.tag} bluetoothProfile?.stop failed. code:${errData?.code} message:${errData?.message}`);
        }
      })
      this.profiles.clear();
      this.finishConnect();
      this.isStart = false;
      LogUtil.info(`${this.tag} BluetoothProfileManager stop end`);
    }
  }
}

/**
 * 蓝牙配对管理类
 *
 * @since 2022-05-20
 */
export class BluetoothPairManager {
  public static readonly PAIR_TIMEOUT: number = 60000; // 60秒
  public readonly tag: string = 'BluetoothPairManager : ';
  public pairDeviceId: string | null = null;
  public listener: BluetoothPairListener | null = null;
  public timerId: number | null = null;

  /**
   * 发起配对流程
   *
   * @param deviceId 要配对ed设备ID
   * @param listener 配对结果监听者
   */
  startPair(deviceId: string, listener?: BluetoothPairListener): boolean {
    if (!deviceId) {
      LogUtil.error(`${this.tag} startPair empty param`);
      return false;
    }
    this.finishPair();
    this.pairDeviceId = deviceId;
    this.listener = listener as BluetoothPairListener;

    this.timerId = setTimeout(() => {
      LogUtil.info(`${this.tag} pair timeout`);
      this.timerId = null;
      this.dispatchPairResult(false, -1);
    }, BluetoothPairManager.PAIR_TIMEOUT);
    try {
      connection.pairDevice(this.pairDeviceId);
    } catch (error) {
      LogUtil.error(`${this.tag} pairDevice error, ${error?.message}`);
      return false;
    }
    return true;
  }

  setPairDeviceId(deviceId: string): void {
    LogUtil.info(`${this.tag} setPairDeviceId. deviceId:${BluetoothUtils.getLogMAC(deviceId)}`);
    this.pairDeviceId = deviceId;
  }

  setListener(listener: BluetoothPairListener): void {
    LogUtil.info(`${this.tag} setListener`);
    if (this.listener === null) {
      this.listener = listener;
    }
  }

  onDevicePairingConfirmation(deviceId: string, isAccept: boolean): void {
    if (!this.pairDeviceId || deviceId != this.pairDeviceId) {
      return;
    }

    if (!isAccept) {
      this.finishPair();
    }
  }

  onBluetoothBondStateChange(stateParam: BondStateParam): void {
    if (!stateParam) {
      return;
    }
    if (!this.pairDeviceId || stateParam.deviceId != this.pairDeviceId) {
      LogUtil.info(`${this.tag} check false`);
      return;
    }

    if (stateParam.state === BondState.BOND_STATE_BONDED) {
      // 配对成功
      this.dispatchPairResult(true, 1);
      return;
    }

    if (stateParam.state === BondState.BOND_STATE_INVALID) {
      // 配对失败
      LogUtil.info(`${this.tag} onBluetoothBondStateChange. pair failed. code:${stateParam.cause}`);
      this.dispatchPairResult(false, stateParam.cause);
      return;
    }
  }

  private dispatchPairResult(isSuccess: boolean, result: number): void {
    this.listener?.onPairResult(this.pairDeviceId as string, result, isSuccess);
    LogUtil.info(`${this.tag} dispatchPairResult ${result}`);

    this.finishPair();
  }

  finishPair(): void {
    if (this.timerId != null) {
      clearTimeout(this.timerId);
      this.timerId = null;
    }
    this.pairDeviceId = null;
    this.listener = null;
  }
}

export let bluetoothPairManager = new BluetoothPairManager();

/**
 * 蓝牙功能使用管理类
 *
 * @since 2022-04-25
 */
export class BluetoothAdapter implements BluetoothPairListener, BluetoothProfileStateChangeListener,
BluetoothConnectListener {
  public isBluetoothPageShow: boolean = false;
  public isStart: boolean = false;
  public isDiscovering: boolean = false;
  public isAutoDiscover: boolean = false;
  public isPauseDiscover: boolean = false;
  public retryTime: number = DISCOVERY_RETRY_COUNT;
  public currentState: number = 0;
  public stateChangeListeners: BluetoothStateChangeListener[] = [];
  public deviceChangeListeners: BluetoothDeviceChangeListener[] = [];
  public deviceNameUpdateListeners: BluetoothDeviceNameUpdateListener[] = [];
  public bondChangeListeners: BluetoothBondChangeListener[] = [];
  public profileStateChangeListeners: BluetoothProfileStateChangeListener[] = [];
  public loadingStateChangerListeners: BluetoothLoadStateChangeListener[] = [];
  public bluetoothRemoveSummaryListeners: BluetoothRemoveSummaryListener[] = [];
  public bondedDeviceChangeListeners: BluetoothBondedDeviceChangeListener[] = [];
  public isPairing: boolean = false;
  public connectingIds: ArrayList<string> = new ArrayList();
  public isIgnoreDiscovery: boolean = false;
  public profileManager = new BluetoothProfileManager();
  public cachedManager: CachedBluetoothDeviceManager = new CachedBluetoothDeviceManager();
  public cachedBondedDevices: Map<string, BluetoothDevice> = new Map();
  public localProfileUuids: connection.ProfileUuids[] = [];
  public delayStartDiscoveryTimer: number | null = null;
  public delayStartDiscoveryAfterPairFinishTimer: number | null = null;
  public delayDispatchDeviceRefreshTimer: number | null = null;
  public isPairBluetoothAdapter: boolean = false;
  public bluetoothDevices: connection.DiscoveryResult[] = [];
  public connectTimestampManager: ConnectTimestampManager = new ConnectTimestampManager();

  setIsPairBluetoothAdapter(isPairBluetoothAdapter: boolean) {
    LogUtil.info(`${TAG} setIsPairBluetoothAdapter: ${isPairBluetoothAdapter}`);
    this.isPairBluetoothAdapter = isPairBluetoothAdapter;
  }

  setIsIgnoreDiscovery(isIgnoreDiscovery: boolean): void {
    LogUtil.info(`${TAG} setIsIgnoreDiscovery isIgnoreDiscovery: ${isIgnoreDiscovery}`);
    this.isIgnoreDiscovery = isIgnoreDiscovery;
  }

  getListenKey(): string {
    return TAG;
  }

  //订阅者信息
  public discoveryFinishedSubscribeInfo: commonEventManager.CommonEventSubscribeInfo = {
    events: [CommonEvent.Support.COMMON_EVENT_BLUETOOTH_HOST_DISCOVERY_FINISHED],
  };
  public discoveryStartedSubscribeInfo: commonEventManager.CommonEventSubscribeInfo = {
    events: [CommonEvent.Support.COMMON_EVENT_BLUETOOTH_HOST_DISCOVERY_STARTED],
  };
  public discoveryRemoteDeviceUUIDInfo: commonEventManager.CommonEventSubscribeInfo = {
    events: [CommonEvent.Support.COMMON_EVENT_BLUETOOTH_REMOTEDEVICE_UUID_VALUE],
  };
  public updateRemoteDeviceName: commonEventManager.CommonEventSubscribeInfo = {
    events: [CommonEvent.Support.COMMON_EVENT_BLUETOOTH_REMOTEDEVICE_NAME_UPDATE],
  };
  public updateRemoteDeviceNameCommonEvent =
    new CommonEventHelper(this.updateRemoteDeviceName, (err: BusinessError, data) => {
      if (err?.code) {
        LogUtil.error(`${TAG} updateDeviceName failed `);
        return;
      }
      if (CheckEmptyUtils.checkStrIsEmpty(data?.parameters?.remoteName)) {
        LogUtil.warn(`${TAG} device is null or remoteName is empty`);
        return;
      }
      let cachedBondedDevice: BluetoothDevice = BluetoothAdapter.getInstance()
        .cachedBondedDevices
        .get(data?.parameters?.deviceAddr) as BluetoothDevice;
      let cachedDevice: BluetoothDevice = this.cachedManager.findDevice(data?.parameters?.deviceAddr);
      if (cachedBondedDevice) {
        cachedBondedDevice.updateDeviceName(data?.parameters?.remoteName);
        this.dispatchDeviceNameUpdate(cachedBondedDevice);
      } else if (cachedDevice) {
        cachedDevice.updateDeviceName(data?.parameters?.remoteName);
        this.dispatchDeviceAdded(cachedDevice);
      } else {
        LogUtil.warn(`${TAG} device is not in the cache`);
      }
    });
  public discoveryFinishCommonEvent =
    new CommonEventHelper(this.discoveryFinishedSubscribeInfo, (err: BusinessError, data: object) => {
      if (err?.code) {
        LogUtil.error(`${TAG} subscribe discovery finish failed code: ${err?.code} message: ${err?.message}`);
      } else if (!this.isIgnoreDiscovery) {
        LogUtil.info(`${TAG} subscribe discovery finish success`);
        this.dispatchDiscoveryState(false);
        this.onDiscoveryFinish();
      }
    });
  public discoveryStartedCommonEvent =
    new CommonEventHelper(this.discoveryStartedSubscribeInfo, (err: BusinessError, data: object) => {
      if (err?.code) {
        LogUtil.error(`${TAG} subscribe discovery started failed code: ${err?.code} message: ${err?.message}`);
      } else if (!this.isIgnoreDiscovery) {
        LogUtil.info(`${TAG} subscribe discovery started success`);
        this.dispatchDiscoveryState(true);
      }
    });
  public discoveryRemoteDeviceUUIDInfoEvent = new CommonEventHelper(this.discoveryRemoteDeviceUUIDInfo,
    (err: BusinessError, data) => {
      LogUtil.info(`${TAG} receive discoveryRemoteDeviceUUIDInfoEvent deviceId:${BluetoothUtils.getLogMAC(data?.parameters?.deviceAddr)}`);
      if (err?.code) {
        LogUtil.error(`${TAG} discoveryRemoteDeviceUUIDInfoEvent failed ${err?.code}`);
      } else {
        this.setBondedDeviceRemoteUuids(data);
        let device: BluetoothDevice = this.getBondedDeviceOrSubDevice(data?.parameters?.deviceAddr) ??
        this.cachedManager.findDevice(data?.parameters?.deviceAddr);
        device?.update();
        this.dispatchDeviceAttributesChanged(device);
        if (!this.isStartConnect(device)) {
          LogUtil.warn(`${TAG} discoveryRemoteDeviceUUIDInfoEvent connect task timeout, ${this.cachedBondedDevices.has(device?.deviceId)}`);
          return;
        }
        if (this.isPairOnlyDevice(device.deviceId)) {
          LogUtil.info(`${TAG} pair only device, skip connect after remote uuid discovery`);
          return;
        }
        this.connectToDeviceAfterPair(device.deviceId);
      }
    });

  private setBondedDeviceRemoteUuids(data: commonEventManager.CommonEventData) {
    let device: BluetoothDevice = this.getBondedDeviceOrSubDevice(data?.parameters?.deviceAddr) ??
    this.cachedManager.findDevice(data?.parameters?.deviceAddr);
    if (!device) {
      LogUtil.warn(`${TAG} do not find the device from cachedBondedDevices or cachedManager`);
      return;
    }
    LogUtil.info(`${TAG} Start set RemoteUuid for BondedDevice device`);
    device.setRemoteUuids(data?.parameters?.remoteUuids)
    device.updateProfilesAndConnectionStatusForRemoteUUID()
  }

  private isStartConnect(device: BluetoothDevice): boolean {
    if (!device) {
      LogUtil.error(`${TAG} device is empty, discoveryRemoteDeviceUUIDInfoEvent`);
      return false;
    }
    // 获取配对连接超时时长,助听器:15s,其他设备3s
    let checkedTimeout = device.isHearingAidDevice() ? HEARINGAID_CONNECT_TASK_TIME_OUT : CONNECT_TASK_TIME_OUT;

    // 设备主动配对且已配对且连接未超时,再发起连接。否则,不去连接
    return this.cachedBondedDevices.has(device.deviceId) &&
    this.connectTimestampManager.checkDeviceConnectTimestampValid(device.deviceId, checkedTimeout);
  }

  public onBluetoothStateChange = (state: number) => {
    LogUtil.info(`${TAG} onBluetoothStateChange, state : ${state}`);

    if (BluetoothUtils.isBluetoothStateOn(state) && this.localProfileUuids.length === 0) {
      LogUtil.info(`${TAG} onBluetoothStateChange setLocalProfileUuids`);
      this.setLocalProfileUuids();
    }

    if (BluetoothUtils.isBluetoothStateOn(state)) {
      // 蓝牙状态变为开启时,同步一次本机名称到蓝牙本地名称,保证广播名称正确
      this.syncLocalNameWithDeviceName();
      this.profileManager.profiles.forEach((bluetoothProfile: BluetoothProfile, key: ProfileId) => {
        if (!bluetoothProfile.lastState) {
          bluetoothProfile.setLastState();
        }
      })
    }

    if (state === null) {
      LogUtil.error(`${TAG} onBluetoothStateChange is null`);
      return;
    }

    this.currentState = state;
    LogUtil.info(`${TAG} onBluetoothStateChange : ${state} ,BluetoothCurrentState : ${this.currentState}`);

    if (BluetoothUtils.isBluetoothDiscoveryOn(state)) {
      this.updateAutoDiscovery();
    }

    if (BluetoothUtils.isBluetoothStateOn(state)) {
      this.updateBondedDevices();
    } else {
      if (BluetoothUtils.isBluetoothStateOff(this.currentState)) {
        // 清理配对中、连接中数据
        this.resetPairAndConnectStatus();
      }
    }
    this.dispatchBluetoothStateChange(state);
  }
  public onBluetoothDeviceFind = (devices: Array<connection.DiscoveryResult>) => {
    if (CheckEmptyUtils.isEmptyArr(devices)) {
      LogUtil.error(`${TAG} the devices is invalid, or deviceName is empty`);
      return;
    }
    LogUtil.info(`${TAG} onBluetoothDeviceFind, deviceId:${BluetoothUtils.getLogMAC(devices[0].deviceId)}`);
    if (CheckEmptyUtils.checkStrIsEmpty(devices[0].deviceName)) {
      LogUtil.warn(`${TAG} the deviceName is empty, add device to cache but not refresh device list`);
      let deviceId: string = devices[0].deviceId;
      let device: BluetoothDevice = this.cachedManager.findDevice(deviceId);
      if (!device) {
        device = BluetoothDevice.createDevice(deviceId, devices[0].deviceName, devices[0].rssi) as BluetoothDevice;
        this.cachedManager.addDevice(device);
      }
      return;
    }
    let device: BluetoothDevice = BluetoothAdapter.getInstance()
      .getBondedDeviceOrSubDevice(devices[0].deviceId) as BluetoothDevice;
    if (device) {
      return;
    }
    this.bluetoothDevices = devices;
    if (!devices) {
      return;
    }
    this.updateDeviceList();
  }

  updateDeviceList() {
    for (let deviceInfo of this.bluetoothDevices) {
      Promise.resolve(this.onDeviceFound(deviceInfo));
    }
  }

  private dispatchDeviceClear(): void {
    for (let listener of this.deviceChangeListeners) {
      listener?.onAvailableDeviceClear();
    }
  }

  public onBluetoothBondStateChange = (stateParam: BondStateParam) => {
    if (!stateParam) {
      return;
    }
    LogUtil.info(`${TAG} onBluetoothBondStateChange : ${stateParam?.state}, device : ${BluetoothUtils.getLogMAC(stateParam?.deviceId)}`);
    if (stateParam.state === BondState.BOND_STATE_BONDING) {
      if (!bluetoothPairManager.pairDeviceId) {
        bluetoothPairManager.setPairDeviceId(stateParam.deviceId);
      }
      if (!bluetoothPairManager.listener) {
        bluetoothPairManager.setListener(this);
      }
    }
    this.bondStateChangeInner(stateParam);
    this.dispatchBondStateChange(stateParam);
    bluetoothPairManager.onBluetoothBondStateChange(stateParam);
  }
  public onBluetoothPinRequired = (pinRequiredParam: PinRequiredParam) => {
    if (pinRequiredParam === null || pinRequiredParam.deviceId === null) {
      return;
    }
    bluetoothPairManager.setPairDeviceId(pinRequiredParam.deviceId);
    bluetoothPairManager.setListener(BluetoothAdapter.getInstance());
    LogUtil.info(`${TAG} onBluetoothPinRequired, device : ${BluetoothUtils.getLogMAC(pinRequiredParam.deviceId)}`);
    this.dispatchPinRequired(pinRequiredParam);
  }
  public onBluetoothPinRequiredForPhone = (deviceId: string) => {
    if (CheckEmptyUtils.checkStrIsEmpty(deviceId)) {
      return;
    }

    bluetoothPairManager.setPairDeviceId(deviceId);
    bluetoothPairManager.setListener(BluetoothAdapter.getInstance());
    LogUtil.info(`${TAG} onBluetoothPinRequiredForPhone, deviceId: ${BluetoothUtils.getLogMAC(deviceId)}`);
  };

  private bondStateChangeInner(stateParam: BondStateParam): void {
    if (!stateParam) {
      return;
    }
    let deviceId = stateParam.deviceId;
    if (stateParam.state !== BondState.BOND_STATE_BONDED && this.cachedBondedDevices.has(deviceId)) {
      LogUtil.info(`${TAG} bondStateChangeInner delete the device from cachedBondedDevices`);
      this.cachedBondedDevices.delete(deviceId);
    }

    if (stateParam.state === BondState.BOND_STATE_BONDED && !this.cachedBondedDevices.has(deviceId)) {
      this.cachedBondedDevices.set(deviceId,
        this.cachedManager.findDevice(deviceId) ?? BluetoothDevice.createDevice(deviceId));
    }

    this.isPairing = stateParam.state === BondState.BOND_STATE_BONDING;
  }

  private dispatchBondStateChange(stateParam: BondStateParam): void {
    for (let listener of this.bondChangeListeners) {
      listener?.onBluetoothBondStateChange(stateParam);
    }
  }

  getBondedDevices(): IterableIterator<BluetoothDevice> {
    return this.cachedBondedDevices.values();
  }

  getBondedDevicesCount(): number {
    return this.cachedBondedDevices.size;
  }

  isBondedDevice(deviceId: string): boolean {
    if (this.isBondedMainDevice(deviceId)) {
      return true;
    }
    return this.isBondedSubDevice(deviceId);
  }

  isBondedMainDevice(deviceId: string): boolean {
    return this.cachedBondedDevices.has(deviceId)
  }

  isBondedSubDevice(deviceId: string): boolean {
    for (let bondedDevice of this.cachedBondedDevices.values()) {
      if (bondedDevice?.getSubDevice()?.deviceId === deviceId) {
        return true;
      }
    }
    return false;
  }

  getBondedDevice(deviceId: string): BluetoothDevice {
    return this.cachedBondedDevices.get(deviceId) as BluetoothDevice;
  }

  getBondedDeviceOrSubDevice(deviceId: string): BluetoothDevice {
    let device = this.getBondedDevice(deviceId) as BluetoothDevice;
    if (device !== undefined) {
      return device;
    }
    for (let bondedDevice of this.cachedBondedDevices.values()) {
      if (bondedDevice?.getSubDevice()?.deviceId === deviceId) {
        return bondedDevice.getSubDevice() as BluetoothDevice;
      }
    }
    return device
  }

  setBondedDevice(deviceId: string, device: BluetoothDevice): void {
    this.setCachedBondedDevice(deviceId, device);
  }

  setBondedDeviceName(deviceId: string, deviceName: string): void {
    let device: BluetoothDevice = this.getBondedDevice(deviceId);
    if (!device) {
      device = BluetoothDevice.createDevice(deviceId) as BluetoothDevice;
    }
    device.deviceName = deviceName;
    this.setCachedBondedDevice(deviceId, device);
  }

  findMainDeviceBySubDevice(subDeviceId: string): BluetoothDevice | undefined {
    for (let bondedDevice of this.cachedBondedDevices.values()) {
      if (bondedDevice.getSubDevice()?.deviceId === subDeviceId) {
        return bondedDevice;
      }
    }
    return undefined;
  }

  updateBluetoothCaches(deviceId: string, deviceName: string): void {
    this.setBondedDeviceName(deviceId, deviceName);
    this.updateCacheDevices(deviceId, deviceName);
  }

  private setCachedBondedDevice(deviceId: string, device: BluetoothDevice): void {
    if (this.mergedHearingAidDevice(this.cachedBondedDevices, device)) {
      this.dispatchBondedDeviceMerged(device);
      return;
    }
    this.cachedBondedDevices.set(deviceId, device);
  }

  private dispatchPinRequired(pinRequiredParam: PinRequiredParam): void {
    for (let listener of this.bondChangeListeners) {
      listener?.onBluetoothPinRequired(pinRequiredParam);
    }
  }

  private dispatchBluetoothStateChange(state: number): void {
    for (let listener of this.stateChangeListeners) {
      listener?.onBluetoothStateChange(state);
    }
  }

  getDeviceName(deviceId: string): string {
    let deviceName: string = BluetoothDevice.getDeviceName(deviceId) as string;
    if (!deviceName) {
      deviceName = bluetooth.getRemoteDeviceName(deviceId);
      LogUtil.info(`${TAG} getDeviceName deviceName: ${LogMaskUtil.getLogNickNameString(deviceName)} , deviceId: ${BluetoothUtils.getLogMAC(deviceId)}`);
    }
    return deviceName;
  }

  updateCacheDevices(deviceId: string, deviceName: string, rssi?: number): void {
    let device: BluetoothDevice = this.cachedManager.findDevice(deviceId);
    if (!device) {
      device = BluetoothDevice.createDevice(deviceId, '', rssi) as BluetoothDevice;
    }
    device.deviceName = deviceName;
    this.cachedManager.addDevice(device);
  }

  private onDeviceFound(deviceInfo: connection.DiscoveryResult): void {
    LogUtil.info(`${TAG} onDeviceFound,deviceId: ${BluetoothUtils.getLogMAC(deviceInfo.deviceId)}`);
    let device = this.cachedManager.findDevice(deviceInfo.deviceId);
    if (!device) {
      // 新发现
      device = BluetoothDevice.createDevice(deviceInfo.deviceId, deviceInfo.deviceName,
        deviceInfo.rssi) as BluetoothDevice;
      LogUtil.info(`${TAG} find device, deviceId: ${BluetoothUtils.getLogMAC(deviceInfo.deviceId)}, rssi: ${deviceInfo.rssi}`);
      if (this.cachedManager.addDevice(device)) {
        this.dispatchDeviceAdded(device); // 只有新设备通知添加
      }
    } else {
      LogUtil.info(`${TAG} update device, deviceId: ${BluetoothUtils.getLogMAC(deviceInfo.deviceId)}, rssi: ${deviceInfo.rssi}`);
      device.update(deviceInfo.deviceName, deviceInfo.rssi);
      this.dispatchDeviceAttributesChanged(device); // 通知设备属性变更
    }
    device.setDiscover(true);
    this.delayRefreshAvailableDevice();
  }

  private delayRefreshAvailableDevice(delayTime: number = 1000): void {
    if (this.delayDispatchDeviceRefreshTimer) {
      return;
    }

    this.delayDispatchDeviceRefreshTimer = setTimeout(() => {
      this.delayDispatchDeviceRefreshTimer = null;
      this.dispatchDeviceRefresh();
    }, delayTime);
  }

  private dispatchDeviceRefresh(): void {
    for (let listener of this.deviceChangeListeners) {
      listener?.onAvailableDevicesRefresh();
    }
  }

  private dispatchDeviceAdded(device: BluetoothDevice): void {
    if (!device) {
      return;
    }
    for (let listener of this.deviceChangeListeners) {
      listener?.onDeviceAdded(device);
    }
  }

  private dispatchDeviceNameUpdate(device: BluetoothDevice): void {
    for (let listener of this.deviceNameUpdateListeners) {
      listener?.onDeviceNameUpdate(device);
    }
  }

  private dispatchDeviceAttributesChanged(device: BluetoothDevice): void {
    if (!device) {
      return;
    }
    for (let listener of this.deviceChangeListeners) {
      listener?.onDeviceAttributesChanged(device);
    }
  }

  private dispatchBondedDeviceMerged(device: BluetoothDevice): void {
    if (!device) {
      return;
    }
    for (let listener of this.bondedDeviceChangeListeners) {
      listener?.onBondedDeviceMerged(device);
    }
  }

  registerRemoveSummaryListener(listener: BluetoothRemoveSummaryListener): void {
    for (const bluetoothRemoveSummaryListener of this.bluetoothRemoveSummaryListeners) {
      if (bluetoothRemoveSummaryListener.getListenKey() === listener.getListenKey()) {
        return;
      }
    }
    this.bluetoothRemoveSummaryListeners.push(listener);
  }

  unRegisterRemoveSummaryListener(listener: BluetoothRemoveSummaryListener): void {
    for (let index = 0; index < this.bluetoothRemoveSummaryListeners.length; index++) {
      if (this.bluetoothRemoveSummaryListeners[index].getListenKey() === listener.getListenKey()) {
        this.bluetoothRemoveSummaryListeners.splice(index, 1);
        return;
      }
    }
  }

  registerStateChangeListener(listener: BluetoothStateChangeListener): void {
    for (const stateChangeListener of this.stateChangeListeners) {
      if (stateChangeListener.getListenKey() === listener.getListenKey()) {
        return;
      }
    }
    this.stateChangeListeners.push(listener);
  }

  // 需要使用到数组下角标因此使用for循环
  unRegisterStateChangeListener(listener: BluetoothStateChangeListener): void {
    for (let index = 0; index < this.stateChangeListeners.length; index++) {
      if (this.stateChangeListeners[index].getListenKey() === listener.getListenKey()) {
        this.stateChangeListeners.splice(index, 1);
        return;
      }
    }
  }

  registerDeviceChangeListener(listener: BluetoothDeviceChangeListener): void {
    for (const deviceChangeListener of this.deviceChangeListeners) {
      if (deviceChangeListener.getListenKey() === listener.getListenKey()) {
        return;
      }
    }
    this.deviceChangeListeners.push(listener);
  }

  unRegisterDeviceChangeListener(listener: BluetoothDeviceChangeListener): void {
    for (let index = 0; index < this.deviceChangeListeners.length; index++) {
      if (this.deviceChangeListeners[index].getListenKey() === listener.getListenKey()) {
        this.deviceChangeListeners.splice(index, 1);
        return;
      }
    }
  }

  registerDeviceNameUpdateListener(listener: BluetoothDeviceNameUpdateListener): void {
    for (const deviceNameUpdateListeners of this.deviceNameUpdateListeners) {
      if (deviceNameUpdateListeners.getListenKey() === listener.getListenKey()) {
        return;
      }
    }
    this.deviceNameUpdateListeners.push(listener);
  }

  unRegisterDeviceNameUpdateListener(listener: BluetoothDeviceNameUpdateListener): void {
    for (let index = 0; index < this.deviceNameUpdateListeners.length; index++) {
      if (this.deviceNameUpdateListeners[index].getListenKey() === listener.getListenKey()) {
        this.deviceNameUpdateListeners.splice(index, 1);
        return;
      }
    }
  }

  registerBondChangeListener(listener: BluetoothBondChangeListener): void {
    for (const bondChangeListener of this.bondChangeListeners) {
      if (bondChangeListener.getListenKey() === listener.getListenKey()) {
        return;
      }
    }
    this.bondChangeListeners.push(listener);
  }

  unRegisterBondChangeListener(listener: BluetoothBondChangeListener): void {
    for (let index = 0; index < this.bondChangeListeners.length; index++) {
      if (this.bondChangeListeners[index].getListenKey() === listener.getListenKey()) {
        this.bondChangeListeners.splice(index, 1);
        return;
      }
    }
  }

  registerLoadChangeListener(listener: BluetoothLoadStateChangeListener): void {
    for (const loadingStateChangerListener of this.loadingStateChangerListeners) {
      if (loadingStateChangerListener.getListenKey() === listener.getListenKey()) {
        return;
      }
    }
    this.loadingStateChangerListeners.push(listener);
  }

  unRegisterLoadChangeListener(listener: BluetoothLoadStateChangeListener): void {
    for (let index = 0; index < this.loadingStateChangerListeners.length; index++) {
      if (this.loadingStateChangerListeners[index].getListenKey() === listener.getListenKey()) {
        this.loadingStateChangerListeners.splice(index, 1);
        return;
      }
    }
  }

  registerProfileStateChangeListener(listener: BluetoothProfileStateChangeListener): void {
    for (const profileStateChangeListener of this.profileStateChangeListeners) {
      if (profileStateChangeListener.getListenKey() === listener.getListenKey()) {
        return;
      }
    }
    this.profileStateChangeListeners.push(listener);
  }

  unRegisterProfileStateChangeListener(listener: BluetoothProfileStateChangeListener): void {
    for (let index = 0; index < this.profileStateChangeListeners.length; index++) {
      if (this.profileStateChangeListeners[index].getListenKey() === listener.getListenKey()) {
        this.profileStateChangeListeners.splice(index, 1);
        return;
      }
    }
  }

  registerBondedDeviceChangeListener(listener: BluetoothBondedDeviceChangeListener): void {
    for (const bondedDeviceChangeListener of this.bondedDeviceChangeListeners) {
      if (bondedDeviceChangeListener.getListenKey() === listener.getListenKey()) {
        return;
      }
    }
    this.bondedDeviceChangeListeners.push(listener);
  }

  unregisterBondedDeviceChangeListener(listener: BluetoothBondedDeviceChangeListener): void {
    for (let index = 0; index < this.bondedDeviceChangeListeners.length; index++) {
      if (this.bondedDeviceChangeListeners[index].getListenKey() === listener.getListenKey()) {
        this.bondedDeviceChangeListeners.splice(index, 1);
        return;
      }
    }
  }

  public updateBondedDevices(): void {
    let bondedDevices: Map<string, BluetoothDevice> = new Map();
    let devices = bluetooth.getPairedDevices();
    LogUtil.info(`${TAG} updateBondedDevices length : ${devices.length}`);

    for (let deviceId of devices) {
      LogUtil.info(`${TAG} updateBondedDevices device : ${BluetoothUtils.getLogMAC(deviceId)}`);
      let device = this.getBondedDeviceOrSubDevice(deviceId);
      // 保存当前设备名称,避免被系统获取的原始名称覆盖
      let cachedDeviceName = device?.deviceName;
      device?.update();
      // 如果有缓存的设备名称,使用它而不是系统获取的名称
      if (cachedDeviceName) {
        device.deviceName = cachedDeviceName;
      }
      if (!device) {
        // 检查是否有缓存的设备名称
        let existingDevice = this.getBondedDevice(deviceId);
        let cachedDeviceName = existingDevice?.deviceName;
        device = BluetoothDevice.createDevice(deviceId) as BluetoothDevice;
        // 如果有缓存的设备名称,直接应用
        if (cachedDeviceName) {
          device.deviceName = cachedDeviceName;
        }
        device.updateProfilesAndConnectionStatus().then(() => {
          LogUtil.info(`${TAG}, updateBondedDevices createDevice update ${BluetoothUtils.getLogMAC(deviceId)}`);
          if (!device) {
            return;
          }
          // 在更新设备信息后再次检查并应用缓存的设备名称
          if (cachedDeviceName) {
            device.deviceName = cachedDeviceName;
          } else {
            device.update();
          }
          this.dispatchDeviceAttributesChanged(device);
          if (this.mergedHearingAidDevice(bondedDevices, device)) {
            this.cachedBondedDevices.delete(deviceId);
            this.dispatchBondedDeviceMerged(device);
          }
        });
      }
      if (this.mergedHearingAidDevice(bondedDevices, device)) {
        this.dispatchBondedDeviceMerged(device);
        continue;
      }
      bondedDevices.set(deviceId, device as BluetoothDevice);
    }

    this.cachedBondedDevices = bondedDevices;
  }

  public updateSwitchState(): void {
    this.currentState = BluetoothUtils.getCurrentBluetoothState();
  }

  public updatePairingState(): void {
    let state: BondState = Utils.getPairState(bluetoothPairManager.pairDeviceId ?? '');
    this.isPairing = state === BondState.BOND_STATE_BONDING;
    if (!this.isPairing) {
      bluetoothPairManager.finishPair();
      this.isPauseDiscover = false;
    }
  }

  start(): void {
    LogUtil.info(`${TAG} start. isStart:${this.isStart}`);
    if (!this.isStart) {
      this.isStart = true;
      this.currentState = bluetooth.getState();
      LogUtil.info(`${TAG} start,  currentState : ${this.currentState}`);
      bluetooth.on('stateChange', this.onBluetoothStateChange);
      try {
        connection.on('bondStateChange', this.onBluetoothBondStateChange as Callback<connection.BondStateParam>);
      } catch (error) {
        LogUtil.error(`${TAG} on bondStateChange failed, ${error?.message}`);
      }
      this.profileManager.start(this);
      if (this.isBluetoothOn()) {
        // 初始化时如果蓝牙已开启,立即同步一次本机名称到蓝牙本地名称
        this.syncLocalNameWithDeviceName();
        this.setLocalProfileUuids();
      }
      if (!this.isPairBluetoothAdapter) {
        LogUtil.info(`${TAG} is not pairDialog`);
        this.updateBondedDevices();
        if (!this.isIgnoreDiscovery) {
          try {
            connection.on('discoveryResult', this.onBluetoothDeviceFind);
          } catch (error) {
            LogUtil.error(`${TAG} is discoveryResult error, ${error?.message}`);
          }

          this.updateAutoDiscovery();
          this.discoveryStartedCommonEvent.registerCommonEvent();
          this.discoveryFinishCommonEvent.registerCommonEvent();
        }
        this.discoveryRemoteDeviceUUIDInfoEvent.registerCommonEvent();
        this.updateRemoteDeviceNameCommonEvent.registerCommonEvent();
      } else {
        LogUtil.info(`${TAG} is pairDialog , pass setting discovery`);
      }
    }
  }

  private async setLocalProfileUuids(): Promise<void> {
    try {
      this.localProfileUuids = await connection.getLocalProfileUuids();
      LogUtil.info(`${TAG} setLocalProfileUuids , size : ${this.localProfileUuids.length}`);
    } catch (err) {
      LogUtil.error(`${TAG} getLocalProfileUuids failed. code:${err?.code} message:${err?.message}`);
    }
  }

  private updateInitStates(): void {
    this.updateBondedDevices();
    this.updateAutoDiscovery();
  }

  stop(): void {
    if (this.isStart) {
      LogUtil.info(`${TAG} stop`);
      bluetooth.off('stateChange', this.onBluetoothStateChange);
      try {
        connection.off('bondStateChange', this.onBluetoothBondStateChange as Callback<connection.BondStateParam>);
      } catch (error) {
        LogUtil.error(`${TAG} off bondStateChange failed, ${error?.message}`);
      }
      if (!this.isPairBluetoothAdapter) {
        LogUtil.info(`${TAG} is not pairDialog`);
        try {
          connection.off('discoveryResult', this.onBluetoothDeviceFind);
        } catch (error) {
          LogUtil.error(`${TAG} off discoveryResult failed, ${error?.message}`);
        }
        this.stopDiscovery();
        this.discoveryStartedCommonEvent.unRegisterCommonEvent();
        this.discoveryFinishCommonEvent.unRegisterCommonEvent();
        this.discoveryRemoteDeviceUUIDInfoEvent.unRegisterCommonEvent();
        this.updateRemoteDeviceNameCommonEvent.unRegisterCommonEvent();
      } else {
        LogUtil.info(`${TAG} is pairDialog , pass setting discovery`);
      }
      this.closeScanTimer()
      this.isStart = false;
      this.resetPairAndConnectStatus();
      this.profileManager.stop();
    }
  }

  /**
   * 退出,清理数据
   */
  onQuit(): void {
    this.stop();
    this.releaseResource();
  }

  private resetPairAndConnectStatus(): void {
    LogUtil.info(`${TAG} resetPairAndConnectStatus`);
    this.profileManager.finishConnect();
    bluetoothPairManager.finishPair();
    this.isPauseDiscover = false;
    this.isPairing = false;
    this.connectingIds.clear();
    this.isDiscovering = false;
    EventBus.getInstance().emit('Setting.Bluetooth.AvailableDeviceGroup.isScanLoadingShow', false);

    this.dispatchDeviceClear();
    this.cachedManager.clear();
  }

  private releaseResource(): void {
    if (!this.isPairBluetoothAdapter) {
      LogUtil.info(`${TAG} is not pairDialog`);
      this.setAutoDiscovery(false);
    } else {
      LogUtil.info(`${TAG} is pairDialog , pass setting discovery`);
    }
    this.resetPairAndConnectStatus();
    this.stateChangeListeners = [];
    this.deviceChangeListeners = [];
    this.deviceNameUpdateListeners = [];
    this.bondChangeListeners = [];
  }

  private delayStartDiscovery(delayTime: number): void {
    LogUtil.info(`${TAG} delayStartDiscovery`);
    if (this.delayStartDiscoveryTimer) {
      LogUtil.info(`${TAG} already has delayStartDiscoveryTimer`);
      return;
    }
    if (!this.isNeedStartDiscovery()) {
      LogUtil.info(`${TAG} not need to discovery, return`);
      return;
    }
    this.delayStartDiscoveryTimer = null;
    this.delayStartDiscoveryAfterPairFinishTimer = null;
    this.resetDiscoverState();
    this.dispatchDeviceClear();
    this.cachedManager.clear();
    this.startDiscovery();
    this.delayStartDiscoveryTimer = setInterval(() => {
      LogUtil.info(`${TAG} startDiscovery after delay`);
      this.startDiscovery();
    }, 5000);
  }

  //关闭定时器
  closeScanTimer() {
    LogUtil.info(`${TAG} updateAutoDiscovery. closeTimer`);
    clearTimeout(this.delayStartDiscoveryTimer)
    this.delayStartDiscoveryTimer = null
  }

  private onDiscoveryFinish(): void {
    LogUtil.info(`${TAG} onDiscoveryFinish. isBluetoothPageShow:${this.isBluetoothPageShow}`);
    this.stopDiscovery();
    if (this.isBluetoothPageShow) {
      this.delayStartDiscovery(DELAY_DISCOVERY_START_DISCOVERY_TIME);
    }
  }

  /**
   * 设置自动扫描开始/停止
   *
   * @param isAutoDiscover true : 开始, false : 停止
   */
  setAutoDiscovery(isAutoDiscover: boolean): void {
    LogUtil.info(`${TAG} setAutoDiscovery. old:${this.isAutoDiscover} new:${isAutoDiscover}`);
    if (this.isAutoDiscover != isAutoDiscover) {
      this.isAutoDiscover = isAutoDiscover;
      this.updateAutoDiscovery();
    }
  }

  private updateAutoDiscovery(delayTime: number = DELAY_DISCOVERY_STATE_TIME): void {
    if (this.isAutoDiscover && this.isBluetoothOn() && this.isStart && this.isBluetoothPageShow) {
      LogUtil.info(`${TAG} updateAutoDiscovery. delayStartDiscovery`);
      this.delayStartDiscovery(delayTime);
    } else {
      LogUtil.info(`${TAG} updateAutoDiscovery. isBluetoothOn:${this.isBluetoothOn()}`);
      this.closeScanTimer()
      if (this.isBluetoothOn()) {
        this.stopDiscovery();
      } else {
        this.isDiscovering = false;
        EventBus.getInstance().emit('Setting.Bluetooth.AvailableDeviceGroup.isScanLoadingShow', false);
      }
    }
  }

  private dispatchDiscoveryState(status: boolean): void {
    for (let listener of this.loadingStateChangerListeners) {
      listener?.onChangeLoadingStatus(status);
    }
  }

  private isNeedStartDiscovery(): boolean {
    LogUtil.info(`${TAG} checkStartDiscovery ${this.isAutoDiscover}, ${this.isStart}, ${this.isDiscovering}, ${this.isBluetoothOn()}, ${this.isPauseDiscover}, ${this.isIgnoreDiscovery}, ${this.isPairBluetoothAdapter}`);
    return this.isAutoDiscover && this.isStart && !this.isDiscovering && this.isBluetoothOn() &&
      !this.isPauseDiscover && !this.isIgnoreDiscovery && !this.isPairBluetoothAdapter;
  }

  /**
   * 同步蓝牙本地名称与系统设备名称
   * 在蓝牙状态变为开启、开始扫描等场景统一调用,保证广播名称和“本机名称”一致。
   */
  private syncLocalNameWithDeviceName(): void {
    try {
      const deviceName: string = DeviceNameUtil.getDeviceNameAsync();
      if (CheckEmptyUtils.checkStrIsEmpty(deviceName)) {
        LogUtil.warn(`${TAG} syncLocalNameWithDeviceName, deviceName is empty`);
        return;
      }
      const localName: string = bluetooth.getLocalName();
      if (localName !== deviceName) {
        bluetooth.setLocalName(deviceName);
        LogUtil.info(`${TAG} syncLocalNameWithDeviceName, setLocalName success. localName: ${localName}, deviceName: ${deviceName}`);
      } else {
        LogUtil.info(`${TAG} syncLocalNameWithDeviceName, localName already up to date`);
      }
    } catch (error) {
      LogUtil.error(`${TAG} syncLocalNameWithDeviceName failed, error: ${error?.message}`);
    }
  }

  startDiscovery(): void {
    LogUtil.info(`${TAG} startDiscovery`);
    let result = bluetooth.startBluetoothDiscovery();

    // 每次开始扫描前,同步一次本地名称,避免辅助设备看到的名字落后
    this.syncLocalNameWithDeviceName();
    LogUtil.info(`${TAG} startBluetoothDiscovery, result : ${result}`);
    if (!result) {
      if (this.retryTime > 0) {
        this.retryTime--;
        bluetooth.stopBluetoothDiscovery();
        this.updateAutoDiscovery(DELAY_DISCOVERY_STATE_RETRY_TIME);
      } else {
        LogUtil.error(`${TAG} try startBluetoothDiscovery failed`);
        this.retryTime = DISCOVERY_RETRY_COUNT;
        this.dispatchDiscoveryState(false);
      }
      return;
    }
    this.retryTime = DISCOVERY_RETRY_COUNT;
    if (this.isBluetoothPageShow) {
      this.isDiscovering = true;
      EventBus.getInstance().emit('Setting.Bluetooth.AvailableDeviceGroup.isScanLoadingShow', true);
    }
  }

  private resetDiscoverState(): void {
    let devices = Array.from(this.cachedManager.getCachedDevices());
    for (let device of devices) {
      device?.setDiscover(false);
    }
  }

  private isBluetoothOn(): boolean {
    return BluetoothUtils.isBluetoothStateOn(this.currentState);
  }

  stopDiscovery(): boolean {
    LogUtil.info(`${TAG} stopDiscovery`);
    if (!this.isDiscovering) {
      LogUtil.info(`${TAG} not discovering, return`);
      return false;
    }

    this.isDiscovering = false;
    EventBus.getInstance().emit('Setting.Bluetooth.AvailableDeviceGroup.isScanLoadingShow', false);
    if (!this.isBluetoothOn()) {
      LogUtil.info(`${TAG} Bluetooth state off, stopDiscovery return`);
      this.dispatchDiscoveryState(false);
      return true;
    }

    let result = bluetooth.stopBluetoothDiscovery();
    LogUtil.info(`${TAG} stopBluetoothDiscovery, result : ${result}`);
    return true;
  }

  private updateCachedDeviceDiscover(): void {
    let devices = Array.from(this.cachedManager.getCachedDevices());
    for (let device of devices) {
      if (!device?.getDiscover()) {
        this.cachedManager.removeDevice(device?.deviceId);
      }
    }
  }

  private dispatchDeviceDeleted(device: BluetoothDevice): void {
    for (let listener of this.deviceChangeListeners) {
      listener?.onDeviceDeleted(device);
    }
  }

  private pauseDiscover(): void {
    LogUtil.info(`${TAG} pauseDiscover`);
    this.isPauseDiscover = true;
    this.stopDiscovery();
  }

  private restoreDiscover(): void {
    LogUtil.info(`${TAG} restoreDiscover. this.isAutoDiscover:${this.isAutoDiscover}`);
    this.isPauseDiscover = false;
    if (this.isAutoDiscover) {
      LogUtil.info(`${TAG} startDiscovery after restoreDiscover`);
      this.startDiscovery();
    }
  }

  /**
   * 发起配对流程
   *
   * @param deviceId 待配对的设备ID
   */
  pairDevice(deviceId: string): boolean {
    if (!deviceId) {
      LogUtil.error(`${TAG} pairDevice param empty`);
    }
    if (this.isPairing) {
      LogUtil.warn(`${TAG} isPairing, pairDevice return`);
      return false;
    }

    if (!this.isBluetoothOn()) {
      LogUtil.warn(`${TAG} Bluetooth off, pairDevice return`);
      return false;
    }

    this.pauseDiscover();
    // 标记设备为本地主动配对
    this.connectTimestampManager.setDeviceBondedFromLocal(deviceId);
    this.isPairing = true;
    LogUtil.info(`${TAG} pairDevice start, device :  ${BluetoothUtils.getLogMAC(deviceId)}`);
    // 底层蓝牙配对管理器发起实际配对
    let result = bluetoothPairManager.startPair(deviceId, this);
    LogUtil.info(`${TAG} pairDevice result : ${result}`);
    return result;
  }

  onPairResult(deviceId: string, result: number, isSuccess: boolean): void {
    LogUtil.info(`${TAG} onPairResult`);
    this.isPairing = false;
    this.isPauseDiscover = false;
    this.dispatchPairResult(deviceId, result, isSuccess);
    // 基于连接性能考虑,1s后再恢复扫描。若在1秒内有其他场景触发开始扫描,则按照对应逻辑开始扫描即可
    this.restoreDiscoverForPairFinish();
  }

  onCancelPair(deviceId: string): void {
    this.restoreDiscover();
    this.isPairing = false;
    this.removeSummary(deviceId);
  }

  private restoreDiscoverForPairFinish(): void {
    if (this.delayStartDiscoveryAfterPairFinishTimer) {
      LogUtil.info(`${TAG} already has delayStartDiscoveryAfterPairFinishTimer`);
      return;
    }
    this.delayStartDiscoveryAfterPairFinishTimer = setTimeout(() => {
      LogUtil.info(`${TAG} startDiscovery after 1s`);
      this.delayStartDiscoveryAfterPairFinishTimer = null;
      this.startDiscovery();
    }, DELAY_DISCOVERY_START_TIME_PAIR_FINISH);
  }

  removeSummary(deviceId: string): void {
    LogUtil.info(`${TAG} setPinCodeDevicePairingConfirmation removeSummary deviceId: ${BluetoothUtils.getLogMAC(deviceId)}`);
    this.bluetoothRemoveSummaryListeners.forEach((listener) => {
      listener.onRemoveSummary(deviceId);
    })
  }

  private dispatchPairResult(deviceId: string, result: number, isSuccess: boolean): void {
    LogUtil.info(`${TAG} dispatchPairResult`);
    for (let listener of this.bondChangeListeners) {
      listener?.onPairResult(deviceId, result, isSuccess);
    }
  }

  /**
   * 配对确认
   *
   * @param deviceId 正在配对的设备ID
   * @param isAccept 是否接受本次配对的设备
   */
  setDevicePairingConfirmation(deviceId: string, isAccept: boolean): void {
    if (!deviceId) {
      LogUtil.error(`${TAG} setDevicePairingConfirmation, param empty`);
      return;
    }
    if (!this.isBluetoothOn()) {
      LogUtil.warn(`${TAG} setDevicePairingConfirmation, bluetooth off, return`);
      return;
    }
    try {
      bluetooth.setDevicePairingConfirmation(deviceId, isAccept);
    } catch (error) {
      LogUtil.error(`${TAG} setDevicePairingConfirmation, error, error: ${error?.message}`);
    } finally {
      bluetoothPairManager.onDevicePairingConfirmation(deviceId, isAccept);
    }
  }

  setPinCodeDevicePairingConfirmation(deviceId: string, isAccept: boolean, code: string): void {
    if (!deviceId) {
      LogUtil.error(`${TAG} setDevicePairingConfirmation, param empty`);
      bluetoothPairManager.finishPair();
      return;
    }
    if (code === undefined) {
      LogUtil.error(`${TAG} setDevicePairingConfirmation, code is undefined`);
      bluetoothPairManager.finishPair();
      return;
    }
    if (!this.isBluetoothOn()) {
      LogUtil.warn(`${TAG} setDevicePairingConfirmation, bluetooth off, return`);
      bluetoothPairManager.finishPair();
      return;
    }
    try {
      if (!isAccept) {
        LogUtil.info(`${TAG} setPinCodeDevicePairingConfirmation cancelPairingDevice`);
        connection.cancelPairingDevice(deviceId).then(() => {
          LogUtil.info(`${TAG} setPinCodeDevicePairingConfirmation cancelPairingDevice end`);
          bluetoothPairManager.onDevicePairingConfirmation(deviceId, isAccept);
        })
        return;
      }

      connection.setDevicePinCode(deviceId, code).then(() => {
        bluetoothPairManager.onDevicePairingConfirmation(deviceId, isAccept);
      });
    } catch (error) {
      LogUtil.error(`${TAG} setPinCodeDevicePairingConfirmation, error, error: ${error?.message}`);
      bluetoothPairManager.finishPair();
    }
  }

  setDefaultPinCodeDevicePairingConfirmation(deviceId: string, isAccept: boolean): void {
    if (!deviceId) {
      LogUtil.error(`${TAG} setDefaultPinCodeDevicePairingConfirmation, param empty`);
      return;
    }
    if (!this.isBluetoothOn()) {
      LogUtil.warn(`${TAG} setDefaultPinCodeDevicePairingConfirmation, bluetooth off, return`);
      return;
    }
    try {
      connection.cancelPairingDevice(deviceId).then(() => {
        bluetoothPairManager.onDevicePairingConfirmation(deviceId, isAccept);
      })
    } catch (err) {
      LogUtil.error(`${TAG} setDefaultPinCodeDevicePairingConfirmation cancelPairingDevice error, code: ${err?.code} message: ${err?.message}`);
      bluetoothPairManager.onDevicePairingConfirmation(deviceId, isAccept);
    }
    return;
  }

  onBluetoothProfileStateChange(profileId: ProfileId, stateChangeParam: StateChangeParam): void {
    if (!stateChangeParam) {
      return;
    }
    LogUtil.info(`${TAG} onBluetoothProfileStateChange, deviceId: ${BluetoothUtils.getLogMAC(stateChangeParam.deviceId)}`);
    let deviceId: string = stateChangeParam.deviceId;
    if (this.isBondedDevice(deviceId)) {
      let device: BluetoothDevice = this.getBondedDeviceOrSubDevice(deviceId) as BluetoothDevice;
      if (stateChangeParam.state === ProfileConnectionState.STATE_CONNECTED) {
        device?.addProfile(profileId, this.profileManager.profiles.get(profileId) as BluetoothProfile);
        device?.updateConnectionStatus();
        this.connectingIds.remove(deviceId);
        // 连接成功,且属于助听器类型设备,且当前设备不属于其他设备的附属设备时,获取HearingAidId,遍历已配对设备列表,识别合并
        if (device !== undefined && device.isHearingAidDevice() && !this.isBondedSubDevice(deviceId)) {
          // device.setHearingAidId(
          //   (this.profileManager.profiles.get(PROFILE_HEARING_AID) as HearingAidProfile)?.getHearingAidId(deviceId));
          if (this.mergedHearingAidDevice(this.cachedBondedDevices, device)) {
            this.cachedBondedDevices.delete(device?.deviceId);
            this.dispatchBondedDeviceMerged(device);
          }
        }
      }
      LogUtil.info(`${TAG} setEnable status, state: ${stateChangeParam.state}, deviceId: ${BluetoothUtils.getLogMAC(stateChangeParam.deviceId)}`);
      if (stateChangeParam.state === ProfileConnectionState.STATE_CONNECTING) {
        device.setEnable(false);
      } else if (stateChangeParam.state === ProfileConnectionState.STATE_DISCONNECTED) {
        this.handleDisconnectedState(profileId, device);
        this.connectingIds.remove(deviceId);
      } else {
        device.setEnable(true);
      }
    } else {
      LogUtil.warn(`${TAG} onBluetoothProfileStateChange, cachedBondedDevices not contain, deviceId: ${BluetoothUtils.getLogMAC(stateChangeParam.deviceId)}`);
    }
    for (let listener of this.profileStateChangeListeners) {
      listener?.onBluetoothProfileStateChange(profileId, stateChangeParam);
    }
  }

  /**
   * 合并列表中的助听器设备
   *
   * @param cacheDevices 缓存的设备列表
   * @param targetDevice 目标设备
   * @returns 是否合并
   */
  private mergedHearingAidDevice(cacheDevices: Map<string, BluetoothDevice>, targetDevice: BluetoothDevice): boolean {
    for (let device of cacheDevices.values()) {
      if (!device || !device.isHearingAidDevice()) {
        continue;
      }
      if (device.deviceId === targetDevice.deviceId) {
        continue;
      }
      if (device.getHearingAidId() !== undefined && targetDevice.getHearingAidId() !== undefined &&
        device.getHearingAidId() === targetDevice.getHearingAidId()) {
        LogUtil.info(`${TAG} mergedHearingAidDevice findSubDevice ${BluetoothUtils.getLogMAC(targetDevice?.deviceId)}`);
        device.setSubDevice(targetDevice);
        return true;
      }
    }
    return false;
  }

  handleDisconnectedState(profileId: ProfileId, device: BluetoothDevice): void {
    if (!device) {
      return;
    }
    let profile: BluetoothProfile = this.profileManager.profiles.get(profileId) as BluetoothProfile;
    // 正在连接 -> 断连, 需等其他profile的连接结果
    if (profile?.lastState === ProfileConnectionState.STATE_CONNECTING) {
      // 只要有一个协议连接上了,不用关注其他协议的断连情况
      if (this.profileManager.isDeviceConnected(device?.deviceId)) {
        device.setEnable(true);
      } else {
        device.setEnable(this.profileManager.isAllProfileDisconnected(device?.deviceId));
      }
    } else {
      device.setEnable(true);
    }
  }

  getProfileState(profileId: ProfileId, deviceId: string): ProfileConnectionState {
    return this.profileManager.getProfileState(profileId, deviceId);
  }

  isDeviceConnected(deviceId: string): boolean {
    return this.profileManager.isDeviceConnected(deviceId);
  }

  isDeviceConnecting(deviceId: string): boolean {
    return this.profileManager.isDeviceConnecting(deviceId);
  }

  isDeviceConnectedOrConnecting(deviceId: string): boolean {
    return this.profileManager.isDeviceConnectedOrConnecting(deviceId);
  }

  /**
   * 发起连接流程
   *
   * @param deviceId 待连接的设备ID
   */
  startConnect(deviceId: string): boolean {
    if (this.isPairOnlyDevice(deviceId)) {
      LogUtil.info(`${TAG} pair only device, skip startConnect`);
      return true;
    }
    if (!this.checkConnectConditionsValid(deviceId)) {
      LogUtil.warn(`${TAG} startConnect. can not connect device, this.isConnecting:${!this.connectingIds.has(deviceId)}`);
      return false;
    }
    if (!this.isBluetoothOn()) {
      LogUtil.warn(`${TAG} startConnect. Bluetooth off`);
      return false;
    }
    LogUtil.info(`${TAG} startConnect. deviceId:${BluetoothUtils.getLogMAC(deviceId)}`);
    this.pauseDiscover();
    this.connectingIds.add(deviceId);
    return this.profileManager.startConnect(deviceId, this);
  }

  /**
   * 点击已配对设备去连接
   */
  startConnectIfSupport(deviceId: string, subDeviceId?: string): boolean {
    LogUtil.info(`${TAG} startConnectIfSupport. deviceId : ${BluetoothUtils.getLogMAC(deviceId)} , subDeviceId : ${BluetoothUtils.getLogMAC(subDeviceId)}`);
    if (this.isPairOnlyDevice(deviceId) || (subDeviceId && this.isPairOnlyDevice(subDeviceId))) {
      LogUtil.info(`${TAG} pair only device, skip startConnectIfSupport`);
      return true;
    }
    let deviceIdValid: boolean = this.checkConnectConditionsValid(deviceId);
    let subDeviceIdValid: boolean = false;
    if (subDeviceId) {
      subDeviceIdValid = this.checkConnectConditionsValid(subDeviceId);
      LogUtil.info(`${TAG} startConnectIfSupport. subDeviceIdValid : ${subDeviceIdValid}, this.isConnecting:${this.connectingIds.has(subDeviceId)}`);
    }
    if (!deviceIdValid && !subDeviceIdValid) {
      LogUtil.warn(`${TAG} startConnectIfSupport. can not connect all Device`);
      return false;
    }

    let deviceHasProfile: boolean = this.getBondedDeviceOrSubDevice(deviceId)?.profileMap.size !== 0;
    let subDeviceHasProfile: boolean = false;
    if (subDeviceId && subDeviceIdValid) {
      subDeviceHasProfile = this.getBondedDeviceOrSubDevice(subDeviceId)?.profileMap.size !== 0;
      LogUtil.info(`${TAG} startConnectIfSupport. is subDevice has profile:${subDeviceHasProfile}`);
    }
    if (!deviceHasProfile && !subDeviceHasProfile) {
      LogUtil.warn(`${TAG} startConnectIfSupport. the device do not support all profiles currently.`);
      return false;
    }
    LogUtil.info(`${TAG} startConnectIfSupport. deviceId:${BluetoothUtils.getLogMAC(deviceId)}`);
    this.pauseDiscover();
    if (deviceHasProfile && deviceIdValid && deviceId) {
      this.connectingIds.add(deviceId);
    }
    if (subDeviceHasProfile && subDeviceIdValid && subDeviceId) {
      this.connectingIds.add(subDeviceId);
    }
    return this.profileManager.startConnect(deviceId, this, subDeviceId);
  }


  /**
   * 配对完成后调用的连接方法
   */
  connectToDeviceAfterPair(deviceId: string): boolean {
    LogUtil.info(`${TAG} connectToDeviceAfterPair deviceId: ${BluetoothUtils.getLogMAC(deviceId)}`);
    if (this.isPairOnlyDevice(deviceId)) {
      LogUtil.info(`${TAG} pair only device, skip connectToDeviceAfterPair`);
      this.connectTimestampManager.resetDeviceBondedFromLocal(deviceId);
      return true;
    }
    if (!this.checkConnectConditionsValid(deviceId)) {
      LogUtil.warn(`${TAG} can not connect device, this.isConnecting: ${this.connectingIds.has(deviceId)}`);
      return false;
    }
    if (!this.connectTimestampManager.checkIsBondedFromLocal(deviceId)) {
      LogUtil.warn(`${TAG} the device is not bonded from local`);
      return false;
    }

    this.connectTimestampManager.setDeviceConnectTimestamp(deviceId, new Date().getTime()); // 设置时间戳
    if (this.cachedBondedDevices.get(deviceId)?.profileMap.size === 0) {
      LogUtil.warn(`${TAG} the device do not support all profiles currently.`);
      return false;
    }

    this.connectTimestampManager.resetDeviceBondedFromLocal(deviceId);
    this.pauseDiscover();

    this.connectingIds.add(deviceId);
    return this.profileManager.startConnect(deviceId, this);
  }

  isPairOnlyDevice(deviceId: string): boolean {
    return checkPairOnlyDevice(deviceId);
  }

  private checkConnectConditionsValid(deviceId: string): boolean {
    return !CheckEmptyUtils.checkStrIsEmpty(deviceId) && !this.connectingIds.has(deviceId) &&
      !this.isDeviceConnected(deviceId);
  }

  /**
   * 断开连接
   *
   * @param deviceId 待断开连接的设备ID
   */
  disconnectDevice(deviceId: string): boolean {
    return this.profileManager.disconnectDevice(deviceId);
  }

  /**
   * disconnect profile.
   * @param deviceId device id
   * @param profileId profile id
   */
  disconnectProfile(deviceId: string | undefined, profileId: number): void {
    this.profileManager.disconnectProfile(deviceId, profileId)
  }

  /**
   * Connect profile.
   * @param deviceId device id
   * @param profileId profile id
   */
  connectProfile(deviceId: string, profileId: number): void {
    this.profileManager.connectProfile(deviceId, profileId);
  }

  onConnectResult(deviceId: string, result: number, isSuccess: boolean): void {
    LogUtil.info(`${TAG} onConnectResult. deviceId:${BluetoothUtils.getLogMAC(deviceId)} result:${result} isSuccess:${isSuccess}`);
    this.connectTimestampManager.resetDeviceConnectTimestamp(deviceId);
    this.dispatchConnectResult(deviceId, result, isSuccess);
    this.connectingIds.remove(deviceId);
    if (this.connectingIds.isEmpty()) {
      // 恢复扫描
      this.restoreDiscover();
    }
  }

  private dispatchConnectResult(deviceId: string, result: number, isSuccess: boolean): void {
    for (let listener of this.profileStateChangeListeners) {
      listener?.onConnectResult(deviceId, result, isSuccess);
    }
  }

  /**
   * 获取蓝牙管理类单例
   */
  static getInstance(): BluetoothAdapter {
    if (!Boolean(AppStorage.get<BluetoothAdapter>('bluetoothAdapter') as BluetoothAdapter).valueOf()) {
      AppStorage.setOrCreate<BluetoothAdapter>('bluetoothAdapter', new BluetoothAdapter());
    }
    return AppStorage.get<BluetoothAdapter>('bluetoothAdapter') as BluetoothAdapter;
  }
}


/**
 * 开关菜单控制器
 *
 * @since 2022-03-21
 */
export class BluetoothStrategySwitchMenuController extends SwitchMenuController implements BluetoothStateChangeListener,
BluetoothProfileStateChangeListener {
  public tag: string = 'BluetoothStrategySwitchMenuController';
  public isChecked: boolean = false;
  public device?: BluetoothDevice | null = null;
  public connectProfile: ConnectionProfile | null = null;
  public connectionProfile: ConnectionProfile | null = null;
  public lastSummaryStatus: SummaryStatus | null = null;
  public isRequestFocus: boolean = true;
  public refreshFromOther: boolean = false;
  public profileMap: Map<string, Map<ProfileId, ProfileConnectionState>> = new Map();

  getListenKey(): string {
    return this.getKey();
  }

  aboutToAppear(): void {
    LogUtil.info(`${this.tag} aboutToAppear`);
    super.aboutToAppear();
  }

  aboutToDisappear(): void {
    super.aboutToDisappear();
  }

  getConnectionProfile(): ConnectionProfile | null | undefined {
    return BluetoothAdapter.getInstance()
      .profileManager?.profiles?.get(this.getProfileId())?.connectionStrategyProfile;
  }

  onBluetoothStateChange(state: number): void {
    LogUtil.info(`${this.tag} onBluetoothStateChange, state :${state}`);
    this.updateToggleStatus(state, BluetoothUtils.isBluetoothDiscoveryOn(state) ?
      this.getConnectionProfile()?.getConnectionState(this.device!.deviceId as string) :
      ProfileConnectionState.STATE_DISCONNECTED);
  }

  onBluetoothProfileStateChange(profileId: ProfileId, stateChangeParam: StateChangeParam): void {
    if (!stateChangeParam) {
      return;
    }
    if (this.profileMap.has(stateChangeParam.deviceId)) {
      let deviceProfileMap: Map<ProfileId, ProfileConnectionState> | undefined =
        this.profileMap.get(stateChangeParam.deviceId);
      if (deviceProfileMap?.get(profileId)?.valueOf() === stateChangeParam.state.valueOf()) {
        LogUtil.info(`${this.tag} onBluetoothProfileStateChange , profileStateChange has changed`);
        return;
      }
    }
    if (this.profileMap.has(stateChangeParam.deviceId)) {
      let deviceProfileMap: Map<ProfileId, ProfileConnectionState> | undefined =
        this.profileMap.get(stateChangeParam.deviceId);
      if (deviceProfileMap) {
        deviceProfileMap.set(profileId, stateChangeParam.state);
      } else {
        deviceProfileMap = new Map();
        deviceProfileMap.set(profileId, stateChangeParam.state);
        this.profileMap.set(stateChangeParam.deviceId, deviceProfileMap);
      }
    } else {
      let deviceProfileMap: Map<ProfileId, ProfileConnectionState> = new Map();
      deviceProfileMap.set(profileId, stateChangeParam.state);
      this.profileMap.set(stateChangeParam.deviceId, deviceProfileMap);
    }
    LogUtil.info(`${this.tag} onBluetoothProfileStateChange, profileId: ${profileId},state :${stateChangeParam.state}`);
    if (profileId === this.getProfileId()) {
      this.refreshFromOther = false;
      this.updateToggleStatus(bluetooth.getState(), stateChangeParam.state);
    }
  }

  onConnectResult(deviceId: string, result: number, isSuccess: boolean): void {
  }

  protected getProfileId(): ProfileId {
    return ProfileId.PROFILE_A2DP_SOURCE;
  }

  protected getConnectProfileId(): constant.ProfileId {
    return constant.ProfileId.PROFILE_HID_HOST;
  }

  private getDevice(params: PushParam): BluetoothDevice | null {
    let device: BluetoothDevice | null = null;
    if (params) {
      device = params.config as BluetoothDevice;
    }
    if (!device) {
      LogUtil.info(`${this.tag} getDevice device invalid `);
      return null;
    }
    return device;
  }

  getProfileData(): void {
    LogUtil.info(`${this.tag} getProfileData`);
    this.device = this.getDevice(this.menu.navRouterParam as PushParam) as BluetoothDevice;
    if (!this.device) {
      LogUtil.error(`${this.tag} get device is null`);
    }
    let bluetoothProfile: BluetoothProfile =
      this.device.getConnectableProfiles()?.get(this.getProfileId()) as BluetoothProfile;
    this.connectProfile = bluetoothProfile?.connectionStrategyProfile;
  }

  updateStatus(): void {
    LogUtil.info(`${this.tag} updateStatus`);
    super.updateStatus();
    this.getProfileData();
    let state: number = bluetooth.getState();
    if (!this.device) {
      return;
    }
    let connectionState: ProfileConnectionState | undefined;
    try {
      connectionState = this.getConnectionProfile()?.getConnectionState(this.device!.deviceId as string);
    } catch (err) {
      LogUtil.error(`${this.tag} getConnectionState fail, err.code: ${err?.code}, err.message: ${err?.message}`);
    }

    if (BluetoothUtils.isBluetoothStateOff(state) || connectionState === ProfileConnectionState.STATE_DISCONNECTED) {
      this.isChecked = false;
      this.setSummary();
    } else if (BluetoothUtils.isBluetoothDiscoveryOn(state) &&
      connectionState === ProfileConnectionState.STATE_CONNECTED) {
      this.isChecked = this.device?.connectionStatusMap.get(this.getProfileId()) !==
      ConnectionStrategy.CONNECTION_STRATEGY_FORBIDDEN;
      if (this.isChecked) {
        this.setSelectorColor($r('app.color.profile_switch_color'));
      }
      this.setSummary();
    } else {
      if (connectionState !== ProfileConnectionState.STATE_DISCONNECTING) {
        this.setSummary($r('app.string.bt_connection_strategy_summary'));
      }
    }
    this.refreshUi();
  }

  protected registerDataChange(): void {
    BluetoothAdapter.getInstance().registerStateChangeListener(this);
    BluetoothAdapter.getInstance().registerProfileStateChangeListener(this);
  }

  protected unRegisterDataChange(): void {
    BluetoothAdapter.getInstance().unRegisterStateChangeListener(this);
    BluetoothAdapter.getInstance().unRegisterProfileStateChangeListener(this);
  }

  /**
   * 返回开关的实时状态
   */
  protected updateToggleStatus(state: number, profileState?: ProfileConnectionState, isInit: boolean = false): void {
    if (this.device) {
      let connectionState: ProfileConnectionState | undefined = profileState ??
      this.getConnectionProfile()?.getConnectionState(this.device.deviceId as string);
      LogUtil.info(`${this.tag} updateCheckedState start, blueState: ${state} , connectionState : ${connectionState}`);
      try {
        if (BluetoothUtils.isBluetoothStateOff(state) || connectionState ===
        ProfileConnectionState.STATE_DISCONNECTED) {
          LogUtil.info(`updateToggleStatus false, ProfileId ${this.getConnectProfileId()}, isOn: ${BluetoothUtils.isBluetoothStateOn(state)}`);
          this.isChecked = false;
          this.setSummary();
          if (!this.refreshFromOther) {
            this.refreshOtherSwitchStatus(true);
          }
          this.refreshFromOther = false;
          this.setToggleMenuStatus(true);
        } else if (BluetoothUtils.isBluetoothDiscoveryOn(state) &&
          connectionState === ProfileConnectionState.STATE_CONNECTED) {
          let timeOut: number = 0;
          if (!isInit) {
            timeOut = FRESH_PROFILE_TIME_OUT;
          }
          setTimeout(() => {
            (this.connectProfile as ConnectionProfile).getConnectionStrategy((this.device as BluetoothDevice).deviceId)
              .then((isCheck) => {
                LogUtil.info(`updateToggleStatus connectionStatusMap status : ${isCheck}`);
                if (!this.isChecked && isCheck === ConnectionStrategy.CONNECTION_STRATEGY_ALLOWED) {
                  if (!this.refreshFromOther) {
                    this.refreshALLSwitchStatus();
                  }
                }
                this.isChecked = isCheck === ConnectionStrategy.CONNECTION_STRATEGY_ALLOWED;
                if (this.isChecked) {
                  this.setSelectorColor($r('app.color.profile_switch_color'));
                }
                this.setSummary();
                if (!this.refreshFromOther) {
                  this.refreshOtherSwitchStatus(true);
                }
                this.refreshFromOther = false;
                this.setToggleMenuStatus(true);
              })
          }, timeOut)
        } else {
          if (connectionState !== ProfileConnectionState.STATE_DISCONNECTING) {
            this.setSummary($r('app.string.bt_connection_strategy_summary'));
          }
        }
        LogUtil.info(`refreshUi isChecked: ${this.isChecked} `);
        this.refreshUi();
      } catch (err) {
        LogUtil.info(`updateCheckedState error code: ${err?.code} message: ${err?.message}`)
      }
    }
  }

  setSelectorColor(resource: Resource): void {
    let style: SwitchMenuStyle = this.menu.style as SwitchMenuStyle;
    let toggleStyle: BluetoothSwitchToggleStyle = style.toggleStyle as BluetoothSwitchToggleStyle;
    toggleStyle.selectedColor = resource;
  }

  setToggleMenuStatus(status: boolean): void {
    if (!status) {
      this.setFontColor($r('app.color.color_E3E3E3_grey'));
      if (this.isChecked) {
        this.setSelectorColor($r('app.color.default_switch_color'));
      }
      this.refreshFontStyle();
      this.setToggleState(false, this.isRequestFocus);
      this.resetRequestFocus();
      return;
    } else {
      this.setFontColor();
      this.refreshFontStyle();
      this.setSelectorColor($r('app.color.profile_switch_color'));
      this.setToggleState(true, this.isRequestFocus);
      this.resetRequestFocus();
      return;
    }
  }

  setSummary(summaryMsg ?: Resource): void {
    LogUtil.info(`${this.tag} setSummary enter`);
    let style: SwitchMenuStyle = this.menu.style as SwitchMenuStyle;
    if (summaryMsg) {
      if (this.lastSummaryStatus === SummaryStatus.OPERATING) {
        return;
      }
      this.menu.summary = summaryMsg;
      ((style.rootContainer as ContainerStyle).size as SizeOptions).height = HEIGHT_64;
      this.setFontColor($r('app.color.color_E3E3E3_grey'));
      LogUtil.info(`${this.tag} setSummary is openning`);
      this.lastSummaryStatus = SummaryStatus.OPERATING;
      this.refreshFontStyle();
      this.setToggleState(false, this.isRequestFocus);
      this.resetRequestFocus();
    } else {
      let timeOut: number = 0;
      if (this.lastSummaryStatus === SummaryStatus.OPERATING) {
        timeOut = FRESH_TITLE_TIME_OUT;
      }
      if (timeOut === 0) {
        this.freshCompletedStatus(style);
      } else {
        setTimeout(() => {
          this.freshCompletedStatus(style);
        }, timeOut);
      }
      LogUtil.info(`${this.tag} setSummary is done`);
    }
  }

  private freshCompletedStatus(style: SwitchMenuStyle): void {
    this.menu.summary = this.isChecked ? $r('app.string.bt_connected_summary') : undefined;
    this.setFontColor();
    if (this.isChecked) {
      ((style.rootContainer as ContainerStyle).size as SizeOptions).height = HEIGHT_64;
    } else {
      ((style.rootContainer as ContainerStyle).size as SizeOptions).height = HEIGHT_48;
    }
    this.refreshFontStyle();
    this.lastSummaryStatus = SummaryStatus.DONE;
    this.setToggleState(true, this.isRequestFocus);
    this.resetRequestFocus();
  }

  resetRequestFocus(): void {
    this.isRequestFocus = true;
  }

  setFontColor(fontColor?: Resource): void {
    LogUtil.info(`${this.tag} setFontColor enter`);
    let style: SwitchMenuStyle = this.menu.style as SwitchMenuStyle;
    if (fontColor) {
      (style.title as TextStyle).fontColor = fontColor;
      (style.summary as TextStyle).fontColor = fontColor;
    } else {
      (style.title as TextStyle).fontColor = $r('sys.color.ohos_id_color_text_primary');
      (style.summary as TextStyle).fontColor = $r('sys.color.ohos_id_color_text_secondary');
    }
  }

  reportStrategySwitchChangeEvent(isOn: boolean): void {
    switch (this.getProfileId()) {
      case ProfileId.PROFILE_A2DP_SOURCE:
        HiSysEventUtil.reportDefaultBehaviorEvent(HiSysBluetoothEventGroup.A2DP_SWITCH_CHANGE, isOn ? 'on' : 'off');
        break;
      case ProfileId.PROFILE_HANDS_FREE_AUDIO_GATEWAY:
        HiSysEventUtil.reportDefaultBehaviorEvent(HiSysBluetoothEventGroup.HFP_SWITCH_CHANGE, isOn ? 'on' : 'off');
        break;
      default:
        break;
    }
  }

  onToggleChange(isOn: boolean): boolean {
    LogUtil.info(`${this.tag} onToggleChange ${isOn}`);
    if (isOn === this.isChecked) {
      return false;
    }
    if (!this.device) {
      return false;
    }
    this.reportStrategySwitchChangeEvent(isOn);
    let booleanValue = Boolean(isOn).valueOf();
    if (booleanValue === false) {
      if (BluetoothUtils.isBluetoothStateOff(bluetooth.getState()) ||
        this.getConnectionProfile()?.getConnectionState(this.device!.deviceId as string) ===
        ProfileConnectionState.STATE_DISCONNECTED) {
        LogUtil.info(`${this.tag} handleCheckedChange setCheck false , bluetooth is off or profile is not connected`);
        return false;
      }
    }
    if (isOn) {
      this.setSummary($r('app.string.bt_connection_strategy_summary'));
    } else {
      this.setToggleMenuStatus(false);
    }
    this.refreshOtherSwitchStatus(false);
    this.handleCheckedChange(booleanValue);
    return true;
  }

  /**
   * 刷新其他toggle的可使用状态
   */
  refreshOtherSwitchStatus(status: boolean): void {
    this.publishDataChange(new ProfileSwitchEventParam(this.getProfileId(), status));
  }

  /**
   * 返回开关的保存状态
   */
  getChecked(): boolean {
    LogUtil.info(`${this.tag} getChecked ${this.isChecked}`);
    return this.isChecked;
  }

  /**
   * 设置开关的状态
   */
  setChecked(isChecked: boolean): void {
    LogUtil.info(`${this.tag} setChecked ${isChecked}`);
    if (this.isChecked !== isChecked) {
      this.isChecked = isChecked;
      LogUtil.info(`${this.tag} setChecked, refresh : ${this.isChecked}`);
      this.refreshUi();
    }
  }

  /**
   * 再设置完某一协议值后需要刷新其他开关的状态值,看是否需要联动打开
   */
  refreshALLSwitchStatus(): void {
    this.publishDataChange(new ProfileSwitchEventParam(this.getProfileId(), undefined));
  }

  onDataChange(fromKey: string, data: object): void {
    let passData: ProfileSwitchEventParam = data as ProfileSwitchEventParam;
    if (this.device) {

      LogUtil.info(`${this.tag} onDataChange , profileId: ${passData.profileId}, status: ${this.getConnectionProfile()?.getConnectionState(this.device?.deviceId as string)}`);
      this.isRequestFocus = false;
      this.refreshFromOther = fromKey !== this.menu.key;
      if (passData.status !== undefined) {
        if (fromKey === this.menu.key) {
          this.isRequestFocus = true;
        }
        this.setToggleMenuStatus(passData.status as boolean);
      } else {
        if (this.isChecked) {
          return;
        }
        if (this.device && passData.profileId !== this.getProfileId()) {
          this.setSummary($r('app.string.bt_connection_strategy_summary'));
          this.updateToggleStatus(bluetooth.getState(),
            this.getConnectionProfile()?.getConnectionState(this.device!.deviceId as string));
        }
      }
    }
  }

  /**
   * 开关变化的回调
   */
  protected handleCheckedChange(isChecked: boolean): boolean {
    LogUtil.info(`${this.tag} handleCheckedChange ${isChecked}`);
    if (this.device && this.connectProfile) {
      try {
        this.connectProfile.setConnectionStrategy(this.device.deviceId, isChecked ?
          ConnectionStrategy.CONNECTION_STRATEGY_ALLOWED : ConnectionStrategy.CONNECTION_STRATEGY_FORBIDDEN)
          .then(() => {
            (this.connectProfile as ConnectionProfile).getConnectionStrategy((this.device as BluetoothDevice).deviceId)
              .then((isCheck) => {
                if (this.device) {
                  this.device.addConnectionStatus(this.getProfileId(), isCheck ?
                    ConnectionStrategy.CONNECTION_STRATEGY_ALLOWED :
                    ConnectionStrategy.CONNECTION_STRATEGY_FORBIDDEN);
                  this.updateToggleStatus(bluetooth.getState(),
                    this.getConnectionProfile()?.getConnectionState(this.device!.deviceId as string));
                }
              })
          })
        return true;
      } catch (err) {
        LogUtil.error(`${this.tag}handleCheckedChange code: ${err?.code} message: ${err?.message}`);
        return false;
      }
    }
    return false;
  }
}

export class A2dpStrategySwitchMenuController extends BluetoothStrategySwitchMenuController {
  public tag: string = 'A2dpStrategySwitchMenuController';

  static createA2dpStrategySwitchMenuController(menu: SettingsBaseMenu): Controller {
    return new A2dpStrategySwitchMenuController(menu);
  }

  aboutToAppear(): void {
    LogUtil.info(`${this.tag} aboutToAppear`);
    super.aboutToAppear();
  }

  aboutToDisappear(): void {
    LogUtil.info(`${this.tag} aboutToDisappear`);
    super.aboutToDisappear();
  }

  protected getProfileId(): ProfileId {
    return ProfileId.PROFILE_A2DP_SOURCE;
  }

  protected getConnectProfileId(): constant.ProfileId {
    return constant.ProfileId.PROFILE_A2DP_SOURCE;
  }

  protected registerDataChange(): void {
    this.registerControllerDataChange(HID_DEVICE_KEY);
    this.registerControllerDataChange(HFP_DEVICE_KEY);
    super.registerDataChange();
  }

  protected unRegisterDataChange(): void {
    this.unRegisterControllerDataChange(HID_DEVICE_KEY);
    this.unRegisterControllerDataChange(HFP_DEVICE_KEY);
    super.unRegisterDataChange();
  }
}

export class HfpStrategySwitchMenuController extends BluetoothStrategySwitchMenuController {
  static CreateHfpStrategySwitchMenuController(menu: SettingsBaseMenu): Controller {
    return new HfpStrategySwitchMenuController(menu);
  }

  public tag: string = 'HfpStrategySwitchMenuController';

  aboutToAppear(): void {
    LogUtil.info(`${this.tag} aboutToAppear`);
    super.aboutToAppear();
  }

  aboutToDisappear(): void {
    LogUtil.info(`${this.tag} aboutToDisappear`);
    super.aboutToDisappear();
  }

  protected getProfileId(): ProfileId {
    return ProfileId.PROFILE_HANDS_FREE_AUDIO_GATEWAY;
  }

  protected registerDataChange(): void {
    this.registerControllerDataChange(A2DP_DEVICE_KEY);
    this.registerControllerDataChange(HID_DEVICE_KEY);
    super.registerDataChange();
  }

  protected getConnectProfileId(): constant.ProfileId {
    return constant.ProfileId.PROFILE_HANDSFREE_AUDIO_GATEWAY;
  }

  protected unRegisterDataChange(): void {
    this.unRegisterControllerDataChange(A2DP_DEVICE_KEY);
    this.registerControllerDataChange(HID_DEVICE_KEY);
    super.unRegisterDataChange();
  }
}

export class HidStrategySwitchMenuController extends BluetoothStrategySwitchMenuController {
  public tag: string = 'HidStrategySwitchMenuController';

  static CreateHidStrategySwitchMenuController(menu: SettingsBaseMenu): Controller {
    return new HidStrategySwitchMenuController(menu);
  }

  aboutToAppear(): void {
    LogUtil.info(`${this.tag} aboutToAppear`);
    super.aboutToAppear();
  }

  aboutToDisappear(): void {
    LogUtil.info(`${this.tag} aboutToDisappear`);
    super.aboutToDisappear();
  }

  protected getProfileId(): ProfileId {
    return ProfileId.PROFILE_HID_HOST;
  }

  protected registerDataChange(): void {
    this.registerControllerDataChange(A2DP_DEVICE_KEY);
    this.registerControllerDataChange(HFP_DEVICE_KEY);
    super.registerDataChange();
  }

  protected getConnectProfileId(): constant.ProfileId {
    return constant.ProfileId.PROFILE_HID_HOST;
  }

  protected unRegisterDataChange(): void {
    this.unRegisterControllerDataChange(A2DP_DEVICE_KEY);
    this.unRegisterControllerDataChange(HFP_DEVICE_KEY);
    super.unRegisterDataChange();
  }
}

export class BluetoothDeviceVolumeSyncPhoneSwitchMenuController extends SwitchMenuController {
  public TAG: string = 'BluetoothDeviceVolumeSyncPhoneSwitchMenuController';
  public deviceId: string;
  public absoluteVolumeEnabled: boolean = false;

  static createBluetoothDeviceVolumeSyncPhoneSwitchMenuController(menu: SettingsBaseMenu): Controller {
    return new BluetoothDeviceVolumeSyncPhoneSwitchMenuController(menu);
  }

  constructor(menu: SettingsBaseMenu) {
    super(menu);
    this.deviceId = (this.menu?.extra as VolumeSyncParam)?.deviceId;
    this.absoluteVolumeEnabled = (this.menu?.extra as VolumeSyncParam)?.isOn;
    LogUtil.info(`${this.TAG} ${BluetoothUtils.getLogMAC(this.deviceId)} , absoluteVolumeEnabled =  ${this.absoluteVolumeEnabled}`);
    this.setChecked(this.absoluteVolumeEnabled);
  }

  aboutToAppear(): void {
    LogUtil.info(`${this.tag} aboutToAppear ${this.getLogKey()}`);
    this.updateCheckedState();
  }

  /**
   * 开关变化的回调
   */
  protected handleCheckedChange(isChecked: boolean): boolean {
    LogUtil.info(`${this.TAG} handleCheckedChange ${isChecked}`);
    if (isChecked) {
      this.enableAbsoluteVolume();
    } else {
      this.disableAbsoluteVolume();
    }
    return true;
  }

  /**
   * 开启蓝牙设备音量与手机同步开关
   */
  private async enableAbsoluteVolume(): Promise<void> {
    if (this.deviceId) {
      try {
        await a2dp.createA2dpSrcProfile()?.enableAbsoluteVolume(this.deviceId).then(() => {
          LogUtil.info(`${this.TAG} enableAbsoluteVolume success`);
          HiSysEventUtil.reportDefaultBehaviorEventByUE(HiSysAboutBluetoothEventGroup.BLUETOOTH_SYNC_VOLUME_SWITCH,
            'on');
          this.updateStatus();
        });
      } catch (err) {
        LogUtil.error(`${this.TAG}  : errCode: ${err?.code} , errMessage: ${err?.message}`);
        this.setChecked(false);
      }
    }
  }

  /**
   * 关闭蓝牙设备音量与手机同步开关
   */
  private async disableAbsoluteVolume(): Promise<void> {
    if (this.deviceId) {
      try {
        await a2dp.createA2dpSrcProfile()?.disableAbsoluteVolume(this?.deviceId).then(() => {
          LogUtil.info(`${this.TAG} disableAbsoluteVolume success`);
          HiSysEventUtil.reportDefaultBehaviorEventByUE(HiSysAboutBluetoothEventGroup.BLUETOOTH_SYNC_VOLUME_SWITCH,
            'off');
          this.updateStatus();
        });
      } catch (err) {
        LogUtil.error(`${this.TAG}  : errCode: ${err?.code} , errMessage: ${err?.message}`);
        this.setChecked(true);
      }
    }
  }

  aboutToDisappear(): void {
    LogUtil.info(`${this.TAG} aboutToDisappear`);
    super.aboutToDisappear();
  }
}

class ProfileSwitchEventParam {
  public profileId: number;
  public status?: boolean;

  constructor(profileId: number, status?: boolean) {
    this.profileId = profileId;
    this.status = status;
  }
}