From: Mariusz Polasinski Date: Mon, 29 Dec 2014 17:32:48 +0000 (+0100) Subject: [TVAudio] Listener implementation X-Git-Tag: submit/tizen_tv/20150603.064601~1^2~675 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5f9213eabd315494db26da87ebf029c7a642da8f;p=platform%2Fcore%2Fapi%2Fwebapi-plugins.git [TVAudio] Listener implementation [Verification] Code complies without error Methods are tested in node Change-Id: Id07de5060a9b456a8ed8f4b4648b4656eaeaf0c3 Signed-off-by: Mariusz Polasinski --- diff --git a/src/tvaudio/tvaudio_api.js b/src/tvaudio/tvaudio_api.js index d3e3a30b..85887234 100644 --- a/src/tvaudio/tvaudio_api.js +++ b/src/tvaudio/tvaudio_api.js @@ -5,12 +5,18 @@ // found in the LICENSE file. - var native = new xwalk.utils.NativeManager(extension); var validator = xwalk.utils.validator; var types = validator.Types; +/** + * @type {string} + * @const + */ +var VOLUME_CHANGE_LISTENER = 'VolumeChangeCallback'; + + /** * This class provides access to the API functionalities through the tizen.tvaudiocontrol interface. @@ -126,7 +132,19 @@ AudioControlManager.prototype.getVolume = function() { * @param {!function} listener The method to invoke when the volume has been changed. */ AudioControlManager.prototype.setVolumeChangeListener = function(listener) { - return undefined; + var args = validator.validateArgs(arguments, [ + {name: 'listener', type: types.FUNCTION} + ]); + + native.removeListener(VOLUME_CHANGE_LISTENER); + + var ret = native.callSync('AudioControlManager_setVolumeChangeListener'); + + if (native.isFailure(ret)) { + throw native.getErrorObject(ret); + } + + native.addListener(VOLUME_CHANGE_LISTENER, args.listener); }; @@ -134,7 +152,13 @@ AudioControlManager.prototype.setVolumeChangeListener = function(listener) { * Unregisters the volume change callback for detecting the volume changes. */ AudioControlManager.prototype.unsetVolumeChangeListener = function() { - return undefined; + var ret = native.callSync('AudioControlManager_unsetVolumeChangeListener'); + + if (native.isFailure(ret)) { + throw native.getErrorObject(ret); + } + + native.removeListener(VOLUME_CHANGE_LISTENER); }; diff --git a/src/tvaudio/tvaudio_instance.cc b/src/tvaudio/tvaudio_instance.cc index 93bccab2..05e8af59 100644 --- a/src/tvaudio/tvaudio_instance.cc +++ b/src/tvaudio/tvaudio_instance.cc @@ -7,6 +7,8 @@ #include #include "common/picojson.h" +#include "common/logger.h" +#include "common/platform_exception.h" #include "tvaudio/tvaudio_instance.h" #include "tvaudio/tvaudio_manager.h" @@ -24,6 +26,7 @@ const std::map AudioOutputModeMap = { } // namespace TVAudioInstance::TVAudioInstance() { + LOGD("Enter"); using std::placeholders::_1; using std::placeholders::_2; #define REGISTER_SYNC(c, x) \ @@ -35,13 +38,18 @@ TVAudioInstance::TVAudioInstance() { REGISTER_SYNC("AudioControlManager_setVolumeDown", setVolumeDown); REGISTER_SYNC("AudioControlManager_getVolume", getVolume); REGISTER_SYNC("AudioControlManager_getOutputMode", getOutputMode); + REGISTER_SYNC("AudioControlManager_setVolumeChangeListener", setVolumeChangeListener); + REGISTER_SYNC("AudioControlManager_unsetVolumeChangeListener", unsetVolumeChangeListener); #undef REGISTER_SYNC } -TVAudioInstance::~TVAudioInstance() {} +TVAudioInstance::~TVAudioInstance() { + LOGD("Enter"); +} void TVAudioInstance::setMute(const picojson::value& args, picojson::object& out) { + LOGD("Enter"); bool mute = args.get("mute").get(); AudioControlManager::getInstance().setMute(mute); ReportSuccess(out); @@ -49,12 +57,14 @@ void TVAudioInstance::setMute(const picojson::value& args, void TVAudioInstance::isMute(const picojson::value& args, picojson::object& out) { + LOGD("Enter"); bool mute = AudioControlManager::getInstance().isMute(); ReportSuccess(picojson::value(mute), out); } void TVAudioInstance::setVolume(const picojson::value& args, picojson::object& out) { + LOGD("Enter"); double volume = args.get("volume").get(); AudioControlManager::getInstance().setVolume(volume); ReportSuccess(out); @@ -62,27 +72,58 @@ void TVAudioInstance::setVolume(const picojson::value& args, void TVAudioInstance::setVolumeUp(const picojson::value& args, picojson::object& out) { + LOGD("Enter"); AudioControlManager::getInstance().setVolumeUp(); ReportSuccess(out); } void TVAudioInstance::setVolumeDown(const picojson::value& args, picojson::object& out) { + LOGD("Enter"); AudioControlManager::getInstance().setVolumeDown(); ReportSuccess(out); } void TVAudioInstance::getVolume(const picojson::value& args, picojson::object& out) { + LOGD("Enter"); u_int16_t volume = AudioControlManager::getInstance().getVolume(); ReportSuccess(picojson::value(static_cast(volume)), out); } void TVAudioInstance::getOutputMode(const picojson::value& args, picojson::object& out) { + LOGD("Enter"); AudioOutputMode mode = AudioControlManager::getInstance().getOutputMode(); ReportSuccess(picojson::value(AudioOutputModeMap.at(mode)), out); } +void TVAudioInstance::setVolumeChangeListener(const picojson::value& args, + picojson::object& out) { + AudioControlManager::getInstance().registerVolumeChangeListener(this); + ReportSuccess(out); +} + +void TVAudioInstance::unsetVolumeChangeListener(const picojson::value& args, + picojson::object& out) { + AudioControlManager::getInstance().unregisterVolumeChangeListener(); + ReportSuccess(out); +} + +void TVAudioInstance::onVolumeChangeCallback(u_int16_t volume) { + LOGD("Enter"); + try { + picojson::value event = picojson::value(picojson::object()); + picojson::object& obj = event.get(); + obj["listenerId"] = picojson::value("VolumeChangeCallback"); + obj["volume"] = picojson::value(static_cast(volume)); + PostMessage(event.serialize().c_str()); + } catch (common::PlatformException& e) { + LOGW("Failed to post message: %s", e.message().c_str()); + } catch (...) { + LOGW("Failed to post message, unknown error"); + } +} + } // namespace tvaudio } // namespace extension diff --git a/src/tvaudio/tvaudio_instance.h b/src/tvaudio/tvaudio_instance.h index 47c6bb7e..f10b7eea 100644 --- a/src/tvaudio/tvaudio_instance.h +++ b/src/tvaudio/tvaudio_instance.h @@ -7,10 +7,14 @@ #include "common/extension.h" +#include "tvaudio/tvaudio_manager.h" + namespace extension { namespace tvaudio { -class TVAudioInstance : public common::ParsedInstance { +class TVAudioInstance : + public common::ParsedInstance, + public VolumeChangeListener { public: TVAudioInstance(); virtual ~TVAudioInstance(); @@ -23,6 +27,10 @@ class TVAudioInstance : public common::ParsedInstance { void setVolumeDown(const picojson::value& args, picojson::object& out); void getVolume(const picojson::value& args, picojson::object& out); void getOutputMode(const picojson::value& args, picojson::object& out); + void setVolumeChangeListener(const picojson::value& args, picojson::object& out); + void unsetVolumeChangeListener(const picojson::value& args, picojson::object& out); + + virtual void onVolumeChangeCallback(u_int16_t volume); }; } // namespace tvaudio diff --git a/src/tvaudio/tvaudio_manager.cc b/src/tvaudio/tvaudio_manager.cc index 6725f033..c8cbe6eb 100755 --- a/src/tvaudio/tvaudio_manager.cc +++ b/src/tvaudio/tvaudio_manager.cc @@ -23,11 +23,18 @@ const int AVOC_SUCCESS = 0; const u_int16_t VOLUME_STEP = 1; } -AudioControlManager::AudioControlManager() { - m_volume_step = VOLUME_STEP; +VolumeChangeListener::~VolumeChangeListener() { + LOGD("Enter"); +} + +AudioControlManager::AudioControlManager() : + m_volume_step(VOLUME_STEP), + m_volume_change_listener(NULL) { + LOGD("Enter"); } AudioControlManager::~AudioControlManager() { + LOGD("Enter"); } AudioControlManager& AudioControlManager::getInstance() { @@ -129,6 +136,50 @@ AudioOutputMode AudioControlManager::getOutputMode() { } } +void AudioControlManager::registerVolumeChangeListener( + VolumeChangeListener* listener) { + LOGD("Enter"); + unregisterVolumeChangeListener(); + int r = sound_manager_set_master_volume_changed_cb( + volumeChangeCallback, NULL); + if (SOUND_MANAGER_ERROR_NONE != r) { + LOGE("Failed to add listener: %d", r); + throw UnknownException("Failed to add listener"); + } + m_volume_change_listener = listener; + LOGD("Added listener"); +} + +void AudioControlManager::unregisterVolumeChangeListener() { + LOGD("Enter"); + int r = sound_manager_unset_master_volume_changed_cb(); + if (SOUND_MANAGER_ERROR_NONE != r) { + LOGW("Failed to remove listener: %d", r); + } + m_volume_change_listener = NULL; +} + +void AudioControlManager::volumeChangeCallback( + unsigned int /*volume*/, + void* /*user_data*/) { + LOGD("Enter"); + try { + if (!getInstance().m_volume_change_listener) { + LOGD("Listener is null. Ignoring"); + return; + } + u_int16_t val; + try { + val = getInstance().getVolume(); + } catch (...) { + LOGE("Failed to retrieve volume level"); + } + getInstance().m_volume_change_listener->onVolumeChangeCallback(val); + } catch (...) { + LOGE("Failed to call callback"); + } +} + } // namespace tvaudio } // namespace extension diff --git a/src/tvaudio/tvaudio_manager.h b/src/tvaudio/tvaudio_manager.h index 8165df57..1cae31ab 100755 --- a/src/tvaudio/tvaudio_manager.h +++ b/src/tvaudio/tvaudio_manager.h @@ -17,6 +17,12 @@ enum AudioOutputMode { AAC }; +class VolumeChangeListener { + public: + virtual void onVolumeChangeCallback(u_int16_t volume) = 0; + virtual ~VolumeChangeListener(); +}; + class AudioControlManager { public: void setMute(bool mute); @@ -26,6 +32,9 @@ class AudioControlManager { void setVolumeDown(); u_int16_t getVolume(); AudioOutputMode getOutputMode(); + void registerVolumeChangeListener(VolumeChangeListener* listener); + void unregisterVolumeChangeListener(); + static void volumeChangeCallback(unsigned int volume, void* user_data); // Not copyable, assignable, movable AudioControlManager(AudioControlManager const&) = delete; @@ -33,8 +42,10 @@ class AudioControlManager { AudioControlManager(AudioControlManager &&) = delete; static AudioControlManager& getInstance(); + private: u_int16_t m_volume_step; + VolumeChangeListener* m_volume_change_listener; AudioControlManager(); virtual ~AudioControlManager();