/*---------------------------------------------------------------------------- * Copyright (c) TJD Technologies Co., Ltd. 2025. All rights reserved. * * Description: TjdUiAppPlayerBTImpl.cpp * * Author: luziquan@ss-tjd.com * * Create: 2025-01-03 *--------------------------------------------------------------------------*/ #include "TjdUiAppPlayerModel.h" #include "TjdUiAppPlayerPresenter.h" #include "TjdUiAppPlayerView.h" #include "TjdUiMultiLanguage.h" #include "TjdUiScreenManage.h" #include "graphic_service.h" #include "service_bt.h" namespace TJD { TjdUiAppPlayerBTImpl::TjdUiAppPlayerBTImpl() {} TjdUiAppPlayerBTImpl::~TjdUiAppPlayerBTImpl() {} #pragma region 耳机扫描 // 列表去重 bool IsExist(std::list &headsetList, const char *name) { for (auto &headset : headsetList) { if (strcmp(headset.name.c_str(), name) == 0) { return true; } } return false; } static bool RssiCompare(const HeadsetInfo &a, const HeadsetInfo &b) { if (a.isConnect && !b.isConnect) { return true; } else if (!a.isConnect && b.isConnect) { return false; } else if (a.isPaired && !b.isPaired) { return true; } else if (!a.isPaired && b.isPaired) { return false; } return a.rssi >= b.rssi; } void TjdUiAppPlayerBTImpl::ScanHeadsetTimerProc() { TjdUiAppPlayerModel *model = TjdUiAppPlayerModel::GetInstance(); TjdUiAppPlayerView *view = TjdUiAppPlayerView::GetInstance(); TjdUiAppPlayerPresenter *presenter = TjdUiAppPlayerPresenter::GetInstance(); if (view == nullptr) { return; } auto currrentView = view->GetCurrentView(); if (++scanHeadsetTimerCount_ == 5) { // 最多扫描10秒 StopScanHeadsetTimer(); /* 10秒后直接跳回列表页面 */ if (currrentView == PlayerViewIndex::SEARCHING_VIEW) { presenter->IsNeedUpdateHeadsetList = true; view->ShowView(PlayerViewIndex::SEARCH_LIST_VIEW); } scanHeadsetTimerCount_ = 0; return; } // 遍历蓝牙耳机列表 osal_list_head *list_head = TjdUiAppPlayerModel::GetInstance()->GetHeadsetInfo(); osal_list_head *node = list_head->next; for (osal_list_head *node = list_head->next; node != NULL && node != list_head; node = node->next) { found_dev_list_node *dev_info = (found_dev_list_node *)node; if (IsExist(headsetList_, (const char *)dev_info->name)) { continue; } headsetList_.push_back({(const char *)dev_info->name, dev_info->bd_addr, dev_info->rssi, dev_info->isPaired, dev_info->isConnected}); if (headsetList_.size() > 1) { // 按信号强度排序 headsetList_.sort(RssiCompare); } presenter->IsNeedUpdateHeadsetList = true; // 搜索到1个设备后马上跳到列表界面 if (currrentView == PlayerViewIndex::SEARCHING_VIEW || currrentView == PlayerViewIndex::SEARCH_LIST_VIEW) { view->ShowView(PlayerViewIndex::SEARCH_LIST_VIEW); } if (dev_info->isConnected) { model->SetConnectEarpod(true); view->SetConnectDevice(OHOS::UICheckBox::UICheckBoxState::SELECTED); StopScanHeadsetTimer(); return; } } } void TjdUiAppPlayerBTImpl::StartScanHeadsetTimer() { TjdUiAppPlayerView *view = TjdUiAppPlayerView::GetInstance(); if (view == nullptr) { return; } if (scanHeadsetTimerId_ == nullptr) { scanHeadsetTimerId_ = osTimerNew( [](void *arg) { auto *btImpl = static_cast(arg); GraphicService::GetInstance()->PostGraphicEvent([btImpl]() { btImpl->ScanHeadsetTimerProc(); }); }, osTimerPeriodic, (void *)this, nullptr); if (scanHeadsetTimerId_ == nullptr) { static_print_error("TjdUiAppPlayerPresenter::StartScanHeadset Create timer fail."); return; } } if (osTimerIsRunning(scanHeadsetTimerId_)) { static_print_error("TjdUiAppPlayerPresenter::StartScanHeadset timer is running"); osTimerStop(scanHeadsetTimerId_); osDelay(50); } gap_br_set_bt_scan_mode(GAP_SCAN_MODE_CONNECTABLE_GENERAL_DISCOVERABLE, 180); // 扫描前清空列表进入等待界面 scanHeadsetTimerCount_ = 0; headsetList_.clear(); view->SetConnectDevice(OHOS::UICheckBox::UICheckBoxState::UNSELECTED); view->SetWaitViewInfo(STR_ID_273); view->ShowView(PlayerViewIndex::SEARCHING_VIEW); TjdUiAppPlayerModel::GetInstance()->StartHeadsetPlug(); int32_t ret = osTimerStart(scanHeadsetTimerId_, 2000); if (ret != 0) { static_print_error("TjdUiAppPlayerPresenter::StartScanHeadset Start timer fail"); return; } TjdUiScreenManage::SetScreenKeepOnTimeout(1000 * 60 * 60); } void TjdUiAppPlayerBTImpl::StopScanHeadsetTimer() { TjdUiScreenManage::SetScreenKeepOnTimeout(); if (scanHeadsetTimerId_ == nullptr) { return; } int32_t ret = osTimerStop(scanHeadsetTimerId_); if (ret != 0) { static_print_error("TjdUiAppPlayerBTImpl::StopScanHeadsetTimer Stop timer fail"); return; } // 停止蓝牙扫描 TjdUiAppPlayerModel::GetInstance()->StopHeadsetPlug(); } HeadsetInfo *TjdUiAppPlayerBTImpl::GetHeadsetInfo(bd_addr_t targetAddr) { for (auto &item : headsetList_) { if (std::equal(std::begin(item.bdAddr.addr), std::begin(item.bdAddr.addr) + BD_ADDR_LEN, std::begin(targetAddr.addr))) { return &item; } } return nullptr; } #pragma endregion #pragma region 连接耳机 void TjdUiAppPlayerBTImpl::ConnectHeadsetTimerProc() { TjdUiAppPlayerView *view = TjdUiAppPlayerView::GetInstance(); if (view == nullptr) { return; } static int retry = 0; auto *headset = GetHeadsetInfo(selectDeviceAddr_); if (headset == nullptr) { static_print_error("ConnectHeadsetTimerProc GetHeadsetInfo fail"); StopConnectHeadsetTimer(); return; } bool isConnect = TjdUiAppPlayerModel::GetInstance()->IsConnectHeadset(headset->bdAddr); if (isConnect == false) { if (++retry > 3) { retry = 0; StopConnectHeadsetTimer(); view->SetDeviceInfo(headset->name.c_str(), headset->isConnect); view->SetConnectDevice(OHOS::UICheckBox::UICheckBoxState::UNSELECTED); view->ShowView(PlayerViewIndex::CONNECT_FAIL_VIEW); TjdUiAppPlayerPresenter::GetInstance()->StartJumpTimer(PlayerViewIndex::DEVICE_CONNECT_VIEW); return; } static_print_error("ConnectHeadsetTimerProc ConnectHeadset fail"); StartConnectHeadsetTimer(); return; } retry = 0; headset->isConnect = true; view->SetDeviceInfo(headset->name.c_str(), headset->isConnect); view->SetConnectDevice(OHOS::UICheckBox::UICheckBoxState::SELECTED); view->ShowView(PlayerViewIndex::CONNECT_SUCCESS_VIEW); view->SetDeviceState(PlayerSource::PLAYER_SOURCE_WATCH, true); TjdUiAppPlayerModel::GetInstance()->SetConnectEarpod(true); TjdUiAppPlayerPresenter::GetInstance()->StartJumpTimer(PlayerViewIndex::DEVICE_VIEW); } void TjdUiAppPlayerBTImpl::StartConnectHeadsetTimer(void) { if (connectHeadsetTimerId_ == nullptr) { connectHeadsetTimerId_ = osTimerNew( [](void *arg) { auto *btImpl = static_cast(arg); GraphicService::GetInstance()->PostGraphicEvent([btImpl]() { btImpl->ConnectHeadsetTimerProc(); }); }, osTimerOnce, (void *)this, nullptr); if (connectHeadsetTimerId_ == nullptr) { static_print_error("TjdUiAppPlayerBTImpl::StartConnectHeadsetTimer Create timer fail."); return; } } if (osTimerIsRunning(connectHeadsetTimerId_)) { static_print_error("TjdUiAppPlayerBTImpl::StartConnectHeadsetTimer timer is running"); osTimerStop(connectHeadsetTimerId_); osDelay(50); } // 开始连接目标耳机,停止扫描 int32_t ret = osTimerStart(connectHeadsetTimerId_, 1000); if (ret != 0) { static_print_error("TjdUiAppPlayerBTImpl::StartConnectHeadsetTimer Start timer fail"); return; } } void TjdUiAppPlayerBTImpl::StopConnectHeadsetTimer(void) { if (connectHeadsetTimerId_ == nullptr) { return; } int32_t ret = osTimerStop(connectHeadsetTimerId_); if (ret != 0) { static_print_error("TjdUiAppPlayerBTImpl::StopConnectHeadsetTimer Stop timer fail"); return; } } #pragma endregion } // namespace TJD