// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <string>

#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/strings/strcat.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/subresource_filter/subresource_filter_browser_test_harness.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/heavy_ad_intervention/heavy_ad_features.h"
#include "components/page_load_metrics/browser/ads_page_load_metrics_test_waiter.h"
#include "components/page_load_metrics/browser/observers/ad_metrics/ad_intervention_browser_test_utils.h"
#include "components/page_load_metrics/browser/observers/ad_metrics/ads_page_load_metrics_observer.h"
#include "components/page_load_metrics/browser/observers/ad_metrics/frame_tree_data.h"
#include "components/page_load_metrics/browser/observers/use_counter_page_load_metrics_observer.h"
#include "components/page_load_metrics/browser/page_load_metrics_memory_tracker.h"
#include "components/page_load_metrics/browser/page_load_metrics_test_waiter.h"
#include "components/performance_manager/public/v8_memory/v8_detailed_memory.h"
#include "components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h"
#include "components/subresource_filter/content/browser/ruleset_service.h"
#include "components/subresource_filter/core/browser/subresource_filter_features.h"
#include "components/subresource_filter/core/common/activation_scope.h"
#include "components/subresource_filter/core/common/common_features.h"
#include "components/subresource_filter/core/common/test_ruleset_utils.h"
#include "components/subresource_filter/core/mojom/subresource_filter.mojom.h"
#include "components/ukm/test_ukm_recorder.h"
#include "content/public/browser/back_forward_cache.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/common/content_features.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/test_navigation_observer.h"
#include "media/base/media_switches.h"
#include "net/base/escape.h"
#include "net/base/net_errors.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/controllable_http_response.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "services/metrics/public/cpp/metrics_utils.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/metrics/public/cpp/ukm_source.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/mojom/web_feature/web_feature.mojom.h"
#include "ui/gfx/geometry/size.h"
#include "url/gurl.h"
#include "url/url_constants.h"

namespace {

using OriginStatus = page_load_metrics::OriginStatus;
using OriginStatusWithThrottling =
    page_load_metrics::OriginStatusWithThrottling;

using FrameTreeNodeId = int;

const char kAdsInterventionRecordedHistogram[] =
    "SubresourceFilter.PageLoad.AdsInterventionTriggered";

const char kCrossOriginHistogramId[] =
    "PageLoad.Clients.Ads.FrameCounts.AdFrames.PerFrame."
    "OriginStatus";

const char kCreativeOriginHistogramId[] =
    "PageLoad.Clients.Ads.FrameCounts.AdFrames.PerFrame."
    "CreativeOriginStatus";

const char kCreativeOriginWithThrottlingHistogramId[] =
    "PageLoad.Clients.Ads.FrameCounts.AdFrames.PerFrame."
    "CreativeOriginStatusWithThrottling";

const char kAdUserActivationHistogramId[] =
    "PageLoad.Clients.Ads.FrameCounts.AdFrames.PerFrame."
    "UserActivation";

const char kPeakWindowdPercentHistogramId[] =
    "PageLoad.Clients.Ads.Cpu.FullPage.PeakWindowedPercent2";

const char kHeavyAdInterventionTypeHistogramId[] =
    "PageLoad.Clients.Ads.HeavyAds.InterventionType2";

const char kMaxAdDensityByAreaHistogramId[] =
    "PageLoad.Clients.Ads.AdDensity.MaxPercentByArea";

const char kMaxAdDensityByHeightHistogramId[] =
    "PageLoad.Clients.Ads.AdDensity.MaxPercentByHeight";

const char kMaxAdDensityRecordedHistogramId[] =
    "PageLoad.Clients.Ads.AdDensity.Recorded";

const char kMemoryPerFrameMaxHistogramId[] =
    "PageLoad.Clients.Ads.Memory.PerFrame.Max";

const char kMemoryAggregateMaxHistogramId[] =
    "PageLoad.Clients.Ads.Memory.Aggregate.Max";

const char kMemoryMainFrameMaxHistogramId[] =
    "PageLoad.Clients.Ads.Memory.MainFrame.Max";

const char kMemoryUpdateCountHistogramId[] =
    "PageLoad.Clients.Ads.Memory.UpdateCount";

}  // namespace

class AdsPageLoadMetricsObserverBrowserTest
    : public subresource_filter::SubresourceFilterBrowserTest {
 public:
  AdsPageLoadMetricsObserverBrowserTest()
      : subresource_filter::SubresourceFilterBrowserTest() {}

  AdsPageLoadMetricsObserverBrowserTest(
      const AdsPageLoadMetricsObserverBrowserTest&) = delete;
  AdsPageLoadMetricsObserverBrowserTest& operator=(
      const AdsPageLoadMetricsObserverBrowserTest&) = delete;

  ~AdsPageLoadMetricsObserverBrowserTest() override {}

  std::unique_ptr<page_load_metrics::PageLoadMetricsTestWaiter>
  CreatePageLoadMetricsTestWaiter() {
    content::WebContents* web_contents =
        browser()->tab_strip_model()->GetActiveWebContents();
    return std::make_unique<page_load_metrics::PageLoadMetricsTestWaiter>(
        web_contents);
  }

  void SetUp() override {
    std::vector<base::Feature> enabled = {
        subresource_filter::kAdTagging, features::kV8PerFrameMemoryMonitoring};
    std::vector<base::Feature> disabled = {};

    scoped_feature_list_.InitWithFeatures(enabled, disabled);
    subresource_filter::SubresourceFilterBrowserTest::SetUp();
  }

  void SetUpOnMainThread() override {
    SubresourceFilterBrowserTest::SetUpOnMainThread();
    SetRulesetWithRules(
        {subresource_filter::testing::CreateSuffixRule("ad_iframe_writer.js"),
         subresource_filter::testing::CreateSuffixRule("ad_script.js"),
         subresource_filter::testing::CreateSuffixRule(
             "expensive_animation_frame.html*"),
         subresource_filter::testing::CreateSuffixRule("ad.html")});
  }

 private:
  base::test::ScopedFeatureList scoped_feature_list_;
};

// Test that an embedded ad is same origin.
IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverBrowserTest,
                       OriginStatusMetricEmbedded) {
  base::HistogramTester histogram_tester;
  auto waiter = CreatePageLoadMetricsTestWaiter();
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(),
      embedded_test_server()->GetURL("/ads_observer/srcdoc_embedded_ad.html")));
  waiter->AddMinimumCompleteResourcesExpectation(4);
  waiter->Wait();
  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));
  histogram_tester.ExpectUniqueSample(
      kCrossOriginHistogramId, page_load_metrics::OriginStatus::kSame, 1);
}

// Test that an empty embedded ad isn't reported at all.
// TODO(crbug.com/1226500): This test is flaky.
IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverBrowserTest,
                       DISABLED_OriginStatusMetricEmbeddedEmpty) {
  base::HistogramTester histogram_tester;
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(), embedded_test_server()->GetURL(
                     "/ads_observer/srcdoc_embedded_ad_empty.html")));
  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));
  histogram_tester.ExpectTotalCount(kCrossOriginHistogramId, 0);
}

// Test that an ad with the same origin as the main page is same origin.
IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverBrowserTest,
                       OriginStatusMetricSame) {
  // Set the frame's resource as a rule.
  SetRulesetWithRules(
      {subresource_filter::testing::CreateSuffixRule("pixel.png")});
  base::HistogramTester histogram_tester;
  ukm::TestAutoSetUkmRecorder ukm_recorder;
  auto waiter = CreatePageLoadMetricsTestWaiter();
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(),
      embedded_test_server()->GetURL("/ads_observer/same_origin_ad.html")));
  waiter->AddMinimumCompleteResourcesExpectation(4);
  waiter->Wait();

  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));
  histogram_tester.ExpectUniqueSample(
      kCrossOriginHistogramId, page_load_metrics::OriginStatus::kSame, 1);
  auto entries =
      ukm_recorder.GetEntriesByName(ukm::builders::AdFrameLoad::kEntryName);
  EXPECT_EQ(1u, entries.size());
  ukm_recorder.ExpectEntryMetric(
      entries.front(), ukm::builders::AdFrameLoad::kStatus_CrossOriginName,
      static_cast<int>(page_load_metrics::OriginStatus::kSame));
}

IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverBrowserTest,
                       OriginStatusMetricCross) {
  // Note: Cannot navigate cross-origin without dynamically generating the URL.
  base::HistogramTester histogram_tester;
  ukm::TestAutoSetUkmRecorder ukm_recorder;
  auto waiter = CreatePageLoadMetricsTestWaiter();

  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(), embedded_test_server()->GetURL("/iframe_blank.html")));
  // Note that the initial iframe is not an ad, so the metric doesn't observe
  // it initially as same origin.  However, on re-navigating to a cross
  // origin site that has an ad at its origin, the ad on that page is cross
  // origin from the original page.
  NavigateIframeToURL(web_contents(), "test",
                      embedded_test_server()->GetURL(
                          "a.com", "/ads_observer/same_origin_ad.html"));

  // Wait until all resource data updates are sent. Note that there is one more
  // than in the tests above due to the navigation to same_origin_ad.html being
  // itself made in an iframe.
  waiter->AddMinimumCompleteResourcesExpectation(5);
  waiter->Wait();
  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));
  histogram_tester.ExpectUniqueSample(
      kCrossOriginHistogramId, page_load_metrics::OriginStatus::kCross, 1);
  auto entries =
      ukm_recorder.GetEntriesByName(ukm::builders::AdFrameLoad::kEntryName);
  EXPECT_EQ(1u, entries.size());
  ukm_recorder.ExpectEntryMetric(
      entries.front(), ukm::builders::AdFrameLoad::kStatus_CrossOriginName,
      static_cast<int>(page_load_metrics::OriginStatus::kCross));
}

// Verifies that the page ad density records the maximum value during
// a page's lifecycling by creating a large ad frame, destroying it, and
// creating a smaller iframe. The ad density recorded is the density with
// the first larger frame.
IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverBrowserTest,
                       PageAdDensityRecordsPageMax) {
  base::HistogramTester histogram_tester;
  ukm::TestAutoSetUkmRecorder ukm_recorder;
  auto waiter = CreatePageLoadMetricsTestWaiter();
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();

  // Evaluate the height and width of the page as the browser_test can
  // vary the dimensions.
  int document_height =
      EvalJs(web_contents, "document.body.scrollHeight").ExtractInt();
  int document_width =
      EvalJs(web_contents, "document.body.scrollWidth").ExtractInt();

  // Expectation is before NavigateToUrl for this test as the expectation can be
  // met after NavigateToUrl and before the Wait.
  waiter->AddMainFrameIntersectionExpectation(
      gfx::Rect(0, 0, document_width,
                document_height));  // Initial main frame rect.
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(),
      embedded_test_server()->GetURL(
          "a.com", "/ads_observer/blank_with_adiframe_writer.html")));
  waiter->Wait();
  web_contents = browser()->tab_strip_model()->GetActiveWebContents();

  // Create a frame at 100,100 of size 200,200.
  waiter->AddMainFrameIntersectionExpectation(gfx::Rect(100, 100, 200, 200));

  // Create the frame with b.com as origin to not get caught by
  // restricted ad tagging.
  EXPECT_TRUE(ExecJs(
      web_contents,
      content::JsReplace(
          "let frame = createAdIframeAtRect(100, 100, 200, 200); "
          "frame.src = $1; ",
          embedded_test_server()->GetURL("b.com", "/ads_observer/pixel.png"))));
  waiter->Wait();

  // Load should stop before we remove the frame.
  EXPECT_TRUE(WaitForLoadStop(web_contents));
  EXPECT_TRUE(ExecJs(web_contents,
                     "let frames = document.getElementsByTagName('iframe'); "
                     "frames[0].remove(); "));
  waiter->AddMainFrameIntersectionExpectation(gfx::Rect(400, 400, 10, 10));

  // Delete the frame and create a new frame at 400,400 of size 10x10. The
  // ad density resulting from this frame is lower than the 200x200.
  EXPECT_TRUE(ExecJs(
      web_contents,
      content::JsReplace("let frame = createAdIframeAtRect(400, 400, 10, 10); "
                         "frame.src = $1; ",
                         embedded_test_server()
                             ->GetURL("b.com", "/ads_observer/pixel.png")
                             .spec())));
  waiter->Wait();

  // Evaluate the height and width of the page as the browser_test can
  // vary the dimensions.
  document_height =
      EvalJs(web_contents, "document.body.scrollHeight").ExtractInt();
  document_width =
      EvalJs(web_contents, "document.body.scrollWidth").ExtractInt();

  int page_area = document_width * document_height;
  int ad_area = 200 * 200;  // The area of the first larger ad iframe.
  int expected_page_density_area = ad_area * 100 / page_area;
  int expected_page_density_height = 200 * 100 / document_height;

  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));

  histogram_tester.ExpectUniqueSample(kMaxAdDensityByAreaHistogramId,
                                      expected_page_density_area, 1);
  histogram_tester.ExpectUniqueSample(kMaxAdDensityByHeightHistogramId,
                                      expected_page_density_height, 1);
  histogram_tester.ExpectUniqueSample(kMaxAdDensityRecordedHistogramId, true,
                                      1);
  auto entries =
      ukm_recorder.GetEntriesByName(ukm::builders::AdPageLoad::kEntryName);
  EXPECT_EQ(1u, entries.size());
  ukm_recorder.ExpectEntryMetric(
      entries.front(), ukm::builders::AdPageLoad::kMaxAdDensityByAreaName,
      expected_page_density_area);
  ukm_recorder.ExpectEntryMetric(
      entries.front(), ukm::builders::AdPageLoad::kMaxAdDensityByHeightName,
      expected_page_density_height);
}

