diff options
40 files changed, 609 insertions, 99 deletions
diff --git a/chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.cc b/chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.cc index 211fd28..d1fb2af 100644 --- a/chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.cc +++ b/chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.cc @@ -4,6 +4,7 @@ #include "chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h" +#include "chrome/browser/renderer_host/pepper/pepper_broker_host.h" #include "chrome/browser/renderer_host/pepper/pepper_flash_device_id_host.h" #include "chrome/browser/renderer_host/pepper/pepper_talk_host.h" #include "content/public/browser/browser_ppapi_host.h" @@ -39,6 +40,9 @@ scoped_ptr<ResourceHost> ChromeBrowserPepperHostFactory::CreateResourceHost( if (host_->GetPpapiHost()->permissions().HasPermission( ppapi::PERMISSION_PRIVATE)) { switch (message.type()) { + case PpapiHostMsg_Broker_Create::ID: + return scoped_ptr<ResourceHost>(new PepperBrokerHost( + host_, instance, params.pp_resource())); case PpapiHostMsg_FlashDeviceID_Create::ID: return scoped_ptr<ResourceHost>(new PepperFlashDeviceIDHost( host_, instance, params.pp_resource())); diff --git a/chrome/browser/renderer_host/pepper/pepper_broker_host.cc b/chrome/browser/renderer_host/pepper/pepper_broker_host.cc new file mode 100644 index 0000000..02bb08a --- /dev/null +++ b/chrome/browser/renderer_host/pepper/pepper_broker_host.cc @@ -0,0 +1,118 @@ +// 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 "chrome/browser/renderer_host/pepper/pepper_broker_host.h" + +#include <string> + +#include "chrome/browser/content_settings/host_content_settings_map.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/common/content_settings.h" +#include "content/public/browser/browser_ppapi_host.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/render_process_host.h" +#include "googleurl/src/gurl.h" +#include "ipc/ipc_message_macros.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/host/dispatch_host_message.h" +#include "ppapi/host/resource_message_filter.h" +#include "ppapi/proxy/ppapi_messages.h" + +using content::BrowserPpapiHost; +using content::BrowserThread; +using content::RenderProcessHost; + +namespace chrome { + +namespace { + +// This filter handles messages for the PepperBrokerHost on the UI thread. +class BrokerMessageFilter : public ppapi::host::ResourceMessageFilter { + public: + BrokerMessageFilter(int render_process_id, GURL document_url); + + protected: + // ppapi::host::ResourceMessageFilter override. + virtual scoped_refptr<base::TaskRunner> OverrideTaskRunnerForMessage( + const IPC::Message& message) OVERRIDE; + + // ppapi::host::ResourceMessageHandler override. + virtual int32_t OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) OVERRIDE; + + private: + virtual ~BrokerMessageFilter(); + + int32_t OnIsAllowed(ppapi::host::HostMessageContext* context); + + int render_process_id_; + GURL document_url_; +}; + +BrokerMessageFilter::BrokerMessageFilter( + int render_process_id, + GURL document_url) + : render_process_id_(render_process_id), + document_url_(document_url) { +} + +BrokerMessageFilter::~BrokerMessageFilter() { +} + +scoped_refptr<base::TaskRunner> +BrokerMessageFilter::OverrideTaskRunnerForMessage( + const IPC::Message& message) { + return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI); +} + +int32_t BrokerMessageFilter::OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) { + IPC_BEGIN_MESSAGE_MAP(BrokerMessageFilter, msg) + PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_Broker_IsAllowed, + OnIsAllowed) + IPC_END_MESSAGE_MAP() + return PP_ERROR_FAILED; +} + +int32_t BrokerMessageFilter::OnIsAllowed( + ppapi::host::HostMessageContext* context) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + if (!document_url_.is_valid()) + return PP_ERROR_FAILED; + RenderProcessHost* render_process_host = + RenderProcessHost::FromID(render_process_id_); + if (!render_process_host) + return PP_ERROR_FAILED; + Profile* profile = + Profile::FromBrowserContext(render_process_host->GetBrowserContext()); + HostContentSettingsMap* content_settings = + profile->GetHostContentSettingsMap(); + ContentSetting setting = + content_settings->GetContentSetting(document_url_, document_url_, + CONTENT_SETTINGS_TYPE_PPAPI_BROKER, + std::string()); + if (setting == CONTENT_SETTING_ALLOW) + return PP_OK; + return PP_ERROR_FAILED; +} + +} // namespace + +PepperBrokerHost::PepperBrokerHost(BrowserPpapiHost* host, + PP_Instance instance, + PP_Resource resource) + : ResourceHost(host->GetPpapiHost(), instance, resource) { + int render_process_id, unused; + host->GetRenderViewIDsForInstance(instance, &render_process_id, &unused); + const GURL& document_url = host->GetDocumentURLForInstance(instance); + AddFilter(make_scoped_refptr(new BrokerMessageFilter(render_process_id, + document_url))); +} + +PepperBrokerHost::~PepperBrokerHost() { +} + +} // namespace chrome diff --git a/chrome/browser/renderer_host/pepper/pepper_broker_host.h b/chrome/browser/renderer_host/pepper/pepper_broker_host.h new file mode 100644 index 0000000..1209701 --- /dev/null +++ b/chrome/browser/renderer_host/pepper/pepper_broker_host.h @@ -0,0 +1,29 @@ +// 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 CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_BROKER_HOST_H_ +#define CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_BROKER_HOST_H_ + +#include "ppapi/host/resource_host.h" + +namespace content { +class BrowserPpapiHost; +} + +namespace chrome { + +class PepperBrokerHost : public ppapi::host::ResourceHost { + public: + PepperBrokerHost(content::BrowserPpapiHost* host, + PP_Instance instance, + PP_Resource resource); + virtual ~PepperBrokerHost(); + + private: + DISALLOW_COPY_AND_ASSIGN(PepperBrokerHost); +}; + +} // namespace chrome + +#endif // CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_BROKER_HOST_H_ diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 4fa3125..a9606aa 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -1663,6 +1663,8 @@ 'browser/renderer_host/offline_resource_throttle.h', 'browser/renderer_host/pepper/chrome_browser_pepper_host_factory.cc', 'browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h', + 'browser/renderer_host/pepper/pepper_broker_host.cc', + 'browser/renderer_host/pepper/pepper_broker_host.h', 'browser/renderer_host/pepper/pepper_flash_device_id_host.cc', 'browser/renderer_host/pepper/pepper_flash_device_id_host.h', 'browser/renderer_host/pepper/pepper_talk_host.cc', diff --git a/chrome/test/ppapi/ppapi_browsertest.cc b/chrome/test/ppapi/ppapi_browsertest.cc index 964d0e7..edcc086 100644 --- a/chrome/test/ppapi/ppapi_browsertest.cc +++ b/chrome/test/ppapi/ppapi_browsertest.cc @@ -143,10 +143,14 @@ IN_PROC_BROWSER_TEST_F(PPAPIBrokerInfoBarTest, Accept) { InfoBarObserver observer; observer.ExpectInfoBarAndAccept(true); - GURL url = GetTestFileUrl("Broker_ConnectPermissionGranted"); - RunTestURL(url); + // PPB_Broker_Trusted::IsAllowed should return false before the infobar is + // popped and true after the infobar is popped. + RunTest("Broker_IsAllowedPermissionDenied"); + RunTest("Broker_ConnectPermissionGranted"); + RunTest("Broker_IsAllowedPermissionGranted"); // It should also set a content settings exception for the site. + GURL url = GetTestFileUrl("Broker_ConnectPermissionGranted"); HostContentSettingsMap* content_settings = browser()->profile()->GetHostContentSettingsMap(); EXPECT_EQ(CONTENT_SETTING_ALLOW, @@ -159,10 +163,14 @@ IN_PROC_BROWSER_TEST_F(PPAPIBrokerInfoBarTest, Deny) { InfoBarObserver observer; observer.ExpectInfoBarAndAccept(false); - GURL url = GetTestFileUrl("Broker_ConnectPermissionDenied"); - RunTestURL(url); + // PPB_Broker_Trusted::IsAllowed should return false before and after the + // infobar is popped. + RunTest("Broker_IsAllowedPermissionDenied"); + RunTest("Broker_ConnectPermissionDenied"); + RunTest("Broker_IsAllowedPermissionDenied"); // It should also set a content settings exception for the site. + GURL url = GetTestFileUrl("Broker_ConnectPermissionDenied"); HostContentSettingsMap* content_settings = browser()->profile()->GetHostContentSettingsMap(); EXPECT_EQ(CONTENT_SETTING_BLOCK, @@ -179,6 +187,7 @@ IN_PROC_BROWSER_TEST_F(PPAPIBrokerInfoBarTest, Blocked) { InfoBarObserver observer; RunTest("Broker_ConnectPermissionDenied"); + RunTest("Broker_IsAllowedPermissionDenied"); } IN_PROC_BROWSER_TEST_F(PPAPIBrokerInfoBarTest, Allowed) { @@ -190,6 +199,7 @@ IN_PROC_BROWSER_TEST_F(PPAPIBrokerInfoBarTest, Allowed) { InfoBarObserver observer; RunTest("Broker_ConnectPermissionGranted"); + RunTest("Broker_IsAllowedPermissionGranted"); } TEST_PPAPI_IN_PROCESS(Core) diff --git a/chrome/test/ppapi/ppapi_test.h b/chrome/test/ppapi/ppapi_test.h index 24a0fbf..0afb371 100644 --- a/chrome/test/ppapi/ppapi_test.h +++ b/chrome/test/ppapi/ppapi_test.h @@ -139,7 +139,7 @@ class PPAPINaClTestDisallowedSockets : public PPAPITestBase { const std::string& test_case) OVERRIDE; }; -class PPAPIBrokerInfoBarTest : public PPAPITest { +class PPAPIBrokerInfoBarTest : public OutOfProcessPPAPITest { public: // PPAPITestBase override: virtual void SetUpOnMainThread() OVERRIDE; diff --git a/content/browser/ppapi_plugin_process_host.cc b/content/browser/ppapi_plugin_process_host.cc index db9f23d..1d7b5b5 100644 --- a/content/browser/ppapi_plugin_process_host.cc +++ b/content/browser/ppapi_plugin_process_host.cc @@ -101,14 +101,12 @@ PpapiPluginProcessHost* PpapiPluginProcessHost::CreateBrokerHost( void PpapiPluginProcessHost::DidCreateOutOfProcessInstance( int plugin_process_id, int32 pp_instance, - int render_process_id, - int render_view_id) { + const PepperRendererInstanceData& instance_data) { for (PpapiPluginProcessHostIterator iter; !iter.Done(); ++iter) { if (iter->process_.get() && iter->process_->GetData().id == plugin_process_id) { // Found the plugin. - iter->host_impl_->AddInstanceForView(pp_instance, - render_process_id, render_view_id); + iter->host_impl_->AddInstance(pp_instance, instance_data); return; } } @@ -130,7 +128,7 @@ void PpapiPluginProcessHost::DidDeleteOutOfProcessInstance( if (iter->process_.get() && iter->process_->GetData().id == plugin_process_id) { // Found the plugin. - iter->host_impl_->DeleteInstanceForView(pp_instance); + iter->host_impl_->DeleteInstance(pp_instance); return; } } diff --git a/content/browser/ppapi_plugin_process_host.h b/content/browser/ppapi_plugin_process_host.h index 9dc3481..6b50856 100644 --- a/content/browser/ppapi_plugin_process_host.h +++ b/content/browser/ppapi_plugin_process_host.h @@ -78,14 +78,15 @@ class PpapiPluginProcessHost : public BrowserChildProcessHostDelegate, static PpapiPluginProcessHost* CreateBrokerHost( const PepperPluginInfo& info); - // Notification that a PP_Instance has been created for the given - // RenderView/Process pair for the given plugin. This is necessary so that - // when the plugin calls us with a PP_Instance we can find the RenderView - // associated with it without trusting the plugin. - static void DidCreateOutOfProcessInstance(int plugin_process_id, - int32 pp_instance, - int render_process_id, - int render_view_id); + // Notification that a PP_Instance has been created and the associated + // renderer related data including the RenderView/Process pair for the given + // plugin. This is necessary so that when the plugin calls us with a + // PP_Instance we can find the RenderView associated with it without trusting + // the plugin. + static void DidCreateOutOfProcessInstance( + int plugin_process_id, + int32 pp_instance, + const PepperRendererInstanceData& instance_data); // The opposite of DIdCreate... above. static void DidDeleteOutOfProcessInstance(int plugin_process_id, diff --git a/content/browser/renderer_host/pepper/browser_ppapi_host_impl.cc b/content/browser/renderer_host/pepper/browser_ppapi_host_impl.cc index 2b79f3b..d039c70 100644 --- a/content/browser/renderer_host/pepper/browser_ppapi_host_impl.cc +++ b/content/browser/renderer_host/pepper/browser_ppapi_host_impl.cc @@ -6,6 +6,7 @@ #include "content/browser/renderer_host/pepper/pepper_message_filter.h" #include "content/browser/trace_message_filter.h" +#include "content/common/pepper_renderer_instance_data.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/render_view_host.h" #include "ipc/ipc_message_macros.h" @@ -73,22 +74,22 @@ base::ProcessHandle BrowserPpapiHostImpl::GetPluginProcessHandle() const { } bool BrowserPpapiHostImpl::IsValidInstance(PP_Instance instance) const { - return instance_to_view_.find(instance) != instance_to_view_.end(); + return instance_map_.find(instance) != instance_map_.end(); } bool BrowserPpapiHostImpl::GetRenderViewIDsForInstance( PP_Instance instance, int* render_process_id, int* render_view_id) const { - InstanceToViewMap::const_iterator found = instance_to_view_.find(instance); - if (found == instance_to_view_.end()) { + InstanceMap::const_iterator found = instance_map_.find(instance); + if (found == instance_map_.end()) { *render_process_id = 0; *render_view_id = 0; return false; } - *render_process_id = found->second.process_id; - *render_view_id = found->second.view_id; + *render_process_id = found->second.render_process_id; + *render_view_id = found->second.render_view_id; return true; } @@ -100,24 +101,34 @@ const FilePath& BrowserPpapiHostImpl::GetProfileDataDirectory() { return profile_data_directory_; } -void BrowserPpapiHostImpl::AddInstanceForView(PP_Instance instance, - int render_process_id, - int render_view_id) { - DCHECK(instance_to_view_.find(instance) == instance_to_view_.end()); +GURL BrowserPpapiHostImpl::GetDocumentURLForInstance(PP_Instance instance) { + InstanceMap::const_iterator found = instance_map_.find(instance); + if (found == instance_map_.end()) + return GURL(); + return found->second.document_url; +} + +GURL BrowserPpapiHostImpl::GetPluginURLForInstance(PP_Instance instance) { + InstanceMap::const_iterator found = instance_map_.find(instance); + if (found == instance_map_.end()) + return GURL(); + return found->second.plugin_url; +} - RenderViewIDs ids; - ids.process_id = render_process_id; - ids.view_id = render_view_id; - instance_to_view_[instance] = ids; +void BrowserPpapiHostImpl::AddInstance( + PP_Instance instance, + const PepperRendererInstanceData& instance_data) { + DCHECK(instance_map_.find(instance) == instance_map_.end()); + instance_map_[instance] = instance_data; } -void BrowserPpapiHostImpl::DeleteInstanceForView(PP_Instance instance) { - InstanceToViewMap::iterator found = instance_to_view_.find(instance); - if (found == instance_to_view_.end()) { +void BrowserPpapiHostImpl::DeleteInstance(PP_Instance instance) { + InstanceMap::iterator found = instance_map_.find(instance); + if (found == instance_map_.end()) { NOTREACHED(); return; } - instance_to_view_.erase(found); + instance_map_.erase(found); } bool BrowserPpapiHostImpl::HostMessageFilter::OnMessageReceived( diff --git a/content/browser/renderer_host/pepper/browser_ppapi_host_impl.h b/content/browser/renderer_host/pepper/browser_ppapi_host_impl.h index 888bb7c..ce3560e 100644 --- a/content/browser/renderer_host/pepper/browser_ppapi_host_impl.h +++ b/content/browser/renderer_host/pepper/browser_ppapi_host_impl.h @@ -19,6 +19,8 @@ namespace content { +struct PepperRendererInstanceData; + class CONTENT_EXPORT BrowserPpapiHostImpl : public BrowserPpapiHost { public: // The creator is responsible for calling set_plugin_process_handle as soon @@ -39,18 +41,19 @@ class CONTENT_EXPORT BrowserPpapiHostImpl : public BrowserPpapiHost { int* render_view_id) const OVERRIDE; virtual const std::string& GetPluginName() OVERRIDE; virtual const FilePath& GetProfileDataDirectory() OVERRIDE; + virtual GURL GetDocumentURLForInstance(PP_Instance instance) OVERRIDE; + virtual GURL GetPluginURLForInstance(PP_Instance instance) OVERRIDE; void set_plugin_process_handle(base::ProcessHandle handle) { plugin_process_handle_ = handle; } // These two functions are notifications that an instance has been created - // or destroyed. They allow us to maintain a mapping of PP_Instance to view - // IDs in the browser process. - void AddInstanceForView(PP_Instance instance, - int render_process_id, - int render_view_id); - void DeleteInstanceForView(PP_Instance instance); + // or destroyed. They allow us to maintain a mapping of PP_Instance to data + // associated with the instance including view IDs in the browser process. + void AddInstance(PP_Instance instance, + const PepperRendererInstanceData& instance_data); + void DeleteInstance(PP_Instance instance); scoped_refptr<IPC::ChannelProxy::MessageFilter> message_filter() { return message_filter_; @@ -59,12 +62,6 @@ class CONTENT_EXPORT BrowserPpapiHostImpl : public BrowserPpapiHost { private: friend class BrowserPpapiHostTest; - struct RenderViewIDs { - int process_id; - int view_id; - }; - typedef std::map<PP_Instance, RenderViewIDs> InstanceToViewMap; - // Implementing MessageFilter on BrowserPpapiHostImpl makes it ref-counted, // preventing us from returning these to embedders without holding a // reference. To avoid that, define a message filter object. @@ -88,9 +85,10 @@ class CONTENT_EXPORT BrowserPpapiHostImpl : public BrowserPpapiHost { std::string plugin_name_; FilePath profile_data_directory_; - // Tracks all PP_Instances in this plugin and maps them to - // RenderProcess/RenderView IDs. - InstanceToViewMap instance_to_view_; + // Tracks all PP_Instances in this plugin and associated renderer-related + // data. + typedef std::map<PP_Instance, PepperRendererInstanceData> InstanceMap; + InstanceMap instance_map_; scoped_refptr<HostMessageFilter> message_filter_; diff --git a/content/browser/renderer_host/render_message_filter.cc b/content/browser/renderer_host/render_message_filter.cc index 9bcd74e..0823310 100644 --- a/content/browser/renderer_host/render_message_filter.cc +++ b/content/browser/renderer_host/render_message_filter.cc @@ -711,7 +711,7 @@ void RenderMessageFilter::OnOpenChannelToPepperPlugin( void RenderMessageFilter::OnDidCreateOutOfProcessPepperInstance( int plugin_child_id, int32 pp_instance, - int render_view_id, + PepperRendererInstanceData instance_data, bool is_external) { // It's important that we supply the render process ID ourselves based on the // channel the message arrived on. We use the @@ -719,16 +719,18 @@ void RenderMessageFilter::OnDidCreateOutOfProcessPepperInstance( // mapping to decide how to handle messages received from the (untrusted) // plugin, so an exploited renderer must not be able to insert fake mappings // that may allow it access to other render processes. + DCHECK(instance_data.render_process_id == 0); + instance_data.render_process_id = render_process_id_; if (is_external) { // We provide the BrowserPpapiHost to the embedder, so it's safe to cast. BrowserPpapiHostImpl* host = static_cast<BrowserPpapiHostImpl*>( GetContentClient()->browser()->GetExternalBrowserPpapiHost( plugin_child_id)); if (host) - host->AddInstanceForView(pp_instance, render_process_id_, render_view_id); + host->AddInstance(pp_instance, instance_data); } else { PpapiPluginProcessHost::DidCreateOutOfProcessInstance( - plugin_child_id, pp_instance, render_process_id_, render_view_id); + plugin_child_id, pp_instance, instance_data); } } @@ -742,7 +744,7 @@ void RenderMessageFilter::OnDidDeleteOutOfProcessPepperInstance( GetContentClient()->browser()->GetExternalBrowserPpapiHost( plugin_child_id)); if (host) - host->DeleteInstanceForView(pp_instance); + host->DeleteInstance(pp_instance); } else { PpapiPluginProcessHost::DidDeleteOutOfProcessInstance( plugin_child_id, pp_instance); diff --git a/content/browser/renderer_host/render_message_filter.h b/content/browser/renderer_host/render_message_filter.h index 2494aa1..fdc933f 100644 --- a/content/browser/renderer_host/render_message_filter.h +++ b/content/browser/renderer_host/render_message_filter.h @@ -19,6 +19,7 @@ #include "base/shared_memory.h" #include "base/string16.h" #include "build/build_config.h" +#include "content/common/pepper_renderer_instance_data.h" #include "content/public/browser/browser_message_filter.h" #include "content/public/common/three_d_api_types.h" #include "media/base/channel_layout.h" @@ -167,10 +168,11 @@ class RenderMessageFilter : public BrowserMessageFilter { IPC::Message* reply_msg); void OnOpenChannelToPepperPlugin(const FilePath& path, IPC::Message* reply_msg); - void OnDidCreateOutOfProcessPepperInstance(int plugin_child_id, - int32 pp_instance, - int render_view_id, - bool is_external); + void OnDidCreateOutOfProcessPepperInstance( + int plugin_child_id, + int32 pp_instance, + PepperRendererInstanceData instance_data, + bool is_external); void OnDidDeleteOutOfProcessPepperInstance(int plugin_child_id, int32 pp_instance, bool is_external); diff --git a/content/common/pepper_renderer_instance_data.cc b/content/common/pepper_renderer_instance_data.cc new file mode 100644 index 0000000..73b67a7 --- /dev/null +++ b/content/common/pepper_renderer_instance_data.cc @@ -0,0 +1,28 @@ +// 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/common/pepper_renderer_instance_data.h" + +namespace content { + +PepperRendererInstanceData::PepperRendererInstanceData() + : render_process_id(0), + render_view_id(0) { +} + +PepperRendererInstanceData::PepperRendererInstanceData( + int render_process, + int render_view, + const GURL& document, + const GURL& plugin) + : render_process_id(render_process), + render_view_id(render_view), + document_url(document), + plugin_url(plugin) { +} + +PepperRendererInstanceData::~PepperRendererInstanceData() { +} + +} // namespace content diff --git a/content/common/pepper_renderer_instance_data.h b/content/common/pepper_renderer_instance_data.h new file mode 100644 index 0000000..b912792 --- /dev/null +++ b/content/common/pepper_renderer_instance_data.h @@ -0,0 +1,31 @@ +// 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_COMMON_PEPPER_RENDERER_INSTANCE_DATA_H_ +#define CONTENT_COMMON_PEPPER_RENDERER_INSTANCE_DATA_H_ + +#include "googleurl/src/gurl.h" + +namespace content { + +// This struct contains data which is associated with a particular plugin +// instance and is related to the renderer in which the plugin instance lives. +// This data is transferred to the browser process from the renderer when the +// instance is created and is stored in the BrowserPpapiHost. +struct PepperRendererInstanceData { + PepperRendererInstanceData(); + PepperRendererInstanceData(int render_process, + int render_view, + const GURL& document, + const GURL& plugin); + ~PepperRendererInstanceData(); + int render_process_id; + int render_view_id; + GURL document_url; + GURL plugin_url; +}; + +} // namespace content + +#endif // CONTENT_COMMON_PEPPER_RENDERER_INSTANCE_DATA_H_ diff --git a/content/common/view_messages.h b/content/common/view_messages.h index 2727d49..5956f0d 100644 --- a/content/common/view_messages.h +++ b/content/common/view_messages.h @@ -12,6 +12,7 @@ #include "content/common/content_param_traits.h" #include "content/common/edit_command.h" #include "content/common/navigation_gesture.h" +#include "content/common/pepper_renderer_instance_data.h" #include "content/common/view_message_enums.h" #include "content/port/common/input_event_ack_state.h" #include "content/public/common/common_param_traits.h" @@ -327,6 +328,13 @@ IPC_STRUCT_TRAITS_BEGIN(content::FrameNavigateParams) IPC_STRUCT_TRAITS_MEMBER(socket_address) IPC_STRUCT_TRAITS_END() +IPC_STRUCT_TRAITS_BEGIN(content::PepperRendererInstanceData) + IPC_STRUCT_TRAITS_MEMBER(render_process_id) + IPC_STRUCT_TRAITS_MEMBER(render_view_id) + IPC_STRUCT_TRAITS_MEMBER(document_url) + IPC_STRUCT_TRAITS_MEMBER(plugin_url) +IPC_STRUCT_TRAITS_END() + IPC_STRUCT_TRAITS_BEGIN(content::RendererPreferences) IPC_STRUCT_TRAITS_MEMBER(can_accept_load_drops) IPC_STRUCT_TRAITS_MEMBER(should_antialias_text) @@ -1953,21 +1961,25 @@ IPC_SYNC_MESSAGE_CONTROL1_2(ViewHostMsg_OpenChannelToPepperPlugin, int /* plugin_child_id */) // Notification that a plugin has created a new plugin instance. The parameters -// indicate the plugin process ID that we're creating the instance for, and the -// routing ID of the render view that the plugin instance is associated with. -// This allows us to create a mapping in the browser process for what objects a -// given PP_Instance is associated with. +// indicate: +// -The plugin process ID that we're creating the instance for. +// -The instance ID of the instance being created. +// -A PepperRendererInstanceData struct which contains properties from the +// renderer which are associated with the plugin instance. This includes the +// routing ID of the associated render view and the URL of plugin. +// -Whether the plugin we're creating an instance for is external or internal. // // This message must be sync even though it returns no parameters to avoid // a race condition with the plugin process. The plugin process sends messages // to the browser that assume the browser knows about the instance. We need to // make sure that the browser actually knows about the instance before we tell // the plugin to run. -IPC_SYNC_MESSAGE_CONTROL4_0(ViewHostMsg_DidCreateOutOfProcessPepperInstance, - int /* plugin_child_id */, - int32 /* pp_instance */, - int /* view_routing_id */, - bool /* is_external */) +IPC_SYNC_MESSAGE_CONTROL4_0( + ViewHostMsg_DidCreateOutOfProcessPepperInstance, + int /* plugin_child_id */, + int32 /* pp_instance */, + content::PepperRendererInstanceData /* creation_data */, + bool /* is_external */) // Notification that a plugin has destroyed an instance. This is the opposite of // the "DidCreate" message above. diff --git a/content/content_common.gypi b/content/content_common.gypi index 3f74f0b..64fc871 100644 --- a/content/content_common.gypi +++ b/content/content_common.gypi @@ -321,6 +321,8 @@ 'common/pepper_messages.h', 'common/pepper_plugin_registry.cc', 'common/pepper_plugin_registry.h', + 'common/pepper_renderer_instance_data.cc', + 'common/pepper_renderer_instance_data.h', 'common/plugin_carbon_interpose_constants_mac.cc', 'common/plugin_carbon_interpose_constants_mac.h', 'common/plugin_messages.h', diff --git a/content/public/browser/browser_ppapi_host.h b/content/public/browser/browser_ppapi_host.h index f5aa11c..08c5f07 100644 --- a/content/public/browser/browser_ppapi_host.h +++ b/content/public/browser/browser_ppapi_host.h @@ -10,6 +10,7 @@ #include "content/common/content_export.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/render_view_host.h" +#include "googleurl/src/gurl.h" #include "ppapi/c/pp_instance.h" namespace IPC { @@ -72,11 +73,16 @@ class CONTENT_EXPORT BrowserPpapiHost { virtual bool GetRenderViewIDsForInstance(PP_Instance instance, int* render_process_id, int* render_view_id) const = 0; + // Returns the name of the plugin. virtual const std::string& GetPluginName() = 0; // Returns the user's profile data directory. virtual const FilePath& GetProfileDataDirectory() = 0; + + // Get the Document/Plugin URLs for the given PP_Instance. + virtual GURL GetDocumentURLForInstance(PP_Instance instance) = 0; + virtual GURL GetPluginURLForInstance(PP_Instance instance) = 0; }; } // namespace content diff --git a/content/renderer/pepper/pepper_plugin_delegate_impl.cc b/content/renderer/pepper/pepper_plugin_delegate_impl.cc index eba8ee3..8bb4767 100644 --- a/content/renderer/pepper/pepper_plugin_delegate_impl.cc +++ b/content/renderer/pepper/pepper_plugin_delegate_impl.cc @@ -73,6 +73,7 @@ #include "ppapi/thunk/ppb_tcp_server_socket_private_api.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebCursorInfo.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginContainer.h" @@ -161,10 +162,16 @@ class HostDispatcherWrapper // isn't true for browser tag support. if (host) { RenderView* render_view = host->GetRenderViewForInstance(instance); + webkit::ppapi::PluginInstance* plugin_instance = + host->GetPluginInstance(instance); render_view->Send(new ViewHostMsg_DidCreateOutOfProcessPepperInstance( plugin_child_id_, instance, - render_view->GetRoutingID(), + PepperRendererInstanceData( + 0, // The render process id will be supplied in the browser. + render_view->GetRoutingID(), + plugin_instance->container()->element().document().url(), + plugin_instance->plugin_url()), is_external_)); } } diff --git a/ppapi/api/trusted/ppb_broker_trusted.idl b/ppapi/api/trusted/ppb_broker_trusted.idl index 54039c4..023d9fc 100644 --- a/ppapi/api/trusted/ppb_broker_trusted.idl +++ b/ppapi/api/trusted/ppb_broker_trusted.idl @@ -9,7 +9,8 @@ */ label Chrome { - M14 = 0.2 + M14 = 0.2, + M25 = 0.3 }; /** @@ -61,5 +62,16 @@ interface PPB_BrokerTrusted { * before connect has completed will return PP_ERROR_FAILED. */ int32_t GetHandle([in] PP_Resource broker, [out] int32_t handle); + + /** + * Returns PP_TRUE if the plugin has permission to launch the broker. A user + * must explicitly grant permission to launch the broker for a particular + * website. This is done through an infobar that is displayed when |Connect| + * is called. This function returns PP_TRUE if the user has already granted + * permission to launch the broker for the website containing this plugin + * instance. Returns PP_FALSE otherwise. + */ + [version=0.3] + PP_Bool IsAllowed([in] PP_Resource broker); }; diff --git a/ppapi/c/trusted/ppb_broker_trusted.h b/ppapi/c/trusted/ppb_broker_trusted.h index 44b6118..019e2e9 100644 --- a/ppapi/c/trusted/ppb_broker_trusted.h +++ b/ppapi/c/trusted/ppb_broker_trusted.h @@ -3,7 +3,7 @@ * found in the LICENSE file. */ -/* From trusted/ppb_broker_trusted.idl modified Wed Oct 5 14:06:02 2011. */ +/* From trusted/ppb_broker_trusted.idl modified Mon Dec 3 11:10:40 2012. */ #ifndef PPAPI_C_TRUSTED_PPB_BROKER_TRUSTED_H_ #define PPAPI_C_TRUSTED_PPB_BROKER_TRUSTED_H_ @@ -16,7 +16,8 @@ #include "ppapi/c/pp_stdint.h" #define PPB_BROKER_TRUSTED_INTERFACE_0_2 "PPB_BrokerTrusted;0.2" -#define PPB_BROKER_TRUSTED_INTERFACE PPB_BROKER_TRUSTED_INTERFACE_0_2 +#define PPB_BROKER_TRUSTED_INTERFACE_0_3 "PPB_BrokerTrusted;0.3" +#define PPB_BROKER_TRUSTED_INTERFACE PPB_BROKER_TRUSTED_INTERFACE_0_3 /** * @file @@ -40,7 +41,7 @@ * handle is closed. The handle should be closed before the resource is * released. */ -struct PPB_BrokerTrusted_0_2 { +struct PPB_BrokerTrusted_0_3 { /** * Returns a trusted broker resource. */ @@ -74,9 +75,26 @@ struct PPB_BrokerTrusted_0_2 { * before connect has completed will return PP_ERROR_FAILED. */ int32_t (*GetHandle)(PP_Resource broker, int32_t* handle); + /** + * Returns PP_TRUE if the plugin has permission to launch the broker. A user + * must explicitly grant permission to launch the broker for a particular + * website. This is done through an infobar that is displayed when |Connect| + * is called. This function returns PP_TRUE if the user has already granted + * permission to launch the broker for the website containing this plugin + * instance. Returns PP_FALSE otherwise. + */ + PP_Bool (*IsAllowed)(PP_Resource broker); }; -typedef struct PPB_BrokerTrusted_0_2 PPB_BrokerTrusted; +typedef struct PPB_BrokerTrusted_0_3 PPB_BrokerTrusted; + +struct PPB_BrokerTrusted_0_2 { + PP_Resource (*CreateTrusted)(PP_Instance instance); + PP_Bool (*IsBrokerTrusted)(PP_Resource resource); + int32_t (*Connect)(PP_Resource broker, + struct PP_CompletionCallback connect_callback); + int32_t (*GetHandle)(PP_Resource broker, int32_t* handle); +}; /** * @} */ diff --git a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c index 1209f47..b3772d9 100644 --- a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c +++ b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c @@ -159,6 +159,7 @@ static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPP_Messaging_1_0; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPP_MouseLock_1_0; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_AudioTrusted_0_6; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_BrokerTrusted_0_2; +static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_BrokerTrusted_0_3; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_BrowserFont_Trusted_1_0; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_BufferTrusted_0_1; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_CharSet_Trusted_1_0; @@ -1281,6 +1282,40 @@ int32_t Pnacl_M14_PPB_BrokerTrusted_GetHandle(PP_Resource broker, int32_t* handl /* End wrapper methods for PPB_BrokerTrusted_0_2 */ +/* Begin wrapper methods for PPB_BrokerTrusted_0_3 */ + +static __attribute__((pnaclcall)) +PP_Resource Pnacl_M25_PPB_BrokerTrusted_CreateTrusted(PP_Instance instance) { + const struct PPB_BrokerTrusted_0_3 *iface = Pnacl_WrapperInfo_PPB_BrokerTrusted_0_3.real_iface; + return iface->CreateTrusted(instance); +} + +static __attribute__((pnaclcall)) +PP_Bool Pnacl_M25_PPB_BrokerTrusted_IsBrokerTrusted(PP_Resource resource) { + const struct PPB_BrokerTrusted_0_3 *iface = Pnacl_WrapperInfo_PPB_BrokerTrusted_0_3.real_iface; + return iface->IsBrokerTrusted(resource); +} + +static __attribute__((pnaclcall)) +int32_t Pnacl_M25_PPB_BrokerTrusted_Connect(PP_Resource broker, struct PP_CompletionCallback connect_callback) { + const struct PPB_BrokerTrusted_0_3 *iface = Pnacl_WrapperInfo_PPB_BrokerTrusted_0_3.real_iface; + return iface->Connect(broker, connect_callback); +} + +static __attribute__((pnaclcall)) +int32_t Pnacl_M25_PPB_BrokerTrusted_GetHandle(PP_Resource broker, int32_t* handle) { + const struct PPB_BrokerTrusted_0_3 *iface = Pnacl_WrapperInfo_PPB_BrokerTrusted_0_3.real_iface; + return iface->GetHandle(broker, handle); +} + +static __attribute__((pnaclcall)) +PP_Bool Pnacl_M25_PPB_BrokerTrusted_IsAllowed(PP_Resource broker) { + const struct PPB_BrokerTrusted_0_3 *iface = Pnacl_WrapperInfo_PPB_BrokerTrusted_0_3.real_iface; + return iface->IsAllowed(broker); +} + +/* End wrapper methods for PPB_BrokerTrusted_0_3 */ + /* Begin wrapper methods for PPB_BrowserFont_Trusted_1_0 */ static __attribute__((pnaclcall)) @@ -3692,6 +3727,14 @@ struct PPB_BrokerTrusted_0_2 Pnacl_Wrappers_PPB_BrokerTrusted_0_2 = { .GetHandle = (int32_t (*)(PP_Resource broker, int32_t* handle))&Pnacl_M14_PPB_BrokerTrusted_GetHandle }; +struct PPB_BrokerTrusted_0_3 Pnacl_Wrappers_PPB_BrokerTrusted_0_3 = { + .CreateTrusted = (PP_Resource (*)(PP_Instance instance))&Pnacl_M25_PPB_BrokerTrusted_CreateTrusted, + .IsBrokerTrusted = (PP_Bool (*)(PP_Resource resource))&Pnacl_M25_PPB_BrokerTrusted_IsBrokerTrusted, + .Connect = (int32_t (*)(PP_Resource broker, struct PP_CompletionCallback connect_callback))&Pnacl_M25_PPB_BrokerTrusted_Connect, + .GetHandle = (int32_t (*)(PP_Resource broker, int32_t* handle))&Pnacl_M25_PPB_BrokerTrusted_GetHandle, + .IsAllowed = (PP_Bool (*)(PP_Resource broker))&Pnacl_M25_PPB_BrokerTrusted_IsAllowed +}; + struct PPB_BrowserFont_Trusted_1_0 Pnacl_Wrappers_PPB_BrowserFont_Trusted_1_0 = { .GetFontFamilies = (struct PP_Var (*)(PP_Instance instance))&Pnacl_M19_PPB_BrowserFont_Trusted_GetFontFamilies, .Create = (PP_Resource (*)(PP_Instance instance, const struct PP_BrowserFont_Trusted_Description* description))&Pnacl_M19_PPB_BrowserFont_Trusted_Create, @@ -4483,6 +4526,12 @@ static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_BrokerTrusted_0_2 = { .real_iface = NULL }; +static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_BrokerTrusted_0_3 = { + .iface_macro = PPB_BROKER_TRUSTED_INTERFACE_0_3, + .wrapped_iface = (void *) &Pnacl_Wrappers_PPB_BrokerTrusted_0_3, + .real_iface = NULL +}; + static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_BrowserFont_Trusted_1_0 = { .iface_macro = PPB_BROWSERFONT_TRUSTED_INTERFACE_1_0, .wrapped_iface = (void *) &Pnacl_Wrappers_PPB_BrowserFont_Trusted_1_0, @@ -5071,6 +5120,7 @@ static struct __PnaclWrapperInfo *s_ppb_wrappers[] = { &Pnacl_WrapperInfo_PPB_WebSocket_1_0, &Pnacl_WrapperInfo_PPB_AudioTrusted_0_6, &Pnacl_WrapperInfo_PPB_BrokerTrusted_0_2, + &Pnacl_WrapperInfo_PPB_BrokerTrusted_0_3, &Pnacl_WrapperInfo_PPB_BrowserFont_Trusted_1_0, &Pnacl_WrapperInfo_PPB_BufferTrusted_0_1, &Pnacl_WrapperInfo_PPB_CharSet_Trusted_1_0, diff --git a/ppapi/ppapi_proxy.gypi b/ppapi/ppapi_proxy.gypi index 81ec94f..9e8220f 100644 --- a/ppapi/ppapi_proxy.gypi +++ b/ppapi/ppapi_proxy.gypi @@ -23,6 +23,8 @@ 'proxy/audio_input_resource.h', 'proxy/broker_dispatcher.cc', 'proxy/broker_dispatcher.h', + 'proxy/broker_resource.cc', + 'proxy/broker_resource.h', 'proxy/browser_font_resource_trusted.cc', 'proxy/browser_font_resource_trusted.h', 'proxy/connection.h', diff --git a/ppapi/proxy/broker_resource.cc b/ppapi/proxy/broker_resource.cc new file mode 100644 index 0000000..4fac07e --- /dev/null +++ b/ppapi/proxy/broker_resource.cc @@ -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. + +#include "ppapi/proxy/broker_resource.h" + +#include "ppapi/c/pp_bool.h" +#include "ppapi/proxy/ppapi_messages.h" + +namespace ppapi { +namespace proxy { + +BrokerResource::BrokerResource(Connection connection, PP_Instance instance) + : PluginResource(connection, instance) { + SendCreate(BROWSER, PpapiHostMsg_Broker_Create()); +} + +BrokerResource::~BrokerResource() { +} + +thunk::PPB_Broker_Instance_API* BrokerResource::AsPPB_Broker_Instance_API() { + return this; +} + +PP_Bool BrokerResource::IsAllowed() { + int32_t result = + SyncCall<IPC::Message>(BROWSER, PpapiHostMsg_Broker_IsAllowed()); + return PP_FromBool(result == PP_OK); +} + +} // namespace proxy +} // namespace ppapi diff --git a/ppapi/proxy/broker_resource.h b/ppapi/proxy/broker_resource.h new file mode 100644 index 0000000..48d8041 --- /dev/null +++ b/ppapi/proxy/broker_resource.h @@ -0,0 +1,35 @@ +// 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_BROKER_RESOURCE_H_ +#define PPAPI_PROXY_BROKER_RESOURCE_H_ + +#include "ppapi/proxy/connection.h" +#include "ppapi/proxy/plugin_resource.h" +#include "ppapi/thunk/ppb_broker_api.h" + +namespace ppapi { +namespace proxy { + +class BrokerResource + : public PluginResource, + public thunk::PPB_Broker_Instance_API { + public: + BrokerResource(Connection connection, PP_Instance instance); + virtual ~BrokerResource(); + + // Resource override. + virtual thunk::PPB_Broker_Instance_API* AsPPB_Broker_Instance_API() OVERRIDE; + + // thunk::PPB_Broker_Instance_API implementation. + virtual PP_Bool IsAllowed() OVERRIDE; + + private: + DISALLOW_COPY_AND_ASSIGN(BrokerResource); +}; + +} // namespace proxy +} // namespace ppapi + +#endif // PPAPI_PROXY_BROKER_RESOURCE_H_ diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h index b5e04de..3ccc3df 100644 --- a/ppapi/proxy/ppapi_messages.h +++ b/ppapi/proxy/ppapi_messages.h @@ -1443,6 +1443,14 @@ IPC_SYNC_MESSAGE_CONTROL2_2(PpapiHostMsg_ResourceSyncCall, //----------------------------------------------------------------------------- // Messages for resources using call/reply above. +// Broker ---------------------------------------------------------------------- +IPC_MESSAGE_CONTROL0(PpapiHostMsg_Broker_Create) + +// Queries whether the plugin has permission to connect to the Pepper broker. +// The response is contained in the error value of the +// ResourceMessageReplyParams in the reply message. +IPC_MESSAGE_CONTROL0(PpapiHostMsg_Broker_IsAllowed) + // File chooser. IPC_MESSAGE_CONTROL0(PpapiHostMsg_FileChooser_Create) IPC_MESSAGE_CONTROL4(PpapiHostMsg_FileChooser_Show, diff --git a/ppapi/proxy/ppb_instance_proxy.cc b/ppapi/proxy/ppb_instance_proxy.cc index 11a2b4b..3fb3e18 100644 --- a/ppapi/proxy/ppb_instance_proxy.cc +++ b/ppapi/proxy/ppb_instance_proxy.cc @@ -14,6 +14,7 @@ #include "ppapi/c/ppb_messaging.h" #include "ppapi/c/ppb_mouse_lock.h" #include "ppapi/c/private/pp_content_decryptor.h" +#include "ppapi/proxy/broker_resource.h" #include "ppapi/proxy/content_decryptor_private_serializer.h" #include "ppapi/proxy/enter_proxy.h" #include "ppapi/proxy/flash_clipboard_resource.h" @@ -372,6 +373,9 @@ Resource* PPB_Instance_Proxy::GetSingletonResource(PP_Instance instance, Connection connection(PluginGlobals::Get()->GetBrowserSender(), dispatcher()); switch (id) { + case BROKER_SINGLETON_ID: + new_singleton = new BrokerResource(connection, instance); + break; case GAMEPAD_SINGLETON_ID: new_singleton = new GamepadResource(connection, instance); break; diff --git a/ppapi/shared_impl/resource.h b/ppapi/shared_impl/resource.h index 6c86868..46cb14c 100644 --- a/ppapi/shared_impl/resource.h +++ b/ppapi/shared_impl/resource.h @@ -24,6 +24,7 @@ F(PPB_AudioInput_API) \ F(PPB_AudioTrusted_API) \ F(PPB_Broker_API) \ + F(PPB_Broker_Instance_API) \ F(PPB_BrowserFont_Trusted_API) \ F(PPB_Buffer_API) \ F(PPB_BufferTrusted_API) \ diff --git a/ppapi/shared_impl/singleton_resource_id.h b/ppapi/shared_impl/singleton_resource_id.h index 442611a..6dc5819 100644 --- a/ppapi/shared_impl/singleton_resource_id.h +++ b/ppapi/shared_impl/singleton_resource_id.h @@ -10,6 +10,10 @@ namespace ppapi { // These IDs are used to access singleton resource objects using // PPB_Instance_API.GetSingletonResource. enum SingletonResourceID { + // TODO(raymes): The broker resource isn't really a singleton. This is only + // a hack until PPB_Broker trusted has been fully refactored to the new + // resource model. + BROKER_SINGLETON_ID, FLASH_CLIPBOARD_SINGLETON_ID, FLASH_FILE_SINGLETON_ID, FLASH_FULLSCREEN_SINGLETON_ID, diff --git a/ppapi/tests/test_broker.cc b/ppapi/tests/test_broker.cc index 63bbd1c..d66e9dd 100644 --- a/ppapi/tests/test_broker.cc +++ b/ppapi/tests/test_broker.cc @@ -222,10 +222,14 @@ void TestBroker::RunTests(const std::string& filter) { RUN_TEST(ConnectPermissionDenied, filter); RUN_TEST(ConnectPermissionGranted, filter); + RUN_TEST(IsAllowedPermissionDenied, filter); + RUN_TEST(IsAllowedPermissionGranted, filter); } std::string TestBroker::TestCreate() { // Very simplistic test to make sure we can create a broker interface. + // TODO(raymes): All of the resources created in this file are leaked. Write + // a C++ wrapper for PPB_Broker_Trusted to avoid these leaks. PP_Resource broker = broker_interface_->CreateTrusted( instance_->pp_instance()); ASSERT_TRUE(broker); @@ -317,3 +321,20 @@ std::string TestBroker::TestConnectPermissionGranted() { PASS(); } +std::string TestBroker::TestIsAllowedPermissionDenied() { + PP_Resource broker = broker_interface_->CreateTrusted( + instance_->pp_instance()); + ASSERT_TRUE(broker); + ASSERT_EQ(PP_FALSE, broker_interface_->IsAllowed(broker)); + + PASS(); +} + +std::string TestBroker::TestIsAllowedPermissionGranted() { + PP_Resource broker = broker_interface_->CreateTrusted( + instance_->pp_instance()); + ASSERT_TRUE(broker); + ASSERT_EQ(PP_TRUE, broker_interface_->IsAllowed(broker)); + + PASS(); +} diff --git a/ppapi/tests/test_broker.h b/ppapi/tests/test_broker.h index a45900e..ee869f6 100644 --- a/ppapi/tests/test_broker.h +++ b/ppapi/tests/test_broker.h @@ -26,6 +26,8 @@ class TestBroker : public TestCase { std::string TestConnectAndPipe(); std::string TestConnectPermissionDenied(); std::string TestConnectPermissionGranted(); + std::string TestIsAllowedPermissionDenied(); + std::string TestIsAllowedPermissionGranted(); const PPB_BrokerTrusted* broker_interface_; }; diff --git a/ppapi/thunk/interfaces_ppb_private.h b/ppapi/thunk/interfaces_ppb_private.h index 48df662..e1c53ec 100644 --- a/ppapi/thunk/interfaces_ppb_private.h +++ b/ppapi/thunk/interfaces_ppb_private.h @@ -20,6 +20,8 @@ PROXIED_API(PPB_Broker) PROXIED_IFACE(PPB_Broker, PPB_BROKER_TRUSTED_INTERFACE_0_2, PPB_BrokerTrusted_0_2) +PROXIED_IFACE(PPB_Broker, PPB_BROKER_TRUSTED_INTERFACE_0_3, + PPB_BrokerTrusted_0_3) PROXIED_IFACE(PPB_Instance, PPB_BROWSERFONT_TRUSTED_INTERFACE_1_0, PPB_BrowserFont_Trusted_1_0) PROXIED_IFACE(PPB_Instance, diff --git a/ppapi/thunk/ppb_broker_api.h b/ppapi/thunk/ppb_broker_api.h index 803c99e..8ac1dd2 100644 --- a/ppapi/thunk/ppb_broker_api.h +++ b/ppapi/thunk/ppb_broker_api.h @@ -6,8 +6,10 @@ #define PPAPI_THUNK_PPB_BROKER_API_H_ #include "base/memory/ref_counted.h" +#include "ppapi/c/pp_bool.h" #include "ppapi/c/pp_completion_callback.h" #include "ppapi/c/pp_stdint.h" +#include "ppapi/shared_impl/singleton_resource_id.h" namespace ppapi { @@ -23,6 +25,19 @@ class PPB_Broker_API { virtual int32_t GetHandle(int32_t* handle) = 0; }; +// TODO(raymes): Merge this into PPB_Broker_API when the PPB_Broker proxy is +// refactored to the new resource model. The IsAllowed function should be +// attached to the resource implementing the PPB_Broker_API. However in order to +// implement this quickly, the function is added in a new instance API. +class PPB_Broker_Instance_API { + public: + virtual ~PPB_Broker_Instance_API() {} + + virtual PP_Bool IsAllowed() = 0; + + static const SingletonResourceID kSingletonResourceID = BROKER_SINGLETON_ID; +}; + } // namespace thunk } // namespace ppapi diff --git a/ppapi/thunk/ppb_broker_thunk.cc b/ppapi/thunk/ppb_broker_thunk.cc index fa192b6..0f2f1c9 100644 --- a/ppapi/thunk/ppb_broker_thunk.cc +++ b/ppapi/thunk/ppb_broker_thunk.cc @@ -42,17 +42,44 @@ int32_t GetHandle(PP_Resource resource, int32_t* handle) { return enter.object()->GetHandle(handle); } -const PPB_BrokerTrusted g_ppb_broker_thunk = { +PP_Bool IsAllowed(PP_Resource resource) { + // TODO(raymes): This is a hack. See the note in ppb_broker_api.h. + PP_Instance instance = 0; + { + EnterResource<PPB_Broker_API> enter_resource(resource, true); + if (enter_resource.failed()) + return PP_FALSE; + instance = enter_resource.resource()->pp_instance(); + } + EnterInstanceAPI<PPB_Broker_Instance_API> enter_instance(instance); + if (enter_instance.failed()) + return PP_FALSE; + return enter_instance.functions()->IsAllowed(); +} + +const PPB_BrokerTrusted_0_2 g_ppb_broker_0_2_thunk = { + &CreateTrusted, + &IsBrokerTrusted, + &Connect, + &GetHandle, +}; + +const PPB_BrokerTrusted_0_3 g_ppb_broker_0_3_thunk = { &CreateTrusted, &IsBrokerTrusted, &Connect, &GetHandle, + &IsAllowed, }; } // namespace const PPB_BrokerTrusted_0_2* GetPPB_BrokerTrusted_0_2_Thunk() { - return &g_ppb_broker_thunk; + return &g_ppb_broker_0_2_thunk; +} + +const PPB_BrokerTrusted_0_3* GetPPB_BrokerTrusted_0_3_Thunk() { + return &g_ppb_broker_0_3_thunk; } } // namespace thunk diff --git a/webkit/plugins/ppapi/host_var_tracker_unittest.cc b/webkit/plugins/ppapi/host_var_tracker_unittest.cc index 92c4119..f2be72c 100644 --- a/webkit/plugins/ppapi/host_var_tracker_unittest.cc +++ b/webkit/plugins/ppapi/host_var_tracker_unittest.cc @@ -85,7 +85,7 @@ class HostVarTrackerTest : public PpapiUnittest { TEST_F(HostVarTrackerTest, DeleteObjectVarWithInstance) { // Make a second instance (the test harness already creates & manages one). scoped_refptr<PluginInstance> instance2( - PluginInstance::Create(delegate(), module())); + PluginInstance::Create(delegate(), module(), NULL, GURL())); PP_Instance pp_instance2 = instance2->pp_instance(); // Make an object var. diff --git a/webkit/plugins/ppapi/plugin_module.cc b/webkit/plugins/ppapi/plugin_module.cc index e993554..79877d1 100644 --- a/webkit/plugins/ppapi/plugin_module.cc +++ b/webkit/plugins/ppapi/plugin_module.cc @@ -533,8 +533,12 @@ bool PluginModule::SupportsInterface(const char* name) { return !!InternalGetInterface(name); } -PluginInstance* PluginModule::CreateInstance(PluginDelegate* delegate) { - PluginInstance* instance = PluginInstance::Create(delegate, this); +PluginInstance* PluginModule::CreateInstance( + PluginDelegate* delegate, + WebKit::WebPluginContainer* container, + const GURL& plugin_url) { + PluginInstance* instance = PluginInstance::Create(delegate, this, container, + plugin_url); if (!instance) { LOG(WARNING) << "Plugin doesn't support instance interface, failing."; return NULL; diff --git a/webkit/plugins/ppapi/plugin_module.h b/webkit/plugins/ppapi/plugin_module.h index 0a23714..e6f3e85 100644 --- a/webkit/plugins/ppapi/plugin_module.h +++ b/webkit/plugins/ppapi/plugin_module.h @@ -33,6 +33,10 @@ class CallbackTracker; class WebKitForwarding; } // namespace ppapi +namespace WebKit { +class WebPluginContainer; +} // namespace WebKit + namespace webkit { namespace ppapi { @@ -135,7 +139,9 @@ class WEBKIT_PLUGINS_EXPORT PluginModule : const FilePath& path() const { return path_; } const ::ppapi::PpapiPermissions& permissions() const { return permissions_; } - PluginInstance* CreateInstance(PluginDelegate* delegate); + PluginInstance* CreateInstance(PluginDelegate* delegate, + WebKit::WebPluginContainer* container, + const GURL& plugin_url); // Returns "some" plugin instance associated with this module. This is not // guaranteed to be any one in particular. This is normally used to execute diff --git a/webkit/plugins/ppapi/ppapi_plugin_instance.cc b/webkit/plugins/ppapi/ppapi_plugin_instance.cc index 5bdacb0..39b5e2d 100644 --- a/webkit/plugins/ppapi/ppapi_plugin_instance.cc +++ b/webkit/plugins/ppapi/ppapi_plugin_instance.cc @@ -308,14 +308,17 @@ scoped_array<const char*> StringVectorToArgArray( // static PluginInstance* PluginInstance::Create(PluginDelegate* delegate, - PluginModule* module) { + PluginModule* module, + WebPluginContainer* container, + const GURL& plugin_url) { base::Callback<const void*(const char*)> get_plugin_interface_func = base::Bind(&PluginModule::GetPluginInterface, module); PPP_Instance_Combined* ppp_instance_combined = PPP_Instance_Combined::Create(get_plugin_interface_func); if (!ppp_instance_combined) return NULL; - return new PluginInstance(delegate, module, ppp_instance_combined); + return new PluginInstance(delegate, module, ppp_instance_combined, container, + plugin_url); } PluginInstance::GamepadImpl::GamepadImpl(PluginDelegate* delegate) @@ -337,12 +340,15 @@ void PluginInstance::GamepadImpl::Sample(PP_GamepadsSampleData* data) { PluginInstance::PluginInstance( PluginDelegate* delegate, PluginModule* module, - ::ppapi::PPP_Instance_Combined* instance_interface) + ::ppapi::PPP_Instance_Combined* instance_interface, + WebPluginContainer* container, + const GURL& plugin_url) : delegate_(delegate), module_(module), instance_interface_(instance_interface), pp_instance_(0), - container_(NULL), + container_(container), + plugin_url_(plugin_url), full_frame_(false), sent_initial_did_change_view_(false), view_change_weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), @@ -560,13 +566,9 @@ static void SetGPUHistogram(const ::ppapi::Preferences& prefs, #endif } -bool PluginInstance::Initialize(WebPluginContainer* container, - const std::vector<std::string>& arg_names, +bool PluginInstance::Initialize(const std::vector<std::string>& arg_names, const std::vector<std::string>& arg_values, - const GURL& plugin_url, bool full_frame) { - container_ = container; - plugin_url_ = plugin_url; full_frame_ = full_frame; UpdateTouchEventRequest(); @@ -2130,8 +2132,9 @@ PP_Bool PluginInstance::GetScreenSize(PP_Instance instance, PP_Size* size) { ::ppapi::Resource* PluginInstance::GetSingletonResource( PP_Instance instance, ::ppapi::SingletonResourceID id) { - // Flash APIs aren't implemented in-process. + // Flash APIs and some others aren't implemented in-process. switch (id) { + case ::ppapi::BROKER_SINGLETON_ID: case ::ppapi::FLASH_CLIPBOARD_SINGLETON_ID: case ::ppapi::FLASH_FILE_SINGLETON_ID: case ::ppapi::FLASH_FULLSCREEN_SINGLETON_ID: diff --git a/webkit/plugins/ppapi/ppapi_plugin_instance.h b/webkit/plugins/ppapi/ppapi_plugin_instance.h index 07f588d..1d0aff5 100644 --- a/webkit/plugins/ppapi/ppapi_plugin_instance.h +++ b/webkit/plugins/ppapi/ppapi_plugin_instance.h @@ -104,7 +104,10 @@ class WEBKIT_PLUGINS_EXPORT PluginInstance : // version of PPP_Instance possible by querying the given get_plugin_interface // function. If the plugin does not support any valid PPP_Instance interface, // returns NULL. - static PluginInstance* Create(PluginDelegate* delegate, PluginModule* module); + static PluginInstance* Create(PluginDelegate* delegate, + PluginModule* module, + WebKit::WebPluginContainer* container, + const GURL& plugin_url); // Delete should be called by the WebPlugin before this destructor. virtual ~PluginInstance(); @@ -163,10 +166,8 @@ class WEBKIT_PLUGINS_EXPORT PluginInstance : const ::ppapi::ViewData& view_data() const { return view_data_; } // PPP_Instance and PPP_Instance_Private pass-through. - bool Initialize(WebKit::WebPluginContainer* container, - const std::vector<std::string>& arg_names, + bool Initialize(const std::vector<std::string>& arg_names, const std::vector<std::string>& arg_values, - const GURL& plugin_url, bool full_frame); bool HandleDocumentLoad(PPB_URLLoader_Impl* loader); bool HandleInputEvent(const WebKit::WebInputEvent& event, @@ -478,7 +479,9 @@ class WEBKIT_PLUGINS_EXPORT PluginInstance : // initialization. PluginInstance(PluginDelegate* delegate, PluginModule* module, - ::ppapi::PPP_Instance_Combined* instance_interface); + ::ppapi::PPP_Instance_Combined* instance_interface, + WebKit::WebPluginContainer* container, + const GURL& plugin_url); bool LoadFindInterface(); bool LoadInputEventInterface(); diff --git a/webkit/plugins/ppapi/ppapi_unittest.cc b/webkit/plugins/ppapi/ppapi_unittest.cc index cb35126..05dbfed 100644 --- a/webkit/plugins/ppapi/ppapi_unittest.cc +++ b/webkit/plugins/ppapi/ppapi_unittest.cc @@ -86,7 +86,7 @@ void PpapiUnittest::SetUp() { ASSERT_TRUE(module_->InitAsInternalPlugin(entry_points)); // Initialize the mock instance. - instance_ = PluginInstance::Create(delegate_.get(), module()); + instance_ = PluginInstance::Create(delegate_.get(), module(), NULL, GURL()); } void PpapiUnittest::TearDown() { diff --git a/webkit/plugins/ppapi/ppapi_webplugin_impl.cc b/webkit/plugins/ppapi/ppapi_webplugin_impl.cc index 0416140..1ff2637 100644 --- a/webkit/plugins/ppapi/ppapi_webplugin_impl.cc +++ b/webkit/plugins/ppapi/ppapi_webplugin_impl.cc @@ -83,14 +83,14 @@ bool WebPluginImpl::initialize(WebPluginContainer* container) { if (!init_data_->delegate) return false; - instance_ = init_data_->module->CreateInstance(init_data_->delegate); + instance_ = init_data_->module->CreateInstance(init_data_->delegate, + container, + init_data_->url); if (!instance_) return false; - bool success = instance_->Initialize(container, - init_data_->arg_names, + bool success = instance_->Initialize(init_data_->arg_names, init_data_->arg_values, - init_data_->url, full_frame_); if (!success) { instance_->Delete(); |