77#include " audio_player_error.h"
88#include " log.h"
99
10+ namespace {
11+
12+ struct IdleData {
13+ AudioPlayer *player;
14+ std::shared_ptr<bool > is_alive;
15+ };
16+
17+ } // namespace
18+
1019AudioPlayer::AudioPlayer (const std::string &player_id,
1120 PreparedListener prepared_listener,
1221 DurationListener duration_listener,
@@ -30,10 +39,11 @@ AudioPlayer::~AudioPlayer() {
3039 player_destroy (player_);
3140 player_ = nullptr ;
3241 }
33- if (timer_ ) {
34- ecore_timer_del (timer_ );
35- timer_ = nullptr ;
42+ if (timer_id_ != 0 ) {
43+ g_source_remove (timer_id_ );
44+ timer_id_ = 0 ;
3645 }
46+ *is_alive_ = false ;
3747}
3848
3949void AudioPlayer::Play () {
@@ -343,28 +353,34 @@ player_state_e AudioPlayer::GetPlayerState() {
343353}
344354
345355void AudioPlayer::OnPrepared (void *data) {
356+ auto *self = reinterpret_cast <AudioPlayer *>(data);
346357 // On TV devices, callbacks are not executed on the main loop. Therefore
347358 // we explicitly transfer the callback to the main loop to avoid any race
348359 // conditions and to allow creating timer objects in StartPositionUpdates.
349- ecore_main_loop_thread_safe_call_async (
350- [](void *data) {
351- auto *player = reinterpret_cast <AudioPlayer *>(data);
360+ g_idle_add_full (
361+ G_PRIORITY_DEFAULT_IDLE ,
362+ [](gpointer data) -> gboolean {
363+ auto *idle = static_cast <IdleData *>(data);
364+ if (!*idle->is_alive ) {
365+ return G_SOURCE_REMOVE ;
366+ }
367+ auto *player = idle->player ;
352368 player->preparing_ = false ;
353369
354370 try {
355371 player->duration_listener_ (player->player_id_ , player->GetDuration ());
356372 player->prepared_listener_ (player->player_id_ , true );
357373 } catch (const AudioPlayerError &error) {
358374 player->log_listener_ (player->player_id_ , error.code ());
359- return ;
375+ return G_SOURCE_REMOVE ;
360376 }
361377 player_set_playback_rate (player->player_ , player->playback_rate_ );
362378
363379 if (player->should_play_ ) {
364380 int ret = player_start (player->player_ );
365381 if (ret != PLAYER_ERROR_NONE ) {
366382 player->log_listener_ (player->player_id_ , " player_start failed." );
367- return ;
383+ return G_SOURCE_REMOVE ;
368384 }
369385 player->StartPositionUpdates ();
370386 player->should_play_ = false ;
@@ -374,48 +390,66 @@ void AudioPlayer::OnPrepared(void *data) {
374390 player->seeking_ = true ;
375391 int ret =
376392 player_set_play_position (player->player_ , player->should_seek_to_ ,
377- true , OnSeekCompleted, data );
393+ true , OnSeekCompleted, player );
378394 if (ret != PLAYER_ERROR_NONE ) {
379395 player->seeking_ = false ;
380396 player->log_listener_ (player->player_id_ ,
381397 " player_set_play_position failed." );
382- return ;
398+ return G_SOURCE_REMOVE ;
383399 }
384400 player->should_seek_to_ = -1 ;
385401 }
402+ return G_SOURCE_REMOVE ;
386403 },
387- data);
404+ new IdleData{self, self->is_alive_ },
405+ [](gpointer data) { delete static_cast <IdleData *>(data); });
388406}
389407
390408void AudioPlayer::OnSeekCompleted (void *data) {
409+ auto *self = reinterpret_cast <AudioPlayer *>(data);
391410 // On TV devices, callbacks are not executed on the main loop. Therefore
392411 // we explicitly transfer the callback to the main loop to avoid any race
393412 // conditions.
394- ecore_main_loop_thread_safe_call_async (
395- [](void *data) {
396- auto *player = reinterpret_cast <AudioPlayer *>(data);
413+ g_idle_add_full (
414+ G_PRIORITY_DEFAULT_IDLE ,
415+ [](gpointer data) -> gboolean {
416+ auto *idle = static_cast <IdleData *>(data);
417+ if (!*idle->is_alive ) {
418+ return G_SOURCE_REMOVE ;
419+ }
420+ auto *player = idle->player ;
397421 player->seek_completed_listener_ (player->player_id_ );
398422 player->seeking_ = false ;
423+ return G_SOURCE_REMOVE ;
399424 },
400- data);
425+ new IdleData{self, self->is_alive_ },
426+ [](gpointer data) { delete static_cast <IdleData *>(data); });
401427}
402428
403429void AudioPlayer::OnPlayCompleted (void *data) {
430+ auto *self = reinterpret_cast <AudioPlayer *>(data);
404431 // On TV devices, callbacks are not executed on the main loop. Therefore
405432 // we explicitly transfer the callback to the main loop to avoid any race
406433 // conditions.
407- ecore_main_loop_thread_safe_call_async (
408- [](void *data) {
409- auto *player = reinterpret_cast <AudioPlayer *>(data);
434+ g_idle_add_full (
435+ G_PRIORITY_DEFAULT_IDLE ,
436+ [](gpointer data) -> gboolean {
437+ auto *idle = static_cast <IdleData *>(data);
438+ if (!*idle->is_alive ) {
439+ return G_SOURCE_REMOVE ;
440+ }
441+ auto *player = idle->player ;
410442 try {
411443 player->Seek (0 );
412444 player->Stop ();
413445 player->play_completed_listener_ (player->player_id_ );
414446 } catch (const AudioPlayerError &error) {
415447 player->log_listener_ (player->player_id_ , error.code ());
416448 }
449+ return G_SOURCE_REMOVE ;
417450 },
418- data);
451+ new IdleData{self, self->is_alive_ },
452+ [](gpointer data) { delete static_cast <IdleData *>(data); });
419453}
420454
421455void AudioPlayer::OnInterrupted (player_interrupted_code_e code, void *data) {
@@ -433,27 +467,27 @@ void AudioPlayer::OnError(int code, void *data) {
433467}
434468
435469void AudioPlayer::StartPositionUpdates () {
436- if (!timer_ ) {
470+ if (timer_id_ == 0 ) {
437471 // The audioplayers app facing package expects position
438472 // update events to fire roughly every 200 milliseconds.
439- const double kTimeInterval = 0.2 ;
440- timer_ = ecore_timer_add (kTimeInterval , OnPositionUpdate, this );
441- if (!timer_ ) {
473+ const guint kTimeInterval = 200 ;
474+ timer_id_ = g_timeout_add (kTimeInterval , OnPositionUpdate, this );
475+ if (timer_id_ == 0 ) {
442476 log_listener_ (player_id_, " Failed to add a position update timer." );
443477 }
444478 }
445479}
446480
447- Eina_Bool AudioPlayer::OnPositionUpdate (void * data) {
481+ gboolean AudioPlayer::OnPositionUpdate (gpointer data) {
448482 auto *player = reinterpret_cast <AudioPlayer *>(data);
449483 try {
450484 if (player->IsPlaying ()) {
451485 player->duration_listener_ (player->player_id_ , player->GetDuration ());
452- return ECORE_CALLBACK_RENEW ;
486+ return G_SOURCE_CONTINUE ;
453487 }
454488 } catch (const AudioPlayerError &error) {
455489 player->log_listener_ (player->player_id_ , " Failed to update position." );
456490 }
457- player->timer_ = nullptr ;
458- return ECORE_CALLBACK_CANCEL ;
491+ player->timer_id_ = 0 ;
492+ return G_SOURCE_REMOVE ;
459493}
0 commit comments