OLD | NEW |
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/sync_file_system/drive_backend/remote_to_local_syncer.h
" | 5 #include "chrome/browser/sync_file_system/drive_backend/remote_to_local_syncer.h
" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/callback.h" | 8 #include "base/callback.h" |
9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
10 #include "base/format_macros.h" | 10 #include "base/format_macros.h" |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 remote_metadata_ = GetFileMetadata( | 142 remote_metadata_ = GetFileMetadata( |
143 metadata_database(), dirty_tracker_->file_id()); | 143 metadata_database(), dirty_tracker_->file_id()); |
144 | 144 |
145 if (!remote_metadata_ || !remote_metadata_->has_details()) { | 145 if (!remote_metadata_ || !remote_metadata_->has_details()) { |
146 if (remote_metadata_ && !remote_metadata_->has_details()) { | 146 if (remote_metadata_ && !remote_metadata_->has_details()) { |
147 token->RecordLog( | 147 token->RecordLog( |
148 "Missing details of a remote file: " + remote_metadata_->file_id()); | 148 "Missing details of a remote file: " + remote_metadata_->file_id()); |
149 NOTREACHED(); | 149 NOTREACHED(); |
150 } | 150 } |
151 token->RecordLog("Missing remote metadata case."); | 151 token->RecordLog("Missing remote metadata case."); |
152 HandleMissingRemoteMetadata(SyncCompletedCallback(token.Pass())); | 152 HandleMissingRemoteMetadata(token.Pass()); |
153 return; | 153 return; |
154 } | 154 } |
155 | 155 |
156 DCHECK(remote_metadata_); | 156 DCHECK(remote_metadata_); |
157 DCHECK(remote_metadata_->has_details()); | 157 DCHECK(remote_metadata_->has_details()); |
158 const FileDetails& remote_details = remote_metadata_->details(); | 158 const FileDetails& remote_details = remote_metadata_->details(); |
159 | 159 |
160 if (!dirty_tracker_->active() || | 160 if (!dirty_tracker_->active() || |
161 HasDisabledAppRoot(metadata_database(), *dirty_tracker_)) { | 161 HasDisabledAppRoot(metadata_database(), *dirty_tracker_)) { |
162 // Handle inactive tracker in SyncCompleted. | 162 // Handle inactive tracker in SyncCompleted. |
(...skipping 16 matching lines...) Expand all Loading... |
179 | 179 |
180 DCHECK(dirty_tracker_->has_synced_details()); | 180 DCHECK(dirty_tracker_->has_synced_details()); |
181 const FileDetails& synced_details = dirty_tracker_->synced_details(); | 181 const FileDetails& synced_details = dirty_tracker_->synced_details(); |
182 | 182 |
183 if (dirty_tracker_->tracker_id() == | 183 if (dirty_tracker_->tracker_id() == |
184 metadata_database()->GetSyncRootTrackerID()) { | 184 metadata_database()->GetSyncRootTrackerID()) { |
185 if (remote_details.missing() || | 185 if (remote_details.missing() || |
186 synced_details.title() != remote_details.title() || | 186 synced_details.title() != remote_details.title() || |
187 remote_details.parent_folder_ids_size()) { | 187 remote_details.parent_folder_ids_size()) { |
188 token->RecordLog("Sync-root deletion."); | 188 token->RecordLog("Sync-root deletion."); |
189 HandleSyncRootDeletion(SyncCompletedCallback(token.Pass())); | 189 HandleSyncRootDeletion(token.Pass()); |
190 return; | 190 return; |
191 } | 191 } |
192 token->RecordLog("Trivial sync-root change."); | 192 token->RecordLog("Trivial sync-root change."); |
193 SyncCompleted(token.Pass(), SYNC_STATUS_OK); | 193 SyncCompleted(token.Pass(), SYNC_STATUS_OK); |
194 return; | 194 return; |
195 } | 195 } |
196 | 196 |
197 DCHECK_NE(dirty_tracker_->tracker_id(), | 197 DCHECK_NE(dirty_tracker_->tracker_id(), |
198 metadata_database()->GetSyncRootTrackerID()); | 198 metadata_database()->GetSyncRootTrackerID()); |
199 | 199 |
200 if (remote_details.missing()) { | 200 if (remote_details.missing()) { |
201 if (!synced_details.missing()) { | 201 if (!synced_details.missing()) { |
202 token->RecordLog("Remote file deletion."); | 202 token->RecordLog("Remote file deletion."); |
203 HandleDeletion(SyncCompletedCallback(token.Pass())); | 203 HandleDeletion(token.Pass()); |
204 return; | 204 return; |
205 } | 205 } |
206 | 206 |
207 DCHECK(synced_details.missing()); | 207 DCHECK(synced_details.missing()); |
208 token->RecordLog("Found a stray missing tracker: " + | 208 token->RecordLog("Found a stray missing tracker: " + |
209 dirty_tracker_->file_id()); | 209 dirty_tracker_->file_id()); |
210 NOTREACHED(); | 210 NOTREACHED(); |
211 SyncCompleted(token.Pass(), SYNC_STATUS_OK); | 211 SyncCompleted(token.Pass(), SYNC_STATUS_OK); |
212 return; | 212 return; |
213 } | 213 } |
(...skipping 22 matching lines...) Expand all Loading... |
236 return; | 236 return; |
237 } | 237 } |
238 DCHECK(remote_details.file_kind() == FILE_KIND_FILE || | 238 DCHECK(remote_details.file_kind() == FILE_KIND_FILE || |
239 remote_details.file_kind() == FILE_KIND_FOLDER); | 239 remote_details.file_kind() == FILE_KIND_FOLDER); |
240 | 240 |
241 if (synced_details.title() != remote_details.title()) { | 241 if (synced_details.title() != remote_details.title()) { |
242 // Handle rename as deletion + addition. | 242 // Handle rename as deletion + addition. |
243 token->RecordLog("Detected file rename."); | 243 token->RecordLog("Detected file rename."); |
244 Prepare(base::Bind(&RemoteToLocalSyncer::DidPrepareForDeletion, | 244 Prepare(base::Bind(&RemoteToLocalSyncer::DidPrepareForDeletion, |
245 weak_ptr_factory_.GetWeakPtr(), | 245 weak_ptr_factory_.GetWeakPtr(), |
246 SyncCompletedCallback(token.Pass()))); | 246 base::Passed(&token))); |
247 return; | 247 return; |
248 } | 248 } |
249 DCHECK_EQ(synced_details.title(), remote_details.title()); | 249 DCHECK_EQ(synced_details.title(), remote_details.title()); |
250 | 250 |
251 FileTracker parent_tracker; | 251 FileTracker parent_tracker; |
252 if (!metadata_database()->FindTrackerByTrackerID( | 252 if (!metadata_database()->FindTrackerByTrackerID( |
253 dirty_tracker_->parent_tracker_id(), &parent_tracker)) { | 253 dirty_tracker_->parent_tracker_id(), &parent_tracker)) { |
254 token->RecordLog("Missing parent tracker for a non sync-root tracker: " | 254 token->RecordLog("Missing parent tracker for a non sync-root tracker: " |
255 + dirty_tracker_->file_id()); | 255 + dirty_tracker_->file_id()); |
256 NOTREACHED(); | 256 NOTREACHED(); |
257 SyncCompleted(token.Pass(), SYNC_STATUS_FAILED); | 257 SyncCompleted(token.Pass(), SYNC_STATUS_FAILED); |
258 return; | 258 return; |
259 } | 259 } |
260 | 260 |
261 if (!HasFolderAsParent(remote_details, parent_tracker.file_id())) { | 261 if (!HasFolderAsParent(remote_details, parent_tracker.file_id())) { |
262 // Handle reorganize as deletion + addition. | 262 // Handle reorganize as deletion + addition. |
263 token->RecordLog("Detected file reorganize."); | 263 token->RecordLog("Detected file reorganize."); |
264 Prepare(base::Bind(&RemoteToLocalSyncer::DidPrepareForDeletion, | 264 Prepare(base::Bind(&RemoteToLocalSyncer::DidPrepareForDeletion, |
265 weak_ptr_factory_.GetWeakPtr(), | 265 weak_ptr_factory_.GetWeakPtr(), |
266 SyncCompletedCallback(token.Pass()))); | 266 base::Passed(&token))); |
267 return; | 267 return; |
268 } | 268 } |
269 | 269 |
270 if (synced_details.file_kind() == FILE_KIND_FILE) { | 270 if (synced_details.file_kind() == FILE_KIND_FILE) { |
271 if (synced_details.md5() != remote_details.md5()) { | 271 if (synced_details.md5() != remote_details.md5()) { |
272 token->RecordLog("Detected file content update."); | 272 token->RecordLog("Detected file content update."); |
273 HandleContentUpdate(SyncCompletedCallback(token.Pass())); | 273 HandleContentUpdate(token.Pass()); |
274 return; | 274 return; |
275 } | 275 } |
276 } else { | 276 } else { |
277 DCHECK_EQ(FILE_KIND_FOLDER, synced_details.file_kind()); | 277 DCHECK_EQ(FILE_KIND_FOLDER, synced_details.file_kind()); |
278 if (synced_details.missing()) { | 278 if (synced_details.missing()) { |
279 token->RecordLog("Detected folder update."); | 279 token->RecordLog("Detected folder update."); |
280 HandleFolderUpdate(SyncCompletedCallback(token.Pass())); | 280 HandleFolderUpdate(token.Pass()); |
281 return; | 281 return; |
282 } | 282 } |
283 if (dirty_tracker_->needs_folder_listing()) { | 283 if (dirty_tracker_->needs_folder_listing()) { |
284 token->RecordLog("Needs listing folder."); | 284 token->RecordLog("Needs listing folder."); |
285 ListFolderContent(SyncCompletedCallback(token.Pass())); | 285 ListFolderContent(token.Pass()); |
286 return; | 286 return; |
287 } | 287 } |
288 SyncCompleted(token.Pass(), SYNC_STATUS_OK); | 288 SyncCompleted(token.Pass(), SYNC_STATUS_OK); |
289 return; | 289 return; |
290 } | 290 } |
291 | 291 |
292 token->RecordLog("Trivial file change."); | 292 token->RecordLog("Trivial file change."); |
293 SyncCompleted(token.Pass(), SYNC_STATUS_OK); | 293 SyncCompleted(token.Pass(), SYNC_STATUS_OK); |
294 } | 294 } |
295 | 295 |
296 void RemoteToLocalSyncer::HandleMissingRemoteMetadata( | 296 void RemoteToLocalSyncer::HandleMissingRemoteMetadata( |
297 const SyncStatusCallback& callback) { | 297 scoped_ptr<SyncTaskToken> token) { |
298 DCHECK(dirty_tracker_); | 298 DCHECK(dirty_tracker_); |
299 | 299 |
300 drive_service()->GetFileResource( | 300 drive_service()->GetFileResource( |
301 dirty_tracker_->file_id(), | 301 dirty_tracker_->file_id(), |
302 base::Bind(&RemoteToLocalSyncer::DidGetRemoteMetadata, | 302 base::Bind(&RemoteToLocalSyncer::DidGetRemoteMetadata, |
303 weak_ptr_factory_.GetWeakPtr(), | 303 weak_ptr_factory_.GetWeakPtr(), |
304 callback)); | 304 base::Passed(&token))); |
305 } | 305 } |
306 | 306 |
307 void RemoteToLocalSyncer::DidGetRemoteMetadata( | 307 void RemoteToLocalSyncer::DidGetRemoteMetadata( |
308 const SyncStatusCallback& callback, | 308 scoped_ptr<SyncTaskToken> token, |
309 google_apis::GDataErrorCode error, | 309 google_apis::GDataErrorCode error, |
310 scoped_ptr<google_apis::FileResource> entry) { | 310 scoped_ptr<google_apis::FileResource> entry) { |
311 DCHECK(sync_context_->GetWorkerTaskRunner()->RunsTasksOnCurrentThread()); | 311 DCHECK(sync_context_->GetWorkerTaskRunner()->RunsTasksOnCurrentThread()); |
312 | 312 |
313 SyncStatusCode status = GDataErrorCodeToSyncStatusCode(error); | 313 SyncStatusCode status = GDataErrorCodeToSyncStatusCode(error); |
314 if (status != SYNC_STATUS_OK && | 314 if (status != SYNC_STATUS_OK && |
315 error != google_apis::HTTP_NOT_FOUND) { | 315 error != google_apis::HTTP_NOT_FOUND) { |
316 callback.Run(status); | 316 SyncCompleted(token.Pass(), status); |
317 return; | 317 return; |
318 } | 318 } |
319 | 319 |
320 if (error == google_apis::HTTP_NOT_FOUND) { | 320 if (error == google_apis::HTTP_NOT_FOUND) { |
321 metadata_database()->UpdateByDeletedRemoteFile( | 321 metadata_database()->UpdateByDeletedRemoteFile( |
322 dirty_tracker_->file_id(), callback); | 322 dirty_tracker_->file_id(), SyncCompletedCallback(token.Pass())); |
323 return; | 323 return; |
324 } | 324 } |
325 | 325 |
326 if (!entry) { | 326 if (!entry) { |
327 NOTREACHED(); | 327 NOTREACHED(); |
328 callback.Run(SYNC_STATUS_FAILED); | 328 SyncCompleted(token.Pass(), SYNC_STATUS_FAILED); |
329 return; | 329 return; |
330 } | 330 } |
331 | 331 |
332 metadata_database()->UpdateByFileResource( | 332 metadata_database()->UpdateByFileResource( |
333 *entry, | 333 *entry, |
334 base::Bind(&RemoteToLocalSyncer::DidUpdateDatabaseForRemoteMetadata, | 334 base::Bind(&RemoteToLocalSyncer::DidUpdateDatabaseForRemoteMetadata, |
335 weak_ptr_factory_.GetWeakPtr(), callback)); | 335 weak_ptr_factory_.GetWeakPtr(), |
| 336 base::Passed(&token))); |
336 } | 337 } |
337 | 338 |
338 void RemoteToLocalSyncer::DidUpdateDatabaseForRemoteMetadata( | 339 void RemoteToLocalSyncer::DidUpdateDatabaseForRemoteMetadata( |
339 const SyncStatusCallback& callback, | 340 scoped_ptr<SyncTaskToken> token, |
340 SyncStatusCode status) { | 341 SyncStatusCode status) { |
341 if (status != SYNC_STATUS_OK) { | 342 if (status != SYNC_STATUS_OK) { |
342 callback.Run(status); | 343 SyncCompleted(token.Pass(), status); |
343 return; | 344 return; |
344 } | 345 } |
345 | 346 |
346 callback.Run(SYNC_STATUS_RETRY); // Do not update |dirty_tracker_|. | 347 // Do not update |dirty_tracker_|. |
| 348 SyncCompleted(token.Pass(), SYNC_STATUS_RETRY); |
347 } | 349 } |
348 | 350 |
349 void RemoteToLocalSyncer::DidPrepareForAddOrUpdateFile( | 351 void RemoteToLocalSyncer::DidPrepareForAddOrUpdateFile( |
350 const SyncStatusCallback& callback, | 352 scoped_ptr<SyncTaskToken> token, |
351 SyncStatusCode status) { | 353 SyncStatusCode status) { |
352 if (status != SYNC_STATUS_OK) { | 354 if (status != SYNC_STATUS_OK) { |
353 callback.Run(status); | 355 SyncCompleted(token.Pass(), status); |
354 return; | 356 return; |
355 } | 357 } |
356 | 358 |
357 DCHECK(url_.is_valid()); | 359 DCHECK(url_.is_valid()); |
358 DCHECK(local_metadata_); | 360 DCHECK(local_metadata_); |
359 DCHECK(local_changes_); | 361 DCHECK(local_changes_); |
360 | 362 |
361 // Check if the local file exists. | 363 // Check if the local file exists. |
362 if (local_metadata_->file_type == SYNC_FILE_TYPE_UNKNOWN || | 364 if (local_metadata_->file_type == SYNC_FILE_TYPE_UNKNOWN || |
363 (!local_changes_->empty() && local_changes_->back().IsDelete())) { | 365 (!local_changes_->empty() && local_changes_->back().IsDelete())) { |
364 sync_action_ = SYNC_ACTION_ADDED; | 366 sync_action_ = SYNC_ACTION_ADDED; |
365 // Missing local file case. | 367 // Missing local file case. |
366 // Download the file and add it to local as a new file. | 368 // Download the file and add it to local as a new file. |
367 DownloadFile(callback); | 369 DownloadFile(token.Pass()); |
368 return; | 370 return; |
369 } | 371 } |
370 | 372 |
371 DCHECK(local_changes_->empty() || local_changes_->back().IsAddOrUpdate()); | 373 DCHECK(local_changes_->empty() || local_changes_->back().IsAddOrUpdate()); |
372 if (local_changes_->empty()) { | 374 if (local_changes_->empty()) { |
373 if (local_metadata_->file_type == SYNC_FILE_TYPE_FILE) { | 375 if (local_metadata_->file_type == SYNC_FILE_TYPE_FILE) { |
374 sync_action_ = SYNC_ACTION_UPDATED; | 376 sync_action_ = SYNC_ACTION_UPDATED; |
375 // Download the file and overwrite the existing local file. | 377 // Download the file and overwrite the existing local file. |
376 DownloadFile(callback); | 378 DownloadFile(token.Pass()); |
377 return; | 379 return; |
378 } | 380 } |
379 | 381 |
380 DCHECK_EQ(SYNC_FILE_TYPE_DIRECTORY, local_metadata_->file_type); | 382 DCHECK_EQ(SYNC_FILE_TYPE_DIRECTORY, local_metadata_->file_type); |
381 | 383 |
382 // Got a remote regular file modification for existing local folder. | 384 // Got a remote regular file modification for existing local folder. |
383 // Our policy prioritize folders in this case. | 385 // Our policy prioritize folders in this case. |
384 // Lower the priority of the tracker to prevent repeated remote sync to the | 386 // Lower the priority of the tracker to prevent repeated remote sync to the |
385 // same tracker, and let local-to-remote sync phase process this change. | 387 // same tracker, and let local-to-remote sync phase process this change. |
386 metadata_database()->LowerTrackerPriority(dirty_tracker_->tracker_id()); | 388 metadata_database()->LowerTrackerPriority(dirty_tracker_->tracker_id()); |
387 remote_change_processor()->RecordFakeLocalChange( | 389 remote_change_processor()->RecordFakeLocalChange( |
388 url_, | 390 url_, |
389 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE, | 391 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE, |
390 local_metadata_->file_type), | 392 local_metadata_->file_type), |
391 callback); | 393 SyncCompletedCallback(token.Pass())); |
392 return; | 394 return; |
393 } | 395 } |
394 | 396 |
395 DCHECK(local_changes_->back().IsAddOrUpdate()); | 397 DCHECK(local_changes_->back().IsAddOrUpdate()); |
396 // Conflict case. | 398 // Conflict case. |
397 // Do nothing for the change now, and handle this in LocalToRemoteSync phase. | 399 // Do nothing for the change now, and handle this in LocalToRemoteSync phase. |
398 | 400 |
399 // Lower the priority of the tracker to prevent repeated remote sync to the | 401 // Lower the priority of the tracker to prevent repeated remote sync to the |
400 // same tracker. | 402 // same tracker. |
401 metadata_database()->LowerTrackerPriority(dirty_tracker_->tracker_id()); | 403 metadata_database()->LowerTrackerPriority(dirty_tracker_->tracker_id()); |
402 callback.Run(SYNC_STATUS_RETRY); | 404 SyncCompleted(token.Pass(), SYNC_STATUS_RETRY); |
403 } | 405 } |
404 | 406 |
405 void RemoteToLocalSyncer::HandleFolderUpdate( | 407 void RemoteToLocalSyncer::HandleFolderUpdate( |
406 const SyncStatusCallback& callback) { | 408 scoped_ptr<SyncTaskToken> token) { |
407 DCHECK(dirty_tracker_); | 409 DCHECK(dirty_tracker_); |
408 DCHECK(dirty_tracker_->active()); | 410 DCHECK(dirty_tracker_->active()); |
409 DCHECK(!HasDisabledAppRoot(metadata_database(), *dirty_tracker_)); | 411 DCHECK(!HasDisabledAppRoot(metadata_database(), *dirty_tracker_)); |
410 | 412 |
411 DCHECK(remote_metadata_); | 413 DCHECK(remote_metadata_); |
412 DCHECK(remote_metadata_->has_details()); | 414 DCHECK(remote_metadata_->has_details()); |
413 DCHECK(!remote_metadata_->details().missing()); | 415 DCHECK(!remote_metadata_->details().missing()); |
414 DCHECK_EQ(FILE_KIND_FOLDER, remote_metadata_->details().file_kind()); | 416 DCHECK_EQ(FILE_KIND_FOLDER, remote_metadata_->details().file_kind()); |
415 | 417 |
416 Prepare(base::Bind(&RemoteToLocalSyncer::DidPrepareForFolderUpdate, | 418 Prepare(base::Bind(&RemoteToLocalSyncer::DidPrepareForFolderUpdate, |
417 weak_ptr_factory_.GetWeakPtr(), callback)); | 419 weak_ptr_factory_.GetWeakPtr(), |
| 420 base::Passed(&token))); |
418 } | 421 } |
419 | 422 |
420 void RemoteToLocalSyncer::DidPrepareForFolderUpdate( | 423 void RemoteToLocalSyncer::DidPrepareForFolderUpdate( |
421 const SyncStatusCallback& callback, | 424 scoped_ptr<SyncTaskToken> token, |
422 SyncStatusCode status) { | 425 SyncStatusCode status) { |
423 if (status != SYNC_STATUS_OK) { | 426 if (status != SYNC_STATUS_OK) { |
424 callback.Run(status); | 427 SyncCompleted(token.Pass(), status); |
425 return; | 428 return; |
426 } | 429 } |
427 | 430 |
428 DCHECK(url_.is_valid()); | 431 DCHECK(url_.is_valid()); |
429 DCHECK(local_metadata_); | 432 DCHECK(local_metadata_); |
430 DCHECK(local_changes_); | 433 DCHECK(local_changes_); |
431 | 434 |
432 // Check if the local file exists. | 435 // Check if the local file exists. |
433 if (local_metadata_->file_type == SYNC_FILE_TYPE_UNKNOWN || | 436 if (local_metadata_->file_type == SYNC_FILE_TYPE_UNKNOWN || |
434 (!local_changes_->empty() && local_changes_->back().IsDelete())) { | 437 (!local_changes_->empty() && local_changes_->back().IsDelete())) { |
435 sync_action_ = SYNC_ACTION_ADDED; | 438 sync_action_ = SYNC_ACTION_ADDED; |
436 // No local file exists at the path. | 439 // No local file exists at the path. |
437 CreateFolder(callback); | 440 CreateFolder(token.Pass()); |
438 return; | 441 return; |
439 } | 442 } |
440 | 443 |
441 if (local_metadata_->file_type == SYNC_FILE_TYPE_DIRECTORY) { | 444 if (local_metadata_->file_type == SYNC_FILE_TYPE_DIRECTORY) { |
442 // There already exists a folder, nothing left to do. | 445 // There already exists a folder, nothing left to do. |
443 if (dirty_tracker_->needs_folder_listing() && | 446 if (dirty_tracker_->needs_folder_listing() && |
444 !dirty_tracker_->synced_details().missing()) { | 447 !dirty_tracker_->synced_details().missing()) { |
445 ListFolderContent(callback); | 448 ListFolderContent(token.Pass()); |
446 } else { | 449 } else { |
447 callback.Run(SYNC_STATUS_OK); | 450 SyncCompleted(token.Pass(), SYNC_STATUS_OK); |
448 } | 451 } |
449 return; | 452 return; |
450 } | 453 } |
451 | 454 |
452 DCHECK_EQ(SYNC_FILE_TYPE_FILE, local_metadata_->file_type); | 455 DCHECK_EQ(SYNC_FILE_TYPE_FILE, local_metadata_->file_type); |
453 sync_action_ = SYNC_ACTION_ADDED; | 456 sync_action_ = SYNC_ACTION_ADDED; |
454 // Got a remote folder for existing local file. | 457 // Got a remote folder for existing local file. |
455 // Our policy prioritize folders in this case. | 458 // Our policy prioritize folders in this case. |
456 CreateFolder(callback); | 459 CreateFolder(token.Pass()); |
457 } | 460 } |
458 | 461 |
459 void RemoteToLocalSyncer::HandleSyncRootDeletion( | 462 void RemoteToLocalSyncer::HandleSyncRootDeletion( |
460 const SyncStatusCallback& callback) { | 463 scoped_ptr<SyncTaskToken> token) { |
461 sync_root_deletion_ = true; | 464 sync_root_deletion_ = true; |
462 callback.Run(SYNC_STATUS_OK); | 465 SyncCompleted(token.Pass(), SYNC_STATUS_OK); |
463 } | 466 } |
464 | 467 |
465 void RemoteToLocalSyncer::HandleDeletion( | 468 void RemoteToLocalSyncer::HandleDeletion( |
466 const SyncStatusCallback& callback) { | 469 scoped_ptr<SyncTaskToken> token) { |
467 DCHECK(dirty_tracker_); | 470 DCHECK(dirty_tracker_); |
468 DCHECK(dirty_tracker_->active()); | 471 DCHECK(dirty_tracker_->active()); |
469 DCHECK(!HasDisabledAppRoot(metadata_database(), *dirty_tracker_)); | 472 DCHECK(!HasDisabledAppRoot(metadata_database(), *dirty_tracker_)); |
470 DCHECK(dirty_tracker_->has_synced_details()); | 473 DCHECK(dirty_tracker_->has_synced_details()); |
471 DCHECK(!dirty_tracker_->synced_details().missing()); | 474 DCHECK(!dirty_tracker_->synced_details().missing()); |
472 | 475 |
473 DCHECK(remote_metadata_); | 476 DCHECK(remote_metadata_); |
474 DCHECK(remote_metadata_->has_details()); | 477 DCHECK(remote_metadata_->has_details()); |
475 DCHECK(remote_metadata_->details().missing()); | 478 DCHECK(remote_metadata_->details().missing()); |
476 | 479 |
477 Prepare(base::Bind(&RemoteToLocalSyncer::DidPrepareForDeletion, | 480 Prepare(base::Bind(&RemoteToLocalSyncer::DidPrepareForDeletion, |
478 weak_ptr_factory_.GetWeakPtr(), callback)); | 481 weak_ptr_factory_.GetWeakPtr(), |
| 482 base::Passed(&token))); |
479 } | 483 } |
480 | 484 |
481 void RemoteToLocalSyncer::DidPrepareForDeletion( | 485 void RemoteToLocalSyncer::DidPrepareForDeletion( |
482 const SyncStatusCallback& callback, | 486 scoped_ptr<SyncTaskToken> token, |
483 SyncStatusCode status) { | 487 SyncStatusCode status) { |
484 if (status != SYNC_STATUS_OK) { | 488 if (status != SYNC_STATUS_OK) { |
485 callback.Run(status); | 489 SyncCompleted(token.Pass(), status); |
486 return; | 490 return; |
487 } | 491 } |
488 | 492 |
489 DCHECK(url_.is_valid()); | 493 DCHECK(url_.is_valid()); |
490 DCHECK(local_metadata_); | 494 DCHECK(local_metadata_); |
491 DCHECK(local_changes_); | 495 DCHECK(local_changes_); |
492 | 496 |
493 // Check if the local file exists. | 497 // Check if the local file exists. |
494 if (local_metadata_->file_type == SYNC_FILE_TYPE_UNKNOWN || | 498 if (local_metadata_->file_type == SYNC_FILE_TYPE_UNKNOWN || |
495 (!local_changes_->empty() && local_changes_->back().IsDelete())) { | 499 (!local_changes_->empty() && local_changes_->back().IsDelete())) { |
496 // No local file exists at the path. | 500 // No local file exists at the path. |
497 callback.Run(SYNC_STATUS_OK); | 501 SyncCompleted(token.Pass(), SYNC_STATUS_OK); |
498 return; | 502 return; |
499 } | 503 } |
500 | 504 |
501 DCHECK(local_changes_->empty() || local_changes_->back().IsAddOrUpdate()); | 505 DCHECK(local_changes_->empty() || local_changes_->back().IsAddOrUpdate()); |
502 if (local_changes_->empty()) { | 506 if (local_changes_->empty()) { |
503 sync_action_ = SYNC_ACTION_DELETED; | 507 sync_action_ = SYNC_ACTION_DELETED; |
504 DeleteLocalFile(callback); | 508 DeleteLocalFile(token.Pass()); |
505 return; | 509 return; |
506 } | 510 } |
507 | 511 |
508 DCHECK(local_changes_->back().IsAddOrUpdate()); | 512 DCHECK(local_changes_->back().IsAddOrUpdate()); |
509 // File is remotely deleted and locally updated. | 513 // File is remotely deleted and locally updated. |
510 // Ignore the remote deletion and handle it as if applied successfully. | 514 // Ignore the remote deletion and handle it as if applied successfully. |
511 callback.Run(SYNC_STATUS_OK); | 515 SyncCompleted(token.Pass(), SYNC_STATUS_OK); |
512 } | 516 } |
513 | 517 |
514 void RemoteToLocalSyncer::HandleContentUpdate( | 518 void RemoteToLocalSyncer::HandleContentUpdate( |
515 const SyncStatusCallback& callback) { | 519 scoped_ptr<SyncTaskToken> token) { |
516 DCHECK(dirty_tracker_); | 520 DCHECK(dirty_tracker_); |
517 DCHECK(dirty_tracker_->active()); | 521 DCHECK(dirty_tracker_->active()); |
518 DCHECK(!HasDisabledAppRoot(metadata_database(), *dirty_tracker_)); | 522 DCHECK(!HasDisabledAppRoot(metadata_database(), *dirty_tracker_)); |
519 DCHECK(dirty_tracker_->has_synced_details()); | 523 DCHECK(dirty_tracker_->has_synced_details()); |
520 DCHECK_EQ(FILE_KIND_FILE, dirty_tracker_->synced_details().file_kind()); | 524 DCHECK_EQ(FILE_KIND_FILE, dirty_tracker_->synced_details().file_kind()); |
521 | 525 |
522 DCHECK(remote_metadata_); | 526 DCHECK(remote_metadata_); |
523 DCHECK(remote_metadata_->has_details()); | 527 DCHECK(remote_metadata_->has_details()); |
524 DCHECK(!remote_metadata_->details().missing()); | 528 DCHECK(!remote_metadata_->details().missing()); |
525 | 529 |
526 DCHECK_NE(dirty_tracker_->synced_details().md5(), | 530 DCHECK_NE(dirty_tracker_->synced_details().md5(), |
527 remote_metadata_->details().md5()); | 531 remote_metadata_->details().md5()); |
528 | 532 |
529 Prepare(base::Bind(&RemoteToLocalSyncer::DidPrepareForAddOrUpdateFile, | 533 Prepare(base::Bind(&RemoteToLocalSyncer::DidPrepareForAddOrUpdateFile, |
530 weak_ptr_factory_.GetWeakPtr(), callback)); | 534 weak_ptr_factory_.GetWeakPtr(), base::Passed(&token))); |
531 } | 535 } |
532 | 536 |
533 void RemoteToLocalSyncer::ListFolderContent( | 537 void RemoteToLocalSyncer::ListFolderContent( |
534 const SyncStatusCallback& callback) { | 538 scoped_ptr<SyncTaskToken> token) { |
535 DCHECK(dirty_tracker_); | 539 DCHECK(dirty_tracker_); |
536 DCHECK(dirty_tracker_->active()); | 540 DCHECK(dirty_tracker_->active()); |
537 DCHECK(!HasDisabledAppRoot(metadata_database(), *dirty_tracker_)); | 541 DCHECK(!HasDisabledAppRoot(metadata_database(), *dirty_tracker_)); |
538 DCHECK(dirty_tracker_->has_synced_details()); | 542 DCHECK(dirty_tracker_->has_synced_details()); |
539 DCHECK(!dirty_tracker_->synced_details().missing()); | 543 DCHECK(!dirty_tracker_->synced_details().missing()); |
540 DCHECK_EQ(FILE_KIND_FOLDER, dirty_tracker_->synced_details().file_kind()); | 544 DCHECK_EQ(FILE_KIND_FOLDER, dirty_tracker_->synced_details().file_kind()); |
541 DCHECK(dirty_tracker_->needs_folder_listing()); | 545 DCHECK(dirty_tracker_->needs_folder_listing()); |
542 | 546 |
543 DCHECK(remote_metadata_); | 547 DCHECK(remote_metadata_); |
544 DCHECK(remote_metadata_->has_details()); | 548 DCHECK(remote_metadata_->has_details()); |
545 DCHECK(!remote_metadata_->details().missing()); | 549 DCHECK(!remote_metadata_->details().missing()); |
546 | 550 |
547 // TODO(tzik): Replace this call with ChildList version. | 551 // TODO(tzik): Replace this call with ChildList version. |
548 drive_service()->GetFileListInDirectory( | 552 drive_service()->GetFileListInDirectory( |
549 dirty_tracker_->file_id(), | 553 dirty_tracker_->file_id(), |
550 base::Bind(&RemoteToLocalSyncer::DidListFolderContent, | 554 base::Bind(&RemoteToLocalSyncer::DidListFolderContent, |
551 weak_ptr_factory_.GetWeakPtr(), | 555 weak_ptr_factory_.GetWeakPtr(), |
552 callback, | 556 base::Passed(&token), |
553 base::Passed(make_scoped_ptr(new FileIDList)))); | 557 base::Passed(make_scoped_ptr(new FileIDList)))); |
554 } | 558 } |
555 | 559 |
556 void RemoteToLocalSyncer::DidListFolderContent( | 560 void RemoteToLocalSyncer::DidListFolderContent( |
557 const SyncStatusCallback& callback, | 561 scoped_ptr<SyncTaskToken> token, |
558 scoped_ptr<FileIDList> children, | 562 scoped_ptr<FileIDList> children, |
559 google_apis::GDataErrorCode error, | 563 google_apis::GDataErrorCode error, |
560 scoped_ptr<google_apis::FileList> file_list) { | 564 scoped_ptr<google_apis::FileList> file_list) { |
561 SyncStatusCode status = GDataErrorCodeToSyncStatusCode(error); | 565 SyncStatusCode status = GDataErrorCodeToSyncStatusCode(error); |
562 if (status != SYNC_STATUS_OK) { | 566 if (status != SYNC_STATUS_OK) { |
563 callback.Run(status); | 567 SyncCompleted(token.Pass(), status); |
564 return; | 568 return; |
565 } | 569 } |
566 | 570 |
567 if (!file_list) { | 571 if (!file_list) { |
568 NOTREACHED(); | 572 NOTREACHED(); |
569 callback.Run(SYNC_STATUS_FAILED); | 573 SyncCompleted(token.Pass(), SYNC_STATUS_FAILED); |
570 return; | 574 return; |
571 } | 575 } |
572 | 576 |
573 children->reserve(children->size() + file_list->items().size()); | 577 children->reserve(children->size() + file_list->items().size()); |
574 for (ScopedVector<google_apis::FileResource>::const_iterator itr = | 578 for (ScopedVector<google_apis::FileResource>::const_iterator itr = |
575 file_list->items().begin(); | 579 file_list->items().begin(); |
576 itr != file_list->items().end(); | 580 itr != file_list->items().end(); |
577 ++itr) { | 581 ++itr) { |
578 children->push_back((*itr)->file_id()); | 582 children->push_back((*itr)->file_id()); |
579 } | 583 } |
580 | 584 |
581 if (!file_list->next_link().is_empty()) { | 585 if (!file_list->next_link().is_empty()) { |
582 drive_service()->GetRemainingFileList( | 586 drive_service()->GetRemainingFileList( |
583 file_list->next_link(), | 587 file_list->next_link(), |
584 base::Bind(&RemoteToLocalSyncer::DidListFolderContent, | 588 base::Bind(&RemoteToLocalSyncer::DidListFolderContent, |
585 weak_ptr_factory_.GetWeakPtr(), | 589 weak_ptr_factory_.GetWeakPtr(), |
586 callback, base::Passed(&children))); | 590 base::Passed(&token), base::Passed(&children))); |
587 return; | 591 return; |
588 } | 592 } |
589 | 593 |
590 metadata_database()->PopulateFolderByChildList( | 594 metadata_database()->PopulateFolderByChildList( |
591 dirty_tracker_->file_id(), *children, callback); | 595 dirty_tracker_->file_id(), *children, |
| 596 SyncCompletedCallback(token.Pass())); |
592 } | 597 } |
593 | 598 |
594 void RemoteToLocalSyncer::SyncCompleted(scoped_ptr<SyncTaskToken> token, | 599 void RemoteToLocalSyncer::SyncCompleted(scoped_ptr<SyncTaskToken> token, |
595 SyncStatusCode status) { | 600 SyncStatusCode status) { |
596 token->RecordLog(base::StringPrintf( | 601 token->RecordLog(base::StringPrintf( |
597 "[Remote -> Local]: Finished: action=%s, tracker=%" PRId64 " status=%s", | 602 "[Remote -> Local]: Finished: action=%s, tracker=%" PRId64 " status=%s", |
598 SyncActionToString(sync_action_), dirty_tracker_->tracker_id(), | 603 SyncActionToString(sync_action_), dirty_tracker_->tracker_id(), |
599 SyncStatusCodeToString(status))); | 604 SyncStatusCodeToString(status))); |
600 | 605 |
601 if (sync_root_deletion_) { | 606 if (sync_root_deletion_) { |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
671 return; | 676 return; |
672 } | 677 } |
673 prepared_ = true; | 678 prepared_ = true; |
674 | 679 |
675 local_metadata_.reset(new SyncFileMetadata(local_metadata)); | 680 local_metadata_.reset(new SyncFileMetadata(local_metadata)); |
676 local_changes_.reset(new FileChangeList(local_changes)); | 681 local_changes_.reset(new FileChangeList(local_changes)); |
677 | 682 |
678 callback.Run(status); | 683 callback.Run(status); |
679 } | 684 } |
680 | 685 |
681 void RemoteToLocalSyncer::DeleteLocalFile(const SyncStatusCallback& callback) { | 686 void RemoteToLocalSyncer::DeleteLocalFile(scoped_ptr<SyncTaskToken> token) { |
682 remote_change_processor()->ApplyRemoteChange( | 687 remote_change_processor()->ApplyRemoteChange( |
683 FileChange(FileChange::FILE_CHANGE_DELETE, SYNC_FILE_TYPE_UNKNOWN), | 688 FileChange(FileChange::FILE_CHANGE_DELETE, SYNC_FILE_TYPE_UNKNOWN), |
684 base::FilePath(), | 689 base::FilePath(), |
685 url_, | 690 url_, |
686 callback); | 691 SyncCompletedCallback(token.Pass())); |
687 } | 692 } |
688 | 693 |
689 void RemoteToLocalSyncer::DownloadFile(const SyncStatusCallback& callback) { | 694 void RemoteToLocalSyncer::DownloadFile(scoped_ptr<SyncTaskToken> token) { |
690 DCHECK(sync_context_->GetWorkerTaskRunner()->RunsTasksOnCurrentThread()); | 695 DCHECK(sync_context_->GetWorkerTaskRunner()->RunsTasksOnCurrentThread()); |
691 | 696 |
692 webkit_blob::ScopedFile file = CreateTemporaryFile( | 697 webkit_blob::ScopedFile file = CreateTemporaryFile( |
693 make_scoped_refptr(sync_context_->GetWorkerTaskRunner())); | 698 make_scoped_refptr(sync_context_->GetWorkerTaskRunner())); |
694 | 699 |
695 base::FilePath path = file.path(); | 700 base::FilePath path = file.path(); |
696 drive_service()->DownloadFile( | 701 drive_service()->DownloadFile( |
697 path, remote_metadata_->file_id(), | 702 path, remote_metadata_->file_id(), |
698 base::Bind(&RemoteToLocalSyncer::DidDownloadFile, | 703 base::Bind(&RemoteToLocalSyncer::DidDownloadFile, |
699 weak_ptr_factory_.GetWeakPtr(), | 704 weak_ptr_factory_.GetWeakPtr(), |
700 callback, base::Passed(&file)), | 705 base::Passed(&token), base::Passed(&file)), |
701 google_apis::GetContentCallback(), | 706 google_apis::GetContentCallback(), |
702 google_apis::ProgressCallback()); | 707 google_apis::ProgressCallback()); |
703 } | 708 } |
704 | 709 |
705 void RemoteToLocalSyncer::DidDownloadFile(const SyncStatusCallback& callback, | 710 void RemoteToLocalSyncer::DidDownloadFile(scoped_ptr<SyncTaskToken> token, |
706 webkit_blob::ScopedFile file, | 711 webkit_blob::ScopedFile file, |
707 google_apis::GDataErrorCode error, | 712 google_apis::GDataErrorCode error, |
708 const base::FilePath&) { | 713 const base::FilePath&) { |
709 DCHECK(sync_context_->GetWorkerTaskRunner()->RunsTasksOnCurrentThread()); | 714 DCHECK(sync_context_->GetWorkerTaskRunner()->RunsTasksOnCurrentThread()); |
710 | 715 |
711 SyncStatusCode status = GDataErrorCodeToSyncStatusCode(error); | 716 SyncStatusCode status = GDataErrorCodeToSyncStatusCode(error); |
712 if (status != SYNC_STATUS_OK) { | 717 if (status != SYNC_STATUS_OK) { |
713 callback.Run(status); | 718 SyncCompleted(token.Pass(), status); |
714 return; | 719 return; |
715 } | 720 } |
716 | 721 |
717 base::FilePath path = file.path(); | 722 base::FilePath path = file.path(); |
718 const std::string md5 = drive::util::GetMd5Digest(path); | 723 const std::string md5 = drive::util::GetMd5Digest(path); |
719 if (md5.empty()) { | 724 if (md5.empty()) { |
720 callback.Run(SYNC_FILE_ERROR_NOT_FOUND); | 725 SyncCompleted(token.Pass(), SYNC_FILE_ERROR_NOT_FOUND); |
721 return; | 726 return; |
722 } | 727 } |
723 | 728 |
724 if (md5 != remote_metadata_->details().md5()) { | 729 if (md5 != remote_metadata_->details().md5()) { |
725 // File has been modified since last metadata retrieval. | 730 // File has been modified since last metadata retrieval. |
726 | 731 |
727 // Lower the priority of the tracker to prevent repeated remote sync to the | 732 // Lower the priority of the tracker to prevent repeated remote sync to the |
728 // same tracker. | 733 // same tracker. |
729 metadata_database()->LowerTrackerPriority(dirty_tracker_->tracker_id()); | 734 metadata_database()->LowerTrackerPriority(dirty_tracker_->tracker_id()); |
730 callback.Run(SYNC_STATUS_RETRY); | 735 SyncCompleted(token.Pass(), SYNC_STATUS_RETRY); |
731 return; | 736 return; |
732 } | 737 } |
733 | 738 |
734 remote_change_processor()->ApplyRemoteChange( | 739 remote_change_processor()->ApplyRemoteChange( |
735 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE, SYNC_FILE_TYPE_FILE), | 740 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE, SYNC_FILE_TYPE_FILE), |
736 path, url_, | 741 path, url_, |
737 base::Bind(&RemoteToLocalSyncer::DidApplyDownload, | 742 base::Bind(&RemoteToLocalSyncer::DidApplyDownload, |
738 weak_ptr_factory_.GetWeakPtr(), | 743 weak_ptr_factory_.GetWeakPtr(), |
739 callback, base::Passed(&file))); | 744 base::Passed(&token), base::Passed(&file))); |
740 } | 745 } |
741 | 746 |
742 void RemoteToLocalSyncer::DidApplyDownload(const SyncStatusCallback& callback, | 747 void RemoteToLocalSyncer::DidApplyDownload(scoped_ptr<SyncTaskToken> token, |
743 webkit_blob::ScopedFile, | 748 webkit_blob::ScopedFile, |
744 SyncStatusCode status) { | 749 SyncStatusCode status) { |
745 if (status != SYNC_STATUS_OK) | 750 if (status != SYNC_STATUS_OK) |
746 metadata_database()->LowerTrackerPriority(dirty_tracker_->tracker_id()); | 751 metadata_database()->LowerTrackerPriority(dirty_tracker_->tracker_id()); |
747 callback.Run(status); | 752 SyncCompleted(token.Pass(), status); |
748 } | 753 } |
749 | 754 |
750 void RemoteToLocalSyncer::CreateFolder(const SyncStatusCallback& callback) { | 755 void RemoteToLocalSyncer::CreateFolder(scoped_ptr<SyncTaskToken> token) { |
751 remote_change_processor()->ApplyRemoteChange( | 756 remote_change_processor()->ApplyRemoteChange( |
752 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE, | 757 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE, |
753 SYNC_FILE_TYPE_DIRECTORY), | 758 SYNC_FILE_TYPE_DIRECTORY), |
754 base::FilePath(), url_, | 759 base::FilePath(), url_, |
755 callback); | 760 SyncCompletedCallback(token.Pass())); |
756 } | 761 } |
757 | 762 |
758 drive::DriveServiceInterface* RemoteToLocalSyncer::drive_service() { | 763 drive::DriveServiceInterface* RemoteToLocalSyncer::drive_service() { |
759 return sync_context_->GetDriveService(); | 764 return sync_context_->GetDriveService(); |
760 } | 765 } |
761 | 766 |
762 MetadataDatabase* RemoteToLocalSyncer::metadata_database() { | 767 MetadataDatabase* RemoteToLocalSyncer::metadata_database() { |
763 return sync_context_->GetMetadataDatabase(); | 768 return sync_context_->GetMetadataDatabase(); |
764 } | 769 } |
765 | 770 |
766 RemoteChangeProcessor* RemoteToLocalSyncer::remote_change_processor() { | 771 RemoteChangeProcessor* RemoteToLocalSyncer::remote_change_processor() { |
767 DCHECK(sync_context_->GetRemoteChangeProcessor()); | 772 DCHECK(sync_context_->GetRemoteChangeProcessor()); |
768 return sync_context_->GetRemoteChangeProcessor(); | 773 return sync_context_->GetRemoteChangeProcessor(); |
769 } | 774 } |
770 | 775 |
771 SyncStatusCallback RemoteToLocalSyncer::SyncCompletedCallback( | 776 SyncStatusCallback RemoteToLocalSyncer::SyncCompletedCallback( |
772 scoped_ptr<SyncTaskToken> token) { | 777 scoped_ptr<SyncTaskToken> token) { |
773 return base::Bind(&RemoteToLocalSyncer::SyncCompleted, | 778 return base::Bind(&RemoteToLocalSyncer::SyncCompleted, |
774 weak_ptr_factory_.GetWeakPtr(), | 779 weak_ptr_factory_.GetWeakPtr(), |
775 base::Passed(&token)); | 780 base::Passed(&token)); |
776 } | 781 } |
777 | 782 |
778 } // namespace drive_backend | 783 } // namespace drive_backend |
779 } // namespace sync_file_system | 784 } // namespace sync_file_system |
OLD | NEW |