// Creates multiple overlapping frames and verifies the page ad density.
IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverBrowserTest,
                       PageAdDensityMultipleFrames) {
  base::HistogramTester histogram_tester;
  ukm::TestAutoSetUkmRecorder ukm_recorder;
  auto waiter = CreatePageLoadMetricsTestWaiter();
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();

  int document_height =
      EvalJs(web_contents, "document.body.scrollHeight").ExtractInt();
  int document_width =
      EvalJs(web_contents, "document.body.scrollWidth").ExtractInt();

  // Expectation is before NavigateToUrl for this test as the expectation can be
  // met after NavigateToUrl and before the Wait.
  waiter->AddMainFrameIntersectionExpectation(
      gfx::Rect(0, 0, document_width,
                document_height));  // Initial main frame rect.

  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(),
      embedded_test_server()->GetURL(
          "a.com", "/ads_observer/blank_with_adiframe_writer.html")));
  waiter->Wait();
  web_contents = browser()->tab_strip_model()->GetActiveWebContents();

  // Create a frame of size 400,400 at 100,100.
  waiter->AddMainFrameIntersectionExpectation(gfx::Rect(400, 400, 100, 100));

  // Create the frame with b.com as origin to not get caught by
  // restricted ad tagging.
  EXPECT_TRUE(ExecJs(
      web_contents, content::JsReplace(
                        "let frame = createAdIframeAtRect(400, 400, 100, 100); "
                        "frame.src = $1",
                        embedded_test_server()
                            ->GetURL("b.com", "/ads_observer/pixel.png")
                            .spec())));

  waiter->Wait();

  // Create a frame at of size 200,200 at 450,450.
  waiter->AddMainFrameIntersectionExpectation(gfx::Rect(450, 450, 200, 200));
  EXPECT_TRUE(ExecJs(
      web_contents, content::JsReplace(
                        "let frame = createAdIframeAtRect(450, 450, 200, 200); "
                        "frame.src = $1",
                        embedded_test_server()
                            ->GetURL("b.com", "/ads_observer/pixel.png")
                            .spec())));
  waiter->Wait();

  // Evaluate the height and width of the page as the browser_test can
  // vary the dimensions.
  document_height =
      EvalJs(web_contents, "document.body.scrollHeight").ExtractInt();
  document_width =
      EvalJs(web_contents, "document.body.scrollWidth").ExtractInt();

  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));

  int page_area = document_width * document_height;
  // The area of the two iframes minus the area of the overlapping section.
  int ad_area = 100 * 100 + 200 * 200 - 50 * 50;
  int expected_page_density_area = ad_area * 100 / page_area;
  int expected_page_density_height = 250 * 100 / document_height;

  histogram_tester.ExpectUniqueSample(kMaxAdDensityByAreaHistogramId,
                                      expected_page_density_area, 1);
  histogram_tester.ExpectUniqueSample(kMaxAdDensityByHeightHistogramId,
                                      expected_page_density_height, 1);
  histogram_tester.ExpectUniqueSample(kMaxAdDensityRecordedHistogramId, true,
                                      1);
  auto entries =
      ukm_recorder.GetEntriesByName(ukm::builders::AdPageLoad::kEntryName);
  EXPECT_EQ(1u, entries.size());
  ukm_recorder.ExpectEntryMetric(
      entries.front(), ukm::builders::AdPageLoad::kMaxAdDensityByAreaName,
      expected_page_density_area);
  ukm_recorder.ExpectEntryMetric(
      entries.front(), ukm::builders::AdPageLoad::kMaxAdDensityByHeightName,
      expected_page_density_height);
}

// Creates a frame with display:none styling and verifies that it has an
// empty intersection with the main frame.
//
// TODO(crbug.com/1121444): This test is disabled due to flaky failures on
// multiple platforms.
IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverBrowserTest,
                       DISABLED_PageAdDensityIgnoreDisplayNoneFrame) {
  base::HistogramTester histogram_tester;
  ukm::TestAutoSetUkmRecorder ukm_recorder;
  auto waiter = CreatePageLoadMetricsTestWaiter();
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();

  // Evaluate the height and width of the page as the browser_test can
  // vary the dimensions.
  int document_height =
      EvalJs(web_contents, "document.body.scrollHeight").ExtractInt();
  int document_width =
      EvalJs(web_contents, "document.body.scrollWidth").ExtractInt();

  // Expectation is before NavigateToUrl for this test as the expectation can be
  // met after NavigateToUrl and before the Wait.
  waiter->AddMainFrameIntersectionExpectation(
      gfx::Rect(0, 0, document_width,
                document_height));  // Initial main frame rect.

  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(),
      embedded_test_server()->GetURL(
          "a.com", "/ads_observer/blank_with_adiframe_writer.html")));
  waiter->Wait();
  web_contents = browser()->tab_strip_model()->GetActiveWebContents();

  // Create a frame at 100,100 of size 200,200. The expectation is an empty rect
  // as the frame is display:none and as a result has no main frame
  // intersection.
  waiter->AddMainFrameIntersectionExpectation(gfx::Rect(0, 0, 0, 0));

  // Create the frame with b.com as origin to not get caught by
  // restricted ad tagging.
  EXPECT_TRUE(ExecJs(
      web_contents, content::JsReplace(
                        "let frame = createAdIframeAtRect(100, 100, 200, 200); "
                        "frame.src = $1; "
                        "frame.style.display = \"none\";",
                        embedded_test_server()
                            ->GetURL("b.com", "/ads_observer/pixel.png")
                            .spec())));

  waiter->Wait();

  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));

  histogram_tester.ExpectUniqueSample(kMaxAdDensityByAreaHistogramId, 0, 1);
  histogram_tester.ExpectUniqueSample(kMaxAdDensityByHeightHistogramId, 0, 1);
  histogram_tester.ExpectUniqueSample(kMaxAdDensityRecordedHistogramId, true,
                                      1);
  auto entries =
      ukm_recorder.GetEntriesByName(ukm::builders::AdPageLoad::kEntryName);
  EXPECT_EQ(1u, entries.size());
  ukm_recorder.ExpectEntryMetric(
      entries.front(), ukm::builders::AdPageLoad::kMaxAdDensityByAreaName, 0);
  ukm_recorder.ExpectEntryMetric(
      entries.front(), ukm::builders::AdPageLoad::kMaxAdDensityByHeightName, 0);
}

// Each CreativeOriginStatus* browser test inputs a pointer to a frame object
// representing the frame tree path of a website with with a (possibly null)
// ad subframe, which itself may have linearly nested subframes.
// Each test then queries cross_site_iframe_factory.html with the query string
// corresponding to the frame tree path, computes the actual creative origin
// status and compares it to the expected creative origin status.
class CreativeOriginAdsPageLoadMetricsObserverBrowserTest
    : public AdsPageLoadMetricsObserverBrowserTest {
 public:
  CreativeOriginAdsPageLoadMetricsObserverBrowserTest() = default;
  ~CreativeOriginAdsPageLoadMetricsObserverBrowserTest() override = default;

  // Data structure to store the frame tree path for the root/main frame and
  // its single ad subframe (if such a child exists), as well as to keep track
  // of whether or not to render text in the frame. A child frame may have at
  // most one child frame of its own, and so forth.
  class Frame {
   public:
    Frame(std::string origin,
          std::unique_ptr<Frame> child,
          bool has_text = false,
          bool is_outside_view = false)
        : origin_(origin),
          child_(std::move(child)),
          has_text_(has_text),
          is_outside_view_(is_outside_view) {}

    ~Frame() = default;

    bool HasChild() const { return child_ != nullptr; }

    bool HasDescendantRenderingText(bool is_top_frame = true) const {
      if (!is_top_frame && has_text_ && !is_outside_view_)
        return true;

      if (!is_top_frame && is_outside_view_)
        return false;

      if (!child_)
        return false;

      return child_->HasDescendantRenderingText(false);
    }

    std::string Hostname() const { return origin_ + ".com"; }

    std::string Print(bool should_escape = false) const {
      std::vector<std::string> query_pieces = {origin_};
      if (!has_text_ && is_outside_view_)
        query_pieces.push_back("{no-text-render,out-of-view}");
      else if (!has_text_)
        query_pieces.push_back("{no-text-render}");
      else if (is_outside_view_)
        query_pieces.push_back("{out-of-view}");
      query_pieces.push_back("(");
      if (child_)
        query_pieces.push_back(child_->Print());
      query_pieces.push_back(")");
      std::string out = base::StrCat(query_pieces);
      if (should_escape)
        out = net::EscapeQueryParamValue(out, false /* use_plus */);
      return out;
    }

    std::string PrintChild(bool should_escape = false) const {
      return HasChild() ? child_->Print(should_escape) : "";
    }

   private:
    std::string origin_;
    std::unique_ptr<Frame> child_;
    bool has_text_;
    bool is_outside_view_;
  };

  // A convenience function to make frame creation less verbose.
  std::unique_ptr<Frame> MakeFrame(std::string origin,
                                   std::unique_ptr<Frame> child,
                                   bool has_text = false,
                                   bool is_outside_view = false) {
    return std::make_unique<Frame>(origin, std::move(child), has_text,
                                   is_outside_view);
  }

  void RecordCreativeOriginStatusHistograms(std::unique_ptr<Frame> frame) {
    // The file cross_site_iframe_factory.html loads URLs like:
    // http://a.com:40919/
    //   cross_site_iframe_factory.html?a{no-text-render}(b(c{no-text-render}))
    // The frame thus intended as the creative will be the only one in which
    // text renders.
    std::string ad_suffix = frame->PrintChild(true /* should_escape */);
    if (!ad_suffix.empty())
      SetRulesetToDisallowURLsWithPathSuffix(ad_suffix);
    std::string query = frame->Print();
    std::string relative_url = "/cross_site_iframe_factory.html?" + query;
    const GURL main_url(
        embedded_test_server()->GetURL(frame->Hostname(), relative_url));

    // If there is text to render in any subframe, wait until there is a first
    // contentful paint. Load some bytes in any case.
    auto waiter = CreatePageLoadMetricsTestWaiter();
    if (frame->HasDescendantRenderingText()) {
      waiter->AddSubFrameExpectation(
          page_load_metrics::PageLoadMetricsTestWaiter::TimingField::
              kFirstContentfulPaint);
    } else if (frame->HasChild()) {
      waiter->AddSubframeDataExpectation();
    }
    EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), main_url));
    waiter->Wait();

    // Navigate away to force the histogram recording.
    EXPECT_TRUE(
        ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));
  }

  void TestCreativeOriginStatus(
      std::unique_ptr<Frame> main_frame,
      page_load_metrics::OriginStatus expected_status,
      absl::optional<page_load_metrics::OriginStatusWithThrottling>
          expected_status_with_throttling) {
    base::HistogramTester histogram_tester;
    bool subframe_exists = main_frame->HasChild();

    RecordCreativeOriginStatusHistograms(std::move(main_frame));

    // Test histograms.
    if (subframe_exists) {
      histogram_tester.ExpectUniqueSample(kCreativeOriginHistogramId,
                                          expected_status, 1);
      if (expected_status_with_throttling.has_value()) {
        histogram_tester.ExpectUniqueSample(
            kCreativeOriginWithThrottlingHistogramId,
            expected_status_with_throttling.value(), 1);
      } else {
        // the CreativeOriginStatusWithThrottling histogram is best-effort,
        // and in the case where there is no content, multiple possible
        // states are valid.
        histogram_tester.ExpectTotalCount(
            kCreativeOriginWithThrottlingHistogramId, 1);
      }

    } else {
      // If no subframe exists, verify that each histogram is not set.
      histogram_tester.ExpectTotalCount(kCreativeOriginHistogramId, 0);
      histogram_tester.ExpectTotalCount(
          kCreativeOriginWithThrottlingHistogramId, 0);
    }
  }
};

