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 |