LOCATION_ENABLE_STATE: 'LOCATION_ENABLE_STATE',
GPS_ENABLE_STATE: 'GPS_ENABLE_STATE',
NPS_ENABLE_STATE: 'NPS_ENABLE_STATE',
- INCOMMING_MSG: 'INCOMMING_MSG',
+ INCOMING_MSG: 'INCOMING_MSG',
TIME_CHANGED: 'TIME_CHANGED',
TIME_ZONE: 'TIME_ZONE',
HOUR_FORMAT: 'HOUR_FORMAT',
};
function _checkEventName(name) {
+ var name = name || '';
if (!(/^([a-zA-Z_]){1}([a-zA-Z0-9_]){0,126}$/.test(name))) {
throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR,
'Invalid event name');
}
}
-Application.prototype.addEventListener = function(name, callback) {
- var args = AV.validateMethod(arguments, [
- {name: 'name', type: AV.Types.STRING},
+var event_listeners_ = {};
+var watchId_ = 0;
+function nextWatchId() {
+ return ++watchId_;
+}
+
+Application.prototype.addEventListener = function(event, callback) {
+ var args = AV.validateArgs(arguments, [
+ {name: 'event', type: AV.Types.DICTIONARY},
{name: 'callback', type: AV.Types.FUNCTION}
]);
- var data = {
- listenerId: 'AppEventListener'
- };
+ var data = {};
- if (Object.keys(SystemEvent).indexOf(args.name) > -1) {
- data.name = 'tizen.system.event.' + args.name.toLowerCase();
+ if (Object.keys(SystemEvent).indexOf(args.event.name) > -1) {
+ data.name = 'tizen.system.event.' + args.event.name.toLowerCase();
} else {
- var _arr = args.name.split('.');
- var _event_name = _arr.pop();
- var _appid = _arr.join('.');
+ _checkEventName(args.event.name);
+ _checkAppId(args.event.appId);
- _checkEventName(_event_name);
- _checkAppId(_appid);
+ data.name = 'event.' + args.event.appId + '.' + args.event.name;
+ }
- data.name = 'event.' + _appid + '.' + _event_name;
+ var watchId = nextWatchId();
+ data.listenerId = data.name;
+ event_listeners_[data.name] = !T.isObject(event_listeners_[data.name])
+ ? {} : event_listeners_[data.name];
+
+ if (!Object.keys(event_listeners_[data.name]).length) {
+ native.addListener(data.name, function(msg) {
+ var eventName = msg.name;
+ var event = eventName.split('.').pop();
+ for (var id in event_listeners_[eventName]) {
+ if (event_listeners_[eventName].hasOwnProperty(id)) {
+ if (msg.data) {
+ event_listeners_[eventName][id](event, msg.data);
+ } else {
+ delete msg.name;
+ msg.type = event; //TODO: type should come from native site
+ event_listeners_[eventName][id](event.toUpperCase(), msg);
+ }
+ }
+ }
+ });
+
+ var result = native.callSync('Application_addEventListener', data);
+ if (native.isFailure(result)) {
+ throw native.getErrorObject(result);
+ }
}
- // @TODO: register eventListener
+ event_listeners_[data.name][watchId] = args.callback;
+ return watchId;
};
+function getEventNameById(watchId) {
+ var eventName;
+ for (var event in event_listeners_) {
+ if (event_listeners_.hasOwnProperty(event)) {
+ for (var id in event_listeners_[event]) {
+ if (event_listeners_[event].hasOwnProperty(id) && Converter.toLong(id) === watchId) {
+ eventName = event;
+ }
+ }
+ }
+ }
+ return eventName;
+}
+
Application.prototype.removeEventListener = function(watchId) {
- var args = AV.validateMethod(arguments, [
+ var args = AV.validateArgs(arguments, [
{name: 'watchId', type: AV.Types.LONG}
]);
- // @TODO: remove eventListener
+ var eventName = getEventNameById(args.watchId);
+
+ if (!eventName) {
+ return;
+ }
+
+ delete event_listeners_[eventName][args.watchId];
+
+ if (!Object.keys(event_listeners_[eventName]).length) {
+ native.removeListener(eventName);
+ var result = native.callSync('Application_removeEventListener', {name: eventName});
+ if (native.isFailure(result)) {
+ throw native.getErrorObject(result);
+ }
+ }
};
-Application.prototype.broadcastEvent = function(name, data) {
+Application.prototype.broadcastEvent = function(event, data) {
var args = AV.validateMethod(arguments, [
- {name: 'name', type: AV.Types.STRING},
+ {name: 'event', type: AV.Types.DICTIONARY},
{name: 'data', type: AV.Types.DICTIONARY}
]);
- _checkEventName(args.name);
+ _checkEventName(args.event.name);
+
+ if (this.appInfo.id !== args.event.appId) {
+ throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR, 'Invalid appId');
+ }
var nativeData = {
- name: 'event.' + this.appInfo.id + '.' + args.name,
+ name: 'event.' + this.appInfo.id + '.' + args.event.name,
data: args.data
};
}
};
-Application.prototype.broadcastTrustedEvent = function(name, data) {
+Application.prototype.broadcastTrustedEvent = function(event, data) {
var args = AV.validateMethod(arguments, [
- {name: 'name', type: AV.Types.STRING},
+ {name: 'event', type: AV.Types.DICTIONARY},
{name: 'data', type: AV.Types.DICTIONARY}
]);
- _checkEventName(args.name);
+ _checkEventName(args.event.name);
+
+ if (this.appInfo.id !== args.event.appId) {
+ throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR, 'Invalid appId');
+ }
var nativeData = {
- name: 'event.' + this.appInfo.id + '.' + args.name,
+ name: 'event.' + this.appInfo.id + '.' + args.event.name,
data: args.data
};
void ApplicationInstance::BroadcastEvent(const picojson::value& args, picojson::object& out) {
LoggerD("Entered");
- bool trusted = false;
- manager_.BroadcastEventHelper(args, out, trusted);
+ manager_.BroadcastEventHelper(args, out, false);
}
void ApplicationInstance::BroadcastTrustedEvent(const picojson::value& args, picojson::object& out) {
LoggerD("Entered");
- bool trusted = true;
- manager_.BroadcastEventHelper(args, out, trusted);
+ manager_.BroadcastEventHelper(args, out, true);
}
void ApplicationInstance::AddEventListener(const picojson::value& args, picojson::object& out) {
LoggerD("Entered");
- manager_.StartEventListener(&out);
+ const std::string& event_name = args.get("name").get<std::string>();
+
+ LOGGER(DEBUG) << "event_name: " << event_name;
+
+ JsonCallback cb = [this, args](picojson::value* event) -> void {
+ picojson::object& event_o = event->get<picojson::object>();
+ event_o["listenerId"] = args.get("listenerId");
+ LOGGER(DEBUG) << event->serialize().c_str();
+ PostMessage(event->serialize().c_str());
+ LOGGER(DEBUG) << event->serialize().c_str();
+ };
+
+ PlatformResult result = manager_.StartEventListener(event_name, cb);
+ if (result) {
+ ReportSuccess(out);
+ } else {
+ ReportError(result, &out);
+ }
}
void ApplicationInstance::RemoveEventListener(const picojson::value& args, picojson::object& out) {
LoggerD("Entered");
- manager_.StopEventListener();
+ const std::string& event_name = args.get("name").get<std::string>();
+
+ LOGGER(DEBUG) << "event_name: " << event_name;
+
+ manager_.StopEventListener(event_name);
}
} // namespace application
#include <aul.h>
#include <package_manager.h>
#include <pkgmgr-info.h>
-#include <app_event.h>
#include <bundle.h>
#include <bundle_internal.h>
const std::string kOnUpdated = "onupdated";
const std::string kOnUninstalled = "onuninstalled";
const std::string kData = "data";
+
+const std::map<std::string, std::string> event_map_ = {
+ {SYSTEM_EVENT_BATTERY_CHARGER_STATUS, EVENT_KEY_BATTERY_CHARGER_STATUS},
+ {SYSTEM_EVENT_BATTERY_LEVEL_STATUS, EVENT_KEY_BATTERY_LEVEL_STATUS},
+ {SYSTEM_EVENT_USB_STATUS, EVENT_KEY_USB_STATUS},
+ {SYSTEM_EVENT_EARJACK_STATUS, EVENT_KEY_EARJACK_STATUS},
+ {SYSTEM_EVENT_DISPLAY_STATE, EVENT_KEY_DISPLAY_STATE},
+ {SYSTEM_EVENT_LOW_MEMORY, EVENT_KEY_LOW_MEMORY},
+ {SYSTEM_EVENT_WIFI_STATE, EVENT_KEY_WIFI_STATE},
+ {SYSTEM_EVENT_BT_STATE, EVENT_KEY_BT_STATE},
+ {SYSTEM_EVENT_LOCATION_ENABLE_STATE, EVENT_KEY_LOCATION_ENABLE_STATE},
+ {SYSTEM_EVENT_GPS_ENABLE_STATE, EVENT_KEY_GPS_ENABLE_STATE},
+ {SYSTEM_EVENT_NPS_ENABLE_STATE, EVENT_KEY_NPS_ENABLE_STATE},
+ {SYSTEM_EVENT_INCOMMING_MSG, EVENT_KEY_MSG_TYPE},
+ {SYSTEM_EVENT_TIME_ZONE, EVENT_KEY_TIME_ZONE},
+ {SYSTEM_EVENT_HOUR_FORMAT, EVENT_KEY_HOUR_FORMAT},
+ {SYSTEM_EVENT_LANGUAGE_SET, EVENT_KEY_LANGUAGE_SET},
+ {SYSTEM_EVENT_REGION_FORMAT, EVENT_KEY_REGION_FORMAT},
+ {SYSTEM_EVENT_SILENT_MODE, EVENT_KEY_SILENT_MODE},
+ {SYSTEM_EVENT_VIBRATION_STATE, EVENT_KEY_VIBRATION_STATE},
+ {SYSTEM_EVENT_SCREEN_AUTOROTATE_STATE, EVENT_KEY_SCREEN_AUTOROTATE_STATE},
+ {SYSTEM_EVENT_MOBILE_DATA_STATE, EVENT_KEY_MOBILE_DATA_STATE},
+ {SYSTEM_EVENT_DATA_ROAMING_STATE, EVENT_KEY_DATA_ROAMING_STATE},
+ {SYSTEM_EVENT_FONT_SET, EVENT_KEY_FONT_SET}
+};
}
ApplicationManager::ApplicationManager(ApplicationInstance& instance) :
}
}
-void ApplicationManager::StartEventListener(picojson::object* out) {
+void ApplicationManager::OnEvent(const char* event_name,
+ bundle* event_data,
+ void* user_data) {
+ LoggerD("Entered");
+ LOGGER(DEBUG) << event_name;
+
+ ApplicationManager* manager = static_cast<ApplicationManager*>(user_data);
+
+ if (!manager->event_callback_) {
+ LOGGER(DEBUG) << "No event listener registered, skipping.";
+ return;
+ }
+
+ picojson::value event = picojson::value(picojson::object());
+ picojson::object& event_o = event.get<picojson::object>();
+
+ int ret;
+ char* val = nullptr;
+
+ if (event_map_.count(event_name)) { // system event
+ const std::string& key = event_map_.at(event_name);
+ std::string state = "true";
+ if (key != "") {
+ ret = bundle_get_str(event_data, key.c_str(), &val);
+ if (EVENT_ERROR_NONE != ret) {
+ LOGGER(ERROR) << "failed to read bundle data, error: " << ret;
+ return;
+ }
+
+ state = std::string(val);
+ }
+
+ LOGGER(DEBUG) << "state is: " << state;
+ event_o["value"] = picojson::value(state);
+
+ } else { // user event
+ ret = bundle_get_str(event_data, "data", &val);
+ if (EVENT_ERROR_NONE != ret) {
+ LOGGER(ERROR) << "failed to read bundle data, error: " << ret;
+ return;
+ }
+
+ picojson::value data;
+ std::string err;
+ picojson::parse(data, val, val + strlen(val), &err);
+ if (!err.empty()) {
+ LOGGER(ERROR) << "Failed to parse bundle data: " << err;
+ return;
+ }
+
+ event_o["data"] = data;
+ }
+
+ LOGGER(DEBUG) << "event_name is: " << event_name;
+ event_o["name"] = picojson::value(event_name);
+
+ manager->event_callback_(&event);
+}
+
+PlatformResult ApplicationManager::StartEventListener(const std::string& event_name,
+ const JsonCallback& callback) {
LoggerD("Entered");
- //TODO: please implement
+ int ret;
+ event_handler_h event_handler;
+
+ ret = event_add_event_handler(event_name.c_str(), OnEvent, this, &event_handler);
+ LOGGER(DEBUG) << "event_add_event_handler() result: " << ret;
+ if (EVENT_ERROR_PERMISSION_DENIED == ret) {
+ LOGGER(ERROR) << "event_add_event_handler failed, error: " << ret;
+ return PlatformResult(ErrorCode::SECURITY_ERR, "The privilege is required");
+ } else if (EVENT_ERROR_NONE != ret) {
+ LOGGER(ERROR) << "event_add_event_handler failed, error: " << ret;
+ return PlatformResult(ErrorCode::UNKNOWN_ERR, "Error setting event listener");
+ }
+
+ event_handler_map_[event_name] = event_handler;
+
+ event_callback_ = callback;
+ LOGGER(DEBUG) << "event_add_event_handler success";
+ return PlatformResult(ErrorCode::NO_ERROR);
}
-void ApplicationManager::StopEventListener() {
+void ApplicationManager::StopEventListener(const std::string& event_name) {
LoggerD("Entered");
- //TODO: please implement
+ int ret;
+ event_handler_h event_handler;
+
+ if (event_handler_map_.find(event_name) != event_handler_map_.end()) {
+ event_handler = event_handler_map_[event_name];
+
+ ret = event_remove_event_handler(event_handler);
+ if (EVENT_ERROR_NONE != ret) {
+ LOGGER(ERROR) << "event_remove_event_handler failed, error: " << ret;
+ return;
+ }
+
+ event_handler_map_.erase(event_name);
+ }
}
} // namespace application
#ifndef SRC_APPLICATION_APPLICATION_MANAGER_H__
#define SRC_APPLICATION_APPLICATION_MANAGER_H__
-#include <string>
+#include <app_event.h>
+#include <bundle.h>
+#include <functional>
#include <memory>
-
#include <package-manager.h>
+#include <string>
#include "common/picojson.h"
#include "common/platform_result.h"
+typedef std::function<void(picojson::value*)> JsonCallback;
+
namespace extension {
namespace application {
void StopAppInfoEventListener();
void GetApplicationInformationSize(const picojson::value& args, picojson::object* out);
void AsyncResponse(common::PlatformResult& result, std::shared_ptr<picojson::value>* response);
+
void BroadcastEventHelper(const picojson::value& args, picojson::object& out, bool trusted);
- void StartEventListener(picojson::object* out);
- void StopEventListener();
+ common::PlatformResult StartEventListener(const std::string& event_name,
+ const JsonCallback& callback);
+ void StopEventListener(const std::string& event_name);
private:
char* GetPackageId(const std::string& app_id);
pkgmgr_client* pkgmgr_client_handle_;
ApplicationInstance& instance_;
+
+ JsonCallback event_callback_;
+ std::map<std::string, event_handler_h> event_handler_map_;
+ static void OnEvent(const char* event_name,
+ bundle* event_data,
+ void* user_data);
};
} // namespace application