// Test that an ad with same origin as the main page is same-origin.
IN_PROC_BROWSER_TEST_F(CreativeOriginAdsPageLoadMetricsObserverBrowserTest,
                       CreativeOriginStatusSame) {
  TestCreativeOriginStatus(
      MakeFrame("a", MakeFrame("a", MakeFrame("b", MakeFrame("c", nullptr)),
                               true /* has_text */)),
      OriginStatus::kSame, OriginStatusWithThrottling::kSameAndUnthrottled);
}

// Test that an ad with a different origin as the main page is cross-origin.
IN_PROC_BROWSER_TEST_F(CreativeOriginAdsPageLoadMetricsObserverBrowserTest,
                       CreativeOriginStatusCross) {
  TestCreativeOriginStatus(
      MakeFrame("a", MakeFrame("b", MakeFrame("c", nullptr), true)),
      OriginStatus::kCross, OriginStatusWithThrottling::kCrossAndUnthrottled);
}

// Test that an ad creative with the same origin as the main page,
// but nested in a cross-origin root ad frame, is same-origin.
IN_PROC_BROWSER_TEST_F(CreativeOriginAdsPageLoadMetricsObserverBrowserTest,
                       CreativeOriginStatusSameNested) {
  TestCreativeOriginStatus(
      MakeFrame("a",
                MakeFrame("b", MakeFrame("a", MakeFrame("c", nullptr), true))),
      OriginStatus::kSame, OriginStatusWithThrottling::kSameAndUnthrottled);
}

// Test that an ad creative with a different origin as the main page,
// but nested in a same-origin root ad frame, is cross-origin.
IN_PROC_BROWSER_TEST_F(CreativeOriginAdsPageLoadMetricsObserverBrowserTest,
                       CreativeOriginStatusCrossNested) {
  TestCreativeOriginStatus(
      MakeFrame("a",
                MakeFrame("a", MakeFrame("b", MakeFrame("c", nullptr), true))),
      page_load_metrics::OriginStatus::kCross,
      page_load_metrics::OriginStatusWithThrottling::kCrossAndUnthrottled);
}

// Test that an ad creative with a different origin as the main page,
// but nested two deep in a same-origin root ad frame, is cross-origin.
IN_PROC_BROWSER_TEST_F(CreativeOriginAdsPageLoadMetricsObserverBrowserTest,
                       CreativeOriginStatusCrossDoubleNested) {
  TestCreativeOriginStatus(
      MakeFrame("a",
                MakeFrame("a", MakeFrame("a", MakeFrame("b", nullptr,
                                                        true /* has_text */)))),
      OriginStatus::kCross, OriginStatusWithThrottling::kCrossAndUnthrottled);
}

// Test that if no iframe renders text, the creative origin status is
// indeterminate. The creative origin status with throttling can be
// either kUnknownAndThrottled or kUnknownAndUnthrottled in this case
// due to race conditions, as nothing is painted.
// TODO(cammie): Find a better workaround for testing COSwT in this
// edge case.
IN_PROC_BROWSER_TEST_F(CreativeOriginAdsPageLoadMetricsObserverBrowserTest,
                       CreativeOriginStatusNoCreativeDesignated) {
  TestCreativeOriginStatus(
      MakeFrame("a", MakeFrame("b", MakeFrame("c", nullptr))),
      OriginStatus::kUnknown, absl::nullopt);
}

// Test that if no iframe is created, there is no histogram set.
IN_PROC_BROWSER_TEST_F(CreativeOriginAdsPageLoadMetricsObserverBrowserTest,
                       CreativeOriginStatusNoSubframes) {
  TestCreativeOriginStatus(MakeFrame("a", nullptr), OriginStatus::kUnknown,
                           OriginStatusWithThrottling::kUnknownAndUnthrottled);
}

// Flakily fails (crbug.com/1099758)
// Test that a throttled ad with a different origin as the main page is
// marked as throttled, with indeterminate creative origin status.
IN_PROC_BROWSER_TEST_F(CreativeOriginAdsPageLoadMetricsObserverBrowserTest,
                       DISABLED_CreativeOriginStatusWithThrottlingUnknown) {
  TestCreativeOriginStatus(
      MakeFrame("a",
                MakeFrame("b", MakeFrame("c", nullptr), true /* has_text */,
                          true /* is_outside_view */)),
      OriginStatus::kUnknown, OriginStatusWithThrottling::kUnknownAndThrottled);
}

// Disabled due to flakiness https://crbug.com/1229601
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_WIN)
#define MAYBE_CreativeOriginStatusWithThrottlingNestedThrottled \
  DISABLED_CreativeOriginStatusWithThrottlingNestedThrottled
#else
#define MAYBE_CreativeOriginStatusWithThrottlingNestedThrottled \
  CreativeOriginStatusWithThrottlingNestedThrottled
#endif

// Test that an ad creative with the same origin as the main page,
// but nested in a throttled cross-origin root ad frame, is marked as
// throttled, with indeterminate creative origin status.
IN_PROC_BROWSER_TEST_F(
    CreativeOriginAdsPageLoadMetricsObserverBrowserTest,
    MAYBE_CreativeOriginStatusWithThrottlingNestedThrottled) {
  TestCreativeOriginStatus(
      MakeFrame(
          "a",
          MakeFrame(
              "b", MakeFrame("a", MakeFrame("c", nullptr), true /* has_text */),
              false /* has_text */, true /* is_outside_view */)),
      OriginStatus::kUnknown, OriginStatusWithThrottling::kUnknownAndThrottled);
}

// Flakily fails. https://crbug.com/1099545
// Test that an ad creative with a different origin as the main page,
// but nested in a same-origin root ad frame, such that its root ad frame
// is outside the main frame but not throttled (because the root is
// same-origin), will be marked as having unknown creative origin status
// (since there will be no FCP) and being unthrottled.
IN_PROC_BROWSER_TEST_F(
    CreativeOriginAdsPageLoadMetricsObserverBrowserTest,
    DISABLED_CreativeOriginStatusWithThrottlingNestedUnthrottled) {
  TestCreativeOriginStatus(
      MakeFrame(
          "a",
          MakeFrame(
              "a", MakeFrame("b", MakeFrame("c", nullptr), true /* has_text */),
              false /* has_text */, true /* is_outside_view */)),
      OriginStatus::kUnknown,
      OriginStatusWithThrottling::kUnknownAndUnthrottled);
}

IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverBrowserTest,
                       UserActivationSetOnFrame) {
  base::HistogramTester histogram_tester;
  ukm::TestAutoSetUkmRecorder ukm_recorder;
  auto waiter = CreatePageLoadMetricsTestWaiter();
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(), embedded_test_server()->GetURL(
                     "foo.com", "/ad_tagging/frame_factory.html")));
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();

  // Create a second frame that will not receive activation.
  EXPECT_TRUE(content::ExecuteScriptWithoutUserGesture(
      web_contents, "createAdFrame('/ad_tagging/ad.html', '');"));
  EXPECT_TRUE(content::ExecuteScriptWithoutUserGesture(
      web_contents, "createAdFrame('/ad_tagging/ad.html', '');"));

  // Wait for the frames resources to be loaded as we only log histograms for
  // frames that have non-zero bytes. Four resources in the main frame and one
  // favicon.
  waiter->AddMinimumCompleteResourcesExpectation(7);
  waiter->Wait();

  // Activate one frame by executing a dummy script.
  content::RenderFrameHost* ad_frame =
      ChildFrameAt(web_contents->GetMainFrame(), 0);
  const std::string no_op_script = "// No-op script";
  EXPECT_TRUE(ExecuteScript(ad_frame, no_op_script));

  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));
  histogram_tester.ExpectBucketCount(
      kAdUserActivationHistogramId,
      page_load_metrics::UserActivationStatus::kReceivedActivation, 1);
  histogram_tester.ExpectBucketCount(
      kAdUserActivationHistogramId,
      page_load_metrics::UserActivationStatus::kNoActivation, 1);
  auto entries =
      ukm_recorder.GetEntriesByName(ukm::builders::AdFrameLoad::kEntryName);
  EXPECT_EQ(2u, entries.size());

  // Verify that one ad was reported to be activated and the other was not.
  EXPECT_TRUE(*ukm_recorder.GetEntryMetric(
                  entries.front(),
                  ukm::builders::AdFrameLoad::kStatus_UserActivationName) !=
              *ukm_recorder.GetEntryMetric(
                  entries.back(),
                  ukm::builders::AdFrameLoad::kStatus_UserActivationName));
}

// See https://crbug.com/1193885.
IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverBrowserTest,
                       UserActivationSetOnFrameAfterSameOriginActivation) {
  base::HistogramTester histogram_tester;
  ukm::TestAutoSetUkmRecorder ukm_recorder;
  auto waiter = CreatePageLoadMetricsTestWaiter();
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(), embedded_test_server()->GetURL(
                     "foo.com", "/ad_tagging/frame_factory.html")));
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();

  // Create two same-origin ad frames.
  EXPECT_TRUE(content::ExecuteScriptWithoutUserGesture(
      web_contents, "createAdFrame('/ad_tagging/ad.html', '');"));
  EXPECT_TRUE(content::ExecuteScriptWithoutUserGesture(
      web_contents, "createAdFrame('/ad_tagging/ad.html', '');"));

  // Wait for the frames resources to be loaded as we only log histograms for
  // frames that have non-zero bytes. Four resources in the main frame and one
  // favicon.
  waiter->AddMinimumCompleteResourcesExpectation(7);
  waiter->Wait();

  // Activate one frame by executing a dummy script. This will inherently
  // activate the second frame due to same-origin visibility user activation.
  // The activation of the second frame by this heuristic should be ignored.
  content::RenderFrameHost* ad_frame =
      ChildFrameAt(web_contents->GetMainFrame(), 0);
  const std::string no_op_script = "// No-op script";
  EXPECT_TRUE(ExecuteScript(ad_frame, no_op_script));

  // Activate the other frame directly by executing a dummy script.
  content::RenderFrameHost* ad_frame_2 =
      ChildFrameAt(web_contents->GetMainFrame(), 1);
  EXPECT_TRUE(ExecuteScript(ad_frame_2, no_op_script));

  // Ensure both frames are marked active.
  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));
  histogram_tester.ExpectUniqueSample(
      kAdUserActivationHistogramId,
      page_load_metrics::UserActivationStatus::kReceivedActivation, 2);
}

// TODO(https://crbug.com/1234339): Test is flaky.
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
#define MAYBE_DocOverwritesNavigation DISABLED_DocOverwritesNavigation
#else
#define MAYBE_DocOverwritesNavigation DocOverwritesNavigation
#endif
// Test that a subframe that aborts (due to doc.write) doesn't cause a crash
// if it continues to load resources.
IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverBrowserTest,
                       MAYBE_DocOverwritesNavigation) {
  // Ensure that the previous page won't be stored in the back/forward cache, so
  // that the histogram will be recorded when the previous page is unloaded.
  // TODO(https://crbug.com/1229122): Investigate if this needs further fix.
  browser()
      ->tab_strip_model()
      ->GetActiveWebContents()
      ->GetController()
      .GetBackForwardCache()
      .DisableForTesting(content::BackForwardCache::TEST_ASSUMES_NO_CACHING);

  content::DOMMessageQueue msg_queue;

  ukm::TestAutoSetUkmRecorder ukm_recorder;
  auto waiter = CreatePageLoadMetricsTestWaiter();
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(), embedded_test_server()->GetURL(
                     "/ads_observer/docwrite_provisional_frame.html")));
  std::string status;
  EXPECT_TRUE(msg_queue.WaitForMessage(&status));
  EXPECT_EQ("\"loaded\"", status);

  // Navigate away to force the histogram recording.
  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));

  auto entries =
      ukm_recorder.GetEntriesByName(ukm::builders::AdFrameLoad::kEntryName);
  EXPECT_EQ(1u, entries.size());
  ukm_recorder.ExpectEntryMetric(
      entries.front(), ukm::builders::AdFrameLoad::kLoading_NumResourcesName,
      3);

  // TODO(https://crbug.com/): We should verify that we also receive FCP for
  // frames that are loaded in this manner. Currently timing updates are not
  // sent for aborted navigations due to doc.write.
}

