[Messageport] Add Messageport implementation.
authorLeandro Pereira <leandro.pereira@intel.com>
Tue, 29 Oct 2013 19:35:05 +0000 (17:35 -0200)
committerLeandro Pereira <leandro.pereira@intel.com>
Tue, 5 Nov 2013 20:53:11 +0000 (18:53 -0200)
Tests are passing, but since application installation support isn't ready,
it requires a few hacks for this to actually work.

This includes writing a short wrapper program that correctly passes the path
to Tizen extensions, adding a mocked version of
`tizen.application.getCurrentApplication()` that returns the standard
`tct-messageport` package ID, installing this package, and modifying
`channel-service` so that the application ID is hardcoded.

messageport/messageport.gyp [new file with mode: 0644]
messageport/messageport_api.js [new file with mode: 0644]
messageport/messageport_extension.cc [new file with mode: 0644]
messageport/messageport_extension.h [new file with mode: 0644]
messageport/messageport_instance.cc [new file with mode: 0644]
messageport/messageport_instance.h [new file with mode: 0644]
packaging/tizen-extensions-crosswalk.spec
tizen-wrt.gyp

diff --git a/messageport/messageport.gyp b/messageport/messageport.gyp
new file mode 100644 (file)
index 0000000..8ca1606
--- /dev/null
@@ -0,0 +1,29 @@
+{
+  'includes':[
+    '../common/common.gypi',
+  ],
+  'targets': [
+    {
+      'target_name': 'tizen_messageport',
+      'type': 'loadable_module',
+      'variables': {
+        'packages': [
+          'bundle',
+          'message-port',
+        ],
+      },
+      'includes': [
+        '../common/pkg-config.gypi',
+      ],
+      'sources': [
+        'messageport_api.js',
+        'messageport_extension.cc',
+        'messageport_extension.h',
+        'messageport_instance.cc',
+        'messageport_instance.h',
+        '../common/extension.cc',
+        '../common/extension.h',
+      ],
+    },
+  ],
+}
diff --git a/messageport/messageport_api.js b/messageport/messageport_api.js
new file mode 100644 (file)
index 0000000..cadafdd
--- /dev/null
@@ -0,0 +1,257 @@
+// 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.
+
+function isInteger(value) {
+  return isFinite(value) && !isNaN(parseInt(value));
+}
+
+function isString(value) {
+  return typeof(value) === 'string' || value instanceof String;
+}
+
+function assertThrow(expr, exception) {
+  if (!expr)
+    throw new tizen.WebAPIException(tizen.WebAPIException[exception]);
+}
+
+function sendSyncMessage(cmd, msg) {
+  msg['cmd'] = cmd;
+
+  var serialized = JSON.stringify(msg);
+  return JSON.parse(extension.internal.sendSyncMessage(serialized));
+}
+
+function NativeBridge() {
+  this.listeners = {};
+  this.next_listener_id = 0;
+  this.queued_messages = {};
+}
+
+NativeBridge.prototype.requestLocalMessagePort = function(messagePortName) {
+  return sendSyncMessage('RequestLocalMessagePort', {
+    messagePortName: messagePortName,
+    trusted: false
+  });
+};
+
+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
+  });
+};
+
+NativeBridge.prototype.requestTrustedRemoteMessagePort = function(appId, messagePortName) {
+  return sendSyncMessage('RequestRemoteMessagePort', {
+    appId: appId,
+    messagePortName: messagePortName,
+    trusted: true
+  });
+};
+
+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]);
+
+  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] = [];
+  }
+
+  return this.next_listener_id;
+};
+
+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);
+  }
+
+  if (to_delete.length == 0)
+    return { not_found: 1 };
+
+  for (var i = 0, j = to_delete.length; i < j; i++)
+    this.listeners.splice(to_delete[i], 1);
+
+  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;
+  }
+
+  // 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
+  });
+};
+
+NativeBridge.prototype.toTizenException = function(nativeError) {
+  function isUndefined(v) {
+    return typeof(v) === 'undefined';
+  }
+
+  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 nativeBridge = new NativeBridge();
+
+extension.setMessageListener(function(json) {
+  var msg = JSON.parse(json);
+
+  if (msg.cmd == 'LocalMessageReceived')
+    nativeBridge.onLocalMessageReceived(msg);
+  else
+    console.error('Unknown command received: ' + msg.cmd);
+});
+
+
+function MessagePortManager() {
+}
+
+MessagePortManager.prototype.requestLocalMessagePort = function(
+    localMessagePortName) {
+  assertThrow(isString(localMessagePortName), 'TYPE_MISMATCH_ERR');
+
+  var messagePort = nativeBridge.requestLocalMessagePort(
+      localMessagePortName);
+  nativeBridge.toTizenException(messagePort);
+
+  return new LocalMessagePort(messagePort.id, localMessagePortName, false);
+};
+
+MessagePortManager.prototype.requestTrustedLocalMessagePort = function(
+    localMessagePortName) {
+  assertThrow(isString(localMessagePortName), 'TYPE_MISMATCH_ERR');
+
+  var messagePort = nativeBridge.requestTrustedLocalMessagePort(
+      localMessagePortName);
+  nativeBridge.toTizenException(messagePort);
+
+  return new LocalMessagePort(messagePort.id, localMessagePortName, true);
+};
+
+MessagePortManager.prototype.requestRemoteMessagePort = function(
+    appId, remoteMessagePortName) {
+  assertThrow(isString(appId), 'TYPE_MISMATCH_ERR');
+  assertThrow(isString(remoteMessagePortName), 'TYPE_MISMATCH_ERR');
+
+  var messagePort = nativeBridge.requestRemoteMessagePort(
+      appId, remoteMessagePortName);
+  nativeBridge.toTizenException(messagePort);
+
+  return new RemoteMessagePort(remoteMessagePortName, appId, false);
+};
+
+MessagePortManager.prototype.requestTrustedRemoteMessagePort = function(
+    appId, remoteMessagePortName) {
+  assertThrow(isString(appId), 'TYPE_MISMATCH_ERR');
+  assertThrow(isString(remoteMessagePortName), 'TYPE_MISMATCH_ERR');
+
+  var messagePort = nativeBridge.requestTrustedRemoteMessagePort(appId,
+      remoteMessagePortName);
+  nativeBridge.toTizenException(messagePort);
+
+  return new RemoteMessagePort(remoteMessagePortName, appId, true);
+};
+
+function LocalMessagePort(id, messagePortName, isTrusted) {
+  Object.defineProperties(this, {
+    '_id': { value: id, writable: false, enumerable: false },
+    'messagePortName': { value: messagePortName, writable: false },
+    'isTrusted': { value: !!isTrusted, writable: false }
+  });
+}
+
+LocalMessagePort.prototype.addMessagePortListener = function(listener) {
+  assertThrow(listener instanceof Function);
+
+  return nativeBridge.addLocalListener(this, listener);
+};
+
+LocalMessagePort.prototype.removeMessagePortListener = function(watchId) {
+  assertThrow(isInteger(watchId), 'TYPE_MISMATCH_ERR');
+  assertThrow(watchId >= 0, 'INVALID_VALUES_ERR');
+
+  var error = nativeBridge.removeLocalListener(this, watchId);
+  nativeBridge.toTizenException(error);
+};
+
+function RemoteMessagePort(messagePortName, appId, isTrusted) {
+  Object.defineProperties(this, {
+    'messagePortName': { value: messagePortName, writable: false },
+    'appId': { value: appId, writable: false },
+    'isTrusted': { value: !!isTrusted, 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');
+
+  var filtered_data = new Array(data.length);
+  try {
+    for (var i = 0, j = data.length; i < j; i++)
+      filtered_data[i] = { key: data[i].key, value: data[i].value };
+  } 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;
+  }
+
+  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;
diff --git a/messageport/messageport_extension.cc b/messageport/messageport_extension.cc
new file mode 100644 (file)
index 0000000..5a4925a
--- /dev/null
@@ -0,0 +1,23 @@
+// 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.
+
+#include "messageport/messageport_extension.h"
+
+#include "messageport/messageport_instance.h"
+
+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);
+}
+
+common::Instance* MessageportExtension::CreateInstance() {
+  return new MessageportInstance();
+}
diff --git a/messageport/messageport_extension.h b/messageport/messageport_extension.h
new file mode 100644 (file)
index 0000000..418e69f
--- /dev/null
@@ -0,0 +1,18 @@
+// 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.
+
+#ifndef MESSAGEPORT_MESSAGEPORT_EXTENSION_H_
+#define MESSAGEPORT_MESSAGEPORT_EXTENSION_H_
+
+#include "common/extension.h"
+
+class MessageportExtension : public common::Extension {
+ public:
+  MessageportExtension();
+ private:
+  // common::Extension implementation.
+  virtual common::Instance* CreateInstance();
+};
+
+#endif  // MESSAGEPORT_MESSAGEPORT_EXTENSION_H_
diff --git a/messageport/messageport_instance.cc b/messageport/messageport_instance.cc
new file mode 100644 (file)
index 0000000..801d75c
--- /dev/null
@@ -0,0 +1,281 @@
+// 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.
+
+#include "messageport/messageport_instance.h"
+
+#include <message-port.h>
+#include <string.h>
+
+#include <map>
+#include <string>
+#include <vector>
+
+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;
+}
+
+};  // namespace
+
+void MessageportInstance::RegisterLocalMessageport(int mp_id,
+      MessageportInstance *instance) {
+  MessageportInstance::mp_id_to_instance_map_[mp_id] = instance;
+}
+
+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;
+}
+
+void MessageportInstance::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);
+  o["value"] = picojson::value(v);
+  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) {
+  picojson::value::object o;
+
+  o["cmd"] = picojson::value("LocalMessageReceived");
+  o["id"] = picojson::value(static_cast<double>(id));
+  o["remoteAppId"] = picojson::value(remote_app_id);
+  o["remotePort"] = picojson::value(remote_port);
+  o["trusted"] = picojson::value(trusted_message);
+
+  picojson::value::array d;
+  bundle_iterate(data, BundleJsonIterator, &d);
+
+  o["data"] = picojson::value(d);
+
+  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::HandleSyncMessage(const char *message) {
+  picojson::value v;
+
+  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;
+  }
+
+  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());
+}
+
+void MessageportInstance::HandleRequestLocalMessagePort(
+        const picojson::value& msg, picojson::value::object& o) {
+  if (ErrorIfMessageHasNoKey(msg, "messagePortName", o))
+    return;
+  if (ErrorIfMessageHasNoKey(msg, "trusted", o))
+    return;
+
+  std::string message_port_name = msg.get("messagePortName").to_str();
+  int mp_id;
+
+  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);
+  }
+
+  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);
+        break;
+      case MESSAGEPORT_ERROR_IO_ERROR:
+        o["io_error"] = picojson::value(true);
+        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);
+  }
+}
+
+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);
+  }
+
+  if (!exist) {
+    o["not_found"] = picojson::value(true);
+    return;
+  }
+
+  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);
+    }
+  } else {
+    o["success"] = picojson::value(true);
+  }
+}
+
+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;
+  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());
+  }
+
+  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);
+    }
+  } else {
+    if (local_port < 0) {
+      ret_val = messageport_send_message(app_id.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);
+    }
+  }
+
+  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);
+  }
+}
diff --git a/messageport/messageport_instance.h b/messageport/messageport_instance.h
new file mode 100644 (file)
index 0000000..ea42f19
--- /dev/null
@@ -0,0 +1,48 @@
+// 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.
+
+#ifndef MESSAGEPORT_MESSAGEPORT_INSTANCE_H_
+#define MESSAGEPORT_MESSAGEPORT_INSTANCE_H_
+
+#include <bundle.h>
+
+#include <map>
+
+#include "common/extension.h"
+#include "common/picojson.h"
+
+class MessageportInstance : public common::Instance {
+ 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);
+};
+
+#endif  // MESSAGEPORT_MESSAGEPORT_INSTANCE_H_
index b0d600b..ba167f9 100644 (file)
@@ -19,8 +19,8 @@ Source4:    %{_examples_package}
 Source5:    %{_system_info_demo_package}
 Source1001: %{name}.manifest
 
