| Index: chrome/browser/sync/internal_api/sync_manager.cc
|
| diff --git a/chrome/browser/sync/internal_api/sync_manager.cc b/chrome/browser/sync/internal_api/sync_manager.cc
|
| index f8c6a69b131b080c69ca63124d3cc1922ce261fa..e2f1c2f14d348d9d3c83d67dbb58bab19f3c91f4 100644
|
| --- a/chrome/browser/sync/internal_api/sync_manager.cc
|
| +++ b/chrome/browser/sync/internal_api/sync_manager.cc
|
| @@ -8,7 +8,11 @@
|
|
|
| #include "base/base64.h"
|
| #include "base/command_line.h"
|
| +#include "base/compiler_specific.h"
|
| #include "base/json/json_writer.h"
|
| +#include "base/memory/ref_counted.h"
|
| +#include "base/observer_list.h"
|
| +#include "base/observer_list_threadsafe.h"
|
| #include "base/string_number_conversions.h"
|
| #include "base/values.h"
|
| #include "chrome/browser/sync/engine/all_status.h"
|
| @@ -72,7 +76,7 @@ using browser_sync::Syncer;
|
| using browser_sync::WeakHandle;
|
| using browser_sync::sessions::SyncSessionContext;
|
| using syncable::DirectoryManager;
|
| -using syncable::EntryKernelMutationMap;
|
| +using syncable::ImmutableWriteTransactionInfo;
|
| using syncable::ModelType;
|
| using syncable::ModelTypeBitSet;
|
| using syncable::SPECIFICS;
|
| @@ -125,7 +129,10 @@ class SyncManager::SyncInternal
|
| explicit SyncInternal(const std::string& name)
|
| : name_(name),
|
| weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
|
| + change_observers_(
|
| + new ObserverListThreadSafe<SyncManager::ChangeObserver>()),
|
| registrar_(NULL),
|
| + change_delegate_(NULL),
|
| initialized_(false),
|
| setup_for_test_mode_(false),
|
| observing_ip_address_changes_(false) {
|
| @@ -171,6 +178,7 @@ class SyncManager::SyncInternal
|
| bool use_ssl,
|
| HttpPostProviderFactory* post_factory,
|
| ModelSafeWorkerRegistrar* model_safe_worker_registrar,
|
| + ChangeDelegate* change_delegate,
|
| const std::string& user_agent,
|
| const SyncCredentials& credentials,
|
| sync_notifier::SyncNotifier* sync_notifier,
|
| @@ -224,15 +232,16 @@ class SyncManager::SyncInternal
|
| // builds the list of sync-engine initiated changes that will be forwarded to
|
| // the SyncManager's Observers.
|
| virtual void HandleTransactionCompleteChangeEvent(
|
| - const ModelTypeBitSet& models_with_changes);
|
| + const ModelTypeBitSet& models_with_changes) OVERRIDE;
|
| virtual ModelTypeBitSet HandleTransactionEndingChangeEvent(
|
| - syncable::BaseTransaction* trans);
|
| + const ImmutableWriteTransactionInfo& write_transaction_info,
|
| + syncable::BaseTransaction* trans) OVERRIDE;
|
| virtual void HandleCalculateChangesChangeEventFromSyncApi(
|
| - const EntryKernelMutationMap& mutations,
|
| - syncable::BaseTransaction* trans);
|
| + const ImmutableWriteTransactionInfo& write_transaction_info,
|
| + syncable::BaseTransaction* trans) OVERRIDE;
|
| virtual void HandleCalculateChangesChangeEventFromSyncer(
|
| - const EntryKernelMutationMap& mutations,
|
| - syncable::BaseTransaction* trans);
|
| + const ImmutableWriteTransactionInfo& write_transaction_info,
|
| + syncable::BaseTransaction* trans) OVERRIDE;
|
|
|
| // Listens for notifications from the ServerConnectionManager
|
| void HandleServerConnectionEvent(const ServerConnectionEvent& event);
|
| @@ -242,16 +251,16 @@ class SyncManager::SyncInternal
|
|
|
| // SyncNotifierObserver implementation.
|
| virtual void OnNotificationStateChange(
|
| - bool notifications_enabled);
|
| + bool notifications_enabled) OVERRIDE;
|
|
|
| virtual void OnIncomingNotification(
|
| - const syncable::ModelTypePayloadMap& type_payloads);
|
| + const syncable::ModelTypePayloadMap& type_payloads) OVERRIDE;
|
| +
|
| + virtual void StoreState(const std::string& cookie) OVERRIDE;
|
|
|
| - virtual void StoreState(const std::string& cookie);
|
| + void AddChangeObserver(SyncManager::ChangeObserver* observer);
|
| + void RemoveChangeObserver(SyncManager::ChangeObserver* observer);
|
|
|
| - // Thread-safe observers_ accessors.
|
| - void CopyObservers(ObserverList<SyncManager::Observer>* observers_copy);
|
| - bool HaveObservers() const;
|
| void AddObserver(SyncManager::Observer* observer);
|
| void RemoveObserver(SyncManager::Observer* observer);
|
|
|
| @@ -297,7 +306,7 @@ class SyncManager::SyncInternal
|
| bool exists_now);
|
|
|
| // Called only by our NetworkChangeNotifier.
|
| - virtual void OnIPAddressChanged();
|
| + virtual void OnIPAddressChanged() OVERRIDE;
|
|
|
| bool InitialSyncEndedForAllEnabledTypes() {
|
| syncable::ModelTypeSet types;
|
| @@ -312,10 +321,11 @@ class SyncManager::SyncInternal
|
| }
|
|
|
| // SyncEngineEventListener implementation.
|
| - virtual void OnSyncEngineEvent(const SyncEngineEvent& event);
|
| + virtual void OnSyncEngineEvent(const SyncEngineEvent& event) OVERRIDE;
|
|
|
| // ServerConnectionEventListener implementation.
|
| - virtual void OnServerConnectionEvent(const ServerConnectionEvent& event);
|
| + virtual void OnServerConnectionEvent(
|
| + const ServerConnectionEvent& event) OVERRIDE;
|
|
|
| // JsBackend implementation.
|
| virtual void SetJsEventHandler(
|
| @@ -484,9 +494,12 @@ class SyncManager::SyncInternal
|
| // constructing any transaction type.
|
| UserShare share_;
|
|
|
| - // We have to lock around every observers_ access because it can get accessed
|
| - // from any thread and added to/removed from on the core thread.
|
| - mutable base::Lock observers_lock_;
|
| + // Even though observers are always added/removed from the sync
|
| + // thread, we still need to use a thread-safe observer list as we
|
| + // can notify from any thread.
|
| + scoped_refptr<ObserverListThreadSafe<SyncManager::ChangeObserver> >
|
| + change_observers_;
|
| +
|
| ObserverList<SyncManager::Observer> observers_;
|
|
|
| // The ServerConnectionManager used to abstract communication between the
|
| @@ -516,6 +529,8 @@ class SyncManager::SyncInternal
|
| // The instance is shared between the SyncManager and the Syncer.
|
| ModelSafeWorkerRegistrar* registrar_;
|
|
|
| + SyncManager::ChangeDelegate* change_delegate_;
|
| +
|
| // Set to true once Init has been called.
|
| bool initialized_;
|
|
|
| @@ -539,6 +554,10 @@ class SyncManager::SyncInternal
|
| const int SyncManager::SyncInternal::kDefaultNudgeDelayMilliseconds = 200;
|
| const int SyncManager::SyncInternal::kPreferencesNudgeDelayMilliseconds = 2000;
|
|
|
| +SyncManager::ChangeDelegate::~ChangeDelegate() {}
|
| +
|
| +SyncManager::ChangeObserver::~ChangeObserver() {}
|
| +
|
| SyncManager::Observer::~Observer() {}
|
|
|
| SyncManager::SyncManager(const std::string& name)
|
| @@ -584,11 +603,13 @@ bool SyncManager::Init(
|
| bool use_ssl,
|
| HttpPostProviderFactory* post_factory,
|
| ModelSafeWorkerRegistrar* registrar,
|
| + ChangeDelegate* change_delegate,
|
| const std::string& user_agent,
|
| const SyncCredentials& credentials,
|
| sync_notifier::SyncNotifier* sync_notifier,
|
| const std::string& restored_key_for_bootstrapping,
|
| bool setup_for_test_mode) {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| DCHECK(post_factory);
|
| VLOG(1) << "SyncManager starting Init...";
|
| string server_string(sync_server_and_path);
|
| @@ -599,6 +620,7 @@ bool SyncManager::Init(
|
| use_ssl,
|
| post_factory,
|
| registrar,
|
| + change_delegate,
|
| user_agent,
|
| credentials,
|
| sync_notifier,
|
| @@ -607,15 +629,18 @@ bool SyncManager::Init(
|
| }
|
|
|
| void SyncManager::UpdateCredentials(const SyncCredentials& credentials) {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| data_->UpdateCredentials(credentials);
|
| }
|
|
|
| void SyncManager::UpdateEnabledTypes() {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| data_->UpdateEnabledTypes();
|
| }
|
|
|
| void SyncManager::MaybeSetSyncTabsInNigoriNode(
|
| const syncable::ModelTypeSet enabled_types) {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| data_->MaybeSetSyncTabsInNigoriNode(enabled_types);
|
| }
|
|
|
| @@ -624,15 +649,18 @@ bool SyncManager::InitialSyncEndedForAllEnabledTypes() {
|
| }
|
|
|
| void SyncManager::StartSyncingNormally() {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| data_->StartSyncingNormally();
|
| }
|
|
|
| void SyncManager::SetPassphrase(const std::string& passphrase,
|
| bool is_explicit) {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| data_->SetPassphrase(passphrase, is_explicit);
|
| }
|
|
|
| void SyncManager::EnableEncryptEverything() {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| {
|
| // Update the cryptographer to know we're now encrypting everything.
|
| WriteTransaction trans(FROM_HERE, GetUserShare());
|
| @@ -659,17 +687,20 @@ bool SyncManager::IsUsingExplicitPassphrase() {
|
| }
|
|
|
| void SyncManager::RequestCleanupDisabledTypes() {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| if (data_->scheduler())
|
| data_->scheduler()->ScheduleCleanupDisabledTypes();
|
| }
|
|
|
| void SyncManager::RequestClearServerData() {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| if (data_->scheduler())
|
| data_->scheduler()->ScheduleClearUserData();
|
| }
|
|
|
| void SyncManager::RequestConfig(const syncable::ModelTypeBitSet& types,
|
| ConfigureReason reason) {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| if (!data_->scheduler()) {
|
| LOG(INFO)
|
| << "SyncManager::RequestConfig: bailing out because scheduler is "
|
| @@ -681,6 +712,7 @@ void SyncManager::RequestConfig(const syncable::ModelTypeBitSet& types,
|
| }
|
|
|
| void SyncManager::StartConfigurationMode(ModeChangeCallback* callback) {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| if (!data_->scheduler()) {
|
| LOG(INFO)
|
| << "SyncManager::StartConfigurationMode: could not start "
|
| @@ -704,6 +736,7 @@ bool SyncManager::SyncInternal::Init(
|
| bool use_ssl,
|
| HttpPostProviderFactory* post_factory,
|
| ModelSafeWorkerRegistrar* model_safe_worker_registrar,
|
| + ChangeDelegate* change_delegate,
|
| const std::string& user_agent,
|
| const SyncCredentials& credentials,
|
| sync_notifier::SyncNotifier* sync_notifier,
|
| @@ -718,10 +751,12 @@ bool SyncManager::SyncInternal::Init(
|
| weak_handle_this_ = MakeWeakHandle(weak_ptr_factory_.GetWeakPtr());
|
|
|
| registrar_ = model_safe_worker_registrar;
|
| + change_delegate_ = change_delegate;
|
| setup_for_test_mode_ = setup_for_test_mode;
|
|
|
| sync_notifier_.reset(sync_notifier);
|
|
|
| + AddChangeObserver(&js_sync_manager_observer_);
|
| AddObserver(&js_sync_manager_observer_);
|
| SetJsEventHandler(event_handler);
|
|
|
| @@ -775,9 +810,7 @@ bool SyncManager::SyncInternal::Init(
|
| // post a task to shutdown sync. But if this function posts any other tasks
|
| // on the UI thread and if shutdown wins then that tasks would execute on
|
| // a freed pointer. This is because UI thread is not shut down.
|
| - ObserverList<SyncManager::Observer> temp_obs_list;
|
| - CopyObservers(&temp_obs_list);
|
| - FOR_EACH_OBSERVER(SyncManager::Observer, temp_obs_list,
|
| + FOR_EACH_OBSERVER(SyncManager::Observer, observers_,
|
| OnInitializationComplete(
|
| WeakHandle<JsBackend>(weak_ptr_factory_.GetWeakPtr()),
|
| signed_in));
|
| @@ -822,9 +855,7 @@ bool SyncManager::SyncInternal::UpdateCryptographerFromNigori() {
|
| sync_pb::NigoriSpecifics nigori(node.GetNigoriSpecifics());
|
| Cryptographer::UpdateResult result = cryptographer->Update(nigori);
|
| if (result == Cryptographer::NEEDS_PASSPHRASE) {
|
| - ObserverList<SyncManager::Observer> temp_obs_list;
|
| - CopyObservers(&temp_obs_list);
|
| - FOR_EACH_OBSERVER(SyncManager::Observer, temp_obs_list,
|
| + FOR_EACH_OBSERVER(SyncManager::Observer, observers_,
|
| OnPassphraseRequired(sync_api::REASON_DECRYPTION));
|
| }
|
|
|
| @@ -961,9 +992,7 @@ void SyncManager::SyncInternal::MaybeSetSyncTabsInNigoriNode(
|
| }
|
|
|
| void SyncManager::SyncInternal::RaiseAuthNeededEvent() {
|
| - ObserverList<SyncManager::Observer> temp_obs_list;
|
| - CopyObservers(&temp_obs_list);
|
| - FOR_EACH_OBSERVER(SyncManager::Observer, temp_obs_list,
|
| + FOR_EACH_OBSERVER(SyncManager::Observer, observers_,
|
| OnAuthError(AuthError(AuthError::INVALID_GAIA_CREDENTIALS)));
|
| }
|
|
|
| @@ -972,9 +1001,7 @@ void SyncManager::SyncInternal::SetPassphrase(
|
| // We do not accept empty passphrases.
|
| if (passphrase.empty()) {
|
| VLOG(1) << "Rejecting empty passphrase.";
|
| - ObserverList<SyncManager::Observer> temp_obs_list;
|
| - CopyObservers(&temp_obs_list);
|
| - FOR_EACH_OBSERVER(SyncManager::Observer, temp_obs_list,
|
| + FOR_EACH_OBSERVER(SyncManager::Observer, observers_,
|
| OnPassphraseRequired(sync_api::REASON_SET_PASSPHRASE_FAILED));
|
| return;
|
| }
|
| @@ -1011,9 +1038,7 @@ void SyncManager::SyncInternal::SetPassphrase(
|
| }
|
|
|
| if (!succeeded) {
|
| - ObserverList<SyncManager::Observer> temp_obs_list;
|
| - CopyObservers(&temp_obs_list);
|
| - FOR_EACH_OBSERVER(SyncManager::Observer, temp_obs_list,
|
| + FOR_EACH_OBSERVER(SyncManager::Observer, observers_,
|
| OnPassphraseRequired(sync_api::REASON_SET_PASSPHRASE_FAILED));
|
| return;
|
| }
|
| @@ -1049,9 +1074,7 @@ void SyncManager::SyncInternal::SetPassphrase(
|
| VLOG(1) << "Passphrase accepted, bootstrapping encryption.";
|
| std::string bootstrap_token;
|
| cryptographer->GetBootstrapToken(&bootstrap_token);
|
| - ObserverList<SyncManager::Observer> temp_obs_list;
|
| - CopyObservers(&temp_obs_list);
|
| - FOR_EACH_OBSERVER(SyncManager::Observer, temp_obs_list,
|
| + FOR_EACH_OBSERVER(SyncManager::Observer, observers_,
|
| OnPassphraseAccepted(bootstrap_token));
|
| }
|
|
|
| @@ -1086,11 +1109,9 @@ void SyncManager::SyncInternal::EncryptDataTypes(
|
| if (!cryptographer->is_ready()) {
|
| VLOG(1) << "Attempting to encrypt datatypes when cryptographer not "
|
| << "initialized, prompting for passphrase.";
|
| - ObserverList<SyncManager::Observer> temp_obs_list;
|
| - CopyObservers(&temp_obs_list);
|
| // TODO(zea): this isn't really decryption, but that's the only way we have
|
| // to prompt the user for a passsphrase. See http://crbug.com/91379.
|
| - FOR_EACH_OBSERVER(SyncManager::Observer, temp_obs_list,
|
| + FOR_EACH_OBSERVER(SyncManager::Observer, observers_,
|
| OnPassphraseRequired(sync_api::REASON_DECRYPTION));
|
| return;
|
| }
|
| @@ -1182,21 +1203,32 @@ void SyncManager::SyncInternal::ReEncryptEverything(WriteTransaction* trans) {
|
| }
|
| }
|
|
|
| - ObserverList<SyncManager::Observer> temp_obs_list;
|
| - CopyObservers(&temp_obs_list);
|
| - FOR_EACH_OBSERVER(SyncManager::Observer, temp_obs_list,
|
| + FOR_EACH_OBSERVER(SyncManager::Observer, observers_,
|
| OnEncryptionComplete(encrypted_types));
|
| }
|
|
|
| SyncManager::~SyncManager() {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| delete data_;
|
| }
|
|
|
| +void SyncManager::AddChangeObserver(ChangeObserver* observer) {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| + data_->AddChangeObserver(observer);
|
| +}
|
| +
|
| +void SyncManager::RemoveChangeObserver(ChangeObserver* observer) {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| + data_->RemoveChangeObserver(observer);
|
| +}
|
| +
|
| void SyncManager::AddObserver(Observer* observer) {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| data_->AddObserver(observer);
|
| }
|
|
|
| void SyncManager::RemoveObserver(Observer* observer) {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| data_->RemoveObserver(observer);
|
| }
|
|
|
| @@ -1215,6 +1247,7 @@ void SyncManager::SyncInternal::RequestEarlyExit() {
|
| }
|
|
|
| void SyncManager::Shutdown() {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| data_->Shutdown();
|
| }
|
|
|
| @@ -1229,6 +1262,7 @@ void SyncManager::SyncInternal::Shutdown() {
|
| scheduler_.reset();
|
|
|
| SetJsEventHandler(WeakHandle<JsEventHandler>());
|
| + RemoveChangeObserver(&js_sync_manager_observer_);
|
| RemoveObserver(&js_sync_manager_observer_);
|
|
|
| if (sync_notifier_.get()) {
|
| @@ -1260,6 +1294,7 @@ void SyncManager::SyncInternal::Shutdown() {
|
| share_.dir_manager.reset();
|
|
|
| setup_for_test_mode_ = false;
|
| + change_delegate_ = NULL;
|
| registrar_ = NULL;
|
|
|
| initialized_ = false;
|
| @@ -1301,25 +1336,19 @@ void SyncManager::SyncInternal::OnServerConnectionEvent(
|
| allstatus_.HandleServerConnectionEvent(event);
|
| if (event.connection_code ==
|
| browser_sync::HttpResponse::SERVER_CONNECTION_OK) {
|
| - ObserverList<SyncManager::Observer> temp_obs_list;
|
| - CopyObservers(&temp_obs_list);
|
| - FOR_EACH_OBSERVER(SyncManager::Observer, temp_obs_list,
|
| + FOR_EACH_OBSERVER(SyncManager::Observer, observers_,
|
| OnAuthError(AuthError::None()));
|
| }
|
|
|
| if (event.connection_code == browser_sync::HttpResponse::SYNC_AUTH_ERROR) {
|
| observing_ip_address_changes_ = false;
|
| - ObserverList<SyncManager::Observer> temp_obs_list;
|
| - CopyObservers(&temp_obs_list);
|
| - FOR_EACH_OBSERVER(SyncManager::Observer, temp_obs_list,
|
| + FOR_EACH_OBSERVER(SyncManager::Observer, observers_,
|
| OnAuthError(AuthError(AuthError::INVALID_GAIA_CREDENTIALS)));
|
| }
|
|
|
| if (event.connection_code ==
|
| browser_sync::HttpResponse::SYNC_SERVER_ERROR) {
|
| - ObserverList<SyncManager::Observer> temp_obs_list;
|
| - CopyObservers(&temp_obs_list);
|
| - FOR_EACH_OBSERVER(SyncManager::Observer, temp_obs_list,
|
| + FOR_EACH_OBSERVER(SyncManager::Observer, observers_,
|
| OnAuthError(AuthError(AuthError::CONNECTION_FAILED)));
|
| }
|
| }
|
| @@ -1329,26 +1358,27 @@ void SyncManager::SyncInternal::HandleTransactionCompleteChangeEvent(
|
| // This notification happens immediately after the transaction mutex is
|
| // released. This allows work to be performed without blocking other threads
|
| // from acquiring a transaction.
|
| - if (!HaveObservers())
|
| + if (!change_delegate_)
|
| return;
|
|
|
| // Call commit.
|
| for (int i = 0; i < syncable::MODEL_TYPE_COUNT; ++i) {
|
| - if (models_with_changes.test(i)) {
|
| - ObserverList<SyncManager::Observer> temp_obs_list;
|
| - CopyObservers(&temp_obs_list);
|
| - FOR_EACH_OBSERVER(SyncManager::Observer, temp_obs_list,
|
| - OnChangesComplete(syncable::ModelTypeFromInt(i)));
|
| + const syncable::ModelType type = syncable::ModelTypeFromInt(i);
|
| + if (models_with_changes.test(type)) {
|
| + change_delegate_->OnChangesComplete(type);
|
| + change_observers_->Notify(
|
| + &SyncManager::ChangeObserver::OnChangesComplete, type);
|
| }
|
| }
|
| }
|
|
|
| ModelTypeBitSet SyncManager::SyncInternal::HandleTransactionEndingChangeEvent(
|
| + const ImmutableWriteTransactionInfo& write_transaction_info,
|
| syncable::BaseTransaction* trans) {
|
| // This notification happens immediately before a syncable WriteTransaction
|
| // falls out of scope. It happens while the channel mutex is still held,
|
| // and while the transaction mutex is held, so it cannot be re-entrant.
|
| - if (!HaveObservers() || ChangeBuffersAreEmpty())
|
| + if (!change_delegate_ || ChangeBuffersAreEmpty())
|
| return ModelTypeBitSet();
|
|
|
| // This will continue the WriteTransaction using a read only wrapper.
|
| @@ -1358,18 +1388,20 @@ ModelTypeBitSet SyncManager::SyncInternal::HandleTransactionEndingChangeEvent(
|
| ReadTransaction read_trans(GetUserShare(), trans);
|
|
|
| syncable::ModelTypeBitSet models_with_changes;
|
| - for (int i = 0; i < syncable::MODEL_TYPE_COUNT; ++i) {
|
| - if (change_buffers_[i].IsEmpty())
|
| + for (int i = syncable::FIRST_REAL_MODEL_TYPE;
|
| + i < syncable::MODEL_TYPE_COUNT; ++i) {
|
| + const syncable::ModelType type = syncable::ModelTypeFromInt(i);
|
| + if (change_buffers_[type].IsEmpty())
|
| continue;
|
|
|
| ImmutableChangeRecordList ordered_changes =
|
| - change_buffers_[i].GetAllChangesInTreeOrder(&read_trans);
|
| + change_buffers_[type].GetAllChangesInTreeOrder(&read_trans);
|
| if (!ordered_changes.Get().empty()) {
|
| - ObserverList<SyncManager::Observer> temp_obs_list;
|
| - CopyObservers(&temp_obs_list);
|
| - FOR_EACH_OBSERVER(SyncManager::Observer, temp_obs_list,
|
| - OnChangesApplied(syncable::ModelTypeFromInt(i),
|
| - &read_trans, ordered_changes));
|
| + change_delegate_->
|
| + OnChangesApplied(type, &read_trans, ordered_changes);
|
| + change_observers_->Notify(
|
| + &SyncManager::ChangeObserver::OnChangesApplied,
|
| + type, write_transaction_info.Get().id, ordered_changes);
|
| models_with_changes.set(i, true);
|
| }
|
| change_buffers_[i].Clear();
|
| @@ -1378,7 +1410,7 @@ ModelTypeBitSet SyncManager::SyncInternal::HandleTransactionEndingChangeEvent(
|
| }
|
|
|
| void SyncManager::SyncInternal::HandleCalculateChangesChangeEventFromSyncApi(
|
| - const EntryKernelMutationMap& mutations,
|
| + const ImmutableWriteTransactionInfo& write_transaction_info,
|
| syncable::BaseTransaction* trans) {
|
| if (!scheduler()) {
|
| return;
|
| @@ -1393,8 +1425,10 @@ void SyncManager::SyncInternal::HandleCalculateChangesChangeEventFromSyncApi(
|
|
|
| // Find the first real mutation. We assume that only a single model
|
| // type is mutated per transaction.
|
| + const syncable::ImmutableEntryKernelMutationMap& mutations =
|
| + write_transaction_info.Get().mutations;
|
| for (syncable::EntryKernelMutationMap::const_iterator it =
|
| - mutations.begin(); it != mutations.end(); ++it) {
|
| + mutations.Get().begin(); it != mutations.Get().end(); ++it) {
|
| if (!it->second.mutated.ref(syncable::IS_UNSYNCED)) {
|
| continue;
|
| }
|
| @@ -1458,7 +1492,7 @@ void SyncManager::SyncInternal::SetExtraChangeRecordData(int64 id,
|
| }
|
|
|
| void SyncManager::SyncInternal::HandleCalculateChangesChangeEventFromSyncer(
|
| - const EntryKernelMutationMap& mutations,
|
| + const ImmutableWriteTransactionInfo& write_transaction_info,
|
| syncable::BaseTransaction* trans) {
|
| // We only expect one notification per sync step, so change_buffers_ should
|
| // contain no pending entries.
|
| @@ -1466,8 +1500,10 @@ void SyncManager::SyncInternal::HandleCalculateChangesChangeEventFromSyncer(
|
| "CALCULATE_CHANGES called with unapplied old changes.";
|
|
|
| Cryptographer* crypto = dir_manager()->GetCryptographer(trans);
|
| + const syncable::ImmutableEntryKernelMutationMap& mutations =
|
| + write_transaction_info.Get().mutations;
|
| for (syncable::EntryKernelMutationMap::const_iterator it =
|
| - mutations.begin(); it != mutations.end(); ++it) {
|
| + mutations.Get().begin(); it != mutations.Get().end(); ++it) {
|
| bool existed_before = !it->second.original.ref(syncable::IS_DEL);
|
| bool exists_now = !it->second.mutated.ref(syncable::IS_DEL);
|
|
|
| @@ -1538,12 +1574,6 @@ void SyncManager::SyncInternal::RequestNudgeForDataType(
|
| void SyncManager::SyncInternal::OnSyncEngineEvent(
|
| const SyncEngineEvent& event) {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
| - if (!HaveObservers()) {
|
| - LOG(INFO)
|
| - << "OnSyncEngineEvent returning because observers_.size() is zero";
|
| - return;
|
| - }
|
| -
|
| // 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
|
| // locally we are "all happy" and up-to-date. There may be new changes on
|
| @@ -1563,17 +1593,13 @@ void SyncManager::SyncInternal::OnSyncEngineEvent(
|
| // yet, prompt the user for a passphrase.
|
| if (cryptographer->has_pending_keys()) {
|
| VLOG(1) << "OnPassPhraseRequired Sent";
|
| - ObserverList<SyncManager::Observer> temp_obs_list;
|
| - CopyObservers(&temp_obs_list);
|
| - FOR_EACH_OBSERVER(SyncManager::Observer, temp_obs_list,
|
| + FOR_EACH_OBSERVER(SyncManager::Observer, observers_,
|
| OnPassphraseRequired(sync_api::REASON_DECRYPTION));
|
| } else if (!cryptographer->is_ready() &&
|
| event.snapshot->initial_sync_ended.test(syncable::NIGORI)) {
|
| VLOG(1) << "OnPassphraseRequired sent because cryptographer is not "
|
| << "ready";
|
| - ObserverList<SyncManager::Observer> temp_obs_list;
|
| - CopyObservers(&temp_obs_list);
|
| - FOR_EACH_OBSERVER(SyncManager::Observer, temp_obs_list,
|
| + FOR_EACH_OBSERVER(SyncManager::Observer, observers_,
|
| OnPassphraseRequired(sync_api::REASON_ENCRYPTION));
|
| }
|
|
|
| @@ -1595,9 +1621,7 @@ void SyncManager::SyncInternal::OnSyncEngineEvent(
|
|
|
| if (!event.snapshot->has_more_to_sync) {
|
| VLOG(1) << "OnSyncCycleCompleted sent";
|
| - ObserverList<SyncManager::Observer> temp_obs_list;
|
| - CopyObservers(&temp_obs_list);
|
| - FOR_EACH_OBSERVER(SyncManager::Observer, temp_obs_list,
|
| + FOR_EACH_OBSERVER(SyncManager::Observer, observers_,
|
| OnSyncCycleCompleted(event.snapshot));
|
| }
|
|
|
| @@ -1620,41 +1644,31 @@ void SyncManager::SyncInternal::OnSyncEngineEvent(
|
| }
|
|
|
| if (event.what_happened == SyncEngineEvent::STOP_SYNCING_PERMANENTLY) {
|
| - ObserverList<SyncManager::Observer> temp_obs_list;
|
| - CopyObservers(&temp_obs_list);
|
| - FOR_EACH_OBSERVER(SyncManager::Observer, temp_obs_list,
|
| + FOR_EACH_OBSERVER(SyncManager::Observer, observers_,
|
| OnStopSyncingPermanently());
|
| return;
|
| }
|
|
|
| if (event.what_happened == SyncEngineEvent::CLEAR_SERVER_DATA_SUCCEEDED) {
|
| - ObserverList<SyncManager::Observer> temp_obs_list;
|
| - CopyObservers(&temp_obs_list);
|
| - FOR_EACH_OBSERVER(SyncManager::Observer, temp_obs_list,
|
| + FOR_EACH_OBSERVER(SyncManager::Observer, observers_,
|
| OnClearServerDataSucceeded());
|
| return;
|
| }
|
|
|
| if (event.what_happened == SyncEngineEvent::CLEAR_SERVER_DATA_FAILED) {
|
| - ObserverList<SyncManager::Observer> temp_obs_list;
|
| - CopyObservers(&temp_obs_list);
|
| - FOR_EACH_OBSERVER(SyncManager::Observer, temp_obs_list,
|
| + FOR_EACH_OBSERVER(SyncManager::Observer, observers_,
|
| OnClearServerDataFailed());
|
| return;
|
| }
|
|
|
| if (event.what_happened == SyncEngineEvent::UPDATED_TOKEN) {
|
| - ObserverList<SyncManager::Observer> temp_obs_list;
|
| - CopyObservers(&temp_obs_list);
|
| - FOR_EACH_OBSERVER(SyncManager::Observer, temp_obs_list,
|
| + FOR_EACH_OBSERVER(SyncManager::Observer, observers_,
|
| OnUpdatedToken(event.updated_token));
|
| return;
|
| }
|
|
|
| if (event.what_happened == SyncEngineEvent::ACTIONABLE_ERROR) {
|
| - ObserverList<SyncManager::Observer> temp_obs_list;
|
| - CopyObservers(&temp_obs_list);
|
| - FOR_EACH_OBSERVER(SyncManager::Observer, temp_obs_list,
|
| + FOR_EACH_OBSERVER(SyncManager::Observer, observers_,
|
| OnActionableError(
|
| event.snapshot->errors.sync_protocol_error));
|
| return;
|
| @@ -1925,37 +1939,23 @@ void SyncManager::SyncInternal::StoreState(
|
| lookup->SaveChanges();
|
| }
|
|
|
| -// Note: it is possible that an observer will remove itself after we have made
|
| -// a copy, but before the copy is consumed. This could theoretically result
|
| -// in accessing a garbage pointer, but can only occur when an about:sync window
|
| -// is closed in the middle of a notification.
|
| -// See crbug.com/85481.
|
| -void SyncManager::SyncInternal::CopyObservers(
|
| - ObserverList<SyncManager::Observer>* observers_copy) {
|
| - DCHECK_EQ(0U, observers_copy->size());
|
| - base::AutoLock lock(observers_lock_);
|
| - if (observers_.size() == 0)
|
| - return;
|
| - ObserverListBase<SyncManager::Observer>::Iterator it(observers_);
|
| - SyncManager::Observer* obs;
|
| - while ((obs = it.GetNext()) != NULL)
|
| - observers_copy->AddObserver(obs);
|
| +void SyncManager::SyncInternal::AddChangeObserver(
|
| + SyncManager::ChangeObserver* observer) {
|
| + change_observers_->AddObserver(observer);
|
| }
|
|
|
| -bool SyncManager::SyncInternal::HaveObservers() const {
|
| - base::AutoLock lock(observers_lock_);
|
| - return observers_.size() > 0;
|
| +void SyncManager::SyncInternal::RemoveChangeObserver(
|
| + SyncManager::ChangeObserver* observer) {
|
| + change_observers_->RemoveObserver(observer);
|
| }
|
|
|
| void SyncManager::SyncInternal::AddObserver(
|
| SyncManager::Observer* observer) {
|
| - base::AutoLock lock(observers_lock_);
|
| observers_.AddObserver(observer);
|
| }
|
|
|
| void SyncManager::SyncInternal::RemoveObserver(
|
| SyncManager::Observer* observer) {
|
| - base::AutoLock lock(observers_lock_);
|
| observers_.RemoveObserver(observer);
|
| }
|
|
|
| @@ -1967,9 +1967,8 @@ SyncManager::Status SyncManager::GetDetailedStatus() const {
|
| return data_->GetStatus();
|
| }
|
|
|
| -SyncManager::SyncInternal* SyncManager::GetImpl() const { return data_; }
|
| -
|
| void SyncManager::SaveChanges() {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| data_->SaveChanges();
|
| }
|
|
|
| @@ -1987,6 +1986,7 @@ UserShare* SyncManager::GetUserShare() const {
|
| }
|
|
|
| void SyncManager::RefreshEncryption() {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| if (data_->UpdateCryptographerFromNigori())
|
| data_->EncryptDataTypes(syncable::ModelTypeSet());
|
| }
|
| @@ -2016,31 +2016,15 @@ bool SyncManager::HasUnsyncedItems() const {
|
| return (trans.GetWrappedTrans()->directory()->unsynced_entity_count() != 0);
|
| }
|
|
|
| -void SyncManager::LogUnsyncedItems(int level) const {
|
| - std::vector<int64> unsynced_handles;
|
| - sync_api::ReadTransaction trans(FROM_HERE, GetUserShare());
|
| - trans.GetWrappedTrans()->directory()->GetUnsyncedMetaHandles(
|
| - trans.GetWrappedTrans(), &unsynced_handles);
|
| -
|
| - for (std::vector<int64>::const_iterator it = unsynced_handles.begin();
|
| - it != unsynced_handles.end(); ++it) {
|
| - ReadNode node(&trans);
|
| - if (node.InitByIdLookup(*it)) {
|
| - scoped_ptr<DictionaryValue> value(node.GetDetailsAsValue());
|
| - std::string info;
|
| - base::JSONWriter::Write(value.get(), true, &info);
|
| - VLOG(level) << info;
|
| - }
|
| - }
|
| -}
|
| -
|
| void SyncManager::TriggerOnNotificationStateChangeForTest(
|
| bool notifications_enabled) {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| data_->OnNotificationStateChange(notifications_enabled);
|
| }
|
|
|
| void SyncManager::TriggerOnIncomingNotificationForTest(
|
| const syncable::ModelTypeBitSet& model_types) {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| syncable::ModelTypePayloadMap model_types_with_payloads =
|
| syncable::ModelTypePayloadMapFromBitSet(model_types,
|
| std::string());
|
|
|