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 |