d6a1435e80f305d0dbf55b5ec3447eb712016b69
[platform/framework/web/crosswalk-tizen.git] / src / bundle / runtime_ipc_client.cc
1 // Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "bundle/runtime_ipc_client.h"
6
7 #include "common/logger.h"
8 #include "common/string_utils.h"
9
10 namespace wrt {
11
12 RuntimeIPCClient::JSCallback::JSCallback(v8::Isolate* isolate,
13                                          v8::Handle<v8::Function> callback) {
14   callback_.Reset(isolate, callback);
15 }
16
17 RuntimeIPCClient::JSCallback::~JSCallback() {
18   callback_.Reset();
19 }
20
21 void RuntimeIPCClient::JSCallback::Call(v8::Isolate* isolate,
22                                         v8::Handle<v8::Value> args[]) {
23   if (!callback_.IsEmpty()) {
24     v8::HandleScope handle_scope(isolate);
25     v8::Handle<v8::Function> func =
26         v8::Local<v8::Function>::New(isolate, callback_);
27     func->Call(func, 1, args);
28   }
29 }
30
31 // static
32 RuntimeIPCClient* RuntimeIPCClient::GetInstance() {
33   static RuntimeIPCClient self;
34   return &self;
35 }
36
37 RuntimeIPCClient::RuntimeIPCClient() : routing_id_(0) {
38 }
39
40 void RuntimeIPCClient::SendMessage(const std::string& type,
41                                    const std::string& value) {
42   Ewk_IPC_Wrt_Message_Data* msg = ewk_ipc_wrt_message_data_new();
43   ewk_ipc_wrt_message_data_id_set(msg, "");
44   ewk_ipc_wrt_message_data_type_set(msg, type.c_str());
45   ewk_ipc_wrt_message_data_value_set(msg, value.c_str());
46
47   if (routing_id_ > 0) {
48     if (!ewk_ipc_plugins_message_send(routing_id_, msg)) {
49       LOGGER(ERROR) << "Failed to send message to runtime using ewk_ipc.";
50     }
51   }
52
53   ewk_ipc_wrt_message_data_del(msg);
54 }
55
56 std::string RuntimeIPCClient::SendSyncMessage(const std::string& type,
57                                               const std::string& value) {
58   Ewk_IPC_Wrt_Message_Data* msg = ewk_ipc_wrt_message_data_new();
59   ewk_ipc_wrt_message_data_type_set(msg, type.c_str());
60   ewk_ipc_wrt_message_data_value_set(msg, value.c_str());
61
62   if (routing_id_ > 0) {
63     if (!ewk_ipc_plugins_sync_message_send(routing_id_, msg)) {
64       LOGGER(ERROR) << "Failed to send message to runtime using ewk_ipc.";
65       ewk_ipc_wrt_message_data_del(msg);
66       return std::string();
67     }
68   }
69
70   Eina_Stringshare* msg_value = ewk_ipc_wrt_message_data_value_get(msg);
71
72   std::string result(msg_value);
73   eina_stringshare_del(msg_value);
74   ewk_ipc_wrt_message_data_del(msg);
75
76   return result;
77 }
78
79 void RuntimeIPCClient::SendAsyncMessage(const std::string& type,
80                                         const std::string& value,
81                                         ReplyCallback callback) {
82   std::string msg_id = utils::GenerateUUID();
83
84   Ewk_IPC_Wrt_Message_Data* msg = ewk_ipc_wrt_message_data_new();
85   ewk_ipc_wrt_message_data_id_set(msg, msg_id.c_str());
86   ewk_ipc_wrt_message_data_type_set(msg, type.c_str());
87   ewk_ipc_wrt_message_data_value_set(msg, value.c_str());
88
89   if (routing_id_ > 0) {
90     if (!ewk_ipc_plugins_message_send(routing_id_, msg)) {
91       LOGGER(ERROR) << "Failed to send message to runtime using ewk_ipc.";
92       ewk_ipc_wrt_message_data_del(msg);
93       return;
94     }
95   }
96
97   callbacks_[msg_id] = callback;
98
99   ewk_ipc_wrt_message_data_del(msg);
100 }
101
102 void RuntimeIPCClient::HandleMessageFromRuntime(
103     const Ewk_IPC_Wrt_Message_Data* msg) {
104   if (msg == NULL) {
105     LOGGER(ERROR) << "received message is NULL";
106     return;
107   }
108
109   Eina_Stringshare* msg_refid = ewk_ipc_wrt_message_data_reference_id_get(msg);
110
111   if (msg_refid == NULL || !strcmp(msg_refid, "")) {
112     if (msg_refid) eina_stringshare_del(msg_refid);
113     LOGGER(ERROR) << "No reference id of received message.";
114     return;
115   }
116
117   auto it = callbacks_.find(msg_refid);
118   if (it == callbacks_.end()) {
119     eina_stringshare_del(msg_refid);
120     LOGGER(ERROR) << "No registered callback with reference id : " << msg_refid;
121     return;
122   }
123
124   Eina_Stringshare* msg_type = ewk_ipc_wrt_message_data_type_get(msg);
125   Eina_Stringshare* msg_value = ewk_ipc_wrt_message_data_value_get(msg);
126
127   ReplyCallback func = it->second;
128   if (func) {
129     func(msg_type, msg_value);
130   }
131
132   callbacks_.erase(it);
133
134   eina_stringshare_del(msg_refid);
135   eina_stringshare_del(msg_type);
136   eina_stringshare_del(msg_value);
137 }
138
139 }  // namespace wrt