Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / sync_file_system / drive_backend / register_app_task.cc
blob91bb5d6abeebb22ef052c24bd1c00768018eda99
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/sync_file_system/drive_backend/register_app_task.h"
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "chrome/browser/drive/drive_api_util.h"
10 #include "chrome/browser/drive/drive_service_interface.h"
11 #include "chrome/browser/sync_file_system/drive_backend/drive_backend_constants.h"
12 #include "chrome/browser/sync_file_system/drive_backend/folder_creator.h"
13 #include "chrome/browser/sync_file_system/drive_backend/metadata_database.h"
14 #include "chrome/browser/sync_file_system/drive_backend/metadata_database.pb.h"
15 #include "chrome/browser/sync_file_system/drive_backend/sync_engine_context.h"
16 #include "chrome/browser/sync_file_system/drive_backend/tracker_set.h"
17 #include "chrome/browser/sync_file_system/syncable_file_system_util.h"
18 #include "google_apis/drive/drive_api_parser.h"
19 #include "google_apis/drive/gdata_wapi_parser.h"
21 namespace sync_file_system {
22 namespace drive_backend {
24 namespace {
26 bool CompareOnCTime(const FileTracker& left,
27 const FileTracker& right) {
28 return left.synced_details().creation_time() <
29 right.synced_details().creation_time();
32 } // namespace
34 RegisterAppTask::RegisterAppTask(SyncEngineContext* sync_context,
35 const std::string& app_id)
36 : sync_context_(sync_context),
37 create_folder_retry_count_(0),
38 app_id_(app_id),
39 weak_ptr_factory_(this) {
42 RegisterAppTask::~RegisterAppTask() {
45 void RegisterAppTask::Run(const SyncStatusCallback& callback) {
46 if (create_folder_retry_count_++ >= kMaxRetry) {
47 callback.Run(SYNC_STATUS_FAILED);
48 return;
51 if (!metadata_database() || !drive_service()) {
52 callback.Run(SYNC_STATUS_FAILED);
53 return;
56 int64 sync_root = metadata_database()->GetSyncRootTrackerID();
57 TrackerSet trackers;
58 if (!metadata_database()->FindTrackersByParentAndTitle(
59 sync_root, app_id_, &trackers)) {
60 CreateAppRootFolder(callback);
61 return;
64 FileTracker candidate;
65 if (!FilterCandidates(trackers, &candidate)) {
66 CreateAppRootFolder(callback);
67 return;
70 if (candidate.active()) {
71 RunSoon(FROM_HERE, base::Bind(callback, SYNC_STATUS_OK));
72 return;
75 RegisterAppIntoDatabase(candidate, callback);
78 void RegisterAppTask::CreateAppRootFolder(const SyncStatusCallback& callback) {
79 int64 sync_root_tracker_id = metadata_database()->GetSyncRootTrackerID();
80 FileTracker sync_root_tracker;
81 bool should_success = metadata_database()->FindTrackerByTrackerID(
82 sync_root_tracker_id,
83 &sync_root_tracker);
84 DCHECK(should_success);
86 DCHECK(!folder_creator_);
87 folder_creator_.reset(new FolderCreator(
88 drive_service(), metadata_database(),
89 sync_root_tracker.file_id(), app_id_));
90 folder_creator_->Run(base::Bind(
91 &RegisterAppTask::DidCreateAppRootFolder,
92 weak_ptr_factory_.GetWeakPtr(), callback));
95 void RegisterAppTask::DidCreateAppRootFolder(
96 const SyncStatusCallback& callback,
97 const std::string& folder_id,
98 SyncStatusCode status) {
99 scoped_ptr<FolderCreator> deleter = folder_creator_.Pass();
100 if (status != SYNC_STATUS_OK) {
101 callback.Run(status);
102 return;
105 Run(callback);
108 bool RegisterAppTask::FilterCandidates(const TrackerSet& trackers,
109 FileTracker* candidate) {
110 DCHECK(candidate);
111 if (trackers.has_active()) {
112 *candidate = *trackers.active_tracker();
113 return true;
116 FileTracker* oldest_tracker = NULL;
117 for (TrackerSet::const_iterator itr = trackers.begin();
118 itr != trackers.end(); ++itr) {
119 FileTracker* tracker = *itr;
120 FileMetadata file;
121 DCHECK(!tracker->active());
122 DCHECK(tracker->has_synced_details());
124 if (!metadata_database()->FindFileByFileID(tracker->file_id(), &file)) {
125 NOTREACHED();
126 // The parent folder is sync-root, whose contents are fetched in
127 // initialization sequence.
128 // So at this point, direct children of sync-root should have
129 // FileMetadata.
130 continue;
133 if (file.details().file_kind() != FILE_KIND_FOLDER)
134 continue;
136 if (file.details().missing())
137 continue;
139 if (oldest_tracker && CompareOnCTime(*oldest_tracker, *tracker))
140 continue;
142 oldest_tracker = tracker;
145 if (!oldest_tracker)
146 return false;
148 *candidate = *oldest_tracker;
149 return true;
152 void RegisterAppTask::RegisterAppIntoDatabase(
153 const FileTracker& tracker,
154 const SyncStatusCallback& callback) {
155 metadata_database()->RegisterApp(
156 app_id_, tracker.file_id(), callback);
159 MetadataDatabase* RegisterAppTask::metadata_database() {
160 return sync_context_->GetMetadataDatabase();
163 drive::DriveServiceInterface* RegisterAppTask::drive_service() {
164 return sync_context_->GetDriveService();
167 } // namespace drive_backend
168 } // namespace sync_file_system