mcu_hi3321_watch/tjd/ui/app/player/TjdUiAppPlayerBTImpl.cpp
2025-05-26 20:15:20 +08:00

249 lines
8.6 KiB
C++

/*----------------------------------------------------------------------------
* 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<HeadsetInfo> &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<TjdUiAppPlayerBTImpl *>(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<TjdUiAppPlayerBTImpl *>(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