Remove WebContentsImpl::frame_count_.

This CL removes WebContentsImpl::frame_count_. Instead of using
frame_count_ to count the number of iframes, this cl iterates through
the frame tree when loading finishes.

Bug: 850328
Change-Id: I0eca46aab70371f296a66f0e7775acd18611acdf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1857647
Reviewed-by: Alex Moshchuk <[email protected]>
Reviewed-by: Alexei Svitkine <[email protected]>
Commit-Queue: Yilkal Abe <[email protected]>
Cr-Commit-Position: refs/heads/master@{#713202}
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 24667e2..553a6ab 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -4394,13 +4394,6 @@
     NavigationHandle* navigation_handle) {
   TRACE_EVENT1("navigation", "WebContentsImpl::ReadyToCommitNavigation",
                "navigation_handle", navigation_handle);
-
-  if (!navigation_handle->GetParentFrame() &&
-      record_max_frame_count_when_leaving_current_page_) {
-    RecordMaxFrameCountUMA(max_frame_count_);
-    record_max_frame_count_when_leaving_current_page_ = false;
-  }
-
   for (auto& observer : observers_)
     observer.ReadyToCommitNavigation(navigation_handle);
 
@@ -4493,15 +4486,20 @@
     should_focus_location_bar_by_default_ = false;
   }
 
-  // If navigation has successfully finished in the main page, set
-  // |record_max_frame_count_when_leaving_current_page_| to true so that when
-  // the main frame navigates away from this page we know to record this page's
-  // max frame count.
-  if (navigation_handle->IsInMainFrame() && !navigation_handle->IsErrorPage()) {
-    record_max_frame_count_when_leaving_current_page_ = true;
+  if (navigation_handle->IsInMainFrame() && first_navigation_completed_)
+    RecordMaxFrameCountUMA(max_loaded_frame_count_);
 
-    // Navigation has completed in main frame. Reset |max_frame_count_| to 1.
-    max_frame_count_ = 1;
+  // If navigation has successfully finished in the main frame, set
+  // |first_navigation_completed_| to true so that we will record
+  // |max_loaded_frame_count_| above when future main frame navigations finish.
+  if (navigation_handle->IsInMainFrame() && !navigation_handle->IsErrorPage()) {
+    first_navigation_completed_ = true;
+
+    // Navigation has completed in main frame. Reset |max_loaded_frame_count_|.
+    // |max_loaded_frame_count_| is not necessarily 1 if the navigation was
+    // served from BackForwardCache.
+    max_loaded_frame_count_ =
+        GetMainFrame()->frame_tree_node()->GetFrameTreeSize();
   }
 }
 
@@ -4858,13 +4856,15 @@
   GURL validated_url(url);
   source->GetProcess()->FilterURL(false, &validated_url);
 
-  if (!source->GetParent()) {
-    size_t frame_count = source->frame_tree_node()->GetFrameTreeSize();
-    UMA_HISTOGRAM_COUNTS_1000("Navigation.MainFrame.FrameCount", frame_count);
-  }
-
   for (auto& observer : observers_)
     observer.DidFinishLoad(source, validated_url);
