| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/renderer/pepper/pepper_plugin_delegate_impl.h" | 5 #include "content/renderer/pepper/pepper_plugin_delegate_impl.h" |
| 6 | 6 |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 #include <cstddef> | 8 #include <cstddef> |
| 9 #include <map> | 9 #include <map> |
| 10 #include <queue> | 10 #include <queue> |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 99 | 99 |
| 100 namespace { | 100 namespace { |
| 101 | 101 |
| 102 // This class wraps a dispatcher and has the same lifetime. A dispatcher has | 102 // This class wraps a dispatcher and has the same lifetime. A dispatcher has |
| 103 // the same lifetime as a plugin module, which is longer than any particular | 103 // the same lifetime as a plugin module, which is longer than any particular |
| 104 // RenderView or plugin instance. | 104 // RenderView or plugin instance. |
| 105 class HostDispatcherWrapper | 105 class HostDispatcherWrapper |
| 106 : public webkit::ppapi::PluginDelegate::OutOfProcessProxy { | 106 : public webkit::ppapi::PluginDelegate::OutOfProcessProxy { |
| 107 public: | 107 public: |
| 108 HostDispatcherWrapper(webkit::ppapi::PluginModule* module, | 108 HostDispatcherWrapper(webkit::ppapi::PluginModule* module, |
| 109 base::ProcessId peer_pid, |
| 109 int plugin_child_id, | 110 int plugin_child_id, |
| 110 const ppapi::PpapiPermissions& perms, | 111 const ppapi::PpapiPermissions& perms, |
| 111 bool is_external) | 112 bool is_external) |
| 112 : module_(module), | 113 : module_(module), |
| 114 peer_pid_(peer_pid), |
| 113 plugin_child_id_(plugin_child_id), | 115 plugin_child_id_(plugin_child_id), |
| 114 permissions_(perms), | 116 permissions_(perms), |
| 115 is_external_(is_external) { | 117 is_external_(is_external) { |
| 116 } | 118 } |
| 117 virtual ~HostDispatcherWrapper() {} | 119 virtual ~HostDispatcherWrapper() {} |
| 118 | 120 |
| 119 bool Init(const IPC::ChannelHandle& channel_handle, | 121 bool Init(const IPC::ChannelHandle& channel_handle, |
| 120 PP_GetInterface_Func local_get_interface, | 122 PP_GetInterface_Func local_get_interface, |
| 121 const ppapi::Preferences& preferences, | 123 const ppapi::Preferences& preferences, |
| 122 PepperHungPluginFilter* filter) { | 124 PepperHungPluginFilter* filter) { |
| 123 if (channel_handle.name.empty()) | 125 if (channel_handle.name.empty()) |
| 124 return false; | 126 return false; |
| 125 | 127 |
| 126 #if defined(OS_POSIX) | 128 #if defined(OS_POSIX) |
| 127 DCHECK_NE(-1, channel_handle.socket.fd); | 129 DCHECK_NE(-1, channel_handle.socket.fd); |
| 128 if (channel_handle.socket.fd == -1) | 130 if (channel_handle.socket.fd == -1) |
| 129 return false; | 131 return false; |
| 130 #endif | 132 #endif |
| 131 | 133 |
| 132 dispatcher_delegate_.reset(new PepperProxyChannelDelegateImpl); | 134 dispatcher_delegate_.reset(new PepperProxyChannelDelegateImpl); |
| 133 dispatcher_.reset(new ppapi::proxy::HostDispatcher( | 135 dispatcher_.reset(new ppapi::proxy::HostDispatcher( |
| 134 module_->pp_module(), local_get_interface, filter, permissions_)); | 136 module_->pp_module(), local_get_interface, filter, permissions_)); |
| 135 | 137 |
| 136 if (!dispatcher_->InitHostWithChannel(dispatcher_delegate_.get(), | 138 if (!dispatcher_->InitHostWithChannel(dispatcher_delegate_.get(), |
| 139 peer_pid_, |
| 137 channel_handle, | 140 channel_handle, |
| 138 true, // Client. | 141 true, // Client. |
| 139 preferences)) { | 142 preferences)) { |
| 140 dispatcher_.reset(); | 143 dispatcher_.reset(); |
| 141 dispatcher_delegate_.reset(); | 144 dispatcher_delegate_.reset(); |
| 142 return false; | 145 return false; |
| 143 } | 146 } |
| 144 dispatcher_->channel()->SetRestrictDispatchChannelGroup( | 147 dispatcher_->channel()->SetRestrictDispatchChannelGroup( |
| 145 kRendererRestrictDispatchGroup_Pepper); | 148 kRendererRestrictDispatchGroup_Pepper); |
| 146 return true; | 149 return true; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 187 instance, | 190 instance, |
| 188 is_external_)); | 191 is_external_)); |
| 189 } | 192 } |
| 190 } | 193 } |
| 191 | 194 |
| 192 ppapi::proxy::HostDispatcher* dispatcher() { return dispatcher_.get(); } | 195 ppapi::proxy::HostDispatcher* dispatcher() { return dispatcher_.get(); } |
| 193 | 196 |
| 194 private: | 197 private: |
| 195 webkit::ppapi::PluginModule* module_; | 198 webkit::ppapi::PluginModule* module_; |
| 196 | 199 |
| 200 base::ProcessId peer_pid_; |
| 201 |
| 197 // ID that the browser process uses to idetify the child process for the | 202 // ID that the browser process uses to idetify the child process for the |
| 198 // plugin. This isn't directly useful from our process (the renderer) except | 203 // plugin. This isn't directly useful from our process (the renderer) except |
| 199 // in messages to the browser to disambiguate plugins. | 204 // in messages to the browser to disambiguate plugins. |
| 200 int plugin_child_id_; | 205 int plugin_child_id_; |
| 201 | 206 |
| 202 ppapi::PpapiPermissions permissions_; | 207 ppapi::PpapiPermissions permissions_; |
| 203 bool is_external_; | 208 bool is_external_; |
| 204 | 209 |
| 205 scoped_ptr<ppapi::proxy::HostDispatcher> dispatcher_; | 210 scoped_ptr<ppapi::proxy::HostDispatcher> dispatcher_; |
| 206 scoped_ptr<ppapi::proxy::ProxyChannel::Delegate> dispatcher_delegate_; | 211 scoped_ptr<ppapi::proxy::ProxyChannel::Delegate> dispatcher_delegate_; |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 390 } else if (!info->is_out_of_process) { | 395 } else if (!info->is_out_of_process) { |
| 391 // In-process plugin not preloaded, it probably couldn't be initialized. | 396 // In-process plugin not preloaded, it probably couldn't be initialized. |
| 392 return scoped_refptr<webkit::ppapi::PluginModule>(); | 397 return scoped_refptr<webkit::ppapi::PluginModule>(); |
| 393 } | 398 } |
| 394 | 399 |
| 395 ppapi::PpapiPermissions permissions = | 400 ppapi::PpapiPermissions permissions = |
| 396 ppapi::PpapiPermissions::GetForCommandLine(info->permissions); | 401 ppapi::PpapiPermissions::GetForCommandLine(info->permissions); |
| 397 | 402 |
| 398 // Out of process: have the browser start the plugin process for us. | 403 // Out of process: have the browser start the plugin process for us. |
| 399 IPC::ChannelHandle channel_handle; | 404 IPC::ChannelHandle channel_handle; |
| 405 base::ProcessId peer_pid; |
| 400 int plugin_child_id = 0; | 406 int plugin_child_id = 0; |
| 401 render_view_->Send(new ViewHostMsg_OpenChannelToPepperPlugin( | 407 render_view_->Send(new ViewHostMsg_OpenChannelToPepperPlugin( |
| 402 path, &channel_handle, &plugin_child_id)); | 408 path, &channel_handle, &peer_pid, &plugin_child_id)); |
| 403 if (channel_handle.name.empty()) { | 409 if (channel_handle.name.empty()) { |
| 404 // Couldn't be initialized. | 410 // Couldn't be initialized. |
| 405 return scoped_refptr<webkit::ppapi::PluginModule>(); | 411 return scoped_refptr<webkit::ppapi::PluginModule>(); |
| 406 } | 412 } |
| 407 | 413 |
| 408 // AddLiveModule must be called before any early returns since the | 414 // AddLiveModule must be called before any early returns since the |
| 409 // module's destructor will remove itself. | 415 // module's destructor will remove itself. |
| 410 module = new webkit::ppapi::PluginModule( | 416 module = new webkit::ppapi::PluginModule( |
| 411 info->name, path, | 417 info->name, path, |
| 412 PepperPluginRegistry::GetInstance(), | 418 PepperPluginRegistry::GetInstance(), |
| 413 permissions); | 419 permissions); |
| 414 PepperPluginRegistry::GetInstance()->AddLiveModule(path, module); | 420 PepperPluginRegistry::GetInstance()->AddLiveModule(path, module); |
| 415 | 421 |
| 416 if (!CreateOutOfProcessModule(module, | 422 if (!CreateOutOfProcessModule(module, |
| 417 path, | 423 path, |
| 418 permissions, | 424 permissions, |
| 419 channel_handle, | 425 channel_handle, |
| 426 peer_pid, |
| 420 plugin_child_id, | 427 plugin_child_id, |
| 421 false)) // is_external = false | 428 false)) // is_external = false |
| 422 return scoped_refptr<webkit::ppapi::PluginModule>(); | 429 return scoped_refptr<webkit::ppapi::PluginModule>(); |
| 423 | 430 |
| 424 return module; | 431 return module; |
| 425 } | 432 } |
| 426 | 433 |
| 427 RendererPpapiHost* PepperPluginDelegateImpl::CreateExternalPluginModule( | 434 RendererPpapiHost* PepperPluginDelegateImpl::CreateExternalPluginModule( |
| 428 scoped_refptr<webkit::ppapi::PluginModule> module, | 435 scoped_refptr<webkit::ppapi::PluginModule> module, |
| 429 const FilePath& path, | 436 const FilePath& path, |
| 430 ppapi::PpapiPermissions permissions, | 437 ppapi::PpapiPermissions permissions, |
| 431 const IPC::ChannelHandle& channel_handle, | 438 const IPC::ChannelHandle& channel_handle, |
| 439 base::ProcessId peer_pid, |
| 432 int plugin_child_id) { | 440 int plugin_child_id) { |
| 433 // We don't call PepperPluginRegistry::AddLiveModule, as this module is | 441 // We don't call PepperPluginRegistry::AddLiveModule, as this module is |
| 434 // managed externally. | 442 // managed externally. |
| 435 return CreateOutOfProcessModule(module, | 443 return CreateOutOfProcessModule(module, |
| 436 path, | 444 path, |
| 437 permissions, | 445 permissions, |
| 438 channel_handle, | 446 channel_handle, |
| 447 peer_pid, |
| 439 plugin_child_id, | 448 plugin_child_id, |
| 440 true); // is_external = true | 449 true); // is_external = true |
| 441 } | 450 } |
| 442 | 451 |
| 443 scoped_refptr<PepperBrokerImpl> PepperPluginDelegateImpl::CreateBroker( | 452 scoped_refptr<PepperBrokerImpl> PepperPluginDelegateImpl::CreateBroker( |
| 444 webkit::ppapi::PluginModule* plugin_module) { | 453 webkit::ppapi::PluginModule* plugin_module) { |
| 445 DCHECK(plugin_module); | 454 DCHECK(plugin_module); |
| 446 DCHECK(!plugin_module->GetBroker()); | 455 DCHECK(!plugin_module->GetBroker()); |
| 447 | 456 |
| 448 // The broker path is the same as the plugin. | 457 // The broker path is the same as the plugin. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 465 } | 474 } |
| 466 | 475 |
| 467 return broker; | 476 return broker; |
| 468 } | 477 } |
| 469 | 478 |
| 470 RendererPpapiHost* PepperPluginDelegateImpl::CreateOutOfProcessModule( | 479 RendererPpapiHost* PepperPluginDelegateImpl::CreateOutOfProcessModule( |
| 471 webkit::ppapi::PluginModule* module, | 480 webkit::ppapi::PluginModule* module, |
| 472 const FilePath& path, | 481 const FilePath& path, |
| 473 ppapi::PpapiPermissions permissions, | 482 ppapi::PpapiPermissions permissions, |
| 474 const IPC::ChannelHandle& channel_handle, | 483 const IPC::ChannelHandle& channel_handle, |
| 484 base::ProcessId peer_pid, |
| 475 int plugin_child_id, | 485 int plugin_child_id, |
| 476 bool is_external) { | 486 bool is_external) { |
| 477 scoped_refptr<PepperHungPluginFilter> hung_filter( | 487 scoped_refptr<PepperHungPluginFilter> hung_filter( |
| 478 new PepperHungPluginFilter(path, | 488 new PepperHungPluginFilter(path, |
| 479 render_view_->routing_id(), | 489 render_view_->routing_id(), |
| 480 plugin_child_id)); | 490 plugin_child_id)); |
| 481 scoped_ptr<HostDispatcherWrapper> dispatcher( | 491 scoped_ptr<HostDispatcherWrapper> dispatcher( |
| 482 new HostDispatcherWrapper(module, | 492 new HostDispatcherWrapper(module, |
| 493 peer_pid, |
| 483 plugin_child_id, | 494 plugin_child_id, |
| 484 permissions, | 495 permissions, |
| 485 is_external)); | 496 is_external)); |
| 486 if (!dispatcher->Init( | 497 if (!dispatcher->Init( |
| 487 channel_handle, | 498 channel_handle, |
| 488 webkit::ppapi::PluginModule::GetLocalGetInterfaceFunc(), | 499 webkit::ppapi::PluginModule::GetLocalGetInterfaceFunc(), |
| 489 GetPreferences(), | 500 GetPreferences(), |
| 490 hung_filter.get())) | 501 hung_filter.get())) |
| 491 return NULL; | 502 return NULL; |
| 492 | 503 |
| 493 RendererPpapiHostImpl* host_impl = | 504 RendererPpapiHostImpl* host_impl = |
| 494 RendererPpapiHostImpl::CreateOnModuleForOutOfProcess( | 505 RendererPpapiHostImpl::CreateOnModuleForOutOfProcess( |
| 495 module, dispatcher->dispatcher(), permissions); | 506 module, dispatcher->dispatcher(), permissions); |
| 496 render_view_->PpapiPluginCreated(host_impl); | 507 render_view_->PpapiPluginCreated(host_impl); |
| 497 | 508 |
| 498 module->InitAsProxied(dispatcher.release()); | 509 module->InitAsProxied(dispatcher.release()); |
| 499 return host_impl; | 510 return host_impl; |
| 500 } | 511 } |
| 501 | 512 |
| 502 void PepperPluginDelegateImpl::OnPpapiBrokerChannelCreated( | 513 void PepperPluginDelegateImpl::OnPpapiBrokerChannelCreated( |
| 503 int request_id, | 514 int request_id, |
| 515 base::ProcessId broker_pid, |
| 504 const IPC::ChannelHandle& handle) { | 516 const IPC::ChannelHandle& handle) { |
| 505 scoped_refptr<PepperBrokerImpl>* broker_ptr = | 517 scoped_refptr<PepperBrokerImpl>* broker_ptr = |
| 506 pending_connect_broker_.Lookup(request_id); | 518 pending_connect_broker_.Lookup(request_id); |
| 507 if (broker_ptr) { | 519 if (broker_ptr) { |
| 508 scoped_refptr<PepperBrokerImpl> broker = *broker_ptr; | 520 scoped_refptr<PepperBrokerImpl> broker = *broker_ptr; |
| 509 pending_connect_broker_.Remove(request_id); | 521 pending_connect_broker_.Remove(request_id); |
| 510 broker->OnBrokerChannelConnected(handle); | 522 broker->OnBrokerChannelConnected(broker_pid, handle); |
| 511 } else { | 523 } else { |
| 512 // There is no broker waiting for this channel. Close it so the broker can | 524 // There is no broker waiting for this channel. Close it so the broker can |
| 513 // clean up and possibly exit. | 525 // clean up and possibly exit. |
| 514 // The easiest way to clean it up is to just put it in an object | 526 // The easiest way to clean it up is to just put it in an object |
| 515 // and then close them. This failure case is not performance critical. | 527 // and then close them. This failure case is not performance critical. |
| 516 PepperBrokerDispatcherWrapper temp_dispatcher; | 528 PepperBrokerDispatcherWrapper temp_dispatcher; |
| 517 temp_dispatcher.Init(handle); | 529 temp_dispatcher.Init(broker_pid, handle); |
| 518 } | 530 } |
| 519 } | 531 } |
| 520 | 532 |
| 521 // Iterates through pending_connect_broker_ to find the broker. | 533 // Iterates through pending_connect_broker_ to find the broker. |
| 522 // Cannot use Lookup() directly because pending_connect_broker_ does not store | 534 // Cannot use Lookup() directly because pending_connect_broker_ does not store |
| 523 // the raw pointer to the broker. Assumes maximum of one copy of broker exists. | 535 // the raw pointer to the broker. Assumes maximum of one copy of broker exists. |
| 524 bool PepperPluginDelegateImpl::StopWaitingForBrokerConnection( | 536 bool PepperPluginDelegateImpl::StopWaitingForBrokerConnection( |
| 525 PepperBrokerImpl* broker) { | 537 PepperBrokerImpl* broker) { |
| 526 for (BrokerMap::iterator i(&pending_connect_broker_); | 538 for (BrokerMap::iterator i(&pending_connect_broker_); |
| 527 !i.IsAtEnd(); i.Advance()) { | 539 !i.IsAtEnd(); i.Advance()) { |
| (...skipping 1189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1717 RenderWidgetFullscreenPepper* container = | 1729 RenderWidgetFullscreenPepper* container = |
| 1718 static_cast<RenderWidgetFullscreenPepper*>( | 1730 static_cast<RenderWidgetFullscreenPepper*>( |
| 1719 instance->fullscreen_container()); | 1731 instance->fullscreen_container()); |
| 1720 return container->mouse_lock_dispatcher(); | 1732 return container->mouse_lock_dispatcher(); |
| 1721 } else { | 1733 } else { |
| 1722 return render_view_->mouse_lock_dispatcher(); | 1734 return render_view_->mouse_lock_dispatcher(); |
| 1723 } | 1735 } |
| 1724 } | 1736 } |
| 1725 | 1737 |
| 1726 } // namespace content | 1738 } // namespace content |
| OLD | NEW |