15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/profile_sync_service.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cstddef>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
96e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include <vector>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
13f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "base/bind_helpers.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
209ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h"
22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h"
23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread_restrictions.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "build/build_config.h"
26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/bookmarks/enhanced_bookmarks_features.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h"
2846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "chrome/browser/browsing_data/browsing_data_helper.h"
297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/defaults.h"
31f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/invalidation/profile_invalidation_provider_factory.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/net/chrome_cookie_notification_details.h"
336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/browser/password_manager/password_store_factory.h"
34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/prefs/chrome_pref_service_factory.h"
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/prefs/pref_service_syncable.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/services/gcm/gcm_profile_service.h"
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/services/gcm/gcm_profile_service_factory.h"
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/signin/about_signin_internals_factory.h"
405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/signin/chrome_signin_client_factory.h"
414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/signin/signin_manager_factory.h"
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/backend_migrator.h"
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/glue/chrome_report_unrecoverable_error.h"
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/sync/glue/favicon_cache.h"
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/sync/glue/sync_backend_host.h"
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/sync/glue/sync_backend_host_impl.h"
48a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/sync/glue/sync_start_util.h"
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/glue/typed_url_data_type_controller.h"
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/profile_sync_components_factory_impl.h"
510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "chrome/browser/sync/sessions/notification_service_sessions_router.h"
52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/sync/supervised_user_signin_manager_wrapper.h"
53effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "chrome/browser/sync/sync_error_controller.h"
546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/browser/sync/sync_type_preference_provider.h"
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h"
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_list.h"
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_window.h"
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/global_error/global_error_service.h"
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/global_error/global_error_service_factory.h"
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_version_info.h"
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h"
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h"
6403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/grit/generated_resources.h"
65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/gcm_driver/gcm_driver.h"
66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/invalidation/invalidation_service.h"
67f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "components/invalidation/profile_invalidation_provider.h"
686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "components/password_manager/core/browser/password_store.h"
69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/pref_registry/pref_registry_syncable.h"
70e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "components/signin/core/browser/about_signin_internals.h"
71effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "components/signin/core/browser/profile_oauth2_token_service.h"
72e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "components/signin/core/browser/signin_manager.h"
73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/signin/core/browser/signin_metrics.h"
740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "components/sync_driver/change_processor.h"
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/sync_driver/data_type_controller.h"
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/sync_driver/device_info.h"
7723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "components/sync_driver/pref_names.h"
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/sync_driver/system_encryptor.h"
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/sync_driver/user_selectable_sync_type.h"
80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/public/browser/browser_thread.h"
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_details.h"
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h"
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/cookies/cookie_monster.h"
85eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "net/url_request/url_request_context_getter.h"
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/api/sync_error.h"
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/configure_reason.h"
88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "sync/internal_api/public/http_bridge_network_resources.h"
89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "sync/internal_api/public/network_resources.h"
90010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "sync/internal_api/public/sessions/type_debug_info_observer.h"
915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "sync/internal_api/public/shutdown_reason.h"
92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "sync/internal_api/public/sync_context_proxy.h"
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/sync_encryption_handler.h"
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/util/experiments.h"
95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "sync/internal_api/public/util/sync_db_util.h"
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/util/sync_string_conversions.h"
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/js/js_event_details.h"
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/util/cryptographer.h"
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
100bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "ui/base/l10n/time_format.h"
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_ANDROID)
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "sync/internal_api/public/read_transaction.h"
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
106a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)using browser_sync::NotificationServiceSessionsRouter;
107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using browser_sync::ProfileSyncServiceStartBehavior;
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing browser_sync::SessionsSyncManager;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using browser_sync::SyncBackendHost;
1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)using sync_driver::ChangeProcessor;
1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)using sync_driver::DataTypeController;
1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)using sync_driver::DataTypeManager;
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing sync_driver::DataTypeStatusTable;
1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing sync_driver::DeviceInfoSyncService;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using syncer::ModelType;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using syncer::ModelTypeSet;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using syncer::JsBackend;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using syncer::JsController;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using syncer::JsEventDetails;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using syncer::JsEventHandler;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using syncer::ModelSafeRoutingInfo;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using syncer::SyncCredentials;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using syncer::SyncProtocolError;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using syncer::WeakHandle;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef GoogleServiceAuthError AuthError;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* ProfileSyncService::kSyncServerUrl =
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "https://clients4.google.com/chrome-sync";
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* ProfileSyncService::kDevServerUrl =
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "https://clients4.google.com/chrome-sync/dev";
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const char kSyncUnrecoverableErrorHistogram[] =
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Sync.UnrecoverableErrors";
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)const net::BackoffEntry::Policy kRequestAccessTokenBackoffPolicy = {
1387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Number of initial errors (in sequence) to ignore before applying
1397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // exponential back-off rules.
1407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  0,
1417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Initial delay for exponential back-off in ms.
1437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  2000,
1447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Factor by which the waiting time will be multiplied.
1467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  2,
1477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Fuzzing percentage. ex: 10% will spread requests randomly
1497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // between 90%-100% of the calculated time.
1507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  0.2, // 20%
1517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Maximum amount of time we are willing to delay our request in ms.
1537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // TODO(pavely): crbug.com/246686 ProfileSyncService should retry
1547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // RequestAccessToken on connection state change after backoff
1557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  1000 * 3600 * 4, // 4 hours.
1567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Time to keep an entry from being discarded even when it
1587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // has no significant state, -1 to never discard.
1597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  -1,
1607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Don't use initial delay unless the last request was an error.
1627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  false,
1637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)};
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)static const base::FilePath::CharType kSyncDataFolderName[] =
166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FILE_PATH_LITERAL("Sync Data");
167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)static const base::FilePath::CharType kSyncBackupDataFolderName[] =
169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FILE_PATH_LITERAL("Sync Data Backup");
170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
17146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)namespace {
17246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
17303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void ClearBrowsingData(BrowsingDataRemover::Observer* observer,
17403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                       Profile* profile,
17503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                       base::Time start,
17603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                       base::Time end) {
17746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // BrowsingDataRemover deletes itself when it's done.
17846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  BrowsingDataRemover* remover = BrowsingDataRemover::CreateForRange(
17946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      profile, start, end);
18003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (observer)
18103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    remover->AddObserver(observer);
18246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  remover->Remove(BrowsingDataRemover::REMOVE_ALL,
18346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                  BrowsingDataHelper::ALL);
1846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<password_manager::PasswordStore> password =
1866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      PasswordStoreFactory::GetForProfile(profile, Profile::EXPLICIT_ACCESS);
1876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  password->RemoveLoginsSyncedBetween(start, end);
18846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
18946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
19046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}  // anonymous namespace
19146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ShouldShowActionOnUI(
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const syncer::SyncProtocolError& error) {
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (error.action != syncer::UNKNOWN_ACTION &&
195868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          error.action != syncer::DISABLE_SYNC_ON_CLIENT &&
196868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          error.action != syncer::STOP_SYNC_FOR_DISABLED_ACCOUNT);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)ProfileSyncService::ProfileSyncService(
2005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    scoped_ptr<ProfileSyncComponentsFactory> factory,
20168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    Profile* profile,
202116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    scoped_ptr<SupervisedUserSigninManagerWrapper> signin_wrapper,
20368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ProfileOAuth2TokenService* oauth2_token_service,
204a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ProfileSyncServiceStartBehavior start_behavior)
2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : OAuth2TokenService::Consumer("sync"),
2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      last_auth_error_(AuthError::AuthErrorNone()),
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      passphrase_required_reason_(syncer::REASON_PASSPHRASE_NOT_REQUIRED),
2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      factory_(factory.Pass()),
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      profile_(profile),
210f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      sync_prefs_(profile_->GetPrefs()),
211f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      sync_service_url_(GetSyncServiceURL(*CommandLine::ForCurrentProcess())),
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_first_time_sync_configure_(false),
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      backend_initialized_(false),
214868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      sync_disabled_by_admin_(false),
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_auth_in_progress_(false),
216f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      signin_(signin_wrapper.Pass()),
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unrecoverable_error_reason_(ERROR_REASON_UNSET),
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      expect_sync_configuration_aborted_(false),
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      encrypted_types_(syncer::SyncEncryptionHandler::SensitiveTypes()),
220ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch      encrypt_everything_allowed_(true),
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      encrypt_everything_(false),
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      encryption_pending_(false),
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      configure_status_(DataTypeManager::UNKNOWN),
22468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      oauth2_token_service_(oauth2_token_service),
2254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      request_access_token_backoff_(&kRequestAccessTokenBackoffPolicy),
226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      weak_factory_(this),
227a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      startup_controller_weak_factory_(this),
228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      connection_status_(syncer::CONNECTION_NOT_ATTEMPTED),
229a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      last_get_token_error_(GoogleServiceAuthError::AuthErrorNone()),
230a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      network_resources_(new syncer::HttpBridgeNetworkResources),
231a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      startup_controller_(
232a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          start_behavior,
233a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          oauth2_token_service,
234a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          &sync_prefs_,
235f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          signin_.get(),
236a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          base::Bind(&ProfileSyncService::StartUpSlowBackendComponents,
237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                     startup_controller_weak_factory_.GetWeakPtr(),
238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                     SYNC)),
239cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      backup_rollback_controller_(
240f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          &sync_prefs_,
241f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          signin_.get(),
242cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          base::Bind(&ProfileSyncService::StartUpSlowBackendComponents,
243cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                     startup_controller_weak_factory_.GetWeakPtr(),
244cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                     BACKUP),
245cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          base::Bind(&ProfileSyncService::StartUpSlowBackendComponents,
246cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                     startup_controller_weak_factory_.GetWeakPtr(),
247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                     ROLLBACK)),
248cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      backend_mode_(IDLE),
2496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      need_backup_(false),
2506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      backup_finished_(false),
25103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      clear_browsing_data_(base::Bind(&ClearBrowsingData)),
25203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      browsing_data_remover_observer_(NULL) {
253f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(profile);
2540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  syncer::SyncableService::StartSyncFlare flare(
2550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      sync_start_util::GetFlareForSyncableService(profile->GetPath()));
2560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<browser_sync::LocalSessionEventRouter> router(
2570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      new NotificationServiceSessionsRouter(profile, flare));
2585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(factory_.get());
2605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  local_device_ = factory_->CreateLocalDeviceInfoProvider();
2610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  sessions_sync_manager_.reset(
2625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      new SessionsSyncManager(profile, local_device_.get(), router.Pass()));
2631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  device_info_sync_service_.reset(
2641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new DeviceInfoSyncService(local_device_.get()));
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProfileSyncService::~ProfileSyncService() {
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_prefs_.RemoveSyncPrefObserver(this);
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Shutdown() should have been called before destruction.
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(!backend_initialized_);
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProfileSyncService::IsSyncEnabledAndLoggedIn() {
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Exit if sync is disabled.
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (IsManaged() || sync_prefs_.IsStartSuppressed())
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Sync is logged in if there is a non-empty effective username.
2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return !signin_->GetEffectiveUsername().empty();
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool ProfileSyncService::IsOAuthRefreshTokenAvailable() {
2831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!oauth2_token_service_)
2841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return false;
285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return oauth2_token_service_->RefreshTokenIsAvailable(
2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      signin_->GetAccountIdToUse());
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProfileSyncService::Initialize() {
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We clear this here (vs Shutdown) because we want to remember that an error
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // happened on shutdown so we can display details (message, location) about it
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in about:sync.
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClearStaleErrors();
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_prefs_.AddSyncPrefObserver(this);
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For now, the only thing we can do through policy is to turn sync off.
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (IsManaged()) {
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DisableForUser();
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterAuthNotifications();
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!HasSyncSetupCompleted() || signin_->GetEffectiveUsername().empty()) {
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Clean up in case of previous crash / setup abort / signout.
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DisableForUser();
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TrySyncDatatypePrefRecovery();
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_CHROMEOS)
314effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  std::string bootstrap_token = sync_prefs_.GetEncryptionBootstrapToken();
315effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (bootstrap_token.empty()) {
316effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    sync_prefs_.SetEncryptionBootstrapToken(
317effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        sync_prefs_.GetSpareBootstrapToken());
318effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if !defined(OS_ANDROID)
322effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK(sync_error_controller_ == NULL)
323effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      << "Initialize() called more than once.";
324effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  sync_error_controller_.reset(new SyncErrorController(this));
325effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  AddObserver(sync_error_controller_.get());
3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  bool running_rollback = false;
329116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (browser_sync::BackupRollbackController::IsBackupEnabled()) {
3306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // Backup is needed if user's not signed in or signed in but previous
3316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // backup didn't finish, i.e. backend didn't switch from backup to sync.
3326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    need_backup_ = signin_->GetEffectiveUsername().empty() ||
3336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        sync_prefs_.GetFirstSyncTime().is_null();
3346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // Try to resume rollback if it didn't finish in last session.
3366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    running_rollback = backup_rollback_controller_.StartRollback();
337116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  } else {
3386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    need_backup_ = false;
3396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
3406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3416d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#if defined(ENABLE_PRE_SYNC_BACKUP)
3426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (!running_rollback && signin_->GetEffectiveUsername().empty()) {
3436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    CleanUpBackup();
344116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
3456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#else
3466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(!running_rollback);
3476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#endif
3486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  startup_controller_.Reset(GetRegisteredDataTypes());
3506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  startup_controller_.TryStart();
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProfileSyncService::TrySyncDatatypePrefRecovery() {
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!sync_initialized());
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!HasSyncSetupCompleted())
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There was a bug where OnUserChoseDatatypes was not properly called on
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // configuration (see crbug.com/154940). We detect this by checking whether
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // kSyncKeepEverythingSynced has a default value. If so, and sync setup has
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // completed, it means sync was not properly configured, so we manually
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // set kSyncKeepEverythingSynced.
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrefService* const pref_service = profile_->GetPrefs();
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!pref_service)
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
366868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (GetPreferredDataTypes().Size() > 1)
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const PrefService::Preference* keep_everything_synced =
37023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      pref_service->FindPreference(
37123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)          sync_driver::prefs::kSyncKeepEverythingSynced);
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This will be false if the preference was properly set or if it's controlled
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // by policy.
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!keep_everything_synced->IsDefaultValue())
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // kSyncKeepEverythingSynced was not properly set. Set it and the preferred
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // types now, before we configure.
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS("Sync.DatatypePrefRecovery", 1);
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_prefs_.SetKeepEverythingSynced(true);
381868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  syncer::ModelTypeSet registered_types = GetRegisteredDataTypes();
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProfileSyncService::StartSyncingWithServer() {
385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (backend_)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    backend_->StartSyncingWithServer();
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProfileSyncService::RegisterAuthNotifications() {
39068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  oauth2_token_service_->AddObserver(this);
391effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (signin())
392effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    signin()->AddObserver(this);
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid ProfileSyncService::UnregisterAuthNotifications() {
396effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (signin())
397effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    signin()->RemoveObserver(this);
39868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  oauth2_token_service_->RemoveObserver(this);
399ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
400ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProfileSyncService::RegisterDataTypeController(
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DataTypeController* data_type_controller) {
4035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  DCHECK_EQ(
4045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      directory_data_type_controllers_.count(data_type_controller->type()),
4055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      0U);
406c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DCHECK(!GetRegisteredNonBlockingDataTypes().Has(
407c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      data_type_controller->type()));
4085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  directory_data_type_controllers_[data_type_controller->type()] =
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_type_controller;
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
412c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid ProfileSyncService::RegisterNonBlockingType(syncer::ModelType type) {
4135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  DCHECK_EQ(directory_data_type_controllers_.count(type), 0U)
4145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      << "Duplicate registration of type " << ModelTypeToString(type);
4155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
4165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // TODO(rlarocque): Set the enable flag properly when crbug.com/368834 is
4175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // fixed and we have some way of telling whether or not this type should be
4185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // enabled.
4195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  non_blocking_data_type_manager_.RegisterType(type, false);
4205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
4215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
4225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid ProfileSyncService::InitializeNonBlockingType(
4235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    syncer::ModelType type,
424116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const scoped_refptr<base::SequencedTaskRunner>& task_runner,
425116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const base::WeakPtr<syncer::ModelTypeSyncProxyImpl>& type_sync_proxy) {
426116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  non_blocking_data_type_manager_.InitializeType(
427116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      type, task_runner, type_sync_proxy);
428c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
429c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
4301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool ProfileSyncService::IsDataTypeControllerRunning(
4311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    syncer::ModelType type) const {
4321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DataTypeController::TypeMap::const_iterator iter =
4331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      directory_data_type_controllers_.find(type);
4341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (iter == directory_data_type_controllers_.end()) {
4351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return false;
4361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
4371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return iter->second->state() == DataTypeController::RUNNING;
438a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
439a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
440f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)browser_sync::OpenTabsUIDelegate* ProfileSyncService::GetOpenTabsUIDelegate() {
4411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!IsDataTypeControllerRunning(syncer::SESSIONS))
442f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return NULL;
4430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return sessions_sync_manager_.get();
444f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
445f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
446f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)browser_sync::FaviconCache* ProfileSyncService::GetFaviconCache() {
4470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return sessions_sync_manager_->GetFaviconCache();
448f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
449f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
4505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)browser_sync::SyncedWindowDelegatesGetter*
4515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)ProfileSyncService::GetSyncedWindowDelegatesGetter() const {
4525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return sessions_sync_manager_->GetSyncedWindowDelegatesGetter();
4535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
4545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccisync_driver::DeviceInfoTracker* ProfileSyncService::GetDeviceInfoTracker()
4561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const {
4571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!IsDataTypeControllerRunning(syncer::DEVICE_INFO))
4581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return NULL;
459a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
4601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return device_info_sync_service_.get();
461424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
462424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
4631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccisync_driver::LocalDeviceInfoProvider*
4641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciProfileSyncService::GetLocalDeviceInfoProvider() {
4651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return local_device_.get();
466424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
467424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProfileSyncService::GetDataTypeControllerStates(
4695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DataTypeController::StateMap* state_map) const {
4705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    for (DataTypeController::TypeMap::const_iterator iter =
4715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu         directory_data_type_controllers_.begin();
4725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu         iter != directory_data_type_controllers_.end();
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         ++iter)
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (*state_map)[iter->first] = iter->second.get()->state();
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SyncCredentials ProfileSyncService::GetCredentials() {
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SyncCredentials credentials;
479cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (backend_mode_ == SYNC) {
480cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    credentials.email = signin_->GetEffectiveUsername();
481cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    DCHECK(!credentials.email.empty());
482cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    credentials.sync_token = access_token_;
483cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
484cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (credentials.sync_token.empty())
485cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      credentials.sync_token = "credentials_lost";
486116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
487116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    credentials.scope_set.insert(signin_->GetSyncScopeToUse());
488cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
4897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return credentials;
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
493cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool ProfileSyncService::ShouldDeleteSyncFolder() {
4946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  switch (backend_mode_) {
4956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    case SYNC:
4966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      return !HasSyncSetupCompleted();
4976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    case BACKUP:
4986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      return true;
4996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    case ROLLBACK:
5006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      return false;
5016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    case IDLE:
5026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      NOTREACHED();
503116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return true;
504116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
5056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return true;
506cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
507cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProfileSyncService::InitializeBackend(bool delete_stale_data) {
509c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!backend_) {
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SyncCredentials credentials = GetCredentials();
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<net::URLRequestContextGetter> request_context_getter(
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      profile_->GetRequestContext());
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
519f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (backend_mode_ == SYNC && delete_stale_data)
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ClearStaleErrors();
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
522a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  scoped_ptr<syncer::UnrecoverableErrorHandler>
523a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      backend_unrecoverable_error_handler(
524a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          new browser_sync::BackendUnrecoverableErrorHandler(
525a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)              MakeWeakHandle(weak_factory_.GetWeakPtr())));
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->Initialize(
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this,
529a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      sync_thread_.Pass(),
530a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      GetJsEventHandler(),
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sync_service_url_,
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      credentials,
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delete_stale_data,
534a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      scoped_ptr<syncer::SyncManagerFactory>(
535cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          new syncer::SyncManagerFactory(GetManagerType())).Pass(),
536a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      backend_unrecoverable_error_handler.Pass(),
537a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      &browser_sync::ChromeReportUnrecoverableError,
538a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      network_resources_.get());
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProfileSyncService::IsEncryptedDatatypeEnabled() const {
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (encryption_pending())
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const syncer::ModelTypeSet preferred_types = GetPreferredDataTypes();
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const syncer::ModelTypeSet encrypted_types = GetEncryptedDataTypes();
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(encrypted_types.Has(syncer::PASSWORDS));
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return !Intersection(preferred_types, encrypted_types).Empty();
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProfileSyncService::OnSyncConfigureRetry() {
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Note: in order to handle auth failures that arise before the backend is
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // initialized (e.g. from invalidation notifier, or downloading new control
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // types), we have to gracefully handle configuration retries at all times.
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // At this point an auth error badge should be shown, which once resolved
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // will trigger a new sync cycle.
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NotifyObservers();
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
559effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid ProfileSyncService::OnProtocolEvent(
560effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    const syncer::ProtocolEvent& event) {
561effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  FOR_EACH_OBSERVER(browser_sync::ProtocolEventObserver,
562effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                    protocol_event_observers_,
563effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                    OnProtocolEvent(event));
564effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
565effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
566010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void ProfileSyncService::OnDirectoryTypeCommitCounterUpdated(
567010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    syncer::ModelType type,
568010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const syncer::CommitCounters& counters) {
569010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  FOR_EACH_OBSERVER(syncer::TypeDebugInfoObserver,
570010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                    type_debug_info_observers_,
571010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                    OnCommitCountersUpdated(type, counters));
572010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
573010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
574010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void ProfileSyncService::OnDirectoryTypeUpdateCounterUpdated(
575010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    syncer::ModelType type,
576010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const syncer::UpdateCounters& counters) {
577010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  FOR_EACH_OBSERVER(syncer::TypeDebugInfoObserver,
578010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                    type_debug_info_observers_,
579010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                    OnUpdateCountersUpdated(type, counters));
580010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
581010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
582010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void ProfileSyncService::OnDirectoryTypeStatusCounterUpdated(
583010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    syncer::ModelType type,
584010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const syncer::StatusCounters& counters) {
585010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  FOR_EACH_OBSERVER(syncer::TypeDebugInfoObserver,
586010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                    type_debug_info_observers_,
587010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                    OnStatusCountersUpdated(type, counters));
588010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
589010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ProfileSyncService::OnDataTypeRequestsSyncStartup(
591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    syncer::ModelType type) {
592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(syncer::UserTypes().Has(type));
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (backend_.get()) {
594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DVLOG(1) << "A data type requested sync startup, but it looks like "
595c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                "something else beat it to the punch.";
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
599a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!GetPreferredDataTypes().Has(type)) {
600c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // We can get here as datatype SyncableServices are typically wired up
601c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // to the native datatype even if sync isn't enabled.
602c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DVLOG(1) << "Dropping sync startup request because type "
603c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)             << syncer::ModelTypeToString(type) << "not enabled.";
604c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
606c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
607a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  startup_controller_.OnDataTypeRequestsSyncStartup(type);
608c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
609c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
610cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ProfileSyncService::StartUpSlowBackendComponents(
611cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ProfileSyncService::BackendMode mode) {
612cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK_NE(IDLE, mode);
613cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (backend_mode_ == mode) {
614cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
615cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
616cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
6176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Backend mode transition rules:
6186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // * can transit from IDLE to any other non-IDLE mode.
6196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // * forbidden to transit from SYNC to any other mode, i.e. SYNC backend must
6206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  //   be explicitly shut down before backup/rollback starts.
6216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // * can not transit out of ROLLBACK mode until rollback is finished
6226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  //   (successfully or unsuccessfully).
6236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // * can not transit out of BACKUP mode until backup is finished
6246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  //   (successfully or unsuccessfully).
6256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // * if backup is needed, can only transit to SYNC if backup is finished,
6266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
6276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (backend_mode_ == SYNC) {
6286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    LOG(DFATAL) << "Shouldn't switch from mode SYNC to mode " << mode;
6296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return;
6306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
6316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
6326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (backend_mode_ == ROLLBACK ||
6336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      (backend_mode_ == BACKUP && !backup_finished_)) {
6346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // Wait for rollback/backup to finish before start new backend.
6356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return;
6366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
6376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
6386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (mode == SYNC && NeedBackup() && !backup_finished_) {
6396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (backend_mode_ != BACKUP)
6406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      backup_rollback_controller_.StartBackup();
6416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return;
6426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
6436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
644cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DVLOG(1) << "Start backend mode: " << mode;
645cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
6465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (backend_) {
6475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (mode == SYNC)
6485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ShutdownImpl(syncer::SWITCH_MODE_SYNC);
6495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    else
6505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ShutdownImpl(syncer::STOP_SYNC);
6515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
652cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
653cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  backend_mode_ = mode;
6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (backend_mode_ == BACKUP)
6566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    backup_start_time_ = base::Time::Now();
6576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
6586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (backend_mode_ == SYNC && !backup_start_time_.is_null()) {
65903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    UMA_HISTOGRAM_MEDIUM_TIMES("Sync.FirstSyncDelayByBackup",
66003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                               base::Time::Now() - backup_start_time_);
6616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    backup_start_time_ = base::Time();
6626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
6636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
66446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (backend_mode_ == ROLLBACK)
66546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ClearBrowsingDataSinceFirstSync();
666116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  else if (backend_mode_ == SYNC)
667116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    CheckSyncBackupIfNeeded();
66846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
669cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::FilePath sync_folder = backend_mode_ == SYNC ?
670cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::FilePath(kSyncDataFolderName) :
671cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::FilePath(kSyncBackupDataFolderName);
672cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
673f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  invalidation::InvalidationService* invalidator = NULL;
674f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (backend_mode_ == SYNC) {
675f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    invalidation::ProfileInvalidationProvider* provider =
676f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        invalidation::ProfileInvalidationProviderFactory::GetForProfile(
677f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)            profile_);
678f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (provider)
679f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      invalidator = provider->GetInvalidationService();
680f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
681a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
6825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  backend_.reset(
6835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      factory_->CreateSyncBackendHost(
6845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          profile_->GetDebugName(),
6855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          profile_,
686cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          invalidator,
687cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          sync_prefs_.AsWeakPtr(),
688cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          sync_folder));
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initialize the backend.  Every time we start up a new SyncBackendHost,
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we'll want to start from a fresh SyncDB, so delete any old one that might
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be there.
693cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  InitializeBackend(ShouldDeleteSyncFolder());
69446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
69546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  UpdateFirstSyncTimePref();
69603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
69703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  NotifyObservers();
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void ProfileSyncService::OnGetTokenSuccess(
7017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const OAuth2TokenService::Request* request,
7027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const std::string& access_token,
7037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const base::Time& expiration_time) {
7047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK_EQ(access_token_request_, request);
7057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  access_token_request_.reset();
7067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  access_token_ = access_token;
707f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  token_receive_time_ = base::Time::Now();
708f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  last_get_token_error_ = GoogleServiceAuthError::AuthErrorNone();
709f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
710f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (sync_prefs_.SyncHasAuthError()) {
711f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    sync_prefs_.SetSyncAuthError(false);
712f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    UMA_HISTOGRAM_ENUMERATION("Sync.SyncAuthError",
713f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              AUTH_ERROR_FIXED,
714f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              AUTH_ERROR_LIMIT);
715f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
716f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
717cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (HasSyncingBackend())
7187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    backend_->UpdateCredentials(GetCredentials());
7197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  else
720a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    startup_controller_.TryStart();
7217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
7227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
7237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void ProfileSyncService::OnGetTokenFailure(
7247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const OAuth2TokenService::Request* request,
7257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const GoogleServiceAuthError& error) {
7267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK_EQ(access_token_request_, request);
7277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK_NE(error.state(), GoogleServiceAuthError::NONE);
7287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  access_token_request_.reset();
729f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  last_get_token_error_ = error;
7307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  switch (error.state()) {
7317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case GoogleServiceAuthError::CONNECTION_FAILED:
73203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    case GoogleServiceAuthError::REQUEST_CANCELED:
73303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    case GoogleServiceAuthError::SERVICE_ERROR:
7347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case GoogleServiceAuthError::SERVICE_UNAVAILABLE: {
7357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      // Transient error. Retry after some time.
7367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      request_access_token_backoff_.InformOfRequest(false);
737f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      next_token_request_time_ = base::Time::Now() +
738f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          request_access_token_backoff_.GetTimeUntilRelease();
7397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      request_access_token_retry_timer_.Start(
7407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            FROM_HERE,
7417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            request_access_token_backoff_.GetTimeUntilRelease(),
7427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            base::Bind(&ProfileSyncService::RequestAccessToken,
7437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                        weak_factory_.GetWeakPtr()));
744f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      NotifyObservers();
7457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      break;
7467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
7477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS: {
748f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      if (!sync_prefs_.SyncHasAuthError()) {
749f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        sync_prefs_.SetSyncAuthError(true);
750f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        UMA_HISTOGRAM_ENUMERATION("Sync.SyncAuthError",
751f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                  AUTH_ERROR_ENCOUNTERED,
752f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                  AUTH_ERROR_LIMIT);
753f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      }
7547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      // Fallthrough.
7557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
7567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    default: {
75703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      if (error.state() != GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS) {
75803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        LOG(ERROR) << "Unexpected persistent error: " << error.ToString();
75903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      }
7607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      // Show error to user.
7617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      UpdateAuthErrorState(error);
7627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
7637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
7647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
7657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
766ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid ProfileSyncService::OnRefreshTokenAvailable(
767ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    const std::string& account_id) {
7685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (account_id == signin_->GetAccountIdToUse())
76968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    OnRefreshTokensLoaded();
770ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
771ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
772ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid ProfileSyncService::OnRefreshTokenRevoked(
7733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const std::string& account_id) {
774ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!IsOAuthRefreshTokenAvailable()) {
77568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    access_token_.clear();
776ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // The additional check around IsOAuthRefreshTokenAvailable() above
777ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // prevents us sounding the alarm if we actually have a valid token but
778f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // a refresh attempt failed for any variety of reasons
779ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // (e.g. flaky network). It's possible the token we do have is also
780ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // invalid, but in that case we should already have (or can expect) an
781ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // auth error sent from the sync backend.
7823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    UpdateAuthErrorState(
7833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED));
784ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
785ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
786ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
787ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid ProfileSyncService::OnRefreshTokensLoaded() {
788f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // This notification gets fired when OAuth2TokenService loads the tokens
789ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // from storage.
790ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Initialize the backend if sync is enabled. If the sync token was
791ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // not loaded, GetCredentials() will generate invalid credentials to
792ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // cause the backend to generate an auth error (crbug.com/121755).
793cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (HasSyncingBackend()) {
794ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    RequestAccessToken();
795ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  } else {
796a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    startup_controller_.TryStart();
797ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
798ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
799ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProfileSyncService::Shutdown() {
801ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  UnregisterAuthNotifications();
802ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
8035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ShutdownImpl(syncer::BROWSER_SHUTDOWN);
804effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (sync_error_controller_) {
805effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // Destroy the SyncErrorController when the service shuts down for good.
806effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    RemoveObserver(sync_error_controller_.get());
807effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    sync_error_controller_.reset();
808effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
809a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
810a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (sync_thread_)
811a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    sync_thread_->Stop();
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ProfileSyncService::ShutdownImpl(syncer::ShutdownReason reason) {
815a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!backend_)
816a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return;
817a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
8185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  non_blocking_data_type_manager_.DisconnectSyncBackend();
8195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
820a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // First, we spin down the backend to stop change processing as soon as
821a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // possible.
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time shutdown_start_time = base::Time::Now();
823a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  backend_->StopSyncingForShutdown();
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Stop all data type controllers, if needed.  Note that until Stop
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // completes, it is possible in theory to have a ChangeProcessor apply a
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // change from a native model.  In that case, it will get applied to the sync
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // database (which doesn't get destroyed until we destroy the backend below)
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // as an unsynced change.  That will be persisted, and committed on restart.
8305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (directory_data_type_manager_) {
8315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    if (directory_data_type_manager_->state() != DataTypeManager::STOPPED) {
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // When aborting as part of shutdown, we should expect an aborted sync
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // configure result, else we'll dcheck when we try to read the sync error.
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      expect_sync_configuration_aborted_ = true;
8355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      directory_data_type_manager_->Stop();
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    directory_data_type_manager_.reset();
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Shutdown the migrator before the backend to ensure it doesn't pull a null
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // snapshot.
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  migrator_.reset();
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_js_controller_.AttachJsBackend(WeakHandle<syncer::JsBackend>());
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move aside the backend so nobody else tries to use it while we are
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // shutting it down.
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SyncBackendHost> doomed_backend(backend_.release());
848c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (doomed_backend) {
8495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    sync_thread_ = doomed_backend->Shutdown(reason);
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    doomed_backend.reset();
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeDelta shutdown_time = base::Time::Now() - shutdown_start_time;
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_TIMES("Sync.Shutdown.BackendDestroyedTime", shutdown_time);
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  weak_factory_.InvalidateWeakPtrs();
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
857cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (backend_mode_ == SYNC)
858cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    startup_controller_.Reset(GetRegisteredDataTypes());
859a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
8606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Don't let backup block sync regardless backup succeeded or not.
8616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (backend_mode_ == BACKUP)
8626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    backup_finished_ = true;
8636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
8646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Sync could be blocked by rollback/backup. Post task to check whether sync
8656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // should start after shutting down rollback/backup backend.
8666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if ((backend_mode_ == ROLLBACK || backend_mode_ == BACKUP) &&
8676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      reason != syncer::SWITCH_MODE_SYNC &&
8686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      reason != syncer::BROWSER_SHUTDOWN) {
8696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    base::MessageLoop::current()->PostTask(
8706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        FROM_HERE, base::Bind(&ProfileSyncService::TryStartSyncAfterBackup,
8716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                              startup_controller_weak_factory_.GetWeakPtr()));
8726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
8736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Clear various flags.
875cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  backend_mode_ = IDLE;
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expect_sync_configuration_aborted_ = false;
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  is_auth_in_progress_ = false;
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_initialized_ = false;
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cached_passphrase_.clear();
8804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  access_token_.clear();
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encryption_pending_ = false;
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encrypt_everything_ = false;
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encrypted_types_ = syncer::SyncEncryptionHandler::SensitiveTypes();
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  passphrase_required_reason_ = syncer::REASON_PASSPHRASE_NOT_REQUIRED;
8857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  request_access_token_retry_timer_.Stop();
8862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Revert to "no auth error".
8872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (last_auth_error_.state() != GoogleServiceAuthError::NONE)
8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateAuthErrorState(GoogleServiceAuthError::AuthErrorNone());
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
890868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NotifyObservers();
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProfileSyncService::DisableForUser() {
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Clear prefs (including SyncSetupHasCompleted) before shutting down so
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // PSS clients don't think we're set up while we're shutting down.
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_prefs_.ClearPreferences();
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClearUnrecoverableError();
8985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ShutdownImpl(syncer::DISABLE_SYNC);
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProfileSyncService::HasSyncSetupCompleted() const {
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return sync_prefs_.HasSyncSetupCompleted();
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProfileSyncService::SetSyncSetupCompleted() {
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_prefs_.SetSyncSetupCompleted();
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProfileSyncService::UpdateLastSyncedTime() {
9105b892326406927b709cdaf6c384d4ababf456332Ben Murdoch  sync_prefs_.SetLastSyncedTime(base::Time::Now());
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProfileSyncService::NotifyObservers() {
914ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  FOR_EACH_OBSERVER(ProfileSyncServiceBase::Observer, observers_,
915ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                    OnStateChanged());
916eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
917eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
918eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid ProfileSyncService::NotifySyncCycleCompleted() {
919ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  FOR_EACH_OBSERVER(ProfileSyncServiceBase::Observer, observers_,
920ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                    OnSyncCycleCompleted());
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProfileSyncService::ClearStaleErrors() {
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClearUnrecoverableError();
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_actionable_error_ = SyncProtocolError();
926c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Clear the data type errors as well.
9271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (directory_data_type_manager_.get())
9281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    directory_data_type_manager_->ResetDataTypeErrors();
9291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProfileSyncService::ClearUnrecoverableError() {
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unrecoverable_error_reason_ = ERROR_REASON_UNSET;
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unrecoverable_error_message_.clear();
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unrecoverable_error_location_ = tracked_objects::Location();
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProfileSyncService::RegisterNewDataType(syncer::ModelType data_type) {
9395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (directory_data_type_controllers_.count(data_type) > 0)
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// An invariant has been violated.  Transition to an error state where we try
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to do as little work as possible, to avoid further corruption or crashes.
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProfileSyncService::OnUnrecoverableError(
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const tracked_objects::Location& from_here,
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& message) {
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Unrecoverable errors that arrive via the syncer::UnrecoverableErrorHandler
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // interface are assumed to originate within the syncer.
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unrecoverable_error_reason_ = ERROR_REASON_SYNCER;
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OnUnrecoverableErrorImpl(from_here, message, true);
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProfileSyncService::OnUnrecoverableErrorImpl(
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const tracked_objects::Location& from_here,
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& message,
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool delete_sync_database) {
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(HasUnrecoverableError());
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unrecoverable_error_message_ = message;
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unrecoverable_error_location_ = from_here;
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_ENUMERATION(kSyncUnrecoverableErrorHistogram,
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            unrecoverable_error_reason_,
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            ERROR_REASON_LIMIT);
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NotifyObservers();
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string location;
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  from_here.Write(true, true, &location);
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(ERROR)
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << "Unrecoverable error detected at " << location
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << " -- ProfileSyncService unusable: " << message;
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Shut all data types down.
974