From: zhao dan Date: Tue, 14 Mar 2023 10:56:26 +0000 (+0800) Subject: [M108 Migration][VD] M108 Migration for Plugin Hole X-Git-Tag: submit/tizen/20230316.160014~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ce32d27e196a38bed6b7ee28f001db7fa96e2389;p=platform%2Fframework%2Fweb%2Fchromium-efl.git [M108 Migration][VD] M108 Migration for Plugin Hole The main hole implementation for plugin and HBBTV. This patch is migrated from: https://review.tizen.org/gerrit/#/c/platform/framework/web/chromium-efl/+/270859/ Change-Id: I19e97a670c11f75461f11b656c3c71774c14402c Signed-off-by: zhao dan --- diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc index 44ed9d8..21b38c9 100644 --- a/cc/layers/layer.cc +++ b/cc/layers/layer.cc @@ -117,7 +117,8 @@ Layer::Layer() property_tree_sequence_number_(-1), ignore_set_needs_commit_for_test_(false), bitflags_(0u), - subtree_property_changed_(false) {} + subtree_property_changed_(false), + contents_opaque_is_fixed_(false) {} Layer::~Layer() { // Our parent should be holding a reference to us so there should be no @@ -867,6 +868,9 @@ bool Layer::HitTestable() const { void Layer::SetContentsOpaque(bool opaque) { DCHECK(IsPropertyChangeAllowed()); + + if (contents_opaque_is_fixed_) + return; if (inputs_.Read(*this).contents_opaque == opaque) return; auto& inputs = inputs_.Write(*this); diff --git a/cc/layers/layer.h b/cc/layers/layer.h index 08b05f5..39e9a72 100644 --- a/cc/layers/layer.h +++ b/cc/layers/layer.h @@ -182,6 +182,8 @@ class CC_EXPORT Layer : public base::RefCounted, // the background_color() if the layer says contents_opaque() is true. void SetSafeOpaqueBackgroundColor(SkColor4f background_color); + void SetContentsOpaqueFixed(bool fixed) { contents_opaque_is_fixed_ = fixed; } + // Returns a background color with opaqueness equal to the value of // contents_opaque(). // If the layer says contents_opaque() is true, in layer tree mode, this @@ -1122,6 +1124,8 @@ class CC_EXPORT Layer : public base::RefCounted, // because it's used in base::AutoReset. ProtectedSequenceReadable ignore_set_needs_commit_for_test_; + bool contents_opaque_is_fixed_ : 1; + enum : uint8_t { kDrawsContentFlagMask = 1 << 0, kShouldCheckBackfaceVisibilityFlagMask = 1 << 1, diff --git a/components/plugins/renderer/loadable_plugin_placeholder.cc b/components/plugins/renderer/loadable_plugin_placeholder.cc index b247fe9..548a8a5 100644 --- a/components/plugins/renderer/loadable_plugin_placeholder.cc +++ b/components/plugins/renderer/loadable_plugin_placeholder.cc @@ -40,6 +40,17 @@ void LoadablePluginPlaceholder::MaybeLoadBlockedPlugin( LoadablePluginPlaceholder::LoadablePluginPlaceholder( RenderFrame* render_frame, + blink::WebLocalFrame* frame, + const blink::WebPluginParams& params, + const std::string& html_data) + : PluginPlaceholderBase(render_frame, frame, params, html_data), + is_blocked_for_prerendering_(false), + allow_loading_(false), + finished_loading_(false), + weak_factory_(this) {} + +LoadablePluginPlaceholder::LoadablePluginPlaceholder( + RenderFrame* render_frame, const blink::WebPluginParams& params, const std::string& html_data) : PluginPlaceholderBase(render_frame, params, html_data), diff --git a/components/plugins/renderer/loadable_plugin_placeholder.h b/components/plugins/renderer/loadable_plugin_placeholder.h index ee2eba9..aac451d 100644 --- a/components/plugins/renderer/loadable_plugin_placeholder.h +++ b/components/plugins/renderer/loadable_plugin_placeholder.h @@ -34,6 +34,10 @@ class LoadablePluginPlaceholder : public PluginPlaceholderBase { protected: LoadablePluginPlaceholder(content::RenderFrame* render_frame, + blink::WebLocalFrame* frame, + const blink::WebPluginParams& params, + const std::string& html_data); + LoadablePluginPlaceholder(content::RenderFrame* render_frame, const blink::WebPluginParams& params, const std::string& html_data); ~LoadablePluginPlaceholder() override; diff --git a/components/plugins/renderer/plugin_placeholder.cc b/components/plugins/renderer/plugin_placeholder.cc index cb9a6ab..1255817 100644 --- a/components/plugins/renderer/plugin_placeholder.cc +++ b/components/plugins/renderer/plugin_placeholder.cc @@ -28,6 +28,23 @@ const char kPluginPlaceholderDataURL[] = "data:text/html,pluginplaceholderdata"; PluginPlaceholderBase::PluginPlaceholderBase( content::RenderFrame* render_frame, + blink::WebLocalFrame* frame, + const blink::WebPluginParams& params, + const std::string& html_data) + : content::RenderFrameObserver(render_frame), + frame_(frame), + plugin_params_(params), + plugin_(WebViewPlugin::Create(render_frame->GetWebFrame()->View(), + this, + render_frame + ? render_frame->GetBlinkPreferences() + : blink::web_pref::WebPreferences(), + html_data, + GURL(kPluginPlaceholderDataURL))), + hidden_(false) {} + +PluginPlaceholderBase::PluginPlaceholderBase( + content::RenderFrame* render_frame, const blink::WebPluginParams& params, const std::string& html_data) : content::RenderFrameObserver(render_frame), @@ -141,10 +158,20 @@ void PluginPlaceholderBase::NotifyPlaceholderReadyForTestingCallback() { void PluginPlaceholderBase::OnDestruct() {} +blink::WebLocalFrame* PluginPlaceholderBase::GetFrame() { + return frame_; +} + // static gin::WrapperInfo PluginPlaceholder::kWrapperInfo = {gin::kEmbedderNativeGin}; PluginPlaceholder::PluginPlaceholder(content::RenderFrame* render_frame, + blink::WebLocalFrame* frame, + const blink::WebPluginParams& params, + const std::string& html_data) + : PluginPlaceholderBase(render_frame, frame, params, html_data) {} + +PluginPlaceholder::PluginPlaceholder(content::RenderFrame* render_frame, const blink::WebPluginParams& params, const std::string& html_data) : PluginPlaceholderBase(render_frame, params, html_data) {} diff --git a/components/plugins/renderer/plugin_placeholder.h b/components/plugins/renderer/plugin_placeholder.h index 6c29a06..c43fe26 100644 --- a/components/plugins/renderer/plugin_placeholder.h +++ b/components/plugins/renderer/plugin_placeholder.h @@ -22,6 +22,10 @@ class PluginPlaceholderBase : public content::RenderFrameObserver, // |render_frame| is a weak pointer. If it is going away, our |plugin_| will // be destroyed as well and will notify us. PluginPlaceholderBase(content::RenderFrame* render_frame, + blink::WebLocalFrame* frame, + const blink::WebPluginParams& params, + const std::string& html_data); + PluginPlaceholderBase(content::RenderFrame* render_frame, const blink::WebPluginParams& params, const std::string& html_data); @@ -33,6 +37,7 @@ class PluginPlaceholderBase : public content::RenderFrameObserver, WebViewPlugin* plugin() { return plugin_; } protected: + blink::WebLocalFrame* GetFrame(); const blink::WebPluginParams& GetPluginParams() const; // WebViewPlugin::Delegate methods: @@ -54,6 +59,7 @@ class PluginPlaceholderBase : public content::RenderFrameObserver, // RenderFrameObserver methods: void OnDestruct() override; + blink::WebLocalFrame* frame_; blink::WebPluginParams plugin_params_; WebViewPlugin* plugin_; @@ -67,8 +73,13 @@ class PluginPlaceholder final : public PluginPlaceholderBase, static gin::WrapperInfo kWrapperInfo; PluginPlaceholder(content::RenderFrame* render_frame, + blink::WebLocalFrame* frame, const blink::WebPluginParams& params, const std::string& html_data); + PluginPlaceholder(content::RenderFrame* render_frame, + const blink::WebPluginParams& params, + const std::string& html_data); + ~PluginPlaceholder() override; private: diff --git a/components/plugins/renderer/webview_plugin.cc b/components/plugins/renderer/webview_plugin.cc index 24294f8..1d3efce 100644 --- a/components/plugins/renderer/webview_plugin.cc +++ b/components/plugins/renderer/webview_plugin.cc @@ -37,6 +37,10 @@ #include "third_party/blink/public/web/web_plugin_container.h" #include "third_party/blink/public/web/web_view.h" +#if BUILDFLAG(IS_TIZEN_TV) +#include "third_party/blink/public/platform/web_application_type.h" +#endif + using blink::DragOperationsMask; using blink::WebDragData; using blink::WebFrameWidget; @@ -61,6 +65,7 @@ WebViewPlugin::WebViewPlugin(WebView* web_view, focused_(false), is_painting_(false), is_resizing_(false), + layer_(nullptr), web_view_helper_(this, preferences, web_view->GetRendererPreferences()) {} // static @@ -118,6 +123,14 @@ bool WebViewPlugin::Initialize(WebPluginContainer* container) { // for animation again, and it does help us in the race-condition situation. container_->ScheduleAnimation(); +#if BUILDFLAG(IS_TIZEN_TV) + if (blink::IsHbbTV()) { + if (container_ && GetCclayer()) { + container_->SetCcLayer(GetCclayer()); + } + } +#endif + old_title_ = container_->GetElement().GetAttribute("title"); web_view()->SetZoomLevel( @@ -191,6 +204,12 @@ void WebViewPlugin::UpdateGeometry(const gfx::Rect& window_rect, web_view()->MainFrameWidget()->Resize(rect_.size()); } +#if BUILDFLAG(IS_TIZEN_TV) + // Need to notify plugin hole to update the rect + if (delegate_ && delegate_->PluginIsAvplayer()) + delegate_->OnUnobscuredRectUpdate(gfx::Rect(unobscured_rect)); +#endif + // Plugin updates are forbidden during Blink layout. Therefore, // UpdatePluginForNewGeometry must be posted to a task to run asynchronously. web_view_helper_.main_frame() @@ -438,7 +457,13 @@ void WebViewPlugin::UpdatePluginForNewGeometry( return; // The delegate may instantiate a new plugin. +#if BUILDFLAG(IS_TIZEN_TV) + if (!delegate_->PluginIsAvplayer()) + delegate_->OnUnobscuredRectUpdate(gfx::Rect(unobscured_rect)); +#else delegate_->OnUnobscuredRectUpdate(gfx::Rect(unobscured_rect)); +#endif + // The delegate may have dirtied style and layout of the WebView. // Run the lifecycle now so that it is clean. DCHECK(web_view()->MainFrameWidget()); diff --git a/components/plugins/renderer/webview_plugin.h b/components/plugins/renderer/webview_plugin.h index 7079ffe..886d3ea 100644 --- a/components/plugins/renderer/webview_plugin.h +++ b/components/plugins/renderer/webview_plugin.h @@ -10,6 +10,7 @@ #include "base/memory/weak_ptr.h" #include "base/task/sequenced_task_runner_helpers.h" +#include "cc/layers/layer.h" #include "mojo/public/cpp/bindings/associated_receiver.h" #include "mojo/public/cpp/bindings/associated_remote.h" #include "third_party/blink/public/mojom/input/focus_type.mojom-forward.h" @@ -63,6 +64,10 @@ class WebViewPlugin : public blink::WebPlugin, public blink::WebViewObserver { // Called when the unobscured rect of the plugin is updated. virtual void OnUnobscuredRectUpdate(const gfx::Rect& unobscured_rect) {} +#if BUILDFLAG(IS_TIZEN_TV) + virtual bool PluginIsAvplayer() { return false; } +#endif + virtual bool IsErrorPlaceholder() = 0; }; @@ -116,6 +121,8 @@ class WebViewPlugin : public blink::WebPlugin, public blink::WebViewObserver { void DidReceiveData(const char* data, size_t data_length) override; void DidFinishLoading() override; void DidFailLoading(const blink::WebURLError& error) override; + void SetCcLayer(cc::Layer* new_layer) { layer_ = new_layer; } + cc::Layer* GetCclayer() { return layer_; } private: friend class base::DeleteHelper; @@ -154,6 +161,7 @@ class WebViewPlugin : public blink::WebPlugin, public blink::WebViewObserver { bool focused_; bool is_painting_; bool is_resizing_; + cc::Layer* layer_; // A helper that handles interaction from WebViewPlugin's internal WebView. class WebViewHelper : public blink::WebViewClient, diff --git a/tizen_src/build/config/BUILD.gn b/tizen_src/build/config/BUILD.gn index 59b1f6e..335ec68 100644 --- a/tizen_src/build/config/BUILD.gn +++ b/tizen_src/build/config/BUILD.gn @@ -56,6 +56,11 @@ config("tizen_feature_flags") { if (tizen_product_tv) { defines += [ "OS_TIZEN_TV_PRODUCT" ] } + if (use_plugin_placeholder_hole) { + defines += [ + "USE_PLUGIN_PLACEHOLDER_HOLE", + ] + } if (tizen_multimedia) { defines += [ "TIZEN_MULTIMEDIA" ] } diff --git a/tizen_src/build/config/tizen_features.gni b/tizen_src/build/config/tizen_features.gni index 2cf0fc4..7c12137 100644 --- a/tizen_src/build/config/tizen_features.gni +++ b/tizen_src/build/config/tizen_features.gni @@ -57,6 +57,8 @@ declare_args() { # Tizen multimedia related tizen_multimedia = false tizen_tbm_support = false + enable_trace_event = false + use_plugin_placeholder_hole = false tizen_video_hole = false tizen_audio_io = false tizen_web_speech_recognition = false diff --git a/tizen_src/build/gn_chromiumefl.sh b/tizen_src/build/gn_chromiumefl.sh index b32bbeb..52f08d0 100755 --- a/tizen_src/build/gn_chromiumefl.sh +++ b/tizen_src/build/gn_chromiumefl.sh @@ -140,6 +140,7 @@ add_desktop_flags() { target_os="\"linux\"" use_sysroot=false use_wayland=false + use_plugin_placeholder_hole=true werror=false dcheck_always_on=false enable_nacl=false @@ -218,6 +219,12 @@ add_tizen_flags() { " fi + + if [ "$tizen_product_tv" == "true" ]; then + ADDITIONAL_GN_PARAMETERS+="enable_plugins=true + use_plugin_placeholder_hole=true + " + fi # [M49_2623] Temporary disabling the flag. # FIXME: http://165.213.149.170/jira/browse/TWF-610 ADDITIONAL_GN_PARAMETERS+="tizen_multimedia=true diff --git a/tizen_src/ewk/efl_integration/BUILD.gn b/tizen_src/ewk/efl_integration/BUILD.gn index a5601cc..06f3a8f 100755 --- a/tizen_src/ewk/efl_integration/BUILD.gn +++ b/tizen_src/ewk/efl_integration/BUILD.gn @@ -594,8 +594,14 @@ shared_library("chromium-ewk") { "renderer/gin_native_bridge_value_converter.h", "renderer/gin_native_function_invocation_helper.cc", "renderer/gin_native_function_invocation_helper.h", + "renderer/plugins/hole_layer.cc", + "renderer/plugins/hole_layer.h", + "renderer/plugins/plugin_placeholder_avplayer.cc", + "renderer/plugins/plugin_placeholder_avplayer.h", "renderer/plugins/plugin_placeholder_efl.cc", "renderer/plugins/plugin_placeholder_efl.h", + "renderer/plugins/plugin_placeholder_hole.cc", + "renderer/plugins/plugin_placeholder_hole.h", "renderer/print_web_view_helper_efl.cc", "renderer/print_web_view_helper_efl.h", "renderer/render_frame_observer_efl.cc", @@ -682,8 +688,14 @@ shared_library("chromium-ewk") { "chromium_ewk.gypi", "file_chooser_controller_efl.cc", "file_chooser_controller_efl.h", + "renderer/plugins/hole_layer.cc", + "renderer/plugins/hole_layer.h", + "renderer/plugins/plugin_placeholder_avplayer.cc", + "renderer/plugins/plugin_placeholder_avplayer.h", "renderer/plugins/plugin_placeholder_efl.cc", "renderer/plugins/plugin_placeholder_efl.h", + "renderer/plugins/plugin_placeholder_hole.cc", + "renderer/plugins/plugin_placeholder_hole.h", "renderer/render_frame_observer_efl.cc", "renderer/render_frame_observer_efl.h", "wrt/wrt_file_protocol_handler.cc", 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 1faaaad..8bce2b8 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 @@ -59,6 +59,12 @@ #if BUILDFLAG(IS_TIZEN_TV) #include "common/application_type.h" +#include "content/public/common/url_utils.h" +#include "renderer/plugins/plugin_placeholder_avplayer.h" +#endif + +#if defined(USE_PLUGIN_PLACEHOLDER_HOLE) +#include "renderer/plugins/plugin_placeholder_hole.h" #endif #if defined(TIZEN_AUTOFILL) @@ -209,16 +215,38 @@ bool ContentRendererClientEfl::OverrideCreatePlugin( if (CreateTrustedPepperPlugin(render_frame, params, plugin)) return true; #endif // TIZEN_PEPPER_EXTENSIONS -#if defined(EWK_BRINGUP) // FIXME: m67 bringup - return false; -#else - PluginPlaceholderEfl* placeholder = - PluginPlaceholderEfl::CreateMissingPlugin(render_frame, params); + +#if BUILDFLAG(ENABLE_PLUGINS) + plugins::PluginPlaceholderBase* placeholder = nullptr; +#if BUILDFLAG(IS_TIZEN_TV) +#if defined(USE_PLUGIN_PLACEHOLDER_HOLE) + if (widget_ && widget_->GetType() == V8Widget::Type::HBBTV && + PluginPlaceholderHole::SupportsMimeType(render_frame->GetWebFrame(), + params.mime_type.Utf8())) { + placeholder = PluginPlaceholderHole::Create( + render_frame, render_frame->GetWebFrame(), params); + } +#endif + if (widget_ && widget_->GetType() == V8Widget::Type::WRT && + PluginPlaceholderAvplayer::SupportsMimeType(params.mime_type.Utf8())) { + placeholder = PluginPlaceholderAvplayer::Create( + render_frame, render_frame->GetWebFrame(), params); + } +#endif + + if (!placeholder) { + placeholder = PluginPlaceholderEfl::CreateMissingPlugin( + render_frame, render_frame->GetWebFrame(), params); + } + if (!placeholder) return false; *plugin = placeholder->plugin(); return true; +#else + return false; // LCOV_EXCL_LINE #endif + } void ContentRendererClientEfl::DidCreateScriptContext( diff --git a/tizen_src/ewk/efl_integration/renderer/plugins/hole_layer.cc b/tizen_src/ewk/efl_integration/renderer/plugins/hole_layer.cc new file mode 100644 index 0000000..229112d --- /dev/null +++ b/tizen_src/ewk/efl_integration/renderer/plugins/hole_layer.cc @@ -0,0 +1,102 @@ +// Copyright 2018 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 "renderer/plugins/hole_layer.h" + +#include + +#include "cc/layers/append_quads_data.h" +#include "cc/layers/layer_impl.h" +#include "cc/trees/occlusion.h" +#include "components/viz/common/quads/shared_quad_state.h" +#include "components/viz/common/quads/solid_color_draw_quad.h" + +namespace cc { + +class HoleLayerImpl : public LayerImpl { + public: + static void AppendSolidQuads(viz::CompositorRenderPass* render_pass, + const Occlusion& occlusion_in_layer_space, + viz::SharedQuadState* shared_quad_state, + const gfx::Rect& visible_layer_rect, + SkColor color, + AppendQuadsData* append_quads_data, + bool opaque); + + HoleLayerImpl(LayerTreeImpl* tree_impl, int id) : LayerImpl(tree_impl, id) { + } + ~HoleLayerImpl() override {} + + // LayerImpl overrides. + std::unique_ptr CreateLayerImpl( + LayerTreeImpl* tree_impl) const override { + return base::WrapUnique(new HoleLayerImpl(tree_impl, id())); + } + void AppendQuads(viz::CompositorRenderPass* render_pass, + AppendQuadsData* append_quads_data) override; + + private: + const char* LayerTypeAsString() const override { return "cc::HoleLayerImpl"; } +}; + +const int kSolidQuadTileSize = 256; + +std::unique_ptr HoleLayer::CreateLayerImpl( + LayerTreeImpl* tree_impl) const { + return base::WrapUnique(new HoleLayerImpl(tree_impl, id())); +} + +void HoleLayerImpl::AppendSolidQuads(viz::CompositorRenderPass* render_pass, + const Occlusion& occlusion_in_layer_space, + viz::SharedQuadState* shared_quad_state, + const gfx::Rect& visible_layer_rect, + SkColor color, + AppendQuadsData* append_quads_data, + bool opaque) { + // We create a series of smaller quads instead of just one large one so that + // the caller can reduce the total pixels drawn. + for (int x = visible_layer_rect.x(); x < visible_layer_rect.right(); + x += kSolidQuadTileSize) { + for (int y = visible_layer_rect.y(); y < visible_layer_rect.bottom(); + y += kSolidQuadTileSize) { + gfx::Rect quad_rect( + x, y, std::min(visible_layer_rect.right() - x, kSolidQuadTileSize), + std::min(visible_layer_rect.bottom() - y, kSolidQuadTileSize)); + gfx::Rect visible_quad_rect = + occlusion_in_layer_space.GetUnoccludedContentRect(quad_rect); + if (visible_quad_rect.IsEmpty()) + continue; + + append_quads_data->visible_layer_area += + visible_quad_rect.width() * visible_quad_rect.height(); + + viz::SolidColorDrawQuad* quad = + render_pass->CreateAndAppendDrawQuad(); + + if (opaque) { + quad->SetAll(shared_quad_state, quad_rect, visible_quad_rect, false, + SkColor4f::FromColor(color), true); + } else { + quad->SetNew(shared_quad_state, quad_rect, visible_quad_rect, SkColor4f::FromColor(color), + false); + } + } + } +} + +void HoleLayerImpl::AppendQuads(viz::CompositorRenderPass* render_pass, + AppendQuadsData* append_quads_data) { + viz::SharedQuadState* shared_quad_state = + render_pass->CreateAndAppendSharedQuadState(); + PopulateSharedQuadState(shared_quad_state, true); + + AppendDebugBorderQuad(render_pass, gfx::Rect(bounds()), shared_quad_state, + append_quads_data); + + AppendSolidQuads(render_pass, draw_properties().occlusion_in_content_space, + shared_quad_state, gfx::Rect(bounds()), background_color().toSkColor(), + append_quads_data, contents_opaque()); +} + +} // namespace cc diff --git a/tizen_src/ewk/efl_integration/renderer/plugins/hole_layer.h b/tizen_src/ewk/efl_integration/renderer/plugins/hole_layer.h new file mode 100644 index 0000000..b124bee --- /dev/null +++ b/tizen_src/ewk/efl_integration/renderer/plugins/hole_layer.h @@ -0,0 +1,25 @@ +// Copyright 2018 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EWK_EFL_INTEGRATION_RENDERER_PLUGINS_HOLE_LAYER_H_ +#define EWK_EFL_INTEGRATION_RENDERER_PLUGINS_HOLE_LAYER_H_ + +#include "cc/layers/layer.h" + +namespace cc { + +class HoleLayer : public Layer { + public: + HoleLayer() {} + HoleLayer(const HoleLayer&) = delete; + HoleLayer& operator=(const HoleLayer&) = delete; + std::unique_ptr CreateLayerImpl(LayerTreeImpl* tree_impl) const override; + + private: + ~HoleLayer() override {} +}; + +} // namespace cc + +#endif // EWK_EFL_INTEGRATION_RENDERER_PLUGINS_HOLE_LAYER_H_ diff --git a/tizen_src/ewk/efl_integration/renderer/plugins/plugin_placeholder_avplayer.cc b/tizen_src/ewk/efl_integration/renderer/plugins/plugin_placeholder_avplayer.cc new file mode 100644 index 0000000..a684436 --- /dev/null +++ b/tizen_src/ewk/efl_integration/renderer/plugins/plugin_placeholder_avplayer.cc @@ -0,0 +1,82 @@ +// Copyright 2018 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 "renderer/plugins/plugin_placeholder_avplayer.h" + +#include +#include + +#include "base/memory/ptr_util.h" +#include "gin/handle.h" +#include "renderer/plugins/hole_layer.h" +#include "third_party/blink/public/web/blink.h" +#include "third_party/blink/public/web/web_local_frame.h" +#include "third_party/blink/public/web/web_plugin_container.h" + +gin::WrapperInfo PluginPlaceholderAvplayer::kWrapperInfo = { + gin::kEmbedderNativeGin}; + +// static +bool PluginPlaceholderAvplayer::SupportsMimeType(const std::string& mimetype) { + return (mimetype == "application/avplayer"); +} + +// static +PluginPlaceholderAvplayer* PluginPlaceholderAvplayer::Create( + content::RenderFrame* render_frame, + blink::WebLocalFrame* frame, + const blink::WebPluginParams& params) { + return new PluginPlaceholderAvplayer(render_frame, frame, params); +} + +PluginPlaceholderAvplayer::PluginPlaceholderAvplayer( + content::RenderFrame* render_frame, + blink::WebLocalFrame* frame, + const blink::WebPluginParams& params) + : plugins::PluginPlaceholderBase(render_frame, + frame, + params, + "" /* html_data */), + hole_layer_(nullptr), + local_rect_(0, 0, 0, 0) { + LOG(INFO) << "PluginPlaceholderAvplayer: create with type " + << params.mime_type.Utf8(); +} + +PluginPlaceholderAvplayer::~PluginPlaceholderAvplayer() {} + +void PluginPlaceholderAvplayer::OnUnobscuredRectUpdate( + const gfx::Rect& unobscured_rect) { + if (unobscured_rect.width() > 0 && unobscured_rect.height() > 0 && + local_rect_ != unobscured_rect) { + local_rect_ = unobscured_rect; + LOG(INFO) << "PluginPlaceholderAvplayer: hole rect changed " + << local_rect_.ToString(); + NotifyTransparentChanged(); + } +} + +void PluginPlaceholderAvplayer::NotifyTransparentChanged() { + if (!hole_layer_) { + if (!plugin()) + return; + blink::WebPluginContainer* container = plugin()->Container(); + if (!container) + return; + hole_layer_ = base::WrapRefCounted(new cc::HoleLayer); + container->SetCcLayer(hole_layer_.get()); + } + + // Transparent color + opaque means hole punch through. + hole_layer_->SetBackgroundColor(SkColor4f::FromColor(SK_ColorTRANSPARENT)); + hole_layer_->SetContentsOpaque(true); + hole_layer_->SetContentsOpaqueFixed(true); + + LOG(INFO) << "PluginPlaceholderAvplayer: Change Transparent succeeded"; +} + +v8::Local PluginPlaceholderAvplayer::GetV8Handle( + v8::Isolate* isolate) { + return gin::CreateHandle(isolate, this).ToV8(); +} diff --git a/tizen_src/ewk/efl_integration/renderer/plugins/plugin_placeholder_avplayer.h b/tizen_src/ewk/efl_integration/renderer/plugins/plugin_placeholder_avplayer.h new file mode 100644 index 0000000..7f881a7 --- /dev/null +++ b/tizen_src/ewk/efl_integration/renderer/plugins/plugin_placeholder_avplayer.h @@ -0,0 +1,51 @@ +// Copyright 2018 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EWK_EFL_INTEGRATION_RENDERER_PLUGINS_PLUGIN_PLACEHOLDER_AVPLAYER_H_ +#define EWK_EFL_INTEGRATION_RENDERER_PLUGINS_PLUGIN_PLACEHOLDER_AVPLAYER_H_ + +#include + +#include "base/memory/weak_ptr.h" +#include "components/plugins/renderer/plugin_placeholder.h" +#include "ui/gfx/geometry/rect.h" + +namespace cc { +class HoleLayer; +} + +class PluginPlaceholderAvplayer + : public plugins::PluginPlaceholderBase, + public gin::Wrappable { + public: + static gin::WrapperInfo kWrapperInfo; + + static bool SupportsMimeType(const std::string& mimetype); + + static PluginPlaceholderAvplayer* Create( + content::RenderFrame* render_frame, + blink::WebLocalFrame* frame, + const blink::WebPluginParams& params); + PluginPlaceholderAvplayer(const PluginPlaceholderAvplayer&) = delete; + PluginPlaceholderAvplayer& operator=(const PluginPlaceholderAvplayer&) = delete; + + private: + PluginPlaceholderAvplayer(content::RenderFrame* render_frame, + blink::WebLocalFrame* frame, + const blink::WebPluginParams& params); + ~PluginPlaceholderAvplayer() override; + + // WebViewPlugin::Delegate method. + v8::Local GetV8Handle(v8::Isolate*) override; +#if defined(OS_TIZEN_TV_PRODUCT) + bool PluginIsAvplayer() override { return true; } +#endif + void OnUnobscuredRectUpdate(const gfx::Rect& unobscured_rect) override; + void NotifyTransparentChanged(); + + scoped_refptr hole_layer_; + gfx::Rect local_rect_; +}; + +#endif // EWK_EFL_INTEGRATION_RENDERER_PLUGINS_PLUGIN_PLACEHOLDER_AVPLAYER_H_ diff --git a/tizen_src/ewk/efl_integration/renderer/plugins/plugin_placeholder_efl.cc b/tizen_src/ewk/efl_integration/renderer/plugins/plugin_placeholder_efl.cc index 55b05fc..69d3af8 100644 --- a/tizen_src/ewk/efl_integration/renderer/plugins/plugin_placeholder_efl.cc +++ b/tizen_src/ewk/efl_integration/renderer/plugins/plugin_placeholder_efl.cc @@ -12,9 +12,13 @@ gin::WrapperInfo PluginPlaceholderEfl::kWrapperInfo = {gin::kEmbedderNativeGin}; PluginPlaceholderEfl::PluginPlaceholderEfl(content::RenderFrame* render_frame, + blink::WebLocalFrame* frame, const blink::WebPluginParams& params, const std::string& html_data) - : plugins::LoadablePluginPlaceholder(render_frame, params, html_data) {} + : plugins::LoadablePluginPlaceholder(render_frame, + frame, + params, + html_data) {} PluginPlaceholderEfl::~PluginPlaceholderEfl() { } @@ -22,11 +26,11 @@ PluginPlaceholderEfl::~PluginPlaceholderEfl() { // static PluginPlaceholderEfl* PluginPlaceholderEfl::CreateMissingPlugin( content::RenderFrame* render_frame, + blink::WebLocalFrame* frame, const blink::WebPluginParams& params) { - // |missing_plugin| will destroy itself when its WebViewPlugin is going away. PluginPlaceholderEfl* missing_plugin = new PluginPlaceholderEfl( - render_frame, params, + render_frame, frame, params, dgettext("WebKit", "IDS_WEBVIEW_BODY_PLUG_IN_MISSING")); missing_plugin->AllowLoading(); return missing_plugin; diff --git a/tizen_src/ewk/efl_integration/renderer/plugins/plugin_placeholder_efl.h b/tizen_src/ewk/efl_integration/renderer/plugins/plugin_placeholder_efl.h index f931723..7a16177 100644 --- a/tizen_src/ewk/efl_integration/renderer/plugins/plugin_placeholder_efl.h +++ b/tizen_src/ewk/efl_integration/renderer/plugins/plugin_placeholder_efl.h @@ -13,24 +13,26 @@ class PluginPlaceholderEfl : public plugins::LoadablePluginPlaceholder, static gin::WrapperInfo kWrapperInfo; // Creates a new WebViewPlugin with a MissingPlugin as a delegate. - static PluginPlaceholderEfl* CreateMissingPlugin( - content::RenderFrame* render_frame, - const blink::WebPluginParams& params); - void OnBlockedContent(content::RenderFrame::PeripheralContentStatus status, - bool is_same_origin) override; - - private: - PluginPlaceholderEfl(content::RenderFrame* render_frame, - const blink::WebPluginParams& params, - const std::string& html_data); - ~PluginPlaceholderEfl() override; - - PluginPlaceholderEfl(const PluginPlaceholderEfl&) = delete; - PluginPlaceholderEfl& operator=(const PluginPlaceholderEfl&) = delete; - - // WebViewPlugin::Delegate (via PluginPlaceholder) method - v8::Local GetV8Handle(v8::Isolate*) override; - blink::WebPlugin* CreatePlugin() override; + static PluginPlaceholderEfl* CreateMissingPlugin( + content::RenderFrame* render_frame, + blink::WebLocalFrame* frame, + const blink::WebPluginParams& params); + void OnBlockedContent(content::RenderFrame::PeripheralContentStatus status, + bool is_same_origin) override; + + private: + PluginPlaceholderEfl(content::RenderFrame* render_frame, + blink::WebLocalFrame* frame, + const blink::WebPluginParams& params, + const std::string& html_data); + ~PluginPlaceholderEfl() override; + + PluginPlaceholderEfl(const PluginPlaceholderEfl&) = delete; + PluginPlaceholderEfl& operator=(const PluginPlaceholderEfl&) = delete; + + // WebViewPlugin::Delegate (via PluginPlaceholder) method + v8::Local GetV8Handle(v8::Isolate*) override; + blink::WebPlugin* CreatePlugin() override; }; #endif // PLUGIN_PLACEHOLDER_EFL_H_ diff --git a/tizen_src/ewk/efl_integration/renderer/plugins/plugin_placeholder_hole.cc b/tizen_src/ewk/efl_integration/renderer/plugins/plugin_placeholder_hole.cc new file mode 100644 index 0000000..a78eed8 --- /dev/null +++ b/tizen_src/ewk/efl_integration/renderer/plugins/plugin_placeholder_hole.cc @@ -0,0 +1,496 @@ +// Copyright 2018 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 "renderer/plugins/plugin_placeholder_hole.h" + +#include +#include + +#include "base/bind.h" +//#include "base/message_loop/message_loop.h" +#include "base/strings/utf_string_conversions.h" +#include "content/child/child_process.h" +#include "content/public/renderer/render_thread.h" +#include "content/renderer/render_thread_impl.h" +#include "gin/handle.h" +#include "renderer/plugins/hole_layer.h" +#include "third_party/blink/public/web/blink.h" +#include "third_party/blink/public/web/web_local_frame.h" +#include "third_party/blink/public/web/web_plugin_container.h" +#include "third_party/blink/public/web/web_script_source.h" +#include "third_party/blink/public/web/web_view.h" +#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h" + +namespace { +#if defined(TIZEN_DESKTOP_SUPPORT) +#define ENSURE CHECK +#else +#define ENSURE DCHECK +#endif +} // namespace + +#define arraysize(array) (int)(sizeof(array) / sizeof((array)[0])) + +// JS functions defined in Javascript and called from c++: +// +// window.supportsMimeType(type): return true if must use PluginPlaceholderHole. +// window.onObjectCreated(object): pass the object tag v8 object to the app. +// object_tag.setWindow(x, y, w, h): notify hole geometry. + +// JS function defined in c++ and called from Javascript +// object_tag.setTransparent(bool): pass true to make the hole, false for black. + +gin::WrapperInfo PluginPlaceholderHole::kWrapperInfo = { + gin::kEmbedderNativeGin}; + +// static +bool PluginPlaceholderHole::SupportsMimeType(blink::WebLocalFrame* frame, + const std::string& mimetype) { + ENSURE(frame); + ENSURE(content::ChildProcess::current() + ->main_thread() + ->main_thread_runner() + ->BelongsToCurrentThread()); + + v8::Isolate* isolate = v8::Isolate::GetCurrent(); + ENSURE(isolate); + + v8::HandleScope isolate_scope(isolate); + + std::string script = "window.supportsMimeType('" + mimetype + "')"; + v8::Local result = frame->ExecuteScriptAndReturnValue( + blink::WebScriptSource(blink::WebString::FromUTF8(script))); + if (!result.IsEmpty() && result->IsBoolean() && + v8::Local::Cast(result)->IsTrue()) { + return true; + } + + LOG(INFO) << "PluginPlaceholderHole: unsupported mimetype " << mimetype; + + return false; +} + +// static +void PluginPlaceholderHole::SetTransparentV8Impl( + const v8::FunctionCallbackInfo& args) { + ENSURE(content::ChildProcess::current() + ->main_thread() + ->main_thread_runner() + ->BelongsToCurrentThread()); + + v8::Isolate* isolate = args.GetIsolate(); + + if (args.Length() == 0 || !args[0]->IsBoolean()) { + args.GetReturnValue().Set(v8::Boolean::New(isolate, false)); + LOG(ERROR) << "PluginPlaceholderHole: wrong SetTransparentV8Impl call"; + return; + } + + const bool transparent = v8::Local::Cast(args[0])->IsTrue(); + + LOG(INFO) << "PluginPlaceholderHole::v8SetTransparent " << transparent; + + v8::Local data = v8::Local::Cast(args.Data()); + + // Thanks to PluginPlaceholderHole::GetV8Handle (see WebViewPlugin) the life + // time of PluginPlaceholder is the same as the frame. + PluginPlaceholderHole* plugin_placeholder_hole = + static_cast(data->Value()); + ENSURE(plugin_placeholder_hole); + + plugin_placeholder_hole->SetTransparentHelper(transparent); + + args.GetReturnValue().Set(v8::Boolean::New(isolate, true)); +} + +// static +PluginPlaceholderHole* PluginPlaceholderHole::Create( + content::RenderFrame* render_frame, + blink::WebLocalFrame* frame, + const blink::WebPluginParams& params) { + return new PluginPlaceholderHole(render_frame, frame, params); +} + +PluginPlaceholderHole::PluginPlaceholderHole( + content::RenderFrame* render_frame, + blink::WebLocalFrame* frame, + const blink::WebPluginParams& params) + : plugins::PluginPlaceholderBase(render_frame, + frame, + params, + "" /* html_data */), + hole_layer_(nullptr), + local_rect_(0, 0, 0, 0), + local_position_in_root_frame_(0, 0), + main_frame_(frame), + weak_factory_(this) { + LOG(INFO) << "PluginPlaceholderHole: create with type " + << params.mime_type.Utf8() << ", ptr: " << this + << ", frame: " << main_frame_; + ENSURE(main_frame_); + + // These 3 getter return the same thread. + ENSURE(content::ChildProcess::current()->main_thread()); + ENSURE(content::RenderThread::Get()); + ENSURE(content::RenderThreadImpl::current()); + + // RenderThreadImpl is the main thread of the Renderer Process. + ENSURE(content::RenderThreadImpl::current() == + content::ChildProcess::current()->main_thread()); + ENSURE(content::RenderThreadImpl::current() == content::RenderThread::Get()); + + // The PluginPlaceholderHole is created from the main thread. + main_task_runner_ = + content::ChildProcess::current()->main_thread()->main_thread_runner(); + ENSURE(main_task_runner_->BelongsToCurrentThread()); + + hole_layer_ = base::WrapRefCounted(new cc::HoleLayer); + hole_layer_->SetBackgroundColor(SkColor4f::FromColor(SK_ColorTRANSPARENT)); + hole_layer_->SetContentsOpaque(true); + hole_layer_->SetContentsOpaqueFixed(true); + plugin()->SetCcLayer(hole_layer_.get()); +} + +PluginPlaceholderHole::~PluginPlaceholderHole() { + ENSURE(main_task_runner_->BelongsToCurrentThread()); + LOG(ERROR) << "PLUGIN IS " << (void*)plugin(); + if (plugin()) + plugin()->SetCcLayer(nullptr); + v8_object_.Reset(); +} + +void PluginPlaceholderHole::PluginDestroyed() { + ENSURE(main_task_runner_->BelongsToCurrentThread()); + + if (v8_object_.IsEmpty()) { + LOG(INFO) << "PluginPlaceholderHole: no object tag to release"; + PluginPlaceholderBase::PluginDestroyed(); + return; + } + + v8::Isolate* isolate = v8::Isolate::GetCurrent(); + ENSURE(isolate); + + blink::ScriptForbiddenScope::AllowUserAgentScript allowScript; + + v8::HandleScope isolate_scope(isolate); + v8::Isolate::AllowJavascriptExecutionScope allowjs(isolate); + + v8::Local context = v8::Context::New(isolate); + if (context.IsEmpty()) { + LOG(ERROR) << "PluginPlaceholderHole: Context is Empty - can't release"; + // We know the v8_object is not empty, so release it (to reduce the + // amount of memory leaked) before dumping the plugin. If we don't exit + // here we try and de-reference the env in the context and the browser + // crashes. + v8_object_.Reset(); + PluginPlaceholderBase::PluginDestroyed(); + return; + } + + v8::Context::Scope context_scope(context); + + v8::Local v8_tag_object = + v8::Local::New(isolate, v8_object_); + + v8::Local func_name = + v8::String::NewFromUtf8(isolate, "release", v8::NewStringType::kNormal) + .ToLocalChecked(); + v8::Local func_val; + if (v8_tag_object->Get(context, func_name).ToLocal(&func_val) && + func_val->IsFunction()) { + LOG(INFO) << "PluginPlaceholderHole: call release function for mimetype: " + << GetPluginParams().mime_type.Utf8(); + + v8::Local func_handle = + v8::Local::Cast(func_val); + v8::TryCatch try_catch(isolate); + + v8::Local result_val; + v8::Local argv[] = {v8_tag_object}; + if (!func_handle->Call(context, v8_tag_object, arraysize(argv), argv) + .ToLocal(&result_val)) { + v8::String::Utf8Value error(isolate, try_catch.Exception()); + if (*error) { + LOG(ERROR) << "PluginPlaceholderHole: release function failed with " + << *error; + } + } + } + + v8_object_.Reset(); + + PluginPlaceholderBase::PluginDestroyed(); +} + +v8::Local PluginPlaceholderHole::GetV8Handle(v8::Isolate* isolate) { + ENSURE(main_task_runner_->BelongsToCurrentThread()); + + GetV8ScriptableObject(isolate); + return gin::CreateHandle(isolate, this).ToV8(); +} + +v8::Local PluginPlaceholderHole::GetV8ScriptableObject( + v8::Isolate* isolate) const { + ENSURE(main_task_runner_->BelongsToCurrentThread()); + + if (!v8_object_.IsEmpty()) + return v8::Local::New(isolate, v8_object_); + + if (!main_frame_) { + LOG(ERROR) << "PluginPlaceholderHole: main frame is null"; + return v8::Local::New(isolate, v8_object_); + } + + v8::Local context = main_frame_->MainWorldScriptContext(); + if (context.IsEmpty()) { + LOG(ERROR) << "PluginPlaceholderHole: context is empty"; + return v8::Local::New(isolate, v8_object_); + } + + v8::Context::Scope context_scope(context); + + v8::Local func_name = + v8::String::NewFromUtf8(isolate, "onObjectCreated", + v8::NewStringType::kNormal) + .ToLocalChecked(); + v8::Local func_val; + if (!context->Global()->Get(context, func_name).ToLocal(&func_val) || + !func_val->IsFunction()) { + LOG(INFO) << "PluginPlaceholderHole: no onObjectCreated function"; + return PluginPlaceholderBase::GetV8ScriptableObject(isolate); + } + + v8::Local obj_tag = v8::Object::New(isolate); + std::string mimeType = GetPluginParams().mime_type.Utf8(); + v8::Local v8context = isolate->GetCurrentContext(); + obj_tag->Set( + v8context, v8::String::NewFromUtf8(isolate, "type").ToLocalChecked(), + v8::String::NewFromUtf8(isolate, mimeType.c_str()).ToLocalChecked()); + + v8::Local plugin_placeholder_hole = + v8::External::New(isolate, const_cast(this)); + obj_tag->Set( + v8context, + v8::String::NewFromUtf8(isolate, "setTransparent").ToLocalChecked(), + v8::Function::New(v8context, SetTransparentV8Impl, + plugin_placeholder_hole) + .ToLocalChecked()); + + v8::Local func_handle = v8::Local::Cast(func_val); + v8::TryCatch try_catch(isolate); + + // onObjectCreated might call setTransparent. + v8_object_.Reset(isolate, obj_tag); + + v8::Local result_val; + v8::Local argv[] = {obj_tag}; + if (!func_handle->Call(context, context->Global(), arraysize(argv), argv) + .ToLocal(&result_val)) { + v8::String::Utf8Value error(isolate, try_catch.Exception()); + if (*error) { + LOG(ERROR) << "PluginPlaceholderHole: onObjectCreated failed with " + << *error; + } + return PluginPlaceholderBase::GetV8ScriptableObject(isolate); + } + + NotitfyAttributes(); + + LOG(INFO) << "PluginPlaceholderHole: v8 scriptable object created for type " + << mimeType << ", initial rect is " << local_rect_.ToString(); + + // Useful when OnUnobscuredRectUpdate is called before creating the v8 object. + if (local_rect_.width() > 0 && local_rect_.height() > 0) + const_cast(this)->NotifyGeometryChanged(); + + return v8::Local::New(isolate, v8_object_); +} + +void PluginPlaceholderHole::OnUnobscuredRectUpdate( + const gfx::Rect& unobscured_rect) { + ENSURE(main_task_runner_->BelongsToCurrentThread()); + + bool should_notify = false; + + if (local_rect_ != unobscured_rect) { + LOG(INFO) << "PluginPlaceholderHole: hole rect changed!!! before:" + << local_rect_.ToString() + << " after:" << unobscured_rect.ToString(); + local_rect_ = unobscured_rect; + should_notify = true; + } + + gfx::Point position_in_root_frame = + plugin()->Container()->LocalToRootFramePoint(unobscured_rect.origin()); + + if (local_position_in_root_frame_ != position_in_root_frame) { + LOG(INFO) << "PluginPlaceholderHole: position changed!!! before:" + << local_position_in_root_frame_.ToString() + << " after:" << position_in_root_frame.ToString(); + local_position_in_root_frame_ = position_in_root_frame; + should_notify = true; + } + + if (!should_notify) + return; + + if (v8_object_.IsEmpty() || !hole_layer_) { + PluginPlaceholderBase::OnUnobscuredRectUpdate(unobscured_rect); + + LOG(INFO) << "PluginPlaceholderHole: delay rect, is object empty: " + << v8_object_.IsEmpty() << ", is layer empty: " << !hole_layer_; + return; + } + + NotifyGeometryChanged(); +} + +void PluginPlaceholderHole::SetTransparentHelper(bool transparent) { + ENSURE(main_task_runner_->BelongsToCurrentThread()); + + if (!hole_layer_) { + if (!plugin()) { + LOG(ERROR) << "PluginPlaceholderHole: failed to set transparent " + << transparent << ", because plugin is null."; + return; + } + blink::WebPluginContainer* container = plugin()->Container(); + if (!container) { + LOG(ERROR) << "PluginPlaceholderHole: failed to set transparent " + << transparent << ", because container is null."; + return; + } + hole_layer_ = base::WrapRefCounted(new cc::HoleLayer); + container->SetCcLayer(hole_layer_.get()); + LOG(INFO) << "PluginPlaceholderHole: hole layer created"; + + // Useful when OnUnobscuredRectUpdate is called before creating the layer. + if (local_rect_.width() > 0 && local_rect_.height() > 0) + const_cast(this)->NotifyGeometryChanged(); + } + + // Transparent color + opaque means hole punch through. + hole_layer_->SetBackgroundColor(transparent ? SkColor4f::FromColor(SK_ColorTRANSPARENT) + : SkColor4f::FromColor(SK_ColorBLACK)); + hole_layer_->SetContentsOpaque(transparent); + hole_layer_->SetContentsOpaqueFixed(transparent); + + LOG(INFO) << "PluginPlaceholderHole: SetTransparentHelper " << transparent; +} + +void PluginPlaceholderHole::NotifyGeometryChanged() { + ENSURE(main_task_runner_->BelongsToCurrentThread()); + + if (v8_object_.IsEmpty()) { + LOG(ERROR) << "PluginPlaceholderHole::NotifyGeometryChanged, wrong state," + << "v8 object should not be empty."; + return; + } + + v8::Isolate* isolate = v8::Isolate::GetCurrent(); + ENSURE(isolate); + + v8::HandleScope isolate_scope(isolate); + v8::Local context = v8::Context::New(isolate); + v8::Context::Scope context_scope(context); + + v8::Local v8_tag_object = + v8::Local::New(isolate, v8_object_); + + v8::Local func_name = + v8::String::NewFromUtf8(isolate, "setWindow", v8::NewStringType::kNormal) + .ToLocalChecked(); + v8::Local func_val; + if (!v8_tag_object->Get(context, func_name).ToLocal(&func_val) || + !func_val->IsFunction()) { + LOG(ERROR) << "PluginPlaceholderHole: no setWindow for mimetype: " + << GetPluginParams().mime_type.Utf8(); + return; + } + + v8::Local func_handle = v8::Local::Cast(func_val); + v8::TryCatch try_catch(isolate); + + gfx::Point position_in_root_frame = + plugin()->Container()->LocalToRootFramePoint(local_rect_.origin()); + + v8::Local result_val; + v8::Local argv[] = { + v8::Integer::New(isolate, position_in_root_frame.x()), + v8::Integer::New(isolate, position_in_root_frame.y()), + v8::Integer::New(isolate, local_rect_.width()), + v8::Integer::New(isolate, local_rect_.height())}; + if (!func_handle->Call(context, v8_tag_object, arraysize(argv), argv) + .ToLocal(&result_val)) { + v8::String::Utf8Value error(isolate, try_catch.Exception()); + if (*error) + LOG(ERROR) << "PluginPlaceholderHole: setWindow failed with " << *error; + return; + } + + LOG(INFO) << "PluginPlaceholderHole: setWindow succeeded"; +} + +void PluginPlaceholderHole::NotitfyAttributes() const { + ENSURE(main_task_runner_->BelongsToCurrentThread()); + + v8::Isolate* isolate = v8::Isolate::GetCurrent(); + ENSURE(isolate); + + v8::HandleScope isolate_scope(isolate); + v8::Local context = v8::Context::New(isolate); + v8::Context::Scope context_scope(context); + + v8::Local v8_tag_object = + v8::Local::New(isolate, v8_object_); + + v8::Local func_name = + v8::String::NewFromUtf8(isolate, "setAttributes", + v8::NewStringType::kNormal) + .ToLocalChecked(); + v8::Local func_val; + if (!v8_tag_object->Get(context, func_name).ToLocal(&func_val) || + !func_val->IsFunction()) { + LOG(ERROR) << "PluginPlaceholderHole: no setAttributes for mimetype: " + << GetPluginParams().mime_type.Utf8(); + return; + } + + size_t params_size = GetPluginParams().attribute_names.size(); + if (params_size == 0) + return; + + v8::Local params = v8::Array::New(isolate, params_size); + + for (size_t i = 0; i < params_size; ++i) { + v8::Local attribute = v8::Object::New(isolate); + attribute->Set( + context, + v8::String::NewFromUtf8( + isolate, GetPluginParams().attribute_names[i].Utf8().c_str()) + .ToLocalChecked(), + v8::String::NewFromUtf8( + isolate, GetPluginParams().attribute_values[i].Utf8().c_str()) + .ToLocalChecked()); + params->Set(context, i, attribute); + } + + v8::Local func_handle = v8::Local::Cast(func_val); + v8::TryCatch try_catch(isolate); + + v8::Local result_val; + v8::Local argv[] = {params}; + if (!func_handle->Call(context, v8_tag_object, arraysize(argv), argv) + .ToLocal(&result_val)) { + v8::String::Utf8Value error(isolate, try_catch.Exception()); + if (*error) { + LOG(ERROR) << "PluginPlaceholderHole: setAttributes failed with " + << *error; + } + return; + } + + LOG(INFO) << "PluginPlaceholderHole: setAttributes succeeded"; +} diff --git a/tizen_src/ewk/efl_integration/renderer/plugins/plugin_placeholder_hole.h b/tizen_src/ewk/efl_integration/renderer/plugins/plugin_placeholder_hole.h new file mode 100644 index 0000000..6596be9 --- /dev/null +++ b/tizen_src/ewk/efl_integration/renderer/plugins/plugin_placeholder_hole.h @@ -0,0 +1,69 @@ +// Copyright 2018 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EWK_EFL_INTEGRATION_RENDERER_PLUGINS_PLUGIN_PLACEHOLDER_HOLE_H_ +#define EWK_EFL_INTEGRATION_RENDERER_PLUGINS_PLUGIN_PLACEHOLDER_HOLE_H_ + +#include + +#include "base/memory/weak_ptr.h" +#include "components/plugins/renderer/plugin_placeholder.h" + +namespace cc { +class HoleLayer; +} + +class PluginPlaceholderHole : public plugins::PluginPlaceholderBase, + public gin::Wrappable { + public: + static gin::WrapperInfo kWrapperInfo; + + static bool SupportsMimeType(blink::WebLocalFrame* frame, + const std::string& mimetype); + + static PluginPlaceholderHole* Create(content::RenderFrame* render_frame, + blink::WebLocalFrame* frame, + const blink::WebPluginParams& params); + PluginPlaceholderHole(const PluginPlaceholderHole&) = delete; + PluginPlaceholderHole& operator=(const PluginPlaceholderHole&) = delete; + + private: + static void SetTransparentV8Impl( + const v8::FunctionCallbackInfo& args); + + PluginPlaceholderHole(content::RenderFrame* render_frame, + blink::WebLocalFrame* frame, + const blink::WebPluginParams& params); + ~PluginPlaceholderHole() override; + + // WebViewPlugin::Delegate method. + void PluginDestroyed() override; + v8::Local GetV8Handle(v8::Isolate*) override; + v8::Local GetV8ScriptableObject( + v8::Isolate* isolate) const override; +#if defined(OS_TIZEN_TV_PRODUCT) + bool PluginIsAvplayer() { return false; } +#endif + void OnUnobscuredRectUpdate(const gfx::Rect& unobscured_rect) override; + + // From v8 to c++. + void SetTransparentHelper(bool transparent); + + // From c++ to v8. + void NotifyGeometryChanged(); + void NotitfyAttributes() const; + + scoped_refptr main_task_runner_; + mutable v8::Persistent v8_object_; + scoped_refptr hole_layer_; + gfx::Rect local_rect_; + gfx::Point local_position_in_root_frame_; + + // Same life time. + blink::WebLocalFrame* main_frame_; + + base::WeakPtrFactory weak_factory_; +}; + +#endif // EWK_EFL_INTEGRATION_RENDERER_PLUGINS_PLUGIN_PLACEHOLDER_HOLE_H_ diff --git a/wrt/src/renderer/tv/wrt_renderer_client_tv.cc b/wrt/src/renderer/tv/wrt_renderer_client_tv.cc index 5113c6f..5c8fc56 100755 --- a/wrt/src/renderer/tv/wrt_renderer_client_tv.cc +++ b/wrt/src/renderer/tv/wrt_renderer_client_tv.cc @@ -14,10 +14,7 @@ #include "tizen_src/chromium_impl/content/renderer/common_renderer_client.h" #include "tizen_src/ewk/efl_integration/common/application_type.h" #include "tizen_src/ewk/efl_integration/common/content_switches_efl.h" -#if !defined(WRT_JS_BRINGUP) -#include "tizen_src/ewk/efl_integration/renderer/key_systems_tizen.h" #include "tizen_src/ewk/efl_integration/renderer/plugins/plugin_placeholder_avplayer.h" -#endif #include "tizen_src/ewk/efl_integration/renderer/plugins/plugin_placeholder_efl.h" #include "url/gurl.h" #include "url/url_util.h" @@ -187,7 +184,6 @@ bool WRTRendererClientTV::OverrideCreatePlugin( plugins::PluginPlaceholderBase* placeholder = nullptr; -#if !defined(WRT_JS_BRINGUP) if (PluginPlaceholderAvplayer::SupportsMimeType(params.mime_type.Utf8())) { placeholder = PluginPlaceholderAvplayer::Create( render_frame, render_frame->GetWebFrame(), params); @@ -197,7 +193,6 @@ bool WRTRendererClientTV::OverrideCreatePlugin( placeholder = PluginPlaceholderEfl::CreateMissingPlugin( render_frame, render_frame->GetWebFrame(), params); } -#endif if (!placeholder) return false;