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" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/user_share.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/util/experiments.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/write_node.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/write_transaction.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/syncapi_internal.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/syncapi_server_connection_manager.h" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/js/js_arg_list.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/js/js_event_details.h" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/js/js_event_handler.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/js/js_reply_handler.h" 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/notifier/invalidation_util.h" 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/notifier/invalidator.h" 43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "sync/notifier/object_id_invalidation_map.h" 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/protocol/proto_value_conversions.h" 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/protocol/sync.pb.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)// Maximum count and size for traffic recorder. 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const unsigned int kMaxMessagesToRecord = 10; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const unsigned int kMaxMessageSizeToRecord = 5 * 1024; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GetUpdatesCallerInfo::GetUpdatesSource GetSourceFromReason( 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConfigureReason reason) { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (reason) { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case CONFIGURE_REASON_RECONFIGURATION: 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetUpdatesCallerInfo::RECONFIGURATION; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case CONFIGURE_REASON_MIGRATION: 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetUpdatesCallerInfo::MIGRATION; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case CONFIGURE_REASON_NEW_CLIENT: 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetUpdatesCallerInfo::NEW_CLIENT; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE: 83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) case CONFIGURE_REASON_CRYPTO: 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetUpdatesCallerInfo::NEWLY_SUPPORTED_DATATYPE; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetUpdatesCallerInfo::UNKNOWN; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A class to calculate nudge delays for types. 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NudgeStrategy { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static TimeDelta GetNudgeDelayTimeDelta(const ModelType& model_type, 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyncManagerImpl* core) { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NudgeDelayStrategy delay_type = GetNudgeDelayStrategy(model_type); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetNudgeDelayTimeDeltaFromType(delay_type, 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_type, 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Possible types of nudge delay for datatypes. 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: These are just hints. If a sync happens then all dirty entries 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // would be committed as part of the sync. 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum NudgeDelayStrategy { 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sync right away. 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IMMEDIATE, 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sync this change while syncing another change. 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ACCOMPANY_ONLY, 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The datatype does not use one of the predefined wait times but defines 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // its own wait time logic for nudge. 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CUSTOM, 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static NudgeDelayStrategy GetNudgeDelayStrategy(const ModelType& type) { 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type) { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case AUTOFILL: 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ACCOMPANY_ONLY; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PREFERENCES: 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SESSIONS: 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case FAVICON_IMAGES: 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case FAVICON_TRACKING: 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CUSTOM; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return IMMEDIATE; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static TimeDelta GetNudgeDelayTimeDeltaFromType( 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NudgeDelayStrategy& delay_type, const ModelType& model_type, 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SyncManagerImpl* core) { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(core); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeDelta delay = TimeDelta::FromMilliseconds( 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kDefaultNudgeDelayMilliseconds); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (delay_type) { 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case IMMEDIATE: 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delay = TimeDelta::FromMilliseconds( 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kDefaultNudgeDelayMilliseconds); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ACCOMPANY_ONLY: 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delay = TimeDelta::FromSeconds(kDefaultShortPollIntervalSeconds); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case CUSTOM: 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (model_type) { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PREFERENCES: 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delay = TimeDelta::FromMilliseconds( 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kPreferencesNudgeDelayMilliseconds); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SESSIONS: 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case FAVICON_IMAGES: 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case FAVICON_TRACKING: 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delay = core->scheduler()->GetSessionsCommitDelay(); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return delay; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SyncManagerImpl::SyncManagerImpl(const std::string& name) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : name_(name), 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) change_delegate_(NULL), 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initialized_(false), 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observing_network_connectivity_changes_(false), 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) invalidator_state_(DEFAULT_INVALIDATION_ERROR), 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) traffic_recorder_(kMaxMessagesToRecord, kMaxMessageSizeToRecord), 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) encryptor_(NULL), 1784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) report_unrecoverable_error_function_(NULL), 1794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) weak_ptr_factory_(this) { 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Pre-fill |notification_info_map_|. 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = FIRST_REAL_MODEL_TYPE; i < MODEL_TYPE_COUNT; ++i) { 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_info_map_.insert( 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::make_pair(ModelTypeFromInt(i), NotificationInfo())); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Bind message handlers. 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BindJsMessageHandler( 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "getNotificationState", 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &SyncManagerImpl::GetNotificationState); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BindJsMessageHandler( 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "getNotificationInfo", 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &SyncManagerImpl::GetNotificationInfo); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BindJsMessageHandler( 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "getRootNodeDetails", 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &SyncManagerImpl::GetRootNodeDetails); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BindJsMessageHandler( 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "getNodeSummariesById", 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &SyncManagerImpl::GetNodeSummariesById); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BindJsMessageHandler( 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "getNodeDetailsById", 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &SyncManagerImpl::GetNodeDetailsById); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BindJsMessageHandler( 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "getAllNodes", 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &SyncManagerImpl::GetAllNodes); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BindJsMessageHandler( 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "getChildNodeIds", 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &SyncManagerImpl::GetChildNodeIds); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BindJsMessageHandler( 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "getClientServerTraffic", 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &SyncManagerImpl::GetClientServerTraffic); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SyncManagerImpl::~SyncManagerImpl() { 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(!initialized_); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SyncManagerImpl::NotificationInfo::NotificationInfo() : total_count(0) {} 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SyncManagerImpl::NotificationInfo::~NotificationInfo() {} 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::DictionaryValue* SyncManagerImpl::NotificationInfo::ToValue() const { 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* value = new base::DictionaryValue(); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value->SetInteger("totalCount", total_count); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value->SetString("payload", payload); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return value; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SyncManagerImpl::VisiblePositionsDiffer( 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const syncable::EntryKernelMutation& mutation) const { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const syncable::EntryKernel& a = mutation.original; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const syncable::EntryKernel& b = mutation.mutated; 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!b.ShouldMaintainPosition()) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!a.ref(UNIQUE_POSITION).Equals(b.ref(UNIQUE_POSITION))) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (a.ref(syncable::PARENT_ID) != b.ref(syncable::PARENT_ID)) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SyncManagerImpl::VisiblePropertiesDiffer( 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const syncable::EntryKernelMutation& mutation, 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Cryptographer* cryptographer) const { 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const syncable::EntryKernel& a = mutation.original; 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const syncable::EntryKernel& b = mutation.mutated; 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const sync_pb::EntitySpecifics& a_specifics = a.ref(SPECIFICS); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const sync_pb::EntitySpecifics& b_specifics = b.ref(SPECIFICS); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(GetModelTypeFromSpecifics(a_specifics), 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetModelTypeFromSpecifics(b_specifics)); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ModelType model_type = GetModelTypeFromSpecifics(b_specifics); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Suppress updates to items that aren't tracked by any browser model. 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (model_type < FIRST_REAL_MODEL_TYPE || 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !a.ref(syncable::UNIQUE_SERVER_TAG).empty()) { 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (a.ref(syncable::IS_DIR) != b.ref(syncable::IS_DIR)) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!AreSpecificsEqual(cryptographer, 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) a.ref(syncable::SPECIFICS), 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) b.ref(syncable::SPECIFICS))) { 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We only care if the name has changed if neither specifics is encrypted 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (encrypted nodes blow away the NON_UNIQUE_NAME). 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!a_specifics.has_encrypted() && !b_specifics.has_encrypted() && 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) a.ref(syncable::NON_UNIQUE_NAME) != b.ref(syncable::NON_UNIQUE_NAME)) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (VisiblePositionsDiffer(mutation)) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::ThrowUnrecoverableError() { 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadTransaction trans(FROM_HERE, GetUserShare()); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) trans.GetWrappedTrans()->OnUnrecoverableError( 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, "Simulating unrecoverable error for testing purposes."); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ModelTypeSet SyncManagerImpl::InitialSyncEndedTypes() { 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return directory()->InitialSyncEndedTypes(); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ModelTypeSet SyncManagerImpl::GetTypesWithEmptyProgressMarkerToken( 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ModelTypeSet types) { 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ModelTypeSet result; 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ModelTypeSet::Iterator i = types.First(); i.Good(); i.Inc()) { 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_pb::DataTypeProgressMarker marker; 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) directory()->GetDownloadProgress(i.Get(), &marker); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (marker.token().empty()) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.Put(i.Get()); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::ConfigureSyncer( 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConfigureReason reason, 299868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ModelTypeSet to_download, 300eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ModelTypeSet to_purge, 301868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ModelTypeSet to_journal, 302868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ModelTypeSet to_unapply, 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ModelSafeRoutingInfo& new_routing_info, 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& ready_task, 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& retry_task) { 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!ready_task.is_null()); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!retry_task.is_null()); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 310868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DVLOG(1) << "Configuring -" 311868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) << "\n\t" << "current types: " 312868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) << ModelTypeSetToString(GetRoutingInfoTypes(new_routing_info)) 313eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << "\n\t" << "types to download: " 314eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << ModelTypeSetToString(to_download) 315eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << "\n\t" << "types to purge: " 316eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << ModelTypeSetToString(to_purge) 317eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << "\n\t" << "types to journal: " 318868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) << ModelTypeSetToString(to_journal) 319eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << "\n\t" << "types to unapply: " 320eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << ModelTypeSetToString(to_unapply); 321eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!PurgeDisabledTypes(to_purge, 322868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) to_journal, 323868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) to_unapply)) { 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We failed to cleanup the types. Invoke the ready task without actually 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // configuring any types. The caller should detect this as a configuration 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // failure and act appropriately. 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ready_task.Run(); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConfigurationParams params(GetSourceFromReason(reason), 332868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) to_download, 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_routing_info, 334f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ready_task, 335f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) retry_task); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scheduler_->Start(SyncScheduler::CONFIGURATION_MODE); 338f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scheduler_->ScheduleConfiguration(params); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::Init( 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& database_location, 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const WeakHandle<JsEventHandler>& event_handler, 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& sync_server_and_path, 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int port, 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool use_ssl, 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<HttpPostProviderFactory> post_factory, 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<ModelSafeWorker*>& workers, 349a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ExtensionsActivity* extensions_activity, 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyncManager::ChangeDelegate* change_delegate, 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SyncCredentials& credentials, 352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& invalidator_client_id, 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& restored_key_for_bootstrapping, 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& restored_keystore_key_for_bootstrapping, 355a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) InternalComponentsFactory* internal_components_factory, 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Encryptor* encryptor, 357a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scoped_ptr<UnrecoverableErrorHandler> unrecoverable_error_handler, 3587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ReportUnrecoverableErrorFunction report_unrecoverable_error_function, 359d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) CancelationSignal* cancelation_signal) { 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(!initialized_); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(post_factory.get()); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!credentials.email.empty()); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!credentials.sync_token.empty()); 365d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(cancelation_signal); 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "SyncManager starting Init..."; 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_handle_this_ = MakeWeakHandle(weak_ptr_factory_.GetWeakPtr()); 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) change_delegate_ = change_delegate; 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddObserver(&js_sync_manager_observer_); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetJsEventHandler(event_handler); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddObserver(&debug_info_event_listener_); 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) database_path_ = database_location.Append( 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncable::Directory::kSyncDatabaseFilename); 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) encryptor_ = encryptor; 380a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) unrecoverable_error_handler_ = unrecoverable_error_handler.Pass(); 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) report_unrecoverable_error_function_ = report_unrecoverable_error_function; 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allstatus_.SetHasKeystoreKey( 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !restored_keystore_key_for_bootstrapping.empty()); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_encryption_handler_.reset(new SyncEncryptionHandlerImpl( 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &share_, 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) encryptor, 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) restored_key_for_bootstrapping, 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) restored_keystore_key_for_bootstrapping)); 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_encryption_handler_->AddObserver(this); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_encryption_handler_->AddObserver(&debug_info_event_listener_); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_encryption_handler_->AddObserver(&js_sync_encryption_handler_observer_); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath absolute_db_path = database_path_; 395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(absolute_db_path.IsAbsolute()); 396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<syncable::DirectoryBackingStore> backing_store = 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) internal_components_factory->BuildDirectoryBackingStore( 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) credentials.email, absolute_db_path).Pass(); 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(backing_store.get()); 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& username = credentials.email; 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) share_.directory.reset( 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new syncable::Directory( 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backing_store.release(), 406a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) unrecoverable_error_handler_.get(), 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) report_unrecoverable_error_function_, 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_encryption_handler_.get(), 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_encryption_handler_->GetCryptographerUnsafe())); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "Username: " << username; 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!OpenDirectory(username)) { 4131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) NotifyInitializationFailure(); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Sync manager initialization failed!"; 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_manager_.reset(new SyncAPIServerConnectionManager( 4191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) sync_server_and_path, port, use_ssl, 420d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) post_factory.release(), cancelation_signal)); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_manager_->set_client_id(directory()->cache_guid()); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_manager_->AddListener(this); 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string sync_id = directory()->cache_guid(); 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) allstatus_.SetSyncId(sync_id); 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) allstatus_.SetInvalidatorClientId(invalidator_client_id); 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "Setting sync client ID: " << sync_id; 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "Setting invalidator client ID: " << invalidator_client_id; 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Build a SyncSessionContext and store the worker in it. 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Sync is bringing up SyncSessionContext."; 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<SyncEngineEventListener*> listeners; 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listeners.push_back(&allstatus_); 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listeners.push_back(this); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_context_ = internal_components_factory->BuildContext( 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_manager_.get(), 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) directory(), 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers, 441a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) extensions_activity, 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listeners, 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &debug_info_event_listener_, 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &traffic_recorder_, 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) invalidator_client_id).Pass(); 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_context_->set_account_name(credentials.email); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scheduler_ = internal_components_factory->BuildScheduler( 448d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) name_, session_context_.get(), cancelation_signal).Pass(); 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scheduler_->Start(SyncScheduler::CONFIGURATION_MODE); 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initialized_ = true; 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetworkChangeNotifier::AddIPAddressObserver(this); 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetworkChangeNotifier::AddConnectionTypeObserver(this); 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observing_network_connectivity_changes_ = true; 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateCredentials(credentials); 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) NotifyInitializationSuccess(); 4611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 4621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 4631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void SyncManagerImpl::NotifyInitializationSuccess() { 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(SyncManager::Observer, observers_, 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnInitializationComplete( 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MakeWeakHandle(weak_ptr_factory_.GetWeakPtr()), 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MakeWeakHandle(debug_info_event_listener_.GetWeakPtr()), 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true, InitialSyncEndedTypes())); 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void SyncManagerImpl::NotifyInitializationFailure() { 4721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) FOR_EACH_OBSERVER(SyncManager::Observer, observers_, 4731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OnInitializationComplete( 4741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) MakeWeakHandle(weak_ptr_factory_.GetWeakPtr()), 4751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) MakeWeakHandle(debug_info_event_listener_.GetWeakPtr()), 4761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) false, ModelTypeSet())); 4771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 4781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::OnPassphraseRequired( 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PassphraseRequiredReason reason, 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const sync_pb::EncryptedData& pending_keys) { 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Does nothing. 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::OnPassphraseAccepted() { 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Does nothing. 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::OnBootstrapTokenUpdated( 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& bootstrap_token, 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BootstrapTokenType type) { 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type == KEYSTORE_BOOTSTRAP_TOKEN) 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allstatus_.SetHasKeystoreKey(true); 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::OnEncryptedTypesChanged(ModelTypeSet encrypted_types, 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool encrypt_everything) { 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allstatus_.SetEncryptedTypes(encrypted_types); 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::OnEncryptionComplete() { 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Does nothing. 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::OnCryptographerStateChanged( 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Cryptographer* cryptographer) { 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allstatus_.SetCryptographerReady(cryptographer->is_ready()); 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allstatus_.SetCryptoHasPendingKeys(cryptographer->has_pending_keys()); 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allstatus_.SetKeystoreMigrationTime( 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_encryption_handler_->migration_time()); 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::OnPassphraseTypeChanged( 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PassphraseType type, 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time explicit_passphrase_time) { 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allstatus_.SetPassphraseType(type); 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allstatus_.SetKeystoreMigrationTime( 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_encryption_handler_->migration_time()); 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::StartSyncingNormally( 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ModelSafeRoutingInfo& routing_info) { 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start the sync scheduler. 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(sync): We always want the newest set of routes when we switch back 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to normal mode. Figure out how to enforce set_routing_info is always 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // appropriately set and that it's only modified when switching to normal 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // mode. 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_context_->set_routing_info(routing_info); 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scheduler_->Start(SyncScheduler::NORMAL_MODE); 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)syncable::Directory* SyncManagerImpl::directory() { 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return share_.directory.get(); 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SyncScheduler* SyncManagerImpl::scheduler() const { 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return scheduler_.get(); 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SyncManagerImpl::GetHasInvalidAuthTokenForTest() const { 5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return connection_manager_->HasInvalidAuthToken(); 5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SyncManagerImpl::OpenDirectory(const std::string& username) { 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!initialized_) << "Should only happen once"; 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set before Open(). 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) change_observer_ = MakeWeakHandle(js_mutation_event_observer_.AsWeakPtr()); 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WeakHandle<syncable::TransactionObserver> transaction_observer( 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MakeWeakHandle(js_mutation_event_observer_.AsWeakPtr())); 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncable::DirOpenResult open_result = syncable::NOT_INITIALIZED; 5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) open_result = directory()->Open(username, this, transaction_observer); 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (open_result != syncable::OPENED) { 5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "Could not open share for:" << username; 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Unapplied datatypes (those that do not have initial sync ended set) get 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // re-downloaded during any configuration. But, it's possible for a datatype 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to have a progress marker but not have initial sync ended yet, making 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it a candidate for migration. This is a problem, as the DataTypeManager 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // does not support a migration while it's already in the middle of a 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // configuration. As a result, any partially synced datatype can stall the 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // DTM, waiting for the configuration to complete, which it never will due 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to the migration error. In addition, a partially synced nigori will 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // trigger the migration logic before the backend is initialized, resulting 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in crashes. We therefore detect and purge any partially synced types as 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // part of initialization. 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!PurgePartiallySyncedTypes()) 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SyncManagerImpl::PurgePartiallySyncedTypes() { 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ModelTypeSet partially_synced_types = ModelTypeSet::All(); 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) partially_synced_types.RemoveAll(InitialSyncEndedTypes()); 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) partially_synced_types.RemoveAll(GetTypesWithEmptyProgressMarkerToken( 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ModelTypeSet::All())); 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "Purging partially synced types " 5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << ModelTypeSetToString(partially_synced_types); 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_COUNTS("Sync.PartiallySyncedTypes", 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) partially_synced_types.Size()); 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (partially_synced_types.Empty()) 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return directory()->PurgeEntriesWithTypeIn(partially_synced_types, 590868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ModelTypeSet(), 5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ModelTypeSet()); 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SyncManagerImpl::PurgeDisabledTypes( 595eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ModelTypeSet to_purge, 596868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ModelTypeSet to_journal, 597868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ModelTypeSet to_unapply) { 598eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (to_purge.Empty()) 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 600eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DVLOG(1) << "Purging disabled types " << ModelTypeSetToString(to_purge); 601eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(to_purge.HasAll(to_journal)); 602eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(to_purge.HasAll(to_unapply)); 603eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return directory()->PurgeEntriesWithTypeIn(to_purge, to_journal, to_unapply); 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncManagerImpl::UpdateCredentials(const SyncCredentials& credentials) { 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(initialized_); 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!credentials.email.empty()); 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!credentials.sync_token.empty()); 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observing_network_connectivity_changes_ = true; 6137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!connection_manager_->SetAuthToken(credentials.sync_token)) 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; // Auth token is known to be invalid, so exit early. 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scheduler_->OnCredentialsUpdated(); 617c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 618c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // TODO(zea): pass the credential age to the debug info event listener. 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::AddObserver(SyncManager::Observer* observer) { 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observers_.AddObserver(observer); 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::RemoveObserver(SyncManager::Observer* observer) { 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observers_.RemoveObserver(observer); 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::ShutdownOnSyncThread() { 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Prevent any in-flight method calls from running. Also 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // invalidates |weak_handle_this_| and |change_observer_|. 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_.InvalidateWeakPtrs(); 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) js_mutation_event_observer_.InvalidateWeakPtrs(); 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scheduler_.reset(); 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_context_.reset(); 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 642c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (sync_encryption_handler_) { 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_encryption_handler_->RemoveObserver(&debug_info_event_listener_); 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_encryption_handler_->RemoveObserver(this); 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetJsEventHandler(WeakHandle<JsEventHandler>()); 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveObserver(&js_sync_manager_observer_); 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveObserver(&debug_info_event_listener_); 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 652eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // |connection_manager_| may end up being NULL here in tests (in synchronous 653eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // initialization mode). 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(akalin): Fix this behavior. 656c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (connection_manager_) 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_manager_->RemoveListener(this); 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_manager_.reset(); 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetworkChangeNotifier::RemoveIPAddressObserver(this); 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this); 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observing_network_connectivity_changes_ = false; 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (initialized_ && directory()) { 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) directory()->SaveChanges(); 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) share_.directory.reset(); 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) change_delegate_ = NULL; 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initialized_ = false; 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We reset these here, since only now we know they will not be 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // accessed from other threads (since we shut down everything). 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) change_observer_.Reset(); 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_handle_this_.Reset(); 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::OnIPAddressChanged() { 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!observing_network_connectivity_changes_) { 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "IP address change dropped."; 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "IP address change detected."; 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnNetworkConnectivityChangedImpl(); 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::OnConnectionTypeChanged( 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetworkChangeNotifier::ConnectionType) { 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!observing_network_connectivity_changes_) { 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Connection type change dropped."; 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Connection type change detected."; 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnNetworkConnectivityChangedImpl(); 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::OnNetworkConnectivityChangedImpl() { 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scheduler_->OnConnectionStatusChange(); 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::OnServerConnectionEvent( 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ServerConnectionEvent& event) { 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event.connection_code == 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpResponse::SERVER_CONNECTION_OK) { 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(SyncManager::Observer, observers_, 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnConnectionStatusChange(CONNECTION_OK)); 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event.connection_code == HttpResponse::SYNC_AUTH_ERROR) { 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observing_network_connectivity_changes_ = false; 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(SyncManager::Observer, observers_, 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnConnectionStatusChange(CONNECTION_AUTH_ERROR)); 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event.connection_code == HttpResponse::SYNC_SERVER_ERROR) { 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(SyncManager::Observer, observers_, 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnConnectionStatusChange(CONNECTION_SERVER_ERROR)); 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::HandleTransactionCompleteChangeEvent( 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ModelTypeSet models_with_changes) { 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This notification happens immediately after the transaction mutex is 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // released. This allows work to be performed without blocking other threads 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // from acquiring a transaction. 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!change_delegate_) 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Call commit. 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ModelTypeSet::Iterator it = models_with_changes.First(); 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it.Good(); it.Inc()) { 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) change_delegate_->OnChangesComplete(it.Get()); 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) change_observer_.Call( 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &SyncManager::ChangeObserver::OnChangesComplete, 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it.Get()); 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ModelTypeSet 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SyncManagerImpl::HandleTransactionEndingChangeEvent( 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ImmutableWriteTransactionInfo& write_transaction_info, 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncable::BaseTransaction* trans) { 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This notification happens immediately before a syncable WriteTransaction 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // falls out of scope. It happens while the channel mutex is still held, 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and while the transaction mutex is held, so it cannot be re-entrant. 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!change_delegate_ || change_records_.empty()) 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ModelTypeSet(); 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This will continue the WriteTransaction using a read only wrapper. 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is the last chance for read to occur in the WriteTransaction 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that's closing. This special ReadTransaction will not close the 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // underlying transaction. 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadTransaction read_trans(GetUserShare(), trans); 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ModelTypeSet models_with_changes; 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ChangeRecordMap::const_iterator it = change_records_.begin(); 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != change_records_.end(); ++it) { 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!it->second.Get().empty()); 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ModelType type = ModelTypeFromInt(it->first); 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) change_delegate_-> 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnChangesApplied(type, trans->directory()->GetTransactionVersion(type), 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &read_trans, it->second); 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) change_observer_.Call(FROM_HERE, 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &SyncManager::ChangeObserver::OnChangesApplied, 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type, write_transaction_info.Get().id, it->second); 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) models_with_changes.Put(type); 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) change_records_.clear(); 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return models_with_changes; 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::HandleCalculateChangesChangeEventFromSyncApi( 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ImmutableWriteTransactionInfo& write_transaction_info, 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncable::BaseTransaction* trans, 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<int64>* entries_changed) { 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We have been notified about a user action changing a sync model. 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG_IF(WARNING, !change_records_.empty()) << 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "CALCULATE_CHANGES called with unapplied old changes."; 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The mutated model type, or UNSPECIFIED if nothing was mutated. 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ModelTypeSet mutated_model_types; 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const syncable::ImmutableEntryKernelMutationMap& mutations = 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_transaction_info.Get().mutations; 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (syncable::EntryKernelMutationMap::const_iterator it = 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mutations.Get().begin(); it != mutations.Get().end(); ++it) { 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!it->second.mutated.ref(syncable::IS_UNSYNCED)) { 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ModelType model_type = 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetModelTypeFromSpecifics(it->second.mutated.ref(SPECIFICS)); 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (model_type < FIRST_REAL_MODEL_TYPE) { 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Permanent or underspecified item changed via syncapi."; 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Found real mutation. 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (model_type != UNSPECIFIED) { 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mutated_model_types.Put(model_type); 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries_changed->push_back(it->second.mutated.ref(syncable::META_HANDLE)); 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Nudge if necessary. 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!mutated_model_types.Empty()) { 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (weak_handle_this_.IsInitialized()) { 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_handle_this_.Call(FROM_HERE, 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &SyncManagerImpl::RequestNudgeForDataTypes, 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mutated_model_types); 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::SetExtraChangeRecordData(int64 id, 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ModelType type, ChangeReorderBuffer* buffer, 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Cryptographer* cryptographer, const syncable::EntryKernel& original, 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool existed_before, bool exists_now) { 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If this is a deletion and the datatype was encrypted, we need to decrypt it 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and attach it to the buffer. 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!exists_now && existed_before) { 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_pb::EntitySpecifics original_specifics(original.ref(SPECIFICS)); 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type == PASSWORDS) { 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Passwords must use their own legacy ExtraPasswordChangeRecordData. 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<sync_pb::PasswordSpecificsData> data( 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DecryptPasswordSpecifics(original_specifics, cryptographer)); 835c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!data) { 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer->SetExtraDataForId(id, new ExtraPasswordChangeRecordData(*data)); 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (original_specifics.has_encrypted()) { 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // All other datatypes can just create a new unencrypted specifics and 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // attach it. 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const sync_pb::EncryptedData& encrypted = original_specifics.encrypted(); 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!cryptographer->Decrypt(encrypted, &original_specifics)) { 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer->SetSpecificsForId(id, original_specifics); 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::HandleCalculateChangesChangeEventFromSyncer( 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ImmutableWriteTransactionInfo& write_transaction_info, 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncable::BaseTransaction* trans, 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<int64>* entries_changed) { 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We only expect one notification per sync step, so change_buffers_ should 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // contain no pending entries. 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG_IF(WARNING, !change_records_.empty()) << 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "CALCULATE_CHANGES called with unapplied old changes."; 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChangeReorderBuffer change_buffers[MODEL_TYPE_COUNT]; 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Cryptographer* crypto = directory()->GetCryptographer(trans); 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const syncable::ImmutableEntryKernelMutationMap& mutations = 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_transaction_info.Get().mutations; 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (syncable::EntryKernelMutationMap::const_iterator it = 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mutations.Get().begin(); it != mutations.Get().end(); ++it) { 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool existed_before = !it->second.original.ref(syncable::IS_DEL); 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool exists_now = !it->second.mutated.ref(syncable::IS_DEL); 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Omit items that aren't associated with a model. 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ModelType type = 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetModelTypeFromSpecifics(it->second.mutated.ref(SPECIFICS)); 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type < FIRST_REAL_MODEL_TYPE) 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 handle = it->first; 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exists_now && !existed_before) 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) change_buffers[type].PushAddedItem(handle); 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (!exists_now && existed_before) 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) change_buffers[type].PushDeletedItem(handle); 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (exists_now && existed_before && 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisiblePropertiesDiffer(it->second, crypto)) { 8857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) change_buffers[type].PushUpdatedItem(handle); 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetExtraChangeRecordData(handle, type, &change_buffers[type], crypto, 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it->second.original, existed_before, exists_now); 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadTransaction read_trans(GetUserShare(), trans); 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = FIRST_REAL_MODEL_TYPE; i < MODEL_TYPE_COUNT; ++i) { 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!change_buffers[i].IsEmpty()) { 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (change_buffers[i].GetAllChangesInTreeOrder(&read_trans, 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &(change_records_[i]))) { 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t j = 0; j < change_records_[i].Get().size(); ++j) 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries_changed->push_back((change_records_[i].Get())[j].id); 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (change_records_[i].Get().empty()) 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) change_records_.erase(i); 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TimeDelta SyncManagerImpl::GetNudgeDelayTimeDelta( 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ModelType& model_type) { 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NudgeStrategy::GetNudgeDelayTimeDelta(model_type, this); 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::RequestNudgeForDataTypes( 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const tracked_objects::Location& nudge_location, 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ModelTypeSet types) { 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) debug_info_event_listener_.OnNudgeFromDatatype(types.First().Get()); 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(lipalani) : Calculate the nudge delay based on all types. 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta nudge_delay = NudgeStrategy::GetNudgeDelayTimeDelta( 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) types.First().Get(), 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this); 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allstatus_.IncrementNudgeCounter(NUDGE_SOURCE_LOCAL); 921b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) scheduler_->ScheduleLocalNudge(nudge_delay, 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) types, 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nudge_location); 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::OnSyncEngineEvent(const SyncEngineEvent& event) { 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only send an event if this is due to a cycle ending and this cycle 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // concludes a canonical "sync" process; that is, based on what is known 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // locally we are "all happy" and up-to-date. There may be new changes on 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the server, but we'll get them on a subsequent sync. 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Notifications are sent at the end of every sync cycle, regardless of 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // whether we should sync again. 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event.what_happened == SyncEngineEvent::SYNC_CYCLE_ENDED) { 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!initialized_) { 937f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << "OnSyncCycleCompleted not sent because sync api is not " 938f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) << "initialized"; 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Sending OnSyncCycleCompleted"; 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(SyncManager::Observer, observers_, 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnSyncCycleCompleted(event.snapshot)); 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event.what_happened == SyncEngineEvent::STOP_SYNCING_PERMANENTLY) { 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(SyncManager::Observer, observers_, 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnStopSyncingPermanently()); 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event.what_happened == SyncEngineEvent::ACTIONABLE_ERROR) { 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER( 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyncManager::Observer, observers_, 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnActionableError( 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event.snapshot.model_neutral_state().sync_protocol_error)); 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::SetJsEventHandler( 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const WeakHandle<JsEventHandler>& event_handler) { 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) js_event_handler_ = event_handler; 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) js_sync_manager_observer_.SetJsEventHandler(js_event_handler_); 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) js_mutation_event_observer_.SetJsEventHandler(js_event_handler_); 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) js_sync_encryption_handler_observer_.SetJsEventHandler(js_event_handler_); 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::ProcessJsMessage( 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& name, const JsArgList& args, 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const WeakHandle<JsReplyHandler>& reply_handler) { 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!initialized_) { 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!reply_handler.IsInitialized()) { 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Uninitialized reply handler; dropping unknown message " 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << name << " with args " << args.ToString(); 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) JsMessageHandler js_message_handler = js_message_handlers_[name]; 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (js_message_handler.is_null()) { 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Dropping unknown message " << name 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " with args " << args.ToString(); 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reply_handler.Call(FROM_HERE, 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &JsReplyHandler::HandleJsReply, 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name, js_message_handler.Run(args)); 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::BindJsMessageHandler( 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& name, 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UnboundJsMessageHandler unbound_message_handler) { 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) js_message_handlers_[name] = 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(unbound_message_handler, base::Unretained(this)); 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::DictionaryValue* SyncManagerImpl::NotificationInfoToValue( 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NotificationInfoMap& notification_info) { 10052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* value = new base::DictionaryValue(); 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (NotificationInfoMap::const_iterator it = notification_info.begin(); 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != notification_info.end(); ++it) { 10094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const std::string model_type_str = ModelTypeToString(it->first); 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value->Set(model_type_str, it->second.ToValue()); 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return value; 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string SyncManagerImpl::NotificationInfoToString( 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NotificationInfoMap& notification_info) { 10182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> value( 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotificationInfoToValue(notification_info)); 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string str; 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::JSONWriter::Write(value.get(), &str); 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return str; 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)JsArgList SyncManagerImpl::GetNotificationState( 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const JsArgList& args) { 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& notification_state = 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InvalidatorStateToString(invalidator_state_); 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "GetNotificationState: " << notification_state; 10302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue return_args; 10312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return_args.Append(new base::StringValue(notification_state)); 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return JsArgList(&return_args); 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)JsArgList SyncManagerImpl::GetNotificationInfo( 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const JsArgList& args) { 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "GetNotificationInfo: " 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << NotificationInfoToString(notification_info_map_); 10392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue return_args; 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return_args.Append(NotificationInfoToValue(notification_info_map_)); 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return JsArgList(&return_args); 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)JsArgList SyncManagerImpl::GetRootNodeDetails( 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const JsArgList& args) { 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadTransaction trans(FROM_HERE, GetUserShare()); 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadNode root(&trans); 10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root.InitByRootLookup(); 10492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue return_args; 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return_args.Append(root.GetDetailsAsValue()); 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return JsArgList(&return_args); 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)JsArgList SyncManagerImpl::GetClientServerTraffic( 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const JsArgList& args) { 10562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue return_args; 10572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* value = traffic_recorder_.ToValue(); 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (value != NULL) 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return_args.Append(value); 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return JsArgList(&return_args); 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int64 GetId(const base::ListValue& ids, int i) { 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string id_str; 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ids.GetString(i, &id_str)) { 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kInvalidId; 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 id = kInvalidId; 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!base::StringToInt64(id_str, &id)) { 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kInvalidId; 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return id; 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)JsArgList GetNodeInfoById( 10782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const JsArgList& args, 10792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UserShare* user_share, 10802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* (BaseNode::*info_getter)() const) { 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(info_getter); 10822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue return_args; 10832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* node_summaries = new base::ListValue(); 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return_args.Append(node_summaries); 10852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::ListValue* id_list = NULL; 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadTransaction trans(FROM_HERE, user_share); 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (args.Get().GetList(0, &id_list)) { 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(id_list); 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < id_list->GetSize(); ++i) { 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 id = GetId(*id_list, i); 10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (id == kInvalidId) { 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadNode node(&trans); 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node.InitByIdLookup(id) != BaseNode::INIT_OK) { 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node_summaries->Append((node.*info_getter)()); 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return JsArgList(&return_args); 11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)JsArgList SyncManagerImpl::GetNodeSummariesById(const JsArgList& args) { 11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetNodeInfoById(args, GetUserShare(), &BaseNode::GetSummaryAsValue); 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)JsArgList SyncManagerImpl::GetNodeDetailsById(const JsArgList& args) { 11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetNodeInfoById(args, GetUserShare(), &BaseNode::GetDetailsAsValue); 11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)JsArgList SyncManagerImpl::GetAllNodes(const JsArgList& args) { 11152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue return_args; 11162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* result = new base::ListValue(); 11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return_args.Append(result); 11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadTransaction trans(FROM_HERE, GetUserShare()); 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<const syncable::EntryKernel*> entry_kernels; 11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) trans.GetDirectory()->GetAllEntryKernels(trans.GetWrappedTrans(), 11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &entry_kernels); 11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<const syncable::EntryKernel*>::const_iterator it = 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry_kernels.begin(); it != entry_kernels.end(); ++it) { 11262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->Append((*it)->ToValue(trans.GetCryptographer())); 11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return JsArgList(&return_args); 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)JsArgList SyncManagerImpl::GetChildNodeIds(const JsArgList& args) { 11332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue return_args; 11342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* child_ids = new base::ListValue(); 11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return_args.Append(child_ids); 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 id = GetId(args.Get(), 0); 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (id != kInvalidId) { 11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadTransaction trans(FROM_HERE, GetUserShare()); 1139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) syncable::Directory::Metahandles child_handles; 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) trans.GetDirectory()->GetChildHandlesByHandle(trans.GetWrappedTrans(), 11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id, &child_handles); 1142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (syncable::Directory::Metahandles::const_iterator it = 11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) child_handles.begin(); it != child_handles.end(); ++it) { 11442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child_ids->Append(new base::StringValue(base::Int64ToString(*it))); 11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return JsArgList(&return_args); 11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::UpdateNotificationInfo( 115158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const ObjectIdInvalidationMap& invalidation_map) { 11524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ObjectIdSet ids = invalidation_map.GetObjectIds(); 11534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (ObjectIdSet::const_iterator it = ids.begin(); it != ids.end(); ++it) { 115458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ModelType type = UNSPECIFIED; 11554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!ObjectIdToRealModelType(*it, &type)) { 11564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) continue; 11574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 11584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const SingleObjectInvalidationSet& type_invalidations = 11594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) invalidation_map.ForObject(*it); 11604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (SingleObjectInvalidationSet::const_iterator inv_it = 11614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) type_invalidations.begin(); inv_it != type_invalidations.end(); 11624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ++inv_it) { 116358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) NotificationInfo* info = ¬ification_info_map_[type]; 116458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) info->total_count++; 11654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::string payload = 11664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) inv_it->is_unknown_version() ? "UNKNOWN" : inv_it->payload(); 11674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) info->payload = payload; 116858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::OnInvalidatorStateChange(InvalidatorState state) { 1173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(thread_checker_.CalledOnValidThread()); 1174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& state_str = InvalidatorStateToString(state); 11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) invalidator_state_ = state; 11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Invalidator state changed to: " << state_str; 11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool notifications_enabled = 11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (invalidator_state_ == INVALIDATIONS_ENABLED); 11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allstatus_.SetNotificationsEnabled(notifications_enabled); 11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scheduler_->SetNotificationsEnabled(notifications_enabled); 11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (js_event_handler_.IsInitialized()) { 11842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue details; 11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) details.SetString("state", state_str); 11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) js_event_handler_.Call(FROM_HERE, 11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &JsEventHandler::HandleJsEvent, 11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "onNotificationStateChange", 11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) JsEventDetails(&details)); 11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::OnIncomingInvalidation( 11942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ObjectIdInvalidationMap& invalidation_map) { 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 11962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 119758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // We should never receive IDs from non-sync objects. 11984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ObjectIdSet ids = invalidation_map.GetObjectIds(); 119958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) for (ObjectIdSet::const_iterator it = ids.begin(); it != ids.end(); ++it) { 120058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ModelType type; 120158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!ObjectIdToRealModelType(*it, &type)) { 120258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DLOG(WARNING) << "Notification has invalid id: " << ObjectIdToString(*it); 120358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 120458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 120558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 12064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (invalidation_map.Empty()) { 12072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(WARNING) << "Sync received invalidation without any type information."; 12082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allstatus_.IncrementNudgeCounter(NUDGE_SOURCE_NOTIFICATION); 1210b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) scheduler_->ScheduleInvalidationNudge( 12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeDelta::FromMilliseconds(kSyncSchedulerDelayMsec), 121258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) invalidation_map, FROM_HERE); 12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allstatus_.IncrementNotificationsReceived(); 121458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) UpdateNotificationInfo(invalidation_map); 121558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) debug_info_event_listener_.OnIncomingNotification(invalidation_map); 12162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 12172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (js_event_handler_.IsInitialized()) { 12192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue details; 12202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* changed_types = new base::ListValue(); 12212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) details.Set("changedTypes", changed_types); 12224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 12234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ObjectIdSet id_set = invalidation_map.GetObjectIds(); 122458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ModelTypeSet nudged_types = ObjectIdSetToModelTypeSet(id_set); 122558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(!nudged_types.Empty()); 122658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) for (ModelTypeSet::Iterator it = nudged_types.First(); 122758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) it.Good(); it.Inc()) { 122858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::string model_type_str = ModelTypeToString(it.Get()); 12292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) changed_types->Append(new base::StringValue(model_type_str)); 12302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 12312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) details.SetString("source", "REMOTE_INVALIDATION"); 12322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) js_event_handler_.Call(FROM_HERE, 12332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &JsEventHandler::HandleJsEvent, 12342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "onIncomingNotification", 12352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) JsEventDetails(&details)); 12362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 12372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 12382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncManagerImpl::RefreshTypes(ModelTypeSet types) { 12402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 1241b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (types.Empty()) { 12422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(WARNING) << "Sync received refresh request with no types specified."; 12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 12442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) allstatus_.IncrementNudgeCounter(NUDGE_SOURCE_LOCAL_REFRESH); 1245b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) scheduler_->ScheduleLocalRefreshRequest( 12462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TimeDelta::FromMilliseconds(kSyncRefreshDelayMsec), 1247b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) types, FROM_HERE); 12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (js_event_handler_.IsInitialized()) { 12512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue details; 12522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* changed_types = new base::ListValue(); 12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) details.Set("changedTypes", changed_types); 1254b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) for (ModelTypeSet::Iterator it = types.First(); it.Good(); it.Inc()) { 12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& model_type_str = 1256b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ModelTypeToString(it.Get()); 12572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) changed_types->Append(new base::StringValue(model_type_str)); 12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) details.SetString("source", "LOCAL_INVALIDATION"); 12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) js_event_handler_.Call(FROM_HERE, 12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &JsEventHandler::HandleJsEvent, 12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "onIncomingNotification", 12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) JsEventDetails(&details)); 12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SyncStatus SyncManagerImpl::GetDetailedStatus() const { 12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return allstatus_.status(); 12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncManagerImpl::SaveChanges() { 12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) directory()->SaveChanges(); 12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UserShare* SyncManagerImpl::GetUserShare() { 12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(initialized_); 12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &share_; 12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const std::string SyncManagerImpl::cache_guid() { 12812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(initialized_); 12822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return directory()->cache_guid(); 12832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 12842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SyncManagerImpl::ReceivedExperiment(Experiments* experiments) { 12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadTransaction trans(FROM_HERE, GetUserShare()); 12872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReadNode nigori_node(&trans); 12882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (nigori_node.InitByTagLookup(kNigoriTag) != BaseNode::INIT_OK) { 12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Couldn't find Nigori node."; 12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool found_experiment = false; 12932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReadNode autofill_culling_node(&trans); 12952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (autofill_culling_node.InitByClientTagLookup( 12962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) syncer::EXPERIMENTS, 12972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) syncer::kAutofillCullingTag) == BaseNode::INIT_OK && 12982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) autofill_culling_node.GetExperimentsSpecifics(). 12992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) autofill_culling().enabled()) { 13002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) experiments->autofill_culling = true; 13012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) found_experiment = true; 13022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 13032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReadNode favicon_sync_node(&trans); 13052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (favicon_sync_node.InitByClientTagLookup( 13062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) syncer::EXPERIMENTS, 1307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) syncer::kFaviconSyncTag) == BaseNode::INIT_OK) { 1308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) experiments->favicon_sync_limit = 1309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) favicon_sync_node.GetExperimentsSpecifics().favicon_sync(). 1310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) favicon_sync_limit(); 13112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) found_experiment = true; 13122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 13132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1314ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ReadNode pre_commit_update_avoidance_node(&trans); 1315ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (pre_commit_update_avoidance_node.InitByClientTagLookup( 1316ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch syncer::EXPERIMENTS, 1317ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch syncer::kPreCommitUpdateAvoidanceTag) == BaseNode::INIT_OK) { 1318ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_context_->set_server_enabled_pre_commit_update_avoidance( 1319ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch pre_commit_update_avoidance_node.GetExperimentsSpecifics(). 1320ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch pre_commit_update_avoidance().enabled()); 1321ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // We don't bother setting found_experiment. The frontend doesn't need to 1322ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // know about this. 1323ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 1324ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return found_experiment; 13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SyncManagerImpl::HasUnsyncedItems() { 13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadTransaction trans(FROM_HERE, GetUserShare()); 13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (trans.GetWrappedTrans()->directory()->unsynced_entity_count() != 0); 13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SyncEncryptionHandler* SyncManagerImpl::GetEncryptionHandler() { 13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sync_encryption_handler_.get(); 13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static. 13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SyncManagerImpl::GetDefaultNudgeDelay() { 13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kDefaultNudgeDelayMilliseconds; 13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static. 13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SyncManagerImpl::GetPreferencesNudgeDelay() { 13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kPreferencesNudgeDelayMilliseconds; 13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace syncer 1348