// Test that a blank ad subframe that is docwritten correctly reports metrics.
IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverBrowserTest,
                       DocWriteAboutBlankAdframe) {
  base::HistogramTester histogram_tester;
  ukm::TestAutoSetUkmRecorder ukm_recorder;
  auto waiter = CreatePageLoadMetricsTestWaiter();
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(), embedded_test_server()->GetURL(
                     "/ads_observer/docwrite_blank_frame.html")));
  waiter->AddMinimumCompleteResourcesExpectation(5);
  waiter->Wait();
  // Navigate away to force the histogram recording.
  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));
  histogram_tester.ExpectUniqueSample(
      "PageLoad.Clients.Ads.FrameCounts.AdFrames.Total", 1, 1);
  histogram_tester.ExpectUniqueSample(
      "PageLoad.Clients.Ads.Bytes.AdFrames.Aggregate.Total2", 0 /* < 1 KB */,
      1);
  auto entries =
      ukm_recorder.GetEntriesByName(ukm::builders::AdFrameLoad::kEntryName);
  EXPECT_EQ(1u, entries.size());
  EXPECT_GT(*ukm_recorder.GetEntryMetric(
                entries.front(),
                ukm::builders::AdFrameLoad::kLoading_NetworkBytesName),
            0);
}

IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverBrowserTest,
                       SubresourceFilter) {
  base::HistogramTester histogram_tester;
  ukm::TestAutoSetUkmRecorder ukm_recorder;
  // cross_site_iframe_factory loads URLs like:
  // http://b.com:40919/cross_site_iframe_factory.html?b()
  SetRulesetToDisallowURLsWithPathSuffix("b()");
  const GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b,b,c,d)"));

  auto waiter = CreatePageLoadMetricsTestWaiter();
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_url));

  // One favicon resource and 2 resources for each frame.
  waiter->AddMinimumCompleteResourcesExpectation(11);
  waiter->Wait();

  // Navigate away to force the histogram recording.
  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));

  histogram_tester.ExpectUniqueSample(
      "PageLoad.Clients.Ads.FrameCounts.AdFrames.Total", 2, 1);
  auto entries =
      ukm_recorder.GetEntriesByName(ukm::builders::AdFrameLoad::kEntryName);
  EXPECT_EQ(2u, entries.size());
}

IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverBrowserTest, FrameDepth) {
  base::HistogramTester histogram_tester;
  ukm::TestAutoSetUkmRecorder ukm_recorder;
  // cross_site_iframe_factory loads URLs like:
  // http://b.com:40919/cross_site_iframe_factory.html?b()
  SetRulesetToDisallowURLsWithPathSuffix("b()))");
  const GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b(b(b())))"));

  auto waiter = CreatePageLoadMetricsTestWaiter();
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_url));

  // One favicon resource and 2 resources for each frame.
  waiter->AddMinimumCompleteResourcesExpectation(9);
  waiter->Wait();

  // Navigate away to force the histogram recording.
  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));
  auto entries =
      ukm_recorder.GetEntriesByName(ukm::builders::AdFrameLoad::kEntryName);
  EXPECT_EQ(1u, entries.size());
  ukm_recorder.ExpectEntryMetric(
      entries.front(), ukm::builders::AdFrameLoad::kFrameDepthName, 2);
}

// Test that an ad frame with visible resource gets a FCP.
IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverBrowserTest,
                       FirstContentfulPaintRecorded) {
  SetRulesetWithRules(
      {subresource_filter::testing::CreateSuffixRule("pixel.png")});
  base::HistogramTester histogram_tester;
  auto waiter = CreatePageLoadMetricsTestWaiter();
  waiter->AddSubFrameExpectation(page_load_metrics::PageLoadMetricsTestWaiter::
                                     TimingField::kFirstContentfulPaint);
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(), embedded_test_server()->GetURL(
                     "/ads_observer/display_block_adframe.html")));

  // Wait for FirstContentfulPaint in a subframe.
  waiter->Wait();

  // Navigate away so that it records the metric.
  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));

  histogram_tester.ExpectTotalCount(
      "PageLoad.Clients.Ads.AdPaintTiming.NavigationToFirstContentfulPaint3",
      1);
  histogram_tester.ExpectTotalCount(
      "PageLoad.Clients.Ads.Visible.AdPaintTiming."
      "NavigationToFirstContentfulPaint3",
      1);
  histogram_tester.ExpectTotalCount(
      "PageLoad.Clients.Ads.NonVisible.AdPaintTiming."
      "NavigationToFirstContentfulPaint3",
      0);
}

// Test that a frame without display:none is reported as visible.
IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverBrowserTest,
                       VisibleAdframeRecorded) {
  SetRulesetWithRules(
      {subresource_filter::testing::CreateSuffixRule("pixel.png")});
  base::HistogramTester histogram_tester;
  ukm::TestAutoSetUkmRecorder ukm_recorder;
  auto waiter = CreatePageLoadMetricsTestWaiter();
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(), embedded_test_server()->GetURL(
                     "/ads_observer/display_block_adframe.html")));
  waiter->AddMinimumCompleteResourcesExpectation(4);
  waiter->Wait();
  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));
  histogram_tester.ExpectTotalCount(
      "PageLoad.Clients.Ads.Visible.Bytes.AdFrames.PerFrame.Total2", 1);
  histogram_tester.ExpectTotalCount(
      "PageLoad.Clients.Ads.Bytes.AdFrames.PerFrame.Total2", 1);
  histogram_tester.ExpectTotalCount(
      "PageLoad.Clients.Ads.NonVisible.Bytes.AdFrames.PerFrame.Total2", 0);
  auto entries =
      ukm_recorder.GetEntriesByName(ukm::builders::AdFrameLoad::kEntryName);
  EXPECT_EQ(1u, entries.size());
  ukm_recorder.ExpectEntryMetric(
      entries.front(), ukm::builders::AdFrameLoad::kVisibility_HiddenName,
      false);
}

IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverBrowserTest,
                       DisplayNoneAdframeRecorded) {
  base::HistogramTester histogram_tester;
  ukm::TestAutoSetUkmRecorder ukm_recorder;
  auto waiter = CreatePageLoadMetricsTestWaiter();
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(), embedded_test_server()->GetURL(
                     "/ads_observer/display_none_adframe.html")));
  waiter->AddMinimumCompleteResourcesExpectation(4);
  waiter->Wait();
  // Navigate away to force the histogram recording.
  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));
  histogram_tester.ExpectTotalCount(
      "PageLoad.Clients.Ads.NonVisible.Bytes.AdFrames.PerFrame.Total2", 1);
  histogram_tester.ExpectTotalCount(
      "PageLoad.Clients.Ads.Bytes.AdFrames.PerFrame.Total2", 1);
  histogram_tester.ExpectTotalCount(
      "PageLoad.Clients.Ads.Visible.Bytes.AdFrames.PerFrame.Total2", 0);
  auto entries =
      ukm_recorder.GetEntriesByName(ukm::builders::AdFrameLoad::kEntryName);
  EXPECT_EQ(1u, entries.size());
  ukm_recorder.ExpectEntryMetric(
      entries.front(), ukm::builders::AdFrameLoad::kVisibility_HiddenName,
      true);
}

// TODO(https://crbug.com/929136): Investigate why setting display: none on the
// frame will cause size updates to not be received. Verify that we record the
// correct sizes for display: none iframes.
IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverBrowserTest, FramePixelSize) {
  SetRulesetWithRules(
      {subresource_filter::testing::CreateSuffixRule("pixel.png")});
  base::HistogramTester histogram_tester;
  ukm::TestAutoSetUkmRecorder ukm_recorder;
  auto waiter = CreatePageLoadMetricsTestWaiter();
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(), embedded_test_server()->GetURL(
                     "/ads_observer/blank_with_adiframe_writer.html")));
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  std::map<std::pair<int, int>, int> expected_dimension_counts;
  std::map<std::pair<int, int>, int> expected_bucketed_dimension_counts;
  expected_dimension_counts[std::make_pair(100, 100)] = 1;
  expected_dimension_counts[std::make_pair(0, 0)] = 1;
  expected_dimension_counts[std::make_pair(10, 1000)] = 1;

  for (auto const& dimension_and_count : expected_dimension_counts) {
    // Convert the expected dimensions into exponential buckets.
    expected_bucketed_dimension_counts[std::make_pair(
        ukm::GetExponentialBucketMinForCounts1000(
            dimension_and_count.first.first),
        ukm::GetExponentialBucketMinForCounts1000(
            dimension_and_count.first.second))] = 1;
    // Create an iframe with the given dimensions.
    ASSERT_TRUE(
        ExecJs(web_contents,
               "let frame = createAdIframe(); frame.width=" +
                   base::NumberToString(dimension_and_count.first.first) +
                   "; frame.height = " +
                   base::NumberToString(dimension_and_count.first.second) +
                   "; "
                   "frame.src = '/ads_observer/pixel.png';"));
  }

  // Wait for each frames resource to load so that they will have non-zero
  // bytes.
  waiter->AddMinimumCompleteResourcesExpectation(6);
  waiter->AddFrameSizeExpectation(gfx::Size(0, 0));
  waiter->AddFrameSizeExpectation(gfx::Size(10, 1000));
  waiter->AddFrameSizeExpectation(gfx::Size(100, 100));
  waiter->Wait();

  // Navigate away to force the histogram recording.
  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));

  // Verify each UKM entry has a corresponding, unique size.
  auto entries =
      ukm_recorder.GetEntriesByName(ukm::builders::AdFrameLoad::kEntryName);
  EXPECT_EQ(3u, entries.size());
  for (auto* const entry : entries) {
    auto dimension = std::make_pair(
        *ukm_recorder.GetEntryMetric(
            entry, ukm::builders::AdFrameLoad::kVisibility_FrameWidthName),
        *ukm_recorder.GetEntryMetric(
            entry, ukm::builders::AdFrameLoad::kVisibility_FrameHeightName));
    EXPECT_EQ(1u, expected_bucketed_dimension_counts.erase(dimension));
  }
}

IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverBrowserTest,
                       FrameWithSmallAreaNotConsideredVisible) {
  base::HistogramTester histogram_tester;
  auto waiter = CreatePageLoadMetricsTestWaiter();
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(), embedded_test_server()->GetURL(
                     "/ads_observer/blank_with_adiframe_writer.html")));
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();

  // Create a 4x4 iframe. The threshold for visibility is an area of 25 pixels
  // or more.
  ASSERT_TRUE(
      ExecJs(web_contents,
             "let frame = createAdIframe(); frame.width=4; frame.height = 4; "
             "frame.src = '/ads_observer/ad.html';"));

  // Wait for each frames resource to load so that they will have non-zero
  // bytes.
  waiter->AddMinimumCompleteResourcesExpectation(4);
  waiter->AddFrameSizeExpectation(gfx::Size(4, 4));
  waiter->Wait();

  // Navigate away to force the histogram recording.
  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));
  histogram_tester.ExpectUniqueSample(
      "PageLoad.Clients.Ads.Visible.FrameCounts.AdFrames.Total", 0, 1);
  histogram_tester.ExpectUniqueSample(
      "PageLoad.Clients.Ads.NonVisible.FrameCounts.AdFrames.Total", 1, 1);
}

IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverBrowserTest,
                       AdFrameRecordMediaStatusNotPlayed) {
  SetRulesetWithRules(
      {subresource_filter::testing::CreateSuffixRule("pixel.png")});
  ukm::TestAutoSetUkmRecorder ukm_recorder;
  auto waiter = CreatePageLoadMetricsTestWaiter();

  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(),
      embedded_test_server()->GetURL("/ads_observer/same_origin_ad.html")));

  waiter->AddMinimumCompleteResourcesExpectation(4);
  waiter->Wait();

  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));

  auto entries =
      ukm_recorder.GetEntriesByName(ukm::builders::AdFrameLoad::kEntryName);
  EXPECT_EQ(1u, entries.size());
  ukm_recorder.ExpectEntryMetric(
      entries.front(), ukm::builders::AdFrameLoad::kStatus_MediaName,
      static_cast<int>(page_load_metrics::MediaStatus::kNotPlayed));
}

