Implementation of IPC Asynchronous Message Support.
authorTae-Jeong Lee <taejeong.lee@samsung.com>
Fri, 28 Jun 2013 12:04:56 +0000 (21:04 +0900)
committerTae-Jeong Lee <taejeong.lee@samsung.com>
Fri, 28 Jun 2013 12:46:13 +0000 (21:46 +0900)
 - sendAsyncMessageToUiProcess()
 - ignoreAsyncMessageReply()

[Issue#] N/A
[Problem] Requirement from webapi team.
[Cause] N/A
[Solution] Add IPC Asynchronous Message Support Feature.

Change-Id: I158eebfd5690e6f1e0828da785cac3568f1f9017

src/plugins-ipc-message/ipc_message_support.cpp
src/plugins-ipc-message/ipc_message_support.h
src/standards/W3C/Widget/CMakeLists.txt

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());
+}
index fa96e3f..d2c5384 100644 (file)
 #ifndef WRT_SRC_IPC_MESSAGE_SUPPORT
 #define WRT_SRC_IPC_MESSAGE_SUPPORT
 
+#include <memory>
+#include <map>
 #include <string>
 #include <WKBundle.h>
+#include <EWebKit2.h>
+
+typedef void (*AsyncReplyCallback)(unsigned int, void*, const char*);
 
 namespace IPCMessageSupport {
+
+static const char * const REPLY_ASYNC = "ToInjectedBundle::REPLY_ASYNC";
+static const char * const TIZEN_CHANGE_USERAGENT = "tizen://changeUA";
+static const char * const TIZEN_DELETE_ALL_COOKIES = "tizen://deleteAllCookies";
+
+class AsyncConnection
+{
+  public:
+    AsyncReplyCallback replyCallback;
+    void* data;
+
+    AsyncConnection(AsyncReplyCallback r, void* d) :
+        replyCallback(r),
+        data(d)
+    {
+    }
+};
+
+typedef std::shared_ptr<AsyncConnection> AsyncConnectionPtr;
+typedef std::map<unsigned int, AsyncConnectionPtr> AsyncConnectionMap;
+
+class AsyncConnectionManager
+{
+  private:
+    AsyncConnectionMap m_connectionMap;
+
+  public:
+    ~AsyncConnectionManager();
+
+    // Singleton
+    static AsyncConnectionManager &instance();
+
+    int addConnection(AsyncConnectionPtr connection);
+    bool removeConnection(int handle);
+    AsyncConnectionPtr getConnection(int handle);
+
+};
+
 void setWKBundleRef(WKBundleRef bundleRef);
 void setXwindowHandle(unsigned int handle);
 const char* sendMessageToUiProcess(const char* name, const char* body);
+int  sendAsyncMessageToUiProcess(const char* name, const char* body, AsyncReplyCallback replyCallback, void* data);
+void* ignoreAsyncMessageReply(int handle);
+void replyAsyncMessageToWebProcess(Ewk_Context* ewkContext, int handle, const char* body);
 }
 
 #endif // WRT_SRC_IPC_MESSAGE_SUPPORT
\ No newline at end of file
index fe0174f..c586b31 100644 (file)
@@ -29,6 +29,7 @@ include_directories(
   ${API_WIDGET_PATH}
   ${webkit2_INCLUDE_DIRS}
   ${plugin-types_INCLUDE_DIRS}
+  ${PLUGINS_IPC_MESSAGE_DIRS}
 )
 
 add_library(${TARGET_NAME} SHARED ${SRCS})
@@ -41,6 +42,7 @@ target_link_libraries(${TARGET_NAME}
   wrt-plugins-localstorage
   wrt-plugins-storageevent
   wrt-dispatch-event
+  wrt-plugins-ipc-message
 )
 
 INSTALL(TARGETS ${TARGET_NAME} LIBRARY DESTINATION /usr/lib/wrt-plugins/w3c-widget-interface)