Commit c86e2ec5 authored by Markus Heintz's avatar Markus Heintz Committed by Commit Bot

Migrate ARC user consent recording to the new Consent Auditor API

TBR=alemate@chromium.org

Bug: 865902
Change-Id: I4ea0613be8db3bb2120d1be9c5137ca81ecd54f4
Reviewed-on: https://chromium-review.googlesource.com/1145318
Commit-Queue: Markus Heintz <markusheintz@chromium.org>
Reviewed-by: default avatarJosh Horwich <jhorwich@chromium.org>
Reviewed-by: default avatarYusuke Sato <yusukes@chromium.org>
Reviewed-by: default avatarTim Schumann <tschumann@chromium.org>
Reviewed-by: default avatarvitaliii <vitaliii@chromium.org>
Cr-Commit-Position: refs/heads/master@{#580111}
parent 6791818d
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
#include "components/sync_preferences/pref_service_syncable.h" #include "components/sync_preferences/pref_service_syncable.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
using sync_pb::UserConsentTypes;
namespace arc { namespace arc {
ArcPlayStoreEnabledPreferenceHandler::ArcPlayStoreEnabledPreferenceHandler( ArcPlayStoreEnabledPreferenceHandler::ArcPlayStoreEnabledPreferenceHandler(
...@@ -125,11 +127,17 @@ void ArcPlayStoreEnabledPreferenceHandler::OnPreferenceChanged() { ...@@ -125,11 +127,17 @@ void ArcPlayStoreEnabledPreferenceHandler::OnPreferenceChanged() {
if (signin_manager->IsAuthenticated()) { if (signin_manager->IsAuthenticated()) {
const std::string account_id = const std::string account_id =
signin_manager->GetAuthenticatedAccountId(); signin_manager->GetAuthenticatedAccountId();
ConsentAuditorFactory::GetForProfile(profile_)->RecordGaiaConsent(
account_id, consent_auditor::Feature::PLAY_STORE, UserConsentTypes::ArcPlayTermsOfServiceConsent play_consent;
{IDS_SETTINGS_ANDROID_APPS_DISABLE_DIALOG_MESSAGE}, play_consent.set_status(UserConsentTypes::NOT_GIVEN);
IDS_SETTINGS_ANDROID_APPS_DISABLE_DIALOG_REMOVE, play_consent.set_confirmation_grd_id(
consent_auditor::ConsentStatus::NOT_GIVEN); IDS_SETTINGS_ANDROID_APPS_DISABLE_DIALOG_REMOVE);
play_consent.add_description_grd_ids(
IDS_SETTINGS_ANDROID_APPS_DISABLE_DIALOG_MESSAGE);
play_consent.set_consent_flow(
UserConsentTypes::ArcPlayTermsOfServiceConsent::SETTING_CHANGE);
ConsentAuditorFactory::GetForProfile(profile_)->RecordArcPlayConsent(
account_id, play_consent);
} }
} }
} }
......
...@@ -31,8 +31,14 @@ ...@@ -31,8 +31,14 @@
#include "components/user_manager/scoped_user_manager.h" #include "components/user_manager/scoped_user_manager.h"
#include "content/public/test/test_browser_thread_bundle.h" #include "content/public/test/test_browser_thread_bundle.h"
#include "services/identity/public/cpp/identity_manager.h" #include "services/identity/public/cpp/identity_manager.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
using ArcPlayTermsOfServiceConsent =
sync_pb::UserConsentTypes::ArcPlayTermsOfServiceConsent;
using sync_pb::UserConsentTypes;
using testing::_;
namespace arc { namespace arc {
namespace { namespace {
...@@ -168,6 +174,20 @@ TEST_F(ArcPlayStoreEnabledPreferenceHandlerTest, RemoveDataDir_Managed) { ...@@ -168,6 +174,20 @@ TEST_F(ArcPlayStoreEnabledPreferenceHandlerTest, RemoveDataDir_Managed) {
} }
TEST_F(ArcPlayStoreEnabledPreferenceHandlerTest, PrefChangeRevokesConsent) { TEST_F(ArcPlayStoreEnabledPreferenceHandlerTest, PrefChangeRevokesConsent) {
consent_auditor::FakeConsentAuditor* auditor = consent_auditor();
ArcPlayTermsOfServiceConsent play_consent;
play_consent.set_status(UserConsentTypes::NOT_GIVEN);
play_consent.set_confirmation_grd_id(
IDS_SETTINGS_ANDROID_APPS_DISABLE_DIALOG_REMOVE);
play_consent.add_description_grd_ids(
IDS_SETTINGS_ANDROID_APPS_DISABLE_DIALOG_MESSAGE);
play_consent.set_consent_flow(
UserConsentTypes::ArcPlayTermsOfServiceConsent::SETTING_CHANGE);
EXPECT_CALL(*auditor, RecordArcPlayConsent(
GetAuthenticatedAccountId(),
consent_auditor::ArcPlayConsentEq(play_consent)));
ASSERT_FALSE(IsArcPlayStoreEnabledForProfile(profile())); ASSERT_FALSE(IsArcPlayStoreEnabledForProfile(profile()));
arc_session_manager()->SetProfile(profile()); arc_session_manager()->SetProfile(profile());
arc_session_manager()->Initialize(); arc_session_manager()->Initialize();
...@@ -179,23 +199,6 @@ TEST_F(ArcPlayStoreEnabledPreferenceHandlerTest, PrefChangeRevokesConsent) { ...@@ -179,23 +199,6 @@ TEST_F(ArcPlayStoreEnabledPreferenceHandlerTest, PrefChangeRevokesConsent) {
arc_session_manager()->state()); arc_session_manager()->state());
SetArcPlayStoreEnabledForProfile(profile(), false); SetArcPlayStoreEnabledForProfile(profile(), false);
// Make sure consent auditing is recording the expected revocation of consent.
const std::vector<int> tos_consent = {
IDS_SETTINGS_ANDROID_APPS_DISABLE_DIALOG_MESSAGE};
const std::vector<std::vector<int>> description_ids = {tos_consent};
const std::vector<int> confirmation_ids = {
IDS_SETTINGS_ANDROID_APPS_DISABLE_DIALOG_REMOVE};
const std::vector<consent_auditor::Feature> features = {
consent_auditor::Feature::PLAY_STORE};
const std::vector<consent_auditor::ConsentStatus> statuses = {
consent_auditor::ConsentStatus::NOT_GIVEN};
EXPECT_EQ(consent_auditor()->account_id(), GetAuthenticatedAccountId());
EXPECT_EQ(consent_auditor()->recorded_confirmation_ids(), confirmation_ids);
EXPECT_EQ(consent_auditor()->recorded_id_vectors(), description_ids);
EXPECT_EQ(consent_auditor()->recorded_features(), features);
EXPECT_EQ(consent_auditor()->recorded_statuses(), statuses);
} }
} // namespace } // namespace
......
...@@ -36,6 +36,8 @@ ...@@ -36,6 +36,8 @@
#include "ui/chromeos/devicetype_utils.h" #include "ui/chromeos/devicetype_utils.h"
#include "ui/display/screen.h" #include "ui/display/screen.h"
using sync_pb::UserConsentTypes;
namespace { namespace {
constexpr char kAction[] = "action"; constexpr char kAction[] = "action";
constexpr char kArcManaged[] = "arcManaged"; constexpr char kArcManaged[] = "arcManaged";
...@@ -178,28 +180,6 @@ std::ostream& operator<<(std::ostream& os, ArcSupportHost::Error error) { ...@@ -178,28 +180,6 @@ std::ostream& operator<<(std::ostream& os, ArcSupportHost::Error error) {
} // namespace } // namespace
// static
std::vector<int> ArcSupportHost::ComputePlayToSConsentIds(
const std::string& content) {
std::vector<int> result;
// Record the content length and the SHA1 hash of the content, rather than
// wastefully copying the entire content which is dynamically loaded from
// Play, rather than included in the Chrome build itself.
result.push_back(static_cast<int>(content.length()));
uint8_t hash[base::kSHA1Length];
base::SHA1HashBytes(reinterpret_cast<const uint8_t*>(content.c_str()),
content.size(), hash);
for (size_t i = 0; i < base::kSHA1Length; i += 4) {
uint32_t acc =
hash[i] << 24 | hash[i + 1] << 16 | hash[i + 2] << 8 | hash[i + 3];
result.push_back(static_cast<int>(acc));
}
return result;
}
ArcSupportHost::ArcSupportHost(Profile* profile) ArcSupportHost::ArcSupportHost(Profile* profile)
: profile_(profile), : profile_(profile),
request_open_app_callback_(base::Bind(&RequestOpenApp)) { request_open_app_callback_(base::Bind(&RequestOpenApp)) {
...@@ -670,38 +650,53 @@ void ArcSupportHost::OnMessage(const base::DictionaryValue& message) { ...@@ -670,38 +650,53 @@ void ArcSupportHost::OnMessage(const base::DictionaryValue& message) {
// Record acceptance of ToS if it was shown to the user, otherwise simply // Record acceptance of ToS if it was shown to the user, otherwise simply
// record acceptance of an empty ToS. // record acceptance of an empty ToS.
// TODO(jhorwich): Replace this approach when passing |is_managed| boolean UserConsentTypes::ArcPlayTermsOfServiceConsent play_consent;
// is supported by the underlying consent protos. play_consent.set_status(accepted ? UserConsentTypes::GIVEN
if (!tos_shown) : UserConsentTypes::NOT_GIVEN);
tos_content.clear(); play_consent.set_confirmation_grd_id(IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE);
ConsentAuditorFactory::GetForProfile(profile_)->RecordGaiaConsent( play_consent.set_consent_flow(
account_id, consent_auditor::Feature::PLAY_STORE, UserConsentTypes::ArcPlayTermsOfServiceConsent::SETUP);
ComputePlayToSConsentIds(tos_content), if (tos_shown) {
IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE, play_consent.set_play_terms_of_service_text_length(tos_content.length());
accepted ? consent_auditor::ConsentStatus::GIVEN play_consent.set_play_terms_of_service_hash(
: consent_auditor::ConsentStatus::NOT_GIVEN); base::SHA1HashString(tos_content));
}
ConsentAuditorFactory::GetForProfile(profile_)->RecordArcPlayConsent(
account_id, play_consent);
// If the user - not policy - controls Backup and Restore setting, record // If the user - not policy - controls Backup and Restore setting, record
// whether consent was given. // whether consent was given.
if (!is_backup_restore_managed) { if (!is_backup_restore_managed) {
ConsentAuditorFactory::GetForProfile(profile_)->RecordGaiaConsent( UserConsentTypes::ArcBackupAndRestoreConsent backup_and_restore_consent;
account_id, consent_auditor::Feature::BACKUP_AND_RESTORE, backup_and_restore_consent.set_confirmation_grd_id(
{IDS_ARC_OPT_IN_DIALOG_BACKUP_RESTORE}, IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE);
IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE, backup_and_restore_consent.add_description_grd_ids(
is_backup_restore_enabled IDS_ARC_OPT_IN_DIALOG_BACKUP_RESTORE);
? consent_auditor::ConsentStatus::GIVEN backup_and_restore_consent.set_status(is_backup_restore_enabled
: consent_auditor::ConsentStatus::NOT_GIVEN); ? UserConsentTypes::GIVEN
: UserConsentTypes::NOT_GIVEN);
ConsentAuditorFactory::GetForProfile(profile_)
->RecordArcBackupAndRestoreConsent(account_id,
backup_and_restore_consent);
} }
// If the user - not policy - controls Location Services setting, record // If the user - not policy - controls Location Services setting, record
// whether consent was given. // whether consent was given.
if (!is_location_service_managed) { if (!is_location_service_managed) {
ConsentAuditorFactory::GetForProfile(profile_)->RecordGaiaConsent( UserConsentTypes::ArcGoogleLocationServiceConsent
account_id, consent_auditor::Feature::GOOGLE_LOCATION_SERVICE, location_service_consent;
{IDS_ARC_OPT_IN_LOCATION_SETTING}, IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE, location_service_consent.set_confirmation_grd_id(
is_location_service_enabled IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE);
? consent_auditor::ConsentStatus::GIVEN location_service_consent.add_description_grd_ids(
: consent_auditor::ConsentStatus::NOT_GIVEN); IDS_ARC_OPT_IN_LOCATION_SETTING);
location_service_consent.set_status(is_location_service_enabled
? UserConsentTypes::GIVEN
: UserConsentTypes::NOT_GIVEN);
ConsentAuditorFactory::GetForProfile(profile_)
->RecordArcGoogleLocationServiceConsent(account_id,
location_service_consent);
} }
if (accepted) { if (accepted) {
......
...@@ -170,12 +170,6 @@ class ArcSupportHost : public arc::ArcSupportMessageHost::Observer, ...@@ -170,12 +170,6 @@ class ArcSupportHost : public arc::ArcSupportMessageHost::Observer,
void SetRequestOpenAppCallbackForTesting( void SetRequestOpenAppCallbackForTesting(
const RequestOpenAppCallback& callback); const RequestOpenAppCallback& callback);
// Computes consent IDs based on the content of the Play ToS. Useful as the
// Play ToS is not contained within the Chrome binary, but rather fetched
// live.
// Returns a vector of consent "IDs" based on the Play ToS content.
static std::vector<int> ComputePlayToSConsentIds(const std::string& content);
private: private:
struct PreferenceCheckboxData { struct PreferenceCheckboxData {
PreferenceCheckboxData() : PreferenceCheckboxData(false, false) {} PreferenceCheckboxData() : PreferenceCheckboxData(false, false) {}
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <vector> #include <vector>
#include "base/sha1.h"
#include "chrome/browser/chromeos/arc/extensions/fake_arc_support.h" #include "chrome/browser/chromeos/arc/extensions/fake_arc_support.h"
#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" #include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h"
#include "chrome/browser/consent_auditor/consent_auditor_factory.h" #include "chrome/browser/consent_auditor/consent_auditor_factory.h"
...@@ -183,6 +184,11 @@ TEST_F(ArcSupportHostTest, AuthRetryOnError) { ...@@ -183,6 +184,11 @@ TEST_F(ArcSupportHostTest, AuthRetryOnError) {
} }
TEST_F(ArcSupportHostTest, TermsOfServiceAccept) { TEST_F(ArcSupportHostTest, TermsOfServiceAccept) {
consent_auditor::FakeConsentAuditor* ca = consent_auditor();
EXPECT_CALL(*ca, RecordArcPlayConsent(_, _));
EXPECT_CALL(*ca, RecordArcBackupAndRestoreConsent(_, _));
EXPECT_CALL(*ca, RecordArcGoogleLocationServiceConsent(_, _));
MockTermsOfServiceDelegate tos_delegate; MockTermsOfServiceDelegate tos_delegate;
support_host()->SetTermsOfServiceDelegate(&tos_delegate); support_host()->SetTermsOfServiceDelegate(&tos_delegate);
...@@ -270,19 +276,4 @@ TEST_F(ArcSupportHostTest, SendFeedbackOnError) { ...@@ -270,19 +276,4 @@ TEST_F(ArcSupportHostTest, SendFeedbackOnError) {
fake_arc_support()->ClickSendFeedbackButton(); fake_arc_support()->ClickSendFeedbackButton();
} }
TEST_F(ArcSupportHostTest, CalculateToSHashInRightOrder) {
std::vector<int> output = ArcSupportHost::ComputePlayToSConsentIds(
"The quick brown fox jumps over the lazy dog");
// Expect length and 5 ints for the hash.
EXPECT_EQ(6, static_cast<int>(output.size()));
// Check string length.
EXPECT_EQ(43, output[0]);
// Verify the hash: 2fd4e1c6 7a2d28fc ed849ee1 bb76e739 1b93eb12.
EXPECT_EQ(static_cast<int>(0x2fd4e1c6), output[1]);
EXPECT_EQ(static_cast<int>(0x7a2d28fc), output[2]);
EXPECT_EQ(static_cast<int>(0xed849ee1), output[3]);
EXPECT_EQ(static_cast<int>(0xbb76e739), output[4]);
EXPECT_EQ(static_cast<int>(0x1b93eb12), output[5]);
}
} // namespace } // namespace
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/run_loop.h" #include "base/run_loop.h"
#include "base/sha1.h"
#include "base/values.h" #include "base/values.h"
#include "chrome/browser/chromeos/arc/arc_support_host.h" #include "chrome/browser/chromeos/arc/arc_support_host.h"
#include "chrome/browser/chromeos/arc/extensions/fake_arc_support.h" #include "chrome/browser/chromeos/arc/extensions/fake_arc_support.h"
...@@ -29,8 +30,25 @@ ...@@ -29,8 +30,25 @@
#include "components/user_manager/scoped_user_manager.h" #include "components/user_manager/scoped_user_manager.h"
#include "content/public/test/test_browser_thread_bundle.h" #include "content/public/test/test_browser_thread_bundle.h"
#include "services/identity/public/cpp/identity_manager.h" #include "services/identity/public/cpp/identity_manager.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
using ::testing::Matches;
using ::testing::Mock;
using ::testing::_;
using consent_auditor::ArcBackupAndRestoreConsentEq;
using consent_auditor::ArcGoogleLocationServiceConsentEq;
using consent_auditor::ArcPlayConsentEq;
using ArcBackupAndRestoreConsent =
sync_pb::UserConsentTypes::ArcBackupAndRestoreConsent;
using ArcGoogleLocationServiceConsent =
sync_pb::UserConsentTypes::ArcGoogleLocationServiceConsent;
using ArcPlayTermsOfServiceConsent =
sync_pb::UserConsentTypes::ArcPlayTermsOfServiceConsent;
using sync_pb::UserConsentTypes;
namespace arc { namespace arc {
class ArcTermsOfServiceDefaultNegotiatorTest class ArcTermsOfServiceDefaultNegotiatorTest
...@@ -93,6 +111,37 @@ class ArcTermsOfServiceDefaultNegotiatorTest ...@@ -93,6 +111,37 @@ class ArcTermsOfServiceDefaultNegotiatorTest
namespace { namespace {
const char kFakeToSContent[] = "fake ToS content";
ArcBackupAndRestoreConsent CreateBaseBackupAndRestoreConsent() {
ArcBackupAndRestoreConsent backup_and_restore_consent;
backup_and_restore_consent.set_confirmation_grd_id(
IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE);
backup_and_restore_consent.add_description_grd_ids(
IDS_ARC_OPT_IN_DIALOG_BACKUP_RESTORE);
return backup_and_restore_consent;
}
ArcGoogleLocationServiceConsent CreateBaseGoogleLocationServiceConsent() {
ArcGoogleLocationServiceConsent google_location_service_consent;
google_location_service_consent.set_confirmation_grd_id(
IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE);
google_location_service_consent.add_description_grd_ids(
IDS_ARC_OPT_IN_LOCATION_SETTING);
return google_location_service_consent;
}
ArcPlayTermsOfServiceConsent CreateBasePlayConsent() {
ArcPlayTermsOfServiceConsent play_consent;
play_consent.set_play_terms_of_service_hash(
base::SHA1HashString(std::string(kFakeToSContent)));
play_consent.set_play_terms_of_service_text_length(
(std::string(kFakeToSContent).length()));
play_consent.set_consent_flow(ArcPlayTermsOfServiceConsent::SETUP);
play_consent.set_confirmation_grd_id(IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE);
return play_consent;
}
enum class Status { enum class Status {
PENDING, PENDING,
ACCEPTED, ACCEPTED,
...@@ -123,9 +172,32 @@ ArcTermsOfServiceNegotiator::NegotiationCallback UpdateStatusCallback( ...@@ -123,9 +172,32 @@ ArcTermsOfServiceNegotiator::NegotiationCallback UpdateStatusCallback(
status); status);
} }
} // namespace
TEST_F(ArcTermsOfServiceDefaultNegotiatorTest, Accept) { TEST_F(ArcTermsOfServiceDefaultNegotiatorTest, Accept) {
// Configure mock expections for proper consent recording.
consent_auditor::FakeConsentAuditor* auditor = consent_auditor();
Mock::VerifyAndClearExpectations(auditor);
ArcPlayTermsOfServiceConsent play_consent = CreateBasePlayConsent();
play_consent.set_status(UserConsentTypes::GIVEN);
EXPECT_CALL(*auditor, RecordArcPlayConsent(GetAuthenticatedAccountId(),
ArcPlayConsentEq(play_consent)));
ArcBackupAndRestoreConsent backup_and_restore_consent =
CreateBaseBackupAndRestoreConsent();
backup_and_restore_consent.set_status(UserConsentTypes::GIVEN);
EXPECT_CALL(*auditor,
RecordArcBackupAndRestoreConsent(
GetAuthenticatedAccountId(),
ArcBackupAndRestoreConsentEq(backup_and_restore_consent)));
ArcGoogleLocationServiceConsent google_location_service_consent =
CreateBaseGoogleLocationServiceConsent();
google_location_service_consent.set_status(UserConsentTypes::GIVEN);
EXPECT_CALL(
*auditor,
RecordArcGoogleLocationServiceConsent(
GetAuthenticatedAccountId(),
ArcGoogleLocationServiceConsentEq(google_location_service_consent)));
// Show Terms of service page. // Show Terms of service page.
Status status = Status::PENDING; Status status = Status::PENDING;
negotiator()->StartNegotiation(UpdateStatusCallback(&status)); negotiator()->StartNegotiation(UpdateStatusCallback(&status));
...@@ -135,8 +207,7 @@ TEST_F(ArcTermsOfServiceDefaultNegotiatorTest, Accept) { ...@@ -135,8 +207,7 @@ TEST_F(ArcTermsOfServiceDefaultNegotiatorTest, Accept) {
EXPECT_EQ(fake_arc_support()->ui_page(), ArcSupportHost::UIPage::TERMS); EXPECT_EQ(fake_arc_support()->ui_page(), ArcSupportHost::UIPage::TERMS);
// Emulate showing of a ToS page with a hard-coded ToS. // Emulate showing of a ToS page with a hard-coded ToS.
std::string tos_content = "fake ToS"; fake_arc_support()->set_tos_content(kFakeToSContent);
fake_arc_support()->set_tos_content(tos_content);
fake_arc_support()->set_tos_shown(true); fake_arc_support()->set_tos_shown(true);
// By default, the preference related checkboxes are checked, despite that // By default, the preference related checkboxes are checked, despite that
...@@ -182,35 +253,38 @@ TEST_F(ArcTermsOfServiceDefaultNegotiatorTest, Accept) { ...@@ -182,35 +253,38 @@ TEST_F(ArcTermsOfServiceDefaultNegotiatorTest, Accept) {
profile()->GetPrefs()->GetBoolean(prefs::kArcBackupRestoreEnabled)); profile()->GetPrefs()->GetBoolean(prefs::kArcBackupRestoreEnabled));
EXPECT_TRUE( EXPECT_TRUE(
profile()->GetPrefs()->GetBoolean(prefs::kArcLocationServiceEnabled)); profile()->GetPrefs()->GetBoolean(prefs::kArcLocationServiceEnabled));
// Make sure consent auditing records expected consents.
std::vector<int> tos_consent =
ArcSupportHost::ComputePlayToSConsentIds(tos_content);
const std::vector<int> backup_consent = {
IDS_ARC_OPT_IN_DIALOG_BACKUP_RESTORE};
const std::vector<int> location_consent = {IDS_ARC_OPT_IN_LOCATION_SETTING};
const std::vector<std::vector<int>> consent_ids = {
tos_consent, backup_consent, location_consent};
const std::vector<int> confirmation_ids = {
IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE, IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE,
IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE};
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::GIVEN,
consent_auditor::ConsentStatus::GIVEN,
consent_auditor::ConsentStatus::GIVEN};
EXPECT_EQ(consent_auditor()->account_id(), GetAuthenticatedAccountId());
EXPECT_EQ(consent_auditor()->recorded_id_vectors(), consent_ids);
EXPECT_EQ(consent_auditor()->recorded_confirmation_ids(), confirmation_ids);
EXPECT_EQ(consent_auditor()->recorded_features(), features);
EXPECT_EQ(consent_auditor()->recorded_statuses(), statuses);
} }
TEST_F(ArcTermsOfServiceDefaultNegotiatorTest, AcceptWithUnchecked) { TEST_F(ArcTermsOfServiceDefaultNegotiatorTest, AcceptWithUnchecked) {
// Configure the mock consent auditor to make sure consent auditing records
// the ToS accept as GIVEN, but the other consents as NOT_GIVEN.
consent_auditor::FakeConsentAuditor* ca = consent_auditor();
Mock::VerifyAndClearExpectations(ca);
ArcPlayTermsOfServiceConsent play_consent = CreateBasePlayConsent();
play_consent.set_status(UserConsentTypes::GIVEN);
EXPECT_CALL(*ca, RecordArcPlayConsent(GetAuthenticatedAccountId(),
ArcPlayConsentEq(play_consent)));
ArcBackupAndRestoreConsent backup_and_restore_consent =
CreateBaseBackupAndRestoreConsent();
backup_and_restore_consent.clear_status();
backup_and_restore_consent.set_status(UserConsentTypes::NOT_GIVEN);
EXPECT_CALL(*ca,
RecordArcBackupAndRestoreConsent(
GetAuthenticatedAccountId(),
ArcBackupAndRestoreConsentEq(backup_and_restore_consent)));
ArcGoogleLocationServiceConsent google_location_service_consent =
CreateBaseGoogleLocationServiceConsent();
google_location_service_consent.clear_status();
google_location_service_consent.set_status(UserConsentTypes::NOT_GIVEN);
EXPECT_CALL(
*ca,
RecordArcGoogleLocationServiceConsent(
GetAuthenticatedAccountId(),
ArcGoogleLocationServiceConsentEq(google_location_service_consent)));
// Show Terms of service page. // Show Terms of service page.
Status status = Status::PENDING; Status status = Status::PENDING;
negotiator()->StartNegotiation(UpdateStatusCallback(&status)); negotiator()->StartNegotiation(UpdateStatusCallback(&status));
...@@ -220,8 +294,7 @@ TEST_F(ArcTermsOfServiceDefaultNegotiatorTest, AcceptWithUnchecked) { ...@@ -220,8 +294,7 @@ TEST_F(ArcTermsOfServiceDefaultNegotiatorTest, AcceptWithUnchecked) {
EXPECT_EQ(fake_arc_support()->ui_page(), ArcSupportHost::UIPage::TERMS); EXPECT_EQ(fake_arc_support()->ui_page(), ArcSupportHost::UIPage::TERMS);
// Emulate showing of a ToS page with a hard-coded ID. // Emulate showing of a ToS page with a hard-coded ID.
const std::string tos_content = "fake ToS content"; fake_arc_support()->set_tos_content(kFakeToSContent);
fake_arc_support()->set_tos_content(tos_content);
fake_arc_support()->set_tos_shown(true); fake_arc_support()->set_tos_shown(true);
// Override the preferences from the default values to true. // Override the preferences from the default values to true.
...@@ -248,36 +321,28 @@ TEST_F(ArcTermsOfServiceDefaultNegotiatorTest, AcceptWithUnchecked) { ...@@ -248,36 +321,28 @@ TEST_F(ArcTermsOfServiceDefaultNegotiatorTest, AcceptWithUnchecked) {
profile()->GetPrefs()->GetBoolean(prefs::kArcBackupRestoreEnabled)); profile()->GetPrefs()->GetBoolean(prefs::kArcBackupRestoreEnabled));
EXPECT_FALSE( EXPECT_FALSE(
profile()->GetPrefs()->GetBoolean(prefs::kArcLocationServiceEnabled)); profile()->GetPrefs()->GetBoolean(prefs::kArcLocationServiceEnabled));
// Make sure consent auditing records the ToS accept as GIVEN, but the other
// consents as NOT_GIVEN.
std::vector<int> tos_consent =
ArcSupportHost::ComputePlayToSConsentIds(tos_content);
const std::vector<int> backup_consent = {
IDS_ARC_OPT_IN_DIALOG_BACKUP_RESTORE};
const std::vector<int> location_consent = {IDS_ARC_OPT_IN_LOCATION_SETTING};
const std::vector<std::vector<int>> consent_ids = {
tos_consent, backup_consent, location_consent};
const std::vector<int> confirmation_ids = {
IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE, IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE,
IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE};
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::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_confirmation_ids(), confirmation_ids);
EXPECT_EQ(consent_auditor()->recorded_features(), features);
EXPECT_EQ(consent_auditor()->recorded_statuses(), statuses);
} }
TEST_F(ArcTermsOfServiceDefaultNegotiatorTest, AcceptWithManagedToS) { TEST_F(ArcTermsOfServiceDefaultNegotiatorTest, AcceptWithManagedToS) {
consent_auditor::FakeConsentAuditor* auditor = consent_auditor();
Mock::VerifyAndClearExpectations(auditor);
ArcPlayTermsOfServiceConsent play_consent = CreateBasePlayConsent();
play_consent.clear_play_terms_of_service_text_length();
play_consent.clear_play_terms_of_service_hash();
play_consent.set_status(UserConsentTypes::GIVEN);
EXPECT_CALL(*auditor, RecordArcPlayConsent(GetAuthenticatedAccountId(),
ArcPlayConsentEq(play_consent)));
ArcGoogleLocationServiceConsent google_location_service_consent =
CreateBaseGoogleLocationServiceConsent();
google_location_service_consent.set_status(UserConsentTypes::GIVEN);
EXPECT_CALL(
*auditor,
RecordArcGoogleLocationServiceConsent(
GetAuthenticatedAccountId(),
ArcGoogleLocationServiceConsentEq(google_location_service_consent)));
// Verifies that we record an empty ToS consent if the ToS is not shown due to // Verifies that we record an empty ToS consent if the ToS is not shown due to
// a managed user scenario. // a managed user scenario.
// Also verifies that a managed setting for Backup and Restore is not recorded // Also verifies that a managed setting for Backup and Restore is not recorded
...@@ -291,7 +356,7 @@ TEST_F(ArcTermsOfServiceDefaultNegotiatorTest, AcceptWithManagedToS) { ...@@ -291,7 +356,7 @@ TEST_F(ArcTermsOfServiceDefaultNegotiatorTest, AcceptWithManagedToS) {
EXPECT_EQ(fake_arc_support()->ui_page(), ArcSupportHost::UIPage::TERMS); EXPECT_EQ(fake_arc_support()->ui_page(), ArcSupportHost::UIPage::TERMS);
// Emulate ToS not shown, and Backup and Restore as a managed setting. // Emulate ToS not shown, and Backup and Restore as a managed setting.
fake_arc_support()->set_tos_content("no ToS shown"); fake_arc_support()->set_tos_content(kFakeToSContent);
fake_arc_support()->set_tos_shown(false); fake_arc_support()->set_tos_shown(false);
fake_arc_support()->set_backup_and_restore_managed(true); fake_arc_support()->set_backup_and_restore_managed(true);
...@@ -309,30 +374,34 @@ TEST_F(ArcTermsOfServiceDefaultNegotiatorTest, AcceptWithManagedToS) { ...@@ -309,30 +374,34 @@ TEST_F(ArcTermsOfServiceDefaultNegotiatorTest, AcceptWithManagedToS) {
profile()->GetPrefs()->GetBoolean(prefs::kArcBackupRestoreEnabled)); profile()->GetPrefs()->GetBoolean(prefs::kArcBackupRestoreEnabled));
EXPECT_TRUE( EXPECT_TRUE(
profile()->GetPrefs()->GetBoolean(prefs::kArcLocationServiceEnabled)); profile()->GetPrefs()->GetBoolean(prefs::kArcLocationServiceEnabled));
// Make sure consent auditing records expected consents.
std::vector<int> tos_consent = ArcSupportHost::ComputePlayToSConsentIds("");
const std::vector<int> location_consent = {IDS_ARC_OPT_IN_LOCATION_SETTING};
const std::vector<std::vector<int>> consent_ids = {tos_consent,
location_consent};
const std::vector<int> confirmation_ids = {
IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE, IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE};
const std::vector<consent_auditor::Feature> features = {
consent_auditor::Feature::PLAY_STORE,
consent_auditor::Feature::GOOGLE_LOCATION_SERVICE};
const std::vector<consent_auditor::ConsentStatus> statuses = {
consent_auditor::ConsentStatus::GIVEN,
consent_auditor::ConsentStatus::GIVEN};
EXPECT_EQ(consent_auditor()->account_id(), GetAuthenticatedAccountId());
EXPECT_EQ(consent_auditor()->recorded_id_vectors(), consent_ids);
EXPECT_EQ(consent_auditor()->recorded_confirmation_ids(), confirmation_ids);
EXPECT_EQ(consent_auditor()->recorded_features(), features);
EXPECT_EQ(consent_auditor()->recorded_statuses(), statuses);
} }
TEST_F(ArcTermsOfServiceDefaultNegotiatorTest, Cancel) { TEST_F(ArcTermsOfServiceDefaultNegotiatorTest, Cancel) {
consent_auditor::FakeConsentAuditor* auditor = consent_auditor();
Mock::VerifyAndClearExpectations(auditor);
ArcPlayTermsOfServiceConsent play_consent = CreateBasePlayConsent();
play_consent.set_status(UserConsentTypes::NOT_GIVEN);
EXPECT_CALL(*auditor, RecordArcPlayConsent(GetAuthenticatedAccountId(),
ArcPlayConsentEq(play_consent)));
ArcBackupAndRestoreConsent backup_and_restore_consent =
CreateBaseBackupAndRestoreConsent();
backup_and_restore_consent.set_status(UserConsentTypes::NOT_GIVEN);
EXPECT_CALL(*auditor,
RecordArcBackupAndRestoreConsent(
GetAuthenticatedAccountId(),
ArcBackupAndRestoreConsentEq(backup_and_restore_consent)));
ArcGoogleLocationServiceConsent google_location_service_consent =
CreateBaseGoogleLocationServiceConsent();
google_location_service_consent.set_status(UserConsentTypes::NOT_GIVEN);
EXPECT_CALL(
*auditor,
RecordArcGoogleLocationServiceConsent(
GetAuthenticatedAccountId(),
ArcGoogleLocationServiceConsentEq(google_location_service_consent)));
// Show Terms of service page. // Show Terms of service page.
Status status = Status::PENDING; Status status = Status::PENDING;
negotiator()->StartNegotiation(UpdateStatusCallback(&status)); negotiator()->StartNegotiation(UpdateStatusCallback(&status));
...@@ -342,8 +411,7 @@ TEST_F(ArcTermsOfServiceDefaultNegotiatorTest, Cancel) { ...@@ -342,8 +411,7 @@ TEST_F(ArcTermsOfServiceDefaultNegotiatorTest, Cancel) {
EXPECT_EQ(fake_arc_support()->ui_page(), ArcSupportHost::UIPage::TERMS); EXPECT_EQ(fake_arc_support()->ui_page(), ArcSupportHost::UIPage::TERMS);
// Emulate showing of a ToS page with a hard-coded ToS. // Emulate showing of a ToS page with a hard-coded ToS.
std::string tos_content = "fake ToS"; fake_arc_support()->set_tos_content(kFakeToSContent);
fake_arc_support()->set_tos_content(tos_content);
fake_arc_support()->set_tos_shown(true); fake_arc_support()->set_tos_shown(true);
// Check the preference related checkbox. // Check the preference related checkbox.
...@@ -366,34 +434,6 @@ TEST_F(ArcTermsOfServiceDefaultNegotiatorTest, Cancel) { ...@@ -366,34 +434,6 @@ TEST_F(ArcTermsOfServiceDefaultNegotiatorTest, Cancel) {
profile()->GetPrefs()->GetBoolean(prefs::kArcBackupRestoreEnabled)); profile()->GetPrefs()->GetBoolean(prefs::kArcBackupRestoreEnabled));
EXPECT_FALSE( EXPECT_FALSE(
profile()->GetPrefs()->GetBoolean(prefs::kArcLocationServiceEnabled)); 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);
const std::vector<int> backup_consent = {
IDS_ARC_OPT_IN_DIALOG_BACKUP_RESTORE};
const std::vector<int> location_consent = {IDS_ARC_OPT_IN_LOCATION_SETTING};
const std::vector<std::vector<int>> consent_ids = {
tos_consent, backup_consent, location_consent};
const std::vector<int> confirmation_ids = {
IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE, IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE,
IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE};
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_confirmation_ids(), confirmation_ids);
EXPECT_EQ(consent_auditor()->recorded_features(), features);
EXPECT_EQ(consent_auditor()->recorded_statuses(), statuses);
} }
TEST_F(ArcTermsOfServiceDefaultNegotiatorTest, Retry) { TEST_F(ArcTermsOfServiceDefaultNegotiatorTest, Retry) {
...@@ -420,4 +460,6 @@ TEST_F(ArcTermsOfServiceDefaultNegotiatorTest, Retry) { ...@@ -420,4 +460,6 @@ TEST_F(ArcTermsOfServiceDefaultNegotiatorTest, Retry) {
EXPECT_EQ(fake_arc_support()->ui_page(), ArcSupportHost::UIPage::TERMS); EXPECT_EQ(fake_arc_support()->ui_page(), ArcSupportHost::UIPage::TERMS);
} }
} // namespace
} // namespace arc } // namespace arc
...@@ -20,6 +20,8 @@ using consent_auditor::Feature; ...@@ -20,6 +20,8 @@ using consent_auditor::Feature;
using fake_server::FakeServer; using fake_server::FakeServer;
using sync_pb::SyncEntity; using sync_pb::SyncEntity;
using sync_pb::UserConsentSpecifics; using sync_pb::UserConsentSpecifics;
using sync_pb::UserConsentTypes;
using SyncConsent = sync_pb::UserConsentTypes::SyncConsent;
namespace { namespace {
...@@ -68,7 +70,7 @@ class UserConsentEqualityChecker : public SingleClientStatusChangeChecker { ...@@ -68,7 +70,7 @@ class UserConsentEqualityChecker : public SingleClientStatusChangeChecker {
EXPECT_TRUE(expected_specifics_.end() != iter); EXPECT_TRUE(expected_specifics_.end() != iter);
if (expected_specifics_.end() == iter) { if (expected_specifics_.end() == iter) {
return false; return false;
}; }
EXPECT_EQ(iter->second.account_id(), server_specifics.account_id()); EXPECT_EQ(iter->second.account_id(), server_specifics.account_id());
expected_specifics_.erase(iter); expected_specifics_.erase(iter);
} }
...@@ -122,9 +124,12 @@ IN_PROC_BROWSER_TEST_F(SingleClientUserConsentsSyncTest, ...@@ -122,9 +124,12 @@ IN_PROC_BROWSER_TEST_F(SingleClientUserConsentsSyncTest,
UserConsentSpecifics specifics; UserConsentSpecifics specifics;
specifics.set_confirmation_grd_id(1); specifics.set_confirmation_grd_id(1);
specifics.set_account_id(GetAccountId()); specifics.set_account_id(GetAccountId());
consent_service->RecordGaiaConsent(
GetAccountId(), Feature::CHROME_SYNC, /*description_grd_ids=*/{}, SyncConsent sync_consent;
/*confirmation_grd_id=*/1, ConsentStatus::GIVEN); sync_consent.set_confirmation_grd_id(1);
sync_consent.set_status(UserConsentTypes::GIVEN);
consent_service->RecordSyncConsent(GetAccountId(), sync_consent);
EXPECT_TRUE(ExpectUserConsents({specifics})); EXPECT_TRUE(ExpectUserConsents({specifics}));
} }
...@@ -142,9 +147,11 @@ IN_PROC_BROWSER_TEST_F( ...@@ -142,9 +147,11 @@ IN_PROC_BROWSER_TEST_F(
ASSERT_TRUE(SetupSync()); ASSERT_TRUE(SetupSync());
consent_auditor::ConsentAuditor* consent_service = consent_auditor::ConsentAuditor* consent_service =
ConsentAuditorFactory::GetForProfile(GetProfile(0)); ConsentAuditorFactory::GetForProfile(GetProfile(0));
consent_service->RecordGaiaConsent(
GetAccountId(), Feature::CHROME_SYNC, /*description_grd_ids=*/{}, SyncConsent sync_consent;
/*confirmation_grd_id=*/1, ConsentStatus::GIVEN); sync_consent.set_confirmation_grd_id(1);
sync_consent.set_status(UserConsentTypes::GIVEN);
consent_service->RecordSyncConsent(GetAccountId(), sync_consent);
GetClient(0)->StopSyncService(syncer::SyncService::CLEAR_DATA); GetClient(0)->StopSyncService(syncer::SyncService::CLEAR_DATA);
ASSERT_TRUE(GetClient(0)->StartSyncService()); ASSERT_TRUE(GetClient(0)->StartSyncService());
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "base/command_line.h" #include "base/command_line.h"
#include "base/i18n/timezone.h" #include "base/i18n/timezone.h"
#include "base/sha1.h"
#include "chrome/browser/chromeos/arc/arc_support_host.h" #include "chrome/browser/chromeos/arc/arc_support_host.h"
#include "chrome/browser/chromeos/arc/arc_util.h" #include "chrome/browser/chromeos/arc/arc_util.h"
#include "chrome/browser/chromeos/arc/optin/arc_optin_preference_handler.h" #include "chrome/browser/chromeos/arc/optin/arc_optin_preference_handler.h"
...@@ -32,6 +33,15 @@ ...@@ -32,6 +33,15 @@
#include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui.h"
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
using ArcBackupAndRestoreConsent =
sync_pb::UserConsentTypes::ArcBackupAndRestoreConsent;
using ArcGoogleLocationServiceConsent =
sync_pb::UserConsentTypes::ArcGoogleLocationServiceConsent;
using ArcPlayTermsOfServiceConsent =
sync_pb::UserConsentTypes::ArcPlayTermsOfServiceConsent;
using sync_pb::UserConsentTypes;
namespace { namespace {
const char kJsScreenPath[] = "login.ArcTermsOfServiceScreen"; const char kJsScreenPath[] = "login.ArcTermsOfServiceScreen";
...@@ -296,32 +306,44 @@ void ArcTermsOfServiceScreenHandler::RecordConsents( ...@@ -296,32 +306,44 @@ void ArcTermsOfServiceScreenHandler::RecordConsents(
DCHECK(signin_manager->IsAuthenticated()); DCHECK(signin_manager->IsAuthenticated());
const std::string account_id = signin_manager->GetAuthenticatedAccountId(); const std::string account_id = signin_manager->GetAuthenticatedAccountId();
// TODO(jhorwich): Replace this approach when passing |is_managed| boolean is ArcPlayTermsOfServiceConsent play_consent;
// supported by the underlying consent protos. play_consent.set_status(tos_accepted ? UserConsentTypes::GIVEN
const std::vector<int> consent_ids = ArcSupportHost::ComputePlayToSConsentIds( : UserConsentTypes::NOT_GIVEN);
record_tos_content ? tos_content : ""); play_consent.set_confirmation_grd_id(IDS_ARC_OOBE_TERMS_BUTTON_ACCEPT);
play_consent.set_consent_flow(ArcPlayTermsOfServiceConsent::SETUP);
consent_auditor->RecordGaiaConsent( if (record_tos_content) {
account_id, consent_auditor::Feature::PLAY_STORE, consent_ids, play_consent.set_play_terms_of_service_text_length(tos_content.length());
IDS_ARC_OOBE_TERMS_BUTTON_ACCEPT, play_consent.set_play_terms_of_service_hash(
tos_accepted ? consent_auditor::ConsentStatus::GIVEN base::SHA1HashString(tos_content));
: consent_auditor::ConsentStatus::NOT_GIVEN); }
consent_auditor->RecordArcPlayConsent(account_id, play_consent);
if (record_backup_consent) { if (record_backup_consent) {
consent_auditor->RecordGaiaConsent( ArcBackupAndRestoreConsent backup_and_restore_consent;
account_id, consent_auditor::Feature::BACKUP_AND_RESTORE, backup_and_restore_consent.set_confirmation_grd_id(
{IDS_ARC_OPT_IN_DIALOG_BACKUP_RESTORE}, IDS_ARC_OOBE_TERMS_BUTTON_ACCEPT);
IDS_ARC_OOBE_TERMS_BUTTON_ACCEPT, backup_and_restore_consent.add_description_grd_ids(
backup_accepted ? consent_auditor::ConsentStatus::GIVEN IDS_ARC_OPT_IN_DIALOG_BACKUP_RESTORE);
: consent_auditor::ConsentStatus::NOT_GIVEN); backup_and_restore_consent.set_status(backup_accepted
? UserConsentTypes::GIVEN
: UserConsentTypes::NOT_GIVEN);
consent_auditor->RecordArcBackupAndRestoreConsent(
account_id, backup_and_restore_consent);
} }
if (record_location_consent) { if (record_location_consent) {
consent_auditor->RecordGaiaConsent( ArcGoogleLocationServiceConsent location_service_consent;
account_id, consent_auditor::Feature::GOOGLE_LOCATION_SERVICE, location_service_consent.set_confirmation_grd_id(
{IDS_ARC_OPT_IN_LOCATION_SETTING}, IDS_ARC_OOBE_TERMS_BUTTON_ACCEPT, IDS_ARC_OOBE_TERMS_BUTTON_ACCEPT);
location_accepted ? consent_auditor::ConsentStatus::GIVEN location_service_consent.add_description_grd_ids(
: consent_auditor::ConsentStatus::NOT_GIVEN); IDS_ARC_OPT_IN_LOCATION_SETTING);
location_service_consent.set_status(location_accepted
? UserConsentTypes::GIVEN
: UserConsentTypes::NOT_GIVEN);
consent_auditor->RecordArcGoogleLocationServiceConsent(
account_id, location_service_consent);
} }
} }
......
...@@ -44,6 +44,7 @@ source_set("test_support") { ...@@ -44,6 +44,7 @@ source_set("test_support") {
deps = [ deps = [
":consent_auditor", ":consent_auditor",
"//components/sync", "//components/sync",
"//testing/gmock",
] ]
} }
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include <utility>
#include <vector> #include <vector>
#include "base/macros.h" #include "base/macros.h"
...@@ -47,21 +48,6 @@ class ConsentAuditor : public KeyedService { ...@@ -47,21 +48,6 @@ class ConsentAuditor : public KeyedService {
ConsentAuditor(); ConsentAuditor();
~ConsentAuditor() override; ~ConsentAuditor() override;
// Records a consent for |feature| for the signed-in GAIA account with
// the ID |account_id| (as defined in AccountInfo).
// Consent text consisted of strings with |consent_grd_ids|, and the UI
// element the user clicked had the ID |confirmation_grd_id|.
// Whether the consent was GIVEN or NOT_GIVEN is passed as |status|.
//
// DEPRECATED
// TODO(markusheintz): Make this method private once all clients have been
// migrated to the new API.
virtual void RecordGaiaConsent(const std::string& account_id,
Feature feature,
const std::vector<int>& description_grd_ids,
int confirmation_grd_id,
ConsentStatus status) = 0;
// Records the ARC Play |consent| for the signed-in GAIA account with the ID // Records the ARC Play |consent| for the signed-in GAIA account with the ID
// |account_id| (as defined in AccountInfo). // |account_id| (as defined in AccountInfo).
virtual void RecordArcPlayConsent( virtual void RecordArcPlayConsent(
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "components/consent_auditor/consent_auditor_impl.h" #include "components/consent_auditor/consent_auditor_impl.h"
#include <memory> #include <memory>
#include <utility>
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros.h"
#include "base/sha1.h" #include "base/sha1.h"
...@@ -17,6 +18,8 @@ ...@@ -17,6 +18,8 @@
#include "components/sync/model/model_type_sync_bridge.h" #include "components/sync/model/model_type_sync_bridge.h"
#include "components/sync/user_events/user_event_service.h" #include "components/sync/user_events/user_event_service.h"
using ArcPlayTermsOfServiceConsent =
sync_pb::UserConsentTypes::ArcPlayTermsOfServiceConsent;
using sync_pb::UserConsentTypes; using sync_pb::UserConsentTypes;
using sync_pb::UserConsentSpecifics; using sync_pb::UserConsentSpecifics;
using sync_pb::UserEventSpecifics; using sync_pb::UserEventSpecifics;
...@@ -218,20 +221,26 @@ ConsentAuditorImpl::ConstructUserConsentSpecifics( ...@@ -218,20 +221,26 @@ ConsentAuditorImpl::ConstructUserConsentSpecifics(
void ConsentAuditorImpl::RecordArcPlayConsent( void ConsentAuditorImpl::RecordArcPlayConsent(
const std::string& account_id, const std::string& account_id,
const UserConsentTypes::ArcPlayTermsOfServiceConsent& consent) { const ArcPlayTermsOfServiceConsent& consent) {
std::vector<int> description_grd_ids; std::vector<int> description_grd_ids;
description_grd_ids.push_back(consent.play_terms_of_service_text_length()); if (consent.consent_flow() == ArcPlayTermsOfServiceConsent::SETTING_CHANGE) {
for (int grd_id : consent.description_grd_ids()) {
// TODO(markusheintz): The code below is a copy from the ARC code base. This description_grd_ids.push_back(grd_id);
// will go away when the consent proto is set on the user consent specifics }
// proto. } else {
const std::string& hash_str = consent.play_terms_of_service_hash(); description_grd_ids.push_back(consent.play_terms_of_service_text_length());
DCHECK_EQ(base::kSHA1Length, hash_str.size());
const uint8_t* hash = reinterpret_cast<const uint8_t*>(hash_str.data()); // TODO(markusheintz): The code below is a copy from the ARC code base. This
for (size_t i = 0; i < base::kSHA1Length; i += 4) { // will go away when the consent proto is set on the user consent specifics
uint32_t acc = // proto.
hash[i] << 24 | hash[i + 1] << 16 | hash[i + 2] << 8 | hash[i + 3]; const std::string& hash_str = consent.play_terms_of_service_hash();
description_grd_ids.push_back(static_cast<int>(acc)); DCHECK_EQ(base::kSHA1Length, hash_str.size());
const uint8_t* hash = reinterpret_cast<const uint8_t*>(hash_str.data());
for (size_t i = 0; i < base::kSHA1Length; i += 4) {
uint32_t acc =
hash[i] << 24 | hash[i + 1] << 16 | hash[i + 2] << 8 | hash[i + 3];
description_grd_ids.push_back(static_cast<int>(acc));
}
} }
RecordGaiaConsent(account_id, Feature::PLAY_STORE, description_grd_ids, RecordGaiaConsent(account_id, Feature::PLAY_STORE, description_grd_ids,
......
...@@ -50,12 +50,6 @@ class ConsentAuditorImpl : public ConsentAuditor { ...@@ -50,12 +50,6 @@ class ConsentAuditorImpl : public ConsentAuditor {
// Registers the preferences needed by this service. // Registers the preferences needed by this service.
static void RegisterProfilePrefs(PrefRegistrySimple* registry); static void RegisterProfilePrefs(PrefRegistrySimple* registry);
// Consent auditor implementation.
void RecordGaiaConsent(const std::string& account_id,
Feature feature,
const std::vector<int>& description_grd_ids,
int confirmation_grd_id,
ConsentStatus status) override;
void RecordArcPlayConsent( void RecordArcPlayConsent(
const std::string& account_id, const std::string& account_id,
const sync_pb::UserConsentTypes::ArcPlayTermsOfServiceConsent& consent) const sync_pb::UserConsentTypes::ArcPlayTermsOfServiceConsent& consent)
...@@ -81,6 +75,17 @@ class ConsentAuditorImpl : public ConsentAuditor { ...@@ -81,6 +75,17 @@ class ConsentAuditorImpl : public ConsentAuditor {
GetControllerDelegateOnUIThread() override; GetControllerDelegateOnUIThread() override;
private: private:
// Records a consent for |feature| for the signed-in GAIA account with
// the ID |account_id| (as defined in AccountInfo).
// Consent text consisted of strings with |consent_grd_ids|, and the UI
// element the user clicked had the ID |confirmation_grd_id|.
// Whether the consent was GIVEN or NOT_GIVEN is passed as |status|.
void RecordGaiaConsent(const std::string& account_id,
Feature feature,
const std::vector<int>& description_grd_ids,
int confirmation_grd_id,
ConsentStatus status);
std::unique_ptr<sync_pb::UserEventSpecifics> ConstructUserEventSpecifics( std::unique_ptr<sync_pb::UserEventSpecifics> ConstructUserEventSpecifics(
const std::string& account_id, const std::string& account_id,
Feature feature, Feature feature,
......
...@@ -7,8 +7,10 @@ ...@@ -7,8 +7,10 @@
#include <map> #include <map>
#include <memory> #include <memory>
#include <string> #include <string>
#include <utility>
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/sha1.h"
#include "base/test/scoped_feature_list.h" #include "base/test/scoped_feature_list.h"
#include "base/test/simple_test_clock.h" #include "base/test/simple_test_clock.h"
#include "base/time/default_clock.h" #include "base/time/default_clock.h"
...@@ -19,8 +21,12 @@ ...@@ -19,8 +21,12 @@
#include "components/sync/user_events/fake_user_event_service.h" #include "components/sync/user_events/fake_user_event_service.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
using ArcPlayTermsOfServiceConsent =
sync_pb::UserConsentTypes::ArcPlayTermsOfServiceConsent;
using SyncConsent = sync_pb::UserConsentTypes::SyncConsent;
using sync_pb::UserConsentSpecifics; using sync_pb::UserConsentSpecifics;
using sync_pb::UserEventSpecifics; using sync_pb::UserEventSpecifics;
using sync_pb::UserConsentTypes;
namespace consent_auditor { namespace consent_auditor {
...@@ -250,9 +256,8 @@ TEST_F(ConsentAuditorImplTest, RecordingEnabled) { ...@@ -250,9 +256,8 @@ TEST_F(ConsentAuditorImplTest, RecordingEnabled) {
SetUserEventService(std::make_unique<syncer::FakeUserEventService>()); SetUserEventService(std::make_unique<syncer::FakeUserEventService>());
BuildConsentAuditorImpl(); BuildConsentAuditorImpl();
sync_pb::UserConsentTypes::SyncConsent sync_consent; SyncConsent sync_consent;
sync_consent.set_status(sync_pb::UserConsentTypes::ConsentStatus:: sync_consent.set_status(UserConsentTypes::GIVEN);
UserConsentTypes_ConsentStatus_GIVEN);
consent_auditor()->RecordSyncConsent(kAccountId, sync_consent); consent_auditor()->RecordSyncConsent(kAccountId, sync_consent);
auto& events = user_event_service()->GetRecordedUserEvents(); auto& events = user_event_service()->GetRecordedUserEvents();
...@@ -267,9 +272,8 @@ TEST_F(ConsentAuditorImplTest, RecordingDisabled) { ...@@ -267,9 +272,8 @@ TEST_F(ConsentAuditorImplTest, RecordingDisabled) {
base::test::ScopedFeatureList scoped_feature_list; base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndDisableFeature(switches::kSyncUserConsentEvents); scoped_feature_list.InitAndDisableFeature(switches::kSyncUserConsentEvents);
sync_pb::UserConsentTypes::SyncConsent sync_consent; SyncConsent sync_consent;
sync_consent.set_status(sync_pb::UserConsentTypes::ConsentStatus:: sync_consent.set_status(UserConsentTypes::GIVEN);
UserConsentTypes_ConsentStatus_GIVEN);
consent_auditor()->RecordSyncConsent(kAccountId, sync_consent); consent_auditor()->RecordSyncConsent(kAccountId, sync_consent);
auto& events = user_event_service()->GetRecordedUserEvents(); auto& events = user_event_service()->GetRecordedUserEvents();
EXPECT_EQ(0U, events.size()); EXPECT_EQ(0U, events.size());
...@@ -293,9 +297,8 @@ TEST_F(ConsentAuditorImplTest, RecordGaiaConsentAsUserEvent) { ...@@ -293,9 +297,8 @@ TEST_F(ConsentAuditorImplTest, RecordGaiaConsentAsUserEvent) {
ASSERT_TRUE(base::Time::FromUTCString("2017-11-14T15:15:38Z", &now)); ASSERT_TRUE(base::Time::FromUTCString("2017-11-14T15:15:38Z", &now));
test_clock.SetNow(now); test_clock.SetNow(now);
sync_pb::UserConsentTypes::SyncConsent sync_consent; SyncConsent sync_consent;
sync_consent.set_status(sync_pb::UserConsentTypes::ConsentStatus:: sync_consent.set_status(UserConsentTypes::GIVEN);
UserConsentTypes_ConsentStatus_GIVEN);
sync_consent.set_confirmation_grd_id(kConfirmationMessageId); sync_consent.set_confirmation_grd_id(kConfirmationMessageId);
for (int id : kDescriptionMessageIds) { for (int id : kDescriptionMessageIds) {
sync_consent.add_description_grd_ids(id); sync_consent.add_description_grd_ids(id);
...@@ -339,9 +342,8 @@ TEST_F(ConsentAuditorImplTest, RecordGaiaConsentAsUserConsent) { ...@@ -339,9 +342,8 @@ TEST_F(ConsentAuditorImplTest, RecordGaiaConsentAsUserConsent) {
ASSERT_TRUE(base::Time::FromUTCString("2017-11-14T15:15:38Z", &now)); ASSERT_TRUE(base::Time::FromUTCString("2017-11-14T15:15:38Z", &now));
test_clock.SetNow(now); test_clock.SetNow(now);
sync_pb::UserConsentTypes::SyncConsent sync_consent; SyncConsent sync_consent;
sync_consent.set_status(sync_pb::UserConsentTypes::ConsentStatus:: sync_consent.set_status(UserConsentTypes::GIVEN);
UserConsentTypes_ConsentStatus_GIVEN);
sync_consent.set_confirmation_grd_id(kConfirmationMessageId); sync_consent.set_confirmation_grd_id(kConfirmationMessageId);
for (int id : kDescriptionMessageIds) { for (int id : kDescriptionMessageIds) {
sync_consent.add_description_grd_ids(id); sync_consent.add_description_grd_ids(id);
...@@ -365,6 +367,107 @@ TEST_F(ConsentAuditorImplTest, RecordGaiaConsentAsUserConsent) { ...@@ -365,6 +367,107 @@ TEST_F(ConsentAuditorImplTest, RecordGaiaConsentAsUserConsent) {
EXPECT_EQ(kCurrentAppLocale, consent.locale()); EXPECT_EQ(kCurrentAppLocale, consent.locale());
} }
TEST_F(ConsentAuditorImplTest, RecordArcPlayConsentRevocation) {
SetIsSeparateConsentTypeEnabledFeature(true);
auto wrapped_fake_bridge = std::make_unique<FakeConsentSyncBridge>();
FakeConsentSyncBridge* fake_bridge = wrapped_fake_bridge.get();
base::SimpleTestClock test_clock;
SetConsentSyncBridge(std::move(wrapped_fake_bridge));
SetUserEventService(nullptr);
SetAppVersion(kCurrentAppVersion);
SetAppLocale(kCurrentAppLocale);
SetClock(&test_clock);
BuildConsentAuditorImpl();
std::vector<int> kDescriptionMessageIds = {12, 37, 42};
int kConfirmationMessageId = 47;
base::Time now;
ASSERT_TRUE(base::Time::FromUTCString("2017-11-14T15:15:38Z", &now));
test_clock.SetNow(now);
ArcPlayTermsOfServiceConsent play_consent;
play_consent.set_status(UserConsentTypes::NOT_GIVEN);
play_consent.set_confirmation_grd_id(kConfirmationMessageId);
for (int id : kDescriptionMessageIds) {
play_consent.add_description_grd_ids(id);
}
play_consent.set_consent_flow(ArcPlayTermsOfServiceConsent::SETTING_CHANGE);
consent_auditor()->RecordArcPlayConsent(kAccountId, play_consent);
std::vector<UserConsentSpecifics> consents =
fake_bridge->GetRecordedUserConsents();
ASSERT_EQ(1U, consents.size());
UserConsentSpecifics consent = consents[0];
EXPECT_EQ(kAccountId, consent.account_id());
EXPECT_EQ(UserConsentTypes::NOT_GIVEN, consent.status());
EXPECT_EQ(UserConsentSpecifics::PLAY_STORE, consent.feature());
EXPECT_EQ(3, consent.description_grd_ids_size());
EXPECT_EQ(kDescriptionMessageIds[0], consent.description_grd_ids(0));
EXPECT_EQ(kDescriptionMessageIds[1], consent.description_grd_ids(1));
EXPECT_EQ(kDescriptionMessageIds[2], consent.description_grd_ids(2));
EXPECT_EQ(kConfirmationMessageId, consent.confirmation_grd_id());
EXPECT_EQ(kCurrentAppLocale, consent.locale());
}
TEST_F(ConsentAuditorImplTest, RecordArcPlayConsent) {
SetIsSeparateConsentTypeEnabledFeature(true);
auto wrapped_fake_bridge = std::make_unique<FakeConsentSyncBridge>();
FakeConsentSyncBridge* fake_bridge = wrapped_fake_bridge.get();
base::SimpleTestClock test_clock;
SetConsentSyncBridge(std::move(wrapped_fake_bridge));
SetUserEventService(nullptr);
SetAppVersion(kCurrentAppVersion);
SetAppLocale(kCurrentAppLocale);
SetClock(&test_clock);
BuildConsentAuditorImpl();
int kConfirmationMessageId = 47;
base::Time now;
ASSERT_TRUE(base::Time::FromUTCString("2017-11-14T15:15:38Z", &now));
test_clock.SetNow(now);
ArcPlayTermsOfServiceConsent play_consent;
play_consent.set_status(UserConsentTypes::GIVEN);
play_consent.set_confirmation_grd_id(kConfirmationMessageId);
play_consent.set_consent_flow(ArcPlayTermsOfServiceConsent::SETUP);
// Verify the hash: 2fd4e1c6 7a2d28fc ed849ee1 bb76e739 1b93eb12.
const char play_tos_hash[] = {0x2f, 0xd4, 0xe1, 0xc6, 0x7a, 0x2d, 0x28,
0xfc, 0xed, 0x84, 0x9e, 0xe1, 0xbb, 0x76,
0xe7, 0x39, 0x1b, 0x93, 0xeb, 0x12};
play_consent.set_play_terms_of_service_hash(
std::string(play_tos_hash, base::kSHA1Length));
play_consent.set_play_terms_of_service_text_length(7);
consent_auditor()->RecordArcPlayConsent(kAccountId, play_consent);
std::vector<UserConsentSpecifics> consents =
fake_bridge->GetRecordedUserConsents();
ASSERT_EQ(1U, consents.size());
UserConsentSpecifics consent = consents[0];
EXPECT_EQ(kAccountId, consent.account_id());
EXPECT_EQ(UserConsentSpecifics::PLAY_STORE, consent.feature());
EXPECT_EQ(6, consent.description_grd_ids_size());
EXPECT_EQ(7, consent.description_grd_ids(0));
EXPECT_EQ(static_cast<int>(0x2fd4e1c6), consent.description_grd_ids(1));
EXPECT_EQ(static_cast<int>(0x7a2d28fc), consent.description_grd_ids(2));
EXPECT_EQ(static_cast<int>(0xed849ee1), consent.description_grd_ids(3));
EXPECT_EQ(static_cast<int>(0xbb76e739), consent.description_grd_ids(4));
EXPECT_EQ(static_cast<int>(0x1b93eb12), consent.description_grd_ids(5));
EXPECT_EQ(kConfirmationMessageId, consent.confirmation_grd_id());
EXPECT_EQ(kCurrentAppLocale, consent.locale());
}
TEST_F(ConsentAuditorImplTest, ShouldReturnNoSyncDelegateWhenNoBridge) { TEST_F(ConsentAuditorImplTest, ShouldReturnNoSyncDelegateWhenNoBridge) {
SetIsSeparateConsentTypeEnabledFeature(false); SetIsSeparateConsentTypeEnabledFeature(false);
SetConsentSyncBridge(nullptr); SetConsentSyncBridge(nullptr);
...@@ -396,33 +499,4 @@ TEST_F(ConsentAuditorImplTest, ShouldReturnSyncDelegateWhenBridgePresent) { ...@@ -396,33 +499,4 @@ TEST_F(ConsentAuditorImplTest, ShouldReturnSyncDelegateWhenBridgePresent) {
consent_auditor()->GetControllerDelegateOnUIThread().get()); consent_auditor()->GetControllerDelegateOnUIThread().get());
} }
// Test that RecordSyncConsent and RecordGaiaConsent record an identical user
// consent proto with the user event service. This test ensures that the two
// methods don't diverge during the migration to the new dedicated protos for
// user events.
TEST_F(ConsentAuditorImplTest, RecordGaiaUserRecordSyncConsentEquivalence) {
SetIsSeparateConsentTypeEnabledFeature(false);
SetConsentSyncBridge(nullptr);
SetUserEventService(std::make_unique<syncer::FakeUserEventService>());
BuildConsentAuditorImpl();
sync_pb::UserConsentTypes::SyncConsent sync_consent;
sync_consent.set_status(sync_pb::UserConsentTypes::ConsentStatus::
UserConsentTypes_ConsentStatus_GIVEN);
sync_consent.set_confirmation_grd_id(21);
sync_consent.add_description_grd_ids(1);
sync_consent.add_description_grd_ids(2);
sync_consent.add_description_grd_ids(3);
consent_auditor()->RecordSyncConsent(kAccountId, sync_consent);
consent_auditor()->RecordGaiaConsent(
kAccountId, consent_auditor::Feature::CHROME_SYNC, {1, 2, 3}, 21,
consent_auditor::ConsentStatus::GIVEN);
auto& events = user_event_service()->GetRecordedUserEvents();
EXPECT_EQ(2U, events.size());
EXPECT_EQ(events.at(0).user_consent().SerializeAsString(),
events.at(1).user_consent().SerializeAsString());
}
} // namespace consent_auditor } // namespace consent_auditor
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include <string>
#include <utility> #include <utility>
#include "components/consent_auditor/consent_auditor.h" #include "components/consent_auditor/consent_auditor.h"
...@@ -42,24 +43,6 @@ void FakeConsentAuditor::RecordSyncConsent( ...@@ -42,24 +43,6 @@ void FakeConsentAuditor::RecordSyncConsent(
ConvertConsentStatus(consent.status())); ConvertConsentStatus(consent.status()));
} }
void FakeConsentAuditor::RecordArcPlayConsent(
const std::string& account_id,
const sync_pb::UserConsentTypes::ArcPlayTermsOfServiceConsent& consent) {
NOTIMPLEMENTED();
}
void FakeConsentAuditor::RecordArcGoogleLocationServiceConsent(
const std::string& account_id,
const sync_pb::UserConsentTypes::ArcGoogleLocationServiceConsent& consent) {
NOTIMPLEMENTED();
}
void FakeConsentAuditor::RecordArcBackupAndRestoreConsent(
const std::string& account_id,
const sync_pb::UserConsentTypes::ArcBackupAndRestoreConsent& consent) {
NOTIMPLEMENTED();
}
void FakeConsentAuditor::RecordUnifiedConsent( void FakeConsentAuditor::RecordUnifiedConsent(
const std::string& account_id, const std::string& account_id,
const sync_pb::UserConsentTypes::UnifiedConsent& consent) { const sync_pb::UserConsentTypes::UnifiedConsent& consent) {
......
...@@ -5,13 +5,17 @@ ...@@ -5,13 +5,17 @@
#ifndef COMPONENTS_CONSENT_AUDITOR_FAKE_CONSENT_AUDITOR_H_ #ifndef COMPONENTS_CONSENT_AUDITOR_FAKE_CONSENT_AUDITOR_H_
#define COMPONENTS_CONSENT_AUDITOR_FAKE_CONSENT_AUDITOR_H_ #define COMPONENTS_CONSENT_AUDITOR_FAKE_CONSENT_AUDITOR_H_
#include <string>
#include <vector> #include <vector>
#include "base/macros.h" #include "base/macros.h"
#include "components/consent_auditor/consent_auditor.h" #include "components/consent_auditor/consent_auditor.h"
#include "testing/gmock/include/gmock/gmock.h"
namespace consent_auditor { using ::testing::Matcher;
namespace consent_auditor {
// TODO(markusheintz): Rename to MockConsentAuditor
class FakeConsentAuditor : public ConsentAuditor { class FakeConsentAuditor : public ConsentAuditor {
public: public:
FakeConsentAuditor(); FakeConsentAuditor();
...@@ -21,31 +25,22 @@ class FakeConsentAuditor : public ConsentAuditor { ...@@ -21,31 +25,22 @@ class FakeConsentAuditor : public ConsentAuditor {
void RecordSyncConsent( void RecordSyncConsent(
const std::string& account_id, const std::string& account_id,
const sync_pb::UserConsentTypes::SyncConsent& consent) override; const sync_pb::UserConsentTypes::SyncConsent& consent) override;
MOCK_METHOD2(
void RecordArcPlayConsent( RecordArcPlayConsent,
const std::string& account_id, void(const std::string&,
const sync_pb::UserConsentTypes::ArcPlayTermsOfServiceConsent& consent) const sync_pb::UserConsentTypes::ArcPlayTermsOfServiceConsent&));
override; MOCK_METHOD2(
RecordArcBackupAndRestoreConsent,
void RecordArcGoogleLocationServiceConsent( void(const std::string&,
const std::string& account_id, const sync_pb::UserConsentTypes::ArcBackupAndRestoreConsent&));
const sync_pb::UserConsentTypes::ArcGoogleLocationServiceConsent& consent) MOCK_METHOD2(
override; RecordArcGoogleLocationServiceConsent,
void(const std::string&,
void RecordArcBackupAndRestoreConsent( const sync_pb::UserConsentTypes::ArcGoogleLocationServiceConsent&));
const std::string& account_id,
const sync_pb::UserConsentTypes::ArcBackupAndRestoreConsent& consent)
override;
void RecordUnifiedConsent( void RecordUnifiedConsent(
const std::string& account_id, const std::string& account_id,
const sync_pb::UserConsentTypes::UnifiedConsent& consent) override; const sync_pb::UserConsentTypes::UnifiedConsent& consent) override;
void RecordGaiaConsent(const std::string& account_id,
consent_auditor::Feature feature,
const std::vector<int>& description_grd_ids,
int confirmation_grd_id,
consent_auditor::ConsentStatus status) override;
void RecordLocalConsent(const std::string& feature, void RecordLocalConsent(const std::string& feature,
const std::string& description_text, const std::string& description_text,
const std::string& confirmation_text) override; const std::string& confirmation_text) override;
...@@ -53,12 +48,24 @@ class FakeConsentAuditor : public ConsentAuditor { ...@@ -53,12 +48,24 @@ class FakeConsentAuditor : public ConsentAuditor {
GetControllerDelegateOnUIThread() override; GetControllerDelegateOnUIThread() override;
// Methods for fake. // Methods for fake.
// TODO(markusheintz): Replace the usage of this methods in all tests.
void RecordGaiaConsent(const std::string& account_id,
consent_auditor::Feature feature,
const std::vector<int>& description_grd_ids,
int confirmation_grd_id,
consent_auditor::ConsentStatus status);
const std::string& account_id() const { return account_id_; } const std::string& account_id() const { return account_id_; }
const sync_pb::UserConsentTypes::SyncConsent& recorded_sync_consent() const { const sync_pb::UserConsentTypes::SyncConsent& recorded_sync_consent() const {
return recorded_sync_consent_; return recorded_sync_consent_;
} }
const sync_pb::UserConsentTypes::ArcPlayTermsOfServiceConsent&
recorded_play_consent() const {
return recorded_play_consent_;
}
const std::vector<std::vector<int>>& recorded_id_vectors() { const std::vector<std::vector<int>>& recorded_id_vectors() {
return recorded_id_vectors_; return recorded_id_vectors_;
} }
...@@ -73,9 +80,11 @@ class FakeConsentAuditor : public ConsentAuditor { ...@@ -73,9 +80,11 @@ class FakeConsentAuditor : public ConsentAuditor {
return recorded_statuses_; return recorded_statuses_;
} }
private:
std::string account_id_; std::string account_id_;
sync_pb::UserConsentTypes::SyncConsent recorded_sync_consent_; sync_pb::UserConsentTypes::SyncConsent recorded_sync_consent_;
sync_pb::UserConsentTypes_ArcPlayTermsOfServiceConsent recorded_play_consent_;
std::vector<std::vector<int>> recorded_id_vectors_; std::vector<std::vector<int>> recorded_id_vectors_;
std::vector<int> recorded_confirmation_ids_; std::vector<int> recorded_confirmation_ids_;
...@@ -85,6 +94,38 @@ class FakeConsentAuditor : public ConsentAuditor { ...@@ -85,6 +94,38 @@ class FakeConsentAuditor : public ConsentAuditor {
DISALLOW_COPY_AND_ASSIGN(FakeConsentAuditor); DISALLOW_COPY_AND_ASSIGN(FakeConsentAuditor);
}; };
MATCHER_P(ArcPlayConsentEq, expected_consent, "") {
const sync_pb::UserConsentTypes::ArcPlayTermsOfServiceConsent&
actual_consent = arg;
if (actual_consent.SerializeAsString() ==
expected_consent.SerializeAsString())
return true;
LOG(ERROR) << "ERROR: actual proto does not match the expected proto";
return false;
}
MATCHER_P(ArcGoogleLocationServiceConsentEq, expected_consent, "") {
const sync_pb::UserConsentTypes::ArcGoogleLocationServiceConsent&
actual_consent = arg;
if (actual_consent.SerializeAsString() ==
expected_consent.SerializeAsString())
return true;
LOG(ERROR) << "ERROR: actual proto does not match the expected proto";
return false;
}
MATCHER_P(ArcBackupAndRestoreConsentEq, expected_consent, "") {
if (arg.SerializeAsString() == expected_consent.SerializeAsString())
return true;
LOG(ERROR) << "ERROR: actual proto does not match the expected proto";
return false;
}
} // namespace consent_auditor } // namespace consent_auditor
#endif // COMPONENTS_CONSENT_AUDITOR_FAKE_CONSENT_AUDITOR_H_ #endif // COMPONENTS_CONSENT_AUDITOR_FAKE_CONSENT_AUDITOR_H_
...@@ -75,14 +75,32 @@ message UserConsentTypes { ...@@ -75,14 +75,32 @@ message UserConsentTypes {
// The length of the UTF-8 encoded string of the Play Terms of Service // The length of the UTF-8 encoded string of the Play Terms of Service
// text. The length is given in number of bytes. // text. The length is given in number of bytes.
optional int32 play_terms_of_service_text_length = 1; optional int32 play_terms_of_service_text_length = 1;
// The SHA1 hash of UTF-8 encoded string of the Play Terms of Service // The SHA1 hash of UTF-8 encoded string of the Play Terms of Service
// displayed to the user. // displayed to the user.
optional bytes play_terms_of_service_hash = 2; optional bytes play_terms_of_service_hash = 2;
// GRD Ids of the strings on the consent UI that was shown to the user.
repeated int32 description_grd_ids = 5;
// Id of the string of the UI element the user clicked when consenting. // Id of the string of the UI element the user clicked when consenting.
optional int32 confirmation_grd_id = 3; optional int32 confirmation_grd_id = 3;
// The status of the Play Terms of Service consent. This specifies whether // The status of the Play Terms of Service consent. This specifies whether
// the consent was given or not given/revoked. // the consent was given or not given/revoked.
optional ConsentStatus status = 4; optional ConsentStatus status = 4;
// Enum describing different user flow during which the ARC Play Terms of
// service consent can be recorded.
enum ConsentFlow {
// The ARC setup flow on a CROS device.
SETUP = 1;
// The user flow for changing the ARC setting on a CROS device.
SETTING_CHANGE = 2;
}
// The user flow during which the consent was recorded. This is necessary in
// order to create the correct UI context and Event for the backend.
optional ConsentFlow consent_flow = 6;
} }
// The User Consent for Chrome Sync is determined by the user action on the // The User Consent for Chrome Sync is determined by the user action on the
......
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