Commit 91ef3f9d authored by Josh Horwich's avatar Josh Horwich Committed by Commit Bot

arc: Record NOT_GIVEN for consents if setup is canceled.

Ensure ARC-related consents are recorded as NOT_GIVEN if the
user cancels during initial setup or during in-session
setup of ARC.

Bug: b:79583966
Test: Cancel ARC opt-in in OOBE and from launcher, unit_tests
Cq-Include-Trybots: master.tryserver.chromium.linux:closure_compilation
Change-Id: I840f90af86c01f1961918b99fd10acf7ef63a354
Reviewed-on: https://chromium-review.googlesource.com/1062971Reviewed-by: default avatarMartin Šrámek <msramek@chromium.org>
Reviewed-by: default avatarAchuith Bhandarkar <achuith@chromium.org>
Commit-Queue: Josh Horwich <jhorwich@chromium.org>
Cr-Commit-Position: refs/heads/master@{#560872}
parent 9076d454
......@@ -83,7 +83,7 @@ constexpr char kEventOnAuthSucceeded[] = "onAuthSucceeded";
constexpr char kEventOnAuthFailed[] = "onAuthFailed";
constexpr char kAuthErrorMessage[] = "errorMessage";
// "onAgree" is fired when a user clicks "Agree" button.
// "onAgreed" is fired when a user clicks "Agree" button.
// The message should have the following fields:
// - tosContent
// - tosShown
......@@ -101,6 +101,10 @@ constexpr char kIsBackupRestoreManaged[] = "isBackupRestoreManaged";
constexpr char kIsLocationServiceEnabled[] = "isLocationServiceEnabled";
constexpr char kIsLocationServiceManaged[] = "isLocationServiceManaged";
// "onCanceled" is fired when user clicks "Cancel" button.
// The message should have the same fields as "onAgreed" above.
constexpr char kEventOnCanceled[] = "onCanceled";
// "onRetryClicked" is fired when a user clicks "RETRY" button on the error
// page.
constexpr char kEventOnRetryClicked[] = "onRetryClicked";
......@@ -627,7 +631,7 @@ void ArcSupportHost::OnMessage(const base::DictionaryValue& message) {
LOG_IF(ERROR, !auth_delegate_)
<< "auth_delegate_ is NULL, error: " << error_message;
auth_delegate_->OnAuthFailed(error_message);
} else if (event == kEventOnAgreed) {
} else if (event == kEventOnAgreed || event == kEventOnCanceled) {
DCHECK(tos_delegate_);
bool tos_shown;
std::string tos_content;
......@@ -651,6 +655,14 @@ void ArcSupportHost::OnMessage(const base::DictionaryValue& message) {
return;
}
bool accepted = event == kEventOnAgreed;
if (!accepted) {
// Cancel is equivalent to not granting consent to the individual
// features, so ensure we don't record consent.
is_backup_restore_enabled = false;
is_location_service_enabled = false;
}
SigninManagerBase* signin_manager =
SigninManagerFactory::GetForProfile(profile_);
DCHECK(signin_manager->IsAuthenticated());
......@@ -662,7 +674,8 @@ void ArcSupportHost::OnMessage(const base::DictionaryValue& message) {
account_id, consent_auditor::Feature::PLAY_STORE,
ComputePlayToSConsentIds(tos_content),
IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE,
consent_auditor::ConsentStatus::GIVEN);
accepted ? consent_auditor::ConsentStatus::GIVEN
: consent_auditor::ConsentStatus::NOT_GIVEN);
}
// If the user - not policy - controls Backup and Restore setting, record
......@@ -688,8 +701,11 @@ void ArcSupportHost::OnMessage(const base::DictionaryValue& message) {
: consent_auditor::ConsentStatus::NOT_GIVEN);
}
tos_delegate_->OnTermsAgreed(is_metrics_enabled, is_backup_restore_enabled,
is_location_service_enabled);
if (accepted) {
tos_delegate_->OnTermsAgreed(is_metrics_enabled,
is_backup_restore_enabled,
is_location_service_enabled);
}
} else if (event == kEventOnRetryClicked) {
// If ToS negotiation or manual authentication is ongoing, call the
// corresponding delegate. Otherwise, call the general retry function.
......
......@@ -88,6 +88,22 @@ void FakeArcSupport::ClickAgreeButton() {
SerializeAndSend(native_message_host_.get(), message);
}
void FakeArcSupport::ClickCancelButton() {
DCHECK_EQ(ui_page_, ArcSupportHost::UIPage::TERMS);
base::DictionaryValue message;
message.SetString("event", "onCanceled");
message.SetString("tosContent", tos_content_);
message.SetBoolean("tosShown", tos_shown_);
message.SetBoolean("isMetricsEnabled", metrics_mode_);
message.SetBoolean("isBackupRestoreEnabled", backup_and_restore_mode_);
message.SetBoolean("isBackupRestoreManaged", backup_and_restore_managed_);
message.SetBoolean("isLocationServiceEnabled", location_service_mode_);
message.SetBoolean("isLocationServiceManaged", location_service_managed_);
SerializeAndSend(native_message_host_.get(), message);
// The cancel button closes the window.
Close();
}
void FakeArcSupport::ClickAdAuthCancelButton() {
DCHECK_EQ(ui_page_, ArcSupportHost::UIPage::ACTIVE_DIRECTORY_AUTH);
// The cancel button closes the window.
......
......@@ -47,6 +47,9 @@ class FakeArcSupport : public extensions::NativeMessageHost::Client {
// Emulates clicking Agree button on the fake terms of service page.
void ClickAgreeButton();
// Emulates clicking Cancel button on the fake terms of service page.
void ClickCancelButton();
// Emulates clicking Cancel button on the fake Active Directory auth page.
void ClickAdAuthCancelButton();
......
......@@ -330,6 +330,11 @@ TEST_F(ArcTermsOfServiceDefaultNegotiatorTest, Cancel) {
EXPECT_EQ(status, Status::PENDING);
EXPECT_EQ(fake_arc_support()->ui_page(), ArcSupportHost::UIPage::TERMS);
// Emulate showing of a ToS page with a hard-coded ToS.
std::string tos_content = "fake ToS";
fake_arc_support()->set_tos_content(tos_content);
fake_arc_support()->set_tos_shown(true);
// Check the preference related checkbox.
fake_arc_support()->set_metrics_mode(true);
fake_arc_support()->set_backup_and_restore_mode(true);
......@@ -342,7 +347,7 @@ TEST_F(ArcTermsOfServiceDefaultNegotiatorTest, Cancel) {
profile()->GetPrefs()->GetBoolean(prefs::kArcLocationServiceEnabled));
// Clicking "CANCEL" button closes the window.
fake_arc_support()->Close();
fake_arc_support()->ClickCancelButton();
EXPECT_EQ(status, Status::CANCELLED);
// Make sure preference checkbox values are discarded.
......@@ -350,6 +355,30 @@ TEST_F(ArcTermsOfServiceDefaultNegotiatorTest, Cancel) {
profile()->GetPrefs()->GetBoolean(prefs::kArcBackupRestoreEnabled));
EXPECT_FALSE(
profile()->GetPrefs()->GetBoolean(prefs::kArcLocationServiceEnabled));
// Make sure consent auditing is recording all consents as NOT_GIVEN.
std::vector<int> tos_consent =
ArcSupportHost::ComputePlayToSConsentIds(tos_content);
tos_consent.push_back(IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE);
const std::vector<int> backup_consent = {IDS_ARC_OPT_IN_DIALOG_BACKUP_RESTORE,
IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE};
const std::vector<int> location_consent = {
IDS_ARC_OPT_IN_LOCATION_SETTING, IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE};
const std::vector<std::vector<int>> consent_ids = {
tos_consent, backup_consent, location_consent};
const std::vector<consent_auditor::Feature> features = {
consent_auditor::Feature::PLAY_STORE,
consent_auditor::Feature::BACKUP_AND_RESTORE,
consent_auditor::Feature::GOOGLE_LOCATION_SERVICE};
const std::vector<consent_auditor::ConsentStatus> statuses = {
consent_auditor::ConsentStatus::NOT_GIVEN,
consent_auditor::ConsentStatus::NOT_GIVEN,
consent_auditor::ConsentStatus::NOT_GIVEN};
EXPECT_EQ(consent_auditor()->account_id(), GetAuthenticatedAccountId());
EXPECT_EQ(consent_auditor()->recorded_id_vectors(), consent_ids);
EXPECT_EQ(consent_auditor()->recorded_features(), features);
EXPECT_EQ(consent_auditor()->recorded_statuses(), statuses);
}
TEST_F(ArcTermsOfServiceDefaultNegotiatorTest, Retry) {
......
......@@ -479,6 +479,19 @@ class TermsOfServicePage {
return undefined;
}
/** Returns user choices and page configuration for processing. */
getPageResults_() {
return {
tosContent: this.tosContent_,
tosShown: this.tosShown_,
isMetricsEnabled: this.metricsCheckbox_.isChecked(),
isBackupRestoreEnabled: this.backupRestoreCheckbox_.isChecked(),
isBackupRestoreManaged: this.backupRestoreCheckbox_.isManaged(),
isLocationServiceEnabled: this.locationServiceCheckbox_.isChecked(),
isLocationServiceManaged: this.locationServiceCheckbox_.isManaged()
};
}
/** Called when the terms-view starts to be loaded. */
onTermsViewLoadStarted_() {
// Note: Reloading can be triggered by user action. E.g., user may select
......@@ -555,19 +568,12 @@ class TermsOfServicePage {
/** Called when "AGREE" button is clicked. */
onAgree() {
sendNativeMessage('onAgreed', {
tosContent: this.tosContent_,
tosShown: this.tosShown_,
isMetricsEnabled: this.metricsCheckbox_.isChecked(),
isBackupRestoreEnabled: this.backupRestoreCheckbox_.isChecked(),
isBackupRestoreManaged: this.backupRestoreCheckbox_.isManaged(),
isLocationServiceEnabled: this.locationServiceCheckbox_.isChecked(),
isLocationServiceManaged: this.locationServiceCheckbox_.isManaged()
});
sendNativeMessage('onAgreed', this.getPageResults_());
}
/** Called when "CANCEL" button is clicked. */
onCancel_() {
sendNativeMessage('onCanceled', this.getPageResults_());
closeWindow();
}
......
......@@ -336,7 +336,7 @@ login.createScreen('ArcTermsOfServiceScreen', 'arc-tos', function() {
onSkip: function() {
this.enableButtons_(false);
chrome.send('arcTermsOfServiceSkip');
chrome.send('arcTermsOfServiceSkip', [this.tosContent_]);
},
/**
......
......@@ -251,57 +251,80 @@ bool ArcTermsOfServiceScreenHandler::NeedDispatchEventOnAction() {
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);
void ArcTermsOfServiceScreenHandler::RecordConsents(
const std::string& tos_content,
bool record_tos_consent,
bool tos_accepted,
bool record_backup_consent,
bool backup_accepted,
bool record_location_consent,
bool location_accepted) {
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();
const 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 (record_tos_consent) {
consent_auditor->RecordGaiaConsent(
account_id, consent_auditor::Feature::PLAY_STORE,
ArcSupportHost::ComputePlayToSConsentIds(tos_content),
IDS_ARC_OOBE_TERMS_BUTTON_ACCEPT,
tos_accepted ? consent_auditor::ConsentStatus::GIVEN
: consent_auditor::ConsentStatus::NOT_GIVEN);
}
// If the user - not policy - controls Backup and Restore setting, record
// whether consent was given.
if (!backup_restore_managed_) {
if (record_backup_consent) {
consent_auditor->RecordGaiaConsent(
account_id, consent_auditor::Feature::BACKUP_AND_RESTORE,
{IDS_ARC_OPT_IN_DIALOG_BACKUP_RESTORE},
IDS_ARC_OOBE_TERMS_BUTTON_ACCEPT,
enable_backup_restore ? consent_auditor::ConsentStatus::GIVEN
: consent_auditor::ConsentStatus::NOT_GIVEN);
backup_accepted ? consent_auditor::ConsentStatus::GIVEN
: consent_auditor::ConsentStatus::NOT_GIVEN);
}
// If the user - not policy - controls Location Services setting, record
// whether onsent was given.
if (!location_services_managed_) {
if (record_location_consent) {
consent_auditor->RecordGaiaConsent(
account_id, consent_auditor::Feature::GOOGLE_LOCATION_SERVICE,
{IDS_ARC_OPT_IN_LOCATION_SETTING}, IDS_ARC_OOBE_TERMS_BUTTON_ACCEPT,
enable_location_services ? consent_auditor::ConsentStatus::GIVEN
: consent_auditor::ConsentStatus::NOT_GIVEN);
location_accepted ? consent_auditor::ConsentStatus::GIVEN
: consent_auditor::ConsentStatus::NOT_GIVEN);
}
}
void ArcTermsOfServiceScreenHandler::HandleSkip(
const std::string& tos_content) {
if (!NeedDispatchEventOnAction())
return;
// Record consents as not accepted for consents that are under user control
// when the user skips ARC setup.
RecordConsents(tos_content,
/*record_tos_content=*/true, /*tos_accepted=*/false,
!backup_restore_managed_, /*backup_accepted=*/false,
!location_services_managed_, /*location_accepted=*/false);
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);
// Record consents as accepted or not accepted as appropriate for consents
// that are under user control when the user completes ARC setup.
RecordConsents(tos_content,
/*record_tos_content=*/true, /*tos_accepted=*/true,
!backup_restore_managed_, enable_backup_restore,
!location_services_managed_, enable_location_services);
for (auto& observer : observer_list_)
observer.OnAccept();
......
......@@ -66,7 +66,7 @@ class ArcTermsOfServiceScreenHandler
void Initialize() override;
void DoShow();
void HandleSkip();
void HandleSkip(const std::string& tos_content);
void HandleAccept(bool enable_backup_restore,
bool enable_location_services,
const std::string& tos_content);
......@@ -76,6 +76,16 @@ class ArcTermsOfServiceScreenHandler
void StartNetworkAndTimeZoneObserving();
// Handles the recording of consent given or not given after the user chooses
// to skip or accept.
void RecordConsents(const std::string& tos_content,
bool record_tos_content,
bool tos_accepted,
bool record_backup_consent,
bool backup_accepted,
bool record_location_consent,
bool location_accepted);
// Sends if Arc enable status is manged to screen.
void SendArcManagedStatus(Profile* profile);
......
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