[M108 Migration][VD] M108 Migration for Plugin Hole 37/289837/4
authorzhao dan <danys.zhao@samsung.com>
Tue, 14 Mar 2023 10:56:26 +0000 (18:56 +0800)
committerBot Blink <blinkbot@samsung.com>
Thu, 16 Mar 2023 06:42:44 +0000 (06:42 +0000)
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 <danys.zhao@samsung.com>
22 files changed:
cc/layers/layer.cc
cc/layers/layer.h
components/plugins/renderer/loadable_plugin_placeholder.cc
components/plugins/renderer/loadable_plugin_placeholder.h
components/plugins/renderer/plugin_placeholder.cc
components/plugins/renderer/plugin_placeholder.h
components/plugins/renderer/webview_plugin.cc
components/plugins/renderer/webview_plugin.h
tizen_src/build/config/BUILD.gn
tizen_src/build/config/tizen_features.gni
tizen_src/build/gn_chromiumefl.sh
tizen_src/ewk/efl_integration/BUILD.gn
tizen_src/ewk/efl_integration/renderer/content_renderer_client_efl.cc
tizen_src/ewk/efl_integration/renderer/plugins/hole_layer.cc [new file with mode: 0644]
tizen_src/ewk/efl_integration/renderer/plugins/hole_layer.h [new file with mode: 0644]
tizen_src/ewk/efl_integration/renderer/plugins/plugin_placeholder_avplayer.cc [new file with mode: 0644]
tizen_src/ewk/efl_integration/renderer/plugins/plugin_placeholder_avplayer.h [new file with mode: 0644]
tizen_src/ewk/efl_integration/renderer/plugins/plugin_placeholder_efl.cc
tizen_src/ewk/efl_integration/renderer/plugins/plugin_placeholder_efl.h
tizen_src/ewk/efl_integration/renderer/plugins/plugin_placeholder_hole.cc [new file with mode: 0644]
tizen_src/ewk/efl_integration/renderer/plugins/plugin_placeholder_hole.h [new file with mode: 0644]
wrt/src/renderer/tv/wrt_renderer_client_tv.cc

index 44ed9d8..21b38c9 100644 (file)
@@ -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);
index 08b05f5..39e9a72 100644 (file)
@@ -182,6 +182,8 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>,
   // 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<Layer>,
   // because it's used in base::AutoReset.
   ProtectedSequenceReadable<bool> ignore_set_needs_commit_for_test_;
 
+  bool contents_opaque_is_fixed_ : 1;
+
   enum : uint8_t {
     kDrawsContentFlagMask = 1 << 0,
     kShouldCheckBackfaceVisibilityFlagMask = 1 << 1,
index b247fe9..548a8a5 100644 (file)
@@ -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),
index ee2eba9..aac451d 100644 (file)
@@ -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;
index cb9a6ab..1255817 100644 (file)
@@ -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) {}
index 6c29a06..c43fe26 100644 (file)
@@ -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:
index 24294f8..1d3efce 100644 (file)
 #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());
index 7079ffe..886d3ea 100644 (file)
@@ -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<WebViewPlugin>;
@@ -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,
index 59b1f6e..335ec68 100644 (file)
@@ -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" ]
     }
index 2cf0fc4..7c12137 100644 (file)
@@ -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
index b32bbeb..52f08d0 100755 (executable)
@@ -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
index a5601cc..06f3a8f 100755 (executable)
@@ -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",
index 1faaaad..8bce2b8 100644 (file)
 
 #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 (file)
index 0000000..229112d
--- /dev/null
@@ -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 <algorithm>
+
+#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<LayerImpl> 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<LayerImpl> 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<viz::SolidColorDrawQuad>();
+
+      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 (file)
index 0000000..b124bee
--- /dev/null
@@ -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<LayerImpl> 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 (file)
index 0000000..a684436
--- /dev/null
@@ -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 <algorithm>
+#include <string>
+
+#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<v8::Value> 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 (file)
index 0000000..7f881a7
--- /dev/null
@@ -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 <string>
+
+#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<PluginPlaceholderAvplayer> {
+ 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<v8::Value> 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<cc::HoleLayer> hole_layer_;
+  gfx::Rect local_rect_;
+};
+
+#endif  // EWK_EFL_INTEGRATION_RENDERER_PLUGINS_PLUGIN_PLACEHOLDER_AVPLAYER_H_
index 55b05fc..69d3af8 100644 (file)
 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;
