diff --git a/content/browser/renderer_host/render_frame_host_delegate.h b/content/browser/renderer_host/render_frame_host_delegate.h index af98ed91893a39..309bc0b22fa042 100644 --- a/content/browser/renderer_host/render_frame_host_delegate.h +++ b/content/browser/renderer_host/render_frame_host_delegate.h @@ -652,6 +652,15 @@ class CONTENT_EXPORT RenderFrameHostDelegate { GetActiveTopLevelDocumentsInBrowsingContextGroup( RenderFrameHostImpl* render_frame_host); +#if BUILDFLAG(ENABLE_PLUGINS) + virtual void OnPepperInstanceCreated(RenderFrameHostImpl* source, + int32_t pp_instance) {} + virtual void OnPepperStartsPlayback(RenderFrameHostImpl* source, + int32_t pp_instance) {} + virtual void OnPepperStopsPlayback(RenderFrameHostImpl* source, + int32_t pp_instance) {} +#endif + protected: virtual ~RenderFrameHostDelegate() = default; }; diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc index cd2992c8fb0124..2389d7b9b38087 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc @@ -870,6 +870,42 @@ void VerifyThatBrowserAndRendererCalculatedOriginsToCommitMatch( } // namespace +#if BUILDFLAG(ENABLE_PLUGINS) +class PepperPluginInstance : public mojom::PepperPluginInstanceHost { + public: + PepperPluginInstance( + int32_t instance_id, + RenderFrameHostImpl* frame_host, + mojo::PendingAssociatedRemote instance, + mojo::PendingAssociatedReceiver host) + : instance_id_(instance_id), + frame_host_(frame_host), + receiver_(this, std::move(host)), + remote_(std::move(instance)) { + frame_host_->delegate()->OnPepperInstanceCreated(frame_host_, instance_id); + remote_.set_disconnect_handler( + base::BindOnce(&RenderFrameHostImpl::PepperInstanceClosed, + base::Unretained(frame_host), instance_id_)); + } + ~PepperPluginInstance() override = default; + + // mojom::PepperPluginInstanceHost overrides. + void StartsPlayback() override { + frame_host_->delegate()->OnPepperStartsPlayback(frame_host_, instance_id_); + } + + void StopsPlayback() override { + frame_host_->delegate()->OnPepperStopsPlayback(frame_host_, instance_id_); + } + + private: + int32_t const instance_id_; + RenderFrameHostImpl* const frame_host_; + mojo::AssociatedReceiver receiver_; + mojo::AssociatedRemote remote_; +}; +#endif // BUILDFLAG(ENABLE_PLUGINS) + class RenderFrameHostImpl::DroppedInterfaceRequestLogger : public blink::mojom::BrowserInterfaceBroker { public: @@ -6871,6 +6907,18 @@ void RenderFrameHostImpl::SetUpMojoIfNeeded() { GetProcess()->GetStoragePartition()->GetFileSystemContext(), ChromeBlobStorageContext::GetFor(GetProcess()->GetBrowserContext()))); +#if BUILDFLAG(ENABLE_PLUGINS) + associated_registry_->AddInterface(base::BindRepeating( + [](RenderFrameHostImpl* impl, + mojo::PendingAssociatedReceiver receiver) { + impl->pepper_host_receiver_.Bind(std::move(receiver)); + impl->pepper_host_receiver_.SetFilter( + impl->CreateMessageFilterForAssociatedReceiver( + mojom::PepperHost::Name_)); + }, + base::Unretained(this))); +#endif + mojo::PendingRemote frame_factory; GetProcess()->BindReceiver(frame_factory.InitWithNewPipeAndPassReceiver()); mojo::Remote(std::move(frame_factory)) @@ -10083,6 +10131,22 @@ void RenderFrameHostImpl::Clone( cookie_observers_.Add(this, std::move(observer)); } +#if BUILDFLAG(ENABLE_PLUGINS) +void RenderFrameHostImpl::InstanceCreated( + int32_t instance_id, + mojo::PendingAssociatedRemote instance, + mojo::PendingAssociatedReceiver host) { + pepper_instance_map_.emplace( + instance_id, + std::make_unique( + instance_id, this, std::move(instance), std::move(host))); +} + +void RenderFrameHostImpl::PepperInstanceClosed(int32_t instance_id) { + pepper_instance_map_.erase(instance_id); +} +#endif // BUILDFLAG(ENABLE_PLUGINS) + void RenderFrameHostImpl::OnCookiesAccessed( network::mojom::CookieAccessDetailsPtr details) { EmitSameSiteCookiesDeprecationWarning(this, details); diff --git a/content/browser/renderer_host/render_frame_host_impl.h b/content/browser/renderer_host/render_frame_host_impl.h index cf35884860f6fe..9b53a1b2edfd25 100644 --- a/content/browser/renderer_host/render_frame_host_impl.h +++ b/content/browser/renderer_host/render_frame_host_impl.h @@ -166,6 +166,10 @@ #include "media/mojo/mojom/remoting.mojom-forward.h" #endif +#if BUILDFLAG(ENABLE_PLUGINS) +#include "content/common/pepper_plugin.mojom.h" +#endif + class GURL; namespace blink { @@ -211,6 +215,7 @@ class KeepAliveHandleFactory; class MediaInterfaceProxy; class NavigationEntryImpl; class NavigationRequest; +class PepperPluginInstance; class PermissionServiceContext; class Portal; class PrefetchedSignedExchangeCache; @@ -259,6 +264,9 @@ class CONTENT_EXPORT RenderFrameHostImpl public network::CSPContext, public blink::mojom::LocalMainFrameHost, public ui::AXActionHandlerBase, +#if BUILDFLAG(ENABLE_PLUGINS) + public mojom::PepperHost, +#endif // BUILDFLAG(ENABLE_PLUGINS) public network::mojom::CookieAccessObserver { public: using AXTreeSnapshotCallback = @@ -1863,6 +1871,10 @@ class CONTENT_EXPORT RenderFrameHostImpl return accessibility_fatal_error_count_; } +#if BUILDFLAG(ENABLE_PLUGINS) + void PepperInstanceClosed(int32_t instance_id); +#endif + protected: friend class RenderFrameHostFactory; @@ -2140,6 +2152,15 @@ class CONTENT_EXPORT RenderFrameHostImpl void Clone(mojo::PendingReceiver observer) override; +#if BUILDFLAG(ENABLE_PLUGINS) + // mojom::PepperHost overrides: + void InstanceCreated( + int32_t instance_id, + mojo::PendingAssociatedRemote instance, + mojo::PendingAssociatedReceiver host) + override; +#endif // BUILDFLAG(ENABLE_PLUGINS) + // Resets any waiting state of this RenderFrameHost that is no longer // relevant. void ResetWaitingState(); @@ -3030,6 +3051,11 @@ class CONTENT_EXPORT RenderFrameHostImpl mojo::AssociatedReceiver dom_automation_controller_receiver_{this}; +#if BUILDFLAG(ENABLE_PLUGINS) + mojo::AssociatedReceiver pepper_host_receiver_{this}; + std::map> pepper_instance_map_; +#endif + std::unique_ptr keep_alive_handle_factory_; base::TimeDelta keep_alive_timeout_; diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 2d80c532a35f39..474d43a691cd38 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc @@ -1148,15 +1148,9 @@ bool WebContentsImpl::OnMessageReceived(RenderFrameHostImpl* render_frame_host, bool handled = true; #if BUILDFLAG(ENABLE_PLUGINS) IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(WebContentsImpl, message, render_frame_host) - IPC_MESSAGE_HANDLER(FrameHostMsg_PepperInstanceCreated, - OnPepperInstanceCreated) IPC_MESSAGE_HANDLER(FrameHostMsg_PepperInstanceDeleted, OnPepperInstanceDeleted) IPC_MESSAGE_HANDLER(FrameHostMsg_PepperPluginHung, OnPepperPluginHung) - IPC_MESSAGE_HANDLER(FrameHostMsg_PepperStartsPlayback, - OnPepperStartsPlayback) - IPC_MESSAGE_HANDLER(FrameHostMsg_PepperStopsPlayback, - OnPepperStopsPlayback) IPC_MESSAGE_HANDLER(FrameHostMsg_PluginCrashed, OnPluginCrashed) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index eddb8f296c6b97..49f45fb8cb76ee 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h @@ -771,6 +771,14 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents, std::vector GetActiveTopLevelDocumentsInBrowsingContextGroup( RenderFrameHostImpl* render_frame_host) override; +#if BUILDFLAG(ENABLE_PLUGINS) + void OnPepperInstanceCreated(RenderFrameHostImpl* source, + int32_t pp_instance) override; + void OnPepperStartsPlayback(RenderFrameHostImpl* source, + int32_t pp_instance) override; + void OnPepperStopsPlayback(RenderFrameHostImpl* source, + int32_t pp_instance) override; +#endif // RenderViewHostDelegate ---------------------------------------------------- RenderViewHostDelegateView* GetDelegateView() override; @@ -1500,16 +1508,12 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents, int minimum_percent, int maximum_percent); #if BUILDFLAG(ENABLE_PLUGINS) - void OnPepperInstanceCreated(RenderFrameHostImpl* source, - int32_t pp_instance); void OnPepperInstanceDeleted(RenderFrameHostImpl* source, int32_t pp_instance); void OnPepperPluginHung(RenderFrameHostImpl* source, int plugin_child_id, const base::FilePath& path, bool is_hung); - void OnPepperStartsPlayback(RenderFrameHostImpl* source, int32_t pp_instance); - void OnPepperStopsPlayback(RenderFrameHostImpl* source, int32_t pp_instance); void OnPluginCrashed(RenderFrameHostImpl* source, const base::FilePath& plugin_path, base::ProcessId plugin_pid); diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn index c370af73382704..99f0104b341ebd 100644 --- a/content/common/BUILD.gn +++ b/content/common/BUILD.gn @@ -474,6 +474,10 @@ mojom("mojo_bindings") { enabled_features += [ "clang_profiling_inside_sandbox" ] } + if (enable_plugins) { + sources += [ "pepper_plugin.mojom" ] + } + cpp_typemaps = [ { types = [ diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h index b7562c8f659d3a..ac1e3b49533e55 100644 --- a/content/common/frame_messages.h +++ b/content/common/frame_messages.h @@ -258,11 +258,6 @@ IPC_MESSAGE_ROUTED2(FrameMsg_SetPepperVolume, // Messages sent from the renderer to the browser. #if BUILDFLAG(ENABLE_PLUGINS) -// Notification sent from a renderer to the browser that a Pepper plugin -// instance is created in the DOM. -IPC_MESSAGE_ROUTED1(FrameHostMsg_PepperInstanceCreated, - int32_t /* pp_instance */) - // Notification sent from a renderer to the browser that a Pepper plugin // instance is deleted from the DOM. IPC_MESSAGE_ROUTED1(FrameHostMsg_PepperInstanceDeleted, @@ -286,16 +281,6 @@ IPC_MESSAGE_ROUTED2(FrameHostMsg_PluginCrashed, base::FilePath /* plugin_path */, base::ProcessId /* plugin_pid */) -// Notification sent from a renderer to the browser that a Pepper plugin -// instance has started playback. -IPC_MESSAGE_ROUTED1(FrameHostMsg_PepperStartsPlayback, - int32_t /* pp_instance */) - -// Notification sent from a renderer to the browser that a Pepper plugin -// instance has stopped playback. -IPC_MESSAGE_ROUTED1(FrameHostMsg_PepperStopsPlayback, - int32_t /* pp_instance */) - // Return information about a plugin for the given URL and MIME // type. If there is no matching plugin, |found| is false. // |actual_mime_type| is the actual mime type supported by the diff --git a/content/common/pepper_plugin.mojom b/content/common/pepper_plugin.mojom new file mode 100644 index 00000000000000..eab70efeea5b6e --- /dev/null +++ b/content/common/pepper_plugin.mojom @@ -0,0 +1,26 @@ +// Copyright 2020 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. + +module content.mojom; + +// Generic Pepper messages. Implemented by the browser. +interface PepperHost { + // Notification that a Pepper plugin instance is created in the DOM. + InstanceCreated(int32 instance_id, + pending_associated_remote instance, + pending_associated_receiver host); +}; + +// Plugin instance specific messages. Implemented by the browser. +interface PepperPluginInstanceHost { + // Notification a plugin instance has started playback. + StartsPlayback(); + + // Notification a plugin instance has stopped playback. + StopsPlayback(); +}; + +// Plugin instance specific messages. Implemented by the renderer. +interface PepperPluginInstance { +}; diff --git a/content/renderer/pepper/pepper_audio_controller.cc b/content/renderer/pepper/pepper_audio_controller.cc index 759666ea3a7fb0..5daa189ff42ba7 100644 --- a/content/renderer/pepper/pepper_audio_controller.cc +++ b/content/renderer/pepper/pepper_audio_controller.cc @@ -92,18 +92,20 @@ void PepperAudioController::OnPepperInstanceDeleted() { void PepperAudioController::NotifyPlaybackStopsOnEmpty() { DCHECK(instance_); - RenderFrameImpl* render_frame = instance_->render_frame(); - if (render_frame) - render_frame->PepperStopsPlayback(instance_); + mojom::PepperPluginInstanceHost* instance_host = + instance_->GetPepperPluginInstanceHost(); + if (instance_host) + instance_host->StopsPlayback(); } void PepperAudioController::StartPlaybackIfFirstInstance() { DCHECK(instance_); if (audio_output_hosts_.empty() && ppb_audios_.empty()) { - RenderFrameImpl* render_frame = instance_->render_frame(); - if (render_frame) - render_frame->PepperStartsPlayback(instance_); + mojom::PepperPluginInstanceHost* instance_host = + instance_->GetPepperPluginInstanceHost(); + if (instance_host) + instance_host->StartsPlayback(); } } diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.cc b/content/renderer/pepper/pepper_plugin_instance_impl.cc index a8800b2374613a..a3af6bf37cdf73 100644 --- a/content/renderer/pepper/pepper_plugin_instance_impl.cc +++ b/content/renderer/pepper/pepper_plugin_instance_impl.cc @@ -542,7 +542,9 @@ PepperPluginInstanceImpl::PepperPluginInstanceImpl( module_->InstanceCreated(this); if (render_frame_) { // NULL in tests or if the frame has been destroyed. - render_frame_->PepperInstanceCreated(this); + render_frame_->PepperInstanceCreated( + this, pepper_receiver_.BindNewEndpointAndPassRemote(), + pepper_host_remote_.BindNewEndpointAndPassReceiver()); view_data_.is_page_visible = !render_frame_->GetLocalRootWebFrameWidget()->IsHidden(); diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.h b/content/renderer/pepper/pepper_plugin_instance_impl.h index 5db128c5c3b458..4cb7ef063725b4 100644 --- a/content/renderer/pepper/pepper_plugin_instance_impl.h +++ b/content/renderer/pepper/pepper_plugin_instance_impl.h @@ -29,10 +29,13 @@ #include "cc/paint/paint_canvas.h" #include "components/viz/common/resources/transferable_resource.h" #include "content/common/content_export.h" +#include "content/common/pepper_plugin.mojom.h" #include "content/public/renderer/pepper_plugin_instance.h" #include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_frame_observer.h" #include "gin/handle.h" +#include "mojo/public/cpp/bindings/associated_receiver.h" +#include "mojo/public/cpp/bindings/associated_remote.h" #include "ppapi/c/dev/pp_cursor_type_dev.h" #include "ppapi/c/dev/ppp_printing_dev.h" #include "ppapi/c/dev/ppp_text_input_dev.h" @@ -119,7 +122,8 @@ class CONTENT_EXPORT PepperPluginInstanceImpl public PepperPluginInstance, public ppapi::PPB_Instance_Shared, public cc::TextureLayerClient, - public RenderFrameObserver { + public RenderFrameObserver, + public mojom::PepperPluginInstance { public: // Create and return a PepperPluginInstanceImpl object which supports the most // recent version of PPP_Instance possible by querying the given @@ -135,9 +139,17 @@ class CONTENT_EXPORT PepperPluginInstanceImpl // Currently only used in tests. static PepperPluginInstanceImpl* GetForTesting(PP_Instance instance_id); + // Returns the associated RenderFrameImpl. Can be null (in tests) or if the + // frame has been destroyed. RenderFrameImpl* render_frame() const { return render_frame_; } PluginModule* module() const { return module_.get(); } + // Returns the associated mojo host channel to the browser. Can be null if + // `render_frame()` returns null. + mojom::PepperPluginInstanceHost* GetPepperPluginInstanceHost() { + return pepper_host_remote_.get(); + } + blink::WebPluginContainer* container() const { return container_; } // Returns the PP_Instance uniquely identifying this instance. Guaranteed @@ -844,6 +856,9 @@ class CONTENT_EXPORT PepperPluginInstanceImpl // progress. base::string16 composition_text_; + mojo::AssociatedRemote pepper_host_remote_; + mojo::AssociatedReceiver pepper_receiver_{this}; + // We use a weak ptr factory for scheduling DidChangeView events so that we // can tell whether updates are pending and consolidate them. When there's // already a weak ptr pending (HasWeakPtrs is true), code should update the diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index d2d9c8d4875d21..b45eeec6b3d8c5 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc @@ -6251,12 +6251,21 @@ bool RenderFrameImpl::IsAccessibilityEnabled() const { } #if BUILDFLAG(ENABLE_PLUGINS) + +mojom::PepperHost* RenderFrameImpl::GetPepperHost() { + if (!pepper_host_remote_.is_bound()) + GetRemoteAssociatedInterfaces()->GetInterface(&pepper_host_remote_); + return pepper_host_remote_.get(); +} + void RenderFrameImpl::PepperInstanceCreated( - PepperPluginInstanceImpl* instance) { + PepperPluginInstanceImpl* instance, + mojo::PendingAssociatedRemote mojo_instance, + mojo::PendingAssociatedReceiver + mojo_host) { active_pepper_instances_.insert(instance); - - Send(new FrameHostMsg_PepperInstanceCreated(routing_id_, - instance->pp_instance())); + GetPepperHost()->InstanceCreated( + instance->pp_instance(), std::move(mojo_instance), std::move(mojo_host)); } void RenderFrameImpl::PepperInstanceDeleted( @@ -6286,22 +6295,6 @@ void RenderFrameImpl::PepperFocusChanged(PepperPluginInstanceImpl* instance, GetLocalRootWebFrameWidget()->UpdateSelectionBounds(); } -void RenderFrameImpl::PepperStartsPlayback(PepperPluginInstanceImpl* instance) { - RenderFrameImpl* const render_frame = instance->render_frame(); - if (render_frame) { - render_frame->Send(new FrameHostMsg_PepperStartsPlayback( - render_frame->GetRoutingID(), instance->pp_instance())); - } -} - -void RenderFrameImpl::PepperStopsPlayback(PepperPluginInstanceImpl* instance) { - RenderFrameImpl* const render_frame = instance->render_frame(); - if (render_frame) { - render_frame->Send(new FrameHostMsg_PepperStopsPlayback( - render_frame->GetRoutingID(), instance->pp_instance())); - } -} - void RenderFrameImpl::OnSetPepperVolume(int32_t pp_instance, double volume) { PepperPluginInstanceImpl* instance = static_cast( PepperPluginInstance::Get(pp_instance)); diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index a7312079163447..22c530f8ad77ea 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h @@ -109,6 +109,10 @@ #include "url/gurl.h" #include "url/origin.h" +#if BUILDFLAG(ENABLE_PLUGINS) +#include "content/common/pepper_plugin.mojom.h" +#endif + namespace blink { namespace scheduler { class WebAgentGroupScheduler; @@ -313,6 +317,8 @@ class CONTENT_EXPORT RenderFrameImpl bool in_frame_tree() { return in_frame_tree_; } #if BUILDFLAG(ENABLE_PLUGINS) + mojom::PepperHost* GetPepperHost(); + // Notification that a PPAPI plugin has been created. void PepperPluginCreated(RendererPpapiHost* host); @@ -745,7 +751,11 @@ class CONTENT_EXPORT RenderFrameImpl return focused_pepper_plugin_; } // Indicates that the given instance has been created. - void PepperInstanceCreated(PepperPluginInstanceImpl* instance); + void PepperInstanceCreated( + PepperPluginInstanceImpl* instance, + mojo::PendingAssociatedRemote mojo_instance, + mojo::PendingAssociatedReceiver + mojo_host); // Indicates that the given instance is being destroyed. This is called from // the destructor, so it's important that the instance is not dereferenced @@ -755,8 +765,6 @@ class CONTENT_EXPORT RenderFrameImpl // Notification that the given plugin is focused or unfocused. void PepperFocusChanged(PepperPluginInstanceImpl* instance, bool focused); - void PepperStartsPlayback(PepperPluginInstanceImpl* instance); - void PepperStopsPlayback(PepperPluginInstanceImpl* instance); void OnSetPepperVolume(int32_t pp_instance, double volume); #endif // ENABLE_PLUGINS @@ -1285,6 +1293,8 @@ class CONTENT_EXPORT RenderFrameImpl // Whether or not the focus is on a PPAPI plugin PepperPluginInstanceImpl* focused_pepper_plugin_; + + mojo::AssociatedRemote pepper_host_remote_; #endif using AutoplayOriginAndFlags = std::pair;