| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/common/child_process_host.h" | 5 #include "chrome/common/child_process_host.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
| 9 #include "base/path_service.h" | 9 #include "base/path_service.h" |
| 10 #include "chrome/common/child_process_info.h" | 10 #include "chrome/common/child_process_info.h" |
| 11 #include "chrome/common/chrome_constants.h" | 11 #include "chrome/common/chrome_constants.h" |
| 12 #include "chrome/common/chrome_paths_internal.h" | 12 #include "chrome/common/chrome_paths_internal.h" |
| 13 #include "chrome/common/chrome_switches.h" | 13 #include "chrome/common/chrome_switches.h" |
| 14 #include "chrome/common/plugin_messages.h" | 14 #include "chrome/common/plugin_messages.h" |
| 15 #include "ipc/ipc_logging.h" | 15 #include "ipc/ipc_logging.h" |
| 16 #include "ipc/ipc_message.h" | |
| 17 | 16 |
| 18 #if defined(OS_LINUX) | 17 #if defined(OS_LINUX) |
| 19 #include "base/linux_util.h" | 18 #include "base/linux_util.h" |
| 20 #endif // OS_LINUX | 19 #endif // OS_LINUX |
| 21 | 20 |
| 22 ChildProcessHost::ChildProcessHost() | 21 ChildProcessHost::ChildProcessHost() |
| 23 : ALLOW_THIS_IN_INITIALIZER_LIST(listener_(this)), | 22 : ALLOW_THIS_IN_INITIALIZER_LIST(listener_(this)), |
| 24 opening_channel_(false) { | 23 opening_channel_(false) { |
| 25 } | 24 } |
| 26 | 25 |
| 27 ChildProcessHost::~ChildProcessHost() { | 26 ChildProcessHost::~ChildProcessHost() { |
| 27 for (size_t i = 0; i < filters_.size(); ++i) { |
| 28 filters_[i]->OnChannelClosing(); |
| 29 filters_[i]->OnFilterRemoved(); |
| 30 } |
| 31 } |
| 32 |
| 33 void ChildProcessHost::AddFilter(IPC::ChannelProxy::MessageFilter* filter) { |
| 34 filters_.push_back(filter); |
| 35 |
| 36 if (channel_.get()) |
| 37 filter->OnFilterAdded(channel_.get()); |
| 28 } | 38 } |
| 29 | 39 |
| 30 // static | 40 // static |
| 31 FilePath ChildProcessHost::GetChildPath(bool allow_self) { | 41 FilePath ChildProcessHost::GetChildPath(bool allow_self) { |
| 32 FilePath child_path; | 42 FilePath child_path; |
| 33 | 43 |
| 34 child_path = CommandLine::ForCurrentProcess()->GetSwitchValuePath( | 44 child_path = CommandLine::ForCurrentProcess()->GetSwitchValuePath( |
| 35 switches::kBrowserSubprocessPath); | 45 switches::kBrowserSubprocessPath); |
| 36 if (!child_path.empty()) | 46 if (!child_path.empty()) |
| 37 return child_path; | 47 return child_path; |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 #endif // OS_WIN | 112 #endif // OS_WIN |
| 103 | 113 |
| 104 | 114 |
| 105 bool ChildProcessHost::CreateChannel() { | 115 bool ChildProcessHost::CreateChannel() { |
| 106 channel_id_ = ChildProcessInfo::GenerateRandomChannelID(this); | 116 channel_id_ = ChildProcessInfo::GenerateRandomChannelID(this); |
| 107 channel_.reset(new IPC::Channel( | 117 channel_.reset(new IPC::Channel( |
| 108 channel_id_, IPC::Channel::MODE_SERVER, &listener_)); | 118 channel_id_, IPC::Channel::MODE_SERVER, &listener_)); |
| 109 if (!channel_->Connect()) | 119 if (!channel_->Connect()) |
| 110 return false; | 120 return false; |
| 111 | 121 |
| 122 for (size_t i = 0; i < filters_.size(); ++i) |
| 123 filters_[i]->OnFilterAdded(channel_.get()); |
| 124 |
| 112 // Make sure these messages get sent first. | 125 // Make sure these messages get sent first. |
| 113 #if defined(IPC_MESSAGE_LOG_ENABLED) | 126 #if defined(IPC_MESSAGE_LOG_ENABLED) |
| 114 bool enabled = IPC::Logging::GetInstance()->Enabled(); | 127 bool enabled = IPC::Logging::GetInstance()->Enabled(); |
| 115 SendOnChannel(new PluginProcessMsg_SetIPCLoggingEnabled(enabled)); | 128 Send(new PluginProcessMsg_SetIPCLoggingEnabled(enabled)); |
| 116 #endif | 129 #endif |
| 117 | 130 |
| 118 SendOnChannel(new PluginProcessMsg_AskBeforeShutdown()); | 131 Send(new PluginProcessMsg_AskBeforeShutdown()); |
| 119 | 132 |
| 120 opening_channel_ = true; | 133 opening_channel_ = true; |
| 121 | 134 |
| 122 return true; | 135 return true; |
| 123 } | 136 } |
| 124 | 137 |
| 125 void ChildProcessHost::InstanceCreated() { | 138 void ChildProcessHost::InstanceCreated() { |
| 126 Notify(NotificationType::CHILD_INSTANCE_CREATED); | 139 Notify(NotificationType::CHILD_INSTANCE_CREATED); |
| 127 } | 140 } |
| 128 | 141 |
| 129 bool ChildProcessHost::SendOnChannel(IPC::Message* msg) { | 142 bool ChildProcessHost::Send(IPC::Message* message) { |
| 130 if (!channel_.get()) { | 143 if (!channel_.get()) { |
| 131 delete msg; | 144 delete message; |
| 132 return false; | 145 return false; |
| 133 } | 146 } |
| 134 return channel_->Send(msg); | 147 return channel_->Send(message); |
| 135 } | 148 } |
| 136 | 149 |
| 137 void ChildProcessHost::OnChildDied() { | 150 void ChildProcessHost::OnChildDied() { |
| 138 delete this; | 151 delete this; |
| 139 } | 152 } |
| 140 | 153 |
| 141 bool ChildProcessHost::InterceptMessageFromChild(const IPC::Message& msg) { | |
| 142 return false; | |
| 143 } | |
| 144 | |
| 145 ChildProcessHost::ListenerHook::ListenerHook(ChildProcessHost* host) | 154 ChildProcessHost::ListenerHook::ListenerHook(ChildProcessHost* host) |
| 146 : host_(host) { | 155 : host_(host) { |
| 147 } | 156 } |
| 148 | 157 |
| 149 void ChildProcessHost::ListenerHook::OnMessageReceived( | 158 void ChildProcessHost::ListenerHook::OnMessageReceived( |
| 150 const IPC::Message& msg) { | 159 const IPC::Message& msg) { |
| 151 #ifdef IPC_MESSAGE_LOG_ENABLED | 160 #ifdef IPC_MESSAGE_LOG_ENABLED |
| 152 IPC::Logging* logger = IPC::Logging::GetInstance(); | 161 IPC::Logging* logger = IPC::Logging::GetInstance(); |
| 153 if (msg.type() == IPC_LOGGING_ID) { | 162 if (msg.type() == IPC_LOGGING_ID) { |
| 154 logger->OnReceivedLoggingMessage(msg); | 163 logger->OnReceivedLoggingMessage(msg); |
| 155 return; | 164 return; |
| 156 } | 165 } |
| 157 | 166 |
| 158 if (logger->Enabled()) | 167 if (logger->Enabled()) |
| 159 logger->OnPreDispatchMessage(msg); | 168 logger->OnPreDispatchMessage(msg); |
| 160 #endif | 169 #endif |
| 161 | 170 |
| 162 bool handled = host_->InterceptMessageFromChild(msg); | 171 if (msg.type() == PluginProcessHostMsg_ShutdownRequest::ID && |
| 172 host_->CanShutdown()) { |
| 173 host_->Send(new PluginProcessMsg_Shutdown()); |
| 174 } |
| 163 | 175 |
| 164 if (!handled) { | 176 bool handled = false; |
| 165 if (msg.type() == PluginProcessHostMsg_ShutdownRequest::ID) { | 177 for (size_t i = 0; i < host_->filters_.size(); ++i) { |
| 166 if (host_->CanShutdown()) | 178 if (host_->filters_[i]->OnMessageReceived(msg)) { |
| 167 host_->SendOnChannel(new PluginProcessMsg_Shutdown()); | 179 handled = true; |
| 168 } else { | 180 break; |
| 169 host_->OnMessageReceived(msg); | |
| 170 } | 181 } |
| 171 } | 182 } |
| 172 | 183 |
| 184 if (!handled) |
| 185 host_->OnMessageReceived(msg); |
| 186 |
| 173 #ifdef IPC_MESSAGE_LOG_ENABLED | 187 #ifdef IPC_MESSAGE_LOG_ENABLED |
| 174 if (logger->Enabled()) | 188 if (logger->Enabled()) |
| 175 logger->OnPostDispatchMessage(msg, host_->channel_id_); | 189 logger->OnPostDispatchMessage(msg, host_->channel_id_); |
| 176 #endif | 190 #endif |
| 177 } | 191 } |
| 178 | 192 |
| 179 void ChildProcessHost::ListenerHook::OnChannelConnected(int32 peer_pid) { | 193 void ChildProcessHost::ListenerHook::OnChannelConnected(int32 peer_pid) { |
| 180 host_->opening_channel_ = false; | 194 host_->opening_channel_ = false; |
| 181 host_->OnChannelConnected(peer_pid); | 195 host_->OnChannelConnected(peer_pid); |
| 182 // Notify in the main loop of the connection. | 196 // Notify in the main loop of the connection. |
| 183 host_->Notify(NotificationType::CHILD_PROCESS_HOST_CONNECTED); | 197 host_->Notify(NotificationType::CHILD_PROCESS_HOST_CONNECTED); |
| 198 |
| 199 for (size_t i = 0; i < host_->filters_.size(); ++i) |
| 200 host_->filters_[i]->OnChannelConnected(peer_pid); |
| 184 } | 201 } |
| 185 | 202 |
| 186 void ChildProcessHost::ListenerHook::OnChannelError() { | 203 void ChildProcessHost::ListenerHook::OnChannelError() { |
| 187 host_->opening_channel_ = false; | 204 host_->opening_channel_ = false; |
| 188 host_->OnChannelError(); | 205 host_->OnChannelError(); |
| 189 | 206 |
| 207 for (size_t i = 0; i < host_->filters_.size(); ++i) |
| 208 host_->filters_[i]->OnChannelError(); |
| 209 |
| 190 // This will delete host_, which will also destroy this! | 210 // This will delete host_, which will also destroy this! |
| 191 host_->OnChildDied(); | 211 host_->OnChildDied(); |
| 192 } | 212 } |
| 193 | 213 |
| 194 void ChildProcessHost::ForceShutdown() { | 214 void ChildProcessHost::ForceShutdown() { |
| 195 SendOnChannel(new PluginProcessMsg_Shutdown()); | 215 Send(new PluginProcessMsg_Shutdown()); |
| 196 } | 216 } |
| OLD | NEW |