// 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.
* @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);
};
* 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);
};
#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"
} // namespace
TVAudioInstance::TVAudioInstance() {
+ LOGD("Enter");
using std::placeholders::_1;
using std::placeholders::_2;
#define REGISTER_SYNC(c, x) \
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);
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);
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
#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();
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
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() {
}
}
+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
AAC
};
+class VolumeChangeListener {
+ public:
+ virtual void onVolumeChangeCallback(u_int16_t volume) = 0;
+ virtual ~VolumeChangeListener();
+};
+
class AudioControlManager {
public:
void setMute(bool mute);
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;
AudioControlManager(AudioControlManager &&) = delete;
static AudioControlManager& getInstance();
+
private:
u_int16_t m_volume_step;
+ VolumeChangeListener* m_volume_change_listener;
AudioControlManager();
virtual ~AudioControlManager();