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..6d51b41efa2c60bf2aa3b12e7eec99a090c3256e |
--- /dev/null |
+++ b/components/framelet/renderer/framelet_container.cc |
@@ -0,0 +1,262 @@ |
+// 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.mojom.h" |
+#include "components/framelet/common/framelet_constants.h" |
+#include "components/framelet/common/value_type_converters.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/common/service_registry.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 "mojo/converters/blink/blink_input_events_type_converters.h" |
+#include "mojo/converters/geometry/geometry_type_converters.h" |
+#include "mojo/converters/surfaces/surfaces_type_converters.h" |
+#include "mojo/public/cpp/bindings/map.h" |
+#include "third_party/WebKit/public/web/WebDocument.h" |
+#include "third_party/WebKit/public/web/WebFramelet.h" |
+#include "third_party/WebKit/public/web/WebInputEvent.h" |
+#include "third_party/WebKit/public/web/WebLocalFrame.h" |
+#include "ui/base/resource/resource_bundle.h" |
+ |
+namespace framelet { |
+ |
+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())), |
+ binding_(this) { |
+ SetElementInstanceID(content::RenderThread::Get()->GenerateRoutingID()); |
+} |
+ |
+FrameletContainer::~FrameletContainer() {} |
+ |
+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() { |
+ if (framelet_guest_) { |
+ framelet_guest_->Destroy(); |
+ framelet_guest_.reset(); |
+ binding_.Close(); |
+ } |
+} |
+ |
+void FrameletContainer::forwardInputEvent( |
+ const blink::WebInputEvent* input_event) { |
+ if (killed_) { |
+ // 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 (click) { |
+ CreateFrameletIfReady(ResourceMonitoring::DISABLED); |
+ return; |
+ } |
+ } |
+ |
+ if (!has_guest()) |
+ return; |
+ |
+ mojo::Array<uint8_t> mojo_input(input_event->size); |
+ memcpy(&mojo_input.front(), input_event, input_event->size); |
+ framelet_guest_->ForwardInput(std::move(mojo_input)); |
+} |
+ |
+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; |
+ |
+ framelet_guest_->Resize(mojo::Size::From(element_size_)); |
+} |
+ |
+void FrameletContainer::updateFocus(bool focused, |
+ blink::WebFocusType focus_type) { |
+ focused_ = focused; |
+ focus_type_ = focus_type; |
+ if (!has_guest()) |
+ return; |
+ framelet_guest_->SetFocus(focused, static_cast<mojom::FocusType>(focus_type)); |
+} |
+ |
+void FrameletContainer::updateVisibility(bool visible) { |
+ visible_ = visible; |
+ if (!has_guest()) |
+ return; |
+ |
+ framelet_guest_->SetVisible(visible); |
+} |
+ |
+mojo::Map<mojo::String, mojom::ValuePtr> FrameletContainer::GetParams( |
+ ResourceMonitoring resource_monitoring) const { |
+ mojo::Map<mojo::String, mojom::ValuePtr> params; |
+ params[guest_view::kElementWidth] = |
+ mojom::Value::From(element_size().width()); |
+ params[guest_view::kElementHeight] = |
+ mojom::Value::From(element_size().height()); |
+ params[guest_view::kUrl] = mojom::Value::From(url().spec()); |
+ params[kFocused] = mojom::Value::From(focused()); |
+ params[kVisible] = mojom::Value::From(visible()); |
+ params[kMonitorResources] = |
+ mojom::Value::From(resource_monitoring == ResourceMonitoring::ENABLED); |
+ return params; |
+} |
+ |
+void FrameletContainer::CreateFrameletIfReady( |
+ ResourceMonitoring resource_monitoring) { |
+ if (!ready_ || !framelet_ || !render_frame()) |
+ return; |
+ |
+ killed_ = false; |
+ solid_layer_->SetIsDrawable(false); |
+ click_to_play_layer_->SetIsDrawable(false); |
+ |
+ // Get a Framelet Factory. |
+ mojom::FrameletFactoryPtr factory; |
+ render_frame()->GetServiceRegistry()->ConnectToRemoteService( |
+ mojo::GetProxy(&factory)); |
+ |
+ // Create a Framelet. |
+ factory->Create(mojo::GetProxy(&framelet_guest_), |
+ GetParams(resource_monitoring)); |
+ |
+ // Attach the Framelet to this container. |
+ mojom::FrameletClientPtr client; |
+ binding_.Bind(GetProxy(&client)); |
+ framelet_guest_->Attach(std::move(client), GetParams(resource_monitoring)); |
+} |
+ |
+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::ReportMemoryUsage( |
+ mojom::ResourceUsageLevel usage_level) { |
+ // TODO(fsamuel): Do something useful with the heap size. |
+ switch (usage_level) { |
+ case mojom::ResourceUsageLevel::LOW: { |
+ solid_layer_->SetIsDrawable(false); |
+ click_to_play_layer_->SetIsDrawable(false); |
+ return; |
+ } |
+ case mojom::ResourceUsageLevel::MEDIUM: { |
+ solid_layer_->SetIsDrawable(true); |
+ solid_layer_->SetBackgroundColor(SkColorSetARGBInline(255, 255, 255, 0)); |
+ click_to_play_layer_->SetIsDrawable(false); |
+ return; |
+ } |
+ case mojom::ResourceUsageLevel::HIGH: { |
+ solid_layer_->SetIsDrawable(true); |
+ solid_layer_->SetBackgroundColor(SkColorSetARGBInline(255, 255, 0, 0)); |
+ click_to_play_layer_->SetIsDrawable(false); |
+ return; |
+ } |
+ case mojom::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. |
+ if (framelet_guest_) { |
+ framelet_guest_->Destroy(); |
+ framelet_guest_.reset(); |
+ binding_.Close(); |
+ } |
+ return; |
+ } |
+ default: |
+ DCHECK(false); |
+ } |
+} |
+ |
+void FrameletContainer::SetChildFrameSurface( |
+ mus::mojom::SurfaceIdPtr surface_id, |
+ mojo::SizePtr frame_size, |
+ float scale_factor) { |
+ 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.To<cc::SurfaceId>(), scale_factor, |
+ frame_size.To<gfx::Size>()); |
+ gfx::Size frame_size_in_dip( |
+ gfx::ScaleToFlooredSize(frame_size.To<gfx::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 |