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

Unified Diff: chrome/browser/sync_file_system/drive_backend/sync_engine_initializer.cc

Issue 23949002: [SyncFS] Implement SyncEngineInitializer (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 7 years, 3 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_file_system/drive_backend/sync_engine_initializer.cc
diff --git a/chrome/browser/sync_file_system/drive_backend/sync_engine_initializer.cc b/chrome/browser/sync_file_system/drive_backend/sync_engine_initializer.cc
index 9cefcf19279b4ae2e40efed3046882c1a12f90c8..5eb8897abf080fe18616081ebc77a653bb25dbff 100644
--- a/chrome/browser/sync_file_system/drive_backend/sync_engine_initializer.cc
+++ b/chrome/browser/sync_file_system/drive_backend/sync_engine_initializer.cc
@@ -7,23 +7,104 @@
#include "base/bind.h"
#include "base/callback.h"
#include "base/logging.h"
+#include "chrome/browser/drive/drive_api_service.h"
+#include "chrome/browser/drive/drive_api_util.h"
+#include "chrome/browser/google_apis/drive_api_parser.h"
#include "chrome/browser/sync_file_system/drive_backend/metadata_database.h"
+#include "chrome/browser/sync_file_system/drive_backend_v1/drive_file_sync_util.h"
namespace sync_file_system {
namespace drive_backend {
+namespace {
+
+// TODO(tzik): Move them to separate file.
+const char kSyncRootFolderTitle[] = "Chrome Syncable FileSystem";
+
+////////////////////////////////////////////////////////////////////////////////
+// Functions below are for wrapping the access to legacy GData WAPI classes.
+
+bool IsDeleted(const google_apis::ResourceEntry& entry) {
+ return entry.deleted();
+}
+
+bool HasNoParents(const google_apis::ResourceEntry& entry) {
+ return !entry.GetLinkByType(google_apis::Link::LINK_PARENT);
+}
+
+bool HasFolderAsParent(const google_apis::ResourceEntry& entry,
+ const std::string& parent_id) {
+ const ScopedVector<google_apis::Link>& links = entry.links();
+ for (ScopedVector<google_apis::Link>::const_iterator itr = links.begin();
+ itr != links.end(); ++itr) {
+ const google_apis::Link& link = **itr;
+ if (link.type() != google_apis::Link::LINK_PARENT)
+ continue;
+ if (drive::util::ExtractResourceIdFromUrl(link.href()) == parent_id)
+ return true;
+ }
+ return false;
+}
+
+bool LessOnCreationTime(const google_apis::ResourceEntry& left,
+ const google_apis::ResourceEntry& right) {
+ return left.published_time() < right.published_time();
+}
+
+// Posts a request to continue listing. Returns false if the list doesn't need
+// listing anymore.
+bool GetRemainingFileList(
+ google_apis::CancelCallback* cancel_callback,
+ drive::DriveServiceInterface* api_service,
+ const google_apis::ResourceList& resource_list,
+ const google_apis::GetResourceListCallback& callback) {
+ GURL next_url;
+ if (!resource_list.GetNextFeedURL(&next_url))
+ return false;
+
+ *cancel_callback = api_service->GetRemainingFileList(next_url, callback);
+ return true;
+}
+
+std::string GetID(const google_apis::ResourceEntry& entry) {
+ return entry.resource_id();
+}
+
+ScopedVector<google_apis::FileResource> ConvertResourceEntriesToFileResources(
+ const ScopedVector<google_apis::ResourceEntry>& entries) {
+ ScopedVector<google_apis::FileResource> resources;
+ for (ScopedVector<google_apis::ResourceEntry>::const_iterator itr =
+ entries.begin();
+ itr != entries.end();
+ ++itr) {
+ resources.push_back(
+ drive::util::ConvertResourceEntryToFileResource(
+ **itr).release());
+ }
+ return resources.Pass();
+}
+
+// Functions above are for wrapping the access to legacy GData WAPI classes.
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace
+
SyncEngineInitializer::SyncEngineInitializer(
base::SequencedTaskRunner* task_runner,
- drive::DriveAPIService* drive_api,
+ drive::DriveServiceInterface* drive_service,
const base::FilePath& database_path)
: task_runner_(task_runner),
- drive_api_(drive_api),
+ drive_service_(drive_service),
database_path_(database_path),
+ largest_change_id_(0),
weak_ptr_factory_(this) {
+ DCHECK(task_runner);
+ DCHECK(drive_service_);
}
SyncEngineInitializer::~SyncEngineInitializer() {
- NOTIMPLEMENTED();
+ if (!cancel_callback_.is_null())
+ cancel_callback_.Run();
}
void SyncEngineInitializer::Run(const SyncStatusCallback& callback) {
@@ -33,6 +114,10 @@ void SyncEngineInitializer::Run(const SyncStatusCallback& callback) {
weak_ptr_factory_.GetWeakPtr(), callback));
}
+scoped_ptr<MetadataDatabase> SyncEngineInitializer::PassMetadataDatabase() {
+ return metadata_database_.Pass();
+}
+
void SyncEngineInitializer::DidCreateMetadataDatabase(
const SyncStatusCallback& callback,
SyncStatusCode status,
@@ -42,13 +127,208 @@ void SyncEngineInitializer::DidCreateMetadataDatabase(
return;
}
+ DCHECK(instance);
metadata_database_ = instance.Pass();
+ if (metadata_database_->HasSyncRoot()) {
+ callback.Run(SYNC_STATUS_OK);
+ return;
+ }
+
+ GetAboutResource(callback);
+}
+
+void SyncEngineInitializer::GetAboutResource(
+ const SyncStatusCallback& callback) {
+ drive_service_->GetAboutResource(
+ base::Bind(&SyncEngineInitializer::DidGetAboutResource,
+ weak_ptr_factory_.GetWeakPtr(), callback));
+}
+
+void SyncEngineInitializer::DidGetAboutResource(
+ const SyncStatusCallback& callback,
+ google_apis::GDataErrorCode error,
+ scoped_ptr<google_apis::AboutResource> about_resource) {
+ cancel_callback_.Reset();
+ if (error != google_apis::HTTP_SUCCESS) {
+ callback.Run(GDataErrorCodeToSyncStatusCode(error));
+ return;
+ }
+
+ DCHECK(about_resource);
+ root_folder_id_ = about_resource->root_folder_id();
+ largest_change_id_ = about_resource->largest_change_id();
+
+ DCHECK(!root_folder_id_.empty());
+ FindSyncRoot(callback);
+}
+
+void SyncEngineInitializer::FindSyncRoot(const SyncStatusCallback& callback) {
+ cancel_callback_ = drive_service_->SearchByTitle(
+ kSyncRootFolderTitle,
+ std::string(), // parent_folder_id
+ base::Bind(&SyncEngineInitializer::DidFindSyncRoot,
+ weak_ptr_factory_.GetWeakPtr(),
+ callback));
+}
+
+void SyncEngineInitializer::DidFindSyncRoot(
+ const SyncStatusCallback& callback,
+ google_apis::GDataErrorCode error,
+ scoped_ptr<google_apis::ResourceList> resource_list) {
+ cancel_callback_.Reset();
+ if (error != google_apis::HTTP_SUCCESS) {
+ callback.Run(GDataErrorCodeToSyncStatusCode(error));
+ return;
+ }
+
+ ScopedVector<google_apis::ResourceEntry>* entries =
+ resource_list->mutable_entries();
+ for (ScopedVector<google_apis::ResourceEntry>::iterator itr =
+ entries->begin();
+ itr != entries->end(); ++itr) {
+ google_apis::ResourceEntry* entry = *itr;
+
+ // Ignore deleted folder.
+ if (IsDeleted(*entry))
+ continue;
- // TODO(tzik): Set up sync root and populate database with initial folder
- // tree.
+ // Pick an orphaned folder or a direct child of the root folder and
+ // ignore others.
+ DCHECK(!root_folder_id_.empty());
+ if (!HasNoParents(*entry) && !HasFolderAsParent(*entry, root_folder_id_))
+ continue;
+
+ if (!sync_root_folder_ || LessOnCreationTime(*entry, *sync_root_folder_)) {
+ sync_root_folder_.reset(entry);
+ *itr = NULL;
+ }
+ }
+
+ // If there are more results, retrieve them.
+ if (GetRemainingFileList(
+ &cancel_callback_,
+ drive_service_, *resource_list,
+ base::Bind(&SyncEngineInitializer::DidFindSyncRoot,
+ weak_ptr_factory_.GetWeakPtr(),
+ callback)))
+ return;
+
+ if (!sync_root_folder_) {
+ CreateSyncRoot(callback);
+ return;
+ }
+
+ if (!HasNoParents(*sync_root_folder_)) {
+ DetachSyncRoot(callback);
+ return;
+ }
+
+ ListAppRootFolders(callback);
+}
+
+void SyncEngineInitializer::CreateSyncRoot(const SyncStatusCallback& callback) {
+ DCHECK(!sync_root_folder_);
+ cancel_callback_ = drive_service_->AddNewDirectory(
+ root_folder_id_, kSyncRootFolderTitle,
+ base::Bind(&SyncEngineInitializer::DidCreateSyncRoot,
+ weak_ptr_factory_.GetWeakPtr(),
+ callback));
+}
+
+void SyncEngineInitializer::DidCreateSyncRoot(
+ const SyncStatusCallback& callback,
+ google_apis::GDataErrorCode error,
+ scoped_ptr<google_apis::ResourceEntry> entry) {
+ DCHECK(!sync_root_folder_);
+ cancel_callback_.Reset();
+ if (error != google_apis::HTTP_SUCCESS &&
+ error != google_apis::HTTP_CREATED) {
+ callback.Run(GDataErrorCodeToSyncStatusCode(error));
+ return;
+ }
+
+ FindSyncRoot(callback);
+}
+
+void SyncEngineInitializer::DetachSyncRoot(const SyncStatusCallback& callback) {
+ DCHECK(sync_root_folder_);
+ cancel_callback_ = drive_service_->RemoveResourceFromDirectory(
+ root_folder_id_, GetID(*sync_root_folder_),
+ base::Bind(&SyncEngineInitializer::DidDetachSyncRoot,
+ weak_ptr_factory_.GetWeakPtr(),
+ callback));
+}
+
+void SyncEngineInitializer::DidDetachSyncRoot(
+ const SyncStatusCallback& callback,
+ google_apis::GDataErrorCode error) {
+ cancel_callback_.Reset();
+ if (error != google_apis::HTTP_SUCCESS) {
+ callback.Run(GDataErrorCodeToSyncStatusCode(error));
+ return;
+ }
+ ListAppRootFolders(callback);
+}
+
+void SyncEngineInitializer::ListAppRootFolders(
+ const SyncStatusCallback& callback) {
+ DCHECK(sync_root_folder_);
+ cancel_callback_ = drive_service_->GetResourceListInDirectory(
+ GetID(*sync_root_folder_),
+ base::Bind(&SyncEngineInitializer::DidListAppRootFolders,
+ weak_ptr_factory_.GetWeakPtr(),
+ callback));
+}
+
+void SyncEngineInitializer::DidListAppRootFolders(
+ const SyncStatusCallback& callback,
+ google_apis::GDataErrorCode error,
+ scoped_ptr<google_apis::ResourceList> resource_list) {
+ cancel_callback_.Reset();
+ if (error != google_apis::HTTP_SUCCESS) {
+ callback.Run(GDataErrorCodeToSyncStatusCode(error));
+ return;
+ }
+
+ ScopedVector<google_apis::ResourceEntry>* new_entries =
+ resource_list->mutable_entries();
+ app_root_folders_.insert(app_root_folders_.end(),
+ new_entries->begin(), new_entries->end());
+ new_entries->weak_clear();
+
+ if (GetRemainingFileList(
+ &cancel_callback_,
+ drive_service_,
+ *resource_list,
+ base::Bind(&SyncEngineInitializer::DidListAppRootFolders,
+ weak_ptr_factory_.GetWeakPtr(), callback)))
+ return;
+
+ PopulateDatabase(callback);
+}
+
+void SyncEngineInitializer::PopulateDatabase(
+ const SyncStatusCallback& callback) {
+ DCHECK(sync_root_folder_);
+ metadata_database_->PopulateInitialData(
+ largest_change_id_,
+ *drive::util::ConvertResourceEntryToFileResource(
+ *sync_root_folder_),
+ ConvertResourceEntriesToFileResources(app_root_folders_),
+ base::Bind(&SyncEngineInitializer::DidPopulateDatabase,
+ weak_ptr_factory_.GetWeakPtr(),
+ callback));
+}
+
+void SyncEngineInitializer::DidPopulateDatabase(
+ const SyncStatusCallback& callback,
+ SyncStatusCode status) {
+ if (status != SYNC_STATUS_OK) {
+ callback.Run(status);
+ return;
+ }
- NOTIMPLEMENTED();
- callback.Run(SYNC_STATUS_FAILED);
+ callback.Run(SYNC_STATUS_OK);
}
} // namespace drive_backend

Powered by Google App Engine
This is Rietveld 408576698