Chromium Code Reviews| 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/move_operation.h" | 5 #include "chrome/browser/chromeos/drive/file_system/move_operation.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_system/operation_observer.h" | 8 #include "chrome/browser/chromeos/drive/file_system/operation_observer.h" |
| 9 #include "chrome/browser/chromeos/drive/file_system_util.h" | 9 #include "chrome/browser/chromeos/drive/file_system_util.h" |
| 10 #include "chrome/browser/chromeos/drive/job_scheduler.h" | 10 #include "chrome/browser/chromeos/drive/job_scheduler.h" |
| 11 #include "content/public/browser/browser_thread.h" | 11 #include "content/public/browser/browser_thread.h" |
| 12 | 12 |
| 13 using content::BrowserThread; | 13 using content::BrowserThread; |
| 14 | 14 |
| 15 namespace drive { | 15 namespace drive { |
| 16 namespace file_system { | 16 namespace file_system { |
| 17 namespace { | |
| 17 | 18 |
| 18 MoveOperation::MoveOperation(OperationObserver* observer, | 19 // Looks up ResourceEntry for source entry and the destination directory. |
| 20 FileError PrepareMove(internal::ResourceMetadata* metadata, | |
| 21 const base::FilePath& src_path, | |
| 22 const base::FilePath& dest_parent_path, | |
| 23 ResourceEntry* src_entry, | |
| 24 ResourceEntry* dest_parent_entry) { | |
| 25 DCHECK(metadata); | |
|
hashimoto
2013/08/21 07:49:08
nit: Do we need this? At least, two functions belo
hidehiko
2013/08/21 08:07:00
Ok, removed.
| |
| 26 DCHECK(src_entry); | |
| 27 DCHECK(dest_parent_entry); | |
| 28 | |
| 29 FileError error = metadata->GetResourceEntryByPath(src_path, src_entry); | |
| 30 if (error != FILE_ERROR_OK) | |
| 31 return error; | |
| 32 | |
| 33 return metadata->GetResourceEntryByPath(dest_parent_path, dest_parent_entry); | |
| 34 } | |
| 35 | |
| 36 // Applies renaming to the local metadata. | |
| 37 FileError RenameLocally(internal::ResourceMetadata* metadata, | |
| 38 const std::string& resource_id, | |
| 39 const std::string& new_title) { | |
| 40 ResourceEntry entry; | |
| 41 FileError error = metadata->GetResourceEntryById(resource_id, &entry); | |
| 42 if (error != FILE_ERROR_OK) | |
| 43 return error; | |
| 44 | |
| 45 entry.set_title(new_title); | |
| 46 return metadata->RefreshEntry(entry); | |
| 47 } | |
| 48 | |
| 49 // Applies directory-moving to the local metadata. | |
| 50 FileError MoveDirectoryLocally(internal::ResourceMetadata* metadata, | |
| 51 const std::string& resource_id, | |
| 52 const std::string& parent_resource_id) { | |
| 53 ResourceEntry entry; | |
| 54 FileError error = metadata->GetResourceEntryById(resource_id, &entry); | |
| 55 if (error != FILE_ERROR_OK) | |
| 56 return error; | |
| 57 | |
| 58 // Make sure that the parent exists and it is actually a directory. | |
|
hashimoto
2013/08/21 07:49:08
ResourceMetadata::RefreshEntry does this check.
hidehiko
2013/08/21 08:07:00
Removed. Instead, edit ResourceMetadata::RefreshEn
| |
| 59 ResourceEntry parent_entry; | |
| 60 error = metadata->GetResourceEntryById(parent_resource_id, &parent_entry); | |
| 61 if (error != FILE_ERROR_OK) | |
| 62 return error; | |
| 63 | |
| 64 if (!parent_entry.file_info().is_directory()) | |
| 65 return FILE_ERROR_NOT_A_DIRECTORY; | |
| 66 | |
| 67 // Update the parent. | |
| 68 entry.set_parent_resource_id(parent_resource_id); | |
| 69 return metadata->RefreshEntry(entry); | |
| 70 } | |
| 71 | |
| 72 } // namespace | |
| 73 | |
| 74 MoveOperation::MoveOperation(base::SequencedTaskRunner* blocking_task_runner, | |
| 75 OperationObserver* observer, | |
| 19 JobScheduler* scheduler, | 76 JobScheduler* scheduler, |
| 20 internal::ResourceMetadata* metadata) | 77 internal::ResourceMetadata* metadata) |
| 21 : observer_(observer), | 78 : blocking_task_runner_(blocking_task_runner), |
| 22 scheduler_(scheduler), | 79 observer_(observer), |
| 23 metadata_(metadata), | 80 scheduler_(scheduler), |
| 24 weak_ptr_factory_(this) { | 81 metadata_(metadata), |
| 82 weak_ptr_factory_(this) { | |
| 25 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 83 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 26 } | 84 } |
| 27 | 85 |
| 28 MoveOperation::~MoveOperation() { | 86 MoveOperation::~MoveOperation() { |
| 29 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 87 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 30 } | 88 } |
| 31 | 89 |
| 32 void MoveOperation::Move(const base::FilePath& src_file_path, | 90 void MoveOperation::Move(const base::FilePath& src_file_path, |
| 33 const base::FilePath& dest_file_path, | 91 const base::FilePath& dest_file_path, |
| 34 const FileOperationCallback& callback) { | 92 const FileOperationCallback& callback) { |
| 35 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 93 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 36 DCHECK(!callback.is_null()); | 94 DCHECK(!callback.is_null()); |
| 37 | 95 |
| 38 metadata_->GetResourceEntryPairByPathsOnUIThread( | 96 scoped_ptr<ResourceEntry> src_entry(new ResourceEntry); |
| 39 src_file_path, | 97 scoped_ptr<ResourceEntry> dest_parent_entry(new ResourceEntry); |
| 40 dest_file_path.DirName(), | 98 ResourceEntry* src_entry_ptr = src_entry.get(); |
| 41 base::Bind(&MoveOperation::MoveAfterGetResourceEntryPair, | 99 ResourceEntry* dest_parent_entry_ptr = dest_parent_entry.get(); |
| 100 base::PostTaskAndReplyWithResult( | |
| 101 blocking_task_runner_.get(), | |
| 102 FROM_HERE, | |
| 103 base::Bind(&PrepareMove, | |
| 104 metadata_, src_file_path, dest_file_path.DirName(), | |
| 105 src_entry_ptr, dest_parent_entry_ptr), | |
| 106 base::Bind(&MoveOperation::MoveAfterPrepare, | |
| 42 weak_ptr_factory_.GetWeakPtr(), | 107 weak_ptr_factory_.GetWeakPtr(), |
| 43 dest_file_path, | 108 src_file_path, dest_file_path, callback, |
| 44 callback)); | 109 base::Passed(&src_entry), |
| 110 base::Passed(&dest_parent_entry))); | |
| 45 } | 111 } |
| 46 | 112 |
| 47 void MoveOperation::MoveAfterGetResourceEntryPair( | 113 void MoveOperation::MoveAfterPrepare( |
| 114 const base::FilePath& src_file_path, | |
| 48 const base::FilePath& dest_file_path, | 115 const base::FilePath& dest_file_path, |
| 49 const FileOperationCallback& callback, | 116 const FileOperationCallback& callback, |
| 50 scoped_ptr<EntryInfoPairResult> src_dest_info) { | 117 scoped_ptr<ResourceEntry> src_entry, |
| 118 scoped_ptr<ResourceEntry> dest_parent_entry, | |
| 119 FileError error) { | |
| 51 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 120 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 52 DCHECK(!callback.is_null()); | 121 DCHECK(!callback.is_null()); |
| 53 DCHECK(src_dest_info.get()); | |
| 54 | |
| 55 if (src_dest_info->first.error != FILE_ERROR_OK) { | |
| 56 callback.Run(src_dest_info->first.error); | |
| 57 return; | |
| 58 } | |
| 59 if (src_dest_info->second.error != FILE_ERROR_OK) { | |
| 60 callback.Run(src_dest_info->second.error); | |
| 61 return; | |
| 62 } | |
| 63 if (!src_dest_info->second.entry->file_info().is_directory()) { | |
| 64 callback.Run(FILE_ERROR_NOT_A_DIRECTORY); | |
| 65 return; | |
| 66 } | |
| 67 | |
| 68 const std::string& src_id = src_dest_info->first.entry->resource_id(); | |
| 69 const base::FilePath& src_path = src_dest_info->first.path; | |
| 70 const base::FilePath new_name = dest_file_path.BaseName(); | |
| 71 const bool new_name_has_hosted_extension = | |
| 72 src_dest_info->first.entry->has_file_specific_info() && | |
| 73 src_dest_info->first.entry->file_specific_info().is_hosted_document() && | |
| 74 new_name.Extension() == | |
| 75 src_dest_info->first.entry->file_specific_info().document_extension(); | |
| 76 | |
| 77 Rename(src_id, src_path, new_name, new_name_has_hosted_extension, | |
| 78 base::Bind(&MoveOperation::MoveAfterRename, | |
| 79 weak_ptr_factory_.GetWeakPtr(), | |
| 80 callback, | |
| 81 base::Passed(&src_dest_info))); | |
| 82 } | |
| 83 | |
| 84 void MoveOperation::MoveAfterRename( | |
| 85 const FileOperationCallback& callback, | |
| 86 scoped_ptr<EntryInfoPairResult> src_dest_info, | |
| 87 FileError error, | |
| 88 const base::FilePath& src_path) { | |
| 89 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 90 | 122 |
| 91 if (error != FILE_ERROR_OK) { | 123 if (error != FILE_ERROR_OK) { |
| 92 callback.Run(error); | 124 callback.Run(error); |
| 93 return; | 125 return; |
| 94 } | 126 } |
| 95 | 127 |
| 96 const std::string& src_id = src_dest_info->first.entry->resource_id(); | 128 if (!dest_parent_entry->file_info().is_directory()) { |
| 97 const std::string& dest_dir_id = src_dest_info->second.entry->resource_id(); | 129 // The parent of the destination is not a directory. |
| 98 const base::FilePath& dest_dir_path = src_dest_info->second.path; | 130 callback.Run(FILE_ERROR_NOT_A_DIRECTORY); |
| 99 | |
| 100 // The source and the destination directory are the same. Nothing more to do. | |
| 101 if (src_path.DirName() == dest_dir_path) { | |
| 102 observer_->OnDirectoryChangedByOperation(dest_dir_path); | |
| 103 callback.Run(FILE_ERROR_OK); | |
| 104 return; | 131 return; |
| 105 } | 132 } |
| 106 | 133 |
| 107 AddToDirectory(src_id, dest_dir_id, src_path, dest_dir_path, | 134 // Strip the extension for a hosted document if necessary. |
| 108 base::Bind(&MoveOperation::MoveAfterAddToDirectory, | 135 const bool has_hosted_document_extension = |
| 109 weak_ptr_factory_.GetWeakPtr(), | 136 src_entry->has_file_specific_info() && |
| 110 callback, | 137 src_entry->file_specific_info().is_hosted_document() && |
| 111 base::Passed(&src_dest_info))); | 138 dest_file_path.Extension() == |
| 139 src_entry->file_specific_info().document_extension(); | |
| 140 const std::string new_title = | |
| 141 has_hosted_document_extension ? | |
| 142 dest_file_path.BaseName().RemoveExtension().AsUTF8Unsafe() : | |
| 143 dest_file_path.BaseName().AsUTF8Unsafe(); | |
| 144 | |
| 145 // TODO(hidehiko): On Drive API v2, we can move a resource by only one | |
| 146 // server request. Implement here. crbug.com/241814 | |
| 147 | |
| 148 ResourceEntry* src_entry_ptr = src_entry.get(); | |
| 149 Rename(*src_entry_ptr, new_title, | |
| 150 base::Bind(&MoveOperation::MoveAfterRename, | |
| 151 weak_ptr_factory_.GetWeakPtr(), | |
| 152 src_file_path, dest_file_path, callback, | |
| 153 base::Passed(&src_entry), | |
| 154 base::Passed(&dest_parent_entry))); | |
| 112 } | 155 } |
| 113 | 156 |
| 114 void MoveOperation::MoveAfterAddToDirectory( | 157 void MoveOperation::MoveAfterRename( |
| 158 const base::FilePath& src_file_path, | |
| 159 const base::FilePath& dest_file_path, | |
| 115 const FileOperationCallback& callback, | 160 const FileOperationCallback& callback, |
| 116 scoped_ptr<EntryInfoPairResult> src_dest_info, | 161 scoped_ptr<ResourceEntry> src_entry, |
| 117 FileError error, | 162 scoped_ptr<ResourceEntry> dest_parent_entry, |
| 118 const base::FilePath& new_path) { | 163 FileError error) { |
| 119 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 164 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 165 DCHECK(!callback.is_null()); | |
| 120 | 166 |
| 121 if (error != FILE_ERROR_OK) { | 167 if (error != FILE_ERROR_OK) { |
| 122 callback.Run(error); | 168 callback.Run(error); |
| 123 return; | 169 return; |
| 124 } | 170 } |
| 125 | 171 |
| 126 const base::FilePath& src_path = src_dest_info->first.path; | 172 // The source and the destination directory are the same. Nothing more to do. |
| 127 observer_->OnDirectoryChangedByOperation(src_path.DirName()); | 173 if (src_entry->parent_resource_id() == dest_parent_entry->resource_id()) { |
| 128 observer_->OnDirectoryChangedByOperation(new_path.DirName()); | 174 observer_->OnDirectoryChangedByOperation(dest_file_path.DirName()); |
| 129 | 175 callback.Run(FILE_ERROR_OK); |
| 130 RemoveFromDirectory(src_dest_info->first.entry->resource_id(), | |
| 131 src_dest_info->first.entry->parent_resource_id(), | |
| 132 callback); | |
| 133 } | |
| 134 | |
| 135 void MoveOperation::Rename(const std::string& src_id, | |
| 136 const base::FilePath& src_path, | |
| 137 const base::FilePath& new_name, | |
| 138 bool new_name_has_hosted_extension, | |
| 139 const FileMoveCallback& callback) { | |
| 140 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 141 | |
| 142 // It is a no-op if the file is renamed to the same name. | |
| 143 if (src_path.BaseName() == new_name) { | |
| 144 callback.Run(FILE_ERROR_OK, src_path); | |
| 145 return; | 176 return; |
| 146 } | 177 } |
| 147 | 178 |
| 148 // Drop the .g<something> extension from |new_name| if the file being | 179 AddToDirectory(src_entry->resource_id(), |
| 149 // renamed is a hosted document and |new_name| has the same .g<something> | 180 dest_parent_entry->resource_id(), |
| 150 // extension as the file. | 181 base::Bind(&MoveOperation::MoveAfterAddToDirectory, |
| 151 const std::string new_title = new_name_has_hosted_extension ? | 182 weak_ptr_factory_.GetWeakPtr(), |
| 152 new_name.RemoveExtension().AsUTF8Unsafe() : | 183 src_file_path, dest_file_path, callback, |
| 153 new_name.AsUTF8Unsafe(); | 184 src_entry->resource_id(), |
| 154 | 185 src_entry->parent_resource_id())); |
| 155 // Rename on the server. | |
| 156 scheduler_->RenameResource(src_id, | |
| 157 new_title, | |
| 158 base::Bind(&MoveOperation::RenameLocally, | |
| 159 weak_ptr_factory_.GetWeakPtr(), | |
| 160 src_path, | |
| 161 new_title, | |
| 162 callback)); | |
| 163 } | 186 } |
| 164 | 187 |
| 165 void MoveOperation::RenameLocally(const base::FilePath& src_path, | 188 void MoveOperation::MoveAfterAddToDirectory( |
| 166 const std::string& new_title, | 189 const base::FilePath& src_file_path, |
| 167 const FileMoveCallback& callback, | 190 const base::FilePath& dest_file_path, |
| 168 google_apis::GDataErrorCode status) { | 191 const FileOperationCallback& callback, |
| 192 const std::string& resource_id, | |
| 193 const std::string& parent_resource_id, | |
| 194 FileError error) { | |
| 169 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 195 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 196 DCHECK(!callback.is_null()); | |
| 197 | |
| 198 if (error != FILE_ERROR_OK) { | |
| 199 callback.Run(error); | |
| 200 return; | |
| 201 } | |
| 202 | |
| 203 // Notify to the observers. | |
| 204 observer_->OnDirectoryChangedByOperation(src_file_path.DirName()); | |
| 205 observer_->OnDirectoryChangedByOperation(dest_file_path.DirName()); | |
| 206 | |
| 207 RemoveFromDirectory(resource_id, parent_resource_id, callback); | |
| 208 } | |
| 209 | |
| 210 void MoveOperation::Rename(const ResourceEntry& entry, | |
| 211 const std::string& new_title, | |
| 212 const FileOperationCallback& callback) { | |
| 213 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 214 DCHECK(!callback.is_null()); | |
| 215 | |
| 216 if (entry.title() == new_title) { | |
| 217 // We have nothing to do. | |
| 218 callback.Run(FILE_ERROR_OK); | |
| 219 return; | |
| 220 } | |
| 221 | |
| 222 // Send a rename request to the server. | |
| 223 scheduler_->RenameResource( | |
| 224 entry.resource_id(), | |
| 225 new_title, | |
| 226 base::Bind(&MoveOperation::RenameAfterRenameResource, | |
| 227 weak_ptr_factory_.GetWeakPtr(), | |
| 228 entry.resource_id(), new_title, callback)); | |
| 229 } | |
| 230 | |
| 231 void MoveOperation::RenameAfterRenameResource( | |
| 232 const std::string& resource_id, | |
| 233 const std::string& new_title, | |
| 234 const FileOperationCallback& callback, | |
| 235 google_apis::GDataErrorCode status) { | |
| 236 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 237 DCHECK(!callback.is_null()); | |
| 170 | 238 |
| 171 const FileError error = GDataToFileError(status); | 239 const FileError error = GDataToFileError(status); |
| 172 if (error != FILE_ERROR_OK) { | 240 if (error != FILE_ERROR_OK) { |
| 173 callback.Run(error, base::FilePath()); | 241 callback.Run(error); |
| 174 return; | 242 return; |
| 175 } | 243 } |
| 176 metadata_->RenameEntryOnUIThread(src_path, new_title, callback); | 244 |
| 245 // Server side renaming is done. Update the local metadata. | |
| 246 base::PostTaskAndReplyWithResult( | |
| 247 blocking_task_runner_.get(), | |
| 248 FROM_HERE, | |
| 249 base::Bind(&RenameLocally, metadata_, resource_id, new_title), | |
| 250 callback); | |
| 177 } | 251 } |
| 178 | 252 |
| 179 void MoveOperation::AddToDirectory(const std::string& src_id, | 253 void MoveOperation::AddToDirectory( |
| 180 const std::string& dest_dir_id, | 254 const std::string& resource_id, |
| 181 const base::FilePath& src_path, | 255 const std::string& parent_resource_id, |
| 182 const base::FilePath& dest_dir_path, | 256 const FileOperationCallback& callback) { |
| 183 const FileMoveCallback& callback) { | |
| 184 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 257 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 258 DCHECK(!callback.is_null()); | |
| 185 | 259 |
| 186 scheduler_->AddResourceToDirectory( | 260 scheduler_->AddResourceToDirectory( |
| 187 dest_dir_id, src_id, | 261 parent_resource_id, resource_id, |
| 188 base::Bind(&MoveOperation::AddToDirectoryLocally, | 262 base::Bind(&MoveOperation::AddToDirectoryAfterAddResourceToDirectory, |
| 189 weak_ptr_factory_.GetWeakPtr(), | 263 weak_ptr_factory_.GetWeakPtr(), |
| 190 src_path, | 264 resource_id, parent_resource_id, callback)); |
| 191 dest_dir_path, | |
| 192 callback)); | |
| 193 } | 265 } |
| 194 | 266 |
| 195 void MoveOperation::AddToDirectoryLocally(const base::FilePath& src_path, | 267 void MoveOperation::AddToDirectoryAfterAddResourceToDirectory( |
| 196 const base::FilePath& dest_dir_path, | 268 const std::string& resource_id, |
| 197 const FileMoveCallback& callback, | 269 const std::string& parent_resource_id, |
| 198 google_apis::GDataErrorCode status) { | 270 const FileOperationCallback& callback, |
| 271 google_apis::GDataErrorCode status) { | |
| 199 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 272 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 273 DCHECK(!callback.is_null()); | |
| 200 | 274 |
| 201 const FileError error = GDataToFileError(status); | 275 const FileError error = GDataToFileError(status); |
| 202 if (error != FILE_ERROR_OK) { | 276 if (error != FILE_ERROR_OK) { |
| 203 callback.Run(error, base::FilePath()); | 277 callback.Run(error); |
| 204 return; | 278 return; |
| 205 } | 279 } |
| 206 metadata_->MoveEntryToDirectoryOnUIThread(src_path, dest_dir_path, callback); | 280 |
| 281 // Server side moving is done. Update the local metadata. | |
| 282 base::PostTaskAndReplyWithResult( | |
| 283 blocking_task_runner_.get(), | |
| 284 FROM_HERE, | |
| 285 base::Bind(&MoveDirectoryLocally, | |
| 286 metadata_, resource_id, parent_resource_id), | |
| 287 callback); | |
| 207 } | 288 } |
| 208 | 289 |
| 209 void MoveOperation::RemoveFromDirectory( | 290 void MoveOperation::RemoveFromDirectory( |
| 210 const std::string& resource_id, | 291 const std::string& resource_id, |
| 211 const std::string& directory_resource_id, | 292 const std::string& directory_resource_id, |
| 212 const FileOperationCallback& callback) { | 293 const FileOperationCallback& callback) { |
| 213 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 294 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 295 DCHECK(!callback.is_null()); | |
| 214 | 296 |
| 215 // Moving files out from "drive/other" special folder for storing orphan files | 297 // Moving files out from "drive/other" special folder for storing orphan files |
| 216 // has no meaning in the server. Just skip the step. | 298 // has no meaning in the server. Just skip the step. |
| 217 if (util::IsSpecialResourceId(directory_resource_id)) { | 299 if (util::IsSpecialResourceId(directory_resource_id)) { |
| 218 callback.Run(FILE_ERROR_OK); | 300 callback.Run(FILE_ERROR_OK); |
| 219 return; | 301 return; |
| 220 } | 302 } |
| 221 | 303 |
| 222 scheduler_->RemoveResourceFromDirectory( | 304 scheduler_->RemoveResourceFromDirectory( |
| 223 directory_resource_id, | 305 directory_resource_id, |
| 224 resource_id, | 306 resource_id, |
| 225 base::Bind(&MoveOperation::RemoveFromDirectoryCompleted, | 307 base::Bind( |
| 226 weak_ptr_factory_.GetWeakPtr(), | 308 &MoveOperation::RemoveFromDirectoryAfterRemoveResourceFromDirectory, |
| 227 callback)); | 309 weak_ptr_factory_.GetWeakPtr(), callback)); |
| 228 } | 310 } |
| 229 | 311 |
| 230 void MoveOperation::RemoveFromDirectoryCompleted( | 312 void MoveOperation::RemoveFromDirectoryAfterRemoveResourceFromDirectory( |
| 231 const FileOperationCallback& callback, | 313 const FileOperationCallback& callback, |
| 232 google_apis::GDataErrorCode status) { | 314 google_apis::GDataErrorCode status) { |
| 233 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 315 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 316 DCHECK(!callback.is_null()); | |
| 234 callback.Run(GDataToFileError(status)); | 317 callback.Run(GDataToFileError(status)); |
| 235 } | 318 } |
| 236 | 319 |
| 237 } // namespace file_system | 320 } // namespace file_system |
| 238 } // namespace drive | 321 } // namespace drive |
| OLD | NEW |