Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(253)

Unified Diff: chrome/browser/sync/glue/new_non_frontend_data_type_controller.cc

Issue 8065016: [Sync] Refactor non-frontend DTC to handle new API properly. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Reffffactor Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/sync/glue/new_non_frontend_data_type_controller.cc
diff --git a/chrome/browser/sync/glue/new_non_frontend_data_type_controller.cc b/chrome/browser/sync/glue/new_non_frontend_data_type_controller.cc
new file mode 100644
index 0000000000000000000000000000000000000000..7a1848004b7b5e6c63e5c5caab634a187120ab57
--- /dev/null
+++ b/chrome/browser/sync/glue/new_non_frontend_data_type_controller.cc
@@ -0,0 +1,206 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/sync/glue/new_non_frontend_data_type_controller.h"
+
+#include "base/logging.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/sync/api/sync_error.h"
+#include "chrome/browser/sync/api/syncable_service.h"
+#include "chrome/browser/sync/glue/generic_change_processor.h"
+#include "chrome/browser/sync/glue/shared_change_processor_ref.h"
+#include "chrome/browser/sync/profile_sync_factory.h"
+#include "chrome/browser/sync/profile_sync_service.h"
+#include "chrome/browser/sync/syncable/model_type.h"
+#include "content/browser/browser_thread.h"
+
+namespace browser_sync {
+
+NewNonFrontendDataTypeController::NewNonFrontendDataTypeController()
+ : user_share_(NULL),
+ shared_change_processor_(NULL) {}
+
+NewNonFrontendDataTypeController::NewNonFrontendDataTypeController(
+ ProfileSyncFactory* profile_sync_factory,
+ Profile* profile)
+ : NonFrontendDataTypeController(profile_sync_factory, profile),
+ user_share_(NULL),
+ shared_change_processor_(NULL) {
+}
+
+NewNonFrontendDataTypeController::~NewNonFrontendDataTypeController() {}
+
+void NewNonFrontendDataTypeController::Start(StartCallback* start_callback) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK(start_callback);
+ if (state() != NOT_RUNNING) {
+ start_callback->Run(BUSY, SyncError());
+ delete start_callback;
+ return;
+ }
+
+ set_start_callback(start_callback);
+
+ set_state(MODEL_STARTING);
+ if (!StartModels()) {
+ // If we are waiting for some external service to load before associating
+ // or we failed to start the models, we exit early.
+ DCHECK(state() == MODEL_STARTING || state() == NOT_RUNNING);
+ return;
+ }
+
+ shared_change_processor_ =
+ profile_sync_factory()->CreateSharedChangeProcessor();
+ user_share_ = profile_sync_service()->GetUserShare();
+
+ // Kick off association on the thread the datatype resides on.
+ set_state(ASSOCIATING);
+ if (!StartAssociationAsync()) {
+ shared_change_processor_ = NULL;
+ SyncError error(FROM_HERE, "Failed to post StartAssociation", type());
+ StartDoneImpl(ASSOCIATION_FAILED, NOT_RUNNING, error);
+ }
+}
+
+// This method can execute after we've already stopped (and possibly even
+// destroyed) both the Syncer and the SyncableService. As a result, all actions
+// must either have no side effects outside of the DTC or must be protected
+// by |shared_change_processor_|, which is guaranteed to have been Disconnected
+// if the syncer shut down.
+void NewNonFrontendDataTypeController::StartAssociation() {
+ DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK_EQ(state(), ASSOCIATING);
+
+ // We're dependent on the SyncableService being destroyed on the same thread
+ // we access it. Therefore, as long as GetWeakHandleToSyncableService returns
+ // an initialized WeakHandle, we can rely on it remaining initialized for the
+ // life of this method.
+ local_service_ = GetWeakHandleToSyncableService();
akalin 2011/10/11 22:41:08 you want this to return a weak pointer. remember
Nicolas Zea 2011/10/12 04:24:19 Done.
+ if (!local_service_.IsInitialized()) {
+ // The SyncableService was destroyed before this task had a chance to
+ // execute.
+ SyncError error(FROM_HERE, "Local service destroyed before association.",
+ type());
+ StartFailed(UNRECOVERABLE_ERROR, error);
+ return;
+ }
+
+ // The ProfileSyncFactory is owned by the profile itself, and gets destroyed
+ // only when the profile gets destroyed. We can be sure the profile is still
+ // running, else |local_service_| would not have been initialized.
+ GenericChangeProcessor* generic_change_processor =
+ profile_sync_factory()->CreateGenericChangeProcessor(
+ profile_sync_service(), this, local_service_.Get());
akalin 2011/10/11 22:41:08 local_service_.Get() -> local_service
Nicolas Zea 2011/10/12 04:24:19 Done.
+
+ // Takes ownership of generic_change_processor. Note that it's possible
+ // the shared_change_processor_ has already been disconnected at this point,
+ // so all our accesses to the syncer should be through it.
+ shared_change_processor_->Connect(generic_change_processor);
+
+ if (!shared_change_processor_->CryptoReadyIfNecessary(type())) {
+ StartFailed(NEEDS_CRYPTO, SyncError());
+ return;
+ }
+
+ bool sync_has_nodes = false;
+ if (!shared_change_processor_->SyncModelHasUserCreatedNodes(
+ type(), &sync_has_nodes)) {
+ SyncError error(FROM_HERE, "Failed to load sync nodes", type());
+ StartFailed(UNRECOVERABLE_ERROR, error);
+ return;
+ }
+
+ base::TimeTicks start_time = base::TimeTicks::Now();
+ SyncError error;
+ SyncDataList initial_sync_data;
+ error = shared_change_processor_->GetSyncDataForType(type(),
+ &initial_sync_data);
+ if (error.IsSet()) {
+ StartFailed(ASSOCIATION_FAILED, error);
+ return;
+ }
+ // Passes a reference to the shared_change_processor_;
+ error = local_service_.Get()->MergeDataAndStartSyncing(
akalin 2011/10/11 22:41:08 local_service
Nicolas Zea 2011/10/12 04:24:19 Done.
+ type(),
+ initial_sync_data,
+ new SharedChangeProcessorRef(shared_change_processor_));
+ RecordAssociationTime(base::TimeTicks::Now() - start_time);
+ if (error.IsSet()) {
+ local_service_.Get()->StopSyncing(type());
akalin 2011/10/11 22:41:08 local_service
Nicolas Zea 2011/10/12 04:24:19 Done.
+ StartFailed(ASSOCIATION_FAILED, error);
+ return;
+ }
+
+ // If we've been disconnected, profile_sync_service() may return an invalid
+ // pointer, but the shared_change_processor_ protects us from attempting to
+ // access it.
+ // Note: This must be done on the datatype's thread to ensure local_service_
+ // doesn't start trying to push changes from it's thread before we activate
+ // the datatype.
+ shared_change_processor_->ActivateDataType(profile_sync_service(),
+ type(), model_safe_group());
+ StartDone(!sync_has_nodes ? OK_FIRST_RUN : OK, RUNNING, SyncError());
+}
+
+void NewNonFrontendDataTypeController::StartDone(
+ DataTypeController::StartResult result,
+ DataTypeController::State new_state,
+ const SyncError& error) {
+ DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI));
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ base::Bind(
+ &NewNonFrontendDataTypeController::StartDoneImpl,
+ this,
+ result,
+ new_state,
+ error));
+}
+
+void NewNonFrontendDataTypeController::Stop() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ // Disconnect the change processor. At this point, the SyncableService
+ // can no longer interact with the Syncer, even if it hasn't finished
+ // MergeDataAndStartSyncing. |local_service_| is not owned by us. Just post a
+ // task to tell it to StopSyncing.
+ if (shared_change_processor_.get()) {
+ shared_change_processor_->Disconnect();
+ local_service_.Call(FROM_HERE, &SyncableService::StopSyncing, type());
+ // Note: we do not release our reference to |shared_change_processor_|
+ // as StartAssociation may be running/not have run yet and may attempt
+ // to access it.
+ }
+
+ // If we haven't finished starting, we need to abort the start.
+ if (state() == MODEL_STARTING) {
+ set_state(STOPPING);
+ StartDoneImpl(ABORTED, NOT_RUNNING, SyncError());
+ return; // The datatype was never activated, we're done.
+ } else if (state() == ASSOCIATING) {
+ set_state(STOPPING);
+ StartDoneImpl(ABORTED, NOT_RUNNING, SyncError());
+ // We continue on to deactivate the datatype.
+ } else {
+ // Datatype was fully started.
+ set_state(STOPPING);
+ StopModels();
+ }
+
+ // Deactivate the DataType on the UI thread. We dont want to listen
+ // for any more changes or process them from the server.
+ profile_sync_service()->DeactivateDataType(type());
+
+ set_state(NOT_RUNNING);
+}
+
+bool NewNonFrontendDataTypeController::StopAssociationAsync() {
+ NOTIMPLEMENTED();
+ return false;
+}
+
+void NewNonFrontendDataTypeController::CreateSyncComponents() {
+ NOTIMPLEMENTED();
+}
+
+} // namepsace browser_sync

Powered by Google App Engine
This is Rietveld 408576698