[Verification] Tested with SDK sample application.
Change-Id: I2373803c70edab07a7e50f182236ecaa436d79a1
BuildRequires: pkgconfig(gio-2.0)
BuildRequires: pkgconfig(glib-2.0)
BuildRequires: pkgconfig(libudev)
-BuildRequires: pkgconfig(message-port)
+BuildRequires: pkgconfig(capi-message-port)
BuildRequires: pkgconfig(minizip)
BuildRequires: pkgconfig(zlib)
BuildRequires: pkgconfig(msg-service)
BuildRequires: pkgconfig(capi-appfw-package-manager)
BuildRequires: pkgconfig(wrt-plugins-ipc-message)
+
%if 0%{?tizen_feature_power_support}
BuildRequires: pkgconfig(capi-system-power)
%endif
{
'target_name': 'tizen_messageport',
'type': 'loadable_module',
- 'variables': {
- 'packages': [
- 'bundle',
- 'message-port',
- ],
- },
'sources': [
'messageport_api.js',
'messageport_extension.cc',
'messageport_instance.cc',
'messageport_instance.h',
],
+ 'conditions': [
+ ['tizen == 1', {
+ 'variables': {
+ 'packages': [
+ 'vconf',
+ 'capi-message-port',
+ 'dlog'
+ ]
+ },
+ }],
+ ],
},
],
}
-// Copyright (c) 2013 Intel Corporation. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// MessagePort
-function isInteger(value) {
- return isFinite(value) && !isNaN(parseInt(value));
-}
+var validator_ = xwalk.utils.validator;
+var types_ = validator_.Types;
-function isString(value) {
- return typeof(value) === 'string' || value instanceof String;
-}
-function assertThrow(expr, exception) {
- if (!expr)
- throw new tizen.WebAPIException(tizen.WebAPIException[exception]);
-}
+var callbackId = 0;
+var callbacks = {};
-function sendSyncMessage(cmd, msg) {
- msg['cmd'] = cmd;
+extension.setMessageListener(function(json) {
+ var msg = JSON.parse(json);
+ var listeners = callbacks[msg['local_port_id']];
- var serialized = JSON.stringify(msg);
- return JSON.parse(extension.internal.sendSyncMessage(serialized));
-}
+ console.log('Listeners length:' + listeners.length);
+ var rmp = new RemoteMessagePort(msg.remotePort, msg.remoteAppId, msg.trusted);
-function NativeBridge() {
- this.listeners = {};
- this.next_listener_id = 0;
- this.queued_messages = {};
-}
+ for (var i = 0; i < listeners.length; i++) {
-NativeBridge.prototype.requestLocalMessagePort = function(messagePortName) {
- return sendSyncMessage('RequestLocalMessagePort', {
- messagePortName: messagePortName,
- trusted: false
- });
-};
+ var func = listeners[i][0];
+ func(msg.message, rmp);
+ }
-NativeBridge.prototype.requestTrustedLocalMessagePort = function(messagePortName) {
- return sendSyncMessage('RequestLocalMessagePort', {
- messagePortName: messagePortName,
- trusted: true
- });
-};
+});
-NativeBridge.prototype.requestRemoteMessagePort = function(appId, messagePortName) {
- return sendSyncMessage('RequestRemoteMessagePort', {
- appId: appId,
- messagePortName: messagePortName,
- trusted: false
- });
-};
+function nextCallbackId() {
+ return callbackId++;
+}
-NativeBridge.prototype.requestTrustedRemoteMessagePort = function(appId, messagePortName) {
- return sendSyncMessage('RequestRemoteMessagePort', {
- appId: appId,
- messagePortName: messagePortName,
- trusted: true
- });
+var ExceptionMap = {
+ 'UnknownError' : tizen.WebAPIException.UNKNOWN_ERR,
+ 'TypeMismatchError' : tizen.WebAPIException.TYPE_MISMATCH_ERR,
+ 'InvalidValuesError' : tizen.WebAPIException.INVALID_VALUES_ERR,
+ 'IOError' : tizen.WebAPIException.IO_ERR,
+ 'ServiceNotAvailableError' : tizen.WebAPIException.SERVICE_NOT_AVAILABLE_ERR,
+ 'SecurityError' : tizen.WebAPIException.SECURITY_ERR,
+ 'NetworkError' : tizen.WebAPIException.NETWORK_ERR,
+ 'NotSupportedError' : tizen.WebAPIException.NOT_SUPPORTED_ERR,
+ 'NotFoundError' : tizen.WebAPIException.NOT_FOUND_ERR,
+ 'InvalidAccessError' : tizen.WebAPIException.INVALID_ACCESS_ERR,
+ 'AbortError' : tizen.WebAPIException.ABORT_ERR,
+ 'QuotaExceededError' : tizen.WebAPIException.QUOTA_EXCEEDED_ERR
};
-NativeBridge.prototype.addLocalListener = function(localPort, listenerFunc) {
- if (!this.listeners.hasOwnProperty(localPort._id))
- this.listeners[localPort._id] = [];
-
- this.next_listener_id++;
- this.listeners[localPort._id].push([listenerFunc, this.next_listener_id]);
+function callNative(cmd, args) {
+ var json = {'cmd': cmd, 'args': args};
+ var argjson = JSON.stringify(json);
+ var resultString = extension.internal.sendSyncMessage(argjson);
+ var result = JSON.parse(resultString);
- if (typeof(this.queued_messages[localPort.id]) !== 'undefined') {
- var queue = this.queued_messages[localPort.id];
- for (var i = 0, j = queue.length; i < j; i++)
- this.onLocalMessageReceived(queue[i]);
- this.queued_messages[localPort.id] = [];
+ if (typeof result !== 'object') {
+ throw new tizen.WebAPIException(tizen.WebAPIException.UNKNOWN_ERR);
}
- return this.next_listener_id;
-};
+ if (result['status'] == 'success') {
+ if (result['result']) {
+ return result['result'];
+ }
+ return true;
+ }
+ else if (result['status'] == 'error') {
+ var err = result['error'];
+ if (err) {
+ if (ExceptionMap[err.name]) {
+ throw new tizen.WebAPIException(ExceptionMap[err.name], err.message);
+ } else {
+ throw new tizen.WebAPIException(tizen.WebAPIException.UNKNOWN_ERR, err.message);
+ }
+ }
+ return false;
+ }
+}
-NativeBridge.prototype.removeLocalListener = function(localPort, watchId) {
- var listeners = this.listeners[localPort._id];
- if (typeof(listeners) === 'undefined')
- return { not_found: 1 };
- var to_delete = [];
- for (var i = 0, j = listeners.length; i < j; i++) {
- var listener_id = listeners[i][1];
- if (watchId == listener_id)
- to_delete.push(i);
+function callNativeWithCallback(cmd, args, callback) {
+ if (callback) {
+ var id = nextCallbackId();
+ args['callbackId'] = id;
+ callbacks[id] = callback;
}
- if (to_delete.length == 0)
- return { not_found: 1 };
+ return callNative(cmd, args);
+}
- for (var i = 0, j = to_delete.length; i < j; i++)
- this.listeners.splice(to_delete[i], 1);
+function SetReadOnlyProperty(obj, n, v) {
+ Object.defineProperty(obj, n, {value: v, writable: false});
+}
- return {};
-};
-NativeBridge.prototype.onLocalMessageReceived = function(msg) {
- var listeners = this.listeners[msg.id];
- if (typeof(listeners) === 'undefined') {
- if (typeof(this.queued_messages[msg.id]) === 'undefined')
- this.queued_messages[msg.id] = [];
- this.queued_messages[msg.id].push(msg);
- return;
- }
+function MessagePortManager() {
+ // constructor of MessagePortManager
+}
- // FIXME(leandro): Reuse RemoteMessagePort if it has been requested
- // previously.
- var rmp = new RemoteMessagePort(msg.remotePort, msg.remoteAppId, msg.trusted);
- for (var i = 0; i < listeners.length; i++) {
- var func = listeners[i][0];
- func(msg.data, rmp);
- }
-};
-NativeBridge.prototype.sendMessage = function(remotePort, data, localPort) {
- return sendSyncMessage('SendMessage', {
- appId: remotePort.appId,
- messagePortName: remotePort.messagePortName,
- data: data,
- trusted: remotePort.isTrusted,
- localPort: localPort ? localPort._id : -1
- });
-};
+MessagePortManager.prototype.requestLocalMessagePort = function(localMessagePortName) {
+ var args = validator_.validateArgs(arguments, [
+ {'name' : 'localMessagePortName', 'type': types_.STRING}
+ ]);
+
+ var nativeParam = {
+ 'localMessagePortName': args.localMessagePortName
+ };
-NativeBridge.prototype.toTizenException = function(nativeError) {
- function isUndefined(v) {
- return typeof(v) === 'undefined';
+ try {
+
+ var localPortId = callNative('MessagePortManager_requestLocalMessagePort', nativeParam);
+
+ } catch (e) {
+ throw e;
}
- assertThrow(isUndefined(nativeError.not_found), 'NOT_FOUND_ERR');
- assertThrow(isUndefined(nativeError.invalid_parameter), 'INVALID_VALUES_ERR');
- assertThrow(isUndefined(nativeError.certificate_error), 'INVALID_ACCESS_ERR');
- assertThrow(isUndefined(nativeError.max_exceeded), 'QUOTA_EXCEEDED_ERR');
- assertThrow(nativeError.success === true, 'UNKNOWN_ERR');
-};
+ var returnObject = new LocalMessagePort(localPortId, args.localMessagePortName, false);
-var nativeBridge = new NativeBridge();
+ return returnObject;
+};
-extension.setMessageListener(function(json) {
- var msg = JSON.parse(json);
+MessagePortManager.prototype.requestTrustedLocalMessagePort = function(localMessagePortName) {
+ var args = validator_.validateArgs(arguments, [
+ {'name' : 'localMessagePortName', 'type': types_.STRING}
+ ]);
- if (msg.cmd == 'LocalMessageReceived')
- nativeBridge.onLocalMessageReceived(msg);
- else
- console.error('Unknown command received: ' + msg.cmd);
-});
+ var nativeParam = {
+ 'localMessagePortName': args.localMessagePortName
+ };
+ try {
-function MessagePortManager() {
-}
+ var localPortId = callNative('MessagePortManager_requestTrustedLocalMessagePort', nativeParam);
-MessagePortManager.prototype.requestLocalMessagePort = function(
- localMessagePortName) {
- assertThrow(isString(localMessagePortName), 'TYPE_MISMATCH_ERR');
+ } catch (e) {
+ throw e;
+ }
- var messagePort = nativeBridge.requestLocalMessagePort(
- localMessagePortName);
- nativeBridge.toTizenException(messagePort);
+ var returnObject = new LocalMessagePort(localPortId, args.localMessagePortName, true);
- return new LocalMessagePort(messagePort.id, localMessagePortName, false);
+ return returnObject;
};
-MessagePortManager.prototype.requestTrustedLocalMessagePort = function(
- localMessagePortName) {
- assertThrow(isString(localMessagePortName), 'TYPE_MISMATCH_ERR');
+MessagePortManager.prototype.requestRemoteMessagePort = function(appId, remoteMessagePortName) {
+ var args = validator_.validateArgs(arguments, [
+ {'name' : 'appId', 'type': types_.STRING},
+ {'name' : 'remoteMessagePortName', 'type': types_.STRING}
+ ]);
- var messagePort = nativeBridge.requestTrustedLocalMessagePort(
- localMessagePortName);
- nativeBridge.toTizenException(messagePort);
+ var nativeParam = {
+ 'appId': args.appId,
+ 'remoteMessagePortName': args.remoteMessagePortName
+ };
- return new LocalMessagePort(messagePort.id, localMessagePortName, true);
-};
+ try {
-MessagePortManager.prototype.requestRemoteMessagePort = function(
- appId, remoteMessagePortName) {
- assertThrow(isString(appId), 'TYPE_MISMATCH_ERR');
- assertThrow(isString(remoteMessagePortName), 'TYPE_MISMATCH_ERR');
+ var syncResult = callNative('MessagePortManager_requestRemoteMessagePort', nativeParam);
- var messagePort = nativeBridge.requestRemoteMessagePort(
- appId, remoteMessagePortName);
- nativeBridge.toTizenException(messagePort);
+ } catch (e) {
+ throw e;
+ }
+
+ var returnObject = new RemoteMessagePort(args.remoteMessagePortName, args.appId, false);
- return new RemoteMessagePort(remoteMessagePortName, appId, false);
+ return returnObject;
};
-MessagePortManager.prototype.requestTrustedRemoteMessagePort = function(
- appId, remoteMessagePortName) {
- assertThrow(isString(appId), 'TYPE_MISMATCH_ERR');
- assertThrow(isString(remoteMessagePortName), 'TYPE_MISMATCH_ERR');
+MessagePortManager.prototype.requestTrustedRemoteMessagePort =
+ function(appId, remoteMessagePortName) {
+ var args = validator_.validateArgs(arguments, [
+ {'name' : 'appId', 'type': types_.STRING},
+ {'name' : 'remoteMessagePortName', 'type': types_.STRING}
+ ]);
+
+ var nativeParam = {
+ 'remoteMessagePortName': args.remoteMessagePortName
+ };
- var messagePort = nativeBridge.requestTrustedRemoteMessagePort(appId,
- remoteMessagePortName);
- nativeBridge.toTizenException(messagePort);
+ try {
+
+ var syncResult = callNative('MessagePortManager_requestTrustedRemoteMessagePort', nativeParam);
- return new RemoteMessagePort(remoteMessagePortName, appId, true);
+ } catch (e) {
+ throw e;
+ }
+
+ var returnObject = new RemoteMessagePort(args.remoteMessagePortName, args.appId, true);
+
+ return returnObject;
};
+
function LocalMessagePort(id, messagePortName, isTrusted) {
Object.defineProperties(this, {
- '_id': { value: id, writable: false, enumerable: false },
- 'messagePortName': { value: messagePortName, writable: false },
+ 'id': { value: id, writable: false },
+ 'messagePortName': { value: messagePortName, writable: false, enumerable: false },
'isTrusted': { value: !!isTrusted, writable: false }
});
}
+
LocalMessagePort.prototype.addMessagePortListener = function(listener) {
- assertThrow(listener instanceof Function);
+ var args = validator_.validateArgs(arguments, [
+ {'name' : 'listener', 'type': types_.FUNCTION, 'nullable': false}
+ ]);
+
+ if (!callbacks.hasOwnProperty(this.id)) callbacks[this.id] = [];
+
+ callbackId++;
+ callbacks[this.id].push([listener, callbackId]);
+
+ return callbackId;
- return nativeBridge.addLocalListener(this, listener);
};
LocalMessagePort.prototype.removeMessagePortListener = function(watchId) {
- assertThrow(isInteger(watchId), 'TYPE_MISMATCH_ERR');
- assertThrow(watchId >= 0, 'INVALID_VALUES_ERR');
+ var args = validator_.validateArgs(arguments, [
+ {'name' : 'watchId', 'type': types_.LONG }
+ ]);
+
+ if (args.watchId <= 0)
+ throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR,
+ 'The input parameter contains an invalid value.');
+
+ var to_delete;
+ var listeners = callbacks[this.id];
+
+ for (var i = 0, j = listeners.length; i < j; i++) {
+ var listener_id = listeners[i][1];
+ if (watchId == listener_id) {
+ to_delete = i;
+ break;
+ }
+ }
+
+ if (typeof to_delete == 'undefined')
+ throw new tizen.WebAPIException(tizen.WebAPIException.NOT_FOUND_ERR,
+ 'The port of the target application is not found.');
+
+ listeners.splice(to_delete, 1);
- var error = nativeBridge.removeLocalListener(this, watchId);
- nativeBridge.toTizenException(error);
};
+
function RemoteMessagePort(messagePortName, appId, isTrusted) {
Object.defineProperties(this, {
'messagePortName': { value: messagePortName, writable: false },
});
}
-RemoteMessagePort.prototype.sendMessage = function(data, localMessagePort) {
- assertThrow(data instanceof Array, 'TYPE_MISMATCH_ERR');
- if (arguments.length >= 2)
- assertThrow(localMessagePort instanceof LocalMessagePort, 'TYPE_MISMATCH_ERR');
+RemoteMessagePort.prototype.sendMessage = function(data) {
+ var args = validator_.validateArgs(arguments, [
+ {'name' : 'data', 'type': types_.ARRAY},
+ {'name' : 'localMessagePort', 'type': types_.PLATFORM_OBJECT, 'optional' : true,
+ 'nullable' : true, 'values' : LocalMessagePort }
+ ]);
var filtered_data = new Array(data.length);
+
+ for (var i = 0, j = data.length; i < j; i++) {
+ if (Object.hasOwnProperty(data[i], 'key'))
+ throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR,
+ 'The input parameter contains an invalid value.');
+ if (Object.hasOwnProperty(data[i], 'value'))
+ throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR,
+ 'The input parameter contains an invalid value.');
+ filtered_data[i] = { key: data[i].key, value: data[i].value };
+ }
+
+
+ var nativeParam = {
+ 'appId': this.appId,
+ 'messagePortName': this.messagePortName,
+ 'data': filtered_data,
+ 'trusted': this.isTrusted,
+ 'local_port_id': args.localMessagePort ? args.localMessagePort.id : -1
+ };
+
try {
- for (var i = 0, j = data.length; i < j; i++)
- filtered_data[i] = { key: data[i].key, value: data[i].value };
+ var syncResult = callNative('RemoteMessagePort_sendMessage', nativeParam);
+
} catch (e) {
- assertThrow(Object.hasOwnProperty(data[i], 'key'), 'INVALID_VALUES_ERR');
- assertThrow(Object.hasOwnProperty(data[i], 'value'), 'INVALID_VALUES_ERR');
- throw new tizen.WebAPIException.UNKNOWN_ERR;
+ throw e;
}
- var error = nativeBridge.sendMessage(this, filtered_data, localMessagePort);
- nativeBridge.toTizenException(error);
};
-var messagePortManagerObject = new MessagePortManager();
-exports.requestLocalMessagePort =
- messagePortManagerObject.requestLocalMessagePort;
-exports.requestTrustedLocalMessagePort =
- messagePortManagerObject.requestTrustedLocalMessagePort;
-exports.requestRemoteMessagePort =
- messagePortManagerObject.requestRemoteMessagePort;
-exports.requestTrustedRemoteMessagePort =
- messagePortManagerObject.requestTrustedRemoteMessagePort;
+
+
+exports = new MessagePortManager();
+
-// Copyright (c) 2013 Intel Corporation. All rights reserved.
+// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "messageport/messageport_instance.h"
+// This will be generated from messageport_api.js
+extern const char kSource_messageport_api[];
+
common::Extension* CreateExtension() {
return new MessageportExtension;
}
-// This will be generated from messageport_api.js.
-extern const char kSource_messageport_api[];
-
MessageportExtension::MessageportExtension() {
SetExtensionName("tizen.messageport");
SetJavaScriptAPI(kSource_messageport_api);
}
+MessageportExtension::~MessageportExtension() {}
+
common::Instance* MessageportExtension::CreateInstance() {
- return new MessageportInstance();
+ return new extension::messageport::MessageportInstance;
}
-// Copyright (c) 2013 Intel Corporation. All rights reserved.
+// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
class MessageportExtension : public common::Extension {
public:
MessageportExtension();
+ virtual ~MessageportExtension();
+
private:
- // common::Extension implementation.
virtual common::Instance* CreateInstance();
};
-// Copyright (c) 2013 Intel Corporation. All rights reserved.
+// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "messageport/messageport_instance.h"
-#include <message-port.h>
-#include <string.h>
-
-#include <map>
-#include <string>
+#include <functional>
#include <vector>
+#include <string>
-MessageportInstance::MessageportIdToInstanceMap
- MessageportInstance::mp_id_to_instance_map_;
-
-namespace {
-
-bool ErrorIfMessageHasNoKey(const picojson::value& msg,
- const std::string& key, picojson::value::object& reply) {
- if (!msg.contains(key)) {
- std::cerr << "Required parameter \"" << key << "\" missing from message\n";
-
- reply["invalid_parameter"] = picojson::value(true);
- return true;
- }
-
- return false;
+#include "common/picojson.h"
+#include "common/logger.h"
+#include "common/platform_exception.h"
+
+namespace extension {
+namespace messageport {
+
+using common::TypeMismatchException;
+using common::InvalidValuesException;
+using common::UnknownException;
+using common::NotFoundException;
+using common::QuotaExceededException;
+
+MessageportInstance::MessageportInstance() {
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+ #define REGISTER_SYNC(c, x) \
+ RegisterSyncHandler(c, std::bind(&MessageportInstance::x, this, _1, _2));
+ REGISTER_SYNC("MessagePortManager_requestTrustedRemoteMessagePort",
+ MessagePortManagerRequesttrustedremotemessageport);
+ REGISTER_SYNC("MessagePortManager_requestLocalMessagePort",
+ MessagePortManagerRequestlocalmessageport);
+ REGISTER_SYNC("MessagePortManager_requestTrustedLocalMessagePort",
+ MessagePortManagerRequesttrustedlocalmessageport);
+ REGISTER_SYNC("MessagePortManager_requestRemoteMessagePort",
+ MessagePortManagerRequestremotemessageport);
+ REGISTER_SYNC("RemoteMessagePort_sendMessage", RemoteMessagePortSendmessage);
+ #undef REGISTER_SYNC
}
-}; // namespace
-
-void MessageportInstance::RegisterLocalMessageport(int mp_id,
- MessageportInstance *instance) {
- MessageportInstance::mp_id_to_instance_map_[mp_id] = instance;
+MessageportInstance::~MessageportInstance() {
}
-MessageportInstance* MessageportInstance::GetInstanceByPortId(int mp_id) {
- MessageportIdToInstanceMap::iterator it =
- MessageportInstance::mp_id_to_instance_map_.find(mp_id);
- if (it == mp_id_to_instance_map_.end())
- return 0;
- return it->second;
-}
+enum MessageportCallbacks {
+ MessagePortManagerRequesttrustedremotemessageportCallback,
+ MessagePortManagerRequestlocalmessageportCallback,
+ MessagePortManagerRequesttrustedlocalmessageportCallback,
+ MessagePortManagerRequestremotemessageportCallback,
+ LocalMessagePortRemovemessageportlistenerCallback,
+ RemoteMessagePortSendmessageCallback,
+ LocalMessagePortAddmessageportlistenerCallback
+};
-void MessageportInstance::BundleJsonIterator(
- const char *k, const char *v, void *d) {
+static void BundleJsonIterator(const char *k, const char *v, void *d) {
picojson::value::array *array = static_cast<picojson::value::array *>(d);
picojson::value::object o;
o["key"] = picojson::value(k);
array->push_back(picojson::value(o));
}
-void MessageportInstance::OnReceiveLocalMessage(
- int id, const char* remote_app_id, const char* remote_port,
- bool trusted_message, bundle* data) {
+#define CHECK_EXIST(args, name, out) \
+ if (!args.contains(name)) {\
+ ReportError(TypeMismatchException(name" is required argument"), out);\
+ return;\
+ }
+
+static void OnReceiveLocalMessage(int local_port_id,
+ const char* remote_app_id, const char* remote_port,
+ bool trusted_remote_port, bundle* message, void* user_data) {
+ MessageportInstance* object = static_cast<MessageportInstance*>(user_data);
picojson::value::object o;
+ picojson::value::array data;
- o["cmd"] = picojson::value("LocalMessageReceived");
- o["id"] = picojson::value(static_cast<double>(id));
+ o["local_port_id"] = picojson::value(static_cast<double>(local_port_id));
o["remoteAppId"] = picojson::value(remote_app_id);
o["remotePort"] = picojson::value(remote_port);
- o["trusted"] = picojson::value(trusted_message);
+ o["trusted_remote_port"] = picojson::value(trusted_remote_port);
+
+ LoggerD("Msg received from: %s", remote_app_id);
- picojson::value::array d;
- bundle_iterate(data, BundleJsonIterator, &d);
+ bundle_iterate(message, BundleJsonIterator, &data);
- o["data"] = picojson::value(d);
+ o["message"] = picojson::value(data);
- PostMessage(picojson::value(o).serialize().c_str());
+ object->PostMessage(picojson::value(o).serialize().c_str());
}
-void MessageportInstance::OnReceiveLocalMessageThunk(
- int id, const char* remote_app_id, const char* remote_port,
- bool trusted_message, bundle* data) {
- MessageportInstance* self = MessageportInstance::GetInstanceByPortId(id);
- if (!self) {
- std::cerr << "Could not find Messageport by id: " << id << "\n";
- return;
- }
- self->OnReceiveLocalMessage(id, remote_app_id, remote_port, trusted_message,
- data);
-}
+void MessageportInstance::MessagePortManagerRequestlocalmessageport
+ (const picojson::value& args, picojson::object& out) {
+ CHECK_EXIST(args, "localMessagePortName", out)
-void MessageportInstance::HandleSyncMessage(const char *message) {
- picojson::value v;
+ int portId;
+ const std::string& localMessagePortName =
+ args.get("localMessagePortName").get<std::string>();
- std::string err;
- picojson::parse(v, message, message + strlen(message), &err);
- if (!err.empty()) {
- std::cerr << "Ignoring unparsable sync message: " << message << "\n";
- std::cerr << "Error was: " << err << "\n";
- return;
- }
+ portId = message_port_register_local_port
+ (localMessagePortName.c_str(), OnReceiveLocalMessage, this);
+
+ LoggerD("Registering local port %s : %s", localMessagePortName.c_str(),
+ portId < 0 ? "false" : "true");
- picojson::value::object o;
- if (!ErrorIfMessageHasNoKey(v, "cmd", o)) {
- std::string cmd = v.get("cmd").to_str();
-
- if (cmd == "RequestLocalMessagePort") {
- HandleRequestLocalMessagePort(v, o);
- } else if (cmd == "RequestRemoteMessagePort") {
- HandleRequestRemoteMessagePort(v, o);
- } else if (cmd == "SendMessage") {
- HandleSendMessage(v, o);
- } else {
- std::cerr << "Ignoring unknown command: " << cmd << "\n";
- return;
- }
- } else {
- std::cerr << "Message has no command, ignoring\n";
- return;
- }
- SendSyncReply(picojson::value(o).serialize().c_str());
+ if(portId < 0){
+
+ switch (portId) {
+ case MESSAGE_PORT_ERROR_INVALID_PARAMETER:
+ ReportError(InvalidValuesException
+ ("The input parameter contains an invalid value."),out);
+ break;
+ case MESSAGE_PORT_ERROR_OUT_OF_MEMORY:
+ ReportError(UnknownException("Out of memory."),out);
+ break;
+ case MESSAGE_PORT_ERROR_IO_ERROR:
+ ReportError(UnknownException("Internal I/O error ocurred."),out);
+ break;
+ default:
+ ReportError(UnknownException("Unknown Exception"),out);
+ break;
+ }
+ }
+ else
+ ReportSuccess(picojson::value(static_cast<double>(portId)), out);
}
-void MessageportInstance::HandleRequestLocalMessagePort(
- const picojson::value& msg, picojson::value::object& o) {
- if (ErrorIfMessageHasNoKey(msg, "messagePortName", o))
- return;
- if (ErrorIfMessageHasNoKey(msg, "trusted", o))
- return;
+void MessageportInstance::
+ MessagePortManagerRequesttrustedlocalmessageport
+ (const picojson::value& args, picojson::object& out) {
+ CHECK_EXIST(args, "localMessagePortName", out)
- std::string message_port_name = msg.get("messagePortName").to_str();
- int mp_id;
+ int portId;
+ const std::string& localMessagePortName =
+ args.get("localMessagePortName").get<std::string>();
- if (msg.get("trusted").get<bool>()) {
- mp_id = messageport_register_trusted_local_port(message_port_name.c_str(),
- OnReceiveLocalMessageThunk);
- } else {
- mp_id = messageport_register_local_port(message_port_name.c_str(),
- OnReceiveLocalMessageThunk);
- }
+ portId = message_port_register_trusted_local_port
+ (localMessagePortName.c_str(), OnReceiveLocalMessage, NULL);
- if (mp_id < 0) {
- switch (mp_id) {
- case MESSAGEPORT_ERROR_INVALID_PARAMETER:
- o["invalid_parameter"] = picojson::value(true);
- break;
- case MESSAGEPORT_ERROR_OUT_OF_MEMORY:
- o["out_of_memory"] = picojson::value(true);
+ LoggerD("Registering trusted local port %s:%s", localMessagePortName.c_str(),
+ portId < 0 ? "false" : "true");
+
+ if(portId < 0){
+
+ switch (portId) {
+ case MESSAGE_PORT_ERROR_INVALID_PARAMETER:
+ ReportError(InvalidValuesException
+ ("The input parameter contains an invalid value."),out);
break;
- case MESSAGEPORT_ERROR_IO_ERROR:
- o["io_error"] = picojson::value(true);
+ case MESSAGE_PORT_ERROR_OUT_OF_MEMORY:
+ ReportError(UnknownException("Out of memory."),out);
break;
+ case MESSAGE_PORT_ERROR_IO_ERROR:
+ ReportError(UnknownException("Internal I/O error ocurred."),out);
+ break;
default:
- o["unknown_error"] = picojson::value(true);
- }
- } else {
- MessageportInstance::RegisterLocalMessageport(mp_id, this);
- o["id"] = picojson::value(static_cast<double>(mp_id));
- o["success"] = picojson::value(true);
+ ReportError(UnknownException("Unknown Exception"),out);
+ break;
+ }
}
+ else
+ ReportSuccess(picojson::value(static_cast<double>(portId)), out);
+
}
-void MessageportInstance::HandleRequestRemoteMessagePort(
- const picojson::value& msg, picojson::value::object& o) {
- if (ErrorIfMessageHasNoKey(msg, "messagePortName", o))
- return;
- if (ErrorIfMessageHasNoKey(msg, "trusted", o))
- return;
- if (ErrorIfMessageHasNoKey(msg, "appId", o))
- return;
-
- std::string message_port_name = msg.get("messagePortName").to_str();
- std::string app_id = msg.get("appId").to_str();
- int ret_val;
- bool exist;
-
- if (msg.get("trusted").get<bool>()) {
- ret_val = messageport_check_trusted_remote_port(app_id.c_str(),
- message_port_name.c_str(), &exist);
- } else {
- ret_val = messageport_check_remote_port(app_id.c_str(),
- message_port_name.c_str(), &exist);
- }
+void MessageportInstance::
+ MessagePortManagerRequestremotemessageport
+ (const picojson::value& args, picojson::object& out) {
+ CHECK_EXIST(args, "remoteMessagePortName", out)
+
+ const std::string& remoteMessagePortName =
+ args.get("remoteMessagePortName").get<std::string>();
+ const std::string& appId = args.get("appId").get<std::string>();
+
+ int ret;
+ bool portCheck;
- if (!exist) {
- o["not_found"] = picojson::value(true);
- return;
+ ret = message_port_check_remote_port(appId.c_str(),
+ remoteMessagePortName.c_str(), &portCheck);
+
+ LoggerD("Checking remote port of %s: %s", remoteMessagePortName.c_str(),
+ portCheck ? "true" : "false");
+
+ if(ret == MESSAGE_PORT_ERROR_NONE){
+ if (portCheck) ReportSuccess(out);
+ else
+ ReportError(NotFoundException
+ ("The port of the target application is not found"), out);
}
+ else if(ret == MESSAGE_PORT_ERROR_INVALID_PARAMETER)
+ ReportError(InvalidValuesException
+ ("An input parameter contains an invalid value."),out);
+ else if(ret == MESSAGE_PORT_ERROR_OUT_OF_MEMORY)
+ ReportError(UnknownException("Out of memory."), out);
+ else if(ret == MESSAGE_PORT_ERROR_IO_ERROR)
+ ReportError(UnknownException("Internal I/O error ocurred."),out);
+ else
+ ReportError(UnknownException("Unknown Error"),out);
+
+}
- if (ret_val < 0) {
- switch (ret_val) {
- case MESSAGEPORT_ERROR_INVALID_PARAMETER:
- o["invalid_parameter"] = picojson::value(true);
- break;
- case MESSAGEPORT_ERROR_OUT_OF_MEMORY:
- o["out_of_memory"] = picojson::value(true);
- break;
- case MESSAGEPORT_ERROR_IO_ERROR:
- o["io_error"] = picojson::value(true);
- break;
- case MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH:
- o["certificate_error"] = picojson::value(true);
- break;
- default:
- o["unknown_error"] = picojson::value(true);
+void MessageportInstance::
+ MessagePortManagerRequesttrustedremotemessageport
+ (const picojson::value& args, picojson::object& out) {
+ CHECK_EXIST(args, "remoteMessagePortName", out)
+
+ const std::string& remoteMessagePortName =
+ args.get("remoteMessagePortName").get<std::string>();
+ const std::string& appId = args.get("appId").get<std::string>();
+
+ bool portCheck;
+ int ret;
+
+ ret = message_port_check_trusted_remote_port
+ (appId.c_str(), remoteMessagePortName.c_str(), &portCheck);
+
+ LoggerD("Checking trusted remoteport of %s:%s",
+ remoteMessagePortName.c_str(), portCheck ? "true":"false");
+
+
+ if(ret == MESSAGE_PORT_ERROR_NONE){
+ if (portCheck) ReportSuccess(out);
+ else
+ ReportError(NotFoundException
+ ("The port of the target application is not found"), out);
}
- } else {
- o["success"] = picojson::value(true);
- }
+ else if(ret == MESSAGE_PORT_ERROR_INVALID_PARAMETER)
+ ReportError(InvalidValuesException
+ ("An input parameter contains an invalid value."),out);
+ else if(ret == MESSAGE_PORT_ERROR_OUT_OF_MEMORY)
+ ReportError(UnknownException("Out of memory."), out);
+ else if(ret == MESSAGE_PORT_ERROR_IO_ERROR)
+ ReportError(UnknownException("Internal I/O error ocurred."),out);
+ else if(ret == MESSAGE_PORT_ERROR_CERTIFICATE_NOT_MATCH)
+ ReportError(UnknownException(
+ "The remote application is not signed with the same certificate"),out);
+ else
+ ReportError(UnknownException("Unknown Error"),out);
+
}
-void MessageportInstance::HandleSendMessage(
- const picojson::value& msg, picojson::value::object& o) {
- if (ErrorIfMessageHasNoKey(msg, "messagePortName", o))
- return;
- if (ErrorIfMessageHasNoKey(msg, "trusted", o))
- return;
- if (ErrorIfMessageHasNoKey(msg, "appId", o))
- return;
- if (ErrorIfMessageHasNoKey(msg, "localPort", o))
- return;
- if (ErrorIfMessageHasNoKey(msg, "data", o))
- return;
-
- std::string app_id = msg.get("appId").to_str();
- std::string message_port_name = msg.get("messagePortName").to_str();
- int local_port = static_cast<int>(msg.get("localPort").get<double>());
- std::vector<picojson::value> data = msg.get("data").get<picojson::array>();
- int ret_val;
+void MessageportInstance::RemoteMessagePortSendmessage
+ (const picojson::value& args, picojson::object& out) {
+ const std::string& appId = args.get("appId").get<std::string>();
+ const std::string& message_port_name =
+ args.get("messagePortName").get<std::string>();
+ std::vector<picojson::value> data = args.get("data").get<picojson::array>();
+
+ long local_port_id =
+ static_cast<long>(args.get("local_port_id").get<double>());
+ bool trusted = args.get("trusted").get<bool>();
+
+ int result;
+
bundle* bundle = bundle_create();
for (picojson::value::array::iterator it = data.begin();
- it != data.end(); it++) {
- bundle_add(bundle, (*it).get("key").to_str().c_str(),
- (*it).get("value").to_str().c_str());
+ it != data.end(); it++) {
+ bundle_add(bundle, (*it).get("key").to_str().c_str(),
+ (*it).get("value").to_str().c_str());
}
- if (msg.get("trusted").get<bool>()) {
- if (local_port < 0) {
- ret_val = messageport_send_trusted_message(app_id.c_str(),
- message_port_name.c_str(), bundle);
- } else {
- ret_val = messageport_send_bidirectional_trusted_message(local_port,
- app_id.c_str(), message_port_name.c_str(), bundle);
- }
+ LoggerD("%s to %s", trusted ?
+ "Sending trusted messages" : "Sending normal messages",
+ message_port_name.c_str());
+
+ if (trusted) {
+ if (local_port_id < 0) {
+ result = message_port_send_trusted_message
+ (appId.c_str(), message_port_name.c_str(), bundle);
+ } else {
+ result = message_port_send_trusted_message_with_local_port
+ (appId.c_str(), message_port_name.c_str(), bundle, local_port_id);
+ }
} else {
- if (local_port < 0) {
- ret_val = messageport_send_message(app_id.c_str(),
- message_port_name.c_str(), bundle);
+ if (local_port_id < 0) {
+ result = message_port_send_message
+ (appId.c_str(), message_port_name.c_str(), bundle);
} else {
- ret_val = messageport_send_bidirectional_message(local_port,
- app_id.c_str(), message_port_name.c_str(), bundle);
+ result = message_port_send_message_with_local_port
+ (appId.c_str(), message_port_name.c_str(), bundle, local_port_id);
}
}
bundle_free(bundle);
- if (ret_val < 0) {
- switch (ret_val) {
- case MESSAGEPORT_ERROR_INVALID_PARAMETER:
- o["invalid_parameter"] = picojson::value(true);
- return;
- case MESSAGEPORT_ERROR_OUT_OF_MEMORY:
- o["out_of_memory"] = picojson::value(true);
- return;
- case MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND:
- o["messageport_not_found"] = picojson::value(true);
- return;
- case MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH:
- o["certificate_not_found"] = picojson::value(true);
- return;
- case MESSAGEPORT_ERROR_MAX_EXCEEDED:
- o["max_exceeded"] = picojson::value(true);
- return;
- case MESSAGEPORT_ERROR_IO_ERROR:
- o["io_error"] = picojson::value(true);
- return;
- default:
- o["unknown_error"] = picojson::value(true);
- }
- } else {
- o["success"] = picojson::value(true);
- }
+ if(result == MESSAGE_PORT_ERROR_NONE)
+ ReportSuccess(out);
+ else if(result == MESSAGE_PORT_ERROR_INVALID_PARAMETER)
+ ReportError(InvalidValuesException
+ ("An input parameter contains an invalid value."),out);
+ else if(result == MESSAGE_PORT_ERROR_PORT_NOT_FOUND)
+ ReportError(NotFoundException
+ ("The port of the target application is not found"),out);
+ else if(result == MESSAGE_PORT_ERROR_MAX_EXCEEDED)
+ ReportError(QuotaExceededException
+ ("The size of message has exceeded the maximum limit."),out);
+ else if(result == MESSAGE_PORT_ERROR_RESOURCE_UNAVAILABLE)
+ ReportError(UnknownException("A resource is temporarily unavailable."),out);
+ else if(result == MESSAGE_PORT_ERROR_OUT_OF_MEMORY)
+ ReportError(UnknownException("Out of memory."),out);
+ else if(result == MESSAGE_PORT_ERROR_IO_ERROR)
+ ReportError(UnknownException("Internal I/O error ocurred."),out);
+ else if(result == MESSAGE_PORT_ERROR_CERTIFICATE_NOT_MATCH)
+ ReportError(UnknownException
+ ("The remote application is not signed with the same certificate"),out);
+ else ReportError(UnknownException("Unknown Exception"),out);
+
}
+
+
+#undef CHECK_EXIST
+
+} // namespace messageport
+} // namespace extension
-// Copyright (c) 2013 Intel Corporation. All rights reserved.
+// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#define MESSAGEPORT_MESSAGEPORT_INSTANCE_H_
#include <bundle.h>
-
-#include <map>
+#include <message_port.h>
#include "common/extension.h"
-#include "common/picojson.h"
-class MessageportInstance : public common::Instance {
+namespace extension {
+namespace messageport {
+
+class MessageportInstance : public common::ParsedInstance {
+ public:
+ MessageportInstance();
+ virtual ~MessageportInstance();
+
private:
- // common::Instance implementation.
- virtual void HandleMessage(const char*) {}
- virtual void HandleSyncMessage(const char* msg);
-
- // Command handlers.
- void HandleRequestLocalMessagePort(const picojson::value& msg,
- picojson::value::object& reply);
- void HandleRequestRemoteMessagePort(const picojson::value& msg,
- picojson::value::object& reply);
- void HandleSendMessage(const picojson::value& msg,
- picojson::value::object& reply);
-
- // Messageport ID <-> MessageportInstance mapping.
- typedef std::map<int, MessageportInstance *> MessageportIdToInstanceMap;
- static MessageportIdToInstanceMap mp_id_to_instance_map_;
-
- static void RegisterLocalMessageport(int mp_id,
- MessageportInstance *instance);
- static MessageportInstance* GetInstanceByPortId(int mp_id);
-
- // bundle_iterate() callback.
- static void BundleJsonIterator(const char *key, const char *value,
- void *data);
-
- // messageport_register[_trusted]_local_port() implementation.
- void OnReceiveLocalMessage(int id, const char* remote_app_id,
- const char* remote_port, bool trusted_message, bundle* data);
- static void OnReceiveLocalMessageThunk(int id, const char* remote_app_id,
- const char* remote_port, bool trusted_message, bundle* data);
+ void MessagePortManagerRequestlocalmessageport
+ (const picojson::value& args, picojson::object& out);
+ void MessagePortManagerRequesttrustedlocalmessageport
+ (const picojson::value& args, picojson::object& out);
+ void MessagePortManagerRequestremotemessageport
+ (const picojson::value& args, picojson::object& out);
+ void MessagePortManagerRequesttrustedremotemessageport
+ (const picojson::value& args, picojson::object& out);
+ void RemoteMessagePortSendmessage
+ (const picojson::value& args, picojson::object& out);
};
+} // namespace messageport
+} // namespace extension
+
#endif // MESSAGEPORT_MESSAGEPORT_INSTANCE_H_