From 70610c5fd2971566574d8172c1a0a3fd389b0dd0 Mon Sep 17 00:00:00 2001 From: Denis Dolzhenko Date: Fri, 29 Apr 2016 17:51:16 +0300 Subject: [PATCH] Added functionality to interrupt video/sound during call (not completed) Change-Id: Iff06bcb843714414243c7155ee2eee676e606808 Signed-off-by: Denis Dolzhenko --- src/Common/Utils/inc/CallbackAssist.h | 5 +++ src/Viewer/Controller/inc/SmilPage.h | 2 ++ src/Viewer/Controller/inc/SmilPlayer.h | 11 +++++- src/Viewer/Controller/src/SmilPage.cpp | 8 +++++ src/Viewer/Controller/src/SmilPlayer.cpp | 33 ++++++++++++++++++ src/Viewer/Utils/inc/MediaPlayer.h | 11 ++++++ src/Viewer/Utils/src/MediaPlayer.cpp | 59 +++++++++++++++++++++++++------- 7 files changed, 116 insertions(+), 13 deletions(-) diff --git a/src/Common/Utils/inc/CallbackAssist.h b/src/Common/Utils/inc/CallbackAssist.h index eb7270d..07d8100 100644 --- a/src/Common/Utils/inc/CallbackAssist.h +++ b/src/Common/Utils/inc/CallbackAssist.h @@ -51,4 +51,9 @@ static_cast(data)->method(obj, emission, source); \ } +#define ECORE_CALLBACK(ClassName, method) [](void *data) \ +{ \ + static_cast(data)->method(); \ +} + #endif /* CallBackAssist_h_ */ diff --git a/src/Viewer/Controller/inc/SmilPage.h b/src/Viewer/Controller/inc/SmilPage.h index 6e7bb26..6488ce2 100644 --- a/src/Viewer/Controller/inc/SmilPage.h +++ b/src/Viewer/Controller/inc/SmilPage.h @@ -37,6 +37,7 @@ namespace Msg int getDuration() const; bool hasMedia() const; bool hasVideo() const; + bool hasAudio() const; bool hasAnimation() const; void playAnimation(bool play); Evas_Object *getVideoSink() const; @@ -57,6 +58,7 @@ namespace Msg int m_Duration; std::string m_MediaPath; Evas_Object *m_pVideoSink; + bool m_HasAudio; SmilImageItemView *m_pImageItem; }; } diff --git a/src/Viewer/Controller/inc/SmilPlayer.h b/src/Viewer/Controller/inc/SmilPlayer.h index b59c594..1f9e36c 100644 --- a/src/Viewer/Controller/inc/SmilPlayer.h +++ b/src/Viewer/Controller/inc/SmilPlayer.h @@ -32,6 +32,7 @@ namespace Msg class SmilPlayer : public SmilPlayerView + , private IMediaPlayerListener { public: typedef std::vector PageList; @@ -62,6 +63,13 @@ namespace Msg unsigned getCurrentPageIndex() const; private: + // IMediaPlayerListener: + virtual void onMediaPlayerSoundFocusChanged(); + + // View: + virtual void onBeforeDelete(View &view); + + private: void playPage(); void startMedia(); void stopMedia(); @@ -72,7 +80,8 @@ namespace Msg void continueTimer(); Eina_Bool onTick(); void setState(State state); - virtual void onBeforeDelete(View &view); + void showUnableToPlayVideoNotif(); + void showUnableToPlayAudioNotif(); private: ISmilPlayerListener *m_pListener; diff --git a/src/Viewer/Controller/src/SmilPage.cpp b/src/Viewer/Controller/src/SmilPage.cpp index ff6ceca..425e5ab 100644 --- a/src/Viewer/Controller/src/SmilPage.cpp +++ b/src/Viewer/Controller/src/SmilPage.cpp @@ -36,6 +36,7 @@ SmilPage::SmilPage(Evas_Object *parent, const MsgPage &page) : SmilPageLayout(parent) , m_Duration(0) , m_pVideoSink(nullptr) + , m_HasAudio(false) , m_pImageItem(nullptr) { build(page); @@ -45,6 +46,7 @@ SmilPage::SmilPage(Evas_Object *parent, const MsgAttachmentList &list) : SmilPageLayout(parent) , m_Duration(0) , m_pVideoSink(nullptr) + , m_HasAudio(false) , m_pImageItem(nullptr) { build(list); @@ -70,6 +72,11 @@ bool SmilPage::hasVideo() const return m_pVideoSink != nullptr; } +bool SmilPage::hasAudio() const +{ + return m_HasAudio; +} + Evas_Object *SmilPage::getVideoSink() const { return m_pVideoSink; @@ -169,6 +176,7 @@ void SmilPage::buildText(const MsgMedia& media) void SmilPage::buildAudio(const MsgMedia& media) { m_MediaPath = media.getFilePath(); + m_HasAudio = true; if(m_Duration == 0) m_Duration = MediaUtils::getDurationSec(m_MediaPath); diff --git a/src/Viewer/Controller/src/SmilPlayer.cpp b/src/Viewer/Controller/src/SmilPlayer.cpp index ff9c0b6..f2295b3 100644 --- a/src/Viewer/Controller/src/SmilPlayer.cpp +++ b/src/Viewer/Controller/src/SmilPlayer.cpp @@ -18,6 +18,9 @@ #include "SmilPlayer.h" #include "Logger.h" #include "CallbackAssist.h" +#include "LangUtils.h" + +#include using namespace Msg; @@ -41,6 +44,8 @@ SmilPlayer::~SmilPlayer() void SmilPlayer::create(const MessageMms &mms) { + m_MediaPlayer.setListener(this); + // Pages: const MsgPageList &pages = mms.getPageList(); for(int i = 0; i < pages.getLength(); ++i) @@ -270,6 +275,18 @@ unsigned SmilPlayer::getCurrentPageIndex() const return m_CurrentPageIndex; } +void SmilPlayer::showUnableToPlayVideoNotif() +{ + // TODO: localization "Video" word + notification_status_message_post(msg("IDS_MSG_POP_UNABLE_TO_PLAY_DURING_CALL").cStr()); +} + +void SmilPlayer::showUnableToPlayAudioNotif() +{ + // TODO: localization "Audo" word + notification_status_message_post(msg("IDS_MSG_POP_UNABLE_TO_PLAY_DURING_CALL").cStr()); +} + void SmilPlayer::onBeforeDelete(View &view) { MSG_LOG(""); @@ -287,5 +304,21 @@ void SmilPlayer::onBeforeDelete(View &view) ecore_timer_del(m_pTimer); m_pTimer = nullptr; } +} +void SmilPlayer::onMediaPlayerSoundFocusChanged() +{ + MSG_LOG(""); + if(m_MediaPlayer.isPlaying()) + { + SmilPage *page = getCurrentPage(); + if(page) + { + m_MediaPlayer.pause(); + if(page->hasVideo()) + showUnableToPlayVideoNotif(); + else if(page->hasAudio()) + showUnableToPlayAudioNotif(); + } + } } diff --git a/src/Viewer/Utils/inc/MediaPlayer.h b/src/Viewer/Utils/inc/MediaPlayer.h index 9cbd9b4..24a670f 100644 --- a/src/Viewer/Utils/inc/MediaPlayer.h +++ b/src/Viewer/Utils/inc/MediaPlayer.h @@ -44,15 +44,25 @@ namespace Msg int getDuration() const; // msec void setPosition(int msec); static int getDuration(const std::string &uri); + bool isSoundFocusAcquired() const; private: static void on_completed_cb(void *user_data); static void on_seek_cb(void *user_data); + + // Call from UI thread: + void onSoundStreamFocusStateWatch(); + + // Cll from media internal thread: + static void on_sound_stream_focus_state_watch_cb(sound_stream_focus_mask_e focus_mask, + sound_stream_focus_state_e focus_state, sound_stream_focus_change_reason_e reason, + const char *extra_info, void *user_data); player_state_e getState() const; private: player_h m_Player; IMediaPlayerListener *m_pListener; + bool m_IsSoundFocusAcquired; }; class IMediaPlayerListener @@ -60,6 +70,7 @@ namespace Msg public: virtual ~IMediaPlayerListener() {} virtual void onMediaPlayerCompleted() {}; + virtual void onMediaPlayerSoundFocusChanged() {}; }; } diff --git a/src/Viewer/Utils/src/MediaPlayer.cpp b/src/Viewer/Utils/src/MediaPlayer.cpp index 4573f82..4231870 100644 --- a/src/Viewer/Utils/src/MediaPlayer.cpp +++ b/src/Viewer/Utils/src/MediaPlayer.cpp @@ -17,22 +17,30 @@ #include "MediaPlayer.h" #include "Logger.h" +#include "CallbackAssist.h" + +#include +#include using namespace Msg; MediaPlayer::MediaPlayer() : m_Player() , m_pListener(nullptr) + , m_IsSoundFocusAcquired(false) { player_create(&m_Player); player_set_sound_type(m_Player, SOUND_TYPE_MEDIA); player_set_volume(m_Player, 1.0, 1.0); player_set_looping(m_Player, false); player_set_completed_cb(m_Player, on_completed_cb, this); + + sound_manager_set_focus_state_watch_cb(SOUND_STREAM_FOCUS_FOR_PLAYBACK, on_sound_stream_focus_state_watch_cb, this); } MediaPlayer::~MediaPlayer() { + sound_manager_unset_focus_state_watch_cb(); m_pListener = nullptr; stop(); player_unprepare(m_Player); @@ -53,6 +61,11 @@ player_state_e MediaPlayer::getState() const return state; } +bool MediaPlayer::isSoundFocusAcquired() const +{ + return m_IsSoundFocusAcquired; +} + void MediaPlayer::start() { if(getState() == PLAYER_STATE_IDLE) @@ -104,18 +117,6 @@ void MediaPlayer::setPosition(int msec) player_set_play_position(m_Player, msec, true, on_seek_cb, this); } -void MediaPlayer::on_completed_cb(void *user_data) -{ - IMediaPlayerListener *l = static_cast(user_data)->m_pListener; - if(l) - l->onMediaPlayerCompleted(); -} - -void MediaPlayer::on_seek_cb(void *user_data) -{ - MSG_LOG(""); -} - int MediaPlayer::getDuration(const std::string &uri) { int msec = 0; @@ -133,3 +134,37 @@ int MediaPlayer::getDuration(const std::string &uri) } return msec; } + +void MediaPlayer::on_completed_cb(void *user_data) +{ + IMediaPlayerListener *l = static_cast(user_data)->m_pListener; + if(l) + l->onMediaPlayerCompleted(); +} + +void MediaPlayer::on_seek_cb(void *user_data) +{ + MSG_LOG(""); +} + +void MediaPlayer::onSoundStreamFocusStateWatch() +{ + MSG_LOG(""); + if(m_pListener) + m_pListener->onMediaPlayerSoundFocusChanged(); +} + +void MediaPlayer::on_sound_stream_focus_state_watch_cb(sound_stream_focus_mask_e focus_mask, + sound_stream_focus_state_e focus_state, sound_stream_focus_change_reason_e reason, + const char *extra_info, void *user_data) +{ + MSG_LOG("Interrupted focus state = ", focus_state); + MSG_LOG("Interrupted focus change reason = ", reason); + + if(reason == SOUND_STREAM_FOCUS_CHANGED_BY_CALL) + { + MediaPlayer *self = static_cast(user_data); + self->m_IsSoundFocusAcquired = focus_state == SOUND_STREAM_FOCUS_STATE_ACQUIRED; + ecore_main_loop_thread_safe_call_sync(ECORE_CALLBACK(MediaPlayer, onSoundStreamFocusStateWatch), self); + } +} -- 2.7.4