blob: e5a5b564ccee4089a96799cd34b5102ac3653475 [file] [log] [blame]
// Copyright 2018 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 "extensions/renderer/guest_view/mime_handler_view/mime_handler_view_frame_container.h"
#include <string>
#include "base/containers/flat_set.h"
#include "base/pickle.h"
#include "content/public/common/webplugininfo.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_frame_observer.h"
#include "content/public/renderer/render_thread.h"
#include "third_party/blink/public/web/web_document.h"
#include "third_party/blink/public/web/web_frame.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/blink/public/web/web_remote_frame.h"
#include "ui/gfx/geometry/size.h"
namespace extensions {
class MimeHandlerViewFrameContainer::RenderFrameLifetimeObserver
: public content::RenderFrameObserver {
public:
RenderFrameLifetimeObserver(content::RenderFrame* render_frame,
MimeHandlerViewFrameContainer* container);
~RenderFrameLifetimeObserver() override;
// content:RenderFrameObserver override.
void OnDestruct() final;
private:
MimeHandlerViewFrameContainer* const container_;
};
MimeHandlerViewFrameContainer::RenderFrameLifetimeObserver::
RenderFrameLifetimeObserver(content::RenderFrame* render_frame,
MimeHandlerViewFrameContainer* container)
: content::RenderFrameObserver(render_frame), container_(container) {}
MimeHandlerViewFrameContainer::RenderFrameLifetimeObserver::
~RenderFrameLifetimeObserver() {}
void MimeHandlerViewFrameContainer::RenderFrameLifetimeObserver::OnDestruct() {
container_->OnDestroyFrameContainer(container_->element_instance_id_);
}
// static.
bool MimeHandlerViewFrameContainer::IsSupportedMimeType(
const std::string& mime_type) {
return mime_type == "text/pdf" || mime_type == "application/pdf" ||
mime_type == "text/csv";
}
// static
bool MimeHandlerViewFrameContainer::Create(
const blink::WebElement& plugin_element,
const GURL& resource_url,
const std::string& mime_type,
const content::WebPluginInfo& plugin_info,
int32_t element_instance_id) {
if (plugin_info.type != content::WebPluginInfo::PLUGIN_TYPE_BROWSER_PLUGIN) {
// TODO(ekaramad): Rename this plugin type once https://crbug.com/659750 is
// fixed. We only create a MHVFC for the plugin types of BrowserPlugin
// (which used to create a MimeHandlerViewContainer).
return false;
}
if (!IsSupportedMimeType(mime_type))
return false;
// Life time is managed by the class itself: when the MimeHandlerViewGuest
// is destroyed an IPC is sent to renderer to cleanup this instance.
return new MimeHandlerViewFrameContainer(plugin_element, resource_url,
mime_type, plugin_info,
element_instance_id);
}
// static
void MimeHandlerViewFrameContainer::CreateWithFrame(
blink::WebLocalFrame* web_frame,
const GURL& resource_url,
const std::string& mime_type,
const std::string& view_id) {
new MimeHandlerViewFrameContainer(web_frame, resource_url, mime_type,
view_id);
}
MimeHandlerViewFrameContainer::MimeHandlerViewFrameContainer(
const blink::WebElement& plugin_element,
const GURL& resource_url,
const std::string& mime_type,
const content::WebPluginInfo& plugin_info,
int32_t element_instance_id)
: MimeHandlerViewContainerBase(content::RenderFrame::FromWebFrame(
plugin_element.GetDocument().GetFrame()),
plugin_info,
mime_type,
resource_url),
plugin_element_(plugin_element),
element_instance_id_(element_instance_id),
render_frame_lifetime_observer_(
new RenderFrameLifetimeObserver(GetEmbedderRenderFrame(), this)) {
is_embedded_ = true;
SendResourceRequest();
}
MimeHandlerViewFrameContainer::MimeHandlerViewFrameContainer(
blink::WebLocalFrame* web_local_frame,
const GURL& resource_url,
const std::string& mime_type,
const std::string& view_id)
: MimeHandlerViewContainerBase(
content::RenderFrame::FromWebFrame(
web_local_frame->Parent()->ToWebLocalFrame()),
content::WebPluginInfo(),
mime_type,
resource_url),
element_instance_id_(content::RenderThread::Get()->GenerateRoutingID()) {
is_embedded_ = false;
view_id_ = view_id;
plugin_frame_routing_id_ =
content::RenderFrame::FromWebFrame(web_local_frame)->GetRoutingID();
MimeHandlerViewContainerBase::CreateMimeHandlerViewGuestIfNecessary();
}
MimeHandlerViewFrameContainer::~MimeHandlerViewFrameContainer() {}
void MimeHandlerViewFrameContainer::CreateMimeHandlerViewGuestIfNecessary() {
if (auto* frame = GetContentFrame()) {
plugin_frame_routing_id_ =
content::RenderFrame::GetRoutingIdForWebFrame(frame);
}
if (plugin_frame_routing_id_ == MSG_ROUTING_NONE) {
OnDestroyFrameContainer(element_instance_id_);
return;
}
MimeHandlerViewContainerBase::CreateMimeHandlerViewGuestIfNecessary();
}
void MimeHandlerViewFrameContainer::OnRetryCreatingMimeHandlerViewGuest(
int32_t element_instance_id) {
CreateMimeHandlerViewGuestIfNecessary();
}
void MimeHandlerViewFrameContainer::OnDestroyFrameContainer(
int32_t element_instance_id) {
delete this;
}
blink::WebRemoteFrame* MimeHandlerViewFrameContainer::GetGuestProxyFrame()
const {
return GetContentFrame()->ToWebRemoteFrame();
}
int32_t MimeHandlerViewFrameContainer::GetInstanceId() const {
return element_instance_id_;
}
gfx::Size MimeHandlerViewFrameContainer::GetElementSize() const {
return gfx::Size();
}
blink::WebFrame* MimeHandlerViewFrameContainer::GetContentFrame() const {
if (is_embedded_)
return blink::WebFrame::FromFrameOwnerElement(plugin_element_);
return GetEmbedderRenderFrame()->GetWebFrame()->FirstChild();
}
// mime_handler::BeforeUnloadControl implementation.
void MimeHandlerViewFrameContainer::SetShowBeforeUnloadDialog(
bool show_dialog,
SetShowBeforeUnloadDialogCallback callback) {
// TODO(ekaramad): Implement.
}
} // namespace extensions