1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "components/autofill/core/browser/payments/autofill_wallet_model_type_controller.h"
6 
7 #include <utility>
8 
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
11 #include "components/autofill/core/common/autofill_prefs.h"
12 #include "components/prefs/pref_service.h"
13 #include "components/sync/driver/sync_auth_util.h"
14 #include "components/sync/driver/sync_service.h"
15 #include "google_apis/gaia/google_service_auth_error.h"
16 
17 namespace browser_sync {
18 
AutofillWalletModelTypeController(syncer::ModelType type,std::unique_ptr<syncer::ModelTypeControllerDelegate> delegate_for_full_sync_mode,PrefService * pref_service,syncer::SyncService * sync_service)19 AutofillWalletModelTypeController::AutofillWalletModelTypeController(
20     syncer::ModelType type,
21     std::unique_ptr<syncer::ModelTypeControllerDelegate>
22         delegate_for_full_sync_mode,
23     PrefService* pref_service,
24     syncer::SyncService* sync_service)
25     : ModelTypeController(type, std::move(delegate_for_full_sync_mode)),
26       pref_service_(pref_service),
27       sync_service_(sync_service) {
28   DCHECK(type == syncer::AUTOFILL_WALLET_DATA ||
29          type == syncer::AUTOFILL_WALLET_METADATA);
30   SubscribeToPrefChanges();
31   // TODO(crbug.com/906995): remove this observing mechanism once all sync
32   // datatypes are stopped by ProfileSyncService, when sync is paused.
33   sync_service_->AddObserver(this);
34 }
35 
AutofillWalletModelTypeController(syncer::ModelType type,std::unique_ptr<syncer::ModelTypeControllerDelegate> delegate_for_full_sync_mode,std::unique_ptr<syncer::ModelTypeControllerDelegate> delegate_for_transport_mode,PrefService * pref_service,syncer::SyncService * sync_service)36 AutofillWalletModelTypeController::AutofillWalletModelTypeController(
37     syncer::ModelType type,
38     std::unique_ptr<syncer::ModelTypeControllerDelegate>
39         delegate_for_full_sync_mode,
40     std::unique_ptr<syncer::ModelTypeControllerDelegate>
41         delegate_for_transport_mode,
42     PrefService* pref_service,
43     syncer::SyncService* sync_service)
44     : ModelTypeController(type,
45                           std::move(delegate_for_full_sync_mode),
46                           std::move(delegate_for_transport_mode)),
47       pref_service_(pref_service),
48       sync_service_(sync_service) {
49   DCHECK(type == syncer::AUTOFILL_WALLET_DATA ||
50          type == syncer::AUTOFILL_WALLET_METADATA);
51   SubscribeToPrefChanges();
52   // TODO(crbug.com/906995): remove this observing mechanism once all sync
53   // datatypes are stopped by ProfileSyncService, when sync is paused.
54   sync_service_->AddObserver(this);
55 }
56 
~AutofillWalletModelTypeController()57 AutofillWalletModelTypeController::~AutofillWalletModelTypeController() {
58   sync_service_->RemoveObserver(this);
59 }
60 
Stop(syncer::ShutdownReason shutdown_reason,StopCallback callback)61 void AutofillWalletModelTypeController::Stop(
62     syncer::ShutdownReason shutdown_reason,
63     StopCallback callback) {
64   DCHECK(CalledOnValidThread());
65   switch (shutdown_reason) {
66     case syncer::STOP_SYNC:
67       // Special case: For AUTOFILL_WALLET_DATA and AUTOFILL_WALLET_METADATA, we
68       // want to clear all data even when Sync is stopped temporarily.
69       shutdown_reason = syncer::DISABLE_SYNC;
70       break;
71     case syncer::DISABLE_SYNC:
72     case syncer::BROWSER_SHUTDOWN:
73       break;
74   }
75   ModelTypeController::Stop(shutdown_reason, std::move(callback));
76 }
77 
78 syncer::DataTypeController::PreconditionState
GetPreconditionState() const79 AutofillWalletModelTypeController::GetPreconditionState() const {
80   DCHECK(CalledOnValidThread());
81   // Not being in a persistent error state implies not being in a web signout
82   // state.
83   // TODO(https://crbug.com/819729): Add integration tests for web signout and
84   // other persistent auth errors.
85   bool preconditions_met =
86       pref_service_->GetBoolean(
87           autofill::prefs::kAutofillWalletImportEnabled) &&
88       pref_service_->GetBoolean(autofill::prefs::kAutofillCreditCardEnabled) &&
89       !sync_service_->GetAuthError().IsPersistentError();
90   return preconditions_met ? PreconditionState::kPreconditionsMet
91                            : PreconditionState::kMustStopAndClearData;
92 }
93 
OnUserPrefChanged()94 void AutofillWalletModelTypeController::OnUserPrefChanged() {
95   DCHECK(CalledOnValidThread());
96   sync_service_->DataTypePreconditionChanged(type());
97 }
98 
SubscribeToPrefChanges()99 void AutofillWalletModelTypeController::SubscribeToPrefChanges() {
100   pref_registrar_.Init(pref_service_);
101   pref_registrar_.Add(
102       autofill::prefs::kAutofillWalletImportEnabled,
103       base::BindRepeating(&AutofillWalletModelTypeController::OnUserPrefChanged,
104                           base::Unretained(this)));
105   pref_registrar_.Add(
106       autofill::prefs::kAutofillCreditCardEnabled,
107       base::BindRepeating(&AutofillWalletModelTypeController::OnUserPrefChanged,
108                           base::Unretained(this)));
109 }
110 
OnStateChanged(syncer::SyncService * sync)111 void AutofillWalletModelTypeController::OnStateChanged(
112     syncer::SyncService* sync) {
113   DCHECK(CalledOnValidThread());
114   sync_service_->DataTypePreconditionChanged(type());
115 }
116 
117 }  // namespace browser_sync
118