[TVAudio] Listener implementation
authorMariusz Polasinski <m.polasinski@samsung.com>
Mon, 29 Dec 2014 17:32:48 +0000 (18:32 +0100)
committerLukasz Foniok <l.foniok@samsung.com>
Wed, 7 Jan 2015 12:18:13 +0000 (13:18 +0100)
[Verification]
Code complies without error
Methods are tested in node

Change-Id: Id07de5060a9b456a8ed8f4b4648b4656eaeaf0c3
Signed-off-by: Mariusz Polasinski <m.polasinski@samsung.com>
src/tvaudio/tvaudio_api.js
src/tvaudio/tvaudio_instance.cc
src/tvaudio/tvaudio_instance.h
src/tvaudio/tvaudio_manager.cc
src/tvaudio/tvaudio_manager.h

index d3e3a30baebd19fbec6a675ceec6cd34f8daa8d3..85887234ea9ab8d721f89b5e9746af0b307c5004 100644 (file)
@@ -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);
 };
 
 
index 93bccab2a3361455ed77a436b25568c96fa6cedf..05e8af59e1e8eec56f5e9f56393c4fbb94ecba1c 100644 (file)
@@ -7,6 +7,8 @@
 #include <string>
 
 #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<AudioOutputMode, std::string> 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<bool>();
     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<double>();
     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<double>(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<picojson::object>();
+      obj["listenerId"] = picojson::value("VolumeChangeCallback");
+      obj["volume"] = picojson::value(static_cast<double>(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
index 47c6bb7ea4054ae29e28ccb9cae951c0dd7eceaa..f10b7eeac8e69fedb7e16d02c2c0c531501bbc21 100644 (file)
@@ -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
index 6725f03383f462089812f4ae47d32ff3ff3aa60f..c8cbe6ebc818f3ea7bb112f91478e50f255d0258 100755 (executable)
@@ -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
 
index 8165df57c9694c55a7a0b402145cffb1b6af23ce..1cae31ab423fe34499e1368e6dc557e70e74a785 100755 (executable)
@@ -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();