Commit dd904c24 authored by Mihai Sardarescu's avatar Mihai Sardarescu Committed by Commit Bot

[unified-consent] Use URL-keyed anonymized data collection consent for UKM.

For profiles with unified consent enabled, the sync state is completely
ignored when deciding whether UKM is enabled. The decision whether UKM
is allowed for a profile with user consent enabled is based only on the
URL-keyed anonymized data collection enabled preference.

This CL changes the UKM logic to check whether URL-keyed anonymized data
collections is enabled for profiles where unified consent is enabled.

This CL also updates the ProfileSyncServiceHarness to set/unset the
state of the UnifiedConsentGiven flag when the state of sync everything
changes.

Bug: 861777
Cq-Include-Trybots: luci.chromium.try:ios-simulator-full-configs;master.tryserver.chromium.mac:ios-simulator-cronet
Change-Id: I974a3eea2caa424efe44c1dd8b7c6f2bb24f156e
Reviewed-on: https://chromium-review.googlesource.com/1152744Reviewed-by: default avatarBrian White <bcwhite@chromium.org>
Reviewed-by: default avatarBernhard Bauer <bauerb@chromium.org>
Reviewed-by: default avatarMikel Astiz <mastiz@chromium.org>
Reviewed-by: default avatarThomas Tangl <tangltom@chromium.org>
Reviewed-by: default avatarOlivier Robin <olivierrobin@chromium.org>
Commit-Queue: Mihai Sardarescu <msarda@chromium.org>
Cr-Commit-Position: refs/heads/master@{#580210}
parent 9392ad2e
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
#include "chrome/browser/metrics/subprocess_metrics_provider.h" #include "chrome/browser/metrics/subprocess_metrics_provider.h"
#include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/safe_browsing/certificate_reporting_metrics_provider.h" #include "chrome/browser/safe_browsing/certificate_reporting_metrics_provider.h"
#include "chrome/browser/signin/unified_consent_helper.h"
#include "chrome/browser/sync/chrome_sync_client.h" #include "chrome/browser/sync/chrome_sync_client.h"
#include "chrome/browser/sync/profile_sync_service_factory.h" #include "chrome/browser/sync/profile_sync_service_factory.h"
#include "chrome/browser/translate/translate_ranker_metrics_provider.h" #include "chrome/browser/translate/translate_ranker_metrics_provider.h"
...@@ -906,12 +907,13 @@ bool ChromeMetricsServiceClient::RegisterForProfileEvents(Profile* profile) { ...@@ -906,12 +907,13 @@ bool ChromeMetricsServiceClient::RegisterForProfileEvents(Profile* profile) {
ObserveServiceForDeletions(history_service); ObserveServiceForDeletions(history_service);
browser_sync::ProfileSyncService* sync = syncer::SyncService* sync =
ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile); ProfileSyncServiceFactory::GetSyncServiceForBrowserContext(profile);
if (!sync) { if (!sync) {
return false; return false;
} }
ObserveServiceForSyncDisables(static_cast<syncer::SyncService*>(sync)); ObserveServiceForSyncDisables(sync, profile->GetPrefs(),
IsUnifiedConsentEnabled(profile));
return true; return true;
} }
......
This diff is collapsed.
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/signin/identity_manager_factory.h"
#include "chrome/browser/signin/signin_manager_factory.h" #include "chrome/browser/signin/signin_manager_factory.h"
#include "chrome/browser/signin/unified_consent_helper.h"
#include "chrome/browser/sync/profile_sync_service_factory.h" #include "chrome/browser/sync/profile_sync_service_factory.h"
#include "chrome/browser/sync/test/integration/quiesce_status_change_checker.h" #include "chrome/browser/sync/test/integration/quiesce_status_change_checker.h"
#include "chrome/browser/sync/test/integration/single_client_status_change_checker.h" #include "chrome/browser/sync/test/integration/single_client_status_change_checker.h"
...@@ -25,6 +26,7 @@ ...@@ -25,6 +26,7 @@
#include "chrome/browser/ui/webui/signin/login_ui_service.h" #include "chrome/browser/ui/webui/signin/login_ui_service.h"
#include "chrome/browser/ui/webui/signin/login_ui_service_factory.h" #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
#include "chrome/browser/ui/webui/signin/login_ui_test_utils.h" #include "chrome/browser/ui/webui/signin/login_ui_test_utils.h"
#include "chrome/browser/unified_consent/unified_consent_service_factory.h"
#include "chrome/common/channel_info.h" #include "chrome/common/channel_info.h"
#include "chrome/common/chrome_switches.h" #include "chrome/common/chrome_switches.h"
#include "components/invalidation/impl/p2p_invalidation_service.h" #include "components/invalidation/impl/p2p_invalidation_service.h"
...@@ -33,6 +35,7 @@ ...@@ -33,6 +35,7 @@
#include "components/sync/base/progress_marker_map.h" #include "components/sync/base/progress_marker_map.h"
#include "components/sync/driver/about_sync_util.h" #include "components/sync/driver/about_sync_util.h"
#include "components/sync/engine/sync_string_conversions.h" #include "components/sync/engine/sync_string_conversions.h"
#include "components/unified_consent/unified_consent_service.h"
#include "google_apis/gaia/gaia_constants.h" #include "google_apis/gaia/gaia_constants.h"
#include "services/identity/public/cpp/identity_manager.h" #include "services/identity/public/cpp/identity_manager.h"
...@@ -205,7 +208,17 @@ bool ProfileSyncServiceHarness::SetupSync(syncer::ModelTypeSet synced_datatypes, ...@@ -205,7 +208,17 @@ bool ProfileSyncServiceHarness::SetupSync(syncer::ModelTypeSet synced_datatypes,
// Choose the datatypes to be synced. If all datatypes are to be synced, // Choose the datatypes to be synced. If all datatypes are to be synced,
// set sync_everything to true; otherwise, set it to false. // set sync_everything to true; otherwise, set it to false.
bool sync_everything = (synced_datatypes == syncer::UserSelectableTypes()); bool sync_everything = (synced_datatypes == syncer::UserSelectableTypes());
service()->OnUserChoseDatatypes(sync_everything, synced_datatypes); if (IsUnifiedConsentEnabled(profile_)) {
// When unified consent given is set to |true|, the unified consent service
// enables syncing all datatypes.
UnifiedConsentServiceFactory::GetForProfile(profile_)
->SetUnifiedConsentGiven(sync_everything);
if (!sync_everything) {
service()->OnUserChoseDatatypes(sync_everything, synced_datatypes);
}
} else {
service()->OnUserChoseDatatypes(sync_everything, synced_datatypes);
}
// Notify ProfileSyncService that we are done with configuration. // Notify ProfileSyncService that we are done with configuration.
if (skip_passphrase_verification) { if (skip_passphrase_verification) {
...@@ -494,6 +507,12 @@ bool ProfileSyncServiceHarness::DisableSyncForDatatype( ...@@ -494,6 +507,12 @@ bool ProfileSyncServiceHarness::DisableSyncForDatatype(
return true; return true;
} }
// Disable unified consent first as otherwise disabling sync is not possible.
if (IsUnifiedConsentEnabled(profile_)) {
UnifiedConsentServiceFactory::GetForProfile(profile_)
->SetUnifiedConsentGiven(false);
}
synced_datatypes.RetainAll(syncer::UserSelectableTypes()); synced_datatypes.RetainAll(syncer::UserSelectableTypes());
synced_datatypes.Remove(datatype); synced_datatypes.Remove(datatype);
service()->OnUserChoseDatatypes(false, synced_datatypes); service()->OnUserChoseDatatypes(false, synced_datatypes);
......
...@@ -56,6 +56,10 @@ static_library("observers") { ...@@ -56,6 +56,10 @@ static_library("observers") {
"//components/history/core/browser", "//components/history/core/browser",
"//components/sync", "//components/sync",
] ]
public_deps = [
"//components/unified_consent",
]
} }
static_library("test_support") { static_library("test_support") {
...@@ -95,6 +99,7 @@ source_set("unit_tests") { ...@@ -95,6 +99,7 @@ source_set("unit_tests") {
"//components/prefs:test_support", "//components/prefs:test_support",
"//components/sync", "//components/sync",
"//components/sync:test_support_driver", "//components/sync:test_support_driver",
"//components/sync_preferences:test_support",
"//components/variations", "//components/variations",
"//net:test_support", "//net:test_support",
"//services/metrics/public/cpp:ukm_builders", "//services/metrics/public/cpp:ukm_builders",
......
include_rules = [ include_rules = [
"+components/metrics", "+components/metrics",
"+components/prefs", "+components/prefs",
"+components/unified_consent",
"+components/variations", "+components/variations",
"+mojo/public", "+mojo/public",
"+services/metrics/public", "+services/metrics/public",
"+third_party/metrics_proto", "+third_party/metrics_proto",
"+third_party/zlib/google", "+third_party/zlib/google",
] ]
specific_include_rules = {
".*unittest\.cc": [
"+components/sync_preferences/testing_pref_service_syncable.h",
]
}
\ No newline at end of file
...@@ -9,6 +9,9 @@ ...@@ -9,6 +9,9 @@
#include "base/stl_util.h" #include "base/stl_util.h"
#include "components/sync/driver/sync_token_status.h" #include "components/sync/driver/sync_token_status.h"
#include "components/sync/engine/connection_status.h" #include "components/sync/engine/connection_status.h"
#include "components/unified_consent/url_keyed_data_collection_consent_helper.h"
using unified_consent::UrlKeyedDataCollectionConsentHelper;
namespace ukm { namespace ukm {
...@@ -34,6 +37,7 @@ enum DisableInfo { ...@@ -34,6 +37,7 @@ enum DisableInfo {
DISABLED_BY_HISTORY_CONNECTED_PASSPHRASE, DISABLED_BY_HISTORY_CONNECTED_PASSPHRASE,
DISABLED_BY_INITIALIZED_CONNECTED_PASSPHRASE, DISABLED_BY_INITIALIZED_CONNECTED_PASSPHRASE,
DISABLED_BY_HISTORY_INITIALIZED_CONNECTED_PASSPHRASE, DISABLED_BY_HISTORY_INITIALIZED_CONNECTED_PASSPHRASE,
DISABLED_BY_ANONYMIZED_DATA_COLLECTION,
MAX_DISABLE_INFO MAX_DISABLE_INFO
}; };
...@@ -43,16 +47,30 @@ void RecordDisableInfo(DisableInfo info) { ...@@ -43,16 +47,30 @@ void RecordDisableInfo(DisableInfo info) {
} // namespace } // namespace
SyncDisableObserver::SyncDisableObserver() SyncDisableObserver::SyncDisableObserver() : sync_observer_(this) {}
: sync_observer_(this),
all_histories_enabled_(false), SyncDisableObserver::~SyncDisableObserver() {
all_extensions_enabled_(false) {} for (const auto& entry : consent_helpers_) {
entry.second->RemoveObserver(this);
}
}
bool SyncDisableObserver::SyncState::AllowsUkm() const {
if (anonymized_data_collection_state == DataCollectionState::kIgnored)
return history_enabled && initialized && connected && !passphrase_protected;
else
return anonymized_data_collection_state == DataCollectionState::kEnabled;
}
SyncDisableObserver::~SyncDisableObserver() {} bool SyncDisableObserver::SyncState::AllowsUkmWithExtension() const {
return AllowsUkm() && extensions_enabled && initialized && connected &&
!passphrase_protected;
}
// static // static
SyncDisableObserver::SyncState SyncDisableObserver::GetSyncState( SyncDisableObserver::SyncState SyncDisableObserver::GetSyncState(
syncer::SyncService* sync_service) { syncer::SyncService* sync_service,
UrlKeyedDataCollectionConsentHelper* consent_helper) {
syncer::SyncTokenStatus status = sync_service->GetSyncTokenStatus(); syncer::SyncTokenStatus status = sync_service->GetSyncTokenStatus();
SyncState state; SyncState state;
state.history_enabled = sync_service->GetPreferredDataTypes().Has( state.history_enabled = sync_service->GetPreferredDataTypes().Has(
...@@ -64,26 +82,46 @@ SyncDisableObserver::SyncState SyncDisableObserver::GetSyncState( ...@@ -64,26 +82,46 @@ SyncDisableObserver::SyncState SyncDisableObserver::GetSyncState(
status.connection_status == syncer::CONNECTION_OK; status.connection_status == syncer::CONNECTION_OK;
state.passphrase_protected = state.passphrase_protected =
state.initialized && sync_service->IsUsingSecondaryPassphrase(); state.initialized && sync_service->IsUsingSecondaryPassphrase();
if (consent_helper) {
state.anonymized_data_collection_state =
consent_helper->IsEnabled() ? DataCollectionState::kEnabled
: DataCollectionState::kDisabled;
}
return state; return state;
} }
void SyncDisableObserver::ObserveServiceForSyncDisables( void SyncDisableObserver::ObserveServiceForSyncDisables(
syncer::SyncService* sync_service) { syncer::SyncService* sync_service,
previous_states_[sync_service] = GetSyncState(sync_service); PrefService* prefs,
bool is_unified_consent_enabled) {
std::unique_ptr<UrlKeyedDataCollectionConsentHelper> consent_helper;
if (is_unified_consent_enabled) {
consent_helper = UrlKeyedDataCollectionConsentHelper::
NewAnonymizedDataCollectionConsentHelper(true, prefs, sync_service);
}
SyncState state = GetSyncState(sync_service, consent_helper.get());
previous_states_[sync_service] = state;
if (consent_helper) {
consent_helper->AddObserver(this);
consent_helpers_[sync_service] = std::move(consent_helper);
}
sync_observer_.Add(sync_service); sync_observer_.Add(sync_service);
UpdateAllProfileEnabled(false); UpdateAllProfileEnabled(false);
} }
void SyncDisableObserver::UpdateAllProfileEnabled(bool must_purge) { void SyncDisableObserver::UpdateAllProfileEnabled(bool must_purge) {
bool all_enabled = CheckSyncStateOnAllProfiles(); bool all_sync_states_allow_ukm = CheckSyncStateOnAllProfiles();
bool all_extensions_enabled = bool all_sync_states_allow_extension_ukm =
all_enabled && CheckSyncStateForExtensionsOnAllProfiles(); all_sync_states_allow_ukm && CheckSyncStateForExtensionsOnAllProfiles();
// Any change in sync settings needs to call OnSyncPrefsChanged so that the // Any change in sync settings needs to call OnSyncPrefsChanged so that the
// new settings take effect. // new settings take effect.
if (must_purge || (all_enabled != all_histories_enabled_) || if (must_purge || (all_sync_states_allow_ukm != all_sync_states_allow_ukm_) ||
(all_extensions_enabled != all_extensions_enabled_)) { (all_sync_states_allow_extension_ukm !=
all_histories_enabled_ = all_enabled; all_sync_states_allow_extension_ukm_)) {
all_extensions_enabled_ = all_extensions_enabled; all_sync_states_allow_ukm_ = all_sync_states_allow_ukm;
all_sync_states_allow_extension_ukm_ = all_sync_states_allow_extension_ukm;
OnSyncPrefsChanged(must_purge); OnSyncPrefsChanged(must_purge);
} }
} }
...@@ -93,17 +131,23 @@ bool SyncDisableObserver::CheckSyncStateOnAllProfiles() { ...@@ -93,17 +131,23 @@ bool SyncDisableObserver::CheckSyncStateOnAllProfiles() {
return false; return false;
for (const auto& kv : previous_states_) { for (const auto& kv : previous_states_) {
const SyncDisableObserver::SyncState& state = kv.second; const SyncDisableObserver::SyncState& state = kv.second;
if (!state.history_enabled || !state.initialized || !state.connected || if (!state.AllowsUkm()) {
state.passphrase_protected) {
int disabled_by = 0; int disabled_by = 0;
if (!state.history_enabled) if (state.anonymized_data_collection_state ==
disabled_by |= 1 << 0; DataCollectionState::kIgnored) {
if (!state.initialized) if (!state.history_enabled)
disabled_by |= 1 << 1; disabled_by |= 1 << 0;
if (!state.connected) if (!state.initialized)
disabled_by |= 1 << 2; disabled_by |= 1 << 1;
if (state.passphrase_protected) if (!state.connected)
disabled_by |= 1 << 3; disabled_by |= 1 << 2;
if (state.passphrase_protected)
disabled_by |= 1 << 3;
} else {
DCHECK_EQ(DataCollectionState::kDisabled,
state.anonymized_data_collection_state);
disabled_by |= 1 << 4;
}
RecordDisableInfo(DisableInfo(disabled_by)); RecordDisableInfo(DisableInfo(disabled_by));
return false; return false;
} }
...@@ -124,36 +168,60 @@ bool SyncDisableObserver::CheckSyncStateForExtensionsOnAllProfiles() { ...@@ -124,36 +168,60 @@ bool SyncDisableObserver::CheckSyncStateForExtensionsOnAllProfiles() {
} }
void SyncDisableObserver::OnStateChanged(syncer::SyncService* sync) { void SyncDisableObserver::OnStateChanged(syncer::SyncService* sync) {
UrlKeyedDataCollectionConsentHelper* consent_helper = nullptr;
auto found = consent_helpers_.find(sync);
if (found != consent_helpers_.end())
consent_helper = found->second.get();
UpdateSyncState(sync, consent_helper);
}
void SyncDisableObserver::OnUrlKeyedDataCollectionConsentStateChanged(
unified_consent::UrlKeyedDataCollectionConsentHelper* consent_helper) {
DCHECK(consent_helper);
syncer::SyncService* sync_service = nullptr;
for (const auto& entry : consent_helpers_) {
if (consent_helper == entry.second.get()) {
sync_service = entry.first;
break;
}
}
DCHECK(sync_service);
UpdateSyncState(sync_service, consent_helper);
}
void SyncDisableObserver::UpdateSyncState(
syncer::SyncService* sync,
UrlKeyedDataCollectionConsentHelper* consent_helper) {
DCHECK(base::ContainsKey(previous_states_, sync)); DCHECK(base::ContainsKey(previous_states_, sync));
SyncDisableObserver::SyncState state = GetSyncState(sync);
const SyncDisableObserver::SyncState& previous_state = previous_states_[sync]; const SyncDisableObserver::SyncState& previous_state = previous_states_[sync];
bool must_purge = DCHECK(previous_state.anonymized_data_collection_state ==
// Trigger a purge if history sync was disabled. DataCollectionState::kIgnored ||
(previous_state.history_enabled && !state.history_enabled) || consent_helper);
// Trigger a purge if engine has become disabled. SyncDisableObserver::SyncState state = GetSyncState(sync, consent_helper);
(previous_state.initialized && !state.initialized) || // Trigger a purge if sync state no longer allows UKM.
// Trigger a purge if the user added a passphrase. Since we can't detect bool must_purge = previous_state.AllowsUkm() && !state.AllowsUkm();
// the use of a passphrase while the engine is not initialized, we may
// miss the transition if the user adds a passphrase in this state.
(previous_state.initialized && state.initialized &&
!previous_state.passphrase_protected && state.passphrase_protected);
previous_states_[sync] = state; previous_states_[sync] = state;
UpdateAllProfileEnabled(must_purge); UpdateAllProfileEnabled(must_purge);
} }
void SyncDisableObserver::OnSyncShutdown(syncer::SyncService* sync) { void SyncDisableObserver::OnSyncShutdown(syncer::SyncService* sync) {
DCHECK(base::ContainsKey(previous_states_, sync)); DCHECK(base::ContainsKey(previous_states_, sync));
auto found = consent_helpers_.find(sync);
if (found != consent_helpers_.end()) {
found->second->RemoveObserver(this);
consent_helpers_.erase(found);
}
sync_observer_.Remove(sync); sync_observer_.Remove(sync);
previous_states_.erase(sync); previous_states_.erase(sync);
UpdateAllProfileEnabled(false); UpdateAllProfileEnabled(false);
} }
bool SyncDisableObserver::SyncStateAllowsUkm() { bool SyncDisableObserver::SyncStateAllowsUkm() {
return all_histories_enabled_; return all_sync_states_allow_ukm_;
} }
bool SyncDisableObserver::SyncStateAllowsExtensionUkm() { bool SyncDisableObserver::SyncStateAllowsExtensionUkm() {
return all_extensions_enabled_; return all_sync_states_allow_extension_ukm_;
} }
} // namespace ukm } // namespace ukm
...@@ -10,25 +10,38 @@ ...@@ -10,25 +10,38 @@
#include "base/scoped_observer.h" #include "base/scoped_observer.h"
#include "components/sync/driver/sync_service.h" #include "components/sync/driver/sync_service.h"
#include "components/sync/driver/sync_service_observer.h" #include "components/sync/driver/sync_service_observer.h"
#include "components/unified_consent/url_keyed_data_collection_consent_helper.h"
class PrefService;
namespace ukm { namespace ukm {
// Observes the state of a set of SyncServices for changes to history sync // Observer that monitors whether UKM is allowed for all profiles.
// preferences. This is for used to trigger purging of local state when //
// sync is disabled on a profile and disabling recording when any non-syncing // For one profile, UKM is allowed under the following conditions:
// profiles are active. // * If unified consent is disabled, then UKM is allowed for the profile iff
class SyncDisableObserver : public syncer::SyncServiceObserver { // sync history is active;
// * If unified consent is enabled, then UKM is allowed for the profile iff
// URL-keyed anonymized data collectiion is enabled.
class SyncDisableObserver
: public syncer::SyncServiceObserver,
public unified_consent::UrlKeyedDataCollectionConsentHelper::Observer {
public: public:
SyncDisableObserver(); SyncDisableObserver();
~SyncDisableObserver() override; ~SyncDisableObserver() override;
// Starts observing a service for sync disables. // Starts observing a service for sync disables.
void ObserveServiceForSyncDisables(syncer::SyncService* sync_service); void ObserveServiceForSyncDisables(syncer::SyncService* sync_service,
PrefService* pref_service,
// Returns true iff sync is in a state that allows UKM to be enabled. bool is_unified_consent_enabled);
// This means that for all profiles, sync is initialized, connected, has the
// HISTORY_DELETE_DIRECTIVES data type enabled, and does not have a secondary // Returns true iff all sync states alllow UKM to be enabled. This means that
// passphrase enabled. // for all profiles:
// * If unified consent is disabled, then sync is initialized, connected, has
// the HISTORY_DELETE_DIRECTIVES data type enabled, and does not have a
// secondary passphrase enabled.
// * If unified consent is enabled, then URL-keyed anonymized data collection
// is enabled for that profile.
virtual bool SyncStateAllowsUkm(); virtual bool SyncStateAllowsUkm();
// Returns true iff sync is in a state that allows UKM to capture extensions. // Returns true iff sync is in a state that allows UKM to capture extensions.
...@@ -46,6 +59,11 @@ class SyncDisableObserver : public syncer::SyncServiceObserver { ...@@ -46,6 +59,11 @@ class SyncDisableObserver : public syncer::SyncServiceObserver {
void OnStateChanged(syncer::SyncService* sync) override; void OnStateChanged(syncer::SyncService* sync) override;
void OnSyncShutdown(syncer::SyncService* sync) override; void OnSyncShutdown(syncer::SyncService* sync) override;
// unified_consent::UrlKeyedDataCollectionConsentHelper::Observer:
void OnUrlKeyedDataCollectionConsentStateChanged(
unified_consent::UrlKeyedDataCollectionConsentHelper* consent_helper)
override;
// Recomputes all_profiles_enabled_ state from previous_states_; // Recomputes all_profiles_enabled_ state from previous_states_;
void UpdateAllProfileEnabled(bool must_purge); void UpdateAllProfileEnabled(bool must_purge);
...@@ -61,8 +79,29 @@ class SyncDisableObserver : public syncer::SyncServiceObserver { ...@@ -61,8 +79,29 @@ class SyncDisableObserver : public syncer::SyncServiceObserver {
ScopedObserver<syncer::SyncService, syncer::SyncServiceObserver> ScopedObserver<syncer::SyncService, syncer::SyncServiceObserver>
sync_observer_; sync_observer_;
enum class DataCollectionState {
// Matches the case when unified consent feature is disabled
kIgnored,
// Unified consent feature is enabled and the user has disabled URL-keyed
// anonymized data collection.
kDisabled,
// Unified consent feature is enabled and the user has enabled URL-keyed
// anonymized data collection.
kEnabled
};
// State data about sync services that we need to remember. // State data about sync services that we need to remember.
struct SyncState { struct SyncState {
// Returns true if this sync state allows UKM:
// * If unified consent is disabled, then sync is initialized, connected,
// has history data type enabled, and does not have a secondary passphrase
// enabled.
// * If unified consent is enabled, then URL-keyed anonymized data
// collection is enabled.
bool AllowsUkm() const;
// Returns true if |AllowUkm| and if sync extensions are enabled.
bool AllowsUkmWithExtension() const;
// If the user has history sync enabled. // If the user has history sync enabled.
bool history_enabled = false; bool history_enabled = false;
// If the user has extension sync enabled. // If the user has extension sync enabled.
...@@ -74,21 +113,45 @@ class SyncDisableObserver : public syncer::SyncServiceObserver { ...@@ -74,21 +113,45 @@ class SyncDisableObserver : public syncer::SyncServiceObserver {
// Whether user data is hidden by a secondary passphrase. // Whether user data is hidden by a secondary passphrase.
// This is not valid if the state is not initialized. // This is not valid if the state is not initialized.
bool passphrase_protected = false; bool passphrase_protected = false;
// Whether anonymized data collection is enabled.
// Note: This is not managed by sync service. It was added in this enum
// for convenience.
DataCollectionState anonymized_data_collection_state =
DataCollectionState::kIgnored;
}; };
// Updates the sync state for |sync| service. Updates all profiles if needed.
void UpdateSyncState(
syncer::SyncService* sync,
unified_consent::UrlKeyedDataCollectionConsentHelper* consent_helper);
// Gets the current state of a SyncService. // Gets the current state of a SyncService.
static SyncState GetSyncState(syncer::SyncService* sync); // A non-null |consent_helper| implies that Unified Consent is enabled.
static SyncState GetSyncState(
syncer::SyncService* sync,
unified_consent::UrlKeyedDataCollectionConsentHelper* consent_helper);
// The list of services that had sync enabled when we last checked. // The state of the sync services being observed.
std::map<syncer::SyncService*, SyncState> previous_states_; std::map<syncer::SyncService*, SyncState> previous_states_;
// Tracks if history sync was enabled on all profiles after the last state // The list of URL-keyed anonymized data collection consent helpers.
// change. //
bool all_histories_enabled_; // Note: UrlKeyedDataCollectionConsentHelper do not rely on sync when
// unified consent feature is enabled but there must be exactly one per
// Chromium profile. As there is a single sync service per profile, it is safe
// to key them by sync service instead of introducing an additional map.
std::map<
syncer::SyncService*,
std::unique_ptr<unified_consent::UrlKeyedDataCollectionConsentHelper>>
consent_helpers_;
// Tracks if UKM is allowed on all profiles after the last state change.
bool all_sync_states_allow_ukm_ = false;
// Tracks if extension sync was enabled on all profiles after the last state // Tracks if extension sync was enabled on all profiles after the last state
// change. // change.
bool all_extensions_enabled_; bool all_sync_states_allow_extension_ukm_ = false;
DISALLOW_COPY_AND_ASSIGN(SyncDisableObserver); DISALLOW_COPY_AND_ASSIGN(SyncDisableObserver);
}; };
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
#include "services/metrics/public/mojom/ukm_interface.mojom.h" #include "services/metrics/public/mojom/ukm_interface.mojom.h"
namespace metrics { namespace metrics {
class UkmBrowserTest; class UkmBrowserTestBase;
class UkmEGTestHelper; class UkmEGTestHelper;
} }
...@@ -90,7 +90,7 @@ class UkmRecorderImpl : public UkmRecorder { ...@@ -90,7 +90,7 @@ class UkmRecorderImpl : public UkmRecorder {
virtual bool ShouldRestrictToWhitelistedEntries() const; virtual bool ShouldRestrictToWhitelistedEntries() const;
private: private:
friend ::metrics::UkmBrowserTest; friend ::metrics::UkmBrowserTestBase;
friend ::metrics::UkmEGTestHelper; friend ::metrics::UkmEGTestHelper;
friend ::ukm::debug::UkmDebugDataExtractor; friend ::ukm::debug::UkmDebugDataExtractor;
friend ::ukm::UkmUtilsForTest; friend ::ukm::UkmUtilsForTest;
......
...@@ -24,7 +24,7 @@ class PrefService; ...@@ -24,7 +24,7 @@ class PrefService;
namespace metrics { namespace metrics {
class MetricsServiceClient; class MetricsServiceClient;
class UkmBrowserTest; class UkmBrowserTestBase;
class UkmEGTestHelper; class UkmEGTestHelper;
} }
...@@ -81,7 +81,7 @@ class UkmService : public UkmRecorderImpl { ...@@ -81,7 +81,7 @@ class UkmService : public UkmRecorderImpl {
int32_t report_count() const { return report_count_; } int32_t report_count() const { return report_count_; }
private: private:
friend ::metrics::UkmBrowserTest; friend ::metrics::UkmBrowserTestBase;
friend ::metrics::UkmEGTestHelper; friend ::metrics::UkmEGTestHelper;
friend ::ukm::debug::UkmDebugDataExtractor; friend ::ukm::debug::UkmDebugDataExtractor;
friend ::ukm::UkmUtilsForTest; friend ::ukm::UkmUtilsForTest;
......
...@@ -178,15 +178,23 @@ void UnifiedConsentService::OnUnifiedConsentGivenPrefChanged() { ...@@ -178,15 +178,23 @@ void UnifiedConsentService::OnUnifiedConsentGivenPrefChanged() {
} }
void UnifiedConsentService::SetSyncEverythingIfPossible(bool sync_everything) { void UnifiedConsentService::SetSyncEverythingIfPossible(bool sync_everything) {
syncer::SyncPrefs sync_prefs(pref_service_);
if (sync_everything == sync_prefs.HasKeepEverythingSynced())
return;
if (!sync_service_->IsEngineInitialized()) if (!sync_service_->IsEngineInitialized())
return; return;
if (sync_everything) { if (sync_everything) {
pref_service_->SetBoolean(autofill::prefs::kAutofillWalletImportEnabled, pref_service_->SetBoolean(autofill::prefs::kAutofillWalletImportEnabled,
true); true);
sync_service_->OnUserChoseDatatypes(sync_everything,
syncer::UserSelectableTypes());
} else {
syncer::ModelTypeSet preferred = sync_service_->GetPreferredDataTypes();
preferred.RetainAll(syncer::UserSelectableTypes());
sync_service_->OnUserChoseDatatypes(false, preferred);
} }
sync_service_->OnUserChoseDatatypes(sync_everything,
syncer::UserSelectableTypes());
} }
void UnifiedConsentService::MigrateProfileToUnifiedConsent() { void UnifiedConsentService::MigrateProfileToUnifiedConsent() {
......
...@@ -53,6 +53,7 @@ source_set("metrics") { ...@@ -53,6 +53,7 @@ source_set("metrics") {
"//ios/chrome/browser/sync", "//ios/chrome/browser/sync",
"//ios/chrome/browser/tabs", "//ios/chrome/browser/tabs",
"//ios/chrome/browser/translate", "//ios/chrome/browser/translate",
"//ios/chrome/browser/unified_consent:feature",
"//ios/chrome/browser/variations", "//ios/chrome/browser/variations",
"//ios/chrome/browser/variations:ios_chrome_ui_string_overrider_factory", "//ios/chrome/browser/variations:ios_chrome_ui_string_overrider_factory",
"//ios/chrome/browser/web_state_list", "//ios/chrome/browser/web_state_list",
......
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
#include "components/variations/variations_associated_data.h" #include "components/variations/variations_associated_data.h"
#include "components/version_info/version_info.h" #include "components/version_info/version_info.h"
#include "ios/chrome/browser/application_context.h" #include "ios/chrome/browser/application_context.h"
#include "ios/chrome/browser/browser_state/chrome_browser_state.h"
#include "ios/chrome/browser/browser_state/chrome_browser_state_manager.h" #include "ios/chrome/browser/browser_state/chrome_browser_state_manager.h"
#include "ios/chrome/browser/chrome_paths.h" #include "ios/chrome/browser/chrome_paths.h"
#include "ios/chrome/browser/google/google_brand.h" #include "ios/chrome/browser/google/google_brand.h"
...@@ -58,6 +59,7 @@ ...@@ -58,6 +59,7 @@
#include "ios/chrome/browser/tab_parenting_global_observer.h" #include "ios/chrome/browser/tab_parenting_global_observer.h"
#import "ios/chrome/browser/tabs/tab_model_list.h" #import "ios/chrome/browser/tabs/tab_model_list.h"
#include "ios/chrome/browser/translate/translate_ranker_metrics_provider.h" #include "ios/chrome/browser/translate/translate_ranker_metrics_provider.h"
#include "ios/chrome/browser/unified_consent/feature.h"
#include "ios/chrome/common/channel_info.h" #include "ios/chrome/common/channel_info.h"
#include "ios/web/public/web_thread.h" #include "ios/web/public/web_thread.h"
...@@ -290,7 +292,9 @@ bool IOSChromeMetricsServiceClient::RegisterForBrowserStateEvents( ...@@ -290,7 +292,9 @@ bool IOSChromeMetricsServiceClient::RegisterForBrowserStateEvents(
browser_sync::ProfileSyncService* sync = browser_sync::ProfileSyncService* sync =
ProfileSyncServiceFactory::GetInstance()->GetForBrowserState( ProfileSyncServiceFactory::GetInstance()->GetForBrowserState(
browser_state); browser_state);
ObserveServiceForSyncDisables(static_cast<syncer::SyncService*>(sync)); ObserveServiceForSyncDisables(static_cast<syncer::SyncService*>(sync),
browser_state->GetPrefs(),
IsUnifiedConsentEnabled());
return (history_service != nullptr && sync != nullptr); return (history_service != nullptr && sync != nullptr);
} }
......
...@@ -47434,6 +47434,7 @@ Full version information for the fingerprint enum values: ...@@ -47434,6 +47434,7 @@ Full version information for the fingerprint enum values:
<int value="14" label="Disabled by initialized, connected, passphrase"/> <int value="14" label="Disabled by initialized, connected, passphrase"/>
<int value="15" <int value="15"
label="Disabled by history, initialized, connected, passphrase"/> label="Disabled by history, initialized, connected, passphrase"/>
<int value="16" label="Disabled by URL-keyed anonymized data collection"/>
</enum> </enum>
<enum name="UmaCleanExitConsistency"> <enum name="UmaCleanExitConsistency">
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment