// 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 "chrome/browser/metrics/process_memory_metrics_emitter.h"

#include "base/memory/ref_counted.h"
#include "base/run_loop.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/trace_event_analyzer.h"
#include "base/trace_event/memory_dump_manager.h"
#include "base/trace_event/trace_config_memory_test_util.h"
#include "build/build_config.h"
#include "chrome/browser/extensions/extension_browsertest.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/tracing.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/ukm/test_ukm_recorder.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/test/test_utils.h"
#include "extensions/buildflags/buildflags.h"
#include "net/dns/mock_host_resolver.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/metrics/public/cpp/ukm_source.h"
#include "services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation.h"
#include "url/gurl.h"
#include "url/url_constants.h"

#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "extensions/browser/process_manager.h"
#include "extensions/common/extension.h"
#include "extensions/test/background_page_watcher.h"
#include "extensions/test/test_extension_dir.h"
#endif

namespace {

using base::trace_event::MemoryDumpType;
using memory_instrumentation::GlobalMemoryDump;
using memory_instrumentation::mojom::ProcessType;

#if BUILDFLAG(ENABLE_EXTENSIONS)
using extensions::BackgroundPageWatcher;
using extensions::Extension;
using extensions::ProcessManager;
using extensions::TestExtensionDir;
#endif

using UkmEntry = ukm::builders::Memory_Experimental;

void RequestGlobalDumpCallback(base::Closure quit_closure,
                               bool success,
                               uint64_t) {
  base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, quit_closure);
  ASSERT_TRUE(success);
}

void OnStartTracingDoneCallback(
    base::trace_event::MemoryDumpLevelOfDetail explicit_dump_type,
    base::Closure quit_closure) {
  memory_instrumentation::MemoryInstrumentation::GetInstance()
      ->RequestGlobalDumpAndAppendToTrace(
          MemoryDumpType::EXPLICITLY_TRIGGERED, explicit_dump_type,
          Bind(&RequestGlobalDumpCallback, quit_closure));
}

class ProcessMemoryMetricsEmitterFake : public ProcessMemoryMetricsEmitter {
 public:
  explicit ProcessMemoryMetricsEmitterFake(base::RunLoop* run_loop,
                                           ukm::TestUkmRecorder* recorder)
      : run_loop_(run_loop), recorder_(recorder) {}

 private:
  ~ProcessMemoryMetricsEmitterFake() override {}

  void ReceivedMemoryDump(bool success,
                          std::unique_ptr<GlobalMemoryDump> ptr) override {
    EXPECT_TRUE(success);
    ProcessMemoryMetricsEmitter::ReceivedMemoryDump(success, std::move(ptr));
    finished_memory_dump_ = true;
    QuitIfFinished();
  }

  void ReceivedProcessInfos(
      std::vector<resource_coordinator::mojom::ProcessInfoPtr> process_infos)
      override {
    ProcessMemoryMetricsEmitter::ReceivedProcessInfos(std::move(process_infos));
    finished_process_info_ = true;
    QuitIfFinished();
  }

  void QuitIfFinished() {
    if (!finished_memory_dump_ || !finished_process_info_)
      return;
    if (run_loop_)
      run_loop_->Quit();
  }

  ukm::UkmRecorder* GetUkmRecorder() override { return recorder_; }

  base::RunLoop* run_loop_;
  bool finished_memory_dump_ = false;
  bool finished_process_info_ = false;
  ukm::TestUkmRecorder* recorder_;

  DISALLOW_COPY_AND_ASSIGN(ProcessMemoryMetricsEmitterFake);
};