-BuildRequires: python
 BuildRequires: pkgconfig(appcore-common)
+BuildRequires: pkgconfig(bluez)
 BuildRequires: pkgconfig(capi-appfw-application)
 BuildRequires: pkgconfig(capi-network-bluetooth)
 BuildRequires: pkgconfig(capi-network-connection)
@@ -32,19 +32,19 @@ BuildRequires: pkgconfig(capi-system-sensor)
 BuildRequires: pkgconfig(capi-system-system-settings)
 BuildRequires: pkgconfig(capi-telephony-sim)
 BuildRequires: pkgconfig(capi-web-favorites)
-# Evas.h is required by capi-web-favorites.
-BuildRequires: pkgconfig(evas)
 BuildRequires: pkgconfig(capi-web-url-download)
 BuildRequires: pkgconfig(dbus-glib-1)
-BuildRequires: pkgconfig(bluez)
+BuildRequires: pkgconfig(evas) # Evas.h is required by capi-web-favorites.
 BuildRequires: pkgconfig(glib-2.0)
 BuildRequires: pkgconfig(libudev)
+BuildRequires: pkgconfig(message-port)
 BuildRequires: pkgconfig(notification)
 BuildRequires: pkgconfig(pkgmgr-info)
 BuildRequires: pkgconfig(pmapi)
+BuildRequires: pkgconfig(vconf)
 BuildRequires: pkgconfig(x11)
 BuildRequires: pkgconfig(xrandr)
-BuildRequires: pkgconfig(vconf)
+BuildRequires: python
 Requires:      crosswalk
 
 %description
index 333b6af..12f9fb0 100644 (file)
@@ -23,6 +23,7 @@
           'dependencies': [
             'download/download.gyp:*',
             'bookmark/bookmark.gyp:*',
+            'messageport/messageport.gyp:*',
           ],
         }],
       ],