// Flaky on all platforms, http://crbug.com/972822.
IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverBrowserTest,
                       DISABLED_AdFrameRecordMediaStatusPlayed) {
  base::HistogramTester histogram_tester;
  ukm::TestAutoSetUkmRecorder ukm_recorder;
  auto waiter = CreatePageLoadMetricsTestWaiter();
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(),
      embedded_test_server()->GetURL("/ad_tagging/frame_factory.html")));
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();

  // Create a second frame that will not receive activation.
  EXPECT_TRUE(content::ExecuteScriptWithoutUserGesture(
      web_contents,
      "createAdFrame('/ad_tagging/multiple_mimes.html', 'test');"));

  waiter->AddMinimumCompleteResourcesExpectation(8);
  waiter->Wait();

  // Wait for the video to autoplay in the frame.
  content::RenderFrameHost* ad_frame =
      ChildFrameAt(web_contents->GetMainFrame(), 0);
  const std::string play_script =
      "var video = document.getElementsByTagName('video')[0];"
      "video.onplaying = () => { "
      "window.domAutomationController.send('true'); };"
      "video.play();";
  EXPECT_EQ("true", content::EvalJs(ad_frame, play_script,
                                    content::EXECUTE_SCRIPT_USE_MANUAL_REPLY));

  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));

  auto entries =
      ukm_recorder.GetEntriesByName(ukm::builders::AdFrameLoad::kEntryName);
  EXPECT_EQ(1u, entries.size());
  ukm_recorder.ExpectEntryMetric(
      entries.front(), ukm::builders::AdFrameLoad::kStatus_MediaName,
      static_cast<int>(page_load_metrics::MediaStatus::kPlayed));
}

IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverBrowserTest,
                       SameDomainFrameCreatedByAdScript_NotRecorddedAsAd) {
  base::HistogramTester histogram_tester;
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();

  auto waiter = CreatePageLoadMetricsTestWaiter();
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(),
      embedded_test_server()->GetURL(
          "a.com", "/ads_observer/blank_with_adiframe_writer.html")));

  waiter->AddSubframeDataExpectation();
  EXPECT_TRUE(
      ExecJs(web_contents,
             content::JsReplace("createAdIframeWithSrc($1);",
                                embedded_test_server()
                                    ->GetURL("a.com", "/ads_observer/pixel.png")
                                    .spec())));
  waiter->Wait();

  // Re-navigate to record histograms.
  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));

  // There should be no observed ads because the ad iframe was same domain.
  histogram_tester.ExpectUniqueSample(
      "PageLoad.Clients.Ads.FrameCounts.AdFrames.Total", 0, 1);
  histogram_tester.ExpectUniqueSample(
      "PageLoad.Clients.Ads.FrameCounts.IgnoredByRestrictedAdTagging", 1, 1);

  waiter = CreatePageLoadMetricsTestWaiter();
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(),
      embedded_test_server()->GetURL(
          "a.com", "/ads_observer/blank_with_adiframe_writer.html")));

  // This time create a frame that is not same-domain.
  waiter->AddSubframeDataExpectation();
  EXPECT_TRUE(
      ExecJs(web_contents,
             content::JsReplace("createAdIframeWithSrc($1);",
                                embedded_test_server()
                                    ->GetURL("b.com", "/ads_observer/pixel.png")
                                    .spec())));
  waiter->Wait();

  // The frame should be tagged an ad.
  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));
  histogram_tester.ExpectBucketCount(
      "PageLoad.Clients.Ads.FrameCounts.AdFrames.Total", 1, 1);
  histogram_tester.ExpectBucketCount(
      "PageLoad.Clients.Ads.FrameCounts.IgnoredByRestrictedAdTagging", 0, 1);
}

IN_PROC_BROWSER_TEST_F(
    AdsPageLoadMetricsObserverBrowserTest,
    FrameCreatedByAdScriptNavigatedToAllowListRule_NotRecorddedAsAd) {
  // Subdocument resources should always check allowlist rules, even if
  // there is not matching blocklist rule.
  SetRulesetWithRules(
      {subresource_filter::testing::CreateSuffixRule("ad_iframe_writer.js"),
       subresource_filter::testing::CreateAllowlistSuffixRule("xel.png")});
  base::HistogramTester histogram_tester;
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();

  auto waiter = CreatePageLoadMetricsTestWaiter();
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(),
      embedded_test_server()->GetURL(
          "a.com", "/ads_observer/blank_with_adiframe_writer.html")));

  waiter->AddSubframeDataExpectation();
  EXPECT_TRUE(
      ExecJs(web_contents,
             content::JsReplace("createAdIframeWithSrc($1);",
                                embedded_test_server()
                                    ->GetURL("b.com", "/ads_observer/pixel.png")
                                    .spec())));
  waiter->Wait();

  // Re-navigate to record histograms.
  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));

  // There should be no observed ads because the ad iframe was navigated to an
  // allowlist rule.
  histogram_tester.ExpectUniqueSample(
      "PageLoad.Clients.Ads.FrameCounts.AdFrames.Total", 0, 1);
  histogram_tester.ExpectUniqueSample(
      "PageLoad.Clients.Ads.FrameCounts.IgnoredByRestrictedAdTagging", 1, 1);
}

// This test harness does not start the test server and allows
// ControllableHttpResponses to be declared.
class AdsPageLoadMetricsObserverResourceBrowserTest
    : public subresource_filter::SubresourceFilterBrowserTest {
 public:
  AdsPageLoadMetricsObserverResourceBrowserTest() {
    scoped_feature_list_.InitWithFeaturesAndParameters(
        {{subresource_filter::kAdTagging, {}},
         {subresource_filter::kAdsInterventionsEnforced, {}},
         {heavy_ad_intervention::features::kHeavyAdIntervention, {}},
         {heavy_ad_intervention::features::kHeavyAdPrivacyMitigations,
          {{"host-threshold", "3"}}}},
        {});
  }

  ~AdsPageLoadMetricsObserverResourceBrowserTest() override {}
  void SetUpOnMainThread() override {
    host_resolver()->AddRule("*", "127.0.0.1");
    embedded_test_server()->ServeFilesFromSourceDirectory(
        "components/test/data");
    content::SetupCrossSiteRedirector(embedded_test_server());
    SetRulesetWithRules(
        {subresource_filter::testing::CreateSuffixRule("ad_script.js"),
         subresource_filter::testing::CreateSuffixRule("ad_script_2.js"),
         subresource_filter::testing::CreateSuffixRule("ad_iframe_writer.js")});
  }

  void SetUpCommandLine(base::CommandLine* command_line) override {
    command_line->AppendSwitchASCII(
        switches::kAutoplayPolicy,
        switches::autoplay::kNoUserGestureRequiredPolicy);
  }

  // This function loads a |large_resource| and if |will_block| is set, then
  // checks to see the resource is blocked, otherwise, it uses the |waiter| to
  // wait until the resource is loaded.
  void LoadHeavyAdResourceAndWaitOrError(
      net::test_server::ControllableHttpResponse* large_resource,
      page_load_metrics::PageLoadMetricsTestWaiter* waiter,
      bool will_block) {
    // Create a frame for the large resource.
    content::WebContents* web_contents =
        browser()->tab_strip_model()->GetActiveWebContents();
    EXPECT_TRUE(ExecJs(web_contents,
                       "createAdFrame('/ads_observer/"
                       "ad_with_incomplete_resource.html', '');"));

    if (will_block) {
      // If we expect the resource to be blocked, load a resource large enough
      // to trigger the intervention and ensure that the navigation failed.
      content::TestNavigationObserver error_observer(
          web_contents, net::ERR_BLOCKED_BY_CLIENT);
      page_load_metrics::LoadLargeResource(
          large_resource, page_load_metrics::kMaxHeavyAdNetworkSize);
      error_observer.WaitForNavigationFinished();
      EXPECT_FALSE(error_observer.last_navigation_succeeded());
    } else {
      // Otherwise load the resource, ensuring enough bytes were loaded.
      int64_t current_network_bytes = waiter->current_network_bytes();
      page_load_metrics::LoadLargeResource(
          large_resource, page_load_metrics::kMaxHeavyAdNetworkSize);
      waiter->AddMinimumNetworkBytesExpectation(
          current_network_bytes + page_load_metrics::kMaxHeavyAdNetworkSize);
      waiter->Wait();
    }
  }

 protected:
  std::unique_ptr<page_load_metrics::AdsPageLoadMetricsTestWaiter>
  CreateAdsPageLoadMetricsTestWaiter() {
    content::WebContents* web_contents =
        browser()->tab_strip_model()->GetActiveWebContents();
    return std::make_unique<page_load_metrics::AdsPageLoadMetricsTestWaiter>(
        web_contents);
  }

 private:
  base::test::ScopedFeatureList scoped_feature_list_;
};

IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverResourceBrowserTest,
                       ReceivedAdResources) {
  ASSERT_TRUE(embedded_test_server()->Start());

  auto waiter = CreateAdsPageLoadMetricsTestWaiter();
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(), embedded_test_server()->GetURL(
                     "foo.com", "/ad_tagging/frame_factory.html")));
  // Two subresources should have been reported as ads.
  waiter->AddMinimumAdResourceExpectation(2);
  waiter->Wait();
}

// Main resources for adframes are counted as ad resources.
IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverResourceBrowserTest,
                       ReceivedMainResourceAds) {
  ASSERT_TRUE(embedded_test_server()->Start());

  auto waiter = CreateAdsPageLoadMetricsTestWaiter();

  content::WebContents* contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(), embedded_test_server()->GetURL(
                     "foo.com", "/ad_tagging/frame_factory.html")));
  contents->GetMainFrame()->ExecuteJavaScriptForTests(
      u"createAdFrame('frame_factory.html', '');", base::NullCallback());
  // Two pages subresources should have been reported as ad. The iframe resource
  // and its three subresources should also be reported as ads.
  waiter->AddMinimumAdResourceExpectation(6);
  waiter->Wait();
}

// Subframe navigations report ad resources correctly.
IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverResourceBrowserTest,
                       ReceivedSubframeNavigationAds) {
  ASSERT_TRUE(embedded_test_server()->Start());

  auto waiter = CreateAdsPageLoadMetricsTestWaiter();

  content::WebContents* contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(), embedded_test_server()->GetURL(
                     "foo.com", "/ad_tagging/frame_factory.html")));
  contents->GetMainFrame()->ExecuteJavaScriptForTests(
      u"createAdFrame('frame_factory.html', 'test');", base::NullCallback());
  waiter->AddMinimumAdResourceExpectation(6);
  waiter->Wait();
  NavigateIframeToURL(web_contents(), "test",
                      embedded_test_server()->GetURL(
                          "foo.com", "/ad_tagging/frame_factory.html"));
  // The new subframe and its three subresources should be reported
  // as ads.
  waiter->AddMinimumAdResourceExpectation(10);
  waiter->Wait();
}

// Verify that per-resource metrics are recorded correctly.
IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverResourceBrowserTest,
                       ReceivedAdResourceMetrics) {
  SetRulesetWithRules(
      {subresource_filter::testing::CreateSuffixRule("ad.html"),
       subresource_filter::testing::CreateSuffixRule("ad_script.js")});
  base::HistogramTester histogram_tester;

  auto main_html_response =
      std::make_unique<net::test_server::ControllableHttpResponse>(
          embedded_test_server(), "/mock_page.html",
          true /*relative_url_is_prefix*/);
  auto ad_script_response =
      std::make_unique<net::test_server::ControllableHttpResponse>(
          embedded_test_server(), "/ad_script.js",
          true /*relative_url_is_prefix*/);
  auto iframe_response =
      std::make_unique<net::test_server::ControllableHttpResponse>(
          embedded_test_server(), "/ad.html", true /*relative_url_is_prefix*/);
  auto vanilla_script_response =
      std::make_unique<net::test_server::ControllableHttpResponse>(
          embedded_test_server(), "/vanilla_script.js",
          true /*relative_url_is_prefix*/);
  ASSERT_TRUE(embedded_test_server()->Start());

  auto waiter = CreateAdsPageLoadMetricsTestWaiter();

  browser()->OpenURL(content::OpenURLParams(
      embedded_test_server()->GetURL("/mock_page.html"), content::Referrer(),
      WindowOpenDisposition::CURRENT_TAB, ui::PAGE_TRANSITION_TYPED, false));

  main_html_response->WaitForRequest();
  main_html_response->Send(page_load_metrics::kHttpOkResponseHeader);
  main_html_response->Send(
      "<html><body></body><script src=\"ad_script.js\"></script></html>");
  main_html_response->Send(std::string(1024, ' '));
  main_html_response->Done();

  ad_script_response->WaitForRequest();
  ad_script_response->Send(page_load_metrics::kHttpOkResponseHeader);
  ad_script_response->Send(
      "var iframe = document.createElement(\"iframe\");"
      "iframe.src =\"ad.html\";"
      "document.body.appendChild(iframe);");
  ad_script_response->Send(std::string(1000, ' '));
  ad_script_response->Done();

  iframe_response->WaitForRequest();
  iframe_response->Send(page_load_metrics::kHttpOkResponseHeader);
  iframe_response->Send("<html><script src=\"vanilla_script.js\"></script>");
  iframe_response->Send(std::string(2000, ' '));
  iframe_response->Send("</html>");
  iframe_response->Done();

  vanilla_script_response->WaitForRequest();
  vanilla_script_response->Send(page_load_metrics::kHttpOkResponseHeader);
  vanilla_script_response->Send(std::string(1024, ' '));
  waiter->AddMinimumNetworkBytesExpectation(5000);
  waiter->Wait();

  // Close all tabs instead of navigating as the embedded_test_server will
  // hang waiting for loads to finish when we have an unfinished
  // ControllableHttpResponse.
  browser()->tab_strip_model()->CloseAllTabs();

  // We have received 4 KB of ads, including 1 KB of mainframe ads, plus 1 KB of
  // mainframe content.
  histogram_tester.ExpectBucketCount(
      "PageLoad.Clients.Ads.Bytes.FullPage.Network", 5, 1);
  histogram_tester.ExpectBucketCount(
      "PageLoad.Clients.Ads.Resources.Bytes.Ads2", 4, 1);
  histogram_tester.ExpectBucketCount(
      "PageLoad.Clients.Ads.AllPages.NonAdNetworkBytes", 1, 1);
  histogram_tester.ExpectBucketCount(
      "PageLoad.Clients.Ads.Bytes.MainFrame.Ads.Total2", 1, 1);
  histogram_tester.ExpectBucketCount(
      "PageLoad.Clients.Ads.Bytes.MainFrame.Total2", 2, 1);
}

IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverResourceBrowserTest,
                       IncompleteResourcesRecordedToFrameMetrics) {
  base::HistogramTester histogram_tester;
  ukm::TestAutoSetUkmRecorder ukm_recorder;
  auto incomplete_resource_response =
      std::make_unique<net::test_server::ControllableHttpResponse>(
          embedded_test_server(), "/ads_observer/incomplete_resource.js",
          true /*relative_url_is_prefix*/);
  ASSERT_TRUE(embedded_test_server()->Start());

  auto waiter = CreateAdsPageLoadMetricsTestWaiter();

  browser()->OpenURL(content::OpenURLParams(
      embedded_test_server()->GetURL(
          "/ads_observer/ad_with_incomplete_resource.html"),
      content::Referrer(), WindowOpenDisposition::CURRENT_TAB,
      ui::PAGE_TRANSITION_TYPED, false));

  waiter->AddMinimumCompleteResourcesExpectation(3);
  waiter->Wait();
  int64_t initial_page_bytes = waiter->current_network_bytes();

  // Make the response large enough so that normal editing to the resource files
  // won't interfere with the test expectations.
  const int response_kilobytes = 64;
  const int response_bytes = response_kilobytes * 1024;

  // Ad resource will not finish loading but should be reported to metrics.
  incomplete_resource_response->WaitForRequest();
  incomplete_resource_response->Send(page_load_metrics::kHttpOkResponseHeader);
  incomplete_resource_response->Send(std::string(response_bytes, ' '));

  // Wait for the resource update to be received for the incomplete response.

  waiter->AddMinimumNetworkBytesExpectation(response_bytes);
  waiter->Wait();

  // Close all tabs instead of navigating as the embedded_test_server will
  // hang waiting for loads to finish when we have an unfinished
  // ControllableHttpResponse.
  browser()->tab_strip_model()->CloseAllTabs();

  int expected_page_kilobytes = (initial_page_bytes + response_bytes) / 1024;

  histogram_tester.ExpectBucketCount(
      "PageLoad.Clients.Ads.Bytes.FullPage.Network", expected_page_kilobytes,
      1);
  histogram_tester.ExpectBucketCount(
      "PageLoad.Clients.Ads.Bytes.AdFrames.Aggregate.Network",
      response_kilobytes, 1);
  histogram_tester.ExpectBucketCount(
      "PageLoad.Clients.Ads.Bytes.AdFrames.Aggregate.Total2",
      response_kilobytes, 1);
  histogram_tester.ExpectBucketCount(
      "PageLoad.Clients.Ads.Bytes.AdFrames.PerFrame.Network",
      response_kilobytes, 1);
  histogram_tester.ExpectBucketCount(
      "PageLoad.Clients.Ads.Bytes.AdFrames.PerFrame.Total2", response_kilobytes,
      1);
  auto entries =
      ukm_recorder.GetEntriesByName(ukm::builders::AdFrameLoad::kEntryName);
  EXPECT_EQ(1u, entries.size());
  ukm_recorder.ExpectEntryMetric(
      entries.front(), ukm::builders::AdFrameLoad::kLoading_NetworkBytesName,
      ukm::GetExponentialBucketMinForBytes(response_bytes));
  ukm_recorder.ExpectEntryMetric(
      entries.front(), ukm::builders::AdFrameLoad::kLoading_CacheBytes2Name, 0);
}

// Verifies that the ad unloaded by the heavy ad intervention receives an
// intervention report prior to being unloaded.
IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverResourceBrowserTest,
                       HeavyAdInterventionFired_ReportSent) {
  base::HistogramTester histogram_tester;
  auto incomplete_resource_response =
      std::make_unique<net::test_server::ControllableHttpResponse>(
          embedded_test_server(), "/ads_observer/incomplete_resource.js",
          true /*relative_url_is_prefix*/);
  ASSERT_TRUE(embedded_test_server()->Start());

  // Create a navigation observer that will watch for the intervention to
  // navigate the frame.
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();

  auto waiter = CreateAdsPageLoadMetricsTestWaiter();
  GURL url = embedded_test_server()->GetURL(
      "/ads_observer/ad_with_incomplete_resource.html");
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

  content::RenderFrameHost* ad_frame =
      ChildFrameAt(web_contents->GetMainFrame(), 0);

  content::DOMMessageQueue message_queue(ad_frame);

  const std::string report_script = R"(
      function process(report) {
        if (report.body.id === 'HeavyAdIntervention')
          window.domAutomationController.send('REPORT');
      }

      let observer = new ReportingObserver((reports, observer) => {
        reports.forEach(process);
      });
      observer.observe();

      window.addEventListener('unload', function(event) {
        observer.takeRecords().forEach(process);
        window.domAutomationController.send('END');
      });
  )";
  EXPECT_TRUE(content::ExecJs(ad_frame, report_script,
                              content::EXECUTE_SCRIPT_NO_USER_GESTURE));

  // Load a resource large enough to trigger the intervention.
  page_load_metrics::LoadLargeResource(
      incomplete_resource_response.get(),
      page_load_metrics::kMaxHeavyAdNetworkSize);

  std::string message;
  bool got_report = false;
  while (message_queue.WaitForMessage(&message)) {
    if (message == "\"REPORT\"") {
      got_report = true;
      break;
    }
    if (message == "\"END\"")
      break;
  }
  EXPECT_TRUE(got_report);
}

// Verifies that reports are sent to all children.
// crbug.com/1189635: flaky on win and linux.
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN)
#define MAYBE_HeavyAdInterventionFired_ReportsToAllChildren \
  DISABLED_HeavyAdInterventionFired_ReportsToAllChildren
#else
#define MAYBE_HeavyAdInterventionFired_ReportsToAllChildren \
  HeavyAdInterventionFired_ReportsToAllChildren
#endif
IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverResourceBrowserTest,
                       MAYBE_HeavyAdInterventionFired_ReportsToAllChildren) {
  SetRulesetWithRules(
      {subresource_filter::testing::CreateSuffixRule("frame_factory.html")});
  base::HistogramTester histogram_tester;
  auto large_resource =
      std::make_unique<net::test_server::ControllableHttpResponse>(
          embedded_test_server(), "/ads_observer/incomplete_resource.js",
          false /*relative_url_is_prefix*/);
  ASSERT_TRUE(embedded_test_server()->Start());

  // Create a navigation observer that will watch for the intervention to
  // navigate the frame.
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  content::TestNavigationObserver child_observer(web_contents, 2);
  content::TestNavigationObserver error_observer(web_contents,
                                                 net::ERR_BLOCKED_BY_CLIENT);

  auto waiter = CreateAdsPageLoadMetricsTestWaiter();
  content::WebContentsConsoleObserver console_observer(web_contents);
  console_observer.SetPattern("Ad was removed*");

  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(), embedded_test_server()->GetURL(
                     "foo.com", "/ad_tagging/frame_factory.html")));

  EXPECT_TRUE(ExecJs(web_contents,
                     "createAdFrame('/ad_tagging/frame_factory.html', '');"));

  child_observer.Wait();

  content::RenderFrameHost* ad_frame =
      ChildFrameAt(web_contents->GetMainFrame(), 0);

  auto cross_origin_ad_url = embedded_test_server()->GetURL(
      "xyz.com", "/ad_tagging/frame_factory.html");

  EXPECT_TRUE(ExecJs(
      ad_frame,
      "createAdFrame('/ads_observer/ad_with_incomplete_resource.html', '');",
      content::EXECUTE_SCRIPT_NO_USER_GESTURE));
  EXPECT_TRUE(ExecJs(ad_frame,
                     "createAdFrame('" + cross_origin_ad_url.spec() + "', '');",
                     content::EXECUTE_SCRIPT_NO_USER_GESTURE));

  // Load a resource large enough to trigger the intervention.
  page_load_metrics::LoadLargeResource(
      large_resource.get(), page_load_metrics::kMaxHeavyAdNetworkSize);

  error_observer.WaitForNavigationFinished();

  // Every frame should get a report (ad_with_incomplete_resource.html loads two
  // frames).
  EXPECT_EQ(4u, console_observer.messages().size());
}

// Verifies that the frame is navigated to the intervention page when a
// heavy ad intervention triggers.
IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverResourceBrowserTest,
                       HeavyAdInterventionEnabled_ErrorPageLoaded) {
  base::HistogramTester histogram_tester;
  auto incomplete_resource_response =
      std::make_unique<net::test_server::ControllableHttpResponse>(
          embedded_test_server(), "/ads_observer/incomplete_resource.js",
          true /*relative_url_is_prefix*/);
  ASSERT_TRUE(embedded_test_server()->Start());

  // Create a navigation observer that will watch for the intervention to
  // navigate the frame.
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  content::TestNavigationObserver error_observer(web_contents,
                                                 net::ERR_BLOCKED_BY_CLIENT);

  auto waiter = CreateAdsPageLoadMetricsTestWaiter();
  GURL url = embedded_test_server()->GetURL(
      "/ads_observer/ad_with_incomplete_resource.html");
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

  // Load a resource large enough to trigger the intervention.
  page_load_metrics::LoadLargeResource(
      incomplete_resource_response.get(),
      page_load_metrics::kMaxHeavyAdNetworkSize);

  // Wait for the intervention page navigation to finish on the frame.
  error_observer.WaitForNavigationFinished();

  histogram_tester.ExpectUniqueSample(
      kHeavyAdInterventionTypeHistogramId,
      page_load_metrics::HeavyAdStatus::kNetwork, 1);

  // Check that the ad frame was navigated to the intervention page.
  EXPECT_FALSE(error_observer.last_navigation_succeeded());

  histogram_tester.ExpectUniqueSample(
      kHeavyAdInterventionTypeHistogramId,
      page_load_metrics::HeavyAdStatus::kNetwork, 1);
  histogram_tester.ExpectBucketCount(
      "Blink.UseCounter.Features",
      blink::mojom::WebFeature::kHeavyAdIntervention, 1);
}

class AdsPageLoadMetricsObserverResourceBrowserTestWithoutHeavyAdIntervention
    : public AdsPageLoadMetricsObserverResourceBrowserTest {
 public:
  AdsPageLoadMetricsObserverResourceBrowserTestWithoutHeavyAdIntervention() {
    // The experiment is "on" if either intervention or reporting is active.
    feature_list_.InitWithFeatures(
        {}, {heavy_ad_intervention::features::kHeavyAdIntervention,
             heavy_ad_intervention::features::kHeavyAdInterventionWarning});
  }

 private:
  base::test::ScopedFeatureList feature_list_;
};

