fake_file_system.cc revision b2df76ea8fec9e32f6f3718986dba0d95315b29c
1// Copyright (c) 2013 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/fake_file_system.h" 6 7#include "base/bind.h" 8#include "base/bind_helpers.h" 9#include "base/callback.h" 10#include "base/file_util.h" 11#include "base/files/file_path.h" 12#include "base/logging.h" 13#include "chrome/browser/chromeos/drive/drive.pb.h" 14#include "chrome/browser/chromeos/drive/file_errors.h" 15#include "chrome/browser/chromeos/drive/file_system_util.h" 16#include "chrome/browser/chromeos/drive/resource_entry_conversion.h" 17#include "chrome/browser/google_apis/drive_api_parser.h" 18#include "chrome/browser/google_apis/gdata_wapi_parser.h" 19#include "content/public/browser/browser_thread.h" 20 21namespace drive { 22namespace test_util { 23 24using content::BrowserThread; 25 26FakeFileSystem::FakeFileSystem( 27 google_apis::DriveServiceInterface* drive_service) 28 : drive_service_(drive_service), 29 weak_ptr_factory_(this) { 30} 31 32FakeFileSystem::~FakeFileSystem() { 33} 34 35bool FakeFileSystem::InitializeForTesting() { 36 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 37 return cache_dir_.CreateUniqueTempDir(); 38} 39 40void FakeFileSystem::Initialize() { 41 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 42 InitializeForTesting(); 43} 44 45void FakeFileSystem::AddObserver(FileSystemObserver* observer) { 46 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 47} 48 49void FakeFileSystem::RemoveObserver(FileSystemObserver* observer) { 50 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 51} 52 53void FakeFileSystem::CheckForUpdates() { 54 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 55} 56 57void FakeFileSystem::GetEntryInfoByResourceId( 58 const std::string& resource_id, 59 const GetEntryInfoWithFilePathCallback& callback) { 60 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 61 62 drive_service_->GetResourceEntry( 63 resource_id, 64 base::Bind( 65 &FakeFileSystem::GetEntryInfoByResourceIdAfterGetResourceEntry, 66 weak_ptr_factory_.GetWeakPtr(), callback)); 67} 68 69void FakeFileSystem::TransferFileFromRemoteToLocal( 70 const base::FilePath& remote_src_file_path, 71 const base::FilePath& local_dest_file_path, 72 const FileOperationCallback& callback) { 73 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 74} 75 76void FakeFileSystem::TransferFileFromLocalToRemote( 77 const base::FilePath& local_src_file_path, 78 const base::FilePath& remote_dest_file_path, 79 const FileOperationCallback& callback) { 80 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 81} 82 83void FakeFileSystem::OpenFile(const base::FilePath& file_path, 84 const OpenFileCallback& callback) { 85 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 86} 87 88void FakeFileSystem::CloseFile(const base::FilePath& file_path, 89 const FileOperationCallback& callback) { 90 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 91} 92 93void FakeFileSystem::Copy(const base::FilePath& src_file_path, 94 const base::FilePath& dest_file_path, 95 const FileOperationCallback& callback) { 96 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 97} 98 99void FakeFileSystem::Move(const base::FilePath& src_file_path, 100 const base::FilePath& dest_file_path, 101 const FileOperationCallback& callback) { 102 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 103} 104 105void FakeFileSystem::Remove(const base::FilePath& file_path, 106 bool is_recursive, 107 const FileOperationCallback& callback) { 108 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 109} 110 111void FakeFileSystem::CreateDirectory( 112 const base::FilePath& directory_path, 113 bool is_exclusive, 114 bool is_recursive, 115 const FileOperationCallback& callback) { 116 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 117} 118 119void FakeFileSystem::CreateFile(const base::FilePath& file_path, 120 bool is_exclusive, 121 const FileOperationCallback& callback) { 122 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 123} 124 125void FakeFileSystem::Pin(const base::FilePath& file_path, 126 const FileOperationCallback& callback) { 127 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 128} 129 130void FakeFileSystem::Unpin(const base::FilePath& file_path, 131 const FileOperationCallback& callback) { 132 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 133} 134 135void FakeFileSystem::GetFileByPath(const base::FilePath& file_path, 136 const GetFileCallback& callback) { 137 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 138} 139 140void FakeFileSystem::GetFileByResourceId( 141 const std::string& resource_id, 142 const DriveClientContext& context, 143 const GetFileCallback& get_file_callback, 144 const google_apis::GetContentCallback& get_content_callback) { 145 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 146} 147 148void FakeFileSystem::GetFileContentByPath( 149 const base::FilePath& file_path, 150 const GetFileContentInitializedCallback& initialized_callback, 151 const google_apis::GetContentCallback& get_content_callback, 152 const FileOperationCallback& completion_callback) { 153 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 154 155 GetEntryInfoByPath( 156 file_path, 157 base::Bind(&FakeFileSystem::GetFileContentByPathAfterGetEntryInfo, 158 weak_ptr_factory_.GetWeakPtr(), 159 file_path, initialized_callback, get_content_callback, 160 completion_callback)); 161} 162 163void FakeFileSystem::UpdateFileByResourceId( 164 const std::string& resource_id, 165 const DriveClientContext& context, 166 const FileOperationCallback& callback) { 167 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 168} 169 170void FakeFileSystem::GetEntryInfoByPath( 171 const base::FilePath& file_path, 172 const GetEntryInfoCallback& callback) { 173 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 174 175 // Now, we only support files under my drive. 176 DCHECK(!util::IsUnderDriveMountPoint(file_path)); 177 178 if (file_path == util::GetDriveMyDriveRootPath()) { 179 // Specialized for the root entry. 180 drive_service_->GetAboutResource( 181 base::Bind( 182 &FakeFileSystem::GetEntryInfoByPathAfterGetAboutResource, 183 weak_ptr_factory_.GetWeakPtr(), callback)); 184 return; 185 } 186 187 GetEntryInfoByPath( 188 file_path.DirName(), 189 base::Bind( 190 &FakeFileSystem::GetEntryInfoByPathAfterGetParentEntryInfo, 191 weak_ptr_factory_.GetWeakPtr(), file_path.BaseName(), callback)); 192} 193 194void FakeFileSystem::ReadDirectoryByPath( 195 const base::FilePath& file_path, 196 const ReadDirectoryWithSettingCallback& callback) { 197 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 198} 199 200void FakeFileSystem::RefreshDirectory( 201 const base::FilePath& file_path, 202 const FileOperationCallback& callback) { 203 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 204} 205 206void FakeFileSystem::Search(const std::string& search_query, 207 const GURL& next_feed, 208 const SearchCallback& callback) { 209 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 210} 211 212void FakeFileSystem::SearchMetadata( 213 const std::string& query, 214 int options, 215 int at_most_num_matches, 216 const SearchMetadataCallback& callback) { 217 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 218} 219 220void FakeFileSystem::GetAvailableSpace( 221 const GetAvailableSpaceCallback& callback) { 222 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 223} 224 225void FakeFileSystem::AddUploadedFile( 226 scoped_ptr<google_apis::ResourceEntry> doc_entry, 227 const base::FilePath& file_content_path, 228 const FileOperationCallback& callback) { 229 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 230} 231 232void FakeFileSystem::GetMetadata( 233 const GetFilesystemMetadataCallback& callback) { 234 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 235} 236 237void FakeFileSystem::MarkCacheFileAsMounted( 238 const base::FilePath& drive_file_path, 239 const OpenFileCallback& callback) { 240 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 241} 242 243void FakeFileSystem::MarkCacheFileAsUnmounted( 244 const base::FilePath& cache_file_path, 245 const FileOperationCallback& callback) { 246 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 247} 248 249void FakeFileSystem::GetCacheEntryByResourceId( 250 const std::string& resource_id, 251 const std::string& md5, 252 const GetCacheEntryCallback& callback) { 253 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 254} 255 256void FakeFileSystem::Reload() { 257} 258 259// Implementation of GetFilePath. 260void FakeFileSystem::GetFilePath(const std::string& resource_id, 261 const GetFilePathCallback& callback) { 262 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 263 264 drive_service_->GetAboutResource( 265 base::Bind( 266 &FakeFileSystem::GetFilePathAfterGetAboutResource, 267 weak_ptr_factory_.GetWeakPtr(), resource_id, callback)); 268} 269 270void FakeFileSystem::GetFilePathAfterGetAboutResource( 271 const std::string& resource_id, 272 const GetFilePathCallback& callback, 273 google_apis::GDataErrorCode error, 274 scoped_ptr<google_apis::AboutResource> about_resource) { 275 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 276 277 // We assume the call always success for test. 278 DCHECK_EQ(util::GDataToFileError(error), FILE_ERROR_OK); 279 DCHECK(about_resource); 280 281 GetFilePathInternal(about_resource->root_folder_id(), resource_id, 282 base::FilePath(), callback); 283} 284 285void FakeFileSystem::GetFilePathInternal( 286 const std::string& root_resource_id, 287 const std::string& resource_id, 288 const base::FilePath& file_path, 289 const GetFilePathCallback& callback) { 290 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 291 292 if (resource_id == root_resource_id) { 293 // Reached to the root. Append the drive root path, and run |callback|. 294 callback.Run(util::GetDriveMyDriveRootPath().Append(file_path)); 295 return; 296 } 297 298 drive_service_->GetResourceEntry( 299 resource_id, 300 base::Bind( 301 &FakeFileSystem::GetFilePathAfterGetResourceEntry, 302 weak_ptr_factory_.GetWeakPtr(), 303 root_resource_id, file_path, callback)); 304} 305 306void FakeFileSystem::GetFilePathAfterGetResourceEntry( 307 const std::string& root_resource_id, 308 const base::FilePath& remaining_file_path, 309 const GetFilePathCallback& callback, 310 google_apis::GDataErrorCode error_in, 311 scoped_ptr<google_apis::ResourceEntry> resource_entry) { 312 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 313 314 // We assume the call always success for test. 315 DCHECK_EQ(util::GDataToFileError(error_in), FILE_ERROR_OK); 316 DCHECK(resource_entry); 317 318 ResourceEntry entry = ConvertToResourceEntry(*resource_entry); 319 base::FilePath file_path = 320 base::FilePath::FromUTF8Unsafe(entry.base_name()).Append( 321 remaining_file_path); 322 323 GetFilePathInternal(root_resource_id, entry.parent_resource_id(), 324 file_path, callback); 325} 326 327// Implementation of GetEntryInfoByResourceId. 328void FakeFileSystem::GetEntryInfoByResourceIdAfterGetResourceEntry( 329 const GetEntryInfoWithFilePathCallback& callback, 330 google_apis::GDataErrorCode error_in, 331 scoped_ptr<google_apis::ResourceEntry> resource_entry) { 332 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 333 334 FileError error = util::GDataToFileError(error_in); 335 if (error != FILE_ERROR_OK) { 336 callback.Run(error, base::FilePath(), scoped_ptr<ResourceEntry>()); 337 return; 338 } 339 340 DCHECK(resource_entry); 341 scoped_ptr<ResourceEntry> entry(new ResourceEntry( 342 ConvertToResourceEntry(*resource_entry))); 343 344 const std::string parent_resource_id = entry->parent_resource_id(); 345 GetFilePath( 346 parent_resource_id, 347 base::Bind( 348 &FakeFileSystem::GetEntryInfoByResourceIdAfterGetFilePath, 349 weak_ptr_factory_.GetWeakPtr(), 350 callback, error, base::Passed(&entry))); 351} 352 353void FakeFileSystem::GetEntryInfoByResourceIdAfterGetFilePath( 354 const GetEntryInfoWithFilePathCallback& callback, 355 FileError error, 356 scoped_ptr<ResourceEntry> entry, 357 const base::FilePath& parent_file_path) { 358 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 359 base::FilePath file_path = parent_file_path.Append( 360 base::FilePath::FromUTF8Unsafe(entry->base_name())); 361 callback.Run(error, file_path, entry.Pass()); 362} 363 364// Implementation of GetFileContentByPath. 365void FakeFileSystem::GetFileContentByPathAfterGetEntryInfo( 366 const base::FilePath& file_path, 367 const GetFileContentInitializedCallback& initialized_callback, 368 const google_apis::GetContentCallback& get_content_callback, 369 const FileOperationCallback& completion_callback, 370 FileError error, 371 scoped_ptr<ResourceEntry> entry) { 372 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 373 374 if (error != FILE_ERROR_OK) { 375 completion_callback.Run(error); 376 return; 377 } 378 DCHECK(entry); 379 380 // We're only interested in a file. 381 if (entry->file_info().is_directory()) { 382 completion_callback.Run(FILE_ERROR_NOT_A_FILE); 383 return; 384 } 385 386 // Fetch the ResourceEntry for its |download_url|. 387 drive_service_->GetResourceEntry( 388 entry->resource_id(), 389 base::Bind(&FakeFileSystem::GetFileContentByPathAfterGetResourceEntry, 390 weak_ptr_factory_.GetWeakPtr(), 391 file_path, 392 initialized_callback, 393 get_content_callback, 394 completion_callback)); 395} 396 397void FakeFileSystem::GetFileContentByPathAfterGetResourceEntry( 398 const base::FilePath& file_path, 399 const GetFileContentInitializedCallback& initialized_callback, 400 const google_apis::GetContentCallback& get_content_callback, 401 const FileOperationCallback& completion_callback, 402 google_apis::GDataErrorCode gdata_error, 403 scoped_ptr<google_apis::ResourceEntry> gdata_entry) { 404 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 405 406 FileError error = util::GDataToFileError(gdata_error); 407 if (error != FILE_ERROR_OK) { 408 completion_callback.Run(error); 409 return; 410 } 411 DCHECK(gdata_entry); 412 413 scoped_ptr<ResourceEntry> entry( 414 new ResourceEntry(ConvertToResourceEntry(*gdata_entry))); 415 416 base::FilePath cache_path = 417 cache_dir_.path().AppendASCII(entry->resource_id()); 418 if (file_util::PathExists(cache_path)) { 419 // Cache file is found. 420 initialized_callback.Run(FILE_ERROR_OK, entry.Pass(), cache_path, 421 base::Closure()); 422 completion_callback.Run(FILE_ERROR_OK); 423 return; 424 } 425 426 initialized_callback.Run(FILE_ERROR_OK, entry.Pass(), base::FilePath(), 427 base::Bind(&base::DoNothing)); 428 drive_service_->DownloadFile( 429 file_path, 430 cache_path, 431 GURL(gdata_entry->download_url()), 432 base::Bind(&FakeFileSystem::GetFileContentByPathAfterDownloadFile, 433 weak_ptr_factory_.GetWeakPtr(), 434 completion_callback), 435 get_content_callback, 436 google_apis::ProgressCallback()); 437} 438 439void FakeFileSystem::GetFileContentByPathAfterDownloadFile( 440 const FileOperationCallback& completion_callback, 441 google_apis::GDataErrorCode gdata_error, 442 const base::FilePath& temp_file) { 443 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 444 completion_callback.Run(util::GDataToFileError(gdata_error)); 445} 446 447// Implementation of GetEntryInfoByPath. 448void FakeFileSystem::GetEntryInfoByPathAfterGetAboutResource( 449 const GetEntryInfoCallback& callback, 450 google_apis::GDataErrorCode gdata_error, 451 scoped_ptr<google_apis::AboutResource> about_resource) { 452 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 453 454 FileError error = util::GDataToFileError(gdata_error); 455 if (error != FILE_ERROR_OK) { 456 callback.Run(error, scoped_ptr<ResourceEntry>()); 457 return; 458 } 459 460 DCHECK(about_resource); 461 scoped_ptr<ResourceEntry> root(new ResourceEntry); 462 root->mutable_file_info()->set_is_directory(true); 463 root->set_resource_id(about_resource->root_folder_id()); 464 root->set_title(util::kDriveMyDriveRootDirName); 465 callback.Run(error, root.Pass()); 466} 467 468void FakeFileSystem::GetEntryInfoByPathAfterGetParentEntryInfo( 469 const base::FilePath& base_name, 470 const GetEntryInfoCallback& callback, 471 FileError error, 472 scoped_ptr<ResourceEntry> parent_entry) { 473 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 474 475 if (error != FILE_ERROR_OK) { 476 callback.Run(error, scoped_ptr<ResourceEntry>()); 477 return; 478 } 479 480 DCHECK(parent_entry); 481 drive_service_->GetResourceListInDirectory( 482 parent_entry->resource_id(), 483 base::Bind( 484 &FakeFileSystem::GetEntryInfoByPathAfterGetResourceList, 485 weak_ptr_factory_.GetWeakPtr(), base_name, callback)); 486} 487 488void FakeFileSystem::GetEntryInfoByPathAfterGetResourceList( 489 const base::FilePath& base_name, 490 const GetEntryInfoCallback& callback, 491 google_apis::GDataErrorCode gdata_error, 492 scoped_ptr<google_apis::ResourceList> resource_list) { 493 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 494 495 FileError error = util::GDataToFileError(gdata_error); 496 if (error != FILE_ERROR_OK) { 497 callback.Run(error, scoped_ptr<ResourceEntry>()); 498 return; 499 } 500 501 DCHECK(resource_list); 502 const ScopedVector<google_apis::ResourceEntry>& entries = 503 resource_list->entries(); 504 for (size_t i = 0; i < entries.size(); ++i) { 505 scoped_ptr<ResourceEntry> entry(new ResourceEntry( 506 ConvertToResourceEntry(*entries[i]))); 507 if (entry->base_name() == base_name.AsUTF8Unsafe()) { 508 // Found the target entry. 509 callback.Run(FILE_ERROR_OK, entry.Pass()); 510 return; 511 } 512 } 513 514 callback.Run(FILE_ERROR_NOT_FOUND, scoped_ptr<ResourceEntry>()); 515} 516 517} // namespace test_util 518} // namespace drive 519