bool ChromeContentRendererClient::IsOriginIsolatedPepperPlugin(
const base::FilePath& plugin_path) {
- // Hosting plugins in-process is inherently incompatible with attempting to
- // process-isolate plugins from different origins.
- auto* cmdline = base::CommandLine::ForCurrentProcess();
- if (cmdline->HasSwitch(switches::kPpapiInProcess)) {
- // The kPpapiInProcess switch should only be used by tests. In particular,
- // we expect that the PDF plugin should always be isolated in the product
- // (and that the switch won't interfere with PDF isolation).
- CHECK_NE(ChromeContentClient::kPDFPluginPath, plugin_path.value());
-
- return false;
- }
-
-#if BUILDFLAG(ENABLE_NACL)
- // Don't isolate the NaCl plugin (preserving legacy behavior).
- if (plugin_path.value() == nacl::kInternalNaClPluginFileName)
- return false;
-#endif
-
- // Isolate all the other plugins (including the PDF plugin + test plugins).
- return true;
+ return plugin_path.value() == ChromeContentClient::kPDFPluginPath;
}
#if BUILDFLAG(ENABLE_PLUGINS) && BUILDFLAG(ENABLE_EXTENSIONS)
# Enables Native Client support.
#
# Intentionally and permanently disable nacl on arm64 mac.
- enable_nacl =
- checkout_nacl && _cpu_is_supported && target_os != "ios" && !is_android &&
- !is_fuchsia && !is_castos && !(is_win && host_os != "win") &&
- !(is_mac && (host_os != "mac" || target_cpu != "x64")) && !use_efl
+ #enable_nacl = !is_ios && !is_android && !is_fuchsia && !is_chromecast &&
+ # current_cpu != "mipsel" && current_cpu != "mips64el" &&
+ # !(is_linux && target_cpu == "arm64") && !use_efl
+ #TDDO: When nacl module upload, enable_nacl will be changed.
+ enable_nacl = false
}
assert(!(is_win && host_os != "win") || !enable_nacl,
i->second.push_back(time);
}
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+void PluginServiceImpl::AddPepperPlugins(
+ const std::vector<ContentPluginInfo>& plugins) {
+ for (const auto& plugin : plugins) {
+ plugins_.push_back(plugin);
+ RegisterInternalPlugin(plugin.ToWebPluginInfo(), true);
+ }
+}
+#endif
+
bool PluginServiceImpl::IsPluginUnstable(const base::FilePath& path) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
std::map<base::FilePath, std::vector<base::Time> >::const_iterator i =
// Used to monitor plugin stability.
void RegisterPluginCrash(const base::FilePath& plugin_path);
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+ void AddPepperPlugins(const std::vector<ContentPluginInfo>& plugins);
+#endif
+
// For testing without creating many, many processes.
void SetMaxPpapiProcessesPerProfileForTesting(int number) {
max_ppapi_processes_per_profile_ = number;
setenv("HOME", homedir.value().c_str(), 1);
#endif
+#if defined(USE_EFL) && defined(TIZEN_PEPPER_EXTENSIONS)
+ base::SingleThreadTaskExecutor main_thread_task_executor(
+ base::MessagePumpType::ECORE);
+#else
base::SingleThreadTaskExecutor main_thread_task_executor;
+#endif
base::PlatformThread::SetName("CrPPAPIMain");
base::trace_event::TraceLog::GetInstance()->set_process_name("PPAPI Process");
base::trace_event::TraceLog::GetInstance()->SetProcessSortIndex(
ContentPluginInfo::ContentPluginInfo() = default;
ContentPluginInfo::ContentPluginInfo(const ContentPluginInfo& other) = default;
-ContentPluginInfo::ContentPluginInfo(ContentPluginInfo&& other) noexcept =
- default;
+//ContentPluginInfo::ContentPluginInfo(ContentPluginInfo&& other) noexcept =
+// default;
ContentPluginInfo::~ContentPluginInfo() = default;
WebPluginInfo ContentPluginInfo::ToWebPluginInfo() const {
ContentPluginInfo();
ContentPluginInfo(const ContentPluginInfo& other);
- ContentPluginInfo(ContentPluginInfo&& other) noexcept;
+// ContentPluginInfo(ContentPluginInfo&& other) noexcept;
~ContentPluginInfo();
WebPluginInfo ToWebPluginInfo() const;
#include "content/public/renderer/content_renderer_client.h"
-#include "base/command_line.h"
#include "build/build_config.h"
#include "components/cast_streaming/renderer/public/resource_provider.h"
-#include "content/public/common/content_switches.h"
#include "media/base/demuxer.h"
#include "media/base/renderer_factory.h"
#include "third_party/blink/public/common/security/protocol_handler_security_level.h"
bool ContentRendererClient::IsOriginIsolatedPepperPlugin(
const base::FilePath& plugin_path) {
- // Hosting plugins in-process is inherently incompatible with attempting to
- // process-isolate plugins from different origins.
- auto* cmdline = base::CommandLine::ForCurrentProcess();
- if (cmdline->HasSwitch(switches::kPpapiInProcess))
- return false;
-
- return true;
+ return false;
}
void ContentRendererClient::GetSupportedKeySystems(
}
void PepperPluginInstanceImpl::InstanceCrashed() {
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+ SendCrashEvent();
+#endif // defined(TIZEN_PEPPER_EXTENSIONS)
// Force free all resources and vars.
HostGlobals::Get()->InstanceCrashed(pp_instance());
// Some APIs aren't implemented in-process.
switch (id) {
case ppapi::BROWSER_FONT_SINGLETON_ID:
+ case ppapi::EXTENSION_SYSTEM_SINGLETON_ID:
case ppapi::ISOLATED_FILESYSTEM_SINGLETON_ID:
case ppapi::NETWORK_PROXY_SINGLETON_ID:
+ case ppapi::REMOTE_CONTROLLER_SINGLETON_ID:
NOTIMPLEMENTED();
return nullptr;
case ppapi::GAMEPAD_SINGLETON_ID:
audio_controller().SetVolume(volume);
}
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+void PepperPluginInstanceImpl::SendCrashEventOnMainThread() {
+ LOG(WARNING) << "Sending event crash";
+ // It's possible that container() is NULL if the plugin has been removed from
+ // the DOM (but the PluginInstance is not destroyed yet).
+ if (!container_) {
+ LOG(WARNING) << "No container information, can't send crash event";
+ return;
+ }
+
+ blink::WebLocalFrame* frame =
+ container_->GetElement().GetDocument().GetFrame();
+ if (!frame) {
+ LOG(WARNING) << "Failed to acquire frame, can't send crash event";
+ return;
+ }
+ v8::HandleScope handle_scope(GetIsolate());
+ v8::Local<v8::Context> context(GetIsolate()->GetCurrentContext());
+ if (context.IsEmpty()) {
+ // If there's no JavaScript on the stack, we have to make a new Context.
+ context = v8::Context::New(GetIsolate());
+ }
+ v8::Context::Scope context_scope(context);
+ container_->DispatchProgressEvent(WebString::FromUTF8("crash"), true, 1, 1,
+ WebString::FromUTF8(""));
+}
+
+void PepperPluginInstanceImpl::SendCrashEvent() {
+ ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&PepperPluginInstanceImpl::SendCrashEventOnMainThread, this));
+}
+#endif // defined(TIZEN_PEPPER_EXTENSIONS)
} // namespace content
// Whether a given viz::TransferableResource is in use by |texture_layer_|.
bool IsTextureInUse(const viz::TransferableResource& resource) const;
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+ void SendCrashEvent();
+ void SendCrashEventOnMainThread();
+#endif // defined(TIZEN_PEPPER_EXTENSIONS)
+
RenderFrameImpl* render_frame_;
scoped_refptr<PluginModule> module_;
std::unique_ptr<ppapi::PPP_Instance_Combined> instance_interface_;
#include "content/renderer/pepper/plugin_module.h"
#include "ppapi/shared_impl/ppapi_permissions.h"
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+#include <algorithm>
+#endif
+
namespace content {
// static
PepperPluginRegistry::PepperPluginRegistry() {}
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+void PepperPluginRegistry::AddOutOfProcessPlugins(
+ const std::vector<ContentPluginInfo>& plugins) {
+ std::copy(plugins.begin(), plugins.end(), std::back_inserter(plugin_list_));
+}
+#endif
+
void PepperPluginRegistry::Initialize() {
ComputePepperPluginList(&plugin_list_);
#include <map>
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+#include <vector>
+#endif
+
#include "base/memory/ref_counted.h"
#include "content/public/common/content_plugin_info.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
void PluginModuleDead(PluginModule* dead_module);
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+ // Adds out-of-process plugins which became available after registry
+ // has been initialized
+ void AddOutOfProcessPlugins(const std::vector<ContentPluginInfo>& plugins);
+#endif
+
private:
PepperPluginRegistry();
void Initialize();
#include "ppapi/thunk/enter.h"
#include "ppapi/thunk/ppb_graphics_2d_api.h"
#include "ppapi/thunk/thunk.h"
+
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+#include "ppapi/c/samsung/ppb_extension_system_samsung.h"
+#include "ppapi/c/samsung/ppb_remote_controller_samsung.h"
+#endif // defined(TIZEN_PEPPER_EXTENSIONS)
+
#include "third_party/blink/public/platform/web_security_origin.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/blink/public/web/web_view.h"
#include "ppapi/thunk/interfaces_ppb_public_dev_channel.h"
#include "ppapi/thunk/interfaces_ppb_public_socket.h"
#include "ppapi/thunk/interfaces_ppb_public_stable.h"
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+#include "ppapi/thunk/interfaces_ppb_samsung.h"
+#endif // defined(TIZEN_PEPPER_EXTENSIONS)
#undef PROXIED_IFACE
#if BUILDFLAG(ENABLE_PLUGINS)
#if defined(ENABLE_WRT_JS)
namespace content {
-struct PepperPluginInfo;
+struct ContentPluginInfo;
}
#else
#include "content/public/common/content_plugin_info.h"
BuildRequires: pkgconfig(capi-media-sound-manager)
BuildRequires: pkgconfig(capi-stt-wrapper-tv)
BuildRequires: pkgconfig(capi-system-display-rotator)
+BuildRequires: pkgconfig(capi-appfw-app-manager)
+BuildRequires: pkgconfig(cynara-client)
BuildRequires: pkgconfig(drmdecrypt)
BuildRequires: pkgconfig(efl-assist)
BuildRequires: pkgconfig(lwipc)
Chromium EFL unit test utilities
%endif
+%if 0%{?build_tizen_ppapi_extension_unittests}
+%package tizen_ppapi_extension_unittests
+Summary: Chromium tizen ppapi extension unittests
+Group: Development/UnitTests
+Requires: %{name} = %{version}-%{release}
+%description tizen_ppapi_extension_unittests
+Chromium tizen ppapi extension unit test utilities
+%endif
+
# The macros '%TZ_' are valid from tizen v3.0
%define _pkgid org.tizen.%{name}
%define _xmldir %TZ_SYS_RO_PACKAGES
%if 0%{?build_ewk_unittests}
ewk_unittests \
%endif
+%if 0%{?build_tizen_ppapi_extension_unittests}
+ efl_integration_unittests \
+ ppapi_unittests \
+%endif
%if 0%{?__enable_wrt_js}
wrt wrt-service wrt-service-launcher \
%endif
%if 0%{?_enable_unittests}
ninja %{_smp_mflags} -C"%{OUTPUT_FOLDER}" angle_unittests env_chromium_unittests cacheinvalidation_unittests \
+ angle_unittests env_chromium_unittests cacheinvalidation_unittests \
url_unittests sandbox_linux_unittests crypto_unittests sql_unittests accessibility_unittests \
gfx_unittests printing_unittests events_unittests ppapi_unittests jingle_unittests \
flip_in_mem_edsm_server_unittests breakpad_unittests dbus_unittests libphonenumber_unittests \
if [ ! -d %{buildroot}/../../OTHER/ -a -f /opt/testing/bin/rpmlint ]; then
mkdir -p %{buildroot}/../../OTHER/
fi
+# Running unittests
+%if 0%{?run_unittests_in_gbs}
+%if 0%{?build_tizen_ppapi_extension_unittests}
+%{OUTPUT_FOLDER}/efl_integration_unittests
+%{OUTPUT_FOLDER}/ppapi_unittests
+%endif
+%endif
echo %{version} > "%{OUTPUT_FOLDER}"/version
install -m 0755 tizen_src/ewk/utc_gtest_run.sh %{buildroot}/opt/usr/utc_exec/
%endif
+%if 0%{?build_tizen_ppapi_extension_unittests}
+mkdir -p %{buildroot}/opt/usr/utc_exec/
+install -m 0755 -p -D %{OUTPUT_FOLDER}/efl_integration_unittests %{buildroot}/opt/usr/utc_exec/
+install -m 0755 -p -D %{OUTPUT_FOLDER}/ppapi_unittests %{buildroot}/opt/usr/utc_exec/
+%endif
%if 0%{?__enable_wrt_js}
%define __wrt_resourcedir %{CHROMIUM_LIB_DIR}/wrt
%if "%{?tizen_profile_name}" != "tv"
/opt/usr/utc_exec/*
/opt/usr/resources/*
%endif
+
+%if "%{chromium_efl_tizen_profile}" == "tv"
+ln -s %{CHROMIUM_EXE_DIR}/efl_webprocess %{buildroot}%{CHROMIUM_EXE_DIR}/efl_pluginprocess
+%endif
+
+%if 0%{?build_tizen_ppapi_extension_unittests}
+%files tizen_ppapi_extension_unittests
+%defattr(-,root,root,-)
+%manifest ./packaging/chromium-tizen_ppapi_extension_unittests.manifest
+/opt/usr/utc_exec/*
+%endif
--- /dev/null
+<manifest>
+ <request>
+ <domain name="_"/>
+ </request>
+</manifest>
\ No newline at end of file
"shared_impl/var_tracker_unittest.cc",
]
+ if(tizen_pepper_extensions == 1 && enable_plugins == 1) {
+ sources += [
+ "proxy/var_value_converter_unittest.cc",
+ ]
+ }
+
deps = [
"//base/test:test_support",
"//gpu/ipc/common:command_buffer_traits",
'ppapi/thunk/interfaces_ppb_public_dev_channel.h',
'ppapi/thunk/interfaces_ppb_public_dev.h',
'ppapi/thunk/interfaces_ppb_public_stable.h',
- 'ppapi/thunk/interfaces_ppb_public_socket.h')
+ 'ppapi/thunk/interfaces_ppb_public_socket.h',
+ 'ppapi/thunk/interfaces_ppb_samsung.h')
+
HISTOGRAM_XML_FILE = 'tools/metrics/histograms/enums.xml'
interface_changes = []
has_histogram_xml_change = False
--- /dev/null
+// Copyright 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.
+/**
+ * This file defines the <code>PPB_ExtensionSystem_Samsung</code> interface.
+ */
+
+[generate_thunk]
+
+label Chrome {
+ M35 = 0.1
+ };
+
+/**
+ * The PPB_ExtensionSystem_Samsung interface contains pointers to functions
+ * related to the extension system. The extension system can be different for
+ * each browser.
+ */
+ [singleton]
+interface PPB_ExtensionSystem_Samsung {
+ /**
+ * GetEmbedderName() provides string with embedder name (embedder of current
+ * extension). "Chrome", "TizenWRT", "ExtensionEngine" are one of possible
+ * values.
+ *
+ * @param[in] instance A <code>PP_Instance</code> identifying one instance
+ * of a module.
+ *
+ * @return A <code>PP_Var</code> with name of extension embedder.
+ */
+ PP_Var GetEmbedderName(
+ [in] PP_Instance instance);
+
+ /**
+ * GetCurrentExtensionInfo() gets dictionary with information for current
+ * extension. Keys and values of the dictionary are dependant on the
+ * embedder, and they can differ between embedders. If current embedder does
+ * not support extension system undefined value is returned.
+ *
+ * @param[in] instance A <code>PP_Instance</code> identifying one instance
+ * of a module.
+ *
+ * @return A <code>PP_Var</code> with information of current extension.
+ */
+ PP_Var GetCurrentExtensionInfo(
+ [in] PP_Instance instance);
+
+ /**
+ * GenericSyncCall() executes operation associated with the current
+ * extension. The operation is synchronous and blocks the caller until
+ * completes. See embedder documentation to know what operations are
+ * possible.
+ *
+ * @param[in] instance A <code>PP_Instance</code> identifying one instance
+ * of a module.
+ * @param[in] operation_name A string with name of operation to execute.
+ * @param[in] operation_argument A variable to be passed to embedder
+ * @param[out] result A variable containing result of execution (embedder
+ * defined).
+ *
+ * @return An int32_t containing an error code from <code>pp_errors.h</code>.
+ */
+ int32_t GenericSyncCall(
+ [in] PP_Instance instance,
+ [in] PP_Var operation_name,
+ [in] PP_Var operation_argument,
+ [out] PP_Var result);
+};
--- /dev/null
+/* Copyright 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.
+ */
+
+/**
+ * This file defines <code>PPB_RemoteController_Samsung</code> interface,
+ * which can be used for various actions related to TV Remote Controller like
+ * registering for input Keys.
+ *
+ * See
+ * <code>https://www.samsungdforum.com/TizenGuide/tizen231/index.html</code>
+ * for description of Remote Controller and its keys.
+ */
+
+[generate_thunk]
+
+label Chrome {
+ M47 = 0.1
+};
+
+/**
+ * The PPB_RemoteControl_Samsung interface contains pointer to functions
+ * related to Remote Controller.
+ *
+ * See
+ * <code>https://www.samsungdforum.com/TizenGuide/tizen231/index.html</code>
+ * for description of Remote Controller and its keys.
+ */
+[singleton]
+interface PPB_RemoteController_Samsung {
+ /**
+ * RegisterKeys() function registers given key arrays to be grabbed by
+ * the application/widget containing pepper plugin calling this method.
+ *
+ * <strong>Note:</strong>
+ * After registering for grabbing keys, events related to that key
+ * will be delivered directly to the application/widget.
+ *
+ * <strong>Note:</strong>
+ * For some embedders, we can`t tell if key that we try to register have
+ * failed because it have been already registered. So if at least one key
+ * have been successfully processed, we assume that other keys that failed,
+ * have been already registered before this call.
+ *
+ * @param[in] instance A <code>PP_Instance</code> identifying instance
+ * of the module
+ * @param[in] key_count A number of keys which will be grabbed.
+ * @param[in] keys An array containing list of keys which should be grabbed.
+ *
+ * @return An int32_t containing an error code from <code>pp_errors.h</code>.
+ * Returns <code>PP_ERROR_BADARGUMENT</code> if <code>key_count</code> is
+ * equal 0 or one of <code>keys</code> is not supported anymore.
+ * Returns <code>PP_ERROR_NOTSUPPORTED</code> if currently launched embedder
+ * doesn`t support key registering.
+ * Returns <code>PP_ERROR_FAILED</code> if registering all <code>keys</code>
+ * have failed.
+ * Returns <code>PP_OK</code> if at lest one key from <code>keys</code> have
+ * been registered.
+ */
+ int32_t RegisterKeys([in] PP_Instance instance,
+ [in] uint32_t key_count,
+ [in, size_as=key_count] str_t[] keys);
+
+ /**
+ * UnregisterKeys() function unregisters given key arrays from being grabbed
+ * by the application/widget containing pepper plugin calling this method.
+ *
+ * <strong>Note:</strong>
+ * For some embedders, we can`t tell if key that we try to unregister have
+ * failed because it have been already unregistered. So if at least one key
+ * have been successfully processed, we assume that other keys that failed,
+ * have been already unregistered before this call.
+ *
+ * @param[in] instance A <code>PP_Instance</code> identifying instance
+ * of the module
+ * @param[in] key_count A number of keys which will be grabbed.
+ * @param[in] keys An array containing list of keys which should be grabbed.
+ *
+ * @return An int32_t containing an error code from <code>pp_errors.h</code>.
+ * Returns <code>PP_ERROR_BADARGUMENT</code> if <code>key_count</code> is
+ * equal 0 or one of <code>keys</code> is not supported anymore.
+ * Returns <code>PP_ERROR_NOTSUPPORTED</code> if currently launched embedder
+ * doesn`t support key registering.
+ * Returns <code>PP_ERROR_FAILED</code> if registering all <code>keys</code>
+ * have failed.
+ * Returns <code>PP_OK</code> if at lest one key from <code>keys</code> have
+ * been registered.
+ */
+ int32_t UnRegisterKeys([in] PP_Instance instance,
+ [in] uint32_t key_count,
+ [in, size_as=key_count] str_t[] keys);
+};
#
# In particular, the PDF viewer (enable_pdf) requires plugin support, but it
# does not require Pepper support (enable_ppapi).
- enable_plugins = !is_android && !is_ios && !is_castos
+ enable_plugins = is_tizen || (!is_android && !is_ios && !is_castos)
}
declare_args() {
--- /dev/null
+/* Copyright (c) 2016 Samsung Electronics. All rights reserved.
+ */
+
+/* From samsung/ppb_extension_system_samsung.idl,
+ * modified Thu Feb 25 15:18:37 2016.
+ */
+
+#ifndef PPAPI_C_SAMSUNG_PPB_EXTENSION_SYSTEM_SAMSUNG_H_
+#define PPAPI_C_SAMSUNG_PPB_EXTENSION_SYSTEM_SAMSUNG_H_
+
+#include "ppapi/c/pp_bool.h"
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_macros.h"
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/c/pp_var.h"
+
+#define PPB_EXTENSIONSYSTEM_SAMSUNG_INTERFACE_0_1 \
+ "PPB_ExtensionSystem_Samsung;0.1"
+#define PPB_EXTENSIONSYSTEM_SAMSUNG_INTERFACE \
+ PPB_EXTENSIONSYSTEM_SAMSUNG_INTERFACE_0_1
+
+/**
+ * @file
+ * This file defines the <code>PPB_ExtensionSystem_Samsung</code> interface.
+ */
+
+/**
+ * @addtogroup Interfaces
+ * @{
+ */
+/**
+ * The PPB_ExtensionSystem_Samsung interface contains pointers to functions
+ * related to the extension system. The extension system can be different for
+ * each browser.
+ */
+struct PPB_ExtensionSystem_Samsung_0_1 {
+ /**
+ * GetEmbedderName() provides string with embedder name (embedder of current
+ * extension).
+ *
+ * @param[in] instance A <code>PP_Instance</code> identifying one instance
+ * of a module.
+ *
+ * @return A <code>PP_Var</code> with name of extension embedder.
+ */
+ struct PP_Var (*GetEmbedderName)(PP_Instance instance);
+ /**
+ * GetCurrentExtensionInfo() gets dictionary with information for current
+ * extension. Keys and values of the dictionary are dependant on the
+ * embedder, and they can differ between embedders. If current embedder does
+ * not support extension system undefined value is returned.
+ *
+ * @param[in] instance A <code>PP_Instance</code> identifying one instance
+ * of a module.
+ *
+ * @return A <code>PP_Var</code> with information of current extension.
+ */
+ struct PP_Var (*GetCurrentExtensionInfo)(PP_Instance instance);
+ /**
+ * GenericSyncCall() executes operation associated with the current
+ * extension. The operation is synchronous and blocks the caller until
+ * completes. See embedder documentation to know what operations are
+ * possible.
+ *
+ * @param[in] instance A <code>PP_Instance</code> identifying one instance
+ * of a module.
+ * @param[in] operation_name A string with name of operation to execute.
+ * @param[in] operation_argument A variable to be passed to embedder
+ * @param[out] result A variable containing result of execution (embedder
+ * defined).
+ *
+ * @return An int32_t containing an error code from <code>pp_errors.h</code>.
+ */
+ int32_t (*GenericSyncCall)(PP_Instance instance,
+ struct PP_Var operation_name,
+ struct PP_Var operation_argument,
+ struct PP_Var* result);
+};
+
+typedef struct PPB_ExtensionSystem_Samsung_0_1 PPB_ExtensionSystem_Samsung;
+/**
+ * @}
+ */
+
+#endif /* PPAPI_C_SAMSUNG_PPB_EXTENSION_SYSTEM_SAMSUNG_H_ */
--- /dev/null
+/* Copyright 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.
+ */
+
+/* From samsung/ppb_remote_controller_samsung.idl,
+ * modified Fri Oct 7 12:45:45 2016.
+ */
+
+#ifndef PPAPI_C_SAMSUNG_PPB_REMOTE_CONTROLLER_SAMSUNG_H_
+#define PPAPI_C_SAMSUNG_PPB_REMOTE_CONTROLLER_SAMSUNG_H_
+
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_macros.h"
+#include "ppapi/c/pp_stdint.h"
+
+#define PPB_REMOTECONTROLLER_SAMSUNG_INTERFACE_0_1 \
+ "PPB_RemoteController_Samsung;0.1"
+#define PPB_REMOTECONTROLLER_SAMSUNG_INTERFACE \
+ PPB_REMOTECONTROLLER_SAMSUNG_INTERFACE_0_1
+
+/**
+ * @file
+ * This file defines <code>PPB_RemoteController_Samsung</code> interface,
+ * which can be used for various actions related to TV Remote Controller like
+ * registering for input Keys.
+ *
+ * See
+ * <code>https://www.samsungdforum.com/TizenGuide/tizen231/index.html</code>
+ * for description of Remote Controller and its keys.
+ */
+
+/**
+ * @addtogroup Interfaces
+ * @{
+ */
+/**
+ * The PPB_RemoteControl_Samsung interface contains pointer to functions
+ * related to Remote Controller.
+ *
+ * See
+ * <code>https://www.samsungdforum.com/TizenGuide/tizen231/index.html</code>
+ * for description of Remote Controller and its keys.
+ */
+struct PPB_RemoteController_Samsung_0_1 {
+ /**
+ * RegisterKeys() function registers given key arrays to be grabbed by
+ * the application/widget containing pepper plugin calling this method.
+ *
+ * <strong>Note:</strong>
+ * After registering for grabbing keys, events related to that key
+ * will be delivered directly to the application/widget.
+ *
+ * <strong>Note:</strong>
+ * For some embedders, we can`t tell if key that we try to register have
+ * failed because it have been already registered. So if at least one key
+ * have been successfully processed, we assume that other keys that failed,
+ * have been already registered before this call.
+ *
+ * @param[in] instance A <code>PP_Instance</code> identifying instance
+ * of the module
+ * @param[in] key_count A number of keys which will be grabbed.
+ * @param[in] keys An array containing list of keys which should be grabbed.
+ *
+ * @return An int32_t containing an error code from <code>pp_errors.h</code>.
+ * Returns <code>PP_ERROR_BADARGUMENT</code> if <code>key_count</code> is
+ * equal 0 or one of <code>keys</code> is not supported anymore.
+ * Returns <code>PP_ERROR_NOTSUPPORTED</code> if currently launched embedder
+ * doesn`t support key registering.
+ * Returns <code>PP_ERROR_FAILED</code> if registering all <code>keys</code>
+ * have failed.
+ * Returns <code>PP_OK</code> if at lest one key from <code>keys</code> have
+ * been registered.
+ */
+ int32_t (*RegisterKeys)(PP_Instance instance,
+ uint32_t key_count,
+ const char* keys[]);
+ /**
+ * UnregisterKeys() function unregisters given key arrays from being grabbed
+ * by the application/widget containing pepper plugin calling this method.
+ *
+ * <strong>Note:</strong>
+ * For some embedders, we can`t tell if key that we try to unregister have
+ * failed because it have been already unregistered. So if at least one key
+ * have been successfully processed, we assume that other keys that failed,
+ * have been already unregistered before this call.
+ *
+ * @param[in] instance A <code>PP_Instance</code> identifying instance
+ * of the module
+ * @param[in] key_count A number of keys which will be grabbed.
+ * @param[in] keys An array containing list of keys which should be grabbed.
+ *
+ * @return An int32_t containing an error code from <code>pp_errors.h</code>.
+ * Returns <code>PP_ERROR_BADARGUMENT</code> if <code>key_count</code> is
+ * equal 0 or one of <code>keys</code> is not supported anymore.
+ * Returns <code>PP_ERROR_NOTSUPPORTED</code> if currently launched embedder
+ * doesn`t support key registering.
+ * Returns <code>PP_ERROR_FAILED</code> if registering all <code>keys</code>
+ * have failed.
+ * Returns <code>PP_OK</code> if at lest one key from <code>keys</code> have
+ * been registered.
+ */
+ int32_t (*UnRegisterKeys)(PP_Instance instance,
+ uint32_t key_count,
+ const char* keys[]);
+};
+
+typedef struct PPB_RemoteController_Samsung_0_1 PPB_RemoteController_Samsung;
+/**
+ * @}
+ */
+
+#endif /* PPAPI_C_SAMSUNG_PPB_REMOTE_CONTROLLER_SAMSUNG_H_ */
--- /dev/null
+// Copyright 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.
+
+#include "ppapi/cpp/samsung/extension_system_samsung.h"
+
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/c/samsung/ppb_extension_system_samsung.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace pp {
+
+namespace {
+
+template <>
+const char* interface_name<PPB_ExtensionSystem_Samsung_0_1>() {
+ return PPB_EXTENSIONSYSTEM_SAMSUNG_INTERFACE_0_1;
+}
+
+} // namespace
+
+ExtensionSystemSamsung::ExtensionSystemSamsung(const InstanceHandle& instance)
+ : instance_(instance) {}
+
+ExtensionSystemSamsung::~ExtensionSystemSamsung() {}
+
+std::string ExtensionSystemSamsung::GetEmbedderName() const {
+ if (!has_interface<PPB_ExtensionSystem_Samsung_0_1>())
+ return std::string();
+ Var result(PASS_REF,
+ get_interface<PPB_ExtensionSystem_Samsung_0_1>()->GetEmbedderName(
+ instance_.pp_instance()));
+ return result.is_string() ? result.AsString() : std::string();
+}
+
+Var ExtensionSystemSamsung::GetCurrentExtensionInfo() {
+ if (!has_interface<PPB_ExtensionSystem_Samsung_0_1>())
+ return Var();
+ PP_Var rv =
+ get_interface<PPB_ExtensionSystem_Samsung_0_1>()->GetCurrentExtensionInfo(
+ instance_.pp_instance());
+ return Var(PASS_REF, rv);
+}
+
+Var ExtensionSystemSamsung::GenericSyncCall(const Var& operation_name,
+ const Var& operation_data) {
+ if (!has_interface<PPB_ExtensionSystem_Samsung_0_1>())
+ return Var();
+ PP_Var operation_result;
+ int32_t error =
+ get_interface<PPB_ExtensionSystem_Samsung_0_1>()->GenericSyncCall(
+ instance_.pp_instance(), operation_name.pp_var(),
+ operation_data.pp_var(), &operation_result);
+ if (error != PP_OK)
+ return Var();
+ return Var(PASS_REF, operation_result);
+}
+
+} // namespace pp
--- /dev/null
+// Copyright 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 PPAPI_CPP_SAMSUNG_EXTENSION_SYSTEM_SAMSUNG_H_
+#define PPAPI_CPP_SAMSUNG_EXTENSION_SYSTEM_SAMSUNG_H_
+
+#include <string>
+
+#include "ppapi/cpp/instance_handle.h"
+#include "ppapi/cpp/var.h"
+
+/// @file
+/// This file defines APIs related to extension system provided by the browser.
+
+namespace pp {
+
+class ExtensionSystemSamsung {
+ public:
+ /// GetEmbedderName() returns name of the extension system provider.
+ std::string GetEmbedderName() const;
+
+ /// GetCurrentExtensionInfo() returns information about current extension.
+ /// If browser does not support extension system, it will return undefined
+ /// value.
+ Var GetCurrentExtensionInfo();
+
+ /// GenericSyncCall() communicates synchronously with extension system.
+ /// The extension system will execute operation |operation_name| with provided
+ /// arguments |operation_data|. See embedder documentation to know what
+ /// operations are possible.
+ ///
+ /// @param[in] operation_name The name of operation to execute.
+ /// @param[in] operation_data Additional arguments for operation execution.
+ Var GenericSyncCall(const Var& operation_name, const Var& operation_data);
+
+ protected:
+ /// A constructor for creating a <code>ExtensionSystemSamsung</code>.
+ ///
+ /// @param[in] instance The instance with which this resource will be
+ /// associated.
+ explicit ExtensionSystemSamsung(const InstanceHandle& instance);
+
+ /// Destructor.
+ ~ExtensionSystemSamsung();
+
+ private:
+ InstanceHandle instance_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_SAMSUNG_EXTENSION_SYSTEM_SAMSUNG_H_
--- /dev/null
+// Copyright 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.
+
+#include "ppapi/cpp/samsung/extension_system_samsung_tizen.h"
+
+namespace {
+const char kCheckPrivilegeOperationName[] = "check_ace_privilege";
+const char kGetWindowIdOperationName[] = "get_window_id";
+#if defined(OS_TIZEN_TV_PRODUCT)
+const char kSetIMERecommendedWordsName[] = "set_ime_recommended_words";
+const char kSetIMERecommendedWordsTypeName[] = "set_ime_recommended_words_type";
+#endif
+} // namespace
+
+namespace pp {
+ExtensionSystemSamsungTizen::ExtensionSystemSamsungTizen(
+ const InstanceHandle& instance)
+ : ExtensionSystemSamsung(instance) {}
+
+ExtensionSystemSamsungTizen::~ExtensionSystemSamsungTizen() {}
+
+bool ExtensionSystemSamsungTizen::CheckPrivilege(const Var& privilege) {
+ if (!privilege.is_string())
+ return false;
+ std::string privilege_string = privilege.AsString();
+ std::map<std::string, bool>::iterator it =
+ privileges_result_.find(privilege_string);
+ if (it != privileges_result_.end())
+ return it->second;
+ Var call_result = GenericSyncCall(kCheckPrivilegeOperationName, privilege);
+ bool has_privilege = false;
+ if (call_result.is_bool())
+ has_privilege = call_result.AsBool();
+ privileges_result_[privilege_string] = has_privilege;
+ return has_privilege;
+}
+
+#if defined(OS_TIZEN_TV_PRODUCT)
+bool ExtensionSystemSamsungTizen::SetIMERecommendedWords(const Var& words) {
+ Var call_result = GenericSyncCall(kSetIMERecommendedWordsName, words);
+ if (call_result.is_bool())
+ return call_result.AsBool();
+ return false;
+}
+
+bool ExtensionSystemSamsungTizen::SetIMERecommendedWordsType(
+ bool should_enable) {
+ Var enable_var(should_enable);
+ Var call_result =
+ GenericSyncCall(kSetIMERecommendedWordsTypeName, enable_var);
+ if (call_result.is_bool())
+ return call_result.AsBool();
+ return false;
+}
+#endif
+
+int32_t ExtensionSystemSamsungTizen::GetWindowId() {
+ // The 'dummy' variable is not used, but needed because of the signature
+ // of the get_window_id operation.
+ Var call_result = GenericSyncCall(kGetWindowIdOperationName, pp::Var());
+ if (call_result.is_number())
+ return call_result.AsInt();
+ return -1;
+}
+} // namespace pp
--- /dev/null
+// Copyright 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 PPAPI_CPP_SAMSUNG_EXTENSION_SYSTEM_SAMSUNG_TIZEN_H_
+#define PPAPI_CPP_SAMSUNG_EXTENSION_SYSTEM_SAMSUNG_TIZEN_H_
+
+#include <map>
+#include <string>
+
+#include "ppapi/cpp/samsung/extension_system_samsung.h"
+
+/// @file
+/// This file defines APIs related to extension system provided by the Tizen.
+
+namespace pp {
+
+class ExtensionSystemSamsungTizen : public ExtensionSystemSamsung {
+ public:
+ /// A constructor for creating a <code>ExtensionSystemSamsung</code>.
+ ///
+ /// @param[in] instance The instance with which this resource will be
+ /// associated.
+ explicit ExtensionSystemSamsungTizen(const InstanceHandle& instance);
+
+ /// Destructor.
+ ~ExtensionSystemSamsungTizen();
+
+ /// CheckPrivilege() returns true if the current extension has given
+ /// privilege, false otherwise.
+ bool CheckPrivilege(const Var& privilege);
+
+ /// SetIMERecommendedWords() returns true if setting recommended words
+ /// was successful, false otherwise.
+ ///
+ /// @param[in] words Var containing std::string with words to set.
+ bool SetIMERecommendedWords(const Var& words);
+
+ /// SetIMERecommendedWordsType() returns true if setting specified
+ /// IME Recommended Words type was successful, false otherwise.
+ ///
+ /// @param[in] should_enable bool indicating if
+ /// IMERecommendedWordsType should be enabled or disabled.
+ bool SetIMERecommendedWordsType(bool should_enable);
+
+ /// GetWindowId() returns the X window Id for the current window.
+ int32_t GetWindowId();
+
+ private:
+ std::map<std::string, bool> privileges_result_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_SAMSUNG_EXTENSION_SYSTEM_SAMSUNG_TIZEN_H_
--- /dev/null
+// Copyright 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.
+
+#include "ppapi/cpp/samsung/extension_system_samsung_wrt.h"
+
+namespace {
+const char kWrtEmbedderName[] = "TizenWRT";
+} // namespace
+
+namespace pp {
+ExtensionSystemSamsungWRT::ExtensionSystemSamsungWRT(
+ const InstanceHandle& instance)
+ : ExtensionSystemSamsungTizen(instance) {}
+
+ExtensionSystemSamsungWRT::~ExtensionSystemSamsungWRT() {}
+
+bool ExtensionSystemSamsungWRT::IsValid() const {
+ static bool is_valid = (GetEmbedderName() == kWrtEmbedderName);
+ return is_valid;
+}
+} // namespace pp
--- /dev/null
+// Copyright 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 PPAPI_CPP_SAMSUNG_EXTENSION_SYSTEM_SAMSUNG_WRT_H_
+#define PPAPI_CPP_SAMSUNG_EXTENSION_SYSTEM_SAMSUNG_WRT_H_
+
+#include <map>
+#include <string>
+
+#include "ppapi/cpp/samsung/extension_system_samsung_tizen.h"
+
+/// @file
+/// This file defines APIs related to extension system provided by the WRT.
+
+namespace pp {
+
+class ExtensionSystemSamsungWRT : public ExtensionSystemSamsungTizen {
+ public:
+ /// A constructor for creating a <code>ExtensionSystemSamsung</code>.
+ ///
+ /// @param[in] instance The instance with which this resource will be
+ /// associated.
+ explicit ExtensionSystemSamsungWRT(const InstanceHandle& instance);
+
+ /// Destructor.
+ ~ExtensionSystemSamsungWRT();
+
+ /// IsValid() returns true if this object is valid in this context, i.e.
+ /// current extension system is WRT.
+ bool IsValid() const;
+
+ private:
+ std::map<std::string, bool> privileges_result_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_SAMSUNG_EXTENSION_SYSTEM_SAMSUNG_WRT_H_
--- /dev/null
+// Copyright 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.
+
+#include "ppapi/cpp/samsung/remote_controller_samsung.h"
+
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace pp {
+
+namespace {
+
+template <>
+const char* interface_name<PPB_RemoteController_Samsung_0_1>() {
+ return PPB_REMOTECONTROLLER_SAMSUNG_INTERFACE_0_1;
+}
+
+} // namespace
+
+RemoteControllerSamsung::RemoteControllerSamsung(const InstanceHandle& instance)
+ : instance_(instance) {}
+
+int32_t RemoteControllerSamsung::RegisterKeys(uint32_t key_count,
+ const char* keys[]) {
+ if (!has_interface<PPB_RemoteController_Samsung_0_1>())
+ return PP_ERROR_NOINTERFACE;
+
+ return get_interface<PPB_RemoteController_Samsung_0_1>()->RegisterKeys(
+ instance_.pp_instance(), key_count, keys);
+}
+
+int32_t RemoteControllerSamsung::RegisterKeys(
+ const std::vector<std::string>& keys) {
+ std::vector<const char*> v;
+ v.reserve(keys.size());
+ for (uint32_t i = 0; i < keys.size(); ++i)
+ v.push_back(keys[i].c_str());
+ return RegisterKeys(static_cast<uint32_t>(v.size()), &v[0]);
+}
+
+int32_t RemoteControllerSamsung::UnRegisterKeys(uint32_t key_count,
+ const char* keys[]) {
+ if (!has_interface<PPB_RemoteController_Samsung_0_1>())
+ return PP_ERROR_NOINTERFACE;
+
+ return get_interface<PPB_RemoteController_Samsung_0_1>()->UnRegisterKeys(
+ instance_.pp_instance(), key_count, keys);
+}
+
+int32_t RemoteControllerSamsung::UnRegisterKeys(
+ const std::vector<std::string>& keys) {
+ std::vector<const char*> v;
+ v.reserve(keys.size());
+ for (uint32_t i = 0; i < keys.size(); ++i)
+ v.push_back(keys[i].c_str());
+ return UnRegisterKeys(static_cast<uint32_t>(v.size()), &v[0]);
+}
+
+} // namespace pp
--- /dev/null
+// Copyright 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 PPAPI_CPP_SAMSUNG_REMOTE_CONTROLLER_SAMSUNG_H_
+#define PPAPI_CPP_SAMSUNG_REMOTE_CONTROLLER_SAMSUNG_H_
+
+#include <string>
+#include <vector>
+
+#include "ppapi/c/samsung/ppb_remote_controller_samsung.h"
+#include "ppapi/cpp/instance_handle.h"
+
+/// @file
+/// This file defines API related to TV Remote Controller
+
+namespace pp {
+
+class RemoteControllerSamsung {
+ public:
+ /// A constructor for creating a <code>RemoteControllerSamsung</code> class
+ /// for given instance of a module.
+ explicit RemoteControllerSamsung(const InstanceHandle& instance);
+
+ /// RegisterKeys() function registers given key arrays to be grabbed by
+ /// the application/widget containing pepper plugin calling this method.
+ ///
+ /// <strong>Note:</strong>
+ /// After registering for grabbing keys, events related to that key
+ /// will be delivered directly to the application/widget.
+ ///
+ /// <strong>Note:</strong>
+ /// For some embedders, we can`t tell if key that we try to register have
+ /// failed because it have been already registered. So if at least one key
+ /// have been successfully processed, we assume that other keys that failed,
+ /// have been already registered before this call.
+ ///
+ /// @param[in] key_count A number of keys which will be grabbed.
+ /// @param[in] keys An array containing list of keys which should be grabbed.
+ ///
+ /// @return An int32_t containing an error code from <code>pp_errors.h</code>.
+ /// Returns <code>PP_ERROR_BADARGUMENT</code> if <code>key_count</code> is
+ /// equal 0 or one of <code>keys</code> is not supported anymore.
+ /// Returns <code>PP_ERROR_NOTSUPPORTED</code> if currently launched embedder
+ /// doesn`t support key registering.
+ /// Returns <code>PP_ERROR_FAILED</code> if registering all <code>keys</code>
+ /// have failed.
+ /// Returns <code>PP_OK</code> if at lest one key from <code>keys</code> have
+ /// been registered.
+ int32_t RegisterKeys(uint32_t key_count, const char* keys[]);
+
+ /// RegisterKeys() function registers given key arrays to be grabbed by
+ /// the application/widget containing pepper plugin calling this method.
+ ///
+ /// <strong>Note:</strong>
+ /// After registering for grabbing keys, events related to that key
+ /// will be delivered directly to the application/widget.
+ ///
+ /// <strong>Note:</strong>
+ /// For some embedders, we can`t tell if key that we try to register have
+ /// failed because it have been already registered. So if at least one key
+ /// have been successfully processed, we assume that other keys that failed,
+ /// have been already registered before this call.
+ ///
+ /// @param[in] keys A vector containing list of keys which should be grabbed.
+ ///
+ /// @return An int32_t containing an error code from <code>pp_errors.h</code>.
+ /// Returns <code>PP_ERROR_BADARGUMENT</code> if <code>key_count</code> is
+ /// equal 0 or one of <code>keys</code> is not supported anymore.
+ /// Returns <code>PP_ERROR_NOTSUPPORTED</code> if currently launched embedder
+ /// doesn`t support key registering.
+ /// Returns <code>PP_ERROR_FAILED</code> if registering all <code>keys</code>
+ /// have failed.
+ /// Returns <code>PP_OK</code> if at lest one key from <code>keys</code> have
+ /// been registered.
+ int32_t RegisterKeys(const std::vector<std::string>& keys);
+
+ /// UnregisterKeys() function unregisters given key arrays from being grabbed
+ /// by the application/widget containing pepper plugin calling this method.
+ ///
+ /// <strong>Note:</strong>
+ /// For some embedders, we can`t tell if key that we try to unregister have
+ /// failed because it have been already unregistered. So if at least one key
+ /// have been successfully processed, we assume that other keys that failed,
+ /// have been already unregistered before this call.
+ ///
+ /// @param[in] key_count A number of keys which will be grabbed.
+ /// @param[in] keys An array containing list of keys which should be grabbed.
+ ///
+ /// @return An int32_t containing an error code from <code>pp_errors.h</code>.
+ /// Returns <code>PP_ERROR_BADARGUMENT</code> if <code>key_count</code> is
+ /// equal 0 or one of <code>keys</code> is not supported anymore.
+ /// Returns <code>PP_ERROR_NOTSUPPORTED</code> if currently launched embedder
+ /// doesn`t support key registering.
+ /// Returns <code>PP_ERROR_FAILED</code> if registering all <code>keys</code>
+ /// have failed.
+ /// Returns <code>PP_OK</code> if at lest one key from <code>keys</code> have
+ /// been registered.
+ int32_t UnRegisterKeys(uint32_t key_count, const char* keys[]);
+
+ /// UnregisterKeys() function unregisters given key arrays from being grabbed
+ /// by the application/widget containing pepper plugin calling this method.
+ ///
+ /// <strong>Note:</strong>
+ /// For some embedders, we can`t tell if key that we try to unregister have
+ /// failed because it have been already unregistered. So if at least one key
+ /// have been successfully processed, we assume that other keys that failed,
+ /// have been already unregistered before this call.
+ ///
+ /// @param[in] keys A vector containing list of keys which should be grabbed.
+ ///
+ /// @return An int32_t containing an error code from <code>pp_errors.h</code>.
+ /// Returns <code>PP_ERROR_BADARGUMENT</code> if <code>key_count</code> is
+ /// equal 0 or one of <code>keys</code> is not supported anymore.
+ /// Returns <code>PP_ERROR_NOTSUPPORTED</code> if currently launched embedder
+ /// doesn`t support key registering.
+ /// Returns <code>PP_ERROR_FAILED</code> if registering all <code>keys</code>
+ /// have failed.
+ /// Returns <code>PP_OK</code> if at lest one key from <code>keys</code> have
+ /// been registered.
+ int32_t UnRegisterKeys(const std::vector<std::string>& keys);
+
+ private:
+ InstanceHandle instance_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_SAMSUNG_REMOTE_CONTROLLER_SAMSUNG_H_
""" Parser for PPAPI IDL """
+# Modified by SRPOL, take caution when updating.
+
#
# IDL Parser
#
return errs
-default_dirs = ['.', 'trusted', 'dev', 'private']
+default_dirs = ['.', 'trusted', 'dev', 'private', 'samsung']
def ParseFiles(filenames):
parser = IDLParser()
filenodes = []
""" Generator for C++ style thunks """
+# Modified by SRPOL, take caution when updating.
+
from __future__ import print_function
import glob
api_basename = api_basename[:-len('_trusted')]
if api_basename.endswith('_private'):
api_basename = api_basename[:-len('_private')]
+ if api_basename.endswith('_samsung'):
+ api_basename = api_basename[:-len('_samsung')]
return api_basename
api_name = api_name[:-len('_Dev')]
if api_name.endswith('_Private'):
api_name = api_name[:-len('_Private')]
+ if api_name.endswith('_Samsung'):
+ api_name = api_name[:-len('_Samsung')]
return api_name
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+if (is_tizen) {
+ import("//tizen_src/build/config/tizen_features.gni")
+}
import("//build/config/nacl/config.gni")
import("//components/nacl/toolchain.gni")
import("//ppapi/buildflags/buildflags.gni")
"//ui/surface",
]
}
+ if (is_tizen) {
+ if(tizen_pepper_extensions) {
+ sources += [
+ "extension_system_resource.cc",
+ "extension_system_resource.h",
+ "remote_controller_resource.cc",
+ "remote_controller_resource.h",
+ "var_value_converter.cc",
+ "var_value_converter.h",
+ ]
+ }
+ }
}
source_set("common") {
--- /dev/null
+// Copyright 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.
+
+#include "ppapi/proxy/extension_system_resource.h"
+
+#include "base/json/json_string_value_serializer.h"
+#include "base/logging.h"
+#include "ppapi/proxy/plugin_dispatcher.h"
+#include "ppapi/proxy/ppapi_messages.h"
+#include "ppapi/proxy/raw_var_data.h"
+#include "ppapi/proxy/serialized_var.h"
+#include "ppapi/proxy/var_value_converter.h"
+#include "ppapi/shared_impl/var.h"
+
+namespace ppapi {
+namespace proxy {
+
+ExtensionSystemResource::ExtensionSystemResource(Connection connection,
+ PP_Instance instance)
+ : PluginResource(connection, instance) {
+ SendCreate(BROWSER, PpapiHostMsg_ExtensionSystem_Create());
+}
+
+ExtensionSystemResource::~ExtensionSystemResource() {}
+
+thunk::PPB_ExtensionSystem_API*
+ExtensionSystemResource::AsPPB_ExtensionSystem_API() {
+ return this;
+}
+
+PP_Var ExtensionSystemResource::GetEmbedderName() {
+ if (!embedder_name_.empty())
+ return StringVar::StringToPPVar(embedder_name_);
+
+ int32_t result =
+ SyncCall<PpapiPluginMsg_ExtensionSystem_GetEmbedderNameReply>(
+ BROWSER, PpapiHostMsg_ExtensionSystem_GetEmbedderName(),
+ &embedder_name_);
+ if (result != PP_OK)
+ return PP_MakeUndefined();
+
+ return StringVar::StringToPPVar(embedder_name_);
+}
+
+PP_Var ExtensionSystemResource::GetCurrentExtensionInfo() {
+ if (current_extension_info_.get().type == PP_VARTYPE_UNDEFINED) {
+ std::string json_result;
+
+ int32_t sync_call_result =
+ SyncCall<PpapiPluginMsg_ExtensionSystem_GetCurrentExtensionInfoReply>(
+ BROWSER, PpapiHostMsg_ExtensionSystem_GetCurrentExtensionInfo(),
+ &json_result);
+ if (sync_call_result != PP_OK)
+ return PP_MakeUndefined();
+
+ base::StringPiece result_str(json_result);
+ JSONStringValueDeserializer json_deserializer(result_str);
+ std::unique_ptr<base::Value> result_ptr(
+ json_deserializer.Deserialize(nullptr, nullptr));
+ if (!result_ptr)
+ return PP_MakeUndefined();
+
+ ScopedPPVar var = VarFromValue(result_ptr.get());
+ if (var.get().type != PP_VARTYPE_DICTIONARY)
+ return PP_MakeUndefined();
+
+ // cache the value of the extension info
+ current_extension_info_ = var;
+ }
+
+ ScopedPPVar info_copy = current_extension_info_;
+ return info_copy.Release();
+}
+
+int32_t ExtensionSystemResource::GenericSyncCall(PP_Var operation_name,
+ PP_Var operation_data,
+ PP_Var* operation_result) {
+ if (!operation_result) {
+ LOG(ERROR) << "Operation result is NULL";
+ return PP_ERROR_BADARGUMENT;
+ }
+ StringVar* op_name = StringVar::FromPPVar(operation_name);
+ if (!op_name) {
+ LOG(ERROR) << "Invalid operation name";
+ return PP_ERROR_BADARGUMENT;
+ }
+ if (op_name->value().empty()) {
+ LOG(ERROR) << "Empty operation name";
+ return PP_ERROR_BADARGUMENT;
+ }
+
+ // We do not support cycles in operation_data parameter.
+ // We check it by trying to create RawVarDataGraph (will return NULL if
+ // operation_data parameter does contain any cycles) because neither
+ // JSONStringValueSerializer or ValueFromVar check for it.
+ std::unique_ptr<RawVarDataGraph> cycle_check(
+ RawVarDataGraph::Create(operation_data, pp_instance()));
+ if (!cycle_check) {
+ LOG(ERROR) << "Cycle detected in operation data";
+ return PP_ERROR_BADARGUMENT;
+ }
+
+ std::string serialized_operation_data;
+ JSONStringValueSerializer json_serializer(&serialized_operation_data);
+ if (!json_serializer.Serialize(*(ValueFromVar(operation_data).get()))) {
+ LOG(ERROR) << "JSON serialization failed";
+ return PP_ERROR_BADARGUMENT;
+ }
+
+ std::string json_result;
+
+ int32_t sync_call_result =
+ SyncCall<PpapiPluginMsg_ExtensionSystem_GenericSyncCallReply>(
+ BROWSER,
+ PpapiHostMsg_ExtensionSystem_GenericSyncCall(
+ op_name->value(), serialized_operation_data),
+ &json_result);
+ if (sync_call_result != PP_OK)
+ return sync_call_result;
+
+ base::StringPiece result_str(json_result);
+ JSONStringValueDeserializer json_deserializer(result_str);
+ std::unique_ptr<base::Value> result_ptr(
+ json_deserializer.Deserialize(nullptr, nullptr));
+ if (!result_ptr) {
+ LOG(ERROR) << "JSON deserialization failed";
+ return PP_ERROR_FAILED;
+ }
+
+ *operation_result = VarFromValue(result_ptr.get()).Release();
+ return PP_OK;
+}
+
+} // namespace proxy
+} // namespace ppapi
--- /dev/null
+// Copyright 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 PPAPI_PROXY_EXTENSION_SYSTEM_RESOURCE_H_
+#define PPAPI_PROXY_EXTENSION_SYSTEM_RESOURCE_H_
+
+#include <string>
+
+#include "ppapi/c/samsung/ppb_extension_system_samsung.h"
+#include "ppapi/proxy/plugin_resource.h"
+#include "ppapi/proxy/ppapi_proxy_export.h"
+#include "ppapi/shared_impl/scoped_pp_var.h"
+#include "ppapi/thunk/ppb_extension_system_samsung_api.h"
+
+namespace ppapi {
+namespace proxy {
+
+class ExtensionSystemResource : public PluginResource,
+ public thunk::PPB_ExtensionSystem_API {
+ public:
+ ExtensionSystemResource(Connection connection, PP_Instance instance);
+
+ ~ExtensionSystemResource() override;
+
+ // Resource implementation.
+ thunk::PPB_ExtensionSystem_API* AsPPB_ExtensionSystem_API() override;
+
+ // PPBExtensionSystemAPI implementation.
+ PP_Var GetEmbedderName() override;
+ PP_Var GetCurrentExtensionInfo() override;
+ int32_t GenericSyncCall(PP_Var operation_name,
+ PP_Var operation_data,
+ PP_Var* operation_result) override;
+
+ private:
+ ScopedPPVar current_extension_info_;
+ std::string embedder_name_;
+};
+
+} // namespace proxy
+} // namespace ppapi
+
+#endif // PPAPI_PROXY_EXTENSION_SYSTEM_RESOURCE_H_
#include "ppapi/shared_impl/ppb_var_shared.h"
#include "ppapi/thunk/thunk.h"
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+#include "ppapi/c/samsung/ppb_extension_system_samsung.h"
+#include "ppapi/c/samsung/ppb_remote_controller_samsung.h"
+#endif // defined(TIZEN_PEPPER_EXTENSIONS)
+
// Helper to get the proxy name PPB_Foo_Proxy given the API name PPB_Foo.
#define PROXY_CLASS_NAME(api_name) api_name##_Proxy
Permission current_required_permission = PERMISSION_NONE;
#include "ppapi/thunk/interfaces_ppb_private_no_permissions.h"
#include "ppapi/thunk/interfaces_ppb_public_stable.h"
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+ #include "ppapi/thunk/interfaces_ppb_samsung.h"
+#endif // defined(TIZEN_PEPPER_EXTENSIONS)
}
{
Permission current_required_permission = PERMISSION_DEV;
#include "ppapi/shared_impl/url_request_info_data.h"
#include "ppapi/shared_impl/url_response_info_data.h"
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+#include "ppapi/c/samsung/ppb_remote_controller_samsung.h"
+#endif
#undef IPC_MESSAGE_EXPORT
#define IPC_MESSAGE_EXPORT PPAPI_PROXY_EXPORT
int32_t /* error */)
IPC_MESSAGE_CONTROL0(PpapiHostMsg_VideoEncoder_Close)
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+
+// Extension system samsung messages
+IPC_MESSAGE_CONTROL0(PpapiHostMsg_ExtensionSystem_Create)
+IPC_MESSAGE_CONTROL0(PpapiHostMsg_ExtensionSystem_GetEmbedderName)
+IPC_MESSAGE_CONTROL1(PpapiPluginMsg_ExtensionSystem_GetEmbedderNameReply,
+ std::string /*Embedder name*/)
+IPC_MESSAGE_CONTROL0(PpapiHostMsg_ExtensionSystem_GetCurrentExtensionInfo)
+IPC_MESSAGE_CONTROL1(
+ PpapiPluginMsg_ExtensionSystem_GetCurrentExtensionInfoReply,
+ std::string /*extension info dictionary in JSON format*/)
+IPC_MESSAGE_CONTROL2(PpapiHostMsg_ExtensionSystem_GenericSyncCall,
+ std::string /*operation name*/,
+ std::string /*operation data in JSON format*/)
+IPC_MESSAGE_CONTROL1(PpapiPluginMsg_ExtensionSystem_GenericSyncCallReply,
+ std::string /*operation result in JSON format*/)
+
+// Remote Controller Samsung messages
+IPC_MESSAGE_CONTROL0(PpapiHostMsg_RemoteController_Create)
+IPC_MESSAGE_CONTROL1(PpapiHostMsg_RemoteController_RegisterKeys,
+ std::vector<std::string> /* keys */)
+IPC_MESSAGE_CONTROL0(PpapiHostMsg_RemoteController_RegisterKeysReply)
+
+IPC_MESSAGE_CONTROL1(PpapiHostMsg_RemoteController_UnRegisterKeys,
+ std::vector<std::string> /* keys */)
+IPC_MESSAGE_CONTROL0(PpapiHostMsg_RemoteController_UnRegisterKeysReply)
+
+#endif // defined(TIZEN_PEPPER_EXTENSIONS)
#if !BUILDFLAG(IS_NACL) && !defined(NACL_WIN64)
// Audio input.
#include "ppapi/thunk/ppb_graphics_3d_api.h"
#include "ppapi/thunk/thunk.h"
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+#include "ppapi/proxy/extension_system_resource.h"
+#include "ppapi/proxy/remote_controller_resource.h"
+#endif // defined(TIZEN_PEPPER_EXTENSIONS)
+
// Windows headers interfere with this file.
#ifdef PostMessage
#undef PostMessage
case BROWSER_FONT_SINGLETON_ID:
new_singleton = new BrowserFontSingletonResource(connection, instance);
break;
+ case EXTENSION_SYSTEM_SINGLETON_ID:
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+ new_singleton = new ExtensionSystemResource(connection, instance);
+#else
+ NOTREACHED();
+#endif // defined(TIZEN_PEPPER_EXTENSIONS)
+ break;
+ case REMOTE_CONTROLLER_SINGLETON_ID:
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+ new_singleton = new RemoteControllerResource(connection, instance);
+#else
+ NOTREACHED();
+#endif // defined(TIZEN_PEPPER_EXTENSIONS)
+ break;
#else
case BROWSER_FONT_SINGLETON_ID:
+ case EXTENSION_SYSTEM_SINGLETON_ID:
+ case REMOTE_CONTROLLER_SINGLETON_ID:
NOTREACHED();
break;
#endif // !BUILDFLAG(IS_NACL) && !defined(NACL_WIN64)
--- /dev/null
+// Copyright 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.
+
+#include "ppapi/proxy/remote_controller_resource.h"
+
+#include <vector>
+
+#include "base/logging.h"
+#include "ppapi/proxy/plugin_dispatcher.h"
+#include "ppapi/proxy/ppapi_messages.h"
+
+namespace ppapi {
+namespace proxy {
+
+namespace {
+
+int32_t CheckParameters(uint32_t key_count, const char* keys[]) {
+ if (key_count == 0 || !keys) {
+ LOG(ERROR) << "keys is " << keys << ", key_count= " << key_count;
+ return PP_ERROR_BADARGUMENT;
+ }
+
+ for (uint32_t i = 0; i < key_count; ++i) {
+ if (!keys[i]) {
+ LOG(ERROR) << "keys[" << i << "] is NULL";
+ return PP_ERROR_BADARGUMENT;
+ }
+ }
+ return PP_OK;
+}
+
+} // namespace
+
+RemoteControllerResource::RemoteControllerResource(Connection connection,
+ PP_Instance instance)
+ : PluginResource(connection, instance) {
+ SendCreate(BROWSER, PpapiHostMsg_RemoteController_Create());
+}
+
+RemoteControllerResource::~RemoteControllerResource() = default;
+
+// Resource implementation.
+thunk::PPB_RemoteController_API*
+RemoteControllerResource::AsPPB_RemoteController_API() {
+ return this;
+}
+
+// PPB_RemoteController_API implementation.
+int32_t RemoteControllerResource::RegisterKeys(PP_Instance instance,
+ uint32_t key_count,
+ const char* keys[]) {
+ int32_t ret = CheckParameters(key_count, keys);
+ if (ret != PP_OK)
+ return ret;
+
+ std::vector<std::string> keys_vec(keys, keys + key_count);
+ return SyncCall<PpapiHostMsg_RemoteController_RegisterKeysReply>(
+ BROWSER, PpapiHostMsg_RemoteController_RegisterKeys(keys_vec));
+}
+
+int32_t RemoteControllerResource::UnRegisterKeys(PP_Instance instance,
+ uint32_t key_count,
+ const char* keys[]) {
+ int32_t ret = CheckParameters(key_count, keys);
+ if (ret != PP_OK)
+ return ret;
+
+ std::vector<std::string> keys_vec(keys, keys + key_count);
+ return SyncCall<PpapiHostMsg_RemoteController_UnRegisterKeysReply>(
+ BROWSER, PpapiHostMsg_RemoteController_UnRegisterKeys(keys_vec));
+}
+
+} // namespace proxy
+} // namespace ppapi
--- /dev/null
+// Copyright 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 PPAPI_PROXY_REMOTE_CONTROLLER_RESOURCE_H_
+#define PPAPI_PROXY_REMOTE_CONTROLLER_RESOURCE_H_
+
+#include <string>
+
+#include "ppapi/c/samsung/ppb_remote_controller_samsung.h"
+#include "ppapi/proxy/plugin_resource.h"
+#include "ppapi/proxy/ppapi_proxy_export.h"
+#include "ppapi/shared_impl/scoped_pp_var.h"
+#include "ppapi/thunk/ppb_remote_controller_samsung_api.h"
+
+namespace ppapi {
+namespace proxy {
+
+class RemoteControllerResource : public PluginResource,
+ public thunk::PPB_RemoteController_API {
+ public:
+ RemoteControllerResource(Connection connection, PP_Instance instance);
+
+ ~RemoteControllerResource() override;
+
+ // Resource implementation.
+ thunk::PPB_RemoteController_API* AsPPB_RemoteController_API() override;
+
+ // PPB_RemoteController_API implementation.
+ int32_t RegisterKeys(PP_Instance instance,
+ uint32_t key_count,
+ const char* keys[]) override;
+ int32_t UnRegisterKeys(PP_Instance instance,
+ uint32_t key_count,
+ const char* keys[]) override;
+};
+
+} // namespace proxy
+} // namespace ppapi
+
+#endif // PPAPI_PROXY_REMOTE_CONTROLLER_RESOURCE_H_
--- /dev/null
+// Copyright 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.
+
+#include "ppapi/proxy/var_value_converter.h"
+
+#include <string>
+
+#include "base/memory/ptr_util.h"
+#include "ppapi/shared_impl/array_var.h"
+#include "ppapi/shared_impl/dictionary_var.h"
+
+namespace ppapi {
+namespace proxy {
+
+namespace {
+
+std::unique_ptr<base::Value> ValueFromVarArray(const PP_Var& var) {
+ if (var.type == PP_VARTYPE_ARRAY) {
+ scoped_refptr<ArrayVar> array =
+ scoped_refptr<ArrayVar>(ArrayVar::FromPPVar(var));
+ if (!array) {
+ return std::make_unique<base::Value>();
+ }
+ auto ret = std::make_unique<base::ListValue>();
+ for (size_t i = 0; i < array->GetLength(); ++i) {
+ ScopedPPVar var(ScopedPPVar::PassRef(), array->Get(i));
+ ret->Append(std::move(*ValueFromVar(var.get())));
+ }
+ return std::move(ret);
+ }
+
+ return std::make_unique<base::Value>();
+}
+
+std::unique_ptr<base::Value> ValueFromVarDictionary(const PP_Var& var) {
+ if (var.type == PP_VARTYPE_DICTIONARY) {
+ scoped_refptr<DictionaryVar> dict =
+ scoped_refptr<DictionaryVar>(DictionaryVar::FromPPVar(var));
+ if (!dict) {
+ return std::make_unique<base::Value>();
+ }
+ ScopedPPVar keys_var(ScopedPPVar::PassRef(), dict->GetKeys());
+ scoped_refptr<ArrayVar> keys =
+ scoped_refptr<ArrayVar>(ArrayVar::FromPPVar(keys_var.get()));
+ if (!keys) {
+ return std::make_unique<base::Value>();
+ }
+
+ auto ret = std::make_unique<base::DictionaryValue>();
+ for (size_t i = 0; i < keys->GetLength(); ++i) {
+ ScopedPPVar var_k(ScopedPPVar::PassRef(), keys->Get(i));
+ scoped_refptr<StringVar> key =
+ scoped_refptr<StringVar>(StringVar::FromPPVar(var_k.get()));
+ if (!key) {
+ continue;
+ }
+ std::string key_string = key->value();
+
+ ScopedPPVar var_v(ScopedPPVar::PassRef(), dict->Get(var_k.get()));
+ // SetWithoutPathExpansion is used instead of Set here to allow
+ // e.g. URLs to be used as keys. Set method treats '.' as keys separator.
+ ret->SetKey(key_string, std::move(*ValueFromVar(var_v.get())));
+ }
+ return std::move(ret);
+ }
+
+ return std::make_unique<base::Value>();
+}
+
+ScopedPPVar VarFromValueArray(const base::Value* value) {
+ if (!value)
+ return ScopedPPVar();
+
+ if (value->type() == base::Value::Type::LIST) {
+ scoped_refptr<ArrayVar> ret(new ArrayVar);
+ const base::ListValue* list = static_cast<const base::ListValue*>(value);
+ size_t size = list->GetList().size();
+ ret->SetLength(size);
+ for (size_t i = 0; i < size; ++i) {
+ const base::Value* val;
+ val = const_cast<base::Value*>(&(list->GetList().operator[](i)));
+ ScopedPPVar var = VarFromValue(val);
+ ret->Set(i, var.get());
+ }
+
+ return ScopedPPVar(ScopedPPVar::PassRef(), ret->GetPPVar());
+ }
+
+ return ScopedPPVar();
+}
+
+ScopedPPVar VarFromValueDictionary(const base::Value* value) {
+ if (!value)
+ return ScopedPPVar();
+
+ if (value->type() == base::Value::Type::DICTIONARY) {
+ scoped_refptr<DictionaryVar> ret(new DictionaryVar);
+ const base::DictionaryValue* dict;
+ value->GetAsDictionary(&dict);
+ base::detail::const_dict_iterator it = dict->DictItems().begin();
+ while (it!=dict->DictItems().end()) {
+ ScopedPPVar var_k(ScopedPPVar::PassRef(),
+ StringVar::StringToPPVar(it->first));
+ ScopedPPVar var_v = VarFromValue(&(it->second));
+ ret->Set(var_k.get(), var_v.get());
+ it++;
+ }
+ return ScopedPPVar(ScopedPPVar::PassRef(), ret->GetPPVar());
+ }
+
+ return ScopedPPVar();
+}
+
+} // namespace
+
+std::unique_ptr<base::Value> ValueFromVar(const PP_Var& var) {
+ switch (var.type) {
+ case PP_VARTYPE_BOOL:
+ return std::make_unique<base::Value>(PP_ToBool(var.value.as_bool));
+ case PP_VARTYPE_INT32:
+ return std::make_unique<base::Value>(var.value.as_int);
+ case PP_VARTYPE_DOUBLE:
+ return std::make_unique<base::Value>(var.value.as_double);
+ case PP_VARTYPE_STRING: {
+ StringVar* str = StringVar::FromPPVar(var);
+ if (!str)
+ return std::make_unique<base::Value>();
+ return std::make_unique<base::Value>(str->value());
+ }
+ case PP_VARTYPE_ARRAY:
+ return ValueFromVarArray(var);
+ case PP_VARTYPE_DICTIONARY:
+ return ValueFromVarDictionary(var);
+ default:
+ return std::make_unique<base::Value>();
+ }
+}
+
+ScopedPPVar VarFromValue(const base::Value* value) {
+ if (!value)
+ return ScopedPPVar();
+
+ switch (value->type()) {
+ case base::Value::Type::BOOLEAN: {
+ bool val = value->GetBool();
+ return ScopedPPVar(ScopedPPVar::PassRef(), PP_MakeBool(PP_FromBool(val)));
+ }
+ case base::Value::Type::INTEGER: {
+ int val = value->GetInt();
+ return ScopedPPVar(ScopedPPVar::PassRef(), PP_MakeInt32(val));
+ }
+ case base::Value::Type::DOUBLE: {
+ double val = value->GetDouble();
+ return ScopedPPVar(ScopedPPVar::PassRef(), PP_MakeDouble(val));
+ }
+ case base::Value::Type::STRING: {
+ const std::string& val = value->GetString();
+ return ScopedPPVar(ScopedPPVar::PassRef(), StringVar::StringToPPVar(val));
+ }
+ case base::Value::Type::LIST:
+ return VarFromValueArray(value);
+ case base::Value::Type::DICTIONARY:
+ return VarFromValueDictionary(value);
+ default:
+ return ScopedPPVar();
+ }
+}
+
+} // namespace proxy
+} // namespace ppapi
--- /dev/null
+// Copyright 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 PPAPI_PROXY_VAR_VALUE_CONVERTER_H_
+#define PPAPI_PROXY_VAR_VALUE_CONVERTER_H_
+
+#include "base/values.h"
+#include "ppapi/c/pp_var.h"
+#include "ppapi/shared_impl/scoped_pp_var.h"
+
+namespace ppapi {
+namespace proxy {
+
+// TODO(m.majczak) Implement cycle detection in vars and values.
+// Currentely value/var with cycle will result in an application crash.
+
+/**
+ * Converts PP_Var to base::Value, passes the ownership of the created value.
+ *
+ * @param var Reference to an object of type PP_Var that will be converted to
+ * base::Value. The ownership of the var is not passed.
+ *
+ * @return scoped_ptr pointing to newly created base::Value.
+ */
+std::unique_ptr<base::Value> ValueFromVar(const PP_Var& var);
+
+/**
+ * Converts base::Value to PP_Var.
+ *
+ * @param value Pointer to an object of type base::Value that will be converted
+ * to PP_Var. The ownership of the value is not passed.
+ *
+ * @return ScopedPPVar that was creted from the value
+ */
+ScopedPPVar VarFromValue(const base::Value* value);
+
+} // namespace proxy
+} // namespace ppapi
+
+#endif // PPAPI_PROXY_VAR_VALUE_CONVERTER_H_
--- /dev/null
+// Copyright 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.
+
+#include "ppapi/proxy/var_value_converter.h"
+
+#include <limits>
+#include <random>
+#include <sstream>
+#include <string>
+
+#include "base/message_loop/message_loop.h"
+#include "ppapi/shared_impl/array_var.h"
+#include "ppapi/shared_impl/dictionary_var.h"
+#include "ppapi/shared_impl/test_globals.h"
+#include "ppapi/shared_impl/var.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+template <typename T, size_t N>
+size_t ArraySize(T (&)[N]) {
+ return N;
+}
+
+namespace {
+
+std::string RandomStr() {
+ static std::random_device rd;
+ static std::mt19937 gen(rd());
+ static std::uniform_int_distribution<> len_gen(1, 129);
+ static std::uniform_int_distribution<> char_gen(32, 125);
+
+ int length = len_gen(gen);
+ std::stringstream ss;
+ for (int i = 0; i < length; ++i) {
+ // generate random printable character
+ ss << static_cast<char>(char_gen(gen));
+ }
+ return ss.str();
+}
+
+std::string test_keys[] = {"bool_key", "int_key", "double_key",
+ "string_key", "array_key", "dictionary_key"};
+
+enum TestKeysTypes {
+ BOOL_KEY,
+ INT_KEY,
+ DOUBLE_KEY,
+ STRING_KEY,
+ ARRAY_KEY,
+ DICT_KEY,
+ KEY_COUNT
+};
+
+enum ArrayValueTypes {
+ BOOL_IDX,
+ INT_IDX,
+ DOUBLE_IDX,
+ STRING_IDX,
+ ARRAY_IDX,
+ IDX_COUNT
+};
+
+// This is required to assert size of nested containers in array test.
+// If adding more POD types, please add them just after the last POD type.
+const size_t kArrayPODIdxCount = STRING_IDX;
+// This value defines size of the tested array in ArrayVarValueConversionTest.
+const size_t kArrayTestSize = IDX_COUNT;
+
+// This is required to assert size of nested containers in dictionary test.
+// If adding more POD types, please add them just after the last POD type.
+const size_t kPODKeysCount = STRING_KEY;
+
+void SetAndForget(scoped_refptr<ppapi::ArrayVar> arr, int idx, PP_Var var) {
+ arr->Set(idx, var);
+ ppapi::PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(var);
+}
+
+void SetAndForget(scoped_refptr<ppapi::DictionaryVar> dict,
+ const ppapi::ScopedPPVar& key,
+ PP_Var var) {
+ dict->Set(key.get(), var);
+ ppapi::PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(var);
+}
+
+} // namespace
+
+namespace ppapi {
+namespace proxy {
+
+class VarValueConverterTest : public ::testing::Test {
+ protected:
+ void SetUp() override {
+ // check if initial var count is 0
+ EXPECT_EQ(PpapiGlobals::Get()->GetVarTracker()->GetLiveVars().size(), 0u);
+ }
+ void TearDown() override {
+ // check if everything is freed properely
+ EXPECT_EQ(PpapiGlobals::Get()->GetVarTracker()->GetLiveVars().size(), 0u);
+ }
+
+ private:
+ base::MessageLoop message_loop_; // required to instantiate globals
+ TestGlobals globals_; // required for var management
+};
+
+TEST_F(VarValueConverterTest, BoolVarValueConversionTest) {
+ bool b;
+ // to value
+ ScopedPPVar var1(ScopedPPVar::PassRef(), PP_MakeBool(PP_TRUE));
+ std::unique_ptr<base::Value> value1 = ValueFromVar(var1.get());
+ EXPECT_EQ(value1->GetType(), base::Value::Type::BOOLEAN);
+ ASSERT_TRUE(value1->GetAsBoolean(&b));
+ EXPECT_EQ(b, PP_ToBool(var1.get().value.as_bool));
+
+ ScopedPPVar var2(ScopedPPVar::PassRef(), PP_MakeBool(PP_FALSE));
+ std::unique_ptr<base::Value> value2 = ValueFromVar(var2.get());
+ EXPECT_EQ(value1->GetType(), base::Value::Type::BOOLEAN);
+ ASSERT_TRUE(value2->GetAsBoolean(&b));
+ EXPECT_EQ(b, PP_ToBool(var2.get().value.as_bool));
+
+ // to var
+ ScopedPPVar result1 = VarFromValue(value1.get());
+ ASSERT_TRUE(value1->GetAsBoolean(&b));
+ EXPECT_EQ(b, PP_ToBool(result1.get().value.as_bool));
+
+ ScopedPPVar result2 = VarFromValue(value2.get());
+ ASSERT_TRUE(value2->GetAsBoolean(&b));
+ EXPECT_EQ(b, PP_ToBool(result2.get().value.as_bool));
+}
+
+TEST_F(VarValueConverterTest, IntVarValueConversionTest) {
+ for (int k = -102; k < 100; ++k) {
+ int i;
+ ScopedPPVar var;
+ switch (k) {
+ case -102:
+ var = ScopedPPVar(ScopedPPVar::PassRef(),
+ PP_MakeInt32(std::numeric_limits<int>::min()));
+ break;
+ case -101:
+ var = ScopedPPVar(ScopedPPVar::PassRef(),
+ PP_MakeInt32(std::numeric_limits<int>::max()));
+ break;
+ default:
+ var = ScopedPPVar(ScopedPPVar::PassRef(), PP_MakeInt32(k));
+ break;
+ }
+
+ // to value
+ std::unique_ptr<base::Value> value = ValueFromVar(var.get());
+ EXPECT_EQ(value->GetType(), base::Value::Type::INTEGER);
+ ASSERT_TRUE(value->GetAsInteger(&i));
+ EXPECT_EQ(i, var.get().value.as_int);
+
+ // to var
+ ScopedPPVar result = VarFromValue(value.get());
+ EXPECT_EQ(i, result.get().value.as_int);
+ }
+}
+
+TEST_F(VarValueConverterTest, DoubleVarValueConversionTest) {
+ for (int k = -104; k < 100; ++k) {
+ // prepare test data
+ double d;
+ ScopedPPVar var;
+ // Warning!! NaN, Inf and -Inf cannot be tested as base::Value doesn't
+ // support them, they are represented as 0 upon conversion to base::Value.
+ // This is due to JSON serialization requirements.
+ switch (k) {
+ case -103:
+ var = ScopedPPVar(ScopedPPVar::PassRef(),
+ PP_MakeDouble(std::numeric_limits<double>::min()));
+ break;
+ case -102:
+ var = ScopedPPVar(ScopedPPVar::PassRef(),
+ PP_MakeDouble(-std::numeric_limits<double>::max()));
+ break;
+ case -101:
+ var = ScopedPPVar(ScopedPPVar::PassRef(),
+ PP_MakeDouble(std::numeric_limits<double>::max()));
+ break;
+ default:
+ var = ScopedPPVar(ScopedPPVar::PassRef(),
+ PP_MakeDouble(static_cast<double>(k) * M_PI));
+ break;
+ }
+
+ // to value
+ std::unique_ptr<base::Value> value = ValueFromVar(var.get());
+ EXPECT_EQ(value->GetType(), base::Value::Type::DOUBLE);
+ ASSERT_TRUE(value->GetAsDouble(&d));
+ EXPECT_EQ(d, var.get().value.as_double);
+
+ // to var
+ ScopedPPVar result = VarFromValue(value.get());
+ EXPECT_EQ(d, result.get().value.as_double);
+ }
+}
+
+TEST_F(VarValueConverterTest, StringVarValueConversionTest) {
+ for (int k = 0; k < 100; ++k) {
+ // prepare test data
+ std::string s;
+ std::string str = RandomStr();
+ ScopedPPVar var(ScopedPPVar::PassRef(), StringVar::StringToPPVar(str));
+
+ // to value
+ std::unique_ptr<base::Value> value = ValueFromVar(var.get());
+ ASSERT_TRUE(value != NULL);
+ EXPECT_EQ(value->GetType(), base::Value::Type::STRING);
+ ASSERT_TRUE(value->GetAsString(&s));
+ EXPECT_STREQ(str.c_str(), s.c_str());
+
+ // to var
+ ScopedPPVar result = VarFromValue(value.get());
+ scoped_refptr<StringVar> str_var =
+ scoped_refptr<StringVar>(StringVar::FromPPVar(result.get()));
+ ASSERT_TRUE(str_var != NULL);
+ EXPECT_STREQ(str_var->value().c_str(), s.c_str());
+ }
+}
+
+TEST_F(VarValueConverterTest, ArrayVarValueConversionTest) {
+ for (int k = 0; k < 100; ++k) {
+ // prepare test data
+ bool b = ((k % 2) == 0);
+ int i = k;
+ double d = k;
+ std::string str = RandomStr();
+ bool b2;
+ int i2;
+ double d2;
+ std::string str2;
+
+ scoped_refptr<ArrayVar> nested_array =
+ scoped_refptr<ArrayVar>(new ArrayVar());
+ nested_array->SetLength(kArrayPODIdxCount);
+ size_t current_idx = BOOL_IDX;
+ SetAndForget(nested_array, current_idx++, PP_MakeBool(PP_FromBool(b)));
+ SetAndForget(nested_array, current_idx++, PP_MakeInt32(i));
+ SetAndForget(nested_array, current_idx++, PP_MakeDouble(d));
+ ASSERT_EQ(current_idx, kArrayPODIdxCount);
+
+ scoped_refptr<ArrayVar> array = scoped_refptr<ArrayVar>(new ArrayVar());
+ array->SetLength(kArrayTestSize);
+ current_idx = BOOL_IDX;
+ SetAndForget(array, current_idx++, PP_MakeBool(PP_FromBool(b)));
+ SetAndForget(array, current_idx++, PP_MakeInt32(i));
+ SetAndForget(array, current_idx++, PP_MakeDouble(d));
+ SetAndForget(array, current_idx++, StringVar::StringToPPVar(str));
+ SetAndForget(array, current_idx++, nested_array->GetPPVar());
+ ASSERT_EQ(current_idx, kArrayTestSize);
+
+ // convert to value
+ ScopedPPVar var(ScopedPPVar::PassRef(), array->GetPPVar());
+ std::unique_ptr<base::Value> value = ValueFromVar(var.get());
+
+ ASSERT_TRUE(value != NULL);
+ EXPECT_EQ(value->GetType(), base::Value::Type::LIST);
+ base::ListValue* list = nullptr;
+ ASSERT_TRUE(value->GetAsList(&list));
+ ASSERT_TRUE(list != NULL);
+ EXPECT_EQ(list->GetSize(), kArrayTestSize);
+
+ ASSERT_TRUE(list->GetBoolean(BOOL_IDX, &b2));
+ EXPECT_EQ(b, b2);
+ ASSERT_TRUE(list->GetInteger(INT_IDX, &i2));
+ EXPECT_EQ(i, i2);
+ ASSERT_TRUE(list->GetDouble(DOUBLE_IDX, &d2));
+ EXPECT_EQ(d, d2);
+ ASSERT_TRUE(list->GetString(STRING_IDX, &str2));
+ EXPECT_STREQ(str.c_str(), str2.c_str());
+
+ base::ListValue* nested_list = nullptr;
+ ASSERT_TRUE(list->GetList(ARRAY_IDX, &nested_list));
+ ASSERT_TRUE(nested_list != NULL);
+ EXPECT_EQ(nested_list->GetSize(), kArrayPODIdxCount);
+
+ ASSERT_TRUE(nested_list->GetBoolean(BOOL_IDX, &b2));
+ EXPECT_EQ(b, b2);
+ ASSERT_TRUE(nested_list->GetInteger(INT_IDX, &i2));
+ EXPECT_EQ(i, i2);
+ ASSERT_TRUE(nested_list->GetDouble(DOUBLE_IDX, &d2));
+ EXPECT_EQ(d, d2);
+
+ // convert back to var
+ var = VarFromValue(value.get());
+ ASSERT_EQ(var.get().type, PP_VARTYPE_ARRAY);
+ scoped_refptr<ArrayVar> result =
+ scoped_refptr<ArrayVar>(ArrayVar::FromPPVar(var.get()));
+
+ ASSERT_TRUE(result != NULL);
+ EXPECT_EQ(result->GetLength(), kArrayTestSize);
+
+ var = ScopedPPVar(ScopedPPVar::PassRef(), result->Get(BOOL_IDX));
+ EXPECT_EQ(var.get().type, PP_VARTYPE_BOOL);
+ EXPECT_EQ(var.get().value.as_bool, PP_FromBool(b));
+ var = ScopedPPVar(ScopedPPVar::PassRef(), result->Get(INT_IDX));
+ EXPECT_EQ(var.get().type, PP_VARTYPE_INT32);
+ EXPECT_EQ(var.get().value.as_int, i);
+ var = ScopedPPVar(ScopedPPVar::PassRef(), result->Get(DOUBLE_IDX));
+ EXPECT_EQ(var.get().type, PP_VARTYPE_DOUBLE);
+ EXPECT_EQ(var.get().value.as_double, d);
+ var = ScopedPPVar(ScopedPPVar::PassRef(), result->Get(STRING_IDX));
+ EXPECT_EQ(var.get().type, PP_VARTYPE_STRING);
+ scoped_refptr<StringVar> str_var =
+ scoped_refptr<StringVar>(StringVar::FromPPVar(var.get()));
+ ASSERT_TRUE(str_var != NULL);
+ EXPECT_STREQ(str.c_str(), str_var->value().c_str());
+
+ var = ScopedPPVar(ScopedPPVar::PassRef(), result->Get(ARRAY_IDX));
+ ASSERT_EQ(var.get().type, PP_VARTYPE_ARRAY);
+ scoped_refptr<ArrayVar> nested_var =
+ scoped_refptr<ArrayVar>(ArrayVar::FromPPVar(var.get()));
+ ASSERT_TRUE(nested_var != NULL);
+ EXPECT_EQ(nested_var->GetLength(), kArrayPODIdxCount);
+ var = ScopedPPVar(ScopedPPVar::PassRef(), nested_var->Get(BOOL_IDX));
+ EXPECT_EQ(var.get().type, PP_VARTYPE_BOOL);
+ EXPECT_EQ(var.get().value.as_bool, PP_FromBool(b));
+ var = ScopedPPVar(ScopedPPVar::PassRef(), nested_var->Get(INT_IDX));
+ EXPECT_EQ(var.get().type, PP_VARTYPE_INT32);
+ EXPECT_EQ(var.get().value.as_int, i);
+ var = ScopedPPVar(ScopedPPVar::PassRef(), nested_var->Get(DOUBLE_IDX));
+ EXPECT_EQ(var.get().type, PP_VARTYPE_DOUBLE);
+ EXPECT_EQ(var.get().value.as_double, d);
+ }
+}
+
+TEST_F(VarValueConverterTest, DictionaryVarValueConversionTest) {
+ ScopedPPVar key_vars[] = {
+ ScopedPPVar(ScopedPPVar::PassRef(),
+ StringVar::StringToPPVar(test_keys[BOOL_KEY])),
+ ScopedPPVar(ScopedPPVar::PassRef(),
+ StringVar::StringToPPVar(test_keys[INT_KEY])),
+ ScopedPPVar(ScopedPPVar::PassRef(),
+ StringVar::StringToPPVar(test_keys[DOUBLE_KEY])),
+ ScopedPPVar(ScopedPPVar::PassRef(),
+ StringVar::StringToPPVar(test_keys[STRING_KEY])),
+ ScopedPPVar(ScopedPPVar::PassRef(),
+ StringVar::StringToPPVar(test_keys[ARRAY_KEY])),
+ ScopedPPVar(ScopedPPVar::PassRef(),
+ StringVar::StringToPPVar(test_keys[DICT_KEY]))};
+
+ for (int k = 0; k < 100; ++k) {
+ // prepare test data
+
+ bool b = ((k % 2) == 0);
+ int i = k;
+ double d = k;
+ std::string str = RandomStr();
+ bool b2;
+ int i2;
+ double d2;
+ std::string str2;
+
+ scoped_refptr<ArrayVar> nested_array =
+ scoped_refptr<ArrayVar>(new ArrayVar());
+ nested_array->SetLength(kArrayPODIdxCount);
+ size_t current_idx = BOOL_IDX;
+ SetAndForget(nested_array, current_idx++, PP_MakeBool(PP_FromBool(b)));
+ SetAndForget(nested_array, current_idx++, PP_MakeInt32(i));
+ SetAndForget(nested_array, current_idx++, PP_MakeDouble(d));
+ ASSERT_EQ(current_idx, kArrayPODIdxCount);
+
+ scoped_refptr<DictionaryVar> nested_dict =
+ scoped_refptr<DictionaryVar>(new DictionaryVar());
+ SetAndForget(nested_dict, key_vars[BOOL_KEY], PP_MakeBool(PP_FromBool(b)));
+ SetAndForget(nested_dict, key_vars[INT_KEY], PP_MakeInt32(i));
+ SetAndForget(nested_dict, key_vars[DOUBLE_KEY], PP_MakeDouble(d));
+
+ scoped_refptr<DictionaryVar> dict =
+ scoped_refptr<DictionaryVar>(new DictionaryVar());
+ SetAndForget(dict, key_vars[BOOL_KEY], PP_MakeBool(PP_FromBool(b)));
+ SetAndForget(dict, key_vars[INT_KEY], PP_MakeInt32(i));
+ SetAndForget(dict, key_vars[DOUBLE_KEY], PP_MakeDouble(d));
+ SetAndForget(dict, key_vars[STRING_KEY], StringVar::StringToPPVar(str));
+ SetAndForget(dict, key_vars[ARRAY_KEY], nested_array->GetPPVar());
+ SetAndForget(dict, key_vars[DICT_KEY], nested_dict->GetPPVar());
+
+ // convert to value
+ ScopedPPVar var = ScopedPPVar(ScopedPPVar::PassRef(), dict->GetPPVar());
+ std::unique_ptr<base::Value> value = ValueFromVar(var.get());
+ ASSERT_TRUE(value != NULL);
+ EXPECT_EQ(value->GetType(), base::Value::Type::DICTIONARY);
+ base::DictionaryValue* dict_val = nullptr;
+ ASSERT_TRUE(value->GetAsDictionary(&dict_val));
+ ASSERT_TRUE(dict_val != NULL);
+ EXPECT_EQ(dict_val->size(), ArraySize(key_vars));
+
+ ASSERT_TRUE(dict_val->GetBoolean(test_keys[BOOL_KEY], &b2));
+ EXPECT_EQ(b, b2);
+ ASSERT_TRUE(dict_val->GetInteger(test_keys[INT_KEY], &i2));
+ EXPECT_EQ(i, i2);
+ ASSERT_TRUE(dict_val->GetDouble(test_keys[DOUBLE_KEY], &d2));
+ EXPECT_EQ(d, d2);
+ ASSERT_TRUE(dict_val->GetString(test_keys[STRING_KEY], &str2));
+ EXPECT_STREQ(str.c_str(), str2.c_str());
+
+ base::ListValue* nested_list = nullptr;
+ ASSERT_TRUE(dict_val->GetList(test_keys[ARRAY_KEY], &nested_list));
+ ASSERT_TRUE(nested_list != NULL);
+ EXPECT_EQ(nested_list->GetSize(), kPODKeysCount);
+
+ ASSERT_TRUE(nested_list->GetBoolean(BOOL_IDX, &b2));
+ EXPECT_EQ(b, b2);
+ ASSERT_TRUE(nested_list->GetInteger(INT_IDX, &i2));
+ EXPECT_EQ(i, i2);
+ ASSERT_TRUE(nested_list->GetDouble(DOUBLE_IDX, &d2));
+ EXPECT_EQ(d, d2);
+
+ base::DictionaryValue* nested_dict_val = nullptr;
+ ASSERT_TRUE(dict_val->GetDictionary(test_keys[DICT_KEY], &nested_dict_val));
+ ASSERT_TRUE(nested_dict_val != NULL);
+ EXPECT_EQ(nested_dict_val->size(), kPODKeysCount);
+
+ ASSERT_TRUE(nested_dict_val->GetBoolean(test_keys[BOOL_KEY], &b2));
+ EXPECT_EQ(b, b2);
+ ASSERT_TRUE(nested_dict_val->GetInteger(test_keys[INT_KEY], &i2));
+ EXPECT_EQ(i, i2);
+ ASSERT_TRUE(nested_dict_val->GetDouble(test_keys[DOUBLE_KEY], &d2));
+ EXPECT_EQ(d, d2);
+
+ // convert back to var
+ var = VarFromValue(value.get());
+ ASSERT_EQ(var.get().type, PP_VARTYPE_DICTIONARY);
+ scoped_refptr<DictionaryVar> result =
+ scoped_refptr<DictionaryVar>(DictionaryVar::FromPPVar(var.get()));
+ ASSERT_TRUE(result != NULL);
+
+ var = ScopedPPVar(ScopedPPVar::PassRef(),
+ result->Get(key_vars[BOOL_KEY].get()));
+ EXPECT_EQ(var.get().type, PP_VARTYPE_BOOL);
+ EXPECT_EQ(var.get().value.as_bool, PP_FromBool(b));
+ var = ScopedPPVar(ScopedPPVar::PassRef(),
+ result->Get(key_vars[INT_KEY].get()));
+ EXPECT_EQ(var.get().type, PP_VARTYPE_INT32);
+ EXPECT_EQ(var.get().value.as_int, i);
+ var = ScopedPPVar(ScopedPPVar::PassRef(),
+ result->Get(key_vars[DOUBLE_KEY].get()));
+ EXPECT_EQ(var.get().type, PP_VARTYPE_DOUBLE);
+ EXPECT_EQ(var.get().value.as_double, d);
+ var = ScopedPPVar(ScopedPPVar::PassRef(),
+ result->Get(key_vars[STRING_KEY].get()));
+ EXPECT_EQ(var.get().type, PP_VARTYPE_STRING);
+ scoped_refptr<StringVar> str_var =
+ scoped_refptr<StringVar>(StringVar::FromPPVar(var.get()));
+ ASSERT_TRUE(str_var != NULL);
+ EXPECT_STREQ(str.c_str(), str_var->value().c_str());
+
+ var = ScopedPPVar(ScopedPPVar::PassRef(),
+ result->Get(key_vars[ARRAY_KEY].get()));
+ EXPECT_EQ(var.get().type, PP_VARTYPE_ARRAY);
+ scoped_refptr<ArrayVar> nested_var =
+ scoped_refptr<ArrayVar>(ArrayVar::FromPPVar(var.get()));
+ ASSERT_TRUE(nested_var != NULL);
+ EXPECT_EQ(nested_var->GetLength(), kPODKeysCount);
+ var = ScopedPPVar(ScopedPPVar::PassRef(), nested_var->Get(BOOL_IDX));
+ EXPECT_EQ(var.get().type, PP_VARTYPE_BOOL);
+ EXPECT_EQ(var.get().value.as_bool, PP_FromBool(b));
+ var = ScopedPPVar(ScopedPPVar::PassRef(), nested_var->Get(INT_IDX));
+ EXPECT_EQ(var.get().type, PP_VARTYPE_INT32);
+ EXPECT_EQ(var.get().value.as_int, i);
+ var = ScopedPPVar(ScopedPPVar::PassRef(), nested_var->Get(DOUBLE_IDX));
+ EXPECT_EQ(var.get().type, PP_VARTYPE_DOUBLE);
+ EXPECT_EQ(var.get().value.as_double, d);
+
+ var = ScopedPPVar(ScopedPPVar::PassRef(),
+ result->Get(key_vars[DICT_KEY].get()));
+ EXPECT_EQ(var.get().type, PP_VARTYPE_DICTIONARY);
+ scoped_refptr<DictionaryVar> nested_var2 =
+ scoped_refptr<DictionaryVar>(DictionaryVar::FromPPVar(var.get()));
+ ASSERT_TRUE(nested_var2 != NULL);
+ var = ScopedPPVar(ScopedPPVar::PassRef(),
+ nested_var2->Get(key_vars[BOOL_KEY].get()));
+ EXPECT_EQ(var.get().type, PP_VARTYPE_BOOL);
+ EXPECT_EQ(var.get().value.as_bool, PP_FromBool(b));
+ var = ScopedPPVar(ScopedPPVar::PassRef(),
+ nested_var2->Get(key_vars[INT_KEY].get()));
+ EXPECT_EQ(var.get().type, PP_VARTYPE_INT32);
+ EXPECT_EQ(var.get().value.as_int, i);
+ var = ScopedPPVar(ScopedPPVar::PassRef(),
+ nested_var2->Get(key_vars[DOUBLE_KEY].get()));
+ EXPECT_EQ(var.get().type, PP_VARTYPE_DOUBLE);
+ EXPECT_EQ(var.get().value.as_double, d);
+ }
+}
+
+} // namespace proxy
+} // namespace ppapi
F(PPB_CameraDevice_API) \
F(PPB_DeviceRef_API) \
F(PPB_Ext_CrxFileSystem_Private_API) \
+ F(PPB_ExtensionSystem_API) \
F(PPB_FileChooser_API) \
F(PPB_FileIO_API) \
F(PPB_FileRef_API) \
F(PPB_NetworkMonitor_API) \
F(PPB_NetworkProxy_API) \
F(PPB_Printing_API) \
+ F(PPB_RemoteController_API) \
F(PPB_Scrollbar_API) \
F(PPB_TCPServerSocket_Private_API) \
F(PPB_TCPSocket_API) \
// PPB_Instance_API.GetSingletonResource.
enum SingletonResourceID {
BROWSER_FONT_SINGLETON_ID,
+ EXTENSION_SYSTEM_SINGLETON_ID,
GAMEPAD_SINGLETON_ID,
ISOLATED_FILESYSTEM_SINGLETON_ID,
NETWORK_PROXY_SINGLETON_ID,
+ REMOTE_CONTROLLER_SINGLETON_ID,
UMA_SINGLETON_ID,
};
#include "ppapi/c/private/ppp_instance_private.h"
#include "ppapi/c/trusted/ppb_url_loader_trusted.h"
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+#include "ppapi/c/samsung/ppb_extension_system_samsung.h"
+#endif /* defined(TIZEN_PEPPER_EXTENSIONS) */
+
#endif /* PPAPI_TESTS_ALL_C_INCLUDES_H_ */
#include "ppapi/utility/threading/lock.h"
#include "ppapi/utility/threading/simple_thread.h"
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+#include "ppapi/cpp/samsung/extension_system_samsung.h"
+#include "ppapi/cpp/samsung/extension_system_samsung_tizen.h"
+#include "ppapi/cpp/samsung/extension_system_samsung_wrt.h"
+#endif // defined(TIZEN_PEPPER_EXTENSIONS)
+
#endif // PPAPI_TESTS_ALL_CPP_INCLUDES_H_
import("//ppapi/buildflags/buildflags.gni")
assert(enable_ppapi)
+if (is_tizen) {
+ import("//tizen_src/build/config/tizen_features.gni")
+}
source_set("headers") {
visibility = [
]
}
+ if (is_tizen) {
+ if (tizen_pepper_extensions) {
+ sources += [
+ "ppb_extension_system_samsung_thunk.cc",
+ "ppb_remote_controller_samsung_thunk.cc",
+ ]
+ }
+ }
+
configs += [
"//ppapi/shared_impl:export_shared_impl_and_thunk",
"//build/config:precompiled_headers",
--- /dev/null
+// Copyright 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.
+
+// Please see inteface_ppb_public_stable for the documentation on the format of
+// this file.
+
+#include "ppapi/thunk/interfaces_preamble.h"
+
+#if !defined(OS_NACL)
+PROXIED_IFACE(PPB_EXTENSIONSYSTEM_SAMSUNG_INTERFACE_0_1,
+ PPB_ExtensionSystem_Samsung_0_1)
+PROXIED_IFACE(PPB_REMOTECONTROLLER_SAMSUNG_INTERFACE_0_1,
+ PPB_RemoteController_Samsung_0_1)
+#endif // !defined(OS_NACL)
+
+#include "ppapi/thunk/interfaces_postamble.h"
--- /dev/null
+// Copyright 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 PPAPI_THUNK_PPB_EXTENSION_SYSTEM_SAMSUNG_API_H_
+#define PPAPI_THUNK_PPB_EXTENSION_SYSTEM_SAMSUNG_API_H_
+
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/shared_impl/singleton_resource_id.h"
+#include "ppapi/thunk/ppapi_thunk_export.h"
+
+namespace ppapi {
+namespace thunk {
+
+class PPAPI_THUNK_EXPORT PPB_ExtensionSystem_API {
+ public:
+ virtual ~PPB_ExtensionSystem_API() {}
+
+ virtual PP_Var GetEmbedderName() = 0;
+ virtual PP_Var GetCurrentExtensionInfo() = 0;
+ virtual int32_t GenericSyncCall(PP_Var operation_name,
+ PP_Var operation_data,
+ PP_Var* operation_result) = 0;
+
+ static const SingletonResourceID kSingletonResourceID =
+ EXTENSION_SYSTEM_SINGLETON_ID;
+};
+
+} // namespace thunk
+} // namespace ppapi
+
+#endif // PPAPI_THUNK_PPB_EXTENSION_SYSTEM_SAMSUNG_API_H_
--- /dev/null
+// Copyright 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.
+
+#include "base/logging.h"
+#include "ppapi/c/pp_completion_callback.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/shared_impl/tracked_callback.h"
+#include "ppapi/thunk/enter.h"
+#include "ppapi/thunk/ppb_instance_api.h"
+#include "ppapi/thunk/resource_creation_api.h"
+#include "ppapi/thunk/thunk.h"
+
+#include "ppapi/c/samsung/ppb_extension_system_samsung.h"
+#include "ppapi/thunk/ppb_extension_system_samsung_api.h"
+
+namespace ppapi {
+namespace thunk {
+
+namespace {
+
+PP_Var GetEmbedderName(PP_Instance instance) {
+ EnterInstanceAPI<PPB_ExtensionSystem_API> enter(instance);
+ if (enter.failed())
+ return PP_MakeUndefined();
+ return enter.functions()->GetEmbedderName();
+}
+
+PP_Var GetCurrentExtensionInfo(PP_Instance instance) {
+ EnterInstanceAPI<PPB_ExtensionSystem_API> enter(instance);
+ if (enter.failed())
+ return PP_MakeUndefined();
+ return enter.functions()->GetCurrentExtensionInfo();
+}
+
+int32_t GenericSyncCall(PP_Instance instance,
+ PP_Var operation_name,
+ PP_Var operation_data,
+ PP_Var* operation_result) {
+ EnterInstanceAPI<PPB_ExtensionSystem_API> enter(instance);
+ if (enter.failed())
+ return enter.retval();
+ return enter.SetResult(enter.functions()->GenericSyncCall(
+ operation_name, operation_data, operation_result));
+}
+
+const PPB_ExtensionSystem_Samsung_0_1 g_ppb_extensionsystem_samsung_thunk_0_1 =
+ {&GetEmbedderName, &GetCurrentExtensionInfo, &GenericSyncCall};
+
+} // namespace
+
+const PPB_ExtensionSystem_Samsung_0_1*
+GetPPB_ExtensionSystem_Samsung_0_1_Thunk() {
+ return &g_ppb_extensionsystem_samsung_thunk_0_1;
+}
+
+} // namespace thunk
+} // namespace ppapi
--- /dev/null
+// Copyright 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 PPAPI_THUNK_PPB_REMOTE_CONTROLLER_SAMSUNG_API_H_
+#define PPAPI_THUNK_PPB_REMOTE_CONTROLLER_SAMSUNG_API_H_
+
+#include "ppapi/c/samsung/ppb_remote_controller_samsung.h"
+#include "ppapi/shared_impl/singleton_resource_id.h"
+#include "ppapi/thunk/ppapi_thunk_export.h"
+
+namespace ppapi {
+
+namespace thunk {
+
+class PPAPI_THUNK_EXPORT PPB_RemoteController_API {
+ public:
+ virtual ~PPB_RemoteController_API() {}
+
+ virtual int32_t RegisterKeys(PP_Instance instance,
+ uint32_t key_count,
+ const char* keys[]) = 0;
+ virtual int32_t UnRegisterKeys(PP_Instance instance,
+ uint32_t key_count,
+ const char* keys[]) = 0;
+
+ static const SingletonResourceID kSingletonResourceID =
+ REMOTE_CONTROLLER_SINGLETON_ID;
+};
+
+} // namespace thunk
+} // namespace ppapi
+
+#endif // PPAPI_THUNK_PPB_REMOTE_CONTROLLER_SAMSUNG_API_H_
--- /dev/null
+// Copyright 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.
+
+// From samsung/ppb_remote_controller_samsung.idl modified Tue Jul 12 15:37:43
+// 2016.
+#include "base/logging.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/c/samsung/ppb_remote_controller_samsung.h"
+#include "ppapi/shared_impl/tracked_callback.h"
+#include "ppapi/thunk/enter.h"
+#include "ppapi/thunk/ppapi_thunk_export.h"
+#include "ppapi/thunk/ppb_remote_controller_samsung_api.h"
+
+namespace ppapi {
+namespace thunk {
+
+namespace {
+
+int32_t RegisterKeys(PP_Instance instance,
+ uint32_t key_count,
+ const char* keys[]) {
+ VLOG(4) << "PPB_RemoteController_Samsung::RegisterKeys()";
+ EnterInstanceAPI<PPB_RemoteController_API> enter(instance);
+ if (enter.failed())
+ return enter.retval();
+ return enter.functions()->RegisterKeys(instance, key_count, keys);
+}
+
+int32_t UnRegisterKeys(PP_Instance instance,
+ uint32_t key_count,
+ const char* keys[]) {
+ VLOG(4) << "PPB_RemoteController_Samsung::UnRegisterKeys()";
+ EnterInstanceAPI<PPB_RemoteController_API> enter(instance);
+ if (enter.failed())
+ return enter.retval();
+ return enter.functions()->UnRegisterKeys(instance, key_count, keys);
+}
+
+const PPB_RemoteController_Samsung_0_1
+ g_ppb_remotecontroller_samsung_thunk_0_1 = {&RegisterKeys, &UnRegisterKeys};
+
+} // namespace
+
+PPAPI_THUNK_EXPORT const PPB_RemoteController_Samsung_0_1*
+GetPPB_RemoteController_Samsung_0_1_Thunk() {
+ return &g_ppb_remotecontroller_samsung_thunk_0_1;
+}
+
+} // namespace thunk
+} // namespace ppapi
#include "ppapi/thunk/interfaces_ppb_private_no_permissions.h"
#include "ppapi/thunk/interfaces_ppb_public_dev.h"
#include "ppapi/thunk/interfaces_ppb_public_dev_channel.h"
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+#include "ppapi/thunk/interfaces_ppb_samsung.h"
+#endif // defined(TIZEN_PEPPER_EXTENSIONS)
#include "ppapi/thunk/interfaces_ppb_public_socket.h"
#include "ppapi/thunk/interfaces_ppb_public_stable.h"
#undef PROXIED_IFACE
namespace {
+#if defined(OS_TIZEN_TV_PRODUCT)
+const char kVDToolsLibName[] = "libvdtools.so";
+#endif
+
void LogSandboxStarted(const std::string& sandbox_name) {
const std::string process_type =
base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
#endif
}
+#if defined(OS_TIZEN_TV_PRODUCT)
+// TODO(d.sura): Find better solution to detect if we are running DUMA/DML
+bool IsRunningDUMADML() {
+ char* env = getenv("LD_PRELOAD");
+ if (!env)
+ return false;
+ std::string str_env(env);
+ if (str_env.find(kVDToolsLibName) == std::string::npos)
+ return false;
+ return true;
+}
+#endif
+
// Get a file descriptor to /proc. Either duplicate |proc_fd| or try to open
// it by using the filesystem directly.
// TODO(jln): get rid of this ugly interface.
if (IsRunningTSAN())
return false;
+#if defined(OS_TIZEN_TV_PRODUCT)
+ // The same as TSAN above. The DUMA/DML is spawning additional thread.
+ if (IsRunningDUMADML())
+ return false;
+#endif
+
// The GPU process is allowed to call InitializeSandbox() with threads.
bool sandbox_failure_fatal = process_type != switches::kGpuProcess;
// This can be disabled with the '--gpu-sandbox-failures-fatal' flag.
// Enables the CHECK for open directories. The open directory check is only
// useful for the chroot jail (from the semantic layer of the sandbox), and
// can safely be disabled if we are only enabling the seccomp-BPF layer.
+#if defined(OS_TIZEN_TV_PRODUCT)
+ //To fix smack issue in InitializeSandbox
+ bool check_for_open_directories = false;
+#else
bool check_for_open_directories = true;
+#endif
};
// Callers can provide this hook to run code right before the policy
OPTIONS:
-h, --help Show this message
--build-ewk-unittests Build ewk unittests
+ --enable-pepper-extensions Enable Tizen Pepper Extensions
--ccache Configure ccache installed in your system
--clang Use chromium's clang compiler to build the sources
--debug Build debug version of chromium-efl (out.${host_arch}/Debug instead of out.${host_arch}/Release)
export BUILD_CHROME=0
export BUILD_SUBDIRECTORY=Release
export COMPONENT_BUILD=0
+ export ENABLE_PEPPER_EXTENSIONS=0
local platform="$1"
shift
--component-build)
export COMPONENT_BUILD=1
;;
+ --enable-pepper-extensions)
+ export ENABLE_PEPPER_EXTENSIONS=1
+ ;;
-j*)
export JOBS="$1"
;;
if [[ $SKIP_GN != 1 ]]; then
local XWALK_ARG=""
local COMPONENT_ARG=""
+ local PEPPER_EXTENSIONS_ARG=""
if [[ $COMPONENT_BUILD == 1 ]]; then
COMPONENT_ARG="component=shared_library"
fi
+ if [[ $ENABLE_PEPPER_EXTENSIONS == 1 ]]; then
+ PEPPER_EXTENSIONS_ARG="tizen_pepper_extensions=true"
+ fi
${TOPDIR}/tizen_src/build/gn_chromiumefl.sh \
$XWALK_ARG \
$COMPONENT_ARG \
+ $PEPPER_EXTENSIONS_ARG \
$@
fi
}
"WRT_JS_BRINGUP",
]
}
+ if (tizen_pepper_extensions) {
+ defines += [
+ "TIZEN_PEPPER_EXTENSIONS"
+ ]
+ }
}
ADDITIONAL_GN_PARAMETERS+="is_tizen=true
use_zygote_handle=true
gcc_ver=\"$(getGccVersion)\"
+ enable_plugins=true
python_ver=\"$(getPythonVersion)\"
is_official_build=true
enable_nacl=false
tizen_tbm_support=true
tizen_video_hole=true
"
+
+ if [ "$tizen_product_tv" == "true" ]; then
+ ADDITIONAL_GN_PARAMETERS+="tizen_pepper_extensions=true
+ "
+ fi
}
add_wayland_flags() {
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+import("//build/config/features.gni")
import("//tizen_src/build/config/tizen_features.gni")
+import("//ppapi/buildflags/buildflags.gni")
##############################################################################
# Configs
]
}
+if (tizen_pepper_extensions && enable_plugins) {
+ external_content_browser_efl_sources += [
+ "//tizen_src/chromium_impl/content/browser/renderer_host/pepper/browser_pepper_host_factory_efl.h",
+ "//tizen_src/chromium_impl/content/browser/renderer_host/pepper/browser_pepper_host_factory_efl.cc",
+ "//tizen_src/chromium_impl/content/browser/renderer_host/pepper/pepper_extension_system_host.cc",
+ "//tizen_src/chromium_impl/content/browser/renderer_host/pepper/pepper_extension_system_host.h",
+ "//tizen_src/chromium_impl/content/browser/renderer_host/pepper/pepper_remote_controller_host.cc",
+ "//tizen_src/chromium_impl/content/browser/renderer_host/pepper/pepper_remote_controller_host.h",
+ "//tizen_src/chromium_impl/content/browser/renderer_host/pepper/remote_controller_wrt.cc",
+ "//tizen_src/chromium_impl/content/browser/renderer_host/pepper/remote_controller_wrt.h",
+ "//tizen_src/chromium_impl/content/public/browser/extension_system_delegate.cc",
+ "//tizen_src/chromium_impl/content/public/browser/extension_system_delegate.h",
+ ]
+}
+
if (tizen_web_speech_recognition) {
external_content_browser_efl_sources += [
"//tizen_src/chromium_impl/content/browser/speech/speech_recognizer_impl_tizen.cc",
--- /dev/null
+// Copyright 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.
+
+#include "content/browser/renderer_host/pepper/browser_pepper_host_factory_efl.h"
+
+#include <memory>
+
+#include "build/build_config.h"
+#include "content/public/browser/browser_ppapi_host.h"
+#include "ppapi/host/ppapi_host.h"
+#include "ppapi/host/resource_host.h"
+#include "ppapi/proxy/ppapi_message_utils.h"
+#include "ppapi/proxy/ppapi_messages.h"
+
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+#include "content/browser/renderer_host/pepper/pepper_extension_system_host.h"
+#include "content/browser/renderer_host/pepper/pepper_remote_controller_host.h"
+#endif
+
+using ppapi::UnpackMessage;
+using ppapi::host::ResourceHost;
+
+BrowserPepperHostFactoryEfl::BrowserPepperHostFactoryEfl(
+ content::BrowserPpapiHost* host)
+ : host_(host) {}
+
+BrowserPepperHostFactoryEfl::~BrowserPepperHostFactoryEfl() {}
+
+std::unique_ptr<ResourceHost> BrowserPepperHostFactoryEfl::CreateResourceHost(
+ ppapi::host::PpapiHost* host,
+ PP_Resource resource,
+ PP_Instance instance,
+ const IPC::Message& message) {
+ DCHECK(host == host_->GetPpapiHost());
+
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+ if (message.type() == PpapiHostMsg_ExtensionSystem_Create::ID) {
+ return std::make_unique<content::PepperExtensionSystemHost>(host_, instance,
+ resource);
+ }
+
+ if (message.type() == PpapiHostMsg_RemoteController_Create::ID) {
+ return std::make_unique<content::PepperRemoteControllerHost>(
+ host_, instance, resource);
+ }
+#endif // defined(TIZEN_PEPPER_EXTENSIONS)
+
+ return std::unique_ptr<ResourceHost>();
+}
--- /dev/null
+// Copyright 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 BROWSER_PEPPER_HOST_FACTORY_EFL_H_
+#define BROWSER_PEPPER_HOST_FACTORY_EFL_H_
+
+#include "base/compiler_specific.h"
+#include "ppapi/host/host_factory.h"
+
+namespace content {
+class BrowserPpapiHost;
+} // namespace content
+
+class BrowserPepperHostFactoryEfl : public ppapi::host::HostFactory {
+ public:
+ // Non-owning pointer to the filter must outlive this class.
+ explicit BrowserPepperHostFactoryEfl(content::BrowserPpapiHost* host);
+ ~BrowserPepperHostFactoryEfl() override;
+
+ std::unique_ptr<ppapi::host::ResourceHost> CreateResourceHost(
+ ppapi::host::PpapiHost* host,
+ PP_Resource resource,
+ PP_Instance instance,
+ const IPC::Message& message) override;
+
+ private:
+ // Non-owning pointer.
+ content::BrowserPpapiHost* host_;
+};
+
+#endif // BROWSER_PEPPER_HOST_FACTORY_EFL_H_
--- /dev/null
+// Copyright 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.
+
+#include "content/browser/renderer_host/pepper/pepper_extension_system_host.h"
+
+#include <memory>
+
+#include "base/json/json_string_value_serializer.h"
+#include "base/logging.h"
+#include "base/task/thread_pool.h"
+#include "base/task/task_runner.h"
+#include "content/public/browser/browser_ppapi_host.h"
+#include "content/public/browser/browser_task_traits.h"
+#include "content/public/browser/browser_thread.h"
+#include "ewk/efl_integration/ewk_privilege_checker.h"
+#include "ppapi/cpp/samsung/extension_system_samsung_tizen.h"
+#include "ppapi/host/dispatch_host_message.h"
+#include "ppapi/host/ppapi_host.h"
+#include "ppapi/proxy/plugin_dispatcher.h"
+#include "ppapi/proxy/ppapi_messages.h"
+
+namespace content {
+
+namespace {
+const char kCheckPrivilegeOperationName[] = "check_ace_privilege";
+const char kGetWindowIdOperationName[] = "get_window_id";
+
+std::tuple<bool, std::string> GetEmbedderName(
+ ExtensionSystemDelegateManager::RenderFrameID render_frame_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ ExtensionSystemDelegate* delegate =
+ ExtensionSystemDelegateManager::GetInstance()->GetDelegateForFrame(
+ render_frame_id);
+ if (delegate)
+ return std::make_tuple(true, delegate->GetEmbedderName());
+ return std::make_tuple(false, "");
+}
+
+std::tuple<bool, std::string> GetExtensionInfo(
+ ExtensionSystemDelegateManager::RenderFrameID render_frame_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ ExtensionSystemDelegate* delegate =
+ ExtensionSystemDelegateManager::GetInstance()->GetDelegateForFrame(
+ render_frame_id);
+ std::string result;
+ if (delegate) {
+ std::unique_ptr<base::Value> res_ptr = delegate->GetExtensionInfo();
+ if (!res_ptr)
+ return std::make_tuple(false, "");
+
+ JSONStringValueSerializer json_serializer(&result);
+ if (!json_serializer.Serialize(*res_ptr))
+ return std::make_tuple(false, "");
+ }
+ return std::make_tuple(true, result);
+}
+
+std::tuple<bool, std::string> HandleGenericSyncCall(
+ ExtensionSystemDelegateManager::RenderFrameID render_frame_id,
+ const std::string operation_name,
+ base::Value* raw_pointer_data) {
+ std::unique_ptr<base::Value> data(raw_pointer_data);
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ std::string result;
+ ExtensionSystemDelegate* delegate =
+ ExtensionSystemDelegateManager::GetInstance()->GetDelegateForFrame(
+ render_frame_id);
+ if (delegate) {
+ std::unique_ptr<base::Value> res_ptr =
+ delegate->GenericSyncCall(operation_name, *data);
+ if (!res_ptr)
+ return std::make_tuple(false, "");
+
+ JSONStringValueSerializer json_serializer(&result);
+ if (!json_serializer.Serialize(*res_ptr))
+ return std::make_tuple(false, "");
+ }
+ return std::make_tuple(true, result);
+}
+} // namespace
+
+PepperExtensionSystemHost::PepperExtensionSystemHost(BrowserPpapiHost* host,
+ PP_Instance instance,
+ PP_Resource resource)
+ : ResourceHost(host->GetPpapiHost(), instance, resource) {
+ host->GetRenderFrameIDsForInstance(instance,
+ &render_frame_id_.render_process_id,
+ &render_frame_id_.render_frame_id);
+ extension_function_handlers_[kGetWindowIdOperationName] =
+ [this](const base::Value& data) { return GetWindowId(data); };
+ extension_function_handlers_[kCheckPrivilegeOperationName] =
+ [this](const base::Value& data) { return CheckPrivilege(data); };
+}
+
+PepperExtensionSystemHost::~PepperExtensionSystemHost() {}
+
+int32_t PepperExtensionSystemHost::OnResourceMessageReceived(
+ const IPC::Message& msg,
+ ppapi::host::HostMessageContext* context) {
+ PPAPI_BEGIN_MESSAGE_MAP(PepperExtensionSystemHost, msg)
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(
+ PpapiHostMsg_ExtensionSystem_GetEmbedderName, OnHostMsgGetEmbedderName)
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(
+ PpapiHostMsg_ExtensionSystem_GetCurrentExtensionInfo,
+ OnHostMsgGetCurrentExtensionInfo)
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL(
+ PpapiHostMsg_ExtensionSystem_GenericSyncCall, OnHostMsgGenericSyncCall)
+ PPAPI_END_MESSAGE_MAP()
+ return PP_ERROR_FAILED;
+}
+
+int32_t PepperExtensionSystemHost::OnHostMsgGetEmbedderName(
+ ppapi::host::HostMessageContext* context) {
+ GetUIThreadTaskRunner({})->PostTaskAndReplyWithResult(
+ FROM_HERE,
+ base::BindOnce(&GetEmbedderName, render_frame_id_),
+ base::BindOnce(&PepperExtensionSystemHost::DidGetEmbedderName, AsWeakPtr(),
+ context->MakeReplyMessageContext()));
+ return PP_OK_COMPLETIONPENDING;
+}
+
+int32_t PepperExtensionSystemHost::OnHostMsgGetCurrentExtensionInfo(
+ ppapi::host::HostMessageContext* context) {
+ GetUIThreadTaskRunner({})->PostTaskAndReplyWithResult(
+ FROM_HERE,
+ base::BindOnce(&GetExtensionInfo, render_frame_id_),
+ base::BindOnce(&PepperExtensionSystemHost::DidGetExtensionInfo, AsWeakPtr(),
+ context->MakeReplyMessageContext()));
+ return PP_OK_COMPLETIONPENDING;
+}
+
+int32_t PepperExtensionSystemHost::OnHostMsgGenericSyncCall(
+ ppapi::host::HostMessageContext* context,
+ const std::string& operation_name,
+ const std::string& operation_data) {
+ base::StringPiece data_str(operation_data);
+ JSONStringValueDeserializer json_deserializer(data_str);
+
+ std::unique_ptr<base::Value> data(
+ json_deserializer.Deserialize(nullptr, nullptr));
+ if (!data) {
+ LOG(ERROR) << "Couldn`t deserialize data";
+ return PP_ERROR_FAILED;
+ }
+
+ bool is_handled;
+ std::unique_ptr<base::Value> res_ptr =
+ TryHandleInternally(operation_name, *data, &is_handled);
+ if (!is_handled) {
+ GetUIThreadTaskRunner({})->PostTaskAndReplyWithResult(
+ FROM_HERE,
+ base::BindOnce(&HandleGenericSyncCall, render_frame_id_, operation_name,
+ data.release()),
+ base::BindOnce(&PepperExtensionSystemHost::DidHandledGenericSyncCall,
+ AsWeakPtr(), context->MakeReplyMessageContext()));
+ return PP_OK_COMPLETIONPENDING;
+ }
+
+ if (!res_ptr) {
+ LOG(ERROR);
+ return PP_ERROR_FAILED;
+ }
+
+ std::string result;
+ JSONStringValueSerializer json_serializer(&result);
+ if (!json_serializer.Serialize(*res_ptr)) {
+ LOG(WARNING) << "Couldn`t serialize result of GenericSyncCall";
+ return PP_ERROR_FAILED;
+ }
+
+ context->reply_msg =
+ PpapiPluginMsg_ExtensionSystem_GenericSyncCallReply(result);
+ return PP_OK;
+}
+
+void PepperExtensionSystemHost::DidGetEmbedderName(
+ ppapi::host::ReplyMessageContext reply_context,
+ std::tuple<bool, std::string> embedder_name) {
+ if (std::get<0>(embedder_name))
+ reply_context.params.set_result(PP_OK);
+ else
+ reply_context.params.set_result(PP_ERROR_FAILED);
+ host()->SendReply(reply_context,
+ PpapiPluginMsg_ExtensionSystem_GetEmbedderNameReply(
+ std::get<1>(embedder_name)));
+}
+
+void PepperExtensionSystemHost::DidGetExtensionInfo(
+ ppapi::host::ReplyMessageContext reply_context,
+ std::tuple<bool, std::string> serialized_data) {
+ if (std::get<0>(serialized_data))
+ reply_context.params.set_result(PP_OK);
+ else
+ reply_context.params.set_result(PP_ERROR_FAILED);
+ host()->SendReply(reply_context,
+ PpapiPluginMsg_ExtensionSystem_GetCurrentExtensionInfoReply(
+ std::get<1>(serialized_data)));
+}
+
+void PepperExtensionSystemHost::DidHandledGenericSyncCall(
+ ppapi::host::ReplyMessageContext reply_context,
+ std::tuple<bool, std::string> operation_result) {
+ if (std::get<0>(operation_result))
+ reply_context.params.set_result(PP_OK);
+ else
+ reply_context.params.set_result(PP_ERROR_FAILED);
+ host()->SendReply(reply_context,
+ PpapiPluginMsg_ExtensionSystem_GenericSyncCallReply(
+ std::get<1>(operation_result)));
+}
+
+std::unique_ptr<base::Value> PepperExtensionSystemHost::TryHandleInternally(
+ const std::string& operation_name,
+ const base::Value& data,
+ bool* was_handled) {
+ *was_handled = false;
+
+ auto it = extension_function_handlers_.find(operation_name);
+ if (it == extension_function_handlers_.end())
+ return std::make_unique<base::Value>();
+ *was_handled = true;
+ return it->second(data);
+}
+
+std::unique_ptr<base::Value> PepperExtensionSystemHost::GetWindowId(
+ const base::Value& data) {
+ int id = -1;
+ ExtensionSystemDelegate* delegate =
+ ExtensionSystemDelegateManager::GetInstance()->GetDelegateForFrame(
+ render_frame_id_);
+ if (delegate)
+ id = delegate->GetWindowId();
+ return std::unique_ptr<base::Value>(new base::Value(id));
+}
+
+std::unique_ptr<base::Value> PepperExtensionSystemHost::CheckPrivilege(
+ const base::Value& data) {
+ const std::string* privilege = data.GetIfString();
+ if (!privilege) {
+ LOG(ERROR) << "Provided data for checking privilege is not a string!";
+ return std::make_unique<base::Value>(false);
+ }
+
+ bool result = EwkPrivilegeChecker::GetInstance()->CheckPrivilege(*privilege);
+ LOG_IF(WARNING, !result) << "Privilege " << *privilege << " is not granted";
+ return std::make_unique<base::Value>(result);
+}
+
+} // namespace content
--- /dev/null
+// Copyright 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 CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_EXTENSION_SYSTEM_HOST_H_
+#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_EXTENSION_SYSTEM_HOST_H_
+
+#include <functional>
+#include <string>
+#include <tuple>
+#include <unordered_map>
+
+#include "base/memory/weak_ptr.h"
+#include "content/public/browser/extension_system_delegate.h"
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_var.h"
+#include "ppapi/host/host_message_context.h"
+#include "ppapi/host/resource_host.h"
+#include "ppapi/proxy/serialized_var.h"
+
+namespace content {
+
+class BrowserPpapiHost;
+
+class PepperExtensionSystemHost
+ : public ppapi::host::ResourceHost,
+ public base::SupportsWeakPtr<PepperExtensionSystemHost> {
+ public:
+ PepperExtensionSystemHost(BrowserPpapiHost* host,
+ PP_Instance instance,
+ PP_Resource resource);
+ ~PepperExtensionSystemHost() override;
+
+ protected:
+ // ppapi::host::ResourceHost override.
+ int32_t OnResourceMessageReceived(
+ const IPC::Message& msg,
+ ppapi::host::HostMessageContext* context) override;
+
+ private:
+ int32_t OnHostMsgGenericSyncCall(ppapi::host::HostMessageContext* context,
+ const std::string& operation_name,
+ const std::string& operation_data);
+ int32_t OnHostMsgGetEmbedderName(ppapi::host::HostMessageContext* context);
+ int32_t OnHostMsgGetCurrentExtensionInfo(
+ ppapi::host::HostMessageContext* context);
+
+ void DidGetEmbedderName(ppapi::host::ReplyMessageContext,
+ std::tuple<bool, std::string> embedder_name);
+ void DidGetExtensionInfo(ppapi::host::ReplyMessageContext,
+ std::tuple<bool, std::string> serialized_data);
+ void DidHandledGenericSyncCall(
+ ppapi::host::ReplyMessageContext,
+ std::tuple<bool, std::string> operation_result);
+
+ std::unique_ptr<base::Value> TryHandleInternally(
+ const std::string& operation_name,
+ const base::Value& data,
+ bool* was_handled);
+ std::unique_ptr<base::Value> GetWindowId(const base::Value& data);
+ std::unique_ptr<base::Value> CheckPrivilege(const base::Value& data);
+
+ using FunctionHandler =
+ std::function<std::unique_ptr<base::Value>(const base::Value&)>;
+ std::unordered_map<std::string, FunctionHandler> extension_function_handlers_;
+
+ ExtensionSystemDelegateManager::RenderFrameID render_frame_id_;
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_EXTENSION_SYSTEM_HOST_H_
--- /dev/null
+// Copyright 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.
+
+#include "content/browser/renderer_host/pepper/pepper_remote_controller_host.h"
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "content/public/browser/browser_ppapi_host.h"
+#include "content/public/browser/browser_thread.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/host/dispatch_host_message.h"
+#include "ppapi/host/host_message_context.h"
+#include "ppapi/host/ppapi_host.h"
+#include "ppapi/proxy/dispatch_reply_message.h"
+#include "ppapi/proxy/ppapi_messages.h"
+
+#if defined(OS_TIZEN_TV_PRODUCT)
+#include "content/browser/renderer_host/pepper/remote_controller_wrt.h"
+#include "ewk/efl_integration/common/application_type.h"
+#endif
+
+namespace content {
+
+PepperRemoteControllerHost::PepperRemoteControllerHost(BrowserPpapiHost* host,
+ PP_Instance instance,
+ PP_Resource resource)
+ : ResourceHost(host->GetPpapiHost(), instance, resource), host_(host) {}
+
+PepperRemoteControllerHost::~PepperRemoteControllerHost() = default;
+
+int32_t PepperRemoteControllerHost::OnResourceMessageReceived(
+ const IPC::Message& msg,
+ ppapi::host::HostMessageContext* context) {
+ PPAPI_BEGIN_MESSAGE_MAP(PepperRemoteControllerHost, msg)
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_RemoteController_RegisterKeys,
+ OnHostMsgRegisterKeys)
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL(
+ PpapiHostMsg_RemoteController_UnRegisterKeys, OnHostMsgUnRegisterKeys)
+ PPAPI_END_MESSAGE_MAP()
+ LOG(ERROR) << "Resource message unresolved";
+ return PP_ERROR_FAILED;
+}
+
+int32_t PepperRemoteControllerHost::OnHostMsgRegisterKeys(
+ ppapi::host::HostMessageContext* context,
+ const std::vector<std::string>& keys) {
+ auto delegate = GetPlatformDelegate();
+ if (!delegate) {
+ LOG(ERROR) << "Invalid delegate";
+ return PP_ERROR_NOTSUPPORTED;
+ }
+
+// auto cb = base::BindOnce(&PepperRemoteControllerHost::DidRegisterKeys,
+// AsWeakPtr(), context->MakeReplyMessageContext());
+ delegate->RegisterKeys(keys,
+ base::BindOnce(&PepperRemoteControllerHost::DidRegisterKeys,
+ AsWeakPtr(), context->MakeReplyMessageContext()));
+ return PP_OK_COMPLETIONPENDING;
+}
+
+int32_t PepperRemoteControllerHost::OnHostMsgUnRegisterKeys(
+ ppapi::host::HostMessageContext* context,
+ const std::vector<std::string>& keys) {
+ auto delegate = GetPlatformDelegate();
+ if (!delegate) {
+ LOG(ERROR) << "Invalid delegate";
+ return PP_ERROR_NOTSUPPORTED;
+ }
+
+// auto cb = base::BindOnce(&PepperRemoteControllerHost::DidUnRegisterKeys,
+ // AsWeakPtr(), context->MakeReplyMessageContext());
+ delegate->UnRegisterKeys(keys,
+ base::BindOnce(&PepperRemoteControllerHost::DidUnRegisterKeys,
+ AsWeakPtr(), context->MakeReplyMessageContext()));
+ return PP_OK_COMPLETIONPENDING;
+}
+
+void PepperRemoteControllerHost::DidRegisterKeys(
+ ppapi::host::ReplyMessageContext reply_context,
+ int32_t result) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ reply_context.params.set_result(result);
+ host()->SendReply(reply_context,
+ PpapiHostMsg_RemoteController_RegisterKeysReply());
+}
+
+void PepperRemoteControllerHost::DidUnRegisterKeys(
+ ppapi::host::ReplyMessageContext reply_context,
+ int32_t result) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ reply_context.params.set_result(result);
+ host()->SendReply(reply_context,
+ PpapiHostMsg_RemoteController_UnRegisterKeysReply());
+}
+
+PepperRemoteControllerHost::PlatformDelegate*
+PepperRemoteControllerHost::GetPlatformDelegate() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ if (delegate_)
+ return delegate_.get();
+#if defined(OS_TIZEN_TV_PRODUCT)
+ if (IsTIZENWRT())
+ delegate_ = CreateRemoteControllerWRT(pp_instance(), host_);
+#endif
+ return delegate_.get();
+}
+
+} // namespace content
--- /dev/null
+// Copyright 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 CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_REMOTE_CONTROLLER_HOST_H_
+#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_REMOTE_CONTROLLER_HOST_H_
+
+#include <memory>
+#include <vector>
+
+#include "base/callback.h"
+#include "base/memory/weak_ptr.h"
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/samsung/ppb_remote_controller_samsung.h"
+#include "ppapi/host/resource_host.h"
+
+namespace content {
+
+class BrowserPpapiHost;
+
+class PepperRemoteControllerHost
+ : public ppapi::host::ResourceHost,
+ public base::SupportsWeakPtr<PepperRemoteControllerHost> {
+ public:
+ PepperRemoteControllerHost(BrowserPpapiHost* host,
+ PP_Instance instance,
+ PP_Resource resource);
+
+ ~PepperRemoteControllerHost() override;
+
+ // Interface for Platform Remote Controller implementation
+ class PlatformDelegate {
+ public:
+ virtual ~PlatformDelegate() {}
+
+ virtual void RegisterKeys(const std::vector<std::string>& keys,
+ const base::OnceCallback<void(int32_t)> cb) = 0;
+
+ virtual void UnRegisterKeys(const std::vector<std::string>& keys,
+ const base::OnceCallback<void(int32_t)> cb) = 0;
+ };
+
+ protected:
+ // ppapi::host::ResourceHost override.
+ int32_t OnResourceMessageReceived(
+ const IPC::Message& msg,
+ ppapi::host::HostMessageContext* context) override;
+
+ private:
+ int32_t OnHostMsgRegisterKeys(ppapi::host::HostMessageContext* context,
+ const std::vector<std::string>& keys);
+
+ int32_t OnHostMsgUnRegisterKeys(ppapi::host::HostMessageContext* context,
+ const std::vector<std::string>& keys);
+
+ void DidRegisterKeys(ppapi::host::ReplyMessageContext reply_context,
+ int32_t result);
+
+ void DidUnRegisterKeys(ppapi::host::ReplyMessageContext reply_context,
+ int32_t result);
+
+ // Used to lazy initialize delegate_
+ PlatformDelegate* GetPlatformDelegate();
+
+ BrowserPpapiHost* host_;
+ std::unique_ptr<PlatformDelegate> delegate_;
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_REMOTE_CONTROLLER_HOST_H_
--- /dev/null
+// Copyright 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.
+
+#include "remote_controller_wrt.h"
+
+#include <tuple>
+#include <unordered_map>
+#include <vector>
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/logging.h"
+#include "base/memory/ref_counted.h"
+#include "base/task/thread_pool.h"
+#include "base/task/task_runner.h"
+#include "content/public/browser/browser_ppapi_host.h"
+#include "content/public/browser/browser_task_traits.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/extension_system_delegate.h"
+#include "ppapi/c/pp_errors.h"
+
+namespace content {
+
+namespace {
+
+static const char kOperationNameRegister[] = "RegisterKey";
+static const char kOperationNameUnRegister[] = "UnRegisterKey";
+
+class RemoteControllerWRT
+ : public content::PepperRemoteControllerHost::PlatformDelegate {
+ public:
+ RemoteControllerWRT(int render_process_id, int render_frame_id);
+ ~RemoteControllerWRT() override = default;
+
+ void RegisterKeys(const std::vector<std::string>& keys,
+ base::OnceCallback<void(int32_t)> cb) override;
+
+ void UnRegisterKeys(const std::vector<std::string>& keys,
+ base::OnceCallback<void(int32_t)> cb) override;
+
+ private:
+ // Class which will execute requests on UI Thread
+ class TaskExecutor;
+ scoped_refptr<TaskExecutor> executor_;
+};
+
+class RemoteControllerWRT::TaskExecutor
+ : public base::RefCountedThreadSafe<TaskExecutor> {
+ public:
+ TaskExecutor(int render_process_id, int render_frame_id);
+
+ int32_t RegisterKeys(const std::vector<std::string>& keys);
+
+ int32_t UnRegisterKeys(const std::vector<std::string>& keys);
+
+ private:
+ friend class base::RefCountedThreadSafe<TaskExecutor>;
+ ~TaskExecutor() = default;
+
+ int32_t DispatchToGenericSyncCall(const std::string& operation_name,
+ const std::vector<std::string>& keys);
+
+ ExtensionSystemDelegateManager::RenderFrameID render_frame_id_;
+};
+
+RemoteControllerWRT::TaskExecutor::TaskExecutor(int render_process_id,
+ int render_frame_id) {
+ render_frame_id_.render_frame_id = render_frame_id;
+ render_frame_id_.render_process_id = render_process_id;
+}
+
+int32_t RemoteControllerWRT::TaskExecutor::RegisterKeys(
+ const std::vector<std::string>& keys) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ int32_t ret = DispatchToGenericSyncCall(kOperationNameRegister, keys);
+ LOG_IF(ERROR, ret != PP_OK) << "Registering keys failed";
+ return ret;
+}
+
+int32_t RemoteControllerWRT::TaskExecutor::UnRegisterKeys(
+ const std::vector<std::string>& keys) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ int32_t ret = DispatchToGenericSyncCall(kOperationNameUnRegister, keys);
+ LOG_IF(ERROR, ret != PP_OK) << "UnRegistering Keys failed";
+ return ret;
+}
+
+int32_t RemoteControllerWRT::TaskExecutor::DispatchToGenericSyncCall(
+ const std::string& operation_name,
+ const std::vector<std::string>& keys) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ ExtensionSystemDelegate* delegate =
+ ExtensionSystemDelegateManager::GetInstance()->GetDelegateForFrame(
+ render_frame_id_);
+ if (!delegate) {
+ LOG(ERROR) << "Failed to acquire delegate can`t perform " << operation_name;
+ return PP_ERROR_FAILED;
+ }
+
+ // We can`t tell if key that we try to (Un)Register have failed because
+ // it have been already (Un)Registered. So if at least one key have
+ // been successfully processed, we assume that other keys that failed have
+ // been already registered before the call.
+ // This logic will fail when WRT removes support for specific key and we
+ // try to register on it. But this can be quickly checked basing on printed
+ // below log and looking in to sources of
+ // (crosswalk_tizen)/runtime/browser/input_device_manager.cc
+ bool registered_any_key = false;
+ for (const std::string& key_platform_name : keys) {
+ if (key_platform_name.empty()) {
+ LOG(ERROR) << "Key platform name is empty.";
+ return PP_ERROR_BADARGUMENT;
+ }
+ std::unique_ptr<base::Value> key_name =
+ std::make_unique<base::Value>(key_platform_name);
+ std::unique_ptr<base::Value> res_ptr =
+ delegate->GenericSyncCall(operation_name, *key_name);
+ auto sync_call_result = res_ptr->GetIfBool();
+ if (sync_call_result) {
+ registered_any_key = true;
+ } else {
+ LOG(WARNING) << "Result of " << operation_name << ": "
+ << key_platform_name << ", returned false. Either "
+ << operation_name << " failed or Key have been already "
+ << "processed before call. Continuing...";
+ }
+ }
+ return (registered_any_key ? PP_OK : PP_ERROR_FAILED);
+}
+
+RemoteControllerWRT::RemoteControllerWRT(int render_process_id,
+ int render_frame_id)
+ : executor_{new TaskExecutor(render_process_id, render_frame_id)} {}
+
+void RemoteControllerWRT::RegisterKeys(
+ const std::vector<std::string>& keys,
+ base::OnceCallback<void(int32_t)> cb) {
+ GetUIThreadTaskRunner({})->PostTaskAndReplyWithResult(
+ FROM_HERE,
+ base::BindOnce(&RemoteControllerWRT::TaskExecutor::RegisterKeys, executor_,
+ keys),
+ std::move(cb));
+}
+
+void RemoteControllerWRT::UnRegisterKeys(
+ const std::vector<std::string>& keys,
+ base::OnceCallback<void(int32_t)> cb) {
+ GetUIThreadTaskRunner({})->PostTaskAndReplyWithResult(
+ FROM_HERE,
+ base::BindOnce(&RemoteControllerWRT::TaskExecutor::UnRegisterKeys, executor_,
+ keys),
+ std::move(cb));
+}
+
+} // namespace
+
+std::unique_ptr<PepperRemoteControllerHost::PlatformDelegate>
+CreateRemoteControllerWRT(PP_Instance instance,
+ content::BrowserPpapiHost* host) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ int render_process_id, render_frame_id;
+ if (!host->GetRenderFrameIDsForInstance(instance, &render_process_id,
+ &render_frame_id)) {
+ LOG(ERROR) << "Can't get process_id and frame_id";
+ return {};
+ }
+
+ return std::make_unique<RemoteControllerWRT>(render_process_id,
+ render_frame_id);
+}
+
+} // namespace content
--- /dev/null
+// Copyright 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 CONTENT_BROWSER_RENDERER_HOST_PEPPER_REMOTE_CONTROLLER_WRT_H_
+#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_REMOTE_CONTROLLER_WRT_H_
+
+#include <memory>
+
+#include "content/browser/renderer_host/pepper/pepper_remote_controller_host.h"
+
+namespace content {
+class BrowserPpapiHost;
+
+// Factory method
+std::unique_ptr<content::PepperRemoteControllerHost::PlatformDelegate>
+CreateRemoteControllerWRT(PP_Instance instance,
+ content::BrowserPpapiHost* host);
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_RENDERER_HOST_PEPPER_REMOTE_CONTROLLER_WRT_H_
--- /dev/null
+// Copyright 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.
+
+#include "content/public/browser/extension_system_delegate.h"
+
+#include "base/hash/hash.h"
+#include "base/memory/singleton.h"
+
+namespace content {
+
+ExtensionSystemDelegateManager::~ExtensionSystemDelegateManager() = default;
+
+ExtensionSystemDelegateManager* ExtensionSystemDelegateManager::GetInstance() {
+ return base::Singleton<ExtensionSystemDelegateManager>::get();
+}
+
+ExtensionSystemDelegate* ExtensionSystemDelegateManager::GetDelegateForFrame(
+ const ExtensionSystemDelegateManager::RenderFrameID& id) {
+ auto found_it = delegates_.find(id);
+ if (found_it != delegates_.end()) {
+ return found_it->second.get();
+ }
+
+ // Find delegate with lowest frame_id for given pid.
+ // Such situation might happen when plugin is loaded in <iframe> element
+ for (auto it = delegates_.begin(); it != delegates_.end(); ++it) {
+ if (it->first.render_process_id != id.render_process_id)
+ continue;
+
+ if (found_it == delegates_.end() ||
+ it->first.render_frame_id < found_it->first.render_frame_id) {
+ found_it = it;
+ }
+ }
+
+ if (found_it != delegates_.end())
+ return found_it->second.get();
+
+ return nullptr;
+}
+
+void ExtensionSystemDelegateManager::RegisterDelegate(
+ const ExtensionSystemDelegateManager::RenderFrameID& id,
+ std::unique_ptr<ExtensionSystemDelegate> delegate) {
+ delegates_[id] = std::move(delegate);
+}
+
+bool ExtensionSystemDelegateManager::UnregisterDelegate(
+ const ExtensionSystemDelegateManager::RenderFrameID& id) {
+ return delegates_.erase(id) > 0;
+}
+
+bool ExtensionSystemDelegateManager::RenderFrameID::operator==(
+ const ExtensionSystemDelegateManager::RenderFrameID& rhs) const {
+ return render_process_id == rhs.render_process_id &&
+ render_frame_id == rhs.render_frame_id;
+}
+
+std::size_t ExtensionSystemDelegateManager::RenderFrameIDHasher::operator()(
+ const ExtensionSystemDelegateManager::RenderFrameID& k) const {
+ return base::HashInts32(k.render_process_id, k.render_frame_id);
+}
+
+ExtensionSystemDelegateManager::ExtensionSystemDelegateManager() = default;
+
+} // namespace content
--- /dev/null
+// Copyright 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 CONTENT_PUBLIC_BROWSER_EXTENSION_SYSTEM_DELEGATE_H_
+#define CONTENT_PUBLIC_BROWSER_EXTENSION_SYSTEM_DELEGATE_H_
+
+#include <memory>
+#include <string>
+#include <unordered_map>
+
+#include "base/values.h"
+
+namespace base {
+template <typename T>
+struct DefaultSingletonTraits;
+}
+
+namespace content {
+
+/*
+ * ExtensionSystemDelegate is an interface for communication with the EWebView
+ */
+class ExtensionSystemDelegate {
+ public:
+ virtual ~ExtensionSystemDelegate() {}
+ virtual std::string GetEmbedderName() const = 0;
+ virtual std::unique_ptr<base::Value> GetExtensionInfo() const = 0;
+ virtual std::unique_ptr<base::Value> GenericSyncCall(
+ const std::string& name,
+ const base::Value& data) = 0;
+ virtual int GetWindowId() const = 0;
+};
+
+/*
+ * ExtensionSystemDelegateManager is a singleton for accessing the
+ * ExtensionSystemDelegate interfaces that were registered by the EWebView
+ */
+class ExtensionSystemDelegateManager {
+ public:
+ // Struct that acts as a key for the interfaces map
+ struct RenderFrameID {
+ int render_process_id;
+ int render_frame_id;
+ bool operator==(const RenderFrameID& rhs) const;
+ };
+
+ static ExtensionSystemDelegateManager* GetInstance();
+
+ // This function is called by the Host, it returns weak_ptr to the interface
+ ExtensionSystemDelegate* GetDelegateForFrame(const RenderFrameID& id);
+
+ // This set of functions should be accessed only by the EWebView
+ // in order to manage the interface life
+ void RegisterDelegate(const RenderFrameID& id,
+ std::unique_ptr<ExtensionSystemDelegate> delegate);
+ bool UnregisterDelegate(const RenderFrameID& id);
+
+ private:
+ struct RenderFrameIDHasher {
+ std::size_t operator()(const RenderFrameID& k) const;
+ };
+
+ friend struct base::DefaultSingletonTraits<ExtensionSystemDelegateManager>;
+
+ ExtensionSystemDelegateManager();
+ ~ExtensionSystemDelegateManager();
+
+ std::unordered_map<RenderFrameID,
+ std::unique_ptr<ExtensionSystemDelegate>,
+ RenderFrameIDHasher>
+ delegates_;
+};
+
+} // namespace content
+
+#endif // CONTENT_PUBLIC_BROWSER_EXTENSION_SYSTEM_DELEGATE_H_
import("//base/allocator/allocator.gni")
import("//build/config/features.gni")
import("//printing/buildflags/buildflags.gni")
+import("//testing/test.gni")
+import("//ppapi/buildflags/buildflags.gni")
# Components used to auto generate CHROMIUM_VERSION preprocessor define.
version_file = "//chrome/VERSION"
}
}
+component("chromium_ewk_component") {
+ include_dirs = [
+ ".",
+ ]
+
+ deps = [
+ "//base:base_static",
+ ]
+}
+
shared_library("chromium-ewk") {
testonly = true
if (enable_ewk_interface) {
"//third_party/leveldatabase",
"//third_party/sqlite",
"//tizen_src/chromium_impl/efl:efl-init",
+ "//tizen_src/ewk/efl_integration:chromium_ewk_component",
"//tizen_src/ewk/po_tizen:locale_efl",
"//tizen_src/ewk/po_tizen:packed_locales_efl",
"//ui/compositor",
]
}
+ if (tizen_pepper_extensions) {
+ configs += [ "//tizen_src/build:cynara-client" ]
+ configs += [ "//tizen_src/build:wayland-client" ]
+ configs += [ "//tizen_src/build:tizen-extension-client" ]
+ }
+
# TODO : Below dependency is set in chromium/device/battery_tizen.gypi,
# but since m47 it failed to get properly "injected"
# to device_battery target due to the new nesting
"public/ewk_tracing_internal.h",
"public/ewk_user_media.cc",
"public/ewk_user_media_internal.h",
- "public/ewk_value.cc",
- "public/ewk_value_product.h",
"public/ewk_view.cc",
"public/ewk_view.h",
"public/ewk_view_internal.h",
]
}
+ if (tizen_pepper_extensions) {
+ sources += [
+ "renderer/pepper/pepper_helper.cc",
+ "renderer/pepper/pepper_helper.h",
+ "renderer/pepper/pepper_shared_memory_message_filter.cc",
+ "renderer/pepper/pepper_shared_memory_message_filter.h",
+ "common/trusted_pepper_plugin_info_cache.cc",
+ "common/trusted_pepper_plugin_info_cache.h",
+ "common/trusted_pepper_plugin_util.cc",
+ "common/trusted_pepper_plugin_util.h",
+ "ewk_extension_system_delegate.cc",
+ "ewk_extension_system_delegate.h",
+ "ewk_privilege_checker.cc",
+ "ewk_privilege_checker.h",
+ "private/ewk_value_private.cc",
+ "private/ewk_value_private.h",
+ "public/ewk_value.cc",
+ "public/ewk_value_product.h",
+ "public/ewk_value_type.h",
+ ]
+ }
+
sources -= exclude_source_set
# FIXME: Followings are guarded just for bringup.
}
}
+test("efl_integration_unittests") {
+ deps = [
+ "//base/test:test_support",
+ "//ipc",
+ "//ipc:run_all_unittests",
+ ]
+
+ libs = [ "dlog" ]
+
+ include_dirs = [
+ ".",
+ "test"
+ ]
+
+ cflags = [
+ # Treat warning as error for this target.
+ # It needs to be included by means of pattern list because '-Werror' cflag
+ # will be excluded in chromium side (src/build/common.gypi), and GYP
+ # processes pattern lists after exclusion lists.
+ # (ref: https://gyp.gsrc.io/docs/InputFormatReference.md#Processing-Order)
+ "-Werror"
+ ]
+
+ if (tizen_pepper_extensions && enable_plugins) {
+ sources = [
+ "common/trusted_pepper_plugin_info_cache_unittest.cc",
+ "common/trusted_pepper_plugin_info_cache.cc",
+ "common/trusted_pepper_plugin_info_cache.h",
+ "../../../content/public/common/pepper_plugin_info.cc",
+ "../../../content/public/common/pepper_plugin_info.h",
+ "../../../content/public/common/webplugininfo.cc",
+ "../../../content/public/common/webplugininfo.h",
+ "../../../base/logging.cc",
+ "../../../base/logging.h",
+ ]
+ deps += [
+ "//net:net",
+ "//url:url"
+ ]
+}
+}
+
copy("launch_exec_script") {
sources = [ "launch_exec.sh" ]
outputs = [ "$root_out_dir/{{source_file_part}}" ]
#include "common/content_client_efl.h"
#include "ipc/ipc_message.h"
+#include "ppapi/buildflags/buildflags.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
+#if BUILDFLAG(ENABLE_PLUGINS)
+#include "content/public/common/content_plugin_info.h"
+#endif
+#if BUILDFLAG(ENABLE_PLUGINS) && defined(TIZEN_PEPPER_EXTENSIONS)
+#include "base/command_line.h"
+#include "common/trusted_pepper_plugin_info_cache.h"
+#include "common/trusted_pepper_plugin_util.h"
+#include "content/public/common/content_switches.h"
+#endif
+
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+namespace {
+inline bool IsPepperPluginProcess() {
+ auto& command_line = *base::CommandLine::ForCurrentProcess();
+ auto type = command_line.GetSwitchValueASCII(switches::kProcessType);
+ return type == switches::kPpapiPluginProcess;
+}
+} // namespace
+#endif
std::u16string ContentClientEfl::GetLocalizedString(int message_id) {
// TODO(boliu): Used only by WebKit, so only bundle those resources for
// Because of this we should never drop any synchronous IPC replies.
return message->type() == IPC_REPLY_ID;
}
+void ContentClientEfl::AddPlugins(
+ std::vector<content::ContentPluginInfo>* plugins) {
+#if BUILDFLAG(ENABLE_PLUGINS) && defined(TIZEN_PEPPER_EXTENSIONS)
+ DCHECK(plugins);
+ if (!IsPepperPluginProcess() && !pepper::AreTrustedPepperPluginsDisabled())
+ pepper::TrustedPepperPluginInfoCache::GetInstance()->GetPlugins(plugins);
+#endif
+}
std::string GetDataResourceString(int resource_id) override;
gfx::Image& GetNativeImageNamed(int resource_id) override;
bool CanSendWhileSwappedOut(const IPC::Message* message);
+ void AddPlugins(
+ std::vector<content::ContentPluginInfo>* plugins) override;
};
#endif // CONTENT_CLIENT_EFL_H_
const char kEwkEnableMobileFeaturesForDesktop[] =
"ewk-enable-mobile-features-for-desktop";
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+const char kEnableTrustedPepperPlugins[] = "enable-trusted-pepper-plugins";
+const char kTrustedPepperPluginsSearchPaths[] =
+ "trusted-pepper-plugins-search-paths";
+#endif
// Don't dump stuff here, follow the same order as the header.
} // namespace switches
// similar set of features that mobile build has.
CONTENT_EXPORT extern const char kEwkEnableMobileFeaturesForDesktop[];
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+// Allow Trusted Pepper Plugins to be loaded in WebBrowser/ubrowser,
+// which is used for development purposes.
+CONTENT_EXPORT extern const char kEnableTrustedPepperPlugins[];
+
+// Additional Trusted Pepper Plugins search paths.
+// Useful for development purposes. Multiple files can be used by separating
+// them with a semicolon (;).
+CONTENT_EXPORT extern const char kTrustedPepperPluginsSearchPaths[];
+#endif
// DON'T ADD RANDOM STUFF HERE. Put it in the main section above in
// alphabetical order, or in one of the ifdefs (also in order in each section).
--- /dev/null
+// Copyright 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.
+
+#include "common/trusted_pepper_plugin_info_cache.h"
+
+#include <iterator>
+#include <unordered_set>
+
+#include "base/command_line.h"
+#include "base/files/file.h"
+#include "base/files/file_enumerator.h"
+#include "base/files/file_util.h"
+#include "base/json/json_reader.h"
+#include "base/lazy_instance.h"
+#include "base/logging.h"
+#include "base/memory/singleton.h"
+#include "base/strings/string_split.h"
+#include "base/values.h"
+#include "common/content_switches_efl.h"
+#include "content/public/common/content_plugin_info.h"
+#include "net/base/mime_util.h"
+#include "ppapi/shared_impl/ppapi_permissions.h"
+#include "url/gurl.h"
+
+#define PARSING_ERROR(pmf) \
+ LOG(WARNING) << "Malformed PMF: " << pmf.LossyDisplayName() << ": "
+using base::FilePath;
+using content::ContentPluginInfo;
+using content::WebPluginMimeType;
+
+namespace pepper {
+
+namespace {
+
+// TODO(a.bujalski, d.sura):
+// Path for TrustedPepperPlugins providing TV specific WebAPIs.
+// Currently we don`t have tizen environment which defines TrustedPepperPlugins
+// paths ("/opt/usr/apps/pepper" and "/usr/lib/pepper"), thus we use hardcoded
+// values. We should use proper environment variable as soon as specific
+// variable is added for TrustedPepperPlugins.
+// Our environment variable should be registered in Tizen3.0 Multi-user
+// Platform Metadata. See:
+// https://wiki.tizen.org/wiki/Multi-user_Platform_Metadata
+const FilePath::CharType* kPepperPluginsPaths[] = {
+ // "/opt/usr/apps/pepper" is mount point for squash-fs archive contating
+ // Pepper Plugins providing implementation for TV specific WebAPIs.
+ // This archive is bundled together with Tizen TV image. Additionally
+ // this archive can be updated without full platform update.
+ // Updates are downloaded from Samsung servers.
+ FILE_PATH_LITERAL("/opt/usr/apps/pepper"),
+ FILE_PATH_LITERAL("/usr/lib/pepper")};
+
+const FilePath::CharType kPepperPluginManifestExtension[] =
+ FILE_PATH_LITERAL(".pmf");
+const FilePath::CharType kPepperPluginExtension[] = FILE_PATH_LITERAL(".so");
+const char kPepperManifestNameKey[] = "name";
+const char kPepperManifestProgramKey[] = "program";
+const char kPepperManifestUrlKey[] = "url";
+const char kPepperManifestVersionKey[] = "version";
+const char kPepperManifestDescriptionKey[] = "description";
+const char kPepperManifestTypeKey[] = "type";
+const char kPepperManifestTypePepper[] = "pepper";
+const char kPepperManifestMimesKey[] = "mimes";
+const char kPepperManifestMimesTypeKey[] = "type";
+const char kPepperManifestMimesDescriptionKey[] = "description";
+const char kPepperManifestMimesExtensionsKey[] = "extensions";
+
+using Hash = std::hash<FilePath>;
+using FilesContainer = std::unordered_set<FilePath, Hash>;
+
+bool GetStringValue(const base::DictionaryValue* dict,
+ const std::string& key,
+ std::string* out_value) {
+ const std::string* val = dict->FindStringPath(key);
+ if (nullptr != val && !val->empty()) {
+ *out_value = *val;
+ return true;
+ }
+
+ return false;
+}
+
+bool GetStringValue(const base::ListValue* list,
+ size_t i,
+ std::string* out_value) {
+ std::string val = list->GetList().operator[](i).GetString();
+ if (!val.empty()) {
+ *out_value = val;
+ return true;
+ }
+
+ return false;
+}
+
+bool GetListValue(const base::DictionaryValue* dict,
+ const std::string& key,
+ const base::ListValue** out_value) {
+ const base::ListValue* val = static_cast<const base::ListValue*>(dict->FindListKey(key));
+ if (val) {
+ *out_value = val;
+ return true;
+ }
+
+ return false;
+}
+
+bool GetDictionaryValue(const base::DictionaryValue* dict,
+ const std::string& key,
+ const base::DictionaryValue** out_value) {
+ const base::DictionaryValue* val = static_cast<const base::DictionaryValue*>(dict->FindDictKey(key));
+ if (val) {
+ *out_value = val;
+ return true;
+ }
+
+ return false;
+}
+
+bool GetDictionaryValue(const base::ListValue* list,
+ size_t i,
+ const base::DictionaryValue** out_value) {
+ const base::Value* val;
+ val = const_cast<base::Value*>(&(list->GetList().operator[](i)));
+
+ if(val && val->is_dict()) {
+ *out_value = static_cast<const base::DictionaryValue*>(val);
+ return true;
+ }
+ return false;
+}
+
+void GetMimeTypeExtensions(const base::DictionaryValue* dict,
+ std::vector<std::string>* out_exensions) {
+ const base::ListValue* list;
+ std::string val;
+ if (GetListValue(dict, kPepperManifestMimesExtensionsKey, &list)) {
+ size_t size = list->GetList().size();
+ for (size_t i = 0; i < size; ++i)
+ if (GetStringValue(list, i, &val))
+ out_exensions->push_back(val);
+ } else if (GetStringValue(dict, kPepperManifestMimesExtensionsKey, &val)) {
+ out_exensions->push_back(val);
+ }
+}
+
+bool GetWebPluginMimeType(const FilePath& pmf,
+ const base::ListValue* mimes,
+ size_t i,
+ WebPluginMimeType* plugin_mime) {
+ std::string type;
+ std::string description;
+ std::vector<std::string> extensions;
+
+ const base::DictionaryValue* dict = nullptr;
+ if (GetDictionaryValue(mimes, i, &dict)) {
+ // "type" : (mandatory)
+ if (!GetStringValue(dict, kPepperManifestMimesTypeKey, &type)) {
+ PARSING_ERROR(pmf) << "MIME type attribute not found";
+ return false;
+ }
+
+ GetStringValue(dict, kPepperManifestMimesDescriptionKey, &description);
+ GetMimeTypeExtensions(dict, &extensions);
+ } else { // The MIME list item is not a dictionary.
+ // We allow the MIME to be just a string type,
+ // without the description and extensions.
+ if (GetStringValue(mimes, i, &type)) {
+ PARSING_ERROR(pmf) << "The MIME has no type entry";
+ return false;
+ }
+ }
+
+ *plugin_mime = WebPluginMimeType(type, "", description);
+ plugin_mime->file_extensions = extensions;
+ return true;
+}
+
+bool GetPuginMimeTypes(const FilePath& pmf,
+ const base::ListValue* mimes_list,
+ std::vector<WebPluginMimeType>* mime_types) {
+ if (mimes_list->type() != base::Value::Type::LIST) {
+ PARSING_ERROR(pmf) << "The mimes must be a list";
+ return false;
+ }
+
+ size_t size = mimes_list->GetList().size();
+ for (size_t i = 0; i < size; ++i) {
+ WebPluginMimeType mime_type;
+ if (GetWebPluginMimeType(pmf, mimes_list, i, &mime_type))
+ mime_types->push_back(mime_type);
+ }
+
+ return true;
+}
+
+bool ReadPluginMimeTypes(const FilePath& pmf,
+ const base::DictionaryValue* dict,
+ ContentPluginInfo* info) {
+ // Get the MIME types.
+ const base::ListValue* mimes_list = nullptr;
+ if (!GetListValue(dict, kPepperManifestMimesKey, &mimes_list)) {
+ PARSING_ERROR(pmf) << "Can't read the MIME types list";
+ return false;
+ }
+
+ std::vector<WebPluginMimeType> mime_types;
+ if (!GetPuginMimeTypes(pmf, mimes_list, &mime_types)) {
+ PARSING_ERROR(pmf) << "Can't parse MIME types";
+ return false;
+ }
+
+ if (mime_types.empty()) {
+ PARSING_ERROR(pmf) << " no mime types defined for the plugin";
+ return false;
+ }
+
+ info->mime_types = mime_types;
+ return true;
+}
+
+bool ReadPluginPath(const FilePath& pmf,
+ const base::DictionaryValue* dict,
+ ContentPluginInfo* info) {
+ // Path to the plugin. The url attribute has higher priority
+ // than the manifest name.
+ const base::DictionaryValue* program_dict;
+ if (!GetDictionaryValue(dict, kPepperManifestProgramKey, &program_dict)) {
+ auto key = dict->FindKey(kPepperManifestProgramKey);
+ bool has_key = (key != nullptr ? true:false);
+
+ if (has_key) {
+ PARSING_ERROR(pmf) << "invalid \"program\" key present:"
+ << " not a dictionary";
+ return false;
+ }
+
+ // No program key present.
+ // Path to manifest is: /pepper/plugins_dir/my_plugin.pmf
+ // Path to plugin will be: /pepper/plugins_dir/my_plugin.so
+ info->path = pmf.RemoveExtension().AddExtension(kPepperPluginExtension);
+ return true;
+ }
+
+ std::string val;
+ if (GetStringValue(program_dict, kPepperManifestUrlKey, &val)) {
+ FilePath plugin_path(val);
+ if (plugin_path.IsAbsolute())
+ info->path = plugin_path;
+ else
+ info->path = pmf.DirName().Append(val);
+ } else {
+ PARSING_ERROR(pmf) << "\"program\" key present but it does not contain"
+ " \"url\" entry";
+ return false;
+ }
+ return true;
+}
+
+bool ValidatePluginType(const FilePath& pmf,
+ const base::DictionaryValue* dict) {
+ std::string val;
+ if (!GetStringValue(dict, kPepperManifestTypeKey, &val)) {
+ PARSING_ERROR(pmf) << "No type attribute in the PMF file";
+ return false;
+ }
+
+ if (val != kPepperManifestTypePepper) {
+ PARSING_ERROR(pmf) << "Unknown plugin type: " << val;
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidatePepperPluginInfo(const FilePath& pmf,
+ const ContentPluginInfo& info) {
+ if (!PathExists(info.path)) {
+ PARSING_ERROR(pmf) << " invalid plugin path: "
+ << info.path.LossyDisplayName();
+ return false;
+ }
+
+ return true;
+}
+
+} // namespace
+
+TrustedPepperPluginInfoCache* TrustedPepperPluginInfoCache::GetInstance() {
+ return base::Singleton<TrustedPepperPluginInfoCache>::get();
+}
+
+TrustedPepperPluginInfoCache::TrustedPepperPluginInfoCache(
+ const std::vector<base::FilePath>& paths) {
+
+ for (const auto& path : paths)
+ {
+ AddPluginsFromDirectory(path);
+ }
+
+}
+
+TrustedPepperPluginInfoCache::~TrustedPepperPluginInfoCache() {}
+
+void TrustedPepperPluginInfoCache::GetPlugins(
+ std::vector<ContentPluginInfo>* plugins) const {
+ if (plugins->empty()) {
+ plugins->reserve(plugins_.size());
+ std::for_each(plugins_.cbegin(), plugins_.cend(),
+ [plugins](const PluginEntry& element) {
+ plugins->push_back(*(element.second));
+ });
+ } else {
+ FilesContainer plugins_not_to_add;
+ for (const auto& plugin : *plugins)
+ plugins_not_to_add.insert(plugin.path);
+
+ for (const auto& plugin : plugins_) {
+ if (!plugins_not_to_add.count(plugin.second->path))
+ plugins->push_back(*(plugin.second));
+ }
+ }
+}
+
+bool TrustedPepperPluginInfoCache::FindPlugin(
+ std::string mime_type,
+ const GURL& url,
+ ContentPluginInfo* found_plugin) const {
+ if (mime_type.empty()) {
+ // Try to guess the MIME type based on the extension.
+ auto filename = url.ExtractFileName();
+ auto extension_pos = filename.rfind('.');
+ if (extension_pos != std::string::npos) {
+ auto extension = filename.substr(extension_pos + 1);
+ net::GetWellKnownMimeTypeFromExtension(extension, &mime_type);
+ }
+
+ if (mime_type.empty())
+ return false;
+ }
+
+ auto it = mime_map_.find(mime_type);
+ if (it != mime_map_.cend()) {
+ *found_plugin = *(it->second);
+ return true;
+ }
+
+ return false;
+}
+
+TrustedPepperPluginInfoCache::TrustedPepperPluginInfoCache() {
+ for (const auto& path : kPepperPluginsPaths)
+ AddPluginsFromDirectory(base::FilePath(path));
+
+ base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+ if (command_line->HasSwitch(switches::kTrustedPepperPluginsSearchPaths)) {
+ const std::string value = command_line->GetSwitchValueASCII(
+ switches::kTrustedPepperPluginsSearchPaths);
+ std::vector<std::string> paths = base::SplitString(
+ value, ";", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
+ for (const auto& path : paths)
+ AddPluginsFromDirectory(base::FilePath(path));
+ }
+}
+
+void TrustedPepperPluginInfoCache::AddPluginsFromDirectory(
+ const FilePath& dir) {
+ if (!base::PathExists(dir))
+ return;
+
+ base::FileEnumerator it(dir, true, base::FileEnumerator::FILES);
+ for (FilePath name = it.Next(); !name.empty(); name = it.Next()) {
+ if (name.Extension() != kPepperPluginManifestExtension)
+ continue;
+
+ std::unique_ptr<ContentPluginInfo> info{new ContentPluginInfo};
+ if (!FillPepperPluginInfoFromManifest(name, info.get()))
+ continue;
+
+ for (const auto& plugin_mime : info->mime_types) {
+ if (mime_map_.count(plugin_mime.mime_type)) {
+ LOG(WARNING)
+ << "mime_type: " << plugin_mime.mime_type
+ << " is already handled by plugin: "
+ << mime_map_[plugin_mime.mime_type]->path.LossyDisplayName();
+ continue;
+ }
+
+ mime_map_[plugin_mime.mime_type] = info.get();
+ }
+
+ plugins_.emplace_back(name, std::move(info));
+ }
+}
+
+bool ParsePepperPluginManifest(const FilePath& pmf,
+ const std::string& contents,
+ ContentPluginInfo* out_info) {
+ auto root = base::JSONReader::ReadAndReturnValueWithError(contents);
+ if (!root.has_value()) {
+ PARSING_ERROR(pmf) << "Ill formatted PMF file: not a proper JSON.";
+ return false;
+ }
+
+ if (root.value().type() != base::Value::Type::DICTIONARY) {
+ PARSING_ERROR(pmf) << "Ill formatted PMF file: "
+ << "the root node is not an object.";
+ return false;
+ }
+
+ base::DictionaryValue* dict = 0;
+ if (!root.value().GetAsDictionary(&dict) || !dict) {
+ PARSING_ERROR(pmf) << "Can't to get the root node as an object.";
+ return false;
+ }
+
+ if (!ValidatePluginType(pmf, dict))
+ return false;
+
+ // Let's set the default values for the info in case they are not present
+ // in the manifest.
+ ContentPluginInfo info;
+ info.is_out_of_process = true;
+ info.is_internal = false;
+ // Trusted Pepper Plugins have all possible permissions
+ info.permissions = ppapi::Permission::PERMISSION_ALL_BITS;
+
+ GetStringValue(dict, kPepperManifestNameKey, &(info.name));
+ GetStringValue(dict, kPepperManifestDescriptionKey, &(info.description));
+ GetStringValue(dict, kPepperManifestVersionKey, &(info.version));
+
+ if (!ReadPluginMimeTypes(pmf, dict, &info))
+ return false;
+
+ if (!ReadPluginPath(pmf, dict, &info))
+ return false;
+
+ *out_info = info;
+ return true;
+}
+
+bool FillPepperPluginInfoFromManifest(const FilePath& pmf,
+ ContentPluginInfo* out_info) {
+ std::string contents;
+ if (!base::ReadFileToString(pmf, &contents)) {
+ PARSING_ERROR(pmf) << "Could not read manifest file ";
+ return false;
+ }
+
+ ContentPluginInfo info;
+ if (!ParsePepperPluginManifest(pmf, contents, &info))
+ return false;
+
+ if (!ValidatePepperPluginInfo(pmf, info))
+ return false;
+
+ *out_info = info;
+ return true;
+}
+
+} // namespace pepper
--- /dev/null
+// Copyright 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 EWK_EFL_INTEGRATION_COMMON_TRUSTED_PEPPER_PLUGIN_INFO_CACHE_H_
+#define EWK_EFL_INTEGRATION_COMMON_TRUSTED_PEPPER_PLUGIN_INFO_CACHE_H_
+
+#include <memory>
+#include <string>
+#include <unordered_map>
+#include <utility>
+#include <vector>
+
+//#include "base/containers/hash_tables.h"
+#include "base/files/file_path.h"
+#include "content/public/common/content_plugin_info.h"
+#include "url/gurl.h"
+
+namespace base {
+template <typename T>
+struct DefaultSingletonTraits;
+}
+
+namespace pepper {
+
+// Class holding (caching) discovered plugins in given directories.
+// Plugin needs to have manifest file pmf which descibes it.
+//
+// See |ParsePepperPluginManifest| for Plugin Manifest File (pmf) specification.
+class TrustedPepperPluginInfoCache {
+ public:
+ // Gets singleton of representing cache built for predefined directories.
+ static TrustedPepperPluginInfoCache* GetInstance();
+
+ // Special constructor only used during unit testing:
+ explicit TrustedPepperPluginInfoCache(
+ const std::vector<base::FilePath>& paths);
+
+ ~TrustedPepperPluginInfoCache();
+
+ // Adds all the plugins present in the cache to the |plugins| vector.
+ //
+ // If the plugins vector is empty then adds all plugins present currently
+ // in the cache to the vector.
+ //
+ // If the plugins vector is not empty then adds only those plugins that
+ // are present in the cache, but are not present in the vector.
+ //
+ // |plugins| is *non-null* pointer to vector which will be filled
+ void GetPlugins(std::vector<content::ContentPluginInfo>* plugins) const;
+
+ // Searches cached pepper plugins whether there is plugin which supports
+ // given |mime_type| or |url|. If |mime_type| is empty, method tries to find
+ // plugin basing on |url| extension.
+ //
+ // If plugin was found function returns true and sets |found_plugin|
+ // information for plugin found. Otherwise function returns false and
+ // doesn't touch |found_plugin| argument.
+ //
+ // |found_plugin| must be *non-null* pointer
+ bool FindPlugin(std::string mime_type,
+ const GURL& url,
+ content::ContentPluginInfo* found_plugin) const;
+
+ private:
+ friend struct base::DefaultSingletonTraits<TrustedPepperPluginInfoCache>;
+
+ // Builds plugin cache based on predefined directories.
+ TrustedPepperPluginInfoCache();
+
+ // Discover plugins in given directory by scanning it recursively
+ // and adds their descriptions to the cache.
+ void AddPluginsFromDirectory(const base::FilePath& dir);
+
+ using PluginEntry =
+ std::pair<base::FilePath, std::unique_ptr<content::ContentPluginInfo>>;
+
+ // cached plugin infos
+ std::vector<PluginEntry> plugins_;
+
+ // ContentPluginInfo is non owning pointer to plugins element
+ std::unordered_map<std::string, content::ContentPluginInfo*> mime_map_;
+};
+
+// Exposed in header for UnitTesting:
+//
+// Parses Plugin Manifest File (PMF) provided as string |contents|
+// and fills properly |out_info|.
+//
+// |pmf| is path from which PMF was loaded from and its used to fill
+// |ContentPluginInfo::path| field if such information is not present in the PMF.
+//
+// This function does not performs any operation on filesystem.
+//
+// Sample PMFs:
+//
+// libsample_plugin.pmf:
+// {
+// "type" : "pepper",
+// "name" : "Sample Trusted Plugin",
+// "version" : "1.0",
+// "description" : "Example Pepper Trusted Plugin",
+// "mimes" : [
+// {
+// "type" : "application/x-ppapi-example",
+// "description" : "Example Ppapi",
+// "extensions" : [ ".ext1", ".ext2" ]
+// },
+// {
+// "type" : "application/x-ppapi-example2"
+// }
+// ]
+// }
+//
+// test_plugin.pmf:
+// {
+// "type" : "pepper",
+// "name" : "Test Trusted Plugin",
+// "version" : "1.2",
+// "description" : "Test Trusted Pepper Plugin",
+// "mimes": [ { type: "application/x-ppapi-test" } ],
+// "program": { "url": "libtest_plugin.so" }
+// }
+//
+// PMF is a JSON wich have following fields:
+// - type (mandatory)
+// type of the plugin, must be set to "pepper'
+// - name (optional)
+// plugin name, value for |ContentPluginInfo::name|
+// - description (optional)
+// plugin description, value for |ContentPluginInfo::description|
+// - version (optional)
+// plugin version, value for |ContentPluginInfo::version|
+// - mimes (mandatory)
+// provides list of mime types, value for |ContentPluginInfo::mime_types|
+// - mimes/type (mandatory)
+// defines mime_type itself, value for |WebPluginMimeType::mime_type|
+// - mimes/description (optional)
+// defines mime_type description, value for |WebPluginMimeType::description|
+// - mimes/extensions (optional)
+// defines list of the file extensions for this mime type,
+// value for |WebPluginMimeType::file_extensions|
+// - program (optional)
+// provides path for pepper plugin shared library, value for
+// |ContentPluginInfo::path|. If value is not present in the manifest,
+// then path is deduced from |pmf|, by replacing .pmf extension form the
+// manifest to platform dependent library extension (.so on POSIX systems).
+// - program/url (mandatory if program argument is present)
+// provides relative or absolute path to pepper plugin shared library.
+//
+// Following fields are not present in PMF and are set to given values:
+// - ContentPluginInfo::is_internal is set to |false|
+// - ContentPluginInfo::is_out_of_process is set to |true|
+//
+// Function returns true if manifest is parsed and follows specification
+// given above.
+bool ParsePepperPluginManifest(const base::FilePath& pmf,
+ const std::string& contents,
+ content::ContentPluginInfo* out_info);
+
+// Exposed in header for UnitTesting:
+//
+// Reads plugin manifest from |pmf| path, parses it and validates
+// whether plugin path (|ContentPluginInfo::path|) is valid (exsists).
+//
+// See |ParsePepperPluginManifest| for Plugin Manifest File (pmf) specification.
+bool FillPepperPluginInfoFromManifest(const base::FilePath& pmf,
+ content::ContentPluginInfo* out_info);
+
+} // namespace pepper
+
+#endif // EWK_EFL_INTEGRATION_COMMON_TRUSTED_PEPPER_PLUGIN_INFO_CACHE_H_
--- /dev/null
+// Copyright 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.
+
+#include "common/trusted_pepper_plugin_info_cache.h"
+
+#include <algorithm>
+#include <iterator>
+#include <memory>
+#include <sstream>
+#include <string>
+#include <tuple>
+#include <vector>
+
+#include "base/files/file_util.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/logging.h"
+#include "base/strings/string_util.h"
+#include "ppapi/shared_impl/ppapi_permissions.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "content/public/common/content_plugin_info.h"
+
+using base::FilePath;
+using content::ContentPluginInfo;
+using content::WebPluginMimeType;
+
+namespace pepper {
+
+namespace {
+
+enum PluginFilesWriteOptions { PMF_ONLY, PMF_AND_LIBRARY };
+
+const std::vector<std::string> kNonExistingMimes = {
+ "application/x-invalid-mime", "invalid/invalid",
+ "test/x-test-invalid-mime"};
+
+FilePath AddLibrarySuffix(const FilePath& path) {
+ return path.AddExtension(FILE_PATH_LITERAL(".so"));
+}
+
+bool EqualPluginMimeType(const WebPluginMimeType& lhs,
+ const WebPluginMimeType& rhs);
+
+template <class T>
+bool EqualVectors(const std::vector<T>& lhs, const std::vector<T>& rhs) {
+ if (lhs.size() != rhs.size())
+ return false;
+
+ return std::equal(lhs.cbegin(), lhs.cend(), rhs.cbegin());
+}
+
+bool EqualVectors(const std::vector<WebPluginMimeType>& lhs,
+ const std::vector<WebPluginMimeType>& rhs) {
+ if (lhs.size() != rhs.size())
+ return false;
+
+ return std::equal(lhs.cbegin(), lhs.cend(), rhs.cbegin(),
+ EqualPluginMimeType);
+}
+
+bool EqualPluginMimeType(const WebPluginMimeType& lhs,
+ const WebPluginMimeType& rhs) {
+ return lhs.mime_type == rhs.mime_type &&
+ EqualVectors(lhs.file_extensions, rhs.file_extensions) &&
+ lhs.description == rhs.description &&
+ EqualVectors(lhs.additional_param_names, rhs.additional_param_names) &&
+ EqualVectors(lhs.additional_param_values, rhs.additional_param_values);
+}
+
+bool EqualPepperPluginInfo(const ContentPluginInfo& lhs,
+ const ContentPluginInfo& rhs) {
+ return lhs.is_internal == rhs.is_internal &&
+ lhs.is_out_of_process == rhs.is_out_of_process &&
+ lhs.path == rhs.path && lhs.name == rhs.name &&
+ lhs.description == rhs.description && lhs.version == rhs.version &&
+ EqualVectors(lhs.mime_types, rhs.mime_types) &&
+ lhs.permissions == rhs.permissions;
+}
+
+ContentPluginInfo GetTestPlugin1() {
+ ContentPluginInfo plugin;
+
+ plugin.is_internal = false;
+ plugin.is_out_of_process = true;
+ plugin.name = "plugin1";
+ plugin.description = "Test Plugin1";
+ plugin.version = "1.0";
+ plugin.mime_types.emplace_back("plugin1/mime1", ".ext1", "mime1");
+ plugin.mime_types.emplace_back("plugin1/mime2", ".ext2", "mime2");
+ plugin.permissions = ppapi::Permission::PERMISSION_ALL_BITS;
+
+ return plugin;
+}
+
+ContentPluginInfo GetTestPlugin2() {
+ WebPluginMimeType plugin_mime;
+ plugin_mime.mime_type = "plugin2/mime";
+
+ ContentPluginInfo plugin;
+ plugin.is_internal = false;
+ plugin.is_out_of_process = true;
+ plugin.name = "plugin2";
+ plugin.description = "Test Plugin2";
+ plugin.version = "1.1";
+ plugin.mime_types.push_back(plugin_mime);
+ plugin.permissions = ppapi::Permission::PERMISSION_ALL_BITS;
+
+ return plugin;
+}
+
+ContentPluginInfo GetTestPlugin3() {
+ ContentPluginInfo plugin;
+
+ plugin.is_internal = false;
+ plugin.is_out_of_process = true;
+ plugin.name = "plugin3";
+ plugin.description = "Test Plugin3";
+ plugin.version = "1.0";
+ plugin.mime_types.emplace_back("plugin3/mime1", ".e1", "mime1");
+ plugin.mime_types.emplace_back("plugin3/mime2", ".e2", "mime2");
+ plugin.permissions = ppapi::Permission::PERMISSION_ALL_BITS;
+
+ return plugin;
+}
+
+ContentPluginInfo GetTestPlugin4() {
+ ContentPluginInfo plugin;
+
+ plugin.is_internal = false;
+ plugin.is_out_of_process = true;
+ plugin.name = "plugin4";
+ plugin.description = "Test Plugin4";
+ plugin.version = "4.0";
+ plugin.mime_types.emplace_back("plugin4/mime1", ".f1", "mime1");
+ plugin.mime_types.emplace_back("plugin4/mime2", ".f2", "mime2");
+ plugin.permissions = ppapi::Permission::PERMISSION_ALL_BITS;
+
+ return plugin;
+}
+
+ContentPluginInfo GetTestPlugin5() {
+ ContentPluginInfo plugin;
+
+ plugin.is_internal = false;
+ plugin.is_out_of_process = true;
+ plugin.name = "plugin5";
+ plugin.description = "Test Plugin5";
+ plugin.version = "1.10";
+ plugin.mime_types.emplace_back("plugin5/mime1", ".p1", "mime1");
+ plugin.mime_types.emplace_back("plugin5/mime2", ".p2", "mime2");
+ plugin.permissions = ppapi::Permission::PERMISSION_ALL_BITS;
+
+ return plugin;
+}
+
+ContentPluginInfo GetTestPlugin6() {
+ ContentPluginInfo plugin;
+
+ plugin.is_internal = false;
+ plugin.is_out_of_process = true;
+ plugin.name = "plugin6";
+ plugin.description = "Test Plugin6";
+ plugin.version = "1.10";
+ plugin.mime_types.emplace_back("application/x-shockwave-flash", ".swf",
+ "mime1");
+ plugin.permissions = ppapi::Permission::PERMISSION_ALL_BITS;
+
+ return plugin;
+}
+
+std::string PluginMimesToJSON(const ContentPluginInfo& plugin) {
+ std::ostringstream oss;
+
+ for (size_t i = 0; i < plugin.mime_types.size(); ++i) {
+ if (i > 0)
+ oss << ",\n";
+
+ const auto& mime = plugin.mime_types[i];
+ oss << " {"
+ << " \"type\" : \"" << mime.mime_type << "\"";
+
+ if (!mime.description.empty()) {
+ oss << ",\n"
+ << " \"description\" : \"" << mime.description << "\"";
+ }
+
+ if (!mime.file_extensions.empty()) {
+ oss << ",\n"
+ << " \"extensions\" : [ ";
+
+ for (size_t j = 0; j < mime.file_extensions.size(); ++j) {
+ if (j > 0)
+ oss << ", ";
+
+ oss << "\"" << mime.file_extensions[j] << "\"";
+ }
+
+ oss << " ]";
+ }
+
+ oss << " }";
+ }
+
+ return oss.str();
+}
+
+std::string GeneratePMF(const ContentPluginInfo& plugin) {
+ std::ostringstream pmf_stream;
+ pmf_stream << "{"
+ << " \"type\": \"pepper\",\n"
+ << " \"name\": \"" << plugin.name << "\",\n"
+ << " \"description\": \"" << plugin.description << "\",\n"
+ << " \"version\": \"" << plugin.version << "\",\n"
+ << " \"mimes\": [\n"
+ << PluginMimesToJSON(plugin) << "\n"
+ << " ],\n"
+ << " \"program\": { \n"
+ << " \"url\": \"" << plugin.path.AsUTF8Unsafe() << "\"\n"
+ << " }\n"
+ << "}";
+
+ return pmf_stream.str();
+}
+
+// uses |ContentPluginInfo.name| as file paths.
+void WritePluginFiles(const FilePath& plugin_dir,
+ PluginFilesWriteOptions files_to_write,
+ ContentPluginInfo* plugin) {
+ FilePath base_path = plugin_dir.AppendASCII(plugin->name);
+ plugin->path = AddLibrarySuffix(base_path);
+
+ std::string pmf = GeneratePMF(*plugin);
+ FilePath pmf_path = base_path.AddExtension(FILE_PATH_LITERAL(".pmf"));
+
+ ContentPluginInfo info;
+ ASSERT_TRUE(ParsePepperPluginManifest(pmf_path, pmf, &info));
+ ASSERT_TRUE(EqualPepperPluginInfo(*plugin, info));
+
+ int data_written = base::WriteFile(pmf_path, pmf.c_str(), pmf.size());
+ ASSERT_GE(data_written, 0);
+ ASSERT_EQ(pmf.size(), static_cast<size_t>(data_written));
+
+ if (files_to_write == PMF_AND_LIBRARY) {
+ std::string plugin_lib = plugin->name;
+ int plugin_data_written =
+ base::WriteFile(plugin->path, plugin_lib.c_str(), plugin_lib.size());
+ ASSERT_GE(plugin_data_written, 0);
+ ASSERT_EQ(plugin_lib.size(), static_cast<size_t>(plugin_data_written));
+ }
+
+ bool fill_plugin_res = FillPepperPluginInfoFromManifest(pmf_path, &info);
+ if (files_to_write == PMF_AND_LIBRARY) {
+ ASSERT_TRUE(fill_plugin_res);
+ ASSERT_TRUE(EqualPepperPluginInfo(*plugin, info));
+ } else {
+ ASSERT_FALSE(fill_plugin_res);
+ }
+}
+
+class TrustedPepperPluginInfoCacheTest : public testing::Test {
+ public:
+ TrustedPepperPluginInfoCacheTest() {}
+
+ void SetUp() override {
+ InitializePluginsDir();
+ InitializeEmptyDir();
+ cache_.reset(new TrustedPepperPluginInfoCache(dir_paths_));
+ ASSERT_NE(nullptr, cache_.get());
+ }
+
+ protected:
+ // Valid plugins added to temp dir, should be present in cache
+ std::vector<ContentPluginInfo> valid_plugins_;
+
+ // Plugins with invalid manifests which shouldn't be added
+ // to the cache
+ std::vector<ContentPluginInfo> invalid_plugins_;
+
+ std::unique_ptr<TrustedPepperPluginInfoCache> cache_;
+
+ private:
+ void CreatePluginInDir(const FilePath& dir,
+ PluginFilesWriteOptions valid,
+ ContentPluginInfo plugin) {
+ WritePluginFiles(dir, valid, &plugin);
+ if (valid == PMF_AND_LIBRARY)
+ valid_plugins_.push_back(plugin);
+ else
+ invalid_plugins_.push_back(plugin);
+ }
+
+ void InitializePluginsDir() {
+ ASSERT_TRUE(plugins_dir_.CreateUniqueTempDir());
+ dir_paths_.push_back(plugins_dir_.GetPath());
+
+ FilePath dir1;
+ ASSERT_TRUE(
+ CreateTemporaryDirInDir(plugins_dir_.GetPath(), "plugins1_", &dir1));
+
+ CreatePluginInDir(dir1, PMF_AND_LIBRARY, GetTestPlugin1());
+ CreatePluginInDir(dir1, PMF_AND_LIBRARY, GetTestPlugin2());
+
+ FilePath dir2;
+ ASSERT_TRUE(
+ CreateTemporaryDirInDir(plugins_dir_.GetPath(), "plugins2_", &dir2));
+
+ CreatePluginInDir(dir2, PMF_AND_LIBRARY, GetTestPlugin3());
+ CreatePluginInDir(dir2, PMF_ONLY, GetTestPlugin4());
+
+ FilePath dir3;
+ ASSERT_TRUE(
+ CreateTemporaryDirInDir(plugins_dir_.GetPath(), "plugins3_", &dir3));
+ CreatePluginInDir(dir3, PMF_ONLY, GetTestPlugin5());
+ CreatePluginInDir(dir3, PMF_AND_LIBRARY, GetTestPlugin6());
+ }
+
+ void InitializeEmptyDir() {
+ ASSERT_TRUE(empty_dir_.CreateUniqueTempDir());
+ dir_paths_.push_back(empty_dir_.GetPath());
+ }
+
+ base::ScopedTempDir plugins_dir_;
+ base::ScopedTempDir empty_dir_;
+ std::vector<base::FilePath> dir_paths_;
+};
+
+TEST(ParsePepperPluginManifestTest, MinimalManifest) {
+ std::string pmfs[] = {
+ "{"
+ " \"type\": \"pepper\","
+ " \"mimes\": ["
+ " { \"type\": \"application/x-ppapi-minimal-manifest\" }"
+ " ]"
+ "}",
+
+ "{"
+ " \"not-specified-key\": \"some value\","
+ " \"type\": \"pepper\","
+ " \"mimes\": ["
+ " { \"type\": \"application/x-ppapi-minimal-manifest\" }"
+ " ],"
+ " \"excessive-key\": \"excessive-value\""
+ "}"};
+
+ for (const auto& pmf : pmfs) {
+ LOG(INFO) << "Parsing pmf: " << pmf;
+ FilePath path(FILE_PATH_LITERAL("minimal_test.pmf"));
+
+ ContentPluginInfo info;
+ ASSERT_TRUE(ParsePepperPluginManifest(path, pmf, &info));
+
+ EXPECT_FALSE(info.is_internal);
+ EXPECT_TRUE(info.is_out_of_process);
+ EXPECT_EQ(info.permissions, ppapi::Permission::PERMISSION_ALL_BITS);
+ EXPECT_TRUE(info.name.empty());
+ EXPECT_TRUE(info.description.empty());
+ EXPECT_TRUE(info.version.empty());
+
+ ASSERT_EQ(1u, info.mime_types.size());
+ EXPECT_EQ("application/x-ppapi-minimal-manifest",
+ info.mime_types[0].mime_type);
+ EXPECT_TRUE(info.mime_types[0].file_extensions.empty());
+
+ FilePath expected_path(AddLibrarySuffix(path.RemoveExtension()));
+ EXPECT_EQ(expected_path, info.path);
+ }
+}
+
+TEST(ParsePepperPluginManifestTest, EmptyManifest) {
+ std::string pmfs[] = {"", "{}"};
+ FilePath path(FILE_PATH_LITERAL("empty_test.pmf"));
+
+ for (const auto& pmf : pmfs) {
+ ContentPluginInfo info;
+ EXPECT_FALSE(ParsePepperPluginManifest(path, pmf, &info));
+ }
+}
+
+TEST(ParsePepperPluginManifestTest, BadPluginType) {
+ std::string pmfs[] = {
+ // missing type
+ "{"
+ " \"mimes\": [ { \"type\": \"application/x-ppapi-bad-type\" } ]"
+ "}",
+
+ "{"
+ " \"type\": \"bad-type\","
+ " \"mimes\": [ { \"type\": \"application/x-ppapi-bad-type\" } ]"
+ "}",
+
+ // space before pepper
+ "{"
+ " \"type\": \" pepper\","
+ " \"mimes\": [ { \"type\": \"application/x-ppapi-bad-type\" } ]"
+ "}"};
+ FilePath path(FILE_PATH_LITERAL("bad_type_test.pmf"));
+
+ for (const auto& pmf : pmfs) {
+ LOG(INFO) << "Parsing pmf: " << pmf;
+
+ ContentPluginInfo info;
+ EXPECT_FALSE(ParsePepperPluginManifest(path, pmf, &info));
+ }
+}
+
+TEST(ParsePepperPluginManifestTest, BadJSON) {
+ std::string pmfs[] = {
+ // no coma
+ "{"
+ " \"type\": \"pepper\"" // no coma
+ " \"mimes\": [ { \"type\": \"application/x-ppapi-bad-json\" } ]"
+ "}",
+
+ // Comma after last entry
+ "{"
+ " \"type\": \"pepper\","
+ " \"mimes\": [ { \"type\": \"application/x-ppapi-bad-json\" } ],"
+ "}",
+
+ // no double quotes (")
+ "{"
+ " type: pepper,"
+ " mimes: [ { \"type\": \"application/x-ppapi-bad-json\" } ],"
+ "}",
+
+ // root object is not a dictionary
+ "["
+ " { \"type\": \"pepper\" },"
+ " { \"mimes\": ["
+ " { \"type\": \"application/x-ppapi-minimal-manifest\" }"
+ " ] }"
+ "]",
+
+ // root object is not a dictionary
+ " \"type\": \"pepper\" "};
+ FilePath path(FILE_PATH_LITERAL("bad_type_test.pmf"));
+
+ for (const auto& pmf : pmfs) {
+ LOG(INFO) << "Parsing pmf: " << pmf;
+
+ ContentPluginInfo info;
+ EXPECT_FALSE(ParsePepperPluginManifest(path, pmf, &info));
+ }
+}
+
+TEST(ParsePepperPluginManifestTest, MultipleMimes) {
+ std::string pmf =
+ "{"
+ " \"type\" : \"pepper\","
+ " \"name\" : \"Sample Trusted Plugin\","
+ " \"version\" : \"1.0\","
+ " \"description\" : \"Example Pepper Trusted Plugin\","
+ " \"mimes\" : ["
+ " {"
+ " \"type\" : \"application/x-ppapi-example\","
+ " \"description\" : \"Example Ppapi\","
+ " \"extensions\" : [ \".ext1\", \".ext2\" ]"
+ " },"
+ " {"
+ " \"type\" : \"application/x-ppapi-example2\""
+ " }"
+ " ]"
+ " }";
+
+ ContentPluginInfo info;
+ FilePath path(FILE_PATH_LITERAL("libsample_plugin.pmf"));
+ ASSERT_TRUE(ParsePepperPluginManifest(path, pmf, &info));
+
+ EXPECT_FALSE(info.is_internal);
+ EXPECT_TRUE(info.is_out_of_process);
+ EXPECT_EQ(info.permissions, ppapi::Permission::PERMISSION_ALL_BITS);
+ EXPECT_EQ("Sample Trusted Plugin", info.name);
+ EXPECT_EQ("Example Pepper Trusted Plugin", info.description);
+ EXPECT_EQ("1.0", info.version);
+
+ ASSERT_EQ(2u, info.mime_types.size());
+ EXPECT_EQ("application/x-ppapi-example", info.mime_types[0].mime_type);
+ EXPECT_TRUE(
+ base::EqualsASCII(info.mime_types[0].description, "Example Ppapi"));
+ ASSERT_EQ(2u, info.mime_types[0].file_extensions.size());
+ EXPECT_EQ(".ext1", info.mime_types[0].file_extensions[0]);
+ EXPECT_EQ(".ext2", info.mime_types[0].file_extensions[1]);
+
+ EXPECT_EQ("application/x-ppapi-example2", info.mime_types[1].mime_type);
+ EXPECT_TRUE(info.mime_types[1].description.empty());
+ EXPECT_TRUE(info.mime_types[1].file_extensions.empty());
+
+ FilePath expected_path(AddLibrarySuffix(path.RemoveExtension()));
+ EXPECT_EQ(info.path, expected_path);
+}
+
+TEST(ParsePepperPluginManifestTest, EmptyMimes) {
+ std::string pmfs[] = {
+ // missing mimes key
+ "{"
+ " \"type\" : \"pepper\""
+ "}",
+
+ // no mimes at all
+ "{"
+ " \"type\" : \"pepper\","
+ " \"mimes\" : ["
+ " ]"
+ "}",
+
+ // missing type
+ "{"
+ " \"type\" : \"pepper\","
+ " \"mimes\" : ["
+ " {"
+ " \"description\" : \"Example Ppapi\","
+ " \"extensions\" : [ \".ext1\", \".ext2\" ]"
+ " }"
+ " ]"
+ "}",
+ };
+ FilePath path(FILE_PATH_LITERAL("libsample_plugin.pmf"));
+
+ for (const auto& pmf : pmfs) {
+ LOG(INFO) << "Parsing pmf: " << pmf;
+
+ ContentPluginInfo info;
+ EXPECT_FALSE(ParsePepperPluginManifest(path, pmf, &info));
+ }
+}
+
+TEST(ParsePepperPluginManifestTest, InvalidProgramUrlKey) {
+ std::string pmfs[] = {
+ // empty program
+ "{"
+ " \"type\" : \"pepper\","
+ " \"mimes\": [ { \"type\": \"application/x-ppapi-invalid-url\" } ],"
+ " \"program\": { }"
+ "}",
+
+ // valid path but not in url key
+ "{"
+ " \"type\" : \"pepper\","
+ " \"mimes\": [ { \"type\": \"application/x-ppapi-invalid-url\" } ],"
+ " \"program\": \"libtest_plugin.so\""
+ "}",
+
+ // no url key
+ "{"
+ " \"type\" : \"pepper\","
+ " \"mimes\": [ { \"type\": \"application/x-ppapi-invalid-url\" } ],"
+ " \"program\": { \"path\": \"libtest_plugin.so\" }" // not an url key
+ "}",
+
+ // empty url key
+ "{"
+ " \"type\" : \"pepper\","
+ " \"mimes\": [ { \"type\": \"application/x-ppapi-invalid-url\" } ],"
+ " \"program\": { \"url\": \"\" }"
+ "}"};
+
+ FilePath path(FILE_PATH_LITERAL("plugin_manifest.pmf"));
+ for (const auto& pmf : pmfs) {
+ LOG(INFO) << "Parsing pmf: " << pmf;
+
+ ContentPluginInfo info;
+ EXPECT_FALSE(ParsePepperPluginManifest(path, pmf, &info));
+ }
+}
+
+TEST(ParsePepperPluginManifestTest, ProgramUrlPaths) {
+ FilePath path(FILE_PATH_LITERAL("/my_plugin_dir/plugin_manifest.pmf"));
+
+ std::pair<std::string, FilePath::StringType> pmf_and_path_list[] = {
+ // Relative path
+ {"{"
+ " \"type\" : \"pepper\","
+ " \"name\" : \"Test Trusted Plugin\","
+ " \"version\" : \"1.2\","
+ " \"description\" : \"Test Trusted Pepper Plugin\","
+ " \"mimes\": [ { \"type\": \"application/x-ppapi-test\" } ],"
+ " \"program\": { \"url\": \"libtest_plugin.so\" }"
+ "}",
+ FILE_PATH_LITERAL("/my_plugin_dir/libtest_plugin.so")},
+
+ // Absolute path
+ {"{"
+ " \"type\" : \"pepper\","
+ " \"name\" : \"Test Trusted Plugin\","
+ " \"version\" : \"1.2\","
+ " \"description\" : \"Test Trusted Pepper Plugin\","
+ " \"mimes\": [ { \"type\": \"application/x-ppapi-test\" } ],"
+ " \"program\": { \"url\": \"/my_lib_dir/libtest_plugin.so\" }"
+ "}",
+ FILE_PATH_LITERAL("/my_lib_dir/libtest_plugin.so")},
+
+ // Deduced path
+ {"{"
+ " \"type\" : \"pepper\","
+ " \"name\" : \"Test Trusted Plugin\","
+ " \"version\" : \"1.2\","
+ " \"description\" : \"Test Trusted Pepper Plugin\","
+ " \"mimes\": [ { \"type\": \"application/x-ppapi-test\" } ]"
+ "}",
+ FILE_PATH_LITERAL("/my_plugin_dir/plugin_manifest.so")}};
+
+ for (const auto& entry : pmf_and_path_list) {
+ const auto& pmf = entry.first;
+ const auto& expected_path = entry.second;
+ LOG(INFO) << "Parsing pmf: " << pmf;
+
+ ContentPluginInfo info;
+ EXPECT_TRUE(ParsePepperPluginManifest(path, pmf, &info));
+
+ EXPECT_FALSE(info.is_internal);
+ EXPECT_TRUE(info.is_out_of_process);
+ EXPECT_EQ(info.permissions, ppapi::Permission::PERMISSION_ALL_BITS);
+ EXPECT_EQ("Test Trusted Plugin", info.name);
+ EXPECT_EQ("Test Trusted Pepper Plugin", info.description);
+ EXPECT_EQ("1.2", info.version);
+
+ EXPECT_EQ(1u, info.mime_types.size());
+ if (info.mime_types.size() == 1) {
+ EXPECT_EQ("application/x-ppapi-test", info.mime_types[0].mime_type);
+ EXPECT_TRUE(info.mime_types[0].description.empty());
+ EXPECT_TRUE(info.mime_types[0].file_extensions.empty());
+ }
+
+ EXPECT_EQ(FilePath(expected_path), info.path);
+ }
+}
+
+TEST(FillPepperPluginInfoFromManifestTest, InvalidManifest) {
+ std::string pmf =
+ // empty url key
+ "{"
+ " \"type\" : \"pepper\","
+ " \"mimes\": [ { \"type\": \"application/x-ppapi-invalid-url\" } ],"
+ " \"program\": { \"url\": \"\" }"
+ "}";
+
+ base::ScopedTempDir temp_dir;
+ ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
+
+ FilePath path;
+ ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir.GetPath(), &path));
+
+ int data_written = WriteFile(path, pmf.c_str(), pmf.size());
+ ASSERT_GE(data_written, 0);
+ ASSERT_EQ(pmf.size(), static_cast<size_t>(data_written));
+
+ ContentPluginInfo info;
+ EXPECT_FALSE(FillPepperPluginInfoFromManifest(path, &info));
+}
+
+TEST(FillPepperPluginInfoFromManifestTest, NonExsistingManifest) {
+ base::ScopedTempDir temp_dir;
+ ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
+
+ FilePath path;
+ ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir.GetPath(), &path));
+
+ FilePath non_existing_path = path.AddExtension(".non_exsisting");
+ ASSERT_FALSE(base::PathExists(non_existing_path));
+
+ ContentPluginInfo info;
+ EXPECT_FALSE(FillPepperPluginInfoFromManifest(path, &info));
+}
+
+TEST(FillPepperPluginInfoFromManifestTest, WrongLibraryPath) {
+ base::ScopedTempDir temp_dir;
+ ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
+
+ FilePath path;
+ ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir.GetPath(), &path));
+
+ FilePath non_existing_path = path.AddExtension(".non_exsisting");
+ ASSERT_FALSE(base::PathExists(non_existing_path));
+
+ std::ostringstream pmf_stream;
+ pmf_stream << "{"
+ << " \"type\": \"pepper\","
+ << " \"mimes\": ["
+ << " { \"type\": \"application/x-ppapi-minimal-manifest\" }"
+ << " ],"
+ << " \"program\": "
+ << " { \"url\": \"" << non_existing_path.AsUTF8Unsafe()
+ << "\" }"
+ << "}";
+ std::string pmf = pmf_stream.str();
+
+ ContentPluginInfo info;
+ ASSERT_TRUE(ParsePepperPluginManifest(path, pmf, &info));
+
+ int data_written = base::WriteFile(path, pmf.c_str(), pmf.size());
+ ASSERT_GE(data_written, 0);
+ ASSERT_EQ(pmf.size(), static_cast<size_t>(data_written));
+
+ EXPECT_FALSE(FillPepperPluginInfoFromManifest(path, &info));
+}
+
+TEST(FillPepperPluginInfoFromManifestTest, ValidManifest) {
+ base::ScopedTempDir temp_dir;
+ ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
+
+ FilePath pmf_path;
+ ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir.GetPath(), &pmf_path));
+
+ FilePath plugin_path;
+ ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir.GetPath(), &plugin_path));
+
+ std::ostringstream pmf_stream;
+ pmf_stream << "{"
+ << " \"type\": \"pepper\","
+ << " \"mimes\": ["
+ << " { \"type\": \"application/x-ppapi-minimal-manifest\" }"
+ << " ],"
+ << " \"program\": "
+ << " { \"url\": \"" << plugin_path.AsUTF8Unsafe() << "\" }"
+ << "}";
+ std::string pmf = pmf_stream.str();
+
+ ContentPluginInfo info;
+ ASSERT_TRUE(ParsePepperPluginManifest(pmf_path, pmf, &info));
+
+ int data_written = base::WriteFile(pmf_path, pmf.c_str(), pmf.size());
+ ASSERT_GE(data_written, 0);
+ ASSERT_EQ(pmf.size(), static_cast<size_t>(data_written));
+
+ EXPECT_TRUE(FillPepperPluginInfoFromManifest(pmf_path, &info));
+}
+
+TEST_F(TrustedPepperPluginInfoCacheTest, GetPlugins) {
+ // Test checks:
+ // 1. That plugins all plugins present in cache are listed
+ // exacly once in plugins vector passed to
+ // |TrustedPepperPluginInfoCache::GetPlugins|
+ // 2. That plugins present in vector passed to
+ // |TrustedPepperPluginInfoCache::GetPlugins| are not added
+ // for the 2nd time
+ // 3. Entries present in vector passed to
+ // |TrustedPepperPluginInfoCache::GetPlugins| and not present in cache
+ // are untouched.
+ //
+ // To acheive that:
+ // - set of all plugins present in cache and not present in cache
+ // is build
+ // - for all subsets it is checked that passing such subset to
+ // |TrustedPepperPluginInfoCache::GetPlugins| will result
+ // in behavior from point 1 - 3.
+ using PluginEntry = std::tuple<ContentPluginInfo, bool, bool>;
+ std::vector<PluginEntry> all_plugins;
+
+ for (const auto& plugin : valid_plugins_)
+ all_plugins.emplace_back(plugin, true, false);
+
+ for (const auto& plugin : invalid_plugins_)
+ all_plugins.emplace_back(plugin, false, false);
+
+ // This test browses all subsets, so ensure that it won't last to long
+ ASSERT_LT(all_plugins.size(), 16u)
+ << "Too much plugins - test will lasts to long";
+
+ uint32_t subsets_count = 1 << all_plugins.size();
+ LOG(INFO) << "all_plugins.size: " << all_plugins.size();
+ LOG(INFO) << "subsets_count: " << subsets_count;
+
+ // Process all subsets of |all_plugins|
+ for (uint32_t subset = 0; subset < subsets_count; ++subset) {
+ LOG(INFO) << "processing subset: " << subset << " hex: " << std::hex
+ << subset;
+
+ // Build initial plugins vector and compute how much plugins should be
+ // added from cache to the vector.
+ std::vector<ContentPluginInfo> init_plugins;
+ size_t missing_plugins_count = valid_plugins_.size();
+ for (size_t i = 0; i < all_plugins.size(); ++i) {
+ std::get<2>(all_plugins[i]) = (subset & (1 << i));
+
+ if (std::get<1>(all_plugins[i]) && std::get<2>(all_plugins[i]))
+ --missing_plugins_count;
+
+ if (std::get<2>(all_plugins[i]))
+ init_plugins.push_back(std::get<0>(all_plugins[i]));
+ }
+ std::vector<ContentPluginInfo> plugins = init_plugins;
+
+ // Call |TrustedPepperPluginInfoCache::GetPlugins| and fill plugins vector
+ cache_->GetPlugins(&plugins);
+
+ // Test that required plugins were added to the vector
+ size_t expected_plugins_size = init_plugins.size() + missing_plugins_count;
+ EXPECT_EQ(expected_plugins_size, plugins.size());
+ EXPECT_LE(init_plugins.size(), plugins.size());
+
+ // Check that initial pluings in vector are left untouched
+ if (init_plugins.size() <= plugins.size()) {
+ EXPECT_TRUE(std::equal(init_plugins.cbegin(), init_plugins.cend(),
+ plugins.cbegin(), EqualPepperPluginInfo));
+ }
+
+ // Check that all valid are present in |plugins| exactly once
+ for (const auto& plugin : valid_plugins_) {
+ EXPECT_EQ(1, count_if(plugins.cbegin(), plugins.cend(),
+ [&plugin](const ContentPluginInfo& info) {
+ return EqualPepperPluginInfo(plugin, info);
+ }));
+ }
+ }
+}
+
+TEST_F(TrustedPepperPluginInfoCacheTest, FindValidPlugin) {
+ for (const auto& plugin : valid_plugins_) {
+ for (const auto& web_plugin_mime : plugin.mime_types) {
+ ContentPluginInfo found_plugin;
+ EXPECT_TRUE(
+ cache_->FindPlugin(web_plugin_mime.mime_type, GURL(), &found_plugin));
+ EXPECT_TRUE(EqualPepperPluginInfo(plugin, found_plugin));
+ }
+ }
+}
+
+TEST_F(TrustedPepperPluginInfoCacheTest, FindInvalidPlugin) {
+ for (const auto& plugin : invalid_plugins_) {
+ for (const auto& web_plugin_mime : plugin.mime_types) {
+ ContentPluginInfo found_plugin;
+ EXPECT_FALSE(
+ cache_->FindPlugin(web_plugin_mime.mime_type, GURL(), &found_plugin));
+ }
+ }
+}
+
+TEST_F(TrustedPepperPluginInfoCacheTest, FindNonExistingMimes) {
+ for (const auto& mime_type : kNonExistingMimes) {
+ ContentPluginInfo found_plugin;
+ EXPECT_FALSE(cache_->FindPlugin(mime_type, GURL(), &found_plugin));
+ }
+}
+
+TEST_F(TrustedPepperPluginInfoCacheTest, FindByUrl) {
+ GURL url = GURL("file:///example.swf");
+ ContentPluginInfo found_plugin;
+ EXPECT_TRUE(cache_->FindPlugin("", url, &found_plugin));
+ EXPECT_STREQ("application/x-shockwave-flash",
+ found_plugin.mime_types[0].mime_type.data());
+}
+
+} // namespace
+} // namespace pepper
--- /dev/null
+// Copyright 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.
+
+#include "common/trusted_pepper_plugin_util.h"
+
+#include <vector>
+
+#include "base/command_line.h"
+#include "common/application_type.h"
+#include "common/content_switches_efl.h"
+#include "common/trusted_pepper_plugin_info_cache.h"
+#include "content/browser/plugin_service_impl.h"
+#include "content/public/common/content_plugin_info.h"
+#include "content/renderer/pepper/pepper_plugin_registry.h"
+
+using content::ContentPluginInfo;
+using content::PepperPluginRegistry;
+using content::PluginServiceImpl;
+using pepper::TrustedPepperPluginInfoCache;
+
+namespace pepper {
+
+void UpdatePluginService(Ewk_Application_Type embedder_type) {
+ // Don't need to check kEnableTrustedPepperPlugins command line switch,
+ // because in that case Trusted Pepper Plugins will be added to
+ // PluginServiceImpl at its initialization by call to
+ // ContentClientEfl::AddPepperPlugins.
+ if (embedder_type == EWK_APPLICATION_TYPE_WEBBROWSER)
+ return;
+
+ std::vector<ContentPluginInfo> plugins;
+ TrustedPepperPluginInfoCache::GetInstance()->GetPlugins(&plugins);
+ PluginServiceImpl::GetInstance()->AddPepperPlugins(plugins);
+}
+
+void UpdatePluginRegistry() {
+ // Don't need to check kEnableTrustedPepperPlugins command line switch,
+ // because in that case Trusted Pepper Plugins will be added to
+ // PepperPluginRegistry at its initialization by call to
+ // ContentClientEfl::AddPepperPlugins.
+ if (content::IsWebBrowser())
+ return;
+
+ std::vector<ContentPluginInfo> plugins;
+ TrustedPepperPluginInfoCache::GetInstance()->GetPlugins(&plugins);
+ PepperPluginRegistry::GetInstance()->AddOutOfProcessPlugins(plugins);
+}
+
+bool AreTrustedPepperPluginsDisabled() {
+ auto command_line = base::CommandLine::ForCurrentProcess();
+ return
+#if defined(OS_TIZEN_TV_PRODUCT)
+ content::IsWebBrowser() &&
+#endif
+ !command_line->HasSwitch(switches::kEnableTrustedPepperPlugins);
+}
+} // namespace pepper
--- /dev/null
+// Copyright 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 TIZEN_SRC_EWK_EFL_INTEGRATION_COMMON_TRUSTED_PEPPER_PLUGIN_UTIL_H_
+#define TIZEN_SRC_EWK_EFL_INTEGRATION_COMMON_TRUSTED_PEPPER_PLUGIN_UTIL_H_
+
+#include "tizen_src/ewk/efl_integration/public/ewk_context_product.h"
+
+namespace pepper {
+
+// Updates list of pepper plugins held by PluginServiceImpl.
+// Call this function in browser process after embedder type has been
+// properly initialized.
+void UpdatePluginService(Ewk_Application_Type embedder_type);
+
+// Update list of pepper plugins held by PepperPluginRegistry.
+// Call this function in renderer process after embedder type has been
+// properly initialized.
+void UpdatePluginRegistry();
+
+// Due to security reasons such trusted pepper plugins are disabled in
+// WebBrowser embedder, unless explicitly allowed by command line switch.
+bool AreTrustedPepperPluginsDisabled();
+} // namespace pepper
+
+#endif // TIZEN_SRC_EWK_EFL_INTEGRATION_COMMON_TRUSTED_PEPPER_PLUGIN_UTIL_H_
#include "private/ewk_notification_private.h"
+#if BUILDFLAG(ENABLE_NACL) || \
+ (defined(TIZEN_PEPPER_EXTENSIONS) && BUILDFLAG(ENABLE_PLUGINS))
+#include "content/browser/renderer_host/pepper/browser_pepper_host_factory_efl.h"
+#include "content/public/browser/browser_ppapi_host.h"
+#include "ppapi/host/ppapi_host.h"
+#endif
+
#if defined(TIZEN_WEB_SPEECH_RECOGNITION)
#include "content/browser/speech/tizen_speech_recognition_manager_delegate.h"
#endif
}
/* LCOV_EXCL_STOP */
+#if BUILDFLAG(ENABLE_NACL) || \
+ (defined(TIZEN_PEPPER_EXTENSIONS) && BUILDFLAG(ENABLE_PLUGINS))
+void ContentBrowserClientEfl::DidCreatePpapiPlugin(
+ content::BrowserPpapiHost* browser_host) {
+ browser_host->GetPpapiHost()->AddHostFactoryFilter(
+ std::make_unique<BrowserPepperHostFactoryEfl>(browser_host));
+}
+#endif
+
std::string ContentBrowserClientEfl::GetApplicationLocale() {
char* local_default = setlocale(LC_CTYPE, 0);
if (!local_default)
#include "third_party/blink/public/common/loader/url_loader_throttle.h"
#include "third_party/blink/public/web/web_window_features.h"
#include "tizen/system_info.h"
+#include "components/nacl/common/buildflags.h"
+#include "ppapi/buildflags/buildflags.h"
namespace base {
class CommandLine;
DevToolsManagerDelegate* GetDevToolsManagerDelegate();
std::unique_ptr<content::DevToolsManagerDelegate>
CreateDevToolsManagerDelegate() override;
+#if BUILDFLAG(ENABLE_NACL) || \
+ (defined(TIZEN_PEPPER_EXTENSIONS) && BUILDFLAG(ENABLE_PLUGINS))
+ void DidCreatePpapiPlugin(content::BrowserPpapiHost* browser_host) override;
+#endif
std::string GetApplicationLocale() override;
std::unique_ptr<WebContentsViewDelegate> GetWebContentsViewDelegate(
WebContents* web_contents) override;
#include "public/ewk_media_downloadable_font_info.h"
#endif // OS_TIZEN_TV_PRODUCT
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+#include "efl/window_factory.h"
+#include "ewk/efl_integration/ewk_privilege_checker.h"
+#endif // defined(TIZEN_PEPPER_EXTENSIONS)
+
+#if defined(USE_WAYLAND) && defined(TIZEN_PEPPER_EXTENSIONS)
+#include <Ecore_Wayland.h>
+#endif // defined(USE_WAYLAND)
+
using namespace content;
using web_contents_utils::WebViewFromWebContents;
scroll_detector_.reset(new ScrollDetector(this));
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+ InitializePepperExtensionSystem();
+#endif
DCHECK(web_contents_->GetRenderViewHost());
// Settings (content::WebPreferences) will be initalized by
// RenderViewHostImpl::ComputeWebkitPrefs() based on command line switches.
cbce->RemoveAcceptLangsChangedCallback(
std::move(accept_langs_changed_callback_));
#endif
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+ UnregisterPepperExtensionDelegate();
+#endif
evas_object_event_callback_del(native_view_, EVAS_CALLBACK_RESIZE,
EWebView::NativeViewResize);
GetJavaScriptDialogManagerEfl()->ReplyBeforeUnloadConfirmPanel(result);
}
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+void EWebView::InitializePepperExtensionSystem() {
+ RegisterPepperExtensionDelegate();
+ SetWindowId();
+}
+
+EwkExtensionSystemDelegate* EWebView::GetExtensionDelegate() {
+ RenderFrameHost* render_frame_host = web_contents_->GetPrimaryMainFrame();
+ if (!render_frame_host)
+ return nullptr;
+
+ ExtensionSystemDelegateManager::RenderFrameID id;
+ id.render_process_id = render_frame_host->GetProcess()->GetID();
+ id.render_frame_id = render_frame_host->GetRoutingID();
+ return static_cast<EwkExtensionSystemDelegate*>(
+ ExtensionSystemDelegateManager::GetInstance()->GetDelegateForFrame(id));
+}
+
+void EWebView::SetWindowId() {
+ EwkExtensionSystemDelegate* delegate = GetExtensionDelegate();
+ if (!delegate) {
+ LOG(WARNING) << "No delegate is available to set window id";
+ return;
+ }
+ Evas_Object* main_wind =
+ efl::WindowFactory::GetHostWindow(web_contents_.get());
+ if (!main_wind) {
+ LOG(ERROR) << "Can`t get main window";
+ return;
+ }
+ delegate->SetWindowId(main_wind);
+}
+
+void EWebView::SetPepperExtensionWidgetInfo(Ewk_Value widget_pepper_ext_info) {
+ EwkExtensionSystemDelegate* delegate = GetExtensionDelegate();
+ if (!delegate) {
+ LOG(WARNING) << "No delegate is available to set extension info";
+ return;
+ }
+ delegate->SetExtensionInfo(widget_pepper_ext_info);
+}
+
+void EWebView::SetPepperExtensionCallback(Generic_Sync_Call_Callback cb,
+ void* data) {
+ EwkExtensionSystemDelegate* delegate = GetExtensionDelegate();
+ if (!delegate) {
+ LOG(WARNING) << "No delegate is available to set generic callback";
+ return;
+ }
+ delegate->SetGenericSyncCallback(cb, data);
+}
+
+void EWebView::RegisterPepperExtensionDelegate() {
+ RenderFrameHost* render_frame_host = web_contents_->GetPrimaryMainFrame();
+ if (!render_frame_host) {
+ LOG(WARNING) << "render_frame_host is nullptr, can't register delegate";
+ return;
+ }
+
+ ExtensionSystemDelegateManager::RenderFrameID id;
+ id.render_process_id = render_frame_host->GetProcess()->GetID();
+ id.render_frame_id = render_frame_host->GetRoutingID();
+
+ EwkExtensionSystemDelegate* delegate = new EwkExtensionSystemDelegate;
+ ExtensionSystemDelegateManager::GetInstance()->RegisterDelegate(
+ id, std::unique_ptr<EwkExtensionSystemDelegate>{delegate});
+}
+
+void EWebView::UnregisterPepperExtensionDelegate() {
+ if (!web_contents_) {
+ LOG(WARNING) << "web_contents_ is nullptr, can't unregister delegate";
+ return;
+ }
+ RenderFrameHost* render_frame_host = web_contents_->GetPrimaryMainFrame();
+ if (!render_frame_host) {
+ LOG(WARNING) << "render_frame_host is nullptr, can't unregister delegate";
+ return;
+ }
+
+ ExtensionSystemDelegateManager::RenderFrameID id;
+ id.render_process_id = render_frame_host->GetProcess()->GetID();
+ id.render_frame_id = render_frame_host->GetRoutingID();
+
+ if (!ExtensionSystemDelegateManager::GetInstance()->UnregisterDelegate(id))
+ LOG(WARNING) << "Unregistering pepper extension delegate failed";
+}
+#endif // defined(TIZEN_PEPPER_EXTENSIONS)
+
void EWebView::SetExceededIndexedDatabaseQuotaCallback(
Ewk_View_Exceeded_Indexed_Database_Quota_Callback callback,
void* user_data) {
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/size.h"
#include "web_contents_delegate_efl.h"
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+#include "ewk_extension_system_delegate.h"
+#include "public/ewk_value_product.h"
+#endif
namespace aura {
namespace client {
void InitAtk();
bool GetAtkStatus();
#endif
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+ void InitializePepperExtensionSystem();
+ EwkExtensionSystemDelegate* GetExtensionDelegate();
+ void SetWindowId();
+ void SetPepperExtensionWidgetInfo(Ewk_Value widget_pepper_ext_info);
+ void SetPepperExtensionCallback(Generic_Sync_Call_Callback cb, void* data);
+ void RegisterPepperExtensionDelegate();
+ void UnregisterPepperExtensionDelegate();
+#endif
bool ShouldIgnoreNavigation(content::NavigationHandle* navigation_handle);
--- /dev/null
+// Copyright 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.
+
+#include "ewk/efl_integration/ewk_extension_system_delegate.h"
+
+#include "base/lazy_instance.h"
+#include "base/logging.h"
+#include "base/memory/ptr_util.h"
+#include "chromium_impl/build/tizen_version.h"
+#include "ppapi/cpp/samsung/extension_system_samsung_wrt.h"
+#include "private/ewk_value_private.h"
+
+#if defined(OS_TIZEN_TV_PRODUCT) && defined(USE_WAYLAND)
+#include <Ecore_Evas.h>
+#if TIZEN_VERSION_AT_LEAST(5, 0, 0)
+#include <Ecore_Wl2.h>
+#else
+#include <Ecore_Wayland.h>
+#endif
+#include <tizen-extension-client-protocol.h>
+#endif // defined(OS_TIZEN_TV_PRODUCT) && defined(USE_WAYLAND)
+
+namespace {
+static const char kTypeWebBrowserName[] = "WebBrowser";
+static const char kTypeTizenWrtName[] = "TizenWRT";
+static const char kTypeHbbTvName[] = "HbbTV";
+static const char kTypeUnrecognized[] = "UnrecognizedEmbedder";
+
+static base::LazyInstance<std::string>::Leaky current_embedder_name =
+ LAZY_INSTANCE_INITIALIZER;
+
+#if defined(OS_TIZEN_TV_PRODUCT) && defined(USE_WAYLAND)
+
+struct WLRegistryDestroy {
+ void operator()(void* x) const {
+ wl_registry* registry = static_cast<wl_registry*>(x);
+ wl_registry_destroy(registry);
+ }
+};
+
+struct TizenSurfaceDestroy {
+ void operator()(void* x) const {
+ tizen_surface* surface = static_cast<tizen_surface*>(x);
+ tizen_surface_destroy(surface);
+ }
+};
+
+struct TizenResourceDestroy {
+ void operator()(void* x) const {
+ tizen_resource* resource = static_cast<tizen_resource*>(x);
+ tizen_resource_destroy(resource);
+ }
+};
+
+struct WLEventQueueDestroy {
+ void operator()(void* x) const {
+ wl_event_queue* queue = static_cast<wl_event_queue*>(x);
+ wl_event_queue_destroy(queue);
+ }
+};
+
+static void HandleGlobal(void* data,
+ wl_registry* registry,
+ uint32_t name,
+ const char* interface,
+ uint32_t version) {
+ if (data && strcmp(interface, "tizen_surface") == 0) {
+ void** surface = reinterpret_cast<void**>(data);
+ *surface =
+ wl_registry_bind(registry, name, &tizen_surface_interface, version);
+ }
+}
+
+static void RemoveGlobal(void* data,
+ struct wl_registry* wl_registry,
+ uint32_t name) {}
+
+const struct wl_registry_listener registry_listener = {HandleGlobal,
+ RemoveGlobal};
+
+void HandleResourceId(void* data, tizen_resource* tizen_resource, uint32_t id) {
+ if (data)
+ *reinterpret_cast<int*>(data) = id;
+}
+
+const struct tizen_resource_listener tz_resource_listener = {
+ HandleResourceId,
+};
+
+int GetSurfaceResourceId(wl_surface* surface, wl_display* display) {
+ using ScopedWLRegistry = std::unique_ptr<wl_registry, WLRegistryDestroy>;
+ using ScopedWLEventQueue =
+ std::unique_ptr<wl_event_queue, WLEventQueueDestroy>;
+ using ScopedTizenSurface =
+ std::unique_ptr<tizen_surface, TizenSurfaceDestroy>;
+ using ScopedTizenResource =
+ std::unique_ptr<tizen_resource, TizenResourceDestroy>;
+
+ DCHECK(surface && display);
+ if (surface == nullptr || display == nullptr)
+ return 0;
+
+ ScopedWLEventQueue event_queue(wl_display_create_queue(display));
+ DCHECK(event_queue.get());
+ if (event_queue == nullptr)
+ return 0;
+
+ ScopedWLRegistry registry(wl_display_get_registry(display));
+ DCHECK(registry.get());
+ if (registry == nullptr)
+ return 0;
+ wl_proxy_set_queue(reinterpret_cast<wl_proxy*>(registry.get()),
+ event_queue.get());
+
+ tizen_surface* tz_surface_raw = nullptr;
+ wl_registry_add_listener(registry.get(), ®istry_listener, &tz_surface_raw);
+ wl_display_dispatch_queue(display, event_queue.get());
+ wl_display_roundtrip_queue(display, event_queue.get());
+ DCHECK(tz_surface_raw);
+ if (tz_surface_raw == nullptr)
+ return 0;
+ ScopedTizenSurface tz_surface(tz_surface_raw);
+
+ ScopedTizenResource tz_resource(
+ tizen_surface_get_tizen_resource(tz_surface.get(), surface));
+ DCHECK(tz_resource.get());
+ if (tz_resource.get() == nullptr)
+ return 0;
+ wl_proxy_set_queue(reinterpret_cast<wl_proxy*>(tz_resource.get()),
+ event_queue.get());
+
+ int wl_surface_id = 0;
+ tizen_resource_add_listener(tz_resource.get(), &tz_resource_listener,
+ &wl_surface_id);
+ wl_display_roundtrip_queue(display, event_queue.get());
+ return wl_surface_id;
+}
+
+#if TIZEN_VERSION_AT_LEAST(5, 0, 0)
+int GetWaylandWindowId(Ecore_Wl2_Window* ew) {
+ wl_surface* surface = ecore_wl2_window_surface_get(ew);
+ Ecore_Wl2_Display* wl2_display = ecore_wl2_connected_display_get(NULL);
+ wl_display* display = ecore_wl2_display_get(wl2_display);
+ return GetSurfaceResourceId(surface, display);
+}
+#else
+int GetWaylandWindowId(Ecore_Wl_Window* ew) {
+ wl_surface* surface = ecore_wl_window_surface_get(ew);
+ wl_display* display = static_cast<wl_display*>(ecore_wl_display_get());
+ return GetSurfaceResourceId(surface, display);
+}
+#endif // TIZEN_VERSION_AT_LEAST(5, 0, 0)
+
+#endif // defined(OS_TIZEN_TV_PRODUCT) && defined(USE_WAYLAND)
+
+} // namespace
+
+EwkExtensionSystemDelegate::EwkExtensionSystemDelegate()
+ : info_(nullptr), cb_(nullptr), cb_data_(nullptr), window_id_(0) {}
+
+EwkExtensionSystemDelegate::~EwkExtensionSystemDelegate() {
+ ewk_value_unref(info_);
+}
+
+std::string EwkExtensionSystemDelegate::GetEmbedderName() const {
+ return current_embedder_name.Get();
+}
+
+std::unique_ptr<base::Value> EwkExtensionSystemDelegate::GetExtensionInfo()
+ const {
+ base::AutoLock guard{access_lock_};
+ if (!info_)
+ return std::make_unique<base::Value>();
+ return static_cast<const EwkValuePrivate*>(info_)
+ ->GetValue()
+ ->CreateDeepCopy();
+}
+
+int EwkExtensionSystemDelegate::GetWindowId() const {
+ return window_id_;
+}
+
+std::unique_ptr<base::Value> EwkExtensionSystemDelegate::GenericSyncCall(
+ const std::string& name,
+ const base::Value& data) {
+ base::AutoLock guard{access_lock_};
+ if (!cb_)
+ return std::make_unique<base::Value>();
+
+ Ewk_Value arg = static_cast<Ewk_Value>(
+ new EwkValuePrivate(data.CreateDeepCopy()));
+ ewk_value_ref(arg);
+ Ewk_Value result = cb_(name.c_str(), arg, cb_data_);
+ ewk_value_unref(arg);
+ if (!result)
+ return std::make_unique<base::Value>();
+ std::unique_ptr<base::Value> ret =
+ static_cast<const EwkValuePrivate*>(result)->GetValue()->CreateDeepCopy();
+ ewk_value_unref(result);
+ return ret;
+}
+
+void EwkExtensionSystemDelegate::SetEmbedderName(
+ const Ewk_Application_Type embedder_type) {
+ switch (embedder_type) {
+ case EWK_APPLICATION_TYPE_WEBBROWSER:
+ current_embedder_name.Get() = kTypeWebBrowserName;
+ break;
+ case EWK_APPLICATION_TYPE_HBBTV:
+ current_embedder_name.Get() = kTypeHbbTvName;
+ break;
+ case EWK_APPLICATION_TYPE_TIZENWRT:
+ current_embedder_name.Get() = kTypeTizenWrtName;
+ break;
+ default:
+ current_embedder_name.Get() = kTypeUnrecognized;
+ break;
+ }
+}
+
+void EwkExtensionSystemDelegate::SetExtensionInfo(Ewk_Value info) {
+ base::AutoLock guard{access_lock_};
+
+ ewk_value_ref(info);
+ // Unref current info_, if already set
+ ewk_value_unref(info_);
+ info_ = info;
+}
+
+void EwkExtensionSystemDelegate::SetGenericSyncCallback(
+ Generic_Sync_Call_Callback cb,
+ void* data) {
+ base::AutoLock guard{access_lock_};
+ cb_ = cb;
+ cb_data_ = data;
+}
+
+void EwkExtensionSystemDelegate::SetWindowId(const Evas_Object* main_window) {
+#if defined(OS_TIZEN_TV_PRODUCT)
+ Evas* evas = evas_object_evas_get(main_window);
+ if (!evas) {
+ LOG(ERROR) << "Evas can`t be acquired for main window";
+ return;
+ }
+ const Ecore_Evas* ee = ecore_evas_ecore_evas_get(evas);
+ if (!ee) {
+ LOG(ERROR) << "Ecore_Evas can`t be acquired from main window Evas";
+ return;
+ }
+#if defined(USE_WAYLAND)&&!defined(USE_AURA)
+#if TIZEN_VERSION_AT_LEAST(5, 0, 0)
+ Ecore_Wl2_Window* ww = ecore_evas_wayland2_window_get(ee);
+#else
+ Ecore_Wl_Window* ww = ecore_evas_wayland_window_get(ee);
+#endif // TIZEN_VERSION_AT_LEAST(5, 0, 0)
+ if (!ww) {
+ LOG(ERROR) << "Can`t get Wl window";
+ return;
+ }
+ window_id_ = GetWaylandWindowId(ww);
+#else
+ Ecore_X_Window ww = ecore_evas_gl_x11_window_get(ee);
+ window_id_ = static_cast<int>(ww);
+#endif // defined(USE_WAYLAND)
+#endif // defined(OS_TIZEN_TV_PRODUCT)
+}
--- /dev/null
+// Copyright 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 TIZEN_SRC_EWK_EFL_INTEGRATION_EWK_EXTENSION_SYSTEM_DELEGATE_H_
+#define TIZEN_SRC_EWK_EFL_INTEGRATION_EWK_EXTENSION_SYSTEM_DELEGATE_H_
+
+#include <string>
+
+#include "base/synchronization/lock.h"
+#include "content/public/browser/extension_system_delegate.h"
+#include "public/ewk_context_product.h"
+#include "public/ewk_value_product.h"
+#include "public/ewk_view_product.h"
+
+class EwkExtensionSystemDelegate : public content::ExtensionSystemDelegate {
+ public:
+ EwkExtensionSystemDelegate();
+ ~EwkExtensionSystemDelegate() override;
+
+ std::string GetEmbedderName() const override;
+ std::unique_ptr<base::Value> GetExtensionInfo() const override;
+ std::unique_ptr<base::Value> GenericSyncCall(
+ const std::string& name,
+ const base::Value& data) override;
+
+ int GetWindowId() const override;
+
+ static void SetEmbedderName(const Ewk_Application_Type embedder_type);
+ void SetExtensionInfo(Ewk_Value info);
+ void SetGenericSyncCallback(Generic_Sync_Call_Callback cb, void* data);
+
+ void SetWindowId(const Evas_Object* main_window);
+
+ private:
+ Ewk_Value info_;
+ Generic_Sync_Call_Callback cb_;
+ void* cb_data_;
+ int window_id_;
+
+ // TODO(a.bujalski) Check if it is possible to call WRT's cb on IO thread.
+ mutable base::Lock access_lock_;
+};
+
+#endif // TIZEN_SRC_EWK_EFL_INTEGRATION_EWK_EXTENSION_SYSTEM_DELEGATE_H_
--- /dev/null
+// Copyright 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.
+
+#include "ewk/efl_integration/ewk_privilege_checker.h"
+
+#if defined(OS_TIZEN)
+#include <app_manager.h>
+#include <cynara-client.h>
+#include <pkgmgr-info.h>
+#include <unistd.h>
+#endif // defined(OS_TIZEN)
+
+#include <fstream>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/compiler_specific.h"
+#include "base/logging.h"
+
+#if defined(OS_TIZEN)
+namespace {
+bool GetPkgApiVersion(std::string* api_version) {
+ char* app_id = nullptr;
+ char* pkgid = nullptr;
+ // api_ver memory is released by pkgmgrinfo_pkginfo_destroy_pkginfo method
+ char* api_ver = nullptr;
+ app_info_h app_handle = nullptr;
+ pkgmgrinfo_pkginfo_h pkginfo_handle = nullptr;
+
+ pid_t pid = getpid();
+ int ret = app_manager_get_app_id(pid, &app_id);
+ if (ret != APP_MANAGER_ERROR_NONE) {
+ LOG(ERROR) << "Can`t get app_id";
+ return false;
+ }
+
+ ret = app_info_create(app_id, &app_handle);
+ free(app_id);
+ if (ret != APP_MANAGER_ERROR_NONE) {
+ LOG(ERROR) << "Can`t get app_handle";
+ return false;
+ }
+
+ ret = app_info_get_package(app_handle, &pkgid);
+ app_info_destroy(app_handle);
+ if (ret != APP_MANAGER_ERROR_NONE || pkgid == nullptr) {
+ LOG(ERROR) << "Can`t get pkgid";
+ return false;
+ }
+
+ ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, getuid(), &pkginfo_handle);
+ free(pkgid);
+ if (ret != PMINFO_R_OK) {
+ LOG(ERROR) << "Can`t get pkginfo_handle";
+ return false;
+ }
+
+ ret = pkgmgrinfo_pkginfo_get_api_version(pkginfo_handle, &api_ver);
+ if (ret != PMINFO_R_OK) {
+ LOG(ERROR) << "Can`t get api_ver";
+ return false;
+ }
+
+ *api_version = api_ver;
+ pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo_handle);
+ return true;
+}
+
+} // namespace
+#endif // defined(OS_TIZEN)
+
+namespace content {
+
+// static
+EwkPrivilegeChecker* EwkPrivilegeChecker::GetInstance() {
+ return base::Singleton<EwkPrivilegeChecker>::get();
+}
+
+bool EwkPrivilegeChecker::CheckPrivilege(const std::string& privilege_name) {
+#if defined(OS_TIZEN)
+ static constexpr char kSmackLabelFilePath[] = "/proc/self/attr/current";
+
+ int ret;
+ cynara* p_cynara = nullptr;
+ ret = cynara_initialize(&p_cynara, 0);
+ if (ret != CYNARA_API_SUCCESS) {
+ LOG(ERROR) << "Couldn`t initialize Cynara";
+ return false;
+ }
+
+ auto cynara_deleter = [](cynara* p) { cynara_finish(p); };
+ auto cynara_holder = std::unique_ptr<cynara, decltype(cynara_deleter)>{
+ p_cynara, cynara_deleter};
+
+ std::string uid = std::to_string(getuid());
+
+ // Get smack label
+ std::ifstream file(kSmackLabelFilePath);
+ if (!file.is_open()) {
+ LOG(ERROR) << "Failed to open " << kSmackLabelFilePath;
+ return false;
+ }
+
+ std::string smack_label{std::istreambuf_iterator<char>(file),
+ std::istreambuf_iterator<char>()};
+
+ // Get widget api version, which is needed to resolve older privileges from
+ // previous platforms. Api version is set inside of config.xml in widget.
+ std::string api_version;
+ if (!GetPkgApiVersion(&api_version)) {
+ LOG(ERROR) << "Failed to acquire api version. "
+ << "Can`t resolve properly privilege mapping!";
+ return false;
+ }
+
+ ret = cynara_check(p_cynara, smack_label.c_str(), "", uid.c_str(),
+ privilege_name.c_str());
+ if (ret != CYNARA_API_ACCESS_ALLOWED) {
+ LOG(ERROR) << "Failed to acquire mapping for privilege: "
+ << privilege_name.c_str();
+ return false;
+ }
+ return true;
+#else // defined(OS_TIZEN)
+ ALLOW_UNUSED_LOCAL(privilege_name);
+ return false;
+#endif
+}
+} // namespace content
--- /dev/null
+// Copyright 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 TIZEN_SRC_EWK_EFL_INTEGRATION_EWK_PRIVILEGE_CHECKER_H_
+#define TIZEN_SRC_EWK_EFL_INTEGRATION_EWK_PRIVILEGE_CHECKER_H_
+
+#include <string>
+
+#include "base/memory/singleton.h"
+
+namespace content {
+
+/*
+ * EwkPrivilegeChecker is an implementation for resolving access for given
+ * privilege
+ */
+class EwkPrivilegeChecker {
+ public:
+ static EwkPrivilegeChecker* GetInstance();
+ bool CheckPrivilege(const std::string& privilege_name);
+
+ private:
+ EwkPrivilegeChecker() = default;
+ friend struct base::DefaultSingletonTraits<EwkPrivilegeChecker>;
+};
+
+} // namespace content
+
+#endif // TIZEN_SRC_EWK_EFL_INTEGRATION_EWK_PRIVILEGE_CHECKER_H_
--- /dev/null
+// Copyright 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.
+
+#include "ewk_value_private.h"
+
+EwkValuePrivate::EwkValuePrivate() = default;
+
+EwkValuePrivate::EwkValuePrivate(bool value) : value_(new base::Value(value)) {}
+
+EwkValuePrivate::EwkValuePrivate(int value) : value_(new base::Value(value)) {}
+
+EwkValuePrivate::EwkValuePrivate(double value)
+ : value_(new base::Value(value)) {}
+
+EwkValuePrivate::EwkValuePrivate(const std::string& value)
+ : value_(new base::Value(value)) {}
+
+EwkValuePrivate::EwkValuePrivate(std::unique_ptr<base::Value> value)
+ : value_(std::move(value)) {}
+
+base::Value::Type EwkValuePrivate::GetType() const {
+ if (!value_)
+ return base::Value::Type::NONE;
+
+ return value_->type();
+}
+
+base::Value* EwkValuePrivate::GetValue() const {
+ return value_.get();
+}
+
+EwkValuePrivate::~EwkValuePrivate() = default;
--- /dev/null
+// Copyright 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 EWK_EFL_INTEGRATION_PRIVATE_EWK_VALUE_PRIVATE_H_
+#define EWK_EFL_INTEGRATION_PRIVATE_EWK_VALUE_PRIVATE_H_
+
+#include <memory>
+#include <string>
+
+#include "base/memory/ref_counted.h"
+#include "base/values.h"
+
+class EwkValuePrivate : public base::RefCountedThreadSafe<EwkValuePrivate> {
+ public:
+ EwkValuePrivate();
+ explicit EwkValuePrivate(bool value);
+ explicit EwkValuePrivate(int value);
+ explicit EwkValuePrivate(double value);
+ explicit EwkValuePrivate(const std::string& value);
+ explicit EwkValuePrivate(std::unique_ptr<base::Value> value);
+
+ // disable constructor from raw pointer because of implicit conversion
+ // of pointer types to bool
+ explicit EwkValuePrivate(base::Value* value) = delete;
+
+ base::Value::Type GetType() const;
+ base::Value* GetValue() const;
+
+ private:
+ friend class base::RefCountedThreadSafe<EwkValuePrivate>;
+ ~EwkValuePrivate();
+
+ std::unique_ptr<base::Value> value_;
+};
+
+#endif // EWK_EFL_INTEGRATION_PRIVATE_EWK_VALUE_PRIVATE_H_
#if BUILDFLAG(IS_TIZEN)
#include <app_control.h>
-
#include "browser/notification/notification_controller_efl.h"
#endif
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+#include "common/trusted_pepper_plugin_util.h"
+#include "ewk_extension_system_delegate.h"
+#endif
namespace {
ContentBrowserClientEfl* GetContentBrowserClient() {
EINA_SAFETY_ON_NULL_RETURN(ewkContext);
LOG(INFO) << "Set current application type: " << applicationType;
ewkContext->SetApplicationType(applicationType);
+
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+ EwkExtensionSystemDelegate::SetEmbedderName(applicationType);
+ pepper::UpdatePluginService(applicationType);
+#endif // defined(TIZEN_PEPPER_EXTENSIONS)
+
#else
LOG_EWK_API_MOCKUP("Only for Tizen TV");
#endif
-/*
- * Copyright (C) 2016 Samsung Electronics. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY SAMSUNG ELECTRONICS. AND ITS CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SAMSUNG ELECTRONICS. OR ITS
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "ewk_value_product.h"
-#include "private/ewk_private.h"
+// Copyright 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.
+
+#include "public/ewk_value_product.h"
+#include "private/ewk_value_private.h"
+
+#include <memory>
+#include <sstream>
+#include <string>
+
+namespace {
+
+inline Eina_Bool Eina_FromBool(bool v) {
+ return v ? EINA_TRUE : EINA_FALSE;
+}
+
+inline bool Eina_ToBool(Eina_Bool v) {
+ return (v == EINA_FALSE) ? false : true;
+}
+
+inline const EwkValuePrivate* EwkValueCast(Ewk_Value value) {
+ return static_cast<const EwkValuePrivate*>(value);
+}
+
+} // namespace
+
+#define EWK_VALUE_TYPE_CHECK_RETURN_VAL(value, type, retval) \
+ EINA_SAFETY_ON_FALSE_RETURN_VAL((type) == ewk_value_type_get(value), \
+ (retval))
Ewk_Value ewk_value_ref(Ewk_Value value) {
- LOG_EWK_API_MOCKUP();
- return NULL;
+ EINA_SAFETY_ON_NULL_RETURN_VAL(value, NULL);
+ EwkValueCast(value)->AddRef();
+ return value;
}
void ewk_value_unref(Ewk_Value value) {
- LOG_EWK_API_MOCKUP();
+ EINA_SAFETY_ON_NULL_RETURN(value);
+ EwkValueCast(value)->Release();
}
Ewk_Value_Type ewk_value_null_type_get() {
- LOG_EWK_API_MOCKUP();
- return 0;
+ return static_cast<Ewk_Value_Type>(base::Value::Type::NONE);
}
Ewk_Value_Type ewk_value_type_get(Ewk_Value value) {
- LOG_EWK_API_MOCKUP();
- return 0;
+ EINA_SAFETY_ON_NULL_RETURN_VAL(
+ value, static_cast<Ewk_Value_Type>(base::Value::Type::NONE));
+ return static_cast<Ewk_Value_Type>(EwkValueCast(value)->GetType());
}
Ewk_Value ewk_value_boolean_new(Eina_Bool initial_value) {
- LOG_EWK_API_MOCKUP();
- return NULL;
+ Ewk_Value val =
+ static_cast<Ewk_Value>(new EwkValuePrivate(Eina_ToBool(initial_value)));
+ return ewk_value_ref(val);
}
Ewk_Value_Type ewk_value_boolean_type_get() {
- LOG_EWK_API_MOCKUP();
- return 0;
+ return static_cast<Ewk_Value_Type>(base::Value::Type::BOOLEAN);
}
Eina_Bool ewk_value_boolean_value_get(Ewk_Value value, Eina_Bool* dst) {
- LOG_EWK_API_MOCKUP();
- return false;
+ EWK_VALUE_TYPE_CHECK_RETURN_VAL(value, ewk_value_boolean_type_get(),
+ EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
+
+ auto val = EwkValueCast(value)->GetValue()->GetIfBool();
+ *dst = Eina_FromBool(static_cast<bool>(val));
+ return EINA_TRUE;
}
Ewk_Value ewk_value_double_new(double initial_value) {
- LOG_EWK_API_MOCKUP();
- return NULL;
+ Ewk_Value val = static_cast<Ewk_Value>(new EwkValuePrivate(initial_value));
+ return ewk_value_ref(val);
}
Ewk_Value_Type ewk_value_double_type_get() {
- LOG_EWK_API_MOCKUP();
- return 0;
+ return static_cast<Ewk_Value_Type>(base::Value::Type::DOUBLE);
}
Eina_Bool ewk_value_double_value_get(Ewk_Value value, double* dst) {
- LOG_EWK_API_MOCKUP();
- return false;
+ EWK_VALUE_TYPE_CHECK_RETURN_VAL(value, ewk_value_double_type_get(),
+ EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
+ *dst = EwkValueCast(value)->GetValue()->GetDouble();
+ return EINA_TRUE;
}
Ewk_Value ewk_value_int_new(int initial_value) {
- LOG_EWK_API_MOCKUP();
- return NULL;
+ Ewk_Value val = static_cast<Ewk_Value>(new EwkValuePrivate(initial_value));
+ return ewk_value_ref(val);
}
Ewk_Value_Type ewk_value_int_type_get() {
- LOG_EWK_API_MOCKUP();
- return 0;
+ return static_cast<Ewk_Value_Type>(base::Value::Type::INTEGER);
}
Eina_Bool ewk_value_int_value_get(Ewk_Value value, int* dst) {
- LOG_EWK_API_MOCKUP();
- return false;
+ EWK_VALUE_TYPE_CHECK_RETURN_VAL(value, ewk_value_int_type_get(), EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
+ *dst = EwkValueCast(value)->GetValue()->GetInt();
+ return EINA_TRUE;
}
Ewk_Value ewk_value_string_new(const char* initial_value) {
- LOG_EWK_API_MOCKUP();
- return NULL;
+ Ewk_Value val =
+ static_cast<Ewk_Value>(new EwkValuePrivate(std::string(initial_value)));
+ return ewk_value_ref(val);
}
Ewk_Value_Type ewk_value_string_type_get() {
- LOG_EWK_API_MOCKUP();
- return 0;
+ return static_cast<Ewk_Value_Type>(base::Value::Type::STRING);
}
Eina_Stringshare* ewk_value_string_value_get(Ewk_Value value) {
- LOG_EWK_API_MOCKUP();
- return NULL;
+ EWK_VALUE_TYPE_CHECK_RETURN_VAL(value, ewk_value_string_type_get(), NULL);
+ std::string* str = EwkValueCast(value)->GetValue()->GetIfString();
+ if (str) {
+ return eina_stringshare_add(str->c_str());
+ } else {
+ return NULL;
+ }
}
Ewk_Value ewk_value_array_new() {
- LOG_EWK_API_MOCKUP();
- return NULL;
+ Ewk_Value val = static_cast<Ewk_Value>(
+ new EwkValuePrivate(std::unique_ptr<base::Value>(new base::ListValue())));
+ return ewk_value_ref(val);
}
Ewk_Value_Type ewk_value_array_type_get() {
- LOG_EWK_API_MOCKUP();
- return 0;
+ return static_cast<Ewk_Value_Type>(base::Value::Type::LIST);
}
Eina_Bool ewk_value_array_is_mutable(Ewk_Value array) {
- LOG_EWK_API_MOCKUP();
- return false;
+ EWK_VALUE_TYPE_CHECK_RETURN_VAL(array, ewk_value_array_type_get(),
+ EINA_FALSE);
+ return EINA_TRUE;
}
Eina_Bool ewk_value_array_append(Ewk_Value array, Ewk_Value value) {
- LOG_EWK_API_MOCKUP();
-
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(ewk_value_array_is_mutable(array),
+ EINA_FALSE);
+ base::ListValue* list;
+ bool result = EwkValueCast(array)->GetValue()->is_list();
+ if (result) {
+ // TODO(m.majczak) consider a workaround for the deep copy
+ base::ListValue* list = static_cast<base::ListValue*>(EwkValueCast(array)->GetValue());
+ list->Append(std::move(*(EwkValueCast(value)->GetValue()->CreateDeepCopy())));
+ return EINA_TRUE;
+ } else {
+ return EINA_FALSE;
+ }
}
size_t ewk_value_array_count(Ewk_Value array) {
- LOG_EWK_API_MOCKUP();
- return 0;
+ EWK_VALUE_TYPE_CHECK_RETURN_VAL(array, ewk_value_array_type_get(), 0);
+ base::ListValue* list;
+ bool result = EwkValueCast(array)->GetValue()->is_list();
+ if (result) {
+ list = static_cast<base::ListValue*>(EwkValueCast(array)->GetValue());
+ return list->GetList().size();
+ } else {
+ return 0;
+ }
}
Eina_Bool ewk_value_array_get(Ewk_Value array,
size_t position,
Ewk_Value* dst) {
- LOG_EWK_API_MOCKUP();
- return false;
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(position < ewk_value_array_count(array),
+ EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
+ base::ListValue* list;
+ bool result = EwkValueCast(array)->GetValue()->is_list();
+ if (result) {
+ // TODO(m.majczak) consider a workaround for the deep copy
+ list = static_cast<base::ListValue*>(EwkValueCast(array)->GetValue());
+ base::Value* val = nullptr;
+ val = &(list->GetList().operator[](position));
+ if (!val)
+ return EINA_FALSE;
+ Ewk_Value ret = static_cast<Ewk_Value>(
+ new EwkValuePrivate(std::unique_ptr<base::Value>(val->CreateDeepCopy())));
+ // warning!!! the ownership is passed to the caller here
+ ewk_value_ref(ret);
+ *dst = ret;
+ return EINA_TRUE;
+ } else {
+ return EINA_FALSE;
+ }
}
Eina_Bool ewk_value_array_remove(Ewk_Value array, size_t position) {
- LOG_EWK_API_MOCKUP();
- return false;
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(ewk_value_array_is_mutable(array),
+ EINA_FALSE);
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(position < ewk_value_array_count(array),
+ EINA_FALSE);
+ base::Value* list;
+ bool result = EwkValueCast(array)->GetValue()->is_list();
+ if (result) {
+ list = static_cast<base::Value*>(EwkValueCast(array)->GetValue());
+ base::Value::List list_storage = std::move(*list).TakeList();
+ // warning!!! value is completely deleted here
+ list_storage.erase(list_storage.begin() + position);
+ *list = base::Value(std::move(list_storage));
+ return EINA_TRUE;
+ } else {
+ return EINA_FALSE;
+ }
}
Ewk_Value ewk_value_dictionary_new() {
- LOG_EWK_API_MOCKUP();
- return NULL;
+ Ewk_Value val = static_cast<Ewk_Value>(new EwkValuePrivate(
+ std::unique_ptr<base::Value>(new base::DictionaryValue())));
+ return ewk_value_ref(val);
}
Ewk_Value_Type ewk_value_dictionary_type_get() {
- LOG_EWK_API_MOCKUP();
- return 0;
+ return static_cast<Ewk_Value_Type>(base::Value::Type::DICTIONARY);
}
Eina_Bool ewk_value_dictionary_is_mutable(Ewk_Value dictionary) {
- LOG_EWK_API_MOCKUP();
- return false;
+ EWK_VALUE_TYPE_CHECK_RETURN_VAL(dictionary, ewk_value_dictionary_type_get(),
+ EINA_FALSE);
+ return EINA_TRUE;
}
Eina_Bool ewk_value_dictionary_keys(Ewk_Value dictionary, Ewk_Value* keys) {
- LOG_EWK_API_MOCKUP();
- return false;
+ EWK_VALUE_TYPE_CHECK_RETURN_VAL(dictionary, ewk_value_dictionary_type_get(),
+ EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(keys, EINA_FALSE);
+ // warning!!! This is very expensive operation.
+ base::DictionaryValue* dict;
+ bool result = EwkValueCast(dictionary)->GetValue()->GetAsDictionary(&dict);
+ if (result) {
+ *keys = ewk_value_array_new();
+ base::detail::dict_iterator it = dict->DictItems().begin();
+ while (it!=dict->DictItems().end()) {
+ Ewk_Value str = ewk_value_string_new(it->first.c_str());
+ ewk_value_array_append(*keys, str);
+ ewk_value_unref(str);
+ it++;
+ }
+ return EINA_TRUE;
+ } else {
+ return EINA_FALSE;
+ }
}
Eina_Bool ewk_value_dictionary_set(Ewk_Value dictionary,
Ewk_Value key,
Ewk_Value value,
Eina_Bool* new_entry) {
- LOG_EWK_API_MOCKUP();
- return false;
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(ewk_value_dictionary_is_mutable(dictionary),
+ EINA_FALSE);
+ EWK_VALUE_TYPE_CHECK_RETURN_VAL(key, ewk_value_string_type_get(), EINA_FALSE);
+ base::DictionaryValue* dict;
+ std::string k;
+ bool result1 = EwkValueCast(dictionary)->GetValue()->is_dict();
+ bool result2 = EwkValueCast(key)->GetValue()->is_string();
+ if (result1 && result2) {
+ dict = static_cast<base::DictionaryValue*>(EwkValueCast(dictionary)->GetValue());
+ k = *(EwkValueCast(key)->GetValue()->GetIfString());
+ // TODO(m.majczak) consider a workaround for the deep copy
+ auto val = dict->FindKey(k);
+ auto haskey = (val != nullptr)?true:false;
+ *new_entry = Eina_FromBool(!haskey);
+ dict->Set(k, EwkValueCast(value)->GetValue()->CreateDeepCopy());
+ return EINA_TRUE;
+ } else {
+ return EINA_FALSE;
+ }
}
Eina_Bool ewk_value_dictionary_add(Ewk_Value dictionary,
Ewk_Value key,
Ewk_Value value,
Eina_Bool* new_entry) {
- LOG_EWK_API_MOCKUP();
- return false;
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(ewk_value_dictionary_is_mutable(dictionary),
+ EINA_FALSE);
+ EWK_VALUE_TYPE_CHECK_RETURN_VAL(key, ewk_value_string_type_get(), EINA_FALSE);
+ base::DictionaryValue* dict;
+ std::string k;
+ bool result1 = EwkValueCast(dictionary)->GetValue()->GetAsDictionary(&dict);
+ bool result2 = EwkValueCast(key)->GetValue()->is_string();
+ if (result1 && result2) {
+ k = *(EwkValueCast(key)->GetValue()->GetIfString());
+ auto val = dict->FindKey(k);
+ auto haskey = (val != nullptr)?true:false;
+ if (!haskey) {
+ *new_entry = EINA_TRUE;
+ // TODO(m.majczak) consider a workaround for the deep copy
+ dict->Set(k, EwkValueCast(value)->GetValue()->CreateDeepCopy());
+ return EINA_TRUE;
+ }
+ *new_entry = EINA_FALSE;
+ return EINA_FALSE;
+ } else {
+ return EINA_FALSE;
+ }
}
Eina_Bool ewk_value_dictionary_get(Ewk_Value dictionary,
Ewk_Value key,
Ewk_Value* dst) {
- LOG_EWK_API_MOCKUP();
- return false;
+ EWK_VALUE_TYPE_CHECK_RETURN_VAL(dictionary, ewk_value_dictionary_type_get(),
+ EINA_FALSE);
+ EWK_VALUE_TYPE_CHECK_RETURN_VAL(key, ewk_value_string_type_get(), EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
+ base::DictionaryValue* dict;
+ std::string k;
+ bool result1 = EwkValueCast(dictionary)->GetValue()->GetAsDictionary(&dict);
+ bool result2 = EwkValueCast(key)->GetValue()->is_string();
+ if (result1 && result2) {
+ k = *(EwkValueCast(key)->GetValue()->GetIfString());
+ base::Value* val = nullptr;
+ dict->Get(k, &val);
+ if (!val)
+ return EINA_FALSE;
+ // TODO(m.majczak) consider a workaround for the deep copy
+ Ewk_Value ret = static_cast<Ewk_Value>(
+ new EwkValuePrivate(std::unique_ptr<base::Value>(val->CreateDeepCopy())));
+ // warning!!! the ownership is passed to the caller here
+ ewk_value_ref(ret);
+ *dst = ret;
+ return EINA_TRUE;
+ } else {
+ return EINA_FALSE;
+ }
}
Eina_Bool ewk_value_dictionary_remove(Ewk_Value dictionary, Ewk_Value key) {
- LOG_EWK_API_MOCKUP();
- return false;
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(ewk_value_dictionary_is_mutable(dictionary),
+ EINA_FALSE);
+ EWK_VALUE_TYPE_CHECK_RETURN_VAL(key, ewk_value_string_type_get(), EINA_FALSE);
+ base::DictionaryValue* dict;
+ std::string k;
+ bool result1 = EwkValueCast(dictionary)->GetValue()->GetAsDictionary(&dict);
+ bool result2 = EwkValueCast(key)->GetValue()->is_string();
+ if (result1 && result2) {
+ k = *(EwkValueCast(key)->GetValue()->GetIfString());
+ // warning!!! value is completely deleted here
+ return Eina_FromBool(dict->RemoveKey(k));
+ } else {
+ return EINA_FALSE;
+ }
}
void ewk_view_set_cursor_by_client(Evas_Object* ewkView, Eina_Bool enable) {}
void ewk_view_widget_pepper_extension_callback_set(Evas_Object* ewk_view, Generic_Sync_Call_Callback cb, void* user_data) {
- LOG_EWK_API_MOCKUP();
+#if defined(TIZEN_PEPPER_EXTENSIONS) && defined(OS_TIZEN_TV_PRODUCT)
+ EWK_VIEW_IMPL_GET_OR_RETURN(ewk_view, impl);
+ impl->SetPepperExtensionCallback(cb, user_data);
+#else
+ NOTIMPLEMENTED() << "This API is only available with TIZEN_PEPPER_EXTENSIONS"
+ << " macro on TIZEN_TV products.";
+#endif
}
void ewk_view_widget_pepper_extension_info_set(Evas_Object* ewk_view, Ewk_Value widget_pepper_ext_info) {
- LOG_EWK_API_MOCKUP();
+#if defined(TIZEN_PEPPER_EXTENSIONS) && defined(OS_TIZEN_TV_PRODUCT)
+ EWK_VIEW_IMPL_GET_OR_RETURN(ewk_view, impl);
+ impl->SetPepperExtensionWidgetInfo(widget_pepper_ext_info);
+#else
+ NOTIMPLEMENTED() << "This API is only available with TIZEN_PEPPER_EXTENSIONS"
+ << " macro on TIZEN_TV products.";
+#endif
}
void ewk_view_resume_network_loading(Evas_Object* ewkView)
#include "content/common/locale_efl.h"
#include "content/common/paths_efl.h"
#include "content/public/common/content_switches.h"
+#include "content/public/common/content_plugin_info.h"
#include "content/public/renderer/content_renderer_client.h"
#include "content/public/renderer/render_thread.h"
#include "content/renderer/common_renderer_client.h"
using autofill::PasswordGenerationAgent;
#endif
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+#include "common/trusted_pepper_plugin_info_cache.h"
+#include "common/trusted_pepper_plugin_util.h"
+#endif
+
+#if BUILDFLAG(ENABLE_PLUGINS)
+#include "renderer/pepper/pepper_helper.h"
+#endif
+
// Chromium-efl deliberately uses a different value than
// default_maximum_page_scale_factor (4.0) because it has shown
// better empirical results.
static const float minimum_page_scale_for_mobile = 0.25f;
static const float maximum_page_scale_for_mobile = 5.f;
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+namespace {
+
+bool CreateTrustedPepperPlugin(content::RenderFrame* render_frame,
+ const blink::WebPluginParams& params,
+ blink::WebPlugin** plugin) {
+ if (pepper::AreTrustedPepperPluginsDisabled())
+ return false;
+
+ auto cache = pepper::TrustedPepperPluginInfoCache::GetInstance();
+ content::ContentPluginInfo info;
+ if (cache->FindPlugin(params.mime_type.Utf8(), params.url, &info)) {
+ *plugin =
+ render_frame->CreatePlugin(info.ToWebPluginInfo(), params);
+
+ if (*plugin)
+ return true;
+ }
+
+ return false;
+}
+
+} // namespace
+#endif // defined(TIZEN_PEPPER_EXTENSIONS)
+
+/* LCOV_EXCL_START */
ContentRendererClientEfl::ContentRendererClientEfl() {}
ContentRendererClientEfl::~ContentRendererClientEfl() {}
LOG(INFO) << "Sync application type for render thread: " << app_type;
content::SetApplicationType(
static_cast<content::ApplicationType>(app_type));
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+ pepper::UpdatePluginRegistry();
+#endif
}
#endif
registry);
}
#endif
+#if (defined(TIZEN_PEPPER_EXTENSIONS) && BUILDFLAG(ENABLE_PLUGINS))
+ new pepper::PepperHelper(render_frame);
+#endif
}
void ContentRendererClientEfl::WebViewCreated(
content::RenderFrame* render_frame,
const blink::WebPluginParams& params,
blink::WebPlugin** plugin) {
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+ if (CreateTrustedPepperPlugin(render_frame, params, plugin))
+ return true;
+#endif // TIZEN_PEPPER_EXTENSIONS
#if defined(EWK_BRINGUP) // FIXME: m67 bringup
return false;
#else
--- /dev/null
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright 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.
+
+// Copied from chrome/renderer/pepper with minor modifications.
+
+#include "tizen_src/ewk/efl_integration/renderer/pepper/pepper_helper.h"
+
+#include "components/nacl/common/buildflags.h"
+#include "content/public/renderer/renderer_ppapi_host.h"
+#include "ppapi/buildflags/buildflags.h"
+#include "ppapi/host/ppapi_host.h"
+#include "renderer/pepper/pepper_shared_memory_message_filter.h"
+
+#if BUILDFLAG(ENABLE_NACL)
+#include "content/renderer/pepper/renderer_pepper_host_factory_efl.h"
+#endif
+
+namespace pepper {
+
+PepperHelper::PepperHelper(content::RenderFrame* render_frame)
+ : RenderFrameObserver(render_frame) {}
+
+PepperHelper::~PepperHelper() {}
+
+void PepperHelper::DidCreatePepperPlugin(content::RendererPpapiHost* host) {
+#if BUILDFLAG(ENABLE_NACL)
+ host->GetPpapiHost()->AddHostFactoryFilter(
+ std::make_unique<RendererPepperHostFactoryEfl>(host));
+#endif
+ host->GetPpapiHost()->AddInstanceMessageFilter(
+ std::make_unique<PepperSharedMemoryMessageFilter>(host));
+}
+} // namespace pepper
\ No newline at end of file
--- /dev/null
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright 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 RENDERER_PEPPER_PEPPER_HELPER_H_
+#define RENDERER_PEPPER_PEPPER_HELPER_H_
+
+#include "base/compiler_specific.h"
+#include "content/public/renderer/render_frame_observer.h"
+
+// Copied from chrome/renderer/pepper with minor modifications.
+// This class listens for Pepper creation events from the RenderFrame and
+// attaches the parts required for EFL-specific plugin support.
+namespace pepper {
+
+class PepperHelper : public content::RenderFrameObserver {
+ public:
+ explicit PepperHelper(content::RenderFrame* render_frame);
+ ~PepperHelper() override;
+
+ // RenderFrameObserver.
+ void DidCreatePepperPlugin(content::RendererPpapiHost* host) override;
+
+ void OnDestruct(){};
+};
+} // namespace pepper
+#endif // RENDERER_PEPPER_PEPPER_HELPER_H_
--- /dev/null
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Copyright 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.
+
+// This file is copied from chrome/renderer/pepper/
+// TODO(a.bujalski) consider moving class from chrome/ to content/
+
+#include "renderer/pepper/pepper_shared_memory_message_filter.h"
+
+#include <memory>
+
+#include "base/memory/unsafe_shared_memory_region.h"
+#include "base/process/process_handle.h"
+#include "content/public/common/content_client.h"
+#include "content/public/renderer/pepper_plugin_instance.h"
+#include "content/public/renderer/render_thread.h"
+#include "content/public/renderer/renderer_ppapi_host.h"
+#include "mojo/public/cpp/base/shared_memory_utils.h"
+#include "ppapi/host/ppapi_host.h"
+#include "ppapi/proxy/ppapi_messages.h"
+#include "ppapi/shared_impl/var_tracker.h"
+
+PepperSharedMemoryMessageFilter::PepperSharedMemoryMessageFilter(
+ content::RendererPpapiHost* host)
+ : InstanceMessageFilter(host->GetPpapiHost()), host_(host) {}
+
+PepperSharedMemoryMessageFilter::~PepperSharedMemoryMessageFilter() {}
+
+bool PepperSharedMemoryMessageFilter::OnInstanceMessageReceived(
+ const IPC::Message& msg) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(PepperSharedMemoryMessageFilter, msg)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_SharedMemory_CreateSharedMemory,
+ OnHostMsgCreateSharedMemory)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+bool PepperSharedMemoryMessageFilter::Send(IPC::Message* msg) {
+ return host_->GetPpapiHost()->Send(msg);
+}
+
+void PepperSharedMemoryMessageFilter::OnHostMsgCreateSharedMemory(
+ PP_Instance instance,
+ uint32_t size,
+ int* host_handle_id,
+ ppapi::proxy::SerializedHandle* plugin_handle) {
+ plugin_handle->set_null_shmem_region();
+ *host_handle_id = -1;
+ base::UnsafeSharedMemoryRegion shm =
+ base::UnsafeSharedMemoryRegion::Create(size);
+ if (!shm.IsValid())
+ return;
+
+ plugin_handle->set_shmem_region(
+ base::UnsafeSharedMemoryRegion::TakeHandleForSerialization(
+ host_->ShareUnsafeSharedMemoryRegionWithRemote(shm)));
+
+ *host_handle_id =
+ content::PepperPluginInstance::Get(instance)
+ ->GetVarTracker()
+ ->TrackSharedMemoryRegion(instance, std::move(shm), size);
+}
--- /dev/null
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Copyright 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.
+
+// This file is copied from chrome/renderer/pepper/
+// TODO(a.bujalski) consider moving class from chrome/ to content/
+
+#ifndef RENDERER_PEPPER_PEPPER_SHARED_MEMORY_MESSAGE_FILTER_H_
+#define RENDERER_PEPPER_PEPPER_SHARED_MEMORY_MESSAGE_FILTER_H_
+
+#include "base/compiler_specific.h"
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/host/instance_message_filter.h"
+
+#include <stdint.h>
+
+namespace content {
+class RendererPpapiHost;
+}
+
+namespace ppapi {
+namespace proxy {
+class SerializedHandle;
+}
+} // namespace ppapi
+
+// Implements the backend for shared memory messages from a plugin process.
+class PepperSharedMemoryMessageFilter
+ : public ppapi::host::InstanceMessageFilter {
+ public:
+ explicit PepperSharedMemoryMessageFilter(content::RendererPpapiHost* host);
+ ~PepperSharedMemoryMessageFilter() override;
+
+ // InstanceMessageFilter:
+ bool OnInstanceMessageReceived(const IPC::Message& msg) override;
+
+ bool Send(IPC::Message* msg);
+
+ private:
+ // Message handlers.
+ void OnHostMsgCreateSharedMemory(
+ PP_Instance instance,
+ uint32_t size,
+ int* host_shm_handle_id,
+ ppapi::proxy::SerializedHandle* plugin_shm_handle);
+
+ content::RendererPpapiHost* host_;
+};
+
+#endif // RENDERER_PEPPER_PEPPER_SHARED_MEMORY_MESSAGE_FILTER_H_
--- /dev/null
+// Copyright 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.
+
+#include "base/bind.h"
+#include "base/test/launcher/unit_test_launcher.h"
+#include "base/test/test_suite.h"
+
+int main(int argc, char** argv) {
+ base::TestSuite test_suite(argc, argv);
+
+ return base::LaunchUnitTests(
+ argc, argv,
+ base::Bind(&base::TestSuite::Run, base::Unretained(&test_suite)));
+}
\ No newline at end of file
"utc_blink_ewk_home_directory_set_func.cpp",
]
}
+
+ if(tizen_pepper_extensions) {
+ sources += [
+ "utc_blink_ewk_array_value.cpp",
+ "utc_blink_ewk_boolean_value.cpp",
+ "utc_blink_ewk_dictionary_value.cpp",
+ "utc_blink_ewk_double_value.cpp",
+ "utc_blink_ewk_int_value.cpp",
+ "utc_blink_ewk_string_value.cpp",
+ "utc_blink_ewk_value_compare.h",
+ ]
+ }
}
--- /dev/null
+// Copyright 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.
+
+#include <cstring>
+
+#include "ewk_value_product.h"
+#include "utc_blink_ewk_base.h"
+#include "utc_blink_ewk_value_compare.h"
+
+class utc_blink_ewk_array_value : public utc_blink_ewk_base {};
+
+/*
+Tested structure layout:
+[ bool, int, double, string, array[bool, int, double] ]
+*/
+TEST_F(utc_blink_ewk_array_value, POS_TEST) {
+ // check type
+ Ewk_Value arr = ewk_value_array_new();
+ EXPECT_EQ(ewk_value_type_get(arr), ewk_value_array_type_get());
+ ASSERT_EQ(ewk_value_array_count(arr), 0u);
+ ASSERT_EQ(ewk_value_array_is_mutable(arr), EINA_TRUE);
+
+ // add bool
+ Ewk_Value v = ewk_value_boolean_new(EINA_TRUE);
+ ewk_value_array_append(arr, v);
+ ewk_value_unref(v);
+ ASSERT_EQ(ewk_value_array_count(arr), 1u);
+
+ // add double
+ v = ewk_value_double_new(1.23f);
+ ewk_value_array_append(arr, v);
+ ewk_value_unref(v);
+ ASSERT_EQ(ewk_value_array_count(arr), 2u);
+
+ // add int
+ v = ewk_value_int_new(123);
+ ewk_value_array_append(arr, v);
+ ewk_value_unref(v);
+ ASSERT_EQ(ewk_value_array_count(arr), 3u);
+
+ // add string
+ v = ewk_value_string_new("test_string");
+ ewk_value_array_append(arr, v);
+ ewk_value_unref(v);
+ ASSERT_EQ(ewk_value_array_count(arr), 4u);
+
+ // add another array
+ Ewk_Value arr2 = ewk_value_array_new();
+ // add bool
+ v = ewk_value_boolean_new(EINA_TRUE);
+ ewk_value_array_append(arr2, v);
+ ewk_value_unref(v);
+ ASSERT_EQ(ewk_value_array_count(arr2), 1u);
+ // add double
+ v = ewk_value_double_new(1.23f);
+ ewk_value_array_append(arr2, v);
+ ewk_value_unref(v);
+ ASSERT_EQ(ewk_value_array_count(arr2), 2u);
+ // add int
+ v = ewk_value_int_new(123);
+ ewk_value_array_append(arr2, v);
+ ewk_value_unref(v);
+ ASSERT_EQ(ewk_value_array_count(arr2), 3u);
+
+ // append te second array to array
+ ewk_value_array_append(arr, arr2);
+ ewk_value_unref(arr2);
+ ASSERT_EQ(ewk_value_array_count(arr), 5u);
+
+ // check the values
+ // bool
+ ASSERT_EQ(ewk_value_array_get(arr, 0, &v), EINA_TRUE);
+ EXPECT_EQ(ewk_value_type_get(v), ewk_value_boolean_type_get());
+ Eina_Bool b;
+ ASSERT_EQ(ewk_value_boolean_value_get(v, &b), EINA_TRUE);
+ EXPECT_EQ(b, EINA_TRUE);
+ ewk_value_unref(v);
+
+ // double
+ ASSERT_EQ(ewk_value_array_get(arr, 1, &v), EINA_TRUE);
+ EXPECT_EQ(ewk_value_type_get(v), ewk_value_double_type_get());
+ double d;
+ ASSERT_EQ(ewk_value_double_value_get(v, &d), EINA_TRUE);
+ EXPECT_EQ(d, 1.23f);
+ ewk_value_unref(v);
+
+ // int
+ ASSERT_EQ(ewk_value_array_get(arr, 2, &v), EINA_TRUE);
+ EXPECT_EQ(ewk_value_type_get(v), ewk_value_int_type_get());
+ int i;
+ ASSERT_EQ(ewk_value_int_value_get(v, &i), EINA_TRUE);
+ EXPECT_EQ(i, 123);
+ ewk_value_unref(v);
+
+ // string
+ ASSERT_EQ(ewk_value_array_get(arr, 3, &v), EINA_TRUE);
+ EXPECT_EQ(ewk_value_type_get(v), ewk_value_string_type_get());
+ Eina_Stringshare* str = ewk_value_string_value_get(v);
+ ASSERT_TRUE(str != NULL);
+ EXPECT_STREQ((const char*)str, "test_string");
+ eina_stringshare_del(str);
+ ewk_value_unref(v);
+
+ // array
+ ASSERT_EQ(ewk_value_array_get(arr, 4, &arr2), EINA_TRUE);
+ EXPECT_EQ(ewk_value_type_get(arr2), ewk_value_array_type_get());
+ // check values inside the array
+ // bool
+ ASSERT_EQ(ewk_value_array_get(arr2, 0, &v), EINA_TRUE);
+ EXPECT_EQ(ewk_value_type_get(v), ewk_value_boolean_type_get());
+ ASSERT_EQ(ewk_value_boolean_value_get(v, &b), EINA_TRUE);
+ EXPECT_EQ(b, EINA_TRUE);
+ ewk_value_unref(v);
+ // double
+ ASSERT_EQ(ewk_value_array_get(arr2, 1, &v), EINA_TRUE);
+ EXPECT_EQ(ewk_value_type_get(v), ewk_value_double_type_get());
+ ASSERT_EQ(ewk_value_double_value_get(v, &d), EINA_TRUE);
+ EXPECT_EQ(d, 1.23f);
+ ewk_value_unref(v);
+ // int
+ ASSERT_EQ(ewk_value_array_get(arr2, 2, &v), EINA_TRUE);
+ EXPECT_EQ(ewk_value_type_get(v), ewk_value_int_type_get());
+ ASSERT_EQ(ewk_value_int_value_get(v, &i), EINA_TRUE);
+ EXPECT_EQ(i, 123);
+ ewk_value_unref(v);
+ ewk_value_unref(arr2);
+
+ // remove some values
+ // try to remove out of scope
+ EXPECT_EQ(ewk_value_array_remove(arr, 10), EINA_FALSE);
+ ASSERT_EQ(ewk_value_array_count(arr), 5u);
+
+ // remove bool
+ EXPECT_EQ(ewk_value_array_remove(arr, 0), EINA_TRUE);
+ ASSERT_EQ(ewk_value_array_count(arr), 4u);
+
+ // remove int
+ EXPECT_EQ(ewk_value_array_remove(arr, 1), EINA_TRUE);
+ ASSERT_EQ(ewk_value_array_count(arr), 3u);
+
+ // check values that are left
+ // double
+ ASSERT_EQ(ewk_value_array_get(arr, 0, &v), EINA_TRUE);
+ EXPECT_EQ(ewk_value_type_get(v), ewk_value_double_type_get());
+ ASSERT_EQ(ewk_value_double_value_get(v, &d), EINA_TRUE);
+ EXPECT_EQ(d, 1.23f);
+ ewk_value_unref(v);
+
+ // string
+ ASSERT_EQ(ewk_value_array_get(arr, 1, &v), EINA_TRUE);
+ EXPECT_EQ(ewk_value_type_get(v), ewk_value_string_type_get());
+ str = ewk_value_string_value_get(v);
+ ASSERT_TRUE(str != NULL);
+ EXPECT_STREQ((const char*)str, "test_string");
+ eina_stringshare_del(str);
+ ewk_value_unref(v);
+
+ // try to get value out of scope
+ EXPECT_EQ(ewk_value_array_get(arr, 3, &v), EINA_FALSE);
+
+ ewk_value_unref(arr);
+}
--- /dev/null
+// Copyright 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.
+
+#include <cstring>
+
+#include "ewk_value_product.h"
+#include "utc_blink_ewk_base.h"
+
+class utc_blink_ewk_boolean_value : public utc_blink_ewk_base {};
+
+TEST_F(utc_blink_ewk_boolean_value, POS_TEST) {
+ // check type
+ Ewk_Value v = ewk_value_boolean_new(EINA_TRUE);
+ EXPECT_EQ(ewk_value_type_get(v), ewk_value_boolean_type_get());
+
+ // check for true
+ Eina_Bool b;
+ ASSERT_EQ(ewk_value_boolean_value_get(v, &b), EINA_TRUE);
+ EXPECT_EQ(b, EINA_TRUE);
+ ewk_value_unref(v);
+
+ // check for false
+ v = ewk_value_boolean_new(EINA_FALSE);
+ ASSERT_EQ(ewk_value_boolean_value_get(v, &b), EINA_TRUE);
+ EXPECT_EQ(b, EINA_FALSE);
+ ewk_value_unref(v);
+}
--- /dev/null
+// Copyright 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.
+
+#include <cstring>
+
+#include "ewk_value_product.h"
+#include "utc_blink_ewk_base.h"
+#include "utc_blink_ewk_value_compare.h"
+
+class utc_blink_ewk_dictionary_value : public utc_blink_ewk_base {};
+
+/*
+Tested structure layout:
+- bool_key -> bool
+- int_key -> int
+- double_key -> double
+- string key -> string
+- array_key -> array [bool, int, double]
+- dict_key -> dictionary
+ - bool_key -> bool
+ - int_key -> int
+ - double_key -> double
+*/
+TEST_F(utc_blink_ewk_dictionary_value, POS_TEST) {
+ Ewk_Value dict = ewk_value_dictionary_new();
+ EXPECT_EQ(ewk_value_type_get(dict), ewk_value_dictionary_type_get());
+ ASSERT_EQ(ewk_value_dictionary_is_mutable(dict), EINA_TRUE);
+
+ // prepare test keys
+ Ewk_Value test_values[ArraySize(test_keys)];
+ test_values[BOOL_KEY] = ewk_value_boolean_new(EINA_TRUE);
+ test_values[DOUBLE_KEY] = ewk_value_double_new(1.23f);
+ test_values[INT_KEY] = ewk_value_int_new(123);
+ test_values[STRING_KEY] = ewk_value_string_new("test_string");
+ test_values[ARRAY_KEY] = ewk_value_array_new();
+ ewk_value_array_append(test_values[ARRAY_KEY], test_values[BOOL_KEY]);
+ ewk_value_array_append(test_values[ARRAY_KEY], test_values[DOUBLE_KEY]);
+ ewk_value_array_append(test_values[ARRAY_KEY], test_values[INT_KEY]);
+ test_values[DICT_KEY] = ewk_value_dictionary_new();
+
+ Eina_Bool b;
+
+ // set values in the nested dictionary
+ for (size_t i = BOOL_KEY; i < STRING_KEY; ++i) {
+ Ewk_Value k = ewk_value_string_new(test_keys[i]);
+ ASSERT_EQ(
+ ewk_value_dictionary_add(test_values[DICT_KEY], k, test_values[i], &b),
+ EINA_TRUE);
+ EXPECT_EQ(b, EINA_TRUE);
+ ewk_value_unref(k);
+ }
+
+ // set all dictionary values
+ for (size_t i = BOOL_KEY; i < KEY_COUNT; ++i) {
+ Ewk_Value k = ewk_value_string_new(test_keys[i]);
+ ASSERT_EQ(ewk_value_dictionary_add(dict, k, test_values[i], &b), EINA_TRUE);
+ EXPECT_EQ(b, EINA_TRUE);
+ ewk_value_unref(k);
+ }
+
+ // get keys array
+ Ewk_Value keys;
+ ASSERT_EQ(ewk_value_dictionary_keys(dict, &keys), EINA_TRUE);
+ ASSERT_EQ(ewk_value_type_get(keys), ewk_value_array_type_get());
+ ASSERT_EQ(ewk_value_array_is_mutable(keys), EINA_TRUE);
+ ASSERT_EQ(ewk_value_array_count(keys), ArraySize(test_keys));
+
+ for (size_t i = BOOL_KEY; i < KEY_COUNT; ++i) {
+ Ewk_Value key;
+ ASSERT_EQ(ewk_value_array_get(keys, i, &key), EINA_TRUE);
+ Eina_Stringshare* key_str = ewk_value_string_value_get(key);
+
+ // get index of the key in test data
+ size_t idx;
+ for (idx = BOOL_KEY; idx < KEY_COUNT; ++idx) {
+ if (strcmp(static_cast<const char*>(key_str), test_keys[idx]) == 0)
+ break;
+ }
+
+ Ewk_Value v;
+ ASSERT_EQ(ewk_value_dictionary_get(dict, key, &v), EINA_TRUE);
+ EXPECT_TRUE(Compare(v, test_values[idx]));
+
+ ewk_value_unref(key);
+ ewk_value_unref(v);
+ eina_stringshare_del(key_str);
+ }
+
+ // try some invalid operations
+ Ewk_Value v;
+ Ewk_Value k = ewk_value_string_new("non-existent_key");
+ EXPECT_EQ(ewk_value_dictionary_get(dict, k, &v), EINA_FALSE);
+ ewk_value_unref(k);
+
+ k = ewk_value_string_new(test_keys[INT_KEY]);
+
+ EXPECT_EQ(ewk_value_dictionary_add(dict, k, test_values[INT_KEY], &b),
+ EINA_FALSE);
+ EXPECT_EQ(b, EINA_FALSE);
+
+ EXPECT_EQ(ewk_value_dictionary_set(dict, k, test_values[INT_KEY], &b),
+ EINA_TRUE);
+ EXPECT_EQ(b, EINA_FALSE);
+ ewk_value_unref(k);
+}
--- /dev/null
+// Copyright 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.
+
+#include <cstring>
+
+#include "tizen_src/ewk/efl_integration/public/ewk_value_product.h"
+#include "utc_blink_ewk_base.h"
+
+class utc_blink_ewk_double_value : public utc_blink_ewk_base {};
+
+TEST_F(utc_blink_ewk_double_value, POS_TEST) {
+ // check type
+ Ewk_Value v = ewk_value_double_new(0.0);
+ EXPECT_EQ(ewk_value_type_get(v), ewk_value_double_type_get());
+ ewk_value_unref(v);
+
+ // check value range
+ double d;
+ for (int i = -100; i < 100; ++i) {
+ double d2 = static_cast<double>(i) * M_PI;
+ v = ewk_value_double_new(d2);
+ ASSERT_EQ(ewk_value_double_value_get(v, &d), EINA_TRUE);
+ EXPECT_EQ(d, d2);
+ ewk_value_unref(v);
+ }
+}
--- /dev/null
+// Copyright 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.
+
+#include <cstring>
+
+#include "ewk_value_product.h"
+#include "utc_blink_ewk_base.h"
+
+class utc_blink_ewk_int_value : public utc_blink_ewk_base {};
+
+TEST_F(utc_blink_ewk_int_value, POS_TEST) {
+ // check type
+ Ewk_Value v = ewk_value_int_new(0);
+ EXPECT_EQ(ewk_value_type_get(v), ewk_value_int_type_get());
+ ewk_value_unref(v);
+
+ // check value range
+ int n;
+ for (int i = -100; i < 100; ++i) {
+ v = ewk_value_int_new(i);
+ ASSERT_EQ(ewk_value_int_value_get(v, &n), EINA_TRUE);
+ EXPECT_EQ(n, i);
+ ewk_value_unref(v);
+ }
+}
--- /dev/null
+// Copyright 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.
+
+#include <cstring>
+
+#include "ewk_value_product.h"
+#include "utc_blink_ewk_base.h"
+#include "utc_blink_ewk_value_compare.h"
+
+class utc_blink_ewk_string_value : public utc_blink_ewk_base {};
+
+TEST_F(utc_blink_ewk_string_value, POS_TEST) {
+ // check type
+ Ewk_Value v = ewk_value_string_new("");
+ EXPECT_EQ(ewk_value_type_get(v), ewk_value_string_type_get());
+ ewk_value_unref(v);
+
+ // check value range
+ for (size_t i = 0; i < ArraySize(test_strings); ++i) {
+ v = ewk_value_string_new(test_strings[i]);
+ Eina_Stringshare* str = ewk_value_string_value_get(v);
+ ASSERT_TRUE(str != NULL);
+ EXPECT_STREQ((const char*)str, test_strings[i]);
+ eina_stringshare_del(str);
+ ewk_value_unref(v);
+ }
+}
--- /dev/null
+// Copyright 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.
+
+#include <cstring>
+
+#include "ewk_value_product.h"
+#include "utc_blink_ewk_base.h"
+
+template <typename T, size_t N>
+size_t ArraySize(T (&)[N]) {
+ return N;
+}
+
+namespace {
+
+const char* test_strings[] = {
+ "", // empty
+ "a", // one char
+ " \n\n", // white space string
+ "testtesttest", // continous text string
+ "1 2 3 4 5 6 7 8 9 0", // digits
+ "test test test 1 2 3 4 5 6 7 8 9 0" // mixed
+};
+
+const char* test_keys[] = {"bool_key", "double_key", "int_key",
+ "string_key", "array_key", "dictionary_key"};
+
+enum TestKeysTypes {
+ BOOL_KEY,
+ DOUBLE_KEY,
+ INT_KEY,
+ STRING_KEY,
+ ARRAY_KEY,
+ DICT_KEY,
+ KEY_COUNT
+};
+
+bool CompareString(Ewk_Value v1, Ewk_Value v2);
+bool CompareArray(Ewk_Value v1, Ewk_Value v2);
+bool CompareDictionary(Ewk_Value v1, Ewk_Value v2);
+
+bool Compare(Ewk_Value v1, Ewk_Value v2) {
+ if (ewk_value_type_get(v1) != ewk_value_type_get(v2))
+ return false;
+
+ if (ewk_value_type_get(v1) == ewk_value_boolean_type_get()) {
+ Eina_Bool b1, b2;
+ ewk_value_boolean_value_get(v1, &b1);
+ ewk_value_boolean_value_get(v2, &b2);
+ return b1 == b2;
+ } else if (ewk_value_type_get(v1) == ewk_value_double_type_get()) {
+ double d1, d2;
+ ewk_value_double_value_get(v1, &d1);
+ ewk_value_double_value_get(v2, &d2);
+ return d1 == d2;
+ } else if (ewk_value_type_get(v1) == ewk_value_int_type_get()) {
+ int i1, i2;
+ ewk_value_int_value_get(v1, &i1);
+ ewk_value_int_value_get(v2, &i2);
+ return i1 == i2;
+ } else if (ewk_value_type_get(v1) == ewk_value_string_type_get()) {
+ return CompareString(v1, v2);
+ } else if (ewk_value_type_get(v1) == ewk_value_array_type_get()) {
+ return CompareArray(v1, v2);
+ } else if (ewk_value_type_get(v1) == ewk_value_dictionary_type_get()) {
+ return CompareDictionary(v1, v2);
+ } else {
+ return false;
+ }
+}
+
+bool CompareString(Ewk_Value v1, Ewk_Value v2) {
+ if (ewk_value_type_get(v1) != ewk_value_string_type_get() ||
+ ewk_value_type_get(v2) != ewk_value_string_type_get())
+ return false;
+
+ Eina_Stringshare* s1 = ewk_value_string_value_get(v1);
+ Eina_Stringshare* s2 = ewk_value_string_value_get(v2);
+ bool cmp =
+ strcmp(static_cast<const char*>(s1), static_cast<const char*>(s2)) == 0;
+ eina_stringshare_del(s1);
+ eina_stringshare_del(s2);
+ return cmp;
+}
+
+bool CompareArray(Ewk_Value v1, Ewk_Value v2) {
+ if (ewk_value_type_get(v1) != ewk_value_array_type_get() ||
+ ewk_value_type_get(v2) != ewk_value_array_type_get() ||
+ ewk_value_array_is_mutable(v1) == EINA_FALSE ||
+ ewk_value_array_is_mutable(v2) == EINA_FALSE ||
+ ewk_value_array_count(v1) != ewk_value_array_count(v2))
+ return false;
+
+ size_t count = ewk_value_array_count(v1);
+ for (size_t i = 0; i < count; ++i) {
+ Ewk_Value a1, a2;
+ if (ewk_value_array_get(v1, i, &a1) == EINA_FALSE)
+ return false;
+ if (ewk_value_array_get(v2, i, &a2) == EINA_FALSE) {
+ ewk_value_unref(a1);
+ return false;
+ }
+ bool cmp = Compare(a1, a2);
+ ewk_value_unref(a1);
+ ewk_value_unref(a2);
+ if (!cmp)
+ return false;
+ }
+ return true;
+}
+
+bool CompareDictionary(Ewk_Value v1, Ewk_Value v2) {
+ if (ewk_value_type_get(v1) != ewk_value_dictionary_type_get() ||
+ ewk_value_type_get(v2) != ewk_value_dictionary_type_get() ||
+ ewk_value_dictionary_is_mutable(v1) == EINA_FALSE ||
+ ewk_value_dictionary_is_mutable(v2) == EINA_FALSE)
+ return false;
+
+ Ewk_Value k;
+ if (ewk_value_dictionary_keys(v1, &k) == EINA_FALSE)
+ return false;
+
+ size_t count = ewk_value_array_count(k);
+ for (size_t i = 0; i < count; ++i) {
+ Ewk_Value key;
+ if (ewk_value_array_get(k, i, &key) == EINA_FALSE)
+ return false;
+
+ Ewk_Value a1, a2;
+ if (ewk_value_dictionary_get(v1, key, &a1) == EINA_FALSE) {
+ ewk_value_unref(k);
+ return false;
+ }
+ if (ewk_value_dictionary_get(v2, key, &a2) == EINA_FALSE) {
+ ewk_value_unref(k);
+ ewk_value_unref(a1);
+ return false;
+ }
+
+ bool cmp = Compare(a1, a2);
+ ewk_value_unref(a1);
+ ewk_value_unref(a2);
+ if (!cmp) {
+ ewk_value_unref(k);
+ return false;
+ }
+ }
+ ewk_value_unref(k);
+ return true;
+}
+
+} // namespace
#include "base/strings/string_number_conversions.h"
#include "components/visitedlink/renderer/visitedlink_reader.h"
#include "content/public/common/content_switches.h"
+#include "content/public/common/content_plugin_info.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_thread.h"
#include "electron/shell/common/options_switches.h"
#include "tizen_src/ewk/efl_integration/common/trusted_pepper_plugin_util.h"
#endif
-#if BUILDFLAG(ENABLE_PLUGINS) && !defined(WRT_JS_BRINGUP)
+#if BUILDFLAG(ENABLE_PLUGINS)
#include "tizen_src/ewk/efl_integration/renderer/pepper/pepper_helper.h"
#endif
return false;
auto cache = pepper::TrustedPepperPluginInfoCache::GetInstance();
- content::PepperPluginInfo info;
+ content::ContentPluginInfo info;
std::string pkg_id = ApplicationData::GetInstance().GetPackageID();
LOG(INFO) << "WRTRendererClient::CreateTrustedPepperPlugin, plugin cache "
"will FindPlugin(), mime "
<< params.mime_type.Utf8();
- if (cache->FindPlugin(params.mime_type.Utf8(), params.url, &info, pkg_id)) {
+ if (cache->FindPlugin(params.mime_type.Utf8(), params.url, &info)) {
LOG(INFO) << "plugin found! is_out_of_process " << info.is_out_of_process
<< ", path " << info.path.value() << ", name " << info.name
<< ", permissions " << info.permissions