chromium/chrome/browser/metrics/metrics_reporting_state_browsertest.cc

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

#include "chrome/browser/metrics/metrics_reporting_state.h"

#include <memory>
#include <optional>
#include <string>
#include <string_view>

#include "base/files/file_path.h"
#include "base/functional/bind.h"
#include "base/json/json_file_value_serializer.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/statistics_recorder.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/threading/thread_restrictions.h"
#include "base/values.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_browser_main.h"
#include "chrome/browser/chrome_browser_main_extra_parts.h"
#include "chrome/browser/metrics/chrome_metrics_service_accessor.h"
#include "chrome/browser/metrics/testing/metrics_reporting_pref_helper.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "components/metrics/metrics_pref_names.h"
#include "components/metrics/metrics_service_accessor.h"
#include "components/policy/core/common/cloud/test/policy_builder.h"
#include "components/prefs/pref_service.h"
#include "content/public/test/browser_test.h"
#include "testing/gmock/include/gmock/gmock-matchers.h"
#include "testing/gmock/include/gmock/gmock.h"

#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "chrome/browser/ash/settings/device_settings_cache.h"
#include "chromeos/ash/components/install_attributes/stub_install_attributes.h"
#include "components/policy/proto/chrome_device_policy.pb.h"
#include "components/policy/proto/device_management_backend.pb.h"
#endif

#if BUILDFLAG(IS_WIN)
#include "base/test/test_reg_util_win.h"
#endif  // BUILDFLAG(IS_WIN)

struct MetricsReportingStateTestParameterizedParams {};

// ChromeBrowserMainExtraParts implementation that asserts the metrics and
// reporting state matches a particular value in PreCreateThreads().
class ChromeBrowserMainExtraPartsChecker : public ChromeBrowserMainExtraParts {};

// Used to appropriately set up the initial value of
// IsMetricsAndCrashReportingEnabled().
class MetricsReportingStateTest : public InProcessBrowserTest {};

// Used to verify the value for IsMetricsAndCrashReportingEnabled() is correctly
// written to disk when changed. The first parameter of this test corresponds
// to the initial value of IsMetricsAndCrashReportingEnabled(). The second
// parameter corresponds to what the value should change to during the test.
class MetricsReportingStateTestParameterized
    : public MetricsReportingStateTest,
      public testing::WithParamInterface<
          MetricsReportingStateTestParameterizedParams> {};

// Used to verify that metrics collected during a session are discarded upon
// enabling metrics reporting, so that only data collected after enabling
// metrics are collected. Histogram data should only be cleared if metrics
// reporting was enabled from a settings page.
class MetricsReportingStateClearDataTest
    : public MetricsReportingStateTest,
      public testing::WithParamInterface<
          ChangeMetricsReportingStateCalledFrom> {};

void ChromeBrowserMainExtraPartsChecker::PostEarlyInitialization() {}

// Callback from changing whether reporting is enabled.
void OnMetricsReportingStateChanged(bool* new_state_ptr,
                                    base::OnceClosure run_loop_closure,
                                    bool new_state) {}

bool HistogramExists(std::string_view name) {}

base::HistogramBase::Count GetHistogramDeltaTotalCount(std::string_view name) {}

// Verifies that metrics reporting state is correctly written to disk when set.
IN_PROC_BROWSER_TEST_P(MetricsReportingStateTestParameterized,
                       ChangeMetricsReportingState) {}

// Verifies that collected data is cleared after enabling metrics reporting.
// Histogram data should only be cleared (marked as reported) when enabling
// metrics reporting from a settings page.
IN_PROC_BROWSER_TEST_P(MetricsReportingStateClearDataTest,
                       ClearPreviouslyCollectedMetricsData) {}

INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

#if BUILDFLAG(IS_CHROMEOS_ASH)
// Used to verify that managed/unmanged devices returns correct values based on
// management state.
class MetricsReportingStateManagedTest
    : public MetricsReportingStateTest,
      public testing::WithParamInterface<bool> {
 public:
  MetricsReportingStateManagedTest() = default;
  MetricsReportingStateManagedTest(const MetricsReportingStateManagedTest&) =
      delete;
  MetricsReportingStateManagedTest& operator=(
      const MetricsReportingStateManagedTest&) = delete;
  ~MetricsReportingStateManagedTest() = default;

  void SetUp() override {
    is_managed_ = GetParam();
    if (is_managed()) {
      install_attributes_ = std::make_unique<ash::ScopedStubInstallAttributes>(
          ash::StubInstallAttributes::CreateCloudManaged("domain",
                                                         "device_id"));
    } else {
      install_attributes_ = std::make_unique<ash::ScopedStubInstallAttributes>(
          ash::StubInstallAttributes::CreateConsumerOwned());
    }

    MetricsReportingStateTest::SetUp();
  }

  // Set metrics reporting initial value to false.
  bool IsMetricsReportingEnabledInitialValue() const override { return false; }

 protected:
  bool is_managed() const { return is_managed_; }

 private:
  bool is_managed_;
  std::unique_ptr<ash::ScopedStubInstallAttributes> install_attributes_;
};

IN_PROC_BROWSER_TEST_P(MetricsReportingStateManagedTest,
                       IsMetricsReportingPolicyManagedReturnsCorrectValue) {
  EXPECT_EQ(IsMetricsReportingPolicyManaged(), is_managed());
}

IN_PROC_BROWSER_TEST_P(MetricsReportingStateManagedTest,
                       MetricsReportingStateUpdatesOnCrosMetricsChange) {
  // Simulate enabling metrics reporting through OnCrosMetricsChange().
  base::RunLoop run_loop;
  bool value_after_change = false;
  ChangeMetricsReportingStateWithReply(
      true,
      base::BindOnce(&OnMetricsReportingStateChanged, &value_after_change,
                     run_loop.QuitClosure()),
      ChangeMetricsReportingStateCalledFrom::kCrosMetricsSettingsChange);
  run_loop.Run();

  // Value should have changed regardless whether the device is managed or not.
  ASSERT_TRUE(value_after_change);
}

INSTANTIATE_TEST_SUITE_P(MetricsReportingStateTests,
                         MetricsReportingStateManagedTest,
                         testing::Bool());

#endif