<listOptionValue builtIn="false" value="Native_API"/>
</option>
<option id="gnu.cpp.compiler.option.dialect.std.1756711526" name="Language standard" superClass="gnu.cpp.compiler.option.dialect.std" useByScannerDiscovery="true" value="gnu.cpp.compiler.dialect.c++11" valueType="enumerated"/>
- <option id="gnu.cpp.compiler.option.preprocessor.def.1776859471" name="Defined symbols (-D)" superClass="gnu.cpp.compiler.option.preprocessor.def" useByScannerDiscovery="false" valueType="definedSymbols">
- <listOptionValue builtIn="false" value="MSG_PRIVATE_API"/>
- </option>
+ <option id="gnu.cpp.compiler.option.preprocessor.def.1776859471" name="Defined symbols (-D)" superClass="gnu.cpp.compiler.option.preprocessor.def" useByScannerDiscovery="false" valueType="definedSymbols"/>
<option id="gnu.cpp.compiler.option.other.other.1256197611" name="Other flags" superClass="gnu.cpp.compiler.option.other.other" value="-c -fmessage-length=0 -Wno-extern-c-compat" valueType="string"/>
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1529131313" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
</tool>
<listOptionValue builtIn="false" value="Native_API"/>
</option>
<option id="gnu.cpp.compiler.option.dialect.std.177145679" name="Language standard" superClass="gnu.cpp.compiler.option.dialect.std" value="gnu.cpp.compiler.dialect.c++11" valueType="enumerated"/>
- <option id="gnu.cpp.compiler.option.preprocessor.def.889877088" name="Defined symbols (-D)" superClass="gnu.cpp.compiler.option.preprocessor.def" valueType="definedSymbols">
- <listOptionValue builtIn="false" value="MSG_PRIVATE_API"/>
- </option>
+ <option id="gnu.cpp.compiler.option.preprocessor.def.889877088" name="Defined symbols (-D)" superClass="gnu.cpp.compiler.option.preprocessor.def" valueType="definedSymbols"/>
<option id="gnu.cpp.compiler.option.other.other.645149247" name="Other flags" superClass="gnu.cpp.compiler.option.other.other" value="-c -fmessage-length=0 -Wno-extern-c-compat" valueType="string"/>
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1209285457" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
</tool>
}
}
group {
- name: "conv/list/voice_item";
+ name: "conv/list/audio_item";
images {
image: "msg_received.#.png" COMP;
image: "msg_received_play.png" COMP;
color: 0 0 0 255;
}
description {
- state: "play" 0.0;
+ state: "pause" 0.0;
inherit: "default" 0.0;
image.normal: "msg_received_pause.png";
}
name: "play";
signal: "sound,play";
source: "";
- action: STATE_SET "play" 0.0;
+ action: STATE_SET "default" 0.0;
target: "icon";
}
program {
name: "pause";
signal: "sound,pause";
source: "";
- action: STATE_SET "default" 0.0;
+ action: STATE_SET "pause" 0.0;
target: "icon";
}
}
using namespace Msg;
const std::vector<std::string> fileNames = {"cat.png", "Calendar1.vcs", "Contact.vcf",
- "big.txt", "call.csv", "phone.jpg", "table.3gp", "Voice.m4a"};
+ "big.txt", "call.csv", "phone.jpg", "table.3gp",
+ "Voice.m4a", "1.mp3", "2.mp3"};
MsgConvMediaDummy::MsgConvMediaDummy(bool release)
: MsgStructDummy(release)
--- /dev/null
+/*
+ * Copyright 2016 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MediaPlayer_h_
+#define MediaPlayer_h_
+
+#include <player.h>
+#include <sound_manager.h>
+#include <string>
+#include <Evas.h>
+
+namespace Msg {
+ class IMediaPlayerListener;
+
+ class MediaPlayer {
+ public:
+ MediaPlayer();
+ ~MediaPlayer();
+ MediaPlayer(const MediaPlayer&) = delete;
+ MediaPlayer& operator=(const MediaPlayer&) = delete;
+
+ void setDisplay(Evas_Object *obj);
+ bool start();
+ void stop();
+ void pause();
+ bool isPlaying() const;
+ void setUri(const std::string &uri);
+ void setListener(IMediaPlayerListener *l);
+ int getDuration() const; // msec
+ static int getDuration(const std::string &uri);
+ void setPosition(int msec);
+ int getPosition() const; // msec
+ bool getFocus() const;
+
+ private:
+ void onCompleted();
+ void onSeek();
+
+ // Call from media internal thread:
+ void onSoundStreamFocusStateChanged(sound_stream_info_h stream_info,
+ sound_stream_focus_mask_e focus_mask,
+ sound_stream_focus_state_e focus_state,
+ sound_stream_focus_change_reason_e reason,
+ int sound_behavior,
+ const char *extra_info);
+ player_state_e getState() const;
+ static bool isCallReason(sound_stream_focus_change_reason_e reason);
+
+ private:
+ player_h m_Player;
+ IMediaPlayerListener *m_pListener;
+ sound_stream_info_h m_StreamInfo;
+ };
+
+ class IMediaPlayerListener {
+ public:
+ virtual ~IMediaPlayerListener() {}
+ virtual void onCompleted(MediaPlayer &player) {};
+ virtual void onSoundFocusChanged(MediaPlayer &player) {};
+ };
+}
+
+#endif // MediaPlayer_h_
--- /dev/null
+/*
+ * Copyright 2016 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MediaPlayerProvider_h_
+#define MediaPlayerProvider_h_
+
+#include "MediaPlayer.h"
+#include <memory>
+
+namespace Msg {
+ class IMediaPlayerProviderClient;
+ class MediaPlayerProvider;
+ typedef std::shared_ptr<MediaPlayerProvider> MediaPlayerProviderRef;
+
+ class MediaPlayerProvider {
+ public:
+ MediaPlayerProvider();
+ ~MediaPlayerProvider();
+ MediaPlayerProvider(const MediaPlayerProvider&) = delete;
+ MediaPlayerProvider& operator=(const MediaPlayerProvider&) = delete;
+
+ MediaPlayer &acquire(IMediaPlayerProviderClient *client);
+ void release(IMediaPlayerProviderClient *client);
+ IMediaPlayerProviderClient *getClient() const;
+
+ private:
+ IMediaPlayerProviderClient *m_pClient;
+ std::unique_ptr<MediaPlayer> m_Player;
+ };
+
+ class IMediaPlayerProviderClient {
+ public:
+ virtual ~IMediaPlayerProviderClient() {}
+ virtual void onAcquire(MediaPlayerProvider &provider) {};
+ virtual void onRelease(MediaPlayerProvider &provider) {};
+ };
+}
+
+#endif // MediaPlayerProvider_h_
--- /dev/null
+/*
+ * Copyright 2016 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "MediaPlayer.h"
+#include "Logger.h"
+#include "Callback.h"
+
+#include <Ecore.h>
+
+using namespace Msg;
+
+MediaPlayer::MediaPlayer()
+ : m_Player()
+ , m_pListener(nullptr)
+ , m_StreamInfo()
+{
+ sound_manager_create_stream_information(SOUND_STREAM_TYPE_MEDIA,
+ makeCbLast(&MediaPlayer::onSoundStreamFocusStateChanged), this, &m_StreamInfo);
+ if (m_StreamInfo) {
+ player_create(&m_Player);
+ if (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_sound_stream_info(m_Player, m_StreamInfo);
+ player_set_completed_cb(m_Player, makeCbLast(&MediaPlayer::onCompleted), this);
+ }
+ }
+}
+
+MediaPlayer::~MediaPlayer()
+{
+ m_pListener = nullptr;
+ stop();
+
+ if (m_StreamInfo)
+ sound_manager_destroy_stream_information(m_StreamInfo);
+
+ if (m_Player) {
+ player_unprepare(m_Player);
+ player_destroy(m_Player);
+ }
+}
+
+void MediaPlayer::setDisplay(Evas_Object *obj)
+{
+ player_set_display_mode(m_Player, PLAYER_DISPLAY_MODE_LETTER_BOX);
+ player_set_display(m_Player, PLAYER_DISPLAY_TYPE_EVAS, GET_DISPLAY(obj));
+ player_set_display_visible(m_Player, obj != nullptr);
+}
+
+player_state_e MediaPlayer::getState() const
+{
+ player_state_e state = PLAYER_STATE_NONE;
+ player_get_state(m_Player, &state);
+ return state;
+}
+
+bool MediaPlayer::isCallReason(sound_stream_focus_change_reason_e reason)
+{
+ return reason == SOUND_STREAM_FOCUS_CHANGED_BY_RINGTONE ||
+ reason == SOUND_STREAM_FOCUS_CHANGED_BY_VOIP ||
+ reason == SOUND_STREAM_FOCUS_CHANGED_BY_CALL;
+}
+
+bool MediaPlayer::getFocus() const
+{
+ sound_stream_focus_change_reason_e acquiredBy = SOUND_STREAM_FOCUS_CHANGED_BY_MEDIA;
+ int flags = 0;
+ char *extraInfo = nullptr;
+
+ if (sound_manager_get_current_playback_focus(&acquiredBy, &flags, &extraInfo) == SOUND_MANAGER_ERROR_NONE) {
+ free(extraInfo);
+ return !isCallReason(acquiredBy);
+ }
+
+ return true;
+}
+
+bool MediaPlayer::start()
+{
+ sound_manager_acquire_focus(m_StreamInfo, SOUND_STREAM_FOCUS_FOR_PLAYBACK, SOUND_BEHAVIOR_NONE, nullptr);
+ if (getState() == PLAYER_STATE_IDLE)
+ player_prepare(m_Player);
+
+ if (getState() != PLAYER_STATE_PLAYING) {
+ int err = player_start(m_Player);
+ }
+
+ return getState() == PLAYER_STATE_PLAYING;
+}
+
+void MediaPlayer::stop()
+{
+ sound_manager_release_focus(m_StreamInfo, SOUND_STREAM_FOCUS_FOR_PLAYBACK, SOUND_BEHAVIOR_NONE, nullptr);
+ player_state_e state = getState();
+ if (state == PLAYER_STATE_PLAYING || state == PLAYER_STATE_PAUSED)
+ player_stop(m_Player);
+}
+
+void MediaPlayer::pause()
+{
+ if (getState() == PLAYER_STATE_PLAYING)
+ player_pause(m_Player);
+}
+
+bool MediaPlayer::isPlaying() const
+{
+ return getState() == PLAYER_STATE_PLAYING;
+}
+
+void MediaPlayer::setUri(const std::string &uri)
+{
+ stop();
+ player_unprepare(m_Player);
+ player_set_uri(m_Player, uri.c_str());
+}
+
+void MediaPlayer::setListener(IMediaPlayerListener *l)
+{
+ m_pListener = l;
+}
+
+int MediaPlayer::getDuration() const
+{
+ int msec = 0;
+ player_get_duration(m_Player, &msec);
+ return msec;
+}
+
+void MediaPlayer::setPosition(int msec)
+{
+ if (getState() == PLAYER_STATE_IDLE)
+ player_prepare(m_Player);
+
+ player_state_e state = getState();
+ if (state == PLAYER_STATE_PLAYING || state == PLAYER_STATE_PAUSED || state == PLAYER_STATE_READY) {
+ int res = player_set_play_position(m_Player, msec, true, makeCbLast(&MediaPlayer::onSeek), this);
+ }
+}
+
+int MediaPlayer::getPosition() const
+{
+ int msec = 0;
+ player_state_e state = getState();
+ if (state == PLAYER_STATE_PLAYING || state == PLAYER_STATE_PAUSED || state == PLAYER_STATE_READY)
+ player_get_play_position(m_Player, &msec);
+
+ return msec;
+}
+
+int MediaPlayer::getDuration(const std::string &uri)
+{
+ int msec = 0;
+ if (!uri.empty()) {
+ player_h player = {};
+ player_create(&player);
+ if (player_set_uri(player, uri.c_str()) == PLAYER_ERROR_NONE) {
+ player_prepare(player);
+ player_get_duration(player, &msec);
+ player_unprepare(player);
+ }
+ player_destroy(player);
+ }
+ return msec;
+}
+
+void MediaPlayer::onCompleted()
+{
+ stop();
+ if (m_pListener)
+ m_pListener->onCompleted(*this);
+}
+
+void MediaPlayer::onSeek()
+{
+ MSG_LOG("");
+}
+
+void MediaPlayer::onSoundStreamFocusStateChanged(sound_stream_info_h stream_info,
+ sound_stream_focus_mask_e focus_mask,
+ sound_stream_focus_state_e focus_state,
+ sound_stream_focus_change_reason_e reason,
+ int sound_behavior,
+ const char *extra_info)
+{
+ MSG_LOG("Interrupted focus change reason = ", reason);
+ if (isCallReason(reason)) {
+ ecore_main_loop_thread_safe_call_async(
+ [](void *data)
+ {
+ auto *self = (MediaPlayer*)data;
+ if (self->m_pListener)
+ self->m_pListener->onSoundFocusChanged(*self);
+ },
+ this);
+ }
+}
--- /dev/null
+/*
+ * Copyright 2016 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "MediaPlayerProvider.h"
+
+using namespace Msg;
+
+MediaPlayerProvider::MediaPlayerProvider()
+ : m_pClient(nullptr)
+{
+}
+
+MediaPlayerProvider::~MediaPlayerProvider()
+{
+}
+
+MediaPlayer &MediaPlayerProvider::acquire(IMediaPlayerProviderClient *client)
+{
+ if (!m_Player)
+ m_Player.reset(new MediaPlayer);
+
+ if (m_pClient != client) {
+ release(m_pClient);
+
+ m_pClient = client;
+
+ if (m_pClient)
+ m_pClient->onAcquire(*this);
+ }
+
+ return *m_Player;
+}
+
+void MediaPlayerProvider::release(IMediaPlayerProviderClient *client)
+{
+ if (m_pClient == client && m_Player) {
+
+ IMediaPlayerProviderClient *client = m_pClient;
+ m_pClient = nullptr;
+
+ if (client)
+ client->onRelease(*this);
+
+ m_Player->stop();
+ m_Player->setListener(nullptr);
+ }
+}
+
+IMediaPlayerProviderClient *MediaPlayerProvider::getClient() const
+{
+ return m_pClient;
+}
{
MetadataExtractor extractor(uri);
int duration = 0;
- if (extractor.isValid())
- {
+ if (extractor.isValid()) {
duration = extractor.getInt(METADATA_DURATION);
MSG_LOG("Duration msec: ", duration);
}
--- /dev/null
+/*
+ * Copyright 2016 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BubbleAudioEntity_h_
+#define BubbleAudioEntity_h_
+
+#include "BubbleAudioViewItem.h"
+#include "BubbleEntity.h"
+#include "MediaPlayerProvider.h"
+
+#include <Ecore.h>
+
+namespace Msg {
+ class BubbleAudioEntity
+ : public BubbleEntity
+ , private IMediaPlayerProviderClient
+ , private IMediaPlayerListener {
+
+ public:
+ BubbleAudioEntity(MediaPlayerProviderRef mediaPlayerProvider,
+ std::string filePath,
+ std::string fileName,
+ Message::Direction direction);
+
+ virtual ~BubbleAudioEntity();
+
+ void clickHandler();
+ BubbleAudioViewItem *createView(Evas_Object *parent) override;
+
+ private:
+ // View:
+ void onViewDel(Evas *e, Evas_Object *obj, void *event_info);
+
+ // IMediaPlayerProviderClient:
+ void onAcquire(MediaPlayerProvider &provider) override;
+ void onRelease(MediaPlayerProvider &provider) override;
+
+ // IMediaPlayerListener:
+ void onCompleted(MediaPlayer &player) override;
+ void onSoundFocusChanged(MediaPlayer &player) override;
+
+ // Timer:
+ Eina_Bool onTick();
+
+ struct PlayInfo {
+ std::string uri;
+ int duration; // msec
+ int playPos; // msec
+ bool isPlaying;
+ };
+
+ void play();
+ void stop();
+ void stopHandler();
+ void stopTimer();
+ void startTimer();
+ void updateProgress();
+ void updatePlayState();
+
+ private:
+ MediaPlayerProviderRef m_MediaPlayerProvider;
+ BubbleAudioViewItem *m_pView;
+ Ecore_Timer *m_pTimer;
+ MediaPlayer *m_pPlayer;
+ PlayInfo m_PlayInfo;
+ std::string m_FileName;
+ std::string m_DurationStr;
+ };
+}
+
+#endif /* BubbleAudioEntity_h_ */
SubjectItem,
TextItem,
ImageItem,
- VoiceItem,
AudioItem,
VideoItem,
ContactItem,
};
public:
- BubbleEntity(Type type, Message::Direction direction, const std::string &filePath = "");
+ BubbleEntity(Type type, Message::Direction direction, std::string filePath = "");
virtual ~BubbleEntity();
Type getType() const;
long long m_FileSize;
};
- inline BubbleEntity::BubbleEntity(Type type, Message::Direction direction, const std::string &filePath)
+ inline BubbleEntity::BubbleEntity(Type type, Message::Direction direction, std::string filePath)
: m_Type(type)
, m_Direction(direction)
- , m_FilePath(filePath)
+ , m_FilePath(std::move(filePath))
, m_FileSize(!filePath.empty() ? FileUtils::getFileSize(filePath) : 0)
{
}
#include "MsgConversationItem.h"
#include "WorkingDir.h"
#include "BubbleEntity.h"
+#include "MediaPlayerProvider.h"
#include <string>
#include <list>
class BubbleCalEventEntity;
class BubbleContactEntity;
class BubbleNoContentEntity;
+ class MediaPlayer;
class BubbleEntityFactory {
public:
BubbleEntity *createTextEntityFromFile(std::string filePath, Message::Direction direction);
BubbleEntity *createSubjectEntity(const std::string subject, Message::Direction direction);
BubbleEntity *createVideoEntity(std::string filePath, std::string fileName, Message::Direction direction);
- BubbleEntity *createVoiceEntity(std::string filePath, std::string fileName, Message::Direction direction);
+ BubbleEntity *createAudioEntity(std::string filePath, std::string fileName, Message::Direction direction);
BubbleEntityFactory(BubbleEntityFactory&) = delete;
BubbleEntityFactory& operator=(const BubbleEntityFactory&) = delete;
private:
WorkingDirRef m_WorkingDir;
+ MediaPlayerProviderRef m_MediaPlayerProvider;
};
}
+++ /dev/null
-/*
- * Copyright 2016 Samsung Electronics Co., Ltd
- *
- * Licensed under the Flora License, Version 1.1 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://floralicense.org/license/
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef BubbleVoiceEntity_h_
-#define BubbleVoiceEntity_h_
-
-#include "BubbleEntity.h"
-#include "BubbleVoiceViewItem.h"
-
-namespace Msg {
- class BubbleVoiceEntity
- : public BubbleEntity {
- public:
- BubbleVoiceEntity(const std::string &filePath, const std::string fileName, Message::Direction direction);
- virtual ~BubbleVoiceEntity();
-
- BubbleVoiceViewItem *createView(Evas_Object *parent) override;
-
- private:
- std::string m_FileName;
- };
- inline BubbleVoiceEntity::BubbleVoiceEntity(const std::string &filePath, const std::string fileName, Message::Direction direction)
- : BubbleEntity(VoiceItem, direction, filePath)
- , m_FileName(std::move(fileName))
- {
- }
-
- inline BubbleVoiceEntity::~BubbleVoiceEntity()
- {
- }
-
- inline BubbleVoiceViewItem *BubbleVoiceEntity::createView(Evas_Object *parent)
- {
- auto *item = new BubbleVoiceViewItem(parent, *this);
- item->setMainText(m_FileName);
- return item;
- }
-}
-
-#endif /* BubbleVoiceEntity_h_ */
--- /dev/null
+/*
+ * Copyright 2016 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "BubbleAudioEntity.h"
+#include "MediaUtils.h"
+#include "Logger.h"
+
+#include <sstream>
+#include <iomanip>
+#include <math.h>
+
+using namespace Msg;
+
+namespace {
+ std::string makeDurationStr(int msec)
+ {
+ std::stringstream ss;
+ int sec = ceil(msec / 1000.0);
+ int h = sec / 60;
+ int m = sec % 60;
+ ss << std::setfill('0') << std::setw(2) << h << ':'
+ << std::setfill('0') << std::setw(2) << m;
+ return ss.str();
+ }
+}
+
+BubbleAudioEntity::BubbleAudioEntity(MediaPlayerProviderRef mediaPlayerProvider,
+ std::string filePath,
+ std::string fileName,
+ Message::Direction direction)
+ : BubbleEntity(AudioItem, direction, filePath)
+ , m_MediaPlayerProvider(mediaPlayerProvider)
+ , m_pView(nullptr)
+ , m_pTimer(nullptr)
+ , m_pPlayer(nullptr)
+ , m_PlayInfo {}
+ , m_FileName(std::move(fileName))
+ , m_DurationStr()
+{
+ m_PlayInfo.uri = std::move(filePath);
+ m_PlayInfo.duration = MediaUtils::getDuration(m_PlayInfo.uri);
+ m_PlayInfo.isPlaying = false;
+ m_PlayInfo.playPos = 0;
+
+ m_DurationStr = makeDurationStr(m_PlayInfo.duration);
+}
+
+BubbleAudioEntity::~BubbleAudioEntity()
+{
+ stop();
+}
+
+void BubbleAudioEntity::clickHandler()
+{
+ if (m_pPlayer && m_pPlayer->isPlaying())
+ stop();
+ else
+ play();
+}
+
+void BubbleAudioEntity::play()
+{
+ m_pPlayer = &m_MediaPlayerProvider->acquire(this);
+ m_pPlayer->setListener(this);
+ m_pPlayer->setUri(getFilePath());
+
+ if (m_pPlayer->start()) {
+ m_PlayInfo.isPlaying = true;
+ // Warning setPosition() works only after start();
+ if (m_PlayInfo.playPos > 0)
+ m_pPlayer->setPosition(m_PlayInfo.playPos);
+ startTimer();
+ updateProgress();
+ updatePlayState();
+ }
+}
+
+void BubbleAudioEntity::stop()
+{
+ m_MediaPlayerProvider->release(this);
+}
+
+void BubbleAudioEntity::stopHandler()
+{
+ m_PlayInfo.isPlaying = false;
+ m_PlayInfo.playPos = m_pPlayer ? m_pPlayer->getPosition() : 0;
+ stopTimer();
+ updatePlayState();
+ updateProgress();
+}
+
+BubbleAudioViewItem *BubbleAudioEntity::createView(Evas_Object *parent)
+{
+ m_pView = new BubbleAudioViewItem(parent, *this);
+ m_pView->addEventCb(EVAS_CALLBACK_DEL, makeCbFirst(&BubbleAudioEntity::onViewDel), this);
+ m_pView->setMainText(m_FileName);
+ m_pView->setTimeText(m_DurationStr);
+ updateProgress();
+ updatePlayState();
+ return m_pView;
+}
+
+void BubbleAudioEntity::startTimer()
+{
+ static const double timeInterval = 0.01;
+ if (!m_pTimer)
+ m_pTimer = ecore_timer_add(timeInterval, makeCbFirst(&BubbleAudioEntity::onTick), this);
+}
+
+void BubbleAudioEntity::stopTimer()
+{
+ if (m_pTimer) {
+ ecore_timer_del(m_pTimer);
+ m_pTimer = nullptr;
+ }
+}
+
+void BubbleAudioEntity::updateProgress()
+{
+ if (m_pView) {
+ double pos = m_PlayInfo.playPos;
+ double dur = m_PlayInfo.duration;
+ double relPos = dur > 0.0 ? pos / dur : 0.0;
+ m_pView->setProgress(relPos);
+ }
+}
+
+void BubbleAudioEntity::updatePlayState()
+{
+ if (m_pView) {
+ auto state = m_PlayInfo.isPlaying ? BubbleAudioViewItem::PauseState :
+ BubbleAudioViewItem::PlayState;
+ m_pView->setState(state);
+ }
+}
+
+Eina_Bool BubbleAudioEntity::onTick()
+{
+ m_PlayInfo.playPos = m_pPlayer ? m_pPlayer->getPosition() : 0;
+ updateProgress();
+ return true;
+}
+
+void BubbleAudioEntity::onViewDel(Evas *e, Evas_Object *obj, void *event_info)
+{
+ if (m_pView && obj == *m_pView)
+ m_pView = nullptr;
+}
+
+void BubbleAudioEntity::onAcquire(MediaPlayerProvider &provider)
+{
+ MSG_LOG(this);
+}
+
+void BubbleAudioEntity::onRelease(MediaPlayerProvider &provider)
+{
+ MSG_LOG(this);
+ stopHandler();
+ m_pPlayer = nullptr;
+}
+
+void BubbleAudioEntity::onCompleted(MediaPlayer &player)
+{
+ MSG_LOG(this);
+ stopHandler();
+}
+
+void BubbleAudioEntity::onSoundFocusChanged(MediaPlayer &player)
+{
+ MSG_LOG(this);
+ stopHandler();
+}
+
* limitations under the License.
*/
+#include <BubbleAudioEntity.h>
#include "BubbleEntityFactory.h"
#include "FileUtils.h"
#include "MediaType.h"
#include "BubbleCalEventEntity.h"
#include "BubbleContactEntity.h"
#include "BubbleNoContentEntity.h"
-#include "BubbleVoiceEntity.h"
#include "BubbleUnknownFileEntity.h"
#include "BubbleSubjectEntity.h"
BubbleEntityFactory::BubbleEntityFactory(WorkingDirRef &workingDir)
: m_WorkingDir(workingDir)
+ , m_MediaPlayerProvider(std::make_shared<MediaPlayerProvider>())
{
}
case MsgMedia::ImageType:
return new BubbleImageEntity(std::move(filePath), direction);
case MsgMedia::AudioType:
- return createVoiceEntity(std::move(filePath), std::move(fileName), direction);
+ return createAudioEntity(std::move(filePath), std::move(fileName), direction);
case MsgMedia::VideoType:
return createVideoEntity(std::move(filePath), std::move(fileName), direction);
default:
return new BubbleNoContentEntity(direction);
}
-BubbleEntity *BubbleEntityFactory::createVoiceEntity(std::string filePath, std::string fileName, Message::Direction direction)
+BubbleEntity *BubbleEntityFactory::createAudioEntity(std::string filePath, std::string fileName, Message::Direction direction)
{
if (MediaUtils::hasAudio(filePath))
- return new BubbleVoiceEntity(filePath, fileName, direction);
+ return new BubbleAudioEntity(m_MediaPlayerProvider, std::move(filePath), std::move(fileName), direction);
// File does not contain audio or broken:
- return new BubbleUnknownFileEntity(filePath, fileName, direction);
+ return new BubbleUnknownFileEntity(std::move(filePath), std::move(fileName), direction);
}
BubbleEntity *BubbleEntityFactory::createVideoEntity(std::string filePath, std::string fileName, Message::Direction direction)
return new BubbleVideoEntity(m_WorkingDir, std::move(filePath), direction);
// Try to create Audio entity.
- return createVoiceEntity(std::move(filePath), std::move(fileName), direction);
+ return createAudioEntity(std::move(filePath), std::move(fileName), direction);
}
BubbleEntity *BubbleEntityFactory::createTextEntityFromFile(std::string filePath, Message::Direction direction)
#include "ToastPopup.h"
#include "IconTextPopup.h"
#include "Callback.h"
+#include "BubbleAudioEntity.h"
#include <algorithm>
void ConvListItem::onAction(BubbleViewItem &item)
{
MSG_LOG("");
- // TODO: iml.
+ if (auto *audio = dynamic_cast<BubbleAudioEntity*>(&item.getEntity())) {
+ audio->clickHandler();
+ } else {
+ // TODO: impl.
+ }
}
--- /dev/null
+/*
+ * Copyright 2016 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BubbleAudioViewItem_h_
+#define BubbleAudioViewItem_h_
+
+#include "BubbleViewItem.h"
+
+namespace Msg {
+ class BubbleAudioViewItem
+ : public BubbleViewItem {
+
+ public:
+ enum State {
+ PlayState,
+ PauseState
+ };
+
+ public:
+ BubbleAudioViewItem(Evas_Object *parent, BubbleEntity &entity);
+ virtual ~BubbleAudioViewItem();
+
+ void setMainText(const std::string &text);
+ void setTimeText(const std::string &text);
+ void setProgress(double progress);
+ void setState(State state);
+
+ void calculate() override;
+
+ private:
+ Evas_Object *m_pItemLayout;
+ };
+}
+
+#endif /* BubbleAudioViewItem_h_ */
+++ /dev/null
-/*
- * Copyright 2016 Samsung Electronics Co., Ltd
- *
- * Licensed under the Flora License, Version 1.1 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://floralicense.org/license/
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef BubbleVoiceViewItem_h_
-#define BubbleVoiceViewItem_h_
-
-#include "BubbleViewItem.h"
-
-namespace Msg {
- class BubbleVoiceViewItem
- : public BubbleViewItem {
- public:
- BubbleVoiceViewItem(Evas_Object *parent, BubbleEntity &entity);
- virtual ~BubbleVoiceViewItem();
-
- void setMainText(const std::string &text);
- void setTimeText(const std::string &text);
- void setProgress(const double progress);
- void calculate() override;
-
- private:
- Evas_Object *m_pVoiceItemLayout;
- };
-}
-
-#endif /* BubbleVoiceViewItem_h_ */
--- /dev/null
+/*
+ * Copyright 2016 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "BubbleAudioViewItem.h"
+#include "Resource.h"
+#include "TextDecorator.h"
+#include "PathUtils.h"
+
+using namespace Msg;
+
+BubbleAudioViewItem::BubbleAudioViewItem(Evas_Object *parent, BubbleEntity &entity)
+ : BubbleViewItem(parent, entity)
+ , m_pItemLayout(nullptr)
+{
+ m_pItemLayout = addLayout(getEo(), CONV_LIST_BUBBLE_EDJ_PATH, "conv/list/audio_item");
+ setContent(m_pItemLayout);
+}
+
+BubbleAudioViewItem::~BubbleAudioViewItem()
+{
+}
+
+void BubbleAudioViewItem::setMainText(const std::string &text)
+{
+ elm_object_part_text_set(m_pItemLayout, "text.filename", text.c_str());
+}
+
+void BubbleAudioViewItem::setTimeText(const std::string &text)
+{
+ elm_object_part_text_set(m_pItemLayout, "text.time", text.c_str());
+}
+
+void BubbleAudioViewItem::setProgress(const double progress)
+{
+ edje_object_part_drag_value_set(elm_layout_edje_get(m_pItemLayout), "rect.progress", progress, 0.0);
+}
+
+void BubbleAudioViewItem::setState(State state)
+{
+ const char *sig = state == PlayState ? "sound,play" : "sound,pause";
+ emitSignal(m_pItemLayout, sig, "");
+}
+
+void BubbleAudioViewItem::calculate()
+{
+ evas_object_smart_calculate(m_pItemLayout);
+ BubbleViewItem::calculate();
+}
+++ /dev/null
-/*
- * Copyright 2016 Samsung Electronics Co., Ltd
- *
- * Licensed under the Flora License, Version 1.1 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://floralicense.org/license/
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "BubbleVoiceViewItem.h"
-#include "Resource.h"
-#include "TextDecorator.h"
-#include "PathUtils.h"
-
-using namespace Msg;
-
-BubbleVoiceViewItem::BubbleVoiceViewItem(Evas_Object *parent, BubbleEntity &entity)
- : BubbleViewItem(parent, entity)
- , m_pVoiceItemLayout(nullptr)
-{
- m_pVoiceItemLayout = addLayout(getEo(), CONV_LIST_BUBBLE_EDJ_PATH, "conv/list/voice_item");
- setContent(m_pVoiceItemLayout);
-}
-
-BubbleVoiceViewItem::~BubbleVoiceViewItem()
-{
-}
-
-void BubbleVoiceViewItem::setMainText(const std::string &text)
-{
- elm_object_part_text_set(m_pVoiceItemLayout, "text.filename", text.c_str());
-}
-
-void BubbleVoiceViewItem::setTimeText(const std::string &text)
-{
- elm_object_part_text_set(m_pVoiceItemLayout, "text.time", text.c_str());
-}
-
-void BubbleVoiceViewItem::setProgress(const double progress)
-{
- edje_object_part_drag_value_set(elm_layout_edje_get(m_pVoiceItemLayout), "rect.progress", progress, 0.0);
-}
-
-void BubbleVoiceViewItem::calculate()
-{
- evas_object_smart_calculate(m_pVoiceItemLayout);
- BubbleViewItem::calculate();
-}