From 6a4bf28a017ac772f74ce626c32b8b40cf2121f7 Mon Sep 17 00:00:00 2001 From: jiangyuwei Date: Tue, 7 Mar 2023 17:02:13 +0800 Subject: [PATCH 01/16] [M108 Migration][VD] Implement Multi port RWI RWI server can use easily to debug application. Multi port RWI can let 3 applications debug at the same time. Normal RWI server should start when WebContents init. For RELEASE_MODE shuold use ewk_view_inspector_server_start to start RWI server. Reference: - https://review.tizen.org/gerrit/279379/ - https://review.tizen.org/gerrit/281862/ Change-Id: I9dd2be6d0d59c390bb271d004e67b9add29df546 Signed-off-by: jiangyuwei --- content/browser/BUILD.gn | 1 + content/browser/devtools/devtools_http_handler.cc | 45 ++- content/browser/devtools/devtools_http_handler.h | 8 + .../browser/devtools/devtools_video_consumer.cc | 9 +- content/browser/web_contents/web_contents_impl.cc | 5 + .../public/browser/devtools_manager_delegate.cc | 5 + content/public/browser/devtools_manager_delegate.h | 6 +- content/public/browser/javascript_dialog_manager.h | 4 + .../chromium_impl/content/browser/browser_efl.gni | 2 + .../browser/inspector/devtools_util_manager.cc | 172 ++++++++++++ .../browser/inspector/devtools_util_manager.h | 40 +++ tizen_src/ewk/efl_integration/BUILD.gn | 6 + .../browser/javascript_dialog_manager_efl.cc | 9 + .../browser/javascript_dialog_manager_efl.h | 3 + .../ewk/efl_integration/browser_main_parts_efl.cc | 4 +- .../efl_integration/common/content_client_efl.cc | 2 +- .../efl_integration/content_browser_client_efl.cc | 8 +- .../efl_integration/content_browser_client_efl.h | 2 + .../efl_integration/content_main_delegate_efl.cc | 40 ++- .../efl_integration/content_main_delegate_efl.h | 15 +- .../ewk/efl_integration/devtools_delegate_efl.cc | 113 ++------ .../ewk/efl_integration/devtools_delegate_efl.h | 21 +- .../ewk/efl_integration/devtools_port_manager.cc | 304 +++++++++++++++++++++ .../ewk/efl_integration/devtools_port_manager.h | 62 +++++ tizen_src/ewk/efl_integration/devtools_port_msg.cc | 67 +++++ tizen_src/ewk/efl_integration/devtools_port_msg.h | 14 + .../efl_integration/devtools_port_shared_memory.cc | 137 ++++++++++ .../efl_integration/devtools_port_shared_memory.h | 64 +++++ tizen_src/ewk/efl_integration/eweb_context.cc | 40 ++- tizen_src/ewk/efl_integration/eweb_context.h | 5 + tizen_src/ewk/efl_integration/eweb_view.cc | 69 +++++ tizen_src/ewk/efl_integration/eweb_view.h | 20 ++ .../efl_integration/web_contents_delegate_efl.cc | 42 +++ .../efl_integration/web_contents_delegate_efl.h | 1 + .../efl_integration/web_contents_observer_efl.cc | 14 +- wrt/src/browser/api/tv/wrt_api_tv_extension.cc | 11 +- wrt/src/browser/api/wrt_api_web_runtime.cc | 7 +- wrt/src/browser/wrt_devtools_manager_delegate.cc | 4 +- wrt/src/browser/wrt_devtools_manager_delegate.h | 2 +- 39 files changed, 1236 insertions(+), 147 deletions(-) create mode 100644 tizen_src/chromium_impl/content/browser/inspector/devtools_util_manager.cc create mode 100644 tizen_src/chromium_impl/content/browser/inspector/devtools_util_manager.h create mode 100644 tizen_src/ewk/efl_integration/devtools_port_manager.cc create mode 100644 tizen_src/ewk/efl_integration/devtools_port_manager.h create mode 100644 tizen_src/ewk/efl_integration/devtools_port_msg.cc create mode 100644 tizen_src/ewk/efl_integration/devtools_port_msg.h create mode 100644 tizen_src/ewk/efl_integration/devtools_port_shared_memory.cc create mode 100644 tizen_src/ewk/efl_integration/devtools_port_shared_memory.h diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index cb36b60..d3c3c0c 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn @@ -59,6 +59,7 @@ source_set("browser") { frameworks = [] ldflags = [] + include_dirs = [ "//tizen_src/ewk/efl_integration/" ] if (use_efl) { configs += external_content_browser_efl_configs } diff --git a/content/browser/devtools/devtools_http_handler.cc b/content/browser/devtools/devtools_http_handler.cc index 286e99d..cb0697e 100644 --- a/content/browser/devtools/devtools_http_handler.cc +++ b/content/browser/devtools/devtools_http_handler.cc @@ -143,6 +143,10 @@ class ServerWrapper : net::HttpServer::Delegate { void Send500(int connection_id, const std::string& message); void Close(int connection_id); +#if BUILDFLAG(IS_TIZEN_TV) + base::WeakPtr GetHttpHandle() { return handler_; } +#endif + ~ServerWrapper() override {} private: @@ -220,10 +224,25 @@ void TerminateOnUI(std::unique_ptr thread, std::unique_ptr server_wrapper, std::unique_ptr socket_factory) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (server_wrapper) +#if BUILDFLAG(IS_TIZEN_TV) + base::WeakPtr handler; +#endif + if (server_wrapper) { +#if BUILDFLAG(IS_TIZEN_TV) + handler = server_wrapper->GetHttpHandle(); +#endif thread->task_runner()->DeleteSoon(FROM_HERE, std::move(server_wrapper)); - if (socket_factory) + } + if (socket_factory) { thread->task_runner()->DeleteSoon(FROM_HERE, std::move(socket_factory)); +#if BUILDFLAG(IS_TIZEN_TV) + if (handler) { + thread->task_runner()->PostTask( + FROM_HERE, + base::BindOnce(&DevToolsHttpHandler::ReleasePort, handler)); + } +#endif + } if (thread) { base::ThreadPool::PostTask( FROM_HERE, @@ -438,7 +457,15 @@ void ServerWrapper::OnHttpRequest(int connection_id, } server_->SetSendBufferSize(connection_id, kSendBufferSizeForDevTools); - +#if BUILDFLAG(IS_TIZEN_TV) + if (info.path.find("/closeport") == 0) { + // close first listened port + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&DevToolsHttpHandler::OnTerminateSocket, + handler_, connection_id)); + return; + } +#endif if (base::StartsWith(info.path, "/json", base::CompareCase::SENSITIVE)) { GetUIThreadTaskRunner({})->PostTask( FROM_HERE, base::BindOnce(&DevToolsHttpHandler::OnJsonRequest, handler_, @@ -547,6 +574,18 @@ static bool ParseJsonPath( return true; } +#if BUILDFLAG(IS_TIZEN_TV) +void DevToolsHttpHandler::OnTerminateSocket(int connection_id) { + server_wrapper_->Send200(connection_id, "OK", "text/html"); + TerminateOnUI(std::move(thread_), std::move(server_wrapper_), + std::move(socket_factory_)); +} + +void DevToolsHttpHandler::ReleasePort() { + delegate_->ReleasePort(); +} +#endif + // These values are persisted to logs. Entries should not be renumbered and // numeric values should never be reused. enum class DevToolsMutatingHttpActionVerb { diff --git a/content/browser/devtools/devtools_http_handler.h b/content/browser/devtools/devtools_http_handler.h index 04a4905..cd8710e 100644 --- a/content/browser/devtools/devtools_http_handler.h +++ b/content/browser/devtools/devtools_http_handler.h @@ -56,6 +56,10 @@ class DevToolsHttpHandler { ~DevToolsHttpHandler(); +#if BUILDFLAG(IS_TIZEN_TV) + void ReleasePort(); +#endif + private: friend class ServerWrapper; friend void ServerStartedOnUI( @@ -65,6 +69,10 @@ class DevToolsHttpHandler { DevToolsSocketFactory* socket_factory, std::unique_ptr ip_address); +#if BUILDFLAG(IS_TIZEN_TV) + void OnTerminateSocket(int connection_id); +#endif + void OnJsonRequest(int connection_id, const net::HttpServerRequestInfo& info); void RespondToJsonList(int connection_id, diff --git a/content/browser/devtools/devtools_video_consumer.cc b/content/browser/devtools/devtools_video_consumer.cc index a803636..835d7b7 100644 --- a/content/browser/devtools/devtools_video_consumer.cc +++ b/content/browser/devtools/devtools_video_consumer.cc @@ -11,6 +11,7 @@ #include "cc/paint/skia_paint_canvas.h" #include "components/viz/common/surfaces/subtree_capture_id.h" #include "components/viz/host/host_frame_sink_manager.h" +#include "components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl.h" #include "content/browser/compositor/surface_utils.h" #include "media/base/limits.h" #include "media/capture/mojom/video_capture_buffer.mojom.h" @@ -35,7 +36,10 @@ constexpr media::VideoPixelFormat kDefaultPixelFormat = // Creates a ClientFrameSinkVideoCapturer via HostFrameSinkManager. std::unique_ptr CreateCapturer() { - return GetHostFrameSinkManager()->CreateVideoCapturer(); + if (GetHostFrameSinkManager()) + return GetHostFrameSinkManager()->CreateVideoCapturer(); + else + return nullptr; } } // namespace @@ -115,7 +119,8 @@ void DevToolsVideoConsumer::SetFormat(media::VideoPixelFormat format) { void DevToolsVideoConsumer::InnerStartCapture( std::unique_ptr capturer) { capturer_ = std::move(capturer); - + if (!capturer_) + return; // Give |capturer_| the capture parameters. capturer_->SetMinCapturePeriod(min_capture_period_); capturer_->SetMinSizeChangePeriod(kDefaultMinPeriod); diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index b8dbef7..5a50360 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc @@ -8438,6 +8438,11 @@ void WebContentsImpl::OnDialogClosed(int render_process_id, for (auto* handler : page_handlers) handler->DidCloseJavaScriptDialog(success, user_input); +#if BUILDFLAG(IS_TIZEN_TV) + if (dialog_manager_) + dialog_manager_->OnDialogClosed(this); +#endif + is_showing_javascript_dialog_ = false; is_showing_before_unload_dialog_ = false; } diff --git a/content/public/browser/devtools_manager_delegate.cc b/content/public/browser/devtools_manager_delegate.cc index 70900b1..30d31f5 100644 --- a/content/public/browser/devtools_manager_delegate.cc +++ b/content/public/browser/devtools_manager_delegate.cc @@ -70,6 +70,11 @@ std::string DevToolsManagerDelegate::GetDiscoveryPageHTML() { return std::string(); } +std::string DevToolsManagerDelegate::GetFrontendResource( + const std::string& path) { + return std::string(); +} + bool DevToolsManagerDelegate::HasBundledFrontendResources() { return false; } diff --git a/content/public/browser/devtools_manager_delegate.h b/content/public/browser/devtools_manager_delegate.h index cdd9888..facfa79 100644 --- a/content/public/browser/devtools_manager_delegate.h +++ b/content/public/browser/devtools_manager_delegate.h @@ -75,7 +75,7 @@ class CONTENT_EXPORT DevToolsManagerDelegate { // Should return discovery page HTML that should list available tabs // and provide attach links. virtual std::string GetDiscoveryPageHTML(); - + virtual std::string GetFrontendResource(const std::string& path); // Returns whether frontend resources are bundled within the binary. virtual bool HasBundledFrontendResources(); @@ -89,6 +89,10 @@ class CONTENT_EXPORT DevToolsManagerDelegate { virtual bool IsBrowserTargetDiscoverable(); virtual ~DevToolsManagerDelegate(); + +#if BUILDFLAG(IS_TIZEN_TV) + virtual void ReleasePort() {} +#endif }; } // namespace content diff --git a/content/public/browser/javascript_dialog_manager.h b/content/public/browser/javascript_dialog_manager.h index bb0abaf..7449c64 100644 --- a/content/public/browser/javascript_dialog_manager.h +++ b/content/public/browser/javascript_dialog_manager.h @@ -55,6 +55,10 @@ class CONTENT_EXPORT JavaScriptDialogManager { virtual void CancelDialogs(WebContents* web_contents, bool reset_state) = 0; +#if BUILDFLAG(IS_TIZEN_TV) + virtual void OnDialogClosed(WebContents* web_contents) {} +#endif + virtual ~JavaScriptDialogManager() {} }; diff --git a/tizen_src/chromium_impl/content/browser/browser_efl.gni b/tizen_src/chromium_impl/content/browser/browser_efl.gni index 03a1545..158df51 100644 --- a/tizen_src/chromium_impl/content/browser/browser_efl.gni +++ b/tizen_src/chromium_impl/content/browser/browser_efl.gni @@ -118,6 +118,8 @@ external_content_browser_efl_sources = [ "//tizen_src/chromium_impl/content/browser/web_contents/web_drag_dest_efl.h", "//tizen_src/chromium_impl/content/browser/web_contents/web_drag_source_efl.cc", "//tizen_src/chromium_impl/content/browser/web_contents/web_drag_source_efl.h", + "//tizen_src/chromium_impl/content/browser/inspector/devtools_util_manager.cc", + "//tizen_src/chromium_impl/content/browser/inspector/devtools_util_manager.h", ] external_content_browser_efl_sources += [ diff --git a/tizen_src/chromium_impl/content/browser/inspector/devtools_util_manager.cc b/tizen_src/chromium_impl/content/browser/inspector/devtools_util_manager.cc new file mode 100644 index 0000000..9211312 --- /dev/null +++ b/tizen_src/chromium_impl/content/browser/inspector/devtools_util_manager.cc @@ -0,0 +1,172 @@ +// Copyright 2020 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 "devtools_util_manager.h" + +#include "base/command_line.h" +#include "base/strings/string_number_conversions.h" +#include "content/public/browser/devtools_agent_host.h" +#include "content/public/browser/devtools_frontend_host.h" +#include "content/public/browser/devtools_socket_factory.h" +#include "content/public/common/content_switches.h" +#include "net/base/net_errors.h" +#include "net/socket/tcp_server_socket.h" +#include "third_party/zlib/google/compression_utils.h" + +#if BUILDFLAG(IS_TIZEN_TV) +#include "devtools_port_manager.h" +#endif + +using content::DevToolsAgentHost; + +namespace content { + +// Copy of internal class implementation from +// content/shell/browser/shell_devtools_delegate.cc + +const int kBackLog = 10; + +class TCPServerSocketFactory : public content::DevToolsSocketFactory { + public: + TCPServerSocketFactory(const std::string& address, uint16_t port) + : server_socket_(nullptr), address_(address), port_(port) {} + TCPServerSocketFactory(std::unique_ptr server_socket) + : server_socket_(server_socket.release()), port_(0) {} + + private: + std::unique_ptr CreateForHttpServer() override { + if (server_socket_) + return std::unique_ptr(server_socket_); + std::unique_ptr socket( + new net::TCPServerSocket(nullptr, net::NetLogSource())); + if (socket->ListenWithAddressAndPort(address_, port_, kBackLog) != net::OK) + return std::unique_ptr(); + + return socket; + } + + std::unique_ptr CreateForTethering( + std::string* out_name) override { + return nullptr; + } + + net::ServerSocket* server_socket_; + std::string address_; + uint16_t port_; +}; + +// static +uint16_t DevToolsUtilManager::port_ = 0; + +DevToolsUtilManager::DevToolsUtilManager() = default; +DevToolsUtilManager::~DevToolsUtilManager() = default; + +DevToolsUtilManager* DevToolsUtilManager::GetInstance() { + static DevToolsUtilManager instance; + return &instance; +} + +int DevToolsUtilManager::StartDebugServer(int port) { + if (port_ > 0) + return port_; + + // It's a hacky way to early detected if port is available. The problem is + // that the only thing we can do after checking is hope that noone will take + // the port until it's initialized on IO thread again. The best approach would + // be creating async callbacks that would inform when inspector server started + // and on which port. + static std::string addr = "0.0.0.0"; + std::unique_ptr sock( + new net::TCPServerSocket(nullptr, net::NetLogSource())); + + const base::CommandLine* const command_line = + base::CommandLine::ForCurrentProcess(); + // See if the user specified a port on the command line (useful for + // automation). If not, use an ephemeral port by specifying 0. + if (!port && command_line->HasSwitch(switches::kRemoteDebuggingPort)) { + int temp_port = 0; + std::string port_str = + command_line->GetSwitchValueASCII(switches::kRemoteDebuggingPort); + if (base::StringToInt(port_str, &temp_port) && temp_port >= 0 && + temp_port < 65535) { + port = temp_port; + } else { + LOG(WARNING) << "Invalid http debugger port number " << temp_port; + } + } + + // why backlog is 1? + if (sock->ListenWithAddressAndPort(addr, port, 1) != net::OK) { + port_ = 0; +#if BUILDFLAG(IS_TIZEN_TV) + ReleasePort(); +#endif + return port_; + } + + net::IPEndPoint givenIp; + sock->GetLocalAddress(&givenIp); + port_ = givenIp.port(); + LOG(INFO) << "Devtool port:" << port_; + + std::unique_ptr factory( + new TCPServerSocketFactory(std::move(sock))); + DevToolsAgentHost::StartRemoteDebuggingServer( + std::move(factory), base::FilePath(), base::FilePath()); + + return port_; +} + +bool DevToolsUtilManager::StopDebugServer() { + if (port_ == 0) + return false; + port_ = 0; + DevToolsAgentHost::StopRemoteDebuggingServer(); + return true; +} + +unsigned int DevToolsUtilManager::InspectorServerStart(int port) { + InspectorServerStop(); +#if BUILDFLAG(IS_TIZEN_TV) + devtools_http_handler::DevToolsPortManager* port_manager = + devtools_http_handler::DevToolsPortManager::GetInstance(); + if (!port && (port_manager && port_manager->ProcessCompare())) { + if (port_manager->GetValidPort(port)) + port_manager->SetPort(port); + } +#endif + return StartDebugServer(port); +} + +bool DevToolsUtilManager::InspectorServerStop() { + if (!StopDebugServer()) + return false; +#if BUILDFLAG(IS_TIZEN_TV) + ReleasePort(); +#endif + return true; +} + +std::string DevToolsUtilManager::GetFrontendResource(const std::string& path) { + const std::string data = + content::DevToolsFrontendHost::GetFrontendResource(path); + // Detect gzip resource with the gzip magic number(1f 8b) in header + if (data.length() > 2 && data[0] == '\x1F' && data[1] == '\x8B') { + std::string uncompressed_data; + + if (compression::GzipUncompress(data, &uncompressed_data)) + return uncompressed_data; + LOG(ERROR) << "Failed to uncompress " << path; + } + return data; +} + +#if BUILDFLAG(IS_TIZEN_TV) +void DevToolsUtilManager::ReleasePort() { + if (devtools_http_handler::DevToolsPortManager::GetInstance()) + devtools_http_handler::DevToolsPortManager::GetInstance()->ReleasePort(); +} +#endif + +} // namespace content diff --git a/tizen_src/chromium_impl/content/browser/inspector/devtools_util_manager.h b/tizen_src/chromium_impl/content/browser/inspector/devtools_util_manager.h new file mode 100644 index 0000000..77e9f52 --- /dev/null +++ b/tizen_src/chromium_impl/content/browser/inspector/devtools_util_manager.h @@ -0,0 +1,40 @@ +// Copyright 2020 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 DEVTOOLS_UTIL_MANAGER_H_ +#define DEVTOOLS_UTIL_MANAGER_H_ + +#include +#include "build/buildflag.h" +#include "build/build_config.h" + +namespace content { + +class DevToolsUtilManager { + public: + DevToolsUtilManager(); + virtual ~DevToolsUtilManager(); + + static DevToolsUtilManager* GetInstance(); + + unsigned int InspectorServerStart(int port = 0); + bool InspectorServerStop(); + + std::string GetFrontendResource(const std::string& path); + +#if BUILDFLAG(IS_TIZEN_TV) + static uint16_t GetPort() { return port_; } + void ReleasePort(); +#endif + + private: + int StartDebugServer(int port); + bool StopDebugServer(); + + static uint16_t port_; +}; + +} // namespace content + +#endif // DEVTOOLS_UTIL_MANAGER_H_ diff --git a/tizen_src/ewk/efl_integration/BUILD.gn b/tizen_src/ewk/efl_integration/BUILD.gn index 33fac56..87210fc 100755 --- a/tizen_src/ewk/efl_integration/BUILD.gn +++ b/tizen_src/ewk/efl_integration/BUILD.gn @@ -650,6 +650,12 @@ shared_library("chromium-ewk") { "wrt/hbbtv_widget.h", "wrt/hbbtv_widget_host.cc", "wrt/hbbtv_widget_host.h", + "devtools_port_manager.cc", + "devtools_port_manager.h", + "devtools_port_msg.cc", + "devtools_port_msg.h", + "devtools_port_shared_memory.cc", + "devtools_port_shared_memory.h", ] } diff --git a/tizen_src/ewk/efl_integration/browser/javascript_dialog_manager_efl.cc b/tizen_src/ewk/efl_integration/browser/javascript_dialog_manager_efl.cc index 3a5b308..6b00fc3 100644 --- a/tizen_src/ewk/efl_integration/browser/javascript_dialog_manager_efl.cc +++ b/tizen_src/ewk/efl_integration/browser/javascript_dialog_manager_efl.cc @@ -112,6 +112,15 @@ void JavaScriptDialogManagerEfl::SetPopupSize(int width, int height) { dialog_->SetPopupSize(width, height); } +#if BUILDFLAG(IS_TIZEN_TV) +void JavaScriptDialogManagerEfl::OnDialogClosed( + content::WebContents* web_contents) { + EWebView* wv = WebViewFromWebContents(web_contents); + if (wv) + wv->OnDialogClosed(); +} +#endif + void JavaScriptDialogManagerEfl::RunBeforeUnloadDialog( content::WebContents* web_contents, content::RenderFrameHost* render_frame_host, diff --git a/tizen_src/ewk/efl_integration/browser/javascript_dialog_manager_efl.h b/tizen_src/ewk/efl_integration/browser/javascript_dialog_manager_efl.h index 9524650..b37f81e 100644 --- a/tizen_src/ewk/efl_integration/browser/javascript_dialog_manager_efl.h +++ b/tizen_src/ewk/efl_integration/browser/javascript_dialog_manager_efl.h @@ -52,6 +52,9 @@ class JavaScriptDialogManagerEfl : public content::JavaScriptDialogManager { void* user_data); void ExecuteDialogClosedCallBack(bool result, const std::string prompt_data); void SetPopupSize(int width, int height); +#if BUILDFLAG(IS_TIZEN_TV) + void OnDialogClosed(content::WebContents* web_contents) override; +#endif void SetBeforeUnloadConfirmPanelCallback( Ewk_View_Before_Unload_Confirm_Panel_Callback callback, void* user_data); diff --git a/tizen_src/ewk/efl_integration/browser_main_parts_efl.cc b/tizen_src/ewk/efl_integration/browser_main_parts_efl.cc index a95d634..892d028 100644 --- a/tizen_src/ewk/efl_integration/browser_main_parts_efl.cc +++ b/tizen_src/ewk/efl_integration/browser_main_parts_efl.cc @@ -9,6 +9,7 @@ #include "base/base_switches.h" #include "base/command_line.h" +#include "content/browser/inspector/devtools_util_manager.h" #include "content/public/common/content_switches.h" #include "content/public/common/result_codes.h" @@ -32,8 +33,7 @@ int BrowserMainPartsEfl::PreMainMessageLoopRun() { } void BrowserMainPartsEfl::PostMainMessageLoopRun() { - if (devtools_delegate_) - devtools_delegate_->Stop(); + DevToolsUtilManager::GetInstance()->InspectorServerStop(); } } // namespace diff --git a/tizen_src/ewk/efl_integration/common/content_client_efl.cc b/tizen_src/ewk/efl_integration/common/content_client_efl.cc index ddf0186..7dd5a2d 100644 --- a/tizen_src/ewk/efl_integration/common/content_client_efl.cc +++ b/tizen_src/ewk/efl_integration/common/content_client_efl.cc @@ -5,8 +5,8 @@ #include "common/content_client_efl.h" #include "ipc/ipc_message.h" -#include "ui/base/resource/resource_bundle.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/base/resource/resource_bundle.h" std::u16string ContentClientEfl::GetLocalizedString(int message_id) { // TODO(boliu): Used only by WebKit, so only bundle those resources for diff --git a/tizen_src/ewk/efl_integration/content_browser_client_efl.cc b/tizen_src/ewk/efl_integration/content_browser_client_efl.cc index e40da0e..58b9c64 100644 --- a/tizen_src/ewk/efl_integration/content_browser_client_efl.cc +++ b/tizen_src/ewk/efl_integration/content_browser_client_efl.cc @@ -443,10 +443,12 @@ void ContentBrowserClientEfl::RenderProcessWillLaunch( host->AddFilter(new RenderMessageFilterEfl(host->GetID())); } -content::DevToolsManagerDelegate* -ContentBrowserClientEfl::GetDevToolsManagerDelegate() { - return new DevToolsManagerDelegateEfl(); +/* LCOV_EXCL_START */ +std::unique_ptr +ContentBrowserClientEfl::CreateDevToolsManagerDelegate() { + return std::make_unique(); } +/* LCOV_EXCL_STOP */ std::string ContentBrowserClientEfl::GetApplicationLocale() { char* local_default = setlocale(LC_CTYPE, 0); diff --git a/tizen_src/ewk/efl_integration/content_browser_client_efl.h b/tizen_src/ewk/efl_integration/content_browser_client_efl.h index d783485..5c480fc 100644 --- a/tizen_src/ewk/efl_integration/content_browser_client_efl.h +++ b/tizen_src/ewk/efl_integration/content_browser_client_efl.h @@ -110,6 +110,8 @@ class ContentBrowserClientEfl : public ContentBrowserClient { blink::web_pref::WebPreferences* prefs); void RenderProcessWillLaunch(RenderProcessHost* host) override; DevToolsManagerDelegate* GetDevToolsManagerDelegate(); + std::unique_ptr + CreateDevToolsManagerDelegate() override; std::string GetApplicationLocale() override; std::unique_ptr GetWebContentsViewDelegate( WebContents* web_contents) override; diff --git a/tizen_src/ewk/efl_integration/content_main_delegate_efl.cc b/tizen_src/ewk/efl_integration/content_main_delegate_efl.cc index 8ee2f48..d69d015 100644 --- a/tizen_src/ewk/efl_integration/content_main_delegate_efl.cc +++ b/tizen_src/ewk/efl_integration/content_main_delegate_efl.cc @@ -15,7 +15,10 @@ #include "content_browser_client_efl.h" #include "renderer/content_renderer_client_efl.h" #include "ui/base/resource/resource_bundle.h" - +#if BUILDFLAG(IS_TIZEN_TV) +#include "content/public/browser/render_process_host.h" +#include "devtools_port_manager.h" +#endif namespace content { namespace { @@ -65,6 +68,13 @@ void InitializeDiskCacheDir() { } } // namespace +ContentMainDelegateEfl::ContentMainDelegateEfl() { +#if BUILDFLAG(IS_TIZEN_TV) + enableInspector_ = false; +#endif +} + + void ContentMainDelegateEfl::PreSandboxStartupBrowser() { LocaleEfl::Initialize(); base::PathService::Override(base::FILE_EXE, base::FilePath(SubProcessPath())); @@ -118,4 +128,32 @@ ContentBrowserClient* ContentMainDelegateEfl::GetContentBrowserClient() const { return browser_client_.get(); } +#if BUILDFLAG(IS_TIZEN_TV) +void ContentMainDelegateEfl::ProcessExiting(const std::string& process_type) { + if (!enableInspector_) + return; + + if (process_type.empty() && + devtools_http_handler::DevToolsPortManager::GetInstance()) // browser + devtools_http_handler::DevToolsPortManager::GetInstance()->ReleasePort(); +} + +void ContentMainDelegateEfl::SetInspectorStatus(bool enable) { + enableInspector_ = enable; +} + +bool ContentMainDelegateEfl::GetInspectorStatus() { + return enableInspector_; +} + +ContentMainDelegateEfl::~ContentMainDelegateEfl() { + if (content::RenderProcessHost::run_renderer_in_process()) { + LOG(INFO) << "ContentMainDelegateEfl[" << (void*)this + << "]::~ContentMainDelegateEfl, set ContentClient to nullptr"; + content::SetContentClient(nullptr); + } +} +#endif + + } // namespace content diff --git a/tizen_src/ewk/efl_integration/content_main_delegate_efl.h b/tizen_src/ewk/efl_integration/content_main_delegate_efl.h index 470710f..f7697ea 100644 --- a/tizen_src/ewk/efl_integration/content_main_delegate_efl.h +++ b/tizen_src/ewk/efl_integration/content_main_delegate_efl.h @@ -17,8 +17,10 @@ namespace content { class ContentMainDelegateEfl : public ContentMainDelegate { public: - ContentMainDelegateEfl() = default; - ~ContentMainDelegateEfl() override = default; + ContentMainDelegateEfl(); +#if BUILDFLAG(IS_TIZEN_TV) + ~ContentMainDelegateEfl() override; +#endif ContentMainDelegateEfl(const ContentMainDelegateEfl&) = delete; ContentMainDelegateEfl& operator=(const ContentMainDelegateEfl&) = delete; @@ -31,12 +33,21 @@ class ContentMainDelegateEfl ContentBrowserClient* GetContentBrowserClient() const; +#if BUILDFLAG(IS_TIZEN_TV) + void ProcessExiting(const std::string& process_type) override; + void SetInspectorStatus(bool enable); + bool GetInspectorStatus(); +#endif + private: void PreSandboxStartupBrowser(); std::unique_ptr browser_client_; std::unique_ptr renderer_client_; ContentClientEfl content_client_; +#if BUILDFLAG(IS_TIZEN_TV) + bool enableInspector_; +#endif }; } diff --git a/tizen_src/ewk/efl_integration/devtools_delegate_efl.cc b/tizen_src/ewk/efl_integration/devtools_delegate_efl.cc index 3b76a9d..dc20abd 100644 --- a/tizen_src/ewk/efl_integration/devtools_delegate_efl.cc +++ b/tizen_src/ewk/efl_integration/devtools_delegate_efl.cc @@ -19,6 +19,7 @@ #include "common/version_info.h" #include "content/browser/devtools/devtools_http_handler.h" #include "content/browser/devtools/grit/devtools_resources.h" +#include "content/browser/inspector/devtools_util_manager.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/devtools_agent_host.h" #include "content/public/browser/devtools_frontend_host.h" @@ -31,111 +32,41 @@ #include "content/shell/grit/shell_resources.h" #include "net/base/net_errors.h" #include "net/socket/tcp_server_socket.h" +#include "third_party/zlib/google/compression_utils.h" #include "ui/base/resource/resource_bundle.h" using content::BrowserThread; using content::DevToolsHttpHandler; -namespace { - -// Copy of internal class implementation from -// content/shell/browser/shell_devtools_delegate.cc - -const uint16_t kMinTetheringPort = 9333; -const uint16_t kMaxTetheringPort = 9444; -const int kBackLog = 10; - -class TCPServerSocketFactory : public content::DevToolsSocketFactory { - public: - TCPServerSocketFactory(const std::string& address, uint16_t port) - : address_(address), port_(port) {} - - private: - std::unique_ptr CreateForHttpServer() override { - std::unique_ptr socket( - new net::TCPServerSocket(nullptr, net::NetLogSource())); - if (socket->ListenWithAddressAndPort(address_, port_, kBackLog) != net::OK) - return std::unique_ptr(); - - return socket; - } - - std::string address_; - uint16_t port_; -}; - -} // namespace - namespace content { -DevToolsDelegateEfl::DevToolsDelegateEfl(int port) : port_(0) { - // It's a hacky way to early detected if port is available. The problem is - // that the only thing we can do after checking is hope that noone will take - // the port until it's initialized on IO thread again. The best approach would - // be creating async callbacks that would inform when inspector server started - // and on which port. - static std::string addr = "0.0.0.0"; - std::unique_ptr sock( - new net::TCPServerSocket(NULL, net::NetLogSource())); - - const base::CommandLine* const command_line = - base::CommandLine::ForCurrentProcess(); - // See if the user specified a port on the command line (useful for - // automation). If not, use an ephemeral port by specifying 0. - if (!port && command_line->HasSwitch(switches::kRemoteDebuggingPort)) { - int temp_port = 0; - std::string port_str = - command_line->GetSwitchValueASCII(switches::kRemoteDebuggingPort); - if (base::StringToInt(port_str, &temp_port) && (temp_port > 0) && - (temp_port < 65535)) { - port = temp_port; - } else { - DLOG(WARNING) << "Invalid http debugger port number " << temp_port; - } - } - - // why backlog is 1? - if (sock->ListenWithAddressAndPort(addr, port, 1) != net::OK) { - port_ = 0; - return; +/* LCOV_EXCL_START */ +std::string DevToolsDelegateEfl::GetDiscoveryPageHTML() { + std::string data = + std::string(ui::ResourceBundle::GetSharedInstance().GetRawDataResource( + IDR_CONTENT_SHELL_DEVTOOLS_DISCOVERY_PAGE)); + if (data.length() > 2 && data[0] == '\x1F' && data[1] == '\x8B') { + std::string uncompressed_data; + if (compression::GzipUncompress(data, &uncompressed_data)) + return uncompressed_data; + LOG(ERROR) << "Failed to uncompress "; } - - net::IPEndPoint givenIp; - sock->GetLocalAddress(&givenIp); - port_ = givenIp.port(); - -#if !defined(EWK_BRINGUP) // FIXME: m67 bringup - // FIXME: EWK_BRINGUP definition should be removed. - std::unique_ptr factory( - new TCPServerSocketFactory(addr, port_)); - - devtools_http_handler_.reset(new content::DevToolsHttpHandler( - std::move(factory), std::string(), this, base::FilePath(), - base::FilePath(), - EflWebView::VersionInfo::GetInstance() - ->ProductNameAndVersionForUserAgent(), - EflWebView::VersionInfo::GetInstance()->DefaultUserAgent())); -#endif // !defined(EWK_BRINGUP) + return data; } -DevToolsDelegateEfl::~DevToolsDelegateEfl() {} - -void DevToolsDelegateEfl::Stop() { - if (devtools_http_handler_) { - // The call below destroys this. - devtools_http_handler_.reset(); - } else { - BrowserThread::DeleteSoon(BrowserThread::UI, FROM_HERE, this); - } +std::string DevToolsDelegateEfl::GetFrontendResource(const std::string& path) { + return content::DevToolsUtilManager::GetInstance()->GetFrontendResource(path); } -std::string DevToolsDelegateEfl::GetDiscoveryPageHTML() { - return ui::ResourceBundle::GetSharedInstance().LoadDataResourceString( - IDR_CONTENT_SHELL_DEVTOOLS_DISCOVERY_PAGE); +bool DevToolsDelegateEfl::HasBundledFrontendResources() { + return true; } -std::string DevToolsDelegateEfl::GetFrontendResource(const std::string& path) { - return content::DevToolsFrontendHost::GetFrontendResource(path); +#if defined(OS_TIZEN_TV_PRODUCT) +void DevToolsDelegateEfl::ReleasePort() { + content::DevToolsUtilManager::GetInstance()->ReleasePort(); } +#endif +/* LCOV_EXCL_STOP */ } // namespace content diff --git a/tizen_src/ewk/efl_integration/devtools_delegate_efl.h b/tizen_src/ewk/efl_integration/devtools_delegate_efl.h index 5300512..8d47461 100644 --- a/tizen_src/ewk/efl_integration/devtools_delegate_efl.h +++ b/tizen_src/ewk/efl_integration/devtools_delegate_efl.h @@ -18,27 +18,18 @@ class DevToolsHttpHandler; // This class is similar to ShellDevToolsDelegate, which also implements DevToolsHttpHandlerDelegate interface. class DevToolsDelegateEfl : public DevToolsManagerDelegate { public: - explicit DevToolsDelegateEfl(int = 0); - ~DevToolsDelegateEfl() override; + explicit DevToolsDelegateEfl() {} // LCOV_EXCL_LINE + virtual ~DevToolsDelegateEfl() {} // LCOV_EXCL_LIN // DevToolsManagerDelegate implementation. std::string GetDiscoveryPageHTML() override; - // Stops http server. - void Stop(); - std::string GetFrontendResource(const std::string& path); - DevToolsHttpHandler* devtools_http_handler() { - return devtools_http_handler_.get(); - } - int port() const { - return port_; - } - - private: - int port_; - std::unique_ptr devtools_http_handler_; + virtual bool HasBundledFrontendResources(); +#if BUILDFLAG(IS_TIZEN_TV) + void ReleasePort(); +#endif }; } // namespace content diff --git a/tizen_src/ewk/efl_integration/devtools_port_manager.cc b/tizen_src/ewk/efl_integration/devtools_port_manager.cc new file mode 100644 index 0000000..4f35dba --- /dev/null +++ b/tizen_src/ewk/efl_integration/devtools_port_manager.cc @@ -0,0 +1,304 @@ +// 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 "devtools_port_manager.h" + +#include +#include +#include +#include +#include "base/logging.h" +#include "devtools_port_msg.h" +#if defined(OS_TIZEN) +#include +#endif +namespace devtools_http_handler { + +DevToolsPortManager* DevToolsPortManager::s_PortManager = 0; +const int DevToolsPortManager::s_ValidPortList[] = { + DevToolsPort_7011, DevToolsPort_7012, DevToolsPort_7013}; +const int DevToolsPortManager::s_ValidPortCount = + sizeof(s_ValidPortList) / sizeof(int); +const int DevToolsPortManager::s_ProceeNameLength = 128; +// The size of SHM is composed of +// PortCount|Port1|Port2|Port3|pid1|pid2|pid3|appName1|appName2|appName3 +const int DevToolsPortManager::s_DevToolsPortSharedMemorySize = + sizeof(int) + DevToolsPortManager::s_ValidPortCount * sizeof(int) * 2 + + s_ProceeNameLength * sizeof(char) * 3; + +DevToolsPortManager* DevToolsPortManager::GetInstance() { + if (!s_PortManager) { + DevToolsPortSharedMemory* dpsm = + DevToolsPortSharedMemory::Create(s_DevToolsPortSharedMemorySize); + if (dpsm) { + char* memp = (char*)dpsm->Data(); + s_PortManager = new DevToolsPortManager(dpsm); + s_PortManager->m_UsedPortList = (int*)(dpsm->Data()); + s_PortManager->m_PIDList = + s_PortManager->m_UsedPortList + s_ValidPortCount + 1; + s_PortManager->m_AppName = memp; + s_PortManager->m_AppName += + sizeof(int) + DevToolsPortManager::s_ValidPortCount * sizeof(int) * 2; + } + } + + return s_PortManager; +} + +DevToolsPortManager::DevToolsPortManager(DevToolsPortSharedMemory* p) + : m_UsedPortList(0), m_DevToolsSHM(p), usedPort(0) {} + +bool DevToolsPortManager::IsPortUsed(const int port) { + DevToolsLockHolder h(m_DevToolsSHM); + + int usedPortCount = m_UsedPortList[0]; + if (!usedPortCount) + return false; + + if (usedPortCount <= s_ValidPortCount) { + while (usedPortCount > 0) { + if (m_UsedPortList[usedPortCount] == port && + getpid() == m_PIDList[usedPortCount - 1]) + return true; + + usedPortCount--; + } + } + + return false; +} + +bool DevToolsPortManager::GetValidPort(int& port) { + int pid = 0; + + if (GetValidPort(port, pid)) { + if (pid) { + DevToolsPortMsg* dpm = new DevToolsPortMsg(); + dpm->Send(pid, port); + } + m_DevToolsSHM->Lock_Port(port); + if (pid) + UpdatePortInfoInMem(port); + return true; + } + + return false; +} + +bool DevToolsPortManager::GetValidPort(int& port, int& pid) { + DevToolsLockHolder h(m_DevToolsSHM); + + int usedPortCount = m_UsedPortList[0]; + if (usedPortCount == s_ValidPortCount) { + port = m_UsedPortList[1]; + pid = m_PIDList[0]; + } else { + int i = 0; + int j = 0; + bool selected = 0; + std::string processName = GetCurrentProcessName(); + for (i = 0; i < s_ValidPortCount; i++) { + selected = 0; + for (j = 1; j <= usedPortCount; j++) { + if (s_ValidPortList[i] == m_UsedPortList[j]) + selected = 1; + } + if (!selected) + break; + } + if (i < s_ValidPortCount && !selected) { + usedPortCount++; + m_UsedPortList[usedPortCount] = s_ValidPortList[i]; + m_PIDList[usedPortCount - 1] = getpid(); + memset(m_AppName + (usedPortCount - 1) * s_ProceeNameLength, 0, + s_ProceeNameLength); + memcpy(m_AppName + (usedPortCount - 1) * s_ProceeNameLength, + processName.c_str(), processName.length()); + m_UsedPortList[0] = usedPortCount; + port = s_ValidPortList[i]; + } else + return false; + } + return true; +} + +void DevToolsPortManager::UpdatePortInfoInMem(int port) { + DevToolsLockHolder h(m_DevToolsSHM); + std::string processName = GetCurrentProcessName(); + int usedPortCount = m_UsedPortList[0]; + + if (usedPortCount < s_ValidPortCount) { + usedPortCount++; + m_UsedPortList[usedPortCount] = port; + m_PIDList[usedPortCount - 1] = getpid(); + memset(m_AppName + (usedPortCount - 1) * s_ProceeNameLength, 0, + s_ProceeNameLength); + memcpy(m_AppName + (usedPortCount - 1) * s_ProceeNameLength, + processName.c_str(), processName.length()); + m_UsedPortList[0] = usedPortCount; + } +} + +bool DevToolsPortManager::ReleasePort() { + DevToolsLockHolder h(m_DevToolsSHM); + std::string PrcocessName; + PrcocessName = DevToolsPortManager::GetCurrentProcessName(); + int i; + int port = 0; + int usedPortCount = m_UsedPortList[0]; + bool isPortExist = false; + if (usedPort) + port = usedPort; + + if (!usedPortCount) + return false; + for (i = 1; i <= usedPortCount; i++) { + if (m_UsedPortList[i] == port && getpid() == m_PIDList[i - 1]) { + isPortExist = true; + break; + } + } + if (isPortExist) { + m_UsedPortList[i] = 0; + m_PIDList[i - 1] = 0; + memset(m_AppName + (i - 1) * s_ProceeNameLength, 0, s_ProceeNameLength); + for (int k = i + 1; k <= usedPortCount; k++) { + m_UsedPortList[i] = m_UsedPortList[k]; + m_PIDList[i - 1] = m_PIDList[k - 1]; + memset(m_AppName + (i - 1) * s_ProceeNameLength, 0, s_ProceeNameLength); + memcpy(m_AppName + (i - 1) * s_ProceeNameLength, + m_AppName + (k - 1) * s_ProceeNameLength, s_ProceeNameLength); + i++; + } + m_UsedPortList[usedPortCount] = 0; + m_PIDList[usedPortCount - 1] = 0; + memset(m_AppName + (usedPortCount - 1) * s_ProceeNameLength, 0, + s_ProceeNameLength); + usedPortCount--; + m_UsedPortList[0] = usedPortCount; + m_DevToolsSHM->UnLock_Port(usedPort); + } + return isPortExist; +} + +bool DevToolsPortManager::IsValidPort(const int port) { + for (int i = 0; i < s_ValidPortCount; i++) { + if (s_ValidPortList[i] == port) + return true; + } + + return false; +} + +void DevToolsPortManager::GetMappingInfo(std::string& usedMappingInfo) { + DevToolsLockHolder h(m_DevToolsSHM); + + int usedPortCount = m_UsedPortList[0]; + std::string processName; + char portNumber[] = " 99999"; + bool isPortExist = false; + + if (usedPortCount <= 0 || usedPortCount > s_ValidPortCount) + return; + + usedMappingInfo.append("RWI mapping info \n"); + + for (int i = 0; i < s_ValidPortCount; i++) { + isPortExist = false; + + char processName[s_ProceeNameLength]; + + for (int j = 1; j <= usedPortCount; j++) { + if (s_ValidPortList[i] == m_UsedPortList[j]) { + isPortExist = true; + for (int k = 0; k < s_ProceeNameLength; k++) + processName[k] = m_AppName[k + (j - 1) * s_ProceeNameLength]; + + break; + } + } + + snprintf(portNumber, sizeof(portNumber), " %d", s_ValidPortList[i]); + usedMappingInfo.append(portNumber); + usedMappingInfo.append("(RWI):"); + if (isPortExist) + usedMappingInfo.append(processName); + else + usedMappingInfo.append("N/A"); + + usedMappingInfo.append("\n"); + } +} + +bool DevToolsPortManager::ProcessCompare() { + std::string processName = GetCurrentProcessName(); + +#if defined(OS_TIZEN) + char* vconfWidgetName = vconf_get_str("db/rwi/inspected_appid"); +#else + char* vconfWidgetName = NULL; +#endif + if (!vconfWidgetName) { + LOG(INFO) << "[RWI] vconf_ None"; + return false; + } + + std::string widgetName = vconfWidgetName; + free(vconfWidgetName); + LOG(INFO) << "[RWI] WidgetName = " << widgetName.c_str(); + LOG(INFO) << "[RWI] ProcessName = " << processName.c_str(); + + if (!processName.empty()) { + if (widgetName == "org.tizen.browser") + widgetName = "browser"; + else if(widgetName == "org.tizen.wizard") + widgetName = "wizard"; + + if (processName == widgetName) + return true; + } + + return false; +} + +std::string DevToolsPortManager::GetCurrentProcessName() { + std::string processName = GetUniqueName("/proc/self/cmdline"); + + if (!processName.empty()) { + unsigned int slashIndex = processName.rfind('/'); + + if (slashIndex != std::string::npos && slashIndex < processName.size()) + processName = processName.substr(slashIndex + 1); + } + + return processName; +} + +std::string DevToolsPortManager::GetUniqueName(const char* name) { + if (!access(name, F_OK)) { + FILE* file = fopen(name, "r"); + + if (file) { + const int MAX_BUFF = 100; + char buff[MAX_BUFF] = { + 0, + }; + unsigned index = 0; + + while (index < MAX_BUFF) { + int ch = fgetc(file); + if (ch == EOF) + break; + + buff[index] = ch; + index++; + } + + fclose(file); + return std::string(buff); + } + } + return std::string(); +} +} // namespace devtools_http_handler diff --git a/tizen_src/ewk/efl_integration/devtools_port_manager.h b/tizen_src/ewk/efl_integration/devtools_port_manager.h new file mode 100644 index 0000000..8fcf2c26 --- /dev/null +++ b/tizen_src/ewk/efl_integration/devtools_port_manager.h @@ -0,0 +1,62 @@ +// 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 DEVTOOLS_PORT_MANAGER_H_ +#define DEVTOOLS_PORT_MANAGER_H_ + +#include "devtools_port_shared_memory.h" + +#include +#include + +namespace devtools_http_handler { +enum DevToolsPortType { + DevToolsPort_7011 = 7011, + DevToolsPort_7012 = 7012, + DevToolsPort_7013 = 7013 +}; + +class DevToolsPortManager { + public: + bool IsPortUsed(const int port); + bool GetValidPort(int& port); + bool GetValidPort(int& port, int& pid); + void GetMappingInfo(std::string& usedMappingInfo); + bool ReleasePort(); + void SetPort(const int port) { usedPort = port; } + int GetPort() { return usedPort; } + void UpdatePortInfoInMem(int port); + void DumpSharedMemeory(); + + ~DevToolsPortManager(); + + static DevToolsPortManager* GetInstance(); + static bool ProcessCompare(); + static std::string GetCurrentProcessName(); + static std::string GetUniqueName(const char* name); + + private: + DevToolsPortManager(DevToolsPortSharedMemory*); + bool IsValidPort(const int port); + + // PortCount|Port1|Port2|Port3 + int* m_UsedPortList; + // pid1|pid2|pid3 + int* m_PIDList; + // appName1|appName2|appName3 + char* m_AppName; + + DevToolsPortSharedMemory* m_DevToolsSHM; + + int usedPort; + + static DevToolsPortManager* s_PortManager; + + static const int s_ValidPortList[]; + static const int s_ValidPortCount; + static const int s_DevToolsPortSharedMemorySize; + static const int s_ProceeNameLength; +}; +} // namespace devtools_http_handler +#endif // DEVTOOLS_PORT_MANAGER_H_ diff --git a/tizen_src/ewk/efl_integration/devtools_port_msg.cc b/tizen_src/ewk/efl_integration/devtools_port_msg.cc new file mode 100644 index 0000000..ea89831 --- /dev/null +++ b/tizen_src/ewk/efl_integration/devtools_port_msg.cc @@ -0,0 +1,67 @@ +// 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 "devtools_port_msg.h" + +#include +#include +#include +#include +#include +#include + +bool DevToolsPortMsg::Send(int pid, int port) { + int sockfd; + struct ifreq ifr; + sockfd = socket(AF_INET, SOCK_STREAM, 0); + char eth[] = "eth0"; + ifr.ifr_addr.sa_family = AF_INET; + strncpy(ifr.ifr_name, eth, sizeof(eth)); + + if (ioctl(sockfd, SIOCGIFADDR, &ifr) < 0) { + close(sockfd); + return false; + } + struct sockaddr_in servaddr; + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(port); + + char* addr = inet_ntoa(((struct sockaddr_in*)&(ifr.ifr_addr))->sin_addr); + if (inet_pton(AF_INET, addr, &servaddr.sin_addr) <= 0) { + close(sockfd); + return false; + } + + if (connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0) { + return false; + } + const int str_len = 128; + char closeport[str_len]; + memset(closeport, 0, str_len); + strncat(closeport, "GET /closeport HTTP/1.1\n", + sizeof(closeport) - strlen(closeport) - 1); + strncat(closeport, "\r\n", sizeof(closeport) - strlen(closeport) - 1); + int send_size = + send(sockfd, closeport, strlen(closeport), MSG_WAITALL | MSG_NOSIGNAL); + + if (send_size < 0) { + close(sockfd); + return false; + } else { + while (1) { + char read_buf[str_len]; + memset(read_buf, 0, str_len); + int read_size = read(sockfd, read_buf, str_len); + if (read_size) { + continue; + } else { + close(sockfd); + return true; + } + } + } + close(sockfd); + return false; +} diff --git a/tizen_src/ewk/efl_integration/devtools_port_msg.h b/tizen_src/ewk/efl_integration/devtools_port_msg.h new file mode 100644 index 0000000..d9b1fdd --- /dev/null +++ b/tizen_src/ewk/efl_integration/devtools_port_msg.h @@ -0,0 +1,14 @@ +// 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 DEVTOOLS_PORT_MSG_H_ +#define DEVTOOLS_PORT_MSG_H_ + +class DevToolsPortMsg { + public: + DevToolsPortMsg(){}; + bool Send(int pid, int port); +}; + +#endif // DEVTOOLS_PORT_MSG_H_ diff --git a/tizen_src/ewk/efl_integration/devtools_port_shared_memory.cc b/tizen_src/ewk/efl_integration/devtools_port_shared_memory.cc new file mode 100644 index 0000000..c4ce11e --- /dev/null +++ b/tizen_src/ewk/efl_integration/devtools_port_shared_memory.cc @@ -0,0 +1,137 @@ +// 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 "devtools_port_shared_memory.h" + +#include +#include +#include +#include +#include + +namespace devtools_http_handler { +const char* SEM_NAME_ARRAY[4] = {"DevToolsPort.lock", "DevToolsPort.lock_7011", + "DevToolsPort.lock_7012", + "DevToolsPort.lock_7013"}; +#define INSPECTOR_PORT_7011 7011 +#define INSPECTOR_PORT_7012 7012 +#define INSPECTOR_PORT_7013 7013 + +DevToolsLocker::DevToolsLocker(int port) : m_sem(0) { + const char* sem_name; + if (!port) + sem_name = SEM_NAME_ARRAY[0]; + else + sem_name = SEM_NAME_ARRAY[port - 7010]; + m_port = port; + m_sem = sem_open(sem_name, O_CREAT, 0644, 1); + if (m_sem == SEM_FAILED) + sem_unlink(sem_name); +} + +DevToolsLocker::~DevToolsLocker() { + const char* sem_name; + if (!m_sem) + return; + if (!m_port) + sem_name = SEM_NAME_ARRAY[m_port]; + else + sem_name = SEM_NAME_ARRAY[m_port - 7010]; + sem_close(m_sem); +} + +bool DevToolsLocker::Lock() { + if (!m_sem) + return false; + + int result = sem_wait(m_sem); + + return !result; +} + +bool DevToolsLocker::TryLock() { + if (!m_sem) + return false; + + int result = sem_trywait(m_sem); + + return !result; +} + +bool DevToolsLocker::Unlock() { + if (!m_sem) + return false; + + int result = sem_post(m_sem); + + return !result; +} + +const char* DevToolsPortSharedMemory::s_SHMKey = + "/WK2SharedMemory.inspector.port"; + +DevToolsPortSharedMemory::DevToolsPortSharedMemory() { + for (int i = 0; i < 3; i++) { + m_PortLocker[i] = new DevToolsLocker(i + 7011); + } +} + +DevToolsPortSharedMemory::~DevToolsPortSharedMemory() { + if (!(*(int*)m_data)) + shm_unlink(s_SHMKey); + + for (int i = 0; i < 3; i++) { + if (m_PortLocker[i]) + delete (m_PortLocker[i]); + } + munmap(m_data, m_size); +} + +void DevToolsPortSharedMemory::Lock_Port(int port) { + if (port >= INSPECTOR_PORT_7011 && port <= INSPECTOR_PORT_7013) + m_PortLocker[port - INSPECTOR_PORT_7011]->Lock(); +} + +void DevToolsPortSharedMemory::UnLock_Port(int port) { + if (port >= INSPECTOR_PORT_7011 && port <= INSPECTOR_PORT_7013) + m_PortLocker[port - INSPECTOR_PORT_7011]->Unlock(); +} + +bool DevToolsPortSharedMemory::Lock() { + return m_Locker.Lock(); +} + +bool DevToolsPortSharedMemory::Unlock() { + return m_Locker.Unlock(); +} + +DevToolsPortSharedMemory* DevToolsPortSharedMemory::Create(size_t size) { + int fd = shm_open(s_SHMKey, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); + if (fd == -1) + return 0; + + while (ftruncate(fd, size) == -1) { + if (errno != EINTR) { + close(fd); + shm_unlink(s_SHMKey); + return 0; + } + } + + void* data = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (data == MAP_FAILED) { + close(fd); + shm_unlink(s_SHMKey); + return 0; + } + + close(fd); + + static DevToolsPortSharedMemory devtoolsSHM; + devtoolsSHM.m_data = data; + devtoolsSHM.m_size = size; + + return &devtoolsSHM; +} +} // namespace devtools_http_handler diff --git a/tizen_src/ewk/efl_integration/devtools_port_shared_memory.h b/tizen_src/ewk/efl_integration/devtools_port_shared_memory.h new file mode 100644 index 0000000..a44091c --- /dev/null +++ b/tizen_src/ewk/efl_integration/devtools_port_shared_memory.h @@ -0,0 +1,64 @@ +// 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 DEVTOOLS_PORT_SHARED_MEMORY_H_ +#define DEVTOOLS_PORT_SHARED_MEMORY_H_ + +#include +#include +#include +#include + +namespace devtools_http_handler { + +class DevToolsLocker { + public: + DevToolsLocker(int port = 0); + ~DevToolsLocker(); + bool Lock(); + bool TryLock(); + bool Unlock(); + + private: + sem_t* m_sem; + int m_port; +}; + +class DevToolsPortSharedMemory { + public: + // Create a shared memory object with the given size. Will return 0 on + // failure. + static DevToolsPortSharedMemory* Create(size_t); + + ~DevToolsPortSharedMemory(); + + size_t Size() const { return m_size; } + void* Data() const { return m_data; } + bool Lock(); + bool Unlock(); + void Lock_Port(int port); + void UnLock_Port(int port); + + private: + static const char* s_SHMKey; + size_t m_size; + void* m_data; + DevToolsLocker m_Locker; + DevToolsLocker* m_PortLocker[3]; + DevToolsPortSharedMemory(); +}; + +class DevToolsLockHolder { + private: + DevToolsPortSharedMemory* m_lock; + + public: + inline explicit DevToolsLockHolder(DevToolsPortSharedMemory* shmLock) + : m_lock(shmLock) { + shmLock->Lock(); + } + inline ~DevToolsLockHolder() { m_lock->Unlock(); } +}; +} // namespace devtools_http_handler +#endif // DEVTOOLS_PORT_SHARED_MEMORY_H_ diff --git a/tizen_src/ewk/efl_integration/eweb_context.cc b/tizen_src/ewk/efl_integration/eweb_context.cc index ff0aaef..0d9f7a7 100644 --- a/tizen_src/ewk/efl_integration/eweb_context.cc +++ b/tizen_src/ewk/efl_integration/eweb_context.cc @@ -20,6 +20,7 @@ #include "components/autofill/core/browser/webdata/autofill_webdata_service.h" #include "components/password_manager/core/browser/password_form.h" #include "components/password_manager/core/browser/password_store.h" +#include "content/browser/inspector/devtools_util_manager.h" #include "components/services/storage/public/cpp/buckets/bucket_locator.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_task_traits.h" @@ -66,6 +67,8 @@ #if BUILDFLAG(IS_TIZEN_TV) #include "common/application_type.h" +#include "content_main_delegate_efl.h" +#include "net/disk_cache/cache_util.h" #include "wrt/hbbtv_dynamicplugin.h" #include "wrt/hbbtv_widget_host.h" #endif @@ -331,6 +334,7 @@ EWebContext::EWebContext(bool incognito, const std::string& injectedBundlePath) widget_scale_(0), #if BUILDFLAG(IS_TIZEN_TV) application_type_(EWK_APPLICATION_TYPE_WEBBROWSER), + is_showing_mapping_info_(false), #endif m_pixmap(0), inspector_server_(NULL) { @@ -872,18 +876,28 @@ void EWebContext::GetPasswordDataList( } unsigned int EWebContext::InspectorServerStart(unsigned int port) { + LOG(INFO) << "EWebContext::InspectorServerStart"; +#if BUILDFLAG(IS_TIZEN_TV) + is_showing_mapping_info_ = true; + EwkGlobalData::GetInstance()->GetContentMainDelegateEfl().SetInspectorStatus( + true); + if (content::DevToolsUtilManager::GetPort()) + return content::DevToolsUtilManager::GetPort(); +#endif InspectorServerStop(); - inspector_server_ = new content::DevToolsDelegateEfl(port); - return inspector_server_ ? inspector_server_->port() : 0; + return content::DevToolsUtilManager::GetInstance()->InspectorServerStart( + port); } bool EWebContext::InspectorServerStop() { - if (!inspector_server_) +#if BUILDFLAG(IS_TIZEN_TV) + if (!content::DevToolsUtilManager::GetPort()) return false; - // The call below destroys inspector_server_. - inspector_server_->Stop(); - inspector_server_ = NULL; - return true; + is_showing_mapping_info_ = false; + EwkGlobalData::GetInstance()->GetContentMainDelegateEfl().SetInspectorStatus( + false); +#endif + return content::DevToolsUtilManager::GetInstance()->InspectorServerStop(); } void EWebContext::SetNotificationCallbacks( @@ -989,6 +1003,18 @@ void EWebContext::SetApplicationType( } } +bool EWebContext::GetInspectorServerState() { + return content::DevToolsUtilManager::GetPort(); +} + +bool EWebContext::ShowInspectorPortInfoState() { + if (!is_showing_mapping_info_) + return false; + + is_showing_mapping_info_ = false; + return content::DevToolsUtilManager::GetPort(); +} + void EWebContext::RegisterJSPluginMimeTypes(const Eina_List* mime_types_list) { std::string mime_types; const Eina_List* it; diff --git a/tizen_src/ewk/efl_integration/eweb_context.h b/tizen_src/ewk/efl_integration/eweb_context.h index 067c619..dab08bc 100644 --- a/tizen_src/ewk/efl_integration/eweb_context.h +++ b/tizen_src/ewk/efl_integration/eweb_context.h @@ -202,6 +202,9 @@ class EWebContext { #if BUILDFLAG(IS_TIZEN_TV) void SetApplicationType(const Ewk_Application_Type application_type); Ewk_Application_Type GetApplicationType() const { return application_type_; } + // To control applocation only show once inspector port info + bool ShowInspectorPortInfoState(); + bool GetInspectorServerState(); void RegisterJSPluginMimeTypes(const Eina_List*); void RegisterURLSchemesAsCORSEnabled(const Eina_List* schemes_list); void SetTimeOffset(double time_offset); @@ -246,6 +249,8 @@ class EWebContext { int m_pixmap; #if BUILDFLAG(IS_TIZEN_TV) Ewk_Application_Type application_type_; + // For processes which are preloaded and with unknown app id + bool is_showing_mapping_info_; #endif content::DevToolsDelegateEfl* inspector_server_; diff --git a/tizen_src/ewk/efl_integration/eweb_view.cc b/tizen_src/ewk/efl_integration/eweb_view.cc index 909d773..e459577 100644 --- a/tizen_src/ewk/efl_integration/eweb_view.cc +++ b/tizen_src/ewk/efl_integration/eweb_view.cc @@ -100,6 +100,12 @@ #include "components/autofill/core/common/autofill_switches.h" #endif +#if BUILDFLAG(IS_TIZEN_TV) +#include "common/application_type.h" +#include "devtools_port_manager.h" +#include "public/ewk_media_downloadable_font_info.h" +#endif // OS_TIZEN_TV_PRODUCT + using namespace content; using web_contents_utils::WebViewFromWebContents; @@ -333,6 +339,10 @@ EWebView::EWebView(Ewk_Context* context, Evas_Object* object) page_scale_factor_(1.0), x_delta_(0.0), y_delta_(0.0), +#if BUILDFLAG(IS_TIZEN_TV) + use_early_rwi_(false), + rwi_info_showed_(false), +#endif is_initialized_(false) { if (evas_object_) { evas_object_smart_callback_add(evas_object_, @@ -618,6 +628,15 @@ void EWebView::SetURL(const GURL& url, bool from_api) { ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_FROM_API); } +#if BUILDFLAG(IS_TIZEN_TV) + if (use_early_rwi_) { + LOG(INFO) << "[FAST RWI] SetURL Replace [" << url.spec() + << "] to [about:blank]"; + rwi_gurl_ = url; + params.url = GURL("about:blank"); + } +#endif + params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE; web_contents_->GetController().LoadURLWithParams(params); } @@ -2486,10 +2505,30 @@ std::string EWebView::GetPlatformLocale() { } int EWebView::StartInspectorServer(int port) { +#if BUILDFLAG(IS_TIZEN_TV) + if (IsTIZENWRT()) { + use_early_rwi_ = false; + rwi_info_showed_ = false; + } + if (!context_->GetImpl()->GetInspectorServerState()) { + int validPort = 0; + if (!devtools_http_handler::DevToolsPortManager::GetInstance() + ->GetValidPort(validPort)) + return 0; + + port = validPort; + } +#endif return context_->InspectorServerStart(port); } bool EWebView::StopInspectorServer() { +#if BUILDFLAG(IS_TIZEN_TV) + if (IsTIZENWRT()) { + use_early_rwi_ = false; + rwi_info_showed_ = false; + } +#endif return context_->InspectorServerStop(); } @@ -2525,6 +2564,11 @@ void EWebView::HandleRendererProcessCrash() { } void EWebView::InitializeContent() { + LOG(INFO) << "eweb_view.cc InitializeContent" ; +#if BUILDFLAG(IS_TIZEN_TV) + // When initialize content init inspector server + InitInspectorServer(); +#endif WebContents* new_contents = create_new_window_web_contents_cb_.Run(this); if (!new_contents) { WebContents::CreateParams params(context_->browser_context()); @@ -2595,6 +2639,31 @@ void EWebView::InitializeContent() { InitializeWindowTreeHost(); } +#if BUILDFLAG(IS_TIZEN_TV) +void EWebView::OnDialogClosed() { + if (!use_early_rwi_) + return; + + use_early_rwi_ = false; + LOG(INFO) << "[FAST RWI] SetURL Restore [" << rwi_gurl_.spec() + << "] from [about:blank]"; + SetURL(rwi_gurl_); + rwi_gurl_ = GURL(); + rwi_info_showed_ = true; +} + +void EWebView::InitInspectorServer() { + if (devtools_http_handler::DevToolsPortManager::GetInstance() + ->ProcessCompare()) { + int res = StartInspectorServer(0); + if (res) { + LOG(INFO) << "InitInspectorServer SetPort"; + devtools_http_handler::DevToolsPortManager::GetInstance()->SetPort(res); + } + } +} +#endif + void EWebView::InitializeWindowTreeHost() { CHECK(aura::Env::GetInstance()); diff --git a/tizen_src/ewk/efl_integration/eweb_view.h b/tizen_src/ewk/efl_integration/eweb_view.h index bd71c11..6f05ceb 100644 --- a/tizen_src/ewk/efl_integration/eweb_view.h +++ b/tizen_src/ewk/efl_integration/eweb_view.h @@ -712,6 +712,15 @@ class EWebView { void OnSelectionRectReceived(const gfx::Rect& selection_rect) const; +#if BUILDFLAG(IS_TIZEN_TV) + bool SetMixedContents(bool allow); + void ClearAllTilesResources(); + bool UseEarlyRWI() { return use_early_rwi_; } + bool RWIInfoShowed() { return rwi_info_showed_; } + GURL RWIURL() { return rwi_gurl_; } + void OnDialogClosed(); +#endif // OS_TIZEN_TV_PRODUCT + private: static void NativeViewResize(void* data, Evas* e, @@ -727,6 +736,11 @@ class EWebView { int y, Ewk_Hit_Test_Mode mode, WebViewAsyncRequestHitTestDataCallback* cb); + +#if BUILDFLAG(IS_TIZEN_TV) + void InitInspectorServer(); +#endif + #if BUILDFLAG(IS_TIZEN) && !defined(EWK_BRINGUP) static void cameraResultCb(service_h request, service_h reply, @@ -890,6 +904,12 @@ class EWebView { bool is_initialized_; +#if BUILDFLAG(IS_TIZEN_TV) + bool use_early_rwi_; + bool rwi_info_showed_; + GURL rwi_gurl_; +#endif + std::unique_ptr<_Ewk_Back_Forward_List> back_forward_list_; static content::WebContentsEflDelegate::WebContentsCreateCallback diff --git a/tizen_src/ewk/efl_integration/web_contents_delegate_efl.cc b/tizen_src/ewk/efl_integration/web_contents_delegate_efl.cc index 1b9ab28..4fd18d2 100644 --- a/tizen_src/ewk/efl_integration/web_contents_delegate_efl.cc +++ b/tizen_src/ewk/efl_integration/web_contents_delegate_efl.cc @@ -58,6 +58,10 @@ #include "browser/autofill/autofill_request_manager.h" #endif +#if BUILDFLAG(IS_TIZEN_TV) +#include "devtools_port_manager.h" +#endif // OS_TIZEN_TV_PRODUCT + #if defined(TIZEN_AUTOFILL) #include "base/command_line.h" #include "browser/autofill/autofill_client_efl.h" @@ -154,6 +158,10 @@ WebContentsDelegateEfl::~WebContentsDelegateEfl() { delete dialog_manager_; } +static bool IsMainFrame(RenderFrameHost* render_frame_host) { + return !render_frame_host->GetParent(); +} + WebContents* WebContentsDelegateEfl::OpenURLFromTab( WebContents* source, const OpenURLParams& params) { @@ -684,6 +692,40 @@ void WebContentsDelegateEfl::OnDidGetManifest( } #if BUILDFLAG(IS_TIZEN_TV) +void WebContentsDelegateEfl::ShowInspectorPortInfo() { + std::string mappingInfo; + devtools_http_handler::DevToolsPortManager::GetInstance()->GetMappingInfo( + mappingInfo); + if (web_view_->UseEarlyRWI()) { + mappingInfo.append( + "\r\nFast RWI is used, [about:blank] is loaded fist instead of \r\n["); + mappingInfo.append(web_view_->RWIURL().spec()); + mappingInfo.append( + "]\r\nClick OK button will start the real loading.\r\nNotes:\r\nPlease " + "connect to RWI in PC before click OK button.\r\nThen you can get " + "network log from the initial loading.\r\nPlease click Record button " + "in Timeline panel in PC before click OK button,\r\nThen you can get " + "profile log from the initial loading."); + } + LOG(INFO) << "[RWI] WebContentsDelegateEfl::ShowPortInfo mappingInfo = " + << mappingInfo.c_str(); + + if (!mappingInfo.empty()) { + const GURL kGURL(""); + WebContentsImpl* wci = static_cast(&web_contents_); + auto dialog_closed_callback = + base::BindOnce([](JavaScriptDialogManager* manager, bool success, + const std::u16string& response) {}, + dialog_manager_); + wci->RunJavaScriptDialog( + wci->GetPrimaryMainFrame(), base::ASCIIToUTF16(mappingInfo), + base::ASCIIToUTF16(base::StringPiece("OK")), + JAVASCRIPT_DIALOG_TYPE_ALERT, false, std::move(dialog_closed_callback)); + } +} +#endif + +#if BUILDFLAG(IS_TIZEN_TV) void WebContentsDelegateEfl::UpdateTargetURL(WebContents* /*source*/, const GURL& url) { std::string absolute_link_url(url.spec()); diff --git a/tizen_src/ewk/efl_integration/web_contents_delegate_efl.h b/tizen_src/ewk/efl_integration/web_contents_delegate_efl.h index a396563..70b905a 100644 --- a/tizen_src/ewk/efl_integration/web_contents_delegate_efl.h +++ b/tizen_src/ewk/efl_integration/web_contents_delegate_efl.h @@ -129,6 +129,7 @@ class WebContentsDelegateEfl : public WebContentsDelegate { #if BUILDFLAG(IS_TIZEN_TV) void UpdateTargetURL(WebContents* source, const GURL& url) override; + void ShowInspectorPortInfo(); #endif #if defined(TIZEN_AUTOFILL) diff --git a/tizen_src/ewk/efl_integration/web_contents_observer_efl.cc b/tizen_src/ewk/efl_integration/web_contents_observer_efl.cc index 415d1c8..8768401 100644 --- a/tizen_src/ewk/efl_integration/web_contents_observer_efl.cc +++ b/tizen_src/ewk/efl_integration/web_contents_observer_efl.cc @@ -30,9 +30,6 @@ #include "url/gurl.h" #if defined(OS_TIZEN_TV_PRODUCT) -#if !defined(EWK_BRINGUP) -#include "devtools_port_manager.h" -#endif #include "private/ewk_context_private.h" #endif @@ -142,10 +139,21 @@ void WebContentsObserverEfl::LoadProgressChanged(double progress) { void WebContentsObserverEfl::DidFinishLoad(RenderFrameHost* render_frame_host, const GURL& validated_url) { + LOG(INFO) << "WebContentsObserverEfl::DidFinishLoad"; if (!IsMainFrame(render_frame_host)) return; web_view_->SmartCallback().call(); +#if BUILDFLAG(IS_TIZEN_TV) + // After load finish show inspector port info + if (web_view_->context() && web_view_->context()->GetImpl() && + web_view_->context()->GetImpl()->ShowInspectorPortInfoState()) { + if (!web_view_->RWIInfoShowed()) + web_contents_delegate_->ShowInspectorPortInfo(); + } +#endif + + TTRACE_WEB("WebContentsObserverEfl::DidFinishLoad"); web_contents_.Focus(); } diff --git a/wrt/src/browser/api/tv/wrt_api_tv_extension.cc b/wrt/src/browser/api/tv/wrt_api_tv_extension.cc index 6951437..1b8273c 100644 --- a/wrt/src/browser/api/tv/wrt_api_tv_extension.cc +++ b/wrt/src/browser/api/tv/wrt_api_tv_extension.cc @@ -17,9 +17,7 @@ #include "electron/shell/common/gin_converters/content_converter.h" #include "gin/object_template_builder.h" #include "tizen_src/chromium_impl/tizen/vconf_handle.h" -#if !defined(WRT_JS_BRINGUP) #include "tizen_src/ewk/efl_integration/devtools_port_manager.h" -#endif #include "v8/include/v8.h" #include "wrt/src/base/platform_info.h" #include "wrt/src/browser/native_web_runtime.h" @@ -140,12 +138,11 @@ TVExtension::TVExtension() {} TVExtension::~TVExtension() {} bool TVExtension::NeedUseInspector() const { -#if defined(WRT_JS_BRINGUP) + if (devtools_http_handler::DevToolsPortManager::GetInstance() + ->ProcessCompare()) { + return true; + } return false; -#else - return devtools_http_handler::DevToolsPortManager::GetInstance() - ->ProcessCompare(); -#endif } bool TVExtension::IsAlwaysReload() const { diff --git a/wrt/src/browser/api/wrt_api_web_runtime.cc b/wrt/src/browser/api/wrt_api_web_runtime.cc index 619c3c4..c845c00 100755 --- a/wrt/src/browser/api/wrt_api_web_runtime.cc +++ b/wrt/src/browser/api/wrt_api_web_runtime.cc @@ -16,9 +16,7 @@ #include "electron/shell/common/gin_helper/dictionary.h" #include "electron/shell/common/node_includes.h" #include "gin/object_template_builder.h" -#if !defined(WRT_JS_BRINGUP) #include "tizen_src/chromium_impl/content/browser/inspector/devtools_util_manager.h" -#endif #include "tizen_src/chromium_impl/efl/window_factory.h" #include "tizen_src/chromium_impl/tizen/system_info.h" #include "wrt/src/base/file_utils.h" @@ -225,15 +223,11 @@ bool WebRuntime::GetBackgroundSupport() const { } unsigned int WebRuntime::StartInspectorServer() const { -#if !defined(WRT_JS_BRINGUP) return content::DevToolsUtilManager::GetInstance()->InspectorServerStart(); -#endif } void WebRuntime::StopInspectorServer() const { -#if !defined(WRT_JS_BRINGUP) content::DevToolsUtilManager::GetInstance()->InspectorServerStop(); -#endif } void WebRuntime::HandleCertificateError( @@ -715,6 +709,7 @@ gin::ObjectTemplateBuilder WebRuntime::GetObjectTemplateBuilder( v8::Isolate* isolate) { auto object_builder = gin::Wrappable::GetObjectTemplateBuilder(isolate); + if (!ApplicationData::IsServiceApp()) { object_builder .SetMethod("exit", &WebRuntime::Exit) diff --git a/wrt/src/browser/wrt_devtools_manager_delegate.cc b/wrt/src/browser/wrt_devtools_manager_delegate.cc index 0994039..cdd7358 100755 --- a/wrt/src/browser/wrt_devtools_manager_delegate.cc +++ b/wrt/src/browser/wrt_devtools_manager_delegate.cc @@ -4,7 +4,7 @@ #include "wrt/src/browser/wrt_devtools_manager_delegate.h" -#if BUILDFLAG(IS_TIZEN_TV) && !defined(WRT_JS_BRINGUP) +#if BUILDFLAG(IS_TIZEN_TV) #include "tizen_src/chromium_impl/content/browser/inspector/devtools_util_manager.h" #endif @@ -14,7 +14,7 @@ bool WRTDevToolsManagerDelegate::HasBundledFrontendResources() { return true; } -#if BUILDFLAG(IS_TIZEN_TV) && !defined(WRT_JS_BRINGUP) +#if BUILDFLAG(IS_TIZEN_TV) void WRTDevToolsManagerDelegate::ReleasePort() { content::DevToolsUtilManager::GetInstance()->ReleasePort(); } diff --git a/wrt/src/browser/wrt_devtools_manager_delegate.h b/wrt/src/browser/wrt_devtools_manager_delegate.h index eeb95cc..31776a3 100755 --- a/wrt/src/browser/wrt_devtools_manager_delegate.h +++ b/wrt/src/browser/wrt_devtools_manager_delegate.h @@ -19,7 +19,7 @@ class WRTDevToolsManagerDelegate : public electron::DevToolsManagerDelegate { = delete; // Chromium DevToolsHttpHandler::Delegate overrides. -#if BUILDFLAG(IS_TIZEN_TV) && !defined(WRT_JS_BRINGUP) +#if BUILDFLAG(IS_TIZEN_TV) void ReleasePort() override; #endif -- 2.7.4 From 6c3dbe3674f8aad76fba7bc76a9fb7b92192911d Mon Sep 17 00:00:00 2001 From: pengxia Date: Thu, 2 Mar 2023 10:23:29 +0800 Subject: [PATCH 02/16] [M108 Aura Migration][NaCl][PPAPI] Fixing error codes in PPB_FileRef Trying to delete a non-empty directory or rename any directory to an existing, non-empty one results in generic error (PP_ERROR_FAILED that is translated to EPERM by nacl_io). Expected result of such operation would be something that translates to EEXIST or ENOTEMPTY. This patch makes PPB_FileRef methods mentioned above result in PP_ERROR_FILEEXISTS, so that it is translated to EEXIST by nacl_io. Ported patch from M94 Aura: https://review.tizen.org/gerrit/#/c/platform/framework/web/chromium-efl/+/280551/ Change-Id: Ifebf80cc78370a3a170a86dcbd4eb2d10bb41c5a Signed-off-by: pengxia --- ppapi/shared_impl/file_type_conversion.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/ppapi/shared_impl/file_type_conversion.cc b/ppapi/shared_impl/file_type_conversion.cc index 8b6cd3b..3e52485 100644 --- a/ppapi/shared_impl/file_type_conversion.cc +++ b/ppapi/shared_impl/file_type_conversion.cc @@ -16,6 +16,7 @@ int FileErrorToPepperError(base::File::Error error_code) { case base::File::FILE_OK: return PP_OK; case base::File::FILE_ERROR_EXISTS: + case base::File::FILE_ERROR_NOT_EMPTY: return PP_ERROR_FILEEXISTS; case base::File::FILE_ERROR_NOT_FOUND: return PP_ERROR_FILENOTFOUND; -- 2.7.4 From b04cfc174ef6715dc690816a715370bf20d2f689 Mon Sep 17 00:00:00 2001 From: "feifei08.liu" Date: Tue, 28 Feb 2023 13:37:00 +0800 Subject: [PATCH 03/16] [M108 Migration][VD] Fix office 365 Word/Excel show empty blank pages issue 1. Fix redirection issue in WebApp. Now m85, exclude "file://" URLs frome default SiteInstance. So if webapp redirect url in file:///index.html. It will create a new SiteInstance and RenderFrameHost for the redirected url. As WRT only get and store main frame once time (the first time UIprocess communicated with RenderProcess). So if frame changed, wrt cannot send message to the right frame. So avoid this code that will not create new frame while redirection in "file://" URLs. 2. [VD] Disable "OriginIsolationHeader" feature to fix office 365 Word/Excel show empty blank pages issue. "OriginIsolationHeader" enabled in M94 which is in development, it will cause new webview created and some information do not included in requests, this feature disabled in M85, so we follow M85 logic disable this feature. Reference: - https://review.tizen.org/gerrit/286949/ Change-Id: Ic26c5a4ac80bfa246a3f1d205095093b503ae372 Signed-off-by: feifei08.liu --- content/browser/site_instance_impl.cc | 2 ++ content/public/common/content_features.cc | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/content/browser/site_instance_impl.cc b/content/browser/site_instance_impl.cc index f591ec3..e48f32d 100644 --- a/content/browser/site_instance_impl.cc +++ b/content/browser/site_instance_impl.cc @@ -1204,11 +1204,13 @@ bool SiteInstanceImpl::CanBePlacedInDefaultSiteInstance( return false; } +#if !BUILDFLAG(IS_TIZEN_TV) // Exclude "file://" URLs from the default SiteInstance to prevent the // default SiteInstance process from accumulating file access grants that // could be exploited by other non-isolated sites. if (url.SchemeIs(url::kFileScheme)) return false; +#endif // Don't use the default SiteInstance when // kProcessSharingWithStrictSiteInstances is enabled because we want each diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index 2ce7fba..f6160a8 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc @@ -741,9 +741,15 @@ BASE_FEATURE(kNotificationTriggers, // // The name is "OriginIsolationHeader" because that was the old name when the // feature was under development. +#if BUILDFLAG(IS_TIZEN_TV) +BASE_FEATURE(kOriginIsolationHeader, + "OriginIsolationHeader", + base::FEATURE_DISABLED_BY_DEFAULT); +#else BASE_FEATURE(kOriginIsolationHeader, "OriginIsolationHeader", base::FEATURE_ENABLED_BY_DEFAULT); +#endif // History navigation in response to horizontal overscroll (aka gesture-nav). BASE_FEATURE(kOverscrollHistoryNavigation, -- 2.7.4 From 6ca37984fa8438ebb2a2476167e1d7ccb319d573 Mon Sep 17 00:00:00 2001 From: DongHyun Song Date: Thu, 9 Mar 2023 08:53:57 +0900 Subject: [PATCH 04/16] [M108 Migration][WRTjs] Lazy initialization of ContentMainRunner for wrt-loader In case cold booting case, WRT initialization takes much time on the low-end product. (5s ~ 7s) Even though wrt-loader is prepared on cold booting sequence as soon as possible, the candidate launch can be failed because wrt-loader is not yet ready. To make short the initialization time, this patch defers the jobs of WRTContentMain's initialization with ecore_idler, and return loader's create callback early to prepare wrt-loader. Reference: https://review.tizen.org/gerrit/284208/ Change-Id: Icb1be128397415903d3de8b3346a862a98e7f1e2 Signed-off-by: DongHyun Song --- wrt/src/app/wrt_content_main.cc | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/wrt/src/app/wrt_content_main.cc b/wrt/src/app/wrt_content_main.cc index 4fb0b5c..b6c0fcc 100644 --- a/wrt/src/app/wrt_content_main.cc +++ b/wrt/src/app/wrt_content_main.cc @@ -55,9 +55,14 @@ class WRTContentMain::Loader { loader_lifecycle_callback_s callback; callback.create = [](bundle* extra, int type, void* user_data) { LOG(INFO) << "loader created"; - auto* content_main = static_cast(user_data)->content_main_; - content_main->Initialize(); - content_main->main_delegate_->LoaderCreated(); + ecore_idler_add( + [](void* data) { + LOG(INFO) << "ContentMain will be initialized in idler."; + auto* content_main = static_cast(data); + content_main->Initialize(); + content_main->main_delegate_->LoaderCreated(); + return ECORE_CALLBACK_CANCEL; + }, static_cast(user_data)->content_main_); }; #if TIZEN_VERSION_AT_LEAST(6, 5, 0) callback.prelaunch = [](int argc, char** argv, const char* app_path, -- 2.7.4 From cb45d4c10b8de2cae7f7fa37eea5c3b05d6363a3 Mon Sep 17 00:00:00 2001 From: YongGeol Jung Date: Wed, 8 Mar 2023 00:49:22 -0800 Subject: [PATCH 05/16] [Onscreen] Request to redraw window surface when showing. A black scene is observed when app is displayed from a resume activity. Modified to redraw window surface when showing. Change-Id: Ifacbdcc58b0fb8ba107011eafd7f94f669845fa8 Signed-off-by: YongGeol Jung --- tizen_src/chromium_impl/ui/ozone/platform/efl/efl_window.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_window.cc b/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_window.cc index c70585c..6cf4d58 100644 --- a/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_window.cc +++ b/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_window.cc @@ -73,6 +73,10 @@ void EflWindow::Show(bool inactive) { evas_object_show(native_view_); ecore_evas_show(ee_); + + // Request to redraw window surface when showing. If not, a black screen will + // appear. + delegate_->OnDamageRect(bounds_); } void EflWindow::Hide() { -- 2.7.4 From bac9fab87a08b2d8e331e863b1e14e7b415ea1b3 Mon Sep 17 00:00:00 2001 From: zhaosy Date: Thu, 9 Mar 2023 08:04:59 +0800 Subject: [PATCH 06/16] [M108 Migration][WRTjs] Use BUILDFLAG(IS_XXX) for OS checking This patch replaces all occurances of defined(OS_XXX) with BUILDFLAG(IS_XXX) as per upstream changes mentioned in [1]. [1] https://bugs.chromium.org/p/chromium/issues/detail?id=1234043 Below efl/tizen build flags are replaced: USE_EFL -> IS_EFL OS_TIZEN -> IS_TIZEN OS_TIZEN_TV_PRODUCT -> IS_TIZEN_TV Reference: https://review.tizen.org/gerrit/#/c/platform/framework/web/chromium-efl/+/289238/ Change-Id: I387487f030919116dee9210261f23b215b6c4b60 Signed-off-by: zhaosy --- content/common/zygote/zygote_communication_linux.cc | 2 -- electron/shell/browser/api/electron_api_web_contents.cc | 2 +- electron/shell/browser/electron_browser_main_parts.cc | 4 ++-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/content/common/zygote/zygote_communication_linux.cc b/content/common/zygote/zygote_communication_linux.cc index 9e2d158..f707c1b4 100644 --- a/content/common/zygote/zygote_communication_linux.cc +++ b/content/common/zygote/zygote_communication_linux.cc @@ -361,9 +361,7 @@ void ZygoteCommunication::DropProcessPrivileges(const std::string& app_id) { pid_t ZygoteCommunication::GetZygotePid() { return pid_; } -#endif -#if BUILDFLAG(IS_TIZEN_TV) void ZygoteCommunication::SetTimeZoneOffset( const std::string& time_zone_offset) { DCHECK(init_); diff --git a/electron/shell/browser/api/electron_api_web_contents.cc b/electron/shell/browser/api/electron_api_web_contents.cc index 18cea53..c88f1ad 100644 --- a/electron/shell/browser/api/electron_api_web_contents.cc +++ b/electron/shell/browser/api/electron_api_web_contents.cc @@ -3061,7 +3061,7 @@ void WebContents::Focus() { if (owner_window()) owner_window()->Focus(true); #endif -#if !defined(ENABLE_WRT_JS) || !defined(OS_TIZEN_TV_PRODUCT) +#if !defined(ENABLE_WRT_JS) || !BUILDFLAG(IS_TIZEN_TV) web_contents()->Focus(); #endif } diff --git a/electron/shell/browser/electron_browser_main_parts.cc b/electron/shell/browser/electron_browser_main_parts.cc index 40c1830..023bdb0 100644 --- a/electron/shell/browser/electron_browser_main_parts.cc +++ b/electron/shell/browser/electron_browser_main_parts.cc @@ -267,7 +267,7 @@ int ElectronBrowserMainParts::PreEarlyInitialization() { } void ElectronBrowserMainParts::PostEarlyInitialization() { -#if defined(ENABLE_WRT_JS) && defined(OS_TIZEN_TV_PRODUCT) +#if defined(ENABLE_WRT_JS) && BUILDFLAG(IS_TIZEN_TV) LOG(INFO) << "Start Electron PostEarlyInitialization"; #endif @@ -322,7 +322,7 @@ void ElectronBrowserMainParts::PostEarlyInitialization() { // Initialize after user script environment creation. fake_browser_process_->PostEarlyInitialization(); -#if defined(ENABLE_WRT_JS) && defined(OS_TIZEN_TV_PRODUCT) +#if defined(ENABLE_WRT_JS) && BUILDFLAG(IS_TIZEN_TV) LOG(INFO) << "End Electron PostEarlyInitialization"; #endif } -- 2.7.4 From cf59503bd17bb4020fb10e9f0988966605a75e22 Mon Sep 17 00:00:00 2001 From: jiangyuwei Date: Fri, 3 Mar 2023 09:56:18 +0800 Subject: [PATCH 07/16] [M108 Migration] Fix Crash in webview. Add protection in EWebView::SetOrientation. Reference: - https://review.tizen.org/gerrit/#/c/282815/ Change-Id: If424bac3ecba47971b95c7d4df771c626f3b0fb0 Signed-off-by: jiangyuwei --- tizen_src/ewk/efl_integration/eweb_view.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tizen_src/ewk/efl_integration/eweb_view.cc b/tizen_src/ewk/efl_integration/eweb_view.cc index e459577..3503521 100644 --- a/tizen_src/ewk/efl_integration/eweb_view.cc +++ b/tizen_src/ewk/efl_integration/eweb_view.cc @@ -503,6 +503,10 @@ EWebView::~EWebView() { OnCustomScrollBeginCallback); evas_object_smart_callback_del(evas_object_, kCustomScrollEndSignalName, OnCustomScrollEndCallback); +#if BUILDFLAG(IS_TIZEN) + if (window_rotate_handler_) + ecore_event_handler_del(window_rotate_handler_); +#endif } } -- 2.7.4 From 4fdde5f687faf07bef26eb53d4f02ea29c322b1c Mon Sep 17 00:00:00 2001 From: "fr.fang" Date: Wed, 1 Mar 2023 20:59:34 +0800 Subject: [PATCH 08/16] [M108 Migration][VD] Ensure plugin props are setting correctly. Internally, properties of plugin belong to 2 different targets, one is HTMLPluginElement, one is the corresponding scriptable object. Need to set properties to the correct target. Reference: https://review.tizen.org/gerrit/#/c/282087 Change-Id: Ic7509825520413e633114ce93c7a32dfcbed4b1c Signed-off-by: fr.fang --- .../core/v8/custom/v8_html_plugin_element_custom.cc | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/third_party/blink/renderer/bindings/core/v8/custom/v8_html_plugin_element_custom.cc b/third_party/blink/renderer/bindings/core/v8/custom/v8_html_plugin_element_custom.cc index 004130f..944ce8b 100644 --- a/third_party/blink/renderer/bindings/core/v8/custom/v8_html_plugin_element_custom.cc +++ b/third_party/blink/renderer/bindings/core/v8/custom/v8_html_plugin_element_custom.cc @@ -106,11 +106,31 @@ void SetScriptableObjectProperty( v8::Local context = state->GetContext(); bool instance_has_property; bool holder_has_property; +#if BUILDFLAG(IS_TIZEN_TV) + if (!info.Holder() + ->Has(state->GetContext(), v8_name) + .To(&holder_has_property) || + holder_has_property) { + // hbbtv uses Object.defineProperties to add attribututes to the + // scriptable object. Need to set these properties here. + if (!instance + ->HasOwnProperty(info.GetIsolate()->GetCurrentContext(), v8_name) + .To(&instance_has_property) || + instance_has_property) { + [[maybe_unused]] v8::Maybe unused = + instance->Set(info.GetIsolate()->GetCurrentContext(), v8_name, value); + + V8SetReturnValue(info, value); + } + return; + } +#else if (!instance->HasOwnProperty(context, v8_name).To(&instance_has_property) || !info.Holder()->Has(context, v8_name).To(&holder_has_property) || (!instance_has_property && holder_has_property)) { return; } +#endif // FIXME: The gTalk pepper plugin is the only plugin to make use of // SetProperty and that is being deprecated. This can be removed as soon as -- 2.7.4 From 9107378744171945e92e87c05b4cd003b673afff Mon Sep 17 00:00:00 2001 From: liuxd Date: Tue, 28 Feb 2023 14:37:33 +0800 Subject: [PATCH 09/16] [M108 Migration][VD] Fix FocusInOutCallbacks not handled issue FocusInOutCallbacks been set on RenderViewReady, and been handled on OnFocusIn/OnFocusOut. On below case, the FocusInOutCallbacks not handled. 1. open office365 word: open office365 word will CreateNewWindow, and on the process without PostRenderViewReady, cause FocusInOutCallbacks without set. So add PostRenderViewReady when CreateNewWindow. 2. open website by deeplink: ewk_view_focus_set set after PostRenderViewReady. Becasue it takes a long time from PostRenderViewReady to receiving RenderViewReady, cause EWebView receive RenderViewReady later than ewk_view_focus_set. It cause FocusInOutCallbacks set later then OnFocusIn/OnFocusOut, cause FocusInOutCallbacks not handled. So call RenderViewReady directly on PostRenderViewReady. 3. open website by window.open: ewk_view_focus_set set before RenderViewReady, It cause FocusInOutCallbacks set later then OnFocusIn/OnFocusOut, cause FocusInOutCallbacks not handled. So pending setfocus when RenderView is not Live. Refer: https://review.tizen.org/gerrit/#/c/284765 Change-Id: I591ce004f418dca05b56a22c42c7d196a3337024 Signed-off-by: liuxd --- .../browser/renderer_host/render_frame_host_impl.cc | 6 ++++++ .../browser/renderer_host/render_view_host_impl.cc | 4 ++++ tizen_src/ewk/efl_integration/eweb_view.cc | 21 +++++++++++++++++++++ tizen_src/ewk/efl_integration/eweb_view.h | 7 +++++++ 4 files changed, 38 insertions(+) diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc index cf3daa1..eab33b2 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc @@ -7630,6 +7630,12 @@ void RenderFrameHostImpl::CreateNewWindow( // The mojom reply callback with kSuccess causes the renderer to create the // renderer-side objects. new_main_rfh->render_view_host()->RenderViewCreated(new_main_rfh); + +#if BUILDFLAG(IS_TIZEN_TV) + // This must be posted after the RenderViewHost is marked live, with + // `renderer_view_created_`. + new_main_rfh->render_view_host()->PostRenderViewReady(); +#endif } void RenderFrameHostImpl::CreatePortal( diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc index 726013f..a406a51 100644 --- a/content/browser/renderer_host/render_view_host_impl.cc +++ b/content/browser/renderer_host/render_view_host_impl.cc @@ -913,8 +913,12 @@ void RenderViewHostImpl::EnablePreferredSizeMode() { } void RenderViewHostImpl::PostRenderViewReady() { +#if BUILDFLAG(IS_TIZEN_TV) + RenderViewReady(); +#else GetProcess()->PostTaskWhenProcessIsReady(base::BindOnce( &RenderViewHostImpl::RenderViewReady, weak_factory_.GetWeakPtr())); +#endif } void RenderViewHostImpl::OnGpuSwitched(gl::GpuPreference active_gpu_heuristic) { diff --git a/tizen_src/ewk/efl_integration/eweb_view.cc b/tizen_src/ewk/efl_integration/eweb_view.cc index 3503521..ae7d827 100644 --- a/tizen_src/ewk/efl_integration/eweb_view.cc +++ b/tizen_src/ewk/efl_integration/eweb_view.cc @@ -539,11 +539,32 @@ void EWebView::ResetContextMenuController() { return context_menu_.reset(); } +#if BUILDFLAG(IS_TIZEN_TV) +void EWebView::RunPendingSetFocus(Eina_Bool focus) { + if (!web_contents_ || !rwhva() || (HasFocus() == focus)) + return; + rwhva()->offscreen_helper()->Focus(focus); +} +#endif + void EWebView::SetFocus(Eina_Bool focus) { if (!web_contents_ || !rwhva() || (HasFocus() == focus)) return; +#if BUILDFLAG(IS_TIZEN_TV) + if (web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive()) { + rwhva()->offscreen_helper()->Focus(focus); + + if (pending_setfocus_closure_) + pending_setfocus_closure_.Reset(); + } else { + LOG(ERROR) << "SEND DELAY SET FOCUS BIND"; + pending_setfocus_closure_ = base::BindOnce(&EWebView::RunPendingSetFocus, + base::Unretained(this), focus); + } +#else rwhva()->offscreen_helper()->Focus(focus); +#endif } Eina_Bool EWebView::HasFocus() const { diff --git a/tizen_src/ewk/efl_integration/eweb_view.h b/tizen_src/ewk/efl_integration/eweb_view.h index 6f05ceb..2a65608 100644 --- a/tizen_src/ewk/efl_integration/eweb_view.h +++ b/tizen_src/ewk/efl_integration/eweb_view.h @@ -789,6 +789,9 @@ class EWebView { void UpdateContextMenuWithParams(const content::ContextMenuParams& params); static Eina_Bool DelayedPopulateAndShowContextMenu(void* data); +#if BUILDFLAG(IS_TIZEN_TV) + void RunPendingSetFocus(Eina_Bool focus); +#endif scoped_refptr evas_event_handler_; scoped_refptr context_; @@ -944,6 +947,10 @@ class EWebView { #endif Ecore_Timer* delayed_show_context_menu_timer_ = nullptr; + +#if BUILDFLAG(IS_TIZEN_TV) + base::OnceClosure pending_setfocus_closure_; +#endif }; const unsigned int g_default_tilt_motion_sensitivity = 3; -- 2.7.4 From a7fda770bfbacd4bd7e93f833f02b694306a24eb Mon Sep 17 00:00:00 2001 From: liuxd Date: Mon, 6 Mar 2023 14:21:59 +0800 Subject: [PATCH 10/16] [M108 Migration][VD] Disable show DateTimeDialog for datetime input type Issue: click the below input type, will show black screen Solution: disable show DateTimeDialog for avoid show black screen Root Cause: Click the above datetime input type, will show DateTimeDialog. But the DateTimeDialog don't support well when CreateAndShowDateLayout, will show black screen. And we don't support show DateTimeDialog for datetime input type before. So follow as previous, don't support show DateTimeDialog. refer: https://review.tizen.org/gerrit/#/c/282731 Change-Id: Ia585744b046782061a96b490c10c8ac8718c0593 Signed-off-by: liuxd --- tizen_src/chromium_impl/content/browser/date_time_chooser_efl.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tizen_src/chromium_impl/content/browser/date_time_chooser_efl.cc b/tizen_src/chromium_impl/content/browser/date_time_chooser_efl.cc index 372ca2b..3cb6e55 100644 --- a/tizen_src/chromium_impl/content/browser/date_time_chooser_efl.cc +++ b/tizen_src/chromium_impl/content/browser/date_time_chooser_efl.cc @@ -35,10 +35,13 @@ void DateTimeChooserEfl::OpenDateTimeDialog( open_date_time_response_callback_ = std::move(callback); WebContentsImplEfl* wcie = static_cast(web_contents_); +// Don't support show DateTimeDialog for date/time input type as previos for TV. +#if !BUILDFLAG(IS_TIZEN_TV) if (wcie->GetEflDelegate()) wcie->GetEflDelegate()->OpenDateTimeDialog(value->dialog_type, value->dialog_value, this); else +#endif std::move(open_date_time_response_callback_).Run(false, ""); } -- 2.7.4 From 48a29088fe5bb26d0ea94769bdcebd8c0d98fcde Mon Sep 17 00:00:00 2001 From: Suhaspoornachandra Date: Mon, 6 Mar 2023 15:06:54 +0530 Subject: [PATCH 11/16] [M108 Migration] Support new pixel format in webrtc Support PIXEL_FORMAT_TBM_INTER_PROCESS_BUFFER and PIXEL_FORMAT_ENCODED. Reference: https://review.tizen.org/gerrit/#/c/279885 Change-Id: I30659a3c071b697ed06ff8eaf844ca82799d2b55 Signed-off-by: Suhaspoornachandra --- .../public/remoting_proto_enum_utils.cc | 3 + media/base/video_frame.cc | 92 ++++++++++++++++++++++ media/base/video_frame.h | 16 ++++ media/base/video_frame_layout.cc | 6 ++ media/base/video_types.cc | 19 +++++ media/base/video_types.h | 13 ++- media/mojo/mojom/stable/BUILD.gn | 9 +++ .../mojom/stable/stable_video_decoder_types.mojom | 7 ++ .../stable_video_decoder_types_mojom_traits.h | 26 ++++++ media/video/gpu_memory_buffer_video_frame_pool.cc | 3 + .../openscreen/src/cast/streaming/remoting.proto | 1 + 11 files changed, 192 insertions(+), 3 deletions(-) diff --git a/components/cast_streaming/public/remoting_proto_enum_utils.cc b/components/cast_streaming/public/remoting_proto_enum_utils.cc index 98af814..79b80df 100644 --- a/components/cast_streaming/public/remoting_proto_enum_utils.cc +++ b/components/cast_streaming/public/remoting_proto_enum_utils.cc @@ -374,6 +374,9 @@ absl::optional ToMediaVideoPixelFormat( CASE_RETURN_OTHER(PIXEL_FORMAT_P016LE); CASE_RETURN_OTHER(PIXEL_FORMAT_XR30); CASE_RETURN_OTHER(PIXEL_FORMAT_XB30); +#if BUILDFLAG(IS_TIZEN) + CASE_RETURN_OTHER(PIXEL_FORMAT_ENCODED); +#endif #if defined(TIZEN_TBM_SUPPORT) CASE_RETURN_OTHER(PIXEL_FORMAT_TBM_SURFACE); #endif diff --git a/media/base/video_frame.cc b/media/base/video_frame.cc index fd0dd69..d845a3c 100644 --- a/media/base/video_frame.cc +++ b/media/base/video_frame.cc @@ -164,6 +164,9 @@ gfx::Size VideoFrame::SampleSize(VideoPixelFormat format, size_t plane) { case PIXEL_FORMAT_YUV420P12: case PIXEL_FORMAT_P016LE: case PIXEL_FORMAT_YUV420AP10: +#if defined(TIZEN_TBM_SUPPORT) + case PIXEL_FORMAT_TBM_INTER_PROCESS_BUFFER: +#endif return gfx::Size(2, 2); case PIXEL_FORMAT_UYVY: @@ -179,6 +182,9 @@ gfx::Size VideoFrame::SampleSize(VideoPixelFormat format, size_t plane) { case PIXEL_FORMAT_XB30: case PIXEL_FORMAT_BGRA: case PIXEL_FORMAT_RGBAF16: +#if BUILDFLAG(IS_TIZEN) + case PIXEL_FORMAT_ENCODED: +#endif #if defined(TIZEN_TBM_SUPPORT) case PIXEL_FORMAT_TBM_SURFACE: #endif @@ -215,8 +221,12 @@ static bool RequiresEvenSizeAllocation(VideoPixelFormat format) { case PIXEL_FORMAT_XB30: case PIXEL_FORMAT_BGRA: case PIXEL_FORMAT_RGBAF16: +#if BUILDFLAG(IS_TIZEN) + case PIXEL_FORMAT_ENCODED: +#endif #if defined(TIZEN_TBM_SUPPORT) case PIXEL_FORMAT_TBM_SURFACE: + case PIXEL_FORMAT_TBM_INTER_PROCESS_BUFFER: #endif return false; case PIXEL_FORMAT_NV12: @@ -400,6 +410,38 @@ scoped_refptr VideoFrame::WrapTBMSurface( frame->buffer_handle_ = handle; return frame; } + +#if BUILDFLAG(IS_TIZEN_TV) +scoped_refptr VideoFrame::WrapTBMInterProcessBuffer( + const gfx::Size& size, + base::TimeDelta timestamp, + gfx::TbmBufferHandle handle) { + const VideoPixelFormat format = PIXEL_FORMAT_TBM_INTER_PROCESS_BUFFER; +#if defined(TIZEN_VIDEO_HOLE) + const StorageType storage = STORAGE_HOLE; +#else + const StorageType storage = STORAGE_UNKNOWN; +#endif + const gfx::Rect visible_rect = gfx::Rect(size); + if (!IsValidConfig(format, storage, size, visible_rect, size)) { + DLOG(ERROR) << __FUNCTION__ << " WrapTBMInterProcessBuffer Invalid config." + << ConfigToString(format, storage, size, visible_rect, size); + return nullptr; + } + + auto layout = VideoFrameLayout::CreateWithStrides( + format, size, {handle.strides[0], handle.strides[1]}); + if (!layout) { + DLOG(ERROR) << "Invalid layout."; + return nullptr; + } + + scoped_refptr frame( + new VideoFrame(*layout, storage, gfx::Rect(size), size, timestamp)); + frame->buffer_handle_ = handle; + return frame; +} +#endif #endif // static @@ -960,6 +1002,13 @@ scoped_refptr VideoFrame::WrapVideoFrame( frame = frame->wrapped_frame_; } +#if defined(TIZEN_TBM_SUPPORT) + if (frame->format() == PIXEL_FORMAT_TBM_INTER_PROCESS_BUFFER || + frame->format() == PIXEL_FORMAT_TBM_SURFACE) { + wrapping_frame->buffer_handle_ = frame->buffer_handle_; + } +#endif + wrapping_frame->wrapped_frame_ = std::move(frame); return wrapping_frame; } @@ -1111,6 +1160,9 @@ int VideoFrame::BytesPerElement(VideoPixelFormat format, size_t plane) { case PIXEL_FORMAT_XBGR: case PIXEL_FORMAT_XR30: case PIXEL_FORMAT_XB30: +#if BUILDFLAG(IS_TIZEN) + case PIXEL_FORMAT_ENCODED: +#endif return 4; case PIXEL_FORMAT_RGB24: return 3; @@ -1130,6 +1182,9 @@ int VideoFrame::BytesPerElement(VideoPixelFormat format, size_t plane) { case PIXEL_FORMAT_YUV422AP10: case PIXEL_FORMAT_YUV444AP10: return 2; +#if defined(TIZEN_TBM_SUPPORT) + case PIXEL_FORMAT_TBM_INTER_PROCESS_BUFFER: +#endif case PIXEL_FORMAT_NV12: case PIXEL_FORMAT_NV21: { static const int bytes_per_element[] = {1, 2}; @@ -1321,6 +1376,29 @@ T VideoFrame::GetVisibleDataInternal(T data, size_t plane) const { const gfx::Size subsample = SampleSize(format(), plane); DCHECK(offset.x() % subsample.width() == 0); DCHECK(offset.y() % subsample.height() == 0); + +#if defined(TIZEN_TBM_SUPPORT) + const VideoPixelFormat fmt = format(); + if (PIXEL_FORMAT_TBM_INTER_PROCESS_BUFFER == fmt) { + if (!bufmgr_) + bufmgr_ = tbm_bufmgr_init(-1); + { + base::AutoLock autolock(tbm_map_lock_); + if (!vp_[plane]) { + bo_[plane] = tbm_bo_import(bufmgr_, buffer_handle_.key[plane]); + bo_handle_[plane] = + tbm_bo_map(bo_[plane], TBM_DEVICE_CPU, TBM_OPTION_READ); + + vp_[plane] = + (uint8_t*)bo_handle_[plane].ptr + + stride(plane) * (offset.y() / subsample.height()) + // Row offset. + BytesPerElement(format(), plane) * // Column offset. + (offset.x() / subsample.width()); + } + } + return vp_[plane]; + } +#endif return data + stride(plane) * (offset.y() / subsample.height()) + // Row offset. BytesPerElement(format(), plane) * // Column offset. @@ -1480,6 +1558,9 @@ VideoFrame::VideoFrame(const VideoFrameLayout& layout, << coded_size().ToString(); memset(&mailbox_holders_, 0, sizeof(mailbox_holders_)); memset(&data_, 0, sizeof(data_)); +#if defined(TIZEN_TBM_SUPPORT) + memset(bo_handle_, 0, sizeof(tbm_bo_handle) * TBM_BO_NUM_MAX); +#endif } VideoFrame::~VideoFrame() { @@ -1497,6 +1578,17 @@ VideoFrame::~VideoFrame() { for (auto& callback : done_callbacks_) std::move(callback).Run(); + +#if defined(TIZEN_TBM_SUPPORT) + for (int i = 0; i < TBM_BO_NUM_MAX; i++) { + if (bo_handle_[i].ptr) { + if (!tbm_bo_unmap(bo_[i])) + LOG(WARNING) << "unmap bo failed!"; + tbm_bo_unref(bo_[i]); + bo_handle_[i].ptr = nullptr; + } + } +#endif } // static diff --git a/media/base/video_frame.h b/media/base/video_frame.h index b856464..224802f 100644 --- a/media/base/video_frame.h +++ b/media/base/video_frame.h @@ -67,7 +67,9 @@ class GLES2Interface; namespace media { +#if defined(TIZEN_TBM_SUPPORT) constexpr auto TBM_BO_NUM_MAX = 4; +#endif class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe { public: @@ -357,6 +359,12 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe { const gfx::Size& natural_size); #if defined(TIZEN_TBM_SUPPORT) +#if BUILDFLAG(IS_TIZEN_TV) + static scoped_refptr WrapTBMInterProcessBuffer( + const gfx::Size& size, + base::TimeDelta timestamp, + gfx::TbmBufferHandle handle); +#endif // Needed when we have video-frame content in tbm surface. static scoped_refptr WrapTBMSurface(const gfx::Size& size, base::TimeDelta timestamp, @@ -834,6 +842,14 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe { gpu::gles2::GLES2Interface* gl_; unsigned image_id_; scoped_refptr context_provider_; + + mutable tbm_bo bo_[TBM_BO_NUM_MAX] = {nullptr}; + mutable tbm_bo_handle bo_handle_[TBM_BO_NUM_MAX] = { + {nullptr}, + }; + mutable tbm_key key_[TBM_BO_NUM_MAX] = {0}; + mutable uint8_t* vp_[TBM_BO_NUM_MAX] = {nullptr}; + mutable tbm_bufmgr bufmgr_ = {nullptr}; #endif base::TimeDelta timestamp_; diff --git a/media/base/video_frame_layout.cc b/media/base/video_frame_layout.cc index 47bbbffa..760f945 100644 --- a/media/base/video_frame_layout.cc +++ b/media/base/video_frame_layout.cc @@ -56,10 +56,16 @@ size_t VideoFrameLayout::NumPlanes(VideoPixelFormat format) { case PIXEL_FORMAT_XR30: case PIXEL_FORMAT_XB30: case PIXEL_FORMAT_RGBAF16: +#if BUILDFLAG(IS_TIZEN) + case PIXEL_FORMAT_ENCODED: +#endif return 1; case PIXEL_FORMAT_NV12: case PIXEL_FORMAT_NV21: case PIXEL_FORMAT_P016LE: +#if defined(TIZEN_TBM_SUPPORT) + case PIXEL_FORMAT_TBM_INTER_PROCESS_BUFFER: +#endif return 2; case PIXEL_FORMAT_I420: case PIXEL_FORMAT_YV12: diff --git a/media/base/video_types.cc b/media/base/video_types.cc index 4edcc27..f506483 100644 --- a/media/base/video_types.cc +++ b/media/base/video_types.cc @@ -85,9 +85,15 @@ std::string VideoPixelFormatToString(VideoPixelFormat format) { return "PIXEL_FORMAT_YUV422AP10"; case PIXEL_FORMAT_YUV444AP10: return "PIXEL_FORMAT_YUV444AP10"; +#if BUILDFLAG(IS_TIZEN) + case PIXEL_FORMAT_ENCODED: + return "PIXEL_FORMAT_ENCODED"; +#endif #if defined(TIZEN_TBM_SUPPORT) case PIXEL_FORMAT_TBM_SURFACE: return "PIXEL_FORMAT_TBM_SURFACE"; + case PIXEL_FORMAT_TBM_INTER_PROCESS_BUFFER: + return "PIXEL_FORMAT_TBM_INTER_PROCESS_BUFFER"; #endif } NOTREACHED() << "Invalid VideoPixelFormat provided: " << format; @@ -149,6 +155,9 @@ bool IsYuvPlanar(VideoPixelFormat format) { case PIXEL_FORMAT_YUV420AP10: case PIXEL_FORMAT_YUV422AP10: case PIXEL_FORMAT_YUV444AP10: +#if defined(TIZEN_TBM_SUPPORT) + case PIXEL_FORMAT_TBM_INTER_PROCESS_BUFFER: +#endif return true; case PIXEL_FORMAT_UNKNOWN: @@ -165,6 +174,9 @@ bool IsYuvPlanar(VideoPixelFormat format) { case PIXEL_FORMAT_XB30: case PIXEL_FORMAT_BGRA: case PIXEL_FORMAT_RGBAF16: +#if BUILDFLAG(IS_TIZEN) + case PIXEL_FORMAT_ENCODED: +#endif #if defined(TIZEN_TBM_SUPPORT) case PIXEL_FORMAT_TBM_SURFACE: #endif @@ -248,6 +260,7 @@ bool IsOpaque(VideoPixelFormat format) { case PIXEL_FORMAT_XB30: #if defined(TIZEN_TBM_SUPPORT) case PIXEL_FORMAT_TBM_SURFACE: + case PIXEL_FORMAT_TBM_INTER_PROCESS_BUFFER: #endif return true; case PIXEL_FORMAT_I420A: @@ -260,6 +273,9 @@ bool IsOpaque(VideoPixelFormat format) { case PIXEL_FORMAT_YUV420AP10: case PIXEL_FORMAT_YUV422AP10: case PIXEL_FORMAT_YUV444AP10: +#if BUILDFLAG(IS_TIZEN) + case PIXEL_FORMAT_ENCODED: +#endif break; } return false; @@ -291,6 +307,9 @@ size_t BitDepth(VideoPixelFormat format) { case PIXEL_FORMAT_BGRA: case PIXEL_FORMAT_I422A: case PIXEL_FORMAT_I444A: +#if defined(TIZEN_TBM_SUPPORT) + case PIXEL_FORMAT_TBM_INTER_PROCESS_BUFFER: +#endif return 8; case PIXEL_FORMAT_YUV420P9: case PIXEL_FORMAT_YUV422P9: diff --git a/media/base/video_types.h b/media/base/video_types.h index d7dad6d..c6b3709 100644 --- a/media/base/video_types.h +++ b/media/base/video_types.h @@ -89,13 +89,20 @@ enum VideoPixelFormat { PIXEL_FORMAT_YUV444AP10 = 38, // Please update UMA histogram enumeration when adding new formats here. +#if BUILDFLAG(IS_TIZEN) + PIXEL_FORMAT_ENCODED = 39, // encoded pixels, 1 plane #if defined(TIZEN_TBM_SUPPORT) - PIXEL_FORMAT_TBM_SURFACE = 39, - PIXEL_FORMAT_MAX = PIXEL_FORMAT_TBM_SURFACE, + PIXEL_FORMAT_TBM_SURFACE = 40, + PIXEL_FORMAT_TBM_INTER_PROCESS_BUFFER = 41, + PIXEL_FORMAT_MAX = PIXEL_FORMAT_TBM_INTER_PROCESS_BUFFER, +#else + PIXEL_FORMAT_MAX = + PIXEL_FORMAT_ENCODED, // Must always be equal to largest entry logged. +#endif // defined(TIZEN_TBM_SUPPORT) #else PIXEL_FORMAT_MAX = PIXEL_FORMAT_YUV444AP10, // Must always be equal to largest entry logged. -#endif +#endif // defined(OS_TIZEN) }; // These values are persisted to logs. Entries should not be renumbered and diff --git a/media/mojo/mojom/stable/BUILD.gn b/media/mojo/mojom/stable/BUILD.gn index 205688b..2cfd7dd 100644 --- a/media/mojo/mojom/stable/BUILD.gn +++ b/media/mojo/mojom/stable/BUILD.gn @@ -4,6 +4,9 @@ import("//media/gpu/args.gni") import("//mojo/public/tools/bindings/mojom.gni") +if (use_efl) { + import("//tizen_src/build/config/tizen_features.gni") +} mojom("stable_video_decoder") { generate_java = true @@ -17,6 +20,12 @@ mojom("stable_video_decoder") { if (is_linux || is_chromeos_ash) { enabled_features += [ "is_linux_or_chromeos_ash" ] } + if (is_tizen) { + enabled_features += [ "is_tizen" ] + } + if (tizen_tbm_support) { + enabled_features += [ "tizen_tbm_support" ] + } public_deps = [ ":native_pixmap_handle", diff --git a/media/mojo/mojom/stable/stable_video_decoder_types.mojom b/media/mojo/mojom/stable/stable_video_decoder_types.mojom index 02acd4e..637b44e 100644 --- a/media/mojo/mojom/stable/stable_video_decoder_types.mojom +++ b/media/mojo/mojom/stable/stable_video_decoder_types.mojom @@ -400,6 +400,13 @@ enum VideoPixelFormat { [MinVersion=1] kPixelFormatYUV420AP10 = 36, [MinVersion=1] kPixelFormatYUV422AP10 = 37, [MinVersion=1] kPixelFormatYUV444AP10 = 38, + + [EnableIf=is_tizen] kPixelFormatEncoded = 39, + + [EnableIf=tizen_tbm_support] kPixelFormatTbmSurface = 40, + + [EnableIf=tizen_tbm_support] kPixelFormatTbmInterProcessBuffer=41, + }; // Based on |media.mojom.EosVideoFrameData|. diff --git a/media/mojo/mojom/stable/stable_video_decoder_types_mojom_traits.h b/media/mojo/mojom/stable/stable_video_decoder_types_mojom_traits.h index 358f5c2..dbeac05 100644 --- a/media/mojo/mojom/stable/stable_video_decoder_types_mojom_traits.h +++ b/media/mojo/mojom/stable/stable_video_decoder_types_mojom_traits.h @@ -1313,6 +1313,17 @@ struct EnumTraits Date: Tue, 14 Feb 2023 21:24:55 -0800 Subject: [PATCH 12/16] [M108 Migration][MM][HBBTV] Check HLS to enable url demuxer. FFmpeg demuxer is not available for Http Live Streaming contents. Therefore, I modified to use url demuxer for HLS by referring to the existing android code. Reference: https://review.tizen.org/gerrit/#/c/288322/ Change-Id: I6827d16c8f298748743779ac4cb78957cb46ffdb Signed-off-by: Sun-woo Nam --- media/filters/ffmpeg_demuxer.cc | 2 +- .../platform/media/web_media_player_impl.cc | 22 ++++++++++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/media/filters/ffmpeg_demuxer.cc b/media/filters/ffmpeg_demuxer.cc index 76661fc..f2c89c2 100644 --- a/media/filters/ffmpeg_demuxer.cc +++ b/media/filters/ffmpeg_demuxer.cc @@ -1237,7 +1237,7 @@ void FFmpegDemuxer::OnOpenContextDone(bool result) { return; } -#if BUILDFLAG(IS_ANDROID) +#if BUILDFLAG(IS_ANDROID) || defined(TIZEN_MULTIMEDIA) if (glue_->detected_hls()) { MEDIA_LOG(INFO, media_log_) << GetDisplayName() << ": detected HLS manifest"; diff --git a/third_party/blink/renderer/platform/media/web_media_player_impl.cc b/third_party/blink/renderer/platform/media/web_media_player_impl.cc index 8808a01..a61dad6 100644 --- a/third_party/blink/renderer/platform/media/web_media_player_impl.cc +++ b/third_party/blink/renderer/platform/media/web_media_player_impl.cc @@ -1938,14 +1938,18 @@ void WebMediaPlayerImpl::OnError(media::PipelineStatus status) { if (suppress_destruction_errors_) return; -#if BUILDFLAG(IS_ANDROID) +#if BUILDFLAG(IS_ANDROID) || defined(TIZEN_MULTIMEDIA) // `mb_data_source_` may be nullptr if someone passes in a m3u8 as a data:// // URL, since MediaPlayer doesn't support data:// URLs, fail playback now. - const bool found_hls = base::FeatureList::IsEnabled(media::kHlsPlayer) && - status == media::DEMUXER_ERROR_DETECTED_HLS; + const bool found_hls = +#if BUILDFLAG(IS_ANDROID) + base::FeatureList::IsEnabled(media::kHlsPlayer) && +#endif + status == media::DEMUXER_ERROR_DETECTED_HLS; if (found_hls && mb_data_source_) { demuxer_found_hls_ = true; +#if BUILDFLAG(IS_ANDROID) if (observer_) observer_->OnHlsManifestDetected(); @@ -1979,6 +1983,7 @@ void WebMediaPlayerImpl::OnError(media::PipelineStatus status) { renderer_factory_selector_->SetBaseRendererType( media::RendererType::kMediaPlayer); +#endif loaded_url_ = mb_data_source_->GetUrlAfterRedirects(); DCHECK(data_source_); @@ -2021,7 +2026,7 @@ void WebMediaPlayerImpl::OnError(media::PipelineStatus status) { ScheduleRestart(); return; } -#endif // BUILDFLAG(IS_ANDROID) +#endif // BUILDFLAG(IS_ANDROID) || defined(TIZEN_MULTIMEDIA) MaybeSetContainerNameForMetrics(); simple_watch_timer_.Stop(); @@ -3004,6 +3009,15 @@ void WebMediaPlayerImpl::StartPipeline() { demuxer_.get(), this, false, false); return; } +#elif defined(TIZEN_MULTIMEDIA) + if (demuxer_found_hls_) { + SetDemuxer(std::make_unique( + media_task_runner_, loaded_url_, frame_->GetDocument().SiteForCookies(), + frame_->GetDocument().TopFrameOrigin(), true, demuxer_found_hls_)); + pipeline_controller_->Start(media::Pipeline::StartType::kNormal, + demuxer_.get(), this, false, false); + return; + } #endif // BUILDFLAG(IS_ANDROID) // Figure out which demuxer to use. -- 2.7.4 From 1420a5b55f8391786b3e467e7b9620e7aa5e636a Mon Sep 17 00:00:00 2001 From: Sun-woo Nam Date: Thu, 9 Mar 2023 22:35:08 -0800 Subject: [PATCH 13/16] [M108 Migration][MM] Prevent suspend and release a player during prolonged pause. If a player pauses for 15 seconds, it becomes a 'stale' state. The stale players is suspended and released, but it causes unexpected behavior such as black screen. This patch therefore doesn't suspend the stale players. Reference: https://review.tizen.org/gerrit/#/c/276980/ https://review.tizen.org/gerrit/#/c/277231/ Change-Id: I9190275c60a5c0b66b583ca75cd7e8132a37bc58 Signed-off-by: Sun-woo Nam --- .../ewk/efl_integration/renderer/content_renderer_client_efl.cc | 7 +++++++ .../ewk/efl_integration/renderer/content_renderer_client_efl.h | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/tizen_src/ewk/efl_integration/renderer/content_renderer_client_efl.cc b/tizen_src/ewk/efl_integration/renderer/content_renderer_client_efl.cc index 56d5447..e54c574 100644 --- a/tizen_src/ewk/efl_integration/renderer/content_renderer_client_efl.cc +++ b/tizen_src/ewk/efl_integration/renderer/content_renderer_client_efl.cc @@ -320,3 +320,10 @@ std::unique_ptr ContentRendererClientEfl::OverrideDemuxerForUrl( } return nullptr; } + +#if defined(TIZEN_MULTIMEDIA) +bool ContentRendererClientEfl::IsIdleMediaSuspendEnabled() { + LOG(INFO) << __func__ << ", Disable idle media suspend : return false"; + return false; +} +#endif diff --git a/tizen_src/ewk/efl_integration/renderer/content_renderer_client_efl.h b/tizen_src/ewk/efl_integration/renderer/content_renderer_client_efl.h index 2067164..9d0b969 100644 --- a/tizen_src/ewk/efl_integration/renderer/content_renderer_client_efl.h +++ b/tizen_src/ewk/efl_integration/renderer/content_renderer_client_efl.h @@ -95,6 +95,10 @@ class ContentRendererClientEfl : public content::ContentRendererClient { const GURL& url, scoped_refptr task_runner) override; +#if defined(TIZEN_MULTIMEDIA) + bool IsIdleMediaSuspendEnabled() override; +#endif + bool shutting_down() const { return shutting_down_; } void set_shutting_down(bool shutting_down) { shutting_down_ = shutting_down; } -- 2.7.4 From 53940e75661fd57c559eef3fbcccff5a58783379 Mon Sep 17 00:00:00 2001 From: Suhaspoornachandra Date: Wed, 25 Jan 2023 08:56:36 +0530 Subject: [PATCH 14/16] [M108 Migration][MM] Create MediaPlayerESPlusPlayer as multiple instances. MediaPlayerESPlusPlayer is created as singleton before, previously, but it caused an issue that no video can be played in multi-video content. This patch therefore changes MediaPlayerESPlusPlayer to be created as multiple instances and it makes the latest video be played in multi-video content. References: https://review.tizen.org/gerrit/276973/ https://review.tizen.org/gerrit/277230/ Change-Id: Ifeb2e3af55bd5eba2cb58adcda2132d16d533d24 Signed-off-by: Suhaspoornachandra --- .../content/browser/media/tizen_renderer_impl.cc | 90 +++++++++------------- .../content/browser/media/tizen_renderer_impl.h | 4 +- .../media/filters/media_player_esplusplayer.cc | 8 +- .../media/filters/media_player_esplusplayer.h | 8 +- 4 files changed, 44 insertions(+), 66 deletions(-) diff --git a/tizen_src/chromium_impl/content/browser/media/tizen_renderer_impl.cc b/tizen_src/chromium_impl/content/browser/media/tizen_renderer_impl.cc index 7999ed4..7f91026 100644 --- a/tizen_src/chromium_impl/content/browser/media/tizen_renderer_impl.cc +++ b/tizen_src/chromium_impl/content/browser/media/tizen_renderer_impl.cc @@ -201,25 +201,13 @@ TizenRendererImpl::~TizenRendererImpl() { weak_factory_.InvalidateWeakPtrs(); - if (GetPlayer()) { - GetPlayer()->Release(); - - // TODO(yg48.jung) : Currently |EsppPlayer| is singelton. |media_player_| - // will be changed as |std::unique_ptr| type later. - if (media_player_ != - media::MediaPlayerESPlusPlayer::GetMediaPlayerESPlusPlayer()) - delete media_player_; - media_player_ = nullptr; - } + if (media_player_) + media_player_->Release(); if (web_contents_observer_) web_contents_observer_->RemoveMediaPlayerRenderer(this); } -media::MediaPlayerTizen* TizenRendererImpl::GetPlayer() { - return media_player_; -} - void TizenRendererImpl::Initialize(media::MediaResource* media_resource, media::RendererClient* client, media::PipelineStatusCallback init_cb) { @@ -234,30 +222,29 @@ void TizenRendererImpl::Initialize(media::MediaResource* media_resource, media_resource_ = media_resource; if (media_resource_->GetType() == media::MediaResource::STREAM) { - media_player_ = - media::MediaPlayerESPlusPlayer::GetMediaPlayerESPlusPlayer(); + media_player_ = std::make_unique(); } else { - media_player_ = new media::MediaPlayerBridgeCapiAdapter( + media_player_ = std::make_unique( media_resource->GetMediaUrlParams().media_url, volume_); } - if (!GetPlayer()->CreatePlayer()) { + if (!media_player_->CreatePlayer()) { std::move(init_cb_).Run(media::PIPELINE_ERROR_INITIALIZATION_FAILED); return; } // TODO: return unsupported error for CDM. std::move(init_cb_).Run(media::PIPELINE_OK); - GetPlayer()->SetTaskRunner(task_runner_.get()); + media_player_->SetTaskRunner(task_runner_.get()); } void TizenRendererImpl::SetStreamInfo() { if (media_resource_->GetType() == media::MediaResource::URL) { video_renderer_client_ = std::make_unique( media::DemuxerStream::VIDEO, this); - GetPlayer()->SetStreamInfo(media::DemuxerStream::VIDEO, 0, - video_renderer_client_.get()); - GetPlayer()->SetRendererClientExtension(video_renderer_client_.get()); + media_player_->SetStreamInfo(media::DemuxerStream::VIDEO, 0, + video_renderer_client_.get()); + media_player_->SetRendererClientExtension(video_renderer_client_.get()); return; } @@ -265,26 +252,24 @@ void TizenRendererImpl::SetStreamInfo() { if (audio_stream_) { audio_renderer_client_ = std::make_unique( media::DemuxerStream::AUDIO, this); - GetPlayer()->SetStreamInfo(media::DemuxerStream::AUDIO, audio_stream_, - audio_renderer_client_.get()); + media_player_->SetStreamInfo(media::DemuxerStream::AUDIO, audio_stream_, + audio_renderer_client_.get()); } video_stream_ = media_resource_->GetFirstStream(media::DemuxerStream::VIDEO); if (video_stream_) { video_renderer_client_ = std::make_unique( media::DemuxerStream::VIDEO, this); - GetPlayer()->SetStreamInfo(media::DemuxerStream::VIDEO, video_stream_, - video_renderer_client_.get()); + media_player_->SetStreamInfo(media::DemuxerStream::VIDEO, video_stream_, + video_renderer_client_.get()); + + // Will be removed later by using |ClientExtention| interface. #if defined(TIZEN_TBM_SUPPORT) - media::MediaPlayerESPlusPlayer::GetMediaPlayerESPlusPlayer() - ->SetFrameAvailableCallback( - base::BindRepeating(&TizenRendererImpl::OnNewTbmFrameAvailable, - base::Unretained(this))); + media_player_->SetFrameAvailableCallback(base::BindRepeating( + &TizenRendererImpl::OnNewTbmFrameAvailable, base::Unretained(this))); #else - // Will be removed later by using |ClientExtention| interface. - media::MediaPlayerESPlusPlayer::GetMediaPlayerESPlusPlayer() - ->SetFrameAvailableCallback(base::BindRepeating( - &TizenRendererImpl::OnNewFrameAvailable, base::Unretained(this))); + media_player_->SetFrameAvailableCallback(base::BindRepeating( + &TizenRendererImpl::OnNewFrameAvailable, base::Unretained(this))); #endif } } @@ -338,13 +323,13 @@ void TizenRendererImpl::Flush(base::OnceClosure flush_cb) { flush_cb_ = std::move(flush_cb); state_ = STATE_FLUSHING; - GetPlayer()->Flush(std::move(flush_cb)); + media_player_->Flush(std::move(flush_cb)); } void TizenRendererImpl::Seek(base::TimeDelta time) { LOG(INFO) << "(" << static_cast(this) << ") " << __func__ << " time : " << time.InMicroseconds(); - GetPlayer()->Seek(time); + media_player_->Seek(time); } #if defined(TIZEN_VIDEO_HOLE) @@ -357,8 +342,8 @@ void TizenRendererImpl::SetVideoHole(bool is_video_hole) { } void TizenRendererImpl::SetPlayerVideoHole() { - if (GetPlayer()) - GetPlayer()->SetVideoHole(is_video_hole_); + if (media_player_) + media_player_->SetVideoHole(is_video_hole_); } void TizenRendererImpl::SetMediaGeometry(const gfx::RectF& rect) { @@ -370,8 +355,8 @@ void TizenRendererImpl::SetMediaGeometry(const gfx::RectF& rect) { } void TizenRendererImpl::SetPlayerMediaGeometry() { - if (GetPlayer()) - GetPlayer()->SetMediaGeometry(GetViewportRect(), video_rect_); + if (media_player_) + media_player_->SetMediaGeometry(GetViewportRect(), video_rect_); } gfx::Rect TizenRendererImpl::GetViewportRect() const { @@ -395,28 +380,29 @@ gfx::Rect TizenRendererImpl::GetViewportRect() const { void TizenRendererImpl::StartPlayingFrom(base::TimeDelta time) { LOG(INFO) << "(" << static_cast(this) << ") " << __func__ << " time : " << time.InMicroseconds(); - DCHECK(GetPlayer()); + DCHECK(media_player_); DCHECK(task_runner_->BelongsToCurrentThread()); TRACE_EVENT1("media", "TizenRendererImpl::StartPlayingFrom", "time_us", time.InMicroseconds()); - if (!GetPlayer()->IsInitialized()) + if (!media_player_->IsInitialized()) { #if defined(TIZEN_VIDEO_HOLE) if (is_video_hole_) { SetPlayerVideoHole(); SetPlayerMediaGeometry(); } #endif - GetPlayer()->Initialize(sink_); + media_player_->Initialize(sink_); + } - if (!GetPlayer()->IsPrepared()) { + if (!media_player_->IsPrepared()) { SetStreamInfo(); SetPlayerVolume(); - GetPlayer()->Prepare(); + media_player_->Prepare(); } state_ = STATE_INITIALIZING; - GetPlayer()->Seek(time); + media_player_->Seek(time); state_ = STATE_PLAYING; } @@ -433,10 +419,10 @@ void TizenRendererImpl::SetPlaybackRate(double playback_rate) { playback_rate_ = playback_rate; if (playback_rate > 0) { - GetPlayer()->SetRate(playback_rate_); - GetPlayer()->Play(); + media_player_->SetRate(playback_rate_); + media_player_->Play(); } else { - GetPlayer()->Pause(); + media_player_->Pause(); } } @@ -449,16 +435,16 @@ void TizenRendererImpl::SetVolume(float volume) { volume_ = volume; // |SetVolume| could be called before initializing. - if (GetPlayer()) + if (media_player_) SetPlayerVolume(); } void TizenRendererImpl::SetPlayerVolume() { - GetPlayer()->SetVolume(volume_); + media_player_->SetVolume(volume_); } base::TimeDelta TizenRendererImpl::GetMediaTime() { - return GetPlayer()->GetCurrentTime(); + return media_player_->GetCurrentTime(); } void TizenRendererImpl::OnSelectedVideoTracksChanged( diff --git a/tizen_src/chromium_impl/content/browser/media/tizen_renderer_impl.h b/tizen_src/chromium_impl/content/browser/media/tizen_renderer_impl.h index d526c43..fd4dc95 100644 --- a/tizen_src/chromium_impl/content/browser/media/tizen_renderer_impl.h +++ b/tizen_src/chromium_impl/content/browser/media/tizen_renderer_impl.h @@ -144,8 +144,6 @@ class CONTENT_EXPORT TizenRendererImpl void OnVideoOpacityChange(bool opaque); void OnVideoFrameRateChange(absl::optional fps); - media::MediaPlayerTizen* GetPlayer(); - media::RendererClient* client_; State state_; @@ -172,7 +170,7 @@ class CONTENT_EXPORT TizenRendererImpl media::DemuxerStream* audio_stream_; media::DemuxerStream* video_stream_; - media::MediaPlayerTizen* media_player_ = nullptr; + std::unique_ptr media_player_; double volume_ = kDefaultVolume; double playback_rate_ = 0.0; diff --git a/tizen_src/chromium_impl/media/filters/media_player_esplusplayer.cc b/tizen_src/chromium_impl/media/filters/media_player_esplusplayer.cc index 4b15096..156a7d8 100644 --- a/tizen_src/chromium_impl/media/filters/media_player_esplusplayer.cc +++ b/tizen_src/chromium_impl/media/filters/media_player_esplusplayer.cc @@ -122,9 +122,9 @@ void ErrorCallback(const esplusplayer_error_type error_type, void* user_data) { player->OnError(error_type); } -// static -MediaPlayerESPlusPlayer* MediaPlayerESPlusPlayer::GetMediaPlayerESPlusPlayer() { - return base::Singleton::get(); +MediaPlayerESPlusPlayer::MediaPlayerESPlusPlayer() { + LOG(INFO) << "(" << static_cast(this) << ") " << __func__; + player_id_ = MediaPlayerRegistry::GetInstance()->RegisterMediaPlayer(this); } MediaPlayerESPlusPlayer::~MediaPlayerESPlusPlayer() { @@ -200,8 +200,6 @@ void MediaPlayerESPlusPlayer::Initialize(VideoRendererSink* sink) { return; } - player_id_ = MediaPlayerRegistry::GetInstance()->RegisterMediaPlayer(this); - LOG(INFO) << "(" << static_cast(this) << ") " << __func__ << " state:" << GetString(GetPlayerState()); diff --git a/tizen_src/chromium_impl/media/filters/media_player_esplusplayer.h b/tizen_src/chromium_impl/media/filters/media_player_esplusplayer.h index 1f80bd7..0361c4c 100644 --- a/tizen_src/chromium_impl/media/filters/media_player_esplusplayer.h +++ b/tizen_src/chromium_impl/media/filters/media_player_esplusplayer.h @@ -8,7 +8,6 @@ #include #include "base/containers/circular_deque.h" -#include "base/memory/singleton.h" #include "base/memory/unsafe_shared_memory_region.h" #include "base/task/single_thread_task_runner.h" #include "base/time/time.h" @@ -35,7 +34,8 @@ using Queue = base::circular_deque>; // This class handles media source extensions for CAPI port. class MEDIA_EXPORT MediaPlayerESPlusPlayer : public MediaPlayerTizen { public: - static MediaPlayerESPlusPlayer* GetMediaPlayerESPlusPlayer(); + MediaPlayerESPlusPlayer(); + ~MediaPlayerESPlusPlayer() override; #if defined(TIZEN_TBM_SUPPORT) using DataRequestCB = base::RepeatingCallback< @@ -112,10 +112,6 @@ class MEDIA_EXPORT MediaPlayerESPlusPlayer : public MediaPlayerTizen { base::circular_deque> pending_buffers_; }; - friend struct base::DefaultSingletonTraits; - - explicit MediaPlayerESPlusPlayer() = default; - ~MediaPlayerESPlusPlayer() override; MediaPlayerESPlusPlayer(const MediaPlayerESPlusPlayer&) = delete; MediaPlayerESPlusPlayer& operator=(const MediaPlayerESPlusPlayer&) = delete; -- 2.7.4 From 42e05cbc164a0d1d536fe591437718fe48296438 Mon Sep 17 00:00:00 2001 From: Koyyani Maheswari Date: Fri, 10 Mar 2023 15:11:09 +0530 Subject: [PATCH 15/16] [M108 Migration][MM] Suspend a video if sent to background. The video playback is abnormal when switching tabs in web browser. This patch suspends a video sent to background. Reference: https://review.tizen.org/gerrit/285247/ Change-Id: Ia429bcbfb3a4ce6b4d005694a7dd27a566a10903 Signed-off-by: Koyyani Maheswari --- .../blink/renderer/platform/media/web_media_player_impl.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/third_party/blink/renderer/platform/media/web_media_player_impl.cc b/third_party/blink/renderer/platform/media/web_media_player_impl.cc index a61dad6..4e9ffc6 100644 --- a/third_party/blink/renderer/platform/media/web_media_player_impl.cc +++ b/third_party/blink/renderer/platform/media/web_media_player_impl.cc @@ -2649,8 +2649,14 @@ void WebMediaPlayerImpl::OnFrameHidden() { DCHECK(main_task_runner_->BelongsToCurrentThread()); // Backgrounding a video requires a user gesture to resume playback. - if (IsHidden()) + if (IsHidden()) { +#if defined(TIZEN_MULTIMEDIA) + // Suspend if the video is sent to background. + PauseVideoIfNeeded(); + SetSuspendState(true); +#endif video_locked_when_paused_when_hidden_ = true; + } if (watch_time_reporter_) watch_time_reporter_->OnHidden(); -- 2.7.4 From 0b225facf2141e3014a8473bfa5a332636ae9324 Mon Sep 17 00:00:00 2001 From: Xiaoshu Wei Date: Thu, 9 Mar 2023 15:26:39 +0800 Subject: [PATCH 16/16] [M108 Aura Migration][NaCl][PPFwk] Enable VD Trusted Plugins functionality Migrated from tizen 7.0: https://review.tizen.org/gerrit/#/c/279658/ Change-Id: Id0dcc051a1fbc83f0180b4419b31c7b96c594a42 Signed-off-by: Xiaoshu Wei --- chrome/renderer/chrome_content_renderer_client.cc | 21 +- components/nacl/features.gni | 9 +- content/browser/plugin_service_impl.cc | 10 + content/browser/plugin_service_impl.h | 4 + content/ppapi_plugin/ppapi_plugin_main.cc | 5 + content/public/common/content_plugin_info.cc | 4 +- content/public/common/content_plugin_info.h | 2 +- content/public/renderer/content_renderer_client.cc | 10 +- .../renderer/pepper/pepper_plugin_instance_impl.cc | 38 + .../renderer/pepper/pepper_plugin_instance_impl.h | 5 + content/renderer/pepper/pepper_plugin_registry.cc | 11 + content/renderer/pepper/pepper_plugin_registry.h | 10 + content/renderer/pepper/plugin_module.cc | 9 + electron/shell/app/electron_content_client.cc | 2 +- packaging/chromium-efl.spec | 39 + ...romium-tizen_ppapi_extension_unittests.manifest | 5 + ppapi/BUILD.gn | 6 + ppapi/PRESUBMIT.py | 4 +- ppapi/api/samsung/ppb_extension_system_samsung.idl | 68 ++ .../api/samsung/ppb_remote_controller_samsung.idl | 93 +++ ppapi/buildflags/buildflags.gni | 2 +- ppapi/c/samsung/ppb_extension_system_samsung.h | 85 +++ ppapi/c/samsung/ppb_remote_controller_samsung.h | 113 +++ ppapi/cpp/samsung/extension_system_samsung.cc | 59 ++ ppapi/cpp/samsung/extension_system_samsung.h | 53 ++ .../cpp/samsung/extension_system_samsung_tizen.cc | 66 ++ ppapi/cpp/samsung/extension_system_samsung_tizen.h | 55 ++ ppapi/cpp/samsung/extension_system_samsung_wrt.cc | 22 + ppapi/cpp/samsung/extension_system_samsung_wrt.h | 39 + ppapi/cpp/samsung/remote_controller_samsung.cc | 60 ++ ppapi/cpp/samsung/remote_controller_samsung.h | 129 ++++ ppapi/generators/idl_parser.py | 4 +- ppapi/generators/idl_thunk.py | 6 + ppapi/proxy/BUILD.gn | 15 + ppapi/proxy/extension_system_resource.cc | 136 ++++ ppapi/proxy/extension_system_resource.h | 44 ++ ppapi/proxy/interface_list.cc | 8 + ppapi/proxy/ppapi_messages.h | 31 + ppapi/proxy/ppb_instance_proxy.cc | 21 + ppapi/proxy/remote_controller_resource.cc | 75 ++ ppapi/proxy/remote_controller_resource.h | 41 + ppapi/proxy/var_value_converter.cc | 171 +++++ ppapi/proxy/var_value_converter.h | 41 + ppapi/proxy/var_value_converter_unittest.cc | 489 ++++++++++++ ppapi/shared_impl/resource.h | 2 + ppapi/shared_impl/singleton_resource_id.h | 2 + ppapi/tests/all_c_includes.h | 4 + ppapi/tests/all_cpp_includes.h | 6 + ppapi/thunk/BUILD.gn | 12 + ppapi/thunk/interfaces_ppb_samsung.h | 17 + ppapi/thunk/ppb_extension_system_samsung_api.h | 32 + ppapi/thunk/ppb_extension_system_samsung_thunk.cc | 58 ++ ppapi/thunk/ppb_remote_controller_samsung_api.h | 34 + ppapi/thunk/ppb_remote_controller_samsung_thunk.cc | 51 ++ ppapi/thunk/thunk.h | 3 + sandbox/policy/linux/sandbox_linux.cc | 23 + sandbox/policy/linux/sandbox_linux.h | 5 + tizen_src/build/common.sh | 10 + tizen_src/build/config/BUILD.gn | 5 + tizen_src/build/gn_chromiumefl.sh | 6 + .../chromium_impl/content/browser/browser_efl.gni | 17 + .../pepper/browser_pepper_host_factory_efl.cc | 50 ++ .../pepper/browser_pepper_host_factory_efl.h | 32 + .../pepper/pepper_extension_system_host.cc | 250 ++++++ .../pepper/pepper_extension_system_host.h | 72 ++ .../pepper/pepper_remote_controller_host.cc | 109 +++ .../pepper/pepper_remote_controller_host.h | 71 ++ .../renderer_host/pepper/remote_controller_wrt.cc | 173 +++++ .../renderer_host/pepper/remote_controller_wrt.h | 22 + .../public/browser/extension_system_delegate.cc | 67 ++ .../public/browser/extension_system_delegate.h | 77 ++ tizen_src/ewk/efl_integration/BUILD.gn | 85 ++- .../efl_integration/common/content_client_efl.cc | 28 + .../efl_integration/common/content_client_efl.h | 2 + .../efl_integration/common/content_switches_efl.cc | 5 + .../efl_integration/common/content_switches_efl.h | 10 + .../common/trusted_pepper_plugin_info_cache.cc | 461 +++++++++++ .../common/trusted_pepper_plugin_info_cache.h | 172 +++++ .../trusted_pepper_plugin_info_cache_unittest.cc | 844 +++++++++++++++++++++ .../common/trusted_pepper_plugin_util.cc | 58 ++ .../common/trusted_pepper_plugin_util.h | 27 + .../efl_integration/content_browser_client_efl.cc | 16 + .../efl_integration/content_browser_client_efl.h | 6 + tizen_src/ewk/efl_integration/eweb_view.cc | 103 +++ tizen_src/ewk/efl_integration/eweb_view.h | 13 + .../ewk_extension_system_delegate.cc | 267 +++++++ .../ewk_extension_system_delegate.h | 45 ++ .../ewk/efl_integration/ewk_privilege_checker.cc | 131 ++++ .../ewk/efl_integration/ewk_privilege_checker.h | 30 + .../efl_integration/private/ewk_value_private.cc | 33 + .../efl_integration/private/ewk_value_private.h | 37 + .../ewk/efl_integration/public/ewk_context.cc | 11 +- tizen_src/ewk/efl_integration/public/ewk_value.cc | 334 +++++--- tizen_src/ewk/efl_integration/public/ewk_view.cc | 16 +- .../renderer/content_renderer_client_efl.cc | 46 ++ .../renderer/pepper/pepper_helper.cc | 35 + .../renderer/pepper/pepper_helper.h | 28 + .../pepper/pepper_shared_memory_message_filter.cc | 65 ++ .../pepper/pepper_shared_memory_message_filter.h | 51 ++ .../ewk/efl_integration/test/run_all_unittests.cc | 15 + tizen_src/ewk/unittest/BUILD.gn | 12 + .../ewk/unittest/utc_blink_ewk_array_value.cpp | 163 ++++ .../ewk/unittest/utc_blink_ewk_boolean_value.cpp | 28 + .../unittest/utc_blink_ewk_dictionary_value.cpp | 106 +++ .../ewk/unittest/utc_blink_ewk_double_value.cpp | 27 + tizen_src/ewk/unittest/utc_blink_ewk_int_value.cpp | 26 + .../ewk/unittest/utc_blink_ewk_string_value.cpp | 28 + .../ewk/unittest/utc_blink_ewk_value_compare.h | 153 ++++ wrt/src/renderer/wrt_renderer_client.cc | 7 +- 109 files changed, 6718 insertions(+), 136 deletions(-) create mode 100644 packaging/chromium-tizen_ppapi_extension_unittests.manifest create mode 100644 ppapi/api/samsung/ppb_extension_system_samsung.idl create mode 100644 ppapi/api/samsung/ppb_remote_controller_samsung.idl create mode 100644 ppapi/c/samsung/ppb_extension_system_samsung.h create mode 100644 ppapi/c/samsung/ppb_remote_controller_samsung.h create mode 100644 ppapi/cpp/samsung/extension_system_samsung.cc create mode 100644 ppapi/cpp/samsung/extension_system_samsung.h create mode 100644 ppapi/cpp/samsung/extension_system_samsung_tizen.cc create mode 100644 ppapi/cpp/samsung/extension_system_samsung_tizen.h create mode 100644 ppapi/cpp/samsung/extension_system_samsung_wrt.cc create mode 100644 ppapi/cpp/samsung/extension_system_samsung_wrt.h create mode 100644 ppapi/cpp/samsung/remote_controller_samsung.cc create mode 100644 ppapi/cpp/samsung/remote_controller_samsung.h create mode 100644 ppapi/proxy/extension_system_resource.cc create mode 100644 ppapi/proxy/extension_system_resource.h create mode 100644 ppapi/proxy/remote_controller_resource.cc create mode 100644 ppapi/proxy/remote_controller_resource.h create mode 100644 ppapi/proxy/var_value_converter.cc create mode 100644 ppapi/proxy/var_value_converter.h create mode 100644 ppapi/proxy/var_value_converter_unittest.cc create mode 100644 ppapi/thunk/interfaces_ppb_samsung.h create mode 100644 ppapi/thunk/ppb_extension_system_samsung_api.h create mode 100644 ppapi/thunk/ppb_extension_system_samsung_thunk.cc create mode 100644 ppapi/thunk/ppb_remote_controller_samsung_api.h create mode 100644 ppapi/thunk/ppb_remote_controller_samsung_thunk.cc create mode 100644 tizen_src/chromium_impl/content/browser/renderer_host/pepper/browser_pepper_host_factory_efl.cc create mode 100644 tizen_src/chromium_impl/content/browser/renderer_host/pepper/browser_pepper_host_factory_efl.h create mode 100644 tizen_src/chromium_impl/content/browser/renderer_host/pepper/pepper_extension_system_host.cc create mode 100644 tizen_src/chromium_impl/content/browser/renderer_host/pepper/pepper_extension_system_host.h create mode 100644 tizen_src/chromium_impl/content/browser/renderer_host/pepper/pepper_remote_controller_host.cc create mode 100644 tizen_src/chromium_impl/content/browser/renderer_host/pepper/pepper_remote_controller_host.h create mode 100644 tizen_src/chromium_impl/content/browser/renderer_host/pepper/remote_controller_wrt.cc create mode 100644 tizen_src/chromium_impl/content/browser/renderer_host/pepper/remote_controller_wrt.h create mode 100644 tizen_src/chromium_impl/content/public/browser/extension_system_delegate.cc create mode 100644 tizen_src/chromium_impl/content/public/browser/extension_system_delegate.h create mode 100644 tizen_src/ewk/efl_integration/common/trusted_pepper_plugin_info_cache.cc create mode 100644 tizen_src/ewk/efl_integration/common/trusted_pepper_plugin_info_cache.h create mode 100644 tizen_src/ewk/efl_integration/common/trusted_pepper_plugin_info_cache_unittest.cc create mode 100644 tizen_src/ewk/efl_integration/common/trusted_pepper_plugin_util.cc create mode 100644 tizen_src/ewk/efl_integration/common/trusted_pepper_plugin_util.h create mode 100644 tizen_src/ewk/efl_integration/ewk_extension_system_delegate.cc create mode 100644 tizen_src/ewk/efl_integration/ewk_extension_system_delegate.h create mode 100644 tizen_src/ewk/efl_integration/ewk_privilege_checker.cc create mode 100644 tizen_src/ewk/efl_integration/ewk_privilege_checker.h create mode 100644 tizen_src/ewk/efl_integration/private/ewk_value_private.cc create mode 100644 tizen_src/ewk/efl_integration/private/ewk_value_private.h create mode 100644 tizen_src/ewk/efl_integration/renderer/pepper/pepper_helper.cc create mode 100644 tizen_src/ewk/efl_integration/renderer/pepper/pepper_helper.h create mode 100644 tizen_src/ewk/efl_integration/renderer/pepper/pepper_shared_memory_message_filter.cc create mode 100644 tizen_src/ewk/efl_integration/renderer/pepper/pepper_shared_memory_message_filter.h create mode 100644 tizen_src/ewk/efl_integration/test/run_all_unittests.cc create mode 100644 tizen_src/ewk/unittest/utc_blink_ewk_array_value.cpp create mode 100644 tizen_src/ewk/unittest/utc_blink_ewk_boolean_value.cpp create mode 100644 tizen_src/ewk/unittest/utc_blink_ewk_dictionary_value.cpp create mode 100644 tizen_src/ewk/unittest/utc_blink_ewk_double_value.cpp create mode 100644 tizen_src/ewk/unittest/utc_blink_ewk_int_value.cpp create mode 100644 tizen_src/ewk/unittest/utc_blink_ewk_string_value.cpp create mode 100644 tizen_src/ewk/unittest/utc_blink_ewk_value_compare.h diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc index 2c7ca0d..d6059f1 100644 --- a/chrome/renderer/chrome_content_renderer_client.cc +++ b/chrome/renderer/chrome_content_renderer_client.cc @@ -1438,26 +1438,7 @@ bool ChromeContentRendererClient::IsExternalPepperPlugin( 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) diff --git a/components/nacl/features.gni b/components/nacl/features.gni index 754b12e..d4c6a68 100644 --- a/components/nacl/features.gni +++ b/components/nacl/features.gni @@ -22,10 +22,11 @@ declare_args() { # 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, diff --git a/content/browser/plugin_service_impl.cc b/content/browser/plugin_service_impl.cc index ab3e8c8..2c3f337 100644 --- a/content/browser/plugin_service_impl.cc +++ b/content/browser/plugin_service_impl.cc @@ -342,6 +342,16 @@ void PluginServiceImpl::RegisterPluginCrash(const base::FilePath& path) { i->second.push_back(time); } +#if defined(TIZEN_PEPPER_EXTENSIONS) +void PluginServiceImpl::AddPepperPlugins( + const std::vector& 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 >::const_iterator i = diff --git a/content/browser/plugin_service_impl.h b/content/browser/plugin_service_impl.h index e179b53..5b8305e4 100644 --- a/content/browser/plugin_service_impl.h +++ b/content/browser/plugin_service_impl.h @@ -97,6 +97,10 @@ class CONTENT_EXPORT PluginServiceImpl : public PluginService { // Used to monitor plugin stability. void RegisterPluginCrash(const base::FilePath& plugin_path); +#if defined(TIZEN_PEPPER_EXTENSIONS) + void AddPepperPlugins(const std::vector& plugins); +#endif + // For testing without creating many, many processes. void SetMaxPpapiProcessesPerProfileForTesting(int number) { max_ppapi_processes_per_profile_ = number; diff --git a/content/ppapi_plugin/ppapi_plugin_main.cc b/content/ppapi_plugin/ppapi_plugin_main.cc index 86e093a..d3bd543 100644 --- a/content/ppapi_plugin/ppapi_plugin_main.cc +++ b/content/ppapi_plugin/ppapi_plugin_main.cc @@ -136,7 +136,12 @@ int PpapiPluginMain(MainFunctionParams parameters) { 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( diff --git a/content/public/common/content_plugin_info.cc b/content/public/common/content_plugin_info.cc index a598bcf..2637fde 100644 --- a/content/public/common/content_plugin_info.cc +++ b/content/public/common/content_plugin_info.cc @@ -17,8 +17,8 @@ ContentPluginInfo::EntryPoints::EntryPoints() = default; 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 { diff --git a/content/public/common/content_plugin_info.h b/content/public/common/content_plugin_info.h index 7d018f2..e3f5b55 100644 --- a/content/public/common/content_plugin_info.h +++ b/content/public/common/content_plugin_info.h @@ -44,7 +44,7 @@ struct CONTENT_EXPORT ContentPluginInfo { ContentPluginInfo(); ContentPluginInfo(const ContentPluginInfo& other); - ContentPluginInfo(ContentPluginInfo&& other) noexcept; +// ContentPluginInfo(ContentPluginInfo&& other) noexcept; ~ContentPluginInfo(); WebPluginInfo ToWebPluginInfo() const; diff --git a/content/public/renderer/content_renderer_client.cc b/content/public/renderer/content_renderer_client.cc index e1925ba..c677267 100644 --- a/content/public/renderer/content_renderer_client.cc +++ b/content/public/renderer/content_renderer_client.cc @@ -4,10 +4,8 @@ #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" @@ -147,13 +145,7 @@ bool ContentRendererClient::IsExternalPepperPlugin( 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( diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.cc b/content/renderer/pepper/pepper_plugin_instance_impl.cc index 67e3034..8218fcd 100644 --- a/content/renderer/pepper/pepper_plugin_instance_impl.cc +++ b/content/renderer/pepper/pepper_plugin_instance_impl.cc @@ -741,6 +741,9 @@ void PepperPluginInstanceImpl::FinishedConsumingCommittedTexture( } 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()); @@ -2086,8 +2089,10 @@ ppapi::Resource* PepperPluginInstanceImpl::GetSingletonResource( // 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: @@ -2771,4 +2776,37 @@ void PepperPluginInstanceImpl::SetVolume(double volume) { 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 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 diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.h b/content/renderer/pepper/pepper_plugin_instance_impl.h index 8a29df0..e191cc2 100644 --- a/content/renderer/pepper/pepper_plugin_instance_impl.h +++ b/content/renderer/pepper/pepper_plugin_instance_impl.h @@ -610,6 +610,11 @@ class CONTENT_EXPORT PepperPluginInstanceImpl // 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 module_; std::unique_ptr instance_interface_; diff --git a/content/renderer/pepper/pepper_plugin_registry.cc b/content/renderer/pepper/pepper_plugin_registry.cc index 07bd3a0..9b9e730 100644 --- a/content/renderer/pepper/pepper_plugin_registry.cc +++ b/content/renderer/pepper/pepper_plugin_registry.cc @@ -12,6 +12,10 @@ #include "content/renderer/pepper/plugin_module.h" #include "ppapi/shared_impl/ppapi_permissions.h" +#if defined(TIZEN_PEPPER_EXTENSIONS) +#include +#endif + namespace content { // static @@ -106,6 +110,13 @@ PepperPluginRegistry::~PepperPluginRegistry() { PepperPluginRegistry::PepperPluginRegistry() {} +#if defined(TIZEN_PEPPER_EXTENSIONS) +void PepperPluginRegistry::AddOutOfProcessPlugins( + const std::vector& plugins) { + std::copy(plugins.begin(), plugins.end(), std::back_inserter(plugin_list_)); +} +#endif + void PepperPluginRegistry::Initialize() { ComputePepperPluginList(&plugin_list_); diff --git a/content/renderer/pepper/pepper_plugin_registry.h b/content/renderer/pepper/pepper_plugin_registry.h index cc490dd..6f7d160 100644 --- a/content/renderer/pepper/pepper_plugin_registry.h +++ b/content/renderer/pepper/pepper_plugin_registry.h @@ -7,6 +7,10 @@ #include +#if defined(TIZEN_PEPPER_EXTENSIONS) +#include +#endif + #include "base/memory/ref_counted.h" #include "content/public/common/content_plugin_info.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -54,6 +58,12 @@ class PepperPluginRegistry { 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& plugins); +#endif + private: PepperPluginRegistry(); void Initialize(); diff --git a/content/renderer/pepper/plugin_module.cc b/content/renderer/pepper/plugin_module.cc index f8831ab..4da1144 100644 --- a/content/renderer/pepper/plugin_module.cc +++ b/content/renderer/pepper/plugin_module.cc @@ -129,6 +129,12 @@ #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" @@ -297,6 +303,9 @@ const void* InternalGetInterface(const char* name) { #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 diff --git a/electron/shell/app/electron_content_client.cc b/electron/shell/app/electron_content_client.cc index 4371515..2686f14 100644 --- a/electron/shell/app/electron_content_client.cc +++ b/electron/shell/app/electron_content_client.cc @@ -45,7 +45,7 @@ #if BUILDFLAG(ENABLE_PLUGINS) #if defined(ENABLE_WRT_JS) namespace content { -struct PepperPluginInfo; +struct ContentPluginInfo; } #else #include "content/public/common/content_plugin_info.h" diff --git a/packaging/chromium-efl.spec b/packaging/chromium-efl.spec index 5506c64..6a4b46e 100755 --- a/packaging/chromium-efl.spec +++ b/packaging/chromium-efl.spec @@ -161,6 +161,8 @@ BuildRequires: pkgconfig(aul-extension) 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) @@ -330,6 +332,15 @@ Requires: %{name} = %{version}-%{release} 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 @@ -497,6 +508,10 @@ ninja %{_smp_mflags} -C "%{OUTPUT_FOLDER}" \ %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 @@ -514,6 +529,7 @@ ninja %{_smp_mflags} -C "%{OUTPUT_FOLDER}" \ %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 \ @@ -538,6 +554,13 @@ cp third_party/icu/android/icudtl.dat "%{OUTPUT_FOLDER}" 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 @@ -786,6 +809,11 @@ install -m 0644 "%{OUTPUT_FOLDER}"/ewk_unittests %{buildroot}/opt/usr/utc_exec/ 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" @@ -1131,3 +1159,14 @@ rm -rf %{CHROMIUM_TPK_DIR}/%{_tpk_file_name}.tpk /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 diff --git a/packaging/chromium-tizen_ppapi_extension_unittests.manifest b/packaging/chromium-tizen_ppapi_extension_unittests.manifest new file mode 100644 index 0000000..4ef1828 --- /dev/null +++ b/packaging/chromium-tizen_ppapi_extension_unittests.manifest @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ppapi/BUILD.gn b/ppapi/BUILD.gn index dbe25b5..72d22fc 100644 --- a/ppapi/BUILD.gn +++ b/ppapi/BUILD.gn @@ -293,6 +293,12 @@ test("ppapi_unittests") { "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", diff --git a/ppapi/PRESUBMIT.py b/ppapi/PRESUBMIT.py index 4086c41..fa32c09 100644 --- a/ppapi/PRESUBMIT.py +++ b/ppapi/PRESUBMIT.py @@ -196,7 +196,9 @@ def CheckHistogramXml(input_api, output_api): '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 diff --git a/ppapi/api/samsung/ppb_extension_system_samsung.idl b/ppapi/api/samsung/ppb_extension_system_samsung.idl new file mode 100644 index 0000000..bb2c190 --- /dev/null +++ b/ppapi/api/samsung/ppb_extension_system_samsung.idl @@ -0,0 +1,68 @@ +// 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 PPB_ExtensionSystem_Samsung 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 PP_Instance identifying one instance + * of a module. + * + * @return A PP_Var 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 PP_Instance identifying one instance + * of a module. + * + * @return A PP_Var 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 PP_Instance 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 pp_errors.h. + */ + int32_t GenericSyncCall( + [in] PP_Instance instance, + [in] PP_Var operation_name, + [in] PP_Var operation_argument, + [out] PP_Var result); +}; diff --git a/ppapi/api/samsung/ppb_remote_controller_samsung.idl b/ppapi/api/samsung/ppb_remote_controller_samsung.idl new file mode 100644 index 0000000..8bd9463 --- /dev/null +++ b/ppapi/api/samsung/ppb_remote_controller_samsung.idl @@ -0,0 +1,93 @@ +/* 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 PPB_RemoteController_Samsung interface, + * which can be used for various actions related to TV Remote Controller like + * registering for input Keys. + * + * See + * https://www.samsungdforum.com/TizenGuide/tizen231/index.html + * 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 + * https://www.samsungdforum.com/TizenGuide/tizen231/index.html + * 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. + * + * Note: + * After registering for grabbing keys, events related to that key + * will be delivered directly to the application/widget. + * + * Note: + * 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 PP_Instance 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 pp_errors.h. + * Returns PP_ERROR_BADARGUMENT if key_count is + * equal 0 or one of keys is not supported anymore. + * Returns PP_ERROR_NOTSUPPORTED if currently launched embedder + * doesn`t support key registering. + * Returns PP_ERROR_FAILED if registering all keys + * have failed. + * Returns PP_OK if at lest one key from keys 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. + * + * Note: + * 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 PP_Instance 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 pp_errors.h. + * Returns PP_ERROR_BADARGUMENT if key_count is + * equal 0 or one of keys is not supported anymore. + * Returns PP_ERROR_NOTSUPPORTED if currently launched embedder + * doesn`t support key registering. + * Returns PP_ERROR_FAILED if registering all keys + * have failed. + * Returns PP_OK if at lest one key from keys have + * been registered. + */ + int32_t UnRegisterKeys([in] PP_Instance instance, + [in] uint32_t key_count, + [in, size_as=key_count] str_t[] keys); +}; diff --git a/ppapi/buildflags/buildflags.gni b/ppapi/buildflags/buildflags.gni index 9f1cc34..7996a36 100644 --- a/ppapi/buildflags/buildflags.gni +++ b/ppapi/buildflags/buildflags.gni @@ -11,7 +11,7 @@ declare_args() { # # 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() { diff --git a/ppapi/c/samsung/ppb_extension_system_samsung.h b/ppapi/c/samsung/ppb_extension_system_samsung.h new file mode 100644 index 0000000..d3d55cd --- /dev/null +++ b/ppapi/c/samsung/ppb_extension_system_samsung.h @@ -0,0 +1,85 @@ +/* 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 PPB_ExtensionSystem_Samsung 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 PP_Instance identifying one instance + * of a module. + * + * @return A PP_Var 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 PP_Instance identifying one instance + * of a module. + * + * @return A PP_Var 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 PP_Instance 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 pp_errors.h. + */ + 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_ */ diff --git a/ppapi/c/samsung/ppb_remote_controller_samsung.h b/ppapi/c/samsung/ppb_remote_controller_samsung.h new file mode 100644 index 0000000..08fbd3e --- /dev/null +++ b/ppapi/c/samsung/ppb_remote_controller_samsung.h @@ -0,0 +1,113 @@ +/* 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 PPB_RemoteController_Samsung interface, + * which can be used for various actions related to TV Remote Controller like + * registering for input Keys. + * + * See + * https://www.samsungdforum.com/TizenGuide/tizen231/index.html + * for description of Remote Controller and its keys. + */ + +/** + * @addtogroup Interfaces + * @{ + */ +/** + * The PPB_RemoteControl_Samsung interface contains pointer to functions + * related to Remote Controller. + * + * See + * https://www.samsungdforum.com/TizenGuide/tizen231/index.html + * 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. + * + * Note: + * After registering for grabbing keys, events related to that key + * will be delivered directly to the application/widget. + * + * Note: + * 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 PP_Instance 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 pp_errors.h. + * Returns PP_ERROR_BADARGUMENT if key_count is + * equal 0 or one of keys is not supported anymore. + * Returns PP_ERROR_NOTSUPPORTED if currently launched embedder + * doesn`t support key registering. + * Returns PP_ERROR_FAILED if registering all keys + * have failed. + * Returns PP_OK if at lest one key from keys 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. + * + * Note: + * 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 PP_Instance 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 pp_errors.h. + * Returns PP_ERROR_BADARGUMENT if key_count is + * equal 0 or one of keys is not supported anymore. + * Returns PP_ERROR_NOTSUPPORTED if currently launched embedder + * doesn`t support key registering. + * Returns PP_ERROR_FAILED if registering all keys + * have failed. + * Returns PP_OK if at lest one key from keys 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_ */ diff --git a/ppapi/cpp/samsung/extension_system_samsung.cc b/ppapi/cpp/samsung/extension_system_samsung.cc new file mode 100644 index 0000000..7e23f80 --- /dev/null +++ b/ppapi/cpp/samsung/extension_system_samsung.cc @@ -0,0 +1,59 @@ +// 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() { + 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()) + return std::string(); + Var result(PASS_REF, + get_interface()->GetEmbedderName( + instance_.pp_instance())); + return result.is_string() ? result.AsString() : std::string(); +} + +Var ExtensionSystemSamsung::GetCurrentExtensionInfo() { + if (!has_interface()) + return Var(); + PP_Var rv = + get_interface()->GetCurrentExtensionInfo( + instance_.pp_instance()); + return Var(PASS_REF, rv); +} + +Var ExtensionSystemSamsung::GenericSyncCall(const Var& operation_name, + const Var& operation_data) { + if (!has_interface()) + return Var(); + PP_Var operation_result; + int32_t error = + get_interface()->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 diff --git a/ppapi/cpp/samsung/extension_system_samsung.h b/ppapi/cpp/samsung/extension_system_samsung.h new file mode 100644 index 0000000..e1c1049 --- /dev/null +++ b/ppapi/cpp/samsung/extension_system_samsung.h @@ -0,0 +1,53 @@ +// 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 + +#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 ExtensionSystemSamsung. + /// + /// @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_ diff --git a/ppapi/cpp/samsung/extension_system_samsung_tizen.cc b/ppapi/cpp/samsung/extension_system_samsung_tizen.cc new file mode 100644 index 0000000..5bdd609 --- /dev/null +++ b/ppapi/cpp/samsung/extension_system_samsung_tizen.cc @@ -0,0 +1,66 @@ +// 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::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 diff --git a/ppapi/cpp/samsung/extension_system_samsung_tizen.h b/ppapi/cpp/samsung/extension_system_samsung_tizen.h new file mode 100644 index 0000000..4aeee1a --- /dev/null +++ b/ppapi/cpp/samsung/extension_system_samsung_tizen.h @@ -0,0 +1,55 @@ +// 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 +#include + +#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 ExtensionSystemSamsung. + /// + /// @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 privileges_result_; +}; + +} // namespace pp + +#endif // PPAPI_CPP_SAMSUNG_EXTENSION_SYSTEM_SAMSUNG_TIZEN_H_ diff --git a/ppapi/cpp/samsung/extension_system_samsung_wrt.cc b/ppapi/cpp/samsung/extension_system_samsung_wrt.cc new file mode 100644 index 0000000..3875a0c --- /dev/null +++ b/ppapi/cpp/samsung/extension_system_samsung_wrt.cc @@ -0,0 +1,22 @@ +// 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 diff --git a/ppapi/cpp/samsung/extension_system_samsung_wrt.h b/ppapi/cpp/samsung/extension_system_samsung_wrt.h new file mode 100644 index 0000000..294b488 --- /dev/null +++ b/ppapi/cpp/samsung/extension_system_samsung_wrt.h @@ -0,0 +1,39 @@ +// 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 +#include + +#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 ExtensionSystemSamsung. + /// + /// @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 privileges_result_; +}; + +} // namespace pp + +#endif // PPAPI_CPP_SAMSUNG_EXTENSION_SYSTEM_SAMSUNG_WRT_H_ diff --git a/ppapi/cpp/samsung/remote_controller_samsung.cc b/ppapi/cpp/samsung/remote_controller_samsung.cc new file mode 100644 index 0000000..2de366dc --- /dev/null +++ b/ppapi/cpp/samsung/remote_controller_samsung.cc @@ -0,0 +1,60 @@ +// 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() { + 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()) + return PP_ERROR_NOINTERFACE; + + return get_interface()->RegisterKeys( + instance_.pp_instance(), key_count, keys); +} + +int32_t RemoteControllerSamsung::RegisterKeys( + const std::vector& keys) { + std::vector 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(v.size()), &v[0]); +} + +int32_t RemoteControllerSamsung::UnRegisterKeys(uint32_t key_count, + const char* keys[]) { + if (!has_interface()) + return PP_ERROR_NOINTERFACE; + + return get_interface()->UnRegisterKeys( + instance_.pp_instance(), key_count, keys); +} + +int32_t RemoteControllerSamsung::UnRegisterKeys( + const std::vector& keys) { + std::vector 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(v.size()), &v[0]); +} + +} // namespace pp diff --git a/ppapi/cpp/samsung/remote_controller_samsung.h b/ppapi/cpp/samsung/remote_controller_samsung.h new file mode 100644 index 0000000..af6e9d6 --- /dev/null +++ b/ppapi/cpp/samsung/remote_controller_samsung.h @@ -0,0 +1,129 @@ +// 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 +#include + +#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 RemoteControllerSamsung 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. + /// + /// Note: + /// After registering for grabbing keys, events related to that key + /// will be delivered directly to the application/widget. + /// + /// Note: + /// 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 pp_errors.h. + /// Returns PP_ERROR_BADARGUMENT if key_count is + /// equal 0 or one of keys is not supported anymore. + /// Returns PP_ERROR_NOTSUPPORTED if currently launched embedder + /// doesn`t support key registering. + /// Returns PP_ERROR_FAILED if registering all keys + /// have failed. + /// Returns PP_OK if at lest one key from keys 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. + /// + /// Note: + /// After registering for grabbing keys, events related to that key + /// will be delivered directly to the application/widget. + /// + /// Note: + /// 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 pp_errors.h. + /// Returns PP_ERROR_BADARGUMENT if key_count is + /// equal 0 or one of keys is not supported anymore. + /// Returns PP_ERROR_NOTSUPPORTED if currently launched embedder + /// doesn`t support key registering. + /// Returns PP_ERROR_FAILED if registering all keys + /// have failed. + /// Returns PP_OK if at lest one key from keys have + /// been registered. + int32_t RegisterKeys(const std::vector& keys); + + /// UnregisterKeys() function unregisters given key arrays from being grabbed + /// by the application/widget containing pepper plugin calling this method. + /// + /// Note: + /// 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 pp_errors.h. + /// Returns PP_ERROR_BADARGUMENT if key_count is + /// equal 0 or one of keys is not supported anymore. + /// Returns PP_ERROR_NOTSUPPORTED if currently launched embedder + /// doesn`t support key registering. + /// Returns PP_ERROR_FAILED if registering all keys + /// have failed. + /// Returns PP_OK if at lest one key from keys 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. + /// + /// Note: + /// 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 pp_errors.h. + /// Returns PP_ERROR_BADARGUMENT if key_count is + /// equal 0 or one of keys is not supported anymore. + /// Returns PP_ERROR_NOTSUPPORTED if currently launched embedder + /// doesn`t support key registering. + /// Returns PP_ERROR_FAILED if registering all keys + /// have failed. + /// Returns PP_OK if at lest one key from keys have + /// been registered. + int32_t UnRegisterKeys(const std::vector& keys); + + private: + InstanceHandle instance_; +}; + +} // namespace pp + +#endif // PPAPI_CPP_SAMSUNG_REMOTE_CONTROLLER_SAMSUNG_H_ diff --git a/ppapi/generators/idl_parser.py b/ppapi/generators/idl_parser.py index f5aa1f6..6dcf2b3 100755 --- a/ppapi/generators/idl_parser.py +++ b/ppapi/generators/idl_parser.py @@ -5,6 +5,8 @@ """ Parser for PPAPI IDL """ +# Modified by SRPOL, take caution when updating. + # # IDL Parser # @@ -1239,7 +1241,7 @@ def TestVersionFiles(filter): return errs -default_dirs = ['.', 'trusted', 'dev', 'private'] +default_dirs = ['.', 'trusted', 'dev', 'private', 'samsung'] def ParseFiles(filenames): parser = IDLParser() filenodes = [] diff --git a/ppapi/generators/idl_thunk.py b/ppapi/generators/idl_thunk.py index 3d5d731..89e2217 100755 --- a/ppapi/generators/idl_thunk.py +++ b/ppapi/generators/idl_thunk.py @@ -5,6 +5,8 @@ """ Generator for C++ style thunks """ +# Modified by SRPOL, take caution when updating. + from __future__ import print_function import glob @@ -101,6 +103,8 @@ def _StripFileName(filenode): 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 @@ -112,6 +116,8 @@ def _StripApiName(api_name): 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 diff --git a/ppapi/proxy/BUILD.gn b/ppapi/proxy/BUILD.gn index 21cacd8..34ba497 100644 --- a/ppapi/proxy/BUILD.gn +++ b/ppapi/proxy/BUILD.gn @@ -2,6 +2,9 @@ # 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") @@ -256,6 +259,18 @@ component("proxy") { "//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") { diff --git a/ppapi/proxy/extension_system_resource.cc b/ppapi/proxy/extension_system_resource.cc new file mode 100644 index 0000000..1cc0953 --- /dev/null +++ b/ppapi/proxy/extension_system_resource.cc @@ -0,0 +1,136 @@ +// 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( + 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( + 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 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 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( + 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 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 diff --git a/ppapi/proxy/extension_system_resource.h b/ppapi/proxy/extension_system_resource.h new file mode 100644 index 0000000..1eaf8469 --- /dev/null +++ b/ppapi/proxy/extension_system_resource.h @@ -0,0 +1,44 @@ +// 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 + +#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_ diff --git a/ppapi/proxy/interface_list.cc b/ppapi/proxy/interface_list.cc index 6bfeb89..9797b5c 100644 --- a/ppapi/proxy/interface_list.cc +++ b/ppapi/proxy/interface_list.cc @@ -118,6 +118,11 @@ #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 @@ -168,6 +173,9 @@ InterfaceList::InterfaceList() { 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; diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h index e512022..52e73ff 100644 --- a/ppapi/proxy/ppapi_messages.h +++ b/ppapi/proxy/ppapi_messages.h @@ -84,6 +84,9 @@ #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 @@ -1737,6 +1740,34 @@ IPC_MESSAGE_CONTROL1(PpapiPluginMsg_VideoEncoder_NotifyError, 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 /* keys */) +IPC_MESSAGE_CONTROL0(PpapiHostMsg_RemoteController_RegisterKeysReply) + +IPC_MESSAGE_CONTROL1(PpapiHostMsg_RemoteController_UnRegisterKeys, + std::vector /* keys */) +IPC_MESSAGE_CONTROL0(PpapiHostMsg_RemoteController_UnRegisterKeysReply) + +#endif // defined(TIZEN_PEPPER_EXTENSIONS) #if !BUILDFLAG(IS_NACL) && !defined(NACL_WIN64) // Audio input. diff --git a/ppapi/proxy/ppb_instance_proxy.cc b/ppapi/proxy/ppb_instance_proxy.cc index 7de78e2..37a791c 100644 --- a/ppapi/proxy/ppb_instance_proxy.cc +++ b/ppapi/proxy/ppb_instance_proxy.cc @@ -40,6 +40,11 @@ #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 @@ -326,8 +331,24 @@ Resource* PPB_Instance_Proxy::GetSingletonResource(PP_Instance instance, 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) diff --git a/ppapi/proxy/remote_controller_resource.cc b/ppapi/proxy/remote_controller_resource.cc new file mode 100644 index 0000000..ce80056 --- /dev/null +++ b/ppapi/proxy/remote_controller_resource.cc @@ -0,0 +1,75 @@ +// 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 + +#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 keys_vec(keys, keys + key_count); + return SyncCall( + 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 keys_vec(keys, keys + key_count); + return SyncCall( + BROWSER, PpapiHostMsg_RemoteController_UnRegisterKeys(keys_vec)); +} + +} // namespace proxy +} // namespace ppapi diff --git a/ppapi/proxy/remote_controller_resource.h b/ppapi/proxy/remote_controller_resource.h new file mode 100644 index 0000000..fa81a75 --- /dev/null +++ b/ppapi/proxy/remote_controller_resource.h @@ -0,0 +1,41 @@ +// 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 + +#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_ diff --git a/ppapi/proxy/var_value_converter.cc b/ppapi/proxy/var_value_converter.cc new file mode 100644 index 0000000..9e36bde --- /dev/null +++ b/ppapi/proxy/var_value_converter.cc @@ -0,0 +1,171 @@ +// 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 + +#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 ValueFromVarArray(const PP_Var& var) { + if (var.type == PP_VARTYPE_ARRAY) { + scoped_refptr array = + scoped_refptr(ArrayVar::FromPPVar(var)); + if (!array) { + return std::make_unique(); + } + auto ret = std::make_unique(); + 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(); +} + +std::unique_ptr ValueFromVarDictionary(const PP_Var& var) { + if (var.type == PP_VARTYPE_DICTIONARY) { + scoped_refptr dict = + scoped_refptr(DictionaryVar::FromPPVar(var)); + if (!dict) { + return std::make_unique(); + } + ScopedPPVar keys_var(ScopedPPVar::PassRef(), dict->GetKeys()); + scoped_refptr keys = + scoped_refptr(ArrayVar::FromPPVar(keys_var.get())); + if (!keys) { + return std::make_unique(); + } + + auto ret = std::make_unique(); + for (size_t i = 0; i < keys->GetLength(); ++i) { + ScopedPPVar var_k(ScopedPPVar::PassRef(), keys->Get(i)); + scoped_refptr key = + scoped_refptr(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(); +} + +ScopedPPVar VarFromValueArray(const base::Value* value) { + if (!value) + return ScopedPPVar(); + + if (value->type() == base::Value::Type::LIST) { + scoped_refptr ret(new ArrayVar); + const base::ListValue* list = static_cast(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(&(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 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 ValueFromVar(const PP_Var& var) { + switch (var.type) { + case PP_VARTYPE_BOOL: + return std::make_unique(PP_ToBool(var.value.as_bool)); + case PP_VARTYPE_INT32: + return std::make_unique(var.value.as_int); + case PP_VARTYPE_DOUBLE: + return std::make_unique(var.value.as_double); + case PP_VARTYPE_STRING: { + StringVar* str = StringVar::FromPPVar(var); + if (!str) + return std::make_unique(); + return std::make_unique(str->value()); + } + case PP_VARTYPE_ARRAY: + return ValueFromVarArray(var); + case PP_VARTYPE_DICTIONARY: + return ValueFromVarDictionary(var); + default: + return std::make_unique(); + } +} + +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 diff --git a/ppapi/proxy/var_value_converter.h b/ppapi/proxy/var_value_converter.h new file mode 100644 index 0000000..4457723 --- /dev/null +++ b/ppapi/proxy/var_value_converter.h @@ -0,0 +1,41 @@ +// 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 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_ diff --git a/ppapi/proxy/var_value_converter_unittest.cc b/ppapi/proxy/var_value_converter_unittest.cc new file mode 100644 index 0000000..67ea7ef --- /dev/null +++ b/ppapi/proxy/var_value_converter_unittest.cc @@ -0,0 +1,489 @@ +// 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 +#include +#include +#include + +#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 +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_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 arr, int idx, PP_Var var) { + arr->Set(idx, var); + ppapi::PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(var); +} + +void SetAndForget(scoped_refptr 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 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 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::min())); + break; + case -101: + var = ScopedPPVar(ScopedPPVar::PassRef(), + PP_MakeInt32(std::numeric_limits::max())); + break; + default: + var = ScopedPPVar(ScopedPPVar::PassRef(), PP_MakeInt32(k)); + break; + } + + // to value + std::unique_ptr 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::min())); + break; + case -102: + var = ScopedPPVar(ScopedPPVar::PassRef(), + PP_MakeDouble(-std::numeric_limits::max())); + break; + case -101: + var = ScopedPPVar(ScopedPPVar::PassRef(), + PP_MakeDouble(std::numeric_limits::max())); + break; + default: + var = ScopedPPVar(ScopedPPVar::PassRef(), + PP_MakeDouble(static_cast(k) * M_PI)); + break; + } + + // to value + std::unique_ptr 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 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 str_var = + scoped_refptr(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 nested_array = + scoped_refptr(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 array = scoped_refptr(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 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 result = + scoped_refptr(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 str_var = + scoped_refptr(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 nested_var = + scoped_refptr(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 nested_array = + scoped_refptr(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 nested_dict = + scoped_refptr(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 dict = + scoped_refptr(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 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 result = + scoped_refptr(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 str_var = + scoped_refptr(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 nested_var = + scoped_refptr(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 nested_var2 = + scoped_refptr(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 diff --git a/ppapi/shared_impl/resource.h b/ppapi/shared_impl/resource.h index d9b7429..bdb079b 100644 --- a/ppapi/shared_impl/resource.h +++ b/ppapi/shared_impl/resource.h @@ -31,6 +31,7 @@ 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) \ @@ -51,6 +52,7 @@ 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) \ diff --git a/ppapi/shared_impl/singleton_resource_id.h b/ppapi/shared_impl/singleton_resource_id.h index 3ded9e6..1934bd7 100644 --- a/ppapi/shared_impl/singleton_resource_id.h +++ b/ppapi/shared_impl/singleton_resource_id.h @@ -11,9 +11,11 @@ namespace ppapi { // 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, }; diff --git a/ppapi/tests/all_c_includes.h b/ppapi/tests/all_c_includes.h index 8eedff1..22dc6db 100644 --- a/ppapi/tests/all_c_includes.h +++ b/ppapi/tests/all_c_includes.h @@ -111,4 +111,8 @@ #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_ */ diff --git a/ppapi/tests/all_cpp_includes.h b/ppapi/tests/all_cpp_includes.h index 0fd6e0a..4a7e090 100644 --- a/ppapi/tests/all_cpp_includes.h +++ b/ppapi/tests/all_cpp_includes.h @@ -76,4 +76,10 @@ #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_ diff --git a/ppapi/thunk/BUILD.gn b/ppapi/thunk/BUILD.gn index 87d788d..d2f00d4 100644 --- a/ppapi/thunk/BUILD.gn +++ b/ppapi/thunk/BUILD.gn @@ -5,6 +5,9 @@ import("//ppapi/buildflags/buildflags.gni") assert(enable_ppapi) +if (is_tizen) { + import("//tizen_src/build/config/tizen_features.gni") +} source_set("headers") { visibility = [ @@ -180,6 +183,15 @@ source_set("thunk") { ] } + 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", diff --git a/ppapi/thunk/interfaces_ppb_samsung.h b/ppapi/thunk/interfaces_ppb_samsung.h new file mode 100644 index 0000000..a1da47f --- /dev/null +++ b/ppapi/thunk/interfaces_ppb_samsung.h @@ -0,0 +1,17 @@ +// 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" diff --git a/ppapi/thunk/ppb_extension_system_samsung_api.h b/ppapi/thunk/ppb_extension_system_samsung_api.h new file mode 100644 index 0000000..c20cb1e --- /dev/null +++ b/ppapi/thunk/ppb_extension_system_samsung_api.h @@ -0,0 +1,32 @@ +// 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_ diff --git a/ppapi/thunk/ppb_extension_system_samsung_thunk.cc b/ppapi/thunk/ppb_extension_system_samsung_thunk.cc new file mode 100644 index 0000000..9af4a5d --- /dev/null +++ b/ppapi/thunk/ppb_extension_system_samsung_thunk.cc @@ -0,0 +1,58 @@ +// 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 enter(instance); + if (enter.failed()) + return PP_MakeUndefined(); + return enter.functions()->GetEmbedderName(); +} + +PP_Var GetCurrentExtensionInfo(PP_Instance instance) { + EnterInstanceAPI 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 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 diff --git a/ppapi/thunk/ppb_remote_controller_samsung_api.h b/ppapi/thunk/ppb_remote_controller_samsung_api.h new file mode 100644 index 0000000..122075f --- /dev/null +++ b/ppapi/thunk/ppb_remote_controller_samsung_api.h @@ -0,0 +1,34 @@ +// 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_ diff --git a/ppapi/thunk/ppb_remote_controller_samsung_thunk.cc b/ppapi/thunk/ppb_remote_controller_samsung_thunk.cc new file mode 100644 index 0000000..8b97e91 --- /dev/null +++ b/ppapi/thunk/ppb_remote_controller_samsung_thunk.cc @@ -0,0 +1,51 @@ +// 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 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 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 diff --git a/ppapi/thunk/thunk.h b/ppapi/thunk/thunk.h index aa7f1c4..a7e3030 100644 --- a/ppapi/thunk/thunk.h +++ b/ppapi/thunk/thunk.h @@ -22,6 +22,9 @@ #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 diff --git a/sandbox/policy/linux/sandbox_linux.cc b/sandbox/policy/linux/sandbox_linux.cc index 4cd2957..95ee245 100644 --- a/sandbox/policy/linux/sandbox_linux.cc +++ b/sandbox/policy/linux/sandbox_linux.cc @@ -61,6 +61,10 @@ namespace policy { 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( @@ -79,6 +83,19 @@ bool IsRunningTSAN() { #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. @@ -354,6 +371,12 @@ bool SandboxLinux::InitializeSandbox(sandbox::mojom::Sandbox sandbox_type, 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. diff --git a/sandbox/policy/linux/sandbox_linux.h b/sandbox/policy/linux/sandbox_linux.h index b921ac9..b0cc409 100644 --- a/sandbox/policy/linux/sandbox_linux.h +++ b/sandbox/policy/linux/sandbox_linux.h @@ -111,7 +111,12 @@ class SANDBOX_POLICY_EXPORT SandboxLinux { // 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 diff --git a/tizen_src/build/common.sh b/tizen_src/build/common.sh index a6dd04b..4853132 100755 --- a/tizen_src/build/common.sh +++ b/tizen_src/build/common.sh @@ -81,6 +81,7 @@ Build non gbs version of chromium-efl 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) @@ -113,6 +114,7 @@ function parseHostBuildScriptParams() { export BUILD_CHROME=0 export BUILD_SUBDIRECTORY=Release export COMPONENT_BUILD=0 + export ENABLE_PEPPER_EXTENSIONS=0 local platform="$1" shift @@ -151,6 +153,9 @@ function parseHostBuildScriptParams() { --component-build) export COMPONENT_BUILD=1 ;; + --enable-pepper-extensions) + export ENABLE_PEPPER_EXTENSIONS=1 + ;; -j*) export JOBS="$1" ;; @@ -167,12 +172,17 @@ function hostGnChromiumEfl() { 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 } diff --git a/tizen_src/build/config/BUILD.gn b/tizen_src/build/config/BUILD.gn index f86bfd2..59b1f6e 100644 --- a/tizen_src/build/config/BUILD.gn +++ b/tizen_src/build/config/BUILD.gn @@ -88,4 +88,9 @@ config("tizen_feature_flags") { "WRT_JS_BRINGUP", ] } + if (tizen_pepper_extensions) { + defines += [ + "TIZEN_PEPPER_EXTENSIONS" + ] + } } diff --git a/tizen_src/build/gn_chromiumefl.sh b/tizen_src/build/gn_chromiumefl.sh index b6f6222..b32bbeb 100755 --- a/tizen_src/build/gn_chromiumefl.sh +++ b/tizen_src/build/gn_chromiumefl.sh @@ -170,6 +170,7 @@ add_tizen_flags() { 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 @@ -226,6 +227,11 @@ add_tizen_flags() { 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() { diff --git a/tizen_src/chromium_impl/content/browser/browser_efl.gni b/tizen_src/chromium_impl/content/browser/browser_efl.gni index 158df51..34548a0 100644 --- a/tizen_src/chromium_impl/content/browser/browser_efl.gni +++ b/tizen_src/chromium_impl/content/browser/browser_efl.gni @@ -2,7 +2,9 @@ # 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 @@ -159,6 +161,21 @@ if (tizen_multimedia) { ] } +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", diff --git a/tizen_src/chromium_impl/content/browser/renderer_host/pepper/browser_pepper_host_factory_efl.cc b/tizen_src/chromium_impl/content/browser/renderer_host/pepper/browser_pepper_host_factory_efl.cc new file mode 100644 index 0000000..24050a2 --- /dev/null +++ b/tizen_src/chromium_impl/content/browser/renderer_host/pepper/browser_pepper_host_factory_efl.cc @@ -0,0 +1,50 @@ +// 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 + +#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 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(host_, instance, + resource); + } + + if (message.type() == PpapiHostMsg_RemoteController_Create::ID) { + return std::make_unique( + host_, instance, resource); + } +#endif // defined(TIZEN_PEPPER_EXTENSIONS) + + return std::unique_ptr(); +} diff --git a/tizen_src/chromium_impl/content/browser/renderer_host/pepper/browser_pepper_host_factory_efl.h b/tizen_src/chromium_impl/content/browser/renderer_host/pepper/browser_pepper_host_factory_efl.h new file mode 100644 index 0000000..53b34c8 --- /dev/null +++ b/tizen_src/chromium_impl/content/browser/renderer_host/pepper/browser_pepper_host_factory_efl.h @@ -0,0 +1,32 @@ +// 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 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_ diff --git a/tizen_src/chromium_impl/content/browser/renderer_host/pepper/pepper_extension_system_host.cc b/tizen_src/chromium_impl/content/browser/renderer_host/pepper/pepper_extension_system_host.cc new file mode 100644 index 0000000..ec69ac9 --- /dev/null +++ b/tizen_src/chromium_impl/content/browser/renderer_host/pepper/pepper_extension_system_host.cc @@ -0,0 +1,250 @@ +// 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 + +#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 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 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 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 HandleGenericSyncCall( + ExtensionSystemDelegateManager::RenderFrameID render_frame_id, + const std::string operation_name, + base::Value* raw_pointer_data) { + std::unique_ptr 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 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 data( + json_deserializer.Deserialize(nullptr, nullptr)); + if (!data) { + LOG(ERROR) << "Couldn`t deserialize data"; + return PP_ERROR_FAILED; + } + + bool is_handled; + std::unique_ptr 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 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 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 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 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(); + *was_handled = true; + return it->second(data); +} + +std::unique_ptr 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(new base::Value(id)); +} + +std::unique_ptr 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(false); + } + + bool result = EwkPrivilegeChecker::GetInstance()->CheckPrivilege(*privilege); + LOG_IF(WARNING, !result) << "Privilege " << *privilege << " is not granted"; + return std::make_unique(result); +} + +} // namespace content diff --git a/tizen_src/chromium_impl/content/browser/renderer_host/pepper/pepper_extension_system_host.h b/tizen_src/chromium_impl/content/browser/renderer_host/pepper/pepper_extension_system_host.h new file mode 100644 index 0000000..3c410d9 --- /dev/null +++ b/tizen_src/chromium_impl/content/browser/renderer_host/pepper/pepper_extension_system_host.h @@ -0,0 +1,72 @@ +// 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 +#include +#include +#include + +#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 { + 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 embedder_name); + void DidGetExtensionInfo(ppapi::host::ReplyMessageContext, + std::tuple serialized_data); + void DidHandledGenericSyncCall( + ppapi::host::ReplyMessageContext, + std::tuple operation_result); + + std::unique_ptr TryHandleInternally( + const std::string& operation_name, + const base::Value& data, + bool* was_handled); + std::unique_ptr GetWindowId(const base::Value& data); + std::unique_ptr CheckPrivilege(const base::Value& data); + + using FunctionHandler = + std::function(const base::Value&)>; + std::unordered_map extension_function_handlers_; + + ExtensionSystemDelegateManager::RenderFrameID render_frame_id_; +}; + +} // namespace content + +#endif // CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_EXTENSION_SYSTEM_HOST_H_ diff --git a/tizen_src/chromium_impl/content/browser/renderer_host/pepper/pepper_remote_controller_host.cc b/tizen_src/chromium_impl/content/browser/renderer_host/pepper/pepper_remote_controller_host.cc new file mode 100644 index 0000000..a44fbc8 --- /dev/null +++ b/tizen_src/chromium_impl/content/browser/renderer_host/pepper/pepper_remote_controller_host.cc @@ -0,0 +1,109 @@ +// 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& 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& 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 diff --git a/tizen_src/chromium_impl/content/browser/renderer_host/pepper/pepper_remote_controller_host.h b/tizen_src/chromium_impl/content/browser/renderer_host/pepper/pepper_remote_controller_host.h new file mode 100644 index 0000000..a0b64d5 --- /dev/null +++ b/tizen_src/chromium_impl/content/browser/renderer_host/pepper/pepper_remote_controller_host.h @@ -0,0 +1,71 @@ +// 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 +#include + +#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 { + 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& keys, + const base::OnceCallback cb) = 0; + + virtual void UnRegisterKeys(const std::vector& keys, + const base::OnceCallback 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& keys); + + int32_t OnHostMsgUnRegisterKeys(ppapi::host::HostMessageContext* context, + const std::vector& 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 delegate_; +}; + +} // namespace content + +#endif // CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_REMOTE_CONTROLLER_HOST_H_ diff --git a/tizen_src/chromium_impl/content/browser/renderer_host/pepper/remote_controller_wrt.cc b/tizen_src/chromium_impl/content/browser/renderer_host/pepper/remote_controller_wrt.cc new file mode 100644 index 0000000..6b1845b --- /dev/null +++ b/tizen_src/chromium_impl/content/browser/renderer_host/pepper/remote_controller_wrt.cc @@ -0,0 +1,173 @@ +// 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 +#include +#include + +#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& keys, + base::OnceCallback cb) override; + + void UnRegisterKeys(const std::vector& keys, + base::OnceCallback cb) override; + + private: + // Class which will execute requests on UI Thread + class TaskExecutor; + scoped_refptr executor_; +}; + +class RemoteControllerWRT::TaskExecutor + : public base::RefCountedThreadSafe { + public: + TaskExecutor(int render_process_id, int render_frame_id); + + int32_t RegisterKeys(const std::vector& keys); + + int32_t UnRegisterKeys(const std::vector& keys); + + private: + friend class base::RefCountedThreadSafe; + ~TaskExecutor() = default; + + int32_t DispatchToGenericSyncCall(const std::string& operation_name, + const std::vector& 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& 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& 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& 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 key_name = + std::make_unique(key_platform_name); + std::unique_ptr 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& keys, + base::OnceCallback cb) { + GetUIThreadTaskRunner({})->PostTaskAndReplyWithResult( + FROM_HERE, + base::BindOnce(&RemoteControllerWRT::TaskExecutor::RegisterKeys, executor_, + keys), + std::move(cb)); +} + +void RemoteControllerWRT::UnRegisterKeys( + const std::vector& keys, + base::OnceCallback cb) { + GetUIThreadTaskRunner({})->PostTaskAndReplyWithResult( + FROM_HERE, + base::BindOnce(&RemoteControllerWRT::TaskExecutor::UnRegisterKeys, executor_, + keys), + std::move(cb)); +} + +} // namespace + +std::unique_ptr +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(render_process_id, + render_frame_id); +} + +} // namespace content diff --git a/tizen_src/chromium_impl/content/browser/renderer_host/pepper/remote_controller_wrt.h b/tizen_src/chromium_impl/content/browser/renderer_host/pepper/remote_controller_wrt.h new file mode 100644 index 0000000..035ce57 --- /dev/null +++ b/tizen_src/chromium_impl/content/browser/renderer_host/pepper/remote_controller_wrt.h @@ -0,0 +1,22 @@ +// 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 + +#include "content/browser/renderer_host/pepper/pepper_remote_controller_host.h" + +namespace content { +class BrowserPpapiHost; + +// Factory method +std::unique_ptr +CreateRemoteControllerWRT(PP_Instance instance, + content::BrowserPpapiHost* host); + +} // namespace content + +#endif // CONTENT_BROWSER_RENDERER_HOST_PEPPER_REMOTE_CONTROLLER_WRT_H_ diff --git a/tizen_src/chromium_impl/content/public/browser/extension_system_delegate.cc b/tizen_src/chromium_impl/content/public/browser/extension_system_delegate.cc new file mode 100644 index 0000000..b983a86 --- /dev/null +++ b/tizen_src/chromium_impl/content/public/browser/extension_system_delegate.cc @@ -0,0 +1,67 @@ +// 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::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