From: Piotr Kosko/Tizen API (PLT) /SRPOL/Engineer/Samsung Electronics
Date: Fri, 9 Jul 2021 11:47:13 +0000 (+0200)
Subject: [extension] Binary messanger implementation added
X-Git-Tag: submit/tizen/20210806.090850~2
X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F02%2F261202%2F4;p=platform%2Fcore%2Fapi%2Fwebapi-plugins.git
[extension] Binary messanger implementation added
[verification] Code compiles without errors.
Change-Id: If98eaf371ffbb47a2bf39978f9529307a9e9b06f
---
diff --git a/doc/src/assets/webapi-plugins-devel-test/src/tool/desc_gentool.cc b/doc/src/assets/webapi-plugins-devel-test/src/tool/desc_gentool.cc
index b6fda30d..93804f9f 100644
--- a/doc/src/assets/webapi-plugins-devel-test/src/tool/desc_gentool.cc
+++ b/doc/src/assets/webapi-plugins-devel-test/src/tool/desc_gentool.cc
@@ -105,7 +105,7 @@ const void* get_interface(const char* name) {
return &entryPointsInterface1;
}
- if (!strcmp(name, XW_MESSAGING_INTERFACE_1)) {
+ if (!strcmp(name, XW_MESSAGING_INTERFACE_2)) {
static const XW_MessagingInterface_1 messagingInterface1 = {
[](XW_Extension extension, XW_HandleMessageCallback handle_message) {
},
diff --git a/src/common/XW_Extension.h b/src/common/XW_Extension.h
index 5e6dd9a0..cc89536d 100644
--- a/src/common/XW_Extension.h
+++ b/src/common/XW_Extension.h
@@ -143,12 +143,14 @@ typedef struct XW_CoreInterface_1 XW_CoreInterface;
// code provided by extension.
//
-#define XW_MESSAGING_INTERFACE_1 "XW_MessagingInterface_1"
-#define XW_MESSAGING_INTERFACE XW_MESSAGING_INTERFACE_1
+#define XW_MESSAGING_INTERFACE_2 "XW_MessagingInterface_2"
+#define XW_MESSAGING_INTERFACE XW_MESSAGING_INTERFACE_2
typedef void (*XW_HandleMessageCallback)(XW_Instance instance, const char* message);
+typedef void (*XW_HandleBinaryMessageCallback)(XW_Instance instance, const char* message,
+ size_t size);
-struct XW_MessagingInterface_1 {
+struct XW_MessagingInterface_2 {
// Register a callback to be called when the JavaScript code associated
// with the extension posts a message. Note that the callback will be called
// with the XW_Instance that posted the message as well as the message
@@ -162,9 +164,14 @@ struct XW_MessagingInterface_1 {
// This function is thread-safe and can be called until the instance is
// destroyed.
void (*PostMessage)(XW_Instance instance, const char* message);
+
+ // Provides communication for binary data exchange
+ void (*RegisterBinaryMesssageCallback)(XW_Extension extension,
+ XW_HandleBinaryMessageCallback handle_message);
+ void (*PostBinaryMessage)(XW_Instance instance, const char* message, size_t size);
};
-typedef struct XW_MessagingInterface_1 XW_MessagingInterface;
+typedef struct XW_MessagingInterface_2 XW_MessagingInterface;
#ifdef __cplusplus
} // extern "C"
diff --git a/src/common/extension.cc b/src/common/extension.cc
index ca21c41d..94d17a20 100644
--- a/src/common/extension.cc
+++ b/src/common/extension.cc
@@ -182,6 +182,16 @@ void Extension::HandleMessage(XW_Instance xw_instance, const char* msg) {
instance->HandleMessage(msg);
}
+void Extension::HandleBinaryMessage(XW_Instance xw_instance, const char* msg, size_t size) {
+ ScopeLogger();
+ Instance* instance = reinterpret_cast(g_core->GetInstanceData(xw_instance));
+ if (!instance) {
+ return;
+ }
+ // TODO maybe async version will be needed in future
+ instance->HandleSyncBinaryMessage(msg, size);
+}
+
// static
void Extension::HandleSyncMessage(XW_Instance xw_instance, const char* msg) {
ScopeLogger();
@@ -215,6 +225,8 @@ int32_t Extension::XW_Initialize(XW_Extension extension, XW_GetInterface get_int
g_core->RegisterInstanceCallbacks(extension, created_instance, Extension::OnInstanceDestroyed);
g_messaging->Register(extension, Extension::HandleMessage);
g_sync_messaging->Register(extension, Extension::HandleSyncMessage);
+
+ g_messaging->RegisterBinaryMesssageCallback(extension, Extension::HandleBinaryMessage);
return XW_OK;
}
@@ -264,6 +276,18 @@ void Instance::PostMessage(Instance* that, const char* msg) {
LoggerE("Trying to post message to non-existing instance: [%p], ignoring", that);
}
+void Instance::PostMessage(Instance* that, const char* msg, size_t size) {
+ ScopeLogger();
+ if (nullptr != that) {
+ std::lock_guard lock{instances_mutex_};
+ if (all_instances_.end() != all_instances_.find(that)) {
+ that->PostMessage(msg, size);
+ return;
+ }
+ }
+ LoggerE("Trying to post message to non-existing instance: [%p], ignoring", that);
+}
+
void Instance::PostMessage(Instance* that, const picojson::value& json) {
Instance::PostMessage(that, json.serialize().c_str());
}
@@ -279,6 +303,17 @@ void Instance::PostMessage(const char* msg) {
g_messaging->PostMessage(xw_instance_, msg);
}
+void Instance::PostMessage(const char* msg, size_t size) {
+ ScopeLogger();
+ if (!xw_instance_) {
+ LoggerE(
+ "Ignoring PostMessage() in the constructor or after the "
+ "instance was destroyed.");
+ return;
+ }
+ g_messaging->PostBinaryMessage(xw_instance_, msg, size);
+}
+
void Instance::SendSyncReply(const char* reply) {
ScopeLogger();
if (!xw_instance_) {
@@ -308,6 +343,17 @@ void ParsedInstance::RegisterSyncHandler(const std::string& name, const NativeHa
handler_map_.insert(std::make_pair("#SYNC#" + name, func));
}
+void ParsedInstance::RegisterBinaryHandler(const BinaryNativeHandler& func) {
+ ScopeLogger();
+ binary_handler_vec_.push_back(func);
+}
+
+void ParsedInstance::RegisterBinarySyncHandler(const BinaryNativeHandler& func) {
+ ScopeLogger();
+ // TODO - maybe async version will be needed in future
+ binary_handler_vec_.push_back(func);
+}
+
void ParsedInstance::ReportSuccess(picojson::object& out) {
ScopeLogger();
tools::ReportSuccess(out);
@@ -338,11 +384,21 @@ void ParsedInstance::HandleMessage(const char* msg) {
HandleMessage(msg, false);
}
+void ParsedInstance::HandleBinaryMessage(const char* msg, size_t size) {
+ ScopeLogger();
+ HandleBinaryMessage(msg, size, false);
+}
+
void ParsedInstance::HandleSyncMessage(const char* msg) {
ScopeLogger();
HandleMessage(msg, true);
}
+void ParsedInstance::HandleSyncBinaryMessage(const char* msg, size_t size) {
+ ScopeLogger();
+ HandleBinaryMessage(msg, size, true);
+}
+
void ParsedInstance::HandleMessage(const char* msg, bool is_sync) {
ScopeLogger();
try {
@@ -390,6 +446,29 @@ void ParsedInstance::HandleMessage(const char* msg, bool is_sync) {
}
}
+void ParsedInstance::HandleBinaryMessage(const char* msg, size_t size, bool is_sync) {
+ ScopeLogger();
+ try {
+ // first byte is a method ID
+ auto func = binary_handler_vec_.at(msg[0]);
+
+ picojson::value result = picojson::value(picojson::object());
+ func(msg + 1, size - 1, result.get());
+
+ if (is_sync) SendSyncReply(result.serialize().c_str());
+ } catch (const std::out_of_range& e) {
+ return HandleException(UnknownException("Unknown command"));
+ } catch (const PlatformException& e) {
+ return HandleException(e);
+ } catch (const PlatformException* e) {
+ return HandleException(*e);
+ } catch (const std::exception& e) {
+ return HandleException(e);
+ } catch (...) {
+ return HandleException(UnknownException("Unknown exception"));
+ }
+}
+
void ParsedInstance::HandleException(const PlatformException& ex) {
ScopeLogger();
LoggerE("Exception: %s", ex.message().c_str());
diff --git a/src/common/extension.h b/src/common/extension.h
index 99f459e6..d4594921 100644
--- a/src/common/extension.h
+++ b/src/common/extension.h
@@ -25,6 +25,7 @@
#include
#include
#include
+#include
#include "common/XW_Extension.h"
#include "common/XW_Extension_EntryPoints.h"
@@ -82,8 +83,9 @@ class Extension {
static void OnInstanceCreated(XW_Instance xw_instance, Instance* instance); // modified
static void OnInstanceDestroyed(XW_Instance xw_instance);
static void HandleMessage(XW_Instance xw_instance, const char* msg);
- static void HandleSyncMessage(XW_Instance xw_instance, const char* msg);
+ static void HandleSyncMessage(XW_Instance xw_instance, const char* msg);
+ static void HandleBinaryMessage(XW_Instance instance, const char* message, const size_t size);
XW_Extension xw_extension_;
class Detail;
@@ -97,8 +99,10 @@ class Instance {
static void DoAndPostMessage(Instance* that, const std::function& work,
const picojson::value& json);
static void PostMessage(Instance* that, const char* msg);
+ static void PostMessage(Instance* that, const char* msg, size_t size);
static void PostMessage(Instance* that, const picojson::value& json);
void PostMessage(const char* msg);
+ void PostMessage(const char* msg, size_t size);
void SendSyncReply(const char* reply);
virtual void Initialize() {
@@ -107,6 +111,9 @@ class Instance {
virtual void HandleSyncMessage(const char* msg) {
}
+ virtual void HandleBinaryMessage(const char* msg, size_t size) = 0;
+ virtual void HandleSyncBinaryMessage(const char* msg, size_t size) = 0;
+
XW_Instance xw_instance() const {
return xw_instance_;
}
@@ -121,6 +128,7 @@ class Instance {
};
typedef std::function NativeHandler;
+typedef std::function BinaryNativeHandler;
class ParsedInstance : public Instance {
public:
@@ -131,6 +139,9 @@ class ParsedInstance : public Instance {
void RegisterHandler(const std::string& name, const NativeHandler& func);
void RegisterSyncHandler(const std::string& name, const NativeHandler& func);
+ void RegisterBinaryHandler(const BinaryNativeHandler& func);
+ void RegisterBinarySyncHandler(const BinaryNativeHandler& func);
+
static void ReportSuccess(picojson::object& out);
static void ReportSuccess(const picojson::value& result, picojson::object& out);
static void ReportError(picojson::object& out);
@@ -141,12 +152,17 @@ class ParsedInstance : public Instance {
void HandleMessage(const char* msg);
void HandleSyncMessage(const char* msg);
+ void HandleBinaryMessage(const char* msg, size_t size);
+ void HandleSyncBinaryMessage(const char* msg, size_t size);
+
void HandleMessage(const char* msg, bool is_sync);
+ void HandleBinaryMessage(const char* msg, size_t size, bool is_sync);
void HandleException(const PlatformException& ex);
void HandleException(const std::exception& e);
void HandleError(const PlatformResult& error);
std::map handler_map_;
+ std::vector binary_handler_vec_;
};
} // namespace common
diff --git a/src/tool/desc_gentool.cc b/src/tool/desc_gentool.cc
index 7c4185c3..86d31b0d 100644
--- a/src/tool/desc_gentool.cc
+++ b/src/tool/desc_gentool.cc
@@ -100,10 +100,13 @@ const void* get_interface(const char* name) {
return &entryPointsInterface1;
}
- if (!strcmp(name, XW_MESSAGING_INTERFACE_1)) {
- static const XW_MessagingInterface_1 messagingInterface1 = {
+ if (!strcmp(name, XW_MESSAGING_INTERFACE_2)) {
+ static const XW_MessagingInterface_2 messagingInterface1 = {
[](XW_Extension extension, XW_HandleMessageCallback handle_message) {},
- [](XW_Instance instance, const char* message) {}};
+ [](XW_Instance instance, const char* message) {},
+ [](XW_Extension extension,
+ XW_HandleBinaryMessageCallback handle_message) {},
+ [](XW_Instance instance, const char* message, size_t size) {}};
return &messagingInterface1;
}
diff --git a/src/utils/utils_api.js b/src/utils/utils_api.js
index 684b0f82..e5dde70c 100644
--- a/src/utils/utils_api.js
+++ b/src/utils/utils_api.js
@@ -1325,6 +1325,18 @@ NativeManager.prototype.callSync = function(cmd, args) {
return JSON_.parse(response);
};
+NativeManager.prototype.callSyncBinaryWithJSONAnswer = function(uint8array_data) {
+ // method id should be coded as first byte, refer to:
+ // extension.cc - ParsedInstance:: HandleBinaryMessage
+
+ var response = this.extension.internal.sendSyncMessage(uint8array_data);
+ if (response === undefined) {
+ /* C++ extension didn't set sync response using Instance::SendSyncReply */
+ throw new WebAPIException(WebAPIException.ABORT_ERR, 'Internal error');
+ }
+ return JSON_.parse(response);
+};
+
NativeManager.prototype.sendRuntimeMessage = function(msg, body) {
return this.extension.sendRuntimeMessage(msg, body || '');
};