void CheckMemoryMetric(const std::string& name,
                       const base::HistogramTester& histogram_tester,
                       int count,
                       bool check_minimum,
                       int number_of_processes = 1u) {
  std::unique_ptr<base::HistogramSamples> samples(
      histogram_tester.GetHistogramSamplesSinceCreation(name));
  ASSERT_TRUE(samples);

  bool count_matches = samples->TotalCount() == count * number_of_processes;
  // The exact number of renderers present at the time the metrics are emitted
  // is not deterministic. Sometimes there is an extra renderer.
  if (name.find("Renderer") != std::string::npos) {
    count_matches = samples->TotalCount() >= (count * number_of_processes) &&
                    samples->TotalCount() <= (number_of_processes + 1) * count;
  }

  EXPECT_TRUE(count_matches);

  if (check_minimum)
    EXPECT_GT(samples->sum(), 0u) << name;

  // As a sanity check, no memory stat should exceed 4 GB.
  int64_t maximum_expected_size = 1ll << 32;
  EXPECT_LT(samples->sum(), maximum_expected_size) << name;
}

void CheckAllMemoryMetrics(const base::HistogramTester& histogram_tester,
                           int count,
                           int number_of_renderer_processes = 1u,
                           int number_of_extenstion_processes = 0u) {
#if !defined(OS_WIN)
  CheckMemoryMetric("Memory.Experimental.Browser2.Malloc", histogram_tester,
                    count, true);
#endif
#if !defined(OS_MACOSX)
  CheckMemoryMetric("Memory.Experimental.Browser2.Resident", histogram_tester,
                    count, true);
#endif
  CheckMemoryMetric("Memory.Experimental.Browser2.PrivateMemoryFootprint",
                    histogram_tester, count, true);
  if (number_of_renderer_processes) {
#if !defined(OS_WIN)
    CheckMemoryMetric("Memory.Experimental.Renderer2.Malloc", histogram_tester,
                      count, true, number_of_renderer_processes);
#endif
#if !defined(OS_MACOSX)
    CheckMemoryMetric("Memory.Experimental.Renderer2.Resident",
                      histogram_tester, count, true,
                      number_of_renderer_processes);
#endif
    CheckMemoryMetric("Memory.Experimental.Renderer2.BlinkGC", histogram_tester,
                      count, false, number_of_renderer_processes);
    CheckMemoryMetric("Memory.Experimental.Renderer2.PartitionAlloc",
                      histogram_tester, count, false,
                      number_of_renderer_processes);
    CheckMemoryMetric("Memory.Experimental.Renderer2.V8", histogram_tester,
                      count, true, number_of_renderer_processes);
    CheckMemoryMetric("Memory.Experimental.Renderer2.PrivateMemoryFootprint",
                      histogram_tester, count, true,
                      number_of_renderer_processes);
  }
  if (number_of_extenstion_processes) {
#if !defined(OS_WIN)
    CheckMemoryMetric("Memory.Experimental.Extension2.Malloc", histogram_tester,
                      count, true, number_of_extenstion_processes);
#endif
#if !defined(OS_MACOSX)
    CheckMemoryMetric("Memory.Experimental.Extension2.Resident",
                      histogram_tester, count, true,
                      number_of_extenstion_processes);
#endif
    CheckMemoryMetric("Memory.Experimental.Extension2.BlinkGC",
                      histogram_tester, count, false,
                      number_of_extenstion_processes);
    CheckMemoryMetric("Memory.Experimental.Extension2.PartitionAlloc",
                      histogram_tester, count, false,
                      number_of_extenstion_processes);
    CheckMemoryMetric("Memory.Experimental.Extension2.V8", histogram_tester,
                      count, true, number_of_extenstion_processes);
    CheckMemoryMetric("Memory.Experimental.Extension2.PrivateMemoryFootprint",
                      histogram_tester, count, true,
                      number_of_extenstion_processes);
  }
  CheckMemoryMetric("Memory.Experimental.Total2.PrivateMemoryFootprint",
                    histogram_tester, count, true);
}

}  // namespace

