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 3// found in the LICENSE file. 4 5#include "chrome/browser/chromeos/drive/file_system/remove_operation.h" 6 7#include "base/sequenced_task_runner.h" 8#include "chrome/browser/chromeos/drive/drive.pb.h" 9#include "chrome/browser/chromeos/drive/file_cache.h" 10#include "chrome/browser/chromeos/drive/file_change.h" 11#include "chrome/browser/chromeos/drive/file_system/operation_delegate.h" 12#include "chrome/browser/chromeos/drive/file_system_util.h" 13#include "chrome/browser/chromeos/drive/resource_metadata.h" 14#include "content/public/browser/browser_thread.h" 15 16using content::BrowserThread; 17 18namespace drive { 19namespace file_system { 20 21namespace { 22 23// Removes cache file and moves the metadata entry to the trash. 24FileError UpdateLocalState(internal::ResourceMetadata* metadata, 25 internal::FileCache* cache, 26 const base::FilePath& path, 27 bool is_recursive, 28 std::string* local_id, 29 ResourceEntry* entry, 30 base::FilePath* changed_path) { 31 FileError error = metadata->GetIdByPath(path, local_id); 32 if (error != FILE_ERROR_OK) 33 return error; 34 35 error = metadata->GetResourceEntryById(*local_id, entry); 36 if (error != FILE_ERROR_OK) 37 return error; 38 39 if (entry->file_info().is_directory() && !is_recursive) { 40 // Check emptiness of the directory. 41 ResourceEntryVector entries; 42 error = metadata->ReadDirectoryByPath(path, &entries); 43 if (error != FILE_ERROR_OK) 44 return error; 45 if (!entries.empty()) 46 return FILE_ERROR_NOT_EMPTY; 47 } 48 49 error = cache->Remove(*local_id); 50 if (error != FILE_ERROR_OK) 51 return error; 52 53 *changed_path = path; 54 55 // Move to the trash. 56 entry->set_parent_local_id(util::kDriveTrashDirLocalId); 57 return metadata->RefreshEntry(*entry); 58} 59 60} // namespace 61 62RemoveOperation::RemoveOperation( 63 base::SequencedTaskRunner* blocking_task_runner, 64 OperationDelegate* delegate, 65 internal::ResourceMetadata* metadata, 66 internal::FileCache* cache) 67 : blocking_task_runner_(blocking_task_runner), 68 delegate_(delegate), 69 metadata_(metadata), 70 cache_(cache), 71 weak_ptr_factory_(this) { 72 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 73} 74 75RemoveOperation::~RemoveOperation() { 76 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 77} 78 79void RemoveOperation::Remove(const base::FilePath& path, 80 bool is_recursive, 81 const FileOperationCallback& callback) { 82 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 83 DCHECK(!callback.is_null()); 84 85 std::string* local_id = new std::string; 86 base::FilePath* changed_path = new base::FilePath; 87 ResourceEntry* entry = new ResourceEntry; 88 base::PostTaskAndReplyWithResult( 89 blocking_task_runner_.get(), 90 FROM_HERE, 91 base::Bind(&UpdateLocalState, 92 metadata_, 93 cache_, 94 path, 95 is_recursive, 96 local_id, 97 entry, 98 changed_path), 99 base::Bind(&RemoveOperation::RemoveAfterUpdateLocalState, 100 weak_ptr_factory_.GetWeakPtr(), 101 callback, 102 base::Owned(local_id), 103 base::Owned(entry), 104 base::Owned(changed_path))); 105} 106 107void RemoveOperation::RemoveAfterUpdateLocalState( 108 const FileOperationCallback& callback, 109 const std::string* local_id, 110 const ResourceEntry* entry, 111 const base::FilePath* changed_path, 112 FileError error) { 113 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 114 DCHECK(!callback.is_null()); 115 116 if (!changed_path->empty()) { 117 FileChange changed_file; 118 changed_file.Update(*changed_path, *entry, FileChange::DELETE); 119 if (error == FILE_ERROR_OK) { 120 delegate_->OnFileChangedByOperation(changed_file); 121 delegate_->OnEntryUpdatedByOperation(*local_id); 122 } 123 } 124 125 callback.Run(error); 126} 127 128} // namespace file_system 129} // namespace drive 130