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

888 lines
32 KiB
C++

/*----------------------------------------------------------------------------
* Copyright (c) TJD Technologies Co., Ltd. 2025. All rights reserved.
*
* Description: TjdUiAppPlayerPresenter.cpp
*
* Author: luziquan@ss-tjd.com
*
* Create: 2024-06-07
*--------------------------------------------------------------------------*/
#include "TjdUiAppPlayerPresenter.h"
#include "NativeAbility.h"
#include "TjdPhoneService.h"
#include "TjdUiAppPlayerAdapter.h"
#include "TjdUiAppPlayerModel.h"
#include "TjdUiAppPlayerView.h"
#include "TjdUiRegisterManager.h"
#include "TjdUiScreenManage.h"
#include "dock/input_device.h"
#include "graphic_service.h"
#include "hal_tick.h"
#include "sys_config.h"
#include "ui_screennotify.h"
#define ENABLE_PRINT_INFO 1
#define ENABLE_DEBUG 1
#if ENABLE_PRINT_INFO
#define static_print_info(...) sys_ui_log_i(__VA_ARGS__) // 一般信息打印宏控制
#define static_print_warn(...) sys_ui_log_w(__VA_ARGS__) // 警告信息打印一般常开
#define static_print_error(...) sys_ui_log_e(__VA_ARGS__) // 错误信息打印一般常开
#if ENABLE_DEBUG
#define static_print_debug(...) sys_ui_log_d(__VA_ARGS__) // 调试信息打印一般常开
#else
#define static_print_debug(...)
#endif
#else
#define static_print_info(...)
#define static_print_warn(...)
#define static_print_error(...)
#endif
namespace TJD {
TJD_REGIST_NATIVE_MENU(TJD_APP_VIEW_PLAYER, TjdUiAppPlayerView, TjdUiAppPlayerPresenter, IMG_MENU_LIST_MENU_MUSIC,
STR_ID_10);
static TjdUiAppPlayerPresenter *g_playerPresenter = nullptr;
TjdUiAppPlayerPresenter::TjdUiAppPlayerPresenter()
: volumeListener_(new VolumeChangeListener()), btImpl_(new TjdUiAppPlayerBTImpl()), lrcParser_(new LrcParser())
{
g_playerPresenter = this;
SetPeriod(100);
playModeResMap[static_cast<int>(PlayMode::SEQUENCE)] = IMG_MUSIC_SEQUENTIAL;
playModeResMap[static_cast<int>(PlayMode::REPEATS)] = IMG_MUSIC_AGAIN;
playModeResMap[static_cast<int>(PlayMode::RANDOM)] = IMG_MUSIC_RANDOM;
}
TjdUiAppPlayerPresenter::~TjdUiAppPlayerPresenter() { g_playerPresenter = nullptr; }
TjdUiAppPlayerPresenter *TjdUiAppPlayerPresenter::GetInstance(void) { return g_playerPresenter; }
void TjdUiAppPlayerPresenter::OnStart()
{
TjdUiCommonOnKeyListener::GetInstance()->SetOnKeyActListener(this, KeyModelType::APP_KEY_TYPE);
PlayersListGroup::GetInstance()->SetUpListCase();
TjdUiAppPlayerModel *model = TjdUiAppPlayerModel::GetInstance();
int16_t curMusicIndex = GetCurMusicIndex();
if (curMusicIndex < 0) {
curMusicIndex = 0;
model->SetCurrentIndex(curMusicIndex);
}
model->PlayerInit();
/* 如果是音乐正在播放,则开启歌词解析 */
if (IsPlaying()) {
UpdateLrcData();
view_->SetPlayerButtonState(OHOS::UICheckBox::UICheckBoxState::SELECTED);
}
char *musicName = PlayersListGroup::GetInstance()->GetCase(model->GetCurrentIndex());
SetMusicName(musicName == nullptr ? "无音乐" : musicName);
/* 初始化读取模式 */
view_->ChangedImage(playModeResMap[static_cast<int>(model->GetPlayMode())]);
view_->SetDeviceState(model->GetPlayerDeviceState());
view_->ShowView(PlayerViewIndex::PLAYER_VIEW);
}
void TjdUiAppPlayerPresenter::OnStop()
{
TjdUiCommonOnKeyListener::GetInstance()->ClearOnKeyActListener(KeyModelType::APP_KEY_TYPE);
OHOS::FocusManager::GetInstance()->ClearFocus();
/* 如果退出时是手表音乐并且没有在播放,则销毁资源 */
if (TjdUiAppPlayerModel::GetInstance()->GetPlayerDeviceState() == PlayerSource::PLAYER_SOURCE_WATCH &&
IsPlaying() == false) {
PlayerInterruptListener::StopPlayer();
}
}
void TjdUiAppPlayerPresenter::Notify()
{
TjdUiAppPlayerModel *model = TjdUiAppPlayerModel::GetInstance();
if (view_->GetCurrentView() != PlayerViewIndex::PLAYER_VIEW) {
return;
}
/* 手机音乐的歌词同步不在Notify里实现 */
if (model->GetPlayerDeviceState() == PlayerSource::PLAYER_SOURCE_PHONE) {
return;
}
if (IsPlaying() == false || lrcRunning_.load() == false) {
return;
}
if (seekFlag_) {
seekFlag_ = false;
model->GetPlayerCtr().get()->Rewind(seekTime_, OHOS::Media::PlayerSeekMode::PLAYER_SEEK_CLOSEST_SYNC);
}
const int64_t curPosition = model->GetCurrentPosition();
const uint64_t duration = model->GetDuration();
view_->SetTime(curPosition, duration);
if (curPosition > (lrcParser_->duration() + 1000)) {
return;
}
if (lrcParser_->seek(curPosition)) {
LyricPacket data = lrcParser_->readPacket();
if (data.isEmpty() || lrc_ == data.lyric) {
return;
}
view_->SyncLyric(data.lyric.c_str());
lrc_ = data.lyric;
}
}
void TjdUiAppPlayerPresenter::ExitPlayerView(void)
{
// int32_t playerState;
// PlayerInterruptListener::StopPlayer();
// TjdUiAppPlayerModel::GetInstance()->GetPlayerCtr()->GetPlayerState(playerState);
// if (playerState == PlayerStates::PLAYER_STARTED) {
// TjdUiAppPlayerModel::GetInstance()->GetPlayerCtr()->Stop();
// }
OHOS::NativeAbility::GetInstance().ChangePreSlice();
}
void TjdUiAppPlayerPresenter::ViewExitProcess(bool isSwipe)
{
switch (view_->GetCurrentView()) {
case PlayerViewIndex::PLAYER_VIEW:
ExitPlayerView();
break;
case PlayerViewIndex::MUSIC_LIST_VIEW:
case PlayerViewIndex::VOLUME_VIEW:
case PlayerViewIndex::DEVICE_VIEW:
case PlayerViewIndex::LOW_POWER_VIEW:
view_->ShowView(PlayerViewIndex::PLAYER_VIEW);
break;
case PlayerViewIndex::SEARCH_LIST_VIEW:
case PlayerViewIndex::CONNECT_APP_FAIL_VIEW:
view_->ShowView(PlayerViewIndex::DEVICE_VIEW);
break;
case PlayerViewIndex::DEVICE_CONNECT_VIEW:
view_->ShowView(PlayerViewIndex::SEARCH_LIST_VIEW);
break;
case PlayerViewIndex::DELETE_MUSIC_VIEW:
view_->ShowView(PlayerViewIndex::MUSIC_LIST_VIEW);
break;
default:
break;
}
}
bool TjdUiAppPlayerPresenter::OnKeyAct(OHOS::UIView &view, const OHOS::KeyEvent &event)
{
if (!TjdUiCommonOnKeyListener::CheckIsExitEvent(event)) {
return true;
}
ViewExitProcess(false);
return true;
}
void TjdUiAppPlayerPresenter::OnChange(int32_t value)
{
const uint64_t duration = TjdUiAppPlayerModel::GetInstance()->GetDuration();
uint64_t curPosition = static_cast<uint64_t>((value / 100.0) * duration);
view_->SetTime(curPosition, duration, true);
}
void TjdUiAppPlayerPresenter::OnRelease(int32_t value)
{
if (IsPlaying() == false) {
return;
}
const int64_t curPosition = TjdUiAppPlayerModel::GetInstance()->GetCurrentPosition();
const uint64_t duration = TjdUiAppPlayerModel::GetInstance()->GetDuration();
// sounding -> 0-100 -> 0-duration
seekTime_ = static_cast<int64_t>((value / 100.0) * duration);
seekFlag_ = true;
}
void TjdUiAppPlayerPresenter::PlayerButtonReset(void)
{
if (view_->GetPlayerButtonState() == OHOS::UICheckBox::UICheckBoxState::UNSELECTED) {
view_->SetPlayerButtonState(OHOS::UICheckBox::UICheckBoxState::SELECTED);
} else {
view_->SetPlayerButtonState(OHOS::UICheckBox::UICheckBoxState::UNSELECTED);
}
}
void TjdUiAppPlayerPresenter::PlayerBackReset(void)
{
view_->SetPlayerButtonState(OHOS::UICheckBox::UICheckBoxState::UNSELECTED);
}
void TjdUiAppPlayerPresenter::SetMusicName(const char *musicName) { view_->SetCurrentMusicName(musicName); }
int16_t TjdUiAppPlayerPresenter::GetCurMusicIndex(void)
{
return TjdUiAppPlayerModel::GetInstance()->GetCurrentIndex();
}
bool TjdUiAppPlayerPresenter::IsPlaying()
{
TjdUiAppPlayerModel *model = TjdUiAppPlayerModel::GetInstance();
if (model->GetPlayerDeviceState() == PlayerSource::PLAYER_SOURCE_PHONE) {
return model->PhoneAudioIsPlaying();
}
return model->GetPlayerCtr()->IsPlaying();
}
std::string *TjdUiAppPlayerPresenter::GetLrcPath()
{
std::string path = TJD_FS_DIR_MUSIC;
std::string name = PlayersListGroup::GetInstance()->GetCase(GetCurMusicIndex());
if (name.empty()) {
static_print_error("GetLrcPath name is nullptr");
return nullptr;
}
std::string pureName = name.substr(0, name.rfind("."));
path += "/";
path += pureName;
path += ".lrc";
lrcPath_ = path;
return &lrcPath_;
}
#pragma region 音量调节
VolumeChangeListener::VolumeChangeListener()
{
debounceThread_ = std::thread(&VolumeChangeListener::DebouncedSetVolume, this);
}
VolumeChangeListener::~VolumeChangeListener()
{
{
std::lock_guard<std::mutex> lock(mtx_);
stopThread_ = true;
}
cv_.notify_all();
debounceThread_.join();
}
void VolumeChangeListener::DebouncedSetVolume()
{
while (true) {
std::unique_lock<std::mutex> lock(mtx_);
cv_.wait(lock, [this] { return debounceActive_.load() || stopThread_; });
if (stopThread_) {
break;
}
debounceActive_.store(false);
lock.unlock();
osDelay(debounceInterval_);
lock.lock();
if (!debounceActive_.load()) {
TjdUiAppPlayerModel::GetInstance()->SetVolume(lastVolume_.load());
}
}
}
void VolumeChangeListener::OnChange(int32_t value)
{
lastVolume_.store(value);
{
std::lock_guard<std::mutex> lock(mtx_);
debounceActive_.store(true);
}
cv_.notify_all();
}
void VolumeChangeListener::OnRelease(int32_t sounding) { TjdUiAppPlayerModel::GetInstance()->SetVolume(sounding); }
#pragma endregion
void TjdUiAppPlayerPresenter::StartJumpTimer(PlayerViewIndex jumpView, uint32_t ticks)
{
if (jumpTimerId_ == nullptr) {
jumpTimerId_ = osTimerNew(
[](void *arg) {
PlayerViewIndex jumpView = static_cast<PlayerViewIndex>(reinterpret_cast<intptr_t>(arg));
GraphicService::GetInstance()->PostGraphicEvent([jumpView]() {
TjdUiAppPlayerView *view = TjdUiAppPlayerView::GetInstance();
if (view == nullptr) {
return;
}
if (view->GetCurrentView() != jumpView) {
view->ShowView(jumpView);
}
TjdUiAppPlayerPresenter::GetInstance()->DeleteJumpTimer();
});
},
osTimerOnce, reinterpret_cast<void *>(static_cast<intptr_t>(jumpView)), nullptr);
if (jumpTimerId_ == nullptr) {
static_print_error("TjdUiAppAlipayModel::AlipayStartBind Create timer fail.");
return;
}
}
int32_t ret = osTimerStart(jumpTimerId_, ticks);
if (ret != 0) {
static_print_error("TjdUiAppAlipayModel::AlipayStartBind Start timer fail");
return;
}
}
void TjdUiAppPlayerPresenter::DeleteJumpTimer(void)
{
if (jumpTimerId_ != nullptr) {
osTimerDelete(jumpTimerId_);
jumpTimerId_ = nullptr;
}
}
#pragma region 蓝牙播放器状态监听
void TjdUiAppPlayerPresenter::PhonePlayerStatusChange(int state)
{
avrcp_play_status_t playStatus = static_cast<avrcp_play_status_t>(state);
if (state == avrcp_play_status_t::AVRCP_PLAY_STATUS_PLAYING) {
view_->SetPlayerButtonState(OHOS::UICheckBox::UICheckBoxState::SELECTED);
} else {
view_->SetPlayerButtonState(OHOS::UICheckBox::UICheckBoxState::UNSELECTED);
}
}
void TjdUiAppPlayerPresenter::UpdateLrcData(void)
{
lrcRunning_.store(false);
static_print_debug("UpdateLrcData");
std::string *str = GetLrcPath();
if (str == nullptr) {
return;
}
lrcParser_->parseLrc(str->c_str());
lrcRunning_.store(true);
}
void TjdUiAppPlayerPresenter::LrcSyncCallback(const char *lrc, bool isFirst)
{
lrc_ = std::string(lrc);
if (lrc_.empty()) {
return;
}
if (isFirst) {
std::string name = lrc_;
view_->SetCurrentMusicName(name.c_str());
} else {
view_->SyncLyric(lrc_.c_str());
}
}
void PlayerInterruptListener::OnInterrupt(int32_t type, int32_t hint)
{
if (type == INTERRUPT_TYPE_BEGIN && hint == INTERRUPT_HINT_PAUSE) {
PausePlayer();
}
if (type == INTERRUPT_TYPE_END && hint == INTERRUPT_HINT_RESUME) {
ResumePlayer();
}
if (hint == INTERRUPT_HINT_STOP) {
ResetFlag();
if (type == INTERRUPT_TYPE_BEGIN) {
isBeginStopped_ = true;
StopPlayer();
} else if (type == INTERRUPT_TYPE_END) {
isEndStopped_ = true;
}
}
}
void PlayerInterruptListener::PausePlayer(void)
{
GraphicService::GetInstance()->PostGraphicEvent([]() {
static_print_debug("[PlayerInterruptListener::PausePlayer] start");
int32_t state;
int32_t ret;
auto PlayerIntrptListener = TjdUiAppPlayerModel::GetInstance()->GetPlayerIntrptListener();
if (PlayerIntrptListener == nullptr) {
static_print_debug("[PlayerInterruptListener] Pause PlayerIntrptListener is null");
return;
}
auto player = PlayerIntrptListener->GetPlayer();
if (player.get() == nullptr) {
static_print_debug("[PlayerInterruptListener::PausePlayer] player is nullptr");
return;
}
TjdUiAppPlayerView *playersView = TjdUiAppPlayerView::GetInstance();
player->GetPlayerState(state);
if (state == OHOS::Media::PlayerStates::PLAYER_STARTED) {
ret = player->Pause();
if (ret == 0) {
if (playersView == nullptr) {
TjdUiAppPlayerModel::GetInstance()->SetPlayButtonState(false);
} else {
playersView->SetPlayerButtonState(OHOS::UICheckBox::UICheckBoxState::UNSELECTED);
}
PlayerIntrptListener->ResetFlag();
PlayerIntrptListener->SetPaused(true);
static_print_debug("[PlayerInterruptListener::PausePlayer]");
}
}
});
}
void PlayerInterruptListener::ResumePlayer(void)
{
usleep(50000); // 确保界面切换完成
// if (NativeAbility::GetInstance().GetCurSliceId() == VIEW_MAEKPHONE_SAMPLE ||
// (GetCurrCallState() != HFP_HF_CALL_STATE_FINISHED && GetScoConnectState() == HFP_SCO_STATE_CONNECTED)) {
// static_print_debug("[PlayerInterruptListener::ResumePlayer] this is in calling");
// return; // 通话界面,禁止音乐恢复播放
// }
GraphicService::GetInstance()->PostGraphicEvent([]() {
static_print_debug("[PlayerInterruptListener::Resume] start");
int32_t state;
int32_t ret;
auto PlayerIntrptListener = TJD::TjdUiAppPlayerModel::GetInstance()->GetPlayerIntrptListener();
if (PlayerIntrptListener == nullptr) {
static_print_debug("[PlayerInterruptListener] Pause PlayerIntrptListener is null");
return;
}
auto player = PlayerIntrptListener->GetPlayer();
if (player.get() == nullptr) {
static_print_debug("[PlayerInterruptListener::ResumePlayer] player is nullptr");
return;
}
TjdUiAppPlayerView *playersView = TjdUiAppPlayerView::GetInstance();
player->GetPlayerState(state);
if (state == OHOS::Media::PlayerStates::PLAYER_PAUSED && PlayerIntrptListener->IsPaused()) {
ret = player->Play();
if (ret == 0) {
if (playersView == nullptr) {
TjdUiAppPlayerModel::GetInstance()->SetPlayButtonState(true);
} else {
playersView->SetPlayerButtonState(OHOS::UICheckBox::UICheckBoxState::SELECTED);
}
PlayerIntrptListener->ResetFlag();
PlayerIntrptListener->SetResumed(true);
static_print_debug("[PlayerInterruptListener::ResumePlayer]");
}
}
});
}
void PlayerInterruptListener::StopPlayer(void)
{
GraphicService::GetInstance()->PostGraphicEvent([]() {
TjdUiAppPlayerModel::GetInstance()->PlayerStop();
TjdUiAppPlayerModel::GetInstance()->ClearActivateAudioInterrupt();
});
}
#pragma endregion
void TjdUiAppPlayerPresenter::SetConnectDeviceAddr(bd_addr_t addr) { btImpl_->SetConnectDeviceAddr(addr); }
#pragma region 按钮点击事件
void TjdUiAppPlayerPresenter::MusicListOnClick()
{
view_->SetPlayingMusic(GetCurMusicIndex(), IsPlaying());
view_->ShowView(PlayerViewIndex::MUSIC_LIST_VIEW);
}
void TjdUiAppPlayerPresenter::LeftOnClick()
{
TjdUiAppPlayerModel *model = TjdUiAppPlayerModel::GetInstance();
if (model->GetPlayerDeviceState() == PlayerSource::PLAYER_SOURCE_PHONE && model->IsConnectPhone()) {
model->PhoneAudioPrevious();
return;
}
if (PlayersListGroup::GetInstance()->GetCase().size() == 0) {
return;
}
model->PreviousPlayout();
UpdateLrcData();
}
void TjdUiAppPlayerPresenter::RightOnClick()
{
TjdUiAppPlayerModel *model = TjdUiAppPlayerModel::GetInstance();
if (model->GetPlayerDeviceState() == PlayerSource::PLAYER_SOURCE_PHONE && model->IsConnectPhone()) {
model->PhoneAudioForward();
return;
}
if (PlayersListGroup::GetInstance()->GetCase().size() == 0) {
return;
}
model->LoopingPlayout();
UpdateLrcData();
}
void TjdUiAppPlayerPresenter::StartOnClick()
{
TjdUiAppPlayerModel *model = TjdUiAppPlayerModel::GetInstance();
view_->SwitchPlayerButtonState();
uint8_t state = view_->GetPlayerButtonState();
int32_t connCtState = avrcp_ct_get_device_connect_state(model->GetLastConnedAddr());
int32_t connTgState = avrcp_tg_get_device_connect_state(model->GetLastConnedAddr());
if (model->GetPlayerCtr() == nullptr) {
static_print_error("PlayersModel::GetInstance()->GetPlayerCtr() nullptr");
return;
}
if (state == OHOS::UICheckBox::UICheckBoxState::SELECTED) {
if (model->GetPlayerDeviceState() == PlayerSource::PLAYER_SOURCE_PHONE) {
if (connCtState == HFP_SCO_STATE_CONNECTED || connTgState == HFP_SCO_STATE_CONNECTED) {
model->PhoneAudioPlay();
}
return;
}
bool needUpdateLrc = model->ConnectBtAndLocalPlay(connCtState, connTgState);
TjdUiScreenManage::DisableBackHomeInterval();
if (needUpdateLrc) {
UpdateLrcData();
}
} else if (state == OHOS::UICheckBox::UICheckBoxState::UNSELECTED) {
if (model->GetPlayerDeviceState() == PlayerSource::PLAYER_SOURCE_PHONE) {
if (connCtState == HFP_SCO_STATE_CONNECTED || connTgState == HFP_SCO_STATE_CONNECTED) {
model->PhoneAudioStop();
}
return;
}
model->ConnectBtAndLocalPause(connCtState, connTgState);
TjdUiScreenManage::ResetBackHomeInterval();
lrcRunning_.store(false);
}
}
void TjdUiAppPlayerPresenter::ConnectOnClick()
{
bool ret = TjdUiAppPlayerModel::GetInstance()->IsConnectHeadset();
if (ret) {
static_print_debug("ConnectOnClick headset is connect");
view_->SetConnectDevice(OHOS::UICheckBox::UICheckBoxState::SELECTED);
} else {
static_print_debug("ConnectOnClick headset is not connect");
view_->SetConnectDevice(OHOS::UICheckBox::UICheckBoxState::UNSELECTED);
}
view_->ShowView(PlayerViewIndex::DEVICE_VIEW);
}
void TjdUiAppPlayerPresenter::LoopOnClick()
{
TjdUiAppPlayerModel::GetInstance()->SetPlayModeAddOne();
view_->ChangedImage(playModeResMap[static_cast<int>(TjdUiAppPlayerModel::GetInstance()->GetPlayMode())]);
}
void TjdUiAppPlayerPresenter::VolumeOnClick()
{
int32_t volume = 0;
TjdUiAppPlayerModel *model = TjdUiAppPlayerModel::GetInstance();
if (model->GetPlayerDeviceState() == PlayerSource::PLAYER_SOURCE_PHONE && model->IsConnectPhone()) {
volume = TjdUiAppPlayerModel::GetInstance()->GetA2dpVolume();
static_print_debug("PLAYER_SOURCE_PHONE VolumeOnClick volume = %d", volume);
} else {
volume = TjdUiAppPlayerModel::GetInstance()->GetLocalVolume();
static_print_debug("PLAYER_SOURCE_WATCH VolumeOnClick volume = %d", volume);
}
view_->ChangedVolume(volume);
view_->ShowView(PlayerViewIndex::VOLUME_VIEW);
}
void TjdUiAppPlayerPresenter::ScanHeadsetOnClick() { btImpl_->StartScanHeadsetTimer(); }
void TjdUiAppPlayerPresenter::SelectPhoneDeviceOnClick(void)
{
TjdUiAppPlayerModel *model = TjdUiAppPlayerModel::GetInstance();
if (model->IsConnectEarpod()) {
HeadsetDisableOnClick();
}
if (model->IsConnectBt()) {
model->SetPhoneAudioEnable(true);
view_->SetWaitViewInfo(STR_ID_330);
view_->ShowView(PlayerViewIndex::SEARCHING_VIEW);
view_->SetTime(0, 0);
view_->SyncLyric("");
StartJumpTimer(PlayerViewIndex::DEVICE_VIEW);
/* 切换成手机音乐时停止播放手表音乐 */
model->PlayerStop();
view_->SetPlayerButtonState(model->GetPhoneAudioPlayStatus() == avrcp_play_status_t::AVRCP_PLAY_STATUS_PLAYING
? OHOS::UICheckBox::UICheckBoxState::SELECTED
: OHOS::UICheckBox::UICheckBoxState::UNSELECTED);
model->SetPlayerDeviceState(PlayerSource::PLAYER_SOURCE_PHONE);
view_->SetDeviceState(PlayerSource::PLAYER_SOURCE_PHONE);
} else { // 未连接BT
view_->ShowView(PlayerViewIndex::CONNECT_APP_FAIL_VIEW);
StartJumpTimer(PlayerViewIndex::DEVICE_VIEW);
}
}
void TjdUiAppPlayerPresenter::SelectWatchDeviceOnClick(void)
{
/* 切换成手表音乐时停止播放手机音乐 */
TjdUiAppPlayerModel *model = TjdUiAppPlayerModel::GetInstance();
if (model->PhoneAudioIsPlaying()) {
model->PhoneAudioStop();
}
PlayerInterruptListener::StopPlayer();
model->SetPhoneAudioEnable(false);
view_->SetWaitViewInfo(STR_ID_330);
view_->ShowView(PlayerViewIndex::SEARCHING_VIEW);
const uint64_t duration = model->GetDuration();
view_->SetTime(0, duration);
view_->SyncLyric("");
StartJumpTimer(PlayerViewIndex::DEVICE_VIEW);
view_->SetPlayerButtonState(OHOS::UICheckBox::UICheckBoxState::UNSELECTED);
model->SetPlayerDeviceState(PlayerSource::PLAYER_SOURCE_WATCH);
view_->SetDeviceState(PlayerSource::PLAYER_SOURCE_WATCH);
}
void TjdUiAppPlayerPresenter::HeadsetConnectOnClick(void)
{
// 获取目标耳机的信息
HeadsetInfo *headset = btImpl_->GetHeadsetInfo(btImpl_->GetConnectDeviceAddr());
if (headset == nullptr) {
return;
}
view_->SetDeviceInfo(headset->name.c_str(), headset->isConnect);
view_->ShowView(PlayerViewIndex::DEVICE_CONNECT_VIEW);
}
void TjdUiAppPlayerPresenter::HeadsetConnectDeviceOnClick(void)
{
HeadsetInfo *headset = btImpl_->GetHeadsetInfo(btImpl_->GetConnectDeviceAddr());
if (headset == nullptr) {
static_print_error("HeadsetConnectDeviceOnClick headset is nullptr");
return;
}
TjdUiAppPlayerModel::GetInstance()->ConnectHeadset(headset->bdAddr);
btImpl_->StopScanHeadsetTimer();
view_->SetWaitViewInfo(STR_ID_593);
view_->ShowView(PlayerViewIndex::SEARCHING_VIEW);
btImpl_->StartConnectHeadsetTimer();
}
void TjdUiAppPlayerPresenter::HeadsetConnectCancelOnClick(void) { view_->ShowView(PlayerViewIndex::SEARCH_LIST_VIEW); }
void TjdUiAppPlayerPresenter::HeadsetUnpairDeviceOnClick(void)
{
// 获取解绑耳机的信息
HeadsetInfo *headset = btImpl_->GetHeadsetInfo(btImpl_->GetConnectDeviceAddr());
if (headset == nullptr) {
return;
}
if (TjdUiAppPlayerModel::GetInstance()->UnpairHeadset(headset->bdAddr)) {
headset->isConnect = false;
headset->isPaired = false;
view_->SetDeviceInfo(headset->name.c_str(), headset->isConnect);
view_->SetConnectDevice(OHOS::UICheckBox::UICheckBoxState::UNSELECTED);
}
}
void TjdUiAppPlayerPresenter::HeadsetEnableOnClick(void) { btImpl_->StartScanHeadsetTimer(); }
void TjdUiAppPlayerPresenter::HeadsetDisableOnClick(void)
{
HeadsetInfo *headset = btImpl_->GetHeadsetInfo(btImpl_->GetConnectDeviceAddr());
if (headset == nullptr) {
return;
}
if (TjdUiAppPlayerModel::GetInstance()->DisconnectHeadset(headset->bdAddr)) {
headset->isConnect = false;
view_->SetDeviceInfo(headset->name.c_str(), headset->isConnect);
view_->SetConnectDevice(OHOS::UICheckBox::UICheckBoxState::UNSELECTED);
}
}
void TjdUiAppPlayerPresenter::ClickDeleteCancelEvent(void)
{
if (view_->GetCurrentView() == PlayerViewIndex::DELETE_MUSIC_VIEW) {
view_->ShowView(PlayerViewIndex::MUSIC_LIST_VIEW);
}
}
void TjdUiAppPlayerPresenter::ClickDeleteEntryEvent(void)
{
TjdUiAppPlayerModel *model = TjdUiAppPlayerModel::GetInstance();
PlayersListGroup *listGroup = PlayersListGroup::GetInstance();
auto size = listGroup->GetCase().size();
bool isPlaying = IsPlaying();
if (view_->GetCurrentView() == PlayerViewIndex::DELETE_MUSIC_VIEW) {
/* size == 1 为删除后库上没有音乐的情况 */
if (size == 1) {
model->PlayerStop();
model->SetCurrentIndex(-1);
model->SetPlayerUri("");
view_->SetPlayerButtonState(OHOS::UICheckBox::UICheckBoxState::UNSELECTED);
view_->SetCurrentMusicName("无音乐");
view_->SyncLyric("");
view_->SetPlayingMusic(-1, false);
} else if (selectIndex_ == GetCurMusicIndex()) {
/* 删除正在播放的音乐的情况 */
if (isPlaying) {
StartOnClick();
}
model->LoopingPlayout();
view_->SetPlayingMusic(-1, false);
view_->SyncLyric("");
} else {
/* 删除非正在播放的音乐的情况 */
view_->SetPlayingMusic(selectIndex_, isPlaying);
}
listGroup->RemoveCase(selectIndex_);
view_->RefrashMusicList();
view_->ShowView(PlayerViewIndex::MUSIC_LIST_VIEW);
}
}
struct PlayerOnClickMapper
{
const char *id;
void (TjdUiAppPlayerPresenter::*func)();
};
static const PlayerOnClickMapper g_onClickMapper[] = {
{BTN_MUSIC_LIST_VIEW_ID, &TjdUiAppPlayerPresenter::MusicListOnClick}, // 点击音乐列表
{BTN_LEFT_VIEW_ID, &TjdUiAppPlayerPresenter::LeftOnClick}, // 点击上一首
{BTN_RIGHT_VIEW_ID, &TjdUiAppPlayerPresenter::RightOnClick}, // 点击下一首
{BTN_START_VIEW_ID, &TjdUiAppPlayerPresenter::StartOnClick}, // 点击播放
{BTN_CONNECT_VIEW_ID, &TjdUiAppPlayerPresenter::ConnectOnClick}, // 点击连接
{BTN_LOOP_VIEW_ID, &TjdUiAppPlayerPresenter::LoopOnClick}, // 点击循环模式
{BTN_VOLUME_VIEW_ID, &TjdUiAppPlayerPresenter::VolumeOnClick}, // 点击音量
{BTN_SEARCH_VIEW_ID, &TjdUiAppPlayerPresenter::ScanHeadsetOnClick}, // 点击搜索蓝牙
{BTN_TARGET_HEADSET_VIEW_ID, &TjdUiAppPlayerPresenter::HeadsetConnectOnClick}, // 选择目标耳机
{BTN_CONNECT_ENTER_VIEW_ID, &TjdUiAppPlayerPresenter::HeadsetConnectDeviceOnClick}, // 连接耳机
{BTN_CONNECT_CANCEL_VIEW_ID, &TjdUiAppPlayerPresenter::HeadsetConnectCancelOnClick}, // 取消连接
{BTN_DEVICE_UNPAIR_VIEW_ID, &TjdUiAppPlayerPresenter::HeadsetUnpairDeviceOnClick}, // 解绑耳机
{BTN_DELETE_ENTRY_MUSIC_VIEW_ID, &TjdUiAppPlayerPresenter::ClickDeleteEntryEvent}, // 确认删除音乐
{BTN_DELETE_CANCEL_MUSIC_VIEW_ID, &TjdUiAppPlayerPresenter::ClickDeleteCancelEvent}, // 取消删除音乐
};
bool TjdUiAppPlayerPresenter::OnClick(OHOS::UIView &view, const OHOS::ClickEvent &event)
{
const char *viewId = view.GetViewId();
for (const auto &item : g_onClickMapper) {
if (strcmp(viewId, item.id) == 0) {
(GetInstance()->*item.func)();
}
}
return false;
}
#pragma endregion
#pragma region 列表歌曲点击事件
bool TjdUiAppPlayerPresenter::ClickListMusic(OHOS::UIView *view, bool isDelete)
{
int16_t index = view->GetViewIndex();
int ret = 0;
int32_t playerState = 0;
TjdUiAppPlayerModel *model = TjdUiAppPlayerModel::GetInstance();
char *caseInfo = PlayersListGroup::GetInstance()->GetCase(index);
if (isDelete) {
selectIndex_ = index;
view_->SetDeleteEntryDesc(caseInfo);
view_->ShowView(PlayerViewIndex::DELETE_MUSIC_VIEW);
return true;
}
model->SetCurrentIndex(index);
// 本地播放文件路径和状态
std::string strSrcMusic(TJD_FS_DIR_MUSIC);
model->SetPlayerUri(strSrcMusic + "/" + caseInfo);
std::string strSongName(caseInfo);
view_->SetCurrentMusicName(strSongName.substr(0, strSongName.rfind(".")).c_str());
uint8_t state = view_->GetPlayerButtonState();
if (state == OHOS::UICheckBox::UICheckBoxState::UNSELECTED) {
view_->SetPlayerButtonState(OHOS::UICheckBox::UICheckBoxState::SELECTED);
/* start play */
model->GetPlayerCtr()->GetPlayerState(playerState);
if (playerState == OHOS::Media::PlayerStates::PLAYER_PAUSED) {
ret = model->GetPlayerCtr()->Reset();
}
model->PlayerStart(); // 播放
} else if (state == OHOS::UICheckBox::UICheckBoxState::SELECTED) {
model->GetPlayerCtr()->GetPlayerState(playerState);
if (playerState == OHOS::Media::PlayerStates::PLAYER_STARTED) {
ret = model->GetPlayerCtr()->Stop(); // 停止
ret = model->GetPlayerCtr()->Reset();
}
model->PlayerStart();
}
view_->SetPlayingMusic(index, IsPlaying());
UpdateLrcData();
return true;
}
bool PlayerListOnClickListener::OnClick(OHOS::UIView &view, const OHOS::ClickEvent &event)
{
PlayersCaseView *listView = dynamic_cast<PlayersCaseView *>(view.GetParent());
if (listView == nullptr) {
return true;
}
std::string viewId = view.GetViewId();
if (viewId.empty()) {
return true;
}
TjdUiAppPlayerPresenter *presenter = TjdUiAppPlayerPresenter::GetInstance();
if (presenter == nullptr) {
return true;
}
auto *lastView = static_cast<PlayersCaseView *>(presenter->GetSelectView());
if (lastView != nullptr) {
lastView->StartAnimator(3, 466, 0);
lastView = nullptr;
}
int16_t index = listView->GetViewIndex();
if (viewId == "delete") {
presenter->ClickListMusic(listView, true);
} else {
presenter->ClickListMusic(listView, false);
}
return true;
}
#pragma endregion
#pragma region 播放器状态监听
void PlayerCallbackImpl::OnPlaybackComplete()
{
// 文件播放完成的事件
static_print_debug("OnPlaybackCompleten");
usleep(20000);
GraphicService::GetInstance()->PostGraphicEvent(
std::bind(&TjdUiAppPlayerModel::PlaySwitching, TjdUiAppPlayerModel::GetInstance()));
GraphicService::GetInstance()->PostGraphicEvent([] {
TjdUiAppPlayerPresenter *presenter = TjdUiAppPlayerPresenter::GetInstance();
if (presenter == nullptr) {
return;
}
presenter->UpdateLrcData();
});
}
void PlayerCallbackImpl::OnError(int32_t errorType, int32_t errorCode)
{
static_print_debug("error type:%d, error code:%d", errorType, errorCode);
}
void PlayerCallbackImpl::OnInfo(int32_t errorType, int32_t errorCode)
{
static_print_debug("error type:%d, error code:%d", errorType, errorCode);
}
void PlayerCallbackImpl::OnRewindToComplete() { static_print_debug("OnRewindToComplete"); }
#pragma endregion
} // namespace TJD