| 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/public/browser/browser_message_filter.h" | 5 #include "content/public/browser/browser_message_filter.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 62 if (runner.get()) { | 62 if (runner.get()) { |
| 63 runner->PostTask( | 63 runner->PostTask( |
| 64 FROM_HERE, | 64 FROM_HERE, |
| 65 base::Bind( | 65 base::Bind( |
| 66 base::IgnoreResult(&Internal::DispatchMessage), this, message)); | 66 base::IgnoreResult(&Internal::DispatchMessage), this, message)); |
| 67 return true; | 67 return true; |
| 68 } | 68 } |
| 69 return DispatchMessage(message); | 69 return DispatchMessage(message); |
| 70 } | 70 } |
| 71 | 71 |
| 72 if (thread == BrowserThread::UI && | |
| 73 !BrowserMessageFilter::CheckCanDispatchOnUI(message, filter_.get())) { | |
| 74 return true; | |
| 75 } | |
| 76 | |
| 77 BrowserThread::PostTask( | 72 BrowserThread::PostTask( |
| 78 thread, FROM_HERE, | 73 thread, FROM_HERE, |
| 79 base::Bind( | 74 base::Bind( |
| 80 base::IgnoreResult(&Internal::DispatchMessage), this, message)); | 75 base::IgnoreResult(&Internal::DispatchMessage), this, message)); |
| 81 return true; | 76 return true; |
| 82 } | 77 } |
| 83 | 78 |
| 84 bool GetSupportedMessageClasses( | 79 bool GetSupportedMessageClasses( |
| 85 std::vector<uint32_t>* supported_message_classes) const override { | 80 std::vector<uint32_t>* supported_message_classes) const override { |
| 86 supported_message_classes->assign( | 81 supported_message_classes->assign( |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 150 | 145 |
| 151 delete message; | 146 delete message; |
| 152 return false; | 147 return false; |
| 153 } | 148 } |
| 154 | 149 |
| 155 base::TaskRunner* BrowserMessageFilter::OverrideTaskRunnerForMessage( | 150 base::TaskRunner* BrowserMessageFilter::OverrideTaskRunnerForMessage( |
| 156 const IPC::Message& message) { | 151 const IPC::Message& message) { |
| 157 return nullptr; | 152 return nullptr; |
| 158 } | 153 } |
| 159 | 154 |
| 160 bool BrowserMessageFilter::CheckCanDispatchOnUI(const IPC::Message& message, | |
| 161 IPC::Sender* sender) { | |
| 162 #if defined(OS_WIN) | |
| 163 // On Windows there's a potential deadlock with sync messsages going in | |
| 164 // a circle from browser -> plugin -> renderer -> browser. | |
| 165 // On Linux we can avoid this by avoiding sync messages from browser->plugin. | |
| 166 // On Mac we avoid this by not supporting windowed plugins. | |
| 167 if (message.is_sync() && !message.is_caller_pumping_messages()) { | |
| 168 // NOTE: IF YOU HIT THIS ASSERT, THE SOLUTION IS ALMOST NEVER TO RUN A | |
| 169 // NESTED MESSAGE LOOP IN THE RENDERER!!! | |
| 170 // That introduces reentrancy which causes hard to track bugs. You should | |
| 171 // find a way to either turn this into an asynchronous message, or one | |
| 172 // that can be answered on the IO thread. | |
| 173 NOTREACHED() << "Can't send sync messages to UI thread without pumping " | |
| 174 "messages in the renderer or else deadlocks can occur if the page " | |
| 175 "has windowed plugins! (message type " << message.type() << ")"; | |
| 176 IPC::Message* reply = IPC::SyncMessage::GenerateReply(&message); | |
| 177 reply->set_reply_error(); | |
| 178 sender->Send(reply); | |
| 179 return false; | |
| 180 } | |
| 181 #endif | |
| 182 return true; | |
| 183 } | |
| 184 | |
| 185 void BrowserMessageFilter::ShutdownForBadMessage() { | 155 void BrowserMessageFilter::ShutdownForBadMessage() { |
| 186 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | 156 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
| 187 if (command_line->HasSwitch(switches::kDisableKillAfterBadIPC)) | 157 if (command_line->HasSwitch(switches::kDisableKillAfterBadIPC)) |
| 188 return; | 158 return; |
| 189 | 159 |
| 190 BrowserChildProcessHostImpl::HistogramBadMessageTerminated( | 160 BrowserChildProcessHostImpl::HistogramBadMessageTerminated( |
| 191 PROCESS_TYPE_RENDERER); | 161 PROCESS_TYPE_RENDERER); |
| 192 | 162 |
| 193 #if defined(OS_ANDROID) | 163 #if defined(OS_ANDROID) |
| 194 // Android requires a different approach for killing. | 164 // Android requires a different approach for killing. |
| 195 StopChildProcess(peer_process_.Handle()); | 165 StopChildProcess(peer_process_.Handle()); |
| 196 #else | 166 #else |
| 197 peer_process_.Terminate(content::RESULT_CODE_KILLED_BAD_MESSAGE, false); | 167 peer_process_.Terminate(content::RESULT_CODE_KILLED_BAD_MESSAGE, false); |
| 198 #endif | 168 #endif |
| 199 } | 169 } |
| 200 | 170 |
| 201 BrowserMessageFilter::~BrowserMessageFilter() { | 171 BrowserMessageFilter::~BrowserMessageFilter() { |
| 202 } | 172 } |
| 203 | 173 |
| 204 IPC::MessageFilter* BrowserMessageFilter::GetFilter() { | 174 IPC::MessageFilter* BrowserMessageFilter::GetFilter() { |
| 205 // We create this on demand so that if a filter is used in a unit test but | 175 // We create this on demand so that if a filter is used in a unit test but |
| 206 // never attached to a channel, we don't leak Internal and this; | 176 // never attached to a channel, we don't leak Internal and this; |
| 207 DCHECK(!internal_) << "Should only be called once."; | 177 DCHECK(!internal_) << "Should only be called once."; |
| 208 internal_ = new Internal(this); | 178 internal_ = new Internal(this); |
| 209 return internal_; | 179 return internal_; |
| 210 } | 180 } |
| 211 | 181 |
| 212 } // namespace content | 182 } // namespace content |
| OLD | NEW |