index f931723..7a16177 100644 (file)
@@ -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<v8::Value> 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<v8::Value> 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 (file)
index 0000000..a78eed8
--- /dev/null
@@ -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 <algorithm>
+#include <string>
+
+#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<v8::Value> result = frame->ExecuteScriptAndReturnValue(
+      blink::WebScriptSource(blink::WebString::FromUTF8(script)));
+  if (!result.IsEmpty() && result->IsBoolean() &&
+      v8::Local<v8::Boolean>::Cast(result)->IsTrue()) {
+    return true;
+  }
+
+  LOG(INFO) << "PluginPlaceholderHole: unsupported mimetype " << mimetype;
+
+  return false;
+}
+
+// static
+void PluginPlaceholderHole::SetTransparentV8Impl(
+    const v8::FunctionCallbackInfo<v8::Value>& 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<v8::Boolean>::Cast(args[0])->IsTrue();
+
+  LOG(INFO) << "PluginPlaceholderHole::v8SetTransparent " << transparent;
+
+  v8::Local<v8::External> data = v8::Local<v8::External>::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<PluginPlaceholderHole*>(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<v8::Context> 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::Object> v8_tag_object =
+      v8::Local<v8::Object>::New(isolate, v8_object_);
+
+  v8::Local<v8::String> func_name =
+      v8::String::NewFromUtf8(isolate, "release", v8::NewStringType::kNormal)
+          .ToLocalChecked();
+  v8::Local<v8::Value> 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<v8::Function> func_handle =
+        v8::Local<v8::Function>::Cast(func_val);
+    v8::TryCatch try_catch(isolate);
+
+    v8::Local<v8::Value> result_val;
+    v8::Local<v8::Value> 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<v8::Value> PluginPlaceholderHole::GetV8Handle(v8::Isolate* isolate) {
+  ENSURE(main_task_runner_->BelongsToCurrentThread());
+
+  GetV8ScriptableObject(isolate);
+  return gin::CreateHandle(isolate, this).ToV8();
+}
+
+v8::Local<v8::Object> PluginPlaceholderHole::GetV8ScriptableObject(
+    v8::Isolate* isolate) const {
+  ENSURE(main_task_runner_->BelongsToCurrentThread());
+
+  if (!v8_object_.IsEmpty())
+    return v8::Local<v8::Object>::New(isolate, v8_object_);
+
+  if (!main_frame_) {
+    LOG(ERROR) << "PluginPlaceholderHole: main frame is null";
+    return v8::Local<v8::Object>::New(isolate, v8_object_);
+  }
+
+  v8::Local<v8::Context> context = main_frame_->MainWorldScriptContext();
+  if (context.IsEmpty()) {
+    LOG(ERROR) << "PluginPlaceholderHole: context is empty";
+    return v8::Local<v8::Object>::New(isolate, v8_object_);
+  }
+
+  v8::Context::Scope context_scope(context);
+
+  v8::Local<v8::String> func_name =
+      v8::String::NewFromUtf8(isolate, "onObjectCreated",
+                              v8::NewStringType::kNormal)
+          .ToLocalChecked();
+  v8::Local<v8::Value> 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<v8::Object> obj_tag = v8::Object::New(isolate);
+  std::string mimeType = GetPluginParams().mime_type.Utf8();
+  v8::Local<v8::Context> v8context = isolate->GetCurrentContext();
+  obj_tag->Set(
+      v8context, v8::String::NewFromUtf8(isolate, "type").ToLocalChecked(),
+      v8::String::NewFromUtf8(isolate, mimeType.c_str()).ToLocalChecked());
+
+  v8::Local<v8::External> plugin_placeholder_hole =
+      v8::External::New(isolate, const_cast<PluginPlaceholderHole*>(this));
+  obj_tag->Set(
+      v8context,
+      v8::String::NewFromUtf8(isolate, "setTransparent").ToLocalChecked(),
+      v8::Function::New(v8context, SetTransparentV8Impl,
+                        plugin_placeholder_hole)
+          .ToLocalChecked());
+
+  v8::Local<v8::Function> func_handle = v8::Local<v8::Function>::Cast(func_val);
+  v8::TryCatch try_catch(isolate);
+
+  // onObjectCreated might call setTransparent.
+  v8_object_.Reset(isolate, obj_tag);
+
+  v8::Local<v8::Value> result_val;
+  v8::Local<v8::Value> 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<PluginPlaceholderHole*>(this)->NotifyGeometryChanged();
+
+  return v8::Local<v8::Object>::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<PluginPlaceholderHole*>(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<v8::Context> context = v8::Context::New(isolate);
+  v8::Context::Scope context_scope(context);
+
+  v8::Local<v8::Object> v8_tag_object =
+      v8::Local<v8::Object>::New(isolate, v8_object_);
+
+  v8::Local<v8::String> func_name =
+      v8::String::NewFromUtf8(isolate, "setWindow", v8::NewStringType::kNormal)
+          .ToLocalChecked();
+  v8::Local<v8::Value> 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<v8::Function> func_handle = v8::Local<v8::Function>::Cast(func_val);
+  v8::TryCatch try_catch(isolate);
+
+  gfx::Point position_in_root_frame =
+      plugin()->Container()->LocalToRootFramePoint(local_rect_.origin());
+
+  v8::Local<v8::Value> result_val;
+  v8::Local<v8::Value> 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<v8::Context> context = v8::Context::New(isolate);
+  v8::Context::Scope context_scope(context);
+
+  v8::Local<v8::Object> v8_tag_object =
+      v8::Local<v8::Object>::New(isolate, v8_object_);
+
+  v8::Local<v8::String> func_name =
+      v8::String::NewFromUtf8(isolate, "setAttributes",
+                              v8::NewStringType::kNormal)
+          .ToLocalChecked();
+  v8::Local<v8::Value> 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<v8::Array> params = v8::Array::New(isolate, params_size);
+
+  for (size_t i = 0; i < params_size; ++i) {
+    v8::Local<v8::Object> 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<v8::Function> func_handle = v8::Local<v8::Function>::Cast(func_val);
+  v8::TryCatch try_catch(isolate);
+
+  v8::Local<v8::Value> result_val;
+  v8::Local<v8::Value> 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 (file)
index 0000000..6596be9
--- /dev/null
@@ -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 <string>
+
+#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<PluginPlaceholderHole> {
+ 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<v8::Value>& args);
+
+  PluginPlaceholderHole(content::RenderFrame* render_frame,
+                        blink::WebLocalFrame* frame,
+                        const blink::WebPluginParams& params);
+  ~PluginPlaceholderHole() override;
+
+  // WebViewPlugin::Delegate method.
+  void PluginDestroyed() override;
+  v8::Local<v8::Value> GetV8Handle(v8::Isolate*) override;
+  v8::Local<v8::Object> 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<base::SingleThreadTaskRunner> main_task_runner_;
+  mutable v8::Persistent<v8::Object> v8_object_;
+  scoped_refptr<cc::HoleLayer> hole_layer_;
+  gfx::Rect local_rect_;
+  gfx::Point local_position_in_root_frame_;
+
+  // Same life time.
+  blink::WebLocalFrame* main_frame_;
+
+  base::WeakPtrFactory<PluginPlaceholderHole> weak_factory_;
+};
+
+#endif  // EWK_EFL_INTEGRATION_RENDERER_PLUGINS_PLUGIN_PLACEHOLDER_HOLE_H_
index 5113c6f..5c8fc56 100755 (executable)
 #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;