OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/file_system/copy_operation.h" | 5 #include "chrome/browser/chromeos/drive/file_system/copy_operation.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
10 #include "base/task_runner_util.h" | 10 #include "base/task_runner_util.h" |
11 #include "chrome/browser/chromeos/drive/drive.pb.h" | 11 #include "chrome/browser/chromeos/drive/drive.pb.h" |
12 #include "chrome/browser/chromeos/drive/file_cache.h" | 12 #include "chrome/browser/chromeos/drive/file_cache.h" |
| 13 #include "chrome/browser/chromeos/drive/file_change.h" |
13 #include "chrome/browser/chromeos/drive/file_system/create_file_operation.h" | 14 #include "chrome/browser/chromeos/drive/file_system/create_file_operation.h" |
14 #include "chrome/browser/chromeos/drive/file_system/operation_observer.h" | 15 #include "chrome/browser/chromeos/drive/file_system/operation_observer.h" |
15 #include "chrome/browser/chromeos/drive/file_system_util.h" | 16 #include "chrome/browser/chromeos/drive/file_system_util.h" |
16 #include "chrome/browser/chromeos/drive/job_scheduler.h" | 17 #include "chrome/browser/chromeos/drive/job_scheduler.h" |
17 #include "chrome/browser/chromeos/drive/resource_entry_conversion.h" | 18 #include "chrome/browser/chromeos/drive/resource_entry_conversion.h" |
18 #include "chrome/browser/chromeos/drive/resource_metadata.h" | 19 #include "chrome/browser/chromeos/drive/resource_metadata.h" |
19 #include "chrome/browser/drive/drive_api_util.h" | 20 #include "chrome/browser/drive/drive_api_util.h" |
20 #include "content/public/browser/browser_thread.h" | 21 #include "content/public/browser/browser_thread.h" |
21 #include "google_apis/drive/drive_api_parser.h" | 22 #include "google_apis/drive/drive_api_parser.h" |
22 | 23 |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 return error; | 157 return error; |
157 | 158 |
158 return cache->Store(local_id, std::string(), cache_file_path, | 159 return cache->Store(local_id, std::string(), cache_file_path, |
159 internal::FileCache::FILE_OPERATION_COPY); | 160 internal::FileCache::FILE_OPERATION_COPY); |
160 } | 161 } |
161 | 162 |
162 // Stores the entry returned from the server and returns its path. | 163 // Stores the entry returned from the server and returns its path. |
163 FileError UpdateLocalStateForServerSideOperation( | 164 FileError UpdateLocalStateForServerSideOperation( |
164 internal::ResourceMetadata* metadata, | 165 internal::ResourceMetadata* metadata, |
165 scoped_ptr<google_apis::FileResource> file_resource, | 166 scoped_ptr<google_apis::FileResource> file_resource, |
| 167 ResourceEntry* entry, |
166 base::FilePath* file_path) { | 168 base::FilePath* file_path) { |
167 DCHECK(file_resource); | 169 DCHECK(file_resource); |
168 | 170 |
169 ResourceEntry entry; | |
170 std::string parent_resource_id; | 171 std::string parent_resource_id; |
171 if (!ConvertFileResourceToResourceEntry(*file_resource, &entry, | 172 if (!ConvertFileResourceToResourceEntry( |
172 &parent_resource_id) || | 173 *file_resource, entry, &parent_resource_id) || |
173 parent_resource_id.empty()) | 174 parent_resource_id.empty()) |
174 return FILE_ERROR_NOT_A_FILE; | 175 return FILE_ERROR_NOT_A_FILE; |
175 | 176 |
176 std::string parent_local_id; | 177 std::string parent_local_id; |
177 FileError error = metadata->GetIdByResourceId(parent_resource_id, | 178 FileError error = metadata->GetIdByResourceId(parent_resource_id, |
178 &parent_local_id); | 179 &parent_local_id); |
179 if (error != FILE_ERROR_OK) | 180 if (error != FILE_ERROR_OK) |
180 return error; | 181 return error; |
181 entry.set_parent_local_id(parent_local_id); | 182 entry->set_parent_local_id(parent_local_id); |
182 | 183 |
183 std::string local_id; | 184 std::string local_id; |
184 error = metadata->AddEntry(entry, &local_id); | 185 error = metadata->AddEntry(*entry, &local_id); |
185 // Depending on timing, the metadata may have inserted via change list | 186 // Depending on timing, the metadata may have inserted via change list |
186 // already. So, FILE_ERROR_EXISTS is not an error. | 187 // already. So, FILE_ERROR_EXISTS is not an error. |
187 if (error == FILE_ERROR_EXISTS) | 188 if (error == FILE_ERROR_EXISTS) |
188 error = metadata->GetIdByResourceId(entry.resource_id(), &local_id); | 189 error = metadata->GetIdByResourceId(entry->resource_id(), &local_id); |
189 | 190 |
190 if (error != FILE_ERROR_OK) | 191 if (error != FILE_ERROR_OK) |
191 return error; | 192 return error; |
192 | 193 |
193 return metadata->GetFilePath(local_id, file_path); | 194 return metadata->GetFilePath(local_id, file_path); |
194 } | 195 } |
195 | 196 |
196 // Stores the file at |local_file_path| to the cache as a content of entry at | 197 // Stores the file at |local_file_path| to the cache as a content of entry at |
197 // |remote_dest_path|, and marks it dirty. | 198 // |remote_dest_path|, and marks it dirty. |
198 FileError UpdateLocalStateForScheduleTransfer( | 199 FileError UpdateLocalStateForScheduleTransfer( |
199 internal::ResourceMetadata* metadata, | 200 internal::ResourceMetadata* metadata, |
200 internal::FileCache* cache, | 201 internal::FileCache* cache, |
201 const base::FilePath& local_src_path, | 202 const base::FilePath& local_src_path, |
202 const base::FilePath& remote_dest_path, | 203 const base::FilePath& remote_dest_path, |
| 204 ResourceEntry* entry, |
203 std::string* local_id) { | 205 std::string* local_id) { |
204 FileError error = metadata->GetIdByPath(remote_dest_path, local_id); | 206 FileError error = metadata->GetIdByPath(remote_dest_path, local_id); |
205 if (error != FILE_ERROR_OK) | 207 if (error != FILE_ERROR_OK) |
206 return error; | 208 return error; |
207 | 209 |
208 ResourceEntry entry; | 210 error = metadata->GetResourceEntryById(*local_id, entry); |
209 error = metadata->GetResourceEntryById(*local_id, &entry); | |
210 if (error != FILE_ERROR_OK) | 211 if (error != FILE_ERROR_OK) |
211 return error; | 212 return error; |
212 | 213 |
213 return cache->Store(*local_id, std::string(), local_src_path, | 214 return cache->Store(*local_id, std::string(), local_src_path, |
214 internal::FileCache::FILE_OPERATION_COPY); | 215 internal::FileCache::FILE_OPERATION_COPY); |
215 } | 216 } |
216 | 217 |
217 // Gets the file size of the |local_path|, and the ResourceEntry for the parent | 218 // Gets the file size of the |local_path|, and the ResourceEntry for the parent |
218 // of |remote_path| to prepare the necessary information for transfer. | 219 // of |remote_path| to prepare the necessary information for transfer. |
219 FileError PrepareTransferFileFromLocalToRemote( | 220 FileError PrepareTransferFileFromLocalToRemote( |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
329 const std::vector<std::string>* updated_local_ids, | 330 const std::vector<std::string>* updated_local_ids, |
330 const bool* directory_changed, | 331 const bool* directory_changed, |
331 const bool* should_copy_on_server, | 332 const bool* should_copy_on_server, |
332 FileError error) { | 333 FileError error) { |
333 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 334 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
334 DCHECK(!params->callback.is_null()); | 335 DCHECK(!params->callback.is_null()); |
335 | 336 |
336 for (size_t i = 0; i < updated_local_ids->size(); ++i) | 337 for (size_t i = 0; i < updated_local_ids->size(); ++i) |
337 observer_->OnEntryUpdatedByOperation((*updated_local_ids)[i]); | 338 observer_->OnEntryUpdatedByOperation((*updated_local_ids)[i]); |
338 | 339 |
339 if (*directory_changed) | 340 if (*directory_changed) { |
340 observer_->OnDirectoryChangedByOperation(params->dest_file_path.DirName()); | 341 FileChange changed_file; |
| 342 DCHECK(!params->src_entry.file_info().is_directory()); |
| 343 changed_file.Update(params->dest_file_path, |
| 344 FileChange::FILE_TYPE_FILE, |
| 345 FileChange::ADD_OR_UPDATE); |
| 346 observer_->OnFileChangedByOperation(changed_file); |
| 347 } |
341 | 348 |
342 if (error != FILE_ERROR_OK || !*should_copy_on_server) { | 349 if (error != FILE_ERROR_OK || !*should_copy_on_server) { |
343 params->callback.Run(error); | 350 params->callback.Run(error); |
344 return; | 351 return; |
345 } | 352 } |
346 | 353 |
347 base::FilePath new_title = params->dest_file_path.BaseName(); | 354 base::FilePath new_title = params->dest_file_path.BaseName(); |
348 if (params->src_entry.file_specific_info().is_hosted_document()) { | 355 if (params->src_entry.file_specific_info().is_hosted_document()) { |
349 // Drop the document extension, which should not be in the title. | 356 // Drop the document extension, which should not be in the title. |
350 // TODO(yoshiki): Remove this code with crbug.com/223304. | 357 // TODO(yoshiki): Remove this code with crbug.com/223304. |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
442 case HAS_PARENT: | 449 case HAS_PARENT: |
443 CopyResourceOnServer(params->resource_id, | 450 CopyResourceOnServer(params->resource_id, |
444 params->parent_resource_id, | 451 params->parent_resource_id, |
445 params->new_title, | 452 params->new_title, |
446 base::Time(), | 453 base::Time(), |
447 params->callback); | 454 params->callback); |
448 break; | 455 break; |
449 // When |resource_id| has no parent, we just set the new destination folder | 456 // When |resource_id| has no parent, we just set the new destination folder |
450 // as the parent, for sharing the document between the original source. | 457 // as the parent, for sharing the document between the original source. |
451 // This reparenting is already done in LocalWorkForTransferJsonGdocFile(). | 458 // This reparenting is already done in LocalWorkForTransferJsonGdocFile(). |
452 case IS_ORPHAN: | 459 case IS_ORPHAN: { |
453 DCHECK(!params->changed_path.empty()); | 460 DCHECK(!params->changed_path.empty()); |
454 observer_->OnEntryUpdatedByOperation(params->local_id); | 461 observer_->OnEntryUpdatedByOperation(params->local_id); |
455 observer_->OnDirectoryChangedByOperation(params->changed_path.DirName()); | 462 |
| 463 FileChange changed_file; |
| 464 changed_file.Update( |
| 465 params->changed_path, |
| 466 FileChange::FILE_TYPE_FILE, // This must be a hosted document. |
| 467 FileChange::ADD_OR_UPDATE); |
| 468 observer_->OnFileChangedByOperation(changed_file); |
456 params->callback.Run(error); | 469 params->callback.Run(error); |
457 break; | 470 break; |
| 471 } |
458 // When the |resource_id| is not in the local metadata, assume it to be a | 472 // When the |resource_id| is not in the local metadata, assume it to be a |
459 // document just now shared on the server but not synced locally. | 473 // document just now shared on the server but not synced locally. |
460 // Same as the IS_ORPHAN case, we want to deal the case by setting parent, | 474 // Same as the IS_ORPHAN case, we want to deal the case by setting parent, |
461 // but this time we need to resort to server side operation. | 475 // but this time we need to resort to server side operation. |
462 case NOT_IN_METADATA: | 476 case NOT_IN_METADATA: |
463 scheduler_->UpdateResource( | 477 scheduler_->UpdateResource( |
464 params->resource_id, | 478 params->resource_id, |
465 params->parent_resource_id, | 479 params->parent_resource_id, |
466 params->new_title, | 480 params->new_title, |
467 base::Time(), | 481 base::Time(), |
(...skipping 28 matching lines...) Expand all Loading... |
496 scoped_ptr<google_apis::FileResource> entry) { | 510 scoped_ptr<google_apis::FileResource> entry) { |
497 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 511 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
498 DCHECK(!callback.is_null()); | 512 DCHECK(!callback.is_null()); |
499 | 513 |
500 FileError error = GDataToFileError(status); | 514 FileError error = GDataToFileError(status); |
501 if (error != FILE_ERROR_OK) { | 515 if (error != FILE_ERROR_OK) { |
502 callback.Run(error); | 516 callback.Run(error); |
503 return; | 517 return; |
504 } | 518 } |
505 | 519 |
| 520 ResourceEntry* resource_entry = new ResourceEntry; |
| 521 |
506 // The copy on the server side is completed successfully. Update the local | 522 // The copy on the server side is completed successfully. Update the local |
507 // metadata. | 523 // metadata. |
508 base::FilePath* file_path = new base::FilePath; | 524 base::FilePath* file_path = new base::FilePath; |
509 base::PostTaskAndReplyWithResult( | 525 base::PostTaskAndReplyWithResult( |
510 blocking_task_runner_.get(), | 526 blocking_task_runner_.get(), |
511 FROM_HERE, | 527 FROM_HERE, |
512 base::Bind(&UpdateLocalStateForServerSideOperation, | 528 base::Bind(&UpdateLocalStateForServerSideOperation, |
513 metadata_, base::Passed(&entry), file_path), | 529 metadata_, |
| 530 base::Passed(&entry), |
| 531 resource_entry, |
| 532 file_path), |
514 base::Bind(&CopyOperation::UpdateAfterLocalStateUpdate, | 533 base::Bind(&CopyOperation::UpdateAfterLocalStateUpdate, |
515 weak_ptr_factory_.GetWeakPtr(), | 534 weak_ptr_factory_.GetWeakPtr(), |
516 callback, base::Owned(file_path))); | 535 callback, |
| 536 base::Owned(file_path), |
| 537 base::Owned(resource_entry))); |
517 } | 538 } |
518 | 539 |
519 void CopyOperation::UpdateAfterLocalStateUpdate( | 540 void CopyOperation::UpdateAfterLocalStateUpdate( |
520 const FileOperationCallback& callback, | 541 const FileOperationCallback& callback, |
521 base::FilePath* file_path, | 542 base::FilePath* file_path, |
| 543 const ResourceEntry* entry, |
522 FileError error) { | 544 FileError error) { |
523 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 545 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
524 DCHECK(!callback.is_null()); | 546 DCHECK(!callback.is_null()); |
525 | 547 |
526 if (error == FILE_ERROR_OK) | 548 if (error == FILE_ERROR_OK) { |
527 observer_->OnDirectoryChangedByOperation(file_path->DirName()); | 549 FileChange changed_file; |
| 550 changed_file.Update(*file_path, *entry, FileChange::ADD_OR_UPDATE); |
| 551 observer_->OnFileChangedByOperation(changed_file); |
| 552 } |
528 callback.Run(error); | 553 callback.Run(error); |
529 } | 554 } |
530 | 555 |
531 void CopyOperation::ScheduleTransferRegularFile( | 556 void CopyOperation::ScheduleTransferRegularFile( |
532 const base::FilePath& local_src_path, | 557 const base::FilePath& local_src_path, |
533 const base::FilePath& remote_dest_path, | 558 const base::FilePath& remote_dest_path, |
534 const FileOperationCallback& callback) { | 559 const FileOperationCallback& callback) { |
535 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 560 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
536 DCHECK(!callback.is_null()); | 561 DCHECK(!callback.is_null()); |
537 | 562 |
(...skipping 13 matching lines...) Expand all Loading... |
551 FileError error) { | 576 FileError error) { |
552 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 577 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
553 DCHECK(!callback.is_null()); | 578 DCHECK(!callback.is_null()); |
554 | 579 |
555 if (error != FILE_ERROR_OK) { | 580 if (error != FILE_ERROR_OK) { |
556 callback.Run(error); | 581 callback.Run(error); |
557 return; | 582 return; |
558 } | 583 } |
559 | 584 |
560 std::string* local_id = new std::string; | 585 std::string* local_id = new std::string; |
| 586 ResourceEntry* entry = new ResourceEntry; |
561 base::PostTaskAndReplyWithResult( | 587 base::PostTaskAndReplyWithResult( |
562 blocking_task_runner_.get(), | 588 blocking_task_runner_.get(), |
563 FROM_HERE, | 589 FROM_HERE, |
564 base::Bind( | 590 base::Bind(&UpdateLocalStateForScheduleTransfer, |
565 &UpdateLocalStateForScheduleTransfer, | 591 metadata_, |
566 metadata_, cache_, local_src_path, remote_dest_path, local_id), | 592 cache_, |
| 593 local_src_path, |
| 594 remote_dest_path, |
| 595 entry, |
| 596 local_id), |
567 base::Bind( | 597 base::Bind( |
568 &CopyOperation::ScheduleTransferRegularFileAfterUpdateLocalState, | 598 &CopyOperation::ScheduleTransferRegularFileAfterUpdateLocalState, |
569 weak_ptr_factory_.GetWeakPtr(), callback, remote_dest_path, | 599 weak_ptr_factory_.GetWeakPtr(), |
| 600 callback, |
| 601 remote_dest_path, |
| 602 base::Owned(entry), |
570 base::Owned(local_id))); | 603 base::Owned(local_id))); |
571 } | 604 } |
572 | 605 |
573 void CopyOperation::ScheduleTransferRegularFileAfterUpdateLocalState( | 606 void CopyOperation::ScheduleTransferRegularFileAfterUpdateLocalState( |
574 const FileOperationCallback& callback, | 607 const FileOperationCallback& callback, |
575 const base::FilePath& remote_dest_path, | 608 const base::FilePath& remote_dest_path, |
| 609 const ResourceEntry* entry, |
576 std::string* local_id, | 610 std::string* local_id, |
577 FileError error) { | 611 FileError error) { |
578 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 612 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
579 DCHECK(!callback.is_null()); | 613 DCHECK(!callback.is_null()); |
580 | 614 |
581 if (error == FILE_ERROR_OK) { | 615 if (error == FILE_ERROR_OK) { |
582 observer_->OnDirectoryChangedByOperation(remote_dest_path.DirName()); | 616 FileChange changed_file; |
| 617 changed_file.Update(remote_dest_path, *entry, FileChange::ADD_OR_UPDATE); |
| 618 observer_->OnFileChangedByOperation(changed_file); |
583 observer_->OnEntryUpdatedByOperation(*local_id); | 619 observer_->OnEntryUpdatedByOperation(*local_id); |
584 } | 620 } |
585 callback.Run(error); | 621 callback.Run(error); |
586 } | 622 } |
587 | 623 |
588 } // namespace file_system | 624 } // namespace file_system |
589 } // namespace drive | 625 } // namespace drive |
OLD | NEW |