// Check that when the heavy ad feature is disabled we don't navigate
// the frame.
IN_PROC_BROWSER_TEST_F(
    AdsPageLoadMetricsObserverResourceBrowserTestWithoutHeavyAdIntervention,
    ErrorPageNotLoaded) {
  base::HistogramTester histogram_tester;
  auto incomplete_resource_response =
      std::make_unique<net::test_server::ControllableHttpResponse>(
          embedded_test_server(), "/ads_observer/incomplete_resource.js",
          true /*relative_url_is_prefix*/);
  ASSERT_TRUE(embedded_test_server()->Start());

  auto waiter = CreateAdsPageLoadMetricsTestWaiter();
  GURL url = embedded_test_server()->GetURL(
      "/ads_observer/ad_with_incomplete_resource.html");
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

  // Load a resource large enough to trigger the intervention.
  page_load_metrics::LoadLargeResource(
      incomplete_resource_response.get(),
      page_load_metrics::kMaxHeavyAdNetworkSize);

  // Wait for the resource update to be received for the large resource.
  waiter->AddMinimumNetworkBytesExpectation(
      page_load_metrics::kMaxHeavyAdNetworkSize);
  waiter->Wait();

  // We can't check whether the navigation didn't occur because the error page
  // load is not synchronous. Instead check that we didn't log intervention UMA
  // that is always recorded when the intervention occurs.
  histogram_tester.ExpectTotalCount(kHeavyAdInterventionTypeHistogramId, 0);

  histogram_tester.ExpectBucketCount(
      "Blink.UseCounter.Features",
      blink::mojom::WebFeature::kHeavyAdIntervention, 0);
}

// Check that we don't activate a HeavyAdIntervention field trial if we don't
// have a heavy ad.
IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverResourceBrowserTest,
                       HeavyAdInterventionNoHeavyAd_FieldTrialNotActive) {
  base::HistogramTester histogram_tester;

  auto incomplete_resource_response =
      std::make_unique<net::test_server::ControllableHttpResponse>(
          embedded_test_server(), "/ads_observer/incomplete_resource.js",
          true /*relative_url_is_prefix*/);
  ASSERT_TRUE(embedded_test_server()->Start());

  auto waiter = CreateAdsPageLoadMetricsTestWaiter();
  GURL url = embedded_test_server()->GetURL(
      "/ads_observer/ad_with_incomplete_resource.html");
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

  // Load a resource not large enough to trigger the intervention.
  page_load_metrics::LoadLargeResource(
      incomplete_resource_response.get(),
      page_load_metrics::kMaxHeavyAdNetworkSize / 2);

  // Wait for the resource update to be received for the large resource.
  waiter->AddMinimumNetworkBytesExpectation(
      page_load_metrics::kMaxHeavyAdNetworkSize / 2);
  waiter->Wait();

  histogram_tester.ExpectTotalCount(kHeavyAdInterventionTypeHistogramId, 0);

  // Verify that the trial is not activated if no heavy ads are seen.
  EXPECT_FALSE(base::FieldTrialList::IsTrialActive(
      base::FeatureList::GetFieldTrial(
          heavy_ad_intervention::features::kHeavyAdIntervention)
          ->trial_name()));
}

// Check that the Heavy Ad Intervention fires the correct number of times to
// protect privacy, and that after that limit is hit, the Ads Intervention
// Framework takes over for future navigations.
IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverResourceBrowserTest,
                       HeavyAdInterventionBlocklistFull_InterventionBlocked) {
  std::vector<std::unique_ptr<net::test_server::ControllableHttpResponse>>
      http_responses(4);
  for (auto& http_response : http_responses) {
    http_response =
        std::make_unique<net::test_server::ControllableHttpResponse>(
            embedded_test_server(), "/ads_observer/incomplete_resource.js",
            false /*relative_url_is_prefix*/);
  }
  base::HistogramTester histogram_tester;
  ASSERT_TRUE(embedded_test_server()->Start());

  // Create a waiter for the navigation and navigate.
  auto waiter = CreateAdsPageLoadMetricsTestWaiter();
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(), embedded_test_server()->GetURL(
                     "foo.com", "/ad_tagging/frame_factory.html")));

  // Load and block the resource. The ads intervention framework should not
  // be triggered at this point.
  LoadHeavyAdResourceAndWaitOrError(http_responses[0].get(), waiter.get(),
                                    /*will_block=*/true);
  histogram_tester.ExpectUniqueSample(
      kHeavyAdInterventionTypeHistogramId,
      page_load_metrics::HeavyAdStatus::kNetwork, 1);
  histogram_tester.ExpectTotalCount(kAdsInterventionRecordedHistogram, 0);
  histogram_tester.ExpectBucketCount(
      "SubresourceFilter.Actions2",
      subresource_filter::SubresourceFilterAction::kUIShown, 0);

  // Block a second resource on the page. The ads intervention framework should
  // not be triggered at this point.
  LoadHeavyAdResourceAndWaitOrError(http_responses[1].get(), waiter.get(),
                                    /*will_block=*/true);
  histogram_tester.ExpectUniqueSample(
      kHeavyAdInterventionTypeHistogramId,
      page_load_metrics::HeavyAdStatus::kNetwork, 2);
  histogram_tester.ExpectTotalCount(kAdsInterventionRecordedHistogram, 0);
  histogram_tester.ExpectBucketCount(
      "SubresourceFilter.Actions2",
      subresource_filter::SubresourceFilterAction::kUIShown, 0);

  // Create a new waiter for the next navigation and navigate.
  waiter = CreateAdsPageLoadMetricsTestWaiter();
  // Set query to ensure that it's not treated as a reload as preview metrics
  // are not recorded for reloads.
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(),
      embedded_test_server()->GetURL(
          "foo.com", "/ad_tagging/frame_factory.html?avoid_reload")));

  // Load and block the resource. The ads intervention framework should
  // be triggered at this point.
  LoadHeavyAdResourceAndWaitOrError(http_responses[2].get(), waiter.get(),
                                    /*will_block=*/true);
  histogram_tester.ExpectUniqueSample(
      kHeavyAdInterventionTypeHistogramId,
      page_load_metrics::HeavyAdStatus::kNetwork, 3);
  histogram_tester.ExpectUniqueSample(
      kAdsInterventionRecordedHistogram,
      subresource_filter::mojom::AdsViolation::kHeavyAdsInterventionAtHostLimit,
      1);
  histogram_tester.ExpectBucketCount(
      "SubresourceFilter.Actions2",
      subresource_filter::SubresourceFilterAction::kUIShown, 0);

  // Allow a second resource on the page. The ads intervention shouldn't fire a
  // second time.
  LoadHeavyAdResourceAndWaitOrError(http_responses[3].get(), waiter.get(),
                                    /*will_block=*/false);
  histogram_tester.ExpectUniqueSample(
      kHeavyAdInterventionTypeHistogramId,
      page_load_metrics::HeavyAdStatus::kNetwork, 3);
  histogram_tester.ExpectUniqueSample(
      kAdsInterventionRecordedHistogram,
      subresource_filter::mojom::AdsViolation::kHeavyAdsInterventionAtHostLimit,
      1);
  histogram_tester.ExpectBucketCount(
      "SubresourceFilter.Actions2",
      subresource_filter::SubresourceFilterAction::kUIShown, 0);

  // Reset the waiter and navigate again. Check we show the Ads Intervention UI.
  waiter.reset();
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(), embedded_test_server()->GetURL(
                     "foo.com", "/ad_tagging/frame_factory.html")));
  histogram_tester.ExpectUniqueSample(
      kAdsInterventionRecordedHistogram,
      subresource_filter::mojom::AdsViolation::kHeavyAdsInterventionAtHostLimit,
      1);
  histogram_tester.ExpectBucketCount(
      "SubresourceFilter.Actions2",
      subresource_filter::SubresourceFilterAction::kUIShown, 1);
}

// Verifies that the blocklist is setup correctly and the intervention triggers
// in incognito mode.
IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverResourceBrowserTest,
                       HeavyAdInterventionIncognitoMode_InterventionFired) {
  base::HistogramTester histogram_tester;
  auto incomplete_resource_response =
      std::make_unique<net::test_server::ControllableHttpResponse>(
          embedded_test_server(), "/ads_observer/incomplete_resource.js",
          true /*relative_url_is_prefix*/);
  ASSERT_TRUE(embedded_test_server()->Start());

  Browser* incognito_browser = CreateIncognitoBrowser();
  content::WebContents* web_contents =
      incognito_browser->tab_strip_model()->GetActiveWebContents();

  // Create a navigation observer that will watch for the intervention to
  // navigate the frame.
  content::TestNavigationObserver error_observer(web_contents,
                                                 net::ERR_BLOCKED_BY_CLIENT);

  // Create a waiter for the incognito contents.
  auto waiter = std::make_unique<page_load_metrics::PageLoadMetricsTestWaiter>(
      web_contents);
  GURL url = embedded_test_server()->GetURL(
      "/ads_observer/ad_with_incomplete_resource.html");
  ASSERT_TRUE(ui_test_utils::NavigateToURL(incognito_browser, url));

  // Load a resource large enough to trigger the intervention.
  page_load_metrics::LoadLargeResource(
      incomplete_resource_response.get(),
      page_load_metrics::kMaxHeavyAdNetworkSize);

  // Wait for the intervention page navigation to finish on the frame.
  error_observer.WaitForNavigationFinished();

  // Check that the ad frame was navigated to the intervention page.
  EXPECT_FALSE(error_observer.last_navigation_succeeded());
}

// Verify that UKM metrics are recorded correctly.
IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverResourceBrowserTest,
                       RecordedUKMMetrics) {
  base::HistogramTester histogram_tester;
  ukm::TestAutoSetUkmRecorder ukm_recorder;
  ASSERT_TRUE(embedded_test_server()->Start());

  auto waiter = CreateAdsPageLoadMetricsTestWaiter();

  content::WebContents* contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  GURL url = embedded_test_server()->GetURL("foo.com",
                                            "/ad_tagging/frame_factory.html");
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
  contents->GetMainFrame()->ExecuteJavaScriptForTests(
      u"createAdFrame('multiple_mimes.html', 'test');", base::NullCallback());
  waiter->AddMinimumAdResourceExpectation(8);
  waiter->Wait();

  // Close all tabs to report metrics.
  browser()->tab_strip_model()->CloseAllTabs();

  // Verify UKM Metrics recorded.
  auto entries =
      ukm_recorder.GetEntriesByName(ukm::builders::AdPageLoad::kEntryName);
  EXPECT_EQ(1u, entries.size());
  ukm_recorder.ExpectEntrySourceHasUrl(entries.front(), url);
  EXPECT_GT(*ukm_recorder.GetEntryMetric(
                entries.front(), ukm::builders::AdPageLoad::kAdBytesName),
            0);
  EXPECT_GT(
      *ukm_recorder.GetEntryMetric(
          entries.front(), ukm::builders::AdPageLoad::kMainframeAdBytesName),
      0);
  EXPECT_GT(
      *ukm_recorder.GetEntryMetric(
          entries.front(), ukm::builders::AdPageLoad::kAdJavascriptBytesName),
      0);
  EXPECT_GT(*ukm_recorder.GetEntryMetric(
                entries.front(), ukm::builders::AdPageLoad::kAdVideoBytesName),
            0);
}

void WaitForRAF(content::DOMMessageQueue* message_queue) {
  std::string message;
  while (message_queue->WaitForMessage(&message)) {
    if (message == "\"RAF DONE\"")
      break;
  }
  EXPECT_EQ("\"RAF DONE\"", message);
}

// Test that rAF events are measured as part of the cpu metrics.
IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverBrowserTest,
                       FrameRAFTriggersCpuUpdate) {
  base::HistogramTester histogram_tester;
  auto waiter = CreatePageLoadMetricsTestWaiter();

  // Navigate to the page and set up the waiter.
  base::TimeTicks start_time = base::TimeTicks::Now();
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(), embedded_test_server()->GetURL("/iframe_blank.html")));
  waiter->AddMinimumAggregateCpuTimeExpectation(base::Milliseconds(300));

  // Navigate the iframe to a page with a delayed rAF, waiting for it to
  // complete. Long enough to guarantee the frame client sees a cpu time
  // update. (See: LocalFrame::AddTaskTime kTaskDurationSendThreshold).
  NavigateIframeToURL(
      web_contents(), "test",
      embedded_test_server()->GetURL(
          "a.com", "/ads_observer/expensive_animation_frame.html?delay=300"));

  // Wait until we've received the cpu update and navigate away.
  waiter->Wait();
  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));

  // The elapsed_time is an upper bound on the overall page time, as it runs
  // from just before to just after activation.  The task itself is guaranteed
  // to have run at least 300ms, so we can derive a minimum percent of cpu time
  // that the task should have taken.
  base::TimeDelta elapsed_time = base::TimeTicks::Now() - start_time;
  EXPECT_GE(elapsed_time.InMilliseconds(), 300);

  // Ensure that there is a single entry that is at least the percent specified.
  int min_percent =
      100 * 300 /
      page_load_metrics::PeakCpuAggregator::kWindowSize.InMilliseconds();
  auto samples = histogram_tester.GetAllSamples(kPeakWindowdPercentHistogramId);
  EXPECT_EQ(1u, samples.size());
  EXPECT_EQ(1, samples.front().count);
  EXPECT_LE(min_percent, samples.front().min);
}

