249 lines
8.6 KiB
C++
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
|