| 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
|
|
|