+
+  size_t tree_size = frame_tree_.root()->GetFrameTreeSize();
+  if (max_loaded_frame_count_ < tree_size)
+    max_loaded_frame_count_ = tree_size;
+
+  if (!source->GetParent())
+    UMA_HISTOGRAM_COUNTS_1000("Navigation.MainFrame.FrameCount", tree_size);
 }
 
 void WebContentsImpl::OnGoToEntryAtOffset(RenderFrameHostImpl* source,
@@ -5298,12 +5298,6 @@
 void WebContentsImpl::NotifyFrameSwapped(RenderFrameHost* old_host,
                                          RenderFrameHost* new_host,
                                          bool is_main_frame) {
-  if (!old_host) {
-    frame_count_++;
-    if (max_frame_count_ < frame_count_)
-      max_frame_count_ = frame_count_;
-  }
-
 #if defined(OS_ANDROID)
   // Copy importance from |old_host| if |new_host| is a main frame.
   if (old_host && !new_host->GetParent()) {
@@ -5408,18 +5402,18 @@
 }
 
 void WebContentsImpl::RenderFrameDeleted(RenderFrameHost* render_frame_host) {
-  if (!render_frame_host->GetParent() && IsBeingDestroyed() &&
-      record_max_frame_count_when_leaving_current_page_ &&
+  if (IsBeingDestroyed() && !render_frame_host->GetParent() &&
+      first_navigation_completed_ &&
       !static_cast<RenderFrameHostImpl*>(render_frame_host)
            ->is_in_back_forward_cache()) {
     // Main frame has been deleted because WebContents is being destroyed.
     // Note that we aren't recording this here when the main frame is in the
     // back-forward cache because that means we've actually already navigated
     // away from it (and we got to this point because the WebContents is
-    // deleted), which means |max_frame_count_| is already overwritten.
-    // The |max_frame_count_| value will instead be recorded from within
-    // |WebContentsImpl::ReadyToCommitNavigation()|.
-    RecordMaxFrameCountUMA(max_frame_count_);
+    // deleted), which means |max_loaded_frame_count_| is already overwritten.
+    // The |max_loaded_frame_count_| value will instead be recorded from within
+    // |WebContentsImpl::DidFinishNavigation()|.
+    RecordMaxFrameCountUMA(max_loaded_frame_count_);
   }
 
   is_notifying_observers_ = true;
@@ -6820,8 +6814,6 @@
 }
 
 void WebContentsImpl::OnFrameRemoved(RenderFrameHost* render_frame_host) {
-  frame_count_--;
-
   for (auto& observer : observers_)
     observer.FrameDeleted(render_frame_host);
 }
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
index 9f15d65..f4f9908 100644
--- a/content/browser/web_contents/web_contents_impl.h
+++ b/content/browser/web_contents/web_contents_impl.h
@@ -1929,19 +1929,13 @@
   std::unique_ptr<JavaScriptDialogNavigationDeferrer>
       javascript_dialog_navigation_deferrer_;
 
-  // The number of frames currently in this WebContents.
-  size_t frame_count_ = 0;
+  // The max number of loaded frames that have been seen in this WebContents.
+  // This number is reset with each main frame navigation.
+  size_t max_loaded_frame_count_ = 0;
 
-  // The max number of frames seen in the current page hosted by this
-  // WebContents.
-  size_t max_frame_count_ = 0;
-
-  // This boolean value is used to keep track of whether we should record
-  // |max_frame_count_| when the main frame navigation is ready to commit.
-  // |max_frame_count_| should not be recorded for initial navigation for
-  // example. This is because |max_frame_count_| refers to the page that is
-  // being navigated away from.
-  bool record_max_frame_count_when_leaving_current_page_ = false;
+  // This boolean value is used to keep track of whether we finished the first
+  // successful navigation in this WebContents.
+  bool first_navigation_completed_ = false;
 
   base::WeakPtrFactory<WebContentsImpl> loading_weak_factory_{this};
   base::WeakPtrFactory<WebContentsImpl> weak_factory_{this};
diff --git a/content/browser/web_contents/web_contents_impl_browsertest.cc b/content/browser/web_contents/web_contents_impl_browsertest.cc
index 07d3838..d459c09 100644
--- a/content/browser/web_contents/web_contents_impl_browsertest.cc
+++ b/content/browser/web_contents/web_contents_impl_browsertest.cc
@@ -4156,12 +4156,12 @@
 
   GURL url = embedded_test_server()->GetURL("a.com", "/title1.html");
   EXPECT_TRUE(NavigateToURL(shell(), url));
-  EXPECT_EQ(web_contents->max_frame_count_, 1u);
+  EXPECT_EQ(web_contents->max_loaded_frame_count_, 1u);
 
   GURL url_with_iframes_out_of_process =
       embedded_test_server()->GetURL("b.com", "/page_with_iframe.html");
   EXPECT_TRUE(NavigateToURL(shell(), url_with_iframes_out_of_process));
-  EXPECT_EQ(web_contents->max_frame_count_, 2u);
+  EXPECT_EQ(web_contents->max_loaded_frame_count_, 2u);
 
   // There should be two samples for kFrameCountUMA.
   histogram_tester.ExpectTotalCount(kFrameCountUMA, 2);
@@ -4180,7 +4180,7 @@
   GURL url_with_multiple_iframes = embedded_test_server()->GetURL(
       "b.com", "/cross_site_iframe_factory.html?b(a,c(b),d,b)");
   EXPECT_TRUE(NavigateToURL(shell(), url_with_multiple_iframes));
-  EXPECT_EQ(web_contents->max_frame_count_, 6u);
+  EXPECT_EQ(web_contents->max_loaded_frame_count_, 6u);
 
   histogram_tester.ExpectTotalCount(kMaxFrameCountUMA, 2);
   histogram_tester.ExpectBucketCount(kMaxFrameCountUMA, 1, 1);
@@ -4208,16 +4208,14 @@
   GURL url_with_iframes =
       embedded_test_server()->GetURL("a.com", "/page_with_iframe.html");
   EXPECT_TRUE(NavigateToURL(shell(), url_with_iframes));
-  EXPECT_EQ(web_contents->max_frame_count_, 2u);
+  EXPECT_EQ(web_contents->max_loaded_frame_count_, 2u);
 
   // |url_with_iframes| contains another iframe inside it. This means that we
   // have 4 iframes inside.
   auto* rfh =
       static_cast<RenderFrameHostImpl*>(CreateSubframe(url_with_iframes));
 
-  EXPECT_EQ(web_contents->max_frame_count_, 4u);
-  EXPECT_EQ(web_contents->frame_count_, 4u);
-
+  EXPECT_EQ(web_contents->max_loaded_frame_count_, 4u);
   ASSERT_NE(rfh, nullptr);
 
   shell()->Close();
@@ -4243,13 +4241,12 @@
   GURL url_with_iframes =
       embedded_test_server()->GetURL("a.com", "/page_with_iframe.html");
   EXPECT_TRUE(NavigateToURL(shell(), url_with_iframes));
-  EXPECT_EQ(web_contents->max_frame_count_, 2u);
+  EXPECT_EQ(web_contents->max_loaded_frame_count_, 2u);
 
   GURL url = embedded_test_server()->GetURL("a.com", "/title1.html");
   auto* rfh = static_cast<RenderFrameHostImpl*>(CreateSubframe(url));
   ASSERT_NE(rfh, nullptr);
-  EXPECT_EQ(web_contents->max_frame_count_, 3u);
-  EXPECT_EQ(web_contents->frame_count_, 3u);
+  EXPECT_EQ(web_contents->max_loaded_frame_count_, 3u);
 
   // Let's remove the first child.
   auto* main_frame = web_contents->GetMainFrame();
@@ -4260,8 +4257,7 @@
                             "iframe').parentNode);"));
   observer.Wait();
 
-  EXPECT_EQ(web_contents->max_frame_count_, 3u);
-  EXPECT_EQ(web_contents->frame_count_, 2u);
+  EXPECT_EQ(web_contents->max_loaded_frame_count_, 3u);
 
   // Let's remove the second child.
   node_to_remove = main_frame->child_at(0);
@@ -4271,8 +4267,7 @@
       "document.body.removeChild(document.querySelector('iframe'));"));
   observer_second.Wait();
 
-  EXPECT_EQ(web_contents->max_frame_count_, 3u);
-  EXPECT_EQ(web_contents->frame_count_, 1u);
+  EXPECT_EQ(web_contents->max_loaded_frame_count_, 3u);
 
   shell()->Close();