Implementation of IPC Asynchronous Message Support.
[platform/framework/web/wrt-plugins-common.git] / src / plugins-ipc-message / ipc_message_support.cpp
index 5d2f290..547efae 100644 (file)
@@ -36,7 +36,7 @@ namespace {
 const char* const TIZEN_GET_WINDOW_HANDLE = "tizen://getWindowHandle";
 const char* const TIZEN_CLEAR_ALL_COOKIES = "tizen://clearAllCookies";
 
-std::string toString(WKStringRef str)
+static std::string toString(WKStringRef str)
 {
     if (WKStringIsEmpty(str)) {
         return std::string();
@@ -47,7 +47,7 @@ std::string toString(WKStringRef str)
     return buffer;
 }
 
-std::string sendSyncMessage(const char* name, const char* body)
+static std::string sendSyncMessage(const char* name, const char* body)
 {
     WKStringRef nameWKString = WKStringCreateWithUTF8CString(name);
     WKStringRef bodyWKString = NULL;
@@ -72,7 +72,7 @@ std::string sendSyncMessage(const char* name, const char* body)
     }
 }
 
-void sendAsyncMessage(const char* name, const char* body)
+static void sendPostMessage(const char* name, const char* body)
 {
     WKStringRef nameWKString = WKStringCreateWithUTF8CString(name);
     WKStringRef bodyWKString = NULL;
@@ -88,8 +88,79 @@ void sendAsyncMessage(const char* name, const char* body)
         WKRelease(bodyWKString);
     }
 }
+
+static int sendAsyncMessage(const char* name, const char* body, AsyncReplyCallback replyCallback, void* data)
+{
+    using namespace IPCMessageSupport;
+
+    int handle = AsyncConnectionManager::instance().addConnection(AsyncConnectionPtr(new AsyncConnection(replyCallback, data)));
+
+    std::string strBody = body;
+    std::stringstream ss;
+
+    ss << handle;
+    strBody = ss.str() + "_" + strBody;
+
+    sendPostMessage(name, strBody.c_str());
+
+    return handle;
+}
+
+} // namespace
+
+
+namespace IPCMessageSupport {
+
+AsyncConnectionManager::~AsyncConnectionManager()
+{
+    m_connectionMap.clear();
+}
+
+AsyncConnectionManager &AsyncConnectionManager::instance()
+{
+    static AsyncConnectionManager instance;
+
+    return instance;
+}
+
+int AsyncConnectionManager::addConnection(AsyncConnectionPtr connection)
+{
+    static int latestHandle = -1;
+    int newHandle;
+
+    latestHandle++;
+    if (latestHandle < 0) latestHandle = 0;
+
+    newHandle = latestHandle;
+
+    m_connectionMap.insert(AsyncConnectionMap::value_type(newHandle, connection));
+
+    return newHandle;
+}
+
+bool AsyncConnectionManager::removeConnection(int handle)
+{
+    bool ret = (m_connectionMap.erase(handle) == 1);
+
+    return ret;
+}
+
+AsyncConnectionPtr AsyncConnectionManager::getConnection(int handle)
+{
+    AsyncConnectionMap::iterator iter = m_connectionMap.find(handle);
+
+    if (iter != m_connectionMap.end())
+    {
+        return iter->second;
+    }
+
+    return AsyncConnectionPtr();
 }
 
+
+} // namespace IPCMessageSupport
+
+
 void IPCMessageSupport::setWKBundleRef(WKBundleRef bundleRef)
 {
     LogDebug("setWKBundleRef called");
@@ -134,9 +205,70 @@ const char* IPCMessageSupport::sendMessageToUiProcess(
 
     // tizen://clearAllCookies
     if (!strcmp(name, TIZEN_CLEAR_ALL_COOKIES)) {
-        sendAsyncMessage(name, body);
+        sendPostMessage(name, body);
         return NULL;
     }
 
     return NULL;
 }
+
+int IPCMessageSupport::sendAsyncMessageToUiProcess(const char* name, const char* body, AsyncReplyCallback replyCallback, void* data)
+{
+    LogDebug("sendAsyncMessageToUiProcess called");
+
+    if (s_injectedBundleRef == NULL)
+    {
+        LogError("UI Process information isn't set");
+        return -1;
+    }
+
+    if (name == NULL)
+    {
+        LogError("msg name is null!");
+        return -1;
+    }
+
+    if (body == NULL)
+    {
+        body = "";
+    }
+
+    LogDebug("name = [" << name << "]");
+    LogDebug("body = [" << body << "]");
+
+    return sendAsyncMessage(name, body, replyCallback, data);
+}
+
+void* IPCMessageSupport::ignoreAsyncMessageReply(int handle)
+{
+    LogDebug("ignoreAsyncMessageReply called");
+
+    AsyncConnectionPtr connection = AsyncConnectionManager::instance().getConnection(handle);
+
+    if (!connection)
+    {
+        return NULL;
+    }
+
+    AsyncConnectionManager::instance().removeConnection(handle);
+
+    return connection->data;
+}
+
+void IPCMessageSupport::replyAsyncMessageToWebProcess(Ewk_Context* ewkContext, int handle, const char* body)
+{
+    LogDebug("replyAsyncMessageToWebProcess called");
+
+    if (ewkContext == NULL)
+    {
+        return;
+    }
+
+    std::string strBody = (body) ? (body) : "";
+    std::stringstream ss;
+    ss << handle;
+
+    strBody = ss.str() + "_" + strBody;
+
+    ewk_context_message_post_to_injected_bundle(ewkContext, REPLY_ASYNC, strBody.c_str());
+}