class ProcessMemoryMetricsEmitterTest
    : public extensions::ExtensionBrowserTest {
 public:
  ProcessMemoryMetricsEmitterTest() {
    scoped_feature_list_.InitAndEnableFeature(ukm::kUkmFeature);
  }

  ~ProcessMemoryMetricsEmitterTest() override {}

  void SetUpOnMainThread() override {
    extensions::ExtensionBrowserTest::SetUpOnMainThread();
    host_resolver()->AddRule("*", "127.0.0.1");
  }

  void PreRunTestOnMainThread() override {
    InProcessBrowserTest::PreRunTestOnMainThread();

    test_ukm_recorder_ = std::make_unique<ukm::TestAutoSetUkmRecorder>();
  }

 protected:
  std::unique_ptr<ukm::TestAutoSetUkmRecorder> test_ukm_recorder_;

  void CheckMetricWithName(const ukm::mojom::UkmEntry* entry,
                           const char* name,
                           std::function<bool(int64_t)> check) {
    const int64_t* value = test_ukm_recorder_->GetEntryMetric(entry, name);
    EXPECT_TRUE(value && check(*value)) << name;
  }

  void CheckExactMetricWithName(const ukm::mojom::UkmEntry* entry,
                                const char* name,
                                int64_t expected_value) {
    CheckMetricWithName(entry, name, [expected_value](int64_t value) -> bool {
      return value == expected_value;
    });
  }

  void CheckMemoryMetricWithName(const ukm::mojom::UkmEntry* entry,
                                 const char* name,
                                 bool can_be_zero) {
    CheckMetricWithName(entry, name, [can_be_zero](int64_t value) -> bool {
      return value >= (can_be_zero ? 0 : 1) && value <= 4000;
    });
  }

  void CheckTimeMetricWithName(const ukm::mojom::UkmEntry* entry,
                               const char* name) {
    CheckMetricWithName(entry, name, [](int64_t value) -> bool {
      return value >= 0 && value <= 10;
    });
  }

  void CheckAllUkmEntries(size_t entry_count = 1u) {
    const auto& entries =
        test_ukm_recorder_->GetEntriesByName(UkmEntry::kEntryName);
    size_t browser_entry_count = 0;
    size_t renderer_entry_count = 0;
    size_t total_entry_count = 0;

    for (const auto* entry : entries) {
      if (ProcessHasTypeForEntry(entry, ProcessType::BROWSER)) {
        browser_entry_count++;
        CheckUkmBrowserEntry(entry);
      } else if (ProcessHasTypeForEntry(entry, ProcessType::RENDERER)) {
        renderer_entry_count++;
        CheckUkmRendererEntry(entry);
      } else if (ProcessHasTypeForEntry(entry, ProcessType::GPU)) {
        CheckUkmGPUEntry(entry);
      } else {
        // This must be Total2.
        total_entry_count++;
        CheckMemoryMetricWithName(
            entry, UkmEntry::kTotal2_PrivateMemoryFootprintName, false);
      }
    }
    EXPECT_EQ(entry_count, browser_entry_count);
    EXPECT_EQ(entry_count, total_entry_count);

    EXPECT_GE(renderer_entry_count, entry_count);
  }

  void CheckUkmRendererEntry(const ukm::mojom::UkmEntry* entry) {
#if !defined(OS_WIN)
    CheckMemoryMetricWithName(entry, UkmEntry::kMallocName, false);
#endif
#if !defined(OS_MACOSX)
    CheckMemoryMetricWithName(entry, UkmEntry::kResidentName, false);
#endif
    CheckMemoryMetricWithName(entry, UkmEntry::kPrivateMemoryFootprintName,
                              false);
    CheckMemoryMetricWithName(entry, UkmEntry::kBlinkGCName, true);
    CheckMemoryMetricWithName(entry, UkmEntry::kPartitionAllocName, true);
    CheckMemoryMetricWithName(entry, UkmEntry::kV8Name, true);
    CheckMemoryMetricWithName(entry, UkmEntry::kNumberOfExtensionsName, true);
    CheckTimeMetricWithName(entry, UkmEntry::kUptimeName);

    CheckMemoryMetricWithName(entry, UkmEntry::kNumberOfDocumentsName, true);
    CheckMemoryMetricWithName(entry, UkmEntry::kNumberOfFramesName, true);
    CheckMemoryMetricWithName(entry, UkmEntry::kNumberOfLayoutObjectsName,
                              true);
    CheckMemoryMetricWithName(entry, UkmEntry::kNumberOfNodesName, true);
  }

  void CheckUkmBrowserEntry(const ukm::mojom::UkmEntry* entry) {
#if !defined(OS_WIN)
    CheckMemoryMetricWithName(entry, UkmEntry::kMallocName, false);
#endif
#if !defined(OS_MACOSX)
    CheckMemoryMetricWithName(entry, UkmEntry::kResidentName, false);
#endif
    CheckMemoryMetricWithName(entry, UkmEntry::kPrivateMemoryFootprintName,
                              false);

    CheckTimeMetricWithName(entry, UkmEntry::kUptimeName);
  }

  void CheckUkmGPUEntry(const ukm::mojom::UkmEntry* entry) {
    CheckTimeMetricWithName(entry, UkmEntry::kUptimeName);
  }

  bool ProcessHasTypeForEntry(const ukm::mojom::UkmEntry* entry,
                              ProcessType process_type) {
    const int64_t* value =
        test_ukm_recorder_->GetEntryMetric(entry, UkmEntry::kProcessTypeName);
    return value && *value == static_cast<int64_t>(process_type);
  }

  void CheckPageInfoUkmMetrics(GURL url,
                               bool is_visible,
                               size_t entry_count = 1u) {
    const auto& entries =
        test_ukm_recorder_->GetEntriesByName(UkmEntry::kEntryName);
    size_t found_count = false;
    const ukm::mojom::UkmEntry* last_entry = nullptr;
    for (const auto* entry : entries) {
      const ukm::UkmSource* source =
          test_ukm_recorder_->GetSourceForSourceId(entry->source_id);
      if (!source || source->url() != url)
        continue;
      if (!test_ukm_recorder_->EntryHasMetric(entry, UkmEntry::kIsVisibleName))
        continue;
      found_count++;
      last_entry = entry;
      EXPECT_TRUE(ProcessHasTypeForEntry(entry, ProcessType::RENDERER));
      CheckTimeMetricWithName(entry, UkmEntry::kTimeSinceLastNavigationName);
      CheckTimeMetricWithName(entry,
                              UkmEntry::kTimeSinceLastVisibilityChangeName);
    }
    CheckExactMetricWithName(last_entry, UkmEntry::kIsVisibleName, is_visible);
    EXPECT_EQ(entry_count, found_count);
  }

#if BUILDFLAG(ENABLE_EXTENSIONS)
  // Create an barebones extension with a background page for the given name.
  const Extension* CreateExtension(const std::string& name) {
    auto dir = std::make_unique<TestExtensionDir>();
    dir->WriteManifestWithSingleQuotes(
        base::StringPrintf("{"
                           "'name': '%s',"
                           "'version': '1',"
                           "'manifest_version': 2,"
                           "'background': {'page': 'bg.html'}"
                           "}",
                           name.c_str()));
    dir->WriteFile(FILE_PATH_LITERAL("bg.html"), "");

    const Extension* extension = LoadExtension(dir->UnpackedPath());
    EXPECT_TRUE(extension);
    temp_dirs_.push_back(std::move(dir));
    return extension;
  }

  const Extension* CreateHostedApp(const std::string& name,
                                   const GURL& app_url) {
    std::unique_ptr<TestExtensionDir> dir(new TestExtensionDir);
    dir->WriteManifestWithSingleQuotes(base::StringPrintf(
        "{"
        "'name': '%s',"
        "'version': '1',"
        "'manifest_version': 2,"
        "'app': {'urls': ['%s'], 'launch': {'web_url': '%s'}}"
        "}",
        name.c_str(), app_url.spec().c_str(), app_url.spec().c_str()));

    const Extension* extension = LoadExtension(dir->UnpackedPath());
    EXPECT_TRUE(extension);
    temp_dirs_.push_back(std::move(dir));
    return extension;
  }

#endif

 private:
  base::test::ScopedFeatureList scoped_feature_list_;
#if BUILDFLAG(ENABLE_EXTENSIONS)
  std::vector<std::unique_ptr<TestExtensionDir>> temp_dirs_;
#endif

  DISALLOW_COPY_AND_ASSIGN(ProcessMemoryMetricsEmitterTest);
};

