#include "sync/internal_api/public/internal_components_factory.h"
#include "sync/internal_api/public/read_node.h"
#include "sync/internal_api/public/read_transaction.h"
+#include "sync/internal_api/public/sync_core_proxy.h"
#include "sync/internal_api/public/user_share.h"
#include "sync/internal_api/public/util/experiments.h"
#include "sync/internal_api/public/write_node.h"
#include "sync/internal_api/public/write_transaction.h"
+#include "sync/internal_api/sync_core.h"
+#include "sync/internal_api/sync_core_proxy_impl.h"
#include "sync/internal_api/syncapi_internal.h"
#include "sync/internal_api/syncapi_server_connection_manager.h"
-#include "sync/js/js_arg_list.h"
-#include "sync/js/js_event_details.h"
-#include "sync/js/js_event_handler.h"
-#include "sync/js/js_reply_handler.h"
#include "sync/notifier/invalidation_util.h"
#include "sync/notifier/invalidator.h"
#include "sync/notifier/object_id_invalidation_map.h"
#include "sync/protocol/proto_value_conversions.h"
#include "sync/protocol/sync.pb.h"
+#include "sync/sessions/directory_type_debug_info_emitter.h"
#include "sync/syncable/directory.h"
#include "sync/syncable/entry.h"
#include "sync/syncable/in_memory_directory_backing_store.h"
static const int kSyncRefreshDelayMsec = 500;
static const int kSyncSchedulerDelayMsec = 250;
-// Maximum count and size for traffic recorder.
-static const unsigned int kMaxMessagesToRecord = 10;
-static const unsigned int kMaxMessageSizeToRecord = 5 * 1024;
-
GetUpdatesCallerInfo::GetUpdatesSource GetSourceFromReason(
ConfigureReason reason) {
switch (reason) {
initialized_(false),
observing_network_connectivity_changes_(false),
invalidator_state_(DEFAULT_INVALIDATION_ERROR),
- traffic_recorder_(kMaxMessagesToRecord, kMaxMessageSizeToRecord),
- encryptor_(NULL),
report_unrecoverable_error_function_(NULL),
weak_ptr_factory_(this) {
// Pre-fill |notification_info_map_|.
notification_info_map_.insert(
std::make_pair(ModelTypeFromInt(i), NotificationInfo()));
}
-
- // Bind message handlers.
- BindJsMessageHandler(
- "getNotificationState",
- &SyncManagerImpl::GetNotificationState);
- BindJsMessageHandler(
- "getNotificationInfo",
- &SyncManagerImpl::GetNotificationInfo);
- BindJsMessageHandler(
- "getAllNodes",
- &SyncManagerImpl::GetAllNodes);
- BindJsMessageHandler(
- "getClientServerTraffic",
- &SyncManagerImpl::GetClientServerTraffic);
}
SyncManagerImpl::~SyncManagerImpl() {
database_path_ = database_location.Append(
syncable::Directory::kSyncDatabaseFilename);
- encryptor_ = encryptor;
unrecoverable_error_handler_ = unrecoverable_error_handler.Pass();
report_unrecoverable_error_function_ = report_unrecoverable_error_function;
model_type_registry_.reset(new ModelTypeRegistry(workers, directory()));
+ sync_core_.reset(new SyncCore(model_type_registry_.get()));
+
+ // Bind the SyncCore WeakPtr to this thread. This helps us crash earlier if
+ // the pointer is misused in debug mode.
+ base::WeakPtr<SyncCore> weak_core = sync_core_->AsWeakPtr();
+ weak_core.get();
+
+ sync_core_proxy_.reset(
+ new SyncCoreProxyImpl(base::MessageLoopProxy::current(), weak_core));
+
// Build a SyncSessionContext and store the worker in it.
DVLOG(1) << "Sync is bringing up SyncSessionContext.";
std::vector<SyncEngineEventListener*> listeners;
extensions_activity,
listeners,
&debug_info_event_listener_,
- &traffic_recorder_,
model_type_registry_.get(),
invalidator_client_id).Pass();
session_context_->set_account_name(credentials.email);
base::TimeDelta nudge_delay = NudgeStrategy::GetNudgeDelayTimeDelta(
types.First().Get(),
this);
- allstatus_.IncrementNudgeCounter(NUDGE_SOURCE_LOCAL);
scheduler_->ScheduleLocalNudge(nudge_delay,
types,
nudge_location);
}
-void SyncManagerImpl::OnSyncEngineEvent(const SyncEngineEvent& event) {
+void SyncManagerImpl::OnSyncCycleEvent(const SyncCycleEvent& event) {
DCHECK(thread_checker_.CalledOnValidThread());
// Only send an event if this is due to a cycle ending and this cycle
// concludes a canonical "sync" process; that is, based on what is known
//
// Notifications are sent at the end of every sync cycle, regardless of
// whether we should sync again.
- if (event.what_happened == SyncEngineEvent::SYNC_CYCLE_ENDED) {
+ if (event.what_happened == SyncCycleEvent::SYNC_CYCLE_ENDED) {
if (!initialized_) {
DVLOG(1) << "OnSyncCycleCompleted not sent because sync api is not "
<< "initialized";
FOR_EACH_OBSERVER(SyncManager::Observer, observers_,
OnSyncCycleCompleted(event.snapshot));
}
-
- if (event.what_happened == SyncEngineEvent::STOP_SYNCING_PERMANENTLY) {
- FOR_EACH_OBSERVER(SyncManager::Observer, observers_,
- OnStopSyncingPermanently());
- return;
- }
-
- if (event.what_happened == SyncEngineEvent::ACTIONABLE_ERROR) {
- FOR_EACH_OBSERVER(
- SyncManager::Observer, observers_,
- OnActionableError(
- event.snapshot.model_neutral_state().sync_protocol_error));
- return;
- }
}
-void SyncManagerImpl::SetJsEventHandler(
- const WeakHandle<JsEventHandler>& event_handler) {
- js_event_handler_ = event_handler;
- js_sync_manager_observer_.SetJsEventHandler(js_event_handler_);
- js_mutation_event_observer_.SetJsEventHandler(js_event_handler_);
- js_sync_encryption_handler_observer_.SetJsEventHandler(js_event_handler_);
+void SyncManagerImpl::OnActionableError(const SyncProtocolError& error) {
+ FOR_EACH_OBSERVER(
+ SyncManager::Observer, observers_,
+ OnActionableError(error));
}
-void SyncManagerImpl::ProcessJsMessage(
- const std::string& name, const JsArgList& args,
- const WeakHandle<JsReplyHandler>& reply_handler) {
- if (!initialized_) {
- NOTREACHED();
- return;
- }
+void SyncManagerImpl::OnRetryTimeChanged(base::Time) {}
- if (!reply_handler.IsInitialized()) {
- DVLOG(1) << "Uninitialized reply handler; dropping unknown message "
- << name << " with args " << args.ToString();
- return;
- }
+void SyncManagerImpl::OnThrottledTypesChanged(ModelTypeSet) {}
- JsMessageHandler js_message_handler = js_message_handlers_[name];
- if (js_message_handler.is_null()) {
- DVLOG(1) << "Dropping unknown message " << name
- << " with args " << args.ToString();
- return;
- }
-
- reply_handler.Call(FROM_HERE,
- &JsReplyHandler::HandleJsReply,
- name, js_message_handler.Run(args));
+void SyncManagerImpl::OnMigrationRequested(ModelTypeSet types) {
+ FOR_EACH_OBSERVER(
+ SyncManager::Observer, observers_,
+ OnMigrationRequested(types));
}
-void SyncManagerImpl::BindJsMessageHandler(
- const std::string& name,
- UnboundJsMessageHandler unbound_message_handler) {
- js_message_handlers_[name] =
- base::Bind(unbound_message_handler, base::Unretained(this));
+void SyncManagerImpl::OnProtocolEvent(const ProtocolEvent& event) {
+ protocol_event_buffer_.RecordProtocolEvent(event);
+ FOR_EACH_OBSERVER(SyncManager::Observer, observers_,
+ OnProtocolEvent(event));
}
-base::DictionaryValue* SyncManagerImpl::NotificationInfoToValue(
- const NotificationInfoMap& notification_info) {
- base::DictionaryValue* value = new base::DictionaryValue();
-
- for (NotificationInfoMap::const_iterator it = notification_info.begin();
- it != notification_info.end(); ++it) {
- const std::string model_type_str = ModelTypeToString(it->first);
- value->Set(model_type_str, it->second.ToValue());
+void SyncManagerImpl::SetJsEventHandler(
+ const WeakHandle<JsEventHandler>& event_handler) {
+ js_sync_manager_observer_.SetJsEventHandler(event_handler);
+ js_mutation_event_observer_.SetJsEventHandler(event_handler);
+ js_sync_encryption_handler_observer_.SetJsEventHandler(event_handler);
+}
+
+scoped_ptr<base::ListValue> SyncManagerImpl::GetAllNodesForType(
+ syncer::ModelType type) {
+ DirectoryTypeDebugInfoEmitterMap* emitter_map =
+ model_type_registry_->directory_type_debug_info_emitter_map();
+ DirectoryTypeDebugInfoEmitterMap::iterator it = emitter_map->find(type);
+
+ if (it == emitter_map->end()) {
+ // This can happen in some cases. The UI thread makes requests of us
+ // when it doesn't really know which types are enabled or disabled.
+ DLOG(WARNING) << "Asked to return debug info for invalid type "
+ << ModelTypeToString(type);
+ return scoped_ptr<base::ListValue>();
}
- return value;
-}
-
-std::string SyncManagerImpl::NotificationInfoToString(
- const NotificationInfoMap& notification_info) {
- scoped_ptr<base::DictionaryValue> value(
- NotificationInfoToValue(notification_info));
- std::string str;
- base::JSONWriter::Write(value.get(), &str);
- return str;
-}
-
-JsArgList SyncManagerImpl::GetNotificationState(
- const JsArgList& args) {
- const std::string& notification_state =
- InvalidatorStateToString(invalidator_state_);
- DVLOG(1) << "GetNotificationState: " << notification_state;
- base::ListValue return_args;
- return_args.Append(new base::StringValue(notification_state));
- return JsArgList(&return_args);
-}
-
-JsArgList SyncManagerImpl::GetNotificationInfo(
- const JsArgList& args) {
- DVLOG(1) << "GetNotificationInfo: "
- << NotificationInfoToString(notification_info_map_);
- base::ListValue return_args;
- return_args.Append(NotificationInfoToValue(notification_info_map_));
- return JsArgList(&return_args);
-}
-
-JsArgList SyncManagerImpl::GetClientServerTraffic(
- const JsArgList& args) {
- base::ListValue return_args;
- base::ListValue* value = traffic_recorder_.ToValue();
- if (value != NULL)
- return_args.Append(value);
- return JsArgList(&return_args);
-}
-
-JsArgList SyncManagerImpl::GetAllNodes(const JsArgList& args) {
- ReadTransaction trans(FROM_HERE, GetUserShare());
- base::ListValue return_args;
- scoped_ptr<base::ListValue> nodes(
- trans.GetDirectory()->GetAllNodeDetails(trans.GetWrappedTrans()));
- return_args.Append(nodes.release());
- return JsArgList(&return_args);
-}
-
-void SyncManagerImpl::UpdateNotificationInfo(
- const ObjectIdInvalidationMap& invalidation_map) {
- ObjectIdSet ids = invalidation_map.GetObjectIds();
- for (ObjectIdSet::const_iterator it = ids.begin(); it != ids.end(); ++it) {
- ModelType type = UNSPECIFIED;
- if (!ObjectIdToRealModelType(*it, &type)) {
- continue;
- }
- const SingleObjectInvalidationSet& type_invalidations =
- invalidation_map.ForObject(*it);
- for (SingleObjectInvalidationSet::const_iterator inv_it =
- type_invalidations.begin(); inv_it != type_invalidations.end();
- ++inv_it) {
- NotificationInfo* info = ¬ification_info_map_[type];
- info->total_count++;
- std::string payload =
- inv_it->is_unknown_version() ? "UNKNOWN" : inv_it->payload();
- info->payload = payload;
- }
- }
+ return it->second->GetAllNodes();
}
void SyncManagerImpl::OnInvalidatorStateChange(InvalidatorState state) {
(invalidator_state_ == INVALIDATIONS_ENABLED);
allstatus_.SetNotificationsEnabled(notifications_enabled);
scheduler_->SetNotificationsEnabled(notifications_enabled);
-
- if (js_event_handler_.IsInitialized()) {
- base::DictionaryValue details;
- details.SetString("state", state_str);
- js_event_handler_.Call(FROM_HERE,
- &JsEventHandler::HandleJsEvent,
- "onNotificationStateChange",
- JsEventDetails(&details));
- }
}
void SyncManagerImpl::OnIncomingInvalidation(
if (invalidation_map.Empty()) {
LOG(WARNING) << "Sync received invalidation without any type information.";
} else {
- allstatus_.IncrementNudgeCounter(NUDGE_SOURCE_NOTIFICATION);
scheduler_->ScheduleInvalidationNudge(
TimeDelta::FromMilliseconds(kSyncSchedulerDelayMsec),
invalidation_map, FROM_HERE);
- allstatus_.IncrementNotificationsReceived();
- UpdateNotificationInfo(invalidation_map);
debug_info_event_listener_.OnIncomingNotification(invalidation_map);
}
-
- if (js_event_handler_.IsInitialized()) {
- base::DictionaryValue details;
- base::ListValue* changed_types = new base::ListValue();
- details.Set("changedTypes", changed_types);
-
- ObjectIdSet id_set = invalidation_map.GetObjectIds();
- ModelTypeSet nudged_types = ObjectIdSetToModelTypeSet(id_set);
- DCHECK(!nudged_types.Empty());
- for (ModelTypeSet::Iterator it = nudged_types.First();
- it.Good(); it.Inc()) {
- const std::string model_type_str = ModelTypeToString(it.Get());
- changed_types->Append(new base::StringValue(model_type_str));
- }
- details.SetString("source", "REMOTE_INVALIDATION");
- js_event_handler_.Call(FROM_HERE,
- &JsEventHandler::HandleJsEvent,
- "onIncomingNotification",
- JsEventDetails(&details));
- }
}
+std::string SyncManagerImpl::GetOwnerName() const { return "SyncManagerImpl"; }
+
void SyncManagerImpl::RefreshTypes(ModelTypeSet types) {
DCHECK(thread_checker_.CalledOnValidThread());
if (types.Empty()) {
LOG(WARNING) << "Sync received refresh request with no types specified.";
} else {
- allstatus_.IncrementNudgeCounter(NUDGE_SOURCE_LOCAL_REFRESH);
scheduler_->ScheduleLocalRefreshRequest(
TimeDelta::FromMilliseconds(kSyncRefreshDelayMsec),
types, FROM_HERE);
}
-
- if (js_event_handler_.IsInitialized()) {
- base::DictionaryValue details;
- base::ListValue* changed_types = new base::ListValue();
- details.Set("changedTypes", changed_types);
- for (ModelTypeSet::Iterator it = types.First(); it.Good(); it.Inc()) {
- const std::string& model_type_str =
- ModelTypeToString(it.Get());
- changed_types->Append(new base::StringValue(model_type_str));
- }
- details.SetString("source", "LOCAL_INVALIDATION");
- js_event_handler_.Call(FROM_HERE,
- &JsEventHandler::HandleJsEvent,
- "onIncomingNotification",
- JsEventDetails(&details));
- }
}
SyncStatus SyncManagerImpl::GetDetailedStatus() const {
return &share_;
}
+syncer::SyncCoreProxy* SyncManagerImpl::GetSyncCoreProxy() {
+ DCHECK(initialized_);
+ return sync_core_proxy_.get();
+}
+
const std::string SyncManagerImpl::cache_guid() {
DCHECK(initialized_);
return directory()->cache_guid();
}
bool found_experiment = false;
- ReadNode autofill_culling_node(&trans);
- if (autofill_culling_node.InitByClientTagLookup(
- syncer::EXPERIMENTS,
- syncer::kAutofillCullingTag) == BaseNode::INIT_OK &&
- autofill_culling_node.GetExperimentsSpecifics().
- autofill_culling().enabled()) {
- experiments->autofill_culling = true;
- found_experiment = true;
- }
-
ReadNode favicon_sync_node(&trans);
if (favicon_sync_node.InitByClientTagLookup(
syncer::EXPERIMENTS,
// know about this.
}
+ ReadNode gcm_channel_node(&trans);
+ if (gcm_channel_node.InitByClientTagLookup(
+ syncer::EXPERIMENTS,
+ syncer::kGCMChannelTag) == BaseNode::INIT_OK &&
+ gcm_channel_node.GetExperimentsSpecifics().gcm_channel().has_enabled()) {
+ experiments->gcm_channel_state =
+ (gcm_channel_node.GetExperimentsSpecifics().gcm_channel().enabled() ?
+ syncer::Experiments::ENABLED : syncer::Experiments::SUPPRESSED);
+ found_experiment = true;
+ }
+
+ ReadNode enhanced_bookmarks_node(&trans);
+ if (enhanced_bookmarks_node.InitByClientTagLookup(
+ syncer::EXPERIMENTS, syncer::kEnhancedBookmarksTag) ==
+ BaseNode::INIT_OK &&
+ enhanced_bookmarks_node.GetExperimentsSpecifics()
+ .has_enhanced_bookmarks()) {
+ const sync_pb::EnhancedBookmarksFlags& enhanced_bookmarks =
+ enhanced_bookmarks_node.GetExperimentsSpecifics().enhanced_bookmarks();
+ if (enhanced_bookmarks.has_enabled())
+ experiments->enhanced_bookmarks_enabled = enhanced_bookmarks.enabled();
+ if (enhanced_bookmarks.has_extension_id()) {
+ experiments->enhanced_bookmarks_ext_id =
+ enhanced_bookmarks.extension_id();
+ }
+ found_experiment = true;
+ }
+
+ ReadNode gcm_invalidations_node(&trans);
+ if (gcm_invalidations_node.InitByClientTagLookup(
+ syncer::EXPERIMENTS, syncer::kGCMInvalidationsTag) ==
+ BaseNode::INIT_OK) {
+ const sync_pb::GcmInvalidationsFlags& gcm_invalidations =
+ gcm_invalidations_node.GetExperimentsSpecifics().gcm_invalidations();
+ if (gcm_invalidations.has_enabled()) {
+ experiments->gcm_invalidations_enabled = gcm_invalidations.enabled();
+ found_experiment = true;
+ }
+ }
+
return found_experiment;
}
return sync_encryption_handler_.get();
}
+ScopedVector<syncer::ProtocolEvent>
+ SyncManagerImpl::GetBufferedProtocolEvents() {
+ return protocol_event_buffer_.GetBufferedProtocolEvents();
+}
+
+void SyncManagerImpl::RegisterDirectoryTypeDebugInfoObserver(
+ syncer::TypeDebugInfoObserver* observer) {
+ model_type_registry_->RegisterDirectoryTypeDebugInfoObserver(observer);
+}
+
+void SyncManagerImpl::UnregisterDirectoryTypeDebugInfoObserver(
+ syncer::TypeDebugInfoObserver* observer) {
+ model_type_registry_->UnregisterDirectoryTypeDebugInfoObserver(observer);
+}
+
+bool SyncManagerImpl::HasDirectoryTypeDebugInfoObserver(
+ syncer::TypeDebugInfoObserver* observer) {
+ return model_type_registry_->HasDirectoryTypeDebugInfoObserver(observer);
+}
+
+void SyncManagerImpl::RequestEmitDebugInfo() {
+ model_type_registry_->RequestEmitDebugInfo();
+}
+
// static.
int SyncManagerImpl::GetDefaultNudgeDelay() {
return kDefaultNudgeDelayMilliseconds;