888 lines
32 KiB
C++
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
|