Fix missing DevTool message for cross-site subframe download

The issue: Devtools msg missing when (1)Devtools is open before page load &&
(2)the message is logged in OnResponseStarted::OnResponseStarted && (3)the
response is a download && (4)the frame logging the message is a cross-site
subframe

This is rooted from calling the detach_callback in
TargetAutoAttacher::AutoAttachToFrame. Specifically, for a navigation to
download that occurs in a cross-site subframe, in
TargetAutoAttacher::AutoAttachToFrame, the |old_cross_process| is always true,
and the |new_cross_process| is false because RFH was set to null for download in
OnResponseStarted::OnResponseStarted.

The simplest fix seems to be we skip detaching the host when it's not going to
commit by checking if RFH is nullptr.

This CL also has another small fix: the check for |is_download_| is changed to
|is_download| in 2 sites in NavigationRequest::OnResponseStarted, as in those
2 sites, it should check whether the navigation has turned into a download,
regardless whether he download was intervened or not.

Bug: 961486
Change-Id: I2cc08dfd02bfe4d097c2ed3a3f1b8cfe425b8f01
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1614156
Reviewed-by: Camille Lamy <clamy@chromium.org>
Commit-Queue: Yao Xiao <yaoxia@chromium.org>
Cr-Commit-Position: refs/heads/master@{#661417}
diff --git a/content/browser/devtools/protocol/target_auto_attacher.cc b/content/browser/devtools/protocol/target_auto_attacher.cc
index 053ea04e..97a14a1 100644
--- a/content/browser/devtools/protocol/target_auto_attacher.cc
+++ b/content/browser/devtools/protocol/target_auto_attacher.cc
@@ -211,16 +211,23 @@
 
   FrameTreeNode* frame_tree_node = navigation_handle->frame_tree_node();
   RenderFrameHostImpl* new_host = navigation_handle->GetRenderFrameHost();
+
+  // |new_host| can be nullptr for navigation that doesn't commmit
+  // (e.g. download). Skip possibly detaching the old agent host so the DevTools
+  // message logged via the old RFH can be seen.
+  if (!new_host)
+    return nullptr;
+
   scoped_refptr<DevToolsAgentHost> agent_host =
       RenderFrameDevToolsAgentHost::FindForDangling(frame_tree_node);
 
   bool old_cross_process = !!agent_host;
   bool is_portal_main_frame =
-      frame_tree_node->IsMainFrame() && new_host &&
+      frame_tree_node->IsMainFrame() &&
       static_cast<WebContentsImpl*>(WebContents::FromRenderFrameHost(new_host))
           ->IsPortal();
   bool new_cross_process =
-      (new_host && new_host->IsCrossProcessSubframe()) || is_portal_main_frame;
+      new_host->IsCrossProcessSubframe() || is_portal_main_frame;
 
   if (old_cross_process == new_cross_process)
     return nullptr;
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc
index e89a2121..a0d29a2 100644
--- a/content/browser/frame_host/navigation_request.cc
+++ b/content/browser/frame_host/navigation_request.cc
@@ -1245,9 +1245,9 @@
 
   // Check if the response should be sent to a renderer.
   response_should_be_rendered_ =
-      !is_download_ && (!response->head.headers.get() ||
-                        (response->head.headers->response_code() != 204 &&
-                         response->head.headers->response_code() != 205));
+      !is_download && (!response->head.headers.get() ||
+                       (response->head.headers->response_code() != 204 &&
+                        response->head.headers->response_code() != 205));
 
   // Response that will not commit should be marked as aborted in the
   // NavigationHandle.
@@ -1393,8 +1393,8 @@
   // know how to display the content.  We follow Firefox here and show our
   // own error page instead of intercepting the request as a stream or a
   // download.
-  if (is_download_ && (response->head.headers.get() &&
-                       (response->head.headers->response_code() / 100 != 2))) {
+  if (is_download && (response->head.headers.get() &&
+                      (response->head.headers->response_code() / 100 != 2))) {
     OnRequestFailedInternal(
         network::URLLoaderCompletionStatus(net::ERR_INVALID_RESPONSE),
         false /* skip_throttles */, base::nullopt /* error_page_content */,