Index: ios/chrome/browser/sync/sync_setup_service.cc |
diff --git a/ios/chrome/browser/sync/sync_setup_service.cc b/ios/chrome/browser/sync/sync_setup_service.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..d617324509b65ca2e5b30bce8c6d6c2d38e4f1e9 |
--- /dev/null |
+++ b/ios/chrome/browser/sync/sync_setup_service.cc |
@@ -0,0 +1,196 @@ |
+// Copyright 2012 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 "ios/chrome/browser/sync/sync_setup_service.h" |
+ |
+#include <stdio.h> |
+ |
+#include "base/prefs/pref_service.h" |
+#include "components/sync_driver/sync_prefs.h" |
+#include "components/sync_driver/sync_service.h" |
+#include "google_apis/gaia/google_service_auth_error.h" |
+#include "ios/chrome/browser/pref_names.h" |
+#include "ios/public/provider/chrome/browser/browser_state/chrome_browser_state.h" |
+#include "net/base/network_change_notifier.h" |
+#include "sync/protocol/sync_protocol_error.h" |
+ |
+namespace { |
+// The set of user-selectable datatypes. This must be in the same order as |
+// |SyncSetupService::SyncableDatatype|. |
noyau (Ping after 24h)
2015/05/19 19:45:00
Can't we reuse the other datatype, or ensure in so
|
+syncer::ModelType kDataTypes[] = { |
+ syncer::BOOKMARKS, |
+ syncer::TYPED_URLS, |
+ syncer::PASSWORDS, |
+ syncer::PROXY_TABS, |
+ syncer::AUTOFILL, |
+}; |
+} // namespace |
+ |
+SyncSetupService::SyncSetupService(sync_driver::SyncService* sync_service, |
+ PrefService* prefs) |
+ : sync_service_(sync_service), prefs_(prefs) { |
+ DCHECK(sync_service_); |
+ DCHECK(prefs_); |
+ for (unsigned int i = 0; i < arraysize(kDataTypes); ++i) { |
+ user_selectable_types_.Put(kDataTypes[i]); |
+ } |
+} |
+ |
+SyncSetupService::~SyncSetupService() { |
+} |
+ |
+syncer::ModelType SyncSetupService::GetModelType(SyncableDatatype datatype) { |
+ DCHECK(datatype < arraysize(kDataTypes)); |
+ return kDataTypes[datatype]; |
+} |
+ |
+syncer::ModelTypeSet SyncSetupService::GetDataTypes() const { |
+ return sync_service_->GetPreferredDataTypes(); |
+} |
+ |
+bool SyncSetupService::IsDataTypeEnabled(syncer::ModelType datatype) const { |
+ return GetDataTypes().Has(datatype); |
+} |
+ |
+void SyncSetupService::SetDataTypeEnabled(syncer::ModelType datatype, |
+ bool enabled) { |
+ sync_service_->SetSetupInProgress(true); |
+ syncer::ModelTypeSet types = GetDataTypes(); |
+ if (enabled) |
+ types.Put(datatype); |
+ else |
+ types.Remove(datatype); |
+ types.RetainAll(user_selectable_types_); |
+ if (enabled && !IsSyncEnabled()) |
+ SetSyncEnabledWithoutChangingDatatypes(true); |
+ sync_service_->OnUserChoseDatatypes(IsSyncingAllDataTypes(), types); |
+ if (GetDataTypes().Empty()) |
+ SetSyncEnabled(false); |
+} |
+ |
+bool SyncSetupService::UserActionIsRequiredToHaveSyncWork() { |
+ if (!IsSyncEnabled() || !IsDataTypeEnabled(syncer::PROXY_TABS)) { |
+ return true; |
+ } |
+ switch (this->GetSyncServiceState()) { |
+ // No error. |
+ case SyncSetupService::kNoSyncServiceError: |
+ // These errors are transient and don't mean that sync is off. |
+ case SyncSetupService::kSyncServiceCouldNotConnect: |
+ case SyncSetupService::kSyncServiceServiceUnavailable: |
+ return false; |
+ // These errors effectively amount to disabled sync and require a signin. |
+ case SyncSetupService::kSyncServiceSignInNeedsUpdate: |
+ case SyncSetupService::kSyncServiceNeedsPassphrase: |
+ case SyncSetupService::kSyncServiceUnrecoverableError: |
+ return true; |
+ default: |
+ NOTREACHED() << "Unknown sync service state."; |
+ return true; |
+ } |
+} |
+ |
+bool SyncSetupService::IsSyncingAllDataTypes() const { |
+ sync_driver::SyncPrefs sync_prefs(prefs_); |
+ return sync_prefs.HasKeepEverythingSynced(); |
+} |
+ |
+void SyncSetupService::SetSyncingAllDataTypes(bool sync_all) { |
+ sync_service_->SetSetupInProgress(true); |
+ if (sync_all && !IsSyncEnabled()) |
+ SetSyncEnabled(true); |
+ sync_service_->OnUserChoseDatatypes(sync_all, GetDataTypes()); |
+} |
+ |
+bool SyncSetupService::IsSyncEnabled() const { |
+ return sync_service_->IsSyncEnabledAndLoggedIn(); |
+} |
+ |
+void SyncSetupService::SetSyncEnabled(bool sync_enabled) { |
+ SetSyncEnabledWithoutChangingDatatypes(sync_enabled); |
+ if (sync_enabled && GetDataTypes().Empty()) |
+ SetSyncingAllDataTypes(true); |
+} |
+ |
+SyncSetupService::SyncServiceState SyncSetupService::GetSyncServiceState() { |
+ switch (sync_service_->GetAuthError().state()) { |
+ case GoogleServiceAuthError::REQUEST_CANCELED: |
+ return kSyncServiceCouldNotConnect; |
+ // Based on sync_ui_util::GetStatusLabelsForAuthError, SERVICE_UNAVAILABLE |
+ // corresponds to sync having been disabled for the user's domain. |
+ case GoogleServiceAuthError::SERVICE_UNAVAILABLE: |
+ return kSyncServiceServiceUnavailable; |
+ case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS: |
+ return kSyncServiceSignInNeedsUpdate; |
+ // The following errors are not shown to the user. |
+ case GoogleServiceAuthError::NONE: |
+ // Connection failed is not shown to the user, as this will happen if the |
+ // service retuned a 500 error. A more detail error can always be checked |
+ // on about:sync. |
+ case GoogleServiceAuthError::CONNECTION_FAILED: |
+ case GoogleServiceAuthError::USER_NOT_SIGNED_UP: |
+ case GoogleServiceAuthError::UNEXPECTED_SERVICE_RESPONSE: |
+ break; |
+ // The following errors are unexpected on iOS. |
+ case GoogleServiceAuthError::CAPTCHA_REQUIRED: |
+ case GoogleServiceAuthError::ACCOUNT_DELETED: |
+ case GoogleServiceAuthError::ACCOUNT_DISABLED: |
+ case GoogleServiceAuthError::TWO_FACTOR: |
+ case GoogleServiceAuthError::HOSTED_NOT_ALLOWED: |
+ case GoogleServiceAuthError::SERVICE_ERROR: |
+ case GoogleServiceAuthError::WEB_LOGIN_REQUIRED: |
+ // Conventional value for counting the states, never used. |
+ case GoogleServiceAuthError::NUM_STATES: |
+ NOTREACHED() << "Unexpected Auth error (" |
+ << sync_service_->GetAuthError().state() |
+ << "): " << sync_service_->GetAuthError().error_message(); |
+ break; |
+ } |
+ if (sync_service_->HasUnrecoverableError()) |
+ return kSyncServiceUnrecoverableError; |
+ if (sync_service_->IsPassphraseRequiredForDecryption()) |
+ return kSyncServiceNeedsPassphrase; |
+ return kNoSyncServiceError; |
+} |
+ |
+bool SyncSetupService::HasFinishedInitialSetup() { |
+ // Sync initial setup is considered to finished iff: |
+ // 1. User is signed in with sync enabled and the sync setup was completed. |
+ // OR |
+ // 2. User is not signed in or has disabled sync. |
+ return !sync_service_->IsSyncEnabledAndLoggedIn() || |
+ sync_service_->HasSyncSetupCompleted(); |
+} |
+ |
+void SyncSetupService::PrepareForFirstSyncSetup() { |
+ // |PrepareForFirstSyncSetup| should always be called while the user is signed |
+ // out. At that time, sync setup is not completed. |
+ DCHECK(!sync_service_->HasSyncSetupCompleted()); |
+ sync_service_->SetSetupInProgress(true); |
+} |
+ |
+void SyncSetupService::CommitChanges() { |
+ if (sync_service_->FirstSetupInProgress()) { |
+ // Turn on the sync setup completed flag only if the user did not turn sync |
+ // off. |
+ if (sync_service_->IsSyncEnabledAndLoggedIn()) { |
+ sync_service_->SetSyncSetupCompleted(); |
+ } |
+ } |
+ |
+ sync_service_->SetSetupInProgress(false); |
+} |
+ |
+bool SyncSetupService::HasUncommittedChanges() { |
+ return sync_service_->setup_in_progress(); |
+} |
+ |
+void SyncSetupService::SetSyncEnabledWithoutChangingDatatypes( |
+ bool sync_enabled) { |
+ sync_service_->SetSetupInProgress(true); |
+ if (sync_enabled) |
+ sync_service_->UnsuppressAndStart(); |
+ else |
+ sync_service_->StopAndSuppress(); |
+} |