|  | // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #include "components/drive/file_system/remove_operation.h" | 
|  |  | 
|  | #include "base/sequenced_task_runner.h" | 
|  | #include "components/drive/drive.pb.h" | 
|  | #include "components/drive/file_cache.h" | 
|  | #include "components/drive/file_change.h" | 
|  | #include "components/drive/file_system/operation_delegate.h" | 
|  | #include "components/drive/file_system_core_util.h" | 
|  | #include "components/drive/job_scheduler.h" | 
|  | #include "components/drive/resource_metadata.h" | 
|  |  | 
|  | namespace drive { | 
|  | namespace file_system { | 
|  |  | 
|  | namespace { | 
|  |  | 
|  | // Removes cache file and moves the metadata entry to the trash. | 
|  | FileError UpdateLocalState(internal::ResourceMetadata* metadata, | 
|  | internal::FileCache* cache, | 
|  | const base::FilePath& path, | 
|  | bool is_recursive, | 
|  | std::string* local_id, | 
|  | ResourceEntry* entry, | 
|  | base::FilePath* changed_path) { | 
|  | FileError error = metadata->GetIdByPath(path, local_id); | 
|  | if (error != FILE_ERROR_OK) | 
|  | return error; | 
|  |  | 
|  | error = metadata->GetResourceEntryById(*local_id, entry); | 
|  | if (error != FILE_ERROR_OK) | 
|  | return error; | 
|  |  | 
|  | if (entry->file_info().is_directory() && !is_recursive) { | 
|  | // Check emptiness of the directory. | 
|  | ResourceEntryVector entries; | 
|  | error = metadata->ReadDirectoryByPath(path, &entries); | 
|  | if (error != FILE_ERROR_OK) | 
|  | return error; | 
|  | if (!entries.empty()) | 
|  | return FILE_ERROR_NOT_EMPTY; | 
|  | } | 
|  |  | 
|  | error = cache->Remove(*local_id); | 
|  | if (error != FILE_ERROR_OK) | 
|  | return error; | 
|  |  | 
|  | *changed_path = path; | 
|  |  | 
|  | // Move to the trash. | 
|  | entry->set_parent_local_id(util::kDriveTrashDirLocalId); | 
|  | return metadata->RefreshEntry(*entry); | 
|  | } | 
|  |  | 
|  | }  // namespace | 
|  |  | 
|  | RemoveOperation::RemoveOperation( | 
|  | base::SequencedTaskRunner* blocking_task_runner, | 
|  | OperationDelegate* delegate, | 
|  | internal::ResourceMetadata* metadata, | 
|  | internal::FileCache* cache) | 
|  | : blocking_task_runner_(blocking_task_runner), | 
|  | delegate_(delegate), | 
|  | metadata_(metadata), | 
|  | cache_(cache), | 
|  | weak_ptr_factory_(this) { | 
|  | } | 
|  |  | 
|  | RemoveOperation::~RemoveOperation() { | 
|  | DCHECK(thread_checker_.CalledOnValidThread()); | 
|  | } | 
|  |  | 
|  | void RemoveOperation::Remove(const base::FilePath& path, | 
|  | bool is_recursive, | 
|  | const FileOperationCallback& callback) { | 
|  | DCHECK(thread_checker_.CalledOnValidThread()); | 
|  | DCHECK(!callback.is_null()); | 
|  |  | 
|  | std::string* local_id = new std::string; | 
|  | base::FilePath* changed_path = new base::FilePath; | 
|  | ResourceEntry* entry = new ResourceEntry; | 
|  | base::PostTaskAndReplyWithResult( | 
|  | blocking_task_runner_.get(), | 
|  | FROM_HERE, | 
|  | base::Bind(&UpdateLocalState, | 
|  | metadata_, | 
|  | cache_, | 
|  | path, | 
|  | is_recursive, | 
|  | local_id, | 
|  | entry, | 
|  | changed_path), | 
|  | base::Bind(&RemoveOperation::RemoveAfterUpdateLocalState, | 
|  | weak_ptr_factory_.GetWeakPtr(), | 
|  | callback, | 
|  | base::Owned(local_id), | 
|  | base::Owned(entry), | 
|  | base::Owned(changed_path))); | 
|  | } | 
|  |  | 
|  | void RemoveOperation::RemoveAfterUpdateLocalState( | 
|  | const FileOperationCallback& callback, | 
|  | const std::string* local_id, | 
|  | const ResourceEntry* entry, | 
|  | const base::FilePath* changed_path, | 
|  | FileError error) { | 
|  | DCHECK(thread_checker_.CalledOnValidThread()); | 
|  | DCHECK(!callback.is_null()); | 
|  |  | 
|  | if (!changed_path->empty()) { | 
|  | FileChange changed_file; | 
|  | changed_file.Update(*changed_path, *entry, FileChange::CHANGE_TYPE_DELETE); | 
|  | if (error == FILE_ERROR_OK) { | 
|  | delegate_->OnFileChangedByOperation(changed_file); | 
|  | delegate_->OnEntryUpdatedByOperation(ClientContext(USER_INITIATED), | 
|  | *local_id); | 
|  | } | 
|  | } | 
|  |  | 
|  | callback.Run(error); | 
|  | } | 
|  |  | 
|  | }  // namespace file_system | 
|  | }  // namespace drive |