diff options
60 files changed, 1155 insertions, 459 deletions
diff --git a/chrome/renderer/pepper/pepper_flash_renderer_message_filter.cc b/chrome/renderer/pepper/pepper_flash_renderer_message_filter.cc index c556ae0..5917a43 100644 --- a/chrome/renderer/pepper/pepper_flash_renderer_message_filter.cc +++ b/chrome/renderer/pepper/pepper_flash_renderer_message_filter.cc @@ -5,13 +5,15 @@ #include "chrome/renderer/pepper/pepper_flash_renderer_message_filter.h" #include "chrome/renderer/pepper/ppb_pdf_impl.h" +#include "content/public/renderer/renderer_ppapi_host.h" #include "ppapi/proxy/ppapi_messages.h" namespace chrome { PepperFlashRendererMessageFilter::PepperFlashRendererMessageFilter( - ppapi::host::PpapiHost* host) - : InstanceMessageFilter(host) { + content::RendererPpapiHost* host) + : InstanceMessageFilter(host->GetPpapiHost()), + host_(host) { } PepperFlashRendererMessageFilter::~PepperFlashRendererMessageFilter() { diff --git a/chrome/renderer/pepper/pepper_flash_renderer_message_filter.h b/chrome/renderer/pepper/pepper_flash_renderer_message_filter.h index 3a39ae6..6bda03d 100644 --- a/chrome/renderer/pepper/pepper_flash_renderer_message_filter.h +++ b/chrome/renderer/pepper/pepper_flash_renderer_message_filter.h @@ -10,6 +10,10 @@ #include "ppapi/c/pp_instance.h" #include "ppapi/host/instance_message_filter.h" +namespace content { +class RendererPpapiHost; +} + namespace chrome { // Implements the backend for Flash-specific messages from a plugin process. @@ -18,7 +22,7 @@ class PepperFlashRendererMessageFilter public: // This class is designed to be heap-allocated. It will attach itself to the // given host and delete itself when the host is destroyed. - explicit PepperFlashRendererMessageFilter(ppapi::host::PpapiHost* host); + explicit PepperFlashRendererMessageFilter(content::RendererPpapiHost* host); virtual ~PepperFlashRendererMessageFilter(); // InstanceMessageFilter: @@ -28,6 +32,8 @@ class PepperFlashRendererMessageFilter // Message handlers. void OnHostMsgInvokePrinting(PP_Instance instance); + content::RendererPpapiHost* host_; + DISALLOW_COPY_AND_ASSIGN(PepperFlashRendererMessageFilter); }; diff --git a/chrome/renderer/pepper/pepper_helper.cc b/chrome/renderer/pepper/pepper_helper.cc index 4cd5c4d..37b904c 100644 --- a/chrome/renderer/pepper/pepper_helper.cc +++ b/chrome/renderer/pepper/pepper_helper.cc @@ -6,6 +6,7 @@ #include "chrome/renderer/pepper/chrome_renderer_pepper_host_factory.h" #include "chrome/renderer/pepper/pepper_flash_renderer_message_filter.h" +#include "content/public/renderer/renderer_ppapi_host.h" #include "ppapi/host/ppapi_host.h" namespace chrome { @@ -17,11 +18,11 @@ PepperHelper::PepperHelper(content::RenderView* render_view) PepperHelper::~PepperHelper() { } -void PepperHelper::DidCreatePepperPlugin(ppapi::host::PpapiHost* host) { +void PepperHelper::DidCreatePepperPlugin(content::RendererPpapiHost* host) { // TODO(brettw) figure out how to hook up the host factory. It needs some // kind of filter-like system to allow dynamic additions. // new ChromeRendererPepperHostFactory(host); - host->AddInstanceMessageFilter( + host->GetPpapiHost()->AddInstanceMessageFilter( scoped_ptr<ppapi::host::InstanceMessageFilter>( new PepperFlashRendererMessageFilter(host))); } diff --git a/chrome/renderer/pepper/pepper_helper.h b/chrome/renderer/pepper/pepper_helper.h index 969a80e..5f810b8 100644 --- a/chrome/renderer/pepper/pepper_helper.h +++ b/chrome/renderer/pepper/pepper_helper.h @@ -18,7 +18,7 @@ class PepperHelper : public content::RenderViewObserver { virtual ~PepperHelper(); // RenderViewObserver. - virtual void DidCreatePepperPlugin(ppapi::host::PpapiHost* host) OVERRIDE; + virtual void DidCreatePepperPlugin(content::RendererPpapiHost* host) OVERRIDE; private: DISALLOW_COPY_AND_ASSIGN(PepperHelper); diff --git a/content/browser/ppapi_plugin_process_host.cc b/content/browser/ppapi_plugin_process_host.cc index 518b428..6ca4235 100644 --- a/content/browser/ppapi_plugin_process_host.cc +++ b/content/browser/ppapi_plugin_process_host.cc @@ -123,9 +123,11 @@ PpapiPluginProcessHost::PpapiPluginProcessHost( process_.reset(new BrowserChildProcessHostImpl( content::PROCESS_TYPE_PPAPI_PLUGIN, this)); - filter_ = new PepperMessageFilter( - PepperMessageFilter::PLUGIN, host_resolver, - ppapi::PpapiPermissions(info.permissions)); + filter_ = new PepperMessageFilter(PepperMessageFilter::PLUGIN, + host_resolver); + + ppapi::PpapiPermissions permissions(info.permissions); + host_impl_.reset(new content::BrowserPpapiHostImpl(this, permissions)); file_filter_ = new PepperTrustedFileMessageFilter( process_->GetData().id, info.name, profile_data_directory); diff --git a/content/browser/ppapi_plugin_process_host.h b/content/browser/ppapi_plugin_process_host.h index 07712be..871666d 100644 --- a/content/browser/ppapi_plugin_process_host.h +++ b/content/browser/ppapi_plugin_process_host.h @@ -12,6 +12,7 @@ #include "base/file_path.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" +#include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h" #include "content/browser/renderer_host/pepper/pepper_file_message_filter.h" #include "content/browser/renderer_host/pepper/pepper_message_filter.h" #include "content/public/browser/browser_child_process_host_delegate.h" @@ -123,6 +124,8 @@ class PpapiPluginProcessHost : public content::BrowserChildProcessHostDelegate, // Handles most requests from the plugin. May be NULL. scoped_refptr<PepperMessageFilter> filter_; + scoped_ptr<content::BrowserPpapiHostImpl> host_impl_; + // Handles filesystem requests from flash plugins. May be NULL. scoped_refptr<PepperFileMessageFilter> file_filter_; diff --git a/content/browser/renderer_host/pepper/browser_ppapi_host_impl.cc b/content/browser/renderer_host/pepper/browser_ppapi_host_impl.cc new file mode 100644 index 0000000..8caaaf6 --- /dev/null +++ b/content/browser/renderer_host/pepper/browser_ppapi_host_impl.cc @@ -0,0 +1,37 @@ +// Copyright (c) 2012 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 "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h" + +#include "ipc/ipc_message_macros.h" + +namespace content { + +BrowserPpapiHostImpl::BrowserPpapiHostImpl( + IPC::Sender* sender, + const ppapi::PpapiPermissions& permissions) + : host_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), + ppapi_host_(sender, &host_factory_, permissions) { +} + +BrowserPpapiHostImpl::~BrowserPpapiHostImpl() { +} + +bool BrowserPpapiHostImpl::OnMessageReceived(const IPC::Message& msg) { + /* TODO(brettw) when we add messages, here, the code should look like this: + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(BrowserPpapiHostImpl, msg) + // Add necessary message handlers here. + IPC_MESSAGE_UNHANDLED(handled = ppapi_host_.OnMessageReceived(msg)) + IPC_END_MESSAGE_MAP(); + return handled; + */ + return ppapi_host_.OnMessageReceived(msg); +} + +ppapi::host::PpapiHost* BrowserPpapiHostImpl::GetPpapiHost() { + return &ppapi_host_; +} + +} // namespace content diff --git a/content/browser/renderer_host/pepper/browser_ppapi_host_impl.h b/content/browser/renderer_host/pepper/browser_ppapi_host_impl.h new file mode 100644 index 0000000..2bedbda --- /dev/null +++ b/content/browser/renderer_host/pepper/browser_ppapi_host_impl.h @@ -0,0 +1,42 @@ +// Copyright (c) 2012 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. + +#ifndef CONTENT_BROWSER_RENDERER_HOST_PEPPER_BROWSER_PPAPI_HOST_IMPL_H_ +#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_BROWSER_PPAPI_HOST_IMPL_H_ + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h" +#include "content/public/browser/browser_ppapi_host.h" +#include "ipc/ipc_listener.h" +#include "ppapi/host/ppapi_host.h" + +namespace IPC { +class Sender; +} + +namespace content { + +class BrowserPpapiHostImpl : public BrowserPpapiHost, public IPC::Listener { + public: + BrowserPpapiHostImpl(IPC::Sender* sender, + const ppapi::PpapiPermissions& permissions); + virtual ~BrowserPpapiHostImpl(); + + // IPC::Listener. + virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE; + + // BrowserPpapiHost. + virtual ppapi::host::PpapiHost* GetPpapiHost() OVERRIDE; + + private: + ContentBrowserPepperHostFactory host_factory_; + ppapi::host::PpapiHost ppapi_host_; + + DISALLOW_COPY_AND_ASSIGN(BrowserPpapiHostImpl); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_RENDERER_HOST_PEPPER_BROWSER_PPAPI_HOST_IMPL_H_ diff --git a/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.cc b/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.cc index c55427f..fbe5e6d 100644 --- a/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.cc +++ b/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.cc @@ -12,8 +12,8 @@ using ppapi::host::ResourceHost; namespace content { ContentBrowserPepperHostFactory::ContentBrowserPepperHostFactory( - PepperMessageFilter* filter) - : filter_(filter) { + BrowserPpapiHostImpl* host) + : host_(host) { } ContentBrowserPepperHostFactory::~ContentBrowserPepperHostFactory() { diff --git a/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h b/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h index e800bb3..2bc771f 100644 --- a/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h +++ b/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h @@ -8,14 +8,14 @@ #include "base/compiler_specific.h" #include "ppapi/host/host_factory.h" -class PepperMessageFilter; - namespace content { +class BrowserPpapiHostImpl; + class ContentBrowserPepperHostFactory : public ppapi::host::HostFactory { public: // Non-owning pointer to the filter must outlive this class. - explicit ContentBrowserPepperHostFactory(PepperMessageFilter* filter); + explicit ContentBrowserPepperHostFactory(BrowserPpapiHostImpl* host); virtual ~ContentBrowserPepperHostFactory(); virtual scoped_ptr<ppapi::host::ResourceHost> CreateResourceHost( @@ -26,7 +26,7 @@ class ContentBrowserPepperHostFactory : public ppapi::host::HostFactory { private: // Non-owning pointer. - PepperMessageFilter* filter_; + BrowserPpapiHostImpl* host_; DISALLOW_COPY_AND_ASSIGN(ContentBrowserPepperHostFactory); }; diff --git a/content/browser/renderer_host/pepper/pepper_message_filter.cc b/content/browser/renderer_host/pepper/pepper_message_filter.cc index bced66b..d9dbcdf 100644 --- a/content/browser/renderer_host/pepper/pepper_message_filter.cc +++ b/content/browser/renderer_host/pepper/pepper_message_filter.cc @@ -76,10 +76,6 @@ PepperMessageFilter::PepperMessageFilter( : process_type_(type), process_id_(process_id), resource_context_(browser_context->GetResourceContext()), - permissions_(), // Renderer has no PPAPI permissions, - host_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), - ppapi_host_(ALLOW_THIS_IN_INITIALIZER_LIST(this), &host_factory_, - permissions_), host_resolver_(NULL), next_socket_id_(1) { DCHECK(type == RENDERER); @@ -91,15 +87,10 @@ PepperMessageFilter::PepperMessageFilter( } PepperMessageFilter::PepperMessageFilter(ProcessType type, - net::HostResolver* host_resolver, - const ppapi::PpapiPermissions& perms) + net::HostResolver* host_resolver) : process_type_(type), process_id_(0), resource_context_(NULL), - permissions_(perms), - host_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), - ppapi_host_(ALLOW_THIS_IN_INITIALIZER_LIST(this), &host_factory_, - permissions_), host_resolver_(host_resolver), next_socket_id_(1), incognito_(false) { @@ -124,14 +115,6 @@ void PepperMessageFilter::OverrideThreadForMessage( bool PepperMessageFilter::OnMessageReceived(const IPC::Message& msg, bool* message_was_ok) { -if (process_type_ == PLUGIN) { - // Handle new-style host messages directly from the plugin. Don't allow - // renderers to send these messages since they have fewer capabilities for - // some classes of things than plugins. - if (ppapi_host_.OnMessageReceived(msg)) - return true; - } - bool handled = true; IPC_BEGIN_MESSAGE_MAP_EX(PepperMessageFilter, msg, *message_was_ok) IPC_MESSAGE_HANDLER(PepperMsg_GetLocalTimeZoneOffset, diff --git a/content/browser/renderer_host/pepper/pepper_message_filter.h b/content/browser/renderer_host/pepper/pepper_message_filter.h index fbc91d8..ead15e1 100644 --- a/content/browser/renderer_host/pepper/pepper_message_filter.h +++ b/content/browser/renderer_host/pepper/pepper_message_filter.h @@ -15,7 +15,6 @@ #include "base/memory/scoped_ptr.h" #include "base/process.h" #include "base/time.h" -#include "content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h" #include "content/public/browser/browser_message_filter.h" #include "net/base/network_change_notifier.h" #include "net/base/net_util.h" @@ -73,8 +72,7 @@ class PepperMessageFilter // Constructor when used in the context of a PPAPI process (the argument is // provided for sanity checking). PepperMessageFilter(ProcessType type, - net::HostResolver* host_resolver, - const ppapi::PpapiPermissions& perms); + net::HostResolver* host_resolver); // content::BrowserMessageFilter methods. virtual void OverrideThreadForMessage( @@ -245,11 +243,6 @@ class PepperMessageFilter // When non-NULL, this should be used instead of the host_resolver_. content::ResourceContext* const resource_context_; - ppapi::PpapiPermissions permissions_; - - content::ContentBrowserPepperHostFactory host_factory_; - ppapi::host::PpapiHost ppapi_host_; - // When non-NULL, this should be used instead of the resource_context_. Use // GetHostResolver instead of accessing directly. net::HostResolver* host_resolver_; diff --git a/content/content_browser.gypi b/content/content_browser.gypi index 0dc0025..59027a0 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -47,6 +47,7 @@ 'public/browser/browser_main_runner.h', 'public/browser/browser_message_filter.cc', 'public/browser/browser_message_filter.h', + 'public/browser/browser_ppapi_host.h', 'public/browser/browser_shutdown.h', 'public/browser/browser_url_handler.h', 'public/browser/browser_thread.h', @@ -600,6 +601,8 @@ 'browser/renderer_host/native_web_keyboard_event_gtk.cc', 'browser/renderer_host/native_web_keyboard_event_mac.mm', 'browser/renderer_host/native_web_keyboard_event_win.cc', + 'browser/renderer_host/pepper/browser_ppapi_host_impl.cc', + 'browser/renderer_host/pepper/browser_ppapi_host_impl.h', 'browser/renderer_host/pepper/content_browser_pepper_host_factory.cc', 'browser/renderer_host/pepper/content_browser_pepper_host_factory.h', 'browser/renderer_host/pepper/pepper_file_message_filter.cc', diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi index 69cb8a2..0c0e94d 100644 --- a/content/content_renderer.gypi +++ b/content/content_renderer.gypi @@ -42,6 +42,7 @@ 'public/renderer/render_view_observer.h', 'public/renderer/render_view_observer_tracker.h', 'public/renderer/render_view_visitor.h', + 'public/renderer/renderer_ppapi_host.h', 'public/renderer/v8_value_converter.h', 'renderer/accessibility_node_serializer.cc', 'renderer/accessibility_node_serializer.h', @@ -144,9 +145,6 @@ 'renderer/notification_provider.h', 'renderer/paint_aggregator.cc', 'renderer/paint_aggregator.h', - 'renderer/pepper/pepper_instance_state_accessor.h', - 'renderer/pepper/pepper_instance_state_accessor_impl.cc', - 'renderer/pepper/pepper_instance_state_accessor_impl.h', 'renderer/pepper/content_renderer_pepper_host_factory.cc', 'renderer/pepper/content_renderer_pepper_host_factory.h', 'renderer/pepper/pepper_broker_impl.cc', @@ -159,6 +157,8 @@ 'renderer/pepper/pepper_hung_plugin_filter.h', 'renderer/pepper/pepper_in_process_resource_creation.cc', 'renderer/pepper/pepper_in_process_resource_creation.h', + 'renderer/pepper/pepper_in_process_router.cc', + 'renderer/pepper/pepper_in_process_router.h', 'renderer/pepper/pepper_parent_context_provider.cc', 'renderer/pepper/pepper_parent_context_provider.h', 'renderer/pepper/pepper_platform_audio_input_impl.cc', @@ -175,6 +175,8 @@ 'renderer/pepper/pepper_plugin_delegate_impl.h', 'renderer/pepper/pepper_proxy_channel_delegate_impl.cc', 'renderer/pepper/pepper_proxy_channel_delegate_impl.h', + 'renderer/pepper/renderer_ppapi_host_impl.cc', + 'renderer/pepper/renderer_ppapi_host_impl.h', 'renderer/plugin_channel_host.cc', 'renderer/plugin_channel_host.h', 'renderer/browser_plugin/old/browser_plugin_channel_manager.cc', diff --git a/content/content_tests.gypi b/content/content_tests.gypi index 590da0d..cb98dd1 100644 --- a/content/content_tests.gypi +++ b/content/content_tests.gypi @@ -591,6 +591,7 @@ 'renderer/browser_plugin/browser_plugin_browsertest.h', 'renderer/browser_plugin/browser_plugin_browsertest.cc', 'renderer/mouse_lock_dispatcher_browsertest.cc', + 'renderer/pepper/mock_renderer_ppapi_host.cc', 'renderer/pepper/pepper_file_chooser_host_unittest.cc', 'renderer/render_view_browsertest.cc', 'renderer/render_view_browsertest_mac.mm', diff --git a/content/ppapi_plugin/ppapi_thread.cc b/content/ppapi_plugin/ppapi_thread.cc index f1fb7f7..970468d 100644 --- a/content/ppapi_plugin/ppapi_thread.cc +++ b/content/ppapi_plugin/ppapi_thread.cc @@ -168,6 +168,10 @@ bool PpapiThread::SendToBrowser(IPC::Message* msg) { return sync_message_filter()->Send(msg); } +IPC::Sender* PpapiThread::GetBrowserSender() { + return this; +} + std::string PpapiThread::GetUILanguage() { CommandLine* command_line = CommandLine::ForCurrentProcess(); return command_line->GetSwitchValueASCII(switches::kLang); diff --git a/content/ppapi_plugin/ppapi_thread.h b/content/ppapi_plugin/ppapi_thread.h index 82fb547..06ed0e3 100644 --- a/content/ppapi_plugin/ppapi_thread.h +++ b/content/ppapi_plugin/ppapi_thread.h @@ -61,6 +61,7 @@ class PpapiThread : public ChildThread, // SendToBrowser() is intended to be safe to use on another thread so // long as the main PpapiThread outlives it. virtual bool SendToBrowser(IPC::Message* msg) OVERRIDE; + virtual IPC::Sender* GetBrowserSender() OVERRIDE; virtual std::string GetUILanguage() OVERRIDE; virtual void PreCacheFont(const void* logfontw) OVERRIDE; virtual void SetActiveURL(const std::string& url) OVERRIDE; diff --git a/content/public/browser/browser_ppapi_host.h b/content/public/browser/browser_ppapi_host.h new file mode 100644 index 0000000..a25a6d0 --- /dev/null +++ b/content/public/browser/browser_ppapi_host.h @@ -0,0 +1,32 @@ +// Copyright (c) 2012 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. + +#ifndef CONTENT_PUBLIC_BROWSER_BROWSER_PPAPI_HOST_H_ +#define CONTENT_PUBLIC_BROWSER_BROWSER_PPAPI_HOST_H_ + +namespace ppapi { +namespace host { +class PpapiHost; +} +} + +namespace content { + +// Interface that allows components in the embedder app to talk to the +// PpapiHost in the browser process. +// +// There will be one of these objects in the browser per plugin process. It +// lives entirely on the I/O thread. +class BrowserPpapiHost { + public: + // Returns the PpapiHost object. + virtual ppapi::host::PpapiHost* GetPpapiHost() = 0; + + protected: + virtual ~BrowserPpapiHost() {} +}; + +} // namespace content + +#endif // CONTENT_PUBLIC_BROWSER_BROWSER_PPAPI_HOST_H_ diff --git a/content/public/renderer/render_view_observer.h b/content/public/renderer/render_view_observer.h index 34fa064..94f294e 100644 --- a/content/public/renderer/render_view_observer.h +++ b/content/public/renderer/render_view_observer.h @@ -34,6 +34,7 @@ struct WebURLError; namespace content { +class RendererPpapiHost; class RenderView; // Base class for objects that want to filter incoming IPCs, and also get @@ -84,7 +85,7 @@ class CONTENT_EXPORT RenderViewObserver : public IPC::Listener, // These match the RenderView methods. virtual void DidHandleMouseEvent(const WebKit::WebMouseEvent& event) {} virtual void DidHandleTouchEvent(const WebKit::WebTouchEvent& event) {} - virtual void DidCreatePepperPlugin(ppapi::host::PpapiHost* host) {} + virtual void DidCreatePepperPlugin(RendererPpapiHost* host) {} // These match incoming IPCs. virtual void ContextMenuAction(unsigned id) {} diff --git a/content/public/renderer/renderer_ppapi_host.h b/content/public/renderer/renderer_ppapi_host.h new file mode 100644 index 0000000..8fda769 --- /dev/null +++ b/content/public/renderer/renderer_ppapi_host.h @@ -0,0 +1,51 @@ +// Copyright (c) 2012 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. + +#ifndef CONTENT_PUBLIC_RENDERER_RENDERER_PPAPI_HOST_H_ +#define CONTENT_PUBLIC_RENDERER_RENDERER_PPAPI_HOST_H_ + +#include "ppapi/c/pp_instance.h" + +namespace ppapi { +namespace host { +class PpapiHost; +} +} + +namespace content { + +class RenderView; + +// Interface that allows components in the embedder app to talk to the +// PpapiHost in the renderer process. +// +// There will be one of these objects in the renderer per plugin module. +class RendererPpapiHost { + public: + // Returns the PpapiHost object. + virtual ppapi::host::PpapiHost* GetPpapiHost() = 0; + + // Returns true if the given PP_Instance is valid and belongs to the + // plugin associated with this host. + virtual bool IsValidInstance(PP_Instance instance) const = 0; + + // Returns the RenderView for the given plugin instance, or NULL if the + // instance is invalid. + virtual RenderView* GetRenderViewForInstance(PP_Instance instance) const = 0; + + // Returns true if the given instance is considered to be currently + // processing a user gesture or the plugin module has the "override user + // gesture" flag set (in which case it can always do things normally + // restricted by user gestures). Returns false if the instance is invalid or + // if there is no current user gesture. + virtual bool HasUserGesture(PP_Instance instance) const = 0; + + protected: + virtual ~RendererPpapiHost() {} +}; + +} // namespace content + +#endif // CONTENT_PUBLIC_RENDERER_RENDERER_PPAPI_HOST_H_ + diff --git a/content/renderer/gamepad_shared_memory_reader.h b/content/renderer/gamepad_shared_memory_reader.h index b1d2eef..9a85025 100644 --- a/content/renderer/gamepad_shared_memory_reader.h +++ b/content/renderer/gamepad_shared_memory_reader.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef GAMEPAD_UTIL_H_ -#define GAMEPAD_UTIL_H_ +#ifndef CONTENT_RENDERER_GAMEPAD_UTIL_H_ +#define CONTENT_RENDERER_GAMEPAD_UTIL_H_ #include "base/shared_memory.h" #include "base/memory/scoped_ptr.h" @@ -27,6 +27,6 @@ class GamepadSharedMemoryReader { bool ever_interacted_with_[WebKit::WebGamepads::itemsLengthCap]; }; -} // namespace content +} // namespace content -#endif // GAMEPAD_UTIL_H_ +#endif // CONTENT_RENDERER_GAMEPAD_UTIL_H_ diff --git a/content/renderer/pepper/content_renderer_pepper_host_factory.cc b/content/renderer/pepper/content_renderer_pepper_host_factory.cc index ec7e7ca..d5eb200 100644 --- a/content/renderer/pepper/content_renderer_pepper_host_factory.cc +++ b/content/renderer/pepper/content_renderer_pepper_host_factory.cc @@ -4,8 +4,9 @@ #include "content/renderer/pepper/content_renderer_pepper_host_factory.h" -#include "content/renderer/pepper/pepper_instance_state_accessor.h" +#include "base/logging.h" #include "content/renderer/pepper/pepper_file_chooser_host.h" +#include "content/renderer/pepper/renderer_ppapi_host_impl.h" #include "ppapi/host/resource_host.h" #include "ppapi/proxy/ppapi_messages.h" @@ -14,12 +15,8 @@ using ppapi::host::ResourceHost; namespace content { ContentRendererPepperHostFactory::ContentRendererPepperHostFactory( - RenderViewImpl* render_view, - const ppapi::PpapiPermissions& permissions, - PepperInstanceStateAccessor* state) - : render_view_(render_view), - permissions_(permissions), - instance_state_(state) { + RendererPpapiHostImpl* host) + : host_(host) { } ContentRendererPepperHostFactory::~ContentRendererPepperHostFactory() { @@ -30,22 +27,28 @@ scoped_ptr<ResourceHost> ContentRendererPepperHostFactory::CreateResourceHost( const ppapi::proxy::ResourceMessageCallParams& params, PP_Instance instance, const IPC::Message& message) { + DCHECK(host == host_->GetPpapiHost()); + // Make sure the plugin is giving us a valid instance for this resource. - if (!instance_state_->IsValidInstance(instance)) + if (!host_->IsValidInstance(instance)) return scoped_ptr<ResourceHost>(); // Resources for dev interfaces. // TODO(brettw) when we support any public or private interfaces, put them in // a separate switch above. - if (permissions_.HasPermission(ppapi::PERMISSION_DEV)) { + if (GetPermissions().HasPermission(ppapi::PERMISSION_DEV)) { switch (message.type()) { case PpapiHostMsg_FileChooser_Create::ID: return scoped_ptr<ResourceHost>(new PepperFileChooserHost( - host, instance, params.pp_resource(), render_view_, - instance_state_)); + host_, instance, params.pp_resource())); } } return scoped_ptr<ResourceHost>(); } +const ppapi::PpapiPermissions& +ContentRendererPepperHostFactory::GetPermissions() const { + return host_->GetPpapiHost()->permissions(); +} + } // namespace content diff --git a/content/renderer/pepper/content_renderer_pepper_host_factory.h b/content/renderer/pepper/content_renderer_pepper_host_factory.h index ad92f5b..c4ee4cf 100644 --- a/content/renderer/pepper/content_renderer_pepper_host_factory.h +++ b/content/renderer/pepper/content_renderer_pepper_host_factory.h @@ -11,16 +11,20 @@ class RenderViewImpl; +namespace ppapi { +class PpapiPermissions; +} + namespace content { +class RendererPpapiHostImpl; + class PepperInstanceStateAccessor; class ContentRendererPepperHostFactory : public ppapi::host::HostFactory { public: explicit ContentRendererPepperHostFactory( - RenderViewImpl* render_view, - const ppapi::PpapiPermissions& permissions, - PepperInstanceStateAccessor* state); + RendererPpapiHostImpl* host); virtual ~ContentRendererPepperHostFactory(); virtual scoped_ptr<ppapi::host::ResourceHost> CreateResourceHost( @@ -30,9 +34,10 @@ class ContentRendererPepperHostFactory : public ppapi::host::HostFactory { const IPC::Message& message) OVERRIDE; private: - RenderViewImpl* render_view_; // Non-owning. - ppapi::PpapiPermissions permissions_; - PepperInstanceStateAccessor* instance_state_; // Non-owning. + const ppapi::PpapiPermissions& GetPermissions() const; + + // Non-owning pointer. + RendererPpapiHostImpl* host_; DISALLOW_COPY_AND_ASSIGN(ContentRendererPepperHostFactory); }; diff --git a/content/renderer/pepper/mock_renderer_ppapi_host.cc b/content/renderer/pepper/mock_renderer_ppapi_host.cc new file mode 100644 index 0000000..d72880f --- /dev/null +++ b/content/renderer/pepper/mock_renderer_ppapi_host.cc @@ -0,0 +1,40 @@ +// Copyright (c) 2012 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 "content/renderer/pepper/mock_renderer_ppapi_host.h" + + +namespace content { + +MockRendererPpapiHost::MockRendererPpapiHost(RenderView* render_view, + PP_Instance instance) + : sink_(), + ppapi_host_(&sink_, NULL, ppapi::PpapiPermissions()), + render_view_(render_view), + pp_instance_(instance) { +} + +MockRendererPpapiHost::~MockRendererPpapiHost() { +} + +ppapi::host::PpapiHost* MockRendererPpapiHost::GetPpapiHost() { + return &ppapi_host_; +} + +bool MockRendererPpapiHost::IsValidInstance(PP_Instance instance) const { + return instance == pp_instance_; +} + +RenderView* MockRendererPpapiHost::GetRenderViewForInstance( + PP_Instance instance) const { + if (instance == pp_instance_) + return render_view_; + return NULL; +} + +bool MockRendererPpapiHost::HasUserGesture(PP_Instance instance) const { + return has_user_gesture_; +} + +} // namespace content diff --git a/content/renderer/pepper/mock_renderer_ppapi_host.h b/content/renderer/pepper/mock_renderer_ppapi_host.h new file mode 100644 index 0000000..ddf2437 --- /dev/null +++ b/content/renderer/pepper/mock_renderer_ppapi_host.h @@ -0,0 +1,60 @@ +// Copyright (c) 2012 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. + +#ifndef CONTENT_RENDERER_PEPPER_MOCK_RENDERER_PPAPI_HOST_H_ +#define CONTENT_RENDERER_PEPPER_MOCK_RENDERER_PPAPI_HOST_H_ + +#include "base/basictypes.h" +#include "content/public/renderer/renderer_ppapi_host.h" +#include "content/renderer/pepper/content_renderer_pepper_host_factory.h" +#include "ppapi/host/ppapi_host.h" +#include "ppapi/proxy/resource_message_test_sink.h" + +namespace webkit { +namespace ppapi { +class PluginInstance; +class PluginModule; +} +} + +namespace content { + +// A mock RendererPpapiHost for testing resource hosts. Messages sent by +// resources through this will get added to the test sink. +class MockRendererPpapiHost : public RendererPpapiHost { + public: + // This function takes the RenderView and instance that the mock resource + // host will be associated with. + MockRendererPpapiHost(RenderView* render_view, + PP_Instance instance); + virtual ~MockRendererPpapiHost(); + + ppapi::proxy::ResourceMessageTestSink& sink() { return sink_; } + PP_Instance pp_instance() const { return pp_instance_; } + + void set_has_user_gesture(bool gesture) { has_user_gesture_ = gesture; } + + // RendererPpapiHost. + virtual ppapi::host::PpapiHost* GetPpapiHost() OVERRIDE; + virtual bool IsValidInstance(PP_Instance instance) const OVERRIDE; + virtual RenderView* GetRenderViewForInstance( + PP_Instance instance) const OVERRIDE; + virtual bool HasUserGesture(PP_Instance instance) const OVERRIDE; + + private: + ppapi::proxy::ResourceMessageTestSink sink_; + ppapi::host::PpapiHost ppapi_host_; + + RenderView* render_view_; + PP_Instance pp_instance_; + + bool has_user_gesture_; + + DISALLOW_COPY_AND_ASSIGN(MockRendererPpapiHost); +}; + +} // namespace content + +#endif // CONTENT_RENDERER_PEPPER_MOCK_RENDERER_PPAPI_HOST_H_ + diff --git a/content/renderer/pepper/pepper_file_chooser_host.cc b/content/renderer/pepper/pepper_file_chooser_host.cc index 79c825f..4d15151 100644 --- a/content/renderer/pepper/pepper_file_chooser_host.cc +++ b/content/renderer/pepper/pepper_file_chooser_host.cc @@ -6,7 +6,7 @@ #include "base/file_path.h" #include "base/utf_string_conversions.h" -#include "content/renderer/pepper/pepper_instance_state_accessor.h" +#include "content/public/renderer/renderer_ppapi_host.h" #include "content/renderer/render_view_impl.h" #include "ppapi/c/pp_errors.h" #include "ppapi/host/dispatch_host_message.h" @@ -77,14 +77,11 @@ PepperFileChooserHost::ChosenFileInfo::ChosenFileInfo( PepperFileChooserHost::PepperFileChooserHost( - ppapi::host::PpapiHost* host, + RendererPpapiHost* host, PP_Instance instance, - PP_Resource resource, - RenderViewImpl* render_view, - PepperInstanceStateAccessor* state) - : ResourceHost(host, instance, resource), - render_view_(render_view), - instance_state_(state), + PP_Resource resource) + : ResourceHost(host->GetPpapiHost(), instance, resource), + renderer_ppapi_host_(host), handler_(NULL) { } @@ -140,7 +137,7 @@ int32_t PepperFileChooserHost::OnMsgShow( if (!host()->permissions().HasPermission( ppapi::PERMISSION_BYPASS_USER_GESTURE) && - !instance_state_->HasUserGesture(pp_instance())) { + !renderer_ppapi_host_->HasUserGesture(pp_instance())) { return PP_ERROR_NO_USER_GESTURE; } @@ -161,7 +158,9 @@ int32_t PepperFileChooserHost::OnMsgShow( params.directory = false; handler_ = new CompletionHandler(AsWeakPtr()); - if (!render_view_->runFileChooser(params, handler_)) { + RenderViewImpl* render_view = static_cast<RenderViewImpl*>( + renderer_ppapi_host_->GetRenderViewForInstance(pp_instance())); + if (!render_view || !render_view->runFileChooser(params, handler_)) { delete handler_; handler_ = NULL; return PP_ERROR_NOACCESS; @@ -174,3 +173,4 @@ int32_t PepperFileChooserHost::OnMsgShow( } } // namespace content + diff --git a/content/renderer/pepper/pepper_file_chooser_host.h b/content/renderer/pepper/pepper_file_chooser_host.h index 8dbc4e3..58482b6 100644 --- a/content/renderer/pepper/pepper_file_chooser_host.h +++ b/content/renderer/pepper/pepper_file_chooser_host.h @@ -18,7 +18,7 @@ class RenderViewImpl; namespace content { -class PepperInstanceStateAccessor; +class RendererPpapiHost; class CONTENT_EXPORT PepperFileChooserHost : public ppapi::host::ResourceHost, @@ -31,11 +31,9 @@ class CONTENT_EXPORT PepperFileChooserHost std::string display_name; // May be empty. }; - PepperFileChooserHost(ppapi::host::PpapiHost* host, + PepperFileChooserHost(RendererPpapiHost* host, PP_Instance instance, - PP_Resource resource, - RenderViewImpl* render_view, - PepperInstanceStateAccessor* state); + PP_Resource resource); virtual ~PepperFileChooserHost(); virtual int32_t OnResourceMessageReceived( @@ -53,9 +51,8 @@ class CONTENT_EXPORT PepperFileChooserHost const std::string& suggested_file_name, const std::vector<std::string>& accept_mime_types); - // Non-owning pointers. - RenderViewImpl* render_view_; - PepperInstanceStateAccessor* instance_state_; + // Non-owning pointer. + RendererPpapiHost* renderer_ppapi_host_; ppapi::proxy::ResourceMessageReplyParams reply_params_; CompletionHandler* handler_; diff --git a/content/renderer/pepper/pepper_file_chooser_host_unittest.cc b/content/renderer/pepper/pepper_file_chooser_host_unittest.cc index 09836bc..2e17a80 100644 --- a/content/renderer/pepper/pepper_file_chooser_host_unittest.cc +++ b/content/renderer/pepper/pepper_file_chooser_host_unittest.cc @@ -7,8 +7,9 @@ #include "content/common/view_messages.h" #include "content/public/test/render_view_test.h" #include "content/public/common/file_chooser_params.h" +#include "content/renderer/pepper/mock_renderer_ppapi_host.h" #include "content/renderer/pepper/pepper_file_chooser_host.h" -#include "content/renderer/pepper/pepper_instance_state_accessor.h" +//#include "content/renderer/pepper/pepper_instance_state_accessor.h" #include "content/renderer/render_view_impl.h" #include "content/test/test_content_client.h" #include "ppapi/c/pp_errors.h" @@ -69,36 +70,13 @@ std::string FilePathToUTF8(const FilePath::StringType& path) { #endif } -class MockInstanceState : public PepperInstanceStateAccessor { - public: - MockInstanceState() : has_user_gesture_(true) {} - virtual ~MockInstanceState() {} - - void set_has_user_gesture(bool has) { has_user_gesture_ = has; } - - // PepperInstanceStateAccessor. - virtual bool IsValidInstance(PP_Instance instance) OVERRIDE { - return true; - } - virtual bool HasUserGesture(PP_Instance instance) OVERRIDE { - return has_user_gesture_; - } - - private: - bool has_user_gesture_; -}; - } // namespace TEST_F(PepperFileChooserHostTest, Show) { PP_Resource pp_resource = 123; - MockInstanceState state; - ppapi::proxy::ResourceMessageTestSink sink; - ppapi::host::PpapiHost host(&sink, NULL, ppapi::PpapiPermissions()); - RenderViewImpl* view_impl = static_cast<RenderViewImpl*>(view_); - PepperFileChooserHost chooser(&host, pp_instance(), pp_resource, view_impl, - &state); + MockRendererPpapiHost host(view_, pp_instance()); + PepperFileChooserHost chooser(&host, pp_instance(), pp_resource); std::vector<std::string> accept; accept.push_back("text/plain"); @@ -130,6 +108,7 @@ TEST_F(PepperFileChooserHostTest, Show) { selected_info.local_path = FilePath(FILE_PATH_LITERAL("myp\\ath/foo")); std::vector<ui::SelectedFileInfo> selected_info_vector; selected_info_vector.push_back(selected_info); + RenderViewImpl* view_impl = static_cast<RenderViewImpl*>(view_); ViewMsg_RunFileChooserResponse response(view_impl->routing_id(), selected_info_vector); EXPECT_TRUE(view_impl->OnMessageReceived(response)); @@ -137,7 +116,7 @@ TEST_F(PepperFileChooserHostTest, Show) { // This should have sent the Pepper reply to our test sink. ppapi::proxy::ResourceMessageReplyParams reply_params; IPC::Message reply_msg; - ASSERT_TRUE(sink.GetFirstResourceReplyMatching( + ASSERT_TRUE(host.sink().GetFirstResourceReplyMatching( PpapiPluginMsg_FileChooser_ShowReply::ID, &reply_params, &reply_msg)); // Basic validation of reply. @@ -158,15 +137,11 @@ TEST_F(PepperFileChooserHostTest, Show) { TEST_F(PepperFileChooserHostTest, NoUserGesture) { PP_Resource pp_resource = 123; - MockInstanceState state; - ppapi::proxy::ResourceMessageTestSink sink; - ppapi::host::PpapiHost host(&sink, NULL, ppapi::PpapiPermissions()); - RenderViewImpl* view_impl = static_cast<RenderViewImpl*>(view_); - PepperFileChooserHost chooser(&host, pp_instance(), pp_resource, view_impl, - &state); + MockRendererPpapiHost host(view_, pp_instance()); + PepperFileChooserHost chooser(&host, pp_instance(), pp_resource); // Say there's no user gesture. - state.set_has_user_gesture(false); + host.set_has_user_gesture(false); std::vector<std::string> accept; accept.push_back("text/plain"); diff --git a/content/renderer/pepper/pepper_in_process_resource_creation.cc b/content/renderer/pepper/pepper_in_process_resource_creation.cc index 19eac81..64880db 100644 --- a/content/renderer/pepper/pepper_in_process_resource_creation.cc +++ b/content/renderer/pepper/pepper_in_process_resource_creation.cc @@ -7,8 +7,9 @@ #include "base/bind.h" #include "base/memory/weak_ptr.h" #include "base/message_loop.h" -#include "content/renderer/pepper/content_renderer_pepper_host_factory.h" #include "content/renderer/render_view_impl.h" +#include "content/renderer/pepper/pepper_in_process_router.h" +#include "content/renderer/pepper/renderer_ppapi_host_impl.h" #include "ipc/ipc_message.h" #include "ipc/ipc_message_macros.h" #include "ppapi/host/ppapi_host.h" @@ -25,131 +26,13 @@ namespace content { -class PepperInProcessResourceCreation::PluginToHostRouter - : public IPC::Sender { - public: - PluginToHostRouter(RenderViewImpl* render_view, - PepperInstanceStateAccessor* state, - IPC::Sender* host_to_plugin_sender, - const ppapi::PpapiPermissions& perms); - virtual ~PluginToHostRouter() {} - - ppapi::host::PpapiHost& host() { return host_; } - - // Sender implementation. - virtual bool Send(IPC::Message* msg) OVERRIDE; - - private: - void DoSend(IPC::Message* msg); - - base::WeakPtrFactory<PluginToHostRouter> weak_factory_; - - ContentRendererPepperHostFactory factory_; - ppapi::host::PpapiHost host_; - - DISALLOW_COPY_AND_ASSIGN(PluginToHostRouter); -}; - -PepperInProcessResourceCreation::PluginToHostRouter::PluginToHostRouter( - RenderViewImpl* render_view, - PepperInstanceStateAccessor* state, - IPC::Sender* host_to_plugin_sender, - const ppapi::PpapiPermissions& perms) - : weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), - factory_(render_view, perms, state), - host_(host_to_plugin_sender, &factory_, perms) { -} - -bool PepperInProcessResourceCreation::PluginToHostRouter::Send( - IPC::Message* msg) { - // Don't directly call into the message handler to avoid reentrancy. The IPC - // systen assumes everything is executed from the message loop, so emulate - // the same thing for in-process. - MessageLoop::current()->PostTask(FROM_HERE, - base::Bind(&PluginToHostRouter::DoSend, weak_factory_.GetWeakPtr(), - base::Owned(msg))); - return true; -} - -void PepperInProcessResourceCreation::PluginToHostRouter::DoSend( - IPC::Message* msg) { - host_.OnMessageReceived(*msg); -} - -// HostToPluginRouter --------------------------------------------------------- - -class PepperInProcessResourceCreation::HostToPluginRouter - : public IPC::Sender { - public: - HostToPluginRouter(); - virtual ~HostToPluginRouter() {} - - // Sender implementation. - virtual bool Send(IPC::Message* msg) OVERRIDE; - - private: - void DispatchMsg(IPC::Message* msg); - - void OnMsgResourceReply( - const ppapi::proxy::ResourceMessageReplyParams& reply_params, - const IPC::Message& nested_msg); - - base::WeakPtrFactory<HostToPluginRouter> weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(HostToPluginRouter); -}; - -PepperInProcessResourceCreation::HostToPluginRouter::HostToPluginRouter() - : weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { -} - -bool PepperInProcessResourceCreation::HostToPluginRouter::Send( - IPC::Message* msg) { - // As in the PluginToHostRouter, dispatch from the message loop. - MessageLoop::current()->PostTask(FROM_HERE, - base::Bind(&HostToPluginRouter::DispatchMsg, - weak_factory_.GetWeakPtr(), - base::Owned(msg))); - return true; -} - -void PepperInProcessResourceCreation::HostToPluginRouter::DispatchMsg( - IPC::Message* msg) { - // Emulate the proxy by dispatching the relevant message here. - IPC_BEGIN_MESSAGE_MAP(HostToPluginRouter, *msg) - IPC_MESSAGE_HANDLER(PpapiPluginMsg_ResourceReply, OnMsgResourceReply) - IPC_END_MESSAGE_MAP() -} - -void PepperInProcessResourceCreation::HostToPluginRouter::OnMsgResourceReply( - const ppapi::proxy::ResourceMessageReplyParams& reply_params, - const IPC::Message& nested_msg) { - ppapi::Resource* resource = - ppapi::PpapiGlobals::Get()->GetResourceTracker()->GetResource( - reply_params.pp_resource()); - if (!resource) { - // The resource could have been destroyed while the async processing was - // pending. Just drop the message. - return; - } - resource->OnReplyReceived(reply_params.sequence(), reply_params.result(), - nested_msg); -} - // PepperInProcessResourceCreation -------------------------------------------- PepperInProcessResourceCreation::PepperInProcessResourceCreation( - RenderViewImpl* render_view, - webkit::ppapi::PluginInstance* instance, - const ppapi::PpapiPermissions& perms) + RendererPpapiHostImpl* host_impl, + webkit::ppapi::PluginInstance* instance) : ResourceCreationImpl(instance), - instance_state_(instance->module()), - host_to_plugin_router_(new HostToPluginRouter), - plugin_to_host_router_( - new PluginToHostRouter(render_view, &instance_state_, - host_to_plugin_router_.get(), - perms)) { - render_view->PpapiPluginCreated(&plugin_to_host_router_->host()); + host_impl_(host_impl) { } PepperInProcessResourceCreation::~PepperInProcessResourceCreation() { @@ -160,7 +43,7 @@ PP_Resource PepperInProcessResourceCreation::CreateFileChooser( PP_FileChooserMode_Dev mode, const char* accept_types) { return (new ppapi::proxy::FileChooserResource( - plugin_to_host_router_.get(), + host_impl_->in_process_router()->GetPluginConnection(), instance, mode, accept_types))->GetReference(); } diff --git a/content/renderer/pepper/pepper_in_process_resource_creation.h b/content/renderer/pepper/pepper_in_process_resource_creation.h index 78216b2..add4348 100644 --- a/content/renderer/pepper/pepper_in_process_resource_creation.h +++ b/content/renderer/pepper/pepper_in_process_resource_creation.h @@ -7,30 +7,29 @@ #include "base/basictypes.h" #include "base/memory/scoped_ptr.h" -#include "content/renderer/pepper/pepper_instance_state_accessor_impl.h" +#include "ppapi/proxy/connection.h" #include "webkit/plugins/ppapi/resource_creation_impl.h" -class RenderViewImpl; - -namespace ppapi { -class PpapiPermissions; -} - namespace content { +class RendererPpapiHostImpl; + // This class provides creation functions for the new resources with IPC // backends that live in content/renderer/pepper. // +// (See pepper_in_process_router.h for more information.) +// // This is a bit confusing. The "old-style" resources live in // webkit/plugins/ppapi and are created by the ResourceCreationImpl in that // directory. The "new-style" IPC-only resources are in ppapi/proxy and are // created by the RessourceCreationProxy in that directory. // -// This class allows us to run new-style IPC-only resources in-process. We have -// an IPC reflector to run it in process. But then we have a problem with -// allocating the resources since src/webkit can't depend on IPC or see our IPC -// backend in content. This class overrides the normal in-process resource -// creation and adds in the resources that we implement in ppapi/proxy. +// This class allows us to run new-style IPC-only resources in-process. We use +// the PepperInProcessRouter to run it in process. But then we have a problem +// with allocating the resources since src/webkit can't depend on IPC or see +// our IPC backend in content. This class overrides the normal in-process +// resource creation and adds in the resources that we implement in +// ppapi/proxy. // // When we convert all resources to use the new-style, we can just use the // ResourceCreationProxy for all resources. This class is just glue to manage @@ -38,9 +37,8 @@ namespace content { class PepperInProcessResourceCreation : public webkit::ppapi::ResourceCreationImpl { public: - PepperInProcessResourceCreation(RenderViewImpl* render_view, - webkit::ppapi::PluginInstance* instance, - const ppapi::PpapiPermissions& perms); + PepperInProcessResourceCreation(RendererPpapiHostImpl* host_impl, + webkit::ppapi::PluginInstance* instance); virtual ~PepperInProcessResourceCreation(); // ResourceCreation_API implementation. @@ -50,13 +48,8 @@ class PepperInProcessResourceCreation const char* accept_types) OVERRIDE; private: - PepperInstanceStateAccessorImpl instance_state_; - - class HostToPluginRouter; - scoped_ptr<HostToPluginRouter> host_to_plugin_router_; - - class PluginToHostRouter; - scoped_ptr<PluginToHostRouter> plugin_to_host_router_; + // Non-owning pointer to the host for the current plugin. + RendererPpapiHostImpl* host_impl_; DISALLOW_COPY_AND_ASSIGN(PepperInProcessResourceCreation); }; diff --git a/content/renderer/pepper/pepper_in_process_router.cc b/content/renderer/pepper/pepper_in_process_router.cc new file mode 100644 index 0000000..3ccc537 --- /dev/null +++ b/content/renderer/pepper/pepper_in_process_router.cc @@ -0,0 +1,153 @@ +// Copyright (c) 2012 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 "content/renderer/pepper/pepper_in_process_router.h" + +#include "base/bind.h" +#include "base/message_loop.h" +#include "content/renderer/pepper/renderer_ppapi_host_impl.h" +#include "ipc/ipc_message.h" +#include "ipc/ipc_message_macros.h" +#include "ipc/ipc_sender.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/shared_impl/ppapi_globals.h" +#include "ppapi/shared_impl/resource_tracker.h" + +namespace content { + +class PepperInProcessRouter::DummyBrowserChannel : public IPC::Sender { + public: + DummyBrowserChannel() {} + ~DummyBrowserChannel() {} + + // Sender implementation. + virtual bool Send(IPC::Message* msg) OVERRIDE { + // See the class comment in the header file for what this is about. + NOTREACHED(); + delete msg; + return false; + } +}; + +class PepperInProcessRouter::PluginToHostRouter : public IPC::Sender { + public: + PluginToHostRouter(RendererPpapiHostImpl* host_impl); + virtual ~PluginToHostRouter() {} + + // Sender implementation. + virtual bool Send(IPC::Message* msg) OVERRIDE; + + private: + void DoSend(IPC::Message* msg); + + RendererPpapiHostImpl* host_impl_; + + base::WeakPtrFactory<PluginToHostRouter> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(PluginToHostRouter); +}; + +PepperInProcessRouter::PluginToHostRouter::PluginToHostRouter( + RendererPpapiHostImpl* host_impl) + : host_impl_(host_impl), + weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { +} + +bool PepperInProcessRouter::PluginToHostRouter::Send( + IPC::Message* msg) { + // Don't directly call into the message handler to avoid reentrancy. The IPC + // systen assumes everything is executed from the message loop, so emulate + // the same thing for in-process. + MessageLoop::current()->PostTask(FROM_HERE, + base::Bind(&PluginToHostRouter::DoSend, weak_factory_.GetWeakPtr(), + base::Owned(msg))); + return true; +} + +void PepperInProcessRouter::PluginToHostRouter::DoSend( + IPC::Message* msg) { + host_impl_->GetPpapiHost()->OnMessageReceived(*msg); +} + +// HostToPluginRouter --------------------------------------------------------- + +class PepperInProcessRouter::HostToPluginRouter : public IPC::Sender { + public: + HostToPluginRouter(); + virtual ~HostToPluginRouter() {} + + // Sender implementation. + virtual bool Send(IPC::Message* msg) OVERRIDE; + + private: + void DispatchMsg(IPC::Message* msg); + + void OnMsgResourceReply( + const ppapi::proxy::ResourceMessageReplyParams& reply_params, + const IPC::Message& nested_msg); + + base::WeakPtrFactory<HostToPluginRouter> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(HostToPluginRouter); +}; + +PepperInProcessRouter::HostToPluginRouter::HostToPluginRouter() + : weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { +} + +bool PepperInProcessRouter::HostToPluginRouter::Send( + IPC::Message* msg) { + // As in the PluginToHostRouter, dispatch from the message loop. + MessageLoop::current()->PostTask(FROM_HERE, + base::Bind(&HostToPluginRouter::DispatchMsg, + weak_factory_.GetWeakPtr(), + base::Owned(msg))); + return true; +} + +void PepperInProcessRouter::HostToPluginRouter::DispatchMsg( + IPC::Message* msg) { + // Emulate the proxy by dispatching the relevant message here. + IPC_BEGIN_MESSAGE_MAP(HostToPluginRouter, *msg) + IPC_MESSAGE_HANDLER(PpapiPluginMsg_ResourceReply, OnMsgResourceReply) + IPC_END_MESSAGE_MAP() +} + +void PepperInProcessRouter::HostToPluginRouter::OnMsgResourceReply( + const ppapi::proxy::ResourceMessageReplyParams& reply_params, + const IPC::Message& nested_msg) { + ppapi::Resource* resource = + ppapi::PpapiGlobals::Get()->GetResourceTracker()->GetResource( + reply_params.pp_resource()); + if (!resource) { + // The resource could have been destroyed while the async processing was + // pending. Just drop the message. + return; + } + resource->OnReplyReceived(reply_params, nested_msg); +} + +PepperInProcessRouter::PepperInProcessRouter( + RendererPpapiHostImpl* host_impl) + : host_to_plugin_router_(new HostToPluginRouter), + plugin_to_host_router_(new PluginToHostRouter(host_impl)) { +} + +PepperInProcessRouter::~PepperInProcessRouter() { +} + +IPC::Sender* PepperInProcessRouter::GetPluginToRendererSender() { + return plugin_to_host_router_.get(); +} + +IPC::Sender* PepperInProcessRouter::GetRendererToPluginSender() { + return host_to_plugin_router_.get(); +} + +ppapi::proxy::Connection PepperInProcessRouter::GetPluginConnection() { + return ppapi::proxy::Connection(dummy_browser_channel_.get(), + plugin_to_host_router_.get()); +} + +} // namespace content diff --git a/content/renderer/pepper/pepper_in_process_router.h b/content/renderer/pepper/pepper_in_process_router.h new file mode 100644 index 0000000..dd8e0e2 --- /dev/null +++ b/content/renderer/pepper/pepper_in_process_router.h @@ -0,0 +1,70 @@ +// Copyright (c) 2012 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 "base/basictypes.h" +#include "base/memory/scoped_ptr.h" +#include "ppapi/proxy/connection.h" + +namespace content { + +class RendererPpapiHostImpl; + +// This class fakes an IPC channel so that we can take the new resources with +// IPC backends and run them in-process. +// +// (See pepper_in_process_resource_creation.h for more background.) +// +// This class just provides the fake routing for in-process plugins. +// Asynchronous messages are converted into an asynchronous execution of the +// message receiver on the opposite end. Synchronous messages just call right +// through. +// +// The resources in ppapi/proxy assume that there is an IPC connection to +// both the renderer and the browser processes. They take a connection object +// that includes both of these channels. However, in-process plugins don't +// have a BrowserPpapiHost on the browser side to receive these messages. +// +// As a result, we can't support resources that rely on sending messages to the +// browser process. Since this class is a stopgap until all interfaces are +// converted and all plugins are run out-of-procss, we just choose not to +// support faking IPC channels for resources that send messages directly to the +// browser process. These resources will just have to use the "old" in-process +// implementation until the conversion is complete and all this code can be +// deleted. +// +// To keep things consistent, we provide an IPC::Sender for the browser channel +// in the connection object supplied to resources. This dummy browser channel +// will just assert and delete the message if anything is ever sent over it. +class PepperInProcessRouter { + public: + // The given host parameter owns this class and must outlive us. + PepperInProcessRouter(RendererPpapiHostImpl* host_impl); + ~PepperInProcessRouter(); + + // Returns the dummy sender for the cooresponding end of the in-process + // emulated channel. + IPC::Sender* GetPluginToRendererSender(); + IPC::Sender* GetRendererToPluginSender(); + + // Returns a connection pair for use by a resource proxy. This includes + // the plugin->renderer sender as well as a dummy sender to the browser + // process. See the class comment above about the dummy sender. + ppapi::proxy::Connection GetPluginConnection(); + + private: + class DummyBrowserChannel; + scoped_ptr<DummyBrowserChannel> dummy_browser_channel_; + + // Renderer -> plugin channel. + class HostToPluginRouter; + scoped_ptr<HostToPluginRouter> host_to_plugin_router_; + + // Plugin -> renderer channel. + class PluginToHostRouter; + scoped_ptr<PluginToHostRouter> plugin_to_host_router_; + + DISALLOW_COPY_AND_ASSIGN(PepperInProcessRouter); +}; + +} // namespace content diff --git a/content/renderer/pepper/pepper_instance_state_accessor.h b/content/renderer/pepper/pepper_instance_state_accessor.h deleted file mode 100644 index 120640c..0000000 --- a/content/renderer/pepper/pepper_instance_state_accessor.h +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) 2012 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.
-
-#ifndef CONTENT_RENDERER_PEPPER_PEPPER_INSTANCE_STATE_ACCESSOR_H_
-#define CONTENT_RENDERER_PEPPER_PEPPER_INSTANCE_STATE_ACCESSOR_H_
-
-#include "base/basictypes.h"
-#include "ppapi/c/pp_instance.h"
-
-namespace content {
-
-// This interface provides functions for querying instance state for resource
-// host implementations. It allows us to mock out some of these interactions
-// for testing, as well as limit the dependencies on the webkit layer.
-class PepperInstanceStateAccessor {
- public:
- virtual ~PepperInstanceStateAccessor() {}
-
- // Returns true if the given instance is valid for the host.
- virtual bool IsValidInstance(PP_Instance instance) = 0;
-
- // Returns true if the given instance is considered to be currently
- // processing a user gesture or the plugin module has the "override user
- // gesture" flag set (in which case it can always do things normally
- // restricted by user gestures). Returns false if the instance is invalid or
- // if there is no current user gesture.
- virtual bool HasUserGesture(PP_Instance instance) = 0;
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_PEPPER_PEPPER_INSTANCE_STATE_ACCESSOR_H_
diff --git a/content/renderer/pepper/pepper_instance_state_accessor_impl.cc b/content/renderer/pepper/pepper_instance_state_accessor_impl.cc deleted file mode 100644 index 376d3aa..0000000 --- a/content/renderer/pepper/pepper_instance_state_accessor_impl.cc +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2012 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 "content/renderer/pepper/pepper_instance_state_accessor_impl.h"
-
-#include "ppapi/shared_impl/ppapi_permissions.h"
-#include "webkit/plugins/ppapi/host_globals.h"
-#include "webkit/plugins/ppapi/plugin_module.h"
-#include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
-
-using webkit::ppapi::HostGlobals;
-using webkit::ppapi::PluginInstance;
-
-namespace content {
-
-PepperInstanceStateAccessorImpl::PepperInstanceStateAccessorImpl(
- webkit::ppapi::PluginModule* module)
- : module_(module) {
-}
-
-PepperInstanceStateAccessorImpl::~PepperInstanceStateAccessorImpl() {
-}
-
-bool PepperInstanceStateAccessorImpl::IsValidInstance(PP_Instance instance) {
- return !!GetAndValidateInstance(instance);
-}
-
-bool PepperInstanceStateAccessorImpl::HasUserGesture(PP_Instance pp_instance) {
- PluginInstance* instance = GetAndValidateInstance(pp_instance);
- if (!instance)
- return false;
-
- if (instance->module()->permissions().HasPermission(
- ppapi::PERMISSION_BYPASS_USER_GESTURE))
- return true;
- return instance->IsProcessingUserGesture();
-}
-
-PluginInstance* PepperInstanceStateAccessorImpl::GetAndValidateInstance(
- PP_Instance pp_instance) {
- PluginInstance* instance = HostGlobals::Get()->GetInstance(pp_instance);
- if (!instance)
- return NULL;
- if (instance->module() != module_)
- return NULL;
- return instance;
-}
-
-} // namespace content
diff --git a/content/renderer/pepper/pepper_instance_state_accessor_impl.h b/content/renderer/pepper/pepper_instance_state_accessor_impl.h deleted file mode 100644 index 108686e..0000000 --- a/content/renderer/pepper/pepper_instance_state_accessor_impl.h +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) 2012 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.
-
-#ifndef CONTENT_RENDERER_PEPPER_PEPPER_INSTANCE_STATE_ACCESSOR_IMPL_H
-#define CONTENT_RENDERER_PEPPER_PEPPER_INSTANCE_STATE_ACCESSOR_IMPL_H
-
-#include "base/compiler_specific.h"
-#include "content/renderer/pepper/pepper_instance_state_accessor.h"
-
-namespace webkit {
-namespace ppapi {
-class PluginInstance;
-class PluginModule;
-}
-}
-
-namespace content {
-
-class PepperInstanceStateAccessorImpl : public PepperInstanceStateAccessor {
- public:
- PepperInstanceStateAccessorImpl(webkit::ppapi::PluginModule* module);
- virtual ~PepperInstanceStateAccessorImpl();
-
- // PepperInstanceStateAccessor implmentation.
- virtual bool IsValidInstance(PP_Instance instance) OVERRIDE;
- virtual bool HasUserGesture(PP_Instance pp_instance) OVERRIDE;
-
- private:
- // Retrieves the plugin instance object associated with the given PP_Instance
- // and validates that it is one of the instances associated with our module.
- // Returns NULL on failure.
- //
- // We use this to security check the PP_Instance values sent from a plugin to
- // make sure it's not trying to spoof another instance.
- webkit::ppapi::PluginInstance* GetAndValidateInstance(PP_Instance instance);
-
- webkit::ppapi::PluginModule* module_;
-
- DISALLOW_COPY_AND_ASSIGN(PepperInstanceStateAccessorImpl);
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_PEPPER_PEPPER_INSTANCE_STATE_ACCESSOR_IMPL_H
diff --git a/content/renderer/pepper/pepper_plugin_delegate_impl.cc b/content/renderer/pepper/pepper_plugin_delegate_impl.cc index 0675c2f..427af74 100644 --- a/content/renderer/pepper/pepper_plugin_delegate_impl.cc +++ b/content/renderer/pepper/pepper_plugin_delegate_impl.cc @@ -47,13 +47,13 @@ #include "content/renderer/pepper/pepper_device_enumeration_event_handler.h" #include "content/renderer/pepper/pepper_hung_plugin_filter.h" #include "content/renderer/pepper/pepper_in_process_resource_creation.h" -#include "content/renderer/pepper/pepper_instance_state_accessor.h" #include "content/renderer/pepper/pepper_platform_audio_input_impl.h" #include "content/renderer/pepper/pepper_platform_audio_output_impl.h" #include "content/renderer/pepper/pepper_platform_context_3d_impl.h" #include "content/renderer/pepper/pepper_platform_image_2d_impl.h" #include "content/renderer/pepper/pepper_platform_video_capture_impl.h" #include "content/renderer/pepper/pepper_proxy_channel_delegate_impl.h" +#include "content/renderer/pepper/renderer_ppapi_host_impl.h" #include "content/renderer/render_thread_impl.h" #include "content/renderer/render_view_impl.h" #include "content/renderer/render_widget_fullscreen_pepper.h" @@ -110,9 +110,7 @@ class HostDispatcherWrapper webkit::ppapi::PluginModule* module, const ppapi::PpapiPermissions& perms) : module_(module), - instance_state_(module), - host_factory_(rv, perms, &instance_state_), - render_view_(rv) { + permissions_(perms) { } virtual ~HostDispatcherWrapper() {} @@ -134,10 +132,6 @@ class HostDispatcherWrapper dispatcher_.reset(new ppapi::proxy::HostDispatcher( module_->pp_module(), local_get_interface, filter)); - host_.reset(new ppapi::host::PpapiHost(dispatcher_.get(), &host_factory_, - permissions)); - dispatcher_->AddFilter(host_.get()); - if (!dispatcher_->InitHostWithChannel(dispatcher_delegate_.get(), channel_handle, true, // Client. @@ -148,7 +142,6 @@ class HostDispatcherWrapper } dispatcher_->channel()->SetRestrictDispatchChannelGroup( content::kRendererRestrictDispatchGroup_Pepper); - render_view_->PpapiPluginCreated(host_.get()); return true; } @@ -163,13 +156,12 @@ class HostDispatcherWrapper ppapi::proxy::HostDispatcher::RemoveForInstance(instance); } + ppapi::proxy::HostDispatcher* dispatcher() { return dispatcher_.get(); } + private: webkit::ppapi::PluginModule* module_; - PepperInstanceStateAccessorImpl instance_state_; - ContentRendererPepperHostFactory host_factory_; - RenderViewImpl* render_view_; - scoped_ptr<ppapi::host::PpapiHost> host_; + ppapi::PpapiPermissions permissions_; scoped_ptr<ppapi::proxy::HostDispatcher> dispatcher_; scoped_ptr<ppapi::proxy::ProxyChannel::Delegate> dispatcher_delegate_; @@ -279,6 +271,23 @@ void DoNotifyCloseFile(const GURL& path, base::PlatformFileError /* unused */) { ChildThread::current()->file_system_dispatcher()->NotifyCloseFile(path); } +void CreateHostForInProcessModule(RenderViewImpl* render_view, + webkit::ppapi::PluginModule* module, + const webkit::WebPluginInfo& webplugin_info) { + // First time an in-process plugin was used, make a host for it. + const PepperPluginInfo* info = + PepperPluginRegistry::GetInstance()->GetInfoForPlugin(webplugin_info); + DCHECK(!info->is_out_of_process); + + ppapi::PpapiPermissions perms( + PepperPluginRegistry::GetInstance()->GetInfoForPlugin( + webplugin_info)->permissions); + RendererPpapiHostImpl* host_impl = + content::RendererPpapiHostImpl::CreateOnModuleForInProcess( + module, perms); + render_view->PpapiPluginCreated(host_impl); +} + } // namespace PepperPluginDelegateImpl::PepperPluginDelegateImpl(RenderViewImpl* render_view) @@ -306,8 +315,15 @@ PepperPluginDelegateImpl::CreatePepperPluginModule( FilePath path(webplugin_info.path); scoped_refptr<webkit::ppapi::PluginModule> module = PepperPluginRegistry::GetInstance()->GetLiveModule(path); - if (module) + if (module) { + if (!module->GetEmbedderState()) { + // If the module exists and no embedder state was associated with it, + // then the module was one of the ones preloaded and is an in-process + // plugin. We need to associate our host state with it. + CreateHostForInProcessModule(render_view_, module, webplugin_info); + } return module; + } // In-process plugins will have always been created up-front to avoid the // sandbox restrictions. So getting here implies it doesn't exist or should @@ -354,6 +370,12 @@ PepperPluginDelegateImpl::CreatePepperPluginModule( permissions, hung_filter.get())) return scoped_refptr<webkit::ppapi::PluginModule>(); + + RendererPpapiHostImpl* host_impl = + content::RendererPpapiHostImpl::CreateOnModuleForOutOfProcess( + module, dispatcher->dispatcher(), permissions); + render_view_->PpapiPluginCreated(host_impl); + module->InitAsProxied(dispatcher.release()); return module; } @@ -694,9 +716,9 @@ void PepperPluginDelegateImpl::InstanceDeleted( scoped_ptr< ::ppapi::thunk::ResourceCreationAPI> PepperPluginDelegateImpl::CreateResourceCreationAPI( webkit::ppapi::PluginInstance* instance) { - return scoped_ptr< ::ppapi::thunk::ResourceCreationAPI>( - new PepperInProcessResourceCreation(render_view_, instance, - instance->module()->permissions())); + RendererPpapiHostImpl* host_impl = static_cast<RendererPpapiHostImpl*>( + instance->module()->GetEmbedderState()); + return host_impl->CreateInProcessResourceCreationAPI(instance); } SkBitmap* PepperPluginDelegateImpl::GetSadPluginBitmap() { diff --git a/content/renderer/pepper/pepper_plugin_delegate_impl.h b/content/renderer/pepper/pepper_plugin_delegate_impl.h index 09e3986..54234d1 100644 --- a/content/renderer/pepper/pepper_plugin_delegate_impl.h +++ b/content/renderer/pepper/pepper_plugin_delegate_impl.h @@ -80,6 +80,8 @@ class PepperPluginDelegateImpl explicit PepperPluginDelegateImpl(RenderViewImpl* render_view); virtual ~PepperPluginDelegateImpl(); + RenderViewImpl* render_view() { return render_view_; } + // Attempts to create a PPAPI plugin for the given filepath. On success, it // will return the newly-created module. // diff --git a/content/renderer/pepper/renderer_ppapi_host_impl.cc b/content/renderer/pepper/renderer_ppapi_host_impl.cc new file mode 100644 index 0000000..feafc2e --- /dev/null +++ b/content/renderer/pepper/renderer_ppapi_host_impl.cc @@ -0,0 +1,130 @@ +// Copyright (c) 2012 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 "content/renderer/pepper/renderer_ppapi_host_impl.h" + +#include "base/logging.h" +#include "content/renderer/pepper/pepper_in_process_resource_creation.h" +#include "content/renderer/pepper/pepper_in_process_router.h" +#include "content/renderer/pepper/pepper_plugin_delegate_impl.h" +#include "content/renderer/render_view_impl.h" +#include "ppapi/proxy/host_dispatcher.h" +#include "webkit/plugins/ppapi/host_globals.h" +#include "webkit/plugins/ppapi/ppapi_plugin_instance.h" + +using webkit::ppapi::HostGlobals; +using webkit::ppapi::PluginInstance; + +namespace content { + +// Out-of-process constructor. +RendererPpapiHostImpl::RendererPpapiHostImpl( + webkit::ppapi::PluginModule* module, + ppapi::proxy::HostDispatcher* dispatcher, + const ppapi::PpapiPermissions& permissions) + : module_(module), + host_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { + // Hook the PpapiHost up to the dispatcher for out-of-process communication. + ppapi_host_.reset( + new ppapi::host::PpapiHost(dispatcher, &host_factory_, permissions)); + dispatcher->AddFilter(ppapi_host_.get()); +} + +// In-process constructor. +RendererPpapiHostImpl::RendererPpapiHostImpl( + webkit::ppapi::PluginModule* module, + const ppapi::PpapiPermissions& permissions) + : module_(module), + host_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { + // Hook the host up to the in-process router. + in_process_router_.reset(new PepperInProcessRouter(this)); + ppapi_host_.reset(new ppapi::host::PpapiHost( + in_process_router_->GetRendererToPluginSender(), + &host_factory_, permissions)); +} + +RendererPpapiHostImpl::~RendererPpapiHostImpl() { +} + +// static +RendererPpapiHostImpl* RendererPpapiHostImpl::CreateOnModuleForOutOfProcess( + webkit::ppapi::PluginModule* module, + ppapi::proxy::HostDispatcher* dispatcher, + const ppapi::PpapiPermissions& permissions) { + DCHECK(!module->GetEmbedderState()); + RendererPpapiHostImpl* result = new RendererPpapiHostImpl( + module, dispatcher, permissions); + + // Takes ownership of pointer. + module->SetEmbedderState( + scoped_ptr<webkit::ppapi::PluginModule::EmbedderState>(result)); + + return result; +} + +// static +RendererPpapiHostImpl* RendererPpapiHostImpl::CreateOnModuleForInProcess( + webkit::ppapi::PluginModule* module, + const ppapi::PpapiPermissions& permissions) { + DCHECK(!module->GetEmbedderState()); + RendererPpapiHostImpl* result = new RendererPpapiHostImpl( + module, permissions); + + // Takes ownership of pointer. + module->SetEmbedderState( + scoped_ptr<webkit::ppapi::PluginModule::EmbedderState>(result)); + + return result; +} + +scoped_ptr< ::ppapi::thunk::ResourceCreationAPI> +RendererPpapiHostImpl::CreateInProcessResourceCreationAPI( + webkit::ppapi::PluginInstance* instance) { + return scoped_ptr< ::ppapi::thunk::ResourceCreationAPI>( + new PepperInProcessResourceCreation(this, instance)); +} + +ppapi::host::PpapiHost* RendererPpapiHostImpl::GetPpapiHost() { + return ppapi_host_.get(); +} + +RenderView* RendererPpapiHostImpl::GetRenderViewForInstance( + PP_Instance instance) const { + PluginInstance* instance_object = GetAndValidateInstance(instance); + if (!instance_object) + return NULL; + + // Since we're the embedder, we can make assumptions about the delegate on + // the instance and get back to our RenderView. + return static_cast<PepperPluginDelegateImpl*>( + instance_object->delegate())->render_view(); +} + +bool RendererPpapiHostImpl::IsValidInstance( + PP_Instance instance) const { + return !!GetAndValidateInstance(instance); +} + +bool RendererPpapiHostImpl::HasUserGesture(PP_Instance instance) const { + PluginInstance* instance_object = GetAndValidateInstance(instance); + if (!instance_object) + return false; + + if (instance_object->module()->permissions().HasPermission( + ppapi::PERMISSION_BYPASS_USER_GESTURE)) + return true; + return instance_object->IsProcessingUserGesture(); +} + +PluginInstance* RendererPpapiHostImpl::GetAndValidateInstance( + PP_Instance pp_instance) const { + PluginInstance* instance = HostGlobals::Get()->GetInstance(pp_instance); + if (!instance) + return NULL; + if (instance->module() != module_) + return NULL; + return instance; +} + +} // namespace content diff --git a/content/renderer/pepper/renderer_ppapi_host_impl.h b/content/renderer/pepper/renderer_ppapi_host_impl.h new file mode 100644 index 0000000..a3537fb --- /dev/null +++ b/content/renderer/pepper/renderer_ppapi_host_impl.h @@ -0,0 +1,116 @@ +// Copyright (c) 2012 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. + +#ifndef CONTENT_RENDERER_PEPPER_RENDERER_PPAPI_HOST_IMPL_H_ +#define CONTENT_RENDERER_PEPPER_RENDERER_PPAPI_HOST_IMPL_H_ + +#include "base/basictypes.h" +#include "base/memory/scoped_ptr.h" +#include "content/public/renderer/renderer_ppapi_host.h" +#include "content/renderer/pepper/content_renderer_pepper_host_factory.h" +#include "ppapi/host/ppapi_host.h" +#include "webkit/plugins/ppapi/plugin_module.h" + +namespace IPC { +class Sender; +} + +namespace ppapi { + +namespace proxy { +class HostDispatcher; +} + +namespace thunk { +class ResourceCreationAPI; +} + +} // namespace ppapi + +namespace webkit { +namespace ppapi { +class PluginInstance; +class PluginModule; +} +} + +namespace content { + +class PepperInProcessRouter; + +// This class is attached to a PluginModule via the module's embedder state. +// The plugin module manages our lifetime. +class RendererPpapiHostImpl + : public RendererPpapiHost, + public webkit::ppapi::PluginModule::EmbedderState { + public: + virtual ~RendererPpapiHostImpl(); + + // Factory functions to create in process or out-of-process host impls. The + // host will be created and associated with the given module, which must not + // already have embedder state on it. + // + // The module will take ownership of the new host impl. The returned value + // does not pass ownership, it's just for the information of the caller. + static RendererPpapiHostImpl* CreateOnModuleForOutOfProcess( + webkit::ppapi::PluginModule* module, + ppapi::proxy::HostDispatcher* dispatcher, + const ppapi::PpapiPermissions& permissions); + static RendererPpapiHostImpl* CreateOnModuleForInProcess( + webkit::ppapi::PluginModule* module, + const ppapi::PpapiPermissions& permissions); + + // Returns the router that we use for in-process IPC emulation (see the + // pepper_in_process_router.h for more). This will be NULL when the plugin + // is running out-of-process. + PepperInProcessRouter* in_process_router() { + return in_process_router_.get(); + } + + // Creates the in-process resource creation API wrapper for the given + // plugin instance. This object will reference the host impl, so the + // host impl should outlive the returned pointer. Since the resource + // creation object is associated with the instance, this will generally + // happen automatically. + scoped_ptr< ::ppapi::thunk::ResourceCreationAPI> + CreateInProcessResourceCreationAPI( + webkit::ppapi::PluginInstance* instance); + + // RendererPpapiHost. + virtual ppapi::host::PpapiHost* GetPpapiHost() OVERRIDE; + virtual bool IsValidInstance(PP_Instance instance) const OVERRIDE; + virtual RenderView* GetRenderViewForInstance( + PP_Instance instance) const OVERRIDE; + virtual bool HasUserGesture(PP_Instance instance) const OVERRIDE; + + private: + RendererPpapiHostImpl(webkit::ppapi::PluginModule* module, + ppapi::proxy::HostDispatcher* dispatcher, + const ppapi::PpapiPermissions& permissions); + RendererPpapiHostImpl(webkit::ppapi::PluginModule* module, + const ppapi::PpapiPermissions& permissions); + + // Retrieves the plugin instance object associated with the given PP_Instance + // and validates that it is one of the instances associated with our module. + // Returns NULL on failure. + // + // We use this to security check the PP_Instance values sent from a plugin to + // make sure it's not trying to spoof another instance. + webkit::ppapi::PluginInstance* GetAndValidateInstance( + PP_Instance instance) const; + + webkit::ppapi::PluginModule* module_; // Non-owning pointer. + + ContentRendererPepperHostFactory host_factory_; + scoped_ptr<ppapi::host::PpapiHost> ppapi_host_; + + // Null when running out-of-process. + scoped_ptr<PepperInProcessRouter> in_process_router_; + + DISALLOW_COPY_AND_ASSIGN(RendererPpapiHostImpl); +}; + +} // namespace content + +#endif // CONTENT_RENDERER_PEPPER_RENDERER_PPAPI_HOST_IMPL_H_ diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index 0c021e2..14c8957 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc @@ -5364,7 +5364,7 @@ void RenderViewImpl::PpapiPluginSelectionChanged() { SyncSelectionIfRequired(); } -void RenderViewImpl::PpapiPluginCreated(ppapi::host::PpapiHost* host) { +void RenderViewImpl::PpapiPluginCreated(content::RendererPpapiHost* host) { FOR_EACH_OBSERVER(RenderViewObserver, observers_, DidCreatePepperPlugin(host)); } diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h index 7b8a8b9..63478c0 100644 --- a/content/renderer/render_view_impl.h +++ b/content/renderer/render_view_impl.h @@ -96,6 +96,7 @@ class P2PSocketDispatcher; class RenderViewObserver; class RenderViewTest; class RendererAccessibility; +class RendererPpapiHost; struct CustomContextMenuContext; struct FileChooserParams; @@ -334,7 +335,7 @@ class RenderViewImpl : public RenderWidget, void PpapiPluginSelectionChanged(); // Notification that a PPAPI plugin has been created. - void PpapiPluginCreated(ppapi::host::PpapiHost* host); + void PpapiPluginCreated(content::RendererPpapiHost* host); // Retrieves the current caret position if a PPAPI plugin has focus. bool GetPpapiPluginCaretBounds(gfx::Rect* rect); diff --git a/ppapi/host/dispatch_host_message.h b/ppapi/host/dispatch_host_message.h index 3e60e57..070b746 100644 --- a/ppapi/host/dispatch_host_message.h +++ b/ppapi/host/dispatch_host_message.h @@ -2,14 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ipc/ipc_message_macros.h" - // This file provides infrastructure for dispatching host resource call // messages. Normal IPC message handlers can't take extra parameters or // return values. We want to take a HostMessageContext as a parameter and // also return the int32_t return value to the caller. +#ifndef PPAPI_HOST_DISPATCH_HOST_MESSAGE_H_ +#define PPAPI_HOST_DISPATCH_HOST_MESSAGE_H_ + #include "base/profiler/scoped_profile.h" // For TRACK_RUN_IN_IPC_HANDLER. +#include "ipc/ipc_message_macros.h" #include "ppapi/c/pp_errors.h" namespace ppapi { @@ -76,3 +78,6 @@ inline int32_t DispatchResourceCall(ObjT* obj, Method method, } // namespace host } // namespace ppapi + +#endif // PPAPI_HOST_DISPATCH_HOST_MESSAGE_H_ + diff --git a/ppapi/host/host_message_context.h b/ppapi/host/host_message_context.h index 6e0b70a..a8ac526 100644 --- a/ppapi/host/host_message_context.h +++ b/ppapi/host/host_message_context.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef PPAPI_COMMON_HOST_MESSAGE_CONTEXT_H_ -#define PPAPI_COMMON_HOST_MESSAGE_CONTEXT_H_ +#ifndef PPAPI_HOST_HOST_MESSAGE_CONTEXT_H_ +#define PPAPI_HOST_HOST_MESSAGE_CONTEXT_H_ #include "ipc/ipc_message.h" #include "ppapi/host/ppapi_host_export.h" @@ -32,4 +32,4 @@ struct PPAPI_HOST_EXPORT HostMessageContext { } // namespace host } // namespace ppapi -#endif // PPAPI_COMMON_HOST_MESSAGE_CONTEXT_H_ +#endif // PPAPI_HOST_HOST_MESSAGE_CONTEXT_H_ diff --git a/ppapi/ppapi_proxy.gypi b/ppapi/ppapi_proxy.gypi index 41e1b1e..735b649 100644 --- a/ppapi/ppapi_proxy.gypi +++ b/ppapi/ppapi_proxy.gypi @@ -21,6 +21,7 @@ 'proxy/broker_dispatcher.cc', 'proxy/broker_dispatcher.h', + 'proxy/connection.h', 'proxy/dispatcher.cc', 'proxy/dispatcher.h', 'proxy/enter_proxy.h', diff --git a/ppapi/proxy/connection.h b/ppapi/proxy/connection.h new file mode 100644 index 0000000..5f99f06 --- /dev/null +++ b/ppapi/proxy/connection.h @@ -0,0 +1,34 @@ +// Copyright (c) 2012 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. + +#ifndef PPAPI_PROXY_CONNECTION_H_ +#define PPAPI_PROXY_CONNECTION_H_ + +namespace IPC { +class Sender; +} + +namespace ppapi { +namespace proxy { + +// This struct holds the channels that a resource uses to send message to the +// browser and renderer. +struct Connection { + Connection() : browser_sender(0), renderer_sender(0) { + } + Connection(IPC::Sender* browser, IPC::Sender* renderer) + : browser_sender(browser), + renderer_sender(renderer) { + } + + IPC::Sender* browser_sender; + IPC::Sender* renderer_sender; +}; + +} // namespace proxy +} // namespace ppapi + + +#endif // PPAPI_PROXY_CONNECTION_H_ + diff --git a/ppapi/proxy/dispatch_reply_message.h b/ppapi/proxy/dispatch_reply_message.h new file mode 100644 index 0000000..443c523 --- /dev/null +++ b/ppapi/proxy/dispatch_reply_message.h @@ -0,0 +1,80 @@ +// Copyright (c) 2012 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. + +// This file provides infrastructure for dispatching host resource reply +// messages. Normal IPC Reply handlers can't take extra parameters. +// We want to take a ResourceMessageReplyParams as a parameter. + +#ifndef PPAPI_PROXY_DISPATCH_REPLY_MESSAGE_H_ +#define PPAPI_PROXY_DISPATCH_REPLY_MESSAGE_H_ + +#include "base/profiler/scoped_profile.h" // For TRACK_RUN_IN_IPC_HANDLER. +#include "ipc/ipc_message_macros.h" +#include "ppapi/c/pp_errors.h" + +namespace ppapi { +namespace proxy { + +struct Context; +class ResourceMessageReplyParams; + +template <class ObjT, class Method> +inline void DispatchResourceReply(ObjT* obj, Method method, + const ResourceMessageReplyParams& params, + const Tuple0& arg) { + (obj->*method)(params); +} + +template <class ObjT, class Method, class A> +inline void DispatchResourceReply(ObjT* obj, Method method, + const ResourceMessageReplyParams& params, + const Tuple1<A>& arg) { + return (obj->*method)(params, arg.a); +} + +template<class ObjT, class Method, class A, class B> +inline int32_t DispatchResourceReply(ObjT* obj, Method method, + const ResourceMessageReplyParams& params, + const Tuple2<A, B>& arg) { + return (obj->*method)(params, arg.a, arg.b); +} + +template<class ObjT, class Method, class A, class B, class C> +inline void DispatchResourceReply(ObjT* obj, Method method, + const ResourceMessageReplyParams& params, + const Tuple3<A, B, C>& arg) { + return (obj->*method)(params, arg.a, arg.b, arg.c); +} + +template<class ObjT, class Method, class A, class B, class C, class D> +inline void DispatchResourceReply(ObjT* obj, Method method, + const ResourceMessageReplyParams& params, + const Tuple4<A, B, C, D>& arg) { + return (obj->*method)(params, arg.a, arg.b, arg.c, arg.d); +} + +template<class ObjT, class Method, class A, class B, class C, class D, class E> +inline void DispatchResourceReply(ObjT* obj, Method method, + const ResourceMessageReplyParams& params, + const Tuple5<A, B, C, D, E>& arg) { + return (obj->*method)(params, arg.a, arg.b, arg.c, arg.d, arg.e); +} + +#define PPAPI_DISPATCH_RESOURCE_REPLY(msg_class, member_func) \ + case msg_class::ID: { \ + TRACK_RUN_IN_IPC_HANDLER(member_func); \ + msg_class::Schema::Param p; \ + if (msg_class::Read(&ipc_message__, &p)) { \ + ppapi::proxy::DispatchResourceReply( \ + this, \ + &_IpcMessageHandlerClass::member_func, \ + params, p); \ + } \ + } \ + break; + +} // namespace proxy +} // namespace ppapi + +#endif // PPAPI_PROXY_DISPATCH_REPLY_MESSAGE_H_ diff --git a/ppapi/proxy/file_chooser_resource.cc b/ppapi/proxy/file_chooser_resource.cc index e368f73..87d1128 100644 --- a/ppapi/proxy/file_chooser_resource.cc +++ b/ppapi/proxy/file_chooser_resource.cc @@ -7,6 +7,7 @@ #include "base/string_split.h" #include "ipc/ipc_message.h" #include "ppapi/c/pp_errors.h" +#include "ppapi/proxy/dispatch_reply_message.h" #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/proxy/ppb_file_ref_proxy.h" #include "ppapi/shared_impl/var.h" @@ -14,11 +15,11 @@ namespace ppapi { namespace proxy { -FileChooserResource::FileChooserResource(IPC::Sender* sender, +FileChooserResource::FileChooserResource(Connection connection, PP_Instance instance, PP_FileChooserMode_Dev mode, const std::string& accept_types) - : PluginResource(sender, instance), + : PluginResource(connection, instance), mode_(mode) { PopulateAcceptTypes(accept_types, &accept_types_); } @@ -96,13 +97,18 @@ void FileChooserResource::PopulateAcceptTypes( } } -void FileChooserResource::OnReplyReceived(int /* sequence */, - int32_t result, - const IPC::Message& msg) { - PpapiPluginMsg_FileChooser_ShowReply::Schema::Param param; - PpapiPluginMsg_FileChooser_ShowReply::Read(&msg, ¶m); - const std::vector<ppapi::PPB_FileRef_CreateInfo>& chosen_files = param.a; +void FileChooserResource::OnReplyReceived( + const ResourceMessageReplyParams& params, + const IPC::Message& msg) { + IPC_BEGIN_MESSAGE_MAP(FileChooserResource, msg) + PPAPI_DISPATCH_RESOURCE_REPLY(PpapiPluginMsg_FileChooser_ShowReply, + OnPluginMsgShowReply) + IPC_END_MESSAGE_MAP() +} +void FileChooserResource::OnPluginMsgShowReply( + const ResourceMessageReplyParams& params, + const std::vector<PPB_FileRef_CreateInfo>& chosen_files) { if (output_.is_valid()) { // Using v0.6 of the API with the output array. std::vector<PP_Resource> files; @@ -120,7 +126,7 @@ void FileChooserResource::OnReplyReceived(int /* sequence */, } // Notify the plugin of the new data. - TrackedCallback::ClearAndRun(&callback_, result); + TrackedCallback::ClearAndRun(&callback_, params.result()); // DANGER: May delete |this|! } diff --git a/ppapi/proxy/file_chooser_resource.h b/ppapi/proxy/file_chooser_resource.h index adb20a4..ecf4e87 100644 --- a/ppapi/proxy/file_chooser_resource.h +++ b/ppapi/proxy/file_chooser_resource.h @@ -25,7 +25,7 @@ class PPAPI_PROXY_EXPORT FileChooserResource : public PluginResource, public NON_EXPORTED_BASE(thunk::PPB_FileChooser_API) { public: - FileChooserResource(IPC::Sender* sender, + FileChooserResource(Connection connection, PP_Instance instance, PP_FileChooserMode_Dev mode, const std::string& accept_types); @@ -55,12 +55,12 @@ class PPAPI_PROXY_EXPORT FileChooserResource private: // PluginResource override. - virtual void OnReplyReceived(int sequence, - int32_t result, + virtual void OnReplyReceived(const ResourceMessageReplyParams& params, const IPC::Message& msg) OVERRIDE; void OnPluginMsgShowReply( - const std::vector<ppapi::PPB_FileRef_CreateInfo>& chosen_files); + const ResourceMessageReplyParams& params, + const std::vector<PPB_FileRef_CreateInfo>& chosen_files); int32_t ShowInternal(PP_Bool save_as, const PP_Var& suggested_file_name, diff --git a/ppapi/proxy/plugin_dispatcher.cc b/ppapi/proxy/plugin_dispatcher.cc index 9314713..fc51785 100644 --- a/ppapi/proxy/plugin_dispatcher.cc +++ b/ppapi/proxy/plugin_dispatcher.cc @@ -284,8 +284,7 @@ void PluginDispatcher::OnMsgResourceReply( NOTREACHED(); return; } - resource->OnReplyReceived(reply_params.sequence(), reply_params.result(), - nested_msg); + resource->OnReplyReceived(reply_params, nested_msg); } void PluginDispatcher::OnMsgSupportsInterface( diff --git a/ppapi/proxy/plugin_proxy_delegate.h b/ppapi/proxy/plugin_proxy_delegate.h index 0ce2655..de0c397 100644 --- a/ppapi/proxy/plugin_proxy_delegate.h +++ b/ppapi/proxy/plugin_proxy_delegate.h @@ -7,6 +7,10 @@ #include <string> +namespace IPC { +class Sender; +} + namespace ppapi { namespace proxy { @@ -15,9 +19,13 @@ class PPAPI_PROXY_EXPORT PluginProxyDelegate { virtual ~PluginProxyDelegate() {} // Sends the given message to the browser. Identical semantics to IPC::Sender - // interface. + // interface. New code should use GetBrowserSender instead. + // TODO(brettw) remove this. virtual bool SendToBrowser(IPC::Message* msg) = 0; + // Returns the channel for sending to the browser. + virtual IPC::Sender* GetBrowserSender() = 0; + // Returns the language code of the current UI language. virtual std::string GetUILanguage() = 0; diff --git a/ppapi/proxy/plugin_resource.cc b/ppapi/proxy/plugin_resource.cc index 6e387bb..4464ca65 100644 --- a/ppapi/proxy/plugin_resource.cc +++ b/ppapi/proxy/plugin_resource.cc @@ -10,20 +10,32 @@ namespace ppapi { namespace proxy { -PluginResource::PluginResource(IPC::Sender* sender, PP_Instance instance) +PluginResource::PluginResource(Connection connection, PP_Instance instance) : Resource(OBJECT_IS_PROXY, instance), - sender_(sender), + connection_(connection), next_sequence_number_(0), + sent_create_to_browser_(false), sent_create_to_renderer_(false) { } PluginResource::~PluginResource() { - if (sent_create_to_renderer_) - Send(new PpapiHostMsg_ResourceDestroyed(pp_resource())); + if (sent_create_to_browser_) { + connection_.browser_sender->Send( + new PpapiHostMsg_ResourceDestroyed(pp_resource())); + } + if (sent_create_to_renderer_) { + connection_.renderer_sender->Send( + new PpapiHostMsg_ResourceDestroyed(pp_resource())); + } } -bool PluginResource::Send(IPC::Message* message) { - return sender_->Send(message); +void PluginResource::SendCreateToBrowser(const IPC::Message& msg) { + DCHECK(!sent_create_to_browser_); + sent_create_to_browser_ = true; + ResourceMessageCallParams params(pp_resource(), + next_sequence_number_++); + connection_.browser_sender->Send( + new PpapiHostMsg_ResourceCreated(params, pp_instance(), msg)); } void PluginResource::SendCreateToRenderer(const IPC::Message& msg) { @@ -31,20 +43,35 @@ void PluginResource::SendCreateToRenderer(const IPC::Message& msg) { sent_create_to_renderer_ = true; ResourceMessageCallParams params(pp_resource(), next_sequence_number_++); - Send(new PpapiHostMsg_ResourceCreated(params, pp_instance(), msg)); + connection_.renderer_sender->Send( + new PpapiHostMsg_ResourceCreated(params, pp_instance(), msg)); +} + +void PluginResource::PostToBrowser(const IPC::Message& msg) { + ResourceMessageCallParams params(pp_resource(), + next_sequence_number_++); + connection_.browser_sender->Send(new PpapiHostMsg_ResourceCall(params, msg)); } void PluginResource::PostToRenderer(const IPC::Message& msg) { ResourceMessageCallParams params(pp_resource(), next_sequence_number_++); - Send(new PpapiHostMsg_ResourceCall(params, msg)); + connection_.renderer_sender->Send(new PpapiHostMsg_ResourceCall(params, msg)); +} + +int32_t PluginResource::CallBrowser(const IPC::Message& msg) { + ResourceMessageCallParams params(pp_resource(), + next_sequence_number_++); + params.set_has_callback(); + connection_.browser_sender->Send(new PpapiHostMsg_ResourceCall(params, msg)); + return params.sequence(); } int32_t PluginResource::CallRenderer(const IPC::Message& msg) { ResourceMessageCallParams params(pp_resource(), next_sequence_number_++); params.set_has_callback(); - Send(new PpapiHostMsg_ResourceCall(params, msg)); + connection_.renderer_sender->Send(new PpapiHostMsg_ResourceCall(params, msg)); return params.sequence(); } diff --git a/ppapi/proxy/plugin_resource.h b/ppapi/proxy/plugin_resource.h index 28d1274..972908a 100644 --- a/ppapi/proxy/plugin_resource.h +++ b/ppapi/proxy/plugin_resource.h @@ -7,6 +7,7 @@ #include "base/compiler_specific.h" #include "ipc/ipc_sender.h" +#include "ppapi/proxy/connection.h" #include "ppapi/proxy/ppapi_proxy_export.h" #include "ppapi/shared_impl/resource.h" @@ -19,40 +20,43 @@ namespace proxy { class PluginDispatcher; -class PPAPI_PROXY_EXPORT PluginResource : public Resource, - public IPC::Sender { +class PPAPI_PROXY_EXPORT PluginResource : public Resource { public: - PluginResource(IPC::Sender* sender, - PP_Instance instance); + PluginResource(Connection connection, PP_Instance instance); virtual ~PluginResource(); - // IPC::Sender implementation. - virtual bool Send(IPC::Message* message) OVERRIDE; - + // Returns true if we've previously sent a create message to the browser + // or renderer. Generally resources will use these to tell if they should + // lazily send create messages. + bool sent_create_to_browser() const { return sent_create_to_browser_; } bool sent_create_to_renderer() const { return sent_create_to_renderer_; } protected: - // Sends a create message to the renderer for the current resource. + // Sends a create message to the browser or renderer for the current resource. + void SendCreateToBrowser(const IPC::Message& msg); void SendCreateToRenderer(const IPC::Message& msg); // Sends the given IPC message as a resource request to the host // corresponding to this resource object and does not expect a reply. + void PostToBrowser(const IPC::Message& msg); void PostToRenderer(const IPC::Message& msg); - // Like PostToRenderer but expects a response. + // Like PostToBrowser/Renderer but expects a response. // // Returns the new request's sequence number which can be used to identify // the callback. The host will reply and ppapi::Resource::OnReplyReceived // will be called. // // Note that all integers (including 0 and -1) are valid request IDs. + int32_t CallBrowser(const IPC::Message& msg); int32_t CallRenderer(const IPC::Message& msg); private: - IPC::Sender* sender_; + Connection connection_; int32_t next_sequence_number_; + bool sent_create_to_browser_; bool sent_create_to_renderer_; DISALLOW_COPY_AND_ASSIGN(PluginResource); diff --git a/ppapi/proxy/ppapi_proxy_test.cc b/ppapi/proxy/ppapi_proxy_test.cc index 9f0422e..eba0aed 100644 --- a/ppapi/proxy/ppapi_proxy_test.cc +++ b/ppapi/proxy/ppapi_proxy_test.cc @@ -229,6 +229,11 @@ bool PluginProxyTestHarness::PluginDelegateMock::SendToBrowser( return false; } +IPC::Sender* PluginProxyTestHarness::PluginDelegateMock::GetBrowserSender() { + NOTREACHED(); + return NULL; +} + std::string PluginProxyTestHarness::PluginDelegateMock::GetUILanguage() { return std::string("en-US"); } diff --git a/ppapi/proxy/ppapi_proxy_test.h b/ppapi/proxy/ppapi_proxy_test.h index 782b8c4..9c76b84 100644 --- a/ppapi/proxy/ppapi_proxy_test.h +++ b/ppapi/proxy/ppapi_proxy_test.h @@ -126,6 +126,7 @@ class PluginProxyTestHarness : public ProxyTestHarnessBase { // PluginPepperDelegate implementation. virtual bool SendToBrowser(IPC::Message* msg) OVERRIDE; + virtual IPC::Sender* GetBrowserSender() OVERRIDE; virtual std::string GetUILanguage() OVERRIDE; virtual void PreCacheFont(const void* logfontw) OVERRIDE; virtual void SetActiveURL(const std::string& url) OVERRIDE; diff --git a/ppapi/proxy/resource_creation_proxy.cc b/ppapi/proxy/resource_creation_proxy.cc index 25a02fd..7378311 100644 --- a/ppapi/proxy/resource_creation_proxy.cc +++ b/ppapi/proxy/resource_creation_proxy.cc @@ -7,8 +7,11 @@ #include "ppapi/c/pp_errors.h" #include "ppapi/c/pp_size.h" #include "ppapi/c/trusted/ppb_image_data_trusted.h" +#include "ppapi/proxy/connection.h" #include "ppapi/proxy/file_chooser_resource.h" #include "ppapi/proxy/plugin_dispatcher.h" +#include "ppapi/proxy/plugin_globals.h" +#include "ppapi/proxy/plugin_proxy_delegate.h" #include "ppapi/proxy/plugin_resource_tracker.h" #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/proxy/ppb_audio_input_proxy.h" @@ -271,7 +274,7 @@ PP_Resource ResourceCreationProxy::CreateFileChooser( PP_Instance instance, PP_FileChooserMode_Dev mode, const char* accept_types) { - return (new FileChooserResource(dispatcher(), instance, mode, + return (new FileChooserResource(GetConnection(), instance, mode, accept_types))->GetReference(); } @@ -367,5 +370,11 @@ bool ResourceCreationProxy::OnMessageReceived(const IPC::Message& msg) { return false; } +Connection ResourceCreationProxy::GetConnection() { + return Connection( + PluginGlobals::Get()->plugin_proxy_delegate()->GetBrowserSender(), + dispatcher()); +} + } // namespace proxy } // namespace ppapi diff --git a/ppapi/proxy/resource_creation_proxy.h b/ppapi/proxy/resource_creation_proxy.h index b0d80d3..261cd0e 100644 --- a/ppapi/proxy/resource_creation_proxy.h +++ b/ppapi/proxy/resource_creation_proxy.h @@ -23,6 +23,7 @@ class HostResource; namespace proxy { +struct Connection; class Dispatcher; class ResourceCreationProxy : public InterfaceProxy, @@ -162,6 +163,7 @@ class ResourceCreationProxy : public InterfaceProxy, virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE; private: + Connection GetConnection(); DISALLOW_COPY_AND_ASSIGN(ResourceCreationProxy); }; diff --git a/ppapi/shared_impl/resource.cc b/ppapi/shared_impl/resource.cc index c96bc21..6f095f7 100644 --- a/ppapi/shared_impl/resource.cc +++ b/ppapi/shared_impl/resource.cc @@ -56,8 +56,7 @@ void Resource::InstanceWasDeleted() { host_resource_ = HostResource(); } -void Resource::OnReplyReceived(int sequence, - int32_t result, +void Resource::OnReplyReceived(const proxy::ResourceMessageReplyParams& params, const IPC::Message& msg) { NOTREACHED(); } diff --git a/ppapi/shared_impl/resource.h b/ppapi/shared_impl/resource.h index efe40da..05dc783 100644 --- a/ppapi/shared_impl/resource.h +++ b/ppapi/shared_impl/resource.h @@ -71,6 +71,12 @@ class Message; namespace ppapi { +// Normally we shouldn't reply on proxy here, but this is to support +// OnReplyReceived. See that comment. +namespace proxy { +class ResourceMessageReplyParams; +} + // Forward declare all the resource APIs. namespace thunk { #define DECLARE_RESOURCE_CLASS(RESOURCE) class RESOURCE; @@ -166,10 +172,8 @@ class PPAPI_SHARED_EXPORT Resource : public base::RefCounted<Resource> { template <typename T> T* GetAs() { return NULL; } // Called when a PpapiPluginMsg_ResourceReply reply is received for a - // previous CallRenderer. The sequence number is the value returned the - // send function for the given request. The message is the nested reply - // message, which may be an empty message (depending on what the host - // sends). + // previous CallRenderer. The message is the nested reply message, which may + // be an empty message (depending on what the host sends). // // The default implementation will assert (if you send a request, you should // override this function). @@ -177,8 +181,7 @@ class PPAPI_SHARED_EXPORT Resource : public base::RefCounted<Resource> { // (This function would make more conceptual sense on PluginResource but we // need to call this function from general code that doesn't know how to // distinguish the classes.) - virtual void OnReplyReceived(int sequence, - int32_t result, + virtual void OnReplyReceived(const proxy::ResourceMessageReplyParams& params, const IPC::Message& msg); protected: diff --git a/webkit/plugins/ppapi/plugin_module.cc b/webkit/plugins/ppapi/plugin_module.cc index accc029..3da896e 100644 --- a/webkit/plugins/ppapi/plugin_module.cc +++ b/webkit/plugins/ppapi/plugin_module.cc @@ -460,6 +460,14 @@ PluginModule::~PluginModule() { // previous parts of the destructor. } +void PluginModule::SetEmbedderState(scoped_ptr<EmbedderState> state) { + embedder_state_ = state.Pass(); +} + +PluginModule::EmbedderState* PluginModule::GetEmbedderState() { + return embedder_state_.get(); +} + bool PluginModule::InitAsInternalPlugin(const EntryPoints& entry_points) { if (InitializeModule(entry_points)) { entry_points_ = entry_points; diff --git a/webkit/plugins/ppapi/plugin_module.h b/webkit/plugins/ppapi/plugin_module.h index 827546f..7301723 100644 --- a/webkit/plugins/ppapi/plugin_module.h +++ b/webkit/plugins/ppapi/plugin_module.h @@ -61,6 +61,14 @@ class WEBKIT_PLUGINS_EXPORT PluginModule : PPP_ShutdownModuleFunc shutdown_module; // Optional, may be NULL. }; + // Allows the embedder to associate a class with this module. This is opaque + // from the PluginModule's perspective (see Set/GetEmbedderState below) but + // the module is in charge of deleting the class. + class EmbedderState { + public: + virtual ~EmbedderState() {} + }; + typedef std::set<PluginInstance*> PluginInstanceSet; // You must call one of the Init functions after the constructor to create a @@ -76,6 +84,14 @@ class WEBKIT_PLUGINS_EXPORT PluginModule : ~PluginModule(); + // Sets the given class as being associated with this module. It will be + // deleted when the module is destroyed. You can only set it once, subsequent + // sets will assert. + // + // See EmbedderState above for more. + void SetEmbedderState(scoped_ptr<EmbedderState> state); + EmbedderState* GetEmbedderState(); + // Initializes this module as an internal plugin with the given entrypoints. // This is used for "plugins" compiled into Chrome. Returns true on success. // False means that the plugin can not be used. @@ -163,6 +179,9 @@ class WEBKIT_PLUGINS_EXPORT PluginModule : // Note: This may be null. PluginDelegate::ModuleLifetime* lifetime_delegate_; + // See EmbedderState above. + scoped_ptr<EmbedderState> embedder_state_; + // Tracker for completion callbacks, used mainly to ensure that all callbacks // are properly aborted on module shutdown. scoped_refptr< ::ppapi::CallbackTracker> callback_tracker_; |