blob: 783491f90f5eb4337dabeadc7d7f49b7a852516f [file] [log] [blame]
// Copyright 2016 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 "chrome/browser/ui/webui/chromeos/login/arc_terms_of_service_screen_handler.h"
#include "base/i18n/timezone.h"
#include "chrome/browser/chromeos/arc/arc_support_host.h"
#include "chrome/browser/chromeos/arc/arc_util.h"
#include "chrome/browser/chromeos/arc/optin/arc_optin_preference_handler.h"
#include "chrome/browser/chromeos/login/screens/arc_terms_of_service_screen_view_observer.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/consent_auditor/consent_auditor_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/signin/signin_manager_factory.h"
#include "chrome/grit/generated_resources.h"
#include "chromeos/chromeos_switches.h"
#include "chromeos/network/network_handler.h"
#include "chromeos/network/network_state.h"
#include "chromeos/network/network_state_handler.h"
#include "components/arc/arc_prefs.h"
#include "components/consent_auditor/consent_auditor.h"
#include "components/login/localized_values_builder.h"
#include "components/prefs/pref_service.h"
#include "components/signin/core/browser/signin_manager_base.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h"
#include "ui/base/l10n/l10n_util.h"
namespace {
const char kJsScreenPath[] = "login.ArcTermsOfServiceScreen";
} // namespace
namespace chromeos {
ArcTermsOfServiceScreenHandler::ArcTermsOfServiceScreenHandler()
: BaseScreenHandler(kScreenId) {
set_call_js_prefix(kJsScreenPath);
}
ArcTermsOfServiceScreenHandler::~ArcTermsOfServiceScreenHandler() {
OobeUI* oobe_ui = GetOobeUI();
if (oobe_ui)
oobe_ui->RemoveObserver(this);
chromeos::NetworkHandler::Get()->network_state_handler()->RemoveObserver(
this, FROM_HERE);
system::TimezoneSettings::GetInstance()->RemoveObserver(this);
for (auto& observer : observer_list_)
observer.OnViewDestroyed(this);
}
void ArcTermsOfServiceScreenHandler::RegisterMessages() {
AddCallback("arcTermsOfServiceSkip",
&ArcTermsOfServiceScreenHandler::HandleSkip);
AddCallback("arcTermsOfServiceAccept",
&ArcTermsOfServiceScreenHandler::HandleAccept);
}
void ArcTermsOfServiceScreenHandler::MaybeLoadPlayStoreToS(
bool ignore_network_state) {
const chromeos::NetworkState* default_network =
chromeos::NetworkHandler::Get()
->network_state_handler()
->DefaultNetwork();
if (!ignore_network_state && !default_network)
return;
const std::string country_code = base::CountryCodeForCurrentTimezone();
CallJS("loadPlayStoreToS", country_code);
}
void ArcTermsOfServiceScreenHandler::OnCurrentScreenChanged(
OobeScreen current_screen,
OobeScreen new_screen) {
if (new_screen != OobeScreen::SCREEN_GAIA_SIGNIN)
return;
MaybeLoadPlayStoreToS(false);
StartNetworkAndTimeZoneObserving();
}
void ArcTermsOfServiceScreenHandler::TimezoneChanged(
const icu::TimeZone& timezone) {
MaybeLoadPlayStoreToS(false);
}
void ArcTermsOfServiceScreenHandler::DefaultNetworkChanged(
const NetworkState* network) {
MaybeLoadPlayStoreToS(false);
}
void ArcTermsOfServiceScreenHandler::DeclareLocalizedValues(
::login::LocalizedValuesBuilder* builder) {
builder->Add("arcTermsOfServiceScreenHeading", IDS_ARC_OOBE_TERMS_HEADING);
builder->Add("arcTermsOfServiceScreenDescription",
IDS_ARC_OOBE_TERMS_DESCRIPTION);
builder->Add("arcTermsOfServiceLoading", IDS_ARC_OOBE_TERMS_LOADING);
builder->Add("arcTermsOfServiceError", IDS_ARC_OOBE_TERMS_LOAD_ERROR);
builder->Add("arcTermsOfServiceSkipButton", IDS_ARC_OOBE_TERMS_BUTTON_SKIP);
builder->Add("arcTermsOfServiceRetryButton", IDS_ARC_OOBE_TERMS_BUTTON_RETRY);
builder->Add("arcTermsOfServiceAcceptButton",
IDS_ARC_OOBE_TERMS_BUTTON_ACCEPT);
builder->Add("arcTermsOfServiceNextButton",
IDS_ARC_OPT_IN_DIALOG_BUTTON_NEXT);
builder->Add("arcPolicyLink", IDS_ARC_OPT_IN_PRIVACY_POLICY_LINK);
builder->Add("arcTextBackupRestore", IDS_ARC_OPT_IN_DIALOG_BACKUP_RESTORE);
builder->Add("arcTextLocationService", IDS_ARC_OPT_IN_LOCATION_SETTING);
builder->Add("arcTextPaiService", IDS_ARC_OPT_IN_PAI);
builder->Add("arcTextGoogleServiceConfirmation",
IDS_ARC_OPT_IN_GOOGLE_SERVICE_CONFIRMATION);
builder->Add("arcLearnMoreStatistics", IDS_ARC_OPT_IN_LEARN_MORE_STATISTICS);
builder->Add("arcLearnMoreLocationService",
IDS_ARC_OPT_IN_LEARN_MORE_LOCATION_SERVICES);
builder->Add("arcLearnMoreBackupAndRestore",
IDS_ARC_OPT_IN_LEARN_MORE_BACKUP_AND_RESTORE);
builder->Add("arcLearnMorePaiService", IDS_ARC_OPT_IN_LEARN_MORE_PAI_SERVICE);
builder->Add("arcOverlayClose", IDS_ARC_OOBE_TERMS_POPUP_HELP_CLOSE_BUTTON);
}
void ArcTermsOfServiceScreenHandler::SendArcManagedStatus(Profile* profile) {
CallJS("setArcManaged",
arc::IsArcPlayStoreEnabledPreferenceManagedForProfile(profile));
}
void ArcTermsOfServiceScreenHandler::OnMetricsModeChanged(bool enabled,
bool managed) {
const Profile* const profile = ProfileManager::GetActiveUserProfile();
CHECK(profile);
const user_manager::User* user =
ProfileHelper::Get()->GetUserByProfile(profile);
CHECK(user);
const AccountId owner =
user_manager::UserManager::Get()->GetOwnerAccountId();
// Owner may not be set in case of initial account setup. Note, in case of
// enterprise enrolled devices owner is always empty and we need to account
// managed flag.
const bool owner_profile = !owner.is_valid() || user->GetAccountId() == owner;
if (owner_profile && !managed && !enabled) {
CallJS("setMetricsMode", base::string16(), false);
} else {
int message_id;
if (owner_profile && !managed) {
message_id = IDS_ARC_OOBE_TERMS_DIALOG_METRICS_ENABLED;
} else {
message_id = enabled ? IDS_ARC_OOBE_TERMS_DIALOG_METRICS_MANAGED_ENABLED
: IDS_ARC_OOBE_TERMS_DIALOG_METRICS_MANAGED_DISABLED;
}
CallJS("setMetricsMode", l10n_util::GetStringUTF16(message_id), true);
}
}
void ArcTermsOfServiceScreenHandler::OnBackupAndRestoreModeChanged(
bool enabled, bool managed) {
backup_restore_managed_ = managed;
CallJS("setBackupAndRestoreMode", enabled, managed);
}
void ArcTermsOfServiceScreenHandler::OnLocationServicesModeChanged(
bool enabled, bool managed) {
location_services_managed_ = managed;
CallJS("setLocationServicesMode", enabled, managed);
}
void ArcTermsOfServiceScreenHandler::AddObserver(
ArcTermsOfServiceScreenViewObserver* observer) {
observer_list_.AddObserver(observer);
}
void ArcTermsOfServiceScreenHandler::RemoveObserver(
ArcTermsOfServiceScreenViewObserver* observer) {
observer_list_.RemoveObserver(observer);
}
void ArcTermsOfServiceScreenHandler::Show() {
if (!page_is_ready()) {
show_on_init_ = true;
return;
}
DoShow();
}
void ArcTermsOfServiceScreenHandler::Hide() {
system::TimezoneSettings::GetInstance()->RemoveObserver(this);
pref_handler_.reset();
}
void ArcTermsOfServiceScreenHandler::StartNetworkAndTimeZoneObserving() {
if (network_time_zone_observing_)
return;
chromeos::NetworkHandler::Get()->network_state_handler()->AddObserver(
this, FROM_HERE);
system::TimezoneSettings::GetInstance()->AddObserver(this);
network_time_zone_observing_ = true;
}
void ArcTermsOfServiceScreenHandler::Initialize() {
if (!show_on_init_) {
// Send time zone information as soon as possible to able to pre-load the
// Play Store ToS.
GetOobeUI()->AddObserver(this);
return;
}
Show();
show_on_init_ = false;
}
void ArcTermsOfServiceScreenHandler::DoShow() {
Profile* profile = ProfileManager::GetActiveUserProfile();
CHECK(profile);
// Enable ARC to match ArcSessionManager logic. ArcSessionManager expects that
// ARC is enabled (prefs::kArcEnabled = true) on showing Terms of Service. If
// user accepts ToS then prefs::kArcEnabled is left activated. If user skips
// ToS then prefs::kArcEnabled is automatically reset in ArcSessionManager.
arc::SetArcPlayStoreEnabledForProfile(profile, true);
action_taken_ = false;
ShowScreen(kScreenId);
SendArcManagedStatus(profile);
MaybeLoadPlayStoreToS(true);
StartNetworkAndTimeZoneObserving();
pref_handler_.reset(new arc::ArcOptInPreferenceHandler(
this, profile->GetPrefs()));
pref_handler_->Start();
}
bool ArcTermsOfServiceScreenHandler::NeedDispatchEventOnAction() {
if (action_taken_)
return false;
action_taken_ = true;
return true;
}
void ArcTermsOfServiceScreenHandler::HandleSkip() {
if (!NeedDispatchEventOnAction())
return;
for (auto& observer : observer_list_)
observer.OnSkip();
}
void ArcTermsOfServiceScreenHandler::HandleAccept(
bool enable_backup_restore,
bool enable_location_services,
const std::string& tos_content) {
if (!NeedDispatchEventOnAction())
return;
pref_handler_->EnableBackupRestore(enable_backup_restore);
pref_handler_->EnableLocationService(enable_location_services);
Profile* profile = ProfileManager::GetActiveUserProfile();
consent_auditor::ConsentAuditor* consent_auditor =
ConsentAuditorFactory::GetForProfile(profile);
SigninManagerBase* signin_manager =
SigninManagerFactory::GetForProfile(profile);
DCHECK(signin_manager->IsAuthenticated());
std::string account_id = signin_manager->GetAuthenticatedAccountId();
// Record acceptance of Play ToS.
consent_auditor->RecordGaiaConsent(
account_id, consent_auditor::Feature::PLAY_STORE,
ArcSupportHost::ComputePlayToSConsentIds(tos_content),
IDS_ARC_OOBE_TERMS_BUTTON_ACCEPT, consent_auditor::ConsentStatus::GIVEN);
// If the user - not policy - chose Backup and Restore, record consent.
if (enable_backup_restore && !backup_restore_managed_) {
consent_auditor->RecordGaiaConsent(
account_id, consent_auditor::Feature::BACKUP_AND_RESTORE,
{IDS_ARC_OPT_IN_DIALOG_BACKUP_RESTORE},
IDS_ARC_OOBE_TERMS_BUTTON_ACCEPT,
consent_auditor::ConsentStatus::GIVEN);
}
// If the user - not policy - chose Location Services, record consent.
if (enable_location_services && !location_services_managed_) {
consent_auditor->RecordGaiaConsent(
account_id, consent_auditor::Feature::GOOGLE_LOCATION_SERVICE,
{IDS_ARC_OPT_IN_LOCATION_SETTING}, IDS_ARC_OOBE_TERMS_BUTTON_ACCEPT,
consent_auditor::ConsentStatus::GIVEN);
}
for (auto& observer : observer_list_)
observer.OnAccept();
}
} // namespace chromeos