Fix crashes of SendRuntimeMessage functions.
authorWonYoung Choi <wy80.choi@samsung.com>
Wed, 20 May 2015 09:54:58 +0000 (18:54 +0900)
committerWonYoung Choi <wy80.choi@samsung.com>
Wed, 20 May 2015 09:59:27 +0000 (18:59 +0900)
Change-Id: Iea672cffafbfe546f540ca0469166693544b8807

src/bundle/extension_module.cc
src/bundle/injected_bundle.cc
src/bundle/runtime_ipc_client.cc
src/bundle/runtime_ipc_client.h
src/runtime/web_application.cc

index c1e2b5b9c5541f41385260666fe25df996da6dd1..2b1df89a6d8e0582c99b319c7f1c86f9ce782d21 100755 (executable)
@@ -469,18 +469,22 @@ void ExtensionModule::SendRuntimeAsyncMessageCallback(
     }
   }
 
-  auto callback = [](const std::string& /*type*/,
-                     const std::string& value,
-                     RuntimeIPCClient::JSCallback* js_callback) -> void {
-    if (js_callback) {
-      v8::Handle<v8::Value> args[] = {
-          v8::String::NewFromUtf8(js_callback->isolate(), value.c_str()) };
-      js_callback->Call(args);
+  auto callback = [js_callback](const std::string& /*type*/,
+                     const std::string& value) -> void {
+    if (!js_callback) {
+      LOGGER(ERROR) << "JsCallback is NULL.";
+      return;
     }
+    v8::Isolate* isolate = v8::Isolate::GetCurrent();
+    v8::HandleScope handle_scope(isolate);
+    v8::Handle<v8::Value> args[] = {
+        v8::String::NewFromUtf8(isolate, value.c_str()) };
+    js_callback->Call(isolate, args);
+    delete js_callback;
   };
 
   RuntimeIPCClient* rc = RuntimeIPCClient::GetInstance();
-  rc->SendAsyncMessage(std::string(*type), value_str, callback, js_callback);
+  rc->SendAsyncMessage(std::string(*type), value_str, callback);
 
   result.Set(true);
 }
index 5409445bef4203b510a2c95015365b446fb2f3d9..593e3bf8c6150966b2fead7e14e9ffa9ae1e664a 100755 (executable)
@@ -5,6 +5,7 @@
 #include <unistd.h>
 #include <v8.h>
 #include <ewk_ipc_message.h>
+#include <Ecore.h>
 #include <string>
 #include <memory>
 
@@ -54,6 +55,7 @@ class BundleGlobalData {
 
 extern "C" void DynamicSetWidgetInfo(const char* tizen_id) {
   LOGGER(DEBUG) << "InjectedBundle::DynamicSetWidgetInfo !!" << tizen_id;
+  ecore_init();
   wrt::BundleGlobalData::GetInstance()->Initialize(tizen_id);
 }
 
@@ -92,7 +94,7 @@ extern "C" void DynamicPluginStopSession(
 
 extern "C" void DynamicUrlParsing(
     std::string* old_url, std::string* new_url, const char* tizen_id) {
-  LOGGER(DEBUG) << "InjectedBundle::DynamicUrlParsing !!" << tizen_id;
+  // LOGGER(DEBUG) << "InjectedBundle::DynamicUrlParsing !!" << tizen_id;
   auto res_manager = wrt::BundleGlobalData::GetInstance()->resource_manager();
   if (res_manager == NULL) {
     LOGGER(ERROR) << "Widget Info was not set, Resource Manager is NULL";
@@ -103,7 +105,7 @@ extern "C" void DynamicUrlParsing(
 }
 
 extern "C" void DynamicDatabaseAttach(int /*attach*/) {
-  LOGGER(DEBUG) << "InjectedBundle::DynamicDatabaseAttach !!";
+  // LOGGER(DEBUG) << "InjectedBundle::DynamicDatabaseAttach !!";
 }
 
 extern "C" void DynamicOnIPCMessage(const Ewk_IPC_Wrt_Message_Data& data) {
@@ -113,5 +115,5 @@ extern "C" void DynamicOnIPCMessage(const Ewk_IPC_Wrt_Message_Data& data) {
 }
 
 extern "C" void DynamicPreloading() {
-  LOGGER(DEBUG) << "InjectedBundle::DynamicPreloading !!";
+  // LOGGER(DEBUG) << "InjectedBundle::DynamicPreloading !!";
 }
index b49a3afed8d4d76c53c0a3708ea85f17d3b64dc6..d6a1435e80f305d0dbf55b5ec3447eb712016b69 100644 (file)
@@ -10,8 +10,7 @@
 namespace wrt {
 
 RuntimeIPCClient::JSCallback::JSCallback(v8::Isolate* isolate,
-                                         v8::Handle<v8::Function> callback)
-    : isolate_(isolate) {
+                                         v8::Handle<v8::Function> callback) {
   callback_.Reset(isolate, callback);
 }
 
@@ -19,11 +18,12 @@ RuntimeIPCClient::JSCallback::~JSCallback() {
   callback_.Reset();
 }
 
-void RuntimeIPCClient::JSCallback::Call(v8::Handle<v8::Value> args[]) {
+void RuntimeIPCClient::JSCallback::Call(v8::Isolate* isolate,
+                                        v8::Handle<v8::Value> args[]) {
   if (!callback_.IsEmpty()) {
-    v8::HandleScope handle_scope(isolate_);
+    v8::HandleScope handle_scope(isolate);
     v8::Handle<v8::Function> func =
-        v8::Local<v8::Function>::New(isolate_, callback_);
+        v8::Local<v8::Function>::New(isolate, callback_);
     func->Call(func, 1, args);
   }
 }
@@ -78,8 +78,7 @@ std::string RuntimeIPCClient::SendSyncMessage(const std::string& type,
 
 void RuntimeIPCClient::SendAsyncMessage(const std::string& type,
                                         const std::string& value,
-                                        ReplyCallback callback,
-                                        JSCallback* js_callback) {
+                                        ReplyCallback callback) {
   std::string msg_id = utils::GenerateUUID();
 
   Ewk_IPC_Wrt_Message_Data* msg = ewk_ipc_wrt_message_data_new();
@@ -95,8 +94,7 @@ void RuntimeIPCClient::SendAsyncMessage(const std::string& type,
     }
   }
 
-  callbacks_[msg_id].callback = callback;
-  callbacks_[msg_id].js_callback = js_callback;
+  callbacks_[msg_id] = callback;
 
   ewk_ipc_wrt_message_data_del(msg);
 }
@@ -126,8 +124,11 @@ void RuntimeIPCClient::HandleMessageFromRuntime(
   Eina_Stringshare* msg_type = ewk_ipc_wrt_message_data_type_get(msg);
   Eina_Stringshare* msg_value = ewk_ipc_wrt_message_data_value_get(msg);
 
-  const AsyncData& async_data = it->second;
-  async_data.callback(msg_type, msg_value, async_data.js_callback);
+  ReplyCallback func = it->second;
+  if (func) {
+    func(msg_type, msg_value);
+  }
+
   callbacks_.erase(it);
 
   eina_stringshare_del(msg_refid);
index a09827004913048ceae8f675cee466572d9ff899..6951574f09994adfcc62e6fb9edff60e0e8e5fa9 100644 (file)
@@ -21,17 +21,13 @@ class RuntimeIPCClient {
                         v8::Handle<v8::Function> callback);
     ~JSCallback();
 
-    v8::Isolate* isolate() const { return isolate_; }
-
-    void Call(v8::Handle<v8::Value> args[]);
+    void Call(v8::Isolate* isolate, v8::Handle<v8::Value> args[]);
    private:
-    v8::Isolate* isolate_;
     v8::Persistent<v8::Function> callback_;
   };
 
   typedef std::function<void(const std::string& type,
-                             const std::string& value,
-                             JSCallback* js_callback)> ReplyCallback;
+                             const std::string& value)> ReplyCallback;
 
   static RuntimeIPCClient* GetInstance();
 
@@ -45,7 +41,7 @@ class RuntimeIPCClient {
   // Send message to BrowserProcess asynchronous,
   // reply message will be passed to callback function.
   void SendAsyncMessage(const std::string& type, const std::string& value,
-                        ReplyCallback callback, JSCallback* js_callback);
+                        ReplyCallback callback);
 
   void HandleMessageFromRuntime(const Ewk_IPC_Wrt_Message_Data* msg);
 
@@ -53,20 +49,10 @@ class RuntimeIPCClient {
   void set_routing_id(int routing_id) { routing_id_ = routing_id; }
 
  private:
-  class AsyncData {
-   public:
-    ~AsyncData() {
-      if (js_callback) delete js_callback;
-    }
-
-    ReplyCallback callback;
-    JSCallback* js_callback;
-  };
-
   RuntimeIPCClient();
 
   int routing_id_;
-  std::map<std::string, AsyncData> callbacks_;
+  std::map<std::string, ReplyCallback> callbacks_;
 };
 
 }  // namespace wrt
index 0678c79539f48b4f1c1288ca91dc049256dd27db..cd2b67aa9179bb638aef2b5cd537bd486c4d275f 100755 (executable)
@@ -515,7 +515,17 @@ void WebApplication::OnReceivedWrtMessage(
     ewk_ipc_wrt_message_data_del(ans);
   } else if (TYPE_IS("tizen://test-sync")) {
     // TODO(wy80.choi): this type should be removed after finish test
-    ewk_ipc_wrt_message_data_value_set(msg, "reply!!");
+    ewk_ipc_wrt_message_data_value_set(msg, "Reply!!");
+  } else if (TYPE_IS("tizen://test-async")) {
+    // TODO(wy80.choi): this type should be removed after finish test
+    Ewk_IPC_Wrt_Message_Data* ans = ewk_ipc_wrt_message_data_new();
+    ewk_ipc_wrt_message_data_type_set(ans, msg_type);
+    ewk_ipc_wrt_message_data_reference_id_set(ans, msg_id);
+    ewk_ipc_wrt_message_data_value_set(ans, "Aync Reply!!");
+    if (!ewk_ipc_wrt_message_send(ewk_context_, ans)) {
+      LOGGER(ERROR) << "Failed to send response";
+    }
+    ewk_ipc_wrt_message_data_del(ans);
   }
   #undef TYPE_IS