Index: chrome/browser/sync/glue/data_type_manager_impl.cc |
diff --git a/chrome/browser/sync/glue/data_type_manager_impl.cc b/chrome/browser/sync/glue/data_type_manager_impl.cc |
index 2514c3e2e8678971d70cc48f3519e4e37a4fc366..d6bdec8a73807cf9f98ad6340cc7098731dfb6fb 100644 |
--- a/chrome/browser/sync/glue/data_type_manager_impl.cc |
+++ b/chrome/browser/sync/glue/data_type_manager_impl.cc |
@@ -2,14 +2,14 @@ |
// 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/data_type_manager_impl.h" |
+ |
#include <algorithm> |
#include <functional> |
+#include "base/compiler_specific.h" |
#include "base/logging.h" |
-#include "base/message_loop.h" |
-#include "base/task.h" |
#include "chrome/browser/sync/glue/data_type_controller.h" |
-#include "chrome/browser/sync/glue/data_type_manager_impl.h" |
#include "chrome/browser/sync/glue/sync_backend_host.h" |
#include "content/browser/browser_thread.h" |
#include "content/common/notification_details.h" |
@@ -21,16 +21,23 @@ namespace browser_sync { |
namespace { |
static const syncable::ModelType kStartOrder[] = { |
+ syncable::NIGORI, // Listed for completeness. |
syncable::BOOKMARKS, |
syncable::PREFERENCES, |
syncable::AUTOFILL, |
syncable::AUTOFILL_PROFILE, |
+ syncable::EXTENSIONS, |
+ syncable::APPS, |
syncable::THEMES, |
syncable::TYPED_URLS, |
syncable::PASSWORDS, |
syncable::SESSIONS, |
}; |
+COMPILE_ASSERT(arraysize(kStartOrder) == |
+ syncable::MODEL_TYPE_COUNT - syncable::FIRST_REAL_MODEL_TYPE, |
+ kStartOrder_IncorrectSize); |
+ |
// Comparator used when sorting data type controllers. |
class SortComparator : public std::binary_function<DataTypeController*, |
DataTypeController*, |
@@ -50,18 +57,14 @@ class SortComparator : public std::binary_function<DataTypeController*, |
} // namespace |
-DataTypeManagerImpl::DataTypeManagerImpl( |
- SyncBackendHost* backend, |
+DataTypeManagerImpl::DataTypeManagerImpl(SyncBackendHost* backend, |
const DataTypeController::TypeMap& controllers) |
: backend_(backend), |
controllers_(controllers), |
state_(DataTypeManager::STOPPED), |
- syncer_paused_(false), |
needs_reconfigure_(false), |
- ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
DCHECK(backend_); |
- DCHECK_GT(arraysize(kStartOrder), 0U); |
// Ensure all data type controllers are stopped. |
for (DataTypeController::TypeMap::const_iterator it = controllers_.begin(); |
it != controllers_.end(); ++it) { |
@@ -73,8 +76,7 @@ DataTypeManagerImpl::DataTypeManagerImpl( |
start_order_[kStartOrder[i]] = i; |
} |
-DataTypeManagerImpl::~DataTypeManagerImpl() { |
-} |
+DataTypeManagerImpl::~DataTypeManagerImpl() {} |
bool DataTypeManagerImpl::GetControllersNeedingStart( |
std::vector<DataTypeController*>* needs_start) { |
@@ -147,7 +149,6 @@ void DataTypeManagerImpl::Configure(const TypeSet& desired_types) { |
} |
void DataTypeManagerImpl::Restart() { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
VLOG(1) << "Restarting..."; |
DCHECK(state_ == STOPPED || state_ == CONFIGURED || state_ == BLOCKED); |
@@ -171,50 +172,17 @@ void DataTypeManagerImpl::Restart() { |
controllers_, |
last_requested_types_, |
method_factory_.NewRunnableMethod(&DataTypeManagerImpl::DownloadReady)); |
- |
- // If there were new types needing download, a nudge will have been sent and |
- // we should be in DOWNLOAD_PENDING. In that case we start the syncer thread |
- // (which is idempotent) to fetch these updates. |
- // However, we could actually be in PAUSE_PENDING here as if no new types |
- // were needed, our DownloadReady callback will have fired and we will have |
- // requested a pause already (so starting the syncer thread will still not |
- // let it make forward progress as the pause needs to be resumed by us). |
- // Because both the pause and start syncing commands are posted FCFS to the |
- // core thread, there is no race between the pause and the start; the pause |
- // will always win, so we will always start paused if we don't need to |
- // download new types. Thus, in almost all cases, the syncer thread DOES NOT |
- // start before model association. But... |
- // |
- // TODO(tim): Bug 47957. There is still subtle badness here. If we just |
- // restarted the browser and were upgraded in between, we may be in a state |
- // where a bunch of data types do have initial sync ended, but a new guy |
- // does not. In this case, what we really want is to _only_ download updates |
- // for that new type and not the ones that have already finished and we've |
- // presumably associated before. What happens now is the syncer is nudged |
- // and it does a sync from timestamp 0 for only the new types, and sends the |
- // OnSyncCycleCompleted event, which is how we get the DownloadReady call. |
- // We request a pause at this point, but it is done asynchronously. So in |
- // theory, the syncer could charge forward with another sync (for _all_ |
- // types) before the pause is serviced, which could be bad for associating |
- // models as we'll merge the present cloud with the immediate past, which |
- // opens the door to bugs like "bookmark came back from dead". A lot more |
- // stars have to align now for this to happen, but it's still there. |
- backend_->StartSyncingWithServer(); |
} |
void DataTypeManagerImpl::DownloadReady() { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
DCHECK(state_ == DOWNLOAD_PENDING); |
+ NotificationService::current()->Notify( |
+ NotificationType::SYNC_CONFIGURE_UPDATES_DOWNLOADED, |
+ Source<DataTypeManager>(this), |
+ NotificationService::NoDetails()); |
- if (syncer_paused_) { |
- state_ = CONFIGURING; |
- StartNextType(); |
- return; |
- } |
- |
- // Pause the sync backend before starting the data types. |
- state_ = PAUSE_PENDING; |
- PauseSyncer(); |
+ state_ = CONFIGURING; |
+ StartNextType(); |
} |
void DataTypeManagerImpl::StartNextType() { |
@@ -252,10 +220,9 @@ void DataTypeManagerImpl::StartNextType() { |
return; |
} |
- // If no more data types need starting, we're done. Resume the sync backend |
- // to finish. |
- state_ = RESUME_PENDING; |
- ResumeSyncer(); |
+ // If no more data types need starting, we're done. |
+ state_ = CONFIGURED; |
+ NotifyDone(OK, FROM_HERE); |
} |
void DataTypeManagerImpl::TypeStartCallback( |
@@ -265,40 +232,32 @@ void DataTypeManagerImpl::TypeStartCallback( |
// on the UI thread. |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- // We're done with the data type at the head of the list -- remove it. |
- DataTypeController* started_dtc = needs_start_[0]; |
- DCHECK(needs_start_.size()); |
- DCHECK_EQ(needs_start_[0], started_dtc); |
- needs_start_.erase(needs_start_.begin()); |
- |
- // If we reach this callback while stopping, this means that |
- // DataTypeManager::Stop() was called while the current data type |
- // was starting. Now that it has finished starting, we can finish |
- // stopping the DataTypeManager. This is considered an ABORT. |
if (state_ == STOPPING) { |
+ // If we reach this callback while stopping, this means that |
+ // DataTypeManager::Stop() was called while the current data type |
+ // was starting. Now that it has finished starting, we can finish |
+ // stopping the DataTypeManager. This is considered an ABORT. |
FinishStopAndNotify(ABORTED, FROM_HERE); |
return; |
- } |
- |
- // If our state_ is STOPPED, we have already stopped all of the data |
- // types. We should not be getting callbacks from stopped data types. |
- if (state_ == STOPPED) { |
+ } else if (state_ == STOPPED) { |
+ // If our state_ is STOPPED, we have already stopped all of the data |
+ // types. We should not be getting callbacks from stopped data types. |
LOG(ERROR) << "Start callback called by stopped data type!"; |
return; |
} |
- // If the type is waiting for the cryptographer, continue to the next type. |
- // Once the cryptographer is ready, we'll attempt to restart this type. |
- if (result == DataTypeController::NEEDS_CRYPTO) { |
- VLOG(1) << "Waiting for crypto " << started_dtc->name(); |
- StartNextType(); |
- return; |
- } |
+ // We're done with the data type at the head of the list -- remove it. |
+ DataTypeController* started_dtc = needs_start_[0]; |
+ DCHECK(needs_start_.size()); |
+ DCHECK_EQ(needs_start_[0], started_dtc); |
+ needs_start_.erase(needs_start_.begin()); |
// If the type started normally, continue to the next type. |
- if (result == DataTypeController::OK || |
+ // If the type is waiting for the cryptographer, continue to the next type. |
+ // Once the cryptographer is ready, we'll attempt to restart this type. |
+ if (result == DataTypeController::NEEDS_CRYPTO || |
+ result == DataTypeController::OK || |
result == DataTypeController::OK_FIRST_RUN) { |
- VLOG(1) << "Started " << started_dtc->name(); |
StartNextType(); |
return; |
} |
@@ -347,49 +306,21 @@ void DataTypeManagerImpl::Stop() { |
return; |
} |
- // If Stop() is called while waiting for pause or resume, we no |
- // longer care about this. |
- bool aborted = false; |
- if (state_ == PAUSE_PENDING) { |
- RemoveObserver(NotificationType::SYNC_PAUSED); |
- aborted = true; |
- } |
- if (state_ == RESUME_PENDING) { |
- RemoveObserver(NotificationType::SYNC_RESUMED); |
- aborted = true; |
- } |
- |
- // If Stop() is called while waiting for download, cancel all |
- // outstanding tasks. |
- if (state_ == DOWNLOAD_PENDING) { |
- method_factory_.RevokeAll(); |
- aborted = true; |
- } |
- |
+ const bool download_pending = state_ == DOWNLOAD_PENDING; |
state_ = STOPPING; |
- if (aborted) |
+ if (download_pending) { |
+ // If Stop() is called while waiting for download, cancel all |
+ // outstanding tasks. |
+ method_factory_.RevokeAll(); |
FinishStopAndNotify(ABORTED, FROM_HERE); |
- else |
- FinishStop(); |
-} |
- |
-const DataTypeController::TypeMap& DataTypeManagerImpl::controllers() { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- return controllers_; |
-} |
+ return; |
+ } |
-DataTypeManager::State DataTypeManagerImpl::state() { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- return state_; |
+ FinishStop(); |
} |
void DataTypeManagerImpl::FinishStop() { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- DCHECK(state_== CONFIGURING || |
- state_ == STOPPING || |
- state_ == PAUSE_PENDING || |
- state_ == RESUME_PENDING || |
- state_ == BLOCKED); |
+ DCHECK(state_== CONFIGURING || state_ == STOPPING || state_ == BLOCKED); |
// Simply call the Stop() method on all running data types. |
for (DataTypeController::TypeMap::const_iterator it = controllers_.begin(); |
it != controllers_.end(); ++it) { |
@@ -405,70 +336,11 @@ void DataTypeManagerImpl::FinishStop() { |
void DataTypeManagerImpl::FinishStopAndNotify(ConfigureResult result, |
const tracked_objects::Location& location) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
FinishStop(); |
NotifyDone(result, location); |
} |
-void DataTypeManagerImpl::Observe(NotificationType type, |
- const NotificationSource& source, |
- const NotificationDetails& details) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- switch (type.value) { |
- case NotificationType::SYNC_PAUSED: |
- DCHECK(state_ == PAUSE_PENDING); |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- syncer_paused_ = true; |
- RemoveObserver(NotificationType::SYNC_PAUSED); |
- |
- state_ = CONFIGURING; |
- StartNextType(); |
- break; |
- case NotificationType::SYNC_RESUMED: |
- DCHECK(state_ == RESUME_PENDING); |
- RemoveObserver(NotificationType::SYNC_RESUMED); |
- syncer_paused_ = false; |
- |
- if (needs_reconfigure_) { |
- // An attempt was made to reconfigure while we were already configuring. |
- // This can be because a passphrase was accepted or the user changed the |
- // set of desired types. Either way, |last_requested_types_| will |
- // contain the most recent set of desired types, so we just call |
- // configure. |
- // Note: we do this whether or not GetControllersNeedingStart is true, |
- // because we may need to stop datatypes. |
- state_ = BLOCKED; |
- needs_reconfigure_ = false; |
- VLOG(1) << "Reconfiguring due to previous configure attempt occuring " |
- << " while busy."; |
- Configure(last_requested_types_); |
- return; |
- } |
- |
- state_ = CONFIGURED; |
- NotifyDone(OK, FROM_HERE); |
- break; |
- default: |
- NOTREACHED(); |
- } |
-} |
- |
-void DataTypeManagerImpl::AddObserver(NotificationType type) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- notification_registrar_.Add(this, |
- type, |
- NotificationService::AllSources()); |
-} |
- |
-void DataTypeManagerImpl::RemoveObserver(NotificationType type) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- notification_registrar_.Remove(this, |
- type, |
- NotificationService::AllSources()); |
-} |
- |
void DataTypeManagerImpl::NotifyStart() { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
NotificationService::current()->Notify( |
NotificationType::SYNC_CONFIGURE_START, |
Source<DataTypeManager>(this), |
@@ -477,7 +349,6 @@ void DataTypeManagerImpl::NotifyStart() { |
void DataTypeManagerImpl::NotifyDone(ConfigureResult result, |
const tracked_objects::Location& location) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
ConfigureResultWithErrorLocation result_with_location(result, location); |
NotificationService::current()->Notify( |
NotificationType::SYNC_CONFIGURE_DONE, |
@@ -485,22 +356,12 @@ void DataTypeManagerImpl::NotifyDone(ConfigureResult result, |
Details<ConfigureResultWithErrorLocation>(&result_with_location)); |
} |
-void DataTypeManagerImpl::ResumeSyncer() { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- AddObserver(NotificationType::SYNC_RESUMED); |
- if (!backend_->RequestResume()) { |
- RemoveObserver(NotificationType::SYNC_RESUMED); |
- FinishStopAndNotify(UNRECOVERABLE_ERROR, FROM_HERE); |
- } |
+const DataTypeController::TypeMap& DataTypeManagerImpl::controllers() { |
+ return controllers_; |
} |
-void DataTypeManagerImpl::PauseSyncer() { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- AddObserver(NotificationType::SYNC_PAUSED); |
- if (!backend_->RequestPause()) { |
- RemoveObserver(NotificationType::SYNC_PAUSED); |
- FinishStopAndNotify(UNRECOVERABLE_ERROR, FROM_HERE); |
- } |
+DataTypeManager::State DataTypeManagerImpl::state() { |
tim (not reviewing)
2011/04/18 16:11:47
I'm assuming you made no changes to DataTypeManage
lipalani1
2011/04/18 20:36:41
Yep straight port.
On 2011/04/18 16:11:47, timstee
|
+ return state_; |
} |
} // namespace browser_sync |