| Index: components/framelet/browser/framelet_guest.cc
|
| diff --git a/components/framelet/browser/framelet_guest.cc b/components/framelet/browser/framelet_guest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..9473f84cd0a2e31800389c6a0ddec1a0734087b4
|
| --- /dev/null
|
| +++ b/components/framelet/browser/framelet_guest.cc
|
| @@ -0,0 +1,222 @@
|
| +// 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/browser/framelet_guest.h"
|
| +
|
| +#include "base/strings/stringprintf.h"
|
| +#include "cc/surfaces/surface.h"
|
| +#include "components/framelet/browser/framelet_memory_tracker.h"
|
| +#include "components/framelet/browser/resource_usage_reporter.h"
|
| +#include "components/framelet/common/framelet_constants.h"
|
| +#include "components/framelet/common/framelet_messages.h"
|
| +#include "components/guest_view/browser/guest_view_manager.h"
|
| +#include "components/strings/grit/components_chromium_strings.h"
|
| +#include "content/public/browser/render_process_host.h"
|
| +#include "content/public/browser/site_instance.h"
|
| +#include "content/public/common/url_constants.h"
|
| +#include "ipc/ipc_message.h"
|
| +
|
| +namespace framelet {
|
| +
|
| +// static.
|
| +const char FrameletGuest::Type[] = "framelet";
|
| +
|
| +// static.
|
| +guest_view::GuestViewBase* FrameletGuest::Create(
|
| + content::WebContents* owner_web_contents) {
|
| + return new FrameletGuest(owner_web_contents);
|
| +}
|
| +
|
| +void FrameletGuest::AttachToEmbedderFrame(int element_instance_id,
|
| + int embedder_local_render_frame_id,
|
| + const base::DictionaryValue& params) {
|
| + element_instance_id_ = element_instance_id;
|
| + // We should only update params if there's a change between creation and
|
| + // attachment.
|
| + content::GuestAttachParams attach_params;
|
| + params.GetBoolean(framelet::kVisible, &attach_params.visible);
|
| + params.GetBoolean(framelet::kFocused, &attach_params.focused);
|
| + int element_width = 300;
|
| + int element_height = 300;
|
| + params.GetInteger(guest_view::kElementWidth, &element_width);
|
| + params.GetInteger(guest_view::kElementHeight, &element_height);
|
| + // TODO(fsamuel): This should probably be a size rather than a rect.
|
| + attach_params.view_rect = gfx::Rect(element_width, element_height);
|
| + host()->Attach(element_instance_id, owner_web_contents(), attach_params);
|
| +}
|
| +
|
| +void FrameletGuest::ReportHeapSize(int heap_size) {
|
| + resource_usage_reporter_->ReportUsage(heap_size);
|
| +}
|
| +
|
| +void FrameletGuest::OnResourceUsageLevelChanged(
|
| + const ResourceUsageLevel& usage_level) {
|
| + // The state machine reports usage level here.
|
| + // TODO(fsamuel): Feed this value through a ResourceUsageManager, that
|
| + // collects all values, and only updates the embedder if the max changes.
|
| + owner_web_contents()->Send(new ChromeGuestViewMsg_ReportMemoryUsage(
|
| + element_instance_id(), usage_level));
|
| +}
|
| +
|
| +scoped_ptr<ResourceUsageRange<int>> FrameletGuest::GetRangeForUsageLevel(
|
| + const ResourceUsageLevel& usage_level) const {
|
| + switch (usage_level) {
|
| + case ResourceUsageLevel::LOW:
|
| + return make_scoped_ptr(new ResourceUsageRange<int>(
|
| + ResourceUsageRangeType::LEFT_UNBOUNDED, kMemoryUsageLimitLow));
|
| + case ResourceUsageLevel::MEDIUM:
|
| + return make_scoped_ptr(new ResourceUsageRange<int>(
|
| + kMemoryUsageLimitLow - kMemoryUsageRangeOverlap,
|
| + kMemoryUsageLimitMedium));
|
| + case ResourceUsageLevel::HIGH:
|
| + return make_scoped_ptr(new ResourceUsageRange<int>(
|
| + kMemoryUsageLimitMedium - kMemoryUsageRangeOverlap,
|
| + kMemoryUsageLimitHigh));
|
| + case ResourceUsageLevel::CRITICAL:
|
| + return make_scoped_ptr(new ResourceUsageRange<int>(
|
| + ResourceUsageRangeType::RIGHT_UNBOUNDED, kMemoryUsageLimitHigh));
|
| + default:
|
| + CHECK(false);
|
| + return nullptr;
|
| + }
|
| +}
|
| +
|
| +bool FrameletGuest::SetChildFrameSurface(const cc::SurfaceId& surface_id,
|
| + const gfx::Size& frame_size,
|
| + float scale_factor,
|
| + const cc::SurfaceSequence& sequence) {
|
| + owner_web_contents()->Send(new ChromeGuestViewMsg_SetChildFrameSurface(
|
| + element_instance_id(), surface_id, frame_size, scale_factor, sequence));
|
| + return true;
|
| +}
|
| +
|
| +FrameletGuest::FrameletGuest(content::WebContents* owner_web_contents)
|
| + : GuestView<FrameletGuest>(owner_web_contents), monitor_resources_(true) {}
|
| +
|
| +FrameletGuest::~FrameletGuest() {}
|
| +
|
| +// content::WebContentsDelegate implementation.
|
| +bool FrameletGuest::HandleContextMenu(
|
| + const content::ContextMenuParams& params) {
|
| + return false;
|
| +}
|
| +
|
| +const char* FrameletGuest::GetAPINamespace() const {
|
| + return framelet::kEmbedderAPINamespace;
|
| +}
|
| +
|
| +bool FrameletGuest::CanRunInDetachedState() const {
|
| + return true;
|
| +}
|
| +
|
| +int FrameletGuest::GetTaskPrefix() const {
|
| + return IDS_TASK_MANAGER_FRAMELET_TAG_PREFIX;
|
| +}
|
| +
|
| +void FrameletGuest::CreateWebContents(
|
| + const base::DictionaryValue& create_params,
|
| + const guest_view::GuestViewBase::WebContentsCreatedCallback& callback) {
|
| + // For each embedder process, there should exist a framelet process.
|
| + GURL guest_site(base::StringPrintf(
|
| + "%s://framelet-%d", content::kGuestScheme,
|
| + owner_web_contents()->GetRenderProcessHost()->GetID()));
|
| +
|
| + guest_view::GuestViewManager* guest_view_manager =
|
| + guest_view::GuestViewManager::FromBrowserContext(
|
| + owner_web_contents()->GetBrowserContext());
|
| + content::SiteInstance* guest_site_instance =
|
| + guest_view_manager->GetGuestSiteInstance(guest_site);
|
| + if (!guest_site_instance) {
|
| + guest_site_instance = content::SiteInstance::CreateForURL(
|
| + owner_web_contents()->GetBrowserContext(), guest_site);
|
| + }
|
| + content::WebContents::CreateParams params(
|
| + owner_web_contents()->GetBrowserContext(), guest_site_instance);
|
| + params.guest_delegate = this;
|
| + callback.Run(content::WebContents::Create(params));
|
| +}
|
| +
|
| +void FrameletGuest::DidAttachToEmbedder() {}
|
| +
|
| +void FrameletGuest::DidInitialize(const base::DictionaryValue& create_params) {
|
| + resource_usage_reporter_.reset(new ResourceUsageReporter<int>(this));
|
| + std::string url;
|
| + create_params.GetString(guest_view::kUrl, &url);
|
| + web_contents()->GetController().LoadURL(GURL(url), content::Referrer(),
|
| + ui::PAGE_TRANSITION_AUTO_TOPLEVEL,
|
| + std::string());
|
| +
|
| + create_params.GetBoolean(framelet::kMonitorResources, &monitor_resources_);
|
| +
|
| + if (monitor_resources_) {
|
| + FrameletMemoryTracker::ClientID client_id(
|
| + web_contents()->GetRenderProcessHost()->GetID(),
|
| + web_contents()->GetRoutingID());
|
| + FrameletMemoryTracker::FromBrowserContext(browser_context())
|
| + ->AddClient(client_id, this);
|
| + }
|
| +}
|
| +
|
| +bool FrameletGuest::OnMessageReceivedFromEmbedder(const IPC::Message& message) {
|
| + bool handled = true;
|
| + IPC_BEGIN_MESSAGE_MAP(FrameletGuest, message)
|
| + IPC_MESSAGE_HANDLER(ChromeGuestViewHostMsg_DestroyFramelet,
|
| + OnDestroyFramelet)
|
| + IPC_MESSAGE_HANDLER(ChromeGuestViewHostMsg_ForwardInputEvent,
|
| + OnForwardInputEvent)
|
| + IPC_MESSAGE_HANDLER(ChromeGuestViewHostMsg_ResizeFramelet, OnResizeFramelet)
|
| + IPC_MESSAGE_HANDLER(ChromeGuestViewHostMsg_SetContainerVisible,
|
| + OnSetContainerVisible)
|
| + IPC_MESSAGE_HANDLER(ChromeGuestViewHostMsg_SetFocus, OnSetFocus)
|
| + IPC_MESSAGE_UNHANDLED(handled = false)
|
| + IPC_END_MESSAGE_MAP();
|
| + return handled;
|
| +}
|
| +
|
| +void FrameletGuest::WillDestroy() {
|
| + if (monitor_resources_) {
|
| + // TODO(fsamuel): Verify whether this is actually safe. The WebContents
|
| + // should still exist so we might be fine.
|
| + FrameletMemoryTracker::ClientID client_id(
|
| + web_contents()->GetRenderProcessHost()->GetID(),
|
| + web_contents()->GetRoutingID());
|
| + FrameletMemoryTracker::FromBrowserContext(browser_context())
|
| + ->RemoveClient(client_id);
|
| + }
|
| +}
|
| +
|
| +void FrameletGuest::OnDestroyFramelet(int element_instance_id) {
|
| + // Since FrameletGuest is only managed on one thread, any subsequent IPC sent
|
| + // to the browser will arrive after the guest has been destroyed.
|
| + owner_web_contents()->Send(
|
| + new ChromeGuestViewMsg_DestroyFramelet_ACK(element_instance_id));
|
| + Destroy();
|
| + // WARNING: We cannot access member variables beyond this point because |this|
|
| + // has been destroyed.
|
| +}
|
| +
|
| +void FrameletGuest::OnForwardInputEvent(int element_instance_id,
|
| + const blink::WebInputEvent* event) {
|
| + host()->ForwardInputEvent(event);
|
| +}
|
| +
|
| +void FrameletGuest::OnResizeFramelet(int element_instance_id,
|
| + const gfx::Size& new_size) {
|
| + guest_view::SetSizeParams size_params;
|
| + size_params.normal_size.reset(new gfx::Size(new_size));
|
| + SetSize(size_params);
|
| +}
|
| +
|
| +void FrameletGuest::OnSetContainerVisible(int element_instance_id,
|
| + bool visible) {
|
| + host()->SetContainerVisible(visible);
|
| +}
|
| +
|
| +void FrameletGuest::OnSetFocus(int element_instance_id,
|
| + bool focused,
|
| + blink::WebFocusType focus_type) {
|
| + host()->SetFocus(focused, focus_type);
|
| +}
|
| +
|
| +} // namespace framelet
|
|
|