blob: 1ccfff8c042eeaee8bee4834692c5629ea07f721 [file] [log] [blame]
// Copyright 2018 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 "components/unified_consent/unified_consent_service.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/scoped_observer.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "build/build_config.h"
#include "components/autofill/core/common/autofill_prefs.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/prefs/pref_service.h"
#include "components/sync/base/model_type.h"
#include "components/sync/driver/sync_service.h"
#include "components/sync/driver/sync_user_settings.h"
#include "components/unified_consent/feature.h"
#include "components/unified_consent/pref_names.h"
namespace unified_consent {
UnifiedConsentService::UnifiedConsentService(
std::unique_ptr<UnifiedConsentServiceClient> service_client,
PrefService* pref_service,
identity::IdentityManager* identity_manager,
syncer::SyncService* sync_service)
: service_client_(std::move(service_client)),
pref_service_(pref_service),
identity_manager_(identity_manager),
sync_service_(sync_service) {
DCHECK(service_client_);
DCHECK(pref_service_);
DCHECK(identity_manager_);
DCHECK(sync_service_);
if (GetMigrationState() == MigrationState::kNotInitialized)
MigrateProfileToUnifiedConsent();
identity_manager_->AddObserver(this);
sync_service_->AddObserver(this);
}
UnifiedConsentService::~UnifiedConsentService() {}
// static
void UnifiedConsentService::RegisterPrefs(
user_prefs::PrefRegistrySyncable* registry) {
registry->RegisterBooleanPref(prefs::kUrlKeyedAnonymizedDataCollectionEnabled,
false);
registry->RegisterIntegerPref(
prefs::kUnifiedConsentMigrationState,
static_cast<int>(MigrationState::kNotInitialized));
registry->RegisterBooleanPref(prefs::kAllUnifiedConsentServicesWereEnabled,
false);
}
// static
void UnifiedConsentService::RollbackIfNeeded(
PrefService* user_pref_service,
syncer::SyncService* sync_service,
UnifiedConsentServiceClient* service_client) {
DCHECK(user_pref_service);
DCHECK(service_client);
if (user_pref_service->GetInteger(prefs::kUnifiedConsentMigrationState) ==
static_cast<int>(MigrationState::kNotInitialized)) {
// If there was no migration yet, nothing has to be rolled back.
return;
}
// Turn off all off-by-default services if services were enabled due to
// unified consent.
if (user_pref_service->GetBoolean(
prefs::kAllUnifiedConsentServicesWereEnabled)) {
service_client->SetServiceEnabled(Service::kSafeBrowsingExtendedReporting,
false);
service_client->SetServiceEnabled(Service::kSpellCheck, false);
service_client->SetServiceEnabled(Service::kContextualSearch, false);
}
// Clear all unified consent prefs.
user_pref_service->ClearPref(prefs::kUrlKeyedAnonymizedDataCollectionEnabled);
user_pref_service->ClearPref(prefs::kUnifiedConsentMigrationState);
user_pref_service->ClearPref(prefs::kAllUnifiedConsentServicesWereEnabled);
}
void UnifiedConsentService::EnableGoogleServices() {
DCHECK(identity_manager_->HasPrimaryAccount());
DCHECK_LT(MigrationState::kNotInitialized, GetMigrationState());
if (GetMigrationState() != MigrationState::kCompleted) {
// If the user opted into unified consent, the migration is completed.
SetMigrationState(MigrationState::kCompleted);
}
// Enable all Google services except sync.
pref_service_->SetBoolean(prefs::kUrlKeyedAnonymizedDataCollectionEnabled,
true);
for (int i = 0; i <= static_cast<int>(Service::kLast); ++i) {
Service service = static_cast<Service>(i);
if (service_client_->GetServiceState(service) !=
ServiceState::kNotSupported) {
service_client_->SetServiceEnabled(service, true);
}
}
pref_service_->SetBoolean(prefs::kAllUnifiedConsentServicesWereEnabled, true);
}
void UnifiedConsentService::Shutdown() {
identity_manager_->RemoveObserver(this);
sync_service_->RemoveObserver(this);
}
void UnifiedConsentService::OnPrimaryAccountCleared(
const AccountInfo& account_info) {
pref_service_->SetBoolean(prefs::kAllUnifiedConsentServicesWereEnabled,
false);
// By design, signing out of Chrome automatically disables off-by-default
// services.
pref_service_->SetBoolean(prefs::kUrlKeyedAnonymizedDataCollectionEnabled,
false);
service_client_->SetServiceEnabled(Service::kSafeBrowsingExtendedReporting,
false);
service_client_->SetServiceEnabled(Service::kSpellCheck, false);
service_client_->SetServiceEnabled(Service::kContextualSearch, false);
if (GetMigrationState() != MigrationState::kCompleted) {
// When the user signs out, the migration is complete.
SetMigrationState(MigrationState::kCompleted);
}
}
void UnifiedConsentService::OnStateChanged(syncer::SyncService* sync) {
if (!sync_service_->CanSyncFeatureStart() ||
!sync_service_->IsEngineInitialized()) {
return;
}
if (GetMigrationState() == MigrationState::kInProgressWaitForSyncInit)
UpdateSettingsForMigration();
}
MigrationState UnifiedConsentService::GetMigrationState() {
int migration_state_int =
pref_service_->GetInteger(prefs::kUnifiedConsentMigrationState);
DCHECK_LE(static_cast<int>(MigrationState::kNotInitialized),
migration_state_int);
DCHECK_GE(static_cast<int>(MigrationState::kCompleted), migration_state_int);
return static_cast<MigrationState>(migration_state_int);
}
void UnifiedConsentService::SetMigrationState(MigrationState migration_state) {
pref_service_->SetInteger(prefs::kUnifiedConsentMigrationState,
static_cast<int>(migration_state));
}
void UnifiedConsentService::MigrateProfileToUnifiedConsent() {
DCHECK_EQ(GetMigrationState(), MigrationState::kNotInitialized);
if (!identity_manager_->HasPrimaryAccount()) {
SetMigrationState(MigrationState::kCompleted);
return;
}
UpdateSettingsForMigration();
}
void UnifiedConsentService::UpdateSettingsForMigration() {
if (!sync_service_->IsEngineInitialized()) {
SetMigrationState(MigrationState::kInProgressWaitForSyncInit);
return;
}
// Set URL-keyed anonymized metrics to the state it had before unified
// consent.
bool url_keyed_metrics_enabled =
sync_service_->IsSyncFeatureEnabled() &&
sync_service_->GetUserSettings()->GetChosenDataTypes().Has(
syncer::TYPED_URLS) &&
!sync_service_->GetUserSettings()->IsUsingSecondaryPassphrase();
pref_service_->SetBoolean(prefs::kUrlKeyedAnonymizedDataCollectionEnabled,
url_keyed_metrics_enabled);
SetMigrationState(MigrationState::kCompleted);
}
} // namespace unified_consent