| 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/browser/devtools/render_view_devtools_agent_host.h" | 5 #include "content/browser/devtools/render_view_devtools_agent_host.h" |
| 6 | 6 |
| 7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/lazy_instance.h" | 8 #include "base/lazy_instance.h" |
| 9 #include "content/browser/child_process_security_policy_impl.h" | 9 #include "content/browser/child_process_security_policy_impl.h" |
| 10 #include "content/browser/devtools/devtools_manager_impl.h" | 10 #include "content/browser/devtools/devtools_manager_impl.h" |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 typedef std::vector<RenderViewDevToolsAgentHost*> Instances; | 35 typedef std::vector<RenderViewDevToolsAgentHost*> Instances; |
| 36 | 36 |
| 37 namespace { | 37 namespace { |
| 38 base::LazyInstance<Instances>::Leaky g_instances = LAZY_INSTANCE_INITIALIZER; | 38 base::LazyInstance<Instances>::Leaky g_instances = LAZY_INSTANCE_INITIALIZER; |
| 39 | 39 |
| 40 //Returns RenderViewDevToolsAgentHost attached to any of RenderViewHost | 40 //Returns RenderViewDevToolsAgentHost attached to any of RenderViewHost |
| 41 //instances associated with |web_contents| | 41 //instances associated with |web_contents| |
| 42 static RenderViewDevToolsAgentHost* FindAgentHost(WebContents* web_contents) { | 42 static RenderViewDevToolsAgentHost* FindAgentHost(WebContents* web_contents) { |
| 43 if (g_instances == NULL) | 43 if (g_instances == NULL) |
| 44 return NULL; | 44 return NULL; |
| 45 RenderViewHostDelegate* delegate = | |
| 46 static_cast<WebContentsImpl*>(web_contents); | |
| 47 for (Instances::iterator it = g_instances.Get().begin(); | |
| 48 it != g_instances.Get().end(); ++it) { | |
| 49 RenderViewHost* rvh = (*it)->render_view_host(); | |
| 50 if (rvh && rvh->GetDelegate() == delegate) | |
| 51 return *it; | |
| 52 } | |
| 53 return NULL; | |
| 54 } | |
| 55 | |
| 56 static RenderViewDevToolsAgentHost* FindAgentHost(RenderViewHost* rvh) { | |
| 57 if (g_instances == NULL) | |
| 58 return NULL; | |
| 59 for (Instances::iterator it = g_instances.Get().begin(); | 45 for (Instances::iterator it = g_instances.Get().begin(); |
| 60 it != g_instances.Get().end(); ++it) { | 46 it != g_instances.Get().end(); ++it) { |
| 61 if (rvh == (*it)->render_view_host()) | 47 if ((*it)->GetWebContents() == web_contents) |
| 62 return *it; | 48 return *it; |
| 63 } | 49 } |
| 64 return NULL; | 50 return NULL; |
| 65 } | 51 } |
| 66 | 52 |
| 67 } // namespace | 53 } // namespace |
| 68 | 54 |
| 69 scoped_refptr<DevToolsAgentHost> | 55 scoped_refptr<DevToolsAgentHost> |
| 70 DevToolsAgentHost::GetOrCreateFor(WebContents* web_contents) { | 56 DevToolsAgentHost::GetOrCreateFor(WebContents* web_contents) { |
| 71 RenderViewDevToolsAgentHost* result = FindAgentHost(web_contents); | 57 RenderViewDevToolsAgentHost* result = FindAgentHost(web_contents); |
| 72 if (!result) | 58 if (!result) |
| 73 result = new RenderViewDevToolsAgentHost(web_contents->GetRenderViewHost()); | 59 result = new RenderViewDevToolsAgentHost(web_contents->GetRenderViewHost()); |
| 74 return result; | 60 return result; |
| 75 } | 61 } |
| 76 | 62 |
| 77 // static | 63 // static |
| 78 scoped_refptr<DevToolsAgentHost> | 64 bool DevToolsAgentHost::HasFor(WebContents* web_contents) { |
| 79 DevToolsAgentHost::GetOrCreateFor(RenderViewHost* rvh) { | 65 return FindAgentHost(web_contents) != NULL; |
| 80 RenderViewDevToolsAgentHost* result = FindAgentHost(rvh); | |
| 81 if (!result) | |
| 82 result = new RenderViewDevToolsAgentHost(rvh); | |
| 83 return result; | |
| 84 } | |
| 85 | |
| 86 // static | |
| 87 bool DevToolsAgentHost::HasFor(RenderViewHost* rvh) { | |
| 88 return FindAgentHost(rvh) != NULL; | |
| 89 } | 66 } |
| 90 | 67 |
| 91 // static | 68 // static |
| 92 bool DevToolsAgentHost::IsDebuggerAttached(WebContents* web_contents) { | 69 bool DevToolsAgentHost::IsDebuggerAttached(WebContents* web_contents) { |
| 93 if (g_instances == NULL) | 70 RenderViewDevToolsAgentHost* agent_host = FindAgentHost(web_contents); |
| 94 return false; | 71 return agent_host && agent_host->IsAttached(); |
| 95 DevToolsManager* devtools_manager = DevToolsManager::GetInstance(); | |
| 96 if (!devtools_manager) | |
| 97 return false; | |
| 98 RenderViewHostDelegate* delegate = | |
| 99 static_cast<WebContentsImpl*>(web_contents); | |
| 100 for (Instances::iterator it = g_instances.Get().begin(); | |
| 101 it != g_instances.Get().end(); ++it) { | |
| 102 RenderViewHost* rvh = (*it)->render_view_host_; | |
| 103 if (rvh && rvh->GetDelegate() != delegate) | |
| 104 continue; | |
| 105 if ((*it)->IsAttached()) | |
| 106 return true; | |
| 107 } | |
| 108 return false; | |
| 109 } | 72 } |
| 110 | 73 |
| 111 //static | 74 //static |
| 112 std::vector<RenderViewHost*> DevToolsAgentHost::GetValidRenderViewHosts() { | 75 std::vector<WebContents*> DevToolsAgentHost::GetInspectableWebContents() { |
| 113 std::vector<RenderViewHost*> result; | 76 std::set<WebContents*> set; |
| 114 scoped_ptr<RenderWidgetHostIterator> widgets( | 77 scoped_ptr<RenderWidgetHostIterator> widgets( |
| 115 RenderWidgetHost::GetRenderWidgetHosts()); | 78 RenderWidgetHost::GetRenderWidgetHosts()); |
| 116 while (RenderWidgetHost* widget = widgets->GetNextHost()) { | 79 while (RenderWidgetHost* widget = widgets->GetNextHost()) { |
| 117 // Ignore processes that don't have a connection, such as crashed contents. | 80 // Ignore processes that don't have a connection, such as crashed contents. |
| 118 if (!widget->GetProcess()->HasConnection()) | 81 if (!widget->GetProcess()->HasConnection()) |
| 119 continue; | 82 continue; |
| 120 if (!widget->IsRenderView()) | 83 if (!widget->IsRenderView()) |
| 121 continue; | 84 continue; |
| 122 | 85 |
| 123 RenderViewHost* rvh = RenderViewHost::From(widget); | 86 RenderViewHost* rvh = RenderViewHost::From(widget); |
| 124 WebContents* web_contents = WebContents::FromRenderViewHost(rvh); | 87 WebContents* web_contents = WebContents::FromRenderViewHost(rvh); |
| 125 if (!web_contents) | 88 if (web_contents) |
| 126 continue; | 89 set.insert(web_contents); |
| 127 | |
| 128 // Don't report a RenderViewHost if it is not the current RenderViewHost | |
| 129 // for some WebContents (this filters out pre-render RVHs and similar). | |
| 130 // However report a RenderViewHost created for an out of process iframe. | |
| 131 // TODO (kaznacheev): Revisit this when it is clear how OOP iframes | |
| 132 // interact with pre-rendering. | |
| 133 // TODO (kaznacheev): GetMainFrame() call is a temporary hack. Iterate over | |
| 134 // all RenderFrameHost instances when multiple OOP frames are supported. | |
| 135 if (rvh != web_contents->GetRenderViewHost() && | |
| 136 !rvh->GetMainFrame()->IsCrossProcessSubframe()) { | |
| 137 continue; | |
| 138 } | |
| 139 | |
| 140 result.push_back(rvh); | |
| 141 } | 90 } |
| 91 std::vector<WebContents*> result(set.size()); |
| 92 std::copy(set.begin(), set.end(), result.begin()); |
| 142 return result; | 93 return result; |
| 143 } | 94 } |
| 144 | 95 |
| 145 // static | 96 // static |
| 146 void RenderViewDevToolsAgentHost::OnCancelPendingNavigation( | 97 void RenderViewDevToolsAgentHost::OnCancelPendingNavigation( |
| 147 RenderViewHost* pending, | 98 RenderViewHost* pending, |
| 148 RenderViewHost* current) { | 99 RenderViewHost* current) { |
| 149 RenderViewDevToolsAgentHost* agent_host = FindAgentHost(pending); | 100 WebContents* web_contents = WebContents::FromRenderViewHost(pending); |
| 101 RenderViewDevToolsAgentHost* agent_host = FindAgentHost(web_contents); |
| 150 if (!agent_host) | 102 if (!agent_host) |
| 151 return; | 103 return; |
| 152 agent_host->DisconnectRenderViewHost(); | 104 agent_host->DisconnectRenderViewHost(); |
| 153 agent_host->ConnectRenderViewHost(current); | 105 agent_host->ConnectRenderViewHost(current); |
| 154 } | 106 } |
| 155 | 107 |
| 156 // static | |
| 157 bool RenderViewDevToolsAgentHost::DispatchIPCMessage( | |
| 158 RenderViewHost* source, | |
| 159 const IPC::Message& message) { | |
| 160 RenderViewDevToolsAgentHost* agent_host = FindAgentHost(source); | |
| 161 return agent_host && agent_host->DispatchIPCMessage(message); | |
| 162 } | |
| 163 | |
| 164 RenderViewDevToolsAgentHost::RenderViewDevToolsAgentHost(RenderViewHost* rvh) | 108 RenderViewDevToolsAgentHost::RenderViewDevToolsAgentHost(RenderViewHost* rvh) |
| 165 : render_view_host_(NULL), | 109 : render_view_host_(NULL), |
| 166 overrides_handler_(new RendererOverridesHandler(this)), | 110 overrides_handler_(new RendererOverridesHandler(this)), |
| 167 tracing_handler_( | 111 tracing_handler_( |
| 168 new DevToolsTracingHandler(DevToolsTracingHandler::Renderer)), | 112 new DevToolsTracingHandler(DevToolsTracingHandler::Renderer)), |
| 169 power_handler_(new DevToolsPowerHandler()), | 113 power_handler_(new DevToolsPowerHandler()), |
| 170 reattaching_(false) { | 114 reattaching_(false) { |
| 171 SetRenderViewHost(rvh); | 115 SetRenderViewHost(rvh); |
| 172 DevToolsProtocol::Notifier notifier(base::Bind( | 116 DevToolsProtocol::Notifier notifier(base::Bind( |
| 173 &RenderViewDevToolsAgentHost::OnDispatchOnInspectorFrontend, | 117 &RenderViewDevToolsAgentHost::OnDispatchOnInspectorFrontend, |
| 174 base::Unretained(this))); | 118 base::Unretained(this))); |
| 175 overrides_handler_->SetNotifier(notifier); | 119 overrides_handler_->SetNotifier(notifier); |
| 176 tracing_handler_->SetNotifier(notifier); | 120 tracing_handler_->SetNotifier(notifier); |
| 177 power_handler_->SetNotifier(notifier); | 121 power_handler_->SetNotifier(notifier); |
| 178 g_instances.Get().push_back(this); | 122 g_instances.Get().push_back(this); |
| 179 AddRef(); // Balanced in RenderViewHostDestroyed. | 123 AddRef(); // Balanced in RenderViewHostDestroyed. |
| 180 } | 124 } |
| 181 | 125 |
| 182 RenderViewHost* RenderViewDevToolsAgentHost::GetRenderViewHost() { | 126 WebContents* RenderViewDevToolsAgentHost::GetWebContents() { |
| 183 return render_view_host_; | 127 return web_contents(); |
| 184 } | 128 } |
| 185 | 129 |
| 186 void RenderViewDevToolsAgentHost::DispatchOnInspectorBackend( | 130 void RenderViewDevToolsAgentHost::DispatchOnInspectorBackend( |
| 187 const std::string& message) { | 131 const std::string& message) { |
| 188 std::string error_message; | 132 std::string error_message; |
| 189 | 133 |
| 190 scoped_ptr<base::DictionaryValue> message_dict( | 134 scoped_ptr<base::DictionaryValue> message_dict( |
| 191 DevToolsProtocol::ParseMessage(message, &error_message)); | 135 DevToolsProtocol::ParseMessage(message, &error_message)); |
| 192 scoped_refptr<DevToolsProtocol::Command> command = | 136 scoped_refptr<DevToolsProtocol::Command> command = |
| 193 DevToolsProtocol::ParseCommand(message_dict.get(), &error_message); | 137 DevToolsProtocol::ParseCommand(message_dict.get(), &error_message); |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 DevToolsManagerImpl::GetInstance()->NotifyObservers(this, false); | 222 DevToolsManagerImpl::GetInstance()->NotifyObservers(this, false); |
| 279 } | 223 } |
| 280 | 224 |
| 281 void RenderViewDevToolsAgentHost::InnerClientDetachedFromRenderer() { | 225 void RenderViewDevToolsAgentHost::InnerClientDetachedFromRenderer() { |
| 282 bool process_has_agents = false; | 226 bool process_has_agents = false; |
| 283 RenderProcessHost* render_process_host = render_view_host_->GetProcess(); | 227 RenderProcessHost* render_process_host = render_view_host_->GetProcess(); |
| 284 for (Instances::iterator it = g_instances.Get().begin(); | 228 for (Instances::iterator it = g_instances.Get().begin(); |
| 285 it != g_instances.Get().end(); ++it) { | 229 it != g_instances.Get().end(); ++it) { |
| 286 if (*it == this || !(*it)->IsAttached()) | 230 if (*it == this || !(*it)->IsAttached()) |
| 287 continue; | 231 continue; |
| 288 RenderViewHost* rvh = (*it)->render_view_host(); | 232 RenderViewHost* rvh = (*it)->render_view_host_; |
| 289 if (rvh && rvh->GetProcess() == render_process_host) | 233 if (rvh && rvh->GetProcess() == render_process_host) |
| 290 process_has_agents = true; | 234 process_has_agents = true; |
| 291 } | 235 } |
| 292 | 236 |
| 293 // We are the last to disconnect from the renderer -> revoke permissions. | 237 // We are the last to disconnect from the renderer -> revoke permissions. |
| 294 if (!process_has_agents) { | 238 if (!process_has_agents) { |
| 295 ChildProcessSecurityPolicyImpl::GetInstance()->RevokeReadRawCookies( | 239 ChildProcessSecurityPolicyImpl::GetInstance()->RevokeReadRawCookies( |
| 296 render_process_host->GetID()); | 240 render_process_host->GetID()); |
| 297 } | 241 } |
| 298 } | 242 } |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 356 #if defined(OS_ANDROID) | 300 #if defined(OS_ANDROID) |
| 357 case base::TERMINATION_STATUS_OOM_PROTECTED: | 301 case base::TERMINATION_STATUS_OOM_PROTECTED: |
| 358 #endif | 302 #endif |
| 359 RenderViewCrashed(); | 303 RenderViewCrashed(); |
| 360 break; | 304 break; |
| 361 default: | 305 default: |
| 362 break; | 306 break; |
| 363 } | 307 } |
| 364 } | 308 } |
| 365 | 309 |
| 310 bool RenderViewDevToolsAgentHost::OnMessageReceived( |
| 311 const IPC::Message& message, |
| 312 RenderFrameHost* render_frame_host) { |
| 313 return DispatchIPCMessage(message); |
| 314 } |
| 315 |
| 316 bool RenderViewDevToolsAgentHost::OnMessageReceived( |
| 317 const IPC::Message& message) { |
| 318 return DispatchIPCMessage(message); |
| 319 } |
| 320 |
| 366 void RenderViewDevToolsAgentHost::DidAttachInterstitialPage() { | 321 void RenderViewDevToolsAgentHost::DidAttachInterstitialPage() { |
| 367 if (!render_view_host_) | 322 if (!render_view_host_) |
| 368 return; | 323 return; |
| 369 // The rvh set in AboutToNavigateRenderView turned out to be interstitial. | 324 // The rvh set in AboutToNavigateRenderView turned out to be interstitial. |
| 370 // Connect back to the real one. | 325 // Connect back to the real one. |
| 371 WebContents* web_contents = | 326 WebContents* web_contents = |
| 372 WebContents::FromRenderViewHost(render_view_host_); | 327 WebContents::FromRenderViewHost(render_view_host_); |
| 373 if (!web_contents) | 328 if (!web_contents) |
| 374 return; | 329 return; |
| 375 DisconnectRenderViewHost(); | 330 DisconnectRenderViewHost(); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 400 | 355 |
| 401 void RenderViewDevToolsAgentHost::ClearRenderViewHost() { | 356 void RenderViewDevToolsAgentHost::ClearRenderViewHost() { |
| 402 DCHECK(render_view_host_); | 357 DCHECK(render_view_host_); |
| 403 registrar_.Remove( | 358 registrar_.Remove( |
| 404 this, | 359 this, |
| 405 content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED, | 360 content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED, |
| 406 content::Source<RenderWidgetHost>(render_view_host_)); | 361 content::Source<RenderWidgetHost>(render_view_host_)); |
| 407 render_view_host_ = NULL; | 362 render_view_host_ = NULL; |
| 408 } | 363 } |
| 409 | 364 |
| 365 void RenderViewDevToolsAgentHost::DisconnectWebContents() { |
| 366 DisconnectRenderViewHost(); |
| 367 } |
| 368 |
| 369 void RenderViewDevToolsAgentHost::ConnectWebContents(WebContents* wc) { |
| 370 ConnectRenderViewHost(wc->GetRenderViewHost()); |
| 371 } |
| 372 |
| 410 void RenderViewDevToolsAgentHost::ConnectRenderViewHost(RenderViewHost* rvh) { | 373 void RenderViewDevToolsAgentHost::ConnectRenderViewHost(RenderViewHost* rvh) { |
| 411 SetRenderViewHost(rvh); | 374 SetRenderViewHost(rvh); |
| 412 if (IsAttached()) | 375 if (IsAttached()) |
| 413 Reattach(state_); | 376 Reattach(state_); |
| 414 } | 377 } |
| 415 | 378 |
| 416 void RenderViewDevToolsAgentHost::DisconnectRenderViewHost() { | 379 void RenderViewDevToolsAgentHost::DisconnectRenderViewHost() { |
| 417 ClientDetachedFromRenderer(); | 380 ClientDetachedFromRenderer(); |
| 418 ClearRenderViewHost(); | 381 ClearRenderViewHost(); |
| 419 } | 382 } |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 482 DevToolsProtocol::ParseNotification(message); | 445 DevToolsProtocol::ParseNotification(message); |
| 483 | 446 |
| 484 if (notification) { | 447 if (notification) { |
| 485 tracing_handler_->HandleNotification(notification); | 448 tracing_handler_->HandleNotification(notification); |
| 486 } | 449 } |
| 487 DevToolsManagerImpl::GetInstance()->DispatchOnInspectorFrontend( | 450 DevToolsManagerImpl::GetInstance()->DispatchOnInspectorFrontend( |
| 488 this, message); | 451 this, message); |
| 489 } | 452 } |
| 490 | 453 |
| 491 } // namespace content | 454 } // namespace content |
| OLD | NEW |