license.bot | bf09a50 | 2008-08-24 00:55:55 | [diff] [blame] | 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 |
| 3 | // found in the LICENSE file. |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 4 | |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 5 | #include "chrome/plugin/plugin_channel.h" |
| 6 | |
[email protected] | bf24d2c | 2009-02-24 23:07:45 | [diff] [blame] | 7 | #include "base/command_line.h" |
[email protected] | 4566f13 | 2009-03-12 01:55:13 | [diff] [blame] | 8 | #include "base/process_util.h" |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 9 | #include "base/string_util.h" |
[email protected] | 51d70e0 | 2009-03-27 20:45:59 | [diff] [blame] | 10 | #include "chrome/common/child_process.h" |
| 11 | #include "chrome/common/plugin_messages.h" |
[email protected] | bf24d2c | 2009-02-24 23:07:45 | [diff] [blame] | 12 | #include "chrome/common/chrome_switches.h" |
[email protected] | 8930d47 | 2009-02-21 08:05:28 | [diff] [blame] | 13 | #include "chrome/plugin/plugin_thread.h" |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 14 | |
[email protected] | fa6caa4 | 2009-06-05 05:35:07 | [diff] [blame^] | 15 | PluginChannel* PluginChannel::GetPluginChannel( |
| 16 | int process_id, MessageLoop* ipc_message_loop) { |
| 17 | // map renderer's process id to a (single) channel to that process |
[email protected] | 9a3a293b | 2009-06-04 22:28:16 | [diff] [blame] | 18 | std::string channel_name = StringPrintf( |
[email protected] | fa6caa4 | 2009-06-05 05:35:07 | [diff] [blame^] | 19 | "%d.r%d", base::GetCurrentProcId(), process_id); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 20 | |
[email protected] | 4566f13 | 2009-03-12 01:55:13 | [diff] [blame] | 21 | return static_cast<PluginChannel*>(PluginChannelBase::GetChannel( |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 22 | channel_name, |
| 23 | IPC::Channel::MODE_SERVER, |
| 24 | ClassFactory, |
| 25 | ipc_message_loop, |
[email protected] | 4566f13 | 2009-03-12 01:55:13 | [diff] [blame] | 26 | false)); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 27 | } |
| 28 | |
[email protected] | 157e5d2 | 2009-04-23 18:43:35 | [diff] [blame] | 29 | PluginChannel::PluginChannel() : renderer_handle_(0), in_send_(0), |
| 30 | off_the_record_(false) { |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 31 | SendUnblockingOnlyDuringDispatch(); |
[email protected] | 51d70e0 | 2009-03-27 20:45:59 | [diff] [blame] | 32 | ChildProcess::current()->AddRefProcess(); |
[email protected] | bf24d2c | 2009-02-24 23:07:45 | [diff] [blame] | 33 | const CommandLine* command_line = CommandLine::ForCurrentProcess(); |
| 34 | log_messages_ = command_line->HasSwitch(switches::kLogPluginMessages); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 35 | } |
| 36 | |
| 37 | PluginChannel::~PluginChannel() { |
[email protected] | 157e5d2 | 2009-04-23 18:43:35 | [diff] [blame] | 38 | if (renderer_handle_) |
| 39 | base::CloseProcessHandle(renderer_handle_); |
[email protected] | 51d70e0 | 2009-03-27 20:45:59 | [diff] [blame] | 40 | ChildProcess::current()->ReleaseProcess(); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 41 | } |
| 42 | |
| 43 | bool PluginChannel::Send(IPC::Message* msg) { |
| 44 | in_send_++; |
[email protected] | bf24d2c | 2009-02-24 23:07:45 | [diff] [blame] | 45 | if (log_messages_) { |
| 46 | LOG(INFO) << "sending message @" << msg << " on channel @" << this |
| 47 | << " with type " << msg->type(); |
| 48 | } |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 49 | bool result = PluginChannelBase::Send(msg); |
| 50 | in_send_--; |
| 51 | return result; |
| 52 | } |
| 53 | |
[email protected] | bf24d2c | 2009-02-24 23:07:45 | [diff] [blame] | 54 | void PluginChannel::OnMessageReceived(const IPC::Message& msg) { |
| 55 | if (log_messages_) { |
| 56 | LOG(INFO) << "received message @" << &msg << " on channel @" << this |
| 57 | << " with type " << msg.type(); |
| 58 | } |
| 59 | PluginChannelBase::OnMessageReceived(msg); |
| 60 | } |
| 61 | |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 62 | void PluginChannel::OnControlMessageReceived(const IPC::Message& msg) { |
| 63 | IPC_BEGIN_MESSAGE_MAP(PluginChannel, msg) |
| 64 | IPC_MESSAGE_HANDLER(PluginMsg_CreateInstance, OnCreateInstance) |
[email protected] | f09c718 | 2009-03-10 12:54:04 | [diff] [blame] | 65 | IPC_MESSAGE_HANDLER_DELAY_REPLY(PluginMsg_DestroyInstance, |
| 66 | OnDestroyInstance) |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 67 | IPC_MESSAGE_HANDLER(PluginMsg_GenerateRouteID, OnGenerateRouteID) |
| 68 | IPC_MESSAGE_UNHANDLED_ERROR() |
| 69 | IPC_END_MESSAGE_MAP() |
| 70 | } |
| 71 | |
| 72 | void PluginChannel::OnCreateInstance(const std::string& mime_type, |
| 73 | int* instance_id) { |
| 74 | *instance_id = GenerateRouteID(); |
| 75 | scoped_refptr<WebPluginDelegateStub> stub = new WebPluginDelegateStub( |
| 76 | mime_type, *instance_id, this); |
| 77 | AddRoute(*instance_id, stub, false); |
| 78 | plugin_stubs_.push_back(stub); |
| 79 | } |
| 80 | |
| 81 | void PluginChannel::OnDestroyInstance(int instance_id, |
| 82 | IPC::Message* reply_msg) { |
| 83 | for (size_t i = 0; i < plugin_stubs_.size(); ++i) { |
| 84 | if (plugin_stubs_[i]->instance_id() == instance_id) { |
| 85 | plugin_stubs_.erase(plugin_stubs_.begin() + i); |
| 86 | RemoveRoute(instance_id); |
| 87 | Send(reply_msg); |
| 88 | return; |
| 89 | } |
| 90 | } |
| 91 | |
| 92 | NOTREACHED() << "Couldn't find WebPluginDelegateStub to destroy"; |
| 93 | } |
| 94 | |
| 95 | void PluginChannel::OnGenerateRouteID(int* route_id) { |
| 96 | *route_id = GenerateRouteID(); |
| 97 | } |
| 98 | |
| 99 | int PluginChannel::GenerateRouteID() { |
[email protected] | 157e5d2 | 2009-04-23 18:43:35 | [diff] [blame] | 100 | static int last_id = 0; |
| 101 | return ++last_id; |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 102 | } |
| 103 | |
[email protected] | 4566f13 | 2009-03-12 01:55:13 | [diff] [blame] | 104 | void PluginChannel::OnChannelConnected(int32 peer_pid) { |
[email protected] | 6c6cc80 | 2009-04-03 17:01:36 | [diff] [blame] | 105 | base::ProcessHandle handle; |
| 106 | if (!base::OpenProcessHandle(peer_pid, &handle)) { |
| 107 | NOTREACHED(); |
| 108 | } |
[email protected] | 157e5d2 | 2009-04-23 18:43:35 | [diff] [blame] | 109 | renderer_handle_ = handle; |
[email protected] | 4566f13 | 2009-03-12 01:55:13 | [diff] [blame] | 110 | PluginChannelBase::OnChannelConnected(peer_pid); |
| 111 | } |
| 112 | |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 113 | void PluginChannel::OnChannelError() { |
[email protected] | 157e5d2 | 2009-04-23 18:43:35 | [diff] [blame] | 114 | base::CloseProcessHandle(renderer_handle_); |
| 115 | renderer_handle_ = 0; |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 116 | PluginChannelBase::OnChannelError(); |
| 117 | CleanUp(); |
| 118 | } |
| 119 | |
| 120 | void PluginChannel::CleanUp() { |
| 121 | // We need to clean up the stubs so that they call NPPDestroy. This will |
| 122 | // also lead to them releasing their reference on this object so that it can |
| 123 | // be deleted. |
| 124 | for (size_t i = 0; i < plugin_stubs_.size(); ++i) |
| 125 | RemoveRoute(plugin_stubs_[i]->instance_id()); |
| 126 | |
| 127 | // Need to addref this object temporarily because otherwise removing the last |
| 128 | // stub will cause the destructor of this object to be called, however at |
| 129 | // that point plugin_stubs_ will have one element and its destructor will be |
| 130 | // called twice. |
| 131 | scoped_refptr<PluginChannel> me(this); |
| 132 | |
| 133 | plugin_stubs_.clear(); |
license.bot | bf09a50 | 2008-08-24 00:55:55 | [diff] [blame] | 134 | } |