#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER)
#define MAYBE_FetchAndEmitMetrics DISABLED_FetchAndEmitMetrics
#else
// TODO(michaelpg): Remove this unconditional disabling once new UKM testing
// style CLs land: crbug.com/761524.
#define MAYBE_FetchAndEmitMetrics DISABLED_FetchAndEmitMetrics
#endif
IN_PROC_BROWSER_TEST_F(ProcessMemoryMetricsEmitterTest,
                       MAYBE_FetchAndEmitMetrics) {
  ASSERT_TRUE(embedded_test_server()->Start());
  const GURL url = embedded_test_server()->GetURL("foo.com", "/empty.html");
  ui_test_utils::NavigateToURLWithDisposition(
      browser(), url, WindowOpenDisposition::NEW_FOREGROUND_TAB,
      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);

  base::HistogramTester histogram_tester;
  base::RunLoop run_loop;

  // Intentionally let emitter leave scope to check that it correctly keeps
  // itself alive.
  {
    scoped_refptr<ProcessMemoryMetricsEmitterFake> emitter(
        new ProcessMemoryMetricsEmitterFake(&run_loop,
                                            test_ukm_recorder_.get()));
    emitter->FetchAndEmitProcessMemoryMetrics();
  }

  run_loop.Run();

  CheckAllMemoryMetrics(histogram_tester, 1);
  CheckAllUkmEntries();
  CheckPageInfoUkmMetrics(url, true);
}

