#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
+#if defined(OS_TIZEN)
+#include "tizen/common/command_line.h"
+#include "atom/common/atom_command_line.h"
+#endif
+
namespace atom {
namespace {
// Allow file:// URIs to read other file:// URIs by default.
command_line->AppendSwitch(::switches::kAllowFileAccessFromFiles);
+#if defined(OS_TIZEN)
+ LOG (ERROR) << "Set Injected bundle path to engine";
+ command_line->AppendSwitchASCII("injected-bundle-path","/usr/lib/libxwalk_injected_bundle.so");
+ std::vector<std::string> cmdAgrs = atom::AtomCommandLine::argv();
+ std::string app_id = cmdAgrs[1];
+ command_line->AppendSwitchASCII("widget-id",app_id);
+#endif
+
#if defined(OS_MACOSX)
// Enable AVFoundation.
command_line->AppendSwitch("enable-avfoundation");
BuildRequires: pkgconfig(vd-win-util)
%endif
BuildRequires: pkgconfig(wgt-manifest-handlers)
+BuildRequires: pkgconfig(jsoncpp)
Requires: /usr/bin/systemctl
libchromiumcontent_component=1
use_efl=1
is_tizen=1
+ injected_bundle_path=%{_libdir}/libxwalk_injected_bundle.so
+ extension_path=%{_libdir}/tizen-extensions-crosswalk
"
%if "%{?TIZEN_PRODUCT_TV}" == "1"
DEFINE_ARGS+="
./node_modules/asar/bin/asar p wrt %{_out}/resources/app.asar
install -m 0755 %{_out}/resources/app.asar %{buildroot}/opt/usr/home/owner/data/org.tizen.electron-efl
+# injected bundle and extensions
+mkdir -p %{buildroot}%{extension_path}
+# xwalk extension shared
+install -p -m 644 %{_out}/lib/libxwalk_extension_shared.so %{buildroot}%{_libdir}
+# xwalk_injected_bundle
+install -p -m 755 %{_out}/lib/libxwalk_injected_bundle.so %{buildroot}%{_libdir}
+
%post
# Owner account can't write /opt/usr/home/owner/data/org.tizen.electron-efl
# which is created in 'install'. So we should copy resources in 'post'.
%attr(755,root,root) %{_bindir}/xwalk_runtime
%attr(644,root,root) %{_datadir}/aul/wrt.loader
%attr(644,root,root) %{_libdir}/libwrt_common.so
+%attr(644,root,root) %{_libdir}/libxwalk_extension_shared.so
+%attr(644,root,root) %{_libdir}/libxwalk_injected_bundle.so
{
'variables': {
'build_type%': 'Debug',
-# 'extension_path%': '<(extension_path)',
-# 'injected_bundle_path%': '<(injected_bundle_path)',
+ 'extension_path%': '<(extension_path)',
+ 'injected_bundle_path%': '<(injected_bundle_path)',
},
'target_defaults': {
'variables': {
'../',
'<(SHARED_INTERMEDIATE_DIR)',
],
-# 'defines': [
-# 'EXTENSION_PATH="<(extension_path)"',
-# 'INJECTED_BUNDLE_PATH="<(injected_bundle_path)"',
-# ],
+ 'defines': [
+ 'EXTENSION_PATH="<(extension_path)"',
+ 'INJECTED_BUNDLE_PATH="<(injected_bundle_path)"',
+ ],
'cflags': [
'-std=c++0x',
'-fPIC',
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "extensions/common/constants.h"
+
+namespace extensions {
+
+const char kMethodGetExtensions[] = "xwalk://GetExtensions";
+const char kMethodCreateInstance[] = "xwalk://CreateInstance";
+const char kMethodDestroyInstance[] = "xwalk://DestroyInstance";
+const char kMethodSendSyncMessage[] = "xwalk://SendSyncMessage";
+const char kMethodPostMessage[] = "xwalk://PostMessage";
+const char kMethodGetAPIScript[] = "xwalk://GetAPIScript";
+const char kMethodPostMessageToJS[] = "xwalk://PostMessageToJS";
+
+
+} // namespace extensions
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef XWALK_EXTENSIONS_COMMON_CONSTANTS_H_
+#define XWALK_EXTENSIONS_COMMON_CONSTANTS_H_
+
+namespace extensions {
+
+extern const char kMethodGetExtensions[];
+extern const char kMethodCreateInstance[];
+extern const char kMethodDestroyInstance[];
+extern const char kMethodSendSyncMessage[];
+extern const char kMethodPostMessage[];
+extern const char kMethodGetAPIScript[];
+extern const char kMethodPostMessageToJS[];
+
+} // namespace extensions
+
+#endif // XWALK_EXTENSIONS_COMMON_CONSTANTS_H_
--- /dev/null
+// Copyright (c) 2013 Intel Corporation. All rights reserved.
+// Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "extensions/common/xwalk_extension.h"
+
+#include <dlfcn.h>
+#include <string>
+
+#include "common/logger.h"
+#include "extensions/common/xwalk_extension_adapter.h"
+#include "extensions/public/XW_Extension.h"
+
+namespace extensions {
+
+XWalkExtension::XWalkExtension(const std::string& path,
+ XWalkExtensionDelegate* delegate)
+ : initialized_(false),
+ library_path_(path),
+ xw_extension_(0),
+ lazy_loading_(false),
+ delegate_(delegate),
+ created_instance_callback_(NULL),
+ destroyed_instance_callback_(NULL),
+ shutdown_callback_(NULL),
+ handle_msg_callback_(NULL),
+ handle_sync_msg_callback_(NULL),
+ handle_binary_msg_callback_(NULL) {
+}
+
+XWalkExtension::XWalkExtension(const std::string& path,
+ const std::string& name,
+ const StringVector& entry_points,
+ XWalkExtensionDelegate* delegate)
+ : initialized_(false),
+ library_path_(path),
+ xw_extension_(0),
+ name_(name),
+ entry_points_(entry_points),
+ lazy_loading_(true),
+ delegate_(delegate),
+ created_instance_callback_(NULL),
+ destroyed_instance_callback_(NULL),
+ shutdown_callback_(NULL),
+ handle_msg_callback_(NULL),
+ handle_sync_msg_callback_(NULL),
+ handle_binary_msg_callback_(NULL) {
+}
+
+XWalkExtension::~XWalkExtension() {
+ if (!initialized_)
+ return;
+ if (shutdown_callback_)
+ shutdown_callback_(xw_extension_);
+ XWalkExtensionAdapter::GetInstance()->UnregisterExtension(this);
+}
+
+bool XWalkExtension::Initialize() {
+ if (initialized_)
+ return true;
+
+ LOGGER(DEBUG) << "XWalkExtension:Initialize";
+ void* handle = dlopen(library_path_.c_str(), RTLD_LAZY);
+ if (!handle) {
+ LOGGER(ERROR) << "Error loading extension '"
+ << library_path_ << "' : " << dlerror();
+ return false;
+ }
+
+ XW_Initialize_Func initialize = reinterpret_cast<XW_Initialize_Func>(
+ dlsym(handle, "XW_Initialize"));
+ if (!initialize) {
+ LOGGER(ERROR) << "Error loading extension '" << library_path_
+ << "' : couldn't get XW_Initialize function.";
+ dlclose(handle);
+ return false;
+ }
+
+ XWalkExtensionAdapter* adapter = XWalkExtensionAdapter::GetInstance();
+ xw_extension_ = adapter->GetNextXWExtension();
+ adapter->RegisterExtension(this);
+
+ int ret = initialize(xw_extension_, XWalkExtensionAdapter::GetInterface);
+ if (ret != XW_OK) {
+ LOGGER(ERROR) << "Error loading extension '" << library_path_
+ << "' : XW_Initialize() returned error value.";
+ dlclose(handle);
+ return false;
+ }
+
+ initialized_ = true;
+ return true;
+}
+
+XWalkExtensionInstance* XWalkExtension::CreateInstance() {
+ Initialize();
+ XWalkExtensionAdapter* adapter = XWalkExtensionAdapter::GetInstance();
+ XW_Instance xw_instance = adapter->GetNextXWInstance();
+ return new XWalkExtensionInstance(this, xw_instance);
+}
+
+std::string XWalkExtension::GetJavascriptCode() {
+ Initialize();
+ return javascript_api_;
+}
+
+void XWalkExtension::GetRuntimeVariable(const char* key, char* value,
+ size_t value_len) {
+ if (delegate_) {
+ delegate_->GetRuntimeVariable(key, value, value_len);
+ }
+}
+int XWalkExtension::CheckAPIAccessControl(const char* /*api_name*/) {
+ // Not Supported
+ return XW_OK;
+}
+
+int XWalkExtension::RegisterPermissions(const char* /*perm_table*/) {
+ // Not Supported
+ return XW_OK;
+}
+
+} // namespace extensions
+
--- /dev/null
+// Copyright (c) 2013 Intel Corporation. All rights reserved.
+// Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef XWALK_EXTENSIONS_XWALK_EXTENSION_H_
+#define XWALK_EXTENSIONS_XWALK_EXTENSION_H_
+
+#include <string>
+#include <vector>
+
+#include "extensions/common/xwalk_extension_instance.h"
+#include "extensions/public/XW_Extension.h"
+#include "extensions/public/XW_Extension_SyncMessage.h"
+#include "extensions/public/XW_Extension_Message_2.h"
+
+namespace extensions {
+
+class XWalkExtensionAdapter;
+class XWalkExtensionInstance;
+
+class XWalkExtension {
+ public:
+ typedef std::vector<std::string> StringVector;
+
+ class XWalkExtensionDelegate {
+ public:
+ virtual void GetRuntimeVariable(const char* key, char* value,
+ size_t value_len) = 0;
+ };
+
+ XWalkExtension(const std::string& path, XWalkExtensionDelegate* delegate);
+ XWalkExtension(const std::string& path,
+ const std::string& name,
+ const StringVector& entry_points,
+ XWalkExtensionDelegate* delegate);
+ virtual ~XWalkExtension();
+
+ bool Initialize();
+ XWalkExtensionInstance* CreateInstance();
+ std::string GetJavascriptCode();
+
+ std::string name() const { return name_; }
+
+ const StringVector& entry_points() const {
+ return entry_points_;
+ }
+
+ bool lazy_loading() const {
+ return lazy_loading_;
+ }
+
+ private:
+ friend class XWalkExtensionAdapter;
+ friend class XWalkExtensionInstance;
+
+ void GetRuntimeVariable(const char* key, char* value, size_t value_len);
+ int CheckAPIAccessControl(const char* api_name);
+ int RegisterPermissions(const char* perm_table);
+
+ bool initialized_;
+ std::string library_path_;
+ XW_Extension xw_extension_;
+
+ std::string name_;
+ std::string javascript_api_;
+ StringVector entry_points_;
+ bool lazy_loading_;
+
+ XWalkExtensionDelegate* delegate_;
+
+ XW_CreatedInstanceCallback created_instance_callback_;
+ XW_DestroyedInstanceCallback destroyed_instance_callback_;
+ XW_ShutdownCallback shutdown_callback_;
+ XW_HandleMessageCallback handle_msg_callback_;
+ XW_HandleSyncMessageCallback handle_sync_msg_callback_;
+ XW_HandleBinaryMessageCallback handle_binary_msg_callback_;
+};
+
+} // namespace extensions
+
+#endif // XWALK_EXTENSIONS_XWALK_EXTENSION_H_
--- /dev/null
+// Copyright (c) 2013 Intel Corporation. All rights reserved.
+// Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "extensions/common/xwalk_extension_adapter.h"
+
+#include <string>
+
+#include "common/logger.h"
+
+namespace extensions {
+
+XWalkExtensionAdapter::XWalkExtensionAdapter()
+ : next_xw_extension_(1),
+ next_xw_instance_(1) {
+}
+
+XWalkExtensionAdapter::~XWalkExtensionAdapter() {
+}
+
+XWalkExtensionAdapter* XWalkExtensionAdapter::GetInstance() {
+ static XWalkExtensionAdapter self;
+ return &self;
+}
+
+XW_Extension XWalkExtensionAdapter::GetNextXWExtension() {
+ return next_xw_extension_++;
+}
+
+XW_Instance XWalkExtensionAdapter::GetNextXWInstance() {
+ return next_xw_instance_++;
+}
+
+void XWalkExtensionAdapter::RegisterExtension(XWalkExtension* extension) {
+ XW_Extension xw_extension = extension->xw_extension_;
+ if (!(xw_extension > 0 && xw_extension < next_xw_extension_)) {
+ LOGGER(WARN) << "xw_extension (" << xw_extension << ") is invalid.";
+ return;
+ }
+ if (extension_map_.find(xw_extension) == extension_map_.end())
+ extension_map_[xw_extension] = extension;
+}
+
+void XWalkExtensionAdapter::UnregisterExtension(XWalkExtension* extension) {
+ XW_Extension xw_extension = extension->xw_extension_;
+ if (!(xw_extension > 0 && xw_extension < next_xw_extension_)) {
+ LOGGER(WARN) << "xw_extension (" << xw_extension << ") is invalid.";
+ return;
+ }
+ auto it = extension_map_.find(xw_extension);
+ if (it != extension_map_.end()) {
+ extension_map_.erase(it);
+ }
+}
+
+void XWalkExtensionAdapter::RegisterInstance(
+ XWalkExtensionInstance* instance) {
+ XW_Instance xw_instance = instance->xw_instance_;
+ if (!(xw_instance > 0 && xw_instance < next_xw_instance_)) {
+ LOGGER(WARN) << "xw_instance (" << xw_instance << ") is invalid.";
+ return;
+ }
+ if (instance_map_.find(xw_instance) == instance_map_.end())
+ instance_map_[xw_instance] = instance;
+}
+
+void XWalkExtensionAdapter::UnregisterInstance(
+ XWalkExtensionInstance* instance) {
+ XW_Instance xw_instance = instance->xw_instance_;
+ if (!(xw_instance > 0 && xw_instance < next_xw_instance_)) {
+ LOGGER(WARN) << "xw_instance (" << xw_instance << ") is invalid.";
+ return;
+ }
+ auto it = instance_map_.find(xw_instance);
+ if (it != instance_map_.end()) {
+ instance_map_.erase(it);
+ }
+}
+
+const void* XWalkExtensionAdapter::GetInterface(const char* name) {
+ if (!strcmp(name, XW_CORE_INTERFACE_1)) {
+ static const XW_CoreInterface_1 coreInterface1 = {
+ CoreSetExtensionName,
+ CoreSetJavaScriptAPI,
+ CoreRegisterInstanceCallbacks,
+ CoreRegisterShutdownCallback,
+ CoreSetInstanceData,
+ CoreGetInstanceData
+ };
+ return &coreInterface1;
+ }
+
+ if (!strcmp(name, XW_MESSAGING_INTERFACE_1)) {
+ static const XW_MessagingInterface_1 messagingInterface1 = {
+ MessagingRegister,
+ MessagingPostMessage
+ };
+ return &messagingInterface1;
+ }
+
+ if (!strcmp(name, XW_MESSAGING_INTERFACE_2)) {
+ static const XW_MessagingInterface_2 messagingInterface2 = {
+ MessagingRegister,
+ MessagingPostMessage,
+ MessagingRegisterBinaryMessageCallback,
+ MessagingPostBinaryMessage
+ };
+ return &messagingInterface2;
+ }
+
+ if (!strcmp(name, XW_INTERNAL_SYNC_MESSAGING_INTERFACE_1)) {
+ static const XW_Internal_SyncMessagingInterface_1
+ syncMessagingInterface1 = {
+ SyncMessagingRegister,
+ SyncMessagingSetSyncReply
+ };
+ return &syncMessagingInterface1;
+ }
+
+ if (!strcmp(name, XW_INTERNAL_ENTRY_POINTS_INTERFACE_1)) {
+ static const XW_Internal_EntryPointsInterface_1 entryPointsInterface1 = {
+ EntryPointsSetExtraJSEntryPoints
+ };
+ return &entryPointsInterface1;
+ }
+
+ if (!strcmp(name, XW_INTERNAL_RUNTIME_INTERFACE_1)) {
+ static const XW_Internal_RuntimeInterface_1 runtimeInterface1 = {
+ RuntimeGetStringVariable
+ };
+ return &runtimeInterface1;
+ }
+
+ if (!strcmp(name, XW_INTERNAL_PERMISSIONS_INTERFACE_1)) {
+ static const XW_Internal_PermissionsInterface_1 permissionsInterface1 = {
+ PermissionsCheckAPIAccessControl,
+ PermissionsRegisterPermissions
+ };
+ return &permissionsInterface1;
+ }
+
+ LOGGER(WARN) << "Interface '" << name << "' is not supported.";
+ return NULL;
+}
+
+XWalkExtension* XWalkExtensionAdapter::GetExtension(XW_Extension xw_extension) {
+ XWalkExtensionAdapter* adapter = XWalkExtensionAdapter::GetInstance();
+ ExtensionMap::iterator it = adapter->extension_map_.find(xw_extension);
+ if (it == adapter->extension_map_.end())
+ return NULL;
+ return it->second;
+}
+
+XWalkExtensionInstance* XWalkExtensionAdapter::GetExtensionInstance(
+ XW_Instance xw_instance) {
+ XWalkExtensionAdapter* adapter = XWalkExtensionAdapter::GetInstance();
+ InstanceMap::iterator it = adapter->instance_map_.find(xw_instance);
+ if (it == adapter->instance_map_.end())
+ return NULL;
+ return it->second;
+}
+
+#define CHECK(x, xw) \
+ if (!x) { \
+ LOGGER(WARN) << "Ignoring call. Invalid " << #xw << " = " << xw; \
+ return; \
+ }
+
+#define RETURN_IF_INITIALIZED(x) \
+ if (x->initialized_) \
+ return;
+
+void XWalkExtensionAdapter::CoreSetExtensionName(
+ XW_Extension xw_extension,
+ const char* name) {
+ XWalkExtension* extension = GetExtension(xw_extension);
+ CHECK(extension, xw_extension);
+ RETURN_IF_INITIALIZED(extension);
+ extension->name_ = name;
+}
+
+void XWalkExtensionAdapter::CoreSetJavaScriptAPI(
+ XW_Extension xw_extension,
+ const char* javascript_api) {
+ XWalkExtension* extension = GetExtension(xw_extension);
+ CHECK(extension, xw_extension);
+ RETURN_IF_INITIALIZED(extension);
+ extension->javascript_api_ = javascript_api;
+}
+
+void XWalkExtensionAdapter::CoreRegisterInstanceCallbacks(
+ XW_Extension xw_extension,
+ XW_CreatedInstanceCallback created,
+ XW_DestroyedInstanceCallback destroyed) {
+ XWalkExtension* extension = GetExtension(xw_extension);
+ CHECK(extension, xw_extension);
+ RETURN_IF_INITIALIZED(extension);
+ extension->created_instance_callback_ = created;
+ extension->destroyed_instance_callback_ = destroyed;
+}
+
+void XWalkExtensionAdapter::CoreRegisterShutdownCallback(
+ XW_Extension xw_extension,
+ XW_ShutdownCallback shutdown) {
+ XWalkExtension* extension = GetExtension(xw_extension);
+ CHECK(extension, xw_extension);
+ RETURN_IF_INITIALIZED(extension);
+ extension->shutdown_callback_ = shutdown;
+}
+
+void XWalkExtensionAdapter::CoreSetInstanceData(
+ XW_Instance xw_instance,
+ void* data) {
+ XWalkExtensionInstance* instance = GetExtensionInstance(xw_instance);
+ CHECK(instance, xw_instance);
+ instance->instance_data_ = data;
+}
+
+void* XWalkExtensionAdapter::CoreGetInstanceData(
+ XW_Instance xw_instance) {
+ XWalkExtensionInstance* instance = GetExtensionInstance(xw_instance);
+ if (instance)
+ return instance->instance_data_;
+ else
+ return NULL;
+}
+
+void XWalkExtensionAdapter::MessagingRegister(
+ XW_Extension xw_extension,
+ XW_HandleMessageCallback handle_message) {
+ XWalkExtension* extension = GetExtension(xw_extension);
+ CHECK(extension, xw_extension);
+ RETURN_IF_INITIALIZED(extension);
+ extension->handle_msg_callback_ = handle_message;
+}
+
+void XWalkExtensionAdapter::MessagingPostMessage(
+ XW_Instance xw_instance,
+ const char* message) {
+ XWalkExtensionInstance* instance = GetExtensionInstance(xw_instance);
+ CHECK(instance, xw_instance);
+ instance->PostMessageToJS(message);
+}
+
+void XWalkExtensionAdapter::SyncMessagingRegister(
+ XW_Extension xw_extension,
+ XW_HandleSyncMessageCallback handle_sync_message) {
+ XWalkExtension* extension = GetExtension(xw_extension);
+ CHECK(extension, xw_extension);
+ RETURN_IF_INITIALIZED(extension);
+ extension->handle_sync_msg_callback_ = handle_sync_message;
+}
+
+void XWalkExtensionAdapter::SyncMessagingSetSyncReply(
+ XW_Instance xw_instance,
+ const char* reply) {
+ XWalkExtensionInstance* instance = GetExtensionInstance(xw_instance);
+ CHECK(instance, xw_instance);
+ instance->SyncReplyToJS(reply);
+}
+
+void XWalkExtensionAdapter::EntryPointsSetExtraJSEntryPoints(
+ XW_Extension xw_extension,
+ const char** entry_points) {
+ XWalkExtension* extension = GetExtension(xw_extension);
+ CHECK(extension, xw_extension);
+ RETURN_IF_INITIALIZED(extension);
+
+ for (int i=0; entry_points[i]; ++i) {
+ extension->entry_points_.push_back(std::string(entry_points[i]));
+ }
+}
+
+void XWalkExtensionAdapter::RuntimeGetStringVariable(
+ XW_Extension xw_extension,
+ const char* key,
+ char* value,
+ unsigned int value_len) {
+ XWalkExtension* extension = GetExtension(xw_extension);
+ CHECK(extension, xw_extension);
+ extension->GetRuntimeVariable(key, value, value_len);
+}
+
+int XWalkExtensionAdapter::PermissionsCheckAPIAccessControl(
+ XW_Extension xw_extension,
+ const char* api_name) {
+ XWalkExtension* extension = GetExtension(xw_extension);
+ if (extension)
+ return extension->CheckAPIAccessControl(api_name);
+ else
+ return XW_ERROR;
+}
+
+int XWalkExtensionAdapter::PermissionsRegisterPermissions(
+ XW_Extension xw_extension,
+ const char* perm_table) {
+ XWalkExtension* extension = GetExtension(xw_extension);
+ if (extension)
+ return extension->RegisterPermissions(perm_table);
+ else
+ return XW_ERROR;
+}
+
+void XWalkExtensionAdapter::MessagingRegisterBinaryMessageCallback(
+ XW_Extension xw_extension, XW_HandleBinaryMessageCallback handle_message) {
+ XWalkExtension* extension = GetExtension(xw_extension);
+ CHECK(extension, xw_extension);
+ RETURN_IF_INITIALIZED(extension);
+ extension->handle_binary_msg_callback_ = handle_message;
+}
+
+void XWalkExtensionAdapter::MessagingPostBinaryMessage(
+ XW_Instance xw_instance, const char* message, size_t size) {
+ XWalkExtensionInstance* instance = GetExtensionInstance(xw_instance);
+ CHECK(instance, xw_instance);
+ instance->PostMessageToJS(message);
+}
+
+#undef CHECK
+#undef RETURN_IF_INITIALIZED
+
+} // namespace extensions
--- /dev/null
+// Copyright (c) 2013 Intel Corporation. All rights reserved.
+// Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef XWALK_EXTENSIONS_XWALK_EXTENSION_ADAPTER_H_
+#define XWALK_EXTENSIONS_XWALK_EXTENSION_ADAPTER_H_
+
+#include <map>
+
+#include "extensions/common/xwalk_extension.h"
+#include "extensions/common/xwalk_extension_instance.h"
+#include "extensions/public/XW_Extension.h"
+#include "extensions/public/XW_Extension_EntryPoints.h"
+#include "extensions/public/XW_Extension_Permissions.h"
+#include "extensions/public/XW_Extension_Runtime.h"
+#include "extensions/public/XW_Extension_SyncMessage.h"
+#include "extensions/public/XW_Extension_Message_2.h"
+
+namespace extensions {
+
+class XWalkExtensionAdapter {
+ public:
+ typedef std::map<XW_Extension, XWalkExtension*> ExtensionMap;
+ typedef std::map<XW_Instance, XWalkExtensionInstance*> InstanceMap;
+
+ static XWalkExtensionAdapter* GetInstance();
+
+ XW_Extension GetNextXWExtension();
+ XW_Instance GetNextXWInstance();
+
+ void RegisterExtension(XWalkExtension* extension);
+ void UnregisterExtension(XWalkExtension* extension);
+
+ void RegisterInstance(XWalkExtensionInstance* instance);
+ void UnregisterInstance(XWalkExtensionInstance* instance);
+
+ // Returns the correct struct according to interface asked. This is
+ // passed to external extensions in XW_Initialize() call.
+ static const void* GetInterface(const char* name);
+
+ private:
+ XWalkExtensionAdapter();
+ virtual ~XWalkExtensionAdapter();
+
+ static XWalkExtension* GetExtension(XW_Extension xw_extension);
+ static XWalkExtensionInstance* GetExtensionInstance(XW_Instance xw_instance);
+
+ static void CoreSetExtensionName(
+ XW_Extension xw_extension, const char* name);
+ static void CoreSetJavaScriptAPI(
+ XW_Extension xw_extension, const char* javascript_api);
+ static void CoreRegisterInstanceCallbacks(
+ XW_Extension xw_extension,
+ XW_CreatedInstanceCallback created,
+ XW_DestroyedInstanceCallback destroyed);
+ static void CoreRegisterShutdownCallback(
+ XW_Extension xw_extension,
+ XW_ShutdownCallback shutdown);
+ static void CoreSetInstanceData(
+ XW_Instance xw_instance, void* data);
+ static void* CoreGetInstanceData(XW_Instance xw_instance);
+ static void MessagingRegister(
+ XW_Extension xw_extension,
+ XW_HandleMessageCallback handle_message);
+ static void MessagingPostMessage(
+ XW_Instance xw_instance, const char* message);
+ static void SyncMessagingRegister(
+ XW_Extension xw_extension,
+ XW_HandleSyncMessageCallback handle_sync_message);
+ static void SyncMessagingSetSyncReply(
+ XW_Instance xw_instance, const char* reply);
+ static void EntryPointsSetExtraJSEntryPoints(
+ XW_Extension xw_extension, const char** entry_points);
+ static void RuntimeGetStringVariable(
+ XW_Extension xw_extension,
+ const char* key, char* value, unsigned int value_len);
+ static int PermissionsCheckAPIAccessControl(
+ XW_Extension xw_extension, const char* api_name);
+ static int PermissionsRegisterPermissions(
+ XW_Extension xw_extension, const char* perm_table);
+ static void MessagingRegisterBinaryMessageCallback(
+ XW_Extension xw_extension, XW_HandleBinaryMessageCallback handle_message);
+ static void MessagingPostBinaryMessage(
+ XW_Instance xw_instance, const char* message, size_t size);
+
+ ExtensionMap extension_map_;
+ InstanceMap instance_map_;
+
+ XW_Extension next_xw_extension_;
+ XW_Instance next_xw_instance_;
+};
+
+} // namespace extensions
+
+#endif // XWALK_EXTENSIONS_XWALK_EXTENSION_ADAPTER_H_
--- /dev/null
+// Copyright (c) 2013 Intel Corporation. All rights reserved.
+// Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "extensions/common/xwalk_extension_instance.h"
+
+#include "extensions/common/xwalk_extension_adapter.h"
+#include "extensions/public/XW_Extension_SyncMessage.h"
+
+namespace extensions {
+
+XWalkExtensionInstance::XWalkExtensionInstance(
+ XWalkExtension* extension, XW_Instance xw_instance)
+ : extension_(extension),
+ xw_instance_(xw_instance),
+ instance_data_(NULL) {
+ XWalkExtensionAdapter::GetInstance()->RegisterInstance(this);
+ XW_CreatedInstanceCallback callback = extension_->created_instance_callback_;
+ if (callback)
+ callback(xw_instance_);
+}
+
+XWalkExtensionInstance::~XWalkExtensionInstance() {
+ XW_DestroyedInstanceCallback callback =
+ extension_->destroyed_instance_callback_;
+ if (callback)
+ callback(xw_instance_);
+ XWalkExtensionAdapter::GetInstance()->UnregisterInstance(this);
+}
+
+void XWalkExtensionInstance::HandleMessage(const std::string& msg) {
+ XW_HandleMessageCallback callback = extension_->handle_msg_callback_;
+ if (callback)
+ callback(xw_instance_, msg.c_str());
+}
+
+void XWalkExtensionInstance::HandleSyncMessage(const std::string& msg) {
+ XW_HandleSyncMessageCallback callback = extension_->handle_sync_msg_callback_;
+ if (callback) {
+ callback(xw_instance_, msg.c_str());
+ }
+}
+
+void XWalkExtensionInstance::SetPostMessageCallback(
+ MessageCallback callback) {
+ post_message_callback_ = callback;
+}
+
+void XWalkExtensionInstance::SetSendSyncReplyCallback(
+ MessageCallback callback) {
+ send_sync_reply_callback_ = callback;
+}
+
+void XWalkExtensionInstance::PostMessageToJS(const std::string& msg) {
+ post_message_callback_(msg);
+}
+
+void XWalkExtensionInstance::SyncReplyToJS(const std::string& reply) {
+ send_sync_reply_callback_(reply);
+}
+
+} // namespace extensions
--- /dev/null
+// Copyright (c) 2013 Intel Corporation. All rights reserved.
+// Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef XWALK_EXTENSIONS_XWALK_EXTENSION_INSTANCE_H_
+#define XWALK_EXTENSIONS_XWALK_EXTENSION_INSTANCE_H_
+
+#include <functional>
+#include <string>
+
+#include "extensions/public/XW_Extension.h"
+
+namespace extensions {
+
+class XWalkExtension;
+
+class XWalkExtensionInstance {
+ public:
+ typedef std::function<void(const std::string&)> MessageCallback;
+
+ XWalkExtensionInstance(XWalkExtension* extension, XW_Instance xw_instance);
+ virtual ~XWalkExtensionInstance();
+
+ void HandleMessage(const std::string& msg);
+ void HandleSyncMessage(const std::string& msg);
+
+ void SetPostMessageCallback(MessageCallback callback);
+ void SetSendSyncReplyCallback(MessageCallback callback);
+
+ private:
+ friend class XWalkExtensionAdapter;
+
+ void PostMessageToJS(const std::string& msg);
+ void SyncReplyToJS(const std::string& reply);
+
+ XWalkExtension* extension_;
+ XW_Instance xw_instance_;
+ void* instance_data_;
+
+ MessageCallback post_message_callback_;
+ MessageCallback send_sync_reply_callback_;
+};
+
+} // namespace extensions
+
+#endif // XWALK_EXTENSIONS_XWALK_EXTENSION_INSTANCE_H_
--- /dev/null
+// Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "extensions/common/xwalk_extension_manager.h"
+
+#include <glob.h>
+#include <dlfcn.h>
+#include <sys/utsname.h>
+
+#include <fstream>
+#include <set>
+#include <string>
+#include <vector>
+
+#include "common/app_db.h"
+#include "common/logger.h"
+#include "common/picojson.h"
+#include "common/file_utils.h"
+#include "common/string_utils.h"
+
+#include "extensions/common/constants.h"
+#include "extensions/common/xwalk_extension.h"
+
+#ifndef EXTENSION_PATH
+ #error EXTENSION_PATH is not set.
+#endif
+
+namespace extensions {
+
+namespace {
+
+const char kAppDBRuntimeSection[] = "Runtime";
+
+const char kExtensionPrefix[] = "lib";
+const char kExtensionSuffix[] = ".so";
+const char kExtensionMetadataSuffix[] = ".json";
+
+static const char* kPreloadLibs[] = {
+ EXTENSION_PATH"/libtizen.so",
+ EXTENSION_PATH"/libtizen_common.so",
+ EXTENSION_PATH"/libtizen_application.so",
+ EXTENSION_PATH"/libtizen_utils.so",
+ NULL
+};
+
+const char kUserPluginsDirectory[] = "plugin/";
+const char kArchArmv7l[] = "armv7l";
+const char kArchI586[] = "i586";
+const char kArchDefault[] = "default";
+
+} // namespace
+
+XWalkExtensionManager::XWalkExtensionManager() {
+}
+
+XWalkExtensionManager::~XWalkExtensionManager() {
+}
+
+void XWalkExtensionManager::PreloadExtensions() {
+ for (int i = 0; kPreloadLibs[i]; i++) {
+ LOGGER(DEBUG) << "Preload libs : " << kPreloadLibs[i];
+ void* handle = dlopen(kPreloadLibs[i], RTLD_NOW|RTLD_GLOBAL);
+ if (handle == nullptr) {
+ LOGGER(WARN) << "Fail to load libs : " << dlerror();
+ }
+ }
+}
+
+void XWalkExtensionManager::LoadExtensions(bool meta_only) {
+ if (!extensions_.empty()) {
+ return;
+ }
+
+ std::string extension_path(EXTENSION_PATH);
+
+ // Gets all extension files in the EXTENSION_PATH
+ std::string ext_pattern(extension_path);
+ ext_pattern.append("/");
+ ext_pattern.append(kExtensionPrefix);
+ ext_pattern.append("*");
+ ext_pattern.append(kExtensionSuffix);
+
+ StringSet files;
+ {
+ glob_t glob_result;
+ glob(ext_pattern.c_str(), GLOB_TILDE, NULL, &glob_result);
+ for (unsigned int i = 0; i < glob_result.gl_pathc; ++i) {
+ files.insert(glob_result.gl_pathv[i]);
+ }
+ }
+
+ // Gets all metadata files in the EXTENSION_PATH
+ // Loads information from the metadata files and remove the loaded file from
+ // the set 'files'
+ std::string meta_pattern(extension_path);
+ meta_pattern.append("/");
+ meta_pattern.append("*");
+ meta_pattern.append(kExtensionMetadataSuffix);
+ {
+ glob_t glob_result;
+ glob(meta_pattern.c_str(), GLOB_TILDE, NULL, &glob_result);
+ for (unsigned int i = 0; i < glob_result.gl_pathc; ++i) {
+ RegisterExtensionsByMeta(glob_result.gl_pathv[i], &files);
+ }
+ }
+
+ // Load extensions in the remained files of the set 'files'
+ if (!meta_only) {
+ for (auto it = files.begin(); it != files.end(); ++it) {
+ XWalkExtension* ext = new XWalkExtension(*it, this);
+ RegisterExtension(ext);
+ }
+ }
+}
+
+void XWalkExtensionManager::LoadUserExtensions(const std::string app_path) {
+ if (app_path.empty()) {
+ LOGGER(ERROR) << "Failed to get package root path";
+ return;
+ }
+ std::string app_ext_pattern(app_path);
+ app_ext_pattern.append(kUserPluginsDirectory);
+ struct utsname u;
+ if (0 == uname(&u)) {
+ std::string machine = u.machine;
+ if (!machine.empty()) {
+ if (machine == kArchArmv7l) {
+ app_ext_pattern.append(kArchArmv7l);
+ } else if (machine == kArchI586) {
+ app_ext_pattern.append(kArchI586);
+ } else {
+ app_ext_pattern.append(kArchDefault);
+ }
+ } else {
+ LOGGER(ERROR) << "cannot get machine info";
+ app_ext_pattern.append(kArchDefault);
+ }
+ app_ext_pattern.append("/");
+ }
+ app_ext_pattern.append("*");
+ app_ext_pattern.append(kExtensionSuffix);
+
+ StringSet files;
+ {
+ glob_t glob_result;
+ glob(app_ext_pattern.c_str(), GLOB_TILDE, NULL, &glob_result);
+ for (unsigned int i = 0; i < glob_result.gl_pathc; ++i) {
+ files.insert(glob_result.gl_pathv[i]);
+ }
+ }
+ for (auto it = files.begin(); it != files.end(); ++it) {
+ XWalkExtension* ext = new XWalkExtension(*it, this);
+ RegisterExtension(ext);
+ }
+ LOGGER(DEBUG) << "finish load user extension plugins";
+}
+
+void XWalkExtensionManager::UnloadExtensions() {
+ for (auto it = extensions_.begin(); it != extensions_.end(); ++it) {
+ delete it->second;
+ }
+ extensions_.clear();
+}
+
+bool XWalkExtensionManager::RegisterSymbols(XWalkExtension* extension) {
+ std::string name = extension->name();
+
+ if (extension_symbols_.find(name) != extension_symbols_.end()) {
+ LOGGER(WARN) << "Ignoring extension with name already registred. '"
+ << name << "'";
+ return false;
+ }
+
+ XWalkExtension::StringVector entry_points = extension->entry_points();
+ for (auto it = entry_points.begin(); it != entry_points.end(); ++it) {
+ if (extension_symbols_.find(*it) != extension_symbols_.end()) {
+ LOGGER(WARN) << "Ignoring extension with entry_point already registred. '"
+ << (*it) << "'";
+ return false;
+ }
+ }
+
+ for (auto it = entry_points.begin(); it != entry_points.end(); ++it) {
+ extension_symbols_.insert(*it);
+ }
+
+ extension_symbols_.insert(name);
+
+ return true;
+}
+
+void XWalkExtensionManager::RegisterExtension(XWalkExtension* extension) {
+ if (!extension->lazy_loading() && !extension->Initialize()) {
+ delete extension;
+ return;
+ }
+
+ if (!RegisterSymbols(extension)) {
+ delete extension;
+ return;
+ }
+
+ extensions_[extension->name()] = extension;
+ LOGGER(DEBUG) << extension->name() << " is registered.";
+}
+
+void XWalkExtensionManager::RegisterExtensionsByMeta(
+ const std::string& meta_path, StringSet* files) {
+ std::string extension_path(EXTENSION_PATH);
+
+ std::ifstream metafile(meta_path.c_str());
+ if (!metafile.is_open()) {
+ LOGGER(ERROR) << "Fail to open the plugin metadata file :" << meta_path;
+ return;
+ }
+
+ picojson::value metadata;
+ metafile >> metadata;
+ if (metadata.is<picojson::array>()) {
+ auto& plugins = metadata.get<picojson::array>();
+ for (auto plugin = plugins.begin(); plugin != plugins.end(); ++plugin) {
+ if (!plugin->is<picojson::object>())
+ continue;
+
+ std::string name = plugin->get("name").to_str();
+ std::string lib = plugin->get("lib").to_str();
+ if (!common::utils::StartsWith(lib, "/")) {
+ lib = extension_path + "/" + lib;
+ }
+
+ std::vector<std::string> entries;
+ auto& entry_points_value = plugin->get("entry_points");
+ if (entry_points_value.is<picojson::array>()) {
+ auto& entry_points = entry_points_value.get<picojson::array>();
+ for (auto entry = entry_points.begin(); entry != entry_points.end();
+ ++entry) {
+ entries.push_back(entry->to_str());
+ }
+ }
+ XWalkExtension* extension = new XWalkExtension(lib, name, entries, this);
+ RegisterExtension(extension);
+ files->erase(lib);
+ }
+ } else {
+ LOGGER(ERROR) << meta_path << " is not a valid metadata file.";
+ }
+ metafile.close();
+}
+
+// override
+void XWalkExtensionManager::GetRuntimeVariable(
+ const char* key, char* value, size_t value_len) {
+ common::AppDB* db = common::AppDB::GetInstance();
+ std::string ret = db->Get(kAppDBRuntimeSection, key);
+ strncpy(value, ret.c_str(), value_len);
+}
+
+
+} // namespace extensions
--- /dev/null
+// Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef XWALK_EXTENSIONS_XWALK_EXTENSION_MANAGER_H_
+#define XWALK_EXTENSIONS_XWALK_EXTENSION_MANAGER_H_
+
+#include <string>
+#include <set>
+#include <map>
+
+#include "extensions/common/xwalk_extension.h"
+
+namespace extensions {
+
+class XWalkExtensionManager : public XWalkExtension::XWalkExtensionDelegate {
+ public:
+ typedef std::set<std::string> StringSet;
+ typedef std::map<std::string, XWalkExtension*> ExtensionMap;
+
+ XWalkExtensionManager();
+ virtual ~XWalkExtensionManager();
+
+ ExtensionMap extensions() const { return extensions_; }
+
+ void LoadExtensions(bool meta_only = true);
+ void LoadUserExtensions(const std::string app_path);
+ void PreloadExtensions();
+
+ void UnloadExtensions();
+
+ private:
+ // override
+ void GetRuntimeVariable(const char* key, char* value, size_t value_len);
+
+ bool RegisterSymbols(XWalkExtension* extension);
+ void RegisterExtension(XWalkExtension* extension);
+ void RegisterExtensionsByMeta(const std::string& meta_path,
+ StringSet* files);
+
+ StringSet extension_symbols_;
+ ExtensionMap extensions_;
+};
+
+} // namespace extensions
+
+#endif // XWALK_EXTENSIONS_XWALK_EXTENSION_MANAGER_H_
--- /dev/null
+// Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "extensions/common/xwalk_extension_server.h"
+
+#include <Ecore.h>
+
+#include <string>
+
+#include "common/logger.h"
+#include "common/profiler.h"
+#include "common/string_utils.h"
+#include "extensions/common/constants.h"
+#include "extensions/common/xwalk_extension_manager.h"
+
+namespace extensions {
+
+// static
+XWalkExtensionServer* XWalkExtensionServer::GetInstance() {
+ static XWalkExtensionServer self;
+ return &self;
+}
+
+XWalkExtensionServer::XWalkExtensionServer() {
+ manager_.LoadExtensions();
+}
+
+XWalkExtensionServer::~XWalkExtensionServer() {
+}
+
+void XWalkExtensionServer::SetupIPC(Ewk_Context* ewk_context) {
+ ewk_context_ = ewk_context;
+}
+
+void XWalkExtensionServer::Preload() {
+ manager_.PreloadExtensions();
+}
+
+void XWalkExtensionServer::Shutdown() {
+ for (auto it = instances_.begin(); it != instances_.end(); ++it) {
+ delete it->second;
+ }
+ instances_.clear();
+ manager_.UnloadExtensions();
+}
+
+Json::Value XWalkExtensionServer::GetExtensions() {
+ Json::Value out;
+ auto extensions = manager_.extensions();
+ for (auto it = extensions.begin(); it != extensions.end(); ++it) {
+ Json::Value ext;
+ ext["name"] = it->second->name();
+ // ext["api"] = it->second->GetJavascriptCode();
+ auto entry_points = it->second->entry_points();
+ for (auto ite = entry_points.begin(); ite != entry_points.end(); ++ite) {
+ ext["entry_points"].append(*ite);
+ }
+ out.append(ext);
+ }
+ return out;
+}
+
+std::string XWalkExtensionServer::GetAPIScript(
+ const std::string& extension_name) {
+ auto extensions = manager_.extensions();
+ auto it = extensions.find(extension_name);
+ if (it == extensions.end()) {
+ LOGGER(ERROR) << "No such extension '" << extension_name << "'";
+ return std::string();
+ }
+
+ return it->second->GetJavascriptCode();
+}
+
+std::string XWalkExtensionServer::CreateInstance(
+ const std::string& extension_name) {
+ std::string instance_id;
+
+ auto extensions = manager_.extensions();
+ auto it = extensions.find(extension_name);
+ if (it != extensions.end()) {
+ XWalkExtensionInstance* instance = it->second->CreateInstance();
+ if (instance) {
+ instance_id = common::utils::GenerateUUID();
+ instance->SetPostMessageCallback(
+ [this, instance_id](const std::string& msg) {
+ Ewk_IPC_Wrt_Message_Data* ans = ewk_ipc_wrt_message_data_new();
+ ewk_ipc_wrt_message_data_type_set(ans, kMethodPostMessageToJS);
+ ewk_ipc_wrt_message_data_id_set(ans, instance_id.c_str());
+ ewk_ipc_wrt_message_data_value_set(ans, msg.c_str());
+ if (!ewk_ipc_wrt_message_send(ewk_context_, ans)) {
+ LOGGER(ERROR) << "Failed to send response";
+ }
+ ewk_ipc_wrt_message_data_del(ans);
+ });
+
+ instances_[instance_id] = instance;
+ } else {
+ LOGGER(ERROR) << "Failed to create instance of the extension '"
+ << extension_name << "'";
+ }
+ } else {
+ LOGGER(ERROR) << "No such extension '" << extension_name << "'";
+ }
+ return instance_id;
+}
+
+void XWalkExtensionServer::HandleIPCMessage(Ewk_IPC_Wrt_Message_Data* data) {
+ if (!data) {
+ LOGGER(ERROR) << "Invalid parameter. data is NULL.";
+ return;
+ }
+
+ if (!ewk_context_) {
+ LOGGER(WARN) << "IPC is not ready yet.";
+ return;
+ }
+
+ Eina_Stringshare* msg_type = ewk_ipc_wrt_message_data_type_get(data);
+ #define TYPE_IS(x) (!strcmp(msg_type, x))
+
+ if (TYPE_IS(kMethodGetExtensions)) {
+ HandleGetExtensions(data);
+ } else if (TYPE_IS(kMethodCreateInstance)) {
+ HandleCreateInstance(data);
+ } else if (TYPE_IS(kMethodDestroyInstance)) {
+ HandleDestroyInstance(data);
+ } else if (TYPE_IS(kMethodPostMessage)) {
+ HandlePostMessageToNative(data);
+ } else if (TYPE_IS(kMethodSendSyncMessage)) {
+ HandleSendSyncMessageToNative(data);
+ } else if (TYPE_IS(kMethodGetAPIScript)) {
+ HandleGetAPIScript(data);
+ }
+
+ eina_stringshare_del(msg_type);
+ #undef TYPE_IS
+}
+
+void XWalkExtensionServer::HandleGetExtensions(Ewk_IPC_Wrt_Message_Data* data) {
+ Json::Value reply = GetExtensions();
+ Json::FastWriter writer;
+ std::string reply_str = writer.write(reply);
+ ewk_ipc_wrt_message_data_value_set(data, reply_str.c_str());
+}
+
+void XWalkExtensionServer::HandleCreateInstance(
+ Ewk_IPC_Wrt_Message_Data* data) {
+ Eina_Stringshare* extension_name = ewk_ipc_wrt_message_data_value_get(data);
+
+ std::string instance_id = CreateInstance(extension_name);
+
+ ewk_ipc_wrt_message_data_value_set(data, instance_id.c_str());
+
+ eina_stringshare_del(extension_name);
+}
+
+void XWalkExtensionServer::HandleDestroyInstance(
+ Ewk_IPC_Wrt_Message_Data* data) {
+ Eina_Stringshare* instance_id = ewk_ipc_wrt_message_data_id_get(data);
+
+ auto it = instances_.find(instance_id);
+ if (it != instances_.end()) {
+ XWalkExtensionInstance* instance = it->second;
+ delete instance;
+ instances_.erase(it);
+ } else {
+ LOGGER(ERROR) << "No such instance '" << instance_id << "'";
+ }
+
+ eina_stringshare_del(instance_id);
+}
+
+void XWalkExtensionServer::HandlePostMessageToNative(
+ Ewk_IPC_Wrt_Message_Data* data) {
+ Eina_Stringshare* instance_id = ewk_ipc_wrt_message_data_id_get(data);
+
+ auto it = instances_.find(instance_id);
+ if (it != instances_.end()) {
+ Eina_Stringshare* msg = ewk_ipc_wrt_message_data_value_get(data);
+ XWalkExtensionInstance* instance = it->second;
+ instance->HandleMessage(msg);
+ eina_stringshare_del(msg);
+ } else {
+ LOGGER(ERROR) << "No such instance '" << instance_id << "'";
+ }
+
+ eina_stringshare_del(instance_id);
+}
+
+void XWalkExtensionServer::HandleSendSyncMessageToNative(
+ Ewk_IPC_Wrt_Message_Data* data) {
+ Eina_Stringshare* instance_id = ewk_ipc_wrt_message_data_id_get(data);
+
+ auto it = instances_.find(instance_id);
+ if (it != instances_.end()) {
+ Eina_Stringshare* msg = ewk_ipc_wrt_message_data_value_get(data);
+ XWalkExtensionInstance* instance = it->second;
+ std::string reply;
+ instance->SetSendSyncReplyCallback([&reply](const std::string& msg) {
+ reply = msg;
+ });
+ instance->HandleSyncMessage(msg);
+ ewk_ipc_wrt_message_data_value_set(data, reply.c_str());
+ eina_stringshare_del(msg);
+ } else {
+ LOGGER(ERROR) << "No such instance '" << instance_id << "'";
+ }
+
+ eina_stringshare_del(instance_id);
+}
+
+void XWalkExtensionServer::HandleGetAPIScript(
+ Ewk_IPC_Wrt_Message_Data* data) {
+ Eina_Stringshare* extension_name = ewk_ipc_wrt_message_data_value_get(data);
+
+ std::string api = GetAPIScript(extension_name);
+
+ ewk_ipc_wrt_message_data_value_set(data, api.c_str());
+
+ eina_stringshare_del(extension_name);
+}
+
+void XWalkExtensionServer::LoadUserExtensions(const std::string app_path) {
+ manager_.LoadUserExtensions(app_path);
+}
+
+} // namespace extensions
--- /dev/null
+// Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef XWALK_EXTENSIONS_XWALK_EXTENSION_SERVER_H_
+#define XWALK_EXTENSIONS_XWALK_EXTENSION_SERVER_H_
+
+#include <EWebKit.h>
+#include <EWebKit_internal.h>
+#include <json/json.h>
+
+#include <string>
+#include <map>
+
+#include "extensions/common/xwalk_extension_manager.h"
+#include "extensions/common/xwalk_extension_instance.h"
+
+namespace extensions {
+
+class XWalkExtensionServer {
+ public:
+ static XWalkExtensionServer* GetInstance();
+
+ void SetupIPC(Ewk_Context* ewk_context);
+ void Preload();
+ Json::Value GetExtensions();
+ std::string GetAPIScript(const std::string& extension_name);
+ std::string CreateInstance(const std::string& extension_name);
+
+ void HandleIPCMessage(Ewk_IPC_Wrt_Message_Data* data);
+
+ void Shutdown();
+ void LoadUserExtensions(const std::string app_path);
+
+ private:
+ XWalkExtensionServer();
+ virtual ~XWalkExtensionServer();
+
+ void HandleGetExtensions(Ewk_IPC_Wrt_Message_Data* data);
+ void HandleCreateInstance(Ewk_IPC_Wrt_Message_Data* data);
+ void HandleDestroyInstance(Ewk_IPC_Wrt_Message_Data* data);
+ void HandlePostMessageToNative(Ewk_IPC_Wrt_Message_Data* data);
+ void HandleSendSyncMessageToNative(Ewk_IPC_Wrt_Message_Data* data);
+ void HandleGetAPIScript(Ewk_IPC_Wrt_Message_Data* data);
+
+ typedef std::map<std::string, XWalkExtensionInstance*> InstanceMap;
+
+ Ewk_Context* ewk_context_;
+
+ XWalkExtensionManager manager_;
+
+ InstanceMap instances_;
+};
+
+} // namespace extensions
+
+#endif // XWALK_EXTENSIONS_XWALK_EXTENSION_SERVER_H_
--- /dev/null
+{
+ 'includes':[
+ '../build/common.gypi',
+ ],
+ 'targets': [
+ {
+ 'target_name': 'xwalk_extension_shared',
+ 'type': 'shared_library',
+ 'sources': [
+ 'common/constants.h',
+ 'common/constants.cc',
+ 'common/xwalk_extension.h',
+ 'common/xwalk_extension.cc',
+ 'common/xwalk_extension_instance.h',
+ 'common/xwalk_extension_instance.cc',
+ 'common/xwalk_extension_adapter.h',
+ 'common/xwalk_extension_adapter.cc',
+ 'common/xwalk_extension_manager.h',
+ 'common/xwalk_extension_manager.cc',
+ 'common/xwalk_extension_server.h',
+ 'common/xwalk_extension_server.cc',
+ 'renderer/xwalk_extension_client.h',
+ 'renderer/xwalk_extension_client.cc',
+ 'renderer/xwalk_extension_module.h',
+ 'renderer/xwalk_extension_module.cc',
+ 'renderer/xwalk_extension_renderer_controller.h',
+ 'renderer/xwalk_extension_renderer_controller.cc',
+ 'renderer/xwalk_module_system.h',
+ 'renderer/xwalk_module_system.cc',
+ 'renderer/xwalk_v8tools_module.h',
+ 'renderer/xwalk_v8tools_module.cc',
+ 'renderer/widget_module.h',
+ 'renderer/widget_module.cc',
+ 'renderer/object_tools_module.h',
+ 'renderer/object_tools_module.cc',
+ 'renderer/runtime_ipc_client.h',
+ 'renderer/runtime_ipc_client.cc',
+ ],
+ 'cflags': [
+ '-fvisibility=default',
+ ],
+ 'variables': {
+ 'packages': [
+ 'chromium-efl',
+ 'elementary',
+ ],
+ },
+ 'direct_dependent_settings': {
+# 'libraries': [
+# '-lxwalk_extension_shared',
+# ],
+ 'variables': {
+ 'packages': [
+ 'jsoncpp',
+ ],
+ },
+ },
+ }, # end of target 'xwalk_extension_static'
+ ], # end of targets
+}
--- /dev/null
+[
+ {
+ "name":"SplashScreen",
+ "lib":"libsplash_screen_plugin.so",
+ "entry_points":["window.screen.show"]
+ }
+]
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var sendRuntimeMessage = extension.sendRuntimeMessage || function() {
+ console.error('Runtime did not implement extension.sendRuntimeMessage!');
+};
+window.screen.show = function() {
+ sendRuntimeMessage('tizen://hide_splash_screen');
+};
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <list>
+#include <memory>
+#include <map>
+#include <vector>
+
+#include "extensions/public/XW_Extension.h"
+#include "extensions/public/XW_Extension_EntryPoints.h"
+#include "extensions/public/XW_Extension_Permissions.h"
+#include "extensions/public/XW_Extension_Runtime.h"
+#include "extensions/public/XW_Extension_SyncMessage.h"
+
+#include "common/application_data.h"
+#include "common/locale_manager.h"
+#include "common/logger.h"
+#include "common/string_utils.h"
+
+XW_Extension g_xw_extension = 0;
+const XW_CoreInterface* g_core = NULL;
+const XW_MessagingInterface* g_messaging = NULL;
+const XW_Internal_SyncMessagingInterface* g_sync_messaging = NULL;
+const XW_Internal_EntryPointsInterface* g_entry_points = NULL;
+const XW_Internal_RuntimeInterface* g_runtime = NULL;
+
+extern const char kSource_splash_screen_api[];
+
+extern "C" int32_t XW_Initialize(XW_Extension extension,
+ XW_GetInterface get_interface) {
+ g_xw_extension = extension;
+ g_core = reinterpret_cast<const XW_CoreInterface*>(
+ get_interface(XW_CORE_INTERFACE));
+ if (!g_core) {
+ LOGGER(ERROR)
+ << "Can't initialize extension: error getting Core interface.";
+ return XW_ERROR;
+ }
+
+ g_messaging = reinterpret_cast<const XW_MessagingInterface*>(
+ get_interface(XW_MESSAGING_INTERFACE));
+ if (!g_messaging) {
+ LOGGER(ERROR)
+ << "Can't initialize extension: error getting Messaging interface.";
+ return XW_ERROR;
+ }
+
+ g_sync_messaging =
+ reinterpret_cast<const XW_Internal_SyncMessagingInterface*>(
+ get_interface(XW_INTERNAL_SYNC_MESSAGING_INTERFACE));
+ if (!g_sync_messaging) {
+ LOGGER(ERROR)
+ << "Can't initialize extension: "
+ << "error getting SyncMessaging interface.";
+ return XW_ERROR;
+ }
+
+ g_entry_points = reinterpret_cast<const XW_Internal_EntryPointsInterface*>(
+ get_interface(XW_INTERNAL_ENTRY_POINTS_INTERFACE));
+ if (!g_entry_points) {
+ LOGGER(ERROR)
+ << "NOTE: Entry points interface not available in this version "
+ << "of Crosswalk, ignoring entry point data for extensions.\n";
+ return XW_ERROR;
+ }
+
+ g_runtime = reinterpret_cast<const XW_Internal_RuntimeInterface*>(
+ get_interface(XW_INTERNAL_RUNTIME_INTERFACE));
+ if (!g_runtime) {
+ LOGGER(ERROR)
+ << "NOTE: runtime interface not available in this version "
+ << "of Crosswalk, ignoring runtime variables for extensions.\n";
+ return XW_ERROR;
+ }
+
+ g_core->SetExtensionName(g_xw_extension, "SplashScreen");
+ const char* entry_points[] = {"window.screen.show", NULL};
+ g_entry_points->SetExtraJSEntryPoints(g_xw_extension, entry_points);
+ g_core->SetJavaScriptAPI(g_xw_extension, kSource_splash_screen_api);
+
+ return XW_OK;
+}
--- /dev/null
+[
+ {
+ "name":"Widget",
+ "lib":"libwidget_plugin.so",
+ "entry_points":["widget"]
+ }
+]
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var dispatchStorageEvent = function(key, oldValue, newValue) {
+ var evt = document.createEvent("CustomEvent");
+ evt.initCustomEvent("storage", true, true, null);
+ evt.key = key;
+ evt.oldValue = oldValue;
+ evt.newValue = newValue;
+ evt.storageArea = window.widget.preference;
+ document.dispatchEvent(evt);
+ for (var i=0; i < window.frames.length; i++) {
+ window.frames[i].document.dispatchEvent(evt);
+ }
+};
+
+var widget_info_ = requireNative('WidgetModule');
+var preference_ = widget_info_['preference'];
+preference_.__onChanged_WRT__ = dispatchStorageEvent;
+
+function Widget() {
+ Object.defineProperties(this, {
+ "author": {
+ value: widget_info_[
+"author"],
+ writable: false
+ },
+ "description": {
+ value: widget_info_["description"],
+ writable: false
+ },
+ "name": {
+ value: widget_info_["name"],
+ writable: false
+ },
+ "shortName": {
+ value: widget_info_["shortName"],
+ writable: false
+ },
+ "version": {
+ value: widget_info_["version"],
+ writable: false
+ },
+ "id": {
+ value: widget_info_["id"],
+ writable: false
+ },
+ "authorEmail": {
+ value: widget_info_["authorEmail"],
+ writable: false
+ },
+ "authorHref": {
+ value: widget_info_["authorHref"],
+ writable: false
+ },
+ "height": {
+ get: function() {
+ return window && window.innerHeight || 0;
+ },
+ configurable: false
+ },
+ "width": {
+ get: function() {
+ return window && window.innerWidth || 0;
+ },
+ configurable: false
+ },
+ "preferences": {
+ value: preference_,
+ writable: false
+ }
+ });
+};
+
+Widget.prototype.toString = function() {
+ return "[object Widget]";
+};
+
+window.widget = new Widget();
+exports = Widget;
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <list>
+#include <memory>
+#include <map>
+#include <vector>
+
+#include "extensions/public/XW_Extension.h"
+#include "extensions/public/XW_Extension_EntryPoints.h"
+#include "extensions/public/XW_Extension_Permissions.h"
+#include "extensions/public/XW_Extension_Runtime.h"
+#include "extensions/public/XW_Extension_SyncMessage.h"
+
+#include "common/application_data.h"
+#include "common/locale_manager.h"
+#include "common/logger.h"
+#include "common/string_utils.h"
+
+XW_Extension g_xw_extension = 0;
+const XW_CoreInterface* g_core = NULL;
+const XW_MessagingInterface* g_messaging = NULL;
+const XW_Internal_SyncMessagingInterface* g_sync_messaging = NULL;
+const XW_Internal_EntryPointsInterface* g_entry_points = NULL;
+const XW_Internal_RuntimeInterface* g_runtime = NULL;
+
+extern const char kSource_widget_api[];
+
+extern "C" int32_t XW_Initialize(XW_Extension extension,
+ XW_GetInterface get_interface) {
+ g_xw_extension = extension;
+ g_core = reinterpret_cast<const XW_CoreInterface*>(
+ get_interface(XW_CORE_INTERFACE));
+ if (!g_core) {
+ LOGGER(ERROR)
+ << "Can't initialize extension: error getting Core interface.";
+ return XW_ERROR;
+ }
+
+ g_messaging = reinterpret_cast<const XW_MessagingInterface*>(
+ get_interface(XW_MESSAGING_INTERFACE));
+ if (!g_messaging) {
+ LOGGER(ERROR)
+ << "Can't initialize extension: error getting Messaging interface.";
+ return XW_ERROR;
+ }
+
+ g_sync_messaging =
+ reinterpret_cast<const XW_Internal_SyncMessagingInterface*>(
+ get_interface(XW_INTERNAL_SYNC_MESSAGING_INTERFACE));
+ if (!g_sync_messaging) {
+ LOGGER(ERROR)
+ << "Can't initialize extension: "
+ << "error getting SyncMessaging interface.";
+ return XW_ERROR;
+ }
+
+ g_entry_points = reinterpret_cast<const XW_Internal_EntryPointsInterface*>(
+ get_interface(XW_INTERNAL_ENTRY_POINTS_INTERFACE));
+ if (!g_entry_points) {
+ LOGGER(ERROR)
+ << "NOTE: Entry points interface not available in this version "
+ << "of Crosswalk, ignoring entry point data for extensions.\n";
+ return XW_ERROR;
+ }
+
+ g_runtime = reinterpret_cast<const XW_Internal_RuntimeInterface*>(
+ get_interface(XW_INTERNAL_RUNTIME_INTERFACE));
+ if (!g_runtime) {
+ LOGGER(ERROR)
+ << "NOTE: runtime interface not available in this version "
+ << "of Crosswalk, ignoring runtime variables for extensions.\n";
+ return XW_ERROR;
+ }
+
+ g_core->SetExtensionName(g_xw_extension, "Widget");
+ const char* entry_points[] = {"widget", NULL};
+ g_entry_points->SetExtraJSEntryPoints(g_xw_extension, entry_points);
+ g_core->SetJavaScriptAPI(g_xw_extension, kSource_widget_api);
+
+ return XW_OK;
+}
--- /dev/null
+// Copyright (c) 2013 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef XWALK_EXTENSIONS_PUBLIC_XW_EXTENSION_H_
+#define XWALK_EXTENSIONS_PUBLIC_XW_EXTENSION_H_
+
+// Crosswalk Extensions are modules of code loaded by Crosswalk runtime that
+// allow extending its capabilities. The extension is expected to define a
+// XW_Initialize() function as declared below, get the interfaces it need to
+// use and register to whatever callbacks it needs, then return XW_OK.
+//
+// The Extension is represented by the type XW_Extension. Each extension
+// loaded may be used multiple times for different pages, so to each execution
+// there will be an associated XW_Instance. A reasonable analogy is that the
+// XW_Extension represent a "class", and have concrete instances running.
+//
+// An interface is a struct with a set of functions, provided by Crosswalk,
+// that allow the extension code to interact with the web content. Certain
+// functions in an interface are used to register callbacks, so that Crosswalk
+// can call the extension at specific situations.
+//
+// Crosswalk won't call an extension's XW_Initialize() multiple times in the
+// same process.
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if __GNUC__ >= 4
+#define XW_EXPORT __attribute__ ((visibility("default")))
+#elif defined(_MSC_VER)
+#define XW_EXPORT __declspec(dllexport)
+#endif
+
+#include <stdint.h>
+
+
+// XW_Extension is used to identify your extension when calling functions from
+// the API. You should always use the XW_Extension received at XW_Initialize().
+//
+// XW_Instance is used to identify different web contents using your
+// extension. Each time a new web content is created you can be notified
+// registering the XW_CreatedInstanceCallback, that receives the new
+// XW_Instance. When interacting with an Instance (for example to post a
+// message), you should pass the corresponding XW_Instance.
+//
+// In both types the zero value is never used by Crosswalk, so can be used to
+// initialize variables.
+typedef int32_t XW_Extension;
+typedef int32_t XW_Instance;
+
+enum {
+ XW_OK = 0,
+ XW_ERROR = -1
+};
+
+// Returns a struct containing functions to be used by the extension. Those
+// structs can be stored statically and used until the extension is unloaded.
+// Extensions should use definitions like XW_CORE_INTERFACE, instead of using
+// the versioned definition or the literal string. Returns NULL if the
+// interface is not supported.
+typedef const void* (*XW_GetInterface)(const char* interface_name);
+
+
+typedef int32_t (*XW_Initialize_Func)(XW_Extension extension,
+ XW_GetInterface get_interface);
+
+// XW_Initialize is called after the extension code is loaded. The 'extension'
+// value should be used in further calls that expect XW_Extension argument.
+//
+// The 'get_interface' function should be used to get access to functions that
+// interact with the web content. It is only valid during the execution of the
+// XW_Initialize() function.
+//
+// This function should return XW_OK when the extension was succesfully
+// loaded, otherwise XW_ERROR.
+XW_EXPORT int32_t XW_Initialize(XW_Extension extension,
+ XW_GetInterface get_interface);
+
+
+//
+// XW_CORE_INTERFACE: Basic functionality for Crosswalk Extensions. All
+// extensions should use this interface to set at least their name.
+//
+
+#define XW_CORE_INTERFACE_1 "XW_CoreInterface_1"
+#define XW_CORE_INTERFACE XW_CORE_INTERFACE_1
+
+typedef void (*XW_CreatedInstanceCallback)(XW_Instance instance);
+typedef void (*XW_DestroyedInstanceCallback)(XW_Instance instance);
+typedef void (*XW_ShutdownCallback)(XW_Extension extension);
+
+struct XW_CoreInterface_1 {
+ // Set the name of the extension. It is used as the namespace for the
+ // JavaScript code exposed by the extension. So extension named
+ // 'my_extension', will expose its JavaScript functionality inside
+ // the 'my_extension' namespace.
+ //
+ // This function should be called only during XW_Initialize().
+ void (*SetExtensionName)(XW_Extension extension, const char* name);
+
+ // Set the JavaScript code loaded in the web content when the extension is
+ // used. This can be used together with the messaging mechanism to implement
+ // a higher-level API that posts messages to extensions, see
+ // XW_MESSAGING_INTERFACE below.
+ //
+ // The code will be executed inside a JS function context with the following
+ // objects available:
+ //
+ // - exports: this object should be filled with properties and functions
+ // that will be exposed in the namespace associated with this
+ // extension.
+ //
+ // - extension.postMessage(): post a string message to the extension native
+ // code. See below for details.
+ // - extension.setMessageListener(): allow setting a callback that is called
+ // when the native code sends a message
+ // to JavaScript. Callback takes a string.
+ //
+ // This function should be called only during XW_Initialize().
+ void (*SetJavaScriptAPI)(XW_Extension extension, const char* api);
+
+ // Register callbacks that are called when an instance of this extension
+ // is created or destroyed. Everytime a new web content is loaded, it will
+ // get a new associated instance.
+ //
+ // This function should be called only during XW_Initialize().
+ void (*RegisterInstanceCallbacks)(XW_Extension extension,
+ XW_CreatedInstanceCallback created,
+ XW_DestroyedInstanceCallback destroyed);
+
+ // Register a callback to be executed when the extension will be unloaded.
+ //
+ // This function should be called only during XW_Initialize().
+ void (*RegisterShutdownCallback)(XW_Extension extension,
+ XW_ShutdownCallback shutdown_callback);
+
+ // These two functions are conveniences used to associated arbitrary data
+ // with a given XW_Instance. They can be used only with instances that were
+ // created but not yet completely destroyed. GetInstanceData() can be used
+ // during the destroyed instance callback. If not instance data was set,
+ // getting it returns NULL.
+ void (*SetInstanceData)(XW_Instance instance, void* data);
+ void* (*GetInstanceData)(XW_Instance instance);
+};
+
+typedef struct XW_CoreInterface_1 XW_CoreInterface;
+
+
+//
+// XW_MESSAGING_INTERFACE: Exchange asynchronous messages with JavaScript
+// code provided by extension.
+//
+
+#define XW_MESSAGING_INTERFACE_1 "XW_MessagingInterface_1"
+#define XW_MESSAGING_INTERFACE XW_MESSAGING_INTERFACE_1
+
+typedef void (*XW_HandleMessageCallback)(XW_Instance instance,
+ const char* message);
+
+struct XW_MessagingInterface_1 {
+ // 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
+ // contents.
+ void (*Register)(XW_Extension extension,
+ XW_HandleMessageCallback handle_message);
+
+ // Post a message to the web content associated with the instance. To
+ // receive this message the extension's JavaScript code should set a
+ // listener using extension.setMessageListener() function.
+ //
+ // This function is thread-safe and can be called until the instance is
+ // destroyed.
+ void (*PostMessage)(XW_Instance instance, const char* message);
+};
+
+typedef struct XW_MessagingInterface_1 XW_MessagingInterface;
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // XWALK_EXTENSIONS_PUBLIC_XW_EXTENSION_H_
--- /dev/null
+// Copyright (c) 2013 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef XWALK_EXTENSIONS_PUBLIC_XW_EXTENSION_ENTRYPOINTS_H_
+#define XWALK_EXTENSIONS_PUBLIC_XW_EXTENSION_ENTRYPOINTS_H_
+
+// NOTE: This file and interfaces marked as internal are not considered stable
+// and can be modified in incompatible ways between Crosswalk versions.
+
+#ifndef XWALK_EXTENSIONS_PUBLIC_XW_EXTENSION_H_
+#error "You should include XW_Extension.h before this file"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define XW_INTERNAL_ENTRY_POINTS_INTERFACE_1 \
+ "XW_Internal_EntryPointsInterface_1"
+#define XW_INTERNAL_ENTRY_POINTS_INTERFACE \
+ XW_INTERNAL_ENTRY_POINTS_INTERFACE_1
+
+//
+// XW_INTERNAL_ENTRY_POINTS_INTERFACE: provides a way for extensions to add
+// more information about its implementation. For now, allow extensions to
+// specify more objects that the access should cause the extension to be
+// loaded.
+//
+
+struct XW_Internal_EntryPointsInterface_1 {
+ // Register extra entry points for this extension. An "extra" entry points
+ // are objects outside the implicit namespace for which the extension should
+ // be loaded when they are touched.
+ //
+ // This function should be called only during XW_Initialize().
+ void (*SetExtraJSEntryPoints)(XW_Extension extension,
+ const char** entry_points);
+};
+
+typedef struct XW_Internal_EntryPointsInterface_1
+ XW_Internal_EntryPointsInterface;
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // XWALK_EXTENSIONS_PUBLIC_XW_EXTENSION_ENTRYPOINTS_H_
+
--- /dev/null
+// Copyright (c) 2015 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef XWALK_EXTENSIONS_PUBLIC_XW_EXTENSION_MESSAGE_2_H_
+#define XWALK_EXTENSIONS_PUBLIC_XW_EXTENSION_MESSAGE_2_H_
+
+#ifndef XWALK_EXTENSIONS_PUBLIC_XW_EXTENSION_H_
+#error "You should include XW_Extension.h before this file"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define XW_MESSAGING_INTERFACE_2 "XW_MessagingInterface_2"
+
+typedef void (*XW_HandleBinaryMessageCallback)(XW_Instance instance,
+ const char* message,
+ const size_t size);
+
+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
+ // contents.
+ void (*Register)(XW_Extension extension,
+ XW_HandleMessageCallback handle_message);
+
+ // Post a message to the web content associated with the instance. To
+ // receive this message the extension's JavaScript code should set a
+ // listener using extension.setMessageListener() function.
+ //
+ // This function is thread-safe and can be called until the instance is
+ // destroyed.
+ void (*PostMessage)(XW_Instance instance, const char* message);
+
+ // Register a callback to be called when the JavaScript code associated
+ // with the extension posts a binary message (ArrayBuffer object).
+ // Note that the callback will be called with the XW_Instance that posted
+ // the message as well as the message contents.
+ void (*RegisterBinaryMesssageCallback)(
+ XW_Extension extension,
+ XW_HandleBinaryMessageCallback handle_message);
+
+ // Post a binary message to the web content associated with the instance. To
+ // receive this message the extension's JavaScript code should set a
+ // listener using extension.setMessageListener() function.
+ // The JavaScript message listener function would receive the binary message
+ // in an ArrayBuffer object.
+ //
+ // This function is thread-safe and can be called until the instance is
+ // destroyed.
+ void (*PostBinaryMessage)(XW_Instance instance,
+ const char* message, size_t size);
+};
+
+typedef struct XW_MessagingInterface_2 XW_MessagingInterface2;
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // XWALK_EXTENSIONS_PUBLIC_XW_EXTENSION_MESSAGE_2_H_
--- /dev/null
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef XWALK_EXTENSIONS_PUBLIC_XW_EXTENSION_PERMISSIONS_H_
+#define XWALK_EXTENSIONS_PUBLIC_XW_EXTENSION_PERMISSIONS_H_
+
+// NOTE: This file and interfaces marked as internal are not considered stable
+// and can be modified in incompatible ways between Crosswalk versions.
+
+#ifndef XWALK_EXTENSIONS_PUBLIC_XW_EXTENSION_H_
+#error "You should include XW_Extension.h before this file"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define XW_INTERNAL_PERMISSIONS_INTERFACE_1 \
+ "XW_Internal_PermissionsInterface_1"
+#define XW_INTERNAL_PERMISSIONS_INTERFACE \
+ XW_INTERNAL_PERMISSIONS_INTERFACE_1
+
+//
+// XW_INTERNAL_PERMISSIONS_INTERFACE: provides a way for extensions
+// check if they have the proper permissions for certain APIs.
+//
+
+struct XW_Internal_PermissionsInterface_1 {
+ int (*CheckAPIAccessControl)(XW_Extension extension, const char* api_name);
+ int (*RegisterPermissions)(XW_Extension extension, const char* perm_table);
+};
+
+typedef struct XW_Internal_PermissionsInterface_1
+ XW_Internal_PermissionsInterface;
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // XWALK_EXTENSIONS_PUBLIC_XW_EXTENSION_PERMISSIONS_H_
--- /dev/null
+// Copyright (c) 2013 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef XWALK_EXTENSIONS_PUBLIC_XW_EXTENSION_RUNTIME_H_
+#define XWALK_EXTENSIONS_PUBLIC_XW_EXTENSION_RUNTIME_H_
+
+// NOTE: This file and interfaces marked as internal are not considered stable
+// and can be modified in incompatible ways between Crosswalk versions.
+
+#ifndef XWALK_EXTENSIONS_PUBLIC_XW_EXTENSION_H_
+#error "You should include XW_Extension.h before this file"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define XW_INTERNAL_RUNTIME_INTERFACE_1 \
+ "XW_Internal_RuntimeInterface_1"
+#define XW_INTERNAL_RUNTIME_INTERFACE \
+ XW_INTERNAL_RUNTIME_INTERFACE_1
+
+//
+// XW_INTERNAL_RUNTIME_INTERFACE: allow extensions to gather information
+// from the runtime.
+//
+
+struct XW_Internal_RuntimeInterface_1 {
+ void (*GetRuntimeVariableString)(XW_Extension extension,
+ const char* key,
+ char* value,
+ unsigned int value_len);
+};
+
+typedef struct XW_Internal_RuntimeInterface_1
+ XW_Internal_RuntimeInterface;
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // XWALK_EXTENSIONS_PUBLIC_XW_EXTENSION_RUNTIME_H_
+
--- /dev/null
+// Copyright (c) 2013 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef XWALK_EXTENSIONS_PUBLIC_XW_EXTENSION_SYNCMESSAGE_H_
+#define XWALK_EXTENSIONS_PUBLIC_XW_EXTENSION_SYNCMESSAGE_H_
+
+// NOTE: This file and interfaces marked as internal are not considered stable
+// and can be modified in incompatible ways between Crosswalk versions.
+
+#ifndef XWALK_EXTENSIONS_PUBLIC_XW_EXTENSION_H_
+#error "You should include XW_Extension.h before this file"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//
+// XW_INTERNAL_SYNC_MESSAGING_INTERFACE: allow JavaScript code to send a
+// synchronous message to extension code and block until response is
+// available. The response is made available by calling the SetSyncReply
+// function, that can be done from outside the context of the SyncMessage
+// handler.
+//
+
+#define XW_INTERNAL_SYNC_MESSAGING_INTERFACE_1 \
+ "XW_InternalSyncMessagingInterface_1"
+#define XW_INTERNAL_SYNC_MESSAGING_INTERFACE \
+ XW_INTERNAL_SYNC_MESSAGING_INTERFACE_1
+
+typedef void (*XW_HandleSyncMessageCallback)(XW_Instance instance,
+ const char* message);
+
+struct XW_Internal_SyncMessagingInterface_1 {
+ void (*Register)(XW_Extension extension,
+ XW_HandleSyncMessageCallback handle_sync_message);
+ void (*SetSyncReply)(XW_Instance instance, const char* reply);
+};
+
+typedef struct XW_Internal_SyncMessagingInterface_1
+ XW_Internal_SyncMessagingInterface;
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // XWALK_EXTENSIONS_PUBLIC_XW_EXTENSION_SYNCMESSAGE_H_
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "extensions/renderer/object_tools_module.h"
+
+#include <v8/v8.h>
+
+#include <string>
+
+#include "common/logger.h"
+
+namespace extensions {
+
+namespace {
+const char *kCreateObjectCode =
+ "(function(object) {"
+ " var newobject = Object.create(object);"
+ " Object.getOwnPropertyNames(object).forEach(function(name) {"
+ " if (object[name] instanceof Function) {"
+ " newobject[name] = object[name];"
+ " }"
+ " });"
+ " newobject['origin_prototype'] = {};"
+ " Object.getOwnPropertyNames(object.prototype).forEach(function(name) {"
+ " if (object.prototype[name] instanceof Function) {"
+ " newobject['origin_prototype'][name] = object.prototype[name];"
+ " }"
+ " });"
+ " return function() {"
+ " return newobject;"
+ " };"
+ "}(Object));";
+
+v8::Handle<v8::Value> RunString(const std::string& code) {
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ v8::EscapableHandleScope handle_scope(isolate);
+ v8::Handle<v8::String> v8_code(
+ v8::String::NewFromUtf8(isolate, code.c_str()));
+
+ v8::TryCatch try_catch;
+ try_catch.SetVerbose(true);
+
+ v8::Handle<v8::Script> script(v8::Script::Compile(v8_code));
+ if (try_catch.HasCaught()) {
+ v8::String::Utf8Value exception(try_catch.Exception());
+ LOGGER(ERROR) << "Error occurred(script compile):" << *exception;
+ return handle_scope.Escape(
+ v8::Local<v8::Primitive>(v8::Undefined(isolate)));
+ }
+
+ v8::Local<v8::Value> result = script->Run();
+ if (try_catch.HasCaught()) {
+ v8::String::Utf8Value exception(try_catch.Exception());
+ LOGGER(ERROR) << "Error occurred(script run):" << *exception;
+ return handle_scope.Escape(
+ v8::Local<v8::Primitive>(v8::Undefined(isolate)));
+ }
+ return handle_scope.Escape(result);
+}
+} // namespace
+
+
+ObjectToolsModule::ObjectToolsModule() {
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ v8::HandleScope handle_scope(isolate);
+
+ v8::Handle<v8::Value> result = RunString(kCreateObjectCode);
+ if (!result->IsFunction()) {
+ LOGGER(ERROR) << "Couldn't load Object Create function";
+ return;
+ }
+ v8::Handle<v8::Function> create_function =
+ v8::Handle<v8::Function>::Cast(result);
+
+ create_function_.Reset(isolate, create_function);
+}
+
+ObjectToolsModule::~ObjectToolsModule() {
+ create_function_.Reset();
+}
+
+v8::Handle<v8::Object> ObjectToolsModule::NewInstance() {
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ if (create_function_.IsEmpty()) {
+ return v8::Object::New(isolate);
+ }
+ v8::Handle<v8::Function> function =
+ v8::Local<v8::Function>::New(isolate, create_function_);
+
+ v8::Handle<v8::Context> context = v8::Context::New(isolate);
+ v8::TryCatch try_catch;
+ v8::Handle<v8::Value> ret = function->Call(context->Global(), 0, NULL);
+ if (try_catch.HasCaught()) {
+ LOGGER(ERROR) << "Exception when running create function: ";
+ return v8::Object::New(isolate);
+ }
+ return v8::Handle<v8::Object>::Cast(ret);
+}
+
+} // namespace extensions
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef XWALK_EXTENSIONS_RENDERER_OBJECT_TOOLS_MODULE_H_
+#define XWALK_EXTENSIONS_RENDERER_OBJECT_TOOLS_MODULE_H_
+
+#include "extensions/renderer/xwalk_module_system.h"
+
+namespace extensions {
+
+class ObjectToolsModule : public XWalkNativeModule {
+ public:
+ ObjectToolsModule();
+ ~ObjectToolsModule() override;
+
+ private:
+ v8::Handle<v8::Object> NewInstance() override;
+ v8::Persistent<v8::Function> create_function_;
+};
+
+} // namespace extensions
+
+#endif // XWALK_EXTENSIONS_RENDERER_OBJECT_TOOLS_MODULE_H_
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "extensions/renderer/runtime_ipc_client.h"
+#include "extensions/renderer/xwalk_extension_renderer_controller.h"
+
+#include "common/logger.h"
+#include "common/profiler.h"
+#include "common/string_utils.h"
+
+namespace extensions {
+
+namespace {
+
+const int kRoutingIdEmbedderDataIndex = 12;
+
+} // namespace
+
+RuntimeIPCClient::JSCallback::JSCallback(v8::Isolate* isolate,
+ v8::Handle<v8::Function> callback) {
+ callback_.Reset(isolate, callback);
+}
+
+RuntimeIPCClient::JSCallback::~JSCallback() {
+ callback_.Reset();
+}
+
+void RuntimeIPCClient::JSCallback::Call(v8::Isolate* isolate,
+ v8::Handle<v8::Value> args[]) {
+ if (!callback_.IsEmpty()) {
+ v8::HandleScope handle_scope(isolate);
+ v8::TryCatch try_catch(isolate);
+ v8::Handle<v8::Function> func =
+ v8::Local<v8::Function>::New(isolate, callback_);
+ func->Call(func, 1, args);
+ if (try_catch.HasCaught()) {
+ LOGGER(ERROR) << "Exception when running Javascript callback";
+ v8::String::Utf8Value exception_str(try_catch.Exception());
+ LOGGER(ERROR) << (*exception_str);
+ }
+ }
+}
+
+// static
+RuntimeIPCClient* RuntimeIPCClient::GetInstance() {
+ static RuntimeIPCClient self;
+ return &self;
+}
+
+RuntimeIPCClient::RuntimeIPCClient() {
+}
+
+int RuntimeIPCClient::GetRoutingId(v8::Handle<v8::Context> context) {
+ v8::Handle<v8::Value> value =
+ context->GetEmbedderData(kRoutingIdEmbedderDataIndex);
+ int routing_id = 0;
+ if (value->IsNumber()) {
+ routing_id = value->IntegerValue();
+ } else {
+ LOGGER(WARN) << "Failed to get routing index from context.";
+ }
+
+ return routing_id;
+}
+
+void RuntimeIPCClient::SetRoutingId(v8::Handle<v8::Context> context,
+ int routing_id) {
+ context->SetEmbedderData(kRoutingIdEmbedderDataIndex,
+ v8::Integer::New(context->GetIsolate(), routing_id));
+}
+
+void RuntimeIPCClient::SendMessage(v8::Handle<v8::Context> context,
+ const std::string& type,
+ const std::string& value) {
+ SendMessage(context, type, "", "", value);
+}
+
+void RuntimeIPCClient::SendMessage(v8::Handle<v8::Context> context,
+ const std::string& type,
+ const std::string& id,
+ const std::string& value) {
+ SendMessage(context, type, id, "", value);
+}
+
+void RuntimeIPCClient::SendMessage(v8::Handle<v8::Context> context,
+ const std::string& type,
+ const std::string& id,
+ const std::string& ref_id,
+ const std::string& value) {
+ if (!strcmp(type.c_str(), "tizen://exit")) {
+ extensions::XWalkExtensionRendererController& controller =
+ extensions::XWalkExtensionRendererController::GetInstance();
+ controller.exit_requested = true;
+ }
+
+ int routing_id = GetRoutingId(context);
+ if (routing_id < 1) {
+ LOGGER(ERROR) << "Invalid routing handle for IPC.";
+ return;
+ }
+
+ Ewk_IPC_Wrt_Message_Data* msg = ewk_ipc_wrt_message_data_new();
+ ewk_ipc_wrt_message_data_type_set(msg, type.c_str());
+ ewk_ipc_wrt_message_data_id_set(msg, id.c_str());
+ ewk_ipc_wrt_message_data_reference_id_set(msg, ref_id.c_str());
+ ewk_ipc_wrt_message_data_value_set(msg, value.c_str());
+
+ if (!ewk_ipc_plugins_message_send(routing_id, msg)) {
+ LOGGER(ERROR) << "Failed to send message to runtime using ewk_ipc.";
+ }
+
+ ewk_ipc_wrt_message_data_del(msg);
+}
+
+std::string RuntimeIPCClient::SendSyncMessage(v8::Handle<v8::Context> context,
+ const std::string& type,
+ const std::string& value) {
+ return SendSyncMessage(context, type, "", "", value);
+}
+
+std::string RuntimeIPCClient::SendSyncMessage(v8::Handle<v8::Context> context,
+ const std::string& type,
+ const std::string& id,
+ const std::string& value) {
+ return SendSyncMessage(context, type, id, "", value);
+}
+
+std::string RuntimeIPCClient::SendSyncMessage(v8::Handle<v8::Context> context,
+ const std::string& type,
+ const std::string& id,
+ const std::string& ref_id,
+ const std::string& value) {
+ int routing_id = GetRoutingId(context);
+ if (routing_id < 1) {
+ LOGGER(ERROR) << "Invalid routing handle for IPC.";
+ return std::string();
+ }
+
+ Ewk_IPC_Wrt_Message_Data* msg = ewk_ipc_wrt_message_data_new();
+ ewk_ipc_wrt_message_data_type_set(msg, type.c_str());
+ ewk_ipc_wrt_message_data_id_set(msg, id.c_str());
+ ewk_ipc_wrt_message_data_reference_id_set(msg, ref_id.c_str());
+ ewk_ipc_wrt_message_data_value_set(msg, value.c_str());
+
+ if (!ewk_ipc_plugins_sync_message_send(routing_id, msg)) {
+ LOGGER(ERROR) << "Failed to send message to runtime using ewk_ipc.";
+ ewk_ipc_wrt_message_data_del(msg);
+ return std::string();
+ }
+
+ Eina_Stringshare* msg_value = ewk_ipc_wrt_message_data_value_get(msg);
+ std::string result(msg_value);
+ eina_stringshare_del(msg_value);
+
+ ewk_ipc_wrt_message_data_del(msg);
+
+ return result;
+}
+
+void RuntimeIPCClient::SendAsyncMessage(v8::Handle<v8::Context> context,
+ const std::string& type,
+ const std::string& value,
+ ReplyCallback callback) {
+ int routing_id = GetRoutingId(context);
+ if (routing_id < 1) {
+ LOGGER(ERROR) << "Invalid routing handle for IPC.";
+ return;
+ }
+
+ std::string msg_id = common::utils::GenerateUUID();
+
+ Ewk_IPC_Wrt_Message_Data* msg = ewk_ipc_wrt_message_data_new();
+ ewk_ipc_wrt_message_data_id_set(msg, msg_id.c_str());
+ ewk_ipc_wrt_message_data_type_set(msg, type.c_str());
+ ewk_ipc_wrt_message_data_value_set(msg, value.c_str());
+
+ if (!ewk_ipc_plugins_message_send(routing_id, msg)) {
+ LOGGER(ERROR) << "Failed to send message to runtime using ewk_ipc.";
+ ewk_ipc_wrt_message_data_del(msg);
+ return;
+ }
+
+ callbacks_[msg_id] = callback;
+
+ ewk_ipc_wrt_message_data_del(msg);
+}
+
+void RuntimeIPCClient::HandleMessageFromRuntime(
+ const Ewk_IPC_Wrt_Message_Data* msg) {
+ if (msg == NULL) {
+ LOGGER(ERROR) << "received message is NULL";
+ return;
+ }
+
+ Eina_Stringshare* msg_refid = ewk_ipc_wrt_message_data_reference_id_get(msg);
+
+ if (msg_refid == NULL || !strcmp(msg_refid, "")) {
+ if (msg_refid) eina_stringshare_del(msg_refid);
+ LOGGER(ERROR) << "No reference id of received message.";
+ return;
+ }
+
+ auto it = callbacks_.find(msg_refid);
+ if (it == callbacks_.end()) {
+ eina_stringshare_del(msg_refid);
+ LOGGER(ERROR) << "No registered callback with reference id : " << msg_refid;
+ return;
+ }
+
+ Eina_Stringshare* msg_type = ewk_ipc_wrt_message_data_type_get(msg);
+ Eina_Stringshare* msg_value = ewk_ipc_wrt_message_data_value_get(msg);
+
+ ReplyCallback func = it->second;
+ if (func) {
+ func(msg_type, msg_value);
+ }
+
+ callbacks_.erase(it);
+
+ eina_stringshare_del(msg_refid);
+ eina_stringshare_del(msg_type);
+ eina_stringshare_del(msg_value);
+}
+
+} // namespace extensions
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef XWALK_EXTENSIONS_RENDERER_RUNTIME_IPC_CLIENT_H_
+#define XWALK_EXTENSIONS_RENDERER_RUNTIME_IPC_CLIENT_H_
+
+#include <v8/v8.h>
+#include <EWebKit.h>
+#include <EWebKit_internal.h>
+
+#include <functional>
+#include <map>
+#include <string>
+
+namespace extensions {
+
+class RuntimeIPCClient {
+ public:
+ class JSCallback {
+ public:
+ explicit JSCallback(v8::Isolate* isolate,
+ v8::Handle<v8::Function> callback);
+ ~JSCallback();
+
+ void Call(v8::Isolate* isolate, v8::Handle<v8::Value> args[]);
+ private:
+ v8::Persistent<v8::Function> callback_;
+ };
+
+ typedef std::function<void(const std::string& type,
+ const std::string& value)> ReplyCallback;
+
+ static RuntimeIPCClient* GetInstance();
+
+ // Send message to BrowserProcess without reply
+ void SendMessage(v8::Handle<v8::Context> context,
+ const std::string& type,
+ const std::string& value);
+
+ void SendMessage(v8::Handle<v8::Context> context,
+ const std::string& type,
+ const std::string& id,
+ const std::string& value);
+
+ void SendMessage(v8::Handle<v8::Context> context,
+ const std::string& type,
+ const std::string& id,
+ const std::string& ref_id,
+ const std::string& value);
+
+ // Send message to BrowserProcess synchronous with reply
+ std::string SendSyncMessage(v8::Handle<v8::Context> context,
+ const std::string& type,
+ const std::string& value);
+
+ std::string SendSyncMessage(v8::Handle<v8::Context> context,
+ const std::string& type,
+ const std::string& id,
+ const std::string& value);
+
+ std::string SendSyncMessage(v8::Handle<v8::Context> context,
+ const std::string& type,
+ const std::string& id,
+ const std::string& ref_id,
+ const std::string& value);
+
+ // Send message to BrowserProcess asynchronous,
+ // reply message will be passed to callback function.
+ void SendAsyncMessage(v8::Handle<v8::Context> context,
+ const std::string& type, const std::string& value,
+ ReplyCallback callback);
+
+ void HandleMessageFromRuntime(const Ewk_IPC_Wrt_Message_Data* msg);
+
+ int GetRoutingId(v8::Handle<v8::Context> context);
+
+ void SetRoutingId(v8::Handle<v8::Context> context, int routing_id);
+
+ private:
+ RuntimeIPCClient();
+
+ std::map<std::string, ReplyCallback> callbacks_;
+};
+
+} // namespace extensions
+
+#endif // XWALK_EXTENSIONS_RENDERER_RUNTIME_IPC_CLIENT_H_
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "extensions/renderer/widget_module.h"
+
+#include <v8/v8.h>
+
+#include <algorithm>
+#include <vector>
+
+#include "common/app_db.h"
+#include "common/logger.h"
+
+namespace extensions {
+
+namespace {
+const char* kOnchangedEventHandler = "__onChanged_WRT__";
+const char* kKeyKey = "key";
+const char* kGetItemKey = "getItem";
+const char* kSetItemKey = "setItem";
+const char* kRemoveItemKey = "removeItem";
+const char* kLengthKey = "length";
+const char* kClearKey = "clear";
+const int kKeyLengthLimit = 80;
+const int kValueLengthLimit = 8192;
+
+std::vector<const char*> kExcludeList = {
+ kOnchangedEventHandler,
+ kKeyKey,
+ kGetItemKey,
+ kSetItemKey,
+ kRemoveItemKey,
+ kLengthKey,
+ kClearKey};
+
+void DispatchEvent(const v8::Local<v8::Object>& This,
+ v8::Local<v8::Value> key,
+ v8::Local<v8::Value> oldvalue,
+ v8::Local<v8::Value> newvalue) {
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+
+ v8::Handle<v8::Value> function =
+ This->Get(v8::String::NewFromUtf8(isolate, kOnchangedEventHandler));
+
+ if (function.IsEmpty() || !function->IsFunction()) {
+ LOGGER(DEBUG) << "onChanged function not set";
+ return;
+ }
+
+ v8::Handle<v8::Context> context = v8::Context::New(isolate);
+
+ const int argc = 3;
+ v8::Handle<v8::Value> argv[argc] = {
+ key,
+ oldvalue,
+ newvalue
+ };
+
+ v8::TryCatch try_catch;
+ v8::Handle<v8::Function>::Cast(function)->Call(
+ context->Global(), argc, argv);
+ if (try_catch.HasCaught())
+ LOGGER(DEBUG) << "Exception when running onChanged callback";
+}
+
+v8::Handle<v8::Object> MakeException(int code,
+ std::string name,
+ std::string message) {
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ v8::EscapableHandleScope handle_scope(isolate);
+ v8::Local<v8::Object> error = v8::Object::New(isolate);
+
+ error->Set(
+ v8::String::NewFromUtf8(isolate, "code"),
+ v8::Number::New(isolate, code));
+ error->Set(
+ v8::String::NewFromUtf8(isolate, "name"),
+ v8::String::NewFromUtf8(isolate, name.c_str()));
+ error->Set(
+ v8::String::NewFromUtf8(isolate, "message"),
+ v8::String::NewFromUtf8(isolate, message.c_str()));
+
+ return handle_scope.Escape(error);
+}
+
+void KeyFunction(const v8::FunctionCallbackInfo<v8::Value>& info) {
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ int idx = info[0]->ToInt32()->Value();
+ auto widget = WidgetPreferenceDB::GetInstance();
+ std::string keyname;
+ if (widget->Key(idx, &keyname)) {
+ info.GetReturnValue().Set(
+ v8::String::NewFromUtf8(isolate, keyname.c_str()));
+ } else {
+ info.GetReturnValue().SetNull();
+ }
+}
+
+void GetItemFunction(const v8::FunctionCallbackInfo<v8::Value>& info) {
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ std::string key = *v8::String::Utf8Value(info[0]->ToString());
+ auto widget = WidgetPreferenceDB::GetInstance();
+ std::string valuestr;
+ if (widget->GetItem(key, &valuestr)) {
+ info.GetReturnValue().Set(
+ v8::String::NewFromUtf8(isolate, valuestr.c_str()));
+ } else {
+ info.GetReturnValue().SetNull();
+ }
+}
+
+void SetItemFunction(const v8::FunctionCallbackInfo<v8::Value>& info) {
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ std::string key = *v8::String::Utf8Value(info[0]->ToString());
+ std::string value = *v8::String::Utf8Value(info[1]->ToString());
+ auto widget = WidgetPreferenceDB::GetInstance();
+
+ v8::Local<v8::Value> oldvalue = v8::Null(isolate);
+ std::string oldvaluestr;
+ if (widget->GetItem(key, &oldvaluestr)) {
+ oldvalue = v8::String::NewFromUtf8(isolate, oldvaluestr.c_str());
+ }
+
+ if (widget->SetItem(key, value)) {
+ DispatchEvent(info.This(),
+ info[0],
+ oldvalue,
+ info[1]);
+ } else {
+ info.GetReturnValue().Set(isolate->ThrowException(MakeException(
+ 7, "NoModificationAllowedError", "Read only data")));
+ }
+}
+
+void RemoveItemFunction(const v8::FunctionCallbackInfo<v8::Value>& info) {
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ std::string key = *v8::String::Utf8Value(info[0]->ToString());
+ auto widget = WidgetPreferenceDB::GetInstance();
+
+ if (!widget->HasItem(key)) {
+ return;
+ }
+
+ v8::Local<v8::Value> oldvalue = v8::Null(isolate);
+ std::string oldvaluestr;
+ if (widget->GetItem(key, &oldvaluestr)) {
+ oldvalue = v8::String::NewFromUtf8(isolate, oldvaluestr.c_str());
+ }
+
+ if (widget->RemoveItem(key)) {
+ DispatchEvent(info.This(),
+ info[0],
+ oldvalue,
+ v8::Null(isolate));
+ } else {
+ info.GetReturnValue().Set(isolate->ThrowException(MakeException(
+ 7, "NoModificationAllowedError", "Read only data")));
+ }
+}
+
+void ClearFunction(const v8::FunctionCallbackInfo<v8::Value>& info) {
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ auto widget = WidgetPreferenceDB::GetInstance();
+ widget->Clear();
+ DispatchEvent(info.This(),
+ v8::Null(isolate),
+ v8::Null(isolate),
+ v8::Null(isolate));
+}
+
+} // namespace
+
+WidgetModule::WidgetModule() {
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ v8::HandleScope handle_scope(isolate);
+ v8::Handle<v8::ObjectTemplate>
+ preference_object_template = v8::ObjectTemplate::New();
+
+ auto getter = [](
+ v8::Local<v8::String> property,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ v8::Isolate* isolate = info.GetIsolate();
+ auto widget = WidgetPreferenceDB::GetInstance();
+ std::string key = *v8::String::Utf8Value(property);
+
+ if (key == kLengthKey) {
+ info.GetReturnValue().Set(widget->Length());
+ return;
+ }
+
+ if (std::find(kExcludeList.begin(), kExcludeList.end(), key)
+ != kExcludeList.end()) {
+ return;
+ }
+
+ if (!widget->HasItem(key)) {
+ return;
+ }
+
+ std::string value;
+ if (widget->GetItem(key, &value)) {
+ info.GetReturnValue().Set(
+ v8::String::NewFromUtf8(isolate, value.c_str()));
+ } else {
+ info.GetReturnValue().SetNull();
+ }
+ };
+
+ auto setter = [](
+ v8::Local<v8::String> property,
+ v8::Local<v8::Value> value,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ v8::Isolate* isolate = info.GetIsolate();
+ auto widget = WidgetPreferenceDB::GetInstance();
+ std::string key = *v8::String::Utf8Value(property);
+ std::string nvalue = *v8::String::Utf8Value(value->ToString());
+
+ if (std::find(kExcludeList.begin(), kExcludeList.end(), key)
+ != kExcludeList.end()) {
+ return;
+ }
+
+ v8::Local<v8::Value> oldvalue = v8::Null(isolate);
+ std::string oldvaluestr;
+ if (widget->GetItem(key, &oldvaluestr)) {
+ oldvalue = v8::String::NewFromUtf8(isolate, oldvaluestr.c_str());
+ }
+ if (widget->SetItem(key, nvalue)) {
+ info.GetReturnValue().Set(value);
+ DispatchEvent(info.This(),
+ property,
+ oldvalue,
+ value);
+ }
+ };
+
+ auto deleter = [](
+ v8::Local<v8::String> property,
+ const v8::PropertyCallbackInfo<v8::Boolean>& info) {
+ v8::Isolate* isolate = info.GetIsolate();
+ auto widget = WidgetPreferenceDB::GetInstance();
+ std::string key = *v8::String::Utf8Value(property);
+ if (!widget->HasItem(key)) {
+ info.GetReturnValue().Set(false);
+ return;
+ }
+
+ v8::Local<v8::Value> oldvalue = v8::Null(isolate);
+ std::string oldvaluestr;
+ if (widget->GetItem(key, &oldvaluestr)) {
+ oldvalue = v8::String::NewFromUtf8(isolate, oldvaluestr.c_str());
+ }
+
+ if (widget->RemoveItem(key)) {
+ info.GetReturnValue().Set(true);
+ DispatchEvent(info.This(),
+ property,
+ oldvalue,
+ v8::Null(isolate));
+ } else {
+ info.GetReturnValue().Set(false);
+ }
+ };
+
+ preference_object_template->SetNamedPropertyHandler(
+ getter,
+ setter,
+ NULL,
+ deleter,
+ NULL);
+
+ preference_object_template->Set(
+ v8::String::NewFromUtf8(isolate, kKeyKey),
+ v8::FunctionTemplate::New(isolate, KeyFunction));
+
+ preference_object_template->Set(
+ v8::String::NewFromUtf8(isolate, kGetItemKey),
+ v8::FunctionTemplate::New(isolate, GetItemFunction));
+
+ preference_object_template->Set(
+ v8::String::NewFromUtf8(isolate, kSetItemKey),
+ v8::FunctionTemplate::New(isolate, SetItemFunction));
+
+ preference_object_template->Set(
+ v8::String::NewFromUtf8(isolate, kRemoveItemKey),
+ v8::FunctionTemplate::New(isolate, RemoveItemFunction));
+
+ preference_object_template->Set(
+ v8::String::NewFromUtf8(isolate, kClearKey),
+ v8::FunctionTemplate::New(isolate, ClearFunction));
+
+
+ preference_object_template_.Reset(isolate, preference_object_template);
+}
+
+WidgetModule::~WidgetModule() {
+}
+
+v8::Handle<v8::Object> WidgetModule::NewInstance() {
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ v8::EscapableHandleScope handle_scope(isolate);
+
+ v8::Local<v8::Object> widget = v8::Object::New(isolate);
+ v8::Handle<v8::ObjectTemplate> object_template =
+ v8::Local<v8::ObjectTemplate>::New(isolate, preference_object_template_);
+
+ auto widgetdb = WidgetPreferenceDB::GetInstance();
+ widgetdb->InitializeDB();
+
+ widget->Set(
+ v8::String::NewFromUtf8(isolate, "preference"),
+ object_template->NewInstance());
+
+ widget->Set(
+ v8::String::NewFromUtf8(isolate, "author"),
+ v8::String::NewFromUtf8(isolate, widgetdb->author().c_str()));
+ widget->Set(
+ v8::String::NewFromUtf8(isolate, "description"),
+ v8::String::NewFromUtf8(isolate, widgetdb->description().c_str()));
+ widget->Set(
+ v8::String::NewFromUtf8(isolate, "name"),
+ v8::String::NewFromUtf8(isolate, widgetdb->name().c_str()));
+ widget->Set(
+ v8::String::NewFromUtf8(isolate, "shortName"),
+ v8::String::NewFromUtf8(isolate, widgetdb->shortName().c_str()));
+ widget->Set(
+ v8::String::NewFromUtf8(isolate, "version"),
+ v8::String::NewFromUtf8(isolate, widgetdb->version().c_str()));
+ widget->Set(
+ v8::String::NewFromUtf8(isolate, "id"),
+ v8::String::NewFromUtf8(isolate, widgetdb->id().c_str()));
+ widget->Set(
+ v8::String::NewFromUtf8(isolate, "authorEmail"),
+ v8::String::NewFromUtf8(isolate, widgetdb->authorEmail().c_str()));
+ widget->Set(
+ v8::String::NewFromUtf8(isolate, "authorHref"),
+ v8::String::NewFromUtf8(isolate, widgetdb->authorHref().c_str()));
+
+ return handle_scope.Escape(widget);
+}
+
+
+namespace {
+ const char* kDbInitedCheckKey = "__WRT_DB_INITED__";
+ const char* kDBPublicSection = "public";
+ const char* kDBPrivateSection = "private";
+ const char* kReadOnlyPrefix = "_READONLY_KEY_";
+} // namespace
+
+
+WidgetPreferenceDB* WidgetPreferenceDB::GetInstance() {
+ static WidgetPreferenceDB instance;
+ return &instance;
+}
+
+WidgetPreferenceDB::WidgetPreferenceDB()
+ : appdata_(nullptr),
+ locale_manager_(nullptr) {
+}
+WidgetPreferenceDB::~WidgetPreferenceDB() {
+}
+
+void WidgetPreferenceDB::Initialize(
+ const common::ApplicationData* appdata,
+ common::LocaleManager* locale_manager) {
+ appdata_ = appdata;
+ locale_manager_ = locale_manager;
+}
+
+void WidgetPreferenceDB::InitializeDB() {
+ common::AppDB* db = common::AppDB::GetInstance();
+ if (db->HasKey(kDBPrivateSection, kDbInitedCheckKey)) {
+ return;
+ }
+ if (appdata_->widget_info() == NULL) {
+ return;
+ }
+
+ auto& preferences = appdata_->widget_info()->preferences();
+
+ for (const auto& pref : preferences) {
+ if (pref->Name().empty())
+ continue;
+
+ // check size limit
+ std::string key = pref->Name();
+ std::string value = pref->Value();
+ if (key.length() > kKeyLengthLimit) {
+ key.resize(kKeyLengthLimit);
+ }
+
+ if (db->HasKey(kDBPublicSection, key))
+ continue;
+
+ // check size limit
+ if (value.length() > kValueLengthLimit) {
+ value.resize(kValueLengthLimit);
+ }
+
+ db->Set(kDBPublicSection,
+ key,
+ value);
+ if (pref->ReadOnly()) {
+ db->Set(kDBPrivateSection,
+ kReadOnlyPrefix + key, "true");
+ }
+ }
+ db->Set(kDBPrivateSection, kDbInitedCheckKey, "true");
+}
+
+int WidgetPreferenceDB::Length() {
+ common::AppDB* db = common::AppDB::GetInstance();
+ std::list<std::string> list;
+ db->GetKeys(kDBPublicSection, &list);
+ return list.size();
+}
+
+bool WidgetPreferenceDB::Key(int idx, std::string* key) {
+ common::AppDB* db = common::AppDB::GetInstance();
+ std::list<std::string> list;
+ db->GetKeys(kDBPublicSection, &list);
+
+ auto it = list.begin();
+ for ( ; it != list.end() && idx >= 0; ++it) {
+ if (idx == 0) {
+ *key = *it;
+ return true;
+ }
+ idx--;
+ }
+ return false;
+}
+
+bool WidgetPreferenceDB::GetItem(const std::string& key, std::string* value) {
+ common::AppDB* db = common::AppDB::GetInstance();
+ if (!db->HasKey(kDBPublicSection, key))
+ return false;
+ *value = db->Get(kDBPublicSection, key);
+ return true;
+}
+
+bool WidgetPreferenceDB::SetItem(const std::string& key,
+ const std::string& value) {
+ common::AppDB* db = common::AppDB::GetInstance();
+ if (db->HasKey(kDBPrivateSection, kReadOnlyPrefix + key))
+ return false;
+ db->Set(kDBPublicSection, key, value);
+ return true;
+}
+
+bool WidgetPreferenceDB::RemoveItem(const std::string& key) {
+ common::AppDB* db = common::AppDB::GetInstance();
+ if (!db->HasKey(kDBPublicSection, key))
+ return false;
+ if (db->HasKey(kDBPrivateSection, kReadOnlyPrefix + key))
+ return false;
+ db->Remove(kDBPublicSection, key);
+ return true;
+}
+
+bool WidgetPreferenceDB::HasItem(const std::string& key) {
+ common::AppDB* db = common::AppDB::GetInstance();
+ return db->HasKey(kDBPublicSection, key);
+}
+
+void WidgetPreferenceDB::Clear() {
+ common::AppDB* db = common::AppDB::GetInstance();
+ std::list<std::string> list;
+ db->GetKeys(kDBPublicSection, &list);
+ auto it = list.begin();
+ for ( ; it != list.end(); ++it) {
+ if (db->HasKey(kDBPrivateSection, kReadOnlyPrefix + *it))
+ continue;
+ db->Remove(kDBPublicSection, *it);
+ }
+}
+
+void WidgetPreferenceDB::GetKeys(std::list<std::string>* keys) {
+ common::AppDB* db = common::AppDB::GetInstance();
+ db->GetKeys(kDBPublicSection, keys);
+}
+
+std::string WidgetPreferenceDB::author() {
+ if (appdata_ == NULL ||
+ appdata_->widget_info() == NULL)
+ return std::string();
+ auto widget_info = appdata_->widget_info();
+ return widget_info->author();
+}
+
+std::string WidgetPreferenceDB::description() {
+ if (appdata_ == NULL ||
+ appdata_->widget_info() == NULL ||
+ locale_manager_ == NULL)
+ return std::string();
+ auto widget_info = appdata_->widget_info();
+ return locale_manager_->GetLocalizedString(widget_info->description_set());
+}
+
+std::string WidgetPreferenceDB::name() {
+ if (appdata_ == NULL ||
+ appdata_->widget_info() == NULL ||
+ locale_manager_ == NULL)
+ return std::string();
+
+ auto widget_info = appdata_->widget_info();
+ return locale_manager_->GetLocalizedString(widget_info->name_set());
+}
+
+std::string WidgetPreferenceDB::shortName() {
+ if (appdata_ == NULL ||
+ appdata_->widget_info() == NULL ||
+ locale_manager_ == NULL)
+ return std::string();
+
+ auto widget_info = appdata_->widget_info();
+ return locale_manager_->GetLocalizedString(widget_info->short_name_set());
+}
+
+std::string WidgetPreferenceDB::version() {
+ if (appdata_ == NULL ||
+ appdata_->widget_info() == NULL)
+ return std::string();
+ auto widget_info = appdata_->widget_info();
+ return widget_info->version();
+}
+
+std::string WidgetPreferenceDB::id() {
+ if (appdata_ == NULL ||
+ appdata_->widget_info() == NULL)
+ return std::string();
+ auto widget_info = appdata_->widget_info();
+ return widget_info->id();
+}
+
+std::string WidgetPreferenceDB::authorEmail() {
+ if (appdata_ == NULL ||
+ appdata_->widget_info() == NULL)
+ return std::string();
+ auto widget_info = appdata_->widget_info();
+ return widget_info->author_email();
+}
+
+std::string WidgetPreferenceDB::authorHref() {
+ if (appdata_ == NULL ||
+ appdata_->widget_info() == NULL)
+ return std::string();
+ auto widget_info = appdata_->widget_info();
+ return widget_info->author_href();
+}
+
+unsigned int WidgetPreferenceDB::height() {
+ if (appdata_ == NULL ||
+ appdata_->widget_info() == NULL)
+ return 0;
+ auto widget_info = appdata_->widget_info();
+ return widget_info->height();
+}
+
+unsigned int WidgetPreferenceDB::width() {
+ if (appdata_ == NULL ||
+ appdata_->widget_info() == NULL)
+ return 0;
+ auto widget_info = appdata_->widget_info();
+ return widget_info->width();
+}
+
+} // namespace extensions
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef XWALK_EXTENSIONS_RENDERER_WIDGET_MODULE_H_
+#define XWALK_EXTENSIONS_RENDERER_WIDGET_MODULE_H_
+
+#include <list>
+#include <string>
+
+#include "common/application_data.h"
+#include "common/locale_manager.h"
+#include "extensions/renderer/xwalk_module_system.h"
+
+namespace extensions {
+
+// This module provides widget object
+class WidgetModule : public XWalkNativeModule {
+ public:
+ WidgetModule();
+ ~WidgetModule() override;
+
+ private:
+ v8::Handle<v8::Object> NewInstance() override;
+ v8::Persistent<v8::ObjectTemplate> preference_object_template_;
+};
+
+class WidgetPreferenceDB {
+ public:
+ static WidgetPreferenceDB* GetInstance();
+ void Initialize(const common::ApplicationData* appdata,
+ common::LocaleManager* locale_manager);
+ void InitializeDB();
+ int Length();
+ bool Key(int idx, std::string* key);
+ bool GetItem(const std::string& key, std::string* value);
+ bool SetItem(const std::string& key, const std::string& value);
+ bool RemoveItem(const std::string& key);
+ bool HasItem(const std::string& key);
+ void Clear();
+ void GetKeys(std::list<std::string>* keys);
+
+ std::string author();
+ std::string description();
+ std::string name();
+ std::string shortName();
+ std::string version();
+ std::string id();
+ std::string authorEmail();
+ std::string authorHref();
+ unsigned int height();
+ unsigned int width();
+
+ private:
+ WidgetPreferenceDB();
+ virtual ~WidgetPreferenceDB();
+ const common::ApplicationData* appdata_;
+ common::LocaleManager* locale_manager_;
+};
+
+} // namespace extensions
+
+#endif // XWALK_EXTENSIONS_RENDERER_WIDGET_MODULE_H_
--- /dev/null
+// Copyright (c) 2013 Intel Corporation. All rights reserved.
+// Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "extensions/renderer/xwalk_extension_client.h"
+
+#include <Ecore.h>
+#include <unistd.h>
+#include <v8/v8.h>
+#include <json/json.h>
+
+#include <string>
+
+#include "common/logger.h"
+#include "common/profiler.h"
+#include "common/string_utils.h"
+#include "extensions/common/constants.h"
+#include "extensions/common/xwalk_extension_server.h"
+#include "extensions/renderer/runtime_ipc_client.h"
+
+namespace extensions {
+
+namespace {
+ void* CreateInstanceInMainloop(void* data) {
+ const char* extension_name = static_cast<const char*>(data);
+ XWalkExtensionServer* server = XWalkExtensionServer::GetInstance();
+ std::string instance_id = server->CreateInstance(extension_name);
+ return static_cast<void*>(new std::string(instance_id));
+ }
+} // namespace
+
+XWalkExtensionClient::XWalkExtensionClient() {
+}
+
+XWalkExtensionClient::~XWalkExtensionClient() {
+ for (auto it = extension_apis_.begin(); it != extension_apis_.end(); ++it) {
+ delete it->second;
+ }
+ extension_apis_.clear();
+}
+
+void XWalkExtensionClient::Initialize() {
+ SCOPE_PROFILE();
+ if (!extension_apis_.empty()) {
+ return;
+ }
+
+ XWalkExtensionServer* server = XWalkExtensionServer::GetInstance();
+ Json::Value reply = server->GetExtensions();
+ for (auto it = reply.begin(); it != reply.end(); ++it) {
+ ExtensionCodePoints* codepoint = new ExtensionCodePoints;
+ Json::Value entry_points = (*it)["entry_points"];
+ for (auto ep = entry_points.begin(); ep != entry_points.end(); ++ep) {
+ codepoint->entry_points.push_back((*ep).asString());
+ }
+ std::string name = (*it)["name"].asString();
+ extension_apis_[name] = codepoint;
+ }
+}
+
+std::string XWalkExtensionClient::CreateInstance(
+ v8::Handle<v8::Context> context,
+ const std::string& extension_name, InstanceHandler* handler) {
+ void* ret = ecore_main_loop_thread_safe_call_sync(
+ CreateInstanceInMainloop,
+ static_cast<void*>(const_cast<char*>(extension_name.data())));
+ std::string* sp = static_cast<std::string*>(ret);
+ std::string instance_id = *sp;
+ delete sp;
+
+ handlers_[instance_id] = handler;
+ return instance_id;
+}
+
+void XWalkExtensionClient::DestroyInstance(
+ v8::Handle<v8::Context> context, const std::string& instance_id) {
+ auto it = handlers_.find(instance_id);
+ if (it == handlers_.end()) {
+ LOGGER(WARN) << "Failed to destory invalid instance id: " << instance_id;
+ return;
+ }
+ RuntimeIPCClient* ipc = RuntimeIPCClient::GetInstance();
+ ipc->SendMessage(context, kMethodDestroyInstance, instance_id, "");
+
+ handlers_.erase(it);
+}
+
+void XWalkExtensionClient::PostMessageToNative(
+ v8::Handle<v8::Context> context,
+ const std::string& instance_id, const std::string& msg) {
+ RuntimeIPCClient* ipc = RuntimeIPCClient::GetInstance();
+ ipc->SendMessage(context, kMethodPostMessage, instance_id, msg);
+}
+
+std::string XWalkExtensionClient::SendSyncMessageToNative(
+ v8::Handle<v8::Context> context,
+ const std::string& instance_id, const std::string& msg) {
+ RuntimeIPCClient* ipc = RuntimeIPCClient::GetInstance();
+ std::string reply =
+ ipc->SendSyncMessage(context, kMethodSendSyncMessage, instance_id, msg);
+ return reply;
+}
+
+std::string XWalkExtensionClient::GetAPIScript(
+ v8::Handle<v8::Context> context,
+ const std::string& extension_name) {
+ XWalkExtensionServer* server = XWalkExtensionServer::GetInstance();
+ return server->GetAPIScript(extension_name);
+}
+
+void XWalkExtensionClient::OnReceivedIPCMessage(
+ const std::string& instance_id, const std::string& msg) {
+ auto it = handlers_.find(instance_id);
+ if (it == handlers_.end()) {
+ LOGGER(WARN) << "Failed to post the message. Invalid instance id.";
+ return;
+ }
+
+ if (!it->second)
+ return;
+
+ it->second->HandleMessageFromNative(msg);
+}
+
+void XWalkExtensionClient::LoadUserExtensions(const std::string app_path) {
+ XWalkExtensionServer* server = XWalkExtensionServer::GetInstance();
+ server->LoadUserExtensions(app_path);
+}
+
+} // namespace extensions
--- /dev/null
+// Copyright (c) 2013 Intel Corporation. All rights reserved.
+// Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef XWALK_EXTENSIONS_RENDERER_XWALK_EXTENSION_CLIENT_H_
+#define XWALK_EXTENSIONS_RENDERER_XWALK_EXTENSION_CLIENT_H_
+
+#include <v8/v8.h>
+
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "extensions/renderer/xwalk_module_system.h"
+
+namespace extensions {
+
+class XWalkExtensionClient {
+ public:
+ struct InstanceHandler {
+ virtual void HandleMessageFromNative(const std::string& msg) = 0;
+ protected:
+ ~InstanceHandler() {}
+ };
+
+ XWalkExtensionClient();
+ virtual ~XWalkExtensionClient();
+
+ void Initialize();
+
+ std::string CreateInstance(v8::Handle<v8::Context> context,
+ const std::string& extension_name,
+ InstanceHandler* handler);
+ void DestroyInstance(v8::Handle<v8::Context> context,
+ const std::string& instance_id);
+
+ void PostMessageToNative(v8::Handle<v8::Context> context,
+ const std::string& instance_id,
+ const std::string& msg);
+ std::string SendSyncMessageToNative(v8::Handle<v8::Context> context,
+ const std::string& instance_id,
+ const std::string& msg);
+
+ std::string GetAPIScript(v8::Handle<v8::Context> context,
+ const std::string& extension_name);
+
+ void OnReceivedIPCMessage(const std::string& instance_id,
+ const std::string& msg);
+ void LoadUserExtensions(const std::string app_path);
+
+ struct ExtensionCodePoints {
+ std::string api;
+ std::vector<std::string> entry_points;
+ };
+
+ typedef std::map<std::string, ExtensionCodePoints*> ExtensionAPIMap;
+
+ const ExtensionAPIMap& extension_apis() const { return extension_apis_; }
+
+ private:
+ ExtensionAPIMap extension_apis_;
+
+ typedef std::map<std::string, InstanceHandler*> HandlerMap;
+ HandlerMap handlers_;
+};
+
+} // namespace extensions
+
+#endif // XWALK_EXTENSIONS_RENDERER_XWALK_EXTENSION_CLIENT_H_
--- /dev/null
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright (c) 2013 Intel Corporation. All rights reserved.
+// Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "extensions/renderer/xwalk_extension_module.h"
+
+#include <v8/v8.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+#include <vector>
+
+#include "common/arraysize.h"
+#include "common/logger.h"
+#include "common/profiler.h"
+#include "extensions/renderer/runtime_ipc_client.h"
+#include "extensions/renderer/xwalk_extension_client.h"
+#include "extensions/renderer/xwalk_module_system.h"
+
+namespace extensions {
+
+namespace {
+
+// This is the key used in the data object passed to our callbacks to store a
+// pointer back to kXWalkExtensionModule.
+const char* kXWalkExtensionModule = "kXWalkExtensionModule";
+
+} // namespace
+
+XWalkExtensionModule::XWalkExtensionModule(XWalkExtensionClient* client,
+ XWalkModuleSystem* module_system,
+ const std::string& extension_name,
+ const std::string& extension_code)
+ : extension_name_(extension_name),
+ extension_code_(extension_code),
+ client_(client),
+ module_system_(module_system),
+ instance_id_("") {
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ v8::HandleScope handle_scope(isolate);
+ v8::Handle<v8::Object> function_data = v8::Object::New(isolate);
+ function_data->Set(v8::String::NewFromUtf8(isolate, kXWalkExtensionModule),
+ v8::External::New(isolate, this));
+
+ v8::Handle<v8::ObjectTemplate> object_template =
+ v8::ObjectTemplate::New(isolate);
+ // TODO(cmarcelo): Use Template::Set() function that takes isolate, once we
+ // update the Chromium (and V8) version.
+ object_template->Set(
+ v8::String::NewFromUtf8(isolate, "postMessage"),
+ v8::FunctionTemplate::New(isolate, PostMessageCallback, function_data));
+ object_template->Set(
+ v8::String::NewFromUtf8(isolate, "sendSyncMessage"),
+ v8::FunctionTemplate::New(
+ isolate, SendSyncMessageCallback, function_data));
+ object_template->Set(
+ v8::String::NewFromUtf8(isolate, "setMessageListener"),
+ v8::FunctionTemplate::New(
+ isolate, SetMessageListenerCallback, function_data));
+ object_template->Set(
+ v8::String::NewFromUtf8(isolate, "sendRuntimeMessage"),
+ v8::FunctionTemplate::New(
+ isolate, SendRuntimeMessageCallback, function_data));
+ object_template->Set(
+ v8::String::NewFromUtf8(isolate, "sendRuntimeSyncMessage"),
+ v8::FunctionTemplate::New(
+ isolate, SendRuntimeSyncMessageCallback, function_data));
+ object_template->Set(
+ v8::String::NewFromUtf8(isolate, "sendRuntimeAsyncMessage"),
+ v8::FunctionTemplate::New(
+ isolate, SendRuntimeAsyncMessageCallback, function_data));
+
+ function_data_.Reset(isolate, function_data);
+ object_template_.Reset(isolate, object_template);
+}
+
+XWalkExtensionModule::~XWalkExtensionModule() {
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ v8::HandleScope handle_scope(isolate);
+
+ // Deleting the data will disable the functions, they'll return early. We do
+ // this because it might be the case that the JS objects we created outlive
+ // this object (getting references from inside an iframe and then destroying
+ // the iframe), even if we destroy the references we have.
+ v8::Handle<v8::Object> function_data =
+ v8::Local<v8::Object>::New(isolate, function_data_);
+ function_data->Delete(v8::String::NewFromUtf8(isolate,
+ kXWalkExtensionModule));
+
+ object_template_.Reset();
+ function_data_.Reset();
+ message_listener_.Reset();
+
+ if (!instance_id_.empty())
+ client_->DestroyInstance(module_system_->GetV8Context(), instance_id_);
+}
+
+namespace {
+
+std::string CodeToEnsureNamespace(const std::string& extension_name) {
+ std::string result;
+ size_t pos = 0;
+ while (true) {
+ pos = extension_name.find('.', pos);
+ if (pos == std::string::npos) {
+ result += extension_name + " = {};";
+ break;
+ }
+ std::string ns = extension_name.substr(0, pos);
+ result += ns + " = " + ns + " || {}; ";
+ pos++;
+ }
+ return result;
+}
+
+// Templatized backend for StringPrintF/StringAppendF. This does not finalize
+// the va_list, the caller is expected to do that.
+template <class StringType>
+static void StringAppendVT(StringType* dst,
+ const typename StringType::value_type* format,
+ va_list ap) {
+ // First try with a small fixed size buffer.
+ // This buffer size should be kept in sync with StringUtilTest.GrowBoundary
+ // and StringUtilTest.StringPrintfBounds.
+ typename StringType::value_type stack_buf[1024];
+
+ va_list ap_copy;
+ va_copy(ap_copy, ap);
+
+ int result = vsnprintf(stack_buf, ARRAYSIZE(stack_buf), format, ap_copy);
+ va_end(ap_copy);
+
+ if (result >= 0 && result < static_cast<int>(ARRAYSIZE(stack_buf))) {
+ // It fit.
+ dst->append(stack_buf, result);
+ return;
+ }
+
+ // Repeatedly increase buffer size until it fits.
+ int mem_length = ARRAYSIZE(stack_buf);
+ while (true) {
+ if (result < 0) {
+ if (errno != 0 && errno != EOVERFLOW)
+ return;
+ // Try doubling the buffer size.
+ mem_length *= 2;
+ } else {
+ // We need exactly "result + 1" characters.
+ mem_length = result + 1;
+ }
+
+ if (mem_length > 32 * 1024 * 1024) {
+ // That should be plenty, don't try anything larger. This protects
+ // against huge allocations when using vsnprintfT implementations that
+ // return -1 for reasons other than overflow without setting errno.
+ LOGE("Unable to printf the requested string due to size.");
+ return;
+ }
+
+ std::vector<typename StringType::value_type> mem_buf(mem_length);
+
+ // NOTE: You can only use a va_list once. Since we're in a while loop, we
+ // need to make a new copy each time so we don't use up the original.
+ va_copy(ap_copy, ap);
+ result = vsnprintf(&mem_buf[0], mem_length, format, ap_copy);
+ va_end(ap_copy);
+
+ if ((result >= 0) && (result < mem_length)) {
+ // It fit.
+ dst->append(&mem_buf[0], result);
+ return;
+ }
+ }
+}
+
+std::string StringPrintf(const char* format, ...) {
+ va_list ap;
+ va_start(ap, format);
+ std::string result;
+ StringAppendVT(&result, format, ap);
+ va_end(ap);
+ return result;
+}
+
+// Wrap API code into a callable form that takes extension object as parameter.
+std::string WrapAPICode(const std::string& extension_code,
+ const std::string& extension_name) {
+ // We take care here to make sure that line numbering for api_code after
+ // wrapping doesn't change, so that syntax errors point to the correct line.
+
+ return StringPrintf(
+ "var %s; (function(extension, requireNative) { "
+ "extension.internal = {};"
+ "extension.internal.sendSyncMessage = extension.sendSyncMessage;"
+ "delete extension.sendSyncMessage;"
+ "var Object = requireNative('objecttools');"
+ "var exports = {}; (function() {'use strict'; %s\n})();"
+ "%s = exports; });",
+ CodeToEnsureNamespace(extension_name).c_str(),
+ extension_code.c_str(),
+ extension_name.c_str());
+}
+
+std::string ExceptionToString(const v8::TryCatch& try_catch) {
+ std::string str;
+ v8::HandleScope handle_scope(v8::Isolate::GetCurrent());
+ v8::String::Utf8Value exception(try_catch.Exception());
+ v8::Local<v8::Message> message(try_catch.Message());
+ if (message.IsEmpty()) {
+ str.append(StringPrintf("%s\n", *exception));
+ } else {
+ v8::String::Utf8Value filename(message->GetScriptResourceName());
+ int linenum = message->GetLineNumber();
+ int colnum = message->GetStartColumn();
+ str.append(StringPrintf(
+ "%s:%i:%i %s\n", *filename, linenum, colnum, *exception));
+ v8::String::Utf8Value sourceline(message->GetSourceLine());
+ str.append(StringPrintf("%s\n", *sourceline));
+ }
+ return str;
+}
+
+v8::Handle<v8::Value> RunString(const std::string& code,
+ std::string* exception) {
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ v8::EscapableHandleScope handle_scope(isolate);
+ v8::Handle<v8::String> v8_code(
+ v8::String::NewFromUtf8(isolate, code.c_str()));
+
+ v8::TryCatch try_catch;
+ try_catch.SetVerbose(true);
+
+ v8::Handle<v8::Script> script(v8::Script::Compile(v8_code));
+ if (try_catch.HasCaught()) {
+ *exception = ExceptionToString(try_catch);
+ return handle_scope.Escape(
+ v8::Local<v8::Primitive>(v8::Undefined(isolate)));
+ }
+
+ v8::Local<v8::Value> result = script->Run();
+ if (try_catch.HasCaught()) {
+ *exception = ExceptionToString(try_catch);
+ return handle_scope.Escape(
+ v8::Local<v8::Primitive>(v8::Undefined(isolate)));
+ }
+
+ return handle_scope.Escape(result);
+}
+
+} // namespace
+
+void XWalkExtensionModule::LoadExtensionCode(
+ v8::Handle<v8::Context> context, v8::Handle<v8::Function> require_native) {
+ instance_id_ = client_->CreateInstance(context, extension_name_, this);
+ if (instance_id_.empty()) {
+ LOGGER(ERROR) << "Failed to create an instance of " << extension_name_;
+ return;
+ }
+
+ if (extension_code_.empty()) {
+ extension_code_ = client_->GetAPIScript(context, extension_name_);
+ if (extension_code_.empty()) {
+ LOGGER(ERROR) << "Failed to get API script of " << extension_name_;
+ return;
+ }
+ }
+
+ std::string wrapped_api_code = WrapAPICode(extension_code_, extension_name_);
+
+ std::string exception;
+ v8::Handle<v8::Value> result = RunString(wrapped_api_code, &exception);
+
+ if (!result->IsFunction()) {
+ LOGGER(ERROR) << "Couldn't load JS API code for "
+ << extension_name_ << " : " << exception;
+ return;
+ }
+ v8::Handle<v8::Function> callable_api_code =
+ v8::Handle<v8::Function>::Cast(result);
+ v8::Handle<v8::ObjectTemplate> object_template =
+ v8::Local<v8::ObjectTemplate>::New(context->GetIsolate(),
+ object_template_);
+
+ const int argc = 2;
+ v8::Handle<v8::Value> argv[argc] = {
+ object_template->NewInstance(),
+ require_native
+ };
+
+ v8::TryCatch try_catch;
+ try_catch.SetVerbose(true);
+ callable_api_code->Call(context->Global(), argc, argv);
+ if (try_catch.HasCaught()) {
+ LOGGER(ERROR) << "Exception while loading JS API code for "
+ << extension_name_ << " : " << ExceptionToString(try_catch);
+ }
+}
+
+void XWalkExtensionModule::HandleMessageFromNative(const std::string& msg) {
+ if (message_listener_.IsEmpty())
+ return;
+
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ v8::HandleScope handle_scope(isolate);
+ v8::Handle<v8::Context> context = module_system_->GetV8Context();
+ v8::Context::Scope context_scope(context);
+
+ v8::Handle<v8::Value> args[] = {
+ v8::String::NewFromUtf8(isolate, msg.c_str()) };
+
+ v8::Handle<v8::Function> message_listener =
+ v8::Local<v8::Function>::New(isolate, message_listener_);
+
+ v8::TryCatch try_catch;
+ message_listener->Call(context->Global(), 1, args);
+ if (try_catch.HasCaught())
+ LOGGER(ERROR) << "Exception when running message listener: "
+ << ExceptionToString(try_catch);
+}
+
+// static
+void XWalkExtensionModule::PostMessageCallback(
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ v8::ReturnValue<v8::Value> result(info.GetReturnValue());
+ XWalkExtensionModule* module = GetExtensionModule(info);
+ if (!module || info.Length() != 1) {
+ result.Set(false);
+ return;
+ }
+
+ v8::String::Utf8Value value(info[0]->ToString());
+
+ // CHECK(module->instance_id_);
+ module->client_->PostMessageToNative(module->module_system_->GetV8Context(),
+ module->instance_id_,
+ std::string(*value));
+ result.Set(true);
+}
+
+// static
+void XWalkExtensionModule::SendSyncMessageCallback(
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ v8::ReturnValue<v8::Value> result(info.GetReturnValue());
+ XWalkExtensionModule* module = GetExtensionModule(info);
+ if (!module || info.Length() != 1) {
+ result.Set(false);
+ return;
+ }
+
+ v8::String::Utf8Value value(info[0]->ToString());
+
+ // CHECK(module->instance_id_);
+ std::string reply =
+ module->client_->SendSyncMessageToNative(
+ module->module_system_->GetV8Context(),
+ module->instance_id_,
+ std::string(*value));
+
+ // If we tried to send a message to an instance that became invalid,
+ // then reply will be NULL.
+ if (!reply.empty()) {
+ result.Set(v8::String::NewFromUtf8(info.GetIsolate(), reply.c_str()));
+ }
+}
+
+// static
+void XWalkExtensionModule::SetMessageListenerCallback(
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ v8::ReturnValue<v8::Value> result(info.GetReturnValue());
+ XWalkExtensionModule* module = GetExtensionModule(info);
+ if (!module || info.Length() != 1) {
+ result.Set(false);
+ return;
+ }
+
+ if (!info[0]->IsFunction() && !info[0]->IsUndefined()) {
+ LOGGER(ERROR) << "Trying to set message listener with invalid value.";
+ result.Set(false);
+ return;
+ }
+
+ v8::Isolate* isolate = info.GetIsolate();
+ if (info[0]->IsUndefined())
+ module->message_listener_.Reset();
+ else
+ module->message_listener_.Reset(isolate, info[0].As<v8::Function>());
+
+ result.Set(true);
+}
+
+// static
+void XWalkExtensionModule::SendRuntimeMessageCallback(
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ v8::ReturnValue<v8::Value> result(info.GetReturnValue());
+ XWalkExtensionModule* module = GetExtensionModule(info);
+ if (!module || info.Length() < 1) {
+ result.Set(false);
+ return;
+ }
+
+ v8::String::Utf8Value type(info[0]->ToString());
+ std::string data_str;
+ if (info.Length() > 1) {
+ v8::String::Utf8Value data(info[1]->ToString());
+ data_str = std::string(*data);
+ }
+
+ RuntimeIPCClient* rc = RuntimeIPCClient::GetInstance();
+ rc->SendMessage(module->module_system_->GetV8Context(),
+ std::string(*type), data_str);
+
+ result.Set(true);
+}
+
+// static
+void XWalkExtensionModule::SendRuntimeSyncMessageCallback(
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ v8::Isolate* isolate = info.GetIsolate();
+
+ v8::ReturnValue<v8::Value> result(info.GetReturnValue());
+ XWalkExtensionModule* module = GetExtensionModule(info);
+ if (!module || info.Length() < 1) {
+ result.SetUndefined();
+ return;
+ }
+
+ v8::String::Utf8Value type(info[0]->ToString());
+ std::string data_str;
+ if (info.Length() > 1) {
+ v8::String::Utf8Value data(info[1]->ToString());
+ data_str = std::string(*data);
+ }
+
+ RuntimeIPCClient* rc = RuntimeIPCClient::GetInstance();
+ std::string reply = rc->SendSyncMessage(
+ module->module_system_->GetV8Context(),
+ std::string(*type), data_str);
+
+ result.Set(v8::String::NewFromUtf8(isolate, reply.c_str()));
+}
+
+// static
+void XWalkExtensionModule::SendRuntimeAsyncMessageCallback(
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ v8::Isolate* isolate = info.GetIsolate();
+ v8::HandleScope handle_scope(isolate);
+
+ v8::ReturnValue<v8::Value> result(info.GetReturnValue());
+ XWalkExtensionModule* module = GetExtensionModule(info);
+ if (!module || info.Length() < 1) {
+ result.Set(false);
+ return;
+ }
+
+ // type
+ v8::String::Utf8Value type(info[0]->ToString());
+
+ // value
+ std::string value_str;
+ if (info.Length() > 1) {
+ v8::String::Utf8Value value(info[1]->ToString());
+ value_str = std::string(*value);
+ }
+
+ // callback
+ RuntimeIPCClient::JSCallback* js_callback = NULL;
+ if (info.Length() > 2) {
+ if (info[2]->IsFunction()) {
+ v8::Handle<v8::Function> func = info[2].As<v8::Function>();
+ js_callback = new RuntimeIPCClient::JSCallback(isolate, func);
+ }
+ }
+
+ 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(module->module_system_->GetV8Context(),
+ std::string(*type), value_str, callback);
+
+ result.Set(true);
+}
+
+// static
+XWalkExtensionModule* XWalkExtensionModule::GetExtensionModule(
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ v8::Isolate* isolate = info.GetIsolate();
+ v8::HandleScope handle_scope(isolate);
+
+ v8::Local<v8::Object> data = info.Data().As<v8::Object>();
+ v8::Local<v8::Value> module =
+ data->Get(v8::String::NewFromUtf8(isolate, kXWalkExtensionModule));
+ if (module.IsEmpty() || module->IsUndefined()) {
+ LOGGER(ERROR) << "Trying to use extension from already destroyed context!";
+ return NULL;
+ }
+ // CHECK(module->IsExternal());
+ return static_cast<XWalkExtensionModule*>(module.As<v8::External>()->Value());
+}
+
+} // namespace extensions
--- /dev/null
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright (c) 2013 Intel Corporation. All rights reserved.
+// Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef XWALK_EXTENSIONS_RENDERER_XWALK_EXTENSION_MODULE_H_
+#define XWALK_EXTENSIONS_RENDERER_XWALK_EXTENSION_MODULE_H_
+
+#include <v8/v8.h>
+
+#include <memory>
+#include <string>
+
+#include "extensions/renderer/xwalk_extension_client.h"
+
+namespace extensions {
+
+class XWalkModuleSystem;
+
+// Responsible for running the JS code of a Extension. This includes
+// creating and exposing an 'extension' object for the execution context of
+// the extension JS code.
+//
+// We'll create one XWalkExtensionModule per extension/frame pair, so
+// there'll be a set of different modules per v8::Context.
+class XWalkExtensionModule : public XWalkExtensionClient::InstanceHandler {
+ public:
+ XWalkExtensionModule(XWalkExtensionClient* client,
+ XWalkModuleSystem* module_system,
+ const std::string& extension_name,
+ const std::string& extension_code);
+ virtual ~XWalkExtensionModule();
+
+ // TODO(cmarcelo): Make this return a v8::Handle<v8::Object>, and
+ // let the module system set it to the appropriated object.
+ void LoadExtensionCode(v8::Handle<v8::Context> context,
+ v8::Handle<v8::Function> require_native);
+
+ std::string extension_name() const { return extension_name_; }
+
+ private:
+ // ExtensionClient::InstanceHandler implementation.
+ virtual void HandleMessageFromNative(const std::string& msg);
+
+ // Callbacks for JS functions available in 'extension' object.
+ static void PostMessageCallback(
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void SendSyncMessageCallback(
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void SetMessageListenerCallback(
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void SendRuntimeMessageCallback(
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void SendRuntimeSyncMessageCallback(
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void SendRuntimeAsyncMessageCallback(
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+
+ static XWalkExtensionModule* GetExtensionModule(
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+
+ // Template for the 'extension' object exposed to the extension JS code.
+ v8::Persistent<v8::ObjectTemplate> object_template_;
+
+ // This JS object contains a pointer back to the ExtensionModule, it is
+ // set as data for the function callbacks.
+ v8::Persistent<v8::Object> function_data_;
+
+ // Function to be called when the extension sends a message to its JS code.
+ // This value is registered by using 'extension.setMessageListener()'.
+ v8::Persistent<v8::Function> message_listener_;
+
+ std::string extension_name_;
+ std::string extension_code_;
+
+ XWalkExtensionClient* client_;
+ XWalkModuleSystem* module_system_;
+ std::string instance_id_;
+};
+
+} // namespace extensions
+
+#endif // XWALK_EXTENSIONS_RENDERER_XWALK_EXTENSION_MODULE_H_
--- /dev/null
+// Copyright (c) 2013 Intel Corporation. All rights reserved.
+// Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "extensions/renderer/xwalk_extension_renderer_controller.h"
+
+#include <Ecore.h>
+#include <v8/v8.h>
+#include <string>
+#include <utility>
+
+#include "common/logger.h"
+#include "common/profiler.h"
+#include "extensions/renderer/object_tools_module.h"
+#include "extensions/renderer/widget_module.h"
+#include "extensions/renderer/xwalk_extension_client.h"
+#include "extensions/renderer/xwalk_extension_module.h"
+#include "extensions/renderer/xwalk_module_system.h"
+#include "extensions/renderer/xwalk_v8tools_module.h"
+#include "extensions/renderer/runtime_ipc_client.h"
+
+namespace extensions {
+
+// static
+int XWalkExtensionRendererController::plugin_session_count = 0;
+
+namespace {
+
+void CreateExtensionModules(XWalkExtensionClient* client,
+ XWalkModuleSystem* module_system) {
+ const XWalkExtensionClient::ExtensionAPIMap& extensions =
+ client->extension_apis();
+
+ for (auto it = extensions.begin(); it != extensions.end(); ++it) {
+ XWalkExtensionClient::ExtensionCodePoints* codepoint = it->second;
+ std::unique_ptr<XWalkExtensionModule> module(
+ new XWalkExtensionModule(client, module_system,
+ it->first, codepoint->api));
+ module_system->RegisterExtensionModule(std::move(module),
+ codepoint->entry_points);
+ }
+}
+
+} // namespace
+
+XWalkExtensionRendererController&
+XWalkExtensionRendererController::GetInstance() {
+ static XWalkExtensionRendererController instance;
+ return instance;
+}
+
+XWalkExtensionRendererController::XWalkExtensionRendererController()
+ : exit_requested(false),
+ extensions_client_(new XWalkExtensionClient()) {
+}
+
+XWalkExtensionRendererController::~XWalkExtensionRendererController() {
+}
+
+void XWalkExtensionRendererController::DidCreateScriptContext(
+ v8::Handle<v8::Context> context) {
+ SCOPE_PROFILE();
+
+ // Skip plugin loading after application exit request.
+ if (exit_requested) {
+ return;
+ }
+
+ XWalkModuleSystem* module_system = new XWalkModuleSystem(context);
+ XWalkModuleSystem::SetModuleSystemInContext(
+ std::unique_ptr<XWalkModuleSystem>(module_system), context);
+ module_system->RegisterNativeModule(
+ "v8tools",
+ std::unique_ptr<XWalkNativeModule>(new XWalkV8ToolsModule));
+ module_system->RegisterNativeModule(
+ "WidgetModule",
+ std::unique_ptr<XWalkNativeModule>(new WidgetModule));
+ module_system->RegisterNativeModule(
+ "objecttools",
+ std::unique_ptr<XWalkNativeModule>(new ObjectToolsModule));
+
+ extensions_client_->Initialize();
+ CreateExtensionModules(extensions_client_.get(), module_system);
+
+ module_system->Initialize();
+ plugin_session_count++;
+ LOGGER(DEBUG) << "plugin_session_count : " << plugin_session_count;
+}
+
+void XWalkExtensionRendererController::WillReleaseScriptContext(
+ v8::Handle<v8::Context> context) {
+ v8::Context::Scope contextScope(context);
+ XWalkModuleSystem* module_system = XWalkModuleSystem::GetModuleSystemFromContext(context);
+ if (module_system) {
+ plugin_session_count--;
+ LOGGER(DEBUG) << "plugin_session_count : " << plugin_session_count;
+ }
+ XWalkModuleSystem::ResetModuleSystemFromContext(context);
+}
+
+void XWalkExtensionRendererController::OnReceivedIPCMessage(
+ const Ewk_IPC_Wrt_Message_Data* data) {
+
+ Eina_Stringshare* type = ewk_ipc_wrt_message_data_type_get(data);
+
+#define TYPE_BEGIN(x) (!strncmp(type, x, strlen(x)))
+ if (TYPE_BEGIN("xwalk://")) {
+ Eina_Stringshare* id = ewk_ipc_wrt_message_data_id_get(data);
+ Eina_Stringshare* msg = ewk_ipc_wrt_message_data_value_get(data);
+ extensions_client_->OnReceivedIPCMessage(id, msg);
+ eina_stringshare_del(id);
+ eina_stringshare_del(msg);
+ } else {
+ RuntimeIPCClient* ipc = RuntimeIPCClient::GetInstance();
+ ipc->HandleMessageFromRuntime(data);
+ }
+#undef TYPE_BEGIN
+
+ eina_stringshare_del(type);
+}
+
+void XWalkExtensionRendererController::InitializeExtensionClient() {
+ extensions_client_->Initialize();
+}
+
+void XWalkExtensionRendererController::LoadUserExtensions(
+ const std::string app_path) {
+ extensions_client_->LoadUserExtensions(app_path);
+}
+
+} // namespace extensions
--- /dev/null
+// Copyright (c) 2013 Intel Corporation. All rights reserved.
+// Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef XWALK_EXTENSIONS_RENDERER_XWALK_EXTENSION_RENDERER_CONTROLLER_H_
+#define XWALK_EXTENSIONS_RENDERER_XWALK_EXTENSION_RENDERER_CONTROLLER_H_
+
+#include <EWebKit.h>
+#include <EWebKit_internal.h>
+#include <v8/v8.h>
+
+#include <memory>
+#include <string>
+
+namespace extensions {
+
+class XWalkExtensionClient;
+
+class XWalkExtensionRendererController {
+ public:
+ static XWalkExtensionRendererController& GetInstance();
+ static int plugin_session_count;
+
+ void DidCreateScriptContext(v8::Handle<v8::Context> context);
+ void WillReleaseScriptContext(v8::Handle<v8::Context> context);
+
+ void OnReceivedIPCMessage(const Ewk_IPC_Wrt_Message_Data* data);
+
+ void InitializeExtensionClient();
+ void LoadUserExtensions(const std::string app_path);
+
+ bool exit_requested;
+
+ private:
+ XWalkExtensionRendererController();
+ virtual ~XWalkExtensionRendererController();
+
+ private:
+ std::unique_ptr<XWalkExtensionClient> extensions_client_;
+};
+
+} // namespace extensions
+
+#endif // XWALK_EXTENSIONS_RENDERER_XWALK_EXTENSION_RENDERER_CONTROLLER_H_
--- /dev/null
+// Copyright (c) 2013 Intel Corporation. All rights reserved.
+// Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "extensions/renderer/xwalk_module_system.h"
+
+#include <v8/v8.h>
+
+#include <algorithm>
+
+#include "common/logger.h"
+#include "common/profiler.h"
+#include "extensions/renderer/xwalk_extension_module.h"
+
+namespace extensions {
+
+namespace {
+
+// Index used to set embedder data into v8::Context, so we can get from a
+// context to its corresponding module. Index chosen to not conflict with
+// WebCore::V8ContextEmbedderDataField in V8PerContextData.h.
+const int kModuleSystemEmbedderDataIndex = 8;
+
+// This is the key used in the data object passed to our callbacks to store a
+// pointer back to XWalkExtensionModule.
+const char* kXWalkModuleSystem = "kXWalkModuleSystem";
+
+void RequireNativeCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
+ v8::ReturnValue<v8::Value> result(info.GetReturnValue());
+
+ v8::Isolate* isolate = info.GetIsolate();
+ v8::HandleScope handle_scope(isolate);
+
+ v8::Handle<v8::Object> data = info.Data().As<v8::Object>();
+ v8::Handle<v8::Value> module_system_value =
+ data->Get(v8::String::NewFromUtf8(isolate, kXWalkModuleSystem));
+ if (module_system_value.IsEmpty() || module_system_value->IsUndefined()) {
+ LOGGER(ERROR) << "Trying to use requireNative from already "
+ << "destroyed module system!";
+ result.SetUndefined();
+ return;
+ }
+
+ XWalkModuleSystem* module_system = static_cast<XWalkModuleSystem*>(
+ module_system_value.As<v8::External>()->Value());
+
+ if (info.Length() < 1) {
+ // TODO(cmarcelo): Throw appropriate exception or warning.
+ result.SetUndefined();
+ return;
+ }
+ if (!module_system) {
+ result.SetUndefined();
+ return;
+ }
+ v8::Handle<v8::Object> object =
+ module_system->RequireNative(*v8::String::Utf8Value(info[0]));
+ if (object.IsEmpty()) {
+ // TODO(cmarcelo): Throw appropriate exception or warning.
+ result.SetUndefined();
+ return;
+ }
+ result.Set(object);
+}
+
+} // namespace
+
+XWalkModuleSystem::XWalkModuleSystem(v8::Handle<v8::Context> context) {
+ v8::Isolate* isolate = context->GetIsolate();
+ v8_context_.Reset(isolate, context);
+
+ v8::HandleScope handle_scope(isolate);
+ v8::Handle<v8::Object> function_data = v8::Object::New(isolate);
+ function_data->Set(v8::String::NewFromUtf8(isolate, kXWalkModuleSystem),
+ v8::External::New(isolate, this));
+ v8::Handle<v8::FunctionTemplate> require_native_template =
+ v8::FunctionTemplate::New(isolate, RequireNativeCallback, function_data);
+
+ function_data_.Reset(isolate, function_data);
+ require_native_template_.Reset(isolate, require_native_template);
+}
+
+XWalkModuleSystem::~XWalkModuleSystem() {
+ DeleteExtensionModules();
+ auto it = native_modules_.begin();
+ for ( ; it != native_modules_.end(); ++it) {
+ delete it->second;
+ }
+ native_modules_.clear();
+
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ v8::HandleScope handle_scope(isolate);
+
+ require_native_template_.Reset();
+ function_data_.Reset();
+ v8_context_.Reset();
+}
+
+// static
+XWalkModuleSystem* XWalkModuleSystem::GetModuleSystemFromContext(
+ v8::Handle<v8::Context> context) {
+ return reinterpret_cast<XWalkModuleSystem*>(
+ context->GetAlignedPointerFromEmbedderData(
+ kModuleSystemEmbedderDataIndex));
+}
+
+// static
+void XWalkModuleSystem::SetModuleSystemInContext(
+ std::unique_ptr<XWalkModuleSystem> module_system,
+ v8::Handle<v8::Context> context) {
+ context->SetAlignedPointerInEmbedderData(kModuleSystemEmbedderDataIndex,
+ module_system.release());
+}
+
+// static
+void XWalkModuleSystem::ResetModuleSystemFromContext(
+ v8::Handle<v8::Context> context) {
+ XWalkModuleSystem* module_system = GetModuleSystemFromContext(context);
+ if (module_system) {
+ delete module_system;
+ SetModuleSystemInContext(std::unique_ptr<XWalkModuleSystem>(), context);
+ }
+}
+
+void XWalkModuleSystem::RegisterExtensionModule(
+ std::unique_ptr<XWalkExtensionModule> module,
+ const std::vector<std::string>& entry_points) {
+ const std::string& extension_name = module->extension_name();
+ if (ContainsEntryPoint(extension_name)) {
+ LOGGER(ERROR) << "Can't register Extension Module named for extension '"
+ << extension_name << "' in the Module System because name "
+ << " was already registered.";
+ return;
+ }
+
+ std::vector<std::string>::const_iterator it = entry_points.begin();
+ for (; it != entry_points.end(); ++it) {
+ if (ContainsEntryPoint(*it)) {
+ LOGGER(ERROR) << "Can't register Extension Module named for extension '"
+ << extension_name << "' in the Module System because "
+ << "another extension has the entry point '"
+ << (*it) << "'.";
+ return;
+ }
+ }
+
+ extension_modules_.push_back(
+ ExtensionModuleEntry(extension_name, module.release(), entry_points));
+}
+
+void XWalkModuleSystem::RegisterNativeModule(
+ const std::string& name, std::unique_ptr<XWalkNativeModule> module) {
+ if (native_modules_.find(name) != native_modules_.end()) {
+ return;
+ }
+ native_modules_[name] = module.release();
+}
+
+
+namespace {
+
+v8::Handle<v8::Value> EnsureTargetObjectForTrampoline(
+ v8::Handle<v8::Context> context, const std::vector<std::string>& path,
+ std::string* error) {
+ v8::Handle<v8::Object> object = context->Global();
+ v8::Isolate* isolate = context->GetIsolate();
+
+ std::vector<std::string>::const_iterator it = path.begin();
+ for (; it != path.end(); ++it) {
+ v8::Handle<v8::String> part =
+ v8::String::NewFromUtf8(isolate, it->c_str());
+ v8::Handle<v8::Value> value = object->Get(part);
+
+ if (value->IsUndefined()) {
+ v8::Handle<v8::Object> next_object = v8::Object::New(isolate);
+ object->Set(part, next_object);
+ object = next_object;
+ continue;
+ }
+
+ if (!value->IsObject()) {
+ *error = "the property '" + *it + "' in the path is undefined";
+ return v8::Undefined(isolate);
+ }
+
+ object = value.As<v8::Object>();
+ }
+ return object;
+}
+
+v8::Handle<v8::Value> GetObjectForPath(v8::Handle<v8::Context> context,
+ const std::vector<std::string>& path,
+ std::string* error) {
+ v8::Handle<v8::Object> object = context->Global();
+ v8::Isolate* isolate = context->GetIsolate();
+
+ std::vector<std::string>::const_iterator it = path.begin();
+ for (; it != path.end(); ++it) {
+ v8::Handle<v8::String> part =
+ v8::String::NewFromUtf8(isolate, it->c_str());
+ v8::Handle<v8::Value> value = object->Get(part);
+
+ if (!value->IsObject()) {
+ *error = "the property '" + *it + "' in the path is undefined";
+ return v8::Undefined(isolate);
+ }
+
+ object = value.As<v8::Object>();
+ }
+ return object;
+}
+
+} // namespace
+
+template <typename STR>
+void SplitString(const STR& str, const typename STR::value_type s,
+ std::vector<STR>* r) {
+ r->clear();
+ size_t last = 0;
+ size_t c = str.size();
+ for (size_t i = 0; i <= c; ++i) {
+ if (i == c || str[i] == s) {
+ STR tmp(str, last, i - last);
+ if (i != c || !r->empty() || !tmp.empty())
+ r->push_back(tmp);
+ last = i + 1;
+ }
+ }
+}
+
+bool XWalkModuleSystem::SetTrampolineAccessorForEntryPoint(
+ v8::Handle<v8::Context> context,
+ const std::string& entry_point,
+ v8::Local<v8::External> user_data) {
+ std::vector<std::string> path;
+ SplitString(entry_point, '.', &path);
+ std::string basename = path.back();
+ path.pop_back();
+
+ std::string error;
+ v8::Handle<v8::Value> value =
+ EnsureTargetObjectForTrampoline(context, path, &error);
+ if (value->IsUndefined()) {
+ LOGGER(ERROR) << "Error installing trampoline for " << entry_point
+ << " : " << error;
+ return false;
+ }
+
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::Local<v8::Array> params = v8::Array::New(isolate);
+ v8::Local<v8::String> entry =
+ v8::String::NewFromUtf8(isolate, entry_point.c_str());
+ params->Set(v8::Integer::New(isolate, 0), user_data);
+ params->Set(v8::Integer::New(isolate, 1), entry);
+
+ // FIXME(cmarcelo): ensure that trampoline is readonly.
+ value.As<v8::Object>()->SetAccessor(context,
+ v8::String::NewFromUtf8(isolate, basename.c_str()),
+ TrampolineCallback, TrampolineSetterCallback, params);
+ return true;
+}
+
+// static
+bool XWalkModuleSystem::DeleteAccessorForEntryPoint(
+ v8::Handle<v8::Context> context,
+ const std::string& entry_point) {
+ std::vector<std::string> path;
+ SplitString(entry_point, '.', &path);
+ std::string basename = path.back();
+ path.pop_back();
+
+ std::string error;
+ v8::Handle<v8::Value> value = GetObjectForPath(context, path, &error);
+ if (value->IsUndefined()) {
+ LOGGER(ERROR) << "Error retrieving object for " << entry_point
+ << " : " << error;
+ return false;
+ }
+
+ value.As<v8::Object>()->Delete(
+ v8::String::NewFromUtf8(context->GetIsolate(), basename.c_str()));
+ return true;
+}
+
+bool XWalkModuleSystem::InstallTrampoline(v8::Handle<v8::Context> context,
+ ExtensionModuleEntry* entry) {
+ v8::Local<v8::External> entry_ptr =
+ v8::External::New(context->GetIsolate(), entry);
+ bool ret = SetTrampolineAccessorForEntryPoint(context, entry->name,
+ entry_ptr);
+ if (!ret) {
+ LOGGER(ERROR) << "Error installing trampoline for " << entry->name;
+ return false;
+ }
+
+ std::vector<std::string>::const_iterator it = entry->entry_points.begin();
+ for (; it != entry->entry_points.end(); ++it) {
+ ret = SetTrampolineAccessorForEntryPoint(context, *it, entry_ptr);
+ if (!ret) {
+ // TODO(vcgomes): Remove already added trampolines when it fails.
+ LOGGER(ERROR) << "Error installing trampoline for " << entry->name;
+ return false;
+ }
+ }
+ return true;
+}
+
+v8::Handle<v8::Object> XWalkModuleSystem::RequireNative(
+ const std::string& name) {
+ NativeModuleMap::iterator it = native_modules_.find(name);
+ if (it == native_modules_.end())
+ return v8::Handle<v8::Object>();
+ return it->second->NewInstance();
+}
+
+void XWalkModuleSystem::Initialize() {
+ SCOPE_PROFILE();
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ v8::HandleScope handle_scope(isolate);
+ v8::Handle<v8::Context> context = GetV8Context();
+ v8::Handle<v8::FunctionTemplate> require_native_template =
+ v8::Local<v8::FunctionTemplate>::New(isolate, require_native_template_);
+ v8::Handle<v8::Function> require_native =
+ require_native_template->GetFunction();
+
+ MarkModulesWithTrampoline();
+
+ ExtensionModules::iterator it = extension_modules_.begin();
+ for (; it != extension_modules_.end(); ++it) {
+ if (it->use_trampoline && InstallTrampoline(context, &*it))
+ continue;
+ it->module->LoadExtensionCode(context, require_native);
+ EnsureExtensionNamespaceIsReadOnly(context, it->name);
+ }
+}
+
+v8::Handle<v8::Context> XWalkModuleSystem::GetV8Context() {
+ return v8::Local<v8::Context>::New(v8::Isolate::GetCurrent(), v8_context_);
+}
+
+bool XWalkModuleSystem::ContainsEntryPoint(
+ const std::string& entry) {
+ auto it = extension_modules_.begin();
+ for (; it != extension_modules_.end(); ++it) {
+ if (it->name == entry)
+ return true;
+
+ auto entry_it = std::find(
+ it->entry_points.begin(), it->entry_points.end(), entry);
+ if (entry_it != it->entry_points.end()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void XWalkModuleSystem::DeleteExtensionModules() {
+ for (ExtensionModules::iterator it = extension_modules_.begin();
+ it != extension_modules_.end(); ++it) {
+ delete it->module;
+ }
+ extension_modules_.clear();
+}
+
+// static
+void XWalkModuleSystem::LoadExtensionForTrampoline(
+ v8::Isolate* isolate,
+ v8::Local<v8::Value> data) {
+ v8::HandleScope handle_scope(isolate);
+ v8::Local<v8::Array> params = data.As<v8::Array>();
+ void* ptr = params->Get(
+ v8::Integer::New(isolate, 0)).As<v8::External>()->Value();
+
+ ExtensionModuleEntry* entry = static_cast<ExtensionModuleEntry*>(ptr);
+
+ if (!entry)
+ return;
+
+ v8::Handle<v8::Context> context = isolate->GetCurrentContext();
+
+ DeleteAccessorForEntryPoint(context, entry->name);
+
+ auto it = entry->entry_points.begin();
+ for (; it != entry->entry_points.end(); ++it) {
+ DeleteAccessorForEntryPoint(context, *it);
+ }
+
+ XWalkModuleSystem* module_system = GetModuleSystemFromContext(context);
+ v8::Handle<v8::FunctionTemplate> require_native_template =
+ v8::Local<v8::FunctionTemplate>::New(
+ isolate,
+ module_system->require_native_template_);
+
+ XWalkExtensionModule* module = entry->module;
+ module->LoadExtensionCode(module_system->GetV8Context(),
+ require_native_template->GetFunction());
+
+ module_system->EnsureExtensionNamespaceIsReadOnly(context, entry->name);
+}
+
+// static
+v8::Handle<v8::Value> XWalkModuleSystem::RefetchHolder(
+ v8::Isolate* isolate,
+ v8::Local<v8::Value> data) {
+ v8::Local<v8::Array> params = data.As<v8::Array>();
+ const std::string entry_point = *v8::String::Utf8Value(
+ params->Get(v8::Integer::New(isolate, 1)).As<v8::String>());
+
+ std::vector<std::string> path;
+ SplitString(entry_point, '.', &path);
+ path.pop_back();
+
+ std::string error;
+ return GetObjectForPath(isolate->GetCurrentContext(), path, &error);
+}
+
+// static
+void XWalkModuleSystem::TrampolineCallback(
+ v8::Local<v8::Name> property,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ XWalkModuleSystem::LoadExtensionForTrampoline(info.GetIsolate(), info.Data());
+ v8::Handle<v8::Value> holder = RefetchHolder(info.GetIsolate(), info.Data());
+ if (holder->IsUndefined())
+ return;
+
+ info.GetReturnValue().Set(holder.As<v8::Object>()->Get(property));
+}
+
+// static
+void XWalkModuleSystem::TrampolineSetterCallback(
+ v8::Local<v8::Name> property,
+ v8::Local<v8::Value> value,
+ const v8::PropertyCallbackInfo<void>& info) {
+ XWalkModuleSystem::LoadExtensionForTrampoline(info.GetIsolate(), info.Data());
+ v8::Handle<v8::Value> holder = RefetchHolder(info.GetIsolate(), info.Data());
+ if (holder->IsUndefined())
+ return;
+
+ holder.As<v8::Object>()->Set(property, value);
+}
+
+XWalkModuleSystem::ExtensionModuleEntry::ExtensionModuleEntry(
+ const std::string& name,
+ XWalkExtensionModule* module,
+ const std::vector<std::string>& entry_points) :
+ name(name), module(module), use_trampoline(true),
+ entry_points(entry_points) {
+}
+
+XWalkModuleSystem::ExtensionModuleEntry::~ExtensionModuleEntry() {
+}
+
+// Returns whether the name of first is prefix of the second, considering "."
+// character as a separator. So "a" is prefix of "a.b" but not of "ab".
+bool XWalkModuleSystem::ExtensionModuleEntry::IsPrefix(
+ const ExtensionModuleEntry& first,
+ const ExtensionModuleEntry& second) {
+ const std::string& p = first.name;
+ const std::string& s = second.name;
+ return s.size() > p.size() && s[p.size()] == '.'
+ && std::mismatch(p.begin(), p.end(), s.begin()).first == p.end();
+}
+
+// Mark the extension modules that we want to setup "trampolines"
+// instead of loading the code directly. The current algorithm is very
+// simple: we only create trampolines for extensions that are leaves
+// in the namespace tree.
+//
+// For example, if there are two extensions "tizen" and "tizen.time",
+// the first one won't be marked with trampoline, but the second one
+// will. So we'll only load code for "tizen" extension.
+void XWalkModuleSystem::MarkModulesWithTrampoline() {
+ std::sort(extension_modules_.begin(), extension_modules_.end());
+ {
+ ExtensionModules::iterator it = extension_modules_.begin();
+ while (it != extension_modules_.end()) {
+ it = std::adjacent_find(it, extension_modules_.end(),
+ &ExtensionModuleEntry::IsPrefix);
+ if (it == extension_modules_.end())
+ break;
+ it->use_trampoline = false;
+ ++it;
+ }
+ }
+
+ // NOTE: Special Case for Security Reason
+ // xwalk module should not be trampolined even it does not have any children.
+ {
+ ExtensionModules::iterator it = extension_modules_.begin();
+ while (it != extension_modules_.end()) {
+ if ("xwalk" == (*it).name) {
+ it->use_trampoline = false;
+ break;
+ }
+ ++it;
+ }
+ }
+}
+
+void XWalkModuleSystem::EnsureExtensionNamespaceIsReadOnly(
+ v8::Handle<v8::Context> context,
+ const std::string& extension_name) {
+ std::vector<std::string> path;
+ SplitString(extension_name, '.', &path);
+ std::string basename = path.back();
+ path.pop_back();
+
+ std::string error;
+ v8::Handle<v8::Value> value = GetObjectForPath(context, path, &error);
+ if (value->IsUndefined()) {
+ LOGGER(ERROR) << "Error retrieving object for " << extension_name << " : "
+ << error;
+ return;
+ }
+
+ v8::Handle<v8::String> v8_extension_name(
+ v8::String::NewFromUtf8(context->GetIsolate(), basename.c_str()));
+ value.As<v8::Object>()->ForceSet(
+ v8_extension_name, value.As<v8::Object>()->Get(v8_extension_name),
+ v8::ReadOnly);
+}
+
+} // namespace extensions
--- /dev/null
+// Copyright (c) 2013 Intel Corporation. All rights reserved.
+// Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef XWALK_EXTENSIONS_RENDERER_XWALK_MODULE_SYSTEM_H_
+#define XWALK_EXTENSIONS_RENDERER_XWALK_MODULE_SYSTEM_H_
+
+#include <v8/v8.h>
+
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace extensions {
+
+class XWalkExtensionModule;
+
+// Interface used to expose objects via the requireNative() function in JS API
+// code. Native modules should be registered with the module system.
+class XWalkNativeModule {
+ public:
+ virtual v8::Handle<v8::Object> NewInstance() = 0;
+ virtual ~XWalkNativeModule() {}
+};
+
+
+class XWalkModuleSystem {
+ public:
+ explicit XWalkModuleSystem(v8::Handle<v8::Context> context);
+ ~XWalkModuleSystem();
+
+ static XWalkModuleSystem* GetModuleSystemFromContext(
+ v8::Handle<v8::Context> context);
+ static void SetModuleSystemInContext(
+ std::unique_ptr<XWalkModuleSystem> module_system,
+ v8::Handle<v8::Context> context);
+ static void ResetModuleSystemFromContext(v8::Handle<v8::Context> context);
+
+ void RegisterExtensionModule(std::unique_ptr<XWalkExtensionModule> module,
+ const std::vector<std::string>& entry_points);
+ void RegisterNativeModule(const std::string& name,
+ std::unique_ptr<XWalkNativeModule> module);
+ v8::Handle<v8::Object> RequireNative(const std::string& name);
+
+ void Initialize();
+
+ v8::Handle<v8::Context> GetV8Context();
+
+ private:
+ struct ExtensionModuleEntry {
+ ExtensionModuleEntry(const std::string& name, XWalkExtensionModule* module,
+ const std::vector<std::string>& entry_points);
+ ~ExtensionModuleEntry();
+ std::string name;
+ XWalkExtensionModule* module;
+ bool use_trampoline;
+ std::vector<std::string> entry_points;
+ bool operator<(const ExtensionModuleEntry& other) const {
+ return name < other.name;
+ }
+
+ static bool IsPrefix(const ExtensionModuleEntry& first,
+ const ExtensionModuleEntry& second);
+ };
+
+ bool SetTrampolineAccessorForEntryPoint(
+ v8::Handle<v8::Context> context,
+ const std::string& entry_point,
+ v8::Local<v8::External> user_data);
+
+ static bool DeleteAccessorForEntryPoint(v8::Handle<v8::Context> context,
+ const std::string& entry_point);
+
+ bool InstallTrampoline(v8::Handle<v8::Context> context,
+ ExtensionModuleEntry* entry);
+
+ static void TrampolineCallback(
+ v8::Local<v8::Name> property,
+ const v8::PropertyCallbackInfo<v8::Value>& info);
+ static void TrampolineSetterCallback(
+ v8::Local<v8::Name> property,
+ v8::Local<v8::Value> value,
+ const v8::PropertyCallbackInfo<void>& info);
+ static void LoadExtensionForTrampoline(
+ v8::Isolate* isolate,
+ v8::Local<v8::Value> data);
+ static v8::Handle<v8::Value> RefetchHolder(
+ v8::Isolate* isolate,
+ v8::Local<v8::Value> data);
+
+ bool ContainsEntryPoint(const std::string& entry_point);
+ void MarkModulesWithTrampoline();
+ void DeleteExtensionModules();
+
+ void EnsureExtensionNamespaceIsReadOnly(v8::Handle<v8::Context> context,
+ const std::string& extension_name);
+
+ typedef std::vector<ExtensionModuleEntry> ExtensionModules;
+ ExtensionModules extension_modules_;
+ typedef std::map<std::string, XWalkNativeModule*> NativeModuleMap;
+ NativeModuleMap native_modules_;
+
+ v8::Persistent<v8::FunctionTemplate> require_native_template_;
+ v8::Persistent<v8::Object> function_data_;
+
+ // Points back to the current context, used when native wants to callback
+ // JavaScript. When WillReleaseScriptContext() is called, we dispose this
+ // persistent.
+ v8::Persistent<v8::Context> v8_context_;
+};
+
+} // namespace extensions
+
+#endif // XWALK_EXTENSIONS_RENDERER_XWALK_MODULE_SYSTEM_H_
--- /dev/null
+// Copyright (c) 2013 Intel Corporation. All rights reserved.
+// Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "extensions/renderer/xwalk_v8tools_module.h"
+
+#include <v8/v8.h>
+
+#include "common/logger.h"
+
+namespace extensions {
+
+namespace {
+
+void ForceSetPropertyCallback(
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ if (info.Length() != 3 || !info[0]->IsObject() || !info[1]->IsString()) {
+ return;
+ }
+ info[0].As<v8::Object>()->ForceSet(info[1], info[2]);
+}
+
+// ================
+// lifecycleTracker
+// ================
+struct LifecycleTrackerWrapper {
+ v8::Global<v8::Object> handle;
+ v8::Global<v8::Function> destructor;
+};
+
+void LifecycleTrackerCleanup(
+ const v8::WeakCallbackInfo<LifecycleTrackerWrapper>& data) {
+ LifecycleTrackerWrapper* wrapper = data.GetParameter();
+
+ if (!wrapper->destructor.IsEmpty()) {
+ v8::HandleScope handle_scope(data.GetIsolate());
+ v8::Local<v8::Context> context = v8::Context::New(data.GetIsolate());
+ v8::Context::Scope scope(context);
+
+ v8::Local<v8::Function> destructor =
+ wrapper->destructor.Get(data.GetIsolate());
+
+ v8::MicrotasksScope microtasks(
+ data.GetIsolate(), v8::MicrotasksScope::kDoNotRunMicrotasks);
+
+ v8::TryCatch try_catch(data.GetIsolate());
+ destructor->Call(context->Global(), 0, nullptr);
+
+ if (try_catch.HasCaught()) {
+ LOGGER(WARN) << "Exception when running LifecycleTracker destructor";
+ }
+ }
+}
+
+void LifecycleTracker(const v8::FunctionCallbackInfo<v8::Value>& info) {
+ v8::Isolate* isolate = info.GetIsolate();
+ v8::HandleScope handle_scope(info.GetIsolate());
+
+ v8::Local<v8::Object> tracker = v8::Object::New(isolate);
+ LifecycleTrackerWrapper* wrapper = new LifecycleTrackerWrapper;
+ wrapper->handle.Reset(isolate, tracker);
+ wrapper->handle.SetWeak(wrapper, LifecycleTrackerCleanup,
+ v8::WeakCallbackType::kParameter);
+ info.GetReturnValue().Set(wrapper->handle);
+}
+
+} // namespace
+
+XWalkV8ToolsModule::XWalkV8ToolsModule() {
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ v8::HandleScope handle_scope(isolate);
+ v8::Handle<v8::ObjectTemplate> object_template = v8::ObjectTemplate::New();
+
+ // TODO(cmarcelo): Use Template::Set() function that takes isolate, once we
+ // update the Chromium (and V8) version.
+ object_template->Set(v8::String::NewFromUtf8(isolate, "forceSetProperty"),
+ v8::FunctionTemplate::New(
+ isolate, ForceSetPropertyCallback));
+ object_template->Set(v8::String::NewFromUtf8(isolate, "lifecycleTracker"),
+ v8::FunctionTemplate::New(isolate, LifecycleTracker));
+
+ object_template_.Reset(isolate, object_template);
+}
+
+XWalkV8ToolsModule::~XWalkV8ToolsModule() {
+ object_template_.Reset();
+}
+
+v8::Handle<v8::Object> XWalkV8ToolsModule::NewInstance() {
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ v8::EscapableHandleScope handle_scope(isolate);
+ v8::Handle<v8::ObjectTemplate> object_template =
+ v8::Local<v8::ObjectTemplate>::New(isolate, object_template_);
+ return handle_scope.Escape(object_template->NewInstance());
+}
+
+} // namespace extensions
--- /dev/null
+// Copyright (c) 2013 Intel Corporation. All rights reserved.
+// Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef XWALK_EXTENSIONS_RENDERER_XWALK_V8TOOLS_MODULE_H_
+#define XWALK_EXTENSIONS_RENDERER_XWALK_V8TOOLS_MODULE_H_
+
+#include "extensions/renderer/xwalk_module_system.h"
+
+namespace extensions {
+
+// This module provides extra JS functions that help writing JS API code for
+// extensions, for example: allowing setting a read-only property of an object.
+class XWalkV8ToolsModule : public XWalkNativeModule {
+ public:
+ XWalkV8ToolsModule();
+ ~XWalkV8ToolsModule() override;
+
+ private:
+ v8::Handle<v8::Object> NewInstance() override;
+
+ v8::Persistent<v8::ObjectTemplate> object_template_;
+};
+
+} // namespace extensions
+
+#endif // XWALK_EXTENSIONS_RENDERER_XWALK_V8TOOLS_MODULE_H_
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <Ecore.h>
+#include <EWebKit.h>
+#include <EWebKit_internal.h>
+#include <unistd.h>
+#include <v8.h>
+#include <dlfcn.h>
+
+#include <memory>
+#include <string>
+
+#include "common/application_data.h"
+#include "common/locale_manager.h"
+#include "common/logger.h"
+#include "common/profiler.h"
+#include "common/resource_manager.h"
+#include "common/string_utils.h"
+#include "extensions/renderer/runtime_ipc_client.h"
+#include "extensions/renderer/widget_module.h"
+#include "extensions/renderer/xwalk_extension_renderer_controller.h"
+#include "extensions/renderer/xwalk_module_system.h"
+
+namespace runtime {
+
+class BundleGlobalData {
+ public:
+ static BundleGlobalData* GetInstance() {
+ static BundleGlobalData instance;
+ return &instance;
+ }
+ void PreInitialize() {
+ if (preInitialized)
+ return;
+ preInitialized = true;
+ locale_manager_.reset(new common::LocaleManager);
+ }
+ void Initialize(const std::string& app_id) {
+ PreInitialize();
+
+ auto appdata_manager = common::ApplicationDataManager::GetInstance();
+ common::ApplicationData* app_data =
+ appdata_manager->GetApplicationData(app_id);
+
+ app_data->LoadManifestData();
+ // PreInitialized locale_manager_.reset(new common::LocaleManager);
+ locale_manager_->EnableAutoUpdate(true);
+ if (app_data->widget_info() != NULL &&
+ !app_data->widget_info()->default_locale().empty()) {
+ locale_manager_->SetDefaultLocale(
+ app_data->widget_info()->default_locale());
+ }
+ resource_manager_.reset(new common::ResourceManager(app_data,
+ locale_manager_.get()));
+ resource_manager_->set_base_resource_path(
+ app_data->application_path());
+
+ auto widgetdb = extensions::WidgetPreferenceDB::GetInstance();
+ widgetdb->Initialize(app_data,
+ locale_manager_.get());
+ }
+
+ common::ResourceManager* resource_manager() {
+ return resource_manager_.get();
+ }
+
+ private:
+ BundleGlobalData() : preInitialized(false) {}
+ ~BundleGlobalData() {}
+ std::unique_ptr<common::ResourceManager> resource_manager_;
+ std::unique_ptr<common::LocaleManager> locale_manager_;
+
+ bool preInitialized;
+};
+
+} // namespace runtime
+
+extern "C" unsigned int DynamicPluginVersion(void) {
+ return 1;
+}
+
+extern "C" void DynamicSetWidgetInfo(const char* tizen_id) {
+ SCOPE_PROFILE();
+ ecore_init();
+
+ runtime::BundleGlobalData::GetInstance()->Initialize(tizen_id);
+ extensions::XWalkExtensionRendererController& controller =
+ extensions::XWalkExtensionRendererController::GetInstance();
+ auto appdata_manager = common::ApplicationDataManager::GetInstance();
+ common::ApplicationData* app_data =
+ appdata_manager->GetApplicationData(tizen_id);
+ controller.LoadUserExtensions(app_data->application_path());
+}
+
+extern "C" void DynamicPluginStartSession(const char* tizen_id,
+ v8::Handle<v8::Context> context,
+ int routing_handle,
+ const char* base_url) {
+ SCOPE_PROFILE();
+
+ // Initialize context's aligned pointer in embedder data with null
+ extensions::XWalkModuleSystem::SetModuleSystemInContext(
+ std::unique_ptr<extensions::XWalkModuleSystem>(), context);
+
+ if (base_url == NULL || common::utils::StartsWith(base_url, "http")) {
+ LOGGER(ERROR) << "External url not allowed plugin loading.";
+ return;
+ }
+
+ // Initialize RuntimeIPCClient
+ extensions::RuntimeIPCClient* rc =
+ extensions::RuntimeIPCClient::GetInstance();
+ rc->SetRoutingId(context, routing_handle);
+
+ extensions::XWalkExtensionRendererController& controller =
+ extensions::XWalkExtensionRendererController::GetInstance();
+ controller.DidCreateScriptContext(context);
+}
+
+extern "C" void DynamicPluginStopSession(
+ const char* tizen_id, v8::Handle<v8::Context> context) {
+ SCOPE_PROFILE();
+ extensions::XWalkExtensionRendererController& controller =
+ extensions::XWalkExtensionRendererController::GetInstance();
+ controller.WillReleaseScriptContext(context);
+}
+
+extern "C" void DynamicUrlParsing(
+ std::string* old_url, std::string* new_url, const char* /*tizen_id*/) {
+ LOGGER(DEBUG) << "DynamicUrlParsing";
+ auto res_manager =
+ runtime::BundleGlobalData::GetInstance()->resource_manager();
+ if (res_manager == NULL) {
+ LOGGER(ERROR) << "Widget Info was not set, Resource Manager is NULL";
+ *new_url = *old_url;
+ return;
+ }
+ // Check Access control
+ if (!res_manager->AllowedResource(*old_url)) {
+ // To maintain backward compatibility, we shoudn't explicitly set URL "about:blank"
+ *new_url = std::string();
+ LOGGER(ERROR) << "request was blocked by WARP";
+ return;
+ }
+ // convert to localized path
+ if (common::utils::StartsWith(*old_url, "file:/") ||
+ common::utils::StartsWith(*old_url, "app:/")) {
+ *new_url = res_manager->GetLocalizedPath(*old_url);
+ } else {
+ *new_url = *old_url;
+ }
+ // check encryption
+ if (res_manager->IsEncrypted(*new_url)) {
+ *new_url = res_manager->DecryptResource(*new_url);
+ }
+}
+
+extern "C" void DynamicDatabaseAttach(int /*attach*/) {
+ // LOGGER(DEBUG) << "InjectedBundle::DynamicDatabaseAttach !!";
+}
+
+extern "C" void DynamicOnIPCMessage(const Ewk_IPC_Wrt_Message_Data& data) {
+ SCOPE_PROFILE();
+ extensions::XWalkExtensionRendererController& controller =
+ extensions::XWalkExtensionRendererController::GetInstance();
+ controller.OnReceivedIPCMessage(&data);
+}
+
+extern "C" void DynamicPreloading() {
+ LOGGER(ERROR) << "DynamicPreloading";
+ SCOPE_PROFILE();
+ runtime::BundleGlobalData::GetInstance()->PreInitialize();
+ extensions::XWalkExtensionRendererController& controller =
+ extensions::XWalkExtensionRendererController::GetInstance();
+ controller.InitializeExtensionClient();
+}
--- /dev/null
+{
+ 'includes':[
+ '../build/common.gypi',
+ ],
+ 'targets': [
+ {
+ 'target_name': 'xwalk_injected_bundle',
+ 'type': 'shared_library',
+ 'sources': [
+ 'injected_bundle.cc',
+ ],
+ 'cflags': [
+ '-fvisibility=default',
+ ],
+ 'variables': {
+ 'packages': [
+ 'chromium-efl',
+ 'elementary',
+ ],
+ },
+ }, # end of target 'xwalk_injected_bundle'
+ ],
+}
#include "content/public/browser/storage_partition.h"
#include "net/base/escape.h"
+#if defined(OS_TIZEN)
+#include "content/browser/zygote_host/zygote_communication_linux.h"
+#include "content/public/browser/zygote_handle_linux.h"
+#include "content/public/common/content_switches.h"
+#include "base/command_line.h"
+#endif
+
using content::BrowserThread;
namespace brightray {
content::BrowserContext::Initialize(this, path_);
browser_context_map_[PartitionKey(partition, in_memory)] = GetWeakPtr();
+#if defined(OS_TIZEN)
+ auto command_line = base::CommandLine::ForCurrentProcess();
+ if (command_line->HasSwitch("injected-bundle-path")) {
+ std::string injected_bundle_path = command_line->GetSwitchValueASCII("injected-bundle-path");
+ (*content::GetGenericZygote())->
+ LoadInjectedBundlePath(injected_bundle_path);
+ }
+#endif
}
BrowserContext::~BrowserContext() {
'wrt_lib',
'<(DEPTH)/tizen/common/common.gyp:wrt_common',
'<(DEPTH)/tizen/loader/loader.gyp:wrt-loader',
+ '<(DEPTH)/tizen/extensions/extensions.gyp:xwalk_extension_shared',
+ '<(DEPTH)/tizen/renderer/injected_bundle.gyp:xwalk_injected_bundle',
'<(DEPTH)/efl/build/system.gyp:ecore',
'<(DEPTH)/efl/build/system.gyp:launchpad',
'<(DEPTH)/efl/build/system.gyp:capi-appfw-application',