From c3fd598da77b87e4d000052702f9ae37fe02ef1d Mon Sep 17 00:00:00 2001 From: Hakkyu Kim Date: Thu, 14 Apr 2022 15:01:34 +0900 Subject: [PATCH 01/16] Refactoring - Make internal linkages with unnamed namespace. - Use `const` instead of `#define` for constants. - Relocate constructor logic to RegisterWithRegistrar. - Use helper function `GetValueFromEncodableMap`. - Use `enum class` instead of `enum`. - Some naming changes. - Remove unnecessary logging. - Initialize private variables inline rather than in constructor. - Move `HandleResult` from AudioPlayer's memeber to internal. --- .../audioplayers/tizen/src/audio_player.cc | 201 +++++------- .../audioplayers/tizen/src/audio_player.h | 17 +- .../tizen/src/audio_player_options.h | 6 - .../tizen/src/audioplayers_tizen_plugin.cc | 297 +++++++++--------- 4 files changed, 226 insertions(+), 295 deletions(-) delete mode 100644 packages/audioplayers/tizen/src/audio_player_options.h diff --git a/packages/audioplayers/tizen/src/audio_player.cc b/packages/audioplayers/tizen/src/audio_player.cc index cc4c4a669..384201ab8 100644 --- a/packages/audioplayers/tizen/src/audio_player.cc +++ b/packages/audioplayers/tizen/src/audio_player.cc @@ -3,13 +3,20 @@ #include "audio_player_error.h" #include "log.h" +static void HandleResult(const std::string &func_name, int result) { + if (result != PLAYER_ERROR_NONE) { + std::string error(get_error_message(result)); + LOG_ERROR("%s failed : %s", func_name.c_str(), error.c_str()); + throw AudioPlayerError(error, func_name + " failed"); + } +} + AudioPlayer::AudioPlayer(const std::string &player_id, bool low_latency, PreparedListener prepared_listener, StartPlayingListener start_playing_listener, SeekCompletedListener seek_completed_listener, PlayCompletedListener play_completed_listener, ErrorListener error_listener) { - LOG_INFO("AudioPlayer %s is constructing...", player_id.c_str()); player_id_ = player_id; low_latency_ = low_latency; prepared_listener_ = prepared_listener; @@ -17,23 +24,14 @@ AudioPlayer::AudioPlayer(const std::string &player_id, bool low_latency, seek_completed_listener_ = seek_completed_listener; play_completed_listener_ = play_completed_listener; error_listener_ = error_listener; - - volume_ = 1.0; - playback_rate_ = 1.0; - release_mode_ = RELEASE; - should_seek_to_ = -1; } -AudioPlayer::~AudioPlayer() { - LOG_INFO("AudioPlayer %s is destructing...", player_id_.c_str()); - Release(); -} +AudioPlayer::~AudioPlayer() { Release(); } void AudioPlayer::Play() { - LOG_INFO("AudioPlayer %s will play audio...", player_id_.c_str()); player_state_e state = GetPlayerState(); if (state == PLAYER_STATE_IDLE && preparing_) { - LOG_DEBUG("player is preparing, play will be called in prepared callback"); + // player is preparing, play will be called in prepared callback.; should_play_ = true; return; } @@ -42,54 +40,50 @@ void AudioPlayer::Play() { CreatePlayer(); } - int result; + int ret; switch (state) { case PLAYER_STATE_NONE: case PLAYER_STATE_IDLE: if (audio_data_.size() > 0) { - LOG_DEBUG("set audio buffer, buffer size : %d", audio_data_.size()); - result = player_set_memory_buffer(player_, (void *)audio_data_.data(), - audio_data_.size()); - HandleResult("player_set_memory_buffer", result); + ret = player_set_memory_buffer(player_, (void *)audio_data_.data(), + audio_data_.size()); + HandleResult("player_set_memory_buffer", ret); } else { - LOG_DEBUG("set uri (%s)", url_.c_str()); - result = player_set_uri(player_, url_.c_str()); - HandleResult("player_set_uri", result); + ret = player_set_uri(player_, url_.c_str()); + HandleResult("player_set_uri", ret); } should_play_ = true; PreparePlayer(); break; case PLAYER_STATE_READY: case PLAYER_STATE_PAUSED: - result = player_start(player_); - HandleResult("player_start", result); + ret = player_start(player_); + HandleResult("player_start", ret); should_play_ = false; start_playing_listener_(player_id_); break; default: - LOG_DEBUG("player is already playing audio"); + // "player is already playing audio. break; } } void AudioPlayer::Pause() { - LOG_INFO("AudioPlayer %s is pausing...", player_id_.c_str()); if (GetPlayerState() == PLAYER_STATE_PLAYING) { - int result = player_pause(player_); - HandleResult("player_pause", result); + int ret = player_pause(player_); + HandleResult("player_pause", ret); } should_play_ = false; } void AudioPlayer::Stop() { - LOG_INFO("AudioPlayer %s is stopping...", player_id_.c_str()); - if (release_mode_ == RELEASE) { + if (release_mode_ == ReleaseMode::kRelease) { Release(); } else { player_state_e state = GetPlayerState(); if (state == PLAYER_STATE_PLAYING || state == PLAYER_STATE_PAUSED) { - int result = player_stop(player_); - HandleResult("player_stop", result); + int ret = player_stop(player_); + HandleResult("player_stop", ret); } } should_play_ = false; @@ -97,8 +91,7 @@ void AudioPlayer::Stop() { } void AudioPlayer::Release() { - LOG_INFO("AudioPlayer %s is releasing...", player_id_.c_str()); - if (player_ != nullptr) { + if (player_) { player_unset_completed_cb(player_); player_unset_interrupted_cb(player_); player_unset_error_cb(player_); @@ -108,40 +101,35 @@ void AudioPlayer::Release() { } void AudioPlayer::Seek(int position) { - LOG_INFO("AudioPlayer %s is seeking...", player_id_.c_str()); if (seeking_) { - LOG_DEBUG("player is already seeking, can't seek again"); return; } player_state_e state = GetPlayerState(); if (state == PLAYER_STATE_READY || state == PLAYER_STATE_PLAYING || state == PLAYER_STATE_PAUSED) { - LOG_DEBUG("set play position %d", position); seeking_ = true; - int result = player_set_play_position(player_, position, true, - OnSeekCompleted, (void *)this); - if (result != PLAYER_ERROR_NONE) { + int ret = player_set_play_position(player_, position, true, OnSeekCompleted, + (void *)this); + if (ret != PLAYER_ERROR_NONE) { seeking_ = false; - std::string error(get_error_message(result)); + std::string error(get_error_message(ret)); LOG_ERROR("player_set_play_position failed : %s", error.c_str()); throw AudioPlayerError(error, "player_set_play_position failed"); } } else { - LOG_DEBUG("player is unprepared, do seek in prepared callback"); + // player is unprepared, do seek in prepared callback. should_seek_to_ = position; } } void AudioPlayer::SetUrl(const std::string &url) { - LOG_INFO("AudioPlayer %s is setting url...", player_id_.c_str()); if (url != url_) { url_ = url; ResetPlayer(); - LOG_DEBUG("set new uri (%s)", url.c_str()); - int result = player_set_uri(player_, url.c_str()); - HandleResult("player_set_uri", result); + int ret = player_set_uri(player_, url.c_str()); + HandleResult("player_set_uri", ret); PreparePlayer(); } @@ -149,57 +137,47 @@ void AudioPlayer::SetUrl(const std::string &url) { } void AudioPlayer::SetDataSource(std::vector &data) { - LOG_INFO("AudioPlayer %s is setting buffer...", player_id_.c_str()); if (data != audio_data_) { audio_data_.swap(data); ResetPlayer(); - LOG_DEBUG("set audio buffer, buffer size : %d", audio_data_.size()); - int result = player_set_memory_buffer(player_, (void *)audio_data_.data(), - audio_data_.size()); - HandleResult("player_set_memory_buffer", result); + int ret = player_set_memory_buffer(player_, (void *)audio_data_.data(), + audio_data_.size()); + HandleResult("player_set_memory_buffer", ret); PreparePlayer(); } } void AudioPlayer::SetVolume(double volume) { - LOG_INFO("AudioPlayer %s is setting volume %f...", player_id_.c_str(), - volume); if (volume_ != volume) { volume_ = volume; if (GetPlayerState() != PLAYER_STATE_NONE) { - LOG_DEBUG("set volume : %f", volume_); - int result = player_set_volume(player_, volume_, volume_); - HandleResult("player_set_volume", result); + int ret = player_set_volume(player_, volume_, volume_); + HandleResult("player_set_volume", ret); } } } void AudioPlayer::SetPlaybackRate(double rate) { - LOG_INFO("AudioPlayer %s is setting plackback rate %f...", player_id_.c_str(), - rate); if (playback_rate_ != rate) { playback_rate_ = rate; player_state_e state = GetPlayerState(); if (state == PLAYER_STATE_READY || state == PLAYER_STATE_PLAYING || state == PLAYER_STATE_PAUSED) { - LOG_DEBUG("set plackback rate : %f", rate); - int result = player_set_playback_rate(player_, rate); - HandleResult("player_set_playback_rate", result); + int ret = player_set_playback_rate(player_, rate); + HandleResult("player_set_playback_rate", ret); } } } void AudioPlayer::SetReleaseMode(ReleaseMode mode) { - LOG_INFO("AudioPlayer %s is setting ReleaseMode %d...", player_id_.c_str(), - mode); if (release_mode_ != mode) { release_mode_ = mode; if (GetPlayerState() != PLAYER_STATE_NONE) { - LOG_DEBUG("set looping : %d", release_mode_ == LOOP); - int result = player_set_looping(player_, (release_mode_ == LOOP)); - HandleResult("player_set_looping", result); + int ret = + player_set_looping(player_, (release_mode_ == ReleaseMode::kLoop)); + HandleResult("player_set_looping", ret); } } } @@ -208,7 +186,6 @@ int AudioPlayer::GetDuration() { int duration; int result = player_get_duration(player_, &duration); HandleResult("player_get_duration", result); - LOG_INFO("audio (%s) duration: %d", url_.c_str(), duration); return duration; } @@ -216,58 +193,51 @@ int AudioPlayer::GetCurrentPosition() { int position; int result = player_get_play_position(player_, &position); HandleResult("player_get_play_position", result); - LOG_INFO("audio (%s) position: %d", url_.c_str(), position); return position; } -std::string AudioPlayer::GetPlayerId() const { return player_id_; } - bool AudioPlayer::IsPlaying() { return (GetPlayerState() == PLAYER_STATE_PLAYING); } void AudioPlayer::CreatePlayer() { - LOG_INFO("create audio player..."); should_play_ = false; preparing_ = false; - int result = player_create(&player_); - HandleResult("player_create", result); + int ret = player_create(&player_); + HandleResult("player_create", ret); if (low_latency_) { - result = player_set_audio_latency_mode(player_, AUDIO_LATENCY_MODE_LOW); - HandleResult("player_set_audio_latency_mode", result); + ret = player_set_audio_latency_mode(player_, AUDIO_LATENCY_MODE_LOW); + HandleResult("player_set_audio_latency_mode", ret); } - result = player_set_completed_cb(player_, OnPlayCompleted, (void *)this); - HandleResult("player_set_completed_cb", result); + ret = player_set_completed_cb(player_, OnPlayCompleted, (void *)this); + HandleResult("player_set_completed_cb", ret); - result = player_set_interrupted_cb(player_, OnInterrupted, (void *)this); - HandleResult("player_set_interrupted_cb", result); + ret = player_set_interrupted_cb(player_, OnInterrupted, (void *)this); + HandleResult("player_set_interrupted_cb", ret); - result = player_set_error_cb(player_, OnErrorOccurred, (void *)this); - HandleResult("player_set_error_cb", result); + ret = player_set_error_cb(player_, OnErrorOccurred, (void *)this); + HandleResult("player_set_error_cb", ret); } void AudioPlayer::PreparePlayer() { - LOG_DEBUG("set volume %f", volume_); - int result = player_set_volume(player_, volume_, volume_); - HandleResult("player_set_volume", result); + int ret = player_set_volume(player_, volume_, volume_); + HandleResult("player_set_volume", ret); - LOG_DEBUG("set looping %d", (release_mode_ == LOOP)); - result = player_set_looping(player_, (release_mode_ == LOOP)); - HandleResult("player_set_looping", result); + ret = player_set_looping(player_, (release_mode_ == ReleaseMode::kLoop)); + HandleResult("player_set_looping", ret); LOG_DEBUG("prepare audio player asynchronously"); - result = player_prepare_async(player_, OnPrepared, (void *)this); - HandleResult("player_prepare_async", result); + ret = player_prepare_async(player_, OnPrepared, (void *)this); + HandleResult("player_prepare_async", ret); preparing_ = true; seeking_ = false; } void AudioPlayer::ResetPlayer() { - LOG_INFO("reset audio player..."); - int result; + int ret; player_state_e state = GetPlayerState(); switch (state) { case PLAYER_STATE_NONE: @@ -275,71 +245,58 @@ void AudioPlayer::ResetPlayer() { break; case PLAYER_STATE_IDLE: if (preparing_) { - LOG_DEBUG("player is preparing, unprepare the player"); - result = player_unprepare(player_); - HandleResult("player_unprepare", result); + // Cancel preparing if it's already preparing. + ret = player_unprepare(player_); + HandleResult("player_unprepare", ret); preparing_ = false; } break; case PLAYER_STATE_READY: case PLAYER_STATE_PLAYING: case PLAYER_STATE_PAUSED: - LOG_DEBUG("unprepare audio player"); - result = player_unprepare(player_); - HandleResult("player_unprepare", result); + ret = player_unprepare(player_); + HandleResult("player_unprepare", ret); break; } } player_state_e AudioPlayer::GetPlayerState() { - player_state_e state; - if (player_ == nullptr) { - state = PLAYER_STATE_NONE; - } else { - int result = player_get_state(player_, &state); - if (result != PLAYER_ERROR_NONE) { - state = PLAYER_STATE_NONE; + player_state_e state = PLAYER_STATE_NONE; + if (player_) { + int ret = player_get_state(player_, &state); + if (ret != PLAYER_ERROR_NONE) { + LOG_ERROR("Getting player(id: %s) state failed: %s\n", player_id_.c_str(), + get_error_message(ret)); } } return state; } -void AudioPlayer::HandleResult(const std::string &func_name, int result) { - if (result != PLAYER_ERROR_NONE) { - std::string error(get_error_message(result)); - LOG_ERROR("%s failed : %s", func_name.c_str(), error.c_str()); - throw AudioPlayerError(error, func_name + " failed"); - } -} - void AudioPlayer::OnPrepared(void *data) { - LOG_INFO("Audio player is prepared"); AudioPlayer *player = (AudioPlayer *)data; player->preparing_ = false; int duration = 0; - int result = player_get_duration(player->player_, &duration); - if (result == PLAYER_ERROR_NONE) { + int ret = player_get_duration(player->player_, &duration); + if (ret == PLAYER_ERROR_NONE) { player->prepared_listener_(player->player_id_, duration); } player_set_playback_rate(player->player_, player->playback_rate_); if (player->should_play_) { - LOG_DEBUG("start to play audio"); - result = player_start(player->player_); - if (result == PLAYER_ERROR_NONE) { + ret = player_start(player->player_); + if (ret == PLAYER_ERROR_NONE) { player->start_playing_listener_(player->player_id_); } player->should_play_ = false; } if (player->should_seek_to_ > 0) { - LOG_DEBUG("set play position %d", player->should_seek_to_); player->seeking_ = true; - result = player_set_play_position(player->player_, player->should_seek_to_, - true, OnSeekCompleted, data); - if (result != PLAYER_ERROR_NONE) { + ret = player_set_play_position(player->player_, player->should_seek_to_, + true, OnSeekCompleted, data); + if (ret != PLAYER_ERROR_NONE) { LOG_ERROR("failed to set play position"); player->seeking_ = false; } @@ -348,16 +305,14 @@ void AudioPlayer::OnPrepared(void *data) { } void AudioPlayer::OnSeekCompleted(void *data) { - LOG_DEBUG("completed to set position"); AudioPlayer *player = (AudioPlayer *)data; player->seek_completed_listener_(player->player_id_); player->seeking_ = false; } void AudioPlayer::OnPlayCompleted(void *data) { - LOG_DEBUG("completed to play audio"); AudioPlayer *player = (AudioPlayer *)data; - if (player->release_mode_ != LOOP) { + if (player->release_mode_ != ReleaseMode::kLoop) { player->Stop(); } player->play_completed_listener_(player->player_id_); diff --git a/packages/audioplayers/tizen/src/audio_player.h b/packages/audioplayers/tizen/src/audio_player.h index 037272261..37d350b8b 100644 --- a/packages/audioplayers/tizen/src/audio_player.h +++ b/packages/audioplayers/tizen/src/audio_player.h @@ -7,7 +7,7 @@ #include #include -#include "audio_player_options.h" +enum class ReleaseMode { kRelease, kLoop, kStop }; using PreparedListener = std::function; @@ -42,17 +42,16 @@ class AudioPlayer { void SetReleaseMode(ReleaseMode mode); int GetDuration(); int GetCurrentPosition(); - std::string GetPlayerId() const; + std::string GetPlayerId() const { return player_id_; } bool IsPlaying(); private: - // the player state should be none before call this function + // The player state should be none before calling this function. void CreatePlayer(); - // the player state should be idle before call this function + // The player state should be idle before calling this function. void PreparePlayer(); void ResetPlayer(); player_state_e GetPlayerState(); - void HandleResult(const std::string &func_name, int result); static void OnPrepared(void *data); static void OnSeekCompleted(void *data); @@ -65,10 +64,10 @@ class AudioPlayer { bool low_latency_; std::string url_; std::vector audio_data_; - double volume_; - double playback_rate_; - ReleaseMode release_mode_; - int should_seek_to_; + double volume_ = 1.0; + double playback_rate_ = 1.0; + ReleaseMode release_mode_ = ReleaseMode::kRelease; + int should_seek_to_ = -1; bool preparing_ = false; bool seeking_ = false; bool should_play_ = false; diff --git a/packages/audioplayers/tizen/src/audio_player_options.h b/packages/audioplayers/tizen/src/audio_player_options.h deleted file mode 100644 index d757d419b..000000000 --- a/packages/audioplayers/tizen/src/audio_player_options.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef AUDIO_PLAYER_OPTIONS_H_ -#define AUDIO_PLAYER_OPTIONS_H_ - -enum ReleaseMode { RELEASE, LOOP, STOP }; - -#endif // AUDIO_PLAYER_OPTIONS_H_ diff --git a/packages/audioplayers/tizen/src/audioplayers_tizen_plugin.cc b/packages/audioplayers/tizen/src/audioplayers_tizen_plugin.cc index e6d99d548..99114ee72 100644 --- a/packages/audioplayers/tizen/src/audioplayers_tizen_plugin.cc +++ b/packages/audioplayers/tizen/src/audioplayers_tizen_plugin.cc @@ -6,36 +6,51 @@ #include #include +#include #include #include "audio_player.h" #include "audio_player_error.h" -#include "audio_player_options.h" #include "log.h" -#define TIMEOUT 0.2 +namespace { + +const double kTimeInterval = 0.2; + +template +static bool GetValueFromEncodableMap(const flutter::EncodableMap *map, + const char *key, T &out) { + auto iter = map->find(flutter::EncodableValue(key)); + if (iter != map->end() && !iter->second.IsNull()) { + if (auto *value = std::get_if(&iter->second)) { + out = *value; + return true; + } + } + return false; +} class AudioplayersTizenPlugin : public flutter::Plugin { public: static void RegisterWithRegistrar(flutter::PluginRegistrar *registrar) { - auto plugin = std::make_unique(registrar); - registrar->AddPlugin(std::move(plugin)); - } - - AudioplayersTizenPlugin(flutter::PluginRegistrar *registrar) { auto channel = std::make_unique>( registrar->messenger(), "xyz.luan/audioplayers", &flutter::StandardMethodCodec::GetInstance()); + + auto plugin = std::make_unique(); + channel->SetMethodCallHandler( - [plugin = this](const auto &call, auto result) { - plugin->HandleMethodCall(call, std::move(result)); + [plugin_pointer = plugin.get()](const auto &call, auto result) { + plugin_pointer->HandleMethodCall(call, std::move(result)); }); + plugin->channel_ = std::move(channel); - channel_ = std::move(channel); - timer_ = nullptr; + registrar->AddPlugin(std::move(plugin)); } + AudioplayersTizenPlugin() {} + virtual ~AudioplayersTizenPlugin() { if (timer_) { ecore_timer_del(timer_); @@ -47,148 +62,121 @@ class AudioplayersTizenPlugin : public flutter::Plugin { void HandleMethodCall( const flutter::MethodCall &method_call, std::unique_ptr> result) { - LOG_DEBUG("HandleMethodCall: %s", method_call.method_name().c_str()); - const flutter::EncodableValue *args = method_call.arguments(); - if (std::holds_alternative(*args)) { - flutter::EncodableMap encodables = std::get(*args); - flutter::EncodableValue &player_id_value = - encodables[flutter::EncodableValue("playerId")]; - std::string player_id; - if (std::holds_alternative(player_id_value)) { - player_id = std::get(player_id_value); - LOG_DEBUG("Audio player ID: %s", player_id.c_str()); - } else { - result->Error("Invalid Player ID", "Invalid Player ID for method " + - method_call.method_name()); - return; - } + const auto *arguments = + std::get_if(method_call.arguments()); + if (!arguments) { + result->Error("Invalid arguments", "Invalid arguments for method " + + method_call.method_name()); + return; + } - flutter::EncodableValue &mode_value = - encodables[flutter::EncodableValue("mode")]; - std::string mode; - if (std::holds_alternative(mode_value)) { - mode = std::get(mode_value); - LOG_DEBUG("Audio player Mode: %s", mode.c_str()); - } + std::string player_id, mode; + if (!GetValueFromEncodableMap(arguments, "playerId", player_id)) { + result->Error("Invalid Player ID", "Invalid Player ID for method " + + method_call.method_name()); + return; + } + GetValueFromEncodableMap(arguments, "mode", mode); - AudioPlayer *player = GetAudioPlayer(player_id, mode); - try { - if (method_call.method_name().compare("play") == 0) { - flutter::EncodableValue &volume = - encodables[flutter::EncodableValue("volume")]; - if (std::holds_alternative(volume)) { - player->SetVolume(std::get(volume)); - } - flutter::EncodableValue &url = - encodables[flutter::EncodableValue("url")]; - if (std::holds_alternative(url)) { - player->SetUrl(std::get(url)); - } - player->Play(); - flutter::EncodableValue &position = - encodables[flutter::EncodableValue("position")]; - if (std::holds_alternative(position)) { - player->Seek(std::get(position)); - } - } else if (method_call.method_name().compare("playBytes") == 0) { - flutter::EncodableValue &volume = - encodables[flutter::EncodableValue("volume")]; - if (std::holds_alternative(volume)) { - player->SetVolume(std::get(volume)); - } - flutter::EncodableValue &bytes = - encodables[flutter::EncodableValue("bytes")]; - if (std::holds_alternative>(bytes)) { - player->SetDataSource(std::get>(bytes)); - } - player->Play(); - flutter::EncodableValue &position = - encodables[flutter::EncodableValue("position")]; - if (std::holds_alternative(position)) { - player->Seek(std::get(position)); - } - } else if (method_call.method_name().compare("resume") == 0) { - player->Play(); - } else if (method_call.method_name().compare("pause") == 0) { - player->Pause(); - } else if (method_call.method_name().compare("stop") == 0) { - player->Stop(); - } else if (method_call.method_name().compare("release") == 0) { - player->Release(); - } else if (method_call.method_name().compare("seek") == 0) { - flutter::EncodableValue &position = - encodables[flutter::EncodableValue("position")]; - if (std::holds_alternative(position)) { - player->Seek(std::get(position)); - } else { - result->Error("Invalid position", - "seek failed because of invalid position"); - } - } else if (method_call.method_name().compare("setVolume") == 0) { - flutter::EncodableValue &volume = - encodables[flutter::EncodableValue("volume")]; - if (std::holds_alternative(volume)) { - player->SetVolume(std::get(volume)); - } else { - result->Error("Invalid volume", - "setVolume failed because of invalid volume"); - } - } else if (method_call.method_name().compare("setUrl") == 0) { - flutter::EncodableValue &url = - encodables[flutter::EncodableValue("url")]; - if (std::holds_alternative(url)) { - player->SetUrl(std::get(url)); - } else { - result->Error("Invalid url", - "SetUrl failed because of invalid url"); - } - } else if (method_call.method_name().compare("setPlaybackRate") == 0) { - flutter::EncodableValue &rate = - encodables[flutter::EncodableValue("playbackRate")]; - if (std::holds_alternative(rate)) { - player->SetPlaybackRate(std::get(rate)); - } else { - result->Error("Invalid rate", - "setPlaybackRate failed because of invalid rate"); - } - } else if (method_call.method_name().compare("setReleaseMode") == 0) { - flutter::EncodableValue &release_mode_value = - encodables[flutter::EncodableValue("releaseMode")]; - if (std::holds_alternative(release_mode_value)) { - std::string release_mode = - std::get(release_mode_value); - if (release_mode.compare("ReleaseMode.RELEASE") == 0) { - player->SetReleaseMode(RELEASE); - } else if (release_mode.compare("ReleaseMode.LOOP") == 0) { - player->SetReleaseMode(LOOP); - } else if (release_mode.compare("ReleaseMode.STOP") == 0) { - player->SetReleaseMode(STOP); - } - } else { - result->Error( - "Invalid ReleaseMode", - "setReleaseMode failed because of invalid ReleaseMode"); + AudioPlayer *player = GetAudioPlayer(player_id, mode); + + const auto &method_name = method_call.method_name(); + try { + if (method_name == "play") { + double volume = 0.0; + std::string url; + int32_t position = 0; + if (GetValueFromEncodableMap(arguments, "volume", volume)) { + player->SetVolume(volume); + } + if (GetValueFromEncodableMap(arguments, "url", url)) { + player->SetUrl(url); + } + player->Play(); + if (GetValueFromEncodableMap(arguments, "position", position)) { + player->Seek(position); + } + } else if (method_name == "playBytes") { + double volume = 0.0; + std::vector bytes; + int32_t position = 0; + if (GetValueFromEncodableMap(arguments, "volume", volume)) { + player->SetVolume(volume); + } + if (GetValueFromEncodableMap(arguments, "bytes", bytes)) { + player->SetDataSource(bytes); + } + player->Play(); + if (GetValueFromEncodableMap(arguments, "position", position)) { + player->Seek(position); + } + } else if (method_name == "resume") { + player->Play(); + } else if (method_name == "pause") { + player->Pause(); + } else if (method_name == "stop") { + player->Stop(); + } else if (method_name == "release") { + player->Release(); + } else if (method_name == "seek") { + int32_t position = 0; + if (GetValueFromEncodableMap(arguments, "position", position)) { + player->Seek(position); + } else { + result->Error("Invalid position", + "seek failed because of invalid position"); + } + } else if (method_name == "setVolume") { + double volume = 0.0; + if (GetValueFromEncodableMap(arguments, "volume", volume)) { + player->SetVolume(volume); + } else { + result->Error("Invalid volume", + "setVolume failed because of invalid volume"); + } + } else if (method_name == "setUrl") { + std::string url; + if (GetValueFromEncodableMap(arguments, "url", url)) { + player->SetUrl(url); + } else { + result->Error("Invalid url", "SetUrl failed because of invalid url"); + } + } else if (method_name == "setPlaybackRate") { + double playback_rate = 0.0; + if (GetValueFromEncodableMap(arguments, "playbackRate", + playback_rate)) { + player->SetPlaybackRate(playback_rate); + } else { + result->Error("Invalid rate", + "setPlaybackRate failed because of invalid rate"); + } + } else if (method_name == "setReleaseMode") { + std::string release_mode; + if (GetValueFromEncodableMap(arguments, "releaseMode", release_mode)) { + if (release_mode == "ReleaseMode.RELEASE") { + player->SetReleaseMode(ReleaseMode::kRelease); + } else if (release_mode == "ReleaseMode.LOOP") { + player->SetReleaseMode(ReleaseMode::kLoop); + } else if (release_mode == "ReleaseMode.STOP") { + player->SetReleaseMode(ReleaseMode::kStop); } - } else if (method_call.method_name().compare("getDuration") == 0) { - int duration = player->GetDuration(); - result->Success(flutter::EncodableValue(duration)); - return; - } else if (method_call.method_name().compare("getCurrentPosition") == - 0) { - int position = player->GetCurrentPosition(); - result->Success(flutter::EncodableValue(position)); - return; } else { - result->NotImplemented(); - return; + result->Error("Invalid ReleaseMode", + "setReleaseMode failed because of invalid ReleaseMode"); } - result->Success(flutter::EncodableValue(1)); - } catch (const AudioPlayerError &e) { - result->Error(e.GetCode(), e.GetMessage()); + } else if (method_name == "getDuration") { + result->Success(flutter::EncodableValue(player->GetDuration())); + return; + } else if (method_name == "getCurrentPosition") { + result->Success(flutter::EncodableValue(player->GetCurrentPosition())); + return; + } else { + result->NotImplemented(); + return; } - } else { - result->Error("Invalid arguments", "Invalid arguments for method " + - method_call.method_name()); + result->Success(flutter::EncodableValue(1)); + } catch (const AudioPlayerError &e) { + result->Error(e.GetCode(), e.GetMessage()); } } @@ -199,12 +187,6 @@ class AudioplayersTizenPlugin : public flutter::Plugin { return iter->second.get(); } - bool low_latency = false; - LOG_DEBUG("mode is %s", mode.c_str()); - if (mode.compare("PlayerMode.LOW_LATENCY") == 0) { - low_latency = true; - } - PreparedListener prepared_listener = [channel = channel_.get()](const std::string &player_id, int duration) { flutter::EncodableMap wrapped = {{flutter::EncodableValue("playerId"), @@ -252,6 +234,7 @@ class AudioplayersTizenPlugin : public flutter::Plugin { channel->InvokeMethod("audio.onError", std::move(arguments)); }; + bool low_latency = mode == "PlayerMode.LOW_LATENCY" ? true : false; auto player = std::make_unique( player_id, low_latency, prepared_listener, start_playing_listener, seek_completed_listener, play_completed_listener, error_listener); @@ -262,8 +245,7 @@ class AudioplayersTizenPlugin : public flutter::Plugin { static void StartPositionUpdates(void *data) { AudioplayersTizenPlugin *plugin = (AudioplayersTizenPlugin *)data; if (!plugin->timer_) { - LOG_DEBUG("add timer to update position of playing audio"); - plugin->timer_ = ecore_timer_add(TIMEOUT, UpdatePosition, data); + plugin->timer_ = ecore_timer_add(kTimeInterval, UpdatePosition, data); if (plugin->timer_ == nullptr) { LOG_ERROR("failed to add timer for UpdatePosition"); } @@ -278,7 +260,6 @@ class AudioplayersTizenPlugin : public flutter::Plugin { try { std::string player_id = iter->second->GetPlayerId(); if (iter->second->IsPlaying()) { - LOG_DEBUG("Audio player %s is playing", player_id.c_str()); none_playing = false; flutter::EncodableMap duration = { {flutter::EncodableValue("playerId"), @@ -313,11 +294,13 @@ class AudioplayersTizenPlugin : public flutter::Plugin { } } - Ecore_Timer *timer_; + Ecore_Timer *timer_ = nullptr; std::unique_ptr> channel_; std::map> audio_players_; }; +} // namespace + void AudioplayersTizenPluginRegisterWithRegistrar( FlutterDesktopPluginRegistrarRef registrar) { AudioplayersTizenPlugin::RegisterWithRegistrar( From bcb6a7574dee8b3a8ab912b067b3034d6bcf8e78 Mon Sep 17 00:00:00 2001 From: Hakkyu Kim Date: Thu, 28 Apr 2022 15:40:07 +0900 Subject: [PATCH 02/16] Remove Tizen API from the plugin class --- .../audioplayers/tizen/src/audio_player.cc | 40 ++++++++- .../audioplayers/tizen/src/audio_player.h | 8 +- .../tizen/src/audioplayers_tizen_plugin.cc | 85 +++++-------------- 3 files changed, 65 insertions(+), 68 deletions(-) diff --git a/packages/audioplayers/tizen/src/audio_player.cc b/packages/audioplayers/tizen/src/audio_player.cc index 384201ab8..f6d74d4d4 100644 --- a/packages/audioplayers/tizen/src/audio_player.cc +++ b/packages/audioplayers/tizen/src/audio_player.cc @@ -60,7 +60,7 @@ void AudioPlayer::Play() { ret = player_start(player_); HandleResult("player_start", ret); should_play_ = false; - start_playing_listener_(player_id_); + EmitPositionUpdates(); break; default: // "player is already playing audio. @@ -98,6 +98,10 @@ void AudioPlayer::Release() { player_destroy(player_); player_ = nullptr; } + if (timer_) { + ecore_timer_del(timer_); + timer_ = nullptr; + } } void AudioPlayer::Seek(int position) { @@ -236,6 +240,10 @@ void AudioPlayer::PreparePlayer() { seeking_ = false; } +void AudioPlayer::EmitPositionUpdates() { + ecore_main_loop_thread_safe_call_async(StartPositionUpdates, (void *)this); +} + void AudioPlayer::ResetPlayer() { int ret; player_state_e state = GetPlayerState(); @@ -287,7 +295,7 @@ void AudioPlayer::OnPrepared(void *data) { if (player->should_play_) { ret = player_start(player->player_); if (ret == PLAYER_ERROR_NONE) { - player->start_playing_listener_(player->player_id_); + player->EmitPositionUpdates(); } player->should_play_ = false; } @@ -330,3 +338,31 @@ void AudioPlayer::OnErrorOccurred(int code, void *data) { AudioPlayer *player = (AudioPlayer *)data; player->error_listener_(player->player_id_, "error occurred: " + error); } + +void AudioPlayer::StartPositionUpdates(void *data) { + AudioPlayer *player = (AudioPlayer *)data; + if (!player->timer_) { + const double kTimeInterval = 0.2; + player->timer_ = ecore_timer_add(kTimeInterval, OnPositionUpdate, data); + if (player->timer_ == nullptr) { + LOG_ERROR("failed to add timer for UpdatePosition"); + } + } +} + +Eina_Bool AudioPlayer::OnPositionUpdate(void *data) { + AudioPlayer *player = (AudioPlayer *)data; + std::string player_id = player->GetPlayerId(); + try { + if (player->IsPlaying()) { + int duration = player->GetDuration(); + int position = player->GetCurrentPosition(); + player->start_playing_listener_(player_id, duration, position); + return ECORE_CALLBACK_RENEW; + } + } catch (...) { + LOG_ERROR("failed to update position for player %s", player_id.c_str()); + } + player->timer_ = nullptr; + return ECORE_CALLBACK_CANCEL; +} \ No newline at end of file diff --git a/packages/audioplayers/tizen/src/audio_player.h b/packages/audioplayers/tizen/src/audio_player.h index 37d350b8b..4dd034996 100644 --- a/packages/audioplayers/tizen/src/audio_player.h +++ b/packages/audioplayers/tizen/src/audio_player.h @@ -1,6 +1,7 @@ #ifndef AUDIO_PLAYER_H_ #define AUDIO_PLAYER_H_ +#include #include #include @@ -11,7 +12,8 @@ enum class ReleaseMode { kRelease, kLoop, kStop }; using PreparedListener = std::function; -using StartPlayingListener = std::function; +using StartPlayingListener = std::function; using SeekCompletedListener = std::function; using PlayCompletedListener = std::function; using ErrorListener = std::function #include #include #include @@ -15,8 +14,6 @@ namespace { -const double kTimeInterval = 0.2; - template static bool GetValueFromEncodableMap(const flutter::EncodableMap *map, const char *key, T &out) { @@ -51,12 +48,7 @@ class AudioplayersTizenPlugin : public flutter::Plugin { AudioplayersTizenPlugin() {} - virtual ~AudioplayersTizenPlugin() { - if (timer_) { - ecore_timer_del(timer_); - timer_ = nullptr; - } - } + virtual ~AudioplayersTizenPlugin() {} private: void HandleMethodCall( @@ -208,9 +200,25 @@ class AudioplayersTizenPlugin : public flutter::Plugin { }; StartPlayingListener start_playing_listener = - [plugin = this](const std::string &player_id) { - ecore_main_loop_thread_safe_call_async(StartPositionUpdates, - (void *)plugin); + [channel = channel_.get()](const std::string &player_id, + const int duration, const int position) { + flutter::EncodableMap durationWrapped = { + {flutter::EncodableValue("playerId"), + flutter::EncodableValue(player_id)}, + {flutter::EncodableValue("value"), + flutter::EncodableValue(duration)}}; + channel->InvokeMethod( + "audio.onDuration", + std::make_unique(durationWrapped)); + + flutter::EncodableMap positionWrapped = { + {flutter::EncodableValue("playerId"), + flutter::EncodableValue(player_id)}, + {flutter::EncodableValue("value"), + flutter::EncodableValue(position)}}; + channel->InvokeMethod( + "audio.onCurrentPosition", + std::make_unique(positionWrapped)); }; PlayCompletedListener play_completed_listener = @@ -242,59 +250,6 @@ class AudioplayersTizenPlugin : public flutter::Plugin { return audio_players_[player_id].get(); } - static void StartPositionUpdates(void *data) { - AudioplayersTizenPlugin *plugin = (AudioplayersTizenPlugin *)data; - if (!plugin->timer_) { - plugin->timer_ = ecore_timer_add(kTimeInterval, UpdatePosition, data); - if (plugin->timer_ == nullptr) { - LOG_ERROR("failed to add timer for UpdatePosition"); - } - } - } - - static Eina_Bool UpdatePosition(void *data) { - AudioplayersTizenPlugin *plugin = (AudioplayersTizenPlugin *)data; - bool none_playing = true; - auto iter = plugin->audio_players_.begin(); - while (iter != plugin->audio_players_.end()) { - try { - std::string player_id = iter->second->GetPlayerId(); - if (iter->second->IsPlaying()) { - none_playing = false; - flutter::EncodableMap duration = { - {flutter::EncodableValue("playerId"), - flutter::EncodableValue(player_id)}, - {flutter::EncodableValue("value"), - flutter::EncodableValue(iter->second->GetDuration())}}; - plugin->channel_->InvokeMethod( - "audio.onDuration", - std::make_unique(duration)); - - flutter::EncodableMap position = { - {flutter::EncodableValue("playerId"), - flutter::EncodableValue(player_id)}, - {flutter::EncodableValue("value"), - flutter::EncodableValue(iter->second->GetCurrentPosition())}}; - plugin->channel_->InvokeMethod( - "audio.onCurrentPosition", - std::make_unique(position)); - } - iter++; - } catch (...) { - LOG_ERROR("failed to update position for player %s", - iter->second->GetPlayerId().c_str()); - } - } - - if (none_playing) { - plugin->timer_ = nullptr; - return ECORE_CALLBACK_CANCEL; - } else { - return ECORE_CALLBACK_RENEW; - } - } - - Ecore_Timer *timer_ = nullptr; std::unique_ptr> channel_; std::map> audio_players_; }; From 6d08cc8955f53ebcfa7133a04ce3b086db9dbec1 Mon Sep 17 00:00:00 2001 From: Hakkyu Kim Date: Thu, 28 Apr 2022 15:49:22 +0900 Subject: [PATCH 03/16] Minor cleanups --- .../audioplayers/tizen/src/audio_player.cc | 24 +++++++++---------- .../audioplayers/tizen/src/audio_player.h | 6 ++--- .../tizen/src/audio_player_error.h | 6 ++--- 3 files changed, 17 insertions(+), 19 deletions(-) diff --git a/packages/audioplayers/tizen/src/audio_player.cc b/packages/audioplayers/tizen/src/audio_player.cc index f6d74d4d4..a0542bb78 100644 --- a/packages/audioplayers/tizen/src/audio_player.cc +++ b/packages/audioplayers/tizen/src/audio_player.cc @@ -16,22 +16,21 @@ AudioPlayer::AudioPlayer(const std::string &player_id, bool low_latency, StartPlayingListener start_playing_listener, SeekCompletedListener seek_completed_listener, PlayCompletedListener play_completed_listener, - ErrorListener error_listener) { - player_id_ = player_id; - low_latency_ = low_latency; - prepared_listener_ = prepared_listener; - start_playing_listener_ = start_playing_listener; - seek_completed_listener_ = seek_completed_listener; - play_completed_listener_ = play_completed_listener; - error_listener_ = error_listener; -} + ErrorListener error_listener) + : player_id_(player_id), + low_latency_(low_latency), + prepared_listener_(prepared_listener), + start_playing_listener_(start_playing_listener), + seek_completed_listener_(seek_completed_listener), + play_completed_listener_(play_completed_listener), + error_listener_(error_listener) {} AudioPlayer::~AudioPlayer() { Release(); } void AudioPlayer::Play() { player_state_e state = GetPlayerState(); if (state == PLAYER_STATE_IDLE && preparing_) { - // player is preparing, play will be called in prepared callback.; + // Player is preparing, play will be called in prepared callback. should_play_ = true; return; } @@ -63,7 +62,7 @@ void AudioPlayer::Play() { EmitPositionUpdates(); break; default: - // "player is already playing audio. + // Player is already playing audio. break; } } @@ -122,7 +121,7 @@ void AudioPlayer::Seek(int position) { throw AudioPlayerError(error, "player_set_play_position failed"); } } else { - // player is unprepared, do seek in prepared callback. + // Player is unprepared, do seek in prepared callback. should_seek_to_ = position; } } @@ -233,7 +232,6 @@ void AudioPlayer::PreparePlayer() { ret = player_set_looping(player_, (release_mode_ == ReleaseMode::kLoop)); HandleResult("player_set_looping", ret); - LOG_DEBUG("prepare audio player asynchronously"); ret = player_prepare_async(player_, OnPrepared, (void *)this); HandleResult("player_prepare_async", ret); preparing_ = true; diff --git a/packages/audioplayers/tizen/src/audio_player.h b/packages/audioplayers/tizen/src/audio_player.h index 4dd034996..1a995b23f 100644 --- a/packages/audioplayers/tizen/src/audio_player.h +++ b/packages/audioplayers/tizen/src/audio_player.h @@ -1,5 +1,5 @@ -#ifndef AUDIO_PLAYER_H_ -#define AUDIO_PLAYER_H_ +#ifndef FLUTTER_PLUGIN_AUDIO_PLAYER_H_ +#define FLUTTER_PLUGIN_AUDIO_PLAYER_H_ #include #include @@ -84,4 +84,4 @@ class AudioPlayer { ErrorListener error_listener_; }; -#endif // AUDIO_PLAYER_H_ +#endif // FLUTTER_PLUGIN_AUDIO_PLAYER_H_ diff --git a/packages/audioplayers/tizen/src/audio_player_error.h b/packages/audioplayers/tizen/src/audio_player_error.h index 2517f622f..16ab91bc3 100644 --- a/packages/audioplayers/tizen/src/audio_player_error.h +++ b/packages/audioplayers/tizen/src/audio_player_error.h @@ -1,5 +1,5 @@ -#ifndef AUDIO_PLAYER_ERROR_H_ -#define AUDIO_PLAYER_ERROR_H_ +#ifndef FLUTTER_PLUGIN_AUDIO_PLAYER_ERROR_H_ +#define FLUTTER_PLUGIN_AUDIO_PLAYER_ERROR_H_ #include @@ -27,4 +27,4 @@ class AudioPlayerError { std::string message_; }; -#endif // AUDIO_PLAYER_ERROR_H_ +#endif // FLUTTER_PLUGIN_AUDIO_PLAYER_ERROR_H_ From ba1e80d6ba09d0f39aaeab3965711aa112dba637 Mon Sep 17 00:00:00 2001 From: Hakkyu Kim Date: Mon, 2 May 2022 14:28:27 +0900 Subject: [PATCH 04/16] Remove HandleResult to make the error more visible Also: - Avoid c-style cast syntax. - Declare local variable just before use. - Remove unnecessary LOG_ERRORs. - Rename method OnErrorOccurred -> OnError. - Add newline at the end. --- .../audioplayers/tizen/src/audio_player.cc | 217 +++++++++++------- .../audioplayers/tizen/src/audio_player.h | 2 +- 2 files changed, 132 insertions(+), 87 deletions(-) diff --git a/packages/audioplayers/tizen/src/audio_player.cc b/packages/audioplayers/tizen/src/audio_player.cc index a0542bb78..aa3de4957 100644 --- a/packages/audioplayers/tizen/src/audio_player.cc +++ b/packages/audioplayers/tizen/src/audio_player.cc @@ -3,14 +3,6 @@ #include "audio_player_error.h" #include "log.h" -static void HandleResult(const std::string &func_name, int result) { - if (result != PLAYER_ERROR_NONE) { - std::string error(get_error_message(result)); - LOG_ERROR("%s failed : %s", func_name.c_str(), error.c_str()); - throw AudioPlayerError(error, func_name + " failed"); - } -} - AudioPlayer::AudioPlayer(const std::string &player_id, bool low_latency, PreparedListener prepared_listener, StartPlayingListener start_playing_listener, @@ -39,28 +31,37 @@ void AudioPlayer::Play() { CreatePlayer(); } - int ret; switch (state) { case PLAYER_STATE_NONE: - case PLAYER_STATE_IDLE: + case PLAYER_STATE_IDLE: { if (audio_data_.size() > 0) { - ret = player_set_memory_buffer(player_, (void *)audio_data_.data(), - audio_data_.size()); - HandleResult("player_set_memory_buffer", ret); + int ret = player_set_memory_buffer(player_, audio_data_.data(), + audio_data_.size()); + if (ret != PLAYER_ERROR_NONE) { + throw AudioPlayerError("player_set_memory_buffer failed", + get_error_message(ret)); + } } else { - ret = player_set_uri(player_, url_.c_str()); - HandleResult("player_set_uri", ret); + int ret = player_set_uri(player_, url_.c_str()); + if (ret != PLAYER_ERROR_NONE) { + throw AudioPlayerError("player_set_uri failed", + get_error_message(ret)); + } } should_play_ = true; PreparePlayer(); break; + } case PLAYER_STATE_READY: - case PLAYER_STATE_PAUSED: - ret = player_start(player_); - HandleResult("player_start", ret); + case PLAYER_STATE_PAUSED: { + int ret = player_start(player_); + if (ret != PLAYER_ERROR_NONE) { + throw AudioPlayerError("player_start failed", get_error_message(ret)); + } should_play_ = false; EmitPositionUpdates(); break; + } default: // Player is already playing audio. break; @@ -70,8 +71,11 @@ void AudioPlayer::Play() { void AudioPlayer::Pause() { if (GetPlayerState() == PLAYER_STATE_PLAYING) { int ret = player_pause(player_); - HandleResult("player_pause", ret); + if (ret != PLAYER_ERROR_NONE) { + throw AudioPlayerError("player_pause failed", get_error_message(ret)); + } } + should_play_ = false; } @@ -82,9 +86,12 @@ void AudioPlayer::Stop() { player_state_e state = GetPlayerState(); if (state == PLAYER_STATE_PLAYING || state == PLAYER_STATE_PAUSED) { int ret = player_stop(player_); - HandleResult("player_stop", ret); + if (ret != PLAYER_ERROR_NONE) { + throw AudioPlayerError("player_stop failed", get_error_message(ret)); + } } } + should_play_ = false; seeking_ = false; } @@ -111,15 +118,13 @@ void AudioPlayer::Seek(int position) { player_state_e state = GetPlayerState(); if (state == PLAYER_STATE_READY || state == PLAYER_STATE_PLAYING || state == PLAYER_STATE_PAUSED) { - seeking_ = true; int ret = player_set_play_position(player_, position, true, OnSeekCompleted, - (void *)this); + this); if (ret != PLAYER_ERROR_NONE) { - seeking_ = false; - std::string error(get_error_message(ret)); - LOG_ERROR("player_set_play_position failed : %s", error.c_str()); - throw AudioPlayerError(error, "player_set_play_position failed"); + throw AudioPlayerError("player_set_play_position failed", + get_error_message(ret)); } + seeking_ = true; } else { // Player is unprepared, do seek in prepared callback. should_seek_to_ = position; @@ -132,7 +137,9 @@ void AudioPlayer::SetUrl(const std::string &url) { ResetPlayer(); int ret = player_set_uri(player_, url.c_str()); - HandleResult("player_set_uri", ret); + if (ret != PLAYER_ERROR_NONE) { + throw AudioPlayerError("player_set_uri failed", get_error_message(ret)); + } PreparePlayer(); } @@ -144,9 +151,12 @@ void AudioPlayer::SetDataSource(std::vector &data) { audio_data_.swap(data); ResetPlayer(); - int ret = player_set_memory_buffer(player_, (void *)audio_data_.data(), + int ret = player_set_memory_buffer(player_, audio_data_.data(), audio_data_.size()); - HandleResult("player_set_memory_buffer", ret); + if (ret != PLAYER_ERROR_NONE) { + throw AudioPlayerError("player_set_memory_buffer failed", + get_error_message(ret)); + } PreparePlayer(); } @@ -157,7 +167,10 @@ void AudioPlayer::SetVolume(double volume) { volume_ = volume; if (GetPlayerState() != PLAYER_STATE_NONE) { int ret = player_set_volume(player_, volume_, volume_); - HandleResult("player_set_volume", ret); + if (ret != PLAYER_ERROR_NONE) { + throw AudioPlayerError("player_set_volume failed", + get_error_message(ret)); + } } } } @@ -169,7 +182,10 @@ void AudioPlayer::SetPlaybackRate(double rate) { if (state == PLAYER_STATE_READY || state == PLAYER_STATE_PLAYING || state == PLAYER_STATE_PAUSED) { int ret = player_set_playback_rate(player_, rate); - HandleResult("player_set_playback_rate", ret); + if (ret != PLAYER_ERROR_NONE) { + throw AudioPlayerError("player_set_playback_rate failed", + get_error_message(ret)); + } } } } @@ -180,22 +196,31 @@ void AudioPlayer::SetReleaseMode(ReleaseMode mode) { if (GetPlayerState() != PLAYER_STATE_NONE) { int ret = player_set_looping(player_, (release_mode_ == ReleaseMode::kLoop)); - HandleResult("player_set_looping", ret); + if (ret != PLAYER_ERROR_NONE) { + throw AudioPlayerError("player_set_looping failed", + get_error_message(ret)); + } } } } int AudioPlayer::GetDuration() { int duration; - int result = player_get_duration(player_, &duration); - HandleResult("player_get_duration", result); + int ret = player_get_duration(player_, &duration); + if (ret != PLAYER_ERROR_NONE) { + throw AudioPlayerError("player_get_duration failed", + get_error_message(ret)); + } return duration; } int AudioPlayer::GetCurrentPosition() { int position; - int result = player_get_play_position(player_, &position); - HandleResult("player_get_play_position", result); + int ret = player_get_play_position(player_, &position); + if (ret != PLAYER_ERROR_NONE) { + throw AudioPlayerError("player_get_play_position failed", + get_error_message(ret)); + } return position; } @@ -208,42 +233,63 @@ void AudioPlayer::CreatePlayer() { preparing_ = false; int ret = player_create(&player_); - HandleResult("player_create", ret); + if (ret != PLAYER_ERROR_NONE) { + throw AudioPlayerError("player_create failed", get_error_message(ret)); + } if (low_latency_) { ret = player_set_audio_latency_mode(player_, AUDIO_LATENCY_MODE_LOW); - HandleResult("player_set_audio_latency_mode", ret); + if (ret != PLAYER_ERROR_NONE) { + throw AudioPlayerError("player_set_audio_latency_mode failed", + get_error_message(ret)); + } } - ret = player_set_completed_cb(player_, OnPlayCompleted, (void *)this); - HandleResult("player_set_completed_cb", ret); + ret = player_set_completed_cb(player_, OnPlayCompleted, this); + if (ret != PLAYER_ERROR_NONE) { + throw AudioPlayerError("player_set_completed_cb failed", + get_error_message(ret)); + } - ret = player_set_interrupted_cb(player_, OnInterrupted, (void *)this); - HandleResult("player_set_interrupted_cb", ret); + ret = player_set_interrupted_cb(player_, OnInterrupted, this); + if (ret != PLAYER_ERROR_NONE) { + throw AudioPlayerError("player_set_interrupted_cb failed", + get_error_message(ret)); + } - ret = player_set_error_cb(player_, OnErrorOccurred, (void *)this); - HandleResult("player_set_error_cb", ret); + ret = player_set_error_cb(player_, OnError, this); + if (ret != PLAYER_ERROR_NONE) { + throw AudioPlayerError("player_set_error_cb failed", + get_error_message(ret)); + } } void AudioPlayer::PreparePlayer() { int ret = player_set_volume(player_, volume_, volume_); - HandleResult("player_set_volume", ret); + if (ret != PLAYER_ERROR_NONE) { + throw AudioPlayerError("player_set_volume failed", get_error_message(ret)); + } ret = player_set_looping(player_, (release_mode_ == ReleaseMode::kLoop)); - HandleResult("player_set_looping", ret); + if (ret != PLAYER_ERROR_NONE) { + throw AudioPlayerError("player_set_looping failed", get_error_message(ret)); + } + + ret = player_prepare_async(player_, OnPrepared, this); + if (ret != PLAYER_ERROR_NONE) { + throw AudioPlayerError("player_prepare_async failed", + get_error_message(ret)); + } - ret = player_prepare_async(player_, OnPrepared, (void *)this); - HandleResult("player_prepare_async", ret); preparing_ = true; seeking_ = false; } void AudioPlayer::EmitPositionUpdates() { - ecore_main_loop_thread_safe_call_async(StartPositionUpdates, (void *)this); + ecore_main_loop_thread_safe_call_async(StartPositionUpdates, this); } void AudioPlayer::ResetPlayer() { - int ret; player_state_e state = GetPlayerState(); switch (state) { case PLAYER_STATE_NONE: @@ -252,16 +298,22 @@ void AudioPlayer::ResetPlayer() { case PLAYER_STATE_IDLE: if (preparing_) { // Cancel preparing if it's already preparing. - ret = player_unprepare(player_); - HandleResult("player_unprepare", ret); + int ret = player_unprepare(player_); + if (ret != PLAYER_ERROR_NONE) { + throw AudioPlayerError("player_unprepare failed", + get_error_message(ret)); + } preparing_ = false; } break; case PLAYER_STATE_READY: case PLAYER_STATE_PLAYING: case PLAYER_STATE_PAUSED: - ret = player_unprepare(player_); - HandleResult("player_unprepare", ret); + int ret = player_unprepare(player_); + if (ret != PLAYER_ERROR_NONE) { + throw AudioPlayerError("player_unprepare failed", + get_error_message(ret)); + } break; } } @@ -271,53 +323,48 @@ player_state_e AudioPlayer::GetPlayerState() { if (player_) { int ret = player_get_state(player_, &state); if (ret != PLAYER_ERROR_NONE) { - LOG_ERROR("Getting player(id: %s) state failed: %s\n", player_id_.c_str(), - get_error_message(ret)); + throw AudioPlayerError("player_get_state failed", get_error_message(ret)); } } return state; } void AudioPlayer::OnPrepared(void *data) { - AudioPlayer *player = (AudioPlayer *)data; + auto *player = reinterpret_cast(data); player->preparing_ = false; - int duration = 0; - int ret = player_get_duration(player->player_, &duration); - if (ret == PLAYER_ERROR_NONE) { - player->prepared_listener_(player->player_id_, duration); - } - + player->prepared_listener_(player->player_id_, player->GetDuration()); player_set_playback_rate(player->player_, player->playback_rate_); if (player->should_play_) { - ret = player_start(player->player_); - if (ret == PLAYER_ERROR_NONE) { - player->EmitPositionUpdates(); + int ret = player_start(player->player_); + if (ret != PLAYER_ERROR_NONE) { + throw AudioPlayerError("player_start failed", get_error_message(ret)); } + player->EmitPositionUpdates(); player->should_play_ = false; } if (player->should_seek_to_ > 0) { - player->seeking_ = true; - ret = player_set_play_position(player->player_, player->should_seek_to_, - true, OnSeekCompleted, data); + int ret = player_set_play_position(player->player_, player->should_seek_to_, + true, OnSeekCompleted, data); if (ret != PLAYER_ERROR_NONE) { - LOG_ERROR("failed to set play position"); - player->seeking_ = false; + throw AudioPlayerError("player_set_play_position failed", + get_error_message(ret)); } + player->seeking_ = true; player->should_seek_to_ = -1; } } void AudioPlayer::OnSeekCompleted(void *data) { - AudioPlayer *player = (AudioPlayer *)data; + auto *player = reinterpret_cast(data); player->seek_completed_listener_(player->player_id_); player->seeking_ = false; } void AudioPlayer::OnPlayCompleted(void *data) { - AudioPlayer *player = (AudioPlayer *)data; + auto *player = reinterpret_cast(data); if (player->release_mode_ != ReleaseMode::kLoop) { player->Stop(); } @@ -325,31 +372,29 @@ void AudioPlayer::OnPlayCompleted(void *data) { } void AudioPlayer::OnInterrupted(player_interrupted_code_e code, void *data) { - LOG_ERROR("interruption occurred: %d", code); - AudioPlayer *player = (AudioPlayer *)data; - player->error_listener_(player->player_id_, "player - Interrupted"); + auto *player = reinterpret_cast(data); + player->error_listener_(player->player_id_, "Player interrupted."); } -void AudioPlayer::OnErrorOccurred(int code, void *data) { +void AudioPlayer::OnError(int code, void *data) { + auto *player = reinterpret_cast(data); std::string error(get_error_message(code)); - LOG_ERROR("error occurred: %s", error.c_str()); - AudioPlayer *player = (AudioPlayer *)data; - player->error_listener_(player->player_id_, "error occurred: " + error); + player->error_listener_(player->player_id_, "Player error: " + error); } void AudioPlayer::StartPositionUpdates(void *data) { - AudioPlayer *player = (AudioPlayer *)data; + auto *player = reinterpret_cast(data); if (!player->timer_) { const double kTimeInterval = 0.2; player->timer_ = ecore_timer_add(kTimeInterval, OnPositionUpdate, data); - if (player->timer_ == nullptr) { - LOG_ERROR("failed to add timer for UpdatePosition"); + if (!player->timer_) { + LOG_ERROR("Failed to add timer for UpdatePosition."); } } } Eina_Bool AudioPlayer::OnPositionUpdate(void *data) { - AudioPlayer *player = (AudioPlayer *)data; + auto *player = reinterpret_cast(data); std::string player_id = player->GetPlayerId(); try { if (player->IsPlaying()) { @@ -359,8 +404,8 @@ Eina_Bool AudioPlayer::OnPositionUpdate(void *data) { return ECORE_CALLBACK_RENEW; } } catch (...) { - LOG_ERROR("failed to update position for player %s", player_id.c_str()); + LOG_ERROR("Failed to update position for player %s.", player_id.c_str()); } player->timer_ = nullptr; return ECORE_CALLBACK_CANCEL; -} \ No newline at end of file +} diff --git a/packages/audioplayers/tizen/src/audio_player.h b/packages/audioplayers/tizen/src/audio_player.h index 1a995b23f..82b4de27c 100644 --- a/packages/audioplayers/tizen/src/audio_player.h +++ b/packages/audioplayers/tizen/src/audio_player.h @@ -60,7 +60,7 @@ class AudioPlayer { static void OnSeekCompleted(void *data); static void OnPlayCompleted(void *data); static void OnInterrupted(player_interrupted_code_e code, void *data); - static void OnErrorOccurred(int code, void *data); + static void OnError(int code, void *data); static void StartPositionUpdates(void *data); static Eina_Bool OnPositionUpdate(void *data); From 83d92e010c82c266ea98295f6713eebebf2de39f Mon Sep 17 00:00:00 2001 From: Hakkyu Kim Date: Mon, 2 May 2022 15:35:55 +0900 Subject: [PATCH 05/16] Fix error messages Also: - Remove unused header cassert. - Explicitly add used headers. - Add return statements appropriately. - Minor cleanups. --- .../tizen/src/audioplayers_tizen_plugin.cc | 43 +++++++++++-------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/packages/audioplayers/tizen/src/audioplayers_tizen_plugin.cc b/packages/audioplayers/tizen/src/audioplayers_tizen_plugin.cc index 8edcb7203..3823514d9 100644 --- a/packages/audioplayers/tizen/src/audioplayers_tizen_plugin.cc +++ b/packages/audioplayers/tizen/src/audioplayers_tizen_plugin.cc @@ -5,8 +5,10 @@ #include #include -#include #include +#include +#include +#include #include "audio_player.h" #include "audio_player_error.h" @@ -14,6 +16,8 @@ namespace { +const char *kInvalidArgument = "Invalid argument"; + template static bool GetValueFromEncodableMap(const flutter::EncodableMap *map, const char *key, T &out) { @@ -57,15 +61,13 @@ class AudioplayersTizenPlugin : public flutter::Plugin { const auto *arguments = std::get_if(method_call.arguments()); if (!arguments) { - result->Error("Invalid arguments", "Invalid arguments for method " + - method_call.method_name()); + result->Error(kInvalidArgument, "No arguments provided."); return; } std::string player_id, mode; if (!GetValueFromEncodableMap(arguments, "playerId", player_id)) { - result->Error("Invalid Player ID", "Invalid Player ID for method " + - method_call.method_name()); + result->Error(kInvalidArgument, "No playerId provided."); return; } GetValueFromEncodableMap(arguments, "mode", mode); @@ -115,23 +117,27 @@ class AudioplayersTizenPlugin : public flutter::Plugin { if (GetValueFromEncodableMap(arguments, "position", position)) { player->Seek(position); } else { - result->Error("Invalid position", - "seek failed because of invalid position"); + result->Error(kInvalidArgument, + "No position provided or is invalid value."); + return; } } else if (method_name == "setVolume") { double volume = 0.0; if (GetValueFromEncodableMap(arguments, "volume", volume)) { player->SetVolume(volume); } else { - result->Error("Invalid volume", - "setVolume failed because of invalid volume"); + result->Error(kInvalidArgument, + "No volume provided or is invalid value."); + return; } } else if (method_name == "setUrl") { std::string url; if (GetValueFromEncodableMap(arguments, "url", url)) { player->SetUrl(url); } else { - result->Error("Invalid url", "SetUrl failed because of invalid url"); + result->Error(kInvalidArgument, + "No url provided or is invalid value."); + return; } } else if (method_name == "setPlaybackRate") { double playback_rate = 0.0; @@ -139,8 +145,9 @@ class AudioplayersTizenPlugin : public flutter::Plugin { playback_rate)) { player->SetPlaybackRate(playback_rate); } else { - result->Error("Invalid rate", - "setPlaybackRate failed because of invalid rate"); + result->Error(kInvalidArgument, + "No playbackRate provided or is invalid value."); + return; } } else if (method_name == "setReleaseMode") { std::string release_mode; @@ -153,8 +160,9 @@ class AudioplayersTizenPlugin : public flutter::Plugin { player->SetReleaseMode(ReleaseMode::kStop); } } else { - result->Error("Invalid ReleaseMode", - "setReleaseMode failed because of invalid ReleaseMode"); + result->Error(kInvalidArgument, + "No realeaseMode provided or is invalid value."); + return; } } else if (method_name == "getDuration") { result->Success(flutter::EncodableValue(player->GetDuration())); @@ -167,8 +175,8 @@ class AudioplayersTizenPlugin : public flutter::Plugin { return; } result->Success(flutter::EncodableValue(1)); - } catch (const AudioPlayerError &e) { - result->Error(e.GetCode(), e.GetMessage()); + } catch (const AudioPlayerError &error) { + result->Error(error.GetCode(), error.GetMessage()); } } @@ -242,11 +250,12 @@ class AudioplayersTizenPlugin : public flutter::Plugin { channel->InvokeMethod("audio.onError", std::move(arguments)); }; - bool low_latency = mode == "PlayerMode.LOW_LATENCY" ? true : false; + bool low_latency = mode == "PlayerMode.LOW_LATENCY"; auto player = std::make_unique( player_id, low_latency, prepared_listener, start_playing_listener, seek_completed_listener, play_completed_listener, error_listener); audio_players_[player_id] = std::move(player); + return audio_players_[player_id].get(); } From c8199ce10e69e4cb8313724210364f7e3787b530 Mon Sep 17 00:00:00 2001 From: Hakkyu Kim Date: Mon, 2 May 2022 15:42:59 +0900 Subject: [PATCH 06/16] Call error_listener when position update failes - Rename callback function: StartPlayingListener -> UpdatePositionListener. --- packages/audioplayers/tizen/src/audio_player.cc | 15 +++++++++------ packages/audioplayers/tizen/src/audio_player.h | 6 +++--- .../tizen/src/audioplayers_tizen_plugin.cc | 4 ++-- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/packages/audioplayers/tizen/src/audio_player.cc b/packages/audioplayers/tizen/src/audio_player.cc index aa3de4957..1bf73a290 100644 --- a/packages/audioplayers/tizen/src/audio_player.cc +++ b/packages/audioplayers/tizen/src/audio_player.cc @@ -5,14 +5,14 @@ AudioPlayer::AudioPlayer(const std::string &player_id, bool low_latency, PreparedListener prepared_listener, - StartPlayingListener start_playing_listener, + UpdatePositionListener update_position_listener, SeekCompletedListener seek_completed_listener, PlayCompletedListener play_completed_listener, ErrorListener error_listener) : player_id_(player_id), low_latency_(low_latency), prepared_listener_(prepared_listener), - start_playing_listener_(start_playing_listener), + update_position_listener_(update_position_listener), seek_completed_listener_(seek_completed_listener), play_completed_listener_(play_completed_listener), error_listener_(error_listener) {} @@ -385,10 +385,13 @@ void AudioPlayer::OnError(int code, void *data) { void AudioPlayer::StartPositionUpdates(void *data) { auto *player = reinterpret_cast(data); if (!player->timer_) { + // The audioplayers app facing package expects position + // update events to fire roughly every 200 milliseconds. const double kTimeInterval = 0.2; player->timer_ = ecore_timer_add(kTimeInterval, OnPositionUpdate, data); if (!player->timer_) { - LOG_ERROR("Failed to add timer for UpdatePosition."); + player->error_listener_(player->GetPlayerId(), + "Failed to add postion update timer."); } } } @@ -400,11 +403,11 @@ Eina_Bool AudioPlayer::OnPositionUpdate(void *data) { if (player->IsPlaying()) { int duration = player->GetDuration(); int position = player->GetCurrentPosition(); - player->start_playing_listener_(player_id, duration, position); + player->update_position_listener_(player_id, duration, position); return ECORE_CALLBACK_RENEW; } - } catch (...) { - LOG_ERROR("Failed to update position for player %s.", player_id.c_str()); + } catch (const AudioPlayerError &error) { + player->error_listener_(player_id, "Failed to update position."); } player->timer_ = nullptr; return ECORE_CALLBACK_CANCEL; diff --git a/packages/audioplayers/tizen/src/audio_player.h b/packages/audioplayers/tizen/src/audio_player.h index 82b4de27c..4536ccc63 100644 --- a/packages/audioplayers/tizen/src/audio_player.h +++ b/packages/audioplayers/tizen/src/audio_player.h @@ -12,7 +12,7 @@ enum class ReleaseMode { kRelease, kLoop, kStop }; using PreparedListener = std::function; -using StartPlayingListener = std::function; using SeekCompletedListener = std::function; using PlayCompletedListener = std::function; @@ -23,7 +23,7 @@ class AudioPlayer { public: AudioPlayer(const std::string &player_id, bool low_latency, PreparedListener prepared_listener, - StartPlayingListener start_playing_listener, + UpdatePositionListener update_position_listener, SeekCompletedListener seek_completed_listener, PlayCompletedListener play_completed_listener, ErrorListener error_listener); @@ -78,7 +78,7 @@ class AudioPlayer { bool should_play_ = false; Ecore_Timer *timer_ = nullptr; PreparedListener prepared_listener_; - StartPlayingListener start_playing_listener_; + UpdatePositionListener update_position_listener_; SeekCompletedListener seek_completed_listener_; PlayCompletedListener play_completed_listener_; ErrorListener error_listener_; diff --git a/packages/audioplayers/tizen/src/audioplayers_tizen_plugin.cc b/packages/audioplayers/tizen/src/audioplayers_tizen_plugin.cc index 3823514d9..7d94bba3e 100644 --- a/packages/audioplayers/tizen/src/audioplayers_tizen_plugin.cc +++ b/packages/audioplayers/tizen/src/audioplayers_tizen_plugin.cc @@ -207,7 +207,7 @@ class AudioplayersTizenPlugin : public flutter::Plugin { channel->InvokeMethod("audio.onSeekComplete", std::move(arguments)); }; - StartPlayingListener start_playing_listener = + UpdatePositionListener update_position_listener = [channel = channel_.get()](const std::string &player_id, const int duration, const int position) { flutter::EncodableMap durationWrapped = { @@ -252,7 +252,7 @@ class AudioplayersTizenPlugin : public flutter::Plugin { bool low_latency = mode == "PlayerMode.LOW_LATENCY"; auto player = std::make_unique( - player_id, low_latency, prepared_listener, start_playing_listener, + player_id, low_latency, prepared_listener, update_position_listener, seek_completed_listener, play_completed_listener, error_listener); audio_players_[player_id] = std::move(player); From b4d81f45355342cbca3d2d10226325973161350b Mon Sep 17 00:00:00 2001 From: Hakkyu Kim Date: Mon, 2 May 2022 16:24:48 +0900 Subject: [PATCH 07/16] Handle invalid argument error in catch block - Call result->Success() in every if block to clarify execution path. --- .../tizen/src/audioplayers_tizen_plugin.cc | 100 ++++++++---------- 1 file changed, 46 insertions(+), 54 deletions(-) diff --git a/packages/audioplayers/tizen/src/audioplayers_tizen_plugin.cc b/packages/audioplayers/tizen/src/audioplayers_tizen_plugin.cc index 7d94bba3e..d9f141f22 100644 --- a/packages/audioplayers/tizen/src/audioplayers_tizen_plugin.cc +++ b/packages/audioplayers/tizen/src/audioplayers_tizen_plugin.cc @@ -19,8 +19,8 @@ namespace { const char *kInvalidArgument = "Invalid argument"; template -static bool GetValueFromEncodableMap(const flutter::EncodableMap *map, - const char *key, T &out) { +bool GetValueFromEncodableMap(const flutter::EncodableMap *map, const char *key, + T &out) { auto iter = map->find(flutter::EncodableValue(key)); if (iter != map->end() && !iter->second.IsNull()) { if (auto *value = std::get_if(&iter->second)) { @@ -31,6 +31,28 @@ static bool GetValueFromEncodableMap(const flutter::EncodableMap *map, return false; } +template +T GetRequiredArg(const flutter::EncodableMap *arguments, const char *key) { + T value; + if (GetValueFromEncodableMap(arguments, key, value)) { + return value; + } + std::string message = + "No " + std::string(key) + " provided or is invalid type or value."; + throw std::invalid_argument(message); +} + +ReleaseMode StringToReleaseMode(std::string release_mode) { + if (release_mode == "ReleaseMode.RELEASE") { + return ReleaseMode::kRelease; + } else if (release_mode == "ReleaseMode.LOOP") { + return ReleaseMode::kLoop; + } else if (release_mode == "ReleaseMode.STOP") { + return ReleaseMode::kStop; + } + throw std::invalid_argument("Invalid release mode."); +} + class AudioplayersTizenPlugin : public flutter::Plugin { public: static void RegisterWithRegistrar(flutter::PluginRegistrar *registrar) { @@ -74,8 +96,8 @@ class AudioplayersTizenPlugin : public flutter::Plugin { AudioPlayer *player = GetAudioPlayer(player_id, mode); - const auto &method_name = method_call.method_name(); try { + const auto &method_name = method_call.method_name(); if (method_name == "play") { double volume = 0.0; std::string url; @@ -90,6 +112,7 @@ class AudioplayersTizenPlugin : public flutter::Plugin { if (GetValueFromEncodableMap(arguments, "position", position)) { player->Seek(position); } + result->Success(flutter::EncodableValue(1)); } else if (method_name == "playBytes") { double volume = 0.0; std::vector bytes; @@ -104,77 +127,46 @@ class AudioplayersTizenPlugin : public flutter::Plugin { if (GetValueFromEncodableMap(arguments, "position", position)) { player->Seek(position); } + result->Success(flutter::EncodableValue(1)); } else if (method_name == "resume") { player->Play(); + result->Success(flutter::EncodableValue(1)); } else if (method_name == "pause") { player->Pause(); + result->Success(flutter::EncodableValue(1)); } else if (method_name == "stop") { player->Stop(); + result->Success(flutter::EncodableValue(1)); } else if (method_name == "release") { player->Release(); + result->Success(flutter::EncodableValue(1)); } else if (method_name == "seek") { - int32_t position = 0; - if (GetValueFromEncodableMap(arguments, "position", position)) { - player->Seek(position); - } else { - result->Error(kInvalidArgument, - "No position provided or is invalid value."); - return; - } + player->Seek(GetRequiredArg(arguments, "position")); + result->Success(flutter::EncodableValue(1)); } else if (method_name == "setVolume") { - double volume = 0.0; - if (GetValueFromEncodableMap(arguments, "volume", volume)) { - player->SetVolume(volume); - } else { - result->Error(kInvalidArgument, - "No volume provided or is invalid value."); - return; - } + player->SetVolume(GetRequiredArg(arguments, "volume")); + result->Success(flutter::EncodableValue(1)); } else if (method_name == "setUrl") { - std::string url; - if (GetValueFromEncodableMap(arguments, "url", url)) { - player->SetUrl(url); - } else { - result->Error(kInvalidArgument, - "No url provided or is invalid value."); - return; - } + player->SetUrl(GetRequiredArg(arguments, "url")); + result->Success(flutter::EncodableValue(1)); } else if (method_name == "setPlaybackRate") { - double playback_rate = 0.0; - if (GetValueFromEncodableMap(arguments, "playbackRate", - playback_rate)) { - player->SetPlaybackRate(playback_rate); - } else { - result->Error(kInvalidArgument, - "No playbackRate provided or is invalid value."); - return; - } + player->SetPlaybackRate( + GetRequiredArg(arguments, "playbackRate")); + result->Success(flutter::EncodableValue(1)); } else if (method_name == "setReleaseMode") { - std::string release_mode; - if (GetValueFromEncodableMap(arguments, "releaseMode", release_mode)) { - if (release_mode == "ReleaseMode.RELEASE") { - player->SetReleaseMode(ReleaseMode::kRelease); - } else if (release_mode == "ReleaseMode.LOOP") { - player->SetReleaseMode(ReleaseMode::kLoop); - } else if (release_mode == "ReleaseMode.STOP") { - player->SetReleaseMode(ReleaseMode::kStop); - } - } else { - result->Error(kInvalidArgument, - "No realeaseMode provided or is invalid value."); - return; - } + std::string release_mode = + GetRequiredArg(arguments, "releaseMode"); + player->SetReleaseMode(StringToReleaseMode(release_mode)); + result->Success(flutter::EncodableValue(1)); } else if (method_name == "getDuration") { result->Success(flutter::EncodableValue(player->GetDuration())); - return; } else if (method_name == "getCurrentPosition") { result->Success(flutter::EncodableValue(player->GetCurrentPosition())); - return; } else { result->NotImplemented(); - return; } - result->Success(flutter::EncodableValue(1)); + } catch (const std::invalid_argument &error) { + result->Error(kInvalidArgument, error.what()); } catch (const AudioPlayerError &error) { result->Error(error.GetCode(), error.GetMessage()); } From 3cdb164ee4e5d1d81d0ced48642ab2c4e90812a6 Mon Sep 17 00:00:00 2001 From: Hakkyu Kim Date: Mon, 2 May 2022 16:37:12 +0900 Subject: [PATCH 08/16] Stop player first before release - Remove unused log.h include. --- .../audioplayers/tizen/src/audio_player.cc | 19 +++++++++---------- .../tizen/src/audioplayers_tizen_plugin.cc | 1 - 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/packages/audioplayers/tizen/src/audio_player.cc b/packages/audioplayers/tizen/src/audio_player.cc index 1bf73a290..bff442300 100644 --- a/packages/audioplayers/tizen/src/audio_player.cc +++ b/packages/audioplayers/tizen/src/audio_player.cc @@ -1,7 +1,6 @@ #include "audio_player.h" #include "audio_player_error.h" -#include "log.h" AudioPlayer::AudioPlayer(const std::string &player_id, bool low_latency, PreparedListener prepared_listener, @@ -80,20 +79,20 @@ void AudioPlayer::Pause() { } void AudioPlayer::Stop() { - if (release_mode_ == ReleaseMode::kRelease) { - Release(); - } else { - player_state_e state = GetPlayerState(); - if (state == PLAYER_STATE_PLAYING || state == PLAYER_STATE_PAUSED) { - int ret = player_stop(player_); - if (ret != PLAYER_ERROR_NONE) { - throw AudioPlayerError("player_stop failed", get_error_message(ret)); - } + player_state_e state = GetPlayerState(); + if (state == PLAYER_STATE_PLAYING || state == PLAYER_STATE_PAUSED) { + int ret = player_stop(player_); + if (ret != PLAYER_ERROR_NONE) { + throw AudioPlayerError("player_stop failed", get_error_message(ret)); } } should_play_ = false; seeking_ = false; + + if (release_mode_ == ReleaseMode::kRelease) { + Release(); + } } void AudioPlayer::Release() { diff --git a/packages/audioplayers/tizen/src/audioplayers_tizen_plugin.cc b/packages/audioplayers/tizen/src/audioplayers_tizen_plugin.cc index d9f141f22..aabd12d6b 100644 --- a/packages/audioplayers/tizen/src/audioplayers_tizen_plugin.cc +++ b/packages/audioplayers/tizen/src/audioplayers_tizen_plugin.cc @@ -12,7 +12,6 @@ #include "audio_player.h" #include "audio_player_error.h" -#include "log.h" namespace { From 477d1b7fe39aab12840ef7d97f1a53d5a520a0e1 Mon Sep 17 00:00:00 2001 From: Hakkyu Kim Date: Mon, 2 May 2022 17:12:59 +0900 Subject: [PATCH 09/16] Remove ecore_main_loop_thread_safe_call_async --- .../audioplayers/tizen/src/audio_player.cc | 20 +++++++------------ .../audioplayers/tizen/src/audio_player.h | 3 +-- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/packages/audioplayers/tizen/src/audio_player.cc b/packages/audioplayers/tizen/src/audio_player.cc index bff442300..e631c3562 100644 --- a/packages/audioplayers/tizen/src/audio_player.cc +++ b/packages/audioplayers/tizen/src/audio_player.cc @@ -58,7 +58,7 @@ void AudioPlayer::Play() { throw AudioPlayerError("player_start failed", get_error_message(ret)); } should_play_ = false; - EmitPositionUpdates(); + StartPositionUpdates(); break; } default: @@ -284,10 +284,6 @@ void AudioPlayer::PreparePlayer() { seeking_ = false; } -void AudioPlayer::EmitPositionUpdates() { - ecore_main_loop_thread_safe_call_async(StartPositionUpdates, this); -} - void AudioPlayer::ResetPlayer() { player_state_e state = GetPlayerState(); switch (state) { @@ -340,7 +336,7 @@ void AudioPlayer::OnPrepared(void *data) { if (ret != PLAYER_ERROR_NONE) { throw AudioPlayerError("player_start failed", get_error_message(ret)); } - player->EmitPositionUpdates(); + player->StartPositionUpdates(); player->should_play_ = false; } @@ -381,16 +377,14 @@ void AudioPlayer::OnError(int code, void *data) { player->error_listener_(player->player_id_, "Player error: " + error); } -void AudioPlayer::StartPositionUpdates(void *data) { - auto *player = reinterpret_cast(data); - if (!player->timer_) { +void AudioPlayer::StartPositionUpdates() { + if (!timer_) { // The audioplayers app facing package expects position // update events to fire roughly every 200 milliseconds. const double kTimeInterval = 0.2; - player->timer_ = ecore_timer_add(kTimeInterval, OnPositionUpdate, data); - if (!player->timer_) { - player->error_listener_(player->GetPlayerId(), - "Failed to add postion update timer."); + timer_ = ecore_timer_add(kTimeInterval, OnPositionUpdate, this); + if (!timer_) { + error_listener_(player_id_, "Failed to add postion update timer."); } } } diff --git a/packages/audioplayers/tizen/src/audio_player.h b/packages/audioplayers/tizen/src/audio_player.h index 4536ccc63..76d04b2c7 100644 --- a/packages/audioplayers/tizen/src/audio_player.h +++ b/packages/audioplayers/tizen/src/audio_player.h @@ -53,7 +53,7 @@ class AudioPlayer { // The player state should be idle before calling this function. void PreparePlayer(); void ResetPlayer(); - void EmitPositionUpdates(); + void StartPositionUpdates(); player_state_e GetPlayerState(); static void OnPrepared(void *data); @@ -61,7 +61,6 @@ class AudioPlayer { static void OnPlayCompleted(void *data); static void OnInterrupted(player_interrupted_code_e code, void *data); static void OnError(int code, void *data); - static void StartPositionUpdates(void *data); static Eina_Bool OnPositionUpdate(void *data); player_h player_ = nullptr; From 1394aaf653e985a170ab044a21aeef6cc1023bcc Mon Sep 17 00:00:00 2001 From: Hakkyu Kim Date: Tue, 3 May 2022 09:22:34 +0900 Subject: [PATCH 10/16] Assing seeking to true before calling seek API --- packages/audioplayers/tizen/src/audio_player.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/audioplayers/tizen/src/audio_player.cc b/packages/audioplayers/tizen/src/audio_player.cc index e631c3562..2d628e07a 100644 --- a/packages/audioplayers/tizen/src/audio_player.cc +++ b/packages/audioplayers/tizen/src/audio_player.cc @@ -117,13 +117,14 @@ void AudioPlayer::Seek(int position) { player_state_e state = GetPlayerState(); if (state == PLAYER_STATE_READY || state == PLAYER_STATE_PLAYING || state == PLAYER_STATE_PAUSED) { + seeking_ = true; int ret = player_set_play_position(player_, position, true, OnSeekCompleted, this); if (ret != PLAYER_ERROR_NONE) { + seeking_ = false; throw AudioPlayerError("player_set_play_position failed", get_error_message(ret)); } - seeking_ = true; } else { // Player is unprepared, do seek in prepared callback. should_seek_to_ = position; @@ -341,13 +342,14 @@ void AudioPlayer::OnPrepared(void *data) { } if (player->should_seek_to_ > 0) { + player->seeking_ = true; int ret = player_set_play_position(player->player_, player->should_seek_to_, true, OnSeekCompleted, data); if (ret != PLAYER_ERROR_NONE) { + player->seeking_ = false; throw AudioPlayerError("player_set_play_position failed", get_error_message(ret)); } - player->seeking_ = true; player->should_seek_to_ = -1; } } From c69d799a7d1c1226bcbb1a03935f68519f56a64d Mon Sep 17 00:00:00 2001 From: Hakkyu Kim Date: Wed, 4 May 2022 11:57:25 +0900 Subject: [PATCH 11/16] Introduce TizenResult - Use ouput parameters for methods that return values. - Use exceptions only in HandleMethodCall. --- .../audioplayers/tizen/src/audio_player.cc | 303 ++++++++++++------ .../audioplayers/tizen/src/audio_player.h | 34 +- .../tizen/src/audio_player_error.h | 30 -- .../tizen/src/audioplayers_tizen_plugin.cc | 82 +++-- .../audioplayers/tizen/src/tizen_result.h | 29 ++ 5 files changed, 302 insertions(+), 176 deletions(-) delete mode 100644 packages/audioplayers/tizen/src/audio_player_error.h create mode 100644 packages/audioplayers/tizen/src/tizen_result.h diff --git a/packages/audioplayers/tizen/src/audio_player.cc b/packages/audioplayers/tizen/src/audio_player.cc index 2d628e07a..554b31551 100644 --- a/packages/audioplayers/tizen/src/audio_player.cc +++ b/packages/audioplayers/tizen/src/audio_player.cc @@ -1,7 +1,5 @@ #include "audio_player.h" -#include "audio_player_error.h" - AudioPlayer::AudioPlayer(const std::string &player_id, bool low_latency, PreparedListener prepared_listener, UpdatePositionListener update_position_listener, @@ -18,44 +16,50 @@ AudioPlayer::AudioPlayer(const std::string &player_id, bool low_latency, AudioPlayer::~AudioPlayer() { Release(); } -void AudioPlayer::Play() { - player_state_e state = GetPlayerState(); +TizenResult AudioPlayer::Play() { + player_state_e state; + auto result = GetPlayerState(state); + if (!result) { + return result; + } if (state == PLAYER_STATE_IDLE && preparing_) { // Player is preparing, play will be called in prepared callback. should_play_ = true; - return; - } - - if (state == PLAYER_STATE_NONE) { - CreatePlayer(); + return TizenResult(); } switch (state) { - case PLAYER_STATE_NONE: + case PLAYER_STATE_NONE: { + auto result = CreatePlayer(); + if (!result) { + return result; + } + } case PLAYER_STATE_IDLE: { if (audio_data_.size() > 0) { int ret = player_set_memory_buffer(player_, audio_data_.data(), audio_data_.size()); if (ret != PLAYER_ERROR_NONE) { - throw AudioPlayerError("player_set_memory_buffer failed", - get_error_message(ret)); + return TizenResult(ret, "player_set_memory_buffer failed"); } } else { int ret = player_set_uri(player_, url_.c_str()); if (ret != PLAYER_ERROR_NONE) { - throw AudioPlayerError("player_set_uri failed", - get_error_message(ret)); + return TizenResult(ret, "player_set_uri failed"); } } should_play_ = true; - PreparePlayer(); + auto result = PreparePlayer(); + if (!result) { + return result; + } break; } case PLAYER_STATE_READY: case PLAYER_STATE_PAUSED: { int ret = player_start(player_); if (ret != PLAYER_ERROR_NONE) { - throw AudioPlayerError("player_start failed", get_error_message(ret)); + return TizenResult(ret, "player_start failed"); } should_play_ = false; StartPositionUpdates(); @@ -65,25 +69,39 @@ void AudioPlayer::Play() { // Player is already playing audio. break; } + + return TizenResult(); } -void AudioPlayer::Pause() { - if (GetPlayerState() == PLAYER_STATE_PLAYING) { +TizenResult AudioPlayer::Pause() { + player_state_e state; + auto result = GetPlayerState(state); + if (!result) { + return result; + } + + if (state == PLAYER_STATE_PLAYING) { int ret = player_pause(player_); if (ret != PLAYER_ERROR_NONE) { - throw AudioPlayerError("player_pause failed", get_error_message(ret)); + return TizenResult(ret, "player_pause failed"); } } should_play_ = false; + + return TizenResult(); } -void AudioPlayer::Stop() { - player_state_e state = GetPlayerState(); +TizenResult AudioPlayer::Stop() { + player_state_e state; + auto result = GetPlayerState(state); + if (!result) { + return result; + } if (state == PLAYER_STATE_PLAYING || state == PLAYER_STATE_PAUSED) { int ret = player_stop(player_); if (ret != PLAYER_ERROR_NONE) { - throw AudioPlayerError("player_stop failed", get_error_message(ret)); + return TizenResult(ret, "player_stop failed"); } } @@ -93,6 +111,8 @@ void AudioPlayer::Stop() { if (release_mode_ == ReleaseMode::kRelease) { Release(); } + + return TizenResult(); } void AudioPlayer::Release() { @@ -109,12 +129,16 @@ void AudioPlayer::Release() { } } -void AudioPlayer::Seek(int position) { +TizenResult AudioPlayer::Seek(int position) { if (seeking_) { - return; + return TizenResult(); } - player_state_e state = GetPlayerState(); + player_state_e state; + auto result = GetPlayerState(state); + if (!result) { + return result; + } if (state == PLAYER_STATE_READY || state == PLAYER_STATE_PLAYING || state == PLAYER_STATE_PAUSED) { seeking_ = true; @@ -122,182 +146,223 @@ void AudioPlayer::Seek(int position) { this); if (ret != PLAYER_ERROR_NONE) { seeking_ = false; - throw AudioPlayerError("player_set_play_position failed", - get_error_message(ret)); + return TizenResult(ret, "player_set_play_position failed"); } } else { // Player is unprepared, do seek in prepared callback. should_seek_to_ = position; } + return TizenResult(); } -void AudioPlayer::SetUrl(const std::string &url) { +TizenResult AudioPlayer::SetUrl(const std::string &url) { if (url != url_) { url_ = url; - ResetPlayer(); + + auto reset_result = ResetPlayer(); + if (!reset_result) { + return reset_result; + } int ret = player_set_uri(player_, url.c_str()); if (ret != PLAYER_ERROR_NONE) { - throw AudioPlayerError("player_set_uri failed", get_error_message(ret)); + return TizenResult(ret, "player_set_uri failed"); } - PreparePlayer(); + auto prepare_result = PreparePlayer(); + if (!prepare_result) { + return prepare_result; + } } + audio_data_.clear(); + + return TizenResult(); } -void AudioPlayer::SetDataSource(std::vector &data) { +TizenResult AudioPlayer::SetDataSource(std::vector &data) { if (data != audio_data_) { audio_data_.swap(data); - ResetPlayer(); + + auto reset_result = ResetPlayer(); + if (!reset_result) { + return reset_result; + } int ret = player_set_memory_buffer(player_, audio_data_.data(), audio_data_.size()); if (ret != PLAYER_ERROR_NONE) { - throw AudioPlayerError("player_set_memory_buffer failed", - get_error_message(ret)); + return TizenResult(ret, "player_set_memory_buffer failed"); } - PreparePlayer(); + auto prepare_result = PreparePlayer(); + if (!prepare_result) { + return prepare_result; + } } + + return TizenResult(); } -void AudioPlayer::SetVolume(double volume) { +TizenResult AudioPlayer::SetVolume(double volume) { if (volume_ != volume) { volume_ = volume; - if (GetPlayerState() != PLAYER_STATE_NONE) { + player_state_e state; + auto result = GetPlayerState(state); + if (!result) { + return result; + } + if (state != PLAYER_STATE_NONE) { int ret = player_set_volume(player_, volume_, volume_); if (ret != PLAYER_ERROR_NONE) { - throw AudioPlayerError("player_set_volume failed", - get_error_message(ret)); + return TizenResult(ret, "player_set_volume failed"); } } } + return TizenResult(); } -void AudioPlayer::SetPlaybackRate(double rate) { +TizenResult AudioPlayer::SetPlaybackRate(double rate) { if (playback_rate_ != rate) { playback_rate_ = rate; - player_state_e state = GetPlayerState(); + player_state_e state; + auto result = GetPlayerState(state); + if (!result) { + return result; + } if (state == PLAYER_STATE_READY || state == PLAYER_STATE_PLAYING || state == PLAYER_STATE_PAUSED) { int ret = player_set_playback_rate(player_, rate); if (ret != PLAYER_ERROR_NONE) { - throw AudioPlayerError("player_set_playback_rate failed", - get_error_message(ret)); + return TizenResult(ret, "player_set_playback_rate failed"); } } } + return TizenResult(); } -void AudioPlayer::SetReleaseMode(ReleaseMode mode) { +TizenResult AudioPlayer::SetReleaseMode(ReleaseMode mode) { if (release_mode_ != mode) { release_mode_ = mode; - if (GetPlayerState() != PLAYER_STATE_NONE) { + player_state_e state; + auto result = GetPlayerState(state); + if (!result) { + return result; + } + if (state != PLAYER_STATE_NONE) { int ret = player_set_looping(player_, (release_mode_ == ReleaseMode::kLoop)); if (ret != PLAYER_ERROR_NONE) { - throw AudioPlayerError("player_set_looping failed", - get_error_message(ret)); + return TizenResult(ret, "player_set_looping failed"); } } } + return TizenResult(); } -int AudioPlayer::GetDuration() { - int duration; - int ret = player_get_duration(player_, &duration); +TizenResult AudioPlayer::GetDuration(int &out) { + int ret = player_get_duration(player_, &out); if (ret != PLAYER_ERROR_NONE) { - throw AudioPlayerError("player_get_duration failed", - get_error_message(ret)); + return TizenResult(ret, "player_get_duration failed"); } - return duration; + return TizenResult(); } -int AudioPlayer::GetCurrentPosition() { - int position; - int ret = player_get_play_position(player_, &position); +TizenResult AudioPlayer::GetCurrentPosition(int &out) { + int ret = player_get_play_position(player_, &out); if (ret != PLAYER_ERROR_NONE) { - throw AudioPlayerError("player_get_play_position failed", - get_error_message(ret)); + return TizenResult(ret, "player_get_play_position failed"); } - return position; + return TizenResult(); } -bool AudioPlayer::IsPlaying() { - return (GetPlayerState() == PLAYER_STATE_PLAYING); +TizenResult AudioPlayer::IsPlaying(bool &out) { + player_state_e state; + auto result = GetPlayerState(state); + if (!result) { + return result; + } + out = (state == PLAYER_STATE_PLAYING); + return TizenResult(); } -void AudioPlayer::CreatePlayer() { +TizenResult AudioPlayer::CreatePlayer() { should_play_ = false; preparing_ = false; int ret = player_create(&player_); if (ret != PLAYER_ERROR_NONE) { - throw AudioPlayerError("player_create failed", get_error_message(ret)); + return TizenResult(ret, "player_create failed"); } if (low_latency_) { ret = player_set_audio_latency_mode(player_, AUDIO_LATENCY_MODE_LOW); if (ret != PLAYER_ERROR_NONE) { - throw AudioPlayerError("player_set_audio_latency_mode failed", - get_error_message(ret)); + return TizenResult(ret, "player_set_audio_latency_mode failed"); } } ret = player_set_completed_cb(player_, OnPlayCompleted, this); if (ret != PLAYER_ERROR_NONE) { - throw AudioPlayerError("player_set_completed_cb failed", - get_error_message(ret)); + return TizenResult(ret, "player_set_completed_cb failed"); } ret = player_set_interrupted_cb(player_, OnInterrupted, this); if (ret != PLAYER_ERROR_NONE) { - throw AudioPlayerError("player_set_interrupted_cb failed", - get_error_message(ret)); + return TizenResult(ret, "player_set_interrupted_cb failed"); } ret = player_set_error_cb(player_, OnError, this); if (ret != PLAYER_ERROR_NONE) { - throw AudioPlayerError("player_set_error_cb failed", - get_error_message(ret)); + return TizenResult(ret, "player_set_error_cb failed"); } + + return TizenResult(); } -void AudioPlayer::PreparePlayer() { +TizenResult AudioPlayer::PreparePlayer() { int ret = player_set_volume(player_, volume_, volume_); if (ret != PLAYER_ERROR_NONE) { - throw AudioPlayerError("player_set_volume failed", get_error_message(ret)); + return TizenResult(ret, "player_set_volume failed"); } ret = player_set_looping(player_, (release_mode_ == ReleaseMode::kLoop)); if (ret != PLAYER_ERROR_NONE) { - throw AudioPlayerError("player_set_looping failed", get_error_message(ret)); + return TizenResult(ret, "player_set_looping failed"); } ret = player_prepare_async(player_, OnPrepared, this); if (ret != PLAYER_ERROR_NONE) { - throw AudioPlayerError("player_prepare_async failed", - get_error_message(ret)); + return TizenResult(ret, "player_prepare_async failed"); } preparing_ = true; seeking_ = false; + + return TizenResult(); } -void AudioPlayer::ResetPlayer() { - player_state_e state = GetPlayerState(); +TizenResult AudioPlayer::ResetPlayer() { + player_state_e state; + auto result = GetPlayerState(state); + if (!result) { + return result; + } + switch (state) { - case PLAYER_STATE_NONE: - CreatePlayer(); + case PLAYER_STATE_NONE: { + auto result = CreatePlayer(); + if (!result) { + return result; + } break; + } case PLAYER_STATE_IDLE: if (preparing_) { // Cancel preparing if it's already preparing. int ret = player_unprepare(player_); if (ret != PLAYER_ERROR_NONE) { - throw AudioPlayerError("player_unprepare failed", - get_error_message(ret)); + return TizenResult(ret, "player_unprepare failed"); } preparing_ = false; } @@ -307,35 +372,46 @@ void AudioPlayer::ResetPlayer() { case PLAYER_STATE_PAUSED: int ret = player_unprepare(player_); if (ret != PLAYER_ERROR_NONE) { - throw AudioPlayerError("player_unprepare failed", - get_error_message(ret)); + return TizenResult(ret, "player_unprepare failed"); } break; } + + return TizenResult(); } -player_state_e AudioPlayer::GetPlayerState() { - player_state_e state = PLAYER_STATE_NONE; +TizenResult AudioPlayer::GetPlayerState(player_state_e &out) { + out = PLAYER_STATE_NONE; if (player_) { - int ret = player_get_state(player_, &state); + int ret = player_get_state(player_, &out); if (ret != PLAYER_ERROR_NONE) { - throw AudioPlayerError("player_get_state failed", get_error_message(ret)); + return TizenResult(ret, "player_get_state failed"); } } - return state; + return TizenResult(); } void AudioPlayer::OnPrepared(void *data) { auto *player = reinterpret_cast(data); player->preparing_ = false; - player->prepared_listener_(player->player_id_, player->GetDuration()); + int duration; + auto result = player->GetDuration(duration); + if (!result) { + player->error_listener_(player->GetPlayerId(), result.Message()); + return; + } + + player->prepared_listener_(player->player_id_, duration); player_set_playback_rate(player->player_, player->playback_rate_); if (player->should_play_) { int ret = player_start(player->player_); if (ret != PLAYER_ERROR_NONE) { - throw AudioPlayerError("player_start failed", get_error_message(ret)); + player->error_listener_( + player->GetPlayerId(), + TizenResult(ret, "player_start failed").Message()); + return; } player->StartPositionUpdates(); player->should_play_ = false; @@ -347,8 +423,10 @@ void AudioPlayer::OnPrepared(void *data) { true, OnSeekCompleted, data); if (ret != PLAYER_ERROR_NONE) { player->seeking_ = false; - throw AudioPlayerError("player_set_play_position failed", - get_error_message(ret)); + player->error_listener_( + player->GetPlayerId(), + TizenResult(ret, "player_set_play_position failed").Message()); + return; } player->should_seek_to_ = -1; } @@ -394,16 +472,31 @@ void AudioPlayer::StartPositionUpdates() { Eina_Bool AudioPlayer::OnPositionUpdate(void *data) { auto *player = reinterpret_cast(data); std::string player_id = player->GetPlayerId(); - try { - if (player->IsPlaying()) { - int duration = player->GetDuration(); - int position = player->GetCurrentPosition(); - player->update_position_listener_(player_id, duration, position); - return ECORE_CALLBACK_RENEW; - } - } catch (const AudioPlayerError &error) { - player->error_listener_(player_id, "Failed to update position."); + + bool is_playing; + auto playing_result = player->IsPlaying(is_playing); + if (!playing_result) { + player->error_listener_(player_id, playing_result.Message()); + player->timer_ = nullptr; + return ECORE_CALLBACK_CANCEL; + } + + int duration; + auto duration_result = player->GetDuration(duration); + if (!duration_result) { + player->error_listener_(player_id, duration_result.Message()); + player->timer_ = nullptr; + return ECORE_CALLBACK_CANCEL; + } + + int position; + auto position_result = player->GetCurrentPosition(position); + if (!position_result) { + player->error_listener_(player_id, position_result.Message()); + player->timer_ = nullptr; + return ECORE_CALLBACK_CANCEL; } - player->timer_ = nullptr; - return ECORE_CALLBACK_CANCEL; + + player->update_position_listener_(player_id, duration, position); + return ECORE_CALLBACK_RENEW; } diff --git a/packages/audioplayers/tizen/src/audio_player.h b/packages/audioplayers/tizen/src/audio_player.h index 76d04b2c7..7117a39a8 100644 --- a/packages/audioplayers/tizen/src/audio_player.h +++ b/packages/audioplayers/tizen/src/audio_player.h @@ -8,6 +8,8 @@ #include #include +#include "tizen_result.h" + enum class ReleaseMode { kRelease, kLoop, kStop }; using PreparedListener = @@ -29,32 +31,32 @@ class AudioPlayer { ErrorListener error_listener); ~AudioPlayer(); - void Play(); - void Pause(); - void Stop(); + TizenResult Play(); + TizenResult Pause(); + TizenResult Stop(); void Release(); - void Seek(int position); // milliseconds + TizenResult Seek(int position); // milliseconds // If you use HTTP or RTSP, URI must start with "http://" or "rtsp://". // The default protocol is "file://". - void SetUrl(const std::string &url); - void SetDataSource(std::vector &data); - void SetVolume(double volume); - void SetPlaybackRate(double rate); - void SetReleaseMode(ReleaseMode mode); - int GetDuration(); - int GetCurrentPosition(); + TizenResult SetUrl(const std::string &url); + TizenResult SetDataSource(std::vector &data); + TizenResult SetVolume(double volume); + TizenResult SetPlaybackRate(double rate); + TizenResult SetReleaseMode(ReleaseMode mode); + TizenResult GetDuration(int &out); + TizenResult GetCurrentPosition(int &out); std::string GetPlayerId() const { return player_id_; } - bool IsPlaying(); + TizenResult IsPlaying(bool &out); private: // The player state should be none before calling this function. - void CreatePlayer(); + TizenResult CreatePlayer(); // The player state should be idle before calling this function. - void PreparePlayer(); - void ResetPlayer(); + TizenResult PreparePlayer(); + TizenResult ResetPlayer(); void StartPositionUpdates(); - player_state_e GetPlayerState(); + TizenResult GetPlayerState(player_state_e &out); static void OnPrepared(void *data); static void OnSeekCompleted(void *data); diff --git a/packages/audioplayers/tizen/src/audio_player_error.h b/packages/audioplayers/tizen/src/audio_player_error.h deleted file mode 100644 index 16ab91bc3..000000000 --- a/packages/audioplayers/tizen/src/audio_player_error.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef FLUTTER_PLUGIN_AUDIO_PLAYER_ERROR_H_ -#define FLUTTER_PLUGIN_AUDIO_PLAYER_ERROR_H_ - -#include - -class AudioPlayerError { - public: - AudioPlayerError(const std::string &code, const std::string &message) - : code_(code), message_(message) {} - ~AudioPlayerError() = default; - - AudioPlayerError(const AudioPlayerError &other) { - this->code_ = other.code_; - this->message_ = other.message_; - } - AudioPlayerError &operator=(const AudioPlayerError &other) { - this->code_ = other.code_; - this->message_ = other.message_; - return *this; - } - - std::string GetCode() const { return code_; } - std::string GetMessage() const { return message_; } - - private: - std::string code_; - std::string message_; -}; - -#endif // FLUTTER_PLUGIN_AUDIO_PLAYER_ERROR_H_ diff --git a/packages/audioplayers/tizen/src/audioplayers_tizen_plugin.cc b/packages/audioplayers/tizen/src/audioplayers_tizen_plugin.cc index aabd12d6b..858a2874c 100644 --- a/packages/audioplayers/tizen/src/audioplayers_tizen_plugin.cc +++ b/packages/audioplayers/tizen/src/audioplayers_tizen_plugin.cc @@ -11,7 +11,7 @@ #include #include "audio_player.h" -#include "audio_player_error.h" +#include "tizen_result.h" namespace { @@ -30,18 +30,29 @@ bool GetValueFromEncodableMap(const flutter::EncodableMap *map, const char *key, return false; } +// Returns the value associated with key in arguments. Throws invalid_argument +// exception if key doesn't exist in arguments or if entry has invalid type or +// value. +// +// This function must always be called within a try-catch block. +// See `HandleMethodCall`. template T GetRequiredArg(const flutter::EncodableMap *arguments, const char *key) { T value; if (GetValueFromEncodableMap(arguments, key, value)) { return value; } - std::string message = - "No " + std::string(key) + " provided or is invalid type or value."; + std::string message = "No " + std::string(key) + + " provided or entry has invalid type or value."; throw std::invalid_argument(message); } -ReleaseMode StringToReleaseMode(std::string release_mode) { +// Returns the matching `ReleaseMode` enum from string. Throws invalid_argument +// exception the given string cannot be resolved to any `ReleaseMode`. +// +// This function must always be called within a try-catch block. +// See `HandleMethodCall`. +ReleaseMode StringToReleaseMode(const std::string &release_mode) { if (release_mode == "ReleaseMode.RELEASE") { return ReleaseMode::kRelease; } else if (release_mode == "ReleaseMode.LOOP") { @@ -52,6 +63,16 @@ ReleaseMode StringToReleaseMode(std::string release_mode) { throw std::invalid_argument("Invalid release mode."); } +// Throws result as exception if the given result has error. +// +// This function must always be called within a try-catch block. +// See `HandleMethodCall`. +void ThrowIfError(const TizenResult &result) { + if (!result) { + throw result; + } +} + class AudioplayersTizenPlugin : public flutter::Plugin { public: static void RegisterWithRegistrar(flutter::PluginRegistrar *registrar) { @@ -95,6 +116,10 @@ class AudioplayersTizenPlugin : public flutter::Plugin { AudioPlayer *player = GetAudioPlayer(player_id, mode); + // try-catch block to capture exceptions thrown by: + // - `ThrowIfError` + // - `GetRequiredArg` + // - `StringToReleaseMode` try { const auto &method_name = method_call.method_name(); if (method_name == "play") { @@ -102,14 +127,14 @@ class AudioplayersTizenPlugin : public flutter::Plugin { std::string url; int32_t position = 0; if (GetValueFromEncodableMap(arguments, "volume", volume)) { - player->SetVolume(volume); + ThrowIfError(player->SetVolume(volume)); } if (GetValueFromEncodableMap(arguments, "url", url)) { - player->SetUrl(url); + ThrowIfError(player->SetUrl(url)); } - player->Play(); + ThrowIfError(player->Play()); if (GetValueFromEncodableMap(arguments, "position", position)) { - player->Seek(position); + ThrowIfError(player->Seek(position)); } result->Success(flutter::EncodableValue(1)); } else if (method_name == "playBytes") { @@ -117,57 +142,64 @@ class AudioplayersTizenPlugin : public flutter::Plugin { std::vector bytes; int32_t position = 0; if (GetValueFromEncodableMap(arguments, "volume", volume)) { - player->SetVolume(volume); + ThrowIfError(player->SetVolume(volume)); } if (GetValueFromEncodableMap(arguments, "bytes", bytes)) { - player->SetDataSource(bytes); + ThrowIfError(player->SetDataSource(bytes)); } - player->Play(); + ThrowIfError(player->Play()); if (GetValueFromEncodableMap(arguments, "position", position)) { - player->Seek(position); + ThrowIfError(player->Seek(position)); } result->Success(flutter::EncodableValue(1)); } else if (method_name == "resume") { - player->Play(); + ThrowIfError(player->Play()); result->Success(flutter::EncodableValue(1)); } else if (method_name == "pause") { - player->Pause(); + ThrowIfError(player->Pause()); result->Success(flutter::EncodableValue(1)); } else if (method_name == "stop") { - player->Stop(); + ThrowIfError(player->Stop()); result->Success(flutter::EncodableValue(1)); } else if (method_name == "release") { player->Release(); result->Success(flutter::EncodableValue(1)); } else if (method_name == "seek") { - player->Seek(GetRequiredArg(arguments, "position")); + ThrowIfError( + player->Seek(GetRequiredArg(arguments, "position"))); result->Success(flutter::EncodableValue(1)); } else if (method_name == "setVolume") { - player->SetVolume(GetRequiredArg(arguments, "volume")); + ThrowIfError( + player->SetVolume(GetRequiredArg(arguments, "volume"))); result->Success(flutter::EncodableValue(1)); } else if (method_name == "setUrl") { - player->SetUrl(GetRequiredArg(arguments, "url")); + ThrowIfError( + player->SetUrl(GetRequiredArg(arguments, "url"))); result->Success(flutter::EncodableValue(1)); } else if (method_name == "setPlaybackRate") { - player->SetPlaybackRate( - GetRequiredArg(arguments, "playbackRate")); + ThrowIfError(player->SetPlaybackRate( + GetRequiredArg(arguments, "playbackRate"))); result->Success(flutter::EncodableValue(1)); } else if (method_name == "setReleaseMode") { std::string release_mode = GetRequiredArg(arguments, "releaseMode"); - player->SetReleaseMode(StringToReleaseMode(release_mode)); + ThrowIfError(player->SetReleaseMode(StringToReleaseMode(release_mode))); result->Success(flutter::EncodableValue(1)); } else if (method_name == "getDuration") { - result->Success(flutter::EncodableValue(player->GetDuration())); + int duration; + ThrowIfError(player->GetDuration(duration)); + result->Success(flutter::EncodableValue(duration)); } else if (method_name == "getCurrentPosition") { - result->Success(flutter::EncodableValue(player->GetCurrentPosition())); + int position; + ThrowIfError(player->GetCurrentPosition(position)); + result->Success(flutter::EncodableValue(position)); } else { result->NotImplemented(); } } catch (const std::invalid_argument &error) { result->Error(kInvalidArgument, error.what()); - } catch (const AudioPlayerError &error) { - result->Error(error.GetCode(), error.GetMessage()); + } catch (const TizenResult &error) { + result->Error(error.Message(), error.TizenMessage()); } } diff --git a/packages/audioplayers/tizen/src/tizen_result.h b/packages/audioplayers/tizen/src/tizen_result.h new file mode 100644 index 000000000..2108b336c --- /dev/null +++ b/packages/audioplayers/tizen/src/tizen_result.h @@ -0,0 +1,29 @@ +#ifndef FLUTTER_PLUGIN_TIZEN_RESULT_H_ +#define FLUTTER_PLUGIN_TIZEN_RESULT_H_ + +#include + +#include + +class TizenResult { + public: + // Creates a "successful" result. + TizenResult() : TizenResult(TIZEN_ERROR_NONE, "") {} + TizenResult(int code) : TizenResult(code, "") {} + TizenResult(int code, const std::string &message) + : error_code_(code), message_(message) {} + + // Returns false on error. + operator bool() const { return (error_code_ == TIZEN_ERROR_NONE); } + + std::string TizenMessage() const { return get_error_message(error_code_); } + std::string Message() const { + return message_.empty() ? get_error_message(error_code_) : message_; + } + + private: + int error_code_ = TIZEN_ERROR_NONE; + std::string message_; +}; + +#endif // FLUTTER_PLUGIN_TIZEN_RESULT_H_ From 491cebd0ba5793c7b71769268d779544cfd82596 Mon Sep 17 00:00:00 2001 From: Hakkyu Kim Date: Fri, 6 May 2022 10:56:08 +0900 Subject: [PATCH 12/16] Revert "Remove ecore_main_loop_thread_safe_call_async" This reverts commit 937be2074d224fdb76511aa1f51fa5a0087f946f. --- .../audioplayers/tizen/src/audio_player.cc | 20 ++++++++++++------- .../audioplayers/tizen/src/audio_player.h | 3 ++- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/packages/audioplayers/tizen/src/audio_player.cc b/packages/audioplayers/tizen/src/audio_player.cc index 554b31551..0bc3ef3a2 100644 --- a/packages/audioplayers/tizen/src/audio_player.cc +++ b/packages/audioplayers/tizen/src/audio_player.cc @@ -62,7 +62,7 @@ TizenResult AudioPlayer::Play() { return TizenResult(ret, "player_start failed"); } should_play_ = false; - StartPositionUpdates(); + EmitPositionUpdates(); break; } default: @@ -342,6 +342,10 @@ TizenResult AudioPlayer::PreparePlayer() { return TizenResult(); } +void AudioPlayer::EmitPositionUpdates() { + ecore_main_loop_thread_safe_call_async(StartPositionUpdates, this); +} + TizenResult AudioPlayer::ResetPlayer() { player_state_e state; auto result = GetPlayerState(state); @@ -413,7 +417,7 @@ void AudioPlayer::OnPrepared(void *data) { TizenResult(ret, "player_start failed").Message()); return; } - player->StartPositionUpdates(); + player->EmitPositionUpdates(); player->should_play_ = false; } @@ -457,14 +461,16 @@ void AudioPlayer::OnError(int code, void *data) { player->error_listener_(player->player_id_, "Player error: " + error); } -void AudioPlayer::StartPositionUpdates() { - if (!timer_) { +void AudioPlayer::StartPositionUpdates(void *data) { + auto *player = reinterpret_cast(data); + if (!player->timer_) { // The audioplayers app facing package expects position // update events to fire roughly every 200 milliseconds. const double kTimeInterval = 0.2; - timer_ = ecore_timer_add(kTimeInterval, OnPositionUpdate, this); - if (!timer_) { - error_listener_(player_id_, "Failed to add postion update timer."); + player->timer_ = ecore_timer_add(kTimeInterval, OnPositionUpdate, data); + if (!player->timer_) { + player->error_listener_(player->GetPlayerId(), + "Failed to add postion update timer."); } } } diff --git a/packages/audioplayers/tizen/src/audio_player.h b/packages/audioplayers/tizen/src/audio_player.h index 7117a39a8..252634f8d 100644 --- a/packages/audioplayers/tizen/src/audio_player.h +++ b/packages/audioplayers/tizen/src/audio_player.h @@ -55,7 +55,7 @@ class AudioPlayer { // The player state should be idle before calling this function. TizenResult PreparePlayer(); TizenResult ResetPlayer(); - void StartPositionUpdates(); + void EmitPositionUpdates(); TizenResult GetPlayerState(player_state_e &out); static void OnPrepared(void *data); @@ -63,6 +63,7 @@ class AudioPlayer { static void OnPlayCompleted(void *data); static void OnInterrupted(player_interrupted_code_e code, void *data); static void OnError(int code, void *data); + static void StartPositionUpdates(void *data); static Eina_Bool OnPositionUpdate(void *data); player_h player_ = nullptr; From d4cebb764cc8be3986638a4054dc8457bac96f50 Mon Sep 17 00:00:00 2001 From: Hakkyu Kim Date: Mon, 9 May 2022 14:07:20 +0900 Subject: [PATCH 13/16] Revert "Introduce TizenResult" This reverts commit c69d799a7d1c1226bcbb1a03935f68519f56a64d. --- .../audioplayers/tizen/src/audio_player.cc | 303 ++++++------------ .../audioplayers/tizen/src/audio_player.h | 34 +- .../tizen/src/audio_player_error.h | 30 ++ .../tizen/src/audioplayers_tizen_plugin.cc | 82 ++--- .../audioplayers/tizen/src/tizen_result.h | 29 -- 5 files changed, 176 insertions(+), 302 deletions(-) create mode 100644 packages/audioplayers/tizen/src/audio_player_error.h delete mode 100644 packages/audioplayers/tizen/src/tizen_result.h diff --git a/packages/audioplayers/tizen/src/audio_player.cc b/packages/audioplayers/tizen/src/audio_player.cc index 0bc3ef3a2..1c4c42086 100644 --- a/packages/audioplayers/tizen/src/audio_player.cc +++ b/packages/audioplayers/tizen/src/audio_player.cc @@ -1,5 +1,7 @@ #include "audio_player.h" +#include "audio_player_error.h" + AudioPlayer::AudioPlayer(const std::string &player_id, bool low_latency, PreparedListener prepared_listener, UpdatePositionListener update_position_listener, @@ -16,50 +18,44 @@ AudioPlayer::AudioPlayer(const std::string &player_id, bool low_latency, AudioPlayer::~AudioPlayer() { Release(); } -TizenResult AudioPlayer::Play() { - player_state_e state; - auto result = GetPlayerState(state); - if (!result) { - return result; - } +void AudioPlayer::Play() { + player_state_e state = GetPlayerState(); if (state == PLAYER_STATE_IDLE && preparing_) { // Player is preparing, play will be called in prepared callback. should_play_ = true; - return TizenResult(); + return; + } + + if (state == PLAYER_STATE_NONE) { + CreatePlayer(); } switch (state) { - case PLAYER_STATE_NONE: { - auto result = CreatePlayer(); - if (!result) { - return result; - } - } + case PLAYER_STATE_NONE: case PLAYER_STATE_IDLE: { if (audio_data_.size() > 0) { int ret = player_set_memory_buffer(player_, audio_data_.data(), audio_data_.size()); if (ret != PLAYER_ERROR_NONE) { - return TizenResult(ret, "player_set_memory_buffer failed"); + throw AudioPlayerError("player_set_memory_buffer failed", + get_error_message(ret)); } } else { int ret = player_set_uri(player_, url_.c_str()); if (ret != PLAYER_ERROR_NONE) { - return TizenResult(ret, "player_set_uri failed"); + throw AudioPlayerError("player_set_uri failed", + get_error_message(ret)); } } should_play_ = true; - auto result = PreparePlayer(); - if (!result) { - return result; - } + PreparePlayer(); break; } case PLAYER_STATE_READY: case PLAYER_STATE_PAUSED: { int ret = player_start(player_); if (ret != PLAYER_ERROR_NONE) { - return TizenResult(ret, "player_start failed"); + throw AudioPlayerError("player_start failed", get_error_message(ret)); } should_play_ = false; EmitPositionUpdates(); @@ -69,39 +65,25 @@ TizenResult AudioPlayer::Play() { // Player is already playing audio. break; } - - return TizenResult(); } -TizenResult AudioPlayer::Pause() { - player_state_e state; - auto result = GetPlayerState(state); - if (!result) { - return result; - } - - if (state == PLAYER_STATE_PLAYING) { +void AudioPlayer::Pause() { + if (GetPlayerState() == PLAYER_STATE_PLAYING) { int ret = player_pause(player_); if (ret != PLAYER_ERROR_NONE) { - return TizenResult(ret, "player_pause failed"); + throw AudioPlayerError("player_pause failed", get_error_message(ret)); } } should_play_ = false; - - return TizenResult(); } -TizenResult AudioPlayer::Stop() { - player_state_e state; - auto result = GetPlayerState(state); - if (!result) { - return result; - } +void AudioPlayer::Stop() { + player_state_e state = GetPlayerState(); if (state == PLAYER_STATE_PLAYING || state == PLAYER_STATE_PAUSED) { int ret = player_stop(player_); if (ret != PLAYER_ERROR_NONE) { - return TizenResult(ret, "player_stop failed"); + throw AudioPlayerError("player_stop failed", get_error_message(ret)); } } @@ -111,8 +93,6 @@ TizenResult AudioPlayer::Stop() { if (release_mode_ == ReleaseMode::kRelease) { Release(); } - - return TizenResult(); } void AudioPlayer::Release() { @@ -129,16 +109,12 @@ void AudioPlayer::Release() { } } -TizenResult AudioPlayer::Seek(int position) { +void AudioPlayer::Seek(int position) { if (seeking_) { - return TizenResult(); + return; } - player_state_e state; - auto result = GetPlayerState(state); - if (!result) { - return result; - } + player_state_e state = GetPlayerState(); if (state == PLAYER_STATE_READY || state == PLAYER_STATE_PLAYING || state == PLAYER_STATE_PAUSED) { seeking_ = true; @@ -146,227 +122,186 @@ TizenResult AudioPlayer::Seek(int position) { this); if (ret != PLAYER_ERROR_NONE) { seeking_ = false; - return TizenResult(ret, "player_set_play_position failed"); + throw AudioPlayerError("player_set_play_position failed", + get_error_message(ret)); } } else { // Player is unprepared, do seek in prepared callback. should_seek_to_ = position; } - return TizenResult(); } -TizenResult AudioPlayer::SetUrl(const std::string &url) { +void AudioPlayer::SetUrl(const std::string &url) { if (url != url_) { url_ = url; - - auto reset_result = ResetPlayer(); - if (!reset_result) { - return reset_result; - } + ResetPlayer(); int ret = player_set_uri(player_, url.c_str()); if (ret != PLAYER_ERROR_NONE) { - return TizenResult(ret, "player_set_uri failed"); + throw AudioPlayerError("player_set_uri failed", get_error_message(ret)); } - auto prepare_result = PreparePlayer(); - if (!prepare_result) { - return prepare_result; - } + PreparePlayer(); } - audio_data_.clear(); - - return TizenResult(); } -TizenResult AudioPlayer::SetDataSource(std::vector &data) { +void AudioPlayer::SetDataSource(std::vector &data) { if (data != audio_data_) { audio_data_.swap(data); - - auto reset_result = ResetPlayer(); - if (!reset_result) { - return reset_result; - } + ResetPlayer(); int ret = player_set_memory_buffer(player_, audio_data_.data(), audio_data_.size()); if (ret != PLAYER_ERROR_NONE) { - return TizenResult(ret, "player_set_memory_buffer failed"); + throw AudioPlayerError("player_set_memory_buffer failed", + get_error_message(ret)); } - auto prepare_result = PreparePlayer(); - if (!prepare_result) { - return prepare_result; - } + PreparePlayer(); } - - return TizenResult(); } -TizenResult AudioPlayer::SetVolume(double volume) { +void AudioPlayer::SetVolume(double volume) { if (volume_ != volume) { volume_ = volume; - player_state_e state; - auto result = GetPlayerState(state); - if (!result) { - return result; - } - if (state != PLAYER_STATE_NONE) { + if (GetPlayerState() != PLAYER_STATE_NONE) { int ret = player_set_volume(player_, volume_, volume_); if (ret != PLAYER_ERROR_NONE) { - return TizenResult(ret, "player_set_volume failed"); + throw AudioPlayerError("player_set_volume failed", + get_error_message(ret)); } } } - return TizenResult(); } -TizenResult AudioPlayer::SetPlaybackRate(double rate) { +void AudioPlayer::SetPlaybackRate(double rate) { if (playback_rate_ != rate) { playback_rate_ = rate; - player_state_e state; - auto result = GetPlayerState(state); - if (!result) { - return result; - } + player_state_e state = GetPlayerState(); if (state == PLAYER_STATE_READY || state == PLAYER_STATE_PLAYING || state == PLAYER_STATE_PAUSED) { int ret = player_set_playback_rate(player_, rate); if (ret != PLAYER_ERROR_NONE) { - return TizenResult(ret, "player_set_playback_rate failed"); + throw AudioPlayerError("player_set_playback_rate failed", + get_error_message(ret)); } } } - return TizenResult(); } -TizenResult AudioPlayer::SetReleaseMode(ReleaseMode mode) { +void AudioPlayer::SetReleaseMode(ReleaseMode mode) { if (release_mode_ != mode) { release_mode_ = mode; - player_state_e state; - auto result = GetPlayerState(state); - if (!result) { - return result; - } - if (state != PLAYER_STATE_NONE) { + if (GetPlayerState() != PLAYER_STATE_NONE) { int ret = player_set_looping(player_, (release_mode_ == ReleaseMode::kLoop)); if (ret != PLAYER_ERROR_NONE) { - return TizenResult(ret, "player_set_looping failed"); + throw AudioPlayerError("player_set_looping failed", + get_error_message(ret)); } } } - return TizenResult(); } -TizenResult AudioPlayer::GetDuration(int &out) { - int ret = player_get_duration(player_, &out); +int AudioPlayer::GetDuration() { + int duration; + int ret = player_get_duration(player_, &duration); if (ret != PLAYER_ERROR_NONE) { - return TizenResult(ret, "player_get_duration failed"); + throw AudioPlayerError("player_get_duration failed", + get_error_message(ret)); } - return TizenResult(); + return duration; } -TizenResult AudioPlayer::GetCurrentPosition(int &out) { - int ret = player_get_play_position(player_, &out); +int AudioPlayer::GetCurrentPosition() { + int position; + int ret = player_get_play_position(player_, &position); if (ret != PLAYER_ERROR_NONE) { - return TizenResult(ret, "player_get_play_position failed"); + throw AudioPlayerError("player_get_play_position failed", + get_error_message(ret)); } - return TizenResult(); + return position; } -TizenResult AudioPlayer::IsPlaying(bool &out) { - player_state_e state; - auto result = GetPlayerState(state); - if (!result) { - return result; - } - out = (state == PLAYER_STATE_PLAYING); - return TizenResult(); +bool AudioPlayer::IsPlaying() { + return (GetPlayerState() == PLAYER_STATE_PLAYING); } -TizenResult AudioPlayer::CreatePlayer() { +void AudioPlayer::CreatePlayer() { should_play_ = false; preparing_ = false; int ret = player_create(&player_); if (ret != PLAYER_ERROR_NONE) { - return TizenResult(ret, "player_create failed"); + throw AudioPlayerError("player_create failed", get_error_message(ret)); } if (low_latency_) { ret = player_set_audio_latency_mode(player_, AUDIO_LATENCY_MODE_LOW); if (ret != PLAYER_ERROR_NONE) { - return TizenResult(ret, "player_set_audio_latency_mode failed"); + throw AudioPlayerError("player_set_audio_latency_mode failed", + get_error_message(ret)); } } ret = player_set_completed_cb(player_, OnPlayCompleted, this); if (ret != PLAYER_ERROR_NONE) { - return TizenResult(ret, "player_set_completed_cb failed"); + throw AudioPlayerError("player_set_completed_cb failed", + get_error_message(ret)); } ret = player_set_interrupted_cb(player_, OnInterrupted, this); if (ret != PLAYER_ERROR_NONE) { - return TizenResult(ret, "player_set_interrupted_cb failed"); + throw AudioPlayerError("player_set_interrupted_cb failed", + get_error_message(ret)); } ret = player_set_error_cb(player_, OnError, this); if (ret != PLAYER_ERROR_NONE) { - return TizenResult(ret, "player_set_error_cb failed"); + throw AudioPlayerError("player_set_error_cb failed", + get_error_message(ret)); } - - return TizenResult(); } -TizenResult AudioPlayer::PreparePlayer() { +void AudioPlayer::PreparePlayer() { int ret = player_set_volume(player_, volume_, volume_); if (ret != PLAYER_ERROR_NONE) { - return TizenResult(ret, "player_set_volume failed"); + throw AudioPlayerError("player_set_volume failed", get_error_message(ret)); } ret = player_set_looping(player_, (release_mode_ == ReleaseMode::kLoop)); if (ret != PLAYER_ERROR_NONE) { - return TizenResult(ret, "player_set_looping failed"); + throw AudioPlayerError("player_set_looping failed", get_error_message(ret)); } ret = player_prepare_async(player_, OnPrepared, this); if (ret != PLAYER_ERROR_NONE) { - return TizenResult(ret, "player_prepare_async failed"); + throw AudioPlayerError("player_prepare_async failed", + get_error_message(ret)); } preparing_ = true; seeking_ = false; - - return TizenResult(); } void AudioPlayer::EmitPositionUpdates() { ecore_main_loop_thread_safe_call_async(StartPositionUpdates, this); } -TizenResult AudioPlayer::ResetPlayer() { - player_state_e state; - auto result = GetPlayerState(state); - if (!result) { - return result; - } - +void AudioPlayer::ResetPlayer() { + player_state_e state = GetPlayerState(); switch (state) { - case PLAYER_STATE_NONE: { - auto result = CreatePlayer(); - if (!result) { - return result; - } + case PLAYER_STATE_NONE: + CreatePlayer(); break; - } case PLAYER_STATE_IDLE: if (preparing_) { // Cancel preparing if it's already preparing. int ret = player_unprepare(player_); if (ret != PLAYER_ERROR_NONE) { - return TizenResult(ret, "player_unprepare failed"); + throw AudioPlayerError("player_unprepare failed", + get_error_message(ret)); } preparing_ = false; } @@ -376,46 +311,35 @@ TizenResult AudioPlayer::ResetPlayer() { case PLAYER_STATE_PAUSED: int ret = player_unprepare(player_); if (ret != PLAYER_ERROR_NONE) { - return TizenResult(ret, "player_unprepare failed"); + throw AudioPlayerError("player_unprepare failed", + get_error_message(ret)); } break; } - - return TizenResult(); } -TizenResult AudioPlayer::GetPlayerState(player_state_e &out) { - out = PLAYER_STATE_NONE; +player_state_e AudioPlayer::GetPlayerState() { + player_state_e state = PLAYER_STATE_NONE; if (player_) { - int ret = player_get_state(player_, &out); + int ret = player_get_state(player_, &state); if (ret != PLAYER_ERROR_NONE) { - return TizenResult(ret, "player_get_state failed"); + throw AudioPlayerError("player_get_state failed", get_error_message(ret)); } } - return TizenResult(); + return state; } void AudioPlayer::OnPrepared(void *data) { auto *player = reinterpret_cast(data); player->preparing_ = false; - int duration; - auto result = player->GetDuration(duration); - if (!result) { - player->error_listener_(player->GetPlayerId(), result.Message()); - return; - } - - player->prepared_listener_(player->player_id_, duration); + player->prepared_listener_(player->player_id_, player->GetDuration()); player_set_playback_rate(player->player_, player->playback_rate_); if (player->should_play_) { int ret = player_start(player->player_); if (ret != PLAYER_ERROR_NONE) { - player->error_listener_( - player->GetPlayerId(), - TizenResult(ret, "player_start failed").Message()); - return; + throw AudioPlayerError("player_start failed", get_error_message(ret)); } player->EmitPositionUpdates(); player->should_play_ = false; @@ -427,10 +351,8 @@ void AudioPlayer::OnPrepared(void *data) { true, OnSeekCompleted, data); if (ret != PLAYER_ERROR_NONE) { player->seeking_ = false; - player->error_listener_( - player->GetPlayerId(), - TizenResult(ret, "player_set_play_position failed").Message()); - return; + throw AudioPlayerError("player_set_play_position failed", + get_error_message(ret)); } player->should_seek_to_ = -1; } @@ -478,31 +400,16 @@ void AudioPlayer::StartPositionUpdates(void *data) { Eina_Bool AudioPlayer::OnPositionUpdate(void *data) { auto *player = reinterpret_cast(data); std::string player_id = player->GetPlayerId(); - - bool is_playing; - auto playing_result = player->IsPlaying(is_playing); - if (!playing_result) { - player->error_listener_(player_id, playing_result.Message()); - player->timer_ = nullptr; - return ECORE_CALLBACK_CANCEL; - } - - int duration; - auto duration_result = player->GetDuration(duration); - if (!duration_result) { - player->error_listener_(player_id, duration_result.Message()); - player->timer_ = nullptr; - return ECORE_CALLBACK_CANCEL; - } - - int position; - auto position_result = player->GetCurrentPosition(position); - if (!position_result) { - player->error_listener_(player_id, position_result.Message()); - player->timer_ = nullptr; - return ECORE_CALLBACK_CANCEL; + try { + if (player->IsPlaying()) { + int duration = player->GetDuration(); + int position = player->GetCurrentPosition(); + player->update_position_listener_(player_id, duration, position); + return ECORE_CALLBACK_RENEW; + } + } catch (const AudioPlayerError &error) { + player->error_listener_(player_id, "Failed to update position."); } - - player->update_position_listener_(player_id, duration, position); - return ECORE_CALLBACK_RENEW; + player->timer_ = nullptr; + return ECORE_CALLBACK_CANCEL; } diff --git a/packages/audioplayers/tizen/src/audio_player.h b/packages/audioplayers/tizen/src/audio_player.h index 252634f8d..4536ccc63 100644 --- a/packages/audioplayers/tizen/src/audio_player.h +++ b/packages/audioplayers/tizen/src/audio_player.h @@ -8,8 +8,6 @@ #include #include -#include "tizen_result.h" - enum class ReleaseMode { kRelease, kLoop, kStop }; using PreparedListener = @@ -31,32 +29,32 @@ class AudioPlayer { ErrorListener error_listener); ~AudioPlayer(); - TizenResult Play(); - TizenResult Pause(); - TizenResult Stop(); + void Play(); + void Pause(); + void Stop(); void Release(); - TizenResult Seek(int position); // milliseconds + void Seek(int position); // milliseconds // If you use HTTP or RTSP, URI must start with "http://" or "rtsp://". // The default protocol is "file://". - TizenResult SetUrl(const std::string &url); - TizenResult SetDataSource(std::vector &data); - TizenResult SetVolume(double volume); - TizenResult SetPlaybackRate(double rate); - TizenResult SetReleaseMode(ReleaseMode mode); - TizenResult GetDuration(int &out); - TizenResult GetCurrentPosition(int &out); + void SetUrl(const std::string &url); + void SetDataSource(std::vector &data); + void SetVolume(double volume); + void SetPlaybackRate(double rate); + void SetReleaseMode(ReleaseMode mode); + int GetDuration(); + int GetCurrentPosition(); std::string GetPlayerId() const { return player_id_; } - TizenResult IsPlaying(bool &out); + bool IsPlaying(); private: // The player state should be none before calling this function. - TizenResult CreatePlayer(); + void CreatePlayer(); // The player state should be idle before calling this function. - TizenResult PreparePlayer(); - TizenResult ResetPlayer(); + void PreparePlayer(); + void ResetPlayer(); void EmitPositionUpdates(); - TizenResult GetPlayerState(player_state_e &out); + player_state_e GetPlayerState(); static void OnPrepared(void *data); static void OnSeekCompleted(void *data); diff --git a/packages/audioplayers/tizen/src/audio_player_error.h b/packages/audioplayers/tizen/src/audio_player_error.h new file mode 100644 index 000000000..16ab91bc3 --- /dev/null +++ b/packages/audioplayers/tizen/src/audio_player_error.h @@ -0,0 +1,30 @@ +#ifndef FLUTTER_PLUGIN_AUDIO_PLAYER_ERROR_H_ +#define FLUTTER_PLUGIN_AUDIO_PLAYER_ERROR_H_ + +#include + +class AudioPlayerError { + public: + AudioPlayerError(const std::string &code, const std::string &message) + : code_(code), message_(message) {} + ~AudioPlayerError() = default; + + AudioPlayerError(const AudioPlayerError &other) { + this->code_ = other.code_; + this->message_ = other.message_; + } + AudioPlayerError &operator=(const AudioPlayerError &other) { + this->code_ = other.code_; + this->message_ = other.message_; + return *this; + } + + std::string GetCode() const { return code_; } + std::string GetMessage() const { return message_; } + + private: + std::string code_; + std::string message_; +}; + +#endif // FLUTTER_PLUGIN_AUDIO_PLAYER_ERROR_H_ diff --git a/packages/audioplayers/tizen/src/audioplayers_tizen_plugin.cc b/packages/audioplayers/tizen/src/audioplayers_tizen_plugin.cc index 858a2874c..aabd12d6b 100644 --- a/packages/audioplayers/tizen/src/audioplayers_tizen_plugin.cc +++ b/packages/audioplayers/tizen/src/audioplayers_tizen_plugin.cc @@ -11,7 +11,7 @@ #include #include "audio_player.h" -#include "tizen_result.h" +#include "audio_player_error.h" namespace { @@ -30,29 +30,18 @@ bool GetValueFromEncodableMap(const flutter::EncodableMap *map, const char *key, return false; } -// Returns the value associated with key in arguments. Throws invalid_argument -// exception if key doesn't exist in arguments or if entry has invalid type or -// value. -// -// This function must always be called within a try-catch block. -// See `HandleMethodCall`. template T GetRequiredArg(const flutter::EncodableMap *arguments, const char *key) { T value; if (GetValueFromEncodableMap(arguments, key, value)) { return value; } - std::string message = "No " + std::string(key) + - " provided or entry has invalid type or value."; + std::string message = + "No " + std::string(key) + " provided or is invalid type or value."; throw std::invalid_argument(message); } -// Returns the matching `ReleaseMode` enum from string. Throws invalid_argument -// exception the given string cannot be resolved to any `ReleaseMode`. -// -// This function must always be called within a try-catch block. -// See `HandleMethodCall`. -ReleaseMode StringToReleaseMode(const std::string &release_mode) { +ReleaseMode StringToReleaseMode(std::string release_mode) { if (release_mode == "ReleaseMode.RELEASE") { return ReleaseMode::kRelease; } else if (release_mode == "ReleaseMode.LOOP") { @@ -63,16 +52,6 @@ ReleaseMode StringToReleaseMode(const std::string &release_mode) { throw std::invalid_argument("Invalid release mode."); } -// Throws result as exception if the given result has error. -// -// This function must always be called within a try-catch block. -// See `HandleMethodCall`. -void ThrowIfError(const TizenResult &result) { - if (!result) { - throw result; - } -} - class AudioplayersTizenPlugin : public flutter::Plugin { public: static void RegisterWithRegistrar(flutter::PluginRegistrar *registrar) { @@ -116,10 +95,6 @@ class AudioplayersTizenPlugin : public flutter::Plugin { AudioPlayer *player = GetAudioPlayer(player_id, mode); - // try-catch block to capture exceptions thrown by: - // - `ThrowIfError` - // - `GetRequiredArg` - // - `StringToReleaseMode` try { const auto &method_name = method_call.method_name(); if (method_name == "play") { @@ -127,14 +102,14 @@ class AudioplayersTizenPlugin : public flutter::Plugin { std::string url; int32_t position = 0; if (GetValueFromEncodableMap(arguments, "volume", volume)) { - ThrowIfError(player->SetVolume(volume)); + player->SetVolume(volume); } if (GetValueFromEncodableMap(arguments, "url", url)) { - ThrowIfError(player->SetUrl(url)); + player->SetUrl(url); } - ThrowIfError(player->Play()); + player->Play(); if (GetValueFromEncodableMap(arguments, "position", position)) { - ThrowIfError(player->Seek(position)); + player->Seek(position); } result->Success(flutter::EncodableValue(1)); } else if (method_name == "playBytes") { @@ -142,64 +117,57 @@ class AudioplayersTizenPlugin : public flutter::Plugin { std::vector bytes; int32_t position = 0; if (GetValueFromEncodableMap(arguments, "volume", volume)) { - ThrowIfError(player->SetVolume(volume)); + player->SetVolume(volume); } if (GetValueFromEncodableMap(arguments, "bytes", bytes)) { - ThrowIfError(player->SetDataSource(bytes)); + player->SetDataSource(bytes); } - ThrowIfError(player->Play()); + player->Play(); if (GetValueFromEncodableMap(arguments, "position", position)) { - ThrowIfError(player->Seek(position)); + player->Seek(position); } result->Success(flutter::EncodableValue(1)); } else if (method_name == "resume") { - ThrowIfError(player->Play()); + player->Play(); result->Success(flutter::EncodableValue(1)); } else if (method_name == "pause") { - ThrowIfError(player->Pause()); + player->Pause(); result->Success(flutter::EncodableValue(1)); } else if (method_name == "stop") { - ThrowIfError(player->Stop()); + player->Stop(); result->Success(flutter::EncodableValue(1)); } else if (method_name == "release") { player->Release(); result->Success(flutter::EncodableValue(1)); } else if (method_name == "seek") { - ThrowIfError( - player->Seek(GetRequiredArg(arguments, "position"))); + player->Seek(GetRequiredArg(arguments, "position")); result->Success(flutter::EncodableValue(1)); } else if (method_name == "setVolume") { - ThrowIfError( - player->SetVolume(GetRequiredArg(arguments, "volume"))); + player->SetVolume(GetRequiredArg(arguments, "volume")); result->Success(flutter::EncodableValue(1)); } else if (method_name == "setUrl") { - ThrowIfError( - player->SetUrl(GetRequiredArg(arguments, "url"))); + player->SetUrl(GetRequiredArg(arguments, "url")); result->Success(flutter::EncodableValue(1)); } else if (method_name == "setPlaybackRate") { - ThrowIfError(player->SetPlaybackRate( - GetRequiredArg(arguments, "playbackRate"))); + player->SetPlaybackRate( + GetRequiredArg(arguments, "playbackRate")); result->Success(flutter::EncodableValue(1)); } else if (method_name == "setReleaseMode") { std::string release_mode = GetRequiredArg(arguments, "releaseMode"); - ThrowIfError(player->SetReleaseMode(StringToReleaseMode(release_mode))); + player->SetReleaseMode(StringToReleaseMode(release_mode)); result->Success(flutter::EncodableValue(1)); } else if (method_name == "getDuration") { - int duration; - ThrowIfError(player->GetDuration(duration)); - result->Success(flutter::EncodableValue(duration)); + result->Success(flutter::EncodableValue(player->GetDuration())); } else if (method_name == "getCurrentPosition") { - int position; - ThrowIfError(player->GetCurrentPosition(position)); - result->Success(flutter::EncodableValue(position)); + result->Success(flutter::EncodableValue(player->GetCurrentPosition())); } else { result->NotImplemented(); } } catch (const std::invalid_argument &error) { result->Error(kInvalidArgument, error.what()); - } catch (const TizenResult &error) { - result->Error(error.Message(), error.TizenMessage()); + } catch (const AudioPlayerError &error) { + result->Error(error.GetCode(), error.GetMessage()); } } diff --git a/packages/audioplayers/tizen/src/tizen_result.h b/packages/audioplayers/tizen/src/tizen_result.h deleted file mode 100644 index 2108b336c..000000000 --- a/packages/audioplayers/tizen/src/tizen_result.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef FLUTTER_PLUGIN_TIZEN_RESULT_H_ -#define FLUTTER_PLUGIN_TIZEN_RESULT_H_ - -#include - -#include - -class TizenResult { - public: - // Creates a "successful" result. - TizenResult() : TizenResult(TIZEN_ERROR_NONE, "") {} - TizenResult(int code) : TizenResult(code, "") {} - TizenResult(int code, const std::string &message) - : error_code_(code), message_(message) {} - - // Returns false on error. - operator bool() const { return (error_code_ == TIZEN_ERROR_NONE); } - - std::string TizenMessage() const { return get_error_message(error_code_); } - std::string Message() const { - return message_.empty() ? get_error_message(error_code_) : message_; - } - - private: - int error_code_ = TIZEN_ERROR_NONE; - std::string message_; -}; - -#endif // FLUTTER_PLUGIN_TIZEN_RESULT_H_ From b412746c8ef16e0c199cd2eab3e6802574ad4c22 Mon Sep 17 00:00:00 2001 From: Hakkyu Kim Date: Mon, 9 May 2022 14:32:55 +0900 Subject: [PATCH 14/16] Revert back to using exceptions --- .../audioplayers/tizen/src/audio_player.cc | 35 ++++++++++++------- .../tizen/src/audio_player_error.h | 4 +-- .../tizen/src/audioplayers_tizen_plugin.cc | 4 +-- 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/packages/audioplayers/tizen/src/audio_player.cc b/packages/audioplayers/tizen/src/audio_player.cc index 1c4c42086..aee64c9c2 100644 --- a/packages/audioplayers/tizen/src/audio_player.cc +++ b/packages/audioplayers/tizen/src/audio_player.cc @@ -333,13 +333,19 @@ void AudioPlayer::OnPrepared(void *data) { auto *player = reinterpret_cast(data); player->preparing_ = false; - player->prepared_listener_(player->player_id_, player->GetDuration()); + try { + player->prepared_listener_(player->player_id_, player->GetDuration()); + } catch (const AudioPlayerError &error) { + player->error_listener_(player->player_id_, error.code()); + return; + } player_set_playback_rate(player->player_, player->playback_rate_); if (player->should_play_) { int ret = player_start(player->player_); if (ret != PLAYER_ERROR_NONE) { - throw AudioPlayerError("player_start failed", get_error_message(ret)); + player->error_listener_(player->player_id_, "player_start failed."); + return; } player->EmitPositionUpdates(); player->should_play_ = false; @@ -351,8 +357,9 @@ void AudioPlayer::OnPrepared(void *data) { true, OnSeekCompleted, data); if (ret != PLAYER_ERROR_NONE) { player->seeking_ = false; - throw AudioPlayerError("player_set_play_position failed", - get_error_message(ret)); + player->error_listener_(player->player_id_, + "player_set_play_position failed."); + return; } player->should_seek_to_ = -1; } @@ -366,10 +373,14 @@ void AudioPlayer::OnSeekCompleted(void *data) { void AudioPlayer::OnPlayCompleted(void *data) { auto *player = reinterpret_cast(data); - if (player->release_mode_ != ReleaseMode::kLoop) { - player->Stop(); + try { + if (player->release_mode_ != ReleaseMode::kLoop) { + player->Stop(); + } + player->play_completed_listener_(player->player_id_); + } catch (const AudioPlayerError &error) { + player->error_listener_(player->player_id_, error.code()); } - player->play_completed_listener_(player->player_id_); } void AudioPlayer::OnInterrupted(player_interrupted_code_e code, void *data) { @@ -379,8 +390,7 @@ void AudioPlayer::OnInterrupted(player_interrupted_code_e code, void *data) { void AudioPlayer::OnError(int code, void *data) { auto *player = reinterpret_cast(data); - std::string error(get_error_message(code)); - player->error_listener_(player->player_id_, "Player error: " + error); + player->error_listener_(player->player_id_, get_error_message(code)); } void AudioPlayer::StartPositionUpdates(void *data) { @@ -391,7 +401,7 @@ void AudioPlayer::StartPositionUpdates(void *data) { const double kTimeInterval = 0.2; player->timer_ = ecore_timer_add(kTimeInterval, OnPositionUpdate, data); if (!player->timer_) { - player->error_listener_(player->GetPlayerId(), + player->error_listener_(player->player_id_, "Failed to add postion update timer."); } } @@ -399,16 +409,15 @@ void AudioPlayer::StartPositionUpdates(void *data) { Eina_Bool AudioPlayer::OnPositionUpdate(void *data) { auto *player = reinterpret_cast(data); - std::string player_id = player->GetPlayerId(); try { if (player->IsPlaying()) { int duration = player->GetDuration(); int position = player->GetCurrentPosition(); - player->update_position_listener_(player_id, duration, position); + player->update_position_listener_(player->player_id_, duration, position); return ECORE_CALLBACK_RENEW; } } catch (const AudioPlayerError &error) { - player->error_listener_(player_id, "Failed to update position."); + player->error_listener_(player->player_id_, "Failed to update position."); } player->timer_ = nullptr; return ECORE_CALLBACK_CANCEL; diff --git a/packages/audioplayers/tizen/src/audio_player_error.h b/packages/audioplayers/tizen/src/audio_player_error.h index 16ab91bc3..d8216cfbb 100644 --- a/packages/audioplayers/tizen/src/audio_player_error.h +++ b/packages/audioplayers/tizen/src/audio_player_error.h @@ -19,8 +19,8 @@ class AudioPlayerError { return *this; } - std::string GetCode() const { return code_; } - std::string GetMessage() const { return message_; } + std::string code() const { return code_; } + std::string message() const { return message_; } private: std::string code_; diff --git a/packages/audioplayers/tizen/src/audioplayers_tizen_plugin.cc b/packages/audioplayers/tizen/src/audioplayers_tizen_plugin.cc index aabd12d6b..6bcdd656a 100644 --- a/packages/audioplayers/tizen/src/audioplayers_tizen_plugin.cc +++ b/packages/audioplayers/tizen/src/audioplayers_tizen_plugin.cc @@ -37,7 +37,7 @@ T GetRequiredArg(const flutter::EncodableMap *arguments, const char *key) { return value; } std::string message = - "No " + std::string(key) + " provided or is invalid type or value."; + "No " + std::string(key) + " provided or has invalid type or value."; throw std::invalid_argument(message); } @@ -167,7 +167,7 @@ class AudioplayersTizenPlugin : public flutter::Plugin { } catch (const std::invalid_argument &error) { result->Error(kInvalidArgument, error.what()); } catch (const AudioPlayerError &error) { - result->Error(error.GetCode(), error.GetMessage()); + result->Error(error.code(), error.message()); } } From c8a34038b6d4b51479f33439193f1b862511ceab Mon Sep 17 00:00:00 2001 From: Hakkyu Kim Date: Mon, 9 May 2022 14:47:16 +0900 Subject: [PATCH 15/16] Apply review suggestions --- .../audioplayers/tizen/src/audio_player.cc | 10 ++-- .../audioplayers/tizen/src/audio_player.h | 13 ++--- .../tizen/src/audioplayers_tizen_plugin.cc | 48 +++++++++++-------- 3 files changed, 41 insertions(+), 30 deletions(-) diff --git a/packages/audioplayers/tizen/src/audio_player.cc b/packages/audioplayers/tizen/src/audio_player.cc index aee64c9c2..d20406a13 100644 --- a/packages/audioplayers/tizen/src/audio_player.cc +++ b/packages/audioplayers/tizen/src/audio_player.cc @@ -109,7 +109,7 @@ void AudioPlayer::Release() { } } -void AudioPlayer::Seek(int position) { +void AudioPlayer::Seek(int32_t position) { if (seeking_) { return; } @@ -205,7 +205,7 @@ void AudioPlayer::SetReleaseMode(ReleaseMode mode) { } int AudioPlayer::GetDuration() { - int duration; + int32_t duration; int ret = player_get_duration(player_, &duration); if (ret != PLAYER_ERROR_NONE) { throw AudioPlayerError("player_get_duration failed", @@ -215,7 +215,7 @@ int AudioPlayer::GetDuration() { } int AudioPlayer::GetCurrentPosition() { - int position; + int32_t position; int ret = player_get_play_position(player_, &position); if (ret != PLAYER_ERROR_NONE) { throw AudioPlayerError("player_get_play_position failed", @@ -411,8 +411,8 @@ Eina_Bool AudioPlayer::OnPositionUpdate(void *data) { auto *player = reinterpret_cast(data); try { if (player->IsPlaying()) { - int duration = player->GetDuration(); - int position = player->GetCurrentPosition(); + int32_t duration = player->GetDuration(); + int32_t position = player->GetCurrentPosition(); player->update_position_listener_(player->player_id_, duration, position); return ECORE_CALLBACK_RENEW; } diff --git a/packages/audioplayers/tizen/src/audio_player.h b/packages/audioplayers/tizen/src/audio_player.h index 4536ccc63..792090c6b 100644 --- a/packages/audioplayers/tizen/src/audio_player.h +++ b/packages/audioplayers/tizen/src/audio_player.h @@ -11,9 +11,10 @@ enum class ReleaseMode { kRelease, kLoop, kStop }; using PreparedListener = - std::function; -using UpdatePositionListener = std::function; + std::function; +using UpdatePositionListener = + std::function; using SeekCompletedListener = std::function; using PlayCompletedListener = std::function; using ErrorListener = std::functionSetVolume(volume); } + + std::string url; if (GetValueFromEncodableMap(arguments, "url", url)) { player->SetUrl(url); } + player->Play(); + + int32_t position = 0; if (GetValueFromEncodableMap(arguments, "position", position)) { player->Seek(position); } + result->Success(flutter::EncodableValue(1)); } else if (method_name == "playBytes") { double volume = 0.0; - std::vector bytes; - int32_t position = 0; if (GetValueFromEncodableMap(arguments, "volume", volume)) { player->SetVolume(volume); } + + std::vector bytes; if (GetValueFromEncodableMap(arguments, "bytes", bytes)) { player->SetDataSource(bytes); } + player->Play(); + + int32_t position = 0; if (GetValueFromEncodableMap(arguments, "position", position)) { player->Seek(position); } + result->Success(flutter::EncodableValue(1)); } else if (method_name == "resume") { player->Play(); @@ -178,15 +186,16 @@ class AudioplayersTizenPlugin : public flutter::Plugin { return iter->second.get(); } - PreparedListener prepared_listener = - [channel = channel_.get()](const std::string &player_id, int duration) { - flutter::EncodableMap wrapped = {{flutter::EncodableValue("playerId"), - flutter::EncodableValue(player_id)}, - {flutter::EncodableValue("value"), - flutter::EncodableValue(duration)}}; - auto arguments = std::make_unique(wrapped); - channel->InvokeMethod("audio.onDuration", std::move(arguments)); - }; + PreparedListener prepared_listener = [channel = channel_.get()]( + const std::string &player_id, + int32_t duration) { + flutter::EncodableMap wrapped = {{flutter::EncodableValue("playerId"), + flutter::EncodableValue(player_id)}, + {flutter::EncodableValue("value"), + flutter::EncodableValue(duration)}}; + auto arguments = std::make_unique(wrapped); + channel->InvokeMethod("audio.onDuration", std::move(arguments)); + }; SeekCompletedListener seek_completed_listener = [channel = channel_.get()](const std::string &player_id) { @@ -200,24 +209,25 @@ class AudioplayersTizenPlugin : public flutter::Plugin { UpdatePositionListener update_position_listener = [channel = channel_.get()](const std::string &player_id, - const int duration, const int position) { - flutter::EncodableMap durationWrapped = { + const int32_t duration, + const int32_t position) { + flutter::EncodableMap duration_wrapped = { {flutter::EncodableValue("playerId"), flutter::EncodableValue(player_id)}, {flutter::EncodableValue("value"), flutter::EncodableValue(duration)}}; channel->InvokeMethod( "audio.onDuration", - std::make_unique(durationWrapped)); + std::make_unique(duration_wrapped)); - flutter::EncodableMap positionWrapped = { + flutter::EncodableMap position_wrapped = { {flutter::EncodableValue("playerId"), flutter::EncodableValue(player_id)}, {flutter::EncodableValue("value"), flutter::EncodableValue(position)}}; channel->InvokeMethod( "audio.onCurrentPosition", - std::make_unique(positionWrapped)); + std::make_unique(position_wrapped)); }; PlayCompletedListener play_completed_listener = From f121745f8c8b9d4882218ef45e350ff10c538b7f Mon Sep 17 00:00:00 2001 From: Hakkyu Kim Date: Tue, 10 May 2022 13:33:11 +0900 Subject: [PATCH 16/16] Fix message --- packages/audioplayers/tizen/src/audio_player.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/audioplayers/tizen/src/audio_player.cc b/packages/audioplayers/tizen/src/audio_player.cc index d20406a13..45d34dbd4 100644 --- a/packages/audioplayers/tizen/src/audio_player.cc +++ b/packages/audioplayers/tizen/src/audio_player.cc @@ -402,7 +402,7 @@ void AudioPlayer::StartPositionUpdates(void *data) { player->timer_ = ecore_timer_add(kTimeInterval, OnPositionUpdate, data); if (!player->timer_) { player->error_listener_(player->player_id_, - "Failed to add postion update timer."); + "Failed to add a position update timer."); } } }