Allow ManifestIconDownloader to download images from a specified frame.

Before this CL, ManifestIconDownloader always downloads icons from the
main frame. This creates a buggy interaction with Content Security
Policy, when the manifest icon download is initiated from inside a
frame.

After this CL, the callers of ManifestIconDownloader can specify an
initiator frame (as a GlobalFrameRoutingId) in which to download the
image. The frame routing ID is passed to WebContents to find the correct
frame that exposes the mojo.ImageDownloader interface.

This CL also exposes the mojo.ImageDownloader interface in all frames
instead of just the main frame.

A subsequent CL will update the callers of ManifestIconDownloader to
pass in the correct frame routing ID.

Bug: 1055360
Change-Id: I31fd58453392ec4e1165ac20dc3a1284dc05f6f8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2085752
Commit-Queue: Danyao Wang <[email protected]>
Reviewed-by: Kentaro Hara <[email protected]>
Reviewed-by: Kinuko Yasuda <[email protected]>
Cr-Commit-Position: refs/heads/master@{#747105}
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 749dca3..0e43f7f 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -108,6 +108,7 @@
 #include "content/public/browser/download_manager.h"
 #include "content/public/browser/file_select_listener.h"
 #include "content/public/browser/focused_node_details.h"
+#include "content/public/browser/global_routing_id.h"
 #include "content/public/browser/invalidate_type.h"
 #include "content/public/browser/javascript_dialog_manager.h"
 #include "content/public/browser/keyboard_event_processing_result.h"
@@ -4295,10 +4296,28 @@
     uint32_t max_bitmap_size,
     bool bypass_cache,
     WebContents::ImageDownloadCallback callback) {
+  return DownloadImageInFrame(GlobalFrameRoutingId(), url, is_favicon,
+                              preferred_size, max_bitmap_size, bypass_cache,
+                              std::move(callback));
+}
+
+int WebContentsImpl::DownloadImageInFrame(
+    const GlobalFrameRoutingId& initiator_frame_routing_id,
+    const GURL& url,
+    bool is_favicon,
+    uint32_t preferred_size,
+    uint32_t max_bitmap_size,
+    bool bypass_cache,
+    WebContents::ImageDownloadCallback callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   static int next_image_download_id = 0;
+
+  RenderFrameHostImpl* initiator_frame =
+      initiator_frame_routing_id.child_id
+          ? RenderFrameHostImpl::FromID(initiator_frame_routing_id)
+          : GetMainFrame();
   const mojo::Remote<blink::mojom::ImageDownloader>& mojo_image_downloader =
-      GetMainFrame()->GetMojoImageDownloader();
+      initiator_frame->GetMojoImageDownloader();
   const int download_id = ++next_image_download_id;
   if (!mojo_image_downloader) {
     // If the renderer process is dead (i.e. crash, or memory pressure on