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

Side by Side Diff: chrome/browser/chromeos/drive/sync/entry_update_performer.cc

Issue 145173010: drive: Merge ContentUpdatePerformer to EntryUpdatePerformer (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: please review this Created 6 years, 11 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/chromeos/drive/sync/entry_update_performer.h" 5 #include "chrome/browser/chromeos/drive/sync/entry_update_performer.h"
6 6
7 #include "chrome/browser/chromeos/drive/drive.pb.h" 7 #include "chrome/browser/chromeos/drive/drive.pb.h"
8 #include "chrome/browser/chromeos/drive/file_cache.h"
8 #include "chrome/browser/chromeos/drive/file_system_util.h" 9 #include "chrome/browser/chromeos/drive/file_system_util.h"
9 #include "chrome/browser/chromeos/drive/job_scheduler.h" 10 #include "chrome/browser/chromeos/drive/job_scheduler.h"
10 #include "chrome/browser/chromeos/drive/resource_metadata.h" 11 #include "chrome/browser/chromeos/drive/resource_metadata.h"
11 #include "chrome/browser/chromeos/drive/sync/entry_revert_performer.h" 12 #include "chrome/browser/chromeos/drive/sync/entry_revert_performer.h"
12 #include "chrome/browser/chromeos/drive/sync/remove_performer.h" 13 #include "chrome/browser/chromeos/drive/sync/remove_performer.h"
13 #include "content/public/browser/browser_thread.h" 14 #include "content/public/browser/browser_thread.h"
14 15
15 using content::BrowserThread; 16 using content::BrowserThread;
16 17
17 namespace drive { 18 namespace drive {
18 namespace internal { 19 namespace internal {
20
21 struct EntryUpdatePerformer::LocalState {
22 LocalState() : should_content_update(false) {
23 }
24
25 ResourceEntry entry;
26 ResourceEntry parent_entry;
27 base::FilePath drive_file_path;
28 base::FilePath cache_file_path;
29 bool should_content_update;
30 };
31
19 namespace { 32 namespace {
20 33
21 // Looks up ResourceEntry for source entry and its parent. 34 // Looks up ResourceEntry for source entry and its parent.
22 FileError PrepareUpdate(ResourceMetadata* metadata, 35 FileError PrepareUpdate(ResourceMetadata* metadata,
36 FileCache* cache,
23 const std::string& local_id, 37 const std::string& local_id,
24 ResourceEntry* entry, 38 EntryUpdatePerformer::LocalState* local_state) {
25 ResourceEntry* parent_entry) { 39 FileError error = metadata->GetResourceEntryById(local_id,
26 FileError error = metadata->GetResourceEntryById(local_id, entry); 40 &local_state->entry);
27 if (error != FILE_ERROR_OK) 41 if (error != FILE_ERROR_OK)
28 return error; 42 return error;
29 43
30 error = metadata->GetResourceEntryById(entry->parent_local_id(), 44 error = metadata->GetResourceEntryById(local_state->entry.parent_local_id(),
31 parent_entry); 45 &local_state->parent_entry);
32 if (error != FILE_ERROR_OK) 46 if (error != FILE_ERROR_OK)
33 return error; 47 return error;
34 48
35 switch (entry->metadata_edit_state()) { 49 local_state->drive_file_path = metadata->GetFilePath(local_id);
50 if (local_state->drive_file_path.empty())
51 return FILE_ERROR_NOT_FOUND;
52
53 // Check if content update is needed or not.
54 FileCacheEntry cache_entry;
55 if (cache->GetCacheEntry(local_id, &cache_entry) &&
56 cache_entry.is_dirty() &&
57 !cache->IsOpenedForWrite(local_id)) {
58 // Update cache entry's MD5 if needed.
59 if (cache_entry.md5().empty()) {
60 error = cache->UpdateMd5(local_id);
61 if (error != FILE_ERROR_OK)
62 return error;
63 if (!cache->GetCacheEntry(local_id, &cache_entry))
64 return FILE_ERROR_NOT_FOUND;
65 }
66
67 if (cache_entry.md5() == local_state->entry.file_specific_info().md5()) {
68 error = cache->ClearDirty(local_id);
69 if (error != FILE_ERROR_OK)
70 return error;
71 } else {
72 error = cache->GetFile(local_id, &local_state->cache_file_path);
73 if (error != FILE_ERROR_OK)
74 return error;
75
76 local_state->should_content_update = true;
77 }
78 }
79
80 // Update metadata_edit_state.
81 switch (local_state->entry.metadata_edit_state()) {
36 case ResourceEntry::CLEAN: // Nothing to do. 82 case ResourceEntry::CLEAN: // Nothing to do.
37 case ResourceEntry::SYNCING: // Error during the last update. Go ahead. 83 case ResourceEntry::SYNCING: // Error during the last update. Go ahead.
38 break; 84 break;
39 85
40 case ResourceEntry::DIRTY: 86 case ResourceEntry::DIRTY:
41 entry->set_metadata_edit_state(ResourceEntry::SYNCING); 87 local_state->entry.set_metadata_edit_state(ResourceEntry::SYNCING);
42 error = metadata->RefreshEntry(*entry); 88 error = metadata->RefreshEntry(local_state->entry);
43 if (error != FILE_ERROR_OK) 89 if (error != FILE_ERROR_OK)
44 return error; 90 return error;
45 break; 91 break;
46 } 92 }
47 return FILE_ERROR_OK; 93 return FILE_ERROR_OK;
48 } 94 }
49 95
50 FileError FinishUpdate(ResourceMetadata* metadata, 96 FileError FinishUpdate(ResourceMetadata* metadata,
51 const std::string& local_id) { 97 FileCache* cache,
98 const std::string& local_id,
99 scoped_ptr<google_apis::ResourceEntry> resource_entry) {
52 ResourceEntry entry; 100 ResourceEntry entry;
53 FileError error = metadata->GetResourceEntryById(local_id, &entry); 101 FileError error = metadata->GetResourceEntryById(local_id, &entry);
54 if (error != FILE_ERROR_OK) 102 if (error != FILE_ERROR_OK)
55 return error; 103 return error;
56 104
105 // Update metadata_edit_state and MD5.
57 switch (entry.metadata_edit_state()) { 106 switch (entry.metadata_edit_state()) {
58 case ResourceEntry::CLEAN: // Nothing to do. 107 case ResourceEntry::CLEAN: // Nothing to do.
59 case ResourceEntry::DIRTY: // Entry was edited again during the update. 108 case ResourceEntry::DIRTY: // Entry was edited again during the update.
60 break; 109 break;
61 110
62 case ResourceEntry::SYNCING: 111 case ResourceEntry::SYNCING:
63 entry.set_metadata_edit_state(ResourceEntry::CLEAN); 112 entry.set_metadata_edit_state(ResourceEntry::CLEAN);
64 error = metadata->RefreshEntry(entry);
65 if (error != FILE_ERROR_OK)
66 return error;
67 break; 113 break;
68 } 114 }
115 if (!entry.file_info().is_directory())
116 entry.mutable_file_specific_info()->set_md5(resource_entry->file_md5());
117 error = metadata->RefreshEntry(entry);
118 if (error != FILE_ERROR_OK)
119 return error;
120
121 // Clear dirty bit unless the file has been edited during update.
122 FileCacheEntry cache_entry;
123 if (cache->GetCacheEntry(local_id, &cache_entry) &&
124 cache_entry.md5() == entry.file_specific_info().md5()) {
125 error = cache->ClearDirty(local_id);
126 if (error != FILE_ERROR_OK)
127 return error;
128 }
69 return FILE_ERROR_OK; 129 return FILE_ERROR_OK;
70 } 130 }
71 131
72 } // namespace 132 } // namespace
73 133
74 EntryUpdatePerformer::EntryUpdatePerformer( 134 EntryUpdatePerformer::EntryUpdatePerformer(
75 base::SequencedTaskRunner* blocking_task_runner, 135 base::SequencedTaskRunner* blocking_task_runner,
76 file_system::OperationObserver* observer, 136 file_system::OperationObserver* observer,
77 JobScheduler* scheduler, 137 JobScheduler* scheduler,
78 ResourceMetadata* metadata) 138 ResourceMetadata* metadata,
139 FileCache* cache)
79 : blocking_task_runner_(blocking_task_runner), 140 : blocking_task_runner_(blocking_task_runner),
80 scheduler_(scheduler), 141 scheduler_(scheduler),
81 metadata_(metadata), 142 metadata_(metadata),
143 cache_(cache),
82 remove_performer_(new RemovePerformer(blocking_task_runner, 144 remove_performer_(new RemovePerformer(blocking_task_runner,
83 observer, 145 observer,
84 scheduler, 146 scheduler,
85 metadata)), 147 metadata)),
86 entry_revert_performer_(new EntryRevertPerformer(blocking_task_runner, 148 entry_revert_performer_(new EntryRevertPerformer(blocking_task_runner,
87 observer, 149 observer,
88 scheduler, 150 scheduler,
89 metadata)), 151 metadata)),
90 weak_ptr_factory_(this) { 152 weak_ptr_factory_(this) {
91 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 153 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
92 } 154 }
93 155
94 EntryUpdatePerformer::~EntryUpdatePerformer() { 156 EntryUpdatePerformer::~EntryUpdatePerformer() {
95 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 157 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
96 } 158 }
97 159
98 void EntryUpdatePerformer::UpdateEntry(const std::string& local_id, 160 void EntryUpdatePerformer::UpdateEntry(const std::string& local_id,
99 const ClientContext& context, 161 const ClientContext& context,
100 const FileOperationCallback& callback) { 162 const FileOperationCallback& callback) {
101 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 163 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
102 DCHECK(!callback.is_null()); 164 DCHECK(!callback.is_null());
103 165
104 scoped_ptr<ResourceEntry> entry(new ResourceEntry); 166 scoped_ptr<LocalState> local_state(new LocalState);
105 scoped_ptr<ResourceEntry> parent_entry(new ResourceEntry); 167 LocalState* local_state_ptr = local_state.get();
106 ResourceEntry* entry_ptr = entry.get();
107 ResourceEntry* parent_entry_ptr = parent_entry.get();
108 base::PostTaskAndReplyWithResult( 168 base::PostTaskAndReplyWithResult(
109 blocking_task_runner_.get(), 169 blocking_task_runner_.get(),
110 FROM_HERE, 170 FROM_HERE,
111 base::Bind(&PrepareUpdate, 171 base::Bind(&PrepareUpdate, metadata_, cache_, local_id, local_state_ptr),
112 metadata_, local_id, entry_ptr, parent_entry_ptr),
113 base::Bind(&EntryUpdatePerformer::UpdateEntryAfterPrepare, 172 base::Bind(&EntryUpdatePerformer::UpdateEntryAfterPrepare,
114 weak_ptr_factory_.GetWeakPtr(), context, callback, 173 weak_ptr_factory_.GetWeakPtr(), context, callback,
115 base::Passed(&entry), 174 base::Passed(&local_state)));
116 base::Passed(&parent_entry)));
117 } 175 }
118 176
119 void EntryUpdatePerformer::UpdateEntryAfterPrepare( 177 void EntryUpdatePerformer::UpdateEntryAfterPrepare(
120 const ClientContext& context, 178 const ClientContext& context,
121 const FileOperationCallback& callback, 179 const FileOperationCallback& callback,
122 scoped_ptr<ResourceEntry> entry, 180 scoped_ptr<LocalState> local_state,
123 scoped_ptr<ResourceEntry> parent_entry,
124 FileError error) { 181 FileError error) {
125 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 182 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
126 DCHECK(!callback.is_null()); 183 DCHECK(!callback.is_null());
127 184
128 if (error != FILE_ERROR_OK) { 185 if (error != FILE_ERROR_OK) {
129 callback.Run(error); 186 callback.Run(error);
130 return; 187 return;
131 } 188 }
132 189
133 // Trashed entry should be removed. 190 // Trashed entry should be removed.
134 if (entry->parent_local_id() == util::kDriveTrashDirLocalId) { 191 if (local_state->entry.parent_local_id() == util::kDriveTrashDirLocalId) {
135 remove_performer_->Remove(entry->local_id(), context, callback); 192 remove_performer_->Remove(local_state->entry.local_id(), context, callback);
136 return; 193 return;
137 } 194 }
138 195
139 if (entry->metadata_edit_state() == ResourceEntry::CLEAN) { 196 base::Time last_modified = base::Time::FromInternalValue(
197 local_state->entry.file_info().last_modified());
198 base::Time last_accessed = base::Time::FromInternalValue(
199 local_state->entry.file_info().last_accessed());
200
201 // Perform content update.
202 if (local_state->should_content_update) {
203 drive::DriveUploader::UploadExistingFileOptions options;
204 options.title = local_state->entry.title();
205 options.parent_resource_id = local_state->parent_entry.resource_id();
206 options.modified_date = last_modified;
207 options.last_viewed_by_me_date = last_accessed;
208 scheduler_->UploadExistingFile(
209 local_state->entry.resource_id(),
210 local_state->drive_file_path,
211 local_state->cache_file_path,
212 local_state->entry.file_specific_info().content_mime_type(),
213 options,
214 context,
215 base::Bind(&EntryUpdatePerformer::UpdateEntryAfterUpdateResource,
216 weak_ptr_factory_.GetWeakPtr(),
217 context,
218 callback,
219 local_state->entry.local_id()));
220 return;
221 }
222
223 // No need to perform update.
224 if (local_state->entry.metadata_edit_state() == ResourceEntry::CLEAN) {
140 callback.Run(FILE_ERROR_OK); 225 callback.Run(FILE_ERROR_OK);
141 return; 226 return;
142 } 227 }
143 228
144 base::Time last_modified = 229 // Perform metadata update.
145 base::Time::FromInternalValue(entry->file_info().last_modified());
146 base::Time last_accessed =
147 base::Time::FromInternalValue(entry->file_info().last_accessed());
148 scheduler_->UpdateResource( 230 scheduler_->UpdateResource(
149 entry->resource_id(), parent_entry->resource_id(), 231 local_state->entry.resource_id(), local_state->parent_entry.resource_id(),
150 entry->title(), last_modified, last_accessed, 232 local_state->entry.title(), last_modified, last_accessed,
151 context, 233 context,
152 base::Bind(&EntryUpdatePerformer::UpdateEntryAfterUpdateResource, 234 base::Bind(&EntryUpdatePerformer::UpdateEntryAfterUpdateResource,
153 weak_ptr_factory_.GetWeakPtr(), 235 weak_ptr_factory_.GetWeakPtr(),
154 context, callback, entry->local_id())); 236 context, callback, local_state->entry.local_id()));
155 } 237 }
156 238
157 void EntryUpdatePerformer::UpdateEntryAfterUpdateResource( 239 void EntryUpdatePerformer::UpdateEntryAfterUpdateResource(
158 const ClientContext& context, 240 const ClientContext& context,
159 const FileOperationCallback& callback, 241 const FileOperationCallback& callback,
160 const std::string& local_id, 242 const std::string& local_id,
161 google_apis::GDataErrorCode status, 243 google_apis::GDataErrorCode status,
162 scoped_ptr<google_apis::ResourceEntry> resource_entry) { 244 scoped_ptr<google_apis::ResourceEntry> resource_entry) {
163 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 245 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
164 246
165 if (status == google_apis::HTTP_FORBIDDEN) { 247 if (status == google_apis::HTTP_FORBIDDEN) {
166 // Editing this entry is not allowed, revert local changes. 248 // Editing this entry is not allowed, revert local changes.
167 entry_revert_performer_->RevertEntry(local_id, context, callback); 249 entry_revert_performer_->RevertEntry(local_id, context, callback);
168 return; 250 return;
169 } 251 }
170 252
171 FileError error = GDataToFileError(status); 253 FileError error = GDataToFileError(status);
172 if (error != FILE_ERROR_OK) { 254 if (error != FILE_ERROR_OK) {
173 callback.Run(error); 255 callback.Run(error);
174 return; 256 return;
175 } 257 }
176 258
177 base::PostTaskAndReplyWithResult( 259 base::PostTaskAndReplyWithResult(
178 blocking_task_runner_.get(), 260 blocking_task_runner_.get(),
179 FROM_HERE, 261 FROM_HERE,
180 base::Bind(&FinishUpdate, metadata_, local_id), 262 base::Bind(&FinishUpdate,
263 metadata_, cache_, local_id, base::Passed(&resource_entry)),
181 callback); 264 callback);
182 } 265 }
183 266
184 } // namespace internal 267 } // namespace internal
185 } // namespace drive 268 } // namespace drive
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698