Commit 3c2d1e3b authored by Dave Tapuska's avatar Dave Tapuska Committed by Chromium LUCI CQ

Convert FrameHostMsg_OpenChannelToPepperPlugin to mojom.

Move processing the OpenChannelToPepperPlugin to mojo and handling on
the Pepper specific PepperRendererConnection class. This will allow
the removal of the RenderFrameMessageFilter in a following CL.

The IPC::ChannelHandle that was passed via legacy IPC is now passed
via handle<message_pipe>. There are conversions from the ChannelHandle
to a ScopedMessagePipeHandle, this is safe because Legacy IPC param
traits took ownership of the ChannelHandle during its serialization.
Now it is just more explicit.

BUG=1157519

Change-Id: I6d8a979f98fd91848ae12fd5a6a7234e3ce5e217
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2630226
Commit-Queue: Dave Tapuska <dtapuska@chromium.org>
Reviewed-by: default avatarBill Budge <bbudge@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarArthur Sonzogni <arthursonzogni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#844134}
parent 42f5ba34
......@@ -11,15 +11,20 @@
#include "base/bind.h"
#include "base/memory/ref_counted.h"
#include "base/stl_util.h"
#include "content/browser/bad_message.h"
#include "content/browser/browser_child_process_host_impl.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/plugin_service_impl.h"
#include "content/browser/ppapi_plugin_process_host.h"
#include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h"
#include "content/browser/renderer_host/pepper/pepper_file_ref_host.h"
#include "content/browser/renderer_host/pepper/pepper_file_system_browser_host.h"
#include "content/common/frame_messages.h"
#include "content/common/pepper_renderer_instance_data.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/content_client.h"
#include "ipc/ipc_message_macros.h"
#include "ppapi/host/resource_host.h"
......@@ -94,11 +99,49 @@ PendingHostCreator::~PendingHostCreator() {
} // namespace
PepperRendererConnection::PepperRendererConnection(int render_process_id)
class PepperRendererConnection::OpenChannelToPpapiPluginCallback
: public PpapiPluginProcessHost::PluginClient {
public:
OpenChannelToPpapiPluginCallback(PepperRendererConnection* filter,
OpenChannelToPepperPluginCallback callback)
: callback_(std::move(callback)), filter_(filter) {}
void GetPpapiChannelInfo(base::ProcessHandle* renderer_handle,
int* renderer_id) override {
// base::kNullProcessHandle indicates that the channel will be used by the
// browser itself. Make sure we never output that value here.
CHECK_NE(base::kNullProcessHandle, filter_->PeerHandle());
*renderer_handle = filter_->PeerHandle();
*renderer_id = filter_->render_process_id_;
}
void OnPpapiChannelOpened(const IPC::ChannelHandle& channel_handle,
base::ProcessId plugin_pid,
int plugin_child_id) override {
std::move(callback_).Run(mojo::MakeScopedHandle(channel_handle.mojo_handle),
plugin_pid, plugin_child_id);
delete this;
}
bool Incognito() override { return filter_->incognito_; }
private:
OpenChannelToPepperPluginCallback callback_;
scoped_refptr<PepperRendererConnection> filter_;
};
PepperRendererConnection::PepperRendererConnection(
int render_process_id,
PluginServiceImpl* plugin_service,
BrowserContext* browser_context,
StoragePartition* storage_partition)
: BrowserMessageFilter(kPepperFilteredMessageClasses,
base::size(kPepperFilteredMessageClasses)),
BrowserAssociatedInterface<mojom::PepperIOHost>(this),
render_process_id_(render_process_id) {
render_process_id_(render_process_id),
incognito_(browser_context->IsOffTheRecord()),
plugin_service_(plugin_service),
profile_data_directory_(storage_partition->GetPath()) {
// Only give the renderer permission for stable APIs.
in_process_host_.reset(new BrowserPpapiHostImpl(this,
ppapi::PpapiPermissions(),
......@@ -294,4 +337,24 @@ void PepperRendererConnection::DidDeleteOutOfProcessPepperInstance(
}
}
void PepperRendererConnection::OpenChannelToPepperPlugin(
const url::Origin& embedder_origin,
const base::FilePath& path,
const base::Optional<url::Origin>& origin_lock,
OpenChannelToPepperPluginCallback callback) {
// Enforce that the sender of the IPC (i.e. |render_process_id_|) is actually
// able/allowed to host a frame with |embedder_origin|.
auto* policy = ChildProcessSecurityPolicyImpl::GetInstance();
if (!policy->CanAccessDataForOrigin(render_process_id_, embedder_origin)) {
bad_message::ReceivedBadMessage(
this, bad_message::RFMF_INVALID_PLUGIN_EMBEDDER_ORIGIN);
return;
}
plugin_service_->OpenChannelToPpapiPlugin(
render_process_id_, embedder_origin, path, profile_data_directory_,
origin_lock,
new OpenChannelToPpapiPluginCallback(this, std::move(callback)));
}
} // namespace content
......@@ -24,7 +24,10 @@ class ResourceMessageCallParams;
namespace content {
class BrowserContext;
class BrowserPpapiHostImpl;
class PluginServiceImpl;
class StoragePartition;
// This class represents a connection from the browser to the renderer for
// sending/receiving pepper ResourceHost related messages. When the browser
......@@ -34,7 +37,10 @@ class PepperRendererConnection
: public BrowserMessageFilter,
public BrowserAssociatedInterface<mojom::PepperIOHost> {
public:
explicit PepperRendererConnection(int render_process_id);
PepperRendererConnection(int render_process_id,
PluginServiceImpl* plugin_service,
BrowserContext* browser_context,
StoragePartition* storage_partition);
// BrowserMessageFilter overrides.
bool OnMessageReceived(const IPC::Message& msg) override;
......@@ -42,6 +48,7 @@ class PepperRendererConnection
private:
~PepperRendererConnection() override;
class OpenChannelToPpapiPluginCallback;
// Returns the host for the child process for the given |child_process_id|.
// If |child_process_id| is 0, returns the host owned by this
// PepperRendererConnection, which serves as the host for in-process plugins.
......@@ -72,8 +79,14 @@ class PepperRendererConnection
void DidDeleteOutOfProcessPepperInstance(int32_t plugin_child_id,
int32_t pp_instance,
bool is_external) override;
void OpenChannelToPepperPlugin(
const url::Origin& embedder_origin,
const base::FilePath& path,
const base::Optional<url::Origin>& origin_lock,
OpenChannelToPepperPluginCallback callback) override;
int render_process_id_;
const int render_process_id_;
const bool incognito_;
// We have a single BrowserPpapiHost per-renderer for all in-process plugins
// running. This is just a work-around allowing new style resources to work
......@@ -81,6 +94,9 @@ class PepperRendererConnection
// information (like the plugin name) won't be available.
std::unique_ptr<BrowserPpapiHostImpl> in_process_host_;
PluginServiceImpl* const plugin_service_;
const base::FilePath profile_data_directory_;
DISALLOW_COPY_AND_ASSIGN(PepperRendererConnection);
};
......
......@@ -70,34 +70,6 @@ class RenderMessageCompletionCallback {
} // namespace
class RenderFrameMessageFilter::OpenChannelToPpapiPluginCallback
: public RenderMessageCompletionCallback,
public PpapiPluginProcessHost::PluginClient {
public:
OpenChannelToPpapiPluginCallback(RenderFrameMessageFilter* filter,
IPC::Message* reply_msg)
: RenderMessageCompletionCallback(filter, reply_msg) {}
void GetPpapiChannelInfo(base::ProcessHandle* renderer_handle,
int* renderer_id) override {
// base::kNullProcessHandle indicates that the channel will be used by the
// browser itself. Make sure we never output that value here.
CHECK_NE(base::kNullProcessHandle, filter()->PeerHandle());
*renderer_handle = filter()->PeerHandle();
*renderer_id = filter()->render_process_id_;
}
void OnPpapiChannelOpened(const IPC::ChannelHandle& channel_handle,
base::ProcessId plugin_pid,
int plugin_child_id) override {
FrameHostMsg_OpenChannelToPepperPlugin::WriteReplyParams(
reply_msg(), channel_handle, plugin_pid, plugin_child_id);
SendReplyAndDeleteThis();
}
bool Incognito() override { return filter()->incognito_; }
};
RenderFrameMessageFilter::RenderFrameMessageFilter(
int render_process_id,
PluginServiceImpl* plugin_service,
......@@ -105,8 +77,6 @@ RenderFrameMessageFilter::RenderFrameMessageFilter(
StoragePartition* storage_partition)
: BrowserMessageFilter(FrameMsgStart),
plugin_service_(plugin_service),
profile_data_directory_(storage_partition->GetPath()),
incognito_(browser_context->IsOffTheRecord()),
render_process_id_(render_process_id) {}
RenderFrameMessageFilter::~RenderFrameMessageFilter() {
......@@ -118,8 +88,6 @@ bool RenderFrameMessageFilter::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(RenderFrameMessageFilter, message)
IPC_MESSAGE_HANDLER(FrameHostMsg_GetPluginInfo, OnGetPluginInfo)
IPC_MESSAGE_HANDLER_DELAY_REPLY(FrameHostMsg_OpenChannelToPepperPlugin,
OnOpenChannelToPepperPlugin)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
......@@ -151,24 +119,4 @@ void RenderFrameMessageFilter::OnGetPluginInfo(
allow_wildcard, nullptr, info, actual_mime_type);
}
void RenderFrameMessageFilter::OnOpenChannelToPepperPlugin(
const url::Origin& embedder_origin,
const base::FilePath& path,
const base::Optional<url::Origin>& origin_lock,
IPC::Message* reply_msg) {
// Enforce that the sender of the IPC (i.e. |render_process_id_|) is actually
// able/allowed to host a frame with |embedder_origin|.
auto* policy = ChildProcessSecurityPolicyImpl::GetInstance();
if (!policy->CanAccessDataForOrigin(render_process_id_, embedder_origin)) {
NOTREACHED() << embedder_origin;
bad_message::ReceivedBadMessage(
this, bad_message::RFMF_INVALID_PLUGIN_EMBEDDER_ORIGIN);
return;
}
plugin_service_->OpenChannelToPpapiPlugin(
render_process_id_, embedder_origin, path, profile_data_directory_,
origin_lock, new OpenChannelToPpapiPluginCallback(this, reply_msg));
}
} // namespace content
......@@ -60,8 +60,6 @@ class CONTENT_EXPORT RenderFrameMessageFilter : public BrowserMessageFilter {
friend class BrowserThread;
friend class base::DeleteHelper<RenderFrameMessageFilter>;
class OpenChannelToPpapiPluginCallback;
~RenderFrameMessageFilter() override;
void OnGetPluginInfo(int render_frame_id,
......@@ -71,21 +69,8 @@ class CONTENT_EXPORT RenderFrameMessageFilter : public BrowserMessageFilter {
bool* found,
WebPluginInfo* info,
std::string* actual_mime_type);
void OnOpenChannelToPepperPlugin(
const url::Origin& embedder_origin,
const base::FilePath& path,
const base::Optional<url::Origin>& origin_lock,
IPC::Message* reply_msg);
void OnOpenChannelToPpapiBroker(int routing_id, const base::FilePath& path);
PluginServiceImpl* plugin_service_;
base::FilePath profile_data_directory_;
// Initialized to 0, accessed on FILE thread only.
base::TimeTicks last_plugin_refresh_time_;
// Whether this process is used for incognito contents.
const bool incognito_;
const int render_process_id_;
};
......
......@@ -1930,7 +1930,9 @@ void RenderProcessHostImpl::CreateMessageFilters() {
GetID(), PluginServiceImpl::GetInstance(), GetBrowserContext(),
storage_partition_impl_));
AddFilter(new PepperRendererConnection(GetID()));
AddFilter(new PepperRendererConnection(
GetID(), PluginServiceImpl::GetInstance(), GetBrowserContext(),
storage_partition_impl_));
#endif
p2p_socket_dispatcher_host_ =
......
......@@ -248,31 +248,6 @@ IPC_SYNC_MESSAGE_CONTROL4_3(FrameHostMsg_GetPluginInfo,
content::WebPluginInfo /* plugin info */,
std::string /* actual_mime_type */)
// A renderer sends this to the browser process when it wants to create a ppapi
// plugin. The browser will create the plugin process if necessary, and will
// return a handle to the channel on success.
//
// The plugin_child_id is the ChildProcessHost ID assigned in the browser
// process. This ID is valid only in the context of the browser process and is
// used to identify the proper process when the renderer notifies it that the
// plugin is hung.
//
// |embedder_origin| provides the origin of the frame that embeds the plugin
// (i.e. the origin of the document that contains the <embed> html tag).
// |embedder_origin| needs to be included in the message payload, because the
// message is received and handled on the IO thread in the browser process
// (where it is not possible to consult
// RenderFrameHostImpl::GetLastCommittedOrigin).
//
// On error an empty string and null handles are returned.
IPC_SYNC_MESSAGE_CONTROL3_3(FrameHostMsg_OpenChannelToPepperPlugin,
url::Origin /* embedder_origin */,
base::FilePath /* path */,
base::Optional<url::Origin>, /* origin_lock */
IPC::ChannelHandle /* handle to channel */,
base::ProcessId /* plugin_pid */,
int /* plugin_child_id */)
#endif // BUILDFLAG(ENABLE_PLUGINS)
// Used to tell the parent that the user right clicked on an area of the
......
......@@ -6,6 +6,7 @@ module content.mojom;
import "mojo/public/mojom/base/file_path.mojom";
import "mojo/public/mojom/base/process_id.mojom";
import "url/mojom/origin.mojom";
import "url/mojom/url.mojom";
// Generic Pepper messages. Implemented by the browser.
......@@ -60,6 +61,30 @@ interface PepperIOHost {
DidDeleteOutOfProcessPepperInstance(int32 plugin_child_id,
int32 pp_instance,
bool is_external);
// A renderer sends this to the browser process when it wants to create a
// ppapi plugin. The browser will create the plugin process if necessary,
// and will return a handle to the channel on success.
//
// The plugin_child_id is the ChildProcessHost ID assigned in the browser
// process. This ID is valid only in the context of the browser process and is
// used to identify the proper process when the renderer notifies it that the
// plugin is hung.
//
// |embedder_origin| provides the origin of the frame that embeds the plugin
// (i.e. the origin of the document that contains the <embed> html tag).
// |embedder_origin| needs to be included in the message payload, because the
// message is received and handled on the IO thread in the browser process
// (where it is not possible to consult
// RenderFrameHostImpl::GetLastCommittedOrigin).
//
// On error null handles are returned.
[Sync] OpenChannelToPepperPlugin(url.mojom.Origin embedder_origin,
mojo_base.mojom.FilePath path,
url.mojom.Origin? origin_lock) =>
(handle<message_pipe>? handle_to_channel,
mojo_base.mojom.ProcessId plugin_pid,
int32 plugin_child_id);
};
// This interface is used on the renderer IO thread and is received on the
......
......@@ -75,6 +75,9 @@ class PepperBrowserConnection
int32_t pp_instance,
bool is_external);
// Return a bound PepperIOHost. This may return null in unittests.
mojom::PepperIOHost* GetIOHost();
private:
// RenderFrameObserver implementation.
void OnDestruct() override;
......@@ -84,9 +87,6 @@ class PepperBrowserConnection
int32_t sequence_number,
const std::vector<int>& pending_resource_host_ids);
// Return a bound PepperIOHost. This may return null in unittests.
mojom::PepperIOHost* GetIOHost();
// Return the next sequence number.
int32_t GetNextSequence();
......
......@@ -24,6 +24,7 @@
#include "content/public/renderer/content_renderer_client.h"
#include "content/renderer/pepper/host_dispatcher_wrapper.h"
#include "content/renderer/pepper/host_globals.h"
#include "content/renderer/pepper/pepper_browser_connection.h"
#include "content/renderer/pepper/pepper_hung_plugin_filter.h"
#include "content/renderer/pepper/pepper_plugin_instance_impl.h"
#include "content/renderer/pepper/pepper_plugin_registry.h"
......@@ -697,13 +698,19 @@ scoped_refptr<PluginModule> PluginModule::Create(
}
// Out of process: have the browser start the plugin process for us.
IPC::ChannelHandle channel_handle;
mojo::ScopedMessagePipeHandle channel_handle;
base::ProcessId peer_pid = 0;
int plugin_child_id = 0;
render_frame->Send(new FrameHostMsg_OpenChannelToPepperPlugin(
mojom::PepperIOHost* io_host =
PepperBrowserConnection::Get(render_frame)->GetIOHost();
if (!io_host) {
// Couldn't be initialized.
return scoped_refptr<PluginModule>();
}
io_host->OpenChannelToPepperPlugin(
render_frame->GetWebFrame()->GetSecurityOrigin(), path, origin_lock,
&channel_handle, &peer_pid, &plugin_child_id));
if (!channel_handle.is_mojo_channel_handle()) {
&channel_handle, &peer_pid, &plugin_child_id);
if (!channel_handle.is_valid()) {
// Couldn't be initialized.
return scoped_refptr<PluginModule>();
}
......@@ -717,7 +724,7 @@ scoped_refptr<PluginModule> PluginModule::Create(
module.get());
if (!module->CreateOutOfProcessModule(render_frame, path, permissions,
channel_handle, peer_pid,
channel_handle.release(), peer_pid,
plugin_child_id, false,
task_runner)) // is_external = false
return scoped_refptr<PluginModule>();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment