Upstream version 10.38.208.0
[platform/framework/web/crosswalk.git] / src / content / browser / devtools / render_view_devtools_agent_host.cc
index f3eaf3a..86c0867 100644 (file)
@@ -20,6 +20,7 @@
 #include "content/common/devtools_messages.h"
 #include "content/common/view_messages.h"
 #include "content/public/browser/content_browser_client.h"
+#include "content/public/browser/devtools_manager_delegate.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/notification_types.h"
 #include "content/public/browser/render_widget_host_iterator.h"
@@ -41,23 +42,9 @@ base::LazyInstance<Instances>::Leaky g_instances = LAZY_INSTANCE_INITIALIZER;
 static RenderViewDevToolsAgentHost* FindAgentHost(WebContents* web_contents) {
   if (g_instances == NULL)
     return NULL;
-  RenderViewHostDelegate* delegate =
-      static_cast<WebContentsImpl*>(web_contents);
   for (Instances::iterator it = g_instances.Get().begin();
        it != g_instances.Get().end(); ++it) {
-    RenderViewHost* rvh = (*it)->render_view_host();
-    if (rvh && rvh->GetDelegate() == delegate)
-      return *it;
-  }
-  return NULL;
-}
-
-static RenderViewDevToolsAgentHost* FindAgentHost(RenderViewHost* rvh) {
-  if (g_instances == NULL)
-    return NULL;
-  for (Instances::iterator it = g_instances.Get().begin();
-       it != g_instances.Get().end(); ++it) {
-    if (rvh == (*it)->render_view_host())
+    if ((*it)->GetWebContents() == web_contents)
       return *it;
   }
   return NULL;
@@ -74,42 +61,19 @@ DevToolsAgentHost::GetOrCreateFor(WebContents* web_contents) {
 }
 
 // static
-scoped_refptr<DevToolsAgentHost>
-DevToolsAgentHost::GetOrCreateFor(RenderViewHost* rvh) {
-  RenderViewDevToolsAgentHost* result = FindAgentHost(rvh);
-  if (!result)
-    result = new RenderViewDevToolsAgentHost(rvh);
-  return result;
-}
-
-// static
-bool DevToolsAgentHost::HasFor(RenderViewHost* rvh) {
-  return FindAgentHost(rvh) != NULL;
+bool DevToolsAgentHost::HasFor(WebContents* web_contents) {
+  return FindAgentHost(web_contents) != NULL;
 }
 
 // static
 bool DevToolsAgentHost::IsDebuggerAttached(WebContents* web_contents) {
-  if (g_instances == NULL)
-    return false;
-  DevToolsManager* devtools_manager = DevToolsManager::GetInstance();
-  if (!devtools_manager)
-    return false;
-  RenderViewHostDelegate* delegate =
-      static_cast<WebContentsImpl*>(web_contents);
-  for (Instances::iterator it = g_instances.Get().begin();
-       it != g_instances.Get().end(); ++it) {
-    RenderViewHost* rvh = (*it)->render_view_host_;
-    if (rvh && rvh->GetDelegate() != delegate)
-      continue;
-    if ((*it)->IsAttached())
-      return true;
-  }
-  return false;
+  RenderViewDevToolsAgentHost* agent_host = FindAgentHost(web_contents);
+  return agent_host && agent_host->IsAttached();
 }
 
 //static
-std::vector<RenderViewHost*> DevToolsAgentHost::GetValidRenderViewHosts() {
-  std::vector<RenderViewHost*> result;
+std::vector<WebContents*> DevToolsAgentHost::GetInspectableWebContents() {
+  std::set<WebContents*> set;
   scoped_ptr<RenderWidgetHostIterator> widgets(
       RenderWidgetHost::GetRenderWidgetHosts());
   while (RenderWidgetHost* widget = widgets->GetNextHost()) {
@@ -121,23 +85,11 @@ std::vector<RenderViewHost*> DevToolsAgentHost::GetValidRenderViewHosts() {
 
     RenderViewHost* rvh = RenderViewHost::From(widget);
     WebContents* web_contents = WebContents::FromRenderViewHost(rvh);
-    if (!web_contents)
-      continue;
-
-    // Don't report a RenderViewHost if it is not the current RenderViewHost
-    // for some WebContents (this filters out pre-render RVHs and similar).
-    // However report a RenderViewHost created for an out of process iframe.
-    // TODO (kaznacheev): Revisit this when it is clear how OOP iframes
-    // interact with pre-rendering.
-    // TODO (kaznacheev): GetMainFrame() call is a temporary hack. Iterate over
-    // all RenderFrameHost instances when multiple OOP frames are supported.
-    if (rvh != web_contents->GetRenderViewHost() &&
-        !rvh->GetMainFrame()->IsCrossProcessSubframe()) {
-      continue;
-    }
-
-    result.push_back(rvh);
+    if (web_contents)
+      set.insert(web_contents);
   }
+  std::vector<WebContents*> result(set.size());
+  std::copy(set.begin(), set.end(), result.begin());
   return result;
 }
 
@@ -145,28 +97,21 @@ std::vector<RenderViewHost*> DevToolsAgentHost::GetValidRenderViewHosts() {
 void RenderViewDevToolsAgentHost::OnCancelPendingNavigation(
     RenderViewHost* pending,
     RenderViewHost* current) {
-  RenderViewDevToolsAgentHost* agent_host = FindAgentHost(pending);
+  WebContents* web_contents = WebContents::FromRenderViewHost(pending);
+  RenderViewDevToolsAgentHost* agent_host = FindAgentHost(web_contents);
   if (!agent_host)
     return;
   agent_host->DisconnectRenderViewHost();
   agent_host->ConnectRenderViewHost(current);
 }
 
-// static
-bool RenderViewDevToolsAgentHost::DispatchIPCMessage(
-    RenderViewHost* source,
-    const IPC::Message& message) {
-  RenderViewDevToolsAgentHost* agent_host = FindAgentHost(source);
-  return agent_host && agent_host->DispatchIPCMessage(message);
-}
-
-RenderViewDevToolsAgentHost::RenderViewDevToolsAgentHost(
-    RenderViewHost* rvh)
+RenderViewDevToolsAgentHost::RenderViewDevToolsAgentHost(RenderViewHost* rvh)
     : render_view_host_(NULL),
-      overrides_handler_(new RendererOverridesHandler(this)),
-      tracing_handler_(new DevToolsTracingHandler()),
-      power_handler_(new DevToolsPowerHandler())
- {
+      overrides_handler_(new RendererOverridesHandler()),
+      tracing_handler_(
+          new DevToolsTracingHandler(DevToolsTracingHandler::Renderer)),
+      power_handler_(new DevToolsPowerHandler()),
+      reattaching_(false) {
   SetRenderViewHost(rvh);
   DevToolsProtocol::Notifier notifier(base::Bind(
       &RenderViewDevToolsAgentHost::OnDispatchOnInspectorFrontend,
@@ -178,19 +123,33 @@ RenderViewDevToolsAgentHost::RenderViewDevToolsAgentHost(
   AddRef();  // Balanced in RenderViewHostDestroyed.
 }
 
-RenderViewHost* RenderViewDevToolsAgentHost::GetRenderViewHost() {
-  return render_view_host_;
+WebContents* RenderViewDevToolsAgentHost::GetWebContents() {
+  return web_contents();
 }
 
 void RenderViewDevToolsAgentHost::DispatchOnInspectorBackend(
     const std::string& message) {
   std::string error_message;
+
+  scoped_ptr<base::DictionaryValue> message_dict(
+      DevToolsProtocol::ParseMessage(message, &error_message));
   scoped_refptr<DevToolsProtocol::Command> command =
-      DevToolsProtocol::ParseCommand(message, &error_message);
+      DevToolsProtocol::ParseCommand(message_dict.get(), &error_message);
 
   if (command) {
-    scoped_refptr<DevToolsProtocol::Response> overridden_response =
-        overrides_handler_->HandleCommand(command);
+    scoped_refptr<DevToolsProtocol::Response> overridden_response;
+
+    DevToolsManagerDelegate* delegate =
+        DevToolsManagerImpl::GetInstance()->delegate();
+    if (delegate) {
+      scoped_ptr<base::DictionaryValue> overridden_response_value(
+          delegate->HandleCommand(this, message_dict.get()));
+      if (overridden_response_value)
+        overridden_response = DevToolsProtocol::ParseResponse(
+            overridden_response_value.get());
+    }
+    if (!overridden_response)
+      overridden_response = overrides_handler_->HandleCommand(command);
     if (!overridden_response)
       overridden_response = tracing_handler_->HandleCommand(command);
     if (!overridden_response)
@@ -216,12 +175,17 @@ void RenderViewDevToolsAgentHost::OnClientAttached() {
   if (!render_view_host_)
     return;
 
-  ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadRawCookies(
-      render_view_host_->GetProcess()->GetID());
+  InnerOnClientAttached();
 
   // TODO(kaznacheev): Move this call back to DevToolsManagerImpl when
   // extensions::ProcessManager no longer relies on this notification.
-  DevToolsManagerImpl::GetInstance()->NotifyObservers(this, true);
+  if (!reattaching_)
+    DevToolsManagerImpl::GetInstance()->NotifyObservers(this, true);
+}
+
+void RenderViewDevToolsAgentHost::InnerOnClientAttached() {
+  ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadRawCookies(
+      render_view_host_->GetProcess()->GetID());
 
 #if defined(OS_ANDROID)
   power_save_blocker_.reset(
@@ -241,20 +205,31 @@ void RenderViewDevToolsAgentHost::OnClientDetached() {
   power_save_blocker_.reset();
 #endif
   overrides_handler_->OnClientDetached();
+  tracing_handler_->OnClientDetached();
+  power_handler_->OnClientDetached();
   ClientDetachedFromRenderer();
+
+  // TODO(kaznacheev): Move this call back to DevToolsManagerImpl when
+  // extensions::ProcessManager no longer relies on this notification.
+  if (!reattaching_)
+    DevToolsManagerImpl::GetInstance()->NotifyObservers(this, false);
 }
 
 void RenderViewDevToolsAgentHost::ClientDetachedFromRenderer() {
   if (!render_view_host_)
     return;
 
+  InnerClientDetachedFromRenderer();
+}
+
+void RenderViewDevToolsAgentHost::InnerClientDetachedFromRenderer() {
   bool process_has_agents = false;
   RenderProcessHost* render_process_host = render_view_host_->GetProcess();
   for (Instances::iterator it = g_instances.Get().begin();
        it != g_instances.Get().end(); ++it) {
     if (*it == this || !(*it)->IsAttached())
       continue;
-    RenderViewHost* rvh = (*it)->render_view_host();
+    RenderViewHost* rvh = (*it)->render_view_host_;
     if (rvh && rvh->GetProcess() == render_process_host)
       process_has_agents = true;
   }
@@ -264,10 +239,6 @@ void RenderViewDevToolsAgentHost::ClientDetachedFromRenderer() {
     ChildProcessSecurityPolicyImpl::GetInstance()->RevokeReadRawCookies(
         render_process_host->GetID());
   }
-
-  // TODO(kaznacheev): Move this call back to DevToolsManagerImpl when
-  // extensions::ProcessManager no longer relies on this notification.
-  DevToolsManagerImpl::GetInstance()->NotifyObservers(this, false);
 }
 
 RenderViewDevToolsAgentHost::~RenderViewDevToolsAgentHost() {
@@ -283,12 +254,11 @@ void RenderViewDevToolsAgentHost::AboutToNavigateRenderView(
   if (!render_view_host_)
     return;
 
-  if (render_view_host_ == dest_rvh && static_cast<RenderViewHostImpl*>(
-          render_view_host_)->render_view_termination_status() ==
+  if (render_view_host_ == dest_rvh &&
+          render_view_host_->render_view_termination_status() ==
               base::TERMINATION_STATUS_STILL_RUNNING)
     return;
-  DisconnectRenderViewHost();
-  ConnectRenderViewHost(dest_rvh);
+  ReattachToRenderViewHost(dest_rvh);
 }
 
 void RenderViewDevToolsAgentHost::RenderViewHostChanged(
@@ -297,11 +267,19 @@ void RenderViewDevToolsAgentHost::RenderViewHostChanged(
   if (new_host != render_view_host_) {
     // AboutToNavigateRenderView was not called for renderer-initiated
     // navigation.
-    DisconnectRenderViewHost();
-    ConnectRenderViewHost(new_host);
+    ReattachToRenderViewHost(new_host);
   }
 }
 
+void
+RenderViewDevToolsAgentHost::ReattachToRenderViewHost(RenderViewHost* rvh) {
+  DCHECK(!reattaching_);
+  reattaching_ = true;
+  DisconnectRenderViewHost();
+  ConnectRenderViewHost(rvh);
+  reattaching_ = false;
+}
+
 void RenderViewDevToolsAgentHost::RenderViewDeleted(RenderViewHost* rvh) {
   if (rvh != render_view_host_)
     return;
@@ -329,6 +307,17 @@ void RenderViewDevToolsAgentHost::RenderProcessGone(
   }
 }
 
+bool RenderViewDevToolsAgentHost::OnMessageReceived(
+    const IPC::Message& message,
+    RenderFrameHost* render_frame_host) {
+  return DispatchIPCMessage(message);
+}
+
+bool RenderViewDevToolsAgentHost::OnMessageReceived(
+    const IPC::Message& message) {
+  return DispatchIPCMessage(message);
+}
+
 void RenderViewDevToolsAgentHost::DidAttachInterstitialPage() {
   if (!render_view_host_)
     return;
@@ -353,9 +342,10 @@ void RenderViewDevToolsAgentHost::Observe(int type,
 
 void RenderViewDevToolsAgentHost::SetRenderViewHost(RenderViewHost* rvh) {
   DCHECK(!render_view_host_);
-  render_view_host_ = rvh;
+  render_view_host_ = static_cast<RenderViewHostImpl*>(rvh);
 
   WebContentsObserver::Observe(WebContents::FromRenderViewHost(rvh));
+  overrides_handler_->SetRenderViewHost(render_view_host_);
 
   registrar_.Add(
       this,
@@ -370,6 +360,15 @@ void RenderViewDevToolsAgentHost::ClearRenderViewHost() {
       content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED,
       content::Source<RenderWidgetHost>(render_view_host_));
   render_view_host_ = NULL;
+  overrides_handler_->ClearRenderViewHost();
+}
+
+void RenderViewDevToolsAgentHost::DisconnectWebContents() {
+  DisconnectRenderViewHost();
+}
+
+void RenderViewDevToolsAgentHost::ConnectWebContents(WebContents* wc) {
+  ConnectRenderViewHost(wc->GetRenderViewHost());
 }
 
 void RenderViewDevToolsAgentHost::ConnectRenderViewHost(RenderViewHost* rvh) {
@@ -404,6 +403,8 @@ bool RenderViewDevToolsAgentHost::DispatchIPCMessage(
                         OnSaveAgentRuntimeState)
     IPC_MESSAGE_HANDLER_GENERIC(ViewHostMsg_SwapCompositorFrame,
                                 handled = false; OnSwapCompositorFrame(msg))
+    IPC_MESSAGE_HANDLER_GENERIC(ViewHostMsg_SetTouchEventEmulationEnabled,
+                                handled = OnSetTouchEventEmulationEnabled(msg))
     IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
   return handled;
@@ -417,6 +418,11 @@ void RenderViewDevToolsAgentHost::OnSwapCompositorFrame(
   overrides_handler_->OnSwapCompositorFrame(param.b.metadata);
 }
 
+bool RenderViewDevToolsAgentHost::OnSetTouchEventEmulationEnabled(
+    const IPC::Message& message) {
+  return overrides_handler_->OnSetTouchEventEmulationEnabled();
+}
+
 void RenderViewDevToolsAgentHost::SynchronousSwapCompositorFrame(
     const cc::CompositorFrameMetadata& frame_metadata) {
   if (!render_view_host_)
@@ -435,6 +441,13 @@ void RenderViewDevToolsAgentHost::OnDispatchOnInspectorFrontend(
     const std::string& message) {
   if (!render_view_host_)
     return;
+
+  scoped_refptr<DevToolsProtocol::Notification> notification =
+      DevToolsProtocol::ParseNotification(message);
+
+  if (notification) {
+    tracing_handler_->HandleNotification(notification);
+  }
   DevToolsManagerImpl::GetInstance()->DispatchOnInspectorFrontend(
       this, message);
 }