#if BUILDFLAG(ENABLE_EXTENSIONS)
#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER)
#define MAYBE_FetchAndEmitMetricsWithExtensions \
  DISABLED_FetchAndEmitMetricsWithExtensions
#else
// TODO(michaelpg): Remove this unconditional disabling once new UKM testing
// style CLs land: crbug.com/761524.
#define MAYBE_FetchAndEmitMetricsWithExtensions \
  DISABLED_FetchAndEmitMetricsWithExtensions
#endif
IN_PROC_BROWSER_TEST_F(ProcessMemoryMetricsEmitterTest,
                       MAYBE_FetchAndEmitMetricsWithExtensions) {
  const Extension* extension1 = CreateExtension("Extension 1");
  const Extension* extension2 = CreateExtension("Extension 2");
  ProcessManager* pm = ProcessManager::Get(profile());

  // Verify that the extensions has loaded.
  BackgroundPageWatcher(pm, extension1).WaitForOpen();
  BackgroundPageWatcher(pm, extension2).WaitForOpen();
  EXPECT_EQ(1u, pm->GetRenderFrameHostsForExtension(extension1->id()).size());
  EXPECT_EQ(1u, pm->GetRenderFrameHostsForExtension(extension2->id()).size());

  ASSERT_TRUE(embedded_test_server()->Start());
  const GURL url = embedded_test_server()->GetURL("foo.com", "/empty.html");
  ui_test_utils::NavigateToURLWithDisposition(
      browser(), url, WindowOpenDisposition::NEW_FOREGROUND_TAB,
      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);

  base::HistogramTester histogram_tester;
  base::RunLoop run_loop;

  // Intentionally let emitter leave scope to check that it correctly keeps
  // itself alive.
  {
    scoped_refptr<ProcessMemoryMetricsEmitterFake> emitter(
        new ProcessMemoryMetricsEmitterFake(&run_loop,
                                            test_ukm_recorder_.get()));
    emitter->FetchAndEmitProcessMemoryMetrics();
  }

  run_loop.Run();

  CheckAllMemoryMetrics(histogram_tester, 1, 1, 2);
  // Extension processes do not have page_info.
  CheckAllUkmEntries();
  CheckPageInfoUkmMetrics(url, true);
}

