blob: 1e41fb0e9a8a8840d6d3c5de99c32f05eb15d121 [file] [log] [blame]
// Copyright 2016 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/ash/arc/optin/arc_optin_preference_handler.h"
#include "ash/components/arc/arc_prefs.h"
#include "ash/constants/ash_features.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "chrome/browser/ash/arc/optin/arc_optin_preference_handler_observer.h"
#include "chrome/browser/ash/settings/device_settings_service.h"
#include "chrome/browser/ash/settings/stats_reporting_controller.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/extensions/api/settings_private/prefs_util.h"
#include "chrome/browser/metrics/metrics_reporting_state.h"
#include "chrome/browser/metrics/per_user_state_manager_chromeos.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "components/metrics/metrics_service.h"
#include "components/prefs/pref_service.h"
namespace arc {
ArcOptInPreferenceHandler::ArcOptInPreferenceHandler(
ArcOptInPreferenceHandlerObserver* observer,
PrefService* pref_service,
metrics::MetricsService* metrics_service)
: observer_(observer),
pref_service_(pref_service),
metrics_service_(metrics_service) {
DCHECK(observer_);
DCHECK(pref_service_);
DCHECK(metrics_service_);
}
void ArcOptInPreferenceHandler::Start() {
reporting_consent_subscription_ =
ash::StatsReportingController::Get()->AddObserver(base::BindRepeating(
&ArcOptInPreferenceHandler::OnMetricsPreferenceChanged,
base::Unretained(this)));
pref_change_registrar_.Init(pref_service_);
pref_change_registrar_.Add(
prefs::kArcBackupRestoreEnabled,
base::BindRepeating(
&ArcOptInPreferenceHandler::OnBackupAndRestorePreferenceChanged,
base::Unretained(this)));
pref_change_registrar_.Add(
prefs::kArcLocationServiceEnabled,
base::BindRepeating(
&ArcOptInPreferenceHandler::OnLocationServicePreferenceChanged,
base::Unretained(this)));
if (base::FeatureList::IsEnabled(ash::features::kPerUserMetrics)) {
pref_change_registrar_.Add(
metrics::prefs::kMetricsUserConsent,
base::BindRepeating(
&ArcOptInPreferenceHandler::OnMetricsPreferenceChanged,
base::Unretained(this)));
}
// Send current state.
OnMetricsPreferenceChanged();
SendBackupAndRestoreMode();
SendLocationServicesMode();
}
ArcOptInPreferenceHandler::~ArcOptInPreferenceHandler() = default;
void ArcOptInPreferenceHandler::OnMetricsPreferenceChanged() {
auto* const device_settings_service = ash::DeviceSettingsService::Get();
DCHECK(device_settings_service);
device_settings_service->GetOwnershipStatusAsync(
base::IgnoreArgs<ash::DeviceSettingsService::OwnershipStatus>(
base::BindOnce(&ArcOptInPreferenceHandler::SendMetricsMode,
weak_ptr_factory_.GetWeakPtr())));
}
void ArcOptInPreferenceHandler::OnBackupAndRestorePreferenceChanged() {
SendBackupAndRestoreMode();
}
void ArcOptInPreferenceHandler::OnLocationServicePreferenceChanged() {
SendLocationServicesMode();
}
void ArcOptInPreferenceHandler::EnableMetricsOnOwnershipKnown(
bool metrics_enabled) {
if (ShouldUpdateUserConsent()) {
EnableUserMetrics(metrics_enabled);
} else {
// Handles case in which device is either not owned or per-user is not
// enabled.
ash::StatsReportingController::Get()->SetEnabled(
ProfileManager::GetActiveUserProfile(), metrics_enabled);
}
DCHECK(enable_metrics_callback_);
std::move(enable_metrics_callback_).Run();
}
void ArcOptInPreferenceHandler::SendMetricsMode() {
if (ShouldUpdateUserConsent()) {
observer_->OnMetricsModeChanged(GetUserMetrics(),
IsMetricsReportingPolicyManaged());
} else if (g_browser_process->local_state()) {
bool enabled = ash::StatsReportingController::Get()->IsEnabled();
observer_->OnMetricsModeChanged(enabled, IsMetricsReportingPolicyManaged());
}
}
void ArcOptInPreferenceHandler::SendBackupAndRestoreMode() {
// Override the pref default to the true value, in order to encourage users to
// consent with it during OptIn flow.
const bool enabled =
pref_service_->HasPrefPath(prefs::kArcBackupRestoreEnabled)
? pref_service_->GetBoolean(prefs::kArcBackupRestoreEnabled)
: true;
observer_->OnBackupAndRestoreModeChanged(
enabled,
pref_service_->IsManagedPreference(prefs::kArcBackupRestoreEnabled));
}
void ArcOptInPreferenceHandler::SendLocationServicesMode() {
// Override the pref default to the true value, in order to encourage users to
// consent with it during OptIn flow.
const bool enabled =
pref_service_->HasPrefPath(prefs::kArcLocationServiceEnabled)
? pref_service_->GetBoolean(prefs::kArcLocationServiceEnabled)
: true;
observer_->OnLocationServicesModeChanged(
enabled,
pref_service_->IsManagedPreference(prefs::kArcLocationServiceEnabled));
}
void ArcOptInPreferenceHandler::EnableMetrics(bool is_enabled,
base::OnceClosure callback) {
auto* device_settings_service = ash::DeviceSettingsService::Get();
DCHECK(device_settings_service);
device_settings_service->GetOwnershipStatusAsync(
base::IgnoreArgs<ash::DeviceSettingsService::OwnershipStatus>(
base::BindOnce(
&ArcOptInPreferenceHandler::EnableMetricsOnOwnershipKnown,
weak_ptr_factory_.GetWeakPtr(), is_enabled)));
enable_metrics_callback_ = std::move(callback);
}
void ArcOptInPreferenceHandler::EnableBackupRestore(bool is_enabled) {
pref_service_->SetBoolean(prefs::kArcBackupRestoreEnabled, is_enabled);
}
void ArcOptInPreferenceHandler::EnableLocationService(bool is_enabled) {
pref_service_->SetBoolean(prefs::kArcLocationServiceEnabled, is_enabled);
}
bool ArcOptInPreferenceHandler::ShouldUpdateUserConsent() {
// Return user consent should not be used if feature is disabled.
if (!base::FeatureList::IsEnabled(ash::features::kPerUserMetrics)) {
return false;
}
if (!metrics_service_->GetCurrentUserMetricsConsent().has_value()) {
return false;
}
// Per user metrics should be disabled if the device metrics was disabled by
// the owner.
return ash::StatsReportingController::Get()->IsEnabled();
}
void ArcOptInPreferenceHandler::EnableUserMetrics(bool is_enabled) {
// If user is not eligible for per-user, this will no-op. See details at
// chrome/browser/metrics/per_user_state_manager_chromeos.h.
metrics_service_->UpdateCurrentUserMetricsConsent(is_enabled);
}
bool ArcOptInPreferenceHandler::GetUserMetrics() {
absl::optional<bool> metrics_enabled =
metrics_service_->GetCurrentUserMetricsConsent();
// No value means user is not eligible for per-user consent. This should be
// caught by ShouldUpdateUserConsent().
DCHECK(metrics_enabled.has_value());
return *metrics_enabled;
}
} // namespace arc