From ba3836c993b5a128cd7d9fe21a3bd49e3f5b3acc Mon Sep 17 00:00:00 2001 From: prathmeshm Date: Fri, 23 Mar 2018 12:16:03 +0530 Subject: [PATCH 01/16] Added Injected Bundle and extension server and client - Added injected bundle in electron - Added extension server and client - Set injected bundle path to chromium for init - related patch https://review.tizen.org/gerrit/#/c/174986/ Change-Id: Iee1717b760cb68576ad02c7cab657b099e54b913 Signed-off-by: prathmeshm --- atom/app/atom_main_delegate.cc | 13 + packaging/electron-efl.spec | 12 + tizen/build/common.gypi | 12 +- tizen/extensions/common/constants.cc | 30 ++ tizen/extensions/common/constants.h | 32 ++ tizen/extensions/common/xwalk_extension.cc | 125 +++++ tizen/extensions/common/xwalk_extension.h | 82 +++ tizen/extensions/common/xwalk_extension_adapter.cc | 323 ++++++++++++ tizen/extensions/common/xwalk_extension_adapter.h | 96 ++++ .../extensions/common/xwalk_extension_instance.cc | 63 +++ tizen/extensions/common/xwalk_extension_instance.h | 47 ++ tizen/extensions/common/xwalk_extension_manager.cc | 260 +++++++++ tizen/extensions/common/xwalk_extension_manager.h | 47 ++ tizen/extensions/common/xwalk_extension_server.cc | 229 ++++++++ tizen/extensions/common/xwalk_extension_server.h | 57 ++ tizen/extensions/extensions.gyp | 60 +++ .../internal/splash_screen/splash_screen.json | 7 + .../internal/splash_screen/splash_screen_api.js | 22 + .../splash_screen/splash_screen_extension.cc | 95 ++++ tizen/extensions/internal/widget/widget.json | 7 + tizen/extensions/internal/widget/widget_api.js | 93 ++++ .../extensions/internal/widget/widget_extension.cc | 95 ++++ tizen/extensions/public/XW_Extension.h | 185 +++++++ tizen/extensions/public/XW_Extension_EntryPoints.h | 49 ++ tizen/extensions/public/XW_Extension_Message_2.h | 64 +++ tizen/extensions/public/XW_Extension_Permissions.h | 41 ++ tizen/extensions/public/XW_Extension_Runtime.h | 44 ++ tizen/extensions/public/XW_Extension_SyncMessage.h | 48 ++ tizen/extensions/renderer/object_tools_module.cc | 114 ++++ tizen/extensions/renderer/object_tools_module.h | 36 ++ tizen/extensions/renderer/runtime_ipc_client.cc | 238 +++++++++ tizen/extensions/renderer/runtime_ipc_client.h | 100 ++++ tizen/extensions/renderer/widget_module.cc | 581 +++++++++++++++++++++ tizen/extensions/renderer/widget_module.h | 75 +++ .../extensions/renderer/xwalk_extension_client.cc | 131 +++++ tizen/extensions/renderer/xwalk_extension_client.h | 71 +++ .../extensions/renderer/xwalk_extension_module.cc | 514 ++++++++++++++++++ tizen/extensions/renderer/xwalk_extension_module.h | 84 +++ .../xwalk_extension_renderer_controller.cc | 132 +++++ .../renderer/xwalk_extension_renderer_controller.h | 45 ++ tizen/extensions/renderer/xwalk_module_system.cc | 524 +++++++++++++++++++ tizen/extensions/renderer/xwalk_module_system.h | 116 ++++ tizen/extensions/renderer/xwalk_v8tools_module.cc | 98 ++++ tizen/extensions/renderer/xwalk_v8tools_module.h | 28 + tizen/renderer/injected_bundle.cc | 190 +++++++ tizen/renderer/injected_bundle.gyp | 23 + vendor/brightray/browser/browser_context.cc | 15 + wrt.gyp | 2 + 48 files changed, 5349 insertions(+), 6 deletions(-) create mode 100644 tizen/extensions/common/constants.cc create mode 100644 tizen/extensions/common/constants.h create mode 100644 tizen/extensions/common/xwalk_extension.cc create mode 100644 tizen/extensions/common/xwalk_extension.h create mode 100644 tizen/extensions/common/xwalk_extension_adapter.cc create mode 100644 tizen/extensions/common/xwalk_extension_adapter.h create mode 100644 tizen/extensions/common/xwalk_extension_instance.cc create mode 100644 tizen/extensions/common/xwalk_extension_instance.h create mode 100644 tizen/extensions/common/xwalk_extension_manager.cc create mode 100644 tizen/extensions/common/xwalk_extension_manager.h create mode 100644 tizen/extensions/common/xwalk_extension_server.cc create mode 100644 tizen/extensions/common/xwalk_extension_server.h create mode 100644 tizen/extensions/extensions.gyp create mode 100644 tizen/extensions/internal/splash_screen/splash_screen.json create mode 100644 tizen/extensions/internal/splash_screen/splash_screen_api.js create mode 100644 tizen/extensions/internal/splash_screen/splash_screen_extension.cc create mode 100644 tizen/extensions/internal/widget/widget.json create mode 100644 tizen/extensions/internal/widget/widget_api.js create mode 100644 tizen/extensions/internal/widget/widget_extension.cc create mode 100644 tizen/extensions/public/XW_Extension.h create mode 100644 tizen/extensions/public/XW_Extension_EntryPoints.h create mode 100644 tizen/extensions/public/XW_Extension_Message_2.h create mode 100644 tizen/extensions/public/XW_Extension_Permissions.h create mode 100644 tizen/extensions/public/XW_Extension_Runtime.h create mode 100644 tizen/extensions/public/XW_Extension_SyncMessage.h create mode 100644 tizen/extensions/renderer/object_tools_module.cc create mode 100644 tizen/extensions/renderer/object_tools_module.h create mode 100644 tizen/extensions/renderer/runtime_ipc_client.cc create mode 100644 tizen/extensions/renderer/runtime_ipc_client.h create mode 100644 tizen/extensions/renderer/widget_module.cc create mode 100644 tizen/extensions/renderer/widget_module.h create mode 100644 tizen/extensions/renderer/xwalk_extension_client.cc create mode 100644 tizen/extensions/renderer/xwalk_extension_client.h create mode 100644 tizen/extensions/renderer/xwalk_extension_module.cc create mode 100644 tizen/extensions/renderer/xwalk_extension_module.h create mode 100644 tizen/extensions/renderer/xwalk_extension_renderer_controller.cc create mode 100644 tizen/extensions/renderer/xwalk_extension_renderer_controller.h create mode 100644 tizen/extensions/renderer/xwalk_module_system.cc create mode 100644 tizen/extensions/renderer/xwalk_module_system.h create mode 100644 tizen/extensions/renderer/xwalk_v8tools_module.cc create mode 100644 tizen/extensions/renderer/xwalk_v8tools_module.h create mode 100644 tizen/renderer/injected_bundle.cc create mode 100644 tizen/renderer/injected_bundle.gyp diff --git a/atom/app/atom_main_delegate.cc b/atom/app/atom_main_delegate.cc index 9f9ac69..f840690 100644 --- a/atom/app/atom_main_delegate.cc +++ b/atom/app/atom_main_delegate.cc @@ -25,6 +25,11 @@ #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 { @@ -141,6 +146,14 @@ void AtomMainDelegate::PreSandboxStartup() { // 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 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"); diff --git a/packaging/electron-efl.spec b/packaging/electron-efl.spec index f26da7c..7f48f8b 100755 --- a/packaging/electron-efl.spec +++ b/packaging/electron-efl.spec @@ -53,6 +53,7 @@ BuildRequires: pkgconfig(ttrace) BuildRequires: pkgconfig(vd-win-util) %endif BuildRequires: pkgconfig(wgt-manifest-handlers) +BuildRequires: pkgconfig(jsoncpp) Requires: /usr/bin/systemctl @@ -74,6 +75,8 @@ DEFINE_ARGS=" 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+=" @@ -131,6 +134,13 @@ install -m 0755 %{_out}/resources/electron.asar %{buildroot}/opt/usr/home/ow ./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'. @@ -161,3 +171,5 @@ rm -fr %{buildroot} %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 diff --git a/tizen/build/common.gypi b/tizen/build/common.gypi index 587a0ad..5f90ec5 100644 --- a/tizen/build/common.gypi +++ b/tizen/build/common.gypi @@ -1,8 +1,8 @@ { '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': { @@ -36,10 +36,10 @@ '../', '<(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', diff --git a/tizen/extensions/common/constants.cc b/tizen/extensions/common/constants.cc new file mode 100644 index 0000000..cfc9fa4 --- /dev/null +++ b/tizen/extensions/common/constants.cc @@ -0,0 +1,30 @@ +/* + * 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 diff --git a/tizen/extensions/common/constants.h b/tizen/extensions/common/constants.h new file mode 100644 index 0000000..588f09b --- /dev/null +++ b/tizen/extensions/common/constants.h @@ -0,0 +1,32 @@ +/* + * 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_ diff --git a/tizen/extensions/common/xwalk_extension.cc b/tizen/extensions/common/xwalk_extension.cc new file mode 100644 index 0000000..d41af24 --- /dev/null +++ b/tizen/extensions/common/xwalk_extension.cc @@ -0,0 +1,125 @@ +// 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 +#include + +#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( + 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 + diff --git a/tizen/extensions/common/xwalk_extension.h b/tizen/extensions/common/xwalk_extension.h new file mode 100644 index 0000000..c7aaf83 --- /dev/null +++ b/tizen/extensions/common/xwalk_extension.h @@ -0,0 +1,82 @@ +// 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 +#include + +#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 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_ diff --git a/tizen/extensions/common/xwalk_extension_adapter.cc b/tizen/extensions/common/xwalk_extension_adapter.cc new file mode 100644 index 0000000..ef693ff --- /dev/null +++ b/tizen/extensions/common/xwalk_extension_adapter.cc @@ -0,0 +1,323 @@ +// 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 + +#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 diff --git a/tizen/extensions/common/xwalk_extension_adapter.h b/tizen/extensions/common/xwalk_extension_adapter.h new file mode 100644 index 0000000..9a29c35 --- /dev/null +++ b/tizen/extensions/common/xwalk_extension_adapter.h @@ -0,0 +1,96 @@ +// 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 + +#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 ExtensionMap; + typedef std::map 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_ diff --git a/tizen/extensions/common/xwalk_extension_instance.cc b/tizen/extensions/common/xwalk_extension_instance.cc new file mode 100644 index 0000000..c86bb59 --- /dev/null +++ b/tizen/extensions/common/xwalk_extension_instance.cc @@ -0,0 +1,63 @@ +// 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 diff --git a/tizen/extensions/common/xwalk_extension_instance.h b/tizen/extensions/common/xwalk_extension_instance.h new file mode 100644 index 0000000..9efe2db --- /dev/null +++ b/tizen/extensions/common/xwalk_extension_instance.h @@ -0,0 +1,47 @@ +// 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 +#include + +#include "extensions/public/XW_Extension.h" + +namespace extensions { + +class XWalkExtension; + +class XWalkExtensionInstance { + public: + typedef std::function 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_ diff --git a/tizen/extensions/common/xwalk_extension_manager.cc b/tizen/extensions/common/xwalk_extension_manager.cc new file mode 100644 index 0000000..130eca8 --- /dev/null +++ b/tizen/extensions/common/xwalk_extension_manager.cc @@ -0,0 +1,260 @@ +// 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 +#include +#include + +#include +#include +#include +#include + +#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()) { + auto& plugins = metadata.get(); + for (auto plugin = plugins.begin(); plugin != plugins.end(); ++plugin) { + if (!plugin->is()) + 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 entries; + auto& entry_points_value = plugin->get("entry_points"); + if (entry_points_value.is()) { + auto& entry_points = entry_points_value.get(); + 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 diff --git a/tizen/extensions/common/xwalk_extension_manager.h b/tizen/extensions/common/xwalk_extension_manager.h new file mode 100644 index 0000000..cfbdede --- /dev/null +++ b/tizen/extensions/common/xwalk_extension_manager.h @@ -0,0 +1,47 @@ +// 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 +#include +#include + +#include "extensions/common/xwalk_extension.h" + +namespace extensions { + +class XWalkExtensionManager : public XWalkExtension::XWalkExtensionDelegate { + public: + typedef std::set StringSet; + typedef std::map 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_ diff --git a/tizen/extensions/common/xwalk_extension_server.cc b/tizen/extensions/common/xwalk_extension_server.cc new file mode 100644 index 0000000..fc50396 --- /dev/null +++ b/tizen/extensions/common/xwalk_extension_server.cc @@ -0,0 +1,229 @@ +// 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 + +#include + +#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 diff --git a/tizen/extensions/common/xwalk_extension_server.h b/tizen/extensions/common/xwalk_extension_server.h new file mode 100644 index 0000000..3cd67bf --- /dev/null +++ b/tizen/extensions/common/xwalk_extension_server.h @@ -0,0 +1,57 @@ +// 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 +#include +#include + +#include +#include + +#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 InstanceMap; + + Ewk_Context* ewk_context_; + + XWalkExtensionManager manager_; + + InstanceMap instances_; +}; + +} // namespace extensions + +#endif // XWALK_EXTENSIONS_XWALK_EXTENSION_SERVER_H_ diff --git a/tizen/extensions/extensions.gyp b/tizen/extensions/extensions.gyp new file mode 100644 index 0000000..165271b --- /dev/null +++ b/tizen/extensions/extensions.gyp @@ -0,0 +1,60 @@ +{ + '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 +} diff --git a/tizen/extensions/internal/splash_screen/splash_screen.json b/tizen/extensions/internal/splash_screen/splash_screen.json new file mode 100644 index 0000000..e7a565d --- /dev/null +++ b/tizen/extensions/internal/splash_screen/splash_screen.json @@ -0,0 +1,7 @@ +[ + { + "name":"SplashScreen", + "lib":"libsplash_screen_plugin.so", + "entry_points":["window.screen.show"] + } +] diff --git a/tizen/extensions/internal/splash_screen/splash_screen_api.js b/tizen/extensions/internal/splash_screen/splash_screen_api.js new file mode 100644 index 0000000..551a72d --- /dev/null +++ b/tizen/extensions/internal/splash_screen/splash_screen_api.js @@ -0,0 +1,22 @@ +/* + * 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'); +}; diff --git a/tizen/extensions/internal/splash_screen/splash_screen_extension.cc b/tizen/extensions/internal/splash_screen/splash_screen_extension.cc new file mode 100644 index 0000000..19823e5 --- /dev/null +++ b/tizen/extensions/internal/splash_screen/splash_screen_extension.cc @@ -0,0 +1,95 @@ +/* + * 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 +#include +#include +#include + +#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( + 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( + 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( + 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( + 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( + 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; +} diff --git a/tizen/extensions/internal/widget/widget.json b/tizen/extensions/internal/widget/widget.json new file mode 100644 index 0000000..ae1dbbd --- /dev/null +++ b/tizen/extensions/internal/widget/widget.json @@ -0,0 +1,7 @@ +[ + { + "name":"Widget", + "lib":"libwidget_plugin.so", + "entry_points":["widget"] + } +] diff --git a/tizen/extensions/internal/widget/widget_api.js b/tizen/extensions/internal/widget/widget_api.js new file mode 100644 index 0000000..6a5b7a6 --- /dev/null +++ b/tizen/extensions/internal/widget/widget_api.js @@ -0,0 +1,93 @@ +/* + * 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; diff --git a/tizen/extensions/internal/widget/widget_extension.cc b/tizen/extensions/internal/widget/widget_extension.cc new file mode 100644 index 0000000..aab1dab --- /dev/null +++ b/tizen/extensions/internal/widget/widget_extension.cc @@ -0,0 +1,95 @@ +/* + * 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 +#include +#include +#include + +#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( + 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( + 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( + 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( + 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( + 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; +} diff --git a/tizen/extensions/public/XW_Extension.h b/tizen/extensions/public/XW_Extension.h new file mode 100644 index 0000000..174915a --- /dev/null +++ b/tizen/extensions/public/XW_Extension.h @@ -0,0 +1,185 @@ +// 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 + + +// 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_ diff --git a/tizen/extensions/public/XW_Extension_EntryPoints.h b/tizen/extensions/public/XW_Extension_EntryPoints.h new file mode 100644 index 0000000..54532a9 --- /dev/null +++ b/tizen/extensions/public/XW_Extension_EntryPoints.h @@ -0,0 +1,49 @@ +// 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_ + diff --git a/tizen/extensions/public/XW_Extension_Message_2.h b/tizen/extensions/public/XW_Extension_Message_2.h new file mode 100644 index 0000000..f417f88 --- /dev/null +++ b/tizen/extensions/public/XW_Extension_Message_2.h @@ -0,0 +1,64 @@ +// 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_ diff --git a/tizen/extensions/public/XW_Extension_Permissions.h b/tizen/extensions/public/XW_Extension_Permissions.h new file mode 100644 index 0000000..d25484e --- /dev/null +++ b/tizen/extensions/public/XW_Extension_Permissions.h @@ -0,0 +1,41 @@ +// 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_ diff --git a/tizen/extensions/public/XW_Extension_Runtime.h b/tizen/extensions/public/XW_Extension_Runtime.h new file mode 100644 index 0000000..11ad307 --- /dev/null +++ b/tizen/extensions/public/XW_Extension_Runtime.h @@ -0,0 +1,44 @@ +// 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_ + diff --git a/tizen/extensions/public/XW_Extension_SyncMessage.h b/tizen/extensions/public/XW_Extension_SyncMessage.h new file mode 100644 index 0000000..4eddbf9 --- /dev/null +++ b/tizen/extensions/public/XW_Extension_SyncMessage.h @@ -0,0 +1,48 @@ +// 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_ diff --git a/tizen/extensions/renderer/object_tools_module.cc b/tizen/extensions/renderer/object_tools_module.cc new file mode 100644 index 0000000..67cb503 --- /dev/null +++ b/tizen/extensions/renderer/object_tools_module.cc @@ -0,0 +1,114 @@ +/* + * 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 + +#include + +#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 RunString(const std::string& code) { + v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::EscapableHandleScope handle_scope(isolate); + v8::Handle v8_code( + v8::String::NewFromUtf8(isolate, code.c_str())); + + v8::TryCatch try_catch; + try_catch.SetVerbose(true); + + v8::Handle 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::Undefined(isolate))); + } + + v8::Local 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::Undefined(isolate))); + } + return handle_scope.Escape(result); +} +} // namespace + + +ObjectToolsModule::ObjectToolsModule() { + v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::HandleScope handle_scope(isolate); + + v8::Handle result = RunString(kCreateObjectCode); + if (!result->IsFunction()) { + LOGGER(ERROR) << "Couldn't load Object Create function"; + return; + } + v8::Handle create_function = + v8::Handle::Cast(result); + + create_function_.Reset(isolate, create_function); +} + +ObjectToolsModule::~ObjectToolsModule() { + create_function_.Reset(); +} + +v8::Handle ObjectToolsModule::NewInstance() { + v8::Isolate* isolate = v8::Isolate::GetCurrent(); + if (create_function_.IsEmpty()) { + return v8::Object::New(isolate); + } + v8::Handle function = + v8::Local::New(isolate, create_function_); + + v8::Handle context = v8::Context::New(isolate); + v8::TryCatch try_catch; + v8::Handle 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::Cast(ret); +} + +} // namespace extensions + diff --git a/tizen/extensions/renderer/object_tools_module.h b/tizen/extensions/renderer/object_tools_module.h new file mode 100644 index 0000000..eb4609b --- /dev/null +++ b/tizen/extensions/renderer/object_tools_module.h @@ -0,0 +1,36 @@ +/* + * 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 NewInstance() override; + v8::Persistent create_function_; +}; + +} // namespace extensions + +#endif // XWALK_EXTENSIONS_RENDERER_OBJECT_TOOLS_MODULE_H_ diff --git a/tizen/extensions/renderer/runtime_ipc_client.cc b/tizen/extensions/renderer/runtime_ipc_client.cc new file mode 100644 index 0000000..6b96828 --- /dev/null +++ b/tizen/extensions/renderer/runtime_ipc_client.cc @@ -0,0 +1,238 @@ +/* + * 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 callback) { + callback_.Reset(isolate, callback); +} + +RuntimeIPCClient::JSCallback::~JSCallback() { + callback_.Reset(); +} + +void RuntimeIPCClient::JSCallback::Call(v8::Isolate* isolate, + v8::Handle args[]) { + if (!callback_.IsEmpty()) { + v8::HandleScope handle_scope(isolate); + v8::TryCatch try_catch(isolate); + v8::Handle func = + v8::Local::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 context) { + v8::Handle 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 context, + int routing_id) { + context->SetEmbedderData(kRoutingIdEmbedderDataIndex, + v8::Integer::New(context->GetIsolate(), routing_id)); +} + +void RuntimeIPCClient::SendMessage(v8::Handle context, + const std::string& type, + const std::string& value) { + SendMessage(context, type, "", "", value); +} + +void RuntimeIPCClient::SendMessage(v8::Handle context, + const std::string& type, + const std::string& id, + const std::string& value) { + SendMessage(context, type, id, "", value); +} + +void RuntimeIPCClient::SendMessage(v8::Handle 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 context, + const std::string& type, + const std::string& value) { + return SendSyncMessage(context, type, "", "", value); +} + +std::string RuntimeIPCClient::SendSyncMessage(v8::Handle 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 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 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 diff --git a/tizen/extensions/renderer/runtime_ipc_client.h b/tizen/extensions/renderer/runtime_ipc_client.h new file mode 100644 index 0000000..7f94fb3 --- /dev/null +++ b/tizen/extensions/renderer/runtime_ipc_client.h @@ -0,0 +1,100 @@ +/* + * 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 +#include +#include + +#include +#include +#include + +namespace extensions { + +class RuntimeIPCClient { + public: + class JSCallback { + public: + explicit JSCallback(v8::Isolate* isolate, + v8::Handle callback); + ~JSCallback(); + + void Call(v8::Isolate* isolate, v8::Handle args[]); + private: + v8::Persistent callback_; + }; + + typedef std::function ReplyCallback; + + static RuntimeIPCClient* GetInstance(); + + // Send message to BrowserProcess without reply + void SendMessage(v8::Handle context, + const std::string& type, + const std::string& value); + + void SendMessage(v8::Handle context, + const std::string& type, + const std::string& id, + const std::string& value); + + void SendMessage(v8::Handle 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 context, + const std::string& type, + const std::string& value); + + std::string SendSyncMessage(v8::Handle context, + const std::string& type, + const std::string& id, + const std::string& value); + + std::string SendSyncMessage(v8::Handle 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 context, + const std::string& type, const std::string& value, + ReplyCallback callback); + + void HandleMessageFromRuntime(const Ewk_IPC_Wrt_Message_Data* msg); + + int GetRoutingId(v8::Handle context); + + void SetRoutingId(v8::Handle context, int routing_id); + + private: + RuntimeIPCClient(); + + std::map callbacks_; +}; + +} // namespace extensions + +#endif // XWALK_EXTENSIONS_RENDERER_RUNTIME_IPC_CLIENT_H_ diff --git a/tizen/extensions/renderer/widget_module.cc b/tizen/extensions/renderer/widget_module.cc new file mode 100644 index 0000000..2237501 --- /dev/null +++ b/tizen/extensions/renderer/widget_module.cc @@ -0,0 +1,581 @@ +/* + * 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 + +#include +#include + +#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 kExcludeList = { + kOnchangedEventHandler, + kKeyKey, + kGetItemKey, + kSetItemKey, + kRemoveItemKey, + kLengthKey, + kClearKey}; + +void DispatchEvent(const v8::Local& This, + v8::Local key, + v8::Local oldvalue, + v8::Local newvalue) { + v8::Isolate* isolate = v8::Isolate::GetCurrent(); + + v8::Handle function = + This->Get(v8::String::NewFromUtf8(isolate, kOnchangedEventHandler)); + + if (function.IsEmpty() || !function->IsFunction()) { + LOGGER(DEBUG) << "onChanged function not set"; + return; + } + + v8::Handle context = v8::Context::New(isolate); + + const int argc = 3; + v8::Handle argv[argc] = { + key, + oldvalue, + newvalue + }; + + v8::TryCatch try_catch; + v8::Handle::Cast(function)->Call( + context->Global(), argc, argv); + if (try_catch.HasCaught()) + LOGGER(DEBUG) << "Exception when running onChanged callback"; +} + +v8::Handle MakeException(int code, + std::string name, + std::string message) { + v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::EscapableHandleScope handle_scope(isolate); + v8::Local 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& 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& 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& 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 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& 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 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& 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 + preference_object_template = v8::ObjectTemplate::New(); + + auto getter = []( + v8::Local property, + const v8::PropertyCallbackInfo& 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 property, + v8::Local value, + const v8::PropertyCallbackInfo& 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 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 property, + const v8::PropertyCallbackInfo& 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 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 WidgetModule::NewInstance() { + v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::EscapableHandleScope handle_scope(isolate); + + v8::Local widget = v8::Object::New(isolate); + v8::Handle object_template = + v8::Local::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 list; + db->GetKeys(kDBPublicSection, &list); + return list.size(); +} + +bool WidgetPreferenceDB::Key(int idx, std::string* key) { + common::AppDB* db = common::AppDB::GetInstance(); + std::list 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 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* 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 diff --git a/tizen/extensions/renderer/widget_module.h b/tizen/extensions/renderer/widget_module.h new file mode 100644 index 0000000..36acec1 --- /dev/null +++ b/tizen/extensions/renderer/widget_module.h @@ -0,0 +1,75 @@ +/* + * 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 +#include + +#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 NewInstance() override; + v8::Persistent 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* 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_ diff --git a/tizen/extensions/renderer/xwalk_extension_client.cc b/tizen/extensions/renderer/xwalk_extension_client.cc new file mode 100644 index 0000000..383473f --- /dev/null +++ b/tizen/extensions/renderer/xwalk_extension_client.cc @@ -0,0 +1,131 @@ +// 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 +#include +#include +#include + +#include + +#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(data); + XWalkExtensionServer* server = XWalkExtensionServer::GetInstance(); + std::string instance_id = server->CreateInstance(extension_name); + return static_cast(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 context, + const std::string& extension_name, InstanceHandler* handler) { + void* ret = ecore_main_loop_thread_safe_call_sync( + CreateInstanceInMainloop, + static_cast(const_cast(extension_name.data()))); + std::string* sp = static_cast(ret); + std::string instance_id = *sp; + delete sp; + + handlers_[instance_id] = handler; + return instance_id; +} + +void XWalkExtensionClient::DestroyInstance( + v8::Handle 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 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 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 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 diff --git a/tizen/extensions/renderer/xwalk_extension_client.h b/tizen/extensions/renderer/xwalk_extension_client.h new file mode 100644 index 0000000..5b98ee9 --- /dev/null +++ b/tizen/extensions/renderer/xwalk_extension_client.h @@ -0,0 +1,71 @@ +// 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 + +#include +#include +#include +#include + +#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 context, + const std::string& extension_name, + InstanceHandler* handler); + void DestroyInstance(v8::Handle context, + const std::string& instance_id); + + void PostMessageToNative(v8::Handle context, + const std::string& instance_id, + const std::string& msg); + std::string SendSyncMessageToNative(v8::Handle context, + const std::string& instance_id, + const std::string& msg); + + std::string GetAPIScript(v8::Handle 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 entry_points; + }; + + typedef std::map ExtensionAPIMap; + + const ExtensionAPIMap& extension_apis() const { return extension_apis_; } + + private: + ExtensionAPIMap extension_apis_; + + typedef std::map HandlerMap; + HandlerMap handlers_; +}; + +} // namespace extensions + +#endif // XWALK_EXTENSIONS_RENDERER_XWALK_EXTENSION_CLIENT_H_ diff --git a/tizen/extensions/renderer/xwalk_extension_module.cc b/tizen/extensions/renderer/xwalk_extension_module.cc new file mode 100644 index 0000000..c222556 --- /dev/null +++ b/tizen/extensions/renderer/xwalk_extension_module.cc @@ -0,0 +1,514 @@ +// 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 +#include +#include + +#include + +#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 function_data = v8::Object::New(isolate); + function_data->Set(v8::String::NewFromUtf8(isolate, kXWalkExtensionModule), + v8::External::New(isolate, this)); + + v8::Handle 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 function_data = + v8::Local::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 +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(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 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 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 RunString(const std::string& code, + std::string* exception) { + v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::EscapableHandleScope handle_scope(isolate); + v8::Handle v8_code( + v8::String::NewFromUtf8(isolate, code.c_str())); + + v8::TryCatch try_catch; + try_catch.SetVerbose(true); + + v8::Handle script(v8::Script::Compile(v8_code)); + if (try_catch.HasCaught()) { + *exception = ExceptionToString(try_catch); + return handle_scope.Escape( + v8::Local(v8::Undefined(isolate))); + } + + v8::Local result = script->Run(); + if (try_catch.HasCaught()) { + *exception = ExceptionToString(try_catch); + return handle_scope.Escape( + v8::Local(v8::Undefined(isolate))); + } + + return handle_scope.Escape(result); +} + +} // namespace + +void XWalkExtensionModule::LoadExtensionCode( + v8::Handle context, v8::Handle 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 result = RunString(wrapped_api_code, &exception); + + if (!result->IsFunction()) { + LOGGER(ERROR) << "Couldn't load JS API code for " + << extension_name_ << " : " << exception; + return; + } + v8::Handle callable_api_code = + v8::Handle::Cast(result); + v8::Handle object_template = + v8::Local::New(context->GetIsolate(), + object_template_); + + const int argc = 2; + v8::Handle 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 context = module_system_->GetV8Context(); + v8::Context::Scope context_scope(context); + + v8::Handle args[] = { + v8::String::NewFromUtf8(isolate, msg.c_str()) }; + + v8::Handle message_listener = + v8::Local::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& info) { + v8::ReturnValue 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& info) { + v8::ReturnValue 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& info) { + v8::ReturnValue 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()); + + result.Set(true); +} + +// static +void XWalkExtensionModule::SendRuntimeMessageCallback( + const v8::FunctionCallbackInfo& info) { + v8::ReturnValue 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& info) { + v8::Isolate* isolate = info.GetIsolate(); + + v8::ReturnValue 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& info) { + v8::Isolate* isolate = info.GetIsolate(); + v8::HandleScope handle_scope(isolate); + + v8::ReturnValue 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 func = info[2].As(); + 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 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& info) { + v8::Isolate* isolate = info.GetIsolate(); + v8::HandleScope handle_scope(isolate); + + v8::Local data = info.Data().As(); + v8::Local 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(module.As()->Value()); +} + +} // namespace extensions diff --git a/tizen/extensions/renderer/xwalk_extension_module.h b/tizen/extensions/renderer/xwalk_extension_module.h new file mode 100644 index 0000000..1076f0f --- /dev/null +++ b/tizen/extensions/renderer/xwalk_extension_module.h @@ -0,0 +1,84 @@ +// 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 + +#include +#include + +#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, and + // let the module system set it to the appropriated object. + void LoadExtensionCode(v8::Handle context, + v8::Handle 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& info); + static void SendSyncMessageCallback( + const v8::FunctionCallbackInfo& info); + static void SetMessageListenerCallback( + const v8::FunctionCallbackInfo& info); + static void SendRuntimeMessageCallback( + const v8::FunctionCallbackInfo& info); + static void SendRuntimeSyncMessageCallback( + const v8::FunctionCallbackInfo& info); + static void SendRuntimeAsyncMessageCallback( + const v8::FunctionCallbackInfo& info); + + static XWalkExtensionModule* GetExtensionModule( + const v8::FunctionCallbackInfo& info); + + // Template for the 'extension' object exposed to the extension JS code. + v8::Persistent object_template_; + + // This JS object contains a pointer back to the ExtensionModule, it is + // set as data for the function callbacks. + v8::Persistent 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 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_ diff --git a/tizen/extensions/renderer/xwalk_extension_renderer_controller.cc b/tizen/extensions/renderer/xwalk_extension_renderer_controller.cc new file mode 100644 index 0000000..6c8dd11 --- /dev/null +++ b/tizen/extensions/renderer/xwalk_extension_renderer_controller.cc @@ -0,0 +1,132 @@ +// 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 +#include +#include +#include + +#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 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 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(module_system), context); + module_system->RegisterNativeModule( + "v8tools", + std::unique_ptr(new XWalkV8ToolsModule)); + module_system->RegisterNativeModule( + "WidgetModule", + std::unique_ptr(new WidgetModule)); + module_system->RegisterNativeModule( + "objecttools", + std::unique_ptr(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 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 diff --git a/tizen/extensions/renderer/xwalk_extension_renderer_controller.h b/tizen/extensions/renderer/xwalk_extension_renderer_controller.h new file mode 100644 index 0000000..95e3145 --- /dev/null +++ b/tizen/extensions/renderer/xwalk_extension_renderer_controller.h @@ -0,0 +1,45 @@ +// 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 +#include +#include + +#include +#include + +namespace extensions { + +class XWalkExtensionClient; + +class XWalkExtensionRendererController { + public: + static XWalkExtensionRendererController& GetInstance(); + static int plugin_session_count; + + void DidCreateScriptContext(v8::Handle context); + void WillReleaseScriptContext(v8::Handle 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 extensions_client_; +}; + +} // namespace extensions + +#endif // XWALK_EXTENSIONS_RENDERER_XWALK_EXTENSION_RENDERER_CONTROLLER_H_ diff --git a/tizen/extensions/renderer/xwalk_module_system.cc b/tizen/extensions/renderer/xwalk_module_system.cc new file mode 100644 index 0000000..2218188 --- /dev/null +++ b/tizen/extensions/renderer/xwalk_module_system.cc @@ -0,0 +1,524 @@ +// 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 + +#include + +#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& info) { + v8::ReturnValue result(info.GetReturnValue()); + + v8::Isolate* isolate = info.GetIsolate(); + v8::HandleScope handle_scope(isolate); + + v8::Handle data = info.Data().As(); + v8::Handle 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( + module_system_value.As()->Value()); + + if (info.Length() < 1) { + // TODO(cmarcelo): Throw appropriate exception or warning. + result.SetUndefined(); + return; + } + if (!module_system) { + result.SetUndefined(); + return; + } + v8::Handle 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 context) { + v8::Isolate* isolate = context->GetIsolate(); + v8_context_.Reset(isolate, context); + + v8::HandleScope handle_scope(isolate); + v8::Handle function_data = v8::Object::New(isolate); + function_data->Set(v8::String::NewFromUtf8(isolate, kXWalkModuleSystem), + v8::External::New(isolate, this)); + v8::Handle 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 context) { + return reinterpret_cast( + context->GetAlignedPointerFromEmbedderData( + kModuleSystemEmbedderDataIndex)); +} + +// static +void XWalkModuleSystem::SetModuleSystemInContext( + std::unique_ptr module_system, + v8::Handle context) { + context->SetAlignedPointerInEmbedderData(kModuleSystemEmbedderDataIndex, + module_system.release()); +} + +// static +void XWalkModuleSystem::ResetModuleSystemFromContext( + v8::Handle context) { + XWalkModuleSystem* module_system = GetModuleSystemFromContext(context); + if (module_system) { + delete module_system; + SetModuleSystemInContext(std::unique_ptr(), context); + } +} + +void XWalkModuleSystem::RegisterExtensionModule( + std::unique_ptr module, + const std::vector& 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::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 module) { + if (native_modules_.find(name) != native_modules_.end()) { + return; + } + native_modules_[name] = module.release(); +} + + +namespace { + +v8::Handle EnsureTargetObjectForTrampoline( + v8::Handle context, const std::vector& path, + std::string* error) { + v8::Handle object = context->Global(); + v8::Isolate* isolate = context->GetIsolate(); + + std::vector::const_iterator it = path.begin(); + for (; it != path.end(); ++it) { + v8::Handle part = + v8::String::NewFromUtf8(isolate, it->c_str()); + v8::Handle value = object->Get(part); + + if (value->IsUndefined()) { + v8::Handle 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(); + } + return object; +} + +v8::Handle GetObjectForPath(v8::Handle context, + const std::vector& path, + std::string* error) { + v8::Handle object = context->Global(); + v8::Isolate* isolate = context->GetIsolate(); + + std::vector::const_iterator it = path.begin(); + for (; it != path.end(); ++it) { + v8::Handle part = + v8::String::NewFromUtf8(isolate, it->c_str()); + v8::Handle value = object->Get(part); + + if (!value->IsObject()) { + *error = "the property '" + *it + "' in the path is undefined"; + return v8::Undefined(isolate); + } + + object = value.As(); + } + return object; +} + +} // namespace + +template +void SplitString(const STR& str, const typename STR::value_type s, + std::vector* 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 context, + const std::string& entry_point, + v8::Local user_data) { + std::vector path; + SplitString(entry_point, '.', &path); + std::string basename = path.back(); + path.pop_back(); + + std::string error; + v8::Handle 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 params = v8::Array::New(isolate); + v8::Local 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()->SetAccessor(context, + v8::String::NewFromUtf8(isolate, basename.c_str()), + TrampolineCallback, TrampolineSetterCallback, params); + return true; +} + +// static +bool XWalkModuleSystem::DeleteAccessorForEntryPoint( + v8::Handle context, + const std::string& entry_point) { + std::vector path; + SplitString(entry_point, '.', &path); + std::string basename = path.back(); + path.pop_back(); + + std::string error; + v8::Handle value = GetObjectForPath(context, path, &error); + if (value->IsUndefined()) { + LOGGER(ERROR) << "Error retrieving object for " << entry_point + << " : " << error; + return false; + } + + value.As()->Delete( + v8::String::NewFromUtf8(context->GetIsolate(), basename.c_str())); + return true; +} + +bool XWalkModuleSystem::InstallTrampoline(v8::Handle context, + ExtensionModuleEntry* entry) { + v8::Local 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::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 XWalkModuleSystem::RequireNative( + const std::string& name) { + NativeModuleMap::iterator it = native_modules_.find(name); + if (it == native_modules_.end()) + return v8::Handle(); + return it->second->NewInstance(); +} + +void XWalkModuleSystem::Initialize() { + SCOPE_PROFILE(); + v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::HandleScope handle_scope(isolate); + v8::Handle context = GetV8Context(); + v8::Handle require_native_template = + v8::Local::New(isolate, require_native_template_); + v8::Handle 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 XWalkModuleSystem::GetV8Context() { + return v8::Local::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 data) { + v8::HandleScope handle_scope(isolate); + v8::Local params = data.As(); + void* ptr = params->Get( + v8::Integer::New(isolate, 0)).As()->Value(); + + ExtensionModuleEntry* entry = static_cast(ptr); + + if (!entry) + return; + + v8::Handle 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 require_native_template = + v8::Local::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 XWalkModuleSystem::RefetchHolder( + v8::Isolate* isolate, + v8::Local data) { + v8::Local params = data.As(); + const std::string entry_point = *v8::String::Utf8Value( + params->Get(v8::Integer::New(isolate, 1)).As()); + + std::vector path; + SplitString(entry_point, '.', &path); + path.pop_back(); + + std::string error; + return GetObjectForPath(isolate->GetCurrentContext(), path, &error); +} + +// static +void XWalkModuleSystem::TrampolineCallback( + v8::Local property, + const v8::PropertyCallbackInfo& info) { + XWalkModuleSystem::LoadExtensionForTrampoline(info.GetIsolate(), info.Data()); + v8::Handle holder = RefetchHolder(info.GetIsolate(), info.Data()); + if (holder->IsUndefined()) + return; + + info.GetReturnValue().Set(holder.As()->Get(property)); +} + +// static +void XWalkModuleSystem::TrampolineSetterCallback( + v8::Local property, + v8::Local value, + const v8::PropertyCallbackInfo& info) { + XWalkModuleSystem::LoadExtensionForTrampoline(info.GetIsolate(), info.Data()); + v8::Handle holder = RefetchHolder(info.GetIsolate(), info.Data()); + if (holder->IsUndefined()) + return; + + holder.As()->Set(property, value); +} + +XWalkModuleSystem::ExtensionModuleEntry::ExtensionModuleEntry( + const std::string& name, + XWalkExtensionModule* module, + const std::vector& 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 context, + const std::string& extension_name) { + std::vector path; + SplitString(extension_name, '.', &path); + std::string basename = path.back(); + path.pop_back(); + + std::string error; + v8::Handle value = GetObjectForPath(context, path, &error); + if (value->IsUndefined()) { + LOGGER(ERROR) << "Error retrieving object for " << extension_name << " : " + << error; + return; + } + + v8::Handle v8_extension_name( + v8::String::NewFromUtf8(context->GetIsolate(), basename.c_str())); + value.As()->ForceSet( + v8_extension_name, value.As()->Get(v8_extension_name), + v8::ReadOnly); +} + +} // namespace extensions diff --git a/tizen/extensions/renderer/xwalk_module_system.h b/tizen/extensions/renderer/xwalk_module_system.h new file mode 100644 index 0000000..e8bf6bf --- /dev/null +++ b/tizen/extensions/renderer/xwalk_module_system.h @@ -0,0 +1,116 @@ +// 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 + +#include +#include +#include +#include + +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 NewInstance() = 0; + virtual ~XWalkNativeModule() {} +}; + + +class XWalkModuleSystem { + public: + explicit XWalkModuleSystem(v8::Handle context); + ~XWalkModuleSystem(); + + static XWalkModuleSystem* GetModuleSystemFromContext( + v8::Handle context); + static void SetModuleSystemInContext( + std::unique_ptr module_system, + v8::Handle context); + static void ResetModuleSystemFromContext(v8::Handle context); + + void RegisterExtensionModule(std::unique_ptr module, + const std::vector& entry_points); + void RegisterNativeModule(const std::string& name, + std::unique_ptr module); + v8::Handle RequireNative(const std::string& name); + + void Initialize(); + + v8::Handle GetV8Context(); + + private: + struct ExtensionModuleEntry { + ExtensionModuleEntry(const std::string& name, XWalkExtensionModule* module, + const std::vector& entry_points); + ~ExtensionModuleEntry(); + std::string name; + XWalkExtensionModule* module; + bool use_trampoline; + std::vector 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 context, + const std::string& entry_point, + v8::Local user_data); + + static bool DeleteAccessorForEntryPoint(v8::Handle context, + const std::string& entry_point); + + bool InstallTrampoline(v8::Handle context, + ExtensionModuleEntry* entry); + + static void TrampolineCallback( + v8::Local property, + const v8::PropertyCallbackInfo& info); + static void TrampolineSetterCallback( + v8::Local property, + v8::Local value, + const v8::PropertyCallbackInfo& info); + static void LoadExtensionForTrampoline( + v8::Isolate* isolate, + v8::Local data); + static v8::Handle RefetchHolder( + v8::Isolate* isolate, + v8::Local data); + + bool ContainsEntryPoint(const std::string& entry_point); + void MarkModulesWithTrampoline(); + void DeleteExtensionModules(); + + void EnsureExtensionNamespaceIsReadOnly(v8::Handle context, + const std::string& extension_name); + + typedef std::vector ExtensionModules; + ExtensionModules extension_modules_; + typedef std::map NativeModuleMap; + NativeModuleMap native_modules_; + + v8::Persistent require_native_template_; + v8::Persistent 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_; +}; + +} // namespace extensions + +#endif // XWALK_EXTENSIONS_RENDERER_XWALK_MODULE_SYSTEM_H_ diff --git a/tizen/extensions/renderer/xwalk_v8tools_module.cc b/tizen/extensions/renderer/xwalk_v8tools_module.cc new file mode 100644 index 0000000..4fcad37 --- /dev/null +++ b/tizen/extensions/renderer/xwalk_v8tools_module.cc @@ -0,0 +1,98 @@ +// 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 + +#include "common/logger.h" + +namespace extensions { + +namespace { + +void ForceSetPropertyCallback( + const v8::FunctionCallbackInfo& info) { + if (info.Length() != 3 || !info[0]->IsObject() || !info[1]->IsString()) { + return; + } + info[0].As()->ForceSet(info[1], info[2]); +} + +// ================ +// lifecycleTracker +// ================ +struct LifecycleTrackerWrapper { + v8::Global handle; + v8::Global destructor; +}; + +void LifecycleTrackerCleanup( + const v8::WeakCallbackInfo& data) { + LifecycleTrackerWrapper* wrapper = data.GetParameter(); + + if (!wrapper->destructor.IsEmpty()) { + v8::HandleScope handle_scope(data.GetIsolate()); + v8::Local context = v8::Context::New(data.GetIsolate()); + v8::Context::Scope scope(context); + + v8::Local 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& info) { + v8::Isolate* isolate = info.GetIsolate(); + v8::HandleScope handle_scope(info.GetIsolate()); + + v8::Local 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 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 XWalkV8ToolsModule::NewInstance() { + v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::EscapableHandleScope handle_scope(isolate); + v8::Handle object_template = + v8::Local::New(isolate, object_template_); + return handle_scope.Escape(object_template->NewInstance()); +} + +} // namespace extensions diff --git a/tizen/extensions/renderer/xwalk_v8tools_module.h b/tizen/extensions/renderer/xwalk_v8tools_module.h new file mode 100644 index 0000000..5b31dce --- /dev/null +++ b/tizen/extensions/renderer/xwalk_v8tools_module.h @@ -0,0 +1,28 @@ +// 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 NewInstance() override; + + v8::Persistent object_template_; +}; + +} // namespace extensions + +#endif // XWALK_EXTENSIONS_RENDERER_XWALK_V8TOOLS_MODULE_H_ diff --git a/tizen/renderer/injected_bundle.cc b/tizen/renderer/injected_bundle.cc new file mode 100644 index 0000000..a030975 --- /dev/null +++ b/tizen/renderer/injected_bundle.cc @@ -0,0 +1,190 @@ +/* + * 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 +#include +#include +#include +#include +#include + +#include +#include + +#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 resource_manager_; + std::unique_ptr 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 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(), 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 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(); +} diff --git a/tizen/renderer/injected_bundle.gyp b/tizen/renderer/injected_bundle.gyp new file mode 100644 index 0000000..f6ab6d7 --- /dev/null +++ b/tizen/renderer/injected_bundle.gyp @@ -0,0 +1,23 @@ +{ + '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' + ], +} diff --git a/vendor/brightray/browser/browser_context.cc b/vendor/brightray/browser/browser_context.cc index 46f7630..4ab07e4 100644 --- a/vendor/brightray/browser/browser_context.cc +++ b/vendor/brightray/browser/browser_context.cc @@ -28,6 +28,13 @@ #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 { @@ -100,6 +107,14 @@ BrowserContext::BrowserContext(const std::string& partition, bool in_memory) 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() { diff --git a/wrt.gyp b/wrt.gyp index a24edb4..6ea31d4 100644 --- a/wrt.gyp +++ b/wrt.gyp @@ -13,6 +13,8 @@ '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', -- 2.7.4 From e2f189e3b5d49c98f44ff11b11ec58201712423a Mon Sep 17 00:00:00 2001 From: "k2.nagaraju" Date: Thu, 5 Apr 2018 20:14:03 +0530 Subject: [PATCH 02/16] IPC bring up and removing ewk dependency to support webdevice API. - Modified the exising xwalk extension server and client to work in multiprocess - related patch https://review.tizen.org/gerrit/#/c/173694/ Change-Id: I5675b9fc3f2aad7d477b8a7dd60a3639e3d9b757 Signed-off-by: k2.nagaraju --- atom/app/atom_main_delegate.cc | 7 +- atom/app/runtime.cc | 2 +- atom/browser/api/atom_api_pwrt.cc | 2 +- atom/browser/api/atom_api_web_contents.cc | 38 ++++- atom/browser/api/atom_api_web_contents.h | 6 +- atom/browser/atom_browser_client.cc | 7 +- atom/common/api/api_messages.h | 26 ++++ atom/common/options_switches.cc | 7 + atom/common/options_switches.h | 5 + atom/renderer/atom_renderer_client.cc | 50 +++++++ atom/renderer/atom_renderer_client.h | 5 +- packaging/electron-efl.spec | 4 +- tizen/build/common.gypi | 2 +- tizen/common/common.gyp | 3 + tizen/common/wrt_message_data.cc | 38 +++++ tizen/common/wrt_message_data.h | 26 ++++ tizen/extensions/common/constants.cc | 2 +- tizen/extensions/common/constants.h | 1 + .../extensions/common/xwalk_extension_instance.cc | 1 + tizen/extensions/common/xwalk_extension_server.cc | 67 ++++----- tizen/extensions/common/xwalk_extension_server.h | 21 +-- tizen/extensions/extensions.gyp | 9 ++ tizen/extensions/renderer/runtime_ipc_client.cc | 78 +++++----- tizen/extensions/renderer/runtime_ipc_client.h | 5 +- .../extensions/renderer/xwalk_extension_client.cc | 53 +++++-- tizen/extensions/renderer/xwalk_extension_client.h | 2 +- .../xwalk_extension_renderer_controller.cc | 12 +- .../renderer/xwalk_extension_renderer_controller.h | 5 +- tizen/renderer/injected_bundle.cc | 5 +- tizen/wrt/chromium_wrt.gyp | 55 +++++++ tizen/wrt/dynamicplugin.cc | 89 +++++++++++ tizen/wrt/dynamicplugin.h | 46 ++++++ tizen/wrt/v8widget.cc | 92 ++++++++++++ tizen/wrt/v8widget.h | 41 ++++++ tizen/wrt/wrt_dynamicplugin.cc | 164 +++++++++++++++++++++ tizen/wrt/wrt_dynamicplugin.h | 71 +++++++++ tizen/wrt/wrt_file_protocol_handler.cc | 110 ++++++++++++++ tizen/wrt/wrt_file_protocol_handler.h | 46 ++++++ tizen/wrt/wrt_widget_host.cc | 164 +++++++++++++++++++++ tizen/wrt/wrt_widget_host.h | 89 +++++++++++ tizen/wrt/wrtwidget.cc | 97 ++++++++++++ tizen/wrt/wrtwidget.h | 45 ++++++ vendor/brightray/browser/browser_context.cc | 41 +++++- vendor/brightray/browser/browser_context.h | 4 + .../src/base/trace_event/trace_event.h | 2 +- wrt.gyp | 2 + 46 files changed, 1508 insertions(+), 139 deletions(-) create mode 100644 tizen/common/wrt_message_data.cc create mode 100644 tizen/common/wrt_message_data.h create mode 100644 tizen/wrt/chromium_wrt.gyp create mode 100644 tizen/wrt/dynamicplugin.cc create mode 100644 tizen/wrt/dynamicplugin.h create mode 100644 tizen/wrt/v8widget.cc create mode 100644 tizen/wrt/v8widget.h create mode 100644 tizen/wrt/wrt_dynamicplugin.cc create mode 100644 tizen/wrt/wrt_dynamicplugin.h create mode 100644 tizen/wrt/wrt_file_protocol_handler.cc create mode 100644 tizen/wrt/wrt_file_protocol_handler.h create mode 100644 tizen/wrt/wrt_widget_host.cc create mode 100644 tizen/wrt/wrt_widget_host.h create mode 100644 tizen/wrt/wrtwidget.cc create mode 100644 tizen/wrt/wrtwidget.h diff --git a/atom/app/atom_main_delegate.cc b/atom/app/atom_main_delegate.cc index f840690..32e6ecf 100644 --- a/atom/app/atom_main_delegate.cc +++ b/atom/app/atom_main_delegate.cc @@ -148,9 +148,10 @@ void AtomMainDelegate::PreSandboxStartup() { #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 cmdAgrs = atom::AtomCommandLine::argv(); - std::string app_id = cmdAgrs[1]; + command_line->AppendSwitchASCII( + "injected-bundle-path","/usr/lib/libxwalk_injected_bundle.so"); + std::string app_id = common::CommandLine::ForCurrentProcess()-> + GetAppIdFromCommandLine("/usr/bin/wrt"); command_line->AppendSwitchASCII("widget-id",app_id); #endif diff --git a/atom/app/runtime.cc b/atom/app/runtime.cc index a14e842..ad61e2d 100644 --- a/atom/app/runtime.cc +++ b/atom/app/runtime.cc @@ -42,4 +42,4 @@ std::unique_ptr Runtime::MakeRuntime(content::ContentMainParams *params //} } -} // namespace runtime \ No newline at end of file +} // namespace runtime diff --git a/atom/browser/api/atom_api_pwrt.cc b/atom/browser/api/atom_api_pwrt.cc index e89b1dd..b63ef51 100644 --- a/atom/browser/api/atom_api_pwrt.cc +++ b/atom/browser/api/atom_api_pwrt.cc @@ -54,7 +54,7 @@ bool PWRT::isTizenWebApp() { void PWRT::Log(const std::string& message) { std::string output = "[JS LOG] " + message; - dlog_print(DLOG_INFO, "WRT", output.c_str()); + dlog_print(DLOG_ERROR, "WRT", output.c_str()); } // static diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 8c473c5..8474a5b 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -4,6 +4,7 @@ #include "atom/browser/api/atom_api_web_contents.h" +#include #include #include @@ -77,6 +78,10 @@ #include "third_party/WebKit/public/web/WebFindOptions.h" #include "ui/display/screen.h" +#if defined(USE_EFL) +#include "tizen/extensions/common/xwalk_extension_server.h" +#endif + #if !defined(OS_MACOSX) && !defined(USE_EFL) #include "ui/aura/window.h" #endif @@ -434,7 +439,8 @@ bool WebContents::DidAddMessageToConsole(content::WebContents* source, int32_t line_no, const base::string16& source_id) { if (type_ == BROWSER_WINDOW || type_ == OFF_SCREEN) { - return false; + LOG(ERROR) << "Console Message : " << message << ", source:" << source_id << " (" << line_no << ")"; + return true; } else { Emit("console-message", level, message, line_no, source_id); return true; @@ -897,6 +903,33 @@ void WebContents::DevToolsClosed() { Emit("devtools-closed"); } +void WebContents::OnWrtPluginMessage(const Wrt_Message_Data& data) { + Wrt_Message_Data tmp = data; + HandleWrtPluginMessage(&tmp); +} + +void WebContents::OnWrtPluginSyncMessage(const Wrt_Message_Data& data, + IPC::Message* reply) { + Wrt_Message_Data tmp = data; + HandleWrtPluginMessage(&tmp); + EwkHostMsg_WrtSyncMessage::WriteReplyParams(reply, tmp.value); + Send(reply); +} + +void WebContents::HandleWrtPluginMessage(Wrt_Message_Data* msg) { + Eina_Stringshare* msg_type = msg->GetType(); + +#define TYPE_BEGIN(x) (!strncmp(msg_type, x, strlen(x))) +#define TYPE_IS(x) (!strcmp(msg_type, x)) + + if (TYPE_BEGIN("xwalk://")) { + auto extension_server = extensions::XWalkExtensionServer::GetInstance(); + extension_server->HandleIPCMessage(msg); + } else { + // implement in future + } +} + bool WebContents::OnMessageReceived(const IPC::Message& message) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(WebContents, message) @@ -907,7 +940,8 @@ bool WebContents::OnMessageReceived(const IPC::Message& message) { OnSetTemporaryZoomLevel) IPC_MESSAGE_HANDLER_DELAY_REPLY(AtomViewHostMsg_GetZoomLevel, OnGetZoomLevel) - + IPC_MESSAGE_HANDLER(EwkHostMsg_WrtMessage, OnWrtPluginMessage) + IPC_MESSAGE_HANDLER_DELAY_REPLY(EwkHostMsg_WrtSyncMessage, OnWrtPluginSyncMessage) // FIXME: Disable OnCursorChange due to stach_chk_fail crash. // IPC_MESSAGE_HANDLER_CODE(ViewHostMsg_SetCursor, OnCursorChange, // handled = false) diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 1301ed1..4407b3c 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -18,6 +18,7 @@ #include "content/public/browser/web_contents_observer.h" #include "content/public/common/favicon_url.h" #include "native_mate/handle.h" +#include "tizen/common/wrt_message_data.h" #include "ui/gfx/image/image.h" namespace blink { @@ -217,7 +218,10 @@ class WebContents : public mate::TrackableObject, v8::Local Debugger(v8::Isolate* isolate); WebContentsZoomController* GetZoomController() { return zoom_controller_; } - + void OnWrtPluginMessage(const Wrt_Message_Data& data); + void OnWrtPluginSyncMessage(const Wrt_Message_Data& data, + IPC::Message* reply); + void HandleWrtPluginMessage(Wrt_Message_Data* msg); protected: WebContents(v8::Isolate* isolate, content::WebContents* web_contents, diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index 77c3212..ebbd54a 100644 --- a/atom/browser/atom_browser_client.cc +++ b/atom/browser/atom_browser_client.cc @@ -215,7 +215,12 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches( static const char* const kCommonSwitchNames[] = { switches::kStandardSchemes, switches::kEnableSandbox, - switches::kSecureSchemes + switches::kSecureSchemes, + switches::kInjectedBundlePath, + switches::kTizenAppId, + switches::kWidgetScale, + switches::kWidgetTheme, + switches::kWidgetEncodedBundle }; command_line->CopySwitchesFrom( *base::CommandLine::ForCurrentProcess(), diff --git a/atom/common/api/api_messages.h b/atom/common/api/api_messages.h index ef945d9..cffc9df 100644 --- a/atom/common/api/api_messages.h +++ b/atom/common/api/api_messages.h @@ -9,6 +9,7 @@ #include "base/values.h" #include "content/public/common/common_param_traits.h" #include "ipc/ipc_message_macros.h" +#include "tizen/common/wrt_message_data.h" #include "ui/gfx/ipc/gfx_param_traits.h" // The message starter should be declared in ipc/ipc_message_start.h. Since @@ -21,6 +22,13 @@ IPC_STRUCT_TRAITS_BEGIN(atom::DraggableRegion) IPC_STRUCT_TRAITS_MEMBER(bounds) IPC_STRUCT_TRAITS_END() +IPC_STRUCT_TRAITS_BEGIN(Wrt_Message_Data) + IPC_STRUCT_TRAITS_MEMBER(type) + IPC_STRUCT_TRAITS_MEMBER(value) + IPC_STRUCT_TRAITS_MEMBER(id) + IPC_STRUCT_TRAITS_MEMBER(reference_id) +IPC_STRUCT_TRAITS_END() + IPC_MESSAGE_ROUTED2(AtomViewHostMsg_Message, base::string16 /* channel */, base::ListValue /* arguments */) @@ -49,3 +57,21 @@ IPC_SYNC_MESSAGE_ROUTED1_1(AtomViewHostMsg_SetTemporaryZoomLevel, // Sent by renderer to get the zoom level. IPC_SYNC_MESSAGE_ROUTED0_1(AtomViewHostMsg_GetZoomLevel, double /* result */) + +IPC_MESSAGE_ROUTED1(EwkHostMsg_WrtMessage, + Wrt_Message_Data /* data */) + +IPC_MESSAGE_CONTROL1(WrtMsg_SendWrtMessage, + Wrt_Message_Data /* data */) + +IPC_MESSAGE_CONTROL2(WrtMsg_ParseUrl, + int, // result: request_id + GURL) // result: url + +IPC_MESSAGE_CONTROL2(WrtMsg_ParseUrlResponse, + int, // result: request_id + GURL) // result: url + +IPC_SYNC_MESSAGE_ROUTED1_1(EwkHostMsg_WrtSyncMessage, + Wrt_Message_Data /* data */, + std::string /*result*/) diff --git a/atom/common/options_switches.cc b/atom/common/options_switches.cc index 2f1c036..a2b394e 100644 --- a/atom/common/options_switches.cc +++ b/atom/common/options_switches.cc @@ -182,6 +182,13 @@ const char kWidevineCdmPath[] = "widevine-cdm-path"; // Widevine CDM version. const char kWidevineCdmVersion[] = "widevine-cdm-version"; +const char kInjectedBundlePath[] = "injected-bundle-path"; +// Widget Info +const char kTizenAppId[] = "widget-id"; +const char kWidgetScale[] = "widget-scale"; +const char kWidgetTheme[] = "widget-theme"; +const char kWidgetEncodedBundle[] = "widget-encoded-bundle"; + } // namespace switches } // namespace atom diff --git a/atom/common/options_switches.h b/atom/common/options_switches.h index 69e7af0..6aecbf8 100644 --- a/atom/common/options_switches.h +++ b/atom/common/options_switches.h @@ -97,6 +97,11 @@ extern const char kNodeIntegrationInWorker[]; extern const char kWidevineCdmPath[]; extern const char kWidevineCdmVersion[]; +extern const char kInjectedBundlePath[]; +extern const char kTizenAppId[]; +extern const char kWidgetScale[]; +extern const char kWidgetTheme[]; +extern const char kWidgetEncodedBundle[]; } // namespace switches } // namespace atom diff --git a/atom/renderer/atom_renderer_client.cc b/atom/renderer/atom_renderer_client.cc index 1a9343e..77b5eb0 100644 --- a/atom/renderer/atom_renderer_client.cc +++ b/atom/renderer/atom_renderer_client.cc @@ -9,6 +9,11 @@ #if defined(USE_EFL) #include "atom/common/atom_command_line.h" +#include "base/strings/string_number_conversions.h" +#include "content/common/wrt/wrt_url_parse.h" +#include "content/public/renderer/render_thread.h" +#include "content/public/renderer/render_view.h" +#include "third_party/WebKit/public/web/WebView.h" #endif #include "atom_natives.h" // NOLINT: This file is generated with js2c @@ -53,6 +58,22 @@ const char** StringVectorToArgArray( } // namespace +class WrtUrlParseImpl : public content::WrtUrlParseBase { + public: + WrtUrlParseImpl(WrtWidget* wrt_widget) : wrt_widget_(wrt_widget) {} + GURL parseUrl(const GURL& old_url) const override { + if (!wrt_widget_->IsWidgetInfoSet()) + return old_url; + GURL new_url; + bool is_decrypted_file = false; + wrt_widget_->ParseUrl(old_url, new_url, is_decrypted_file); + return new_url; + } + + private: + WrtWidget* wrt_widget_; +}; + AtomRendererClient::AtomRendererClient() : node_integration_initialized_(false), node_bindings_(NodeBindings::Create(NodeBindings::RENDERER)), @@ -74,6 +95,24 @@ void AtomRendererClient::RenderThreadStarted() { base::CommandLine::StringVector argv = command_line->argv(); const char** c_argv = StringVectorToArgArray(argv); atom::AtomCommandLine::Init(argv.size(), c_argv); + std::string tizen_app_id = command_line->GetSwitchValueASCII( + "widget-id"); + + WrtWidget* wrt_widget = new WrtWidget; + if (wrt_widget == nullptr) { + return; + } + widget_.reset(wrt_widget); + content::RenderThread* thread = content::RenderThread::Get(); + thread->AddObserver(wrt_widget->GetObserver()); + wrt_url_parser_.reset(new WrtUrlParseImpl(wrt_widget)); + std::string theme = command_line->GetSwitchValueASCII("widget-theme"); + std::string encoded_bundle = command_line->GetSwitchValueASCII("widget-encoded-bundle"); + std::string scale = command_line->GetSwitchValueASCII("widget-scale"); + double scale_factor = 0; + base::StringToDouble(scale, &scale_factor); + wrt_widget->SetWidgetInfo(tizen_app_id, scale_factor, theme, + encoded_bundle); #endif OverrideNodeArrayBuffer(); RendererClientBase::RenderThreadStarted(); @@ -140,6 +179,13 @@ void AtomRendererClient::DidCreateScriptContext( // Give the node loop a run to make sure everything is ready. node_bindings_->RunMessageLoop(); } +#if defined(USE_EFL) + if (widget_) { + const content::RenderView* render_view = render_frame->GetRenderView(); + widget_->StartSession(context, render_view->GetRoutingID(), + render_frame->GetWebFrame()->document().baseURL().string().utf8().c_str()); + } +#endif } void AtomRendererClient::WillReleaseScriptContext( @@ -160,6 +206,10 @@ void AtomRendererClient::WillReleaseScriptContext( // Destroy the node environment. node::FreeEnvironment(env); atom_bindings_->EnvironmentDestroyed(env); +#if defined(USE_EFL) + if (widget_) + widget_->StopSession(context); +#endif } bool AtomRendererClient::ShouldFork(blink::WebLocalFrame* frame, diff --git a/atom/renderer/atom_renderer_client.h b/atom/renderer/atom_renderer_client.h index c9ffb29..0e623b5 100644 --- a/atom/renderer/atom_renderer_client.h +++ b/atom/renderer/atom_renderer_client.h @@ -9,11 +9,13 @@ #include #include "atom/renderer/renderer_client_base.h" +#include "tizen/wrt/wrtwidget.h" namespace atom { class AtomBindings; class NodeBindings; +class WrtUrlParseImpl; class AtomRendererClient : public RendererClientBase { public: @@ -41,7 +43,8 @@ class AtomRendererClient : public RendererClientBase { MANUAL_ENABLE_IFRAME, DISABLE, }; - + std::unique_ptr widget_; + std::unique_ptr wrt_url_parser_; // content::ContentRendererClient: void RenderThreadStarted() override; void RenderFrameCreated(content::RenderFrame*) override; diff --git a/packaging/electron-efl.spec b/packaging/electron-efl.spec index 7f48f8b..bafe82b 100755 --- a/packaging/electron-efl.spec +++ b/packaging/electron-efl.spec @@ -140,7 +140,8 @@ mkdir -p %{buildroot}%{extension_path} 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} - +# wrt chromium shared +install -p -m 644 %{_out}/lib/libchromium_wrt_shared.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'. @@ -173,3 +174,4 @@ rm -fr %{buildroot} %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 +%attr(644,root,root) %{_libdir}/libchromium_wrt_shared.so diff --git a/tizen/build/common.gypi b/tizen/build/common.gypi index 5f90ec5..8b70ac2 100644 --- a/tizen/build/common.gypi +++ b/tizen/build/common.gypi @@ -50,4 +50,4 @@ '-L./lib', ], }, -} \ No newline at end of file +} diff --git a/tizen/common/common.gyp b/tizen/common/common.gyp index dfc2494..be5a8ec 100644 --- a/tizen/common/common.gyp +++ b/tizen/common/common.gyp @@ -34,6 +34,8 @@ 'resource_manager.cc', 'platform_info.h', 'platform_info.cc', + 'wrt_message_data.h', + 'wrt_message_data.cc', ], 'cflags': [ '-fvisibility=default', @@ -49,6 +51,7 @@ 'capi-system-info', 'cynara-client', 'dlog', + 'elementary', 'uuid', 'libwebappenc', 'manifest-parser', diff --git a/tizen/common/wrt_message_data.cc b/tizen/common/wrt_message_data.cc new file mode 100644 index 0000000..7b60902 --- /dev/null +++ b/tizen/common/wrt_message_data.cc @@ -0,0 +1,38 @@ +#include "wrt_message_data.h" + +Wrt_Message_Data::Wrt_Message_Data() {} + +Wrt_Message_Data::~Wrt_Message_Data() {} + +Eina_Stringshare* Wrt_Message_Data::GetType() const { + return eina_stringshare_add(type.c_str()); +} + +void Wrt_Message_Data::SetType(const char* val) { + type = val; +} + +Eina_Stringshare* Wrt_Message_Data::GetValue() const { + return eina_stringshare_add(value.c_str()); +} + +void Wrt_Message_Data::SetValue(const char* val) { + value = val; +} + +Eina_Stringshare* Wrt_Message_Data::GetId() const { + return eina_stringshare_add(id.c_str()); +} + +void Wrt_Message_Data::SetId(const char* val) { + id = val; +} + +Eina_Stringshare* Wrt_Message_Data::GetReferenceId() const { + return eina_stringshare_add(reference_id.c_str()); +} + +void Wrt_Message_Data::SetReferenceId(const char* val) { + reference_id = val; +} + diff --git a/tizen/common/wrt_message_data.h b/tizen/common/wrt_message_data.h new file mode 100644 index 0000000..81e7213 --- /dev/null +++ b/tizen/common/wrt_message_data.h @@ -0,0 +1,26 @@ +#ifndef WRT_MESSAGE_DATA_H +#define WRT_MESSAGE_DATA_H + +#include +#include + +struct Wrt_Message_Data { + std::string type; + std::string value; + std::string id; + std::string reference_id; + + Wrt_Message_Data(); + ~Wrt_Message_Data(); + const Eina_Stringshare* GetType() const; + void SetType(const char* val); + const Eina_Stringshare* GetValue() const; + void SetValue(const char* val); + const Eina_Stringshare* GetId() const; + void SetId(const char* val); + const Eina_Stringshare* GetReferenceId() const; + void SetReferenceId(const char* val); +}; + +#endif // WRT_MESSAGE_DATA_H + diff --git a/tizen/extensions/common/constants.cc b/tizen/extensions/common/constants.cc index cfc9fa4..0010130 100644 --- a/tizen/extensions/common/constants.cc +++ b/tizen/extensions/common/constants.cc @@ -25,6 +25,6 @@ const char kMethodSendSyncMessage[] = "xwalk://SendSyncMessage"; const char kMethodPostMessage[] = "xwalk://PostMessage"; const char kMethodGetAPIScript[] = "xwalk://GetAPIScript"; const char kMethodPostMessageToJS[] = "xwalk://PostMessageToJS"; - +const char kMethodLoadUserExtensions[] = "xwalk://LoadUserExtensions"; } // namespace extensions diff --git a/tizen/extensions/common/constants.h b/tizen/extensions/common/constants.h index 588f09b..2da2e20 100644 --- a/tizen/extensions/common/constants.h +++ b/tizen/extensions/common/constants.h @@ -26,6 +26,7 @@ extern const char kMethodSendSyncMessage[]; extern const char kMethodPostMessage[]; extern const char kMethodGetAPIScript[]; extern const char kMethodPostMessageToJS[]; +extern const char kMethodLoadUserExtensions[]; } // namespace extensions diff --git a/tizen/extensions/common/xwalk_extension_instance.cc b/tizen/extensions/common/xwalk_extension_instance.cc index c86bb59..7c6ffba 100644 --- a/tizen/extensions/common/xwalk_extension_instance.cc +++ b/tizen/extensions/common/xwalk_extension_instance.cc @@ -5,6 +5,7 @@ #include "extensions/common/xwalk_extension_instance.h" +#include "common/logger.h" #include "extensions/common/xwalk_extension_adapter.h" #include "extensions/public/XW_Extension_SyncMessage.h" diff --git a/tizen/extensions/common/xwalk_extension_server.cc b/tizen/extensions/common/xwalk_extension_server.cc index fc50396..3cf0acd 100644 --- a/tizen/extensions/common/xwalk_extension_server.cc +++ b/tizen/extensions/common/xwalk_extension_server.cc @@ -8,11 +8,14 @@ #include +#include "atom/common/api/api_messages.h" #include "common/logger.h" #include "common/profiler.h" #include "common/string_utils.h" +#include "content/public/browser/render_process_host.h" #include "extensions/common/constants.h" #include "extensions/common/xwalk_extension_manager.h" +#include "wrt/wrt_widget_host.h" namespace extensions { @@ -29,10 +32,6 @@ XWalkExtensionServer::XWalkExtensionServer() { XWalkExtensionServer::~XWalkExtensionServer() { } -void XWalkExtensionServer::SetupIPC(Ewk_Context* ewk_context) { - ewk_context_ = ewk_context; -} - void XWalkExtensionServer::Preload() { manager_.PreloadExtensions(); } @@ -76,7 +75,6 @@ std::string XWalkExtensionServer::GetAPIScript( 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()) { @@ -85,14 +83,12 @@ std::string XWalkExtensionServer::CreateInstance( 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); + Wrt_Message_Data* ans = new Wrt_Message_Data(); + ans->SetType(kMethodPostMessageToJS); + ans->SetId(instance_id.c_str()); + ans->SetValue(msg.c_str()); + WrtWidgetHost::Get()->SendWrtMessage(*ans); + delete ans; }); instances_[instance_id] = instance; @@ -103,21 +99,16 @@ std::string XWalkExtensionServer::CreateInstance( } else { LOGGER(ERROR) << "No such extension '" << extension_name << "'"; } + LOGGER(ERROR) << instance_id; return instance_id; } -void XWalkExtensionServer::HandleIPCMessage(Ewk_IPC_Wrt_Message_Data* data) { +void XWalkExtensionServer::HandleIPCMessage(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); + Eina_Stringshare* msg_type = data->GetType(); #define TYPE_IS(x) (!strcmp(msg_type, x)) if (TYPE_IS(kMethodGetExtensions)) { @@ -138,27 +129,27 @@ void XWalkExtensionServer::HandleIPCMessage(Ewk_IPC_Wrt_Message_Data* data) { #undef TYPE_IS } -void XWalkExtensionServer::HandleGetExtensions(Ewk_IPC_Wrt_Message_Data* data) { +void XWalkExtensionServer::HandleGetExtensions(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()); + data->SetValue(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); + Wrt_Message_Data* data) { + Eina_Stringshare* extension_name = data->GetValue(); std::string instance_id = CreateInstance(extension_name); - ewk_ipc_wrt_message_data_value_set(data, instance_id.c_str()); + data->SetValue(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); + Wrt_Message_Data* data) { + Eina_Stringshare* instance_id = data->GetId(); auto it = instances_.find(instance_id); if (it != instances_.end()) { @@ -173,12 +164,12 @@ void XWalkExtensionServer::HandleDestroyInstance( } void XWalkExtensionServer::HandlePostMessageToNative( - Ewk_IPC_Wrt_Message_Data* data) { - Eina_Stringshare* instance_id = ewk_ipc_wrt_message_data_id_get(data); + Wrt_Message_Data* data) { + Eina_Stringshare* instance_id = data->GetId(); auto it = instances_.find(instance_id); if (it != instances_.end()) { - Eina_Stringshare* msg = ewk_ipc_wrt_message_data_value_get(data); + Eina_Stringshare* msg = data->GetValue(); XWalkExtensionInstance* instance = it->second; instance->HandleMessage(msg); eina_stringshare_del(msg); @@ -190,19 +181,19 @@ void XWalkExtensionServer::HandlePostMessageToNative( } void XWalkExtensionServer::HandleSendSyncMessageToNative( - Ewk_IPC_Wrt_Message_Data* data) { - Eina_Stringshare* instance_id = ewk_ipc_wrt_message_data_id_get(data); + Wrt_Message_Data* data) { + Eina_Stringshare* instance_id = data->GetId(); auto it = instances_.find(instance_id); if (it != instances_.end()) { - Eina_Stringshare* msg = ewk_ipc_wrt_message_data_value_get(data); + Eina_Stringshare* msg = data->GetValue(); 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()); + data->SetValue(reply.c_str()); eina_stringshare_del(msg); } else { LOGGER(ERROR) << "No such instance '" << instance_id << "'"; @@ -212,12 +203,12 @@ void XWalkExtensionServer::HandleSendSyncMessageToNative( } void XWalkExtensionServer::HandleGetAPIScript( - Ewk_IPC_Wrt_Message_Data* data) { - Eina_Stringshare* extension_name = ewk_ipc_wrt_message_data_value_get(data); + Wrt_Message_Data* data) { + Eina_Stringshare* extension_name = data->GetValue(); std::string api = GetAPIScript(extension_name); - ewk_ipc_wrt_message_data_value_set(data, api.c_str()); + data->SetValue(api.c_str()); eina_stringshare_del(extension_name); } diff --git a/tizen/extensions/common/xwalk_extension_server.h b/tizen/extensions/common/xwalk_extension_server.h index 3cd67bf..7a45752 100644 --- a/tizen/extensions/common/xwalk_extension_server.h +++ b/tizen/extensions/common/xwalk_extension_server.h @@ -5,13 +5,11 @@ #ifndef XWALK_EXTENSIONS_XWALK_EXTENSION_SERVER_H_ #define XWALK_EXTENSIONS_XWALK_EXTENSION_SERVER_H_ -#include -#include #include #include #include - +#include "common/wrt_message_data.h" #include "extensions/common/xwalk_extension_manager.h" #include "extensions/common/xwalk_extension_instance.h" @@ -21,13 +19,12 @@ 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 HandleIPCMessage(Wrt_Message_Data* data); void Shutdown(); void LoadUserExtensions(const std::string app_path); @@ -36,17 +33,15 @@ class XWalkExtensionServer { 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); + void HandleGetExtensions(Wrt_Message_Data* data); + void HandleCreateInstance(Wrt_Message_Data* data); + void HandleDestroyInstance(Wrt_Message_Data* data); + void HandlePostMessageToNative(Wrt_Message_Data* data); + void HandleSendSyncMessageToNative(Wrt_Message_Data* data); + void HandleGetAPIScript(Wrt_Message_Data* data); typedef std::map InstanceMap; - Ewk_Context* ewk_context_; - XWalkExtensionManager manager_; InstanceMap instances_; diff --git a/tizen/extensions/extensions.gyp b/tizen/extensions/extensions.gyp index 165271b..163361d 100644 --- a/tizen/extensions/extensions.gyp +++ b/tizen/extensions/extensions.gyp @@ -45,6 +45,15 @@ 'elementary', ], }, + 'include_dirs': [ + '.', + '../..', + '<(libchromiumcontent_src_dir)', + '<(SHARED_INTERMEDIATE_DIR)', + '<(libchromiumcontent_src_dir)/gen', + '<(libchromiumcontent_src_dir)/third_party/skia/include/config', + '<(libchromiumcontent_src_dir)/third_party/skia/include/core', + ], 'direct_dependent_settings': { # 'libraries': [ # '-lxwalk_extension_shared', diff --git a/tizen/extensions/renderer/runtime_ipc_client.cc b/tizen/extensions/renderer/runtime_ipc_client.cc index 6b96828..f64676b 100644 --- a/tizen/extensions/renderer/runtime_ipc_client.cc +++ b/tizen/extensions/renderer/runtime_ipc_client.cc @@ -13,13 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include #include "extensions/renderer/runtime_ipc_client.h" #include "extensions/renderer/xwalk_extension_renderer_controller.h" +#include "atom/common/api/api_messages.h" #include "common/logger.h" #include "common/profiler.h" #include "common/string_utils.h" +#include "content/public/renderer/render_view.h" namespace extensions { @@ -112,17 +115,16 @@ void RuntimeIPCClient::SendMessage(v8::Handle context, 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); + Wrt_Message_Data* msg = new Wrt_Message_Data(); + msg->SetType(type.c_str()); + msg->SetId(id.c_str()); + msg->SetValue(value.c_str()); + msg->SetReferenceId(ref_id.c_str()); + content::RenderView* render_view = + content::RenderView::FromRoutingID(routing_id); + render_view->Send( + new EwkHostMsg_WrtMessage(render_view->GetRoutingID(), *msg)); + delete msg; } std::string RuntimeIPCClient::SendSyncMessage(v8::Handle context, @@ -149,23 +151,20 @@ std::string RuntimeIPCClient::SendSyncMessage(v8::Handle context, 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); + Wrt_Message_Data* msg = new Wrt_Message_Data(); + msg->SetType(type.c_str()); + msg->SetId(id.c_str()); + msg->SetValue(value.c_str()); + msg->SetReferenceId(ref_id.c_str()); + content::RenderView* render_view = + content::RenderView::FromRoutingID(routing_id); + render_view->Send( + new EwkHostMsg_WrtSyncMessage(render_view->GetRoutingID(), *msg, &msg->value)); + Eina_Stringshare* msg_value = msg->GetValue(); std::string result(msg_value); eina_stringshare_del(msg_value); - ewk_ipc_wrt_message_data_del(msg); + delete msg; return result; } @@ -182,30 +181,27 @@ void RuntimeIPCClient::SendAsyncMessage(v8::Handle context, 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; - } - + Wrt_Message_Data* msg = new Wrt_Message_Data(); + msg->SetType(type.c_str()); + msg->SetId(msg_id.c_str()); + msg->SetValue(value.c_str()); + content::RenderView* render_view = + content::RenderView::FromRoutingID(routing_id); + render_view->Send( + new EwkHostMsg_WrtMessage(render_view->GetRoutingID(), *msg)); callbacks_[msg_id] = callback; - ewk_ipc_wrt_message_data_del(msg); + delete msg; } void RuntimeIPCClient::HandleMessageFromRuntime( - const Ewk_IPC_Wrt_Message_Data* msg) { + const 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); + Eina_Stringshare* msg_refid = msg->GetReferenceId(); if (msg_refid == NULL || !strcmp(msg_refid, "")) { if (msg_refid) eina_stringshare_del(msg_refid); @@ -220,8 +216,8 @@ void RuntimeIPCClient::HandleMessageFromRuntime( 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); + Eina_Stringshare* msg_type = msg->GetType(); + Eina_Stringshare* msg_value = msg->GetValue(); ReplyCallback func = it->second; if (func) { diff --git a/tizen/extensions/renderer/runtime_ipc_client.h b/tizen/extensions/renderer/runtime_ipc_client.h index 7f94fb3..8f40d16 100644 --- a/tizen/extensions/renderer/runtime_ipc_client.h +++ b/tizen/extensions/renderer/runtime_ipc_client.h @@ -18,12 +18,11 @@ #define XWALK_EXTENSIONS_RENDERER_RUNTIME_IPC_CLIENT_H_ #include -#include -#include #include #include #include +#include "common/wrt_message_data.h" namespace extensions { @@ -83,7 +82,7 @@ class RuntimeIPCClient { const std::string& type, const std::string& value, ReplyCallback callback); - void HandleMessageFromRuntime(const Ewk_IPC_Wrt_Message_Data* msg); + void HandleMessageFromRuntime(const Wrt_Message_Data* msg); int GetRoutingId(v8::Handle context); diff --git a/tizen/extensions/renderer/xwalk_extension_client.cc b/tizen/extensions/renderer/xwalk_extension_client.cc index 383473f..d113269 100644 --- a/tizen/extensions/renderer/xwalk_extension_client.cc +++ b/tizen/extensions/renderer/xwalk_extension_client.cc @@ -6,15 +6,17 @@ #include "extensions/renderer/xwalk_extension_client.h" #include +#include #include #include -#include #include +#include "base/command_line.h" #include "common/logger.h" #include "common/profiler.h" #include "common/string_utils.h" +#include "content/public/common/content_switches.h" #include "extensions/common/constants.h" #include "extensions/common/xwalk_extension_server.h" #include "extensions/renderer/runtime_ipc_client.h" @@ -40,14 +42,22 @@ XWalkExtensionClient::~XWalkExtensionClient() { extension_apis_.clear(); } -void XWalkExtensionClient::Initialize() { +void XWalkExtensionClient::Initialize(v8::Handle context) { SCOPE_PROFILE(); if (!extension_apis_.empty()) { return; } - - XWalkExtensionServer* server = XWalkExtensionServer::GetInstance(); - Json::Value reply = server->GetExtensions(); + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + Json::Value reply; + if (command_line->HasSwitch(switches::kSingleProcess)) { + XWalkExtensionServer* server = XWalkExtensionServer::GetInstance(); + reply = server->GetExtensions(); + } else { + RuntimeIPCClient* ipc = RuntimeIPCClient::GetInstance(); + std::string extension_info =ipc->SendSyncMessage(context, kMethodGetExtensions, "", ""); + Json::Reader reader; + reader.parse(extension_info, reply, false); + } for (auto it = reply.begin(); it != reply.end(); ++it) { ExtensionCodePoints* codepoint = new ExtensionCodePoints; Json::Value entry_points = (*it)["entry_points"]; @@ -62,13 +72,20 @@ void XWalkExtensionClient::Initialize() { std::string XWalkExtensionClient::CreateInstance( v8::Handle context, const std::string& extension_name, InstanceHandler* handler) { - void* ret = ecore_main_loop_thread_safe_call_sync( - CreateInstanceInMainloop, - static_cast(const_cast(extension_name.data()))); - std::string* sp = static_cast(ret); - std::string instance_id = *sp; - delete sp; - + std::string instance_id; + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + if (command_line->HasSwitch(switches::kSingleProcess)) { + void* ret = ecore_main_loop_thread_safe_call_sync( + CreateInstanceInMainloop, + static_cast(const_cast(extension_name.data()))); + std::string* sp = static_cast(ret); + instance_id = *sp; + delete sp; + } else { + RuntimeIPCClient* ipc = RuntimeIPCClient::GetInstance(); + instance_id =ipc->SendSyncMessage( + context, kMethodCreateInstance, "", extension_name.data()); + } handlers_[instance_id] = handler; return instance_id; } @@ -105,8 +122,16 @@ std::string XWalkExtensionClient::SendSyncMessageToNative( std::string XWalkExtensionClient::GetAPIScript( v8::Handle context, const std::string& extension_name) { - XWalkExtensionServer* server = XWalkExtensionServer::GetInstance(); - return server->GetAPIScript(extension_name); + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + if (command_line->HasSwitch(switches::kSingleProcess)) { + XWalkExtensionServer* server = XWalkExtensionServer::GetInstance(); + return server->GetAPIScript(extension_name); + } else { + RuntimeIPCClient* ipc = RuntimeIPCClient::GetInstance(); + std::string reply = ipc->SendSyncMessage( + context, kMethodGetAPIScript, "", extension_name.data()); + return reply; + } } void XWalkExtensionClient::OnReceivedIPCMessage( diff --git a/tizen/extensions/renderer/xwalk_extension_client.h b/tizen/extensions/renderer/xwalk_extension_client.h index 5b98ee9..7cb0c11 100644 --- a/tizen/extensions/renderer/xwalk_extension_client.h +++ b/tizen/extensions/renderer/xwalk_extension_client.h @@ -28,7 +28,7 @@ class XWalkExtensionClient { XWalkExtensionClient(); virtual ~XWalkExtensionClient(); - void Initialize(); + void Initialize(v8::Handle context); std::string CreateInstance(v8::Handle context, const std::string& extension_name, diff --git a/tizen/extensions/renderer/xwalk_extension_renderer_controller.cc b/tizen/extensions/renderer/xwalk_extension_renderer_controller.cc index 6c8dd11..982ab23 100644 --- a/tizen/extensions/renderer/xwalk_extension_renderer_controller.cc +++ b/tizen/extensions/renderer/xwalk_extension_renderer_controller.cc @@ -80,7 +80,7 @@ void XWalkExtensionRendererController::DidCreateScriptContext( "objecttools", std::unique_ptr(new ObjectToolsModule)); - extensions_client_->Initialize(); + extensions_client_->Initialize(context); CreateExtensionModules(extensions_client_.get(), module_system); module_system->Initialize(); @@ -100,14 +100,14 @@ void XWalkExtensionRendererController::WillReleaseScriptContext( } void XWalkExtensionRendererController::OnReceivedIPCMessage( - const Ewk_IPC_Wrt_Message_Data* data) { + const Wrt_Message_Data* data) { - Eina_Stringshare* type = ewk_ipc_wrt_message_data_type_get(data); + Eina_Stringshare* type = data->GetType(); #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); + Eina_Stringshare* id = data->GetId(); + Eina_Stringshare* msg = data->GetValue(); extensions_client_->OnReceivedIPCMessage(id, msg); eina_stringshare_del(id); eina_stringshare_del(msg); @@ -121,7 +121,7 @@ void XWalkExtensionRendererController::OnReceivedIPCMessage( } void XWalkExtensionRendererController::InitializeExtensionClient() { - extensions_client_->Initialize(); +// extensions_client_->Initialize(); } void XWalkExtensionRendererController::LoadUserExtensions( diff --git a/tizen/extensions/renderer/xwalk_extension_renderer_controller.h b/tizen/extensions/renderer/xwalk_extension_renderer_controller.h index 95e3145..8fe5ff4 100644 --- a/tizen/extensions/renderer/xwalk_extension_renderer_controller.h +++ b/tizen/extensions/renderer/xwalk_extension_renderer_controller.h @@ -6,12 +6,11 @@ #ifndef XWALK_EXTENSIONS_RENDERER_XWALK_EXTENSION_RENDERER_CONTROLLER_H_ #define XWALK_EXTENSIONS_RENDERER_XWALK_EXTENSION_RENDERER_CONTROLLER_H_ -#include -#include #include #include #include +#include "common/wrt_message_data.h" namespace extensions { @@ -25,7 +24,7 @@ class XWalkExtensionRendererController { void DidCreateScriptContext(v8::Handle context); void WillReleaseScriptContext(v8::Handle context); - void OnReceivedIPCMessage(const Ewk_IPC_Wrt_Message_Data* data); + void OnReceivedIPCMessage(const Wrt_Message_Data* data); void InitializeExtensionClient(); void LoadUserExtensions(const std::string app_path); diff --git a/tizen/renderer/injected_bundle.cc b/tizen/renderer/injected_bundle.cc index a030975..cce38e6 100644 --- a/tizen/renderer/injected_bundle.cc +++ b/tizen/renderer/injected_bundle.cc @@ -15,8 +15,6 @@ */ #include -#include -#include #include #include #include @@ -30,6 +28,7 @@ #include "common/profiler.h" #include "common/resource_manager.h" #include "common/string_utils.h" +#include "common/wrt_message_data.h" #include "extensions/renderer/runtime_ipc_client.h" #include "extensions/renderer/widget_module.h" #include "extensions/renderer/xwalk_extension_renderer_controller.h" @@ -173,7 +172,7 @@ extern "C" void DynamicDatabaseAttach(int /*attach*/) { // LOGGER(DEBUG) << "InjectedBundle::DynamicDatabaseAttach !!"; } -extern "C" void DynamicOnIPCMessage(const Ewk_IPC_Wrt_Message_Data& data) { +extern "C" void DynamicOnIPCMessage(const Wrt_Message_Data& data) { SCOPE_PROFILE(); extensions::XWalkExtensionRendererController& controller = extensions::XWalkExtensionRendererController::GetInstance(); diff --git a/tizen/wrt/chromium_wrt.gyp b/tizen/wrt/chromium_wrt.gyp new file mode 100644 index 0000000..4680117 --- /dev/null +++ b/tizen/wrt/chromium_wrt.gyp @@ -0,0 +1,55 @@ +{ + 'includes':[ + '../build/common.gypi', + ], + 'targets': [ + { + 'target_name': 'chromium_wrt_shared', + 'type': 'shared_library', + 'sources': [ + "dynamicplugin.cc", + "dynamicplugin.h", + "v8widget.cc", + "v8widget.h", + "wrtwidget.cc", + "wrtwidget.h", + "wrt_dynamicplugin.cc", + "wrt_dynamicplugin.h", + "wrt_file_protocol_handler.cc", + "wrt_file_protocol_handler.h", + "wrt_widget_host.cc", + "wrt_widget_host.h", + ], + 'cflags': [ + '-fvisibility=default', + ], + 'variables': { + 'packages': [ + 'chromium-efl', + 'elementary', + ], + }, + 'include_dirs': [ + '.', + '../', + '../..', + '../tizen', + '<(libchromiumcontent_src_dir)', + '<(SHARED_INTERMEDIATE_DIR)', + '<(libchromiumcontent_src_dir)/gen', + '<(libchromiumcontent_src_dir)/third_party/skia/include/config', + '<(libchromiumcontent_src_dir)/third_party/skia/include/core', + ], + 'direct_dependent_settings': { +# 'libraries': [ +# '-lchromium_wrt_shared', +# ], + 'variables': { + 'packages': [ + 'jsoncpp', + ], + }, + }, + }, # end of target 'xwalk_extension_static' + ], # end of targets +} diff --git a/tizen/wrt/dynamicplugin.cc b/tizen/wrt/dynamicplugin.cc new file mode 100644 index 0000000..9512d3e --- /dev/null +++ b/tizen/wrt/dynamicplugin.cc @@ -0,0 +1,89 @@ +// Copyright 2014 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "dynamicplugin.h" + +#include + +#include "base/command_line.h" +#include "base/logging.h" + +namespace { +const char* const VERSION_FUNCTION = "DynamicPluginVersion"; +const char* const START_SESSION_FUNCTION = "DynamicPluginStartSession"; +const char* const STOP_SESSION_FUNCTION = "DynamicPluginStopSession"; +} + +DynamicPlugin::DynamicPlugin() + : m_handle_(0), + m_version_(0), + m_versionFunction_(0), + m_startSession_(0), + m_stopSession_(0) { + const base::CommandLine& commandLine = + *base::CommandLine::ForCurrentProcess(); + std::string injectedBundlePath = + commandLine.GetSwitchValueASCII("injected-bundle-path"); + if (injectedBundlePath.empty()) { + return; + } + m_handle_ = dlopen(injectedBundlePath.c_str(), RTLD_LAZY); + if (!m_handle_) { + LOG(ERROR) << "No handle to " << injectedBundlePath.c_str() << " " + << dlerror() << "\n"; + return; + } + + *reinterpret_cast(&m_versionFunction_) = + dlsym(m_handle_, VERSION_FUNCTION); + if (!m_versionFunction_) { + LOG(ERROR) << "No " << VERSION_FUNCTION << " symbol found!\n"; + } else { + m_version_ = m_versionFunction_(); + if (m_version_ != 0 && m_version_ != 1) { + LOG(ERROR) << "Unknown plugin version: " << m_version_ << "!\n"; + return; + } + } + + *reinterpret_cast(&m_startSession_) = + dlsym(m_handle_, START_SESSION_FUNCTION); + if (!m_startSession_) { + LOG(ERROR) << "No " << START_SESSION_FUNCTION << " symbol found!\n"; + } + *reinterpret_cast(&m_stopSession_) = + dlsym(m_handle_, STOP_SESSION_FUNCTION); + if (!m_stopSession_) { + LOG(ERROR) << "No " << STOP_SESSION_FUNCTION << " symbol found!\n"; + } +} + +void DynamicPlugin::startSession(const char* sessionId, + v8::Handle context, + int routingHandle, + const void* sessionBlob) { + if (!m_startSession_) + return; + + m_startSession_(sessionId, context, routingHandle, sessionBlob); +} + +void DynamicPlugin::stopSession(const char* sessionId, + v8::Handle context) { + if (!m_stopSession_) + return; + + m_stopSession_(sessionId, context); +} + +DynamicPlugin::~DynamicPlugin() { + if (m_handle_) + dlclose(m_handle_); +} + +DynamicPlugin& DynamicPlugin::instance() { + static DynamicPlugin dynamicPlugin; + return dynamicPlugin; +} + diff --git a/tizen/wrt/dynamicplugin.h b/tizen/wrt/dynamicplugin.h new file mode 100644 index 0000000..46a1963 --- /dev/null +++ b/tizen/wrt/dynamicplugin.h @@ -0,0 +1,46 @@ +// Copyright 2014, 2016 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WRT_DYNAMICPLUGIN_H_ +#define WRT_DYNAMICPLUGIN_H_ + +#include +#include "base/macros.h" +#include "v8/include/v8.h" + +typedef unsigned int (*versionFunction)(void); + +typedef void (*startSessionFunction)(const char* sessionId, + v8::Handle context, + int routingHandle, + const void* sessionBlob); + +typedef void (*stopSessionFunction)(const char* sessionId, + v8::Handle context); + +class DynamicPlugin { + public: + void startSession(const char* sessionId, + v8::Handle context, + int routingHandle, + const void* sessionBlob); + void stopSession(const char* sessionId, v8::Handle context); + + virtual ~DynamicPlugin(); + + static DynamicPlugin& instance(); + + protected: + DynamicPlugin(); + DynamicPlugin(const DynamicPlugin&); + DynamicPlugin& operator=(const DynamicPlugin&); + + void* m_handle_; + unsigned int m_version_; + versionFunction m_versionFunction_; + startSessionFunction m_startSession_; + stopSessionFunction m_stopSession_; +}; + +#endif // WRT_DYNAMICPLUGIN_H_ diff --git a/tizen/wrt/v8widget.cc b/tizen/wrt/v8widget.cc new file mode 100644 index 0000000..ef721b8 --- /dev/null +++ b/tizen/wrt/v8widget.cc @@ -0,0 +1,92 @@ +// Copyright 2014, 2015 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "v8widget.h" + +#include "base/logging.h" +#include "dynamicplugin.h" +#if defined(OS_TIZEN_TV_PRODUCT) +#include "wrt/hbbtv_dynamicplugin.h" +#endif +#include "wrt_dynamicplugin.h" + +V8Widget::V8Widget(Type type) : type_(type) {} + +V8Widget::~V8Widget() {} + +void V8Widget::SetId(const std::string& id) { + id_ = id; +} + +V8Widget::Type V8Widget::GetType() const { + return type_; +} + +bool V8Widget::ParseUrl(const GURL& url, + GURL& new_url, + bool& is_decrypted_file) { + if (!id_.empty()) { + std::string old_url = url.possibly_invalid_spec(); + std::string s_new_url; + if (type_ == V8Widget::Type::WRT) + WrtDynamicPlugin::instance().parseURL(&old_url, &s_new_url, id_.c_str(), + &is_decrypted_file); + +#if defined(OS_TIZEN_TV_PRODUCT) + if (type_ == V8Widget::Type::HBBTV) + HbbTVDynamicPlugin::instance().parseURL(&old_url, &s_new_url, id_.c_str(), + &is_decrypted_file); +#endif + + if (!s_new_url.empty()) { + new_url = GURL(s_new_url); + return true; + } + } + return false; +} + +#if defined(OS_TIZEN_TV_PRODUCT) +bool V8Widget::GetFileDecryptedDataBuffer(const GURL& url, + std::vector* data) { + if (!id_.empty()) { + std::string str_url = url.possibly_invalid_spec(); + if (type_ == V8Widget::Type::WRT) + return WrtDynamicPlugin::instance().getFileDecryptedDataBuffer(&str_url, + data); + + if (type_ == V8Widget::Type::HBBTV) + return HbbTVDynamicPlugin::instance().getFileDecryptedDataBuffer(&str_url, + data); + } + return false; +} +#endif + +void V8Widget::StopSession(v8::Handle context) { + if (!id_.empty() && !context.IsEmpty()) { + if (type_ == V8Widget::Type::WRT) + WrtDynamicPlugin::instance().stopSession(id_.c_str(), context); + +#if defined(OS_TIZEN_TV_PRODUCT) + if (type_ == V8Widget::Type::HBBTV) + HbbTVDynamicPlugin::instance().stopSession(id_.c_str(), context); +#endif + } +} + +void V8Widget::StartSession(v8::Handle context, + int routingHandle, + const void* sessionBlob) { + if (!id_.empty() && !context.IsEmpty()) { + if (type_ == V8Widget::Type::WRT) + NOTREACHED(); + +#if defined(OS_TIZEN_TV_PRODUCT) + if (type_ == V8Widget::Type::HBBTV) + HbbTVDynamicPlugin::instance().startSession(id_.c_str(), context, + routingHandle, sessionBlob); +#endif + } +} diff --git a/tizen/wrt/v8widget.h b/tizen/wrt/v8widget.h new file mode 100644 index 0000000..2b843a3 --- /dev/null +++ b/tizen/wrt/v8widget.h @@ -0,0 +1,41 @@ +// Copyright 2014, 2015 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WRT_V8WIDGET_H_ +#define WRT_V8WIDGET_H_ + +#include + +#include "content/public/renderer/render_thread_observer.h" +#include "url/gurl.h" +#include "v8/include/v8.h" + +// Have to be created on the RenderThread. +class V8Widget { + public: + enum class Type { HBBTV, WRT }; + + explicit V8Widget(Type type); + virtual ~V8Widget() = 0; + + void SetId(const std::string& id); + Type GetType() const; + + virtual void StartSession(v8::Handle, + int routingHandle, + const void* sessionBlob); + + virtual void StopSession(v8::Handle); + + bool ParseUrl(const GURL& url, GURL& new_url, bool& is_decrypted_file); + +#if defined(OS_TIZEN_TV_PRODUCT) + bool GetFileDecryptedDataBuffer(const GURL& url, std::vector* data); +#endif + protected: + std::string id_; + Type type_; +}; + +#endif // WRT_V8WIDGET_H_ diff --git a/tizen/wrt/wrt_dynamicplugin.cc b/tizen/wrt/wrt_dynamicplugin.cc new file mode 100644 index 0000000..68cf087 --- /dev/null +++ b/tizen/wrt/wrt_dynamicplugin.cc @@ -0,0 +1,164 @@ +// Copyright 2014 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "wrt_dynamicplugin.h" + +#include + +#include "base/command_line.h" +#include "base/logging.h" + +namespace { +const char* const URL_PARSING_FUNCTION = "DynamicUrlParsing"; +const char* const SET_WIDGET_INFO_FUNCTION = "DynamicSetWidgetInfo"; +const char* const DATABASE_ATTACH_FUNCTION = "DynamicDatabaseAttach"; +#if defined(OS_TIZEN_TV_PRODUCT) +const char* const TVURL_PARSING_FUNCTION = "DynamicTVUrlParsing"; +const char* const GET_FILEDECRYPTED_DATABUFFER = + "DynamicGetFileDecryptedDataBuffer"; +#endif + +typedef void (*startSessionFun_v0)(const char* tizen_app_id, + v8::Handle context, + int routingHandle, + double scaleFactor, + const char* encodedBundle, + const char* theme, + const char* baseURL); +} // namespace + +WrtDynamicPlugin::WrtDynamicPlugin() + : DynamicPlugin(), + m_parseURL_(0), + m_setWidgetInfo_(0), + m_databaseAttach_(0), +#if defined(OS_TIZEN_TV_PRODUCT) + m_getFileDecryptedDataBuffer_(0), + m_parseTVURL_(0), +#endif + m_onIPCMessage_(0) { + *reinterpret_cast(&m_parseURL_) = + dlsym(m_handle_, URL_PARSING_FUNCTION); + if (!m_parseURL_) { + LOG(ERROR) << "No " << URL_PARSING_FUNCTION << " symbol found!\n"; + } + *reinterpret_cast(&m_setWidgetInfo_) = + dlsym(m_handle_, SET_WIDGET_INFO_FUNCTION); + if (!m_setWidgetInfo_) { + LOG(ERROR) << "No " << SET_WIDGET_INFO_FUNCTION << " symbol found!"; + } + *reinterpret_cast(&m_databaseAttach_) = + dlsym(m_handle_, DATABASE_ATTACH_FUNCTION); + if (!m_databaseAttach_) { + LOG(ERROR) << "No " << DATABASE_ATTACH_FUNCTION << " symbol found!\n"; + return; + } + *reinterpret_cast(&m_onIPCMessage_) = + dlsym(m_handle_, "DynamicOnIPCMessage"); + if (!m_onIPCMessage_) { + LOG(ERROR) << "No DynamicOnIPCMessage symbol found!\n"; + } + m_databaseAttach_(1); + +#if defined(OS_TIZEN_TV_PRODUCT) + *reinterpret_cast(&m_parseTVURL_) = + dlsym(m_handle_, TVURL_PARSING_FUNCTION); + if (!m_parseTVURL_) { + LOG(ERROR) << "No " << TVURL_PARSING_FUNCTION << " symbol found!\n"; + } + *reinterpret_cast(&m_getFileDecryptedDataBuffer_) = + dlsym(m_handle_, GET_FILEDECRYPTED_DATABUFFER); + if (!m_getFileDecryptedDataBuffer_) { + LOG(ERROR) << "No " << GET_FILEDECRYPTED_DATABUFFER << " symbol found!\n"; + } +#endif +} + +void WrtDynamicPlugin::startSession(const char* tizen_app_id, + v8::Handle context, + int routingHandle, + double scaleFactor, + const char* encodedBundle, + const char* theme, + const char* baseURL) { + if (!m_startSession_ || !m_databaseAttach_) + return; + switch (m_version_) { + case 0: { + auto startSession_v0 = + reinterpret_cast(m_startSession_); + startSession_v0(tizen_app_id, context, routingHandle, scaleFactor, + encodedBundle, theme, baseURL); + break; + } + case 1: { + DynamicPlugin::startSession(tizen_app_id, context, routingHandle, + baseURL); + break; + } + default: + return; + } +} + +void WrtDynamicPlugin::stopSession(const char* tizen_app_id, + v8::Handle context) { + if (!m_stopSession_ || !m_databaseAttach_) + return; + DynamicPlugin::stopSession(tizen_app_id, context); +} + +void WrtDynamicPlugin::parseURL(std::string* old_url, + std::string* new_url, + const char* tizen_app_id, + bool* is_decrypted_file) { +#if defined(OS_TIZEN_TV_PRODUCT) + if (!m_databaseAttach_) + return; + if (m_parseTVURL_) { + m_parseTVURL_(old_url, new_url, tizen_app_id, is_decrypted_file); + return; + } + if (m_parseURL_) { + m_parseURL_(old_url, new_url, tizen_app_id); + *is_decrypted_file = false; + } +#else + if (!m_parseURL_ || !m_databaseAttach_) + return; + m_parseURL_(old_url, new_url, tizen_app_id); +#endif +} + +#if defined(OS_TIZEN_TV_PRODUCT) +bool WrtDynamicPlugin::getFileDecryptedDataBuffer(const std::string* url, + std::vector* data) { + if (!m_getFileDecryptedDataBuffer_) + return false; + return m_getFileDecryptedDataBuffer_(url, data); +} +#endif + +void WrtDynamicPlugin::setWidgetInfo(const std::string& tizen_app_id) { + if (!m_setWidgetInfo_) + return; + m_setWidgetInfo_(tizen_app_id.c_str()); +} + +WrtDynamicPlugin::~WrtDynamicPlugin() { + if (m_databaseAttach_) + m_databaseAttach_(0); +} + +WrtDynamicPlugin& WrtDynamicPlugin::instance() { + static WrtDynamicPlugin dynamicPlugin; + return dynamicPlugin; +} + +void WrtDynamicPlugin::messageReceived(const Wrt_Message_Data& data) { + if (!m_onIPCMessage_) + return; + + m_onIPCMessage_(data); +} diff --git a/tizen/wrt/wrt_dynamicplugin.h b/tizen/wrt/wrt_dynamicplugin.h new file mode 100644 index 0000000..9554b4d --- /dev/null +++ b/tizen/wrt/wrt_dynamicplugin.h @@ -0,0 +1,71 @@ +// Copyright 2014 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WRT_WRT_DYNAMICPLUGIN_H_ +#define WRT_WRT_DYNAMICPLUGIN_H_ + +#include +#include +#include "dynamicplugin.h" +#include "v8/include/v8.h" +#include "common/wrt_message_data.h" + +typedef void (*onIPCMessageFun)(const Wrt_Message_Data& data); +#if defined(OS_TIZEN_TV_PRODUCT) +typedef void (*TVParseUrlFun)(std::string* old_url, + std::string* new_url, + const char* tizen_app_id, + bool* is_decrypted_file); +typedef bool (*getFileDecryptedDataBufferFun)(const std::string* url, + std::vector* data); +#endif +typedef void (*parseUrlFun)(std::string* old_url, + std::string* new_url, + const char* tizen_app_id); +typedef void (*setWidgetInfoFun)(const char* tizen_app_id); +typedef void (*databaseAttachFun)(int databaseAttach); + +class WrtDynamicPlugin : public DynamicPlugin { + public: + void startSession(const char* tizen_app_id, + v8::Handle context, + int routingHandle, + double scaleFactor, + const char* encodedBundle, + const char* theme, + const char* baseURL); + void stopSession(const char* tizen_app_id, v8::Handle context); + + void parseURL(std::string* old_url, + std::string* new_url, + const char* tizen_app_id, + bool* is_decrypted_file); + +#if defined(OS_TIZEN_TV_PRODUCT) + bool getFileDecryptedDataBuffer(const std::string* url, + std::vector* data); +#endif + + void setWidgetInfo(const std::string& tizen_app_id); + void messageReceived(const Wrt_Message_Data& data); + + static WrtDynamicPlugin& instance(); + ~WrtDynamicPlugin() override; + + private: + WrtDynamicPlugin(); + + parseUrlFun m_parseURL_; + setWidgetInfoFun m_setWidgetInfo_; + databaseAttachFun m_databaseAttach_; +#if defined(OS_TIZEN_TV_PRODUCT) + getFileDecryptedDataBufferFun m_getFileDecryptedDataBuffer_; + TVParseUrlFun m_parseTVURL_; +#endif + onIPCMessageFun m_onIPCMessage_; + + DISALLOW_COPY_AND_ASSIGN(WrtDynamicPlugin); +}; + +#endif // WRT_WRT_DYNAMICPLUGIN_H_ diff --git a/tizen/wrt/wrt_file_protocol_handler.cc b/tizen/wrt/wrt_file_protocol_handler.cc new file mode 100644 index 0000000..5a8ba30 --- /dev/null +++ b/tizen/wrt/wrt_file_protocol_handler.cc @@ -0,0 +1,110 @@ +// Copyright (c) 2014,2015 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "wrt_file_protocol_handler.h" + +#include "base/command_line.h" +//#include "common/content_switches_efl.h" +#include "content/public/common/content_client.h" +#include "content/public/renderer/content_renderer_client.h" +#include "net/base/filename_util.h" +#include "net/url_request/url_request_data_job.h" +#include "net/url_request/url_request_error_job.h" +#include "net/url_request/url_request_file_dir_job.h" +#include "net/url_request/url_request_file_job.h" +#include "net/url_request/url_request_simple_job.h" +#include "wrt_dynamicplugin.h" + +namespace net { + +class WrtURLRequestDataJob : public URLRequestSimpleJob { + public: + /* LCOV_EXCL_START */ + WrtURLRequestDataJob(URLRequest* request, + NetworkDelegate* network_delegate, + const GURL& data_url) + : URLRequestSimpleJob(request, network_delegate) { + data_url_ = data_url; + } + /* LCOV_EXCL_STOP */ + + int GetData(std::string* mime_type, + std::string* charset, + std::string* data, + const CompletionCallback& callback) const override; + + private: + ~WrtURLRequestDataJob() override {} // LCOV_EXCL_LINE + GURL data_url_; +}; + +/* LCOV_EXCL_START */ +int WrtURLRequestDataJob::GetData(std::string* mime_type, + std::string* charset, + std::string* data, + const CompletionCallback& callback) const { + if (!data_url_.is_valid()) + return ERR_INVALID_URL; + + return URLRequestDataJob::BuildResponse(data_url_, mime_type, charset, data, + nullptr); +} + +bool WrtFileProtocolHandler::GetWrtParsedUrl(const GURL& url, + GURL& parsed_url) const { + static std::string tizen_app_id = + base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( + "widget-id"); + if (!tizen_app_id.empty()) { + bool is_decrypted_file; + std::string url_str = url.possibly_invalid_spec(); + std::string parsed_url_str; + WrtDynamicPlugin::instance().parseURL( + &url_str, &parsed_url_str, tizen_app_id.c_str(), &is_decrypted_file); + if (!parsed_url_str.empty()) { + parsed_url = GURL(parsed_url_str); + return true; + } + } + return false; +} +/* LCOV_EXCL_STOP */ + +URLRequestJob* WrtFileProtocolHandler::MaybeCreateJob( + URLRequest* request, + NetworkDelegate* network_delegate) const { + GURL parsed_url; + if (GetWrtParsedUrl(request->url(), parsed_url)) { + // Data URI scheme for WRT encryption content + if (parsed_url.SchemeIs(url::kDataScheme)) + return new WrtURLRequestDataJob(request, network_delegate, parsed_url); + } else + parsed_url = request->url(); + + base::FilePath file_path; + const bool is_file = FileURLToFilePath(parsed_url, &file_path); + + // Check file access permissions. + if (!network_delegate || + !network_delegate->CanAccessFile(*request, file_path)) { + return new URLRequestErrorJob(request, network_delegate, ERR_ACCESS_DENIED); + } + + // We need to decide whether to create URLRequestFileJob for file access or + // URLRequestFileDirJob for directory access. To avoid accessing the + // filesystem, we only look at the path string here. + // The code in the URLRequestFileJob::Start() method discovers that a path, + // which doesn't end with a slash, should really be treated as a directory, + // and it then redirects to the URLRequestFileDirJob. + if (is_file && file_path.EndsWithSeparator() && file_path.IsAbsolute()) { + return new URLRequestFileDirJob(request, network_delegate, file_path); + } + + // Use a regular file request job for all non-directories (including invalid + // file names). + return new URLRequestFileJob(request, network_delegate, file_path, + file_task_runner_); +} + +} // namespace diff --git a/tizen/wrt/wrt_file_protocol_handler.h b/tizen/wrt/wrt_file_protocol_handler.h new file mode 100644 index 0000000..6fab49f --- /dev/null +++ b/tizen/wrt/wrt_file_protocol_handler.h @@ -0,0 +1,46 @@ +// Copyright (c) 2014,2015 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WRT_FILE_PROTOCOL_HANDLER +#define WRT_FILE_PROTOCOL_HANDLER + +#include "base/memory/ref_counted.h" +#include "net/url_request/url_request_job_factory.h" + +class GURL; + +namespace base { +class TaskRunner; +} + +namespace net { + +class NetworkDelegate; +class URLRequestJob; + +class WrtFileProtocolHandler + : public URLRequestJobFactory::ProtocolHandler { + public: + explicit WrtFileProtocolHandler( + const scoped_refptr& file_task_runner) + : file_task_runner_(file_task_runner) {} + ~WrtFileProtocolHandler() override {} + URLRequestJob* MaybeCreateJob( + URLRequest* request, + NetworkDelegate* network_delegate) const override; + /* LCOV_EXCL_START */ + bool IsSafeRedirectTarget(const GURL& location) const override { + return false; + } + /* LCOV_EXCL_STOP */ + + private: + bool GetWrtParsedUrl(const GURL& url, GURL& parsed_url) const; + const scoped_refptr file_task_runner_; + DISALLOW_COPY_AND_ASSIGN(WrtFileProtocolHandler); +}; + +} // namespace net + +#endif // WRT_FILE_PROTOCOL_HANDLER diff --git a/tizen/wrt/wrt_widget_host.cc b/tizen/wrt/wrt_widget_host.cc new file mode 100644 index 0000000..d33c513 --- /dev/null +++ b/tizen/wrt/wrt_widget_host.cc @@ -0,0 +1,164 @@ +// Copyright (c) 2014,2015 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "wrt_widget_host.h" + +#include "base/lazy_instance.h" +//#include "common/render_messages_ewk.h" +#include "atom/common/api/api_messages.h" +#include "content/public/browser/browser_message_filter.h" +#include "content/public/browser/render_process_host.h" +#include "content/public/browser/resource_request_info.h" +//#include "ipc/ipc_message_macros.h" +//#include "ipc_message_start_ewk.h" +#include "net/url_request/url_request.h" +#include "url/gurl.h" + +namespace { +// TODO(z.kostrzewa) I would prefer not make it a singleton, check out +// if it can't be a member of ContentMainDelegateEfl (but keep the static +// getter, maybe?). +base::LazyInstance > g_wrt_widget_host = + LAZY_INSTANCE_INITIALIZER; + +bool SendToAllRenderers(IPC::Message* message) { + bool result = false; + content::RenderProcessHost::iterator it = + content::RenderProcessHost::AllHostsIterator(); + while (!it.IsAtEnd()) { + if (it.GetCurrentValue()->Send(new IPC::Message(*message))) + result = true; + it.Advance(); + } + delete message; + return result; +} + +bool SendToRenderer(int renderer_id, IPC::Message* message) { + return content::RenderProcessHost::FromID(renderer_id)->Send(message); +} +} + +class WrtWidgetHostMessageFilter : public content::BrowserMessageFilter { + public: + explicit WrtWidgetHostMessageFilter(WrtWidgetHost* wrt_widget_host); + + private: + ~WrtWidgetHostMessageFilter() override {} + bool OnMessageReceived(const IPC::Message& message) override; + + WrtWidgetHost* wrt_widget_host_; +}; + +WrtWidgetHostMessageFilter::WrtWidgetHostMessageFilter( + WrtWidgetHost* wrt_widget_host) + : content::BrowserMessageFilter(ShellMsgStart), + wrt_widget_host_(wrt_widget_host) { +} + +bool WrtWidgetHostMessageFilter::OnMessageReceived(const IPC::Message& message) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(WrtWidgetHostMessageFilter, message) + IPC_MESSAGE_FORWARD(WrtMsg_ParseUrlResponse, wrt_widget_host_, WrtWidgetHost::OnUrlRetrieved) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; +} + +WrtWidgetHost* WrtWidgetHost::Get() { + // TODO(z.kostrzewa) LazyInstance is thread-safe but creating + // WrtWidgetHost is not - make it thread-safe. + if (!g_wrt_widget_host.Get().get()) + g_wrt_widget_host.Get().reset(new WrtWidgetHost); + return g_wrt_widget_host.Get().get(); +} + +WrtWidgetHost::WrtWidgetHost() + : message_filter_(new WrtWidgetHostMessageFilter(this)) { +} + +WrtWidgetHost::~WrtWidgetHost() {} + +void WrtWidgetHost::GetUrlForRequest( + net::URLRequest* request, + base::Callback callback) { + // TODO(z.kostrzewa) Check on which thread(s) callbacks_ is touched + // and provide synchronization if required (either via a lock or + // by assuring that it is referenced only on one thread) + int callback_id = callback_id_generator_.GetNext(); + callbacks_[callback_id] = callback; + + int renderer_id, frame_id; + if (content::ResourceRequestInfo::GetRenderFrameForRequest(request, &renderer_id, + &frame_id)) + if (SendToRenderer(renderer_id, new WrtMsg_ParseUrl(callback_id, request->url()))) + return; + + callbacks_.erase(callback_id); + callback.Run(GURL()); +} + +void WrtWidgetHost::SendWrtMessage( + const Wrt_Message_Data& message) { + SendToAllRenderers(new WrtMsg_SendWrtMessage(message)); +} + +// It's only used by the wrt_file_protocol_handler which is not going to be used in the future +// Candidate for deletion. +bool WrtWidgetHost::InWrt() const { + return false; +} + +// It's only used by the wrt_file_protocol_handler which is not going to be used in the future +// Candidate for deletion. +std::string WrtWidgetHost::TizenAppId() const { +#if defined(OS_TIZEN_TV_PRODUCT) + return tizen_app_id_; +#else + return std::string(); +#endif +} + +void WrtWidgetHost::OnUrlRetrieved(int callback_id, const GURL& url) { + callbacks_type::iterator it = callbacks_.find(callback_id); + if (callbacks_.end() == it) + return; + + callbacks_type::mapped_type callback = it->second; + callbacks_.erase(callback_id); + callback.Run(url); +} + +#if defined(OS_TIZEN_TV_PRODUCT) +void WrtWidgetHost::SetTizenAppId(const std::string& tizen_app_id) { + tizen_app_id_ = tizen_app_id; +} + +bool WrtWidgetHost::ShouldAllowRequest(const net::URLRequest& request) { + if (tizen_app_id_.empty() || !check_accessiable_path_callback_) + return true; + + return check_accessiable_path_callback_->TriggerCallback(request.url().spec(), + tizen_app_id_); +} + +bool EwkCheckAccessiablePathCallback::TriggerCallback( + const std::string& url_spec, + const std::string& tizen_app_id) const { + if (!callback_) + return true; + + Eina_Bool result = + (*callback_)(tizen_app_id.c_str(), url_spec.c_str(), user_data_); + return result == EINA_TRUE; +} + +void WrtWidgetHost::SetCheckAccessiablePathCallback( + Ewk_Context_Check_Accessible_Path_Callback callback, + void* user_data) { + check_accessiable_path_callback_.reset( + new EwkCheckAccessiablePathCallback(callback, user_data)); +} +#endif + diff --git a/tizen/wrt/wrt_widget_host.h b/tizen/wrt/wrt_widget_host.h new file mode 100644 index 0000000..11161da --- /dev/null +++ b/tizen/wrt/wrt_widget_host.h @@ -0,0 +1,89 @@ +// Copyright (c) 2014,2015 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WRT_HOST_H +#define WRT_HOST_H + +#include +#include + +#include "base/atomic_sequence_num.h" +#include "base/callback.h" +#include "content/public/browser/browser_message_filter.h" +#include "common/wrt_message_data.h" +#if defined(OS_TIZEN_TV_PRODUCT) +#include "public/ewk_context_product.h" +#endif + +namespace net { +class URLRequest; +} + +class GURL; + +class WrtWidgetHostMessageFilter; + +#if defined(OS_TIZEN_TV_PRODUCT) +class EwkCheckAccessiablePathCallback { + public: + EwkCheckAccessiablePathCallback( + Ewk_Context_Check_Accessible_Path_Callback callback, + void* user_data) + : callback_(callback), user_data_(user_data) {} + bool TriggerCallback(const std::string& url_spec, + const std::string& tizen_app_id) const; + + private: + Ewk_Context_Check_Accessible_Path_Callback callback_; + void* user_data_; +}; +#endif + +class WrtWidgetHost { + public: + static WrtWidgetHost* Get(); + + ~WrtWidgetHost(); + + void GetUrlForRequest(net::URLRequest* request, + base::Callback callback); + + void SendWrtMessage(const Wrt_Message_Data& message); + + bool InWrt() const; + + std::string TizenAppId() const; + +#if defined(OS_TIZEN_TV_PRODUCT) + void SetTizenAppId(const std::string& tizen_app_id); + bool ShouldAllowRequest(const net::URLRequest& request); + + void SetCheckAccessiablePathCallback( + Ewk_Context_Check_Accessible_Path_Callback callback, + void* user_data); +#endif + + private: + friend class WrtWidgetHostMessageFilter; + + typedef std::map > callbacks_type; + + WrtWidgetHost(); + + void OnUrlRetrieved(int callback_id, const GURL& url); + + scoped_refptr message_filter_; + base::AtomicSequenceNumber callback_id_generator_; + callbacks_type callbacks_; + +#if defined(OS_TIZEN_TV_PRODUCT) + std::string tizen_app_id_; + std::unique_ptr check_accessiable_path_callback_; +#endif + + DISALLOW_COPY_AND_ASSIGN(WrtWidgetHost); +}; + + +#endif diff --git a/tizen/wrt/wrtwidget.cc b/tizen/wrt/wrtwidget.cc new file mode 100644 index 0000000..6c877c6 --- /dev/null +++ b/tizen/wrt/wrtwidget.cc @@ -0,0 +1,97 @@ +// Copyright 2014, 2015 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "wrtwidget.h" + +//#include "common/render_messages_ewk.h" +#include "atom/common/api/api_messages.h" +#include "content/public/renderer/render_thread.h" +#include "ipc/ipc_sync_channel.h" +#include "wrt_dynamicplugin.h" + +// TODO(z.kostrzewa) +// Why it can't be implemented as IPC::ChannelProxy::MessageFilter (?) +// Tried that and it seems that Observer starts receiving messages earlier than +// MessageFilter what is crucial for message that sets widget handle +class WrtRenderThreadObserver : public content::RenderThreadObserver { + public: + explicit WrtRenderThreadObserver(WrtWidget* wrt_widget) + : wrt_widget_(wrt_widget), + channel_(content::RenderThread::Get()->GetChannel()) + { } + + bool OnControlMessageReceived(const IPC::Message& message) override { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(WrtRenderThreadObserver, message) + IPC_MESSAGE_FORWARD(WrtMsg_SendWrtMessage, wrt_widget_, WrtWidget::MessageReceived) + IPC_MESSAGE_HANDLER(WrtMsg_ParseUrl, ParseUrl) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; + } + + private: + void ParseUrl(int request_id, const GURL& url) { + GURL response; + bool is_decrypted_file = false; + wrt_widget_->ParseUrl(url, response, is_decrypted_file); + Send(new WrtMsg_ParseUrlResponse(request_id, response)); + } + + void Send(IPC::Message* message) { + if (channel_) + channel_->Send(message); + else + delete message; + } + + WrtWidget* wrt_widget_; + IPC::SyncChannel* channel_; +}; + +WrtWidget::WrtWidget() + : V8Widget(V8Widget::Type::WRT), + scale_(0), + observer_(new WrtRenderThreadObserver(this)) { + DCHECK(content::RenderThread::Get()) + << "WrtWidget must be constructed on the render thread"; +} + +WrtWidget::~WrtWidget() { + delete observer_; +} + +content::RenderThreadObserver* WrtWidget::GetObserver() { + return observer_; +} + +void WrtWidget::SetWidgetInfo(const std::string& tizen_app_id, + double scaleFactor, + const std::string& theme, + const std::string& encodedBundle) { + id_ = tizen_app_id; + scale_ = scaleFactor; + theme_ = theme; + encodedBundle_ = encodedBundle; + WrtDynamicPlugin::instance().setWidgetInfo(id_); +} + +bool WrtWidget::IsWidgetInfoSet() const { + return !id_.empty(); +} + +void WrtWidget::StartSession(v8::Handle context, + int routingHandle, + const void* sessionBlob) { + if (!id_.empty() && !context.IsEmpty()) { + WrtDynamicPlugin::instance().startSession( + id_.c_str(), context, routingHandle, scale_, encodedBundle_.c_str(), + theme_.c_str(), reinterpret_cast(sessionBlob)); + } +} + +void WrtWidget::MessageReceived(const Wrt_Message_Data& data) { + if (!id_.empty()) + WrtDynamicPlugin::instance().messageReceived(data); +} diff --git a/tizen/wrt/wrtwidget.h b/tizen/wrt/wrtwidget.h new file mode 100644 index 0000000..28af8cb --- /dev/null +++ b/tizen/wrt/wrtwidget.h @@ -0,0 +1,45 @@ +// Copyright 2014, 2015 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WRT_WRTWIDGET_H_ +#define WRT_WRTWIDGET_H_ + +#include + +#include "content/public/renderer/render_thread_observer.h" +#include "url/gurl.h" +#include "v8widget.h" +#include "common/wrt_message_data.h" + +class WrtRenderThreadObserver; + +// Have to be created on the RenderThread. +class WrtWidget : public V8Widget { + public: + WrtWidget(); + ~WrtWidget() override; + + content::RenderThreadObserver* GetObserver(); + + void SetWidgetInfo(const std::string& tizen_app_id, + double scaleFactor, + const std::string& theme, + const std::string& encodedBundle); + + bool IsWidgetInfoSet() const; + + void MessageReceived(const Wrt_Message_Data& data); + + void StartSession(v8::Handle, + int routingHandle, + const void* sessionBlob) override; + + private: + double scale_; + std::string encodedBundle_; + std::string theme_; + WrtRenderThreadObserver* observer_; +}; + +#endif // WRT_WRTWIDGET_H_ diff --git a/vendor/brightray/browser/browser_context.cc b/vendor/brightray/browser/browser_context.cc index 4ab07e4..2f709bb 100644 --- a/vendor/brightray/browser/browser_context.cc +++ b/vendor/brightray/browser/browser_context.cc @@ -2,6 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE-CHROMIUM file. +#if defined(OS_TIZEN) +#include +#endif + #include "browser/browser_context.h" #include "browser/media/media_device_id_salt.h" @@ -40,6 +44,10 @@ using content::BrowserThread; namespace brightray { namespace { +#if defined(OS_TIZEN) +const char* const kDynamicPreloading = "DynamicPreloading"; +typedef void (*DynamicPreloading)(void); +#endif // Convert string to lower case and escape it. std::string MakePartitionName(const std::string& input) { @@ -105,16 +113,43 @@ BrowserContext::BrowserContext(const std::string& partition, bool in_memory) MakePartitionName(partition))); 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"); +#if defined(OS_TIZEN) + if (command_line->HasSwitch(switches::kSingleProcess)) { + // Preload injected bundle on here for process pool, + // because the zygote process doesn't exist in single process mode. + // The loaded handle must be closed on termination. + injected_bundle_handle_ = + dlopen(injected_bundle_path.c_str(), RTLD_LAZY); + if (!injected_bundle_handle_) { + LOG(ERROR) << "No handle to " << injected_bundle_path.c_str() + << " error " << dlerror(); + return; + } + + DynamicPreloading dp = reinterpret_cast( + dlsym(injected_bundle_handle_, kDynamicPreloading)); + if (dp) { + dp(); + } else { + LOG(ERROR) << "Fail to load symbol '" + << kDynamicPreloading + << "', error " << dlerror(); + } + } else { +#endif + //content::ZygoteHandle *handle = content::GetGenericZygote(); + //*handle->LoadInjectedBundlePath(injected_bundle_path); (*content::GetGenericZygote())-> LoadInjectedBundlePath(injected_bundle_path); - } +#if defined(OS_TIZEN) + } #endif + } } BrowserContext::~BrowserContext() { diff --git a/vendor/brightray/browser/browser_context.h b/vendor/brightray/browser/browser_context.h index 498fe99..f09b6f1 100644 --- a/vendor/brightray/browser/browser_context.h +++ b/vendor/brightray/browser/browser_context.h @@ -123,6 +123,10 @@ class BrowserContext : public base::RefCounted, base::FilePath path_; bool in_memory_; +#if defined(OS_TIZEN) + void* injected_bundle_handle_; +#endif + DevToolsNetworkControllerHandle network_controller_handle_; std::unique_ptr resource_context_; diff --git a/vendor/brightray/vendor/libchromiumcontent/src/base/trace_event/trace_event.h b/vendor/brightray/vendor/libchromiumcontent/src/base/trace_event/trace_event.h index f1a577f..0718f10 100644 --- a/vendor/brightray/vendor/libchromiumcontent/src/base/trace_event/trace_event.h +++ b/vendor/brightray/vendor/libchromiumcontent/src/base/trace_event/trace_event.h @@ -24,7 +24,7 @@ #include "base/trace_event/trace_log.h" #include "build/build_config.h" -#if defined(USE_EFL) +#if 0//defined(USE_EFL) #include "base/trace_event/ttrace.h" #endif diff --git a/wrt.gyp b/wrt.gyp index 6ea31d4..54377cf 100644 --- a/wrt.gyp +++ b/wrt.gyp @@ -15,6 +15,7 @@ '<(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)/tizen/wrt/chromium_wrt.gyp:chromium_wrt_shared', '<(DEPTH)/efl/build/system.gyp:ecore', '<(DEPTH)/efl/build/system.gyp:launchpad', '<(DEPTH)/efl/build/system.gyp:capi-appfw-application', @@ -104,6 +105,7 @@ ], 'include_dirs': [ '.', + 'tizen', 'chromium_src', 'vendor/brightray', 'vendor/native_mate', -- 2.7.4 From a6289324b1f05291eb6f0de0dccfd6f3664ac3e4 Mon Sep 17 00:00:00 2001 From: "ws29.jung" Date: Tue, 17 Apr 2018 11:13:23 +0900 Subject: [PATCH 03/16] Electron App launching implement Ironically, Electron JS Runtime was not able to execute Electron Web App, but only able to run Tizen Web app. From this patch, if Electron App is packaged as wgt, JS Runtime will parse xml then will launch Electron App from its own entry point. Change-Id: Iec5df77495063e129d99a8e1dd21bc8f489b8ffe Signed-off-by: ws29.jung --- atom/app/ui_runtime.cc | 2 +- atom/browser/api/atom_api_pwrt.cc | 5 +++++ atom/browser/api/atom_api_pwrt.h | 1 + atom/browser/browser.cc | 22 ++++++++++++++++++++++ atom/browser/browser.h | 11 +++++++++++ wrt/src/runtime.js | 19 ++++++++++++++++++- 6 files changed, 58 insertions(+), 2 deletions(-) diff --git a/atom/app/ui_runtime.cc b/atom/app/ui_runtime.cc index 7091bff..959e4ac 100644 --- a/atom/app/ui_runtime.cc +++ b/atom/app/ui_runtime.cc @@ -55,6 +55,7 @@ bool UiRuntime::OnCreate() { } void UiRuntime::OnTerminate() { + LOG(ERROR) << "OnTerminate()"; atom::Browser *browser_model = atom::Browser::Get(); } @@ -99,7 +100,6 @@ int UiRuntime::Exec() { // onCreate ops.create = [](void* data) -> bool { - LOG(ERROR) << "Create Tizen App."; UiRuntime *runtime = (UiRuntime*)data; content::ContentMain(*runtime->_params); diff --git a/atom/browser/api/atom_api_pwrt.cc b/atom/browser/api/atom_api_pwrt.cc index b63ef51..30213c5 100644 --- a/atom/browser/api/atom_api_pwrt.cc +++ b/atom/browser/api/atom_api_pwrt.cc @@ -52,6 +52,10 @@ bool PWRT::isTizenWebApp() { } } +bool PWRT::isElectronLaunch() { + return Browser::Get()->is_electron_launch(); +} + void PWRT::Log(const std::string& message) { std::string output = "[JS LOG] " + message; dlog_print(DLOG_ERROR, "WRT", output.c_str()); @@ -73,6 +77,7 @@ void PWRT::BuildPrototype( .SetMethod("getMessage", &PWRT::GetMessage) .SetMethod("getPath", &PWRT::GetPath) .SetMethod("isTizenWebApp", &PWRT::isTizenWebApp) + .SetMethod("isElectronLaunch", &PWRT::isElectronLaunch) .SetMethod("log", &PWRT::Log); } diff --git a/atom/browser/api/atom_api_pwrt.h b/atom/browser/api/atom_api_pwrt.h index 647a5ae..8b67cc2 100644 --- a/atom/browser/api/atom_api_pwrt.h +++ b/atom/browser/api/atom_api_pwrt.h @@ -19,6 +19,7 @@ class PWRT : public mate::TrackableObject { std::string GetMessage(); std::string GetPath(); bool isTizenWebApp(); + bool isElectronLaunch(); void Log(const std::string& message); protected: diff --git a/atom/browser/browser.cc b/atom/browser/browser.cc index dea0bf2..771cbee 100644 --- a/atom/browser/browser.cc +++ b/atom/browser/browser.cc @@ -21,6 +21,9 @@ namespace atom { Browser::Browser() : is_quiting_(false), +#if defined(OS_TIZEN) + is_electron_launch_(false), +#endif is_exiting_(false), is_ready_(false), is_shutdown_(false), @@ -100,6 +103,22 @@ void Browser::Shutdown() { } } +#if defined(OS_TIZEN) +void Browser::SetElectronAppLaunch() { + if (!is_electron_launch_) { + common::CommandLine* runtime_cmd = common::CommandLine::ForCurrentProcess(); + std::string appid = runtime_cmd->GetAppIdFromCommandLine("/usr/bin/electron"); + auto appdata_manager = common::ApplicationDataManager::GetInstance(); + common::ApplicationData* app_data = appdata_manager->GetApplicationData(appid); + if (!strcmp(app_data->content_info()->src().c_str(), "package.json")) { + is_electron_launch_ = true; + } + } else { + is_electron_launch_ = false; + } +} +#endif + std::string Browser::GetVersion() const { if (version_override_.empty()) { std::string version = GetExecutableFileVersion(); @@ -151,6 +170,9 @@ void Browser::Activate(bool has_visible_windows) { } void Browser::WillFinishLaunching() { +#if defined(OS_TIZEN) + SetElectronAppLaunch(); +#endif for (BrowserObserver& observer : observers_) observer.OnWillFinishLaunching(); } diff --git a/atom/browser/browser.h b/atom/browser/browser.h index 286ba29..dfc4831 100644 --- a/atom/browser/browser.h +++ b/atom/browser/browser.h @@ -222,6 +222,9 @@ class Browser : public WindowListObserver { bool is_shutting_down() const { return is_shutdown_; } bool is_quiting() const { return is_quiting_; } bool is_ready() const { return is_ready_; } +#if defined(OS_TIZEN) + bool is_electron_launch() const { return is_electron_launch_; } +#endif protected: // Returns the version of application bundle or executable file. @@ -245,6 +248,10 @@ class Browser : public WindowListObserver { void OnWindowCloseCancelled(NativeWindow* window) override; void OnWindowAllClosed() override; +#if defined(OS_TIZEN) + void SetElectronAppLaunch(); +#endif + // Observers of the browser. base::ObserverList observers_; @@ -257,6 +264,10 @@ class Browser : public WindowListObserver { // The browser is being shutdown. bool is_shutdown_; +#if defined(OS_TIZEN) + bool is_electron_launch_; +#endif + std::string version_override_; std::string name_override_; diff --git a/wrt/src/runtime.js b/wrt/src/runtime.js index d6c855d..0bdaa49 100644 --- a/wrt/src/runtime.js +++ b/wrt/src/runtime.js @@ -1,5 +1,5 @@ 'use strict'; -const {app, ipcMain} = require('electron'); +const {app, ipcMain, pwrt} = require('electron'); const IPC_MESSAGE = require('./ipc_message'); const WAS_EVENT = require('./was_event'); const WebApplication = require('./web_application'); @@ -13,6 +13,7 @@ class Runtime { this.quitting = false; this.handleWasEvents(); this.handleIpcMessages(); + this.isLaunched = false; var _this = this; app.on('before-quit', function(event) { @@ -40,8 +41,24 @@ class Runtime { app.on('window-all-closed', function(event) { return runtime_debug('window-all-closed'); }); + app.on('will-finish-launching', function(event) { + runtime_debug('will-finish-launching'); + if (pwrt.isElectronLaunch()) { + console.log("Electron App launch"); + let filePath = pwrt.getPath(); + let pkgJson = require(filePath.substr(7, filePath.length - 12)); + let mainJsPath = filePath.substr(7, filePath.length - 19) + + (pkgJson.main || 'index.js'); + + const Module = require('module'); + Module._load(mainJsPath, Module, true); + } + }); app.on('ready', function(event) { runtime_debug('ready'); + if (pwrt.isElectronLaunch()) { + return; + } this.webApplication = new WebApplication(options); }); } -- 2.7.4 From e2d42b261f17377d8acb44d744d591ff151ac62d Mon Sep 17 00:00:00 2001 From: "min7.choi" Date: Thu, 19 Apr 2018 19:30:05 +0900 Subject: [PATCH 04/16] Implement splash screen Implementation of splash screen used in tizen. now the hide screen is only implemented in complete. first-paint and costom will be implemented later. Also, the window state of the splash screen will be implemented later Change-Id: I444f1be7dd04be46d5cd8edca5e022616d9020ff Signed-off-by: min7.choi --- atom/app/ui_runtime.cc | 16 ++- atom/browser/api/atom_api_pwrt.cc | 7 ++ atom/browser/api/atom_api_pwrt.h | 1 + atom/browser/browser.cc | 37 ++++++ atom/browser/browser.h | 12 ++ atom/browser/splash_screen.cc | 238 ++++++++++++++++++++++++++++++++++++++ atom/browser/splash_screen.h | 69 +++++++++++ wrt.gyp | 2 + wrt/src/web_window.js | 4 +- 9 files changed, 384 insertions(+), 2 deletions(-) create mode 100755 atom/browser/splash_screen.cc create mode 100755 atom/browser/splash_screen.h diff --git a/atom/app/ui_runtime.cc b/atom/app/ui_runtime.cc index 959e4ac..e13e1bf 100644 --- a/atom/app/ui_runtime.cc +++ b/atom/app/ui_runtime.cc @@ -29,6 +29,8 @@ #include "tizen/common/app_db.h" #include "tizen/common/app_control.h" #include "tizen/common/constants.h" +#include "tizen/common/application_data.h" +#include "tizen/common/command_line.h" #include "gin/v8_initializer.h" @@ -51,6 +53,17 @@ void UiRuntime::SetParam(content::ContentMainParams *params) { } bool UiRuntime::OnCreate() { + common::CommandLine* runtime_cmd = common::CommandLine::ForCurrentProcess(); + std::string appid = runtime_cmd->GetAppIdFromCommandLine("/usr/bin/electron"); + + auto appdata_manager = common::ApplicationDataManager::GetInstance(); + common::ApplicationData* appdata = appdata_manager->GetApplicationData(appid); + + if(appdata->splash_screen_info()){ + atom::Browser* browser_model = atom::Browser::Get(); + browser_model->SetSplashScreen(); + } + return true; } @@ -72,7 +85,7 @@ void UiRuntime::OnResume() { } void UiRuntime::OnAppControl(app_control_h app_control) { - LOG(ERROR) << "OnAppControl()"; + LOG(ERROR) << "OnAppControl()"; std::unique_ptr appcontrol(new common::AppControl(app_control)); common::AppDB* appdb = common::AppDB::GetInstance(); @@ -102,6 +115,7 @@ int UiRuntime::Exec() { ops.create = [](void* data) -> bool { LOG(ERROR) << "Create Tizen App."; UiRuntime *runtime = (UiRuntime*)data; + runtime->OnCreate(); content::ContentMain(*runtime->_params); return true; }; diff --git a/atom/browser/api/atom_api_pwrt.cc b/atom/browser/api/atom_api_pwrt.cc index 30213c5..aa7b785 100644 --- a/atom/browser/api/atom_api_pwrt.cc +++ b/atom/browser/api/atom_api_pwrt.cc @@ -56,6 +56,12 @@ bool PWRT::isElectronLaunch() { return Browser::Get()->is_electron_launch(); } +void PWRT::HideSplashScreen(int reason) { + LOG(ERROR) << "PWRT::HideSplashScreen"; + atom::Browser *browser_model = atom::Browser::Get(); + browser_model->HideSplashScreen(reason); +} + void PWRT::Log(const std::string& message) { std::string output = "[JS LOG] " + message; dlog_print(DLOG_ERROR, "WRT", output.c_str()); @@ -78,6 +84,7 @@ void PWRT::BuildPrototype( .SetMethod("getPath", &PWRT::GetPath) .SetMethod("isTizenWebApp", &PWRT::isTizenWebApp) .SetMethod("isElectronLaunch", &PWRT::isElectronLaunch) + .SetMethod("hideSplashScreen", &PWRT::HideSplashScreen) .SetMethod("log", &PWRT::Log); } diff --git a/atom/browser/api/atom_api_pwrt.h b/atom/browser/api/atom_api_pwrt.h index 8b67cc2..ab25f34 100644 --- a/atom/browser/api/atom_api_pwrt.h +++ b/atom/browser/api/atom_api_pwrt.h @@ -20,6 +20,7 @@ class PWRT : public mate::TrackableObject { std::string GetPath(); bool isTizenWebApp(); bool isElectronLaunch(); + void HideSplashScreen(int reason); void Log(const std::string& message); protected: diff --git a/atom/browser/browser.cc b/atom/browser/browser.cc index 771cbee..3ebba72 100644 --- a/atom/browser/browser.cc +++ b/atom/browser/browser.cc @@ -16,7 +16,14 @@ #include "base/run_loop.h" #include "base/threading/thread_task_runner_handle.h" #include "brightray/browser/brightray_paths.h" + +#if defined(OS_TIZEN) #include "tizen/common/command_line.h" +#include "tizen/common/application_data.h" +#include +#include "wgt_manifest_handlers/launch_screen_handler.h" +#endif // defined(OS_TIZEN) + namespace atom { Browser::Browser() @@ -277,4 +284,34 @@ void Browser::Launch(std::unique_ptr appcontrol) { //To do:Implementation of relaunching of app } +#if defined(OS_TIZEN) +void Browser::SetSplashScreen() { + common::CommandLine* runtime_cmd = common::CommandLine::ForCurrentProcess(); + std::string appid = runtime_cmd->GetAppIdFromCommandLine("/usr/bin/electron"); + + auto appdata_manager = common::ApplicationDataManager::GetInstance(); + common::ApplicationData* appdata = appdata_manager->GetApplicationData(appid); + + Evas_Object* window_ = elm_win_util_standard_add("", ""); + + splash_screen_.reset( + new SplashScreen( + window_, appdata->splash_screen_info(), appdata->application_path())); +} + +void Browser::HideSplashScreen(int reason) { + common::CommandLine* runtime_cmd = common::CommandLine::ForCurrentProcess(); + std::string appid = runtime_cmd->GetAppIdFromCommandLine("/usr/bin/electron"); + + auto appdata_manager = common::ApplicationDataManager::GetInstance(); + common::ApplicationData* appdata = appdata_manager->GetApplicationData(appid); + + if(appdata->splash_screen_info() == NULL) { + return; + } + + splash_screen_->HideSplashScreen(reason); +} +#endif // defined(OS_TIZEN) + } // namespace atom diff --git a/atom/browser/browser.h b/atom/browser/browser.h index dfc4831..362bfaf 100644 --- a/atom/browser/browser.h +++ b/atom/browser/browser.h @@ -20,6 +20,10 @@ #include "tizen/common/application_data.h" #include "tizen/common/resource_manager.h" #include "tizen/common/locale_manager.h" +#if defined(OS_TIZEN) +#include "atom/browser/splash_screen.h" +#endif // defined(OS_TIZEN) + #if defined(OS_WIN) #include "base/files/file_path.h" @@ -48,6 +52,10 @@ class Browser : public WindowListObserver { std::unique_ptr resource_manager_; std::unique_ptr locale_manager_; +#if defined(OS_TIZEN) + std::unique_ptr splash_screen_; +#endif // defined(OS_TIZEN) + void Initialize(); // Try to close all windows and quit the application. @@ -117,6 +125,10 @@ class Browser : public WindowListObserver { void Show(); void AppControl(std::unique_ptr appcontrol); void Launch(std::unique_ptr appcontrol); +#if defined(OS_TIZEN) + void SetSplashScreen(); + void HideSplashScreen(int reason); +#endif // defined(OS_TIZEN) #if defined(OS_MACOSX) // Hide the application. diff --git a/atom/browser/splash_screen.cc b/atom/browser/splash_screen.cc new file mode 100755 index 0000000..d6c1751 --- /dev/null +++ b/atom/browser/splash_screen.cc @@ -0,0 +1,238 @@ +/* + * 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 "atom/browser/splash_screen.h" + +#include +#include +#include + +#include + +#include "tizen/common/logger.h" + +//using ScreenOrientation = runtime::NativeWindow::ScreenOrientation; + +namespace { + +enum class BorderOption { REPEAT = 1, STRETCH, ROUND }; + +// To do : The orientation will be implemented later. + +/*wgt::parse::ScreenOrientation ChooseOrientation( + const std::map& splash_map, + ScreenOrientation screen_orientation) { + auto orientation_pair = splash_map.end(); + + if (screen_orientation == + runtime::NativeWindow::ScreenOrientation::PORTRAIT_PRIMARY || + screen_orientation == + runtime::NativeWindow::ScreenOrientation::PORTRAIT_SECONDARY) { + orientation_pair = + splash_map.find(wgt::parse::ScreenOrientation::PORTRAIT); + } else { + orientation_pair = + splash_map.find(wgt::parse::ScreenOrientation::LANDSCAPE); + } + if (orientation_pair == splash_map.end()) + orientation_pair = splash_map.find(wgt::parse::ScreenOrientation::AUTO); + + if (orientation_pair != splash_map.end()) return orientation_pair->first; + return wgt::parse::ScreenOrientation::NONE; +}*/ + +bool ParseImageBorder(const std::vector& borders, + std::vector* border_values, + std::vector* border_options) { + std::map scaling_string; + scaling_string["repeat"] = BorderOption::REPEAT; + scaling_string["stretch"] = BorderOption::STRETCH; + scaling_string["round"] = BorderOption::ROUND; + + for (const auto& border : borders) { + std::string::size_type px_index = border.find("px"); + if (px_index != std::string::npos) { + std::string border_value(border.begin(), border.begin() + px_index); + border_values->push_back(std::atoi(border_value.c_str())); + } + for (const auto& border_string_val : scaling_string) { + std::string::size_type index = border.find(border_string_val.first); + if (index != std::string::npos) { + border_options->push_back(border_string_val.second); + } + } + } + + LOGGER(DEBUG) << "Image border values:"; + for (const auto& border_value : *border_values) { + LOGGER(DEBUG) << border_value; + } + LOGGER(DEBUG) << "Image border scaling values:"; + for (const auto& border_option : *border_options) { + LOGGER(DEBUG) << static_cast(border_option); + } + + return !border_values->empty() && !border_options->empty(); +} + +} // namespace + +namespace atom { + +SplashScreen::SplashScreen( + Evas_Object* window, + //runtime::NativeWindow* window, + std::shared_ptr ss_info, + const std::string& app_path) + : ss_info_(ss_info), + window_(window), + image_(nullptr), + background_(nullptr), + background_image_(nullptr), + is_active_(false) { + if (ss_info == nullptr) return; + + auto splash_map = ss_info->launch_screen_data(); + /*auto used_orientation = + ChooseOrientation(splash_map, window->orientation()); + if (used_orientation == wgt::parse::ScreenOrientation::NONE) return; */ + + auto dimensions = GetDimensions(window); + + // To do : The orientation will be implemented later. + SetBackground(splash_map[wgt::parse::ScreenOrientation::AUTO], window, + dimensions, app_path); + SetImage(splash_map[wgt::parse::ScreenOrientation::AUTO], window, + dimensions, app_path); + is_active_ = true; +} + +void SplashScreen::HideSplashScreen(int reason) { + + if (!is_active_) return; + if (reason == HideReason::RENDERED && + ss_info_->ready_when() != wgt::parse::ReadyWhen::FIRSTPAINT) { + return; + } + if (reason == HideReason::LOADFINISHED && + ss_info_->ready_when() != wgt::parse::ReadyWhen::COMPLETE) { + return; + } + if (reason == HideReason::CUSTOM && + ss_info_->ready_when() != wgt::parse::ReadyWhen::CUSTOM) { + return; + } + + evas_object_hide(background_); + evas_object_hide(image_); + evas_object_hide(window_); + evas_object_del(background_); + evas_object_del(image_); + evas_object_hide(window_); + background_ = nullptr; + image_ = nullptr; + window_ = nullptr; + is_active_ = false; +} + +std::pair SplashScreen::GetDimensions(Evas_Object* window) { + int w, h; + elm_win_screen_size_get(window, NULL, NULL, &w, &h); + evas_object_resize(background_, w, h); + return std::make_pair(w, h); +} + +void SplashScreen::SetBackground( + const wgt::parse::LaunchScreenData& splash_data, Evas_Object* parent, + const SplashScreenBound& bound, const std::string& app_path) { + background_ = elm_bg_add(parent); + if (!background_) return; + evas_object_resize(background_, bound.first, bound.second); + + if (splash_data.background_color != nullptr) { + elm_bg_color_set(background_, + splash_data.background_color->red, + splash_data.background_color->green, + splash_data.background_color->blue); + } + + std::vector border_values; + std::vector border_options; + + if (!splash_data.background_images.empty() && + ParseImageBorder( + splash_data.image_border, &border_values, &border_options)) { + const std::string& background_image_path = + splash_data.background_images.front().first; + + background_image_ = elm_image_add(background_); + evas_object_image_file_set(background_image_, + (app_path + background_image_path).c_str(), + NULL); + elm_image_aspect_fixed_set(background_image_, 0); + evas_object_image_border_center_fill_set(background_image_, + EVAS_BORDER_FILL_DEFAULT); + + evas_object_resize(background_image_, bound.first, bound.second); + + int border_l, border_r, border_t, border_b; + switch (border_values.size()) { + case 1: + border_l = border_r = border_t = border_b = -border_values[0]; + break; + case 2: + border_t = border_b = border_values[0]; + border_l = border_r = border_values[1]; + break; + case 4: + border_t = border_values[0]; + border_r = border_values[1]; + border_b = border_values[2]; + border_l = border_values[3]; + break; + default: + border_l = border_r = border_t = border_b = 0; + } + evas_object_image_border_set(background_image_, + border_l, + border_r, + border_t, + border_b); + // TODO(a.szulakiewi): add scaling of horizontal and vertical borders + } + + evas_object_show(background_); + evas_object_show(background_image_); + evas_object_show(parent); +} + +void SplashScreen::SetImage( + const wgt::parse::LaunchScreenData& splash_data, Evas_Object* parent, + const SplashScreenBound& bound, const std::string& app_path) { + if (!background_) return; + image_ = elm_image_add(background_); + if (!image_) return; + + if (splash_data.images.empty()) return; + + const std::string& image_path = splash_data.images.front().first; + elm_image_file_set(image_, (app_path + image_path).c_str(), NULL); + evas_object_resize(image_, bound.first, bound.second); + evas_object_show(image_); + evas_object_show(parent); +} +} // namespace atom diff --git a/atom/browser/splash_screen.h b/atom/browser/splash_screen.h new file mode 100755 index 0000000..593ff06 --- /dev/null +++ b/atom/browser/splash_screen.h @@ -0,0 +1,69 @@ +/* + * 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_RUNTIME_BROWSER_SPLASH_SCREEN_H_ +#define XWALK_RUNTIME_BROWSER_SPLASH_SCREEN_H_ + +#include +#include +#include +#include +#include + +#include +#include "wgt_manifest_handlers/launch_screen_handler.h" + +enum HideReason { RENDERED, LOADFINISHED, CUSTOM }; + +namespace atom { + +enum class ScreenOrientation { + PORTRAIT_PRIMARY = 0, + PORTRAIT_SECONDARY = 1, + LANDSCAPE_PRIMARY = 2, + LANDSCAPE_SECONDARY = 3, + NATURAL = 4, + ANY = 5 +}; + +class SplashScreen { + public: + typedef std::pair SplashScreenBound; + + SplashScreen(Evas_Object* window, + std::shared_ptr ss_info, + const std::string& app_path); + void HideSplashScreen(int reason); + + private: + std::pair GetDimensions(Evas_Object* window); + void SetBackground(const wgt::parse::LaunchScreenData& splash_data, + Evas_Object* parent, const SplashScreenBound& bound, + const std::string& app_path); + + void SetImage(const wgt::parse::LaunchScreenData& splash_data, + Evas_Object* parent, const SplashScreenBound& bound, + const std::string& app_path); + + std::shared_ptr ss_info_; + Evas_Object* window_; + Evas_Object* image_; + Evas_Object* background_; + Evas_Object* background_image_; + bool is_active_; +}; +} // namespace atom +#endif // XWALK_RUNTIME_BROWSER_SPLASH_SCREEN_H_ diff --git a/wrt.gyp b/wrt.gyp index 54377cf..d8528b0 100644 --- a/wrt.gyp +++ b/wrt.gyp @@ -27,6 +27,8 @@ 'tizen/src/wrt_main.h', 'tizen/loader/prelauncher.h', 'tizen/loader/prelauncher.cc', + 'atom/browser/splash_screen.h', + 'atom/browser/splash_screen.cc', ], 'include_dirs': [ 'tizen/src', diff --git a/wrt/src/web_window.js b/wrt/src/web_window.js index 5258234..06b1f31 100644 --- a/wrt/src/web_window.js +++ b/wrt/src/web_window.js @@ -1,5 +1,5 @@ 'use strict'; -const {BrowserWindow, app} = require('electron'); +const {BrowserWindow, app, pwrt} = require('electron'); const IPC_MESSAGE = require('./ipc_message'); const WAS_EVENT = require('./was_event'); const events = require('./events'); @@ -121,6 +121,8 @@ class WebWindow { }); this.mainWindow.webContents.on('did-finish-load', function() { webwindow_debug('WebWindow : webContents did-finish-load'); + pwrt.hideSplashScreen(1); + if(!options.show){ webwindow_debug('WebWindow : browserWindow show options is ',options.show); self.show(); -- 2.7.4 From 45869969409a9fc62ee794439931e8fc33d38599 Mon Sep 17 00:00:00 2001 From: "surya.kumar7" Date: Tue, 15 May 2018 13:44:21 +0530 Subject: [PATCH 05/16] Set default encoding for WebContents as UTF-8 Currently, the default encoding being used is ISO-8859-1 which is a single-byte encoding and is capable of only supporting limited symbols. Change it to UTF-8(multi byte encoding) just like in crosswalk to extend support for more symbols Change-Id: I92e70445ca668c8db8c258e4ad1a6d41816dd2fb Signed-off-by: surya.kumar7 --- atom/browser/atom_browser_client.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index ebbd54a..9408fcf 100644 --- a/atom/browser/atom_browser_client.cc +++ b/atom/browser/atom_browser_client.cc @@ -54,6 +54,8 @@ bool g_suppress_renderer_process_restart = false; // Custom schemes to be registered to handle service worker. std::string g_custom_service_worker_schemes = ""; +const std::string kDefaultEncoding = "UTF-8"; + void Noop(scoped_refptr) { } @@ -161,6 +163,7 @@ void AtomBrowserClient::OverrideWebkitPrefs( prefs->allow_file_access_from_file_urls = true; prefs->experimental_webgl_enabled = true; prefs->allow_running_insecure_content = false; + prefs->default_encoding = kDefaultEncoding; // Custom preferences of guest page. auto web_contents = content::WebContents::FromRenderViewHost(host); -- 2.7.4 From 08923900ea8c54f7fd42a85ace2bff2fa7fa08fb Mon Sep 17 00:00:00 2001 From: deepti Date: Fri, 11 May 2018 16:39:46 +0530 Subject: [PATCH 06/16] Initial Implementation of AppControl Function Handled condition of resetting app. Implemented SendAppControlEvent() for execution of AppControlEventscript. Change-Id: I98b9420a6f5076de598dbdbbdd0968806fc1f34f Signed-off-by: deepti --- atom/browser/browser.cc | 51 ++++++++++++++++++++++++++++++++++++++++++--- atom/browser/browser.h | 1 + atom/browser/window_list.cc | 7 +++++++ atom/browser/window_list.h | 2 +- 4 files changed, 57 insertions(+), 4 deletions(-) diff --git a/atom/browser/browser.cc b/atom/browser/browser.cc index 3ebba72..9efce42 100644 --- a/atom/browser/browser.cc +++ b/atom/browser/browser.cc @@ -14,9 +14,12 @@ #include "base/files/file_util.h" #include "base/path_service.h" #include "base/run_loop.h" +#include "base/strings/string16.h" +#include "base/strings/utf_string_conversions.h" +#include "base/values.h" #include "base/threading/thread_task_runner_handle.h" #include "brightray/browser/brightray_paths.h" - +#include "content/public/browser/render_frame_host.h" #if defined(OS_TIZEN) #include "tizen/common/command_line.h" #include "tizen/common/application_data.h" @@ -43,6 +46,19 @@ Browser::~Browser() { WindowList::RemoveObserver(this); } +const char* kAppControlMain = "http://tizen.org/appcontrol/operation/main"; +const char* kAppControlEventScript = + "(function(){" + "var __event = document.createEvent(\"CustomEvent\");\n" + "__event.initCustomEvent(\"appcontrol\", true, true, null);\n" + "document.dispatchEvent(__event);\n" + "\n" + "for(var i=0; i < window.frames.length; i++)\n" + "{ window.frames[i].document.dispatchEvent(__event); }" + "})()"; +const char* kDefaultCSPRule = + "default-src *; script-src 'self'; style-src 'self'; object-src 'none';"; + // static Browser* Browser::Get() { if (AtomBrowserMainParts::Get()) @@ -276,14 +292,43 @@ void Browser::AppControl(std::unique_ptr appcontrol) { std::unique_ptr res = resource_manager_->GetStartResource(appcontrol.get()); bool do_reset = res->should_reset(); -//To do: Implementation of reset case according to parsed config file parameter. + NativeWindow *last_window= WindowList::GetLastWindow(); + std::string localized_page = res->uri(); + if(!do_reset) + { + std::string current_page=last_window->web_contents()->GetURL().spec(); + if (current_page != localized_page) { + do_reset = true; + } else { + SendAppControlEvent(); + } + } + if (do_reset && (appcontrol->operation() == kAppControlMain)) { + do_reset = false; + SendAppControlEvent(); + } + if (do_reset) { + //To do :Implementation of ClearViewStack(), SetupWebWindow(),SetupWebWindowCompatibilitySettings() function + } +} + +void Browser::SendAppControlEvent() { + std::vector WindowVector; + WindowVector=WindowList::GetWindows(); + NativeWindow *last_window= WindowList::GetLastWindow(); + if (WindowVector.size() > 0 && last_window != NULL) { + content::RenderFrameHost* rfh = last_window->web_contents()->GetMainFrame(); + if (rfh) { + rfh->ExecuteJavaScriptWithUserGestureForTests( + base::UTF8ToUTF16(kAppControlEventScript)); + } + } } void Browser::Launch(std::unique_ptr appcontrol) { launched_ = true; //To do:Implementation of relaunching of app } - #if defined(OS_TIZEN) void Browser::SetSplashScreen() { common::CommandLine* runtime_cmd = common::CommandLine::ForCurrentProcess(); diff --git a/atom/browser/browser.h b/atom/browser/browser.h index 362bfaf..c089fff 100644 --- a/atom/browser/browser.h +++ b/atom/browser/browser.h @@ -125,6 +125,7 @@ class Browser : public WindowListObserver { void Show(); void AppControl(std::unique_ptr appcontrol); void Launch(std::unique_ptr appcontrol); + void SendAppControlEvent(); #if defined(OS_TIZEN) void SetSplashScreen(); void HideSplashScreen(int reason); diff --git a/atom/browser/window_list.cc b/atom/browser/window_list.cc index 374389e..39b91b2 100644 --- a/atom/browser/window_list.cc +++ b/atom/browser/window_list.cc @@ -32,6 +32,13 @@ WindowList::WindowVector WindowList::GetWindows() { } // static +NativeWindow* WindowList::GetLastWindow() { + if (!IsEmpty()) + return GetInstance()->windows_.back(); + else return NULL; +} + +// static bool WindowList::IsEmpty() { return GetInstance()->windows_.empty(); } diff --git a/atom/browser/window_list.h b/atom/browser/window_list.h index e336c80..bffac13 100644 --- a/atom/browser/window_list.h +++ b/atom/browser/window_list.h @@ -22,7 +22,7 @@ class WindowList { static WindowVector GetWindows(); static bool IsEmpty(); - + static NativeWindow* GetLastWindow(); // Adds or removes |window| from the list it is associated with. static void AddWindow(NativeWindow* window); static void RemoveWindow(NativeWindow* window); -- 2.7.4 From 4739f2e776784e72a8eace33defb27e85f161b63 Mon Sep 17 00:00:00 2001 From: "surya.kumar7" Date: Mon, 7 May 2018 17:06:57 +0530 Subject: [PATCH 07/16] Add preload manager and invoke preloadable objects in prelaunch phase Preloading the below engine independent components is giving ~50ms improvement in app launch: xwalk extension server AtomContentClient AtomBrowserClient Change-Id: Iee9bc108aeed0414962b301345c799807dfd043d Signed-off-by: surya.kumar7 --- atom/app/atom_main_delegate.cc | 20 +++++++++++++++-- atom/app/atom_main_delegate.h | 2 ++ atom/app/ui_runtime.cc | 2 ++ atom/browser/atom_browser_main_parts.cc | 9 ++++---- filenames.gypi | 2 ++ tizen/browser/preload_manager.cc | 40 +++++++++++++++++++++++++++++++++ tizen/browser/preload_manager.h | 35 +++++++++++++++++++++++++++++ tizen/src/wrt_main.cc | 2 ++ 8 files changed, 106 insertions(+), 6 deletions(-) create mode 100644 tizen/browser/preload_manager.cc create mode 100644 tizen/browser/preload_manager.h diff --git a/atom/app/atom_main_delegate.cc b/atom/app/atom_main_delegate.cc index 32e6ecf..b88049f 100644 --- a/atom/app/atom_main_delegate.cc +++ b/atom/app/atom_main_delegate.cc @@ -48,8 +48,13 @@ void InvalidParameterHandler(const wchar_t*, const wchar_t*, const wchar_t*, } #endif +bool g_prelaunch_ = false; +std::unique_ptr g_atom_content_client_; +std::unique_ptr g_atom_browser_client_; + } // namespace + AtomMainDelegate::AtomMainDelegate() { } @@ -162,7 +167,9 @@ void AtomMainDelegate::PreSandboxStartup() { } content::ContentBrowserClient* AtomMainDelegate::CreateContentBrowserClient() { - browser_client_.reset(new AtomBrowserClient); + if (!g_prelaunch_) + browser_client_.reset(new AtomBrowserClient); + else browser_client_.reset(g_atom_browser_client_.release()); return browser_client_.get(); } @@ -205,7 +212,16 @@ bool AtomMainDelegate::DelaySandboxInitialization( std::unique_ptr AtomMainDelegate::CreateContentClient() { - return std::unique_ptr(new AtomContentClient); + if (!g_prelaunch_) + return std::unique_ptr(new AtomContentClient); + else return std::unique_ptr(g_atom_content_client_.release()); +} + +// static +void AtomMainDelegate::Preload() { + g_atom_content_client_.reset(new AtomContentClient); + g_atom_browser_client_.reset(new AtomBrowserClient); + g_prelaunch_ = true; } } // namespace atom diff --git a/atom/app/atom_main_delegate.h b/atom/app/atom_main_delegate.h index 64207ae..d768ddf 100644 --- a/atom/app/atom_main_delegate.h +++ b/atom/app/atom_main_delegate.h @@ -17,6 +17,8 @@ class AtomMainDelegate : public brightray::MainDelegate { AtomMainDelegate(); ~AtomMainDelegate(); + static void Preload(); + protected: // content::ContentMainDelegate: bool BasicStartupComplete(int* exit_code) override; diff --git a/atom/app/ui_runtime.cc b/atom/app/ui_runtime.cc index e13e1bf..27f7e0e 100644 --- a/atom/app/ui_runtime.cc +++ b/atom/app/ui_runtime.cc @@ -39,6 +39,8 @@ namespace runtime { UiRuntime::UiRuntime(content::ContentMainParams *params) { _params = params; + // This line's position is essential as this creates the Browser + // object which is needed later on by ui_runtime in its ui_loop callbacks atom::AtomBrowserMainParts::SetNodeEnvironment(); } diff --git a/atom/browser/atom_browser_main_parts.cc b/atom/browser/atom_browser_main_parts.cc index f718f86..3ea0c3e 100644 --- a/atom/browser/atom_browser_main_parts.cc +++ b/atom/browser/atom_browser_main_parts.cc @@ -61,11 +61,8 @@ void Erase(T* container, typename T::iterator iter) { container->erase(iter); } -} // namespace - -// static +// static - lines have been moved to limit their visibility only to this file bool g_prelaunch = false; -AtomBrowserMainParts* AtomBrowserMainParts::self_ = nullptr; node::Environment* env_ = nullptr; scoped_refptr self_bridge_task_runner; std::unique_ptr self_browser; @@ -75,6 +72,10 @@ std::unique_ptr self_atom_bindings; std::unique_ptr self_node_env; std::unique_ptr self_node_debugger; +} // namespace + +AtomBrowserMainParts* AtomBrowserMainParts::self_ = nullptr; + AtomBrowserMainParts::AtomBrowserMainParts() : fake_browser_process_(new BrowserProcess), exit_code_(nullptr), diff --git a/filenames.gypi b/filenames.gypi index 8408b27..0535fab 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -636,6 +636,8 @@ 'chromium_src/net/test/embedded_test_server/stream_listen_socket.h', 'chromium_src/net/test/embedded_test_server/tcp_listen_socket.cc', 'chromium_src/net/test/embedded_test_server/tcp_listen_socket.h', + 'tizen/browser/preload_manager.cc', + 'tizen/browser/preload_manager.h', '<@(native_mate_files)', '<(SHARED_INTERMEDIATE_DIR)/atom_natives.h', '<(SHARED_INTERMEDIATE_DIR)/grit/pdf_viewer_resources_map.cc', diff --git a/tizen/browser/preload_manager.cc b/tizen/browser/preload_manager.cc new file mode 100644 index 0000000..18c645d --- /dev/null +++ b/tizen/browser/preload_manager.cc @@ -0,0 +1,40 @@ +/* + * 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 "tizen/browser/preload_manager.h" + +#include "atom/app/atom_main_delegate.h" +#include "extensions/common/xwalk_extension_server.h" + +namespace tizen { + +PreloadManager* PreloadManager::GetInstance() { + static PreloadManager instance; + return &instance; +} + +PreloadManager::PreloadManager() { +} + +void PreloadManager::CreateCacheComponent() { + // Load extensions in the preload step + auto extension_server = extensions::XWalkExtensionServer::GetInstance(); + extension_server->Preload(); + + atom::AtomMainDelegate::Preload(); +} + +} // namespace tizen diff --git a/tizen/browser/preload_manager.h b/tizen/browser/preload_manager.h new file mode 100644 index 0000000..4f06612 --- /dev/null +++ b/tizen/browser/preload_manager.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2018 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 TIZEN_BROWSER_PRELOAD_MANAGER_H_ +#define TIZEN_BROWSER_PRELOAD_MANAGER_H_ + +#include + + +namespace tizen { +class PreloadManager { + public: + static PreloadManager* GetInstance(); + void CreateCacheComponent(); + + private: + PreloadManager(); +}; + +} // namespace tizen + +#endif // TIZEN_BROWSER_PRELOAD_MANAGER_H_ diff --git a/tizen/src/wrt_main.cc b/tizen/src/wrt_main.cc index 0bf3635..8c8052b 100644 --- a/tizen/src/wrt_main.cc +++ b/tizen/src/wrt_main.cc @@ -44,6 +44,7 @@ #include "tizen/common/application_data.h" #include "tizen/common/command_line.h" #include "tizen/loader/prelauncher.h" +#include "tizen/browser/preload_manager.h" #endif namespace { @@ -236,6 +237,7 @@ int main(int argc, const char* argv[]) { params.argv = const_cast(argv); atom::AtomCommandLine::Init(argc, argv); runtime_ = runtime::Runtime::MakeRuntime(nullptr); + tizen::PreloadManager::GetInstance()->CreateCacheComponent(); return 0; }; auto did_launch = [](const std::string& app_path) { -- 2.7.4 From 1ab663ee093e7a138f14727859f8bc46fad21cd0 Mon Sep 17 00:00:00 2001 From: deepti Date: Wed, 23 May 2018 10:54:04 +0530 Subject: [PATCH 08/16] Refactored code by removing extra check for vector size in SendAppControlEvent function. Removed extra header files and made proper indent. Change-Id: I21281e5009e9c5c3ed7d404f9a0ced7a4c273a7b Signed-off-by: deepti --- atom/browser/browser.cc | 40 +++++++++++++++++----------------------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/atom/browser/browser.cc b/atom/browser/browser.cc index 9efce42..7e87db2 100644 --- a/atom/browser/browser.cc +++ b/atom/browser/browser.cc @@ -14,9 +14,7 @@ #include "base/files/file_util.h" #include "base/path_service.h" #include "base/run_loop.h" -#include "base/strings/string16.h" #include "base/strings/utf_string_conversions.h" -#include "base/values.h" #include "base/threading/thread_task_runner_handle.h" #include "brightray/browser/brightray_paths.h" #include "content/public/browser/render_frame_host.h" @@ -292,37 +290,33 @@ void Browser::AppControl(std::unique_ptr appcontrol) { std::unique_ptr res = resource_manager_->GetStartResource(appcontrol.get()); bool do_reset = res->should_reset(); - NativeWindow *last_window= WindowList::GetLastWindow(); + NativeWindow *last_window = WindowList::GetLastWindow(); std::string localized_page = res->uri(); - if(!do_reset) - { - std::string current_page=last_window->web_contents()->GetURL().spec(); - if (current_page != localized_page) { - do_reset = true; - } else { - SendAppControlEvent(); - } - } + if (!do_reset) { + std::string current_page = last_window->web_contents()->GetURL().spec(); + if (current_page != localized_page) + do_reset = true; + else + SendAppControlEvent(); + } if (do_reset && (appcontrol->operation() == kAppControlMain)) { do_reset = false; SendAppControlEvent(); } - if (do_reset) { - //To do :Implementation of ClearViewStack(), SetupWebWindow(),SetupWebWindowCompatibilitySettings() function - } + if (do_reset) + //To do :Implementation of ClearViewStack(), SetupWebWindow(),SetupWebWindowCompatibilitySettings() function } void Browser::SendAppControlEvent() { - std::vector WindowVector; - WindowVector=WindowList::GetWindows(); - NativeWindow *last_window= WindowList::GetLastWindow(); - if (WindowVector.size() > 0 && last_window != NULL) { - content::RenderFrameHost* rfh = last_window->web_contents()->GetMainFrame(); - if (rfh) { + NativeWindow *last_window = WindowList::GetLastWindow(); + + if (last_window != NULL) { + content::RenderFrameHost* rfh = last_window->web_contents()->GetMainFrame(); + if (rfh) { rfh->ExecuteJavaScriptWithUserGestureForTests( - base::UTF8ToUTF16(kAppControlEventScript)); + base::UTF8ToUTF16(kAppControlEventScript)); } - } + } } void Browser::Launch(std::unique_ptr appcontrol) { -- 2.7.4 From cf48ec941673a8449feac35a2c93075e8317f2c5 Mon Sep 17 00:00:00 2001 From: deepti Date: Mon, 4 Jun 2018 12:56:11 +0530 Subject: [PATCH 09/16] fixup! Refactored code by removing extra check for vector size in SendAppControlEvent function. Removed extra header files and made proper indent. The original patch has build error and this fixes the same. Change-Id: I912029c37dd5085a2dd2792c3ac22485ab58bc19 Signed-off-by: deepti --- atom/browser/browser.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/atom/browser/browser.cc b/atom/browser/browser.cc index 7e87db2..fc2c7a4 100644 --- a/atom/browser/browser.cc +++ b/atom/browser/browser.cc @@ -303,8 +303,9 @@ void Browser::AppControl(std::unique_ptr appcontrol) { do_reset = false; SendAppControlEvent(); } - if (do_reset) + if (do_reset) { //To do :Implementation of ClearViewStack(), SetupWebWindow(),SetupWebWindowCompatibilitySettings() function + } } void Browser::SendAppControlEvent() { -- 2.7.4 From 63823db6a5a7f0630479bb7b9c2d3b181ed74e3e Mon Sep 17 00:00:00 2001 From: "k2.nagaraju" Date: Fri, 11 May 2018 15:29:28 +0530 Subject: [PATCH 10/16] Expose the visibility of classes of chromium for web device api. removed duplicate code from WRT Change-Id: I41ddadd07ef4cdf961a4a470ae311351235b9028 Signed-off-by: k2.nagaraju --- atom/browser/api/atom_api_web_contents.cc | 18 +-- atom/browser/api/atom_api_web_contents.h | 8 +- atom/common/api/api_messages.h | 23 +-- atom/renderer/atom_renderer_client.cc | 18 +-- atom/renderer/atom_renderer_client.h | 2 +- packaging/electron-efl.spec | 3 - tizen/common/common.gyp | 2 - tizen/common/wrt_message_data.cc | 38 ----- tizen/common/wrt_message_data.h | 26 ---- tizen/extensions/common/xwalk_extension_server.cc | 51 +++---- tizen/extensions/common/xwalk_extension_server.h | 17 ++- tizen/extensions/extensions.gyp | 2 + tizen/extensions/renderer/runtime_ipc_client.cc | 54 +++---- tizen/extensions/renderer/runtime_ipc_client.h | 5 +- .../xwalk_extension_renderer_controller.cc | 8 +- .../renderer/xwalk_extension_renderer_controller.h | 5 +- tizen/renderer/injected_bundle.cc | 5 +- tizen/wrt/chromium_wrt.gyp | 55 ------- tizen/wrt/dynamicplugin.cc | 89 ----------- tizen/wrt/dynamicplugin.h | 46 ------ tizen/wrt/v8widget.cc | 92 ------------ tizen/wrt/v8widget.h | 41 ------ tizen/wrt/wrt_dynamicplugin.cc | 164 --------------------- tizen/wrt/wrt_dynamicplugin.h | 71 --------- tizen/wrt/wrt_file_protocol_handler.cc | 110 -------------- tizen/wrt/wrt_file_protocol_handler.h | 46 ------ tizen/wrt/wrt_widget_host.cc | 164 --------------------- tizen/wrt/wrt_widget_host.h | 89 ----------- tizen/wrt/wrtwidget.cc | 97 ------------ tizen/wrt/wrtwidget.h | 45 ------ .../ewk/efl_integration/private/ewk_wrt_private.h | 2 +- .../ewk/efl_integration/wrt/wrt_widget_host.h | 2 +- .../tizen_src/ewk/efl_integration/wrt/wrtwidget.h | 2 +- wrt.gyp | 2 +- 34 files changed, 104 insertions(+), 1298 deletions(-) delete mode 100644 tizen/common/wrt_message_data.cc delete mode 100644 tizen/common/wrt_message_data.h delete mode 100644 tizen/wrt/chromium_wrt.gyp delete mode 100644 tizen/wrt/dynamicplugin.cc delete mode 100644 tizen/wrt/dynamicplugin.h delete mode 100644 tizen/wrt/v8widget.cc delete mode 100644 tizen/wrt/v8widget.h delete mode 100644 tizen/wrt/wrt_dynamicplugin.cc delete mode 100644 tizen/wrt/wrt_dynamicplugin.h delete mode 100644 tizen/wrt/wrt_file_protocol_handler.cc delete mode 100644 tizen/wrt/wrt_file_protocol_handler.h delete mode 100644 tizen/wrt/wrt_widget_host.cc delete mode 100644 tizen/wrt/wrt_widget_host.h delete mode 100644 tizen/wrt/wrtwidget.cc delete mode 100644 tizen/wrt/wrtwidget.h diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 8474a5b..cac60af 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -903,21 +903,21 @@ void WebContents::DevToolsClosed() { Emit("devtools-closed"); } -void WebContents::OnWrtPluginMessage(const Wrt_Message_Data& data) { - Wrt_Message_Data tmp = data; +void WebContents::OnWrtPluginMessage(const Ewk_Wrt_Message_Data& data) { + Ewk_Wrt_Message_Data tmp = data; HandleWrtPluginMessage(&tmp); } -void WebContents::OnWrtPluginSyncMessage(const Wrt_Message_Data& data, +void WebContents::OnWrtPluginSyncMessage(const Ewk_Wrt_Message_Data& data, IPC::Message* reply) { - Wrt_Message_Data tmp = data; + Ewk_Wrt_Message_Data tmp = data; HandleWrtPluginMessage(&tmp); - EwkHostMsg_WrtSyncMessage::WriteReplyParams(reply, tmp.value); + AtomHostMsg_WrtSyncMessage::WriteReplyParams(reply, tmp.value); Send(reply); } -void WebContents::HandleWrtPluginMessage(Wrt_Message_Data* msg) { - Eina_Stringshare* msg_type = msg->GetType(); +void WebContents::HandleWrtPluginMessage(Ewk_Wrt_Message_Data* msg) { + Eina_Stringshare* msg_type = ewk_ipc_wrt_message_data_type_get(msg); #define TYPE_BEGIN(x) (!strncmp(msg_type, x, strlen(x))) #define TYPE_IS(x) (!strcmp(msg_type, x)) @@ -940,8 +940,8 @@ bool WebContents::OnMessageReceived(const IPC::Message& message) { OnSetTemporaryZoomLevel) IPC_MESSAGE_HANDLER_DELAY_REPLY(AtomViewHostMsg_GetZoomLevel, OnGetZoomLevel) - IPC_MESSAGE_HANDLER(EwkHostMsg_WrtMessage, OnWrtPluginMessage) - IPC_MESSAGE_HANDLER_DELAY_REPLY(EwkHostMsg_WrtSyncMessage, OnWrtPluginSyncMessage) + IPC_MESSAGE_HANDLER(AtomHostMsg_WrtMessage, OnWrtPluginMessage) + IPC_MESSAGE_HANDLER_DELAY_REPLY(AtomHostMsg_WrtSyncMessage, OnWrtPluginSyncMessage) // FIXME: Disable OnCursorChange due to stach_chk_fail crash. // IPC_MESSAGE_HANDLER_CODE(ViewHostMsg_SetCursor, OnCursorChange, // handled = false) diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 4407b3c..ef1578c 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -18,7 +18,7 @@ #include "content/public/browser/web_contents_observer.h" #include "content/public/common/favicon_url.h" #include "native_mate/handle.h" -#include "tizen/common/wrt_message_data.h" +#include "tizen_src/ewk/efl_integration/private/ewk_wrt_private.h" #include "ui/gfx/image/image.h" namespace blink { @@ -218,10 +218,10 @@ class WebContents : public mate::TrackableObject, v8::Local Debugger(v8::Isolate* isolate); WebContentsZoomController* GetZoomController() { return zoom_controller_; } - void OnWrtPluginMessage(const Wrt_Message_Data& data); - void OnWrtPluginSyncMessage(const Wrt_Message_Data& data, + void OnWrtPluginMessage(const Ewk_Wrt_Message_Data& data); + void OnWrtPluginSyncMessage(const Ewk_Wrt_Message_Data& data, IPC::Message* reply); - void HandleWrtPluginMessage(Wrt_Message_Data* msg); + void HandleWrtPluginMessage(Ewk_Wrt_Message_Data* msg); protected: WebContents(v8::Isolate* isolate, content::WebContents* web_contents, diff --git a/atom/common/api/api_messages.h b/atom/common/api/api_messages.h index cffc9df..5052c40 100644 --- a/atom/common/api/api_messages.h +++ b/atom/common/api/api_messages.h @@ -9,7 +9,7 @@ #include "base/values.h" #include "content/public/common/common_param_traits.h" #include "ipc/ipc_message_macros.h" -#include "tizen/common/wrt_message_data.h" +#include "tizen_src/ewk/efl_integration/private/ewk_wrt_private.h" #include "ui/gfx/ipc/gfx_param_traits.h" // The message starter should be declared in ipc/ipc_message_start.h. Since @@ -22,7 +22,7 @@ IPC_STRUCT_TRAITS_BEGIN(atom::DraggableRegion) IPC_STRUCT_TRAITS_MEMBER(bounds) IPC_STRUCT_TRAITS_END() -IPC_STRUCT_TRAITS_BEGIN(Wrt_Message_Data) +IPC_STRUCT_TRAITS_BEGIN(Ewk_Wrt_Message_Data) IPC_STRUCT_TRAITS_MEMBER(type) IPC_STRUCT_TRAITS_MEMBER(value) IPC_STRUCT_TRAITS_MEMBER(id) @@ -58,20 +58,9 @@ IPC_SYNC_MESSAGE_ROUTED1_1(AtomViewHostMsg_SetTemporaryZoomLevel, // Sent by renderer to get the zoom level. IPC_SYNC_MESSAGE_ROUTED0_1(AtomViewHostMsg_GetZoomLevel, double /* result */) -IPC_MESSAGE_ROUTED1(EwkHostMsg_WrtMessage, - Wrt_Message_Data /* data */) +IPC_MESSAGE_ROUTED1(AtomHostMsg_WrtMessage, + Ewk_Wrt_Message_Data /* data */) -IPC_MESSAGE_CONTROL1(WrtMsg_SendWrtMessage, - Wrt_Message_Data /* data */) - -IPC_MESSAGE_CONTROL2(WrtMsg_ParseUrl, - int, // result: request_id - GURL) // result: url - -IPC_MESSAGE_CONTROL2(WrtMsg_ParseUrlResponse, - int, // result: request_id - GURL) // result: url - -IPC_SYNC_MESSAGE_ROUTED1_1(EwkHostMsg_WrtSyncMessage, - Wrt_Message_Data /* data */, +IPC_SYNC_MESSAGE_ROUTED1_1(AtomHostMsg_WrtSyncMessage, + Ewk_Wrt_Message_Data /* data */, std::string /*result*/) diff --git a/atom/renderer/atom_renderer_client.cc b/atom/renderer/atom_renderer_client.cc index 77b5eb0..aa3b881 100644 --- a/atom/renderer/atom_renderer_client.cc +++ b/atom/renderer/atom_renderer_client.cc @@ -13,6 +13,7 @@ #include "content/common/wrt/wrt_url_parse.h" #include "content/public/renderer/render_thread.h" #include "content/public/renderer/render_view.h" +#include "tizen_src/ewk/efl_integration/wrt/wrtwidget.h" #include "third_party/WebKit/public/web/WebView.h" #endif #include "atom_natives.h" // NOLINT: This file is generated with js2c @@ -58,22 +59,6 @@ const char** StringVectorToArgArray( } // namespace -class WrtUrlParseImpl : public content::WrtUrlParseBase { - public: - WrtUrlParseImpl(WrtWidget* wrt_widget) : wrt_widget_(wrt_widget) {} - GURL parseUrl(const GURL& old_url) const override { - if (!wrt_widget_->IsWidgetInfoSet()) - return old_url; - GURL new_url; - bool is_decrypted_file = false; - wrt_widget_->ParseUrl(old_url, new_url, is_decrypted_file); - return new_url; - } - - private: - WrtWidget* wrt_widget_; -}; - AtomRendererClient::AtomRendererClient() : node_integration_initialized_(false), node_bindings_(NodeBindings::Create(NodeBindings::RENDERER)), @@ -105,7 +90,6 @@ void AtomRendererClient::RenderThreadStarted() { widget_.reset(wrt_widget); content::RenderThread* thread = content::RenderThread::Get(); thread->AddObserver(wrt_widget->GetObserver()); - wrt_url_parser_.reset(new WrtUrlParseImpl(wrt_widget)); std::string theme = command_line->GetSwitchValueASCII("widget-theme"); std::string encoded_bundle = command_line->GetSwitchValueASCII("widget-encoded-bundle"); std::string scale = command_line->GetSwitchValueASCII("widget-scale"); diff --git a/atom/renderer/atom_renderer_client.h b/atom/renderer/atom_renderer_client.h index 0e623b5..2818ecc 100644 --- a/atom/renderer/atom_renderer_client.h +++ b/atom/renderer/atom_renderer_client.h @@ -9,7 +9,7 @@ #include #include "atom/renderer/renderer_client_base.h" -#include "tizen/wrt/wrtwidget.h" +#include "tizen_src/ewk/efl_integration/wrt/wrtwidget.h" namespace atom { diff --git a/packaging/electron-efl.spec b/packaging/electron-efl.spec index bafe82b..7e464c1 100755 --- a/packaging/electron-efl.spec +++ b/packaging/electron-efl.spec @@ -140,8 +140,6 @@ mkdir -p %{buildroot}%{extension_path} 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} -# wrt chromium shared -install -p -m 644 %{_out}/lib/libchromium_wrt_shared.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'. @@ -174,4 +172,3 @@ rm -fr %{buildroot} %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 -%attr(644,root,root) %{_libdir}/libchromium_wrt_shared.so diff --git a/tizen/common/common.gyp b/tizen/common/common.gyp index be5a8ec..7706dd2 100644 --- a/tizen/common/common.gyp +++ b/tizen/common/common.gyp @@ -34,8 +34,6 @@ 'resource_manager.cc', 'platform_info.h', 'platform_info.cc', - 'wrt_message_data.h', - 'wrt_message_data.cc', ], 'cflags': [ '-fvisibility=default', diff --git a/tizen/common/wrt_message_data.cc b/tizen/common/wrt_message_data.cc deleted file mode 100644 index 7b60902..0000000 --- a/tizen/common/wrt_message_data.cc +++ /dev/null @@ -1,38 +0,0 @@ -#include "wrt_message_data.h" - -Wrt_Message_Data::Wrt_Message_Data() {} - -Wrt_Message_Data::~Wrt_Message_Data() {} - -Eina_Stringshare* Wrt_Message_Data::GetType() const { - return eina_stringshare_add(type.c_str()); -} - -void Wrt_Message_Data::SetType(const char* val) { - type = val; -} - -Eina_Stringshare* Wrt_Message_Data::GetValue() const { - return eina_stringshare_add(value.c_str()); -} - -void Wrt_Message_Data::SetValue(const char* val) { - value = val; -} - -Eina_Stringshare* Wrt_Message_Data::GetId() const { - return eina_stringshare_add(id.c_str()); -} - -void Wrt_Message_Data::SetId(const char* val) { - id = val; -} - -Eina_Stringshare* Wrt_Message_Data::GetReferenceId() const { - return eina_stringshare_add(reference_id.c_str()); -} - -void Wrt_Message_Data::SetReferenceId(const char* val) { - reference_id = val; -} - diff --git a/tizen/common/wrt_message_data.h b/tizen/common/wrt_message_data.h deleted file mode 100644 index 81e7213..0000000 --- a/tizen/common/wrt_message_data.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef WRT_MESSAGE_DATA_H -#define WRT_MESSAGE_DATA_H - -#include -#include - -struct Wrt_Message_Data { - std::string type; - std::string value; - std::string id; - std::string reference_id; - - Wrt_Message_Data(); - ~Wrt_Message_Data(); - const Eina_Stringshare* GetType() const; - void SetType(const char* val); - const Eina_Stringshare* GetValue() const; - void SetValue(const char* val); - const Eina_Stringshare* GetId() const; - void SetId(const char* val); - const Eina_Stringshare* GetReferenceId() const; - void SetReferenceId(const char* val); -}; - -#endif // WRT_MESSAGE_DATA_H - diff --git a/tizen/extensions/common/xwalk_extension_server.cc b/tizen/extensions/common/xwalk_extension_server.cc index 3cf0acd..06c45e0 100644 --- a/tizen/extensions/common/xwalk_extension_server.cc +++ b/tizen/extensions/common/xwalk_extension_server.cc @@ -15,7 +15,7 @@ #include "content/public/browser/render_process_host.h" #include "extensions/common/constants.h" #include "extensions/common/xwalk_extension_manager.h" -#include "wrt/wrt_widget_host.h" +#include "tizen_src/ewk/efl_integration/wrt/wrt_widget_host.h" namespace extensions { @@ -83,12 +83,12 @@ std::string XWalkExtensionServer::CreateInstance( instance_id = common::utils::GenerateUUID(); instance->SetPostMessageCallback( [this, instance_id](const std::string& msg) { - Wrt_Message_Data* ans = new Wrt_Message_Data(); - ans->SetType(kMethodPostMessageToJS); - ans->SetId(instance_id.c_str()); - ans->SetValue(msg.c_str()); + 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()); WrtWidgetHost::Get()->SendWrtMessage(*ans); - delete ans; + ewk_ipc_wrt_message_data_del(ans); }); instances_[instance_id] = instance; @@ -103,12 +103,13 @@ std::string XWalkExtensionServer::CreateInstance( return instance_id; } -void XWalkExtensionServer::HandleIPCMessage(Wrt_Message_Data* data) { +void XWalkExtensionServer::HandleIPCMessage(Ewk_IPC_Wrt_Message_Data* data) { if (!data) { LOGGER(ERROR) << "Invalid parameter. data is NULL."; return; } - Eina_Stringshare* msg_type = data->GetType(); + + Eina_Stringshare* msg_type = ewk_ipc_wrt_message_data_type_get(data); #define TYPE_IS(x) (!strcmp(msg_type, x)) if (TYPE_IS(kMethodGetExtensions)) { @@ -129,27 +130,27 @@ void XWalkExtensionServer::HandleIPCMessage(Wrt_Message_Data* data) { #undef TYPE_IS } -void XWalkExtensionServer::HandleGetExtensions(Wrt_Message_Data* data) { +void XWalkExtensionServer::HandleGetExtensions(Ewk_IPC_Wrt_Message_Data* data) { Json::Value reply = GetExtensions(); Json::FastWriter writer; std::string reply_str = writer.write(reply); - data->SetValue(reply_str.c_str()); + ewk_ipc_wrt_message_data_value_set(data, reply_str.c_str()); } void XWalkExtensionServer::HandleCreateInstance( - Wrt_Message_Data* data) { - Eina_Stringshare* extension_name = data->GetValue(); + 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); - data->SetValue(instance_id.c_str()); + ewk_ipc_wrt_message_data_value_set(data, instance_id.c_str()); eina_stringshare_del(extension_name); } void XWalkExtensionServer::HandleDestroyInstance( - Wrt_Message_Data* data) { - Eina_Stringshare* instance_id = data->GetId(); + 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()) { @@ -164,12 +165,12 @@ void XWalkExtensionServer::HandleDestroyInstance( } void XWalkExtensionServer::HandlePostMessageToNative( - Wrt_Message_Data* data) { - Eina_Stringshare* instance_id = data->GetId(); + 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 = data->GetValue(); + Eina_Stringshare* msg = ewk_ipc_wrt_message_data_value_get(data); XWalkExtensionInstance* instance = it->second; instance->HandleMessage(msg); eina_stringshare_del(msg); @@ -181,19 +182,19 @@ void XWalkExtensionServer::HandlePostMessageToNative( } void XWalkExtensionServer::HandleSendSyncMessageToNative( - Wrt_Message_Data* data) { - Eina_Stringshare* instance_id = data->GetId(); + 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 = data->GetValue(); + 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); - data->SetValue(reply.c_str()); + ewk_ipc_wrt_message_data_value_set(data, reply.c_str()); eina_stringshare_del(msg); } else { LOGGER(ERROR) << "No such instance '" << instance_id << "'"; @@ -203,12 +204,12 @@ void XWalkExtensionServer::HandleSendSyncMessageToNative( } void XWalkExtensionServer::HandleGetAPIScript( - Wrt_Message_Data* data) { - Eina_Stringshare* extension_name = data->GetValue(); + Ewk_IPC_Wrt_Message_Data* data) { + Eina_Stringshare* extension_name = ewk_ipc_wrt_message_data_value_get(data); std::string api = GetAPIScript(extension_name); - data->SetValue(api.c_str()); + ewk_ipc_wrt_message_data_value_set(data, api.c_str()); eina_stringshare_del(extension_name); } diff --git a/tizen/extensions/common/xwalk_extension_server.h b/tizen/extensions/common/xwalk_extension_server.h index 7a45752..a778a5b 100644 --- a/tizen/extensions/common/xwalk_extension_server.h +++ b/tizen/extensions/common/xwalk_extension_server.h @@ -5,11 +5,12 @@ #ifndef XWALK_EXTENSIONS_XWALK_EXTENSION_SERVER_H_ #define XWALK_EXTENSIONS_XWALK_EXTENSION_SERVER_H_ +#include +#include #include #include #include -#include "common/wrt_message_data.h" #include "extensions/common/xwalk_extension_manager.h" #include "extensions/common/xwalk_extension_instance.h" @@ -24,7 +25,7 @@ class XWalkExtensionServer { std::string GetAPIScript(const std::string& extension_name); std::string CreateInstance(const std::string& extension_name); - void HandleIPCMessage(Wrt_Message_Data* data); + void HandleIPCMessage(Ewk_IPC_Wrt_Message_Data* data); void Shutdown(); void LoadUserExtensions(const std::string app_path); @@ -33,12 +34,12 @@ class XWalkExtensionServer { XWalkExtensionServer(); virtual ~XWalkExtensionServer(); - void HandleGetExtensions(Wrt_Message_Data* data); - void HandleCreateInstance(Wrt_Message_Data* data); - void HandleDestroyInstance(Wrt_Message_Data* data); - void HandlePostMessageToNative(Wrt_Message_Data* data); - void HandleSendSyncMessageToNative(Wrt_Message_Data* data); - void HandleGetAPIScript(Wrt_Message_Data* data); + 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 InstanceMap; diff --git a/tizen/extensions/extensions.gyp b/tizen/extensions/extensions.gyp index 163361d..652dfd1 100644 --- a/tizen/extensions/extensions.gyp +++ b/tizen/extensions/extensions.gyp @@ -49,6 +49,8 @@ '.', '../..', '<(libchromiumcontent_src_dir)', + '<(libchromiumcontent_src_dir)/tizen_src/ewk/efl_integration', + '<(libchromiumcontent_src_dir)/tizen_src/chromium_impl', '<(SHARED_INTERMEDIATE_DIR)', '<(libchromiumcontent_src_dir)/gen', '<(libchromiumcontent_src_dir)/third_party/skia/include/config', diff --git a/tizen/extensions/renderer/runtime_ipc_client.cc b/tizen/extensions/renderer/runtime_ipc_client.cc index f64676b..036dc7f 100644 --- a/tizen/extensions/renderer/runtime_ipc_client.cc +++ b/tizen/extensions/renderer/runtime_ipc_client.cc @@ -115,16 +115,16 @@ void RuntimeIPCClient::SendMessage(v8::Handle context, return; } - Wrt_Message_Data* msg = new Wrt_Message_Data(); - msg->SetType(type.c_str()); - msg->SetId(id.c_str()); - msg->SetValue(value.c_str()); - msg->SetReferenceId(ref_id.c_str()); + 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()); content::RenderView* render_view = content::RenderView::FromRoutingID(routing_id); render_view->Send( - new EwkHostMsg_WrtMessage(render_view->GetRoutingID(), *msg)); - delete msg; + new AtomHostMsg_WrtMessage(render_view->GetRoutingID(), *msg)); + ewk_ipc_wrt_message_data_del(msg); } std::string RuntimeIPCClient::SendSyncMessage(v8::Handle context, @@ -151,20 +151,22 @@ std::string RuntimeIPCClient::SendSyncMessage(v8::Handle context, return std::string(); } - Wrt_Message_Data* msg = new Wrt_Message_Data(); - msg->SetType(type.c_str()); - msg->SetId(id.c_str()); - msg->SetValue(value.c_str()); - msg->SetReferenceId(ref_id.c_str()); + 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()); + content::RenderView* render_view = content::RenderView::FromRoutingID(routing_id); render_view->Send( - new EwkHostMsg_WrtSyncMessage(render_view->GetRoutingID(), *msg, &msg->value)); - Eina_Stringshare* msg_value = msg->GetValue(); + new AtomHostMsg_WrtSyncMessage(render_view->GetRoutingID(), *msg, &msg->value)); + + Eina_Stringshare* msg_value = ewk_ipc_wrt_message_data_value_get(msg); std::string result(msg_value); eina_stringshare_del(msg_value); - delete msg; + ewk_ipc_wrt_message_data_del(msg); return result; } @@ -181,27 +183,29 @@ void RuntimeIPCClient::SendAsyncMessage(v8::Handle context, std::string msg_id = common::utils::GenerateUUID(); - Wrt_Message_Data* msg = new Wrt_Message_Data(); - msg->SetType(type.c_str()); - msg->SetId(msg_id.c_str()); - msg->SetValue(value.c_str()); + 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()); + content::RenderView* render_view = content::RenderView::FromRoutingID(routing_id); render_view->Send( - new EwkHostMsg_WrtMessage(render_view->GetRoutingID(), *msg)); + new AtomHostMsg_WrtMessage(render_view->GetRoutingID(), *msg)); + callbacks_[msg_id] = callback; - delete msg; + ewk_ipc_wrt_message_data_del(msg); } void RuntimeIPCClient::HandleMessageFromRuntime( - const Wrt_Message_Data* msg) { + const Ewk_IPC_Wrt_Message_Data* msg) { if (msg == NULL) { LOGGER(ERROR) << "received message is NULL"; return; } - Eina_Stringshare* msg_refid = msg->GetReferenceId(); + 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); @@ -216,8 +220,8 @@ void RuntimeIPCClient::HandleMessageFromRuntime( return; } - Eina_Stringshare* msg_type = msg->GetType(); - Eina_Stringshare* msg_value = msg->GetValue(); + 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) { diff --git a/tizen/extensions/renderer/runtime_ipc_client.h b/tizen/extensions/renderer/runtime_ipc_client.h index 8f40d16..ab28489 100644 --- a/tizen/extensions/renderer/runtime_ipc_client.h +++ b/tizen/extensions/renderer/runtime_ipc_client.h @@ -17,12 +17,13 @@ #ifndef XWALK_EXTENSIONS_RENDERER_RUNTIME_IPC_CLIENT_H_ #define XWALK_EXTENSIONS_RENDERER_RUNTIME_IPC_CLIENT_H_ +#include +#include #include #include #include #include -#include "common/wrt_message_data.h" namespace extensions { @@ -82,7 +83,7 @@ class RuntimeIPCClient { const std::string& type, const std::string& value, ReplyCallback callback); - void HandleMessageFromRuntime(const Wrt_Message_Data* msg); + void HandleMessageFromRuntime(const Ewk_Wrt_Message_Data* msg); int GetRoutingId(v8::Handle context); diff --git a/tizen/extensions/renderer/xwalk_extension_renderer_controller.cc b/tizen/extensions/renderer/xwalk_extension_renderer_controller.cc index 982ab23..2c0a6e2 100644 --- a/tizen/extensions/renderer/xwalk_extension_renderer_controller.cc +++ b/tizen/extensions/renderer/xwalk_extension_renderer_controller.cc @@ -100,14 +100,14 @@ void XWalkExtensionRendererController::WillReleaseScriptContext( } void XWalkExtensionRendererController::OnReceivedIPCMessage( - const Wrt_Message_Data* data) { + const Ewk_IPC_Wrt_Message_Data* data) { - Eina_Stringshare* type = data->GetType(); + 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 = data->GetId(); - Eina_Stringshare* msg = data->GetValue(); + 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); diff --git a/tizen/extensions/renderer/xwalk_extension_renderer_controller.h b/tizen/extensions/renderer/xwalk_extension_renderer_controller.h index 8fe5ff4..86e66fb 100644 --- a/tizen/extensions/renderer/xwalk_extension_renderer_controller.h +++ b/tizen/extensions/renderer/xwalk_extension_renderer_controller.h @@ -6,11 +6,12 @@ #ifndef XWALK_EXTENSIONS_RENDERER_XWALK_EXTENSION_RENDERER_CONTROLLER_H_ #define XWALK_EXTENSIONS_RENDERER_XWALK_EXTENSION_RENDERER_CONTROLLER_H_ +#include +#include #include #include #include -#include "common/wrt_message_data.h" namespace extensions { @@ -24,7 +25,7 @@ class XWalkExtensionRendererController { void DidCreateScriptContext(v8::Handle context); void WillReleaseScriptContext(v8::Handle context); - void OnReceivedIPCMessage(const Wrt_Message_Data* data); + void OnReceivedIPCMessage(const Ewk_Wrt_Message_Data* data); void InitializeExtensionClient(); void LoadUserExtensions(const std::string app_path); diff --git a/tizen/renderer/injected_bundle.cc b/tizen/renderer/injected_bundle.cc index cce38e6..e3ee3c9 100644 --- a/tizen/renderer/injected_bundle.cc +++ b/tizen/renderer/injected_bundle.cc @@ -15,6 +15,8 @@ */ #include +#include +#include #include #include #include @@ -28,7 +30,6 @@ #include "common/profiler.h" #include "common/resource_manager.h" #include "common/string_utils.h" -#include "common/wrt_message_data.h" #include "extensions/renderer/runtime_ipc_client.h" #include "extensions/renderer/widget_module.h" #include "extensions/renderer/xwalk_extension_renderer_controller.h" @@ -172,7 +173,7 @@ extern "C" void DynamicDatabaseAttach(int /*attach*/) { // LOGGER(DEBUG) << "InjectedBundle::DynamicDatabaseAttach !!"; } -extern "C" void DynamicOnIPCMessage(const Wrt_Message_Data& data) { +extern "C" void DynamicOnIPCMessage(const Ewk_Wrt_Message_Data& data) { SCOPE_PROFILE(); extensions::XWalkExtensionRendererController& controller = extensions::XWalkExtensionRendererController::GetInstance(); diff --git a/tizen/wrt/chromium_wrt.gyp b/tizen/wrt/chromium_wrt.gyp deleted file mode 100644 index 4680117..0000000 --- a/tizen/wrt/chromium_wrt.gyp +++ /dev/null @@ -1,55 +0,0 @@ -{ - 'includes':[ - '../build/common.gypi', - ], - 'targets': [ - { - 'target_name': 'chromium_wrt_shared', - 'type': 'shared_library', - 'sources': [ - "dynamicplugin.cc", - "dynamicplugin.h", - "v8widget.cc", - "v8widget.h", - "wrtwidget.cc", - "wrtwidget.h", - "wrt_dynamicplugin.cc", - "wrt_dynamicplugin.h", - "wrt_file_protocol_handler.cc", - "wrt_file_protocol_handler.h", - "wrt_widget_host.cc", - "wrt_widget_host.h", - ], - 'cflags': [ - '-fvisibility=default', - ], - 'variables': { - 'packages': [ - 'chromium-efl', - 'elementary', - ], - }, - 'include_dirs': [ - '.', - '../', - '../..', - '../tizen', - '<(libchromiumcontent_src_dir)', - '<(SHARED_INTERMEDIATE_DIR)', - '<(libchromiumcontent_src_dir)/gen', - '<(libchromiumcontent_src_dir)/third_party/skia/include/config', - '<(libchromiumcontent_src_dir)/third_party/skia/include/core', - ], - 'direct_dependent_settings': { -# 'libraries': [ -# '-lchromium_wrt_shared', -# ], - 'variables': { - 'packages': [ - 'jsoncpp', - ], - }, - }, - }, # end of target 'xwalk_extension_static' - ], # end of targets -} diff --git a/tizen/wrt/dynamicplugin.cc b/tizen/wrt/dynamicplugin.cc deleted file mode 100644 index 9512d3e..0000000 --- a/tizen/wrt/dynamicplugin.cc +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2014 Samsung Electronics. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "dynamicplugin.h" - -#include - -#include "base/command_line.h" -#include "base/logging.h" - -namespace { -const char* const VERSION_FUNCTION = "DynamicPluginVersion"; -const char* const START_SESSION_FUNCTION = "DynamicPluginStartSession"; -const char* const STOP_SESSION_FUNCTION = "DynamicPluginStopSession"; -} - -DynamicPlugin::DynamicPlugin() - : m_handle_(0), - m_version_(0), - m_versionFunction_(0), - m_startSession_(0), - m_stopSession_(0) { - const base::CommandLine& commandLine = - *base::CommandLine::ForCurrentProcess(); - std::string injectedBundlePath = - commandLine.GetSwitchValueASCII("injected-bundle-path"); - if (injectedBundlePath.empty()) { - return; - } - m_handle_ = dlopen(injectedBundlePath.c_str(), RTLD_LAZY); - if (!m_handle_) { - LOG(ERROR) << "No handle to " << injectedBundlePath.c_str() << " " - << dlerror() << "\n"; - return; - } - - *reinterpret_cast(&m_versionFunction_) = - dlsym(m_handle_, VERSION_FUNCTION); - if (!m_versionFunction_) { - LOG(ERROR) << "No " << VERSION_FUNCTION << " symbol found!\n"; - } else { - m_version_ = m_versionFunction_(); - if (m_version_ != 0 && m_version_ != 1) { - LOG(ERROR) << "Unknown plugin version: " << m_version_ << "!\n"; - return; - } - } - - *reinterpret_cast(&m_startSession_) = - dlsym(m_handle_, START_SESSION_FUNCTION); - if (!m_startSession_) { - LOG(ERROR) << "No " << START_SESSION_FUNCTION << " symbol found!\n"; - } - *reinterpret_cast(&m_stopSession_) = - dlsym(m_handle_, STOP_SESSION_FUNCTION); - if (!m_stopSession_) { - LOG(ERROR) << "No " << STOP_SESSION_FUNCTION << " symbol found!\n"; - } -} - -void DynamicPlugin::startSession(const char* sessionId, - v8::Handle context, - int routingHandle, - const void* sessionBlob) { - if (!m_startSession_) - return; - - m_startSession_(sessionId, context, routingHandle, sessionBlob); -} - -void DynamicPlugin::stopSession(const char* sessionId, - v8::Handle context) { - if (!m_stopSession_) - return; - - m_stopSession_(sessionId, context); -} - -DynamicPlugin::~DynamicPlugin() { - if (m_handle_) - dlclose(m_handle_); -} - -DynamicPlugin& DynamicPlugin::instance() { - static DynamicPlugin dynamicPlugin; - return dynamicPlugin; -} - diff --git a/tizen/wrt/dynamicplugin.h b/tizen/wrt/dynamicplugin.h deleted file mode 100644 index 46a1963..0000000 --- a/tizen/wrt/dynamicplugin.h +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2014, 2016 Samsung Electronics. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WRT_DYNAMICPLUGIN_H_ -#define WRT_DYNAMICPLUGIN_H_ - -#include -#include "base/macros.h" -#include "v8/include/v8.h" - -typedef unsigned int (*versionFunction)(void); - -typedef void (*startSessionFunction)(const char* sessionId, - v8::Handle context, - int routingHandle, - const void* sessionBlob); - -typedef void (*stopSessionFunction)(const char* sessionId, - v8::Handle context); - -class DynamicPlugin { - public: - void startSession(const char* sessionId, - v8::Handle context, - int routingHandle, - const void* sessionBlob); - void stopSession(const char* sessionId, v8::Handle context); - - virtual ~DynamicPlugin(); - - static DynamicPlugin& instance(); - - protected: - DynamicPlugin(); - DynamicPlugin(const DynamicPlugin&); - DynamicPlugin& operator=(const DynamicPlugin&); - - void* m_handle_; - unsigned int m_version_; - versionFunction m_versionFunction_; - startSessionFunction m_startSession_; - stopSessionFunction m_stopSession_; -}; - -#endif // WRT_DYNAMICPLUGIN_H_ diff --git a/tizen/wrt/v8widget.cc b/tizen/wrt/v8widget.cc deleted file mode 100644 index ef721b8..0000000 --- a/tizen/wrt/v8widget.cc +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright 2014, 2015 Samsung Electronics. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "v8widget.h" - -#include "base/logging.h" -#include "dynamicplugin.h" -#if defined(OS_TIZEN_TV_PRODUCT) -#include "wrt/hbbtv_dynamicplugin.h" -#endif -#include "wrt_dynamicplugin.h" - -V8Widget::V8Widget(Type type) : type_(type) {} - -V8Widget::~V8Widget() {} - -void V8Widget::SetId(const std::string& id) { - id_ = id; -} - -V8Widget::Type V8Widget::GetType() const { - return type_; -} - -bool V8Widget::ParseUrl(const GURL& url, - GURL& new_url, - bool& is_decrypted_file) { - if (!id_.empty()) { - std::string old_url = url.possibly_invalid_spec(); - std::string s_new_url; - if (type_ == V8Widget::Type::WRT) - WrtDynamicPlugin::instance().parseURL(&old_url, &s_new_url, id_.c_str(), - &is_decrypted_file); - -#if defined(OS_TIZEN_TV_PRODUCT) - if (type_ == V8Widget::Type::HBBTV) - HbbTVDynamicPlugin::instance().parseURL(&old_url, &s_new_url, id_.c_str(), - &is_decrypted_file); -#endif - - if (!s_new_url.empty()) { - new_url = GURL(s_new_url); - return true; - } - } - return false; -} - -#if defined(OS_TIZEN_TV_PRODUCT) -bool V8Widget::GetFileDecryptedDataBuffer(const GURL& url, - std::vector* data) { - if (!id_.empty()) { - std::string str_url = url.possibly_invalid_spec(); - if (type_ == V8Widget::Type::WRT) - return WrtDynamicPlugin::instance().getFileDecryptedDataBuffer(&str_url, - data); - - if (type_ == V8Widget::Type::HBBTV) - return HbbTVDynamicPlugin::instance().getFileDecryptedDataBuffer(&str_url, - data); - } - return false; -} -#endif - -void V8Widget::StopSession(v8::Handle context) { - if (!id_.empty() && !context.IsEmpty()) { - if (type_ == V8Widget::Type::WRT) - WrtDynamicPlugin::instance().stopSession(id_.c_str(), context); - -#if defined(OS_TIZEN_TV_PRODUCT) - if (type_ == V8Widget::Type::HBBTV) - HbbTVDynamicPlugin::instance().stopSession(id_.c_str(), context); -#endif - } -} - -void V8Widget::StartSession(v8::Handle context, - int routingHandle, - const void* sessionBlob) { - if (!id_.empty() && !context.IsEmpty()) { - if (type_ == V8Widget::Type::WRT) - NOTREACHED(); - -#if defined(OS_TIZEN_TV_PRODUCT) - if (type_ == V8Widget::Type::HBBTV) - HbbTVDynamicPlugin::instance().startSession(id_.c_str(), context, - routingHandle, sessionBlob); -#endif - } -} diff --git a/tizen/wrt/v8widget.h b/tizen/wrt/v8widget.h deleted file mode 100644 index 2b843a3..0000000 --- a/tizen/wrt/v8widget.h +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2014, 2015 Samsung Electronics. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WRT_V8WIDGET_H_ -#define WRT_V8WIDGET_H_ - -#include - -#include "content/public/renderer/render_thread_observer.h" -#include "url/gurl.h" -#include "v8/include/v8.h" - -// Have to be created on the RenderThread. -class V8Widget { - public: - enum class Type { HBBTV, WRT }; - - explicit V8Widget(Type type); - virtual ~V8Widget() = 0; - - void SetId(const std::string& id); - Type GetType() const; - - virtual void StartSession(v8::Handle, - int routingHandle, - const void* sessionBlob); - - virtual void StopSession(v8::Handle); - - bool ParseUrl(const GURL& url, GURL& new_url, bool& is_decrypted_file); - -#if defined(OS_TIZEN_TV_PRODUCT) - bool GetFileDecryptedDataBuffer(const GURL& url, std::vector* data); -#endif - protected: - std::string id_; - Type type_; -}; - -#endif // WRT_V8WIDGET_H_ diff --git a/tizen/wrt/wrt_dynamicplugin.cc b/tizen/wrt/wrt_dynamicplugin.cc deleted file mode 100644 index 68cf087..0000000 --- a/tizen/wrt/wrt_dynamicplugin.cc +++ /dev/null @@ -1,164 +0,0 @@ -// Copyright 2014 Samsung Electronics. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "wrt_dynamicplugin.h" - -#include - -#include "base/command_line.h" -#include "base/logging.h" - -namespace { -const char* const URL_PARSING_FUNCTION = "DynamicUrlParsing"; -const char* const SET_WIDGET_INFO_FUNCTION = "DynamicSetWidgetInfo"; -const char* const DATABASE_ATTACH_FUNCTION = "DynamicDatabaseAttach"; -#if defined(OS_TIZEN_TV_PRODUCT) -const char* const TVURL_PARSING_FUNCTION = "DynamicTVUrlParsing"; -const char* const GET_FILEDECRYPTED_DATABUFFER = - "DynamicGetFileDecryptedDataBuffer"; -#endif - -typedef void (*startSessionFun_v0)(const char* tizen_app_id, - v8::Handle context, - int routingHandle, - double scaleFactor, - const char* encodedBundle, - const char* theme, - const char* baseURL); -} // namespace - -WrtDynamicPlugin::WrtDynamicPlugin() - : DynamicPlugin(), - m_parseURL_(0), - m_setWidgetInfo_(0), - m_databaseAttach_(0), -#if defined(OS_TIZEN_TV_PRODUCT) - m_getFileDecryptedDataBuffer_(0), - m_parseTVURL_(0), -#endif - m_onIPCMessage_(0) { - *reinterpret_cast(&m_parseURL_) = - dlsym(m_handle_, URL_PARSING_FUNCTION); - if (!m_parseURL_) { - LOG(ERROR) << "No " << URL_PARSING_FUNCTION << " symbol found!\n"; - } - *reinterpret_cast(&m_setWidgetInfo_) = - dlsym(m_handle_, SET_WIDGET_INFO_FUNCTION); - if (!m_setWidgetInfo_) { - LOG(ERROR) << "No " << SET_WIDGET_INFO_FUNCTION << " symbol found!"; - } - *reinterpret_cast(&m_databaseAttach_) = - dlsym(m_handle_, DATABASE_ATTACH_FUNCTION); - if (!m_databaseAttach_) { - LOG(ERROR) << "No " << DATABASE_ATTACH_FUNCTION << " symbol found!\n"; - return; - } - *reinterpret_cast(&m_onIPCMessage_) = - dlsym(m_handle_, "DynamicOnIPCMessage"); - if (!m_onIPCMessage_) { - LOG(ERROR) << "No DynamicOnIPCMessage symbol found!\n"; - } - m_databaseAttach_(1); - -#if defined(OS_TIZEN_TV_PRODUCT) - *reinterpret_cast(&m_parseTVURL_) = - dlsym(m_handle_, TVURL_PARSING_FUNCTION); - if (!m_parseTVURL_) { - LOG(ERROR) << "No " << TVURL_PARSING_FUNCTION << " symbol found!\n"; - } - *reinterpret_cast(&m_getFileDecryptedDataBuffer_) = - dlsym(m_handle_, GET_FILEDECRYPTED_DATABUFFER); - if (!m_getFileDecryptedDataBuffer_) { - LOG(ERROR) << "No " << GET_FILEDECRYPTED_DATABUFFER << " symbol found!\n"; - } -#endif -} - -void WrtDynamicPlugin::startSession(const char* tizen_app_id, - v8::Handle context, - int routingHandle, - double scaleFactor, - const char* encodedBundle, - const char* theme, - const char* baseURL) { - if (!m_startSession_ || !m_databaseAttach_) - return; - switch (m_version_) { - case 0: { - auto startSession_v0 = - reinterpret_cast(m_startSession_); - startSession_v0(tizen_app_id, context, routingHandle, scaleFactor, - encodedBundle, theme, baseURL); - break; - } - case 1: { - DynamicPlugin::startSession(tizen_app_id, context, routingHandle, - baseURL); - break; - } - default: - return; - } -} - -void WrtDynamicPlugin::stopSession(const char* tizen_app_id, - v8::Handle context) { - if (!m_stopSession_ || !m_databaseAttach_) - return; - DynamicPlugin::stopSession(tizen_app_id, context); -} - -void WrtDynamicPlugin::parseURL(std::string* old_url, - std::string* new_url, - const char* tizen_app_id, - bool* is_decrypted_file) { -#if defined(OS_TIZEN_TV_PRODUCT) - if (!m_databaseAttach_) - return; - if (m_parseTVURL_) { - m_parseTVURL_(old_url, new_url, tizen_app_id, is_decrypted_file); - return; - } - if (m_parseURL_) { - m_parseURL_(old_url, new_url, tizen_app_id); - *is_decrypted_file = false; - } -#else - if (!m_parseURL_ || !m_databaseAttach_) - return; - m_parseURL_(old_url, new_url, tizen_app_id); -#endif -} - -#if defined(OS_TIZEN_TV_PRODUCT) -bool WrtDynamicPlugin::getFileDecryptedDataBuffer(const std::string* url, - std::vector* data) { - if (!m_getFileDecryptedDataBuffer_) - return false; - return m_getFileDecryptedDataBuffer_(url, data); -} -#endif - -void WrtDynamicPlugin::setWidgetInfo(const std::string& tizen_app_id) { - if (!m_setWidgetInfo_) - return; - m_setWidgetInfo_(tizen_app_id.c_str()); -} - -WrtDynamicPlugin::~WrtDynamicPlugin() { - if (m_databaseAttach_) - m_databaseAttach_(0); -} - -WrtDynamicPlugin& WrtDynamicPlugin::instance() { - static WrtDynamicPlugin dynamicPlugin; - return dynamicPlugin; -} - -void WrtDynamicPlugin::messageReceived(const Wrt_Message_Data& data) { - if (!m_onIPCMessage_) - return; - - m_onIPCMessage_(data); -} diff --git a/tizen/wrt/wrt_dynamicplugin.h b/tizen/wrt/wrt_dynamicplugin.h deleted file mode 100644 index 9554b4d..0000000 --- a/tizen/wrt/wrt_dynamicplugin.h +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2014 Samsung Electronics. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WRT_WRT_DYNAMICPLUGIN_H_ -#define WRT_WRT_DYNAMICPLUGIN_H_ - -#include -#include -#include "dynamicplugin.h" -#include "v8/include/v8.h" -#include "common/wrt_message_data.h" - -typedef void (*onIPCMessageFun)(const Wrt_Message_Data& data); -#if defined(OS_TIZEN_TV_PRODUCT) -typedef void (*TVParseUrlFun)(std::string* old_url, - std::string* new_url, - const char* tizen_app_id, - bool* is_decrypted_file); -typedef bool (*getFileDecryptedDataBufferFun)(const std::string* url, - std::vector* data); -#endif -typedef void (*parseUrlFun)(std::string* old_url, - std::string* new_url, - const char* tizen_app_id); -typedef void (*setWidgetInfoFun)(const char* tizen_app_id); -typedef void (*databaseAttachFun)(int databaseAttach); - -class WrtDynamicPlugin : public DynamicPlugin { - public: - void startSession(const char* tizen_app_id, - v8::Handle context, - int routingHandle, - double scaleFactor, - const char* encodedBundle, - const char* theme, - const char* baseURL); - void stopSession(const char* tizen_app_id, v8::Handle context); - - void parseURL(std::string* old_url, - std::string* new_url, - const char* tizen_app_id, - bool* is_decrypted_file); - -#if defined(OS_TIZEN_TV_PRODUCT) - bool getFileDecryptedDataBuffer(const std::string* url, - std::vector* data); -#endif - - void setWidgetInfo(const std::string& tizen_app_id); - void messageReceived(const Wrt_Message_Data& data); - - static WrtDynamicPlugin& instance(); - ~WrtDynamicPlugin() override; - - private: - WrtDynamicPlugin(); - - parseUrlFun m_parseURL_; - setWidgetInfoFun m_setWidgetInfo_; - databaseAttachFun m_databaseAttach_; -#if defined(OS_TIZEN_TV_PRODUCT) - getFileDecryptedDataBufferFun m_getFileDecryptedDataBuffer_; - TVParseUrlFun m_parseTVURL_; -#endif - onIPCMessageFun m_onIPCMessage_; - - DISALLOW_COPY_AND_ASSIGN(WrtDynamicPlugin); -}; - -#endif // WRT_WRT_DYNAMICPLUGIN_H_ diff --git a/tizen/wrt/wrt_file_protocol_handler.cc b/tizen/wrt/wrt_file_protocol_handler.cc deleted file mode 100644 index 5a8ba30..0000000 --- a/tizen/wrt/wrt_file_protocol_handler.cc +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright (c) 2014,2015 Samsung Electronics. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "wrt_file_protocol_handler.h" - -#include "base/command_line.h" -//#include "common/content_switches_efl.h" -#include "content/public/common/content_client.h" -#include "content/public/renderer/content_renderer_client.h" -#include "net/base/filename_util.h" -#include "net/url_request/url_request_data_job.h" -#include "net/url_request/url_request_error_job.h" -#include "net/url_request/url_request_file_dir_job.h" -#include "net/url_request/url_request_file_job.h" -#include "net/url_request/url_request_simple_job.h" -#include "wrt_dynamicplugin.h" - -namespace net { - -class WrtURLRequestDataJob : public URLRequestSimpleJob { - public: - /* LCOV_EXCL_START */ - WrtURLRequestDataJob(URLRequest* request, - NetworkDelegate* network_delegate, - const GURL& data_url) - : URLRequestSimpleJob(request, network_delegate) { - data_url_ = data_url; - } - /* LCOV_EXCL_STOP */ - - int GetData(std::string* mime_type, - std::string* charset, - std::string* data, - const CompletionCallback& callback) const override; - - private: - ~WrtURLRequestDataJob() override {} // LCOV_EXCL_LINE - GURL data_url_; -}; - -/* LCOV_EXCL_START */ -int WrtURLRequestDataJob::GetData(std::string* mime_type, - std::string* charset, - std::string* data, - const CompletionCallback& callback) const { - if (!data_url_.is_valid()) - return ERR_INVALID_URL; - - return URLRequestDataJob::BuildResponse(data_url_, mime_type, charset, data, - nullptr); -} - -bool WrtFileProtocolHandler::GetWrtParsedUrl(const GURL& url, - GURL& parsed_url) const { - static std::string tizen_app_id = - base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( - "widget-id"); - if (!tizen_app_id.empty()) { - bool is_decrypted_file; - std::string url_str = url.possibly_invalid_spec(); - std::string parsed_url_str; - WrtDynamicPlugin::instance().parseURL( - &url_str, &parsed_url_str, tizen_app_id.c_str(), &is_decrypted_file); - if (!parsed_url_str.empty()) { - parsed_url = GURL(parsed_url_str); - return true; - } - } - return false; -} -/* LCOV_EXCL_STOP */ - -URLRequestJob* WrtFileProtocolHandler::MaybeCreateJob( - URLRequest* request, - NetworkDelegate* network_delegate) const { - GURL parsed_url; - if (GetWrtParsedUrl(request->url(), parsed_url)) { - // Data URI scheme for WRT encryption content - if (parsed_url.SchemeIs(url::kDataScheme)) - return new WrtURLRequestDataJob(request, network_delegate, parsed_url); - } else - parsed_url = request->url(); - - base::FilePath file_path; - const bool is_file = FileURLToFilePath(parsed_url, &file_path); - - // Check file access permissions. - if (!network_delegate || - !network_delegate->CanAccessFile(*request, file_path)) { - return new URLRequestErrorJob(request, network_delegate, ERR_ACCESS_DENIED); - } - - // We need to decide whether to create URLRequestFileJob for file access or - // URLRequestFileDirJob for directory access. To avoid accessing the - // filesystem, we only look at the path string here. - // The code in the URLRequestFileJob::Start() method discovers that a path, - // which doesn't end with a slash, should really be treated as a directory, - // and it then redirects to the URLRequestFileDirJob. - if (is_file && file_path.EndsWithSeparator() && file_path.IsAbsolute()) { - return new URLRequestFileDirJob(request, network_delegate, file_path); - } - - // Use a regular file request job for all non-directories (including invalid - // file names). - return new URLRequestFileJob(request, network_delegate, file_path, - file_task_runner_); -} - -} // namespace diff --git a/tizen/wrt/wrt_file_protocol_handler.h b/tizen/wrt/wrt_file_protocol_handler.h deleted file mode 100644 index 6fab49f..0000000 --- a/tizen/wrt/wrt_file_protocol_handler.h +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) 2014,2015 Samsung Electronics. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WRT_FILE_PROTOCOL_HANDLER -#define WRT_FILE_PROTOCOL_HANDLER - -#include "base/memory/ref_counted.h" -#include "net/url_request/url_request_job_factory.h" - -class GURL; - -namespace base { -class TaskRunner; -} - -namespace net { - -class NetworkDelegate; -class URLRequestJob; - -class WrtFileProtocolHandler - : public URLRequestJobFactory::ProtocolHandler { - public: - explicit WrtFileProtocolHandler( - const scoped_refptr& file_task_runner) - : file_task_runner_(file_task_runner) {} - ~WrtFileProtocolHandler() override {} - URLRequestJob* MaybeCreateJob( - URLRequest* request, - NetworkDelegate* network_delegate) const override; - /* LCOV_EXCL_START */ - bool IsSafeRedirectTarget(const GURL& location) const override { - return false; - } - /* LCOV_EXCL_STOP */ - - private: - bool GetWrtParsedUrl(const GURL& url, GURL& parsed_url) const; - const scoped_refptr file_task_runner_; - DISALLOW_COPY_AND_ASSIGN(WrtFileProtocolHandler); -}; - -} // namespace net - -#endif // WRT_FILE_PROTOCOL_HANDLER diff --git a/tizen/wrt/wrt_widget_host.cc b/tizen/wrt/wrt_widget_host.cc deleted file mode 100644 index d33c513..0000000 --- a/tizen/wrt/wrt_widget_host.cc +++ /dev/null @@ -1,164 +0,0 @@ -// Copyright (c) 2014,2015 Samsung Electronics. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "wrt_widget_host.h" - -#include "base/lazy_instance.h" -//#include "common/render_messages_ewk.h" -#include "atom/common/api/api_messages.h" -#include "content/public/browser/browser_message_filter.h" -#include "content/public/browser/render_process_host.h" -#include "content/public/browser/resource_request_info.h" -//#include "ipc/ipc_message_macros.h" -//#include "ipc_message_start_ewk.h" -#include "net/url_request/url_request.h" -#include "url/gurl.h" - -namespace { -// TODO(z.kostrzewa) I would prefer not make it a singleton, check out -// if it can't be a member of ContentMainDelegateEfl (but keep the static -// getter, maybe?). -base::LazyInstance > g_wrt_widget_host = - LAZY_INSTANCE_INITIALIZER; - -bool SendToAllRenderers(IPC::Message* message) { - bool result = false; - content::RenderProcessHost::iterator it = - content::RenderProcessHost::AllHostsIterator(); - while (!it.IsAtEnd()) { - if (it.GetCurrentValue()->Send(new IPC::Message(*message))) - result = true; - it.Advance(); - } - delete message; - return result; -} - -bool SendToRenderer(int renderer_id, IPC::Message* message) { - return content::RenderProcessHost::FromID(renderer_id)->Send(message); -} -} - -class WrtWidgetHostMessageFilter : public content::BrowserMessageFilter { - public: - explicit WrtWidgetHostMessageFilter(WrtWidgetHost* wrt_widget_host); - - private: - ~WrtWidgetHostMessageFilter() override {} - bool OnMessageReceived(const IPC::Message& message) override; - - WrtWidgetHost* wrt_widget_host_; -}; - -WrtWidgetHostMessageFilter::WrtWidgetHostMessageFilter( - WrtWidgetHost* wrt_widget_host) - : content::BrowserMessageFilter(ShellMsgStart), - wrt_widget_host_(wrt_widget_host) { -} - -bool WrtWidgetHostMessageFilter::OnMessageReceived(const IPC::Message& message) { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(WrtWidgetHostMessageFilter, message) - IPC_MESSAGE_FORWARD(WrtMsg_ParseUrlResponse, wrt_widget_host_, WrtWidgetHost::OnUrlRetrieved) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - return handled; -} - -WrtWidgetHost* WrtWidgetHost::Get() { - // TODO(z.kostrzewa) LazyInstance is thread-safe but creating - // WrtWidgetHost is not - make it thread-safe. - if (!g_wrt_widget_host.Get().get()) - g_wrt_widget_host.Get().reset(new WrtWidgetHost); - return g_wrt_widget_host.Get().get(); -} - -WrtWidgetHost::WrtWidgetHost() - : message_filter_(new WrtWidgetHostMessageFilter(this)) { -} - -WrtWidgetHost::~WrtWidgetHost() {} - -void WrtWidgetHost::GetUrlForRequest( - net::URLRequest* request, - base::Callback callback) { - // TODO(z.kostrzewa) Check on which thread(s) callbacks_ is touched - // and provide synchronization if required (either via a lock or - // by assuring that it is referenced only on one thread) - int callback_id = callback_id_generator_.GetNext(); - callbacks_[callback_id] = callback; - - int renderer_id, frame_id; - if (content::ResourceRequestInfo::GetRenderFrameForRequest(request, &renderer_id, - &frame_id)) - if (SendToRenderer(renderer_id, new WrtMsg_ParseUrl(callback_id, request->url()))) - return; - - callbacks_.erase(callback_id); - callback.Run(GURL()); -} - -void WrtWidgetHost::SendWrtMessage( - const Wrt_Message_Data& message) { - SendToAllRenderers(new WrtMsg_SendWrtMessage(message)); -} - -// It's only used by the wrt_file_protocol_handler which is not going to be used in the future -// Candidate for deletion. -bool WrtWidgetHost::InWrt() const { - return false; -} - -// It's only used by the wrt_file_protocol_handler which is not going to be used in the future -// Candidate for deletion. -std::string WrtWidgetHost::TizenAppId() const { -#if defined(OS_TIZEN_TV_PRODUCT) - return tizen_app_id_; -#else - return std::string(); -#endif -} - -void WrtWidgetHost::OnUrlRetrieved(int callback_id, const GURL& url) { - callbacks_type::iterator it = callbacks_.find(callback_id); - if (callbacks_.end() == it) - return; - - callbacks_type::mapped_type callback = it->second; - callbacks_.erase(callback_id); - callback.Run(url); -} - -#if defined(OS_TIZEN_TV_PRODUCT) -void WrtWidgetHost::SetTizenAppId(const std::string& tizen_app_id) { - tizen_app_id_ = tizen_app_id; -} - -bool WrtWidgetHost::ShouldAllowRequest(const net::URLRequest& request) { - if (tizen_app_id_.empty() || !check_accessiable_path_callback_) - return true; - - return check_accessiable_path_callback_->TriggerCallback(request.url().spec(), - tizen_app_id_); -} - -bool EwkCheckAccessiablePathCallback::TriggerCallback( - const std::string& url_spec, - const std::string& tizen_app_id) const { - if (!callback_) - return true; - - Eina_Bool result = - (*callback_)(tizen_app_id.c_str(), url_spec.c_str(), user_data_); - return result == EINA_TRUE; -} - -void WrtWidgetHost::SetCheckAccessiablePathCallback( - Ewk_Context_Check_Accessible_Path_Callback callback, - void* user_data) { - check_accessiable_path_callback_.reset( - new EwkCheckAccessiablePathCallback(callback, user_data)); -} -#endif - diff --git a/tizen/wrt/wrt_widget_host.h b/tizen/wrt/wrt_widget_host.h deleted file mode 100644 index 11161da..0000000 --- a/tizen/wrt/wrt_widget_host.h +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright (c) 2014,2015 Samsung Electronics. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WRT_HOST_H -#define WRT_HOST_H - -#include -#include - -#include "base/atomic_sequence_num.h" -#include "base/callback.h" -#include "content/public/browser/browser_message_filter.h" -#include "common/wrt_message_data.h" -#if defined(OS_TIZEN_TV_PRODUCT) -#include "public/ewk_context_product.h" -#endif - -namespace net { -class URLRequest; -} - -class GURL; - -class WrtWidgetHostMessageFilter; - -#if defined(OS_TIZEN_TV_PRODUCT) -class EwkCheckAccessiablePathCallback { - public: - EwkCheckAccessiablePathCallback( - Ewk_Context_Check_Accessible_Path_Callback callback, - void* user_data) - : callback_(callback), user_data_(user_data) {} - bool TriggerCallback(const std::string& url_spec, - const std::string& tizen_app_id) const; - - private: - Ewk_Context_Check_Accessible_Path_Callback callback_; - void* user_data_; -}; -#endif - -class WrtWidgetHost { - public: - static WrtWidgetHost* Get(); - - ~WrtWidgetHost(); - - void GetUrlForRequest(net::URLRequest* request, - base::Callback callback); - - void SendWrtMessage(const Wrt_Message_Data& message); - - bool InWrt() const; - - std::string TizenAppId() const; - -#if defined(OS_TIZEN_TV_PRODUCT) - void SetTizenAppId(const std::string& tizen_app_id); - bool ShouldAllowRequest(const net::URLRequest& request); - - void SetCheckAccessiablePathCallback( - Ewk_Context_Check_Accessible_Path_Callback callback, - void* user_data); -#endif - - private: - friend class WrtWidgetHostMessageFilter; - - typedef std::map > callbacks_type; - - WrtWidgetHost(); - - void OnUrlRetrieved(int callback_id, const GURL& url); - - scoped_refptr message_filter_; - base::AtomicSequenceNumber callback_id_generator_; - callbacks_type callbacks_; - -#if defined(OS_TIZEN_TV_PRODUCT) - std::string tizen_app_id_; - std::unique_ptr check_accessiable_path_callback_; -#endif - - DISALLOW_COPY_AND_ASSIGN(WrtWidgetHost); -}; - - -#endif diff --git a/tizen/wrt/wrtwidget.cc b/tizen/wrt/wrtwidget.cc deleted file mode 100644 index 6c877c6..0000000 --- a/tizen/wrt/wrtwidget.cc +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright 2014, 2015 Samsung Electronics. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "wrtwidget.h" - -//#include "common/render_messages_ewk.h" -#include "atom/common/api/api_messages.h" -#include "content/public/renderer/render_thread.h" -#include "ipc/ipc_sync_channel.h" -#include "wrt_dynamicplugin.h" - -// TODO(z.kostrzewa) -// Why it can't be implemented as IPC::ChannelProxy::MessageFilter (?) -// Tried that and it seems that Observer starts receiving messages earlier than -// MessageFilter what is crucial for message that sets widget handle -class WrtRenderThreadObserver : public content::RenderThreadObserver { - public: - explicit WrtRenderThreadObserver(WrtWidget* wrt_widget) - : wrt_widget_(wrt_widget), - channel_(content::RenderThread::Get()->GetChannel()) - { } - - bool OnControlMessageReceived(const IPC::Message& message) override { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(WrtRenderThreadObserver, message) - IPC_MESSAGE_FORWARD(WrtMsg_SendWrtMessage, wrt_widget_, WrtWidget::MessageReceived) - IPC_MESSAGE_HANDLER(WrtMsg_ParseUrl, ParseUrl) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - return handled; - } - - private: - void ParseUrl(int request_id, const GURL& url) { - GURL response; - bool is_decrypted_file = false; - wrt_widget_->ParseUrl(url, response, is_decrypted_file); - Send(new WrtMsg_ParseUrlResponse(request_id, response)); - } - - void Send(IPC::Message* message) { - if (channel_) - channel_->Send(message); - else - delete message; - } - - WrtWidget* wrt_widget_; - IPC::SyncChannel* channel_; -}; - -WrtWidget::WrtWidget() - : V8Widget(V8Widget::Type::WRT), - scale_(0), - observer_(new WrtRenderThreadObserver(this)) { - DCHECK(content::RenderThread::Get()) - << "WrtWidget must be constructed on the render thread"; -} - -WrtWidget::~WrtWidget() { - delete observer_; -} - -content::RenderThreadObserver* WrtWidget::GetObserver() { - return observer_; -} - -void WrtWidget::SetWidgetInfo(const std::string& tizen_app_id, - double scaleFactor, - const std::string& theme, - const std::string& encodedBundle) { - id_ = tizen_app_id; - scale_ = scaleFactor; - theme_ = theme; - encodedBundle_ = encodedBundle; - WrtDynamicPlugin::instance().setWidgetInfo(id_); -} - -bool WrtWidget::IsWidgetInfoSet() const { - return !id_.empty(); -} - -void WrtWidget::StartSession(v8::Handle context, - int routingHandle, - const void* sessionBlob) { - if (!id_.empty() && !context.IsEmpty()) { - WrtDynamicPlugin::instance().startSession( - id_.c_str(), context, routingHandle, scale_, encodedBundle_.c_str(), - theme_.c_str(), reinterpret_cast(sessionBlob)); - } -} - -void WrtWidget::MessageReceived(const Wrt_Message_Data& data) { - if (!id_.empty()) - WrtDynamicPlugin::instance().messageReceived(data); -} diff --git a/tizen/wrt/wrtwidget.h b/tizen/wrt/wrtwidget.h deleted file mode 100644 index 28af8cb..0000000 --- a/tizen/wrt/wrtwidget.h +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2014, 2015 Samsung Electronics. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WRT_WRTWIDGET_H_ -#define WRT_WRTWIDGET_H_ - -#include - -#include "content/public/renderer/render_thread_observer.h" -#include "url/gurl.h" -#include "v8widget.h" -#include "common/wrt_message_data.h" - -class WrtRenderThreadObserver; - -// Have to be created on the RenderThread. -class WrtWidget : public V8Widget { - public: - WrtWidget(); - ~WrtWidget() override; - - content::RenderThreadObserver* GetObserver(); - - void SetWidgetInfo(const std::string& tizen_app_id, - double scaleFactor, - const std::string& theme, - const std::string& encodedBundle); - - bool IsWidgetInfoSet() const; - - void MessageReceived(const Wrt_Message_Data& data); - - void StartSession(v8::Handle, - int routingHandle, - const void* sessionBlob) override; - - private: - double scale_; - std::string encodedBundle_; - std::string theme_; - WrtRenderThreadObserver* observer_; -}; - -#endif // WRT_WRTWIDGET_H_ diff --git a/vendor/brightray/vendor/libchromiumcontent/src/tizen_src/ewk/efl_integration/private/ewk_wrt_private.h b/vendor/brightray/vendor/libchromiumcontent/src/tizen_src/ewk/efl_integration/private/ewk_wrt_private.h index c0d5208..2f60494 100644 --- a/vendor/brightray/vendor/libchromiumcontent/src/tizen_src/ewk/efl_integration/private/ewk_wrt_private.h +++ b/vendor/brightray/vendor/libchromiumcontent/src/tizen_src/ewk/efl_integration/private/ewk_wrt_private.h @@ -7,7 +7,7 @@ #include -struct Ewk_Wrt_Message_Data { +struct __attribute__((visibility("default"))) Ewk_Wrt_Message_Data { std::string type; std::string value; std::string id; diff --git a/vendor/brightray/vendor/libchromiumcontent/src/tizen_src/ewk/efl_integration/wrt/wrt_widget_host.h b/vendor/brightray/vendor/libchromiumcontent/src/tizen_src/ewk/efl_integration/wrt/wrt_widget_host.h index ad087e9..01f01c7 100644 --- a/vendor/brightray/vendor/libchromiumcontent/src/tizen_src/ewk/efl_integration/wrt/wrt_widget_host.h +++ b/vendor/brightray/vendor/libchromiumcontent/src/tizen_src/ewk/efl_integration/wrt/wrt_widget_host.h @@ -41,7 +41,7 @@ class EwkCheckAccessiablePathCallback { }; #endif -class WrtWidgetHost { +class __attribute__((visibility("default"))) WrtWidgetHost { public: static WrtWidgetHost* Get(); diff --git a/vendor/brightray/vendor/libchromiumcontent/src/tizen_src/ewk/efl_integration/wrt/wrtwidget.h b/vendor/brightray/vendor/libchromiumcontent/src/tizen_src/ewk/efl_integration/wrt/wrtwidget.h index 45c2c93..4e504e0 100644 --- a/vendor/brightray/vendor/libchromiumcontent/src/tizen_src/ewk/efl_integration/wrt/wrtwidget.h +++ b/vendor/brightray/vendor/libchromiumcontent/src/tizen_src/ewk/efl_integration/wrt/wrtwidget.h @@ -16,7 +16,7 @@ struct Ewk_Wrt_Message_Data; class WrtRenderThreadObserver; // Have to be created on the RenderThread. -class WrtWidget : public V8Widget { +class __attribute__((visibility("default"))) WrtWidget : public V8Widget { public: WrtWidget(); ~WrtWidget() override; diff --git a/wrt.gyp b/wrt.gyp index d8528b0..663ee2c 100644 --- a/wrt.gyp +++ b/wrt.gyp @@ -15,7 +15,6 @@ '<(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)/tizen/wrt/chromium_wrt.gyp:chromium_wrt_shared', '<(DEPTH)/efl/build/system.gyp:ecore', '<(DEPTH)/efl/build/system.gyp:launchpad', '<(DEPTH)/efl/build/system.gyp:capi-appfw-application', @@ -130,6 +129,7 @@ '<(libchromiumcontent_src_dir)/components/cdm', '<(libchromiumcontent_src_dir)/third_party/widevine', '<(libchromiumcontent_src_dir)/tizen_src/chromium_impl', + '<(libchromiumcontent_src_dir)/tizen_src/ewk/efl_integration', ], 'direct_dependent_settings': { 'include_dirs': [ -- 2.7.4 From 4bd93d1032d91f60d9f256bb0dff60f52647dcf9 Mon Sep 17 00:00:00 2001 From: "k2.nagaraju" Date: Mon, 4 Jun 2018 15:08:54 +0530 Subject: [PATCH 11/16] fixup! Expose the visibility of classes of chromium for web device api. Change-Id: Iba81e14e308e17fbfa29aad2c1515b2e4a8c2496 Signed-off-by: k2.nagaraju --- atom/renderer/atom_renderer_client.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/atom/renderer/atom_renderer_client.h b/atom/renderer/atom_renderer_client.h index 2818ecc..1a67a85 100644 --- a/atom/renderer/atom_renderer_client.h +++ b/atom/renderer/atom_renderer_client.h @@ -44,8 +44,7 @@ class AtomRendererClient : public RendererClientBase { DISABLE, }; std::unique_ptr widget_; - std::unique_ptr wrt_url_parser_; - // content::ContentRendererClient: + void RenderThreadStarted() override; void RenderFrameCreated(content::RenderFrame*) override; void RenderViewCreated(content::RenderView*) override; -- 2.7.4 From 45a7143e1856bcf59f0bf72655b83b5c055f7295 Mon Sep 17 00:00:00 2001 From: "jaekuk, lee" Date: Tue, 5 Jun 2018 10:28:38 +0900 Subject: [PATCH 12/16] Implement Runtime Add-on Change-Id: I3d5017a68ba43af8f4efff05069667a35d236e97 Signed-off-by: jaekuk, lee --- wrt/src/extension_manager.js | 2 +- wrt/src/runtime.js | 34 +++++++++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 2 deletions(-) mode change 100644 => 100755 wrt/src/runtime.js diff --git a/wrt/src/extension_manager.js b/wrt/src/extension_manager.js index 21c8cd0..1b9b965 100755 --- a/wrt/src/extension_manager.js +++ b/wrt/src/extension_manager.js @@ -14,7 +14,7 @@ var EXTENSIONS_PATH = process.env.WAS_EXTENSIONS_PATH; if (!EXTENSIONS_PATH) { var resourcePath = __dirname.split('app.asar')[0]; extension_debug('WARNING! WAS_EXTENSIONS_PATH not set - extensions cannot be loaded'); - EXTENSIONS_PATH = path.join(resourcePath, 'wrt_support/extensions'); + EXTENSIONS_PATH = path.join(resourcePath, 'runtime_addon'); extension_debug('Temporarily set WAS_EXTENSIONS_PATH=' + EXTENSIONS_PATH); } diff --git a/wrt/src/runtime.js b/wrt/src/runtime.js old mode 100644 new mode 100755 index 0bdaa49..2c1a1de --- a/wrt/src/runtime.js +++ b/wrt/src/runtime.js @@ -1,4 +1,6 @@ 'use strict'; +const EXTENSIONS_PATH = process.env.WAS_EXTENSIONS_PATH; +const ExtensionManager = require('./extension_manager'); const {app, ipcMain, pwrt} = require('electron'); const IPC_MESSAGE = require('./ipc_message'); const WAS_EVENT = require('./was_event'); @@ -13,15 +15,21 @@ class Runtime { this.quitting = false; this.handleWasEvents(); this.handleIpcMessages(); + this.extensionManager = null; this.isLaunched = false; var _this = this; + app.on('will-finish-launching', function() { + return runtime_debug('will-finish-launching'); + }); app.on('before-quit', function(event) { runtime_debug('before-quit'); - _this.quitting = true; + return _this.quitting = true; }); app.on('will-quit', function(event) { runtime_debug('will-quit'); + this.extensionManager.deactivateAll(app); + return _this.killAllProcesses(); }); app.on('quit', function(event) { return runtime_debug('quit'); @@ -56,10 +64,16 @@ class Runtime { }); app.on('ready', function(event) { runtime_debug('ready'); + this.extensionManager = new ExtensionManager(EXTENSIONS_PATH); + if (!options.noExtensions) { + this.extensionManager.build(); + } if (pwrt.isElectronLaunch()) { + this.extensionManager.activateAll(app); return; } this.webApplication = new WebApplication(options); + this.extensionManager.activateAll(app); }); } onPause(web_window_id) { @@ -81,6 +95,7 @@ class Runtime { onAppControl() {} onLanguageChanged() {} onLowMemory() {} + killAllProcesses() {} handleWasEvents() { var _this = this; events.on(WAS_EVENT.WEBAPPLICATION.RESUME, (sender, id) => { @@ -152,6 +167,23 @@ class Runtime { runtime_debug('handleWasMessages: destroyed ' + id); return app.emit(IPC_MESSAGE.WEBCONTENTS.DESTROYED, id); }); + ipcMain.on(IPC_MESSAGE.EXTENSIONS.INSTALLED, (sender, name) => { + runtime_debug('handleIpcMessages: INSTALLED ' + name); + this.extensionManager.build(); + return this.extensionManager.activate(app, name); + }); + ipcMain.on(IPC_MESSAGE.EXTENSIONS.UNINSTALLED, (sender, name) => { + runtime_debug('handleIpcMessages: UNINSTALLED ' + name); + return this.extensionManager.deactivate(app, name); + }); + ipcMain.on(IPC_MESSAGE.EXTENSIONS.ACTIVATE, (sender, name) => { + runtime_debug('handleIpcMessages: ACTIVATE ' + name); + return this.extensionManager.activate(app, name); + }); + ipcMain.on(IPC_MESSAGE.EXTENSIONS.DEACTIVATE, (sender, name) => { + runtime_debug('handleIpcMessages: DEACTIVATE ' + name); + return this.extensionManager.deactivate(app, name); + }); } } module.exports = Runtime; -- 2.7.4 From bc8a0f7c2d571df8c4a71fa12769978875dca8ac Mon Sep 17 00:00:00 2001 From: "k2.nagaraju" Date: Fri, 20 Apr 2018 09:56:52 +0530 Subject: [PATCH 13/16] Fix for supporting TCT - As node and jquery are having issues, disable node integration for Tizen apps - Handle Tizen Exit event - Allow loading of device API's in both main frame and iframe Change-Id: I3e69b28462761c270862eb47bb37defe37923ea0 Signed-off-by: Prathmesh --- atom/browser/api/atom_api_pwrt.cc | 12 ++++++++++-- atom/browser/api/atom_api_web_contents.cc | 23 +++++++++++++++++++---- atom/browser/browser.cc | 2 +- atom/renderer/atom_renderer_client.cc | 24 +++++++++++++----------- wrt/src/web_window.js | 4 ++++ 5 files changed, 47 insertions(+), 18 deletions(-) diff --git a/atom/browser/api/atom_api_pwrt.cc b/atom/browser/api/atom_api_pwrt.cc index aa7b785..d23679c 100644 --- a/atom/browser/api/atom_api_pwrt.cc +++ b/atom/browser/api/atom_api_pwrt.cc @@ -35,8 +35,16 @@ std::string PWRT::GetPath() { auto appdata_manager = common::ApplicationDataManager::GetInstance(); common::ApplicationData* app_data = appdata_manager->GetApplicationData(appid); // TODO: Use resource-manager's GetStartResource() for localized urls - std::string app_path = "file://" + app_data->application_path() + app_data->content_info()->src(); - return app_path; + // atom::Browser *browser_model = atom::Browser::Get(); + // std::unique_ptr res = browser_model->resource_manager_->GetStartResource(appcontrol.get()); + if (app_data) { + std::string app_path = "file://" + app_data->application_path(); + if (app_data->content_info()) + app_path += app_data->content_info()->src(); + else + app_path += "index.html"; + return app_path; + } } return ""; } diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index cac60af..d81d2cb 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -14,6 +14,7 @@ #include "atom/browser/atom_browser_client.h" #include "atom/browser/atom_browser_context.h" #include "atom/browser/atom_browser_main_parts.h" +#include "atom/browser/browser.h" #include "atom/browser/lib/bluetooth_chooser.h" #include "atom/browser/native_window.h" #include "atom/browser/net/atom_network_delegate.h" @@ -526,7 +527,7 @@ void WebContents::MoveContents(content::WebContents* source, void WebContents::CloseContents(content::WebContents* source) { Emit("close"); - + LOG(ERROR) << __FUNCTION__; if ((type_ == BROWSER_WINDOW || type_ == OFF_SCREEN) && owner_window()) owner_window()->CloseContents(source); } @@ -918,16 +919,29 @@ void WebContents::OnWrtPluginSyncMessage(const Ewk_Wrt_Message_Data& data, void WebContents::HandleWrtPluginMessage(Ewk_Wrt_Message_Data* msg) { Eina_Stringshare* msg_type = ewk_ipc_wrt_message_data_type_get(msg); - + LOG(INFO) << msg_type; #define TYPE_BEGIN(x) (!strncmp(msg_type, x, strlen(x))) #define TYPE_IS(x) (!strcmp(msg_type, x)) - if (TYPE_BEGIN("xwalk://")) { auto extension_server = extensions::XWalkExtensionServer::GetInstance(); extension_server->HandleIPCMessage(msg); } else { - // implement in future + Eina_Stringshare* msg_id = msg->GetId(); + Eina_Stringshare* msg_ref_id = msg->GetReferenceId(); + Eina_Stringshare* msg_value = msg->GetValue(); + if (TYPE_IS("tizen://exit")) { + atom::Browser *browser_model = atom::Browser::Get(); + browser_model->Shutdown(); + } + + eina_stringshare_del(msg_ref_id); + eina_stringshare_del(msg_id); + eina_stringshare_del(msg_value); } +#undef TYPE_IS +#undef TYPE_BEGIN + + eina_stringshare_del(msg_type); } bool WebContents::OnMessageReceived(const IPC::Message& message) { @@ -1090,6 +1104,7 @@ bool WebContents::IsWaitingForResponse() const { } void WebContents::Stop() { + LOG(ERROR) << __FUNCTION__; web_contents()->Stop(); } diff --git a/atom/browser/browser.cc b/atom/browser/browser.cc index fc2c7a4..b26b0e6 100644 --- a/atom/browser/browser.cc +++ b/atom/browser/browser.cc @@ -131,7 +131,7 @@ void Browser::SetElectronAppLaunch() { std::string appid = runtime_cmd->GetAppIdFromCommandLine("/usr/bin/electron"); auto appdata_manager = common::ApplicationDataManager::GetInstance(); common::ApplicationData* app_data = appdata_manager->GetApplicationData(appid); - if (!strcmp(app_data->content_info()->src().c_str(), "package.json")) { + if (app_data->content_info() && !strcmp(app_data->content_info()->src().c_str(), "package.json")) { is_electron_launch_ = true; } } else { diff --git a/atom/renderer/atom_renderer_client.cc b/atom/renderer/atom_renderer_client.cc index aa3b881..87be391 100644 --- a/atom/renderer/atom_renderer_client.cc +++ b/atom/renderer/atom_renderer_client.cc @@ -134,6 +134,14 @@ void AtomRendererClient::RunScriptsAtDocumentEnd( void AtomRendererClient::DidCreateScriptContext( v8::Handle context, content::RenderFrame* render_frame) { + // Tizen device API is required both for main frame and iFrames +#if defined(USE_EFL) + if (widget_) { + const content::RenderView* render_view = render_frame->GetRenderView(); + widget_->StartSession(context, render_view->GetRoutingID(), + render_frame->GetWebFrame()->document().baseURL().string().utf8().c_str()); + } +#endif // Only allow node integration for the main frame, unless it is a devtools // extension page. if (!render_frame->IsMainFrame() && !IsDevToolsExtension(render_frame)) @@ -163,17 +171,15 @@ void AtomRendererClient::DidCreateScriptContext( // Give the node loop a run to make sure everything is ready. node_bindings_->RunMessageLoop(); } -#if defined(USE_EFL) - if (widget_) { - const content::RenderView* render_view = render_frame->GetRenderView(); - widget_->StartSession(context, render_view->GetRoutingID(), - render_frame->GetWebFrame()->document().baseURL().string().utf8().c_str()); - } -#endif } void AtomRendererClient::WillReleaseScriptContext( v8::Handle context, content::RenderFrame* render_frame) { + // Required both for main/sub and iframe +#if defined(USE_EFL) + if (widget_) + widget_->StopSession(context); +#endif // Only allow node integration for the main frame, unless it is a devtools // extension page. if (!render_frame->IsMainFrame() && !IsDevToolsExtension(render_frame)) @@ -190,10 +196,6 @@ void AtomRendererClient::WillReleaseScriptContext( // Destroy the node environment. node::FreeEnvironment(env); atom_bindings_->EnvironmentDestroyed(env); -#if defined(USE_EFL) - if (widget_) - widget_->StopSession(context); -#endif } bool AtomRendererClient::ShouldFork(blink::WebLocalFrame* frame, diff --git a/wrt/src/web_window.js b/wrt/src/web_window.js index 06b1f31..95476d8 100644 --- a/wrt/src/web_window.js +++ b/wrt/src/web_window.js @@ -29,6 +29,10 @@ class WebWindow { return { fullscreen: false, show: false, + webPreferences: { + nodeIntegration: false, + nodeIntegrationInWorker: false + }, 'web-preferences': { 'direct-write': true, 'subpixel-font-scaling': false, -- 2.7.4 From 3ddf2519d1ceb796ce881390185c59bbb595f9eb Mon Sep 17 00:00:00 2001 From: Prathmesh Date: Thu, 7 Jun 2018 12:43:41 +0530 Subject: [PATCH 14/16] Add widget object to electron interface - Generate the idls - Build extension independently and add to extension libs Change-Id: Ida4361a75267341ffca46c4d96369a973311e839 Signed-off-by: Prathmesh --- packaging/electron-efl.spec | 9 ++++- tizen/build/common.gypi | 2 +- tizen/extensions/extensions.gyp | 21 ++++++++++ tizen/tools/generate_api.py | 25 ++++++++++++ tizen/tools/mergejs.py | 89 +++++++++++++++++++++++++++++++++++++++++ wrt.gyp | 7 ++++ 6 files changed, 151 insertions(+), 2 deletions(-) create mode 100644 tizen/tools/generate_api.py create mode 100644 tizen/tools/mergejs.py diff --git a/packaging/electron-efl.spec b/packaging/electron-efl.spec index 7e464c1..93ce41f 100755 --- a/packaging/electron-efl.spec +++ b/packaging/electron-efl.spec @@ -70,13 +70,14 @@ cp %{SOURCE1001} . %define _pkgid org.tizen.%{name} %define _xmldir %TZ_SYS_RO_PACKAGES %define _out out.tizen/out/D +%define extension_path %{_libdir}/tizen-extensions-crosswalk DEFINE_ARGS=" libchromiumcontent_component=1 use_efl=1 is_tizen=1 injected_bundle_path=%{_libdir}/libxwalk_injected_bundle.so - extension_path=%{_libdir}/tizen-extensions-crosswalk + extension_path=%{extension_path} " %if "%{?TIZEN_PRODUCT_TV}" == "1" DEFINE_ARGS+=" @@ -140,6 +141,10 @@ mkdir -p %{buildroot}%{extension_path} 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} +# widget plugin +install -p -m 644 %{_out}/lib/libwidget_plugin.so %{buildroot}%{extension_path} +install -p -m 644 %{_out}/gen/widget.json %{buildroot}%{extension_path} + %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'. @@ -172,3 +177,5 @@ rm -fr %{buildroot} %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 +%attr(644,root,root) %{extension_path}/libwidget_plugin.so +%attr(644,root,root) %{extension_path}/widget.json diff --git a/tizen/build/common.gypi b/tizen/build/common.gypi index 8b70ac2..6b4560f 100644 --- a/tizen/build/common.gypi +++ b/tizen/build/common.gypi @@ -30,7 +30,7 @@ 'includes': [ 'cynara-client.gypi', 'pkg-config.gypi', -# 'xwalk_js2c.gypi', + 'xwalk_js2c.gypi', ], 'include_dirs': [ '../', diff --git a/tizen/extensions/extensions.gyp b/tizen/extensions/extensions.gyp index 652dfd1..db9f91c 100644 --- a/tizen/extensions/extensions.gyp +++ b/tizen/extensions/extensions.gyp @@ -67,5 +67,26 @@ }, }, }, # end of target 'xwalk_extension_static' + { + 'target_name': 'widget_plugin', + 'type': 'shared_library', + 'sources': [ + 'internal/widget/widget_api.js', + 'internal/widget/widget_extension.cc', + ], + 'variables': { + 'packages': [ + 'dlog', + ], + }, + 'copies': [ + { + 'destination': '<(SHARED_INTERMEDIATE_DIR)', + 'files': [ + 'internal/widget/widget.json' + ], + }, + ], + }, # end of target 'widget_plugin' ], # end of targets } diff --git a/tizen/tools/generate_api.py b/tizen/tools/generate_api.py new file mode 100644 index 0000000..b50adea --- /dev/null +++ b/tizen/tools/generate_api.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python + +# Copyright (c) 2013 Intel Corporation. All rights reserved. +# Copyright (c) 2014 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. + +import os +import sys +import subprocess + +TEMPLATE = """\ +extern const char %s[]; +const char %s[] = { %s, 0 }; +""" + +js_code = sys.argv[1] +cmd = "python " + os.path.dirname(__file__) + "/mergejs.py -f" + js_code +lines = subprocess.check_output(cmd, shell=True) +c_code = ', '.join(str(ord(c)) for c in lines) + +symbol_name = sys.argv[2] +output = open(sys.argv[3], "w") +output.write(TEMPLATE % (symbol_name, symbol_name, c_code)) +output.close() diff --git a/tizen/tools/mergejs.py b/tizen/tools/mergejs.py new file mode 100644 index 0000000..fc3dc96 --- /dev/null +++ b/tizen/tools/mergejs.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python + +# Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved. + +import fileinput +import sys +import getopt +import glob +import os + +class Utils: + reqfiles = [] + searchfile = '*_api.js' + startwith = "//= require('" + endwith = "')" + code = "" + + @classmethod + def get_require(self, s): + try: + start = s.index(self.startwith) + len(self.startwith) + end = s.index(self.endwith, start) + filename = s[start:end] + self.reqfiles.append(filename) + except ValueError: + return "" + + @classmethod + def find_require(self): + p = os.path.join('./', self.searchfile) + filenames = glob.glob(self.searchfile) + for fname in filenames: + with open(fname, 'r') as myfile: + for line in myfile: + self.get_require(line) + + @classmethod + def print_lines(self, filename): + with open(filename, 'r') as file: + for line in file: + self.code += line + + @classmethod + def merge_js_files(self, path): + self.find_require() + if len(self.reqfiles) == 0: + s = os.path.join('./', self.searchfile) + sfiles = glob.glob(s) + for fname in sfiles: + self.print_lines(fname) + else: + js = '*.js' + p = os.path.join(path, js) + filenames = glob.glob(p) + for fname in self.reqfiles: + fname = path + '/' + fname + if fname in filenames: + self.print_lines(fname) + + @classmethod + def main(self, argv): + path = 'js' + try: + opts, args = getopt.getopt(argv,"hf:p:",["file=", "path="]) + except getopt.GetoptError: + print __file__ + ' -h' + sys.exit() + if len(argv) > 0: + for opt, arg in opts: + if opt in ("-h"): + print 'Help:' + print '' + print __file__ + '-f -p ' + print '' + print ' \t \t\t ' + print '-f \t --file \t Name of the file where script searching for require files:' + print '\t \t \t ' + self.startwith + 'file_name.js' + self.endwith + print '-p \t --path \t Path to "' + path + '" directory' + print '' + sys.exit() + elif opt in ("-f", "--file"): + self.searchfile = arg + elif opt in ("-p", "--path"): + path = arg + self.merge_js_files(path) + print self.code + +if Utils.__module__ == "__main__": + Utils.main(sys.argv[1:]) diff --git a/wrt.gyp b/wrt.gyp index 663ee2c..38a9337 100644 --- a/wrt.gyp +++ b/wrt.gyp @@ -203,5 +203,12 @@ }, ], }, # target electron_shell_copy + { + 'target_name': 'extension_wrt', + 'type': 'none', + 'dependencies': [ + '<(DEPTH)/tizen/extensions/extensions.gyp:widget_plugin', + ], + }, # end of target 'extension_wrt' ], } -- 2.7.4 From 5a2855d676bcf03507e8f0fc1e74313527cf1a3d Mon Sep 17 00:00:00 2001 From: Prathmesh Date: Thu, 7 Jun 2018 16:31:50 +0530 Subject: [PATCH 15/16] Fix build error in widget object module - Ideally widget module needs to be built separately and not included in "wrt". Same is there in xwalk. - But in electron currently, the build system is tightly coupled with wrt executable, so no module can be build as static_lib separately. - Currently coping widget_object in lib directory so that "wrt" exe will not give linking error. - Need to find way to build widget object as static lib without directly linking to "wrt" exe Change-Id: Ia5a5584f5b2165c1be5b5bd9eafc49a3d45ef195 Signed-off-by: Prathmesh --- packaging/electron-efl.spec | 2 ++ wrt.gyp | 8 +------- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/packaging/electron-efl.spec b/packaging/electron-efl.spec index 93ce41f..4f7009a 100755 --- a/packaging/electron-efl.spec +++ b/packaging/electron-efl.spec @@ -143,6 +143,7 @@ install -p -m 644 %{_out}/lib/libxwalk_extension_shared.so %{buildroot}%{_libdir install -p -m 755 %{_out}/lib/libxwalk_injected_bundle.so %{buildroot}%{_libdir} # widget plugin install -p -m 644 %{_out}/lib/libwidget_plugin.so %{buildroot}%{extension_path} +install -p -m 644 %{_out}/lib/libwidget_plugin.so %{buildroot}%{_libdir} install -p -m 644 %{_out}/gen/widget.json %{buildroot}%{extension_path} %post @@ -177,5 +178,6 @@ rm -fr %{buildroot} %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 +%attr(644,root,root) %{_libdir}/libwidget_plugin.so %attr(644,root,root) %{extension_path}/libwidget_plugin.so %attr(644,root,root) %{extension_path}/widget.json diff --git a/wrt.gyp b/wrt.gyp index 38a9337..73af0b5 100644 --- a/wrt.gyp +++ b/wrt.gyp @@ -14,6 +14,7 @@ '<(DEPTH)/tizen/common/common.gyp:wrt_common', '<(DEPTH)/tizen/loader/loader.gyp:wrt-loader', '<(DEPTH)/tizen/extensions/extensions.gyp:xwalk_extension_shared', + '<(DEPTH)/tizen/extensions/extensions.gyp:widget_plugin', '<(DEPTH)/tizen/renderer/injected_bundle.gyp:xwalk_injected_bundle', '<(DEPTH)/efl/build/system.gyp:ecore', '<(DEPTH)/efl/build/system.gyp:launchpad', @@ -203,12 +204,5 @@ }, ], }, # target electron_shell_copy - { - 'target_name': 'extension_wrt', - 'type': 'none', - 'dependencies': [ - '<(DEPTH)/tizen/extensions/extensions.gyp:widget_plugin', - ], - }, # end of target 'extension_wrt' ], } -- 2.7.4 From 82c0194dbc7c3c332bc5d2f1823cb3363e9bb9ef Mon Sep 17 00:00:00 2001 From: Prathmesh Date: Fri, 8 Jun 2018 12:10:04 +0530 Subject: [PATCH 16/16] Add splash screen object to electron interface - Build and generate idl's - Make splash screen object avaliable Change-Id: I01785552dad600a38b5e13485bfbdabfc6ba68a1 Signed-off-by: Prathmesh --- packaging/electron-efl.spec | 15 +++++++++++++-- tizen/extensions/extensions.gyp | 21 +++++++++++++++++++++ wrt.gyp | 1 + 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/packaging/electron-efl.spec b/packaging/electron-efl.spec index 4f7009a..91e9ae0 100755 --- a/packaging/electron-efl.spec +++ b/packaging/electron-efl.spec @@ -143,8 +143,15 @@ install -p -m 644 %{_out}/lib/libxwalk_extension_shared.so %{buildroot}%{_libdir install -p -m 755 %{_out}/lib/libxwalk_injected_bundle.so %{buildroot}%{_libdir} # widget plugin install -p -m 644 %{_out}/lib/libwidget_plugin.so %{buildroot}%{extension_path} -install -p -m 644 %{_out}/lib/libwidget_plugin.so %{buildroot}%{_libdir} install -p -m 644 %{_out}/gen/widget.json %{buildroot}%{extension_path} +# Need to remove the below line later +install -p -m 644 %{_out}/lib/libwidget_plugin.so %{buildroot}%{_libdir} + +# screen_plugin +install -p -m 644 %{_out}/lib/libsplash_screen_plugin.so %{buildroot}%{extension_path} +install -p -m 644 %{_out}/gen/splash_screen.json %{buildroot}%{extension_path} +# Need to remove the below line later +install -p -m 644 %{_out}/lib/libsplash_screen_plugin.so %{buildroot}%{_libdir} %post # Owner account can't write /opt/usr/home/owner/data/org.tizen.electron-efl @@ -178,6 +185,10 @@ rm -fr %{buildroot} %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 -%attr(644,root,root) %{_libdir}/libwidget_plugin.so %attr(644,root,root) %{extension_path}/libwidget_plugin.so %attr(644,root,root) %{extension_path}/widget.json +%attr(644,root,root) %{extension_path}/libsplash_screen_plugin.so +%attr(644,root,root) %{extension_path}/splash_screen.json +# Need to remove these below lines later +%attr(644,root,root) %{_libdir}/libwidget_plugin.so +%attr(644,root,root) %{_libdir}/libsplash_screen_plugin.so diff --git a/tizen/extensions/extensions.gyp b/tizen/extensions/extensions.gyp index db9f91c..d22c755 100644 --- a/tizen/extensions/extensions.gyp +++ b/tizen/extensions/extensions.gyp @@ -88,5 +88,26 @@ }, ], }, # end of target 'widget_plugin' + { + 'target_name': 'splash_screen_plugin', + 'type': 'shared_library', + 'sources': [ + 'internal/splash_screen/splash_screen_api.js', + 'internal/splash_screen/splash_screen_extension.cc', + ], + 'variables': { + 'packages': [ + 'dlog', + ], + }, + 'copies': [ + { + 'destination': '<(SHARED_INTERMEDIATE_DIR)', + 'files': [ + 'internal/splash_screen/splash_screen.json' + ], + }, + ], + }, # end of target 'splash_screen_plugin' ], # end of targets } diff --git a/wrt.gyp b/wrt.gyp index 73af0b5..eef72f2 100644 --- a/wrt.gyp +++ b/wrt.gyp @@ -15,6 +15,7 @@ '<(DEPTH)/tizen/loader/loader.gyp:wrt-loader', '<(DEPTH)/tizen/extensions/extensions.gyp:xwalk_extension_shared', '<(DEPTH)/tizen/extensions/extensions.gyp:widget_plugin', + '<(DEPTH)/tizen/extensions/extensions.gyp:splash_screen_plugin', '<(DEPTH)/tizen/renderer/injected_bundle.gyp:xwalk_injected_bundle', '<(DEPTH)/efl/build/system.gyp:ecore', '<(DEPTH)/efl/build/system.gyp:launchpad', -- 2.7.4