#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER)
#define MAYBE_FetchAndEmitMetricsWithHostedApps \
  DISABLED_FetchAndEmitMetricsWithHostedApps
#else
// TODO(michaelpg): Remove this unconditional disabling once new UKM testing
// style CLs land: crbug.com/761524.
#define MAYBE_FetchAndEmitMetricsWithHostedApps \
  DISABLED_FetchAndEmitMetricsWithHostedApps
#endif
IN_PROC_BROWSER_TEST_F(ProcessMemoryMetricsEmitterTest,
                       MAYBE_FetchAndEmitMetricsWithHostedApps) {
  ASSERT_TRUE(embedded_test_server()->Start());
  const GURL app_url = embedded_test_server()->GetURL("app.org", "/empty.html");
  const Extension* app = CreateHostedApp("App", GURL("http://app.org"));
  ui_test_utils::NavigateToURL(browser(), app_url);

  // Verify that the hosted app has loaded.
  ProcessManager* pm = ProcessManager::Get(profile());
  EXPECT_EQ(1u, pm->GetRenderFrameHostsForExtension(app->id()).size());

  const GURL url = embedded_test_server()->GetURL("foo.com", "/empty.html");
  ui_test_utils::NavigateToURLWithDisposition(
      browser(), url, WindowOpenDisposition::NEW_FOREGROUND_TAB,
      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);

  base::HistogramTester histogram_tester;
  base::RunLoop run_loop;

  // Intentionally let emitter leave scope to check that it correctly keeps
  // itself alive.
  {
    scoped_refptr<ProcessMemoryMetricsEmitterFake> emitter(
        new ProcessMemoryMetricsEmitterFake(&run_loop,
                                            test_ukm_recorder_.get()));
    emitter->FetchAndEmitProcessMemoryMetrics();
  }

  run_loop.Run();

  // No extensions should be observed
  CheckAllMemoryMetrics(histogram_tester, 1, 1, 0);
  CheckAllUkmEntries();
  CheckPageInfoUkmMetrics(url, true);
}

// Breaks when attempting to add tests for new UKMs: crbug.com/761524
// Re-enable with crrev.com/c/774120.
#define MAYBE_FetchAndEmitMetricsWithExtensionsAndHostReuse \
  DISABLED_FetchAndEmitMetricsWithExtensionsAndHostReuse
IN_PROC_BROWSER_TEST_F(ProcessMemoryMetricsEmitterTest,
                       MAYBE_FetchAndEmitMetricsWithExtensionsAndHostReuse) {
  // This test does not work with --site-per-process flag since this test
  // combines multiple extensions in the same process.
  if (content::AreAllSitesIsolatedForTesting())
    return;
  // Limit the number of renderer processes to force reuse.
  content::RenderProcessHost::SetMaxRendererProcessCount(1);
  const Extension* extension1 = CreateExtension("Extension 1");
  const Extension* extension2 = CreateExtension("Extension 2");
  ProcessManager* pm = ProcessManager::Get(profile());

  // Verify that the extensions has loaded.
  BackgroundPageWatcher(pm, extension1).WaitForOpen();
  BackgroundPageWatcher(pm, extension2).WaitForOpen();
  EXPECT_EQ(1u, pm->GetRenderFrameHostsForExtension(extension1->id()).size());
  EXPECT_EQ(1u, pm->GetRenderFrameHostsForExtension(extension2->id()).size());

  ASSERT_TRUE(embedded_test_server()->Start());
  const GURL url = embedded_test_server()->GetURL("foo.com", "/empty.html");
  ui_test_utils::NavigateToURLWithDisposition(
      browser(), url, WindowOpenDisposition::NEW_FOREGROUND_TAB,
      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);

  base::HistogramTester histogram_tester;
  base::RunLoop run_loop;

  // Intentionally let emitter leave scope to check that it correctly keeps
  // itself alive.
  {
    scoped_refptr<ProcessMemoryMetricsEmitterFake> emitter(
        new ProcessMemoryMetricsEmitterFake(&run_loop,
                                            test_ukm_recorder_.get()));
    emitter->FetchAndEmitProcessMemoryMetrics();
  }

  run_loop.Run();

  CheckAllMemoryMetrics(histogram_tester, 1, 1, 1);
  CheckAllUkmEntries();
  // When hosts share a process, no unique URL is identified, therefore no page
  // info.
  const auto& entries =
      test_ukm_recorder_->GetEntriesByName(UkmEntry::kEntryName);
  for (const auto* entry : entries) {
    EXPECT_EQ(nullptr,
              test_ukm_recorder_->GetSourceForSourceId(entry->source_id));
  }
}
#endif  // BUILDFLAG(ENABLE_EXTENSIONS)

