| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 "chrome/browser/plugin_process_host.h" | 5 #include "chrome/browser/plugin_process_host.h" |
| 6 | 6 |
| 7 #include <windows.h> | 7 #include <windows.h> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| (...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 350 virtual void Run() { | 350 virtual void Run() { |
| 351 DestroyWindow(window_); | 351 DestroyWindow(window_); |
| 352 TRACK_HWND_DESTRUCTION(window_); | 352 TRACK_HWND_DESTRUCTION(window_); |
| 353 } | 353 } |
| 354 | 354 |
| 355 private: | 355 private: |
| 356 HWND window_; | 356 HWND window_; |
| 357 }; | 357 }; |
| 358 | 358 |
| 359 | 359 |
| 360 PluginProcessHost::PluginProcessHost(PluginService* plugin_service) | 360 PluginProcessHost::PluginProcessHost() |
| 361 : opening_channel_(false), | 361 : ChildProcessInfo(PLUGIN_PROCESS), |
| 362 resource_dispatcher_host_(plugin_service->resource_dispatcher_host()), | 362 opening_channel_(false), |
| 363 ALLOW_THIS_IN_INITIALIZER_LIST(resolve_proxy_msg_helper_(this, NULL)), | 363 ALLOW_THIS_IN_INITIALIZER_LIST(resolve_proxy_msg_helper_(this, NULL)) { |
| 364 plugin_service_(plugin_service) { | |
| 365 DCHECK(resource_dispatcher_host_); | |
| 366 set_type(PLUGIN_PROCESS); | |
| 367 } | 364 } |
| 368 | 365 |
| 369 PluginProcessHost::~PluginProcessHost() { | 366 PluginProcessHost::~PluginProcessHost() { |
| 370 if (process().handle()) { | 367 if (process().handle()) { |
| 371 watcher_.StopWatching(); | 368 watcher_.StopWatching(); |
| 372 ProcessWatcher::EnsureProcessTerminated(process().handle()); | 369 ProcessWatcher::EnsureProcessTerminated(process().handle()); |
| 373 } | 370 } |
| 374 } | 371 } |
| 375 | 372 |
| 376 bool PluginProcessHost::Init(const WebPluginInfo& info, | 373 bool PluginProcessHost::Init(const WebPluginInfo& info, |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 439 } | 436 } |
| 440 | 437 |
| 441 if (!locale.empty()) { | 438 if (!locale.empty()) { |
| 442 // Pass on the locale so the null plugin will use the right language in the | 439 // Pass on the locale so the null plugin will use the right language in the |
| 443 // prompt to install the desired plugin. | 440 // prompt to install the desired plugin. |
| 444 cmd_line.AppendSwitchWithValue(switches::kLang, locale); | 441 cmd_line.AppendSwitchWithValue(switches::kLang, locale); |
| 445 } | 442 } |
| 446 | 443 |
| 447 // Gears requires the data dir to be available on startup. | 444 // Gears requires the data dir to be available on startup. |
| 448 std::wstring data_dir = | 445 std::wstring data_dir = |
| 449 plugin_service_->GetChromePluginDataDir().ToWStringHack(); | 446 PluginService::GetInstance()->GetChromePluginDataDir().ToWStringHack(); |
| 450 DCHECK(!data_dir.empty()); | 447 DCHECK(!data_dir.empty()); |
| 451 cmd_line.AppendSwitchWithValue(switches::kPluginDataDir, data_dir); | 448 cmd_line.AppendSwitchWithValue(switches::kPluginDataDir, data_dir); |
| 452 | 449 |
| 453 cmd_line.AppendSwitchWithValue(switches::kProcessType, | 450 cmd_line.AppendSwitchWithValue(switches::kProcessType, |
| 454 switches::kPluginProcess); | 451 switches::kPluginProcess); |
| 455 | 452 |
| 456 cmd_line.AppendSwitchWithValue(switches::kProcessChannelID, | 453 cmd_line.AppendSwitchWithValue(switches::kProcessChannelID, |
| 457 channel_id_); | 454 channel_id_); |
| 458 | 455 |
| 459 cmd_line.AppendSwitchWithValue(switches::kPluginPath, | 456 cmd_line.AppendSwitchWithValue(switches::kPluginPath, |
| 460 info.path.ToWStringHack()); | 457 info.path.ToWStringHack()); |
| 461 | 458 |
| 462 bool in_sandbox = !browser_command_line.HasSwitch(switches::kNoSandbox) && | 459 bool in_sandbox = !browser_command_line.HasSwitch(switches::kNoSandbox) && |
| 463 browser_command_line.HasSwitch(switches::kSafePlugins); | 460 browser_command_line.HasSwitch(switches::kSafePlugins); |
| 464 | 461 |
| 465 bool child_needs_help = | 462 bool child_needs_help = |
| 466 DebugFlags::ProcessDebugFlags(&cmd_line, DebugFlags::PLUGIN, in_sandbox); | 463 DebugFlags::ProcessDebugFlags(&cmd_line, type(), in_sandbox); |
| 467 | 464 |
| 468 if (in_sandbox) { | 465 if (in_sandbox) { |
| 469 // spawn the child process in the sandbox | 466 // spawn the child process in the sandbox |
| 470 sandbox::BrokerServices* broker_service = | 467 sandbox::BrokerServices* broker_service = |
| 471 g_browser_process->broker_services(); | 468 g_browser_process->broker_services(); |
| 472 | 469 |
| 473 sandbox::ResultCode result; | 470 sandbox::ResultCode result; |
| 474 PROCESS_INFORMATION target = {0}; | 471 PROCESS_INFORMATION target = {0}; |
| 475 sandbox::TargetPolicy* policy = broker_service->CreatePolicy(); | 472 sandbox::TargetPolicy* policy = broker_service->CreatePolicy(); |
| 476 | 473 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 540 | 537 |
| 541 // indicates the plugin process has exited | 538 // indicates the plugin process has exited |
| 542 void PluginProcessHost::OnObjectSignaled(HANDLE object) { | 539 void PluginProcessHost::OnObjectSignaled(HANDLE object) { |
| 543 DCHECK(process().handle()); | 540 DCHECK(process().handle()); |
| 544 DCHECK_EQ(object, process().handle()); | 541 DCHECK_EQ(object, process().handle()); |
| 545 | 542 |
| 546 bool did_crash = base::DidProcessCrash(object); | 543 bool did_crash = base::DidProcessCrash(object); |
| 547 | 544 |
| 548 if (did_crash) { | 545 if (did_crash) { |
| 549 // Report that this plugin crashed. | 546 // Report that this plugin crashed. |
| 550 plugin_service_->main_message_loop()->PostTask(FROM_HERE, | 547 PluginService::GetInstance()->main_message_loop()->PostTask( |
| 551 new PluginNotificationTask( | 548 FROM_HERE, new PluginNotificationTask( |
| 552 NotificationType::CHILD_PROCESS_CRASHED, this)); | 549 NotificationType::CHILD_PROCESS_CRASHED, this)); |
| 553 } | 550 } |
| 554 // Notify in the main loop of the disconnection. | 551 // Notify in the main loop of the disconnection. |
| 555 plugin_service_->main_message_loop()->PostTask(FROM_HERE, | 552 PluginService::GetInstance()->main_message_loop()->PostTask( |
| 556 new PluginNotificationTask( | 553 FROM_HERE, new PluginNotificationTask( |
| 557 NotificationType::CHILD_PROCESS_HOST_DISCONNECTED, this)); | 554 NotificationType::CHILD_PROCESS_HOST_DISCONNECTED, this)); |
| 558 | 555 |
| 559 // Cancel all requests for plugin processes. | 556 // Cancel all requests for plugin processes. |
| 560 // TODO(mpcomplete): use a real process ID when http://b/issue?id=1210062 is | 557 // TODO(mpcomplete): use a real process ID when http://b/issue?id=1210062 is |
| 561 // fixed. | 558 // fixed. |
| 562 resource_dispatcher_host_->CancelRequestsForProcess(-1); | 559 PluginService::GetInstance()->resource_dispatcher_host()-> |
| 560 CancelRequestsForProcess(-1); |
| 563 | 561 |
| 564 // This next line will delete this. It should be kept at the end of the | 562 delete this; |
| 565 // method. | |
| 566 plugin_service_->OnPluginProcessExited(this); | |
| 567 } | 563 } |
| 568 | 564 |
| 569 | 565 |
| 570 void PluginProcessHost::OnMessageReceived(const IPC::Message& msg) { | 566 void PluginProcessHost::OnMessageReceived(const IPC::Message& msg) { |
| 571 #ifdef IPC_MESSAGE_LOG_ENABLED | 567 #ifdef IPC_MESSAGE_LOG_ENABLED |
| 572 IPC::Logging* logger = IPC::Logging::current(); | 568 IPC::Logging* logger = IPC::Logging::current(); |
| 573 if (msg.type() == IPC_LOGGING_ID) { | 569 if (msg.type() == IPC_LOGGING_ID) { |
| 574 logger->OnReceivedLoggingMessage(msg); | 570 logger->OnReceivedLoggingMessage(msg); |
| 575 return; | 571 return; |
| 576 } | 572 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 614 | 610 |
| 615 for (size_t i = 0; i < pending_requests_.size(); ++i) { | 611 for (size_t i = 0; i < pending_requests_.size(); ++i) { |
| 616 RequestPluginChannel(pending_requests_[i].renderer_message_filter_.get(), | 612 RequestPluginChannel(pending_requests_[i].renderer_message_filter_.get(), |
| 617 pending_requests_[i].mime_type, | 613 pending_requests_[i].mime_type, |
| 618 pending_requests_[i].reply_msg); | 614 pending_requests_[i].reply_msg); |
| 619 } | 615 } |
| 620 | 616 |
| 621 pending_requests_.clear(); | 617 pending_requests_.clear(); |
| 622 | 618 |
| 623 // Notify in the main loop of the connection. | 619 // Notify in the main loop of the connection. |
| 624 plugin_service_->main_message_loop()->PostTask(FROM_HERE, | 620 PluginService::GetInstance()->main_message_loop()->PostTask( |
| 625 new PluginNotificationTask( | 621 FROM_HERE, new PluginNotificationTask( |
| 626 NotificationType::CHILD_PROCESS_HOST_CONNECTED, this)); | 622 NotificationType::CHILD_PROCESS_HOST_CONNECTED, this)); |
| 627 } | 623 } |
| 628 | 624 |
| 629 void PluginProcessHost::OnChannelError() { | 625 void PluginProcessHost::OnChannelError() { |
| 630 opening_channel_ = false; | 626 opening_channel_ = false; |
| 631 for (size_t i = 0; i < pending_requests_.size(); ++i) { | 627 for (size_t i = 0; i < pending_requests_.size(); ++i) { |
| 632 ReplyToRenderer(pending_requests_[i].renderer_message_filter_.get(), | 628 ReplyToRenderer(pending_requests_[i].renderer_message_filter_.get(), |
| 633 std::wstring(), | 629 std::wstring(), |
| 634 FilePath(), | 630 FilePath(), |
| 635 pending_requests_[i].reply_msg); | 631 pending_requests_[i].reply_msg); |
| 636 } | 632 } |
| 637 | 633 |
| 638 pending_requests_.clear(); | 634 pending_requests_.clear(); |
| 639 } | 635 } |
| 640 | 636 |
| 641 void PluginProcessHost::OpenChannelToPlugin( | 637 void PluginProcessHost::OpenChannelToPlugin( |
| 642 ResourceMessageFilter* renderer_message_filter, | 638 ResourceMessageFilter* renderer_message_filter, |
| 643 const std::string& mime_type, | 639 const std::string& mime_type, |
| 644 IPC::Message* reply_msg) { | 640 IPC::Message* reply_msg) { |
| 645 // Notify in the main loop of the instantiation. | 641 // Notify in the main loop of the instantiation. |
| 646 plugin_service_->main_message_loop()->PostTask(FROM_HERE, | 642 PluginService::GetInstance()->main_message_loop()->PostTask( |
| 647 new PluginNotificationTask( | 643 FROM_HERE, new PluginNotificationTask( |
| 648 NotificationType::CHILD_INSTANCE_CREATED, this)); | 644 NotificationType::CHILD_INSTANCE_CREATED, this)); |
| 649 | 645 |
| 650 if (opening_channel_) { | 646 if (opening_channel_) { |
| 651 pending_requests_.push_back( | 647 pending_requests_.push_back( |
| 652 ChannelRequest(renderer_message_filter, mime_type, reply_msg)); | 648 ChannelRequest(renderer_message_filter, mime_type, reply_msg)); |
| 653 return; | 649 return; |
| 654 } | 650 } |
| 655 | 651 |
| 656 if (!channel_.get()) { | 652 if (!channel_.get()) { |
| 657 // There was an error opening the channel, tell the renderer. | 653 // There was an error opening the channel, tell the renderer. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 671 // TODO(mpcomplete): we need a "process_id" mostly for a unique identifier. | 667 // TODO(mpcomplete): we need a "process_id" mostly for a unique identifier. |
| 672 // We should decouple the idea of a render_process_host_id from the unique ID | 668 // We should decouple the idea of a render_process_host_id from the unique ID |
| 673 // in ResourceDispatcherHost. | 669 // in ResourceDispatcherHost. |
| 674 int render_process_host_id = -1; | 670 int render_process_host_id = -1; |
| 675 URLRequestContext* context = CPBrowsingContextManager::Instance()-> | 671 URLRequestContext* context = CPBrowsingContextManager::Instance()-> |
| 676 ToURLRequestContext(request.request_context); | 672 ToURLRequestContext(request.request_context); |
| 677 // TODO(mpcomplete): remove fallback case when Gears support is prevalent. | 673 // TODO(mpcomplete): remove fallback case when Gears support is prevalent. |
| 678 if (!context) | 674 if (!context) |
| 679 context = Profile::GetDefaultRequestContext(); | 675 context = Profile::GetDefaultRequestContext(); |
| 680 | 676 |
| 681 resource_dispatcher_host_->BeginRequest(this, | 677 PluginService::GetInstance()->resource_dispatcher_host()-> |
| 682 process().handle(), | 678 BeginRequest(this, process().handle(), render_process_host_id, |
| 683 render_process_host_id, | 679 MSG_ROUTING_CONTROL, request_id, request, context, NULL); |
| 684 MSG_ROUTING_CONTROL, | |
| 685 request_id, | |
| 686 request, | |
| 687 context, | |
| 688 NULL); | |
| 689 } | 680 } |
| 690 | 681 |
| 691 void PluginProcessHost::OnCancelRequest(int request_id) { | 682 void PluginProcessHost::OnCancelRequest(int request_id) { |
| 692 int render_process_host_id = -1; | 683 int render_process_host_id = -1; |
| 693 resource_dispatcher_host_->CancelRequest(render_process_host_id, | 684 PluginService::GetInstance()->resource_dispatcher_host()-> |
| 694 request_id, true); | 685 CancelRequest(render_process_host_id, request_id, true); |
| 695 } | 686 } |
| 696 | 687 |
| 697 void PluginProcessHost::OnDataReceivedACK(int request_id) { | 688 void PluginProcessHost::OnDataReceivedACK(int request_id) { |
| 698 int render_process_host_id = -1; | 689 int render_process_host_id = -1; |
| 699 resource_dispatcher_host_->OnDataReceivedACK(render_process_host_id, | 690 PluginService::GetInstance()->resource_dispatcher_host()-> |
| 700 request_id); | 691 OnDataReceivedACK(render_process_host_id, request_id); |
| 701 } | 692 } |
| 702 | 693 |
| 703 void PluginProcessHost::OnUploadProgressACK(int request_id) { | 694 void PluginProcessHost::OnUploadProgressACK(int request_id) { |
| 704 int render_process_host_id = -1; | 695 int render_process_host_id = -1; |
| 705 resource_dispatcher_host_->OnUploadProgressACK(render_process_host_id, | 696 PluginService::GetInstance()->resource_dispatcher_host()-> |
| 706 request_id); | 697 OnUploadProgressACK(render_process_host_id, request_id); |
| 707 } | 698 } |
| 708 | 699 |
| 709 void PluginProcessHost::OnSyncLoad( | 700 void PluginProcessHost::OnSyncLoad( |
| 710 int request_id, | 701 int request_id, |
| 711 const ViewHostMsg_Resource_Request& request, | 702 const ViewHostMsg_Resource_Request& request, |
| 712 IPC::Message* sync_result) { | 703 IPC::Message* sync_result) { |
| 713 int render_process_host_id = -1; | 704 int render_process_host_id = -1; |
| 714 URLRequestContext* context = CPBrowsingContextManager::Instance()-> | 705 URLRequestContext* context = CPBrowsingContextManager::Instance()-> |
| 715 ToURLRequestContext(request.request_context); | 706 ToURLRequestContext(request.request_context); |
| 716 // TODO(mpcomplete): remove fallback case when Gears support is prevalent. | 707 // TODO(mpcomplete): remove fallback case when Gears support is prevalent. |
| 717 if (!context) | 708 if (!context) |
| 718 context = Profile::GetDefaultRequestContext(); | 709 context = Profile::GetDefaultRequestContext(); |
| 719 | 710 |
| 720 resource_dispatcher_host_->BeginRequest(this, | 711 PluginService::GetInstance()->resource_dispatcher_host()-> |
| 721 process().handle(), | 712 BeginRequest(this, process().handle(), render_process_host_id, |
| 722 render_process_host_id, | 713 MSG_ROUTING_CONTROL, request_id, request, context, |
| 723 MSG_ROUTING_CONTROL, | 714 sync_result); |
| 724 request_id, | |
| 725 request, | |
| 726 context, | |
| 727 sync_result); | |
| 728 } | 715 } |
| 729 | 716 |
| 730 void PluginProcessHost::OnGetCookies(uint32 request_context, | 717 void PluginProcessHost::OnGetCookies(uint32 request_context, |
| 731 const GURL& url, | 718 const GURL& url, |
| 732 std::string* cookies) { | 719 std::string* cookies) { |
| 733 URLRequestContext* context = CPBrowsingContextManager::Instance()-> | 720 URLRequestContext* context = CPBrowsingContextManager::Instance()-> |
| 734 ToURLRequestContext(request_context); | 721 ToURLRequestContext(request_context); |
| 735 // TODO(mpcomplete): remove fallback case when Gears support is prevalent. | 722 // TODO(mpcomplete): remove fallback case when Gears support is prevalent. |
| 736 if (!context) | 723 if (!context) |
| 737 context = Profile::GetDefaultRequestContext(); | 724 context = Profile::GetDefaultRequestContext(); |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 830 *plugin_finder_url = kDefaultPluginFinderURL; | 817 *plugin_finder_url = kDefaultPluginFinderURL; |
| 831 } | 818 } |
| 832 | 819 |
| 833 void PluginProcessHost::OnPluginShutdownRequest() { | 820 void PluginProcessHost::OnPluginShutdownRequest() { |
| 834 DCHECK(MessageLoop::current() == | 821 DCHECK(MessageLoop::current() == |
| 835 ChromeThread::GetMessageLoop(ChromeThread::IO)); | 822 ChromeThread::GetMessageLoop(ChromeThread::IO)); |
| 836 | 823 |
| 837 // If we have pending channel open requests from the renderers, then | 824 // If we have pending channel open requests from the renderers, then |
| 838 // refuse the shutdown request from the plugin process. | 825 // refuse the shutdown request from the plugin process. |
| 839 bool ok_to_shutdown = sent_requests_.empty(); | 826 bool ok_to_shutdown = sent_requests_.empty(); |
| 840 | |
| 841 if (ok_to_shutdown) | |
| 842 plugin_service_->OnPluginProcessIsShuttingDown(this); | |
| 843 | |
| 844 Send(new PluginProcessMsg_ShutdownResponse(ok_to_shutdown)); | 827 Send(new PluginProcessMsg_ShutdownResponse(ok_to_shutdown)); |
| 845 } | 828 } |
| 846 | 829 |
| 847 void PluginProcessHost::OnPluginMessage( | 830 void PluginProcessHost::OnPluginMessage( |
| 848 const std::vector<uint8>& data) { | 831 const std::vector<uint8>& data) { |
| 849 DCHECK(MessageLoop::current() == | 832 DCHECK(MessageLoop::current() == |
| 850 ChromeThread::GetMessageLoop(ChromeThread::IO)); | 833 ChromeThread::GetMessageLoop(ChromeThread::IO)); |
| 851 | 834 |
| 852 ChromePluginLib *chrome_plugin = ChromePluginLib::Find(info_.path); | 835 ChromePluginLib *chrome_plugin = ChromePluginLib::Find(info_.path); |
| 853 if (chrome_plugin) { | 836 if (chrome_plugin) { |
| 854 void *data_ptr = const_cast<void*>(reinterpret_cast<const void*>(&data[0])); | 837 void *data_ptr = const_cast<void*>(reinterpret_cast<const void*>(&data[0])); |
| 855 uint32 data_len = static_cast<uint32>(data.size()); | 838 uint32 data_len = static_cast<uint32>(data.size()); |
| 856 chrome_plugin->functions().on_message(data_ptr, data_len); | 839 chrome_plugin->functions().on_message(data_ptr, data_len); |
| 857 } | 840 } |
| 858 } | 841 } |
| 859 | 842 |
| 860 void PluginProcessHost::OnCreateWindow(HWND parent, IPC::Message* reply_msg) { | 843 void PluginProcessHost::OnCreateWindow(HWND parent, IPC::Message* reply_msg) { |
| 861 // Need to create this window on the UI thread. | 844 // Need to create this window on the UI thread. |
| 862 plugin_service_->main_message_loop()->PostTask(FROM_HERE, | 845 PluginService::GetInstance()->main_message_loop()->PostTask( |
| 863 new CreateWindowTask(info_.path, parent, reply_msg)); | 846 FROM_HERE, new CreateWindowTask(info_.path, parent, reply_msg)); |
| 864 } | 847 } |
| 865 | 848 |
| 866 void PluginProcessHost::OnDestroyWindow(HWND window) { | 849 void PluginProcessHost::OnDestroyWindow(HWND window) { |
| 867 plugin_service_->main_message_loop()->PostTask(FROM_HERE, | 850 PluginService::GetInstance()->main_message_loop()->PostTask( |
| 868 new DestroyWindowTask(window)); | 851 FROM_HERE, new DestroyWindowTask(window)); |
| 869 } | 852 } |
| 870 | 853 |
| 871 void PluginProcessHost::Shutdown() { | 854 void PluginProcessHost::Shutdown() { |
| 872 | |
| 873 Send(new PluginProcessMsg_BrowserShutdown); | 855 Send(new PluginProcessMsg_BrowserShutdown); |
| 874 } | 856 } |
| OLD | NEW |