Enable range-based for loops to loop over a WebContents' frame hosts.

BUG=none

Review URL: https://codereview.chromium.org/1658003002

Cr-Commit-Position: refs/heads/master@{#373477}
diff --git a/android_webview/native/aw_contents.cc b/android_webview/native/aw_contents.cc
index 523c637..3aa2337 100644
--- a/android_webview/native/aw_contents.cc
+++ b/android_webview/native/aw_contents.cc
@@ -137,13 +137,6 @@
 
 base::subtle::Atomic32 g_instance_count = 0;
 
-void OnIoThreadClientReady(content::RenderFrameHost* rfh) {
-  int render_process_id = rfh->GetProcess()->GetID();
-  int render_frame_id = rfh->GetRoutingID();
-  AwResourceDispatcherHostDelegate::OnIoThreadClientReady(
-      render_process_id, render_frame_id);
-}
-
 }  // namespace
 
 // static
@@ -245,7 +238,12 @@
           env, intercept_navigation_delegate)));
 
   // Finally, having setup the associations, release any deferred requests
-  web_contents_->ForEachFrame(base::Bind(&OnIoThreadClientReady));
+  for (content::RenderFrameHost* rfh : web_contents_->GetAllFrames()) {
+    int render_process_id = rfh->GetProcess()->GetID();
+    int render_frame_id = rfh->GetRoutingID();
+    AwResourceDispatcherHostDelegate::OnIoThreadClientReady(render_process_id,
+                                                            render_frame_id);
+  }
 }
 
 void AwContents::SetSaveFormData(bool enabled) {
diff --git a/chrome/browser/site_details.cc b/chrome/browser/site_details.cc
index 4a326a83..157a646 100644
--- a/chrome/browser/site_details.cc
+++ b/chrome/browser/site_details.cc
@@ -26,9 +26,9 @@
 namespace {
 
 bool ShouldIsolate(BrowserContext* browser_context,
-                   const IsolationScenario* scenario,
+                   const IsolationScenario& scenario,
                    const GURL& site) {
-  switch (scenario->policy) {
+  switch (scenario.policy) {
     case ISOLATE_NOTHING:
       return false;
     case ISOLATE_ALL_SITES:
@@ -57,52 +57,6 @@
   return true;
 }
 
-// Walk the frame tree and update |scenario|'s data for the given frame. Memoize
-// each frame's computed URL in |frame_urls| so it can be reused when visiting
-// its children.
-void CollectForScenario(std::map<RenderFrameHost*, GURL>* frame_urls,
-                        SiteInstance* primary,
-                        IsolationScenario* scenario,
-                        RenderFrameHost* frame) {
-  BrowserContext* context = primary->GetBrowserContext();
-
-  // Determine the site from the frame's origin, with a fallback to the
-  // frame's URL.  In cases like <iframe sandbox>, we can wind up with an http
-  // URL but a unique origin.  The origin of the resource will still determine
-  // process placement.
-  url::Origin origin = frame->GetLastCommittedOrigin();
-  GURL site = SiteInstance::GetSiteForURL(
-      context, origin.unique() ? frame->GetLastCommittedURL()
-                               : GURL(origin.Serialize()));
-
-  bool should_isolate = ShouldIsolate(context, scenario, site);
-
-  // Treat a subframe as part of its parent site if neither needs isolation.
-  if (!should_isolate && frame->GetParent()) {
-    GURL parent_site = (*frame_urls)[frame->GetParent()];
-    if (!ShouldIsolate(context, scenario, parent_site))
-      site = parent_site;
-  }
-
-  bool process_per_site =
-      site.is_valid() &&
-      RenderProcessHost::ShouldUseProcessPerSite(context, site);
-
-  // If we don't need a dedicated process, and aren't living in a process-
-  // per-site process, we are nothing special: collapse our URL to a dummy
-  // site.
-  if (!process_per_site && !should_isolate)
-    site = GURL("http://");
-
-  // We model process-per-site by only inserting those sites into the first
-  // browsing instance in which they appear.
-  if (scenario->sites.insert(site).second || !process_per_site)
-    scenario->browsing_instance_site_map[primary->GetId()].insert(site);
-
-  // Record our result in |frame_urls| for use by children.
-  (*frame_urls)[frame] = site;
-}
-
 content::SiteInstance* DeterminePrimarySiteInstance(
     content::SiteInstance* instance,
     SiteData* site_data) {
@@ -122,15 +76,6 @@
   return instance;
 }
 
-void CollectCurrentSnapshot(SiteData* site_data, RenderFrameHost* frame) {
-  if (frame->GetParent()) {
-    if (frame->GetSiteInstance() != frame->GetParent()->GetSiteInstance())
-      site_data->out_of_process_frames++;
-  }
-
-  DeterminePrimarySiteInstance(frame->GetSiteInstance(), site_data);
-}
-
 }  // namespace
 
 IsolationScenario::IsolationScenario() : policy(ISOLATE_ALL_SITES) {}
@@ -153,18 +98,58 @@
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   SiteInstance* primary =
       DeterminePrimarySiteInstance(contents->GetSiteInstance(), site_data);
+  BrowserContext* context = primary->GetBrowserContext();
 
   // Now keep track of how many sites we have in this BrowsingInstance (and
   // overall), including sites in iframes.
   for (IsolationScenario& scenario : site_data->scenarios) {
-    std::map<RenderFrameHost*, GURL> memo;
-    contents->ForEachFrame(
-        base::Bind(&CollectForScenario, base::Unretained(&memo),
-                   base::Unretained(primary), base::Unretained(&scenario)));
+    std::map<RenderFrameHost*, GURL> frame_urls;
+    for (RenderFrameHost* frame : contents->GetAllFrames()) {
+      // Determine the site from the frame's origin, with a fallback to the
+      // frame's URL.  In cases like <iframe sandbox>, we can wind up with an
+      // http URL but a unique origin.  The origin of the resource will still
+      // determine process placement.
+      url::Origin origin = frame->GetLastCommittedOrigin();
+      GURL site = SiteInstance::GetSiteForURL(
+          context, origin.unique() ? frame->GetLastCommittedURL()
+                                   : GURL(origin.Serialize()));
+
+      bool should_isolate = ShouldIsolate(context, scenario, site);
+
+      // Treat a subframe as part of its parent site if neither needs isolation.
+      if (!should_isolate && frame->GetParent()) {
+        GURL parent_site = frame_urls[frame->GetParent()];
+        if (!ShouldIsolate(context, scenario, parent_site))
+          site = parent_site;
+      }
+
+      bool process_per_site =
+          site.is_valid() &&
+          RenderProcessHost::ShouldUseProcessPerSite(context, site);
+
+      // If we don't need a dedicated process, and aren't living in a process-
+      // per-site process, we are nothing special: collapse our URL to a dummy
+      // site.
+      if (!process_per_site && !should_isolate)
+        site = GURL("http://");
+
+      // We model process-per-site by only inserting those sites into the first
+      // browsing instance in which they appear.
+      if (scenario.sites.insert(site).second || !process_per_site)
+        scenario.browsing_instance_site_map[primary->GetId()].insert(site);
+
+      // Record our result in |frame_urls| for use by children.
+      frame_urls[frame] = site;
+    }
   }
 
-  contents->ForEachFrame(
-      base::Bind(&CollectCurrentSnapshot, base::Unretained(site_data)));
+  for (RenderFrameHost* frame : contents->GetAllFrames()) {
+    if (frame->GetParent()) {
+      if (frame->GetSiteInstance() != frame->GetParent()->GetSiteInstance())
+        site_data->out_of_process_frames++;
+    }
+    DeterminePrimarySiteInstance(frame->GetSiteInstance(), site_data);
+  }
 }
 
 void SiteDetails::UpdateHistograms(
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 99c9ca8..2af90ae 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -185,24 +185,6 @@
   return false;
 }
 
-void SendToAllFramesInternal(int* number_of_messages,
-                             IPC::Message* message,
-                             RenderFrameHost* rfh) {
-  *number_of_messages = *number_of_messages + 1;
-  IPC::Message* message_copy = new IPC::Message(*message);
-  message_copy->set_routing_id(rfh->GetRoutingID());
-  rfh->Send(message_copy);
-}
-
-void AddRenderWidgetHostViewToSet(std::set<RenderWidgetHostView*>* set,
-                                  RenderFrameHost* rfh) {
-  RenderWidgetHostView* rwhv = static_cast<RenderFrameHostImpl*>(rfh)
-                                   ->frame_tree_node()
-                                   ->render_manager()
-                                   ->GetRenderWidgetHostView();
-  set->insert(rwhv);
-}
-
 void SetAccessibilityModeOnFrame(AccessibilityMode mode,
                                  RenderFrameHost* frame_host) {
   static_cast<RenderFrameHostImpl*>(frame_host)->SetAccessibilityMode(mode);
@@ -789,10 +771,21 @@
   }
 }
 
+std::vector<RenderFrameHost*> WebContentsImpl::GetAllFrames() {
+  std::vector<RenderFrameHost*> frame_hosts;
+  for (FrameTreeNode* node : frame_tree_.Nodes())
+    frame_hosts.push_back(node->current_frame_host());
+  return frame_hosts;
+}
+
 int WebContentsImpl::SendToAllFrames(IPC::Message* message) {
   int number_of_messages = 0;
-  ForEachFrame(
-      base::Bind(&SendToAllFramesInternal, &number_of_messages, message));
+  for (RenderFrameHost* rfh : GetAllFrames()) {
+    ++number_of_messages;
+    IPC::Message* message_copy = new IPC::Message(*message);
+    message_copy->set_routing_id(rfh->GetRoutingID());
+    rfh->Send(message_copy);
+  }
   delete message;
   return number_of_messages;
 }
@@ -915,10 +908,12 @@
 }
 
 void WebContentsImpl::EnableTreeOnlyAccessibilityMode() {
-  if (GetAccessibilityMode() != AccessibilityModeOff)
-    ForEachFrame(base::Bind(&ResetAccessibility));
-  else
+  if (GetAccessibilityMode() != AccessibilityModeOff) {
+    for (RenderFrameHost* rfh : GetAllFrames())
+      ResetAccessibility(rfh);
+  } else {
     AddAccessibilityMode(AccessibilityModeTreeOnly);
+  }
 }
 
 bool WebContentsImpl::IsTreeOnlyAccessibilityModeForTesting() const {
@@ -1507,8 +1502,13 @@
   if (ShowingInterstitialPage()) {
     set.insert(GetRenderWidgetHostView());
   } else {
-    ForEachFrame(
-        base::Bind(&AddRenderWidgetHostViewToSet, base::Unretained(&set)));
+    for (RenderFrameHost* rfh : GetAllFrames()) {
+      RenderWidgetHostView* rwhv = static_cast<RenderFrameHostImpl*>(rfh)
+                                       ->frame_tree_node()
+                                       ->render_manager()
+                                       ->GetRenderWidgetHostView();
+      set.insert(rwhv);
+    }
   }
   return set;
 }
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
index 6e243c66..81bdf75e 100644
--- a/content/browser/web_contents/web_contents_impl.h
+++ b/content/browser/web_contents/web_contents_impl.h
@@ -245,6 +245,7 @@
       int frame_tree_node_id) override;
   void ForEachFrame(
       const base::Callback<void(RenderFrameHost*)>& on_frame) override;
+  std::vector<RenderFrameHost*> GetAllFrames() override;
   int SendToAllFrames(IPC::Message* message) override;
   RenderViewHostImpl* GetRenderViewHost() const override;
   int GetRoutingID() const override;
diff --git a/content/public/browser/web_contents.h b/content/public/browser/web_contents.h
index f7f09b7..5260b91 100644
--- a/content/public/browser/web_contents.h
+++ b/content/public/browser/web_contents.h
@@ -228,6 +228,10 @@
   virtual void ForEachFrame(
       const base::Callback<void(RenderFrameHost*)>& on_frame) = 0;
 
+  // Returns a vector of all RenderFrameHosts in the currently active view in
+  // breadth-first traversal order.
+  virtual std::vector<RenderFrameHost*> GetAllFrames() = 0;
+
   // Sends the given IPC to all frames in the currently active view and returns
   // the number of sent messages (i.e. the number of processed frames). This is
   // a convenience method instead of calling ForEach.