#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER)
#define MAYBE_FetchDuringTrace DISABLED_FetchDuringTrace
#else
// TODO(michaelpg): Remove this unconditional disabling once new UKM testing
// style CLs land: crbug.com/761524.
#define MAYBE_FetchDuringTrace DISABLED_FetchDuringTrace
#endif
IN_PROC_BROWSER_TEST_F(ProcessMemoryMetricsEmitterTest,
                       MAYBE_FetchDuringTrace) {
  ASSERT_TRUE(embedded_test_server()->Start());
  const GURL url = embedded_test_server()->GetURL("foo.com", "/empty.html");
  ui_test_utils::NavigateToURLWithDisposition(
      browser(), url, WindowOpenDisposition::NEW_FOREGROUND_TAB,
      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);

  base::HistogramTester histogram_tester;

  {
    base::RunLoop run_loop;

    base::trace_event::TraceConfig trace_config(
        base::trace_event::TraceConfigMemoryTestUtil::
            GetTraceConfig_EmptyTriggers());
    ASSERT_TRUE(tracing::BeginTracingWithTraceConfig(
        trace_config, Bind(&OnStartTracingDoneCallback,
                           base::trace_event::MemoryDumpLevelOfDetail::DETAILED,
                           run_loop.QuitClosure())));
    run_loop.Run();
  }

  {
    base::RunLoop run_loop;
    scoped_refptr<ProcessMemoryMetricsEmitterFake> emitter(
        new ProcessMemoryMetricsEmitterFake(&run_loop,
                                            test_ukm_recorder_.get()));
    emitter->FetchAndEmitProcessMemoryMetrics();

    run_loop.Run();
  }

  std::string json_events;
  ASSERT_TRUE(tracing::EndTracing(&json_events));

  trace_analyzer::TraceEventVector events;
  std::unique_ptr<trace_analyzer::TraceAnalyzer> analyzer(
      trace_analyzer::TraceAnalyzer::Create(json_events));
  analyzer->FindEvents(
      trace_analyzer::Query::EventPhaseIs(TRACE_EVENT_PHASE_MEMORY_DUMP),
      &events);

  ASSERT_GT(events.size(), 1u);
  ASSERT_TRUE(trace_analyzer::CountMatches(
      events, trace_analyzer::Query::EventNameIs(MemoryDumpTypeToString(
                  MemoryDumpType::EXPLICITLY_TRIGGERED))));

  CheckAllMemoryMetrics(histogram_tester, 1);
  CheckAllUkmEntries();
  CheckPageInfoUkmMetrics(url, true);
}

#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER)
#define MAYBE_FetchThreeTimes DISABLED_FetchThreeTimes
#else
// TODO(michaelpg): Remove this unconditional disabling once new UKM testing
// style CLs land: crbug.com/761524.
#define MAYBE_FetchThreeTimes DISABLED_FetchThreeTimes
#endif
IN_PROC_BROWSER_TEST_F(ProcessMemoryMetricsEmitterTest, MAYBE_FetchThreeTimes) {
  ASSERT_TRUE(embedded_test_server()->Start());
  const GURL url = embedded_test_server()->GetURL("foo.com", "/empty.html");
  ui_test_utils::NavigateToURLWithDisposition(
      browser(), url, WindowOpenDisposition::NEW_FOREGROUND_TAB,
      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);

  base::HistogramTester histogram_tester;
  base::RunLoop run_loop;

  int count = 3;
  for (int i = 0; i < count; ++i) {
    // Only the last emitter should stop the run loop.
    auto emitter = base::MakeRefCounted<ProcessMemoryMetricsEmitterFake>(
        (i == count - 1) ? &run_loop : nullptr, test_ukm_recorder_.get());
    emitter->FetchAndEmitProcessMemoryMetrics();
  }

  run_loop.Run();

  CheckAllMemoryMetrics(histogram_tester, count);
  CheckAllUkmEntries(count);
  CheckPageInfoUkmMetrics(url, true, count);
}

#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER)
#define MAYBE_ForegroundAndBackgroundPages DISABLED_ForegroundAndBackgroundPages
#else
// TODO(michaelpg): Remove this unconditional disabling once new UKM testing
// style CLs land: crbug.com/761524.
#define MAYBE_ForegroundAndBackgroundPages DISABLED_ForegroundAndBackgroundPages
#endif
IN_PROC_BROWSER_TEST_F(ProcessMemoryMetricsEmitterTest,
                       MAYBE_ForegroundAndBackgroundPages) {
  ui_test_utils::WindowedTabAddedNotificationObserver tab_observer(
      content::NotificationService::AllSources());
  ASSERT_TRUE(embedded_test_server()->Start());
  const GURL url1 = embedded_test_server()->GetURL("a.com", "/empty.html");
  const GURL url2 = embedded_test_server()->GetURL("b.com", "/empty.html");
  ui_test_utils::NavigateToURLWithDisposition(
      browser(), url1, WindowOpenDisposition::NEW_FOREGROUND_TAB,
      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
  tab_observer.Wait();
  content::WebContents* tab1 = tab_observer.GetTab();

  ui_test_utils::NavigateToURLWithDisposition(
      browser(), url2, WindowOpenDisposition::NEW_BACKGROUND_TAB,
      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
  tab_observer.Wait();
  content::WebContents* tab2 = tab_observer.GetTab();

  base::HistogramTester histogram_tester;
  {
    base::RunLoop run_loop;
    scoped_refptr<ProcessMemoryMetricsEmitterFake> emitter(
        new ProcessMemoryMetricsEmitterFake(&run_loop,
                                            test_ukm_recorder_.get()));
    emitter->FetchAndEmitProcessMemoryMetrics();
    run_loop.Run();
  }

  CheckAllMemoryMetrics(histogram_tester, 1, 2);
  CheckAllUkmEntries();
  CheckPageInfoUkmMetrics(url1, true /* is_visible */);
  CheckPageInfoUkmMetrics(url2, false /* is_visible */);

  tab1->WasHidden();
  tab2->WasShown();
  {
    base::RunLoop run_loop;
    scoped_refptr<ProcessMemoryMetricsEmitterFake> emitter(
        new ProcessMemoryMetricsEmitterFake(&run_loop,
                                            test_ukm_recorder_.get()));
    emitter->FetchAndEmitProcessMemoryMetrics();
    run_loop.Run();
  }
  CheckAllMemoryMetrics(histogram_tester, 2, 2);
  CheckAllUkmEntries(2);
  CheckPageInfoUkmMetrics(url1, false /* is_visible */, 2);
  CheckPageInfoUkmMetrics(url2, true /* is_visible */, 2);
}