// Test that rAF events are measured as part of the cpu metrics.
IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverBrowserTest,
                       TwoRAFFramesTriggerCpuUpdates) {
  base::HistogramTester histogram_tester;
  auto waiter = CreatePageLoadMetricsTestWaiter();

  // Navigate to the page and set up the waiter.
  content::DOMMessageQueue message_queue(web_contents());
  base::TimeTicks start_time = base::TimeTicks::Now();

  // Each rAF frame in two_raf_frames delays for 200ms.
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(),
      embedded_test_server()->GetURL("/ads_observer/two_raf_frames.html")));

  // Wait for both RAF calls to finish
  WaitForRAF(&message_queue);
  WaitForRAF(&message_queue);
  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));

  // The elapsed_time is an upper bound on the overall page time, as it runs
  // from just before to just after activation.  The task itself is guaranteed
  // to have run at least 200ms, so we can derive a minimum percent of cpu time
  // that the task should have taken.
  base::TimeDelta elapsed_time = base::TimeTicks::Now() - start_time;
  EXPECT_GE(elapsed_time.InMilliseconds(), 200);

  // Ensure that there is a single entry that is at least the peak windowed
  // percent of 400ms.
  int min_percent =
      100 * 400 /
      page_load_metrics::PeakCpuAggregator::kWindowSize.InMilliseconds();
  auto samples = histogram_tester.GetAllSamples(kPeakWindowdPercentHistogramId);
  EXPECT_EQ(1u, samples.size());
  EXPECT_EQ(1, samples.front().count);
  EXPECT_LE(min_percent, samples.front().min);
}

// Test that cpu time aggregation across a subframe navigation is cumulative.
IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverBrowserTest,
                       AggregateCpuTriggersCpuUpdateOverSubframeNavigate) {
  base::HistogramTester histogram_tester;
  auto waiter = CreatePageLoadMetricsTestWaiter();

  // Navigate to the page and set up the waiter.
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(), embedded_test_server()->GetURL("/iframe_blank.html")));
  waiter->AddMinimumAggregateCpuTimeExpectation(base::Milliseconds(100));

  // Navigate twice to a page delaying 50ms.  The first and second navigations
  // by themselves aren't enough to trigger a cpu update, but when combined an
  // update fires. (See: LocalFrame::AddTaskTime kTaskDurationSendThreshold).
  // Navigate the first time, waiting for it to complete so that the work is
  // observed, then renavigate.
  content::DOMMessageQueue message_queue(web_contents());
  NavigateIframeToURL(
      web_contents(), "test",
      embedded_test_server()->GetURL(
          "a.com", "/ads_observer/expensive_animation_frame.html?delay=50"));
  WaitForRAF(&message_queue);
  NavigateIframeToURL(
      web_contents(), "test",
      embedded_test_server()->GetURL(
          "a.com", "/ads_observer/expensive_animation_frame.html?delay=50"));

  // Wait until we've received the cpu update and navigate away. If CPU is
  // not cumulative, this hangs waiting for a CPU update indefinitely.
  waiter->Wait();
  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));
}

// Test that cpu metrics are cumulative across subframe navigations.
IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverBrowserTest,
                       SubframeNavigate_CpuTimesCumulative) {
  base::HistogramTester histogram_tester;
  auto waiter = CreatePageLoadMetricsTestWaiter();

  // Navigate to the page and set up the waiter.
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(), embedded_test_server()->GetURL("/iframe_blank.html")));

  waiter->AddMinimumAggregateCpuTimeExpectation(base::Milliseconds(300));

  // Navigate twice to a page with enough cumulative time to measure
  // at least 1% peak windowed percent (300ms), either individually leads to 0
  // % peak windowed percent.
  base::TimeTicks start_time = base::TimeTicks::Now();
  content::DOMMessageQueue message_queue(web_contents());
  NavigateIframeToURL(
      web_contents(), "test",
      embedded_test_server()->GetURL(
          "a.com", "/ads_observer/expensive_animation_frame.html?delay=200"));
  WaitForRAF(&message_queue);
  NavigateIframeToURL(
      web_contents(), "test",
      embedded_test_server()->GetURL(
          "a.com", "/ads_observer/expensive_animation_frame.html?delay=100"));

  // Wait until we've received the cpu update and navigate away.
  waiter->Wait();
  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));

  // The elapsed_time is an upper bound on the overall page time, as it runs
  // from just before to just after activation.  The tasks in aggregate are
  // guaranteed to have run for at least 300ms, so we can derive a minimum
  // percent of cpu time that the tasks should have taken.
  base::TimeDelta elapsed_time = base::TimeTicks::Now() - start_time;
  EXPECT_GE(elapsed_time.InMilliseconds(), 300);

  // Ensure that there is a single entry that is at least the peak windowed
  // percent of 400ms.
  int min_percent =
      100 * 300 /
      page_load_metrics::PeakCpuAggregator::kWindowSize.InMilliseconds();
  auto samples = histogram_tester.GetAllSamples(kPeakWindowdPercentHistogramId);
  EXPECT_EQ(1u, samples.size());
  EXPECT_EQ(1, samples.front().count);
  EXPECT_LE(min_percent, samples.front().min);
}

IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverBrowserTest,
                       DisallowedAdFrames_NotMeasured) {
  base::HistogramTester histogram_tester;
  ukm::TestAutoSetUkmRecorder ukm_recorder;

  ResetConfiguration(subresource_filter::Configuration(
      subresource_filter::mojom::ActivationLevel::kEnabled,
      subresource_filter::ActivationScope::ALL_SITES));

  // cross_site_iframe_factory loads URLs like:
  // http://b.com:40919/cross_site_iframe_factory.html?b()
  SetRulesetToDisallowURLsWithPathSuffix("b()");
  const GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b,b,c,d)"));

  auto waiter = CreatePageLoadMetricsTestWaiter();
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_url));

  // One favicon resource and 2 resources for frames a,c,d
  waiter->AddPageExpectation(
      page_load_metrics::PageLoadMetricsTestWaiter::TimingField::kLoadEvent);
  waiter->Wait();

  // Navigate away to force the histogram recording.
  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));

  // Check that adframes are not included in UKM's or UMA metrics.
  auto entries =
      ukm_recorder.GetEntriesByName(ukm::builders::AdFrameLoad::kEntryName);
  EXPECT_EQ(0u, entries.size());
  histogram_tester.ExpectTotalCount(
      "PageLoad.Clients.Ads.Bytes.AdFrames.Aggregate.Total2", 0);
  histogram_tester.ExpectTotalCount(
      "PageLoad.Clients.Ads.FrameCounts.AdFrames.Total", 0);
}

// DummyMemoryObserver is a subclass of V8DetailedMemoryObserverAnySeq so
// that we can spin up a request in the AdsMemoryMeasurementBrowserTest with
// MeasurementMode::kEagerForTesting, which will make measurements available
// to the PageLoadMetricsMemoryTracker much more quickly than they would be
// otherwise.
class DummyMemoryObserver
    : public performance_manager::v8_memory::V8DetailedMemoryObserverAnySeq {
 public:
  DummyMemoryObserver() = default;
  ~DummyMemoryObserver() override = default;

  void OnV8MemoryMeasurementAvailable(
      performance_manager::RenderProcessHostId process_id,
      const performance_manager::v8_memory::V8DetailedMemoryProcessData&
          process_data,
      const performance_manager::v8_memory::V8DetailedMemoryObserverAnySeq::
          FrameDataMap& frame_data) override {}
};

class AdsMemoryMeasurementBrowserTest
    : public subresource_filter::SubresourceFilterBrowserTest {
 public:
  AdsMemoryMeasurementBrowserTest() = default;

  AdsMemoryMeasurementBrowserTest(const AdsMemoryMeasurementBrowserTest&) =
      delete;
  AdsMemoryMeasurementBrowserTest& operator=(
      const AdsMemoryMeasurementBrowserTest&) = delete;

  ~AdsMemoryMeasurementBrowserTest() override = default;

  void SetUp() override {
    performance_manager::v8_memory::internal::
        SetEagerMemoryMeasurementEnabledForTesting(true);
    std::vector<base::Feature> enabled = {
        subresource_filter::kAdTagging, features::kV8PerFrameMemoryMonitoring};
    std::vector<base::Feature> disabled = {};
    scoped_feature_list_.InitWithFeatures(enabled, disabled);

    subresource_filter::SubresourceFilterBrowserTest::SetUp();
  }

  std::unique_ptr<page_load_metrics::PageLoadMetricsTestWaiter>
  CreatePageLoadMetricsTestWaiter() {
    content::WebContents* web_contents =
        browser()->tab_strip_model()->GetActiveWebContents();
    return std::make_unique<page_load_metrics::PageLoadMetricsTestWaiter>(
        web_contents);
  }

  std::unordered_set<content::GlobalRenderFrameHostId,
                     content::GlobalRenderFrameHostIdHasher>
  GetFrameRoutingIds() {
    content::WebContents* web_contents =
        browser()->tab_strip_model()->GetActiveWebContents();
    std::unordered_set<content::GlobalRenderFrameHostId,
                       content::GlobalRenderFrameHostIdHasher>
        frame_routing_ids;

    web_contents->GetMainFrame()->ForEachRenderFrameHost(base::BindRepeating(
        [](std::unordered_set<content::GlobalRenderFrameHostId,
                              content::GlobalRenderFrameHostIdHasher>*
               frame_routing_ids,
           content::RenderFrameHost* frame) {
          frame_routing_ids->insert(frame->GetGlobalId());
        },
        &frame_routing_ids));

    return frame_routing_ids;
  }

 private:
  std::unique_ptr<page_load_metrics::PageLoadMetricsTestWaiter> waiter_;
  base::test::ScopedFeatureList scoped_feature_list_;
};

IN_PROC_BROWSER_TEST_F(AdsMemoryMeasurementBrowserTest,
                       SingleAdFrame_MaxMemoryBytesRecorded) {
  base::HistogramTester histogram_tester;

  // Instantiate a memory request and observer to set memory measurement
  // polling parameters.
  std::unique_ptr<performance_manager::v8_memory::V8DetailedMemoryRequestAnySeq>
      memory_request = std::make_unique<
          performance_manager::v8_memory::V8DetailedMemoryRequestAnySeq>(
          base::Seconds(1),
          performance_manager::v8_memory::V8DetailedMemoryRequest::
              MeasurementMode::kEagerForTesting);
  auto memory_observer = std::make_unique<DummyMemoryObserver>();
  memory_request->AddObserver(memory_observer.get());

  // cross_site_iframe_factory loads URLs like:
  // http://b.com:40919/cross_site_iframe_factory.html?b()
  SetRulesetWithRules({subresource_filter::testing::CreateSuffixRule("b()")});
  const GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));

  // Create a waiter, navigate the mainframe to "about:blank", and prime the
  // waiter with the mainframe's routing ID.
  auto waiter = CreatePageLoadMetricsTestWaiter();
  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));

  waiter->AddMemoryUpdateExpectation(browser()
                                         ->tab_strip_model()
                                         ->GetActiveWebContents()
                                         ->GetMainFrame()
                                         ->GetGlobalId());

  // Navigate to the main URL.
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_url));

  // Add any additional frame routing IDs and wait until we get positive
  // memory measurements for each frame.
  for (content::GlobalRenderFrameHostId id : GetFrameRoutingIds())
    waiter->AddMemoryUpdateExpectation(id);
  waiter->Wait();

  // Navigate away to force the histogram recording.
  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));

  histogram_tester.ExpectTotalCount(kMemoryPerFrameMaxHistogramId, 1);
  EXPECT_GT(
      histogram_tester.GetAllSamples(kMemoryPerFrameMaxHistogramId)[0].min, 0);

  histogram_tester.ExpectTotalCount(kMemoryAggregateMaxHistogramId, 1);
  EXPECT_GT(
      histogram_tester.GetAllSamples(kMemoryAggregateMaxHistogramId)[0].min, 0);

  histogram_tester.ExpectTotalCount(kMemoryMainFrameMaxHistogramId, 1);
  EXPECT_GT(
      histogram_tester.GetAllSamples(kMemoryMainFrameMaxHistogramId)[0].min, 0);

  histogram_tester.ExpectTotalCount(kMemoryUpdateCountHistogramId, 1);
  EXPECT_GE(
      histogram_tester.GetAllSamples(kMemoryUpdateCountHistogramId)[0].min, 1);

  memory_request->RemoveObserver(memory_observer.get());
}
