Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(214)

Unified Diff: components/framelet/renderer/framelet_container.cc

Issue 1560553002: Framelet Prototype 2016 Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased + Applied Brett's Windows + Fixed security issue Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « components/framelet/renderer/framelet_container.h ('k') | components/guest_view/browser/guest_view_base.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: components/framelet/renderer/framelet_container.cc
diff --git a/components/framelet/renderer/framelet_container.cc b/components/framelet/renderer/framelet_container.cc
new file mode 100644
index 0000000000000000000000000000000000000000..9009ba0a5142a7633aa93d1b388e6728c63ca424
--- /dev/null
+++ b/components/framelet/renderer/framelet_container.cc
@@ -0,0 +1,389 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/framelet/renderer/framelet_container.h"
+
+#include "cc/blink/web_layer_impl.h"
+#include "cc/layers/solid_color_layer.h"
+#include "cc/layers/surface_layer.h"
+#include "components/framelet/common/framelet_constants.h"
+#include "components/framelet/common/framelet_messages.h"
+#include "components/guest_view/common/guest_view_constants.h"
+#include "components/guest_view/common/guest_view_messages.h"
+#include "components/guest_view/renderer/guest_view_request.h"
+#include "content/public/renderer/render_frame.h"
+#include "content/public/renderer/render_thread.h"
+#include "content/public/renderer/render_view.h"
+#include "grit/components_scaled_resources.h"
+#include "third_party/WebKit/public/web/WebDocument.h"
+#include "third_party/WebKit/public/web/WebFramelet.h"
+#include "third_party/WebKit/public/web/WebLocalFrame.h"
+#include "ui/base/resource/resource_bundle.h"
+
+namespace framelet {
+
+namespace {
+
+class FrameletCreateRequest : public guest_view::GuestViewRequest {
+ public:
+ FrameletCreateRequest(FrameletContainer* framelet_container,
+ ResourceMonitoring resource_monitoring)
+ : guest_view::GuestViewRequest(framelet_container),
+ resource_monitoring_(resource_monitoring) {}
+
+ ~FrameletCreateRequest() override {}
+
+ void PerformRequest() override {
+ DCHECK_NE(container()->element_instance_id(), guest_view::kInstanceIDNone);
+ if (!container() || !container()->render_frame())
+ return;
+
+ // TODO(fsamuel): This is a bit annoying. Maybe container should be a
+ // // template method?
+ FrameletContainer* framelet_container =
+ static_cast<FrameletContainer*>(container());
+ // TODO(fsamuel): We need a mechanism to detach/destroy a guest before
+ // creating a new one.
+ DCHECK(!framelet_container->has_guest());
+
+ scoped_ptr<base::DictionaryValue> params(new base::DictionaryValue());
+ params->SetInteger(guest_view::kElementWidth,
+ framelet_container->element_size().width());
+ params->SetInteger(guest_view::kElementHeight,
+ framelet_container->element_size().height());
+ params->SetString(guest_view::kUrl, framelet_container->url().spec());
+ params->SetBoolean(framelet::kFocused, framelet_container->focused());
+ params->SetBoolean(framelet::kVisible, framelet_container->visible());
+ params->SetBoolean(framelet::kMonitorResources,
+ resource_monitoring_ == ResourceMonitoring::ENABLED);
+
+ container()->render_frame()->Send(new ChromeGuestViewHostMsg_CreateFramelet(
+ container()->render_frame()->GetRoutingID(),
+ container()->element_instance_id(), *params));
+ }
+
+ void HandleResponse(const IPC::Message& message) override {
+ CHECK_EQ(message.type(),
+ static_cast<uint32_t>(ChromeGuestViewMsg_CreateFramelet_ACK::ID));
+ ChromeGuestViewMsg_CreateFramelet_ACK::Param param;
+ if (!ChromeGuestViewMsg_CreateFramelet_ACK::Read(&message, &param))
+ return;
+
+ int guest_instance_id = base::get<1>(param);
+ static_cast<FrameletContainer*>(container())->Attach(guest_instance_id);
+ }
+
+ void HandleDefaultResponse() override {}
+
+ private:
+ ResourceMonitoring resource_monitoring_;
+
+ DISALLOW_COPY_AND_ASSIGN(FrameletCreateRequest);
+};
+
+class FrameletAttachRequest : public guest_view::GuestViewRequest {
+ public:
+ explicit FrameletAttachRequest(FrameletContainer* framelet_container)
+ : guest_view::GuestViewRequest(framelet_container) {}
+
+ ~FrameletAttachRequest() override {}
+
+ void PerformRequest() override {
+ if (!container() || !container()->render_frame())
+ return;
+
+ // TODO(fsamuel): This is a bit annoying. Maybe container should be a
+ // // template method?
+ FrameletContainer* framelet_container =
+ static_cast<FrameletContainer*>(container());
+
+ DCHECK(framelet_container->has_guest());
+
+ scoped_ptr<base::DictionaryValue> params(new base::DictionaryValue());
+ params->SetInteger(guest_view::kElementWidth,
+ framelet_container->element_size().width());
+ params->SetInteger(guest_view::kElementHeight,
+ framelet_container->element_size().height());
+ params->SetBoolean(framelet::kFocused, framelet_container->focused());
+ params->SetBoolean(framelet::kVisible, framelet_container->visible());
+
+ // Step 1, send the attach params to guest_view/.
+ container()->render_frame()->Send(new GuestViewHostMsg_AttachGuest(
+ container()->element_instance_id(),
+ framelet_container->guest_instance_id(), *params));
+
+ // Step 1, Attach to FrameletGuest.
+ container()->render_frame()->Send(new ChromeGuestViewHostMsg_AttachFramelet(
+ container()->render_frame()->GetRoutingID(),
+ container()->element_instance_id(),
+ framelet_container->guest_instance_id(), *params));
+ }
+
+ void HandleResponse(const IPC::Message& message) override {
+ CHECK_EQ(message.type(),
+ static_cast<uint32_t>(GuestViewMsg_GuestAttached::ID));
+ // TODO(fsamuel): We probably don't care about the ontent window here,
+ // but it would be nice to be able to postMessage.
+ }
+
+ void HandleDefaultResponse() override {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(FrameletAttachRequest);
+};
+
+class FrameletDestroyRequest : public guest_view::GuestViewRequest {
+ public:
+ explicit FrameletDestroyRequest(FrameletContainer* framelet_container)
+ : guest_view::GuestViewRequest(framelet_container) {}
+
+ ~FrameletDestroyRequest() override {}
+
+ void PerformRequest() override {
+ if (!container() || !container()->render_frame())
+ return;
+
+ container()->render_frame()->Send(
+ new ChromeGuestViewHostMsg_DestroyFramelet(
+ container()->element_instance_id()));
+
+ static_cast<FrameletContainer*>(container())->Detach();
+ }
+
+ void HandleResponse(const IPC::Message& message) override {
+ CHECK_EQ(message.type(),
+ static_cast<uint32_t>(ChromeGuestViewMsg_DestroyFramelet_ACK::ID));
+ }
+
+ void HandleDefaultResponse() override {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(FrameletDestroyRequest);
+};
+
+} // namespace
+
+FrameletContainer::FrameletContainer(content::RenderFrame* render_frame,
+ const GURL& url,
+ IPC::Sender* thread_safe_sender)
+ : GuestViewContainer(render_frame),
+ guest_instance_id_(guest_view::kInstanceIDNone),
+ focused_(false),
+ visible_(false),
+ killed_(false),
+ url_(url),
+ thread_safe_sender_(thread_safe_sender),
+ framelet_(nullptr),
+ solid_layer_(
+ cc::SolidColorLayer::Create(cc_blink::WebLayerImpl::LayerSettings())),
+ click_to_play_image_(ResourceBundle::GetSharedInstance().GetImageNamed(
+ IDR_FRAMELET_CLICK_TO_PLAY)),
+ click_to_play_layer_(cc::UIResourceLayer::Create(
+ cc_blink::WebLayerImpl::LayerSettings())) {
+ SetElementInstanceID(content::RenderThread::Get()->GenerateRoutingID());
+}
+
+FrameletContainer::~FrameletContainer() {}
+
+void FrameletContainer::Attach(int guest_instance_id) {
+ // Reset the layers.
+ solid_layer_->SetIsDrawable(false);
+ click_to_play_layer_->SetIsDrawable(false);
+ DCHECK(!has_guest());
+ guest_instance_id_ = guest_instance_id;
+ linked_ptr<guest_view::GuestViewRequest> request(
+ new FrameletAttachRequest(this));
+ IssueRequest(request);
+}
+
+void FrameletContainer::Detach() {
+ guest_instance_id_ = guest_view::kInstanceIDNone;
+}
+
+bool FrameletContainer::OnMessage(const IPC::Message& message) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(FrameletContainer, message)
+ IPC_MESSAGE_HANDLER(ChromeGuestViewMsg_ReportMemoryUsage,
+ OnReportMemoryUsage)
+ IPC_MESSAGE_HANDLER(ChromeGuestViewMsg_SetChildFrameSurface,
+ OnSetChildFrameSurface)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void FrameletContainer::didAttach(blink::WebFramelet* framelet) {
+ framelet_ = framelet;
+ // Only create a Framelet if we have a non-zero size.
+ CreateFrameletIfReady(ResourceMonitoring::ENABLED);
+}
+
+void FrameletContainer::didDetach() {
+ linked_ptr<guest_view::GuestViewRequest> request(
+ new FrameletDestroyRequest(this));
+ IssueRequest(request);
+}
+
+void FrameletContainer::forwardInputEvent(
+ const blink::WebInputEvent* input_event) {
+ if (!has_guest()) {
+ // If this guest has been killed.
+ // TODO(fsamuel): We want a platform-agnostic way to detect click.
+ bool click = input_event->type == blink::WebInputEvent::GestureTap ||
+ ((input_event->type == blink::WebInputEvent::MouseUp) &&
+ (static_cast<const blink::WebMouseEvent*>(input_event)
+ ->clickCount == 1));
+ if (killed_ && click) {
+ CreateFrameletIfReady(ResourceMonitoring::DISABLED);
+ return;
+ }
+ }
+
+ render_frame()->Send(new ChromeGuestViewHostMsg_ForwardInputEvent(
+ element_instance_id(), input_event));
+}
+
+void FrameletContainer::frameRectsChanged(const blink::WebRect& frame_rect) {
+ element_size_ = gfx::Size(frame_rect.width, frame_rect.height);
+ UpdateClickToPlayLayerPosition();
+ if (!ready_) {
+ ready_ = true;
+ CreateFrameletIfReady(ResourceMonitoring::ENABLED);
+ return;
+ }
+ if (!has_guest())
+ return;
+ render_frame()->Send(new ChromeGuestViewHostMsg_ResizeFramelet(
+ element_instance_id(), element_size_));
+}
+
+void FrameletContainer::updateFocus(bool focused,
+ blink::WebFocusType focus_type) {
+ focused_ = focused;
+ focus_type_ = focus_type;
+ if (!has_guest())
+ return;
+ render_frame()->Send(new ChromeGuestViewHostMsg_SetFocus(
+ element_instance_id(), focused, focus_type));
+}
+
+void FrameletContainer::updateVisibility(bool visible) {
+ visible_ = visible;
+ if (!has_guest())
+ return;
+ render_frame()->Send(new ChromeGuestViewHostMsg_SetContainerVisible(
+ element_instance_id(), visible));
+}
+
+void FrameletContainer::CreateFrameletIfReady(
+ ResourceMonitoring resource_monitoring) {
+ if (!ready_ || !framelet_)
+ return;
+ killed_ = false;
+ // We might already have a guest at this point that is in the process of being
+ // destroyed. We don't need to worry about that now, we'll find out about it
+ // when this request is handled in queue order.
+ linked_ptr<guest_view::GuestViewRequest> request(
+ new FrameletCreateRequest(this, resource_monitoring));
+ IssueRequest(request);
+}
+
+void FrameletContainer::UpdateClickToPlayLayerPosition() {
+ gfx::PointF position(
+ (element_size().width() - click_to_play_image_.Size().width()) / 2.f,
+ (element_size().height() - click_to_play_image_.Size().height()) / 2.f);
+ click_to_play_layer_->SetPosition(position);
+}
+
+void FrameletContainer::OnReportMemoryUsage(
+ int element_instance_id,
+ const ResourceUsageLevel& memory_usage) {
+ // TODO(fsamuel): Do something useful with the heap size.
+ switch (memory_usage) {
+ case ResourceUsageLevel::LOW: {
+ solid_layer_->SetIsDrawable(false);
+ click_to_play_layer_->SetIsDrawable(false);
+ return;
+ }
+ case ResourceUsageLevel::MEDIUM: {
+ solid_layer_->SetIsDrawable(true);
+ solid_layer_->SetBackgroundColor(SkColorSetARGBInline(255, 255, 255, 0));
+ click_to_play_layer_->SetIsDrawable(false);
+ return;
+ }
+ case ResourceUsageLevel::HIGH: {
+ solid_layer_->SetIsDrawable(true);
+ solid_layer_->SetBackgroundColor(SkColorSetARGBInline(255, 255, 0, 0));
+ click_to_play_layer_->SetIsDrawable(false);
+ return;
+ }
+ case ResourceUsageLevel::CRITICAL: {
+ killed_ = true;
+ solid_layer_->SetIsDrawable(true);
+ solid_layer_->SetBackgroundColor(SkColorSetARGBInline(255, 0, 0, 0));
+ click_to_play_layer_->SetIsDrawable(true);
+ // Kill the guest.
+ linked_ptr<guest_view::GuestViewRequest> request(
+ new FrameletDestroyRequest(this));
+ IssueRequest(request);
+ return;
+ }
+ default:
+ DCHECK(false);
+ }
+}
+
+void FrameletContainer::OnSetChildFrameSurface(
+ int element_instance_id,
+ const cc::SurfaceId& surface_id,
+ const gfx::Size& frame_size,
+ float scale_factor,
+ const cc::SurfaceSequence& sequence) {
+ cc::SurfaceLayer::SatisfyCallback satisfy_callback = base::Bind(
+ &FrameletContainer::SatisfyCallbackOnCompositorThread,
+ thread_safe_sender_, render_frame()->GetRoutingID(), element_instance_id);
+ cc::SurfaceLayer::RequireCallback require_callback = base::Bind(
+ &FrameletContainer::RequireCallbackOnCompositorThread,
+ thread_safe_sender_, render_frame()->GetRoutingID(), element_instance_id);
+ scoped_refptr<cc::SurfaceLayer> surface_layer =
+ cc::SurfaceLayer::Create(cc_blink::WebLayerImpl::LayerSettings(),
+ satisfy_callback, require_callback);
+ surface_layer->SetSurfaceId(surface_id, scale_factor, frame_size);
+ gfx::Size frame_size_in_dip(
+ gfx::ScaleToFlooredSize(frame_size, 1.0f / scale_factor));
+ surface_layer->SetBounds(frame_size_in_dip);
+
+ solid_layer_->SetMasksToBounds(true);
+ solid_layer_->SetBounds(frame_size_in_dip);
+ solid_layer_->SetBackgroundColor(SkColorSetARGBInline(255, 0, 0, 192));
+ solid_layer_->SetIsDrawable(false);
+ solid_layer_->SetOpacity(0.5f);
+ surface_layer->AddChild(solid_layer_);
+
+ SkBitmap* bitmap = const_cast<SkBitmap*>(click_to_play_image_.ToSkBitmap());
+ click_to_play_layer_->SetMasksToBounds(true);
+ click_to_play_layer_->SetBounds(click_to_play_image_.Size());
+ click_to_play_layer_->SetBitmap(*bitmap);
+ click_to_play_layer_->SetOpacity(0.75f);
+ surface_layer->AddChild(click_to_play_layer_);
+
+ blink::WebLayer* layer = new cc_blink::WebLayerImpl(surface_layer);
+ framelet_->setWebLayer(layer);
+ web_layer_.reset(layer);
+}
+
+void FrameletContainer::SatisfyCallbackOnCompositorThread(
+ IPC::Sender* sender,
+ int host_routing_id,
+ int element_instance_id,
+ cc::SurfaceSequence sequence) {}
+
+void FrameletContainer::RequireCallbackOnCompositorThread(
+ IPC::Sender* sender,
+ int host_routing_id,
+ int element_instance_id,
+ cc::SurfaceId id,
+ cc::SurfaceSequence sequence) {}
+
+} // namespace framelet
« no previous file with comments | « components/framelet/renderer/framelet_container.h ('k') | components/guest_view/browser/guest_view_base.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698