#include <memory>
#include <string>
#include "base/files/file_path.h"
#include "base/functional/bind.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/strings/string_util.h"
#include "base/system/sys_info.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "build/buildflag.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/browsing_data/chrome_browsing_data_remover_constants.h"
#include "chrome/browser/metrics/chrome_metrics_service_accessor.h"
#include "chrome/browser/metrics/chrome_metrics_service_client.h"
#include "chrome/browser/metrics/chrome_metrics_services_manager_client.h"
#include "chrome/browser/metrics/testing/metrics_reporting_pref_helper.h"
#include "chrome/browser/metrics/testing/sync_metrics_test_utils.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/profiles/profile_test_util.h"
#include "chrome/browser/signin/identity_manager_factory.h"
#include "chrome/browser/sync/sync_service_factory.h"
#include "chrome/browser/sync/test/integration/secondary_account_helper.h"
#include "chrome/browser/sync/test/integration/sync_service_impl_harness.h"
#include "chrome/browser/sync/test/integration/sync_test.h"
#include "chrome/browser/unified_consent/unified_consent_service_factory.h"
#include "components/metrics/demographics/demographic_metrics_provider.h"
#include "components/metrics/demographics/demographic_metrics_test_utils.h"
#include "components/metrics/metrics_pref_names.h"
#include "components/metrics_services_manager/metrics_services_manager.h"
#include "components/signin/public/base/signin_buildflags.h"
#include "components/signin/public/identity_manager/identity_manager.h"
#include "components/sync/base/features.h"
#include "components/sync/service/sync_service.h"
#include "components/sync/service/sync_service_impl.h"
#include "components/sync/service/sync_token_status.h"
#include "components/sync/test/fake_server_network_resources.h"
#include "components/ukm/ukm_recorder_observer.h"
#include "components/ukm/ukm_service.h"
#include "components/ukm/ukm_test_helper.h"
#include "components/unified_consent/unified_consent_service.h"
#include "components/version_info/version_info.h"
#include "content/public/browser/browsing_data_remover.h"
#include "content/public/common/content_switches.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/browsing_data_remover_test_util.h"
#include "content/public/test/navigation_handle_observer.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/test_utils.h"
#include "services/metrics/public/cpp/ukm_recorder.h"
#include "services/metrics/public/cpp/ukm_source.h"
#include "services/network/test/test_network_quality_tracker.h"
#include "third_party/metrics_proto/ukm/report.pb.h"
#include "third_party/metrics_proto/user_demographics.pb.h"
#include "url/url_constants.h"
#if !BUILDFLAG(IS_ANDROID)
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/tabs/tab_enums.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#else
#include "chrome/browser/flags/android/chrome_feature_list.h"
#include "chrome/browser/flags/android/chrome_session_state.h"
#include "chrome/browser/ui/android/tab_model/tab_model.h"
#include "chrome/browser/ui/android/tab_model/tab_model_list.h"
#include "chrome/browser/ui/android/tab_model/tab_model_observer.h"
#include "chrome/test/base/android/android_browser_test.h"
#include "content/public/browser/web_contents.h"
#endif
#if !BUILDFLAG(IS_CHROMEOS_ASH) && !BUILDFLAG(IS_ANDROID)
#include "chrome/browser/ui/profiles/profile_picker.h"
#include "chrome/browser/ui/profiles/profile_ui_test_utils.h"
#endif
namespace metrics {
namespace {
class TestTabModel;
#if !BUILDFLAG(IS_ANDROID)
PlatformBrowser;
#else
typedef std::unique_ptr<TestTabModel> PlatformBrowser;
#endif
void ClearBrowsingData(Profile* profile) { … }
ukm::UkmService* GetUkmService() { … }
class TestUkmRecorderObserver : public ukm::UkmRecorderObserver { … };
#if BUILDFLAG(IS_ANDROID)
const auto TEST_ACTIVITY_TYPE = chrome::android::ActivityType::kCustomTab;
class TestTabModel : public TabModel {
public:
explicit TestTabModel(Profile* profile)
: TabModel(profile, TEST_ACTIVITY_TYPE),
web_contents_(content::WebContents::Create(
content::WebContents::CreateParams(GetProfile()))) {}
~TestTabModel() override = default;
int GetTabCount() const override { return 0; }
int GetActiveIndex() const override { return 0; }
base::android::ScopedJavaLocalRef<jobject> GetJavaObject() const override {
return nullptr;
}
content::WebContents* GetActiveWebContents() const override {
return web_contents_.get();
}
content::WebContents* GetWebContentsAt(int index) const override {
return nullptr;
}
TabAndroid* GetTabAt(int index) const override { return nullptr; }
void SetActiveIndex(int index) override {}
void CloseTabAt(int index) override {}
void CreateTab(TabAndroid* parent,
content::WebContents* web_contents,
bool select) override {}
void HandlePopupNavigation(TabAndroid* parent,
NavigateParams* params) override {}
content::WebContents* CreateNewTabForDevTools(const GURL& url) override {
return nullptr;
}
bool IsSessionRestoreInProgress() const override { return false; }
bool IsActiveModel() const override { return false; }
void AddObserver(TabModelObserver* observer) override {}
void RemoveObserver(TabModelObserver* observer) override {}
int GetTabCountNavigatedInTimeWindow(
const base::Time& begin_time,
const base::Time& end_time) const override {
return 0;
}
void CloseTabsNavigatedInTimeWindow(const base::Time& begin_time,
const base::Time& end_time) override {}
private:
std::unique_ptr<content::WebContents> web_contents_;
};
#endif
}
class MetricsConsentOverride { … };
class UkmBrowserTestBase : public SyncTest { … };
class UkmBrowserTest : public UkmBrowserTestBase { … };
class UkmBrowserTestWithSyncTransport : public UkmBrowserTestBase { … };
#if !BUILDFLAG(IS_ANDROID)
class UkmConsentParamBrowserTest : public UkmBrowserTestBase,
public testing::WithParamInterface<bool> { … };
#endif
class UkmBrowserTestWithDemographics
: public UkmBrowserTestBase,
public testing::WithParamInterface<test::DemographicsTestParams> { … };
#if BUILDFLAG(IS_ANDROID)
#define MAYBE_RegularPlusIncognitoCheck …
#else
#define MAYBE_RegularPlusIncognitoCheck …
#endif
IN_PROC_BROWSER_TEST_F(UkmBrowserTest, MAYBE_RegularPlusIncognitoCheck) { … }
IN_PROC_BROWSER_TEST_F(UkmBrowserTest, IncognitoPlusRegularCheck) { … }
#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS)
IN_PROC_BROWSER_TEST_F(UkmBrowserTest, RegularPlusGuestCheck) { … }
#endif
#if !BUILDFLAG(IS_CHROMEOS_ASH) && !BUILDFLAG(IS_ANDROID)
IN_PROC_BROWSER_TEST_F(UkmBrowserTest, ProfilePickerCheck) { … }
#endif
#if !BUILDFLAG(IS_ANDROID)
IN_PROC_BROWSER_TEST_F(UkmBrowserTest, OpenNonSyncCheck) { … }
#endif
IN_PROC_BROWSER_TEST_F(UkmBrowserTest, MetricsConsentCheck) { … }
#if !BUILDFLAG(IS_ANDROID)
IN_PROC_BROWSER_TEST_F(UkmBrowserTest, LogProtoData) { … }
#endif
IN_PROC_BROWSER_TEST_P(UkmBrowserTestWithDemographics,
AddSyncedUserBirthYearAndGenderToProtoData) { … }
#if BUILDFLAG(IS_CHROMEOS_ASH)
static const auto kDemographicsTestParams = testing::Values(
test::DemographicsTestParams{false,
false});
#else
static const auto kDemographicsTestParams = …;
#endif
INSTANTIATE_TEST_SUITE_P(…);
#if !BUILDFLAG(IS_ANDROID)
IN_PROC_BROWSER_TEST_F(UkmBrowserTest, NetworkProviderPopulatesSystemProfile) { … }
#endif
#if BUILDFLAG(IS_ANDROID)
#define MAYBE_InstallDateProviderPopulatesSystemProfile …
#else
#define MAYBE_InstallDateProviderPopulatesSystemProfile …
#endif
IN_PROC_BROWSER_TEST_F(UkmBrowserTest,
MAYBE_InstallDateProviderPopulatesSystemProfile) { … }
#if BUILDFLAG(IS_ANDROID)
#define MAYBE_ConsentAddedButNoSyncCheck …
#else
#define MAYBE_ConsentAddedButNoSyncCheck …
#endif
IN_PROC_BROWSER_TEST_F(UkmBrowserTest, MAYBE_ConsentAddedButNoSyncCheck) { … }
#if !BUILDFLAG(IS_ANDROID)
IN_PROC_BROWSER_TEST_F(UkmBrowserTest, SingleDisableExtensionsSyncCheck) { … }
#endif
#if !BUILDFLAG(IS_ANDROID)
IN_PROC_BROWSER_TEST_F(UkmBrowserTest, MultiDisableExtensionsSyncCheck) { … }
#endif
#if !BUILDFLAG(IS_ANDROID)
IN_PROC_BROWSER_TEST_F(UkmBrowserTest, LogsTabId) { … }
#endif
#if !BUILDFLAG(IS_ANDROID)
IN_PROC_BROWSER_TEST_F(UkmBrowserTest, LogsPreviousSourceId) { … }
#endif
#if !BUILDFLAG(IS_ANDROID)
IN_PROC_BROWSER_TEST_F(UkmBrowserTest, LogsOpenerSource) { … }
#endif
#if !BUILDFLAG(IS_CHROMEOS) && !BUILDFLAG(IS_ANDROID)
IN_PROC_BROWSER_TEST_F(UkmBrowserTest, SingleSyncSignoutCheck) { … }
#endif
#if !BUILDFLAG(IS_CHROMEOS) && !BUILDFLAG(IS_ANDROID)
IN_PROC_BROWSER_TEST_F(UkmBrowserTest, MultiSyncSignoutCheck) { … }
#endif
#if !BUILDFLAG(IS_ANDROID)
IN_PROC_BROWSER_TEST_F(UkmBrowserTest, ServiceListenerInitFailedCheck) { … }
#endif
#if !BUILDFLAG(IS_ANDROID)
IN_PROC_BROWSER_TEST_F(UkmBrowserTest, MetricsReportingCheck) { … }
#endif
#if BUILDFLAG(IS_ANDROID)
#define MAYBE_HistoryDeleteCheck …
#else
#define MAYBE_HistoryDeleteCheck …
#endif
IN_PROC_BROWSER_TEST_F(UkmBrowserTest, MAYBE_HistoryDeleteCheck) { … }
#if !BUILDFLAG(IS_CHROMEOS) && !BUILDFLAG(IS_ANDROID)
IN_PROC_BROWSER_TEST_F(UkmBrowserTestWithSyncTransport,
NotEnabledForSecondaryAccountSync) { … }
#endif
#if !BUILDFLAG(IS_ANDROID)
IN_PROC_BROWSER_TEST_P(UkmConsentParamBrowserTest, GroupPolicyConsentCheck) { … }
#endif
#if !BUILDFLAG(IS_ANDROID)
INSTANTIATE_TEST_SUITE_P(…);
#endif
#if !BUILDFLAG(IS_ANDROID)
IN_PROC_BROWSER_TEST_F(UkmBrowserTest, EvictObsoleteSources) { … }
#endif
#if !BUILDFLAG(IS_ANDROID)
IN_PROC_BROWSER_TEST_F(UkmBrowserTest,
MarkObsoleteSourcesSameDocumentNavigation) { … }
#endif
#if !BUILDFLAG(IS_ANDROID)
IN_PROC_BROWSER_TEST_F(UkmBrowserTest, NotMarkSourcesIfNavigationNotCommitted) { … }
#endif
#if !BUILDFLAG(IS_ANDROID)
IN_PROC_BROWSER_TEST_F(UkmBrowserTest, DebugUiRenders) { … }
#endif
#if !BUILDFLAG(IS_ANDROID)
IN_PROC_BROWSER_TEST_F(UkmBrowserTest, AllowedStateChanged) { … }
#endif
#if BUILDFLAG(IS_CHROMEOS_ASH)
class UkmBrowserTestForAppConsent : public UkmBrowserTestBase {
public:
UkmBrowserTestForAppConsent() = default;
};
IN_PROC_BROWSER_TEST_F(UkmBrowserTestForAppConsent, MetricsClientEnablement) {
ukm::UkmService* ukm_service = GetUkmService();
ukm::UkmTestHelper ukm_test_helper(ukm_service);
MetricsConsentOverride metrics_consent(true);
Profile* profile = ProfileManager::GetLastUsedProfileIfLoaded();
unified_consent::UnifiedConsentService* consent_service =
UnifiedConsentServiceFactory::GetForProfile(profile);
std::unique_ptr<SyncServiceImplHarness> harness =
EnableSyncForProfile(profile);
EXPECT_TRUE(ukm_test_helper.IsRecordingEnabled());
EXPECT_TRUE(ukm_service->recording_enabled(ukm::MSBB));
EXPECT_TRUE(ukm_service->recording_enabled(ukm::EXTENSIONS));
EXPECT_TRUE(ukm_service->recording_enabled(ukm::APPS));
consent_service->SetUrlKeyedAnonymizedDataCollectionEnabled(false);
EXPECT_TRUE(ukm_test_helper.IsRecordingEnabled());
EXPECT_FALSE(ukm_service->recording_enabled(ukm::MSBB));
EXPECT_FALSE(ukm_service->recording_enabled(ukm::EXTENSIONS));
EXPECT_TRUE(ukm_service->recording_enabled(ukm::APPS));
auto* user_settings = harness->service()->GetUserSettings();
auto registered_os_sync_types =
user_settings->GetRegisteredSelectableOsTypes();
registered_os_sync_types.Remove(syncer::UserSelectableOsType::kOsApps);
user_settings->SetSelectedOsTypes(false, registered_os_sync_types);
EXPECT_FALSE(ukm_test_helper.IsRecordingEnabled());
EXPECT_FALSE(ukm_service->recording_enabled(ukm::MSBB));
EXPECT_FALSE(ukm_service->recording_enabled(ukm::EXTENSIONS));
EXPECT_FALSE(ukm_service->recording_enabled(ukm::APPS));
}
IN_PROC_BROWSER_TEST_F(UkmBrowserTestForAppConsent,
ClientIdResetWhenConsentRemoved) {
ukm::UkmService* ukm_service = GetUkmService();
ukm::UkmTestHelper ukm_test_helper(ukm_service);
MetricsConsentOverride metrics_consent(true);
Profile* profile = ProfileManager::GetLastUsedProfileIfLoaded();
unified_consent::UnifiedConsentService* consent_service =
UnifiedConsentServiceFactory::GetForProfile(profile);
std::unique_ptr<SyncServiceImplHarness> harness =
EnableSyncForProfile(profile);
const auto original_client_id = ukm_test_helper.GetClientId();
EXPECT_NE(0ul, original_client_id);
EXPECT_TRUE(ukm_test_helper.IsRecordingEnabled());
EXPECT_TRUE(ukm_service->recording_enabled(ukm::MSBB));
EXPECT_TRUE(ukm_service->recording_enabled(ukm::EXTENSIONS));
EXPECT_TRUE(ukm_service->recording_enabled(ukm::APPS));
consent_service->SetUrlKeyedAnonymizedDataCollectionEnabled(false);
EXPECT_FALSE(ukm_service->recording_enabled(ukm::MSBB));
const auto app_sync_client_id = ukm_test_helper.GetClientId();
EXPECT_NE(original_client_id, app_sync_client_id);
auto* user_settings = harness->service()->GetUserSettings();
auto registered_os_sync_types =
user_settings->GetRegisteredSelectableOsTypes();
registered_os_sync_types.Remove(syncer::UserSelectableOsType::kOsApps);
user_settings->SetSelectedOsTypes(false, registered_os_sync_types);
EXPECT_FALSE(ukm_service->recording_enabled(ukm::APPS));
const auto final_client_id = ukm_test_helper.GetClientId();
EXPECT_NE(app_sync_client_id, final_client_id);
}
IN_PROC_BROWSER_TEST_F(UkmBrowserTestForAppConsent,
EnsurePurgeOnConsentChange) {
ukm::UkmService* ukm_service = GetUkmService();
ukm::UkmTestHelper ukm_test_helper(ukm_service);
MetricsConsentOverride metrics_consent(true);
Profile* profile = ProfileManager::GetLastUsedProfileIfLoaded();
unified_consent::UnifiedConsentService* consent_service =
UnifiedConsentServiceFactory::GetForProfile(profile);
std::unique_ptr<SyncServiceImplHarness> harness =
EnableSyncForProfile(profile);
Browser* sync_browser = CreateBrowser(profile);
ASSERT_TRUE(embedded_test_server()->Start());
const std::vector<GURL> test_urls = {
embedded_test_server()->GetURL("/title1.html"),
embedded_test_server()->GetURL("/title2.html"),
embedded_test_server()->GetURL("/title3.html")};
EXPECT_TRUE(ukm_service->recording_enabled(ukm::MSBB));
EXPECT_TRUE(ukm_service->recording_enabled(ukm::EXTENSIONS));
EXPECT_TRUE(ukm_service->recording_enabled(ukm::APPS));
int tab_index = 1;
for (const auto& url : test_urls) {
ASSERT_TRUE(AddTabAtIndexToBrowser(sync_browser, tab_index++,
GURL(url::kAboutBlankURL),
ui::PAGE_TRANSITION_TYPED, true));
NavigateAndGetSource(url, sync_browser, &ukm_test_helper);
}
consent_service->SetUrlKeyedAnonymizedDataCollectionEnabled(false);
EXPECT_FALSE(ukm_service->recording_enabled(ukm::MSBB));
EXPECT_FALSE(ukm_service->recording_enabled(ukm::EXTENSIONS));
EXPECT_TRUE(ukm_service->recording_enabled(ukm::APPS));
ukm_test_helper.BuildAndStoreLog();
const std::unique_ptr<ukm::Report> report = ukm_test_helper.GetUkmReport();
for (int i = 0; i < report->sources_size(); ++i) {
const auto id = report->sources(i).id();
EXPECT_EQ(ukm::GetSourceIdType(id), ukm::SourceIdType::APP_ID);
}
}
#endif
}