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 "sync/internal_api/sync_manager_impl.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/base64.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_writer.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/observer_list.h" 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_number_conversions.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/engine/sync_scheduler.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/engine/syncer_types.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/change_reorder_buffer.h" 22d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "sync/internal_api/public/base/cancelation_signal.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/base/model_type.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/base_node.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/configure_reason.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/engine/polling_constants.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/http_post_provider_factory.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/internal_components_factory.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/read_node.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/read_transaction.h" 31a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "sync/internal_api/public/sync_core_proxy.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/user_share.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/util/experiments.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/write_node.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/write_transaction.h" 36effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "sync/internal_api/sync_core.h" 37a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "sync/internal_api/sync_core_proxy_impl.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/syncapi_internal.h" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/syncapi_server_connection_manager.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/notifier/invalidation_util.h" 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/notifier/invalidator.h" 42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "sync/notifier/object_id_invalidation_map.h" 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/protocol/proto_value_conversions.h" 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/protocol/sync.pb.h" 455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "sync/sessions/directory_type_debug_info_emitter.h" 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/syncable/directory.h" 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/syncable/entry.h" 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/syncable/in_memory_directory_backing_store.h" 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/syncable/on_disk_directory_backing_store.h" 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeDelta; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using sync_pb::GetUpdatesCallerInfo; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace syncer { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using sessions::SyncSessionContext; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using syncable::ImmutableWriteTransactionInfo; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using syncable::SPECIFICS; 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using syncable::UNIQUE_POSITION; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Delays for syncer nudges. 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kDefaultNudgeDelayMilliseconds = 200; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kPreferencesNudgeDelayMilliseconds = 2000; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kSyncRefreshDelayMsec = 500; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kSyncSchedulerDelayMsec = 250; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GetUpdatesCallerInfo::GetUpdatesSource GetSourceFromReason( 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConfigureReason reason) { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (reason) { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case CONFIGURE_REASON_RECONFIGURATION: 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetUpdatesCallerInfo::RECONFIGURATION; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case CONFIGURE_REASON_MIGRATION: 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetUpdatesCallerInfo::MIGRATION; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case CONFIGURE_REASON_NEW_CLIENT: 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetUpdatesCallerInfo::NEW_CLIENT; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE: 79868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) case CONFIGURE_REASON_CRYPTO: 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetUpdatesCallerInfo::NEWLY_SUPPORTED_DATATYPE; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetUpdatesCallerInfo::UNKNOWN; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A class to calculate nudge delays for types. 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NudgeStrategy { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static TimeDelta GetNudgeDelayTimeDelta(const ModelType& model_type, 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyncManagerImpl* core) { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NudgeDelayStrategy delay_type = GetNudgeDelayStrategy(model_type); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetNudgeDelayTimeDeltaFromType(delay_type, 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_type, 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Possible types of nudge delay for datatypes. 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: These are just hints. If a sync happens then all dirty entries 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // would be committed as part of the sync. 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum NudgeDelayStrategy { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sync right away. 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IMMEDIATE, 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sync this change while syncing another change. 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ACCOMPANY_ONLY, 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The datatype does not use one of the predefined wait times but defines 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // its own wait time logic for nudge. 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CUSTOM, 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static NudgeDelayStrategy GetNudgeDelayStrategy(const ModelType& type) { 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type) { 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case AUTOFILL: 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ACCOMPANY_ONLY; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PREFERENCES: 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SESSIONS: 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case FAVICON_IMAGES: 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case FAVICON_TRACKING: 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CUSTOM; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return IMMEDIATE; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static TimeDelta GetNudgeDelayTimeDeltaFromType( 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NudgeDelayStrategy& delay_type, const ModelType& model_type, 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SyncManagerImpl* core) { 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(core); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeDelta delay = TimeDelta::FromMilliseconds( 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kDefaultNudgeDelayMilliseconds); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (delay_type) { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case IMMEDIATE: 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delay = TimeDelta::FromMilliseconds( 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kDefaultNudgeDelayMilliseconds); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ACCOMPANY_ONLY: 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delay = TimeDelta::FromSeconds(kDefaultShortPollIntervalSeconds); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case CUSTOM: 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (model_type) { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PREFERENCES: 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delay = TimeDelta::FromMilliseconds( 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kPreferencesNudgeDelayMilliseconds); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SESSIONS: 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case FAVICON_IMAGES: 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case FAVICON_TRACKING: 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delay = core->scheduler()->GetSessionsCommitDelay(); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return delay; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SyncManagerImpl::SyncManagerImpl(const std::string& name) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : name_(name), 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) change_delegate_(NULL), 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initialized_(false), 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observing_network_connectivity_changes_(false), 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) invalidator_state_(DEFAULT_INVALIDATION_ERROR), 1724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) report_unrecoverable_error_function_(NULL), 1734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) weak_ptr_factory_(this) { 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Pre-fill |notification_info_map_|. 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = FIRST_REAL_MODEL_TYPE; i < MODEL_TYPE_COUNT; ++i) { 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_info_map_.insert( 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::make_pair(ModelTypeFromInt(i), NotificationInfo())); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SyncManagerImpl::~SyncManagerImpl() { 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(!initialized_); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SyncManagerImpl::NotificationInfo::NotificationInfo() : total_count(0) {} 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SyncManagerImpl::NotificationInfo::~NotificationInfo() {} 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::DictionaryValue* SyncManagerImpl::NotificationInfo::ToValue() const { 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* value = new base::DictionaryValue(); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value->SetInteger("totalCount", total_count); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value->SetString("payload", payload); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return value; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SyncManagerImpl::VisiblePositionsDiffer( 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const syncable::EntryKernelMutation& mutation) const { 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const syncable::EntryKernel& a = mutation.original; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const syncable::EntryKernel& b = mutation.mutated; 200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!b.ShouldMaintainPosition()) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!a.ref(UNIQUE_POSITION).Equals(b.ref(UNIQUE_POSITION))) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (a.ref(syncable::PARENT_ID) != b.ref(syncable::PARENT_ID)) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SyncManagerImpl::VisiblePropertiesDiffer( 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const syncable::EntryKernelMutation& mutation, 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Cryptographer* cryptographer) const { 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const syncable::EntryKernel& a = mutation.original; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const syncable::EntryKernel& b = mutation.mutated; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const sync_pb::EntitySpecifics& a_specifics = a.ref(SPECIFICS); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const sync_pb::EntitySpecifics& b_specifics = b.ref(SPECIFICS); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(GetModelTypeFromSpecifics(a_specifics), 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetModelTypeFromSpecifics(b_specifics)); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ModelType model_type = GetModelTypeFromSpecifics(b_specifics); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Suppress updates to items that aren't tracked by any browser model. 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (model_type < FIRST_REAL_MODEL_TYPE || 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !a.ref(syncable::UNIQUE_SERVER_TAG).empty()) { 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (a.ref(syncable::IS_DIR) != b.ref(syncable::IS_DIR)) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!AreSpecificsEqual(cryptographer, 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) a.ref(syncable::SPECIFICS), 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) b.ref(syncable::SPECIFICS))) { 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We only care if the name has changed if neither specifics is encrypted 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (encrypted nodes blow away the NON_UNIQUE_NAME). 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!a_specifics.has_encrypted() && !b_specifics.has_encrypted() && 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) a.ref(syncable::NON_UNIQUE_NAME) != b.ref(syncable::NON_UNIQUE_NAME)) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (VisiblePositionsDiffer(mutation)) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ModelTypeSet SyncManagerImpl::InitialSyncEndedTypes() { 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return directory()->InitialSyncEndedTypes(); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ModelTypeSet SyncManagerImpl::GetTypesWithEmptyProgressMarkerToken( 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ModelTypeSet types) { 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ModelTypeSet result; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ModelTypeSet::Iterator i = types.First(); i.Good(); i.Inc()) { 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_pb::DataTypeProgressMarker marker; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) directory()->GetDownloadProgress(i.Get(), &marker); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (marker.token().empty()) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.Put(i.Get()); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::ConfigureSyncer( 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConfigureReason reason, 260868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ModelTypeSet to_download, 261eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ModelTypeSet to_purge, 262868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ModelTypeSet to_journal, 263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ModelTypeSet to_unapply, 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ModelSafeRoutingInfo& new_routing_info, 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& ready_task, 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& retry_task) { 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!ready_task.is_null()); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!retry_task.is_null()); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 271868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DVLOG(1) << "Configuring -" 272868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) << "\n\t" << "current types: " 273868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) << ModelTypeSetToString(GetRoutingInfoTypes(new_routing_info)) 274eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << "\n\t" << "types to download: " 275eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << ModelTypeSetToString(to_download) 276eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << "\n\t" << "types to purge: " 277eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << ModelTypeSetToString(to_purge) 278eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << "\n\t" << "types to journal: " 279868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) << ModelTypeSetToString(to_journal) 280eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << "\n\t" << "types to unapply: " 281eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << ModelTypeSetToString(to_unapply); 282eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!PurgeDisabledTypes(to_purge, 283868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) to_journal, 284868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) to_unapply)) { 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We failed to cleanup the types. Invoke the ready task without actually 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // configuring any types. The caller should detect this as a configuration 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // failure and act appropriately. 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ready_task.Run(); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConfigurationParams params(GetSourceFromReason(reason), 293868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) to_download, 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_routing_info, 295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ready_task, 296f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) retry_task); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scheduler_->Start(SyncScheduler::CONFIGURATION_MODE); 299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scheduler_->ScheduleConfiguration(params); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::Init( 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& database_location, 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const WeakHandle<JsEventHandler>& event_handler, 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& sync_server_and_path, 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int port, 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool use_ssl, 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<HttpPostProviderFactory> post_factory, 3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::vector<scoped_refptr<ModelSafeWorker> >& workers, 310a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ExtensionsActivity* extensions_activity, 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyncManager::ChangeDelegate* change_delegate, 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SyncCredentials& credentials, 313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& invalidator_client_id, 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& restored_key_for_bootstrapping, 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& restored_keystore_key_for_bootstrapping, 316a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) InternalComponentsFactory* internal_components_factory, 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Encryptor* encryptor, 318a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scoped_ptr<UnrecoverableErrorHandler> unrecoverable_error_handler, 3197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ReportUnrecoverableErrorFunction report_unrecoverable_error_function, 320d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) CancelationSignal* cancelation_signal) { 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(!initialized_); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(post_factory.get()); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!credentials.email.empty()); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!credentials.sync_token.empty()); 326d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(cancelation_signal); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "SyncManager starting Init..."; 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_handle_this_ = MakeWeakHandle(weak_ptr_factory_.GetWeakPtr()); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) change_delegate_ = change_delegate; 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddObserver(&js_sync_manager_observer_); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetJsEventHandler(event_handler); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddObserver(&debug_info_event_listener_); 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) database_path_ = database_location.Append( 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncable::Directory::kSyncDatabaseFilename); 340a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) unrecoverable_error_handler_ = unrecoverable_error_handler.Pass(); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) report_unrecoverable_error_function_ = report_unrecoverable_error_function; 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allstatus_.SetHasKeystoreKey( 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !restored_keystore_key_for_bootstrapping.empty()); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_encryption_handler_.reset(new SyncEncryptionHandlerImpl( 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &share_, 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) encryptor, 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) restored_key_for_bootstrapping, 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) restored_keystore_key_for_bootstrapping)); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_encryption_handler_->AddObserver(this); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_encryption_handler_->AddObserver(&debug_info_event_listener_); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_encryption_handler_->AddObserver(&js_sync_encryption_handler_observer_); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath absolute_db_path = database_path_; 355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(absolute_db_path.IsAbsolute()); 356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<syncable::DirectoryBackingStore> backing_store = 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) internal_components_factory->BuildDirectoryBackingStore( 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) credentials.email, absolute_db_path).Pass(); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(backing_store.get()); 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& username = credentials.email; 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) share_.directory.reset( 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new syncable::Directory( 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backing_store.release(), 366a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) unrecoverable_error_handler_.get(), 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) report_unrecoverable_error_function_, 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_encryption_handler_.get(), 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_encryption_handler_->GetCryptographerUnsafe())); 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "Username: " << username; 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!OpenDirectory(username)) { 3731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) NotifyInitializationFailure(); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Sync manager initialization failed!"; 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_manager_.reset(new SyncAPIServerConnectionManager( 3791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) sync_server_and_path, port, use_ssl, 380d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) post_factory.release(), cancelation_signal)); 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_manager_->set_client_id(directory()->cache_guid()); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_manager_->AddListener(this); 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string sync_id = directory()->cache_guid(); 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DVLOG(1) << "Setting sync client ID: " << sync_id; 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) allstatus_.SetSyncId(sync_id); 3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DVLOG(1) << "Setting invalidator client ID: " << invalidator_client_id; 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) allstatus_.SetInvalidatorClientId(invalidator_client_id); 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) model_type_registry_.reset(new ModelTypeRegistry(workers, directory())); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 393effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch sync_core_.reset(new SyncCore(model_type_registry_.get())); 394effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 395a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Bind the SyncCore WeakPtr to this thread. This helps us crash earlier if 396a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // the pointer is misused in debug mode. 397a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::WeakPtr<SyncCore> weak_core = sync_core_->AsWeakPtr(); 398a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch weak_core.get(); 399a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 400a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch sync_core_proxy_.reset( 401a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch new SyncCoreProxyImpl(base::MessageLoopProxy::current(), weak_core)); 402a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Build a SyncSessionContext and store the worker in it. 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Sync is bringing up SyncSessionContext."; 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<SyncEngineEventListener*> listeners; 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listeners.push_back(&allstatus_); 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listeners.push_back(this); 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_context_ = internal_components_factory->BuildContext( 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_manager_.get(), 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) directory(), 411a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) extensions_activity, 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listeners, 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &debug_info_event_listener_, 4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) model_type_registry_.get(), 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) invalidator_client_id).Pass(); 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_context_->set_account_name(credentials.email); 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scheduler_ = internal_components_factory->BuildScheduler( 418d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) name_, session_context_.get(), cancelation_signal).Pass(); 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scheduler_->Start(SyncScheduler::CONFIGURATION_MODE); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initialized_ = true; 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetworkChangeNotifier::AddIPAddressObserver(this); 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetworkChangeNotifier::AddConnectionTypeObserver(this); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observing_network_connectivity_changes_ = true; 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateCredentials(credentials); 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) NotifyInitializationSuccess(); 4311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 4321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 4331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void SyncManagerImpl::NotifyInitializationSuccess() { 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(SyncManager::Observer, observers_, 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnInitializationComplete( 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MakeWeakHandle(weak_ptr_factory_.GetWeakPtr()), 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MakeWeakHandle(debug_info_event_listener_.GetWeakPtr()), 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true, InitialSyncEndedTypes())); 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void SyncManagerImpl::NotifyInitializationFailure() { 4421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) FOR_EACH_OBSERVER(SyncManager::Observer, observers_, 4431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OnInitializationComplete( 4441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) MakeWeakHandle(weak_ptr_factory_.GetWeakPtr()), 4451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) MakeWeakHandle(debug_info_event_listener_.GetWeakPtr()), 4461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) false, ModelTypeSet())); 4471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 4481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::OnPassphraseRequired( 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PassphraseRequiredReason reason, 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const sync_pb::EncryptedData& pending_keys) { 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Does nothing. 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::OnPassphraseAccepted() { 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Does nothing. 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::OnBootstrapTokenUpdated( 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& bootstrap_token, 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BootstrapTokenType type) { 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type == KEYSTORE_BOOTSTRAP_TOKEN) 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allstatus_.SetHasKeystoreKey(true); 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::OnEncryptedTypesChanged(ModelTypeSet encrypted_types, 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool encrypt_everything) { 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allstatus_.SetEncryptedTypes(encrypted_types); 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::OnEncryptionComplete() { 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Does nothing. 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::OnCryptographerStateChanged( 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Cryptographer* cryptographer) { 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allstatus_.SetCryptographerReady(cryptographer->is_ready()); 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allstatus_.SetCryptoHasPendingKeys(cryptographer->has_pending_keys()); 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allstatus_.SetKeystoreMigrationTime( 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_encryption_handler_->migration_time()); 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::OnPassphraseTypeChanged( 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PassphraseType type, 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time explicit_passphrase_time) { 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allstatus_.SetPassphraseType(type); 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allstatus_.SetKeystoreMigrationTime( 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_encryption_handler_->migration_time()); 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::StartSyncingNormally( 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ModelSafeRoutingInfo& routing_info) { 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start the sync scheduler. 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(sync): We always want the newest set of routes when we switch back 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to normal mode. Figure out how to enforce set_routing_info is always 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // appropriately set and that it's only modified when switching to normal 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // mode. 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 4995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) session_context_->SetRoutingInfo(routing_info); 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scheduler_->Start(SyncScheduler::NORMAL_MODE); 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)syncable::Directory* SyncManagerImpl::directory() { 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return share_.directory.get(); 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SyncScheduler* SyncManagerImpl::scheduler() const { 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return scheduler_.get(); 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SyncManagerImpl::GetHasInvalidAuthTokenForTest() const { 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return connection_manager_->HasInvalidAuthToken(); 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SyncManagerImpl::OpenDirectory(const std::string& username) { 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!initialized_) << "Should only happen once"; 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set before Open(). 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) change_observer_ = MakeWeakHandle(js_mutation_event_observer_.AsWeakPtr()); 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WeakHandle<syncable::TransactionObserver> transaction_observer( 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MakeWeakHandle(js_mutation_event_observer_.AsWeakPtr())); 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncable::DirOpenResult open_result = syncable::NOT_INITIALIZED; 5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) open_result = directory()->Open(username, this, transaction_observer); 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (open_result != syncable::OPENED) { 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "Could not open share for:" << username; 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Unapplied datatypes (those that do not have initial sync ended set) get 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // re-downloaded during any configuration. But, it's possible for a datatype 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to have a progress marker but not have initial sync ended yet, making 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it a candidate for migration. This is a problem, as the DataTypeManager 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // does not support a migration while it's already in the middle of a 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // configuration. As a result, any partially synced datatype can stall the 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // DTM, waiting for the configuration to complete, which it never will due 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to the migration error. In addition, a partially synced nigori will 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // trigger the migration logic before the backend is initialized, resulting 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in crashes. We therefore detect and purge any partially synced types as 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // part of initialization. 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!PurgePartiallySyncedTypes()) 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SyncManagerImpl::PurgePartiallySyncedTypes() { 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ModelTypeSet partially_synced_types = ModelTypeSet::All(); 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) partially_synced_types.RemoveAll(InitialSyncEndedTypes()); 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) partially_synced_types.RemoveAll(GetTypesWithEmptyProgressMarkerToken( 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ModelTypeSet::All())); 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "Purging partially synced types " 5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << ModelTypeSetToString(partially_synced_types); 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_COUNTS("Sync.PartiallySyncedTypes", 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) partially_synced_types.Size()); 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (partially_synced_types.Empty()) 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return directory()->PurgeEntriesWithTypeIn(partially_synced_types, 560868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ModelTypeSet(), 5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ModelTypeSet()); 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SyncManagerImpl::PurgeDisabledTypes( 565eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ModelTypeSet to_purge, 566868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ModelTypeSet to_journal, 567868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ModelTypeSet to_unapply) { 568eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (to_purge.Empty()) 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 570eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DVLOG(1) << "Purging disabled types " << ModelTypeSetToString(to_purge); 571eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(to_purge.HasAll(to_journal)); 572eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(to_purge.HasAll(to_unapply)); 573eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return directory()->PurgeEntriesWithTypeIn(to_purge, to_journal, to_unapply); 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncManagerImpl::UpdateCredentials(const SyncCredentials& credentials) { 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(initialized_); 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!credentials.email.empty()); 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!credentials.sync_token.empty()); 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observing_network_connectivity_changes_ = true; 5837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!connection_manager_->SetAuthToken(credentials.sync_token)) 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; // Auth token is known to be invalid, so exit early. 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scheduler_->OnCredentialsUpdated(); 587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // TODO(zea): pass the credential age to the debug info event listener. 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::AddObserver(SyncManager::Observer* observer) { 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observers_.AddObserver(observer); 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::RemoveObserver(SyncManager::Observer* observer) { 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observers_.RemoveObserver(observer); 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::ShutdownOnSyncThread() { 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Prevent any in-flight method calls from running. Also 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // invalidates |weak_handle_this_| and |change_observer_|. 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_.InvalidateWeakPtrs(); 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) js_mutation_event_observer_.InvalidateWeakPtrs(); 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scheduler_.reset(); 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_context_.reset(); 6115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) model_type_registry_.reset(); 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 613c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (sync_encryption_handler_) { 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_encryption_handler_->RemoveObserver(&debug_info_event_listener_); 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_encryption_handler_->RemoveObserver(this); 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetJsEventHandler(WeakHandle<JsEventHandler>()); 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveObserver(&js_sync_manager_observer_); 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveObserver(&debug_info_event_listener_); 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 623eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // |connection_manager_| may end up being NULL here in tests (in synchronous 624eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // initialization mode). 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(akalin): Fix this behavior. 627c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (connection_manager_) 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_manager_->RemoveListener(this); 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_manager_.reset(); 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetworkChangeNotifier::RemoveIPAddressObserver(this); 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this); 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observing_network_connectivity_changes_ = false; 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (initialized_ && directory()) { 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) directory()->SaveChanges(); 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) share_.directory.reset(); 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) change_delegate_ = NULL; 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initialized_ = false; 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We reset these here, since only now we know they will not be 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // accessed from other threads (since we shut down everything). 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) change_observer_.Reset(); 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_handle_this_.Reset(); 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::OnIPAddressChanged() { 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!observing_network_connectivity_changes_) { 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "IP address change dropped."; 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "IP address change detected."; 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnNetworkConnectivityChangedImpl(); 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::OnConnectionTypeChanged( 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetworkChangeNotifier::ConnectionType) { 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!observing_network_connectivity_changes_) { 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Connection type change dropped."; 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Connection type change detected."; 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnNetworkConnectivityChangedImpl(); 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::OnNetworkConnectivityChangedImpl() { 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scheduler_->OnConnectionStatusChange(); 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::OnServerConnectionEvent( 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ServerConnectionEvent& event) { 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event.connection_code == 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpResponse::SERVER_CONNECTION_OK) { 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(SyncManager::Observer, observers_, 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnConnectionStatusChange(CONNECTION_OK)); 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event.connection_code == HttpResponse::SYNC_AUTH_ERROR) { 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observing_network_connectivity_changes_ = false; 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(SyncManager::Observer, observers_, 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnConnectionStatusChange(CONNECTION_AUTH_ERROR)); 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event.connection_code == HttpResponse::SYNC_SERVER_ERROR) { 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(SyncManager::Observer, observers_, 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnConnectionStatusChange(CONNECTION_SERVER_ERROR)); 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::HandleTransactionCompleteChangeEvent( 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ModelTypeSet models_with_changes) { 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This notification happens immediately after the transaction mutex is 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // released. This allows work to be performed without blocking other threads 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // from acquiring a transaction. 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!change_delegate_) 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Call commit. 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ModelTypeSet::Iterator it = models_with_changes.First(); 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it.Good(); it.Inc()) { 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) change_delegate_->OnChangesComplete(it.Get()); 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) change_observer_.Call( 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &SyncManager::ChangeObserver::OnChangesComplete, 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it.Get()); 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ModelTypeSet 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SyncManagerImpl::HandleTransactionEndingChangeEvent( 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ImmutableWriteTransactionInfo& write_transaction_info, 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncable::BaseTransaction* trans) { 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This notification happens immediately before a syncable WriteTransaction 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // falls out of scope. It happens while the channel mutex is still held, 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and while the transaction mutex is held, so it cannot be re-entrant. 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!change_delegate_ || change_records_.empty()) 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ModelTypeSet(); 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This will continue the WriteTransaction using a read only wrapper. 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is the last chance for read to occur in the WriteTransaction 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that's closing. This special ReadTransaction will not close the 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // underlying transaction. 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadTransaction read_trans(GetUserShare(), trans); 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ModelTypeSet models_with_changes; 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ChangeRecordMap::const_iterator it = change_records_.begin(); 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != change_records_.end(); ++it) { 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!it->second.Get().empty()); 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ModelType type = ModelTypeFromInt(it->first); 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) change_delegate_-> 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnChangesApplied(type, trans->directory()->GetTransactionVersion(type), 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &read_trans, it->second); 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) change_observer_.Call(FROM_HERE, 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &SyncManager::ChangeObserver::OnChangesApplied, 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type, write_transaction_info.Get().id, it->second); 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) models_with_changes.Put(type); 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) change_records_.clear(); 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return models_with_changes; 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::HandleCalculateChangesChangeEventFromSyncApi( 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ImmutableWriteTransactionInfo& write_transaction_info, 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncable::BaseTransaction* trans, 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<int64>* entries_changed) { 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We have been notified about a user action changing a sync model. 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG_IF(WARNING, !change_records_.empty()) << 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "CALCULATE_CHANGES called with unapplied old changes."; 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The mutated model type, or UNSPECIFIED if nothing was mutated. 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ModelTypeSet mutated_model_types; 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const syncable::ImmutableEntryKernelMutationMap& mutations = 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_transaction_info.Get().mutations; 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (syncable::EntryKernelMutationMap::const_iterator it = 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mutations.Get().begin(); it != mutations.Get().end(); ++it) { 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!it->second.mutated.ref(syncable::IS_UNSYNCED)) { 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ModelType model_type = 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetModelTypeFromSpecifics(it->second.mutated.ref(SPECIFICS)); 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (model_type < FIRST_REAL_MODEL_TYPE) { 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Permanent or underspecified item changed via syncapi."; 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Found real mutation. 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (model_type != UNSPECIFIED) { 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mutated_model_types.Put(model_type); 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries_changed->push_back(it->second.mutated.ref(syncable::META_HANDLE)); 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Nudge if necessary. 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!mutated_model_types.Empty()) { 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (weak_handle_this_.IsInitialized()) { 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_handle_this_.Call(FROM_HERE, 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &SyncManagerImpl::RequestNudgeForDataTypes, 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mutated_model_types); 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::SetExtraChangeRecordData(int64 id, 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ModelType type, ChangeReorderBuffer* buffer, 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Cryptographer* cryptographer, const syncable::EntryKernel& original, 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool existed_before, bool exists_now) { 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If this is a deletion and the datatype was encrypted, we need to decrypt it 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and attach it to the buffer. 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!exists_now && existed_before) { 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_pb::EntitySpecifics original_specifics(original.ref(SPECIFICS)); 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type == PASSWORDS) { 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Passwords must use their own legacy ExtraPasswordChangeRecordData. 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<sync_pb::PasswordSpecificsData> data( 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DecryptPasswordSpecifics(original_specifics, cryptographer)); 806c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!data) { 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer->SetExtraDataForId(id, new ExtraPasswordChangeRecordData(*data)); 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (original_specifics.has_encrypted()) { 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // All other datatypes can just create a new unencrypted specifics and 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // attach it. 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const sync_pb::EncryptedData& encrypted = original_specifics.encrypted(); 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!cryptographer->Decrypt(encrypted, &original_specifics)) { 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer->SetSpecificsForId(id, original_specifics); 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::HandleCalculateChangesChangeEventFromSyncer( 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ImmutableWriteTransactionInfo& write_transaction_info, 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncable::BaseTransaction* trans, 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<int64>* entries_changed) { 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We only expect one notification per sync step, so change_buffers_ should 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // contain no pending entries. 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG_IF(WARNING, !change_records_.empty()) << 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "CALCULATE_CHANGES called with unapplied old changes."; 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChangeReorderBuffer change_buffers[MODEL_TYPE_COUNT]; 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Cryptographer* crypto = directory()->GetCryptographer(trans); 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const syncable::ImmutableEntryKernelMutationMap& mutations = 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_transaction_info.Get().mutations; 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (syncable::EntryKernelMutationMap::const_iterator it = 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mutations.Get().begin(); it != mutations.Get().end(); ++it) { 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool existed_before = !it->second.original.ref(syncable::IS_DEL); 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool exists_now = !it->second.mutated.ref(syncable::IS_DEL); 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Omit items that aren't associated with a model. 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ModelType type = 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetModelTypeFromSpecifics(it->second.mutated.ref(SPECIFICS)); 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type < FIRST_REAL_MODEL_TYPE) 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 handle = it->first; 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exists_now && !existed_before) 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) change_buffers[type].PushAddedItem(handle); 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (!exists_now && existed_before) 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) change_buffers[type].PushDeletedItem(handle); 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (exists_now && existed_before && 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisiblePropertiesDiffer(it->second, crypto)) { 8567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) change_buffers[type].PushUpdatedItem(handle); 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetExtraChangeRecordData(handle, type, &change_buffers[type], crypto, 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it->second.original, existed_before, exists_now); 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadTransaction read_trans(GetUserShare(), trans); 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = FIRST_REAL_MODEL_TYPE; i < MODEL_TYPE_COUNT; ++i) { 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!change_buffers[i].IsEmpty()) { 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (change_buffers[i].GetAllChangesInTreeOrder(&read_trans, 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &(change_records_[i]))) { 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t j = 0; j < change_records_[i].Get().size(); ++j) 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries_changed->push_back((change_records_[i].Get())[j].id); 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (change_records_[i].Get().empty()) 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) change_records_.erase(i); 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TimeDelta SyncManagerImpl::GetNudgeDelayTimeDelta( 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ModelType& model_type) { 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NudgeStrategy::GetNudgeDelayTimeDelta(model_type, this); 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::RequestNudgeForDataTypes( 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const tracked_objects::Location& nudge_location, 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ModelTypeSet types) { 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) debug_info_event_listener_.OnNudgeFromDatatype(types.First().Get()); 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(lipalani) : Calculate the nudge delay based on all types. 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta nudge_delay = NudgeStrategy::GetNudgeDelayTimeDelta( 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) types.First().Get(), 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this); 891b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) scheduler_->ScheduleLocalNudge(nudge_delay, 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) types, 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nudge_location); 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SyncManagerImpl::OnSyncCycleEvent(const SyncCycleEvent& event) { 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only send an event if this is due to a cycle ending and this cycle 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // concludes a canonical "sync" process; that is, based on what is known 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // locally we are "all happy" and up-to-date. There may be new changes on 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the server, but we'll get them on a subsequent sync. 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Notifications are sent at the end of every sync cycle, regardless of 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // whether we should sync again. 9055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (event.what_happened == SyncCycleEvent::SYNC_CYCLE_ENDED) { 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!initialized_) { 907f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << "OnSyncCycleCompleted not sent because sync api is not " 908f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) << "initialized"; 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Sending OnSyncCycleCompleted"; 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(SyncManager::Observer, observers_, 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnSyncCycleCompleted(event.snapshot)); 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SyncManagerImpl::OnActionableError(const SyncProtocolError& error) { 9195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FOR_EACH_OBSERVER( 9205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SyncManager::Observer, observers_, 9215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnActionableError(error)); 9225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SyncManagerImpl::OnRetryTimeChanged(base::Time) {} 9255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 9265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SyncManagerImpl::OnThrottledTypesChanged(ModelTypeSet) {} 9275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 9285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SyncManagerImpl::OnMigrationRequested(ModelTypeSet types) { 9295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FOR_EACH_OBSERVER( 9305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SyncManager::Observer, observers_, 9315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnMigrationRequested(types)); 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 934effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid SyncManagerImpl::OnProtocolEvent(const ProtocolEvent& event) { 935e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch protocol_event_buffer_.RecordProtocolEvent(event); 936effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch FOR_EACH_OBSERVER(SyncManager::Observer, observers_, 937effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch OnProtocolEvent(event)); 938effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 939effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::SetJsEventHandler( 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const WeakHandle<JsEventHandler>& event_handler) { 942a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) js_sync_manager_observer_.SetJsEventHandler(event_handler); 943a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) js_mutation_event_observer_.SetJsEventHandler(event_handler); 944a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) js_sync_encryption_handler_observer_.SetJsEventHandler(event_handler); 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 947c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochscoped_ptr<base::ListValue> SyncManagerImpl::GetAllNodesForType( 948c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch syncer::ModelType type) { 949c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DirectoryTypeDebugInfoEmitterMap* emitter_map = 950c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch model_type_registry_->directory_type_debug_info_emitter_map(); 951c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DirectoryTypeDebugInfoEmitterMap::iterator it = emitter_map->find(type); 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 953c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (it == emitter_map->end()) { 9545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // This can happen in some cases. The UI thread makes requests of us 9555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // when it doesn't really know which types are enabled or disabled. 9565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DLOG(WARNING) << "Asked to return debug info for invalid type " 9575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu << ModelTypeToString(type); 958c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return scoped_ptr<base::ListValue>(); 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 961c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return it->second->GetAllNodes(); 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::OnInvalidatorStateChange(InvalidatorState state) { 965eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(thread_checker_.CalledOnValidThread()); 966eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& state_str = InvalidatorStateToString(state); 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) invalidator_state_ = state; 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Invalidator state changed to: " << state_str; 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool notifications_enabled = 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (invalidator_state_ == INVALIDATIONS_ENABLED); 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allstatus_.SetNotificationsEnabled(notifications_enabled); 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scheduler_->SetNotificationsEnabled(notifications_enabled); 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::OnIncomingInvalidation( 9772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ObjectIdInvalidationMap& invalidation_map) { 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 9792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 98058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // We should never receive IDs from non-sync objects. 9814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ObjectIdSet ids = invalidation_map.GetObjectIds(); 98258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) for (ObjectIdSet::const_iterator it = ids.begin(); it != ids.end(); ++it) { 98358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ModelType type; 98458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!ObjectIdToRealModelType(*it, &type)) { 98558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DLOG(WARNING) << "Notification has invalid id: " << ObjectIdToString(*it); 98658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 98758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 98858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 9894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (invalidation_map.Empty()) { 9902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(WARNING) << "Sync received invalidation without any type information."; 9912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 992b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) scheduler_->ScheduleInvalidationNudge( 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeDelta::FromMilliseconds(kSyncSchedulerDelayMsec), 99458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) invalidation_map, FROM_HERE); 99558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) debug_info_event_listener_.OnIncomingNotification(invalidation_map); 9962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 9972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 999a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)std::string SyncManagerImpl::GetOwnerName() const { return "SyncManagerImpl"; } 1000a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 10012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncManagerImpl::RefreshTypes(ModelTypeSet types) { 10022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 1003b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (types.Empty()) { 10042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(WARNING) << "Sync received refresh request with no types specified."; 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1006b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) scheduler_->ScheduleLocalRefreshRequest( 10072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TimeDelta::FromMilliseconds(kSyncRefreshDelayMsec), 1008b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) types, FROM_HERE); 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SyncStatus SyncManagerImpl::GetDetailedStatus() const { 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return allstatus_.status(); 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::SaveChanges() { 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) directory()->SaveChanges(); 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UserShare* SyncManagerImpl::GetUserShare() { 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(initialized_); 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &share_; 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochsyncer::SyncCoreProxy* SyncManagerImpl::GetSyncCoreProxy() { 1026effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK(initialized_); 1027a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return sync_core_proxy_.get(); 1028effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 1029effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 10302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const std::string SyncManagerImpl::cache_guid() { 10312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(initialized_); 10322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return directory()->cache_guid(); 10332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 10342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SyncManagerImpl::ReceivedExperiment(Experiments* experiments) { 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadTransaction trans(FROM_HERE, GetUserShare()); 10372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReadNode nigori_node(&trans); 103846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (nigori_node.InitTypeRoot(NIGORI) != BaseNode::INIT_OK) { 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Couldn't find Nigori node."; 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool found_experiment = false; 10432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReadNode favicon_sync_node(&trans); 10452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (favicon_sync_node.InitByClientTagLookup( 10462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) syncer::EXPERIMENTS, 1047c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) syncer::kFaviconSyncTag) == BaseNode::INIT_OK) { 1048c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) experiments->favicon_sync_limit = 1049c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) favicon_sync_node.GetExperimentsSpecifics().favicon_sync(). 1050c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) favicon_sync_limit(); 10512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) found_experiment = true; 10522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 10532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1054ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ReadNode pre_commit_update_avoidance_node(&trans); 1055ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (pre_commit_update_avoidance_node.InitByClientTagLookup( 1056ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch syncer::EXPERIMENTS, 1057ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch syncer::kPreCommitUpdateAvoidanceTag) == BaseNode::INIT_OK) { 1058ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_context_->set_server_enabled_pre_commit_update_avoidance( 1059ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch pre_commit_update_avoidance_node.GetExperimentsSpecifics(). 1060ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch pre_commit_update_avoidance().enabled()); 1061ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // We don't bother setting found_experiment. The frontend doesn't need to 1062ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // know about this. 1063ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 1064ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 10655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ReadNode gcm_channel_node(&trans); 10665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (gcm_channel_node.InitByClientTagLookup( 10675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) syncer::EXPERIMENTS, 10685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) syncer::kGCMChannelTag) == BaseNode::INIT_OK && 10695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gcm_channel_node.GetExperimentsSpecifics().gcm_channel().has_enabled()) { 10705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) experiments->gcm_channel_state = 10715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (gcm_channel_node.GetExperimentsSpecifics().gcm_channel().enabled() ? 10725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) syncer::Experiments::ENABLED : syncer::Experiments::SUPPRESSED); 10735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) found_experiment = true; 10745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 10755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 10765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ReadNode enhanced_bookmarks_node(&trans); 10775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (enhanced_bookmarks_node.InitByClientTagLookup( 10785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) syncer::EXPERIMENTS, syncer::kEnhancedBookmarksTag) == 10795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BaseNode::INIT_OK && 10805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) enhanced_bookmarks_node.GetExperimentsSpecifics() 10815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) .has_enhanced_bookmarks()) { 10825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const sync_pb::EnhancedBookmarksFlags& enhanced_bookmarks = 10835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) enhanced_bookmarks_node.GetExperimentsSpecifics().enhanced_bookmarks(); 10845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (enhanced_bookmarks.has_enabled()) 10855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) experiments->enhanced_bookmarks_enabled = enhanced_bookmarks.enabled(); 10865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (enhanced_bookmarks.has_extension_id()) { 10875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) experiments->enhanced_bookmarks_ext_id = 10885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) enhanced_bookmarks.extension_id(); 10895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 10905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) found_experiment = true; 10915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 10925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1093effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ReadNode gcm_invalidations_node(&trans); 1094effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (gcm_invalidations_node.InitByClientTagLookup( 1095effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch syncer::EXPERIMENTS, syncer::kGCMInvalidationsTag) == 1096effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch BaseNode::INIT_OK) { 1097effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const sync_pb::GcmInvalidationsFlags& gcm_invalidations = 1098effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch gcm_invalidations_node.GetExperimentsSpecifics().gcm_invalidations(); 1099effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (gcm_invalidations.has_enabled()) { 1100effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch experiments->gcm_invalidations_enabled = gcm_invalidations.enabled(); 1101effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch found_experiment = true; 1102effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 1103effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 1104effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return found_experiment; 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SyncManagerImpl::HasUnsyncedItems() { 11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadTransaction trans(FROM_HERE, GetUserShare()); 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (trans.GetWrappedTrans()->directory()->unsynced_entity_count() != 0); 11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SyncEncryptionHandler* SyncManagerImpl::GetEncryptionHandler() { 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sync_encryption_handler_.get(); 11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1117e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochScopedVector<syncer::ProtocolEvent> 1118e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch SyncManagerImpl::GetBufferedProtocolEvents() { 1119e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return protocol_event_buffer_.GetBufferedProtocolEvents(); 1120e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 1121e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 1122010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void SyncManagerImpl::RegisterDirectoryTypeDebugInfoObserver( 1123010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) syncer::TypeDebugInfoObserver* observer) { 1124010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) model_type_registry_->RegisterDirectoryTypeDebugInfoObserver(observer); 1125010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 1126010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 1127010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void SyncManagerImpl::UnregisterDirectoryTypeDebugInfoObserver( 1128010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) syncer::TypeDebugInfoObserver* observer) { 1129010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) model_type_registry_->UnregisterDirectoryTypeDebugInfoObserver(observer); 1130010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 1131010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 1132010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool SyncManagerImpl::HasDirectoryTypeDebugInfoObserver( 1133010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) syncer::TypeDebugInfoObserver* observer) { 1134010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return model_type_registry_->HasDirectoryTypeDebugInfoObserver(observer); 1135010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 1136010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 1137010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void SyncManagerImpl::RequestEmitDebugInfo() { 1138010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) model_type_registry_->RequestEmitDebugInfo(); 1139010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 1140010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static. 11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SyncManagerImpl::GetDefaultNudgeDelay() { 11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kDefaultNudgeDelayMilliseconds; 11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static. 11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SyncManagerImpl::GetPreferencesNudgeDelay() { 11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kPreferencesNudgeDelayMilliseconds; 11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace syncer 1152