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/gdata/gdata_file_system.h" | 5 #include "chrome/browser/chromeos/gdata/gdata_file_system.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
383 // create GetEntryInfoCallback. | 383 // create GetEntryInfoCallback. |
384 void RunGetEntryInfoWithFilePathCallback( | 384 void RunGetEntryInfoWithFilePathCallback( |
385 const GetEntryInfoWithFilePathCallback& callback, | 385 const GetEntryInfoWithFilePathCallback& callback, |
386 const FilePath& path, | 386 const FilePath& path, |
387 GDataFileError error, | 387 GDataFileError error, |
388 scoped_ptr<GDataEntryProto> entry_proto) { | 388 scoped_ptr<GDataEntryProto> entry_proto) { |
389 if (!callback.is_null()) | 389 if (!callback.is_null()) |
390 callback.Run(error, path, entry_proto.Pass()); | 390 callback.Run(error, path, entry_proto.Pass()); |
391 } | 391 } |
392 | 392 |
393 // Callback for AddEntryToDirectoryFilePathCallbackRunner. | |
394 typedef base::Callback<void(const FilePath&)> | |
395 AddEntryToDirectoryCallback; | |
satorux1
2012/08/10 16:14:44
nit: add a blank line here.
achuithb
2012/08/11 00:37:45
This is gone.
| |
396 // This callback for GDataDirectoryService::AddEntryToDirectory passes | |
397 // the entry's file path to its callback. | |
398 void AddEntryToDirectoryFilePathCallbackRunner(GDataEntry* entry, | |
399 const AddEntryToDirectoryCallback& callback) { | |
400 DCHECK(!callback.is_null()); | |
401 callback.Run(entry->GetFilePath()); | |
402 } | |
403 | |
393 } // namespace | 404 } // namespace |
394 | 405 |
395 // GDataFileSystem::CreateDirectoryParams struct implementation. | 406 // GDataFileSystem::CreateDirectoryParams struct implementation. |
396 struct GDataFileSystem::CreateDirectoryParams { | 407 struct GDataFileSystem::CreateDirectoryParams { |
397 CreateDirectoryParams(const FilePath& created_directory_path, | 408 CreateDirectoryParams(const FilePath& created_directory_path, |
398 const FilePath& target_directory_path, | 409 const FilePath& target_directory_path, |
399 bool is_exclusive, | 410 bool is_exclusive, |
400 bool is_recursive, | 411 bool is_recursive, |
401 const FileOperationCallback& callback); | 412 const FileOperationCallback& callback); |
402 ~CreateDirectoryParams(); | 413 ~CreateDirectoryParams(); |
(...skipping 1577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1980 *params->feed_list, | 1991 *params->feed_list, |
1981 &file_map, | 1992 &file_map, |
1982 &unused_delta_feed_changestamp, | 1993 &unused_delta_feed_changestamp, |
1983 &unused_uma_stats); | 1994 &unused_uma_stats); |
1984 if (error != GDATA_FILE_OK) { | 1995 if (error != GDATA_FILE_OK) { |
1985 LOG(ERROR) << "Failed to convert feed: " << directory_path.value() | 1996 LOG(ERROR) << "Failed to convert feed: " << directory_path.value() |
1986 << ": " << error; | 1997 << ": " << error; |
1987 return; | 1998 return; |
1988 } | 1999 } |
1989 | 2000 |
1990 directory_service_->GetEntryByResourceIdAsync(params->directory_resource_id, | 2001 directory_service_->RefreshDirectory( |
1991 base::Bind(&GDataFileSystem::RequestDirectoryRefreshByEntry, | 2002 params->directory_resource_id, |
2003 file_map, | |
2004 base::Bind(&GDataFileSystem::OnDirectoryChanged, | |
1992 ui_weak_ptr_, | 2005 ui_weak_ptr_, |
1993 directory_path, | 2006 directory_path)); |
1994 params->directory_resource_id, | |
1995 file_map)); | |
1996 } | |
1997 | |
1998 void GDataFileSystem::RequestDirectoryRefreshByEntry( | |
1999 const FilePath& directory_path, | |
2000 const std::string& directory_resource_id, | |
2001 const FileResourceIdMap& file_map, | |
2002 GDataEntry* directory_entry) { | |
2003 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
2004 | |
2005 if (!directory_entry || !directory_entry->AsGDataDirectory()) { | |
2006 LOG(ERROR) << "Directory entry is gone: " << directory_path.value() | |
2007 << ": " << directory_resource_id; | |
2008 return; | |
2009 } | |
2010 GDataDirectory* directory = directory_entry->AsGDataDirectory(); | |
2011 | |
2012 // Remove the existing files. | |
2013 directory->RemoveChildFiles(); | |
2014 // Go through all entries generated by the feed and add files. | |
2015 for (FileResourceIdMap::const_iterator it = file_map.begin(); | |
2016 it != file_map.end(); ++it) { | |
2017 scoped_ptr<GDataEntry> entry(it->second); | |
2018 // Skip if it's not a file (i.e. directory). | |
2019 if (!entry->AsGDataFile()) | |
2020 continue; | |
2021 directory->AddEntry(entry.release()); | |
2022 } | |
2023 | |
2024 // Note that there may be no change in the directory, but it's expensive to | |
2025 // check if the new metadata matches the existing one, so we just always | |
2026 // notify that the directory is changed. | |
2027 OnDirectoryChanged(directory_path); | |
2028 DVLOG(1) << "Directory refreshed: " << directory_path.value(); | |
2029 } | 2007 } |
2030 | 2008 |
2031 void GDataFileSystem::UpdateFileByResourceId( | 2009 void GDataFileSystem::UpdateFileByResourceId( |
2032 const std::string& resource_id, | 2010 const std::string& resource_id, |
2033 const FileOperationCallback& callback) { | 2011 const FileOperationCallback& callback) { |
2034 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || | 2012 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || |
2035 BrowserThread::CurrentlyOn(BrowserThread::IO)); | 2013 BrowserThread::CurrentlyOn(BrowserThread::IO)); |
2036 RunTaskOnUIThread( | 2014 RunTaskOnUIThread( |
2037 base::Bind(&GDataFileSystem::UpdateFileByResourceIdOnUIThread, | 2015 base::Bind(&GDataFileSystem::UpdateFileByResourceIdOnUIThread, |
2038 ui_weak_ptr_, | 2016 ui_weak_ptr_, |
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2470 callback.Run(error); | 2448 callback.Run(error); |
2471 return; | 2449 return; |
2472 } | 2450 } |
2473 | 2451 |
2474 scoped_ptr<DocumentEntry> doc_entry(DocumentEntry::ExtractAndParse(*data)); | 2452 scoped_ptr<DocumentEntry> doc_entry(DocumentEntry::ExtractAndParse(*data)); |
2475 if (!doc_entry.get()) { | 2453 if (!doc_entry.get()) { |
2476 callback.Run(GDATA_FILE_ERROR_FAILED); | 2454 callback.Run(GDATA_FILE_ERROR_FAILED); |
2477 return; | 2455 return; |
2478 } | 2456 } |
2479 | 2457 |
2480 GDataEntry* entry = directory_service_->FromDocumentEntry(doc_entry.get()); | 2458 GDataEntry* entry = directory_service_->FromDocumentEntry(doc_entry.get()); |
satorux1
2012/08/10 23:05:55
we might want to create a proto instead. See my ne
achuithb
2012/08/11 00:37:45
Let's do this in a separate patch.
| |
2481 if (!entry) { | 2459 if (!entry) { |
2482 callback.Run(GDATA_FILE_ERROR_FAILED); | 2460 callback.Run(GDATA_FILE_ERROR_FAILED); |
2483 return; | 2461 return; |
2484 } | 2462 } |
2485 | 2463 |
2486 // |entry| was added in the root directory on the server, so we should | 2464 // |entry| was added in the root directory on the server, so we should |
2487 // first add it to |root_| to mirror the state and then move it to the | 2465 // first add it to |root_| to mirror the state and then move it to the |
2488 // destination directory by MoveEntryFromRootDirectory(). | 2466 // destination directory by MoveEntryFromRootDirectory(). |
2489 directory_service_->root()->AddEntry(entry); | 2467 directory_service_->AddEntryToDirectory( |
2490 MoveEntryFromRootDirectory(dir_path, | 2468 directory_service_->root(), |
2491 callback, | 2469 entry, |
satorux1
2012/08/10 23:05:55
would it be possible for this function to take GDa
satorux1
2012/08/11 00:12:21
Filed a bug crbug.com/142048
achuithb
2012/08/11 00:37:45
I'll file a bug and add a TODO.
| |
2492 GDATA_FILE_OK, | 2470 base::Bind(&AddEntryToDirectoryFilePathCallbackRunner, |
2493 entry->GetFilePath()); | 2471 entry, |
2472 base::Bind(&GDataFileSystem::MoveEntryFromRootDirectory, | |
2473 ui_weak_ptr_, | |
2474 dir_path, | |
2475 callback, | |
2476 GDATA_FILE_OK))); | |
2494 } | 2477 } |
2495 | 2478 |
2496 void GDataFileSystem::OnMoveEntryFromRootDirectoryCompleted( | 2479 void GDataFileSystem::OnMoveEntryFromRootDirectoryCompleted( |
2497 const FileOperationCallback& callback, | 2480 const FileOperationCallback& callback, |
2498 const FilePath& file_path, | 2481 const FilePath& file_path, |
2499 const FilePath& dir_path, | 2482 const FilePath& dir_path, |
2500 GDataErrorCode status, | 2483 GDataErrorCode status, |
2501 const GURL& document_url) { | 2484 const GURL& document_url) { |
2502 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 2485 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
2503 DCHECK(!callback.is_null()); | 2486 DCHECK(!callback.is_null()); |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2745 if (error != GDATA_FILE_OK) | 2728 if (error != GDATA_FILE_OK) |
2746 return error; | 2729 return error; |
2747 | 2730 |
2748 // If resource_id is not empty, remove its corresponding file from cache. | 2731 // If resource_id is not empty, remove its corresponding file from cache. |
2749 if (!resource_id.empty()) | 2732 if (!resource_id.empty()) |
2750 cache_->RemoveOnUIThread(resource_id, CacheOperationCallback()); | 2733 cache_->RemoveOnUIThread(resource_id, CacheOperationCallback()); |
2751 | 2734 |
2752 return GDATA_FILE_OK; | 2735 return GDATA_FILE_OK; |
2753 } | 2736 } |
2754 | 2737 |
2755 // static | |
2756 void GDataFileSystem::RemoveStaleEntryOnUpload(const std::string& resource_id, | 2738 void GDataFileSystem::RemoveStaleEntryOnUpload(const std::string& resource_id, |
2757 GDataDirectory* parent_dir, | 2739 GDataDirectory* parent_dir, |
2758 GDataEntry* existing_entry) { | 2740 GDataEntry* existing_entry) { |
2759 if (existing_entry && | 2741 if (existing_entry && |
2760 // This should always match, but just in case. | 2742 // This should always match, but just in case. |
2761 existing_entry->parent() == parent_dir) { | 2743 existing_entry->parent() == parent_dir) { |
2762 parent_dir->RemoveEntry(existing_entry); | 2744 directory_service_->RemoveEntryFromParent(existing_entry, base::Closure()); |
2763 } else { | 2745 } else { |
2764 LOG(ERROR) << "Entry for the existing file not found: " << resource_id; | 2746 LOG(ERROR) << "Entry for the existing file not found: " << resource_id; |
2765 } | 2747 } |
2766 } | 2748 } |
2767 | 2749 |
2768 void GDataFileSystem::NotifyFileSystemMounted() { | 2750 void GDataFileSystem::NotifyFileSystemMounted() { |
2769 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 2751 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
2770 | 2752 |
2771 DVLOG(1) << "File System is mounted"; | 2753 DVLOG(1) << "File System is mounted"; |
2772 // Notify the observers that the file system is mounted. | 2754 // Notify the observers that the file system is mounted. |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2821 // file with the exact same name. | 2803 // file with the exact same name. |
2822 GDataDirectory* parent_dir = entry->AsGDataDirectory(); | 2804 GDataDirectory* parent_dir = entry->AsGDataDirectory(); |
2823 if (!parent_dir) | 2805 if (!parent_dir) |
2824 return GDATA_FILE_ERROR_FAILED; | 2806 return GDATA_FILE_ERROR_FAILED; |
2825 | 2807 |
2826 GDataEntry* new_entry = | 2808 GDataEntry* new_entry = |
2827 directory_service_->FromDocumentEntry(doc_entry.get()); | 2809 directory_service_->FromDocumentEntry(doc_entry.get()); |
2828 if (!new_entry) | 2810 if (!new_entry) |
2829 return GDATA_FILE_ERROR_FAILED; | 2811 return GDATA_FILE_ERROR_FAILED; |
2830 | 2812 |
2831 parent_dir->AddEntry(new_entry); | 2813 directory_service_->AddEntryToDirectory( |
2832 | 2814 parent_dir, |
2833 OnDirectoryChanged(directory_path); | 2815 new_entry, |
2816 base::Bind(&GDataFileSystem::OnDirectoryChanged, | |
2817 ui_weak_ptr_, | |
2818 directory_path)); | |
2834 return GDATA_FILE_OK; | 2819 return GDATA_FILE_OK; |
2835 } | 2820 } |
2836 | 2821 |
2837 GDataFileSystem::FindMissingDirectoryResult | 2822 GDataFileSystem::FindMissingDirectoryResult |
2838 GDataFileSystem::FindFirstMissingParentDirectory( | 2823 GDataFileSystem::FindFirstMissingParentDirectory( |
2839 const FilePath& directory_path, | 2824 const FilePath& directory_path, |
2840 GURL* last_dir_content_url, | 2825 GURL* last_dir_content_url, |
2841 FilePath* first_missing_parent_path) { | 2826 FilePath* first_missing_parent_path) { |
2842 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 2827 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
2843 | 2828 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2882 // You can't remove root element. | 2867 // You can't remove root element. |
2883 if (!entry->parent()) | 2868 if (!entry->parent()) |
2884 return GDATA_FILE_ERROR_ACCESS_DENIED; | 2869 return GDATA_FILE_ERROR_ACCESS_DENIED; |
2885 | 2870 |
2886 // If it's a file (only files have resource id), get its resource id so that | 2871 // If it's a file (only files have resource id), get its resource id so that |
2887 // we can remove it after releasing the auto lock. | 2872 // we can remove it after releasing the auto lock. |
2888 if (entry->AsGDataFile()) | 2873 if (entry->AsGDataFile()) |
2889 *resource_id = entry->AsGDataFile()->resource_id(); | 2874 *resource_id = entry->AsGDataFile()->resource_id(); |
2890 | 2875 |
2891 GDataDirectory* parent_dir = entry->parent(); | 2876 GDataDirectory* parent_dir = entry->parent(); |
2892 parent_dir->RemoveEntry(entry); | 2877 directory_service_->RemoveEntryFromParent( |
2893 | 2878 entry, |
2894 OnDirectoryChanged(parent_dir->GetFilePath()); | 2879 base::Bind(&GDataFileSystem::OnDirectoryChanged, |
2880 ui_weak_ptr_, | |
2881 parent_dir->GetFilePath())); | |
2895 return GDATA_FILE_OK; | 2882 return GDATA_FILE_OK; |
2896 } | 2883 } |
2897 | 2884 |
2898 void GDataFileSystem::AddUploadedFile( | 2885 void GDataFileSystem::AddUploadedFile( |
2899 UploadMode upload_mode, | 2886 UploadMode upload_mode, |
2900 const FilePath& virtual_dir_path, | 2887 const FilePath& virtual_dir_path, |
2901 scoped_ptr<DocumentEntry> entry, | 2888 scoped_ptr<DocumentEntry> entry, |
2902 const FilePath& file_content_path, | 2889 const FilePath& file_content_path, |
2903 GDataCache::FileOperationType cache_operation, | 2890 GDataCache::FileOperationType cache_operation, |
2904 const base::Closure& callback) { | 2891 const base::Closure& callback) { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2946 return; | 2933 return; |
2947 | 2934 |
2948 scoped_ptr<GDataEntry> new_entry( | 2935 scoped_ptr<GDataEntry> new_entry( |
2949 directory_service_->FromDocumentEntry(entry.get())); | 2936 directory_service_->FromDocumentEntry(entry.get())); |
2950 if (!new_entry.get()) | 2937 if (!new_entry.get()) |
2951 return; | 2938 return; |
2952 | 2939 |
2953 if (upload_mode == UPLOAD_EXISTING_FILE) { | 2940 if (upload_mode == UPLOAD_EXISTING_FILE) { |
2954 // Remove an existing entry, which should be present. | 2941 // Remove an existing entry, which should be present. |
2955 const std::string& resource_id = new_entry->resource_id(); | 2942 const std::string& resource_id = new_entry->resource_id(); |
2956 directory_service_->GetEntryByResourceIdAsync(resource_id, | 2943 directory_service_->GetEntryByResourceIdAsync( |
2957 base::Bind(&RemoveStaleEntryOnUpload, resource_id, parent_dir)); | 2944 resource_id, |
2945 base::Bind(&GDataFileSystem::RemoveStaleEntryOnUpload, | |
2946 ui_weak_ptr_, | |
2947 resource_id, | |
2948 parent_dir)); | |
2958 } | 2949 } |
2959 | 2950 |
2960 GDataFile* file = new_entry->AsGDataFile(); | 2951 GDataFile* file = new_entry->AsGDataFile(); |
2961 DCHECK(file); | 2952 DCHECK(file); |
2962 const std::string& resource_id = file->resource_id(); | 2953 const std::string& resource_id = file->resource_id(); |
2963 const std::string& md5 = file->file_md5(); | 2954 const std::string& md5 = file->file_md5(); |
2964 parent_dir->AddEntry(new_entry.release()); | 2955 directory_service_->AddEntryToDirectory( |
2965 | 2956 parent_dir, |
2966 OnDirectoryChanged(virtual_dir_path); | 2957 new_entry.release(), |
2958 base::Bind(&GDataFileSystem::OnDirectoryChanged, | |
2959 ui_weak_ptr_, | |
2960 virtual_dir_path)); | |
2967 | 2961 |
2968 if (upload_mode == UPLOAD_NEW_FILE) { | 2962 if (upload_mode == UPLOAD_NEW_FILE) { |
2969 // Add the file to the cache if we have uploaded a new file. | 2963 // Add the file to the cache if we have uploaded a new file. |
2970 cache_->StoreOnUIThread(resource_id, | 2964 cache_->StoreOnUIThread(resource_id, |
2971 md5, | 2965 md5, |
2972 file_content_path, | 2966 file_content_path, |
2973 cache_operation, | 2967 cache_operation, |
2974 base::Bind(&OnCacheUpdatedForAddUploadedFile, | 2968 base::Bind(&OnCacheUpdatedForAddUploadedFile, |
2975 callback_runner.Release())); | 2969 callback_runner.Release())); |
2976 } else if (upload_mode == UPLOAD_EXISTING_FILE) { | 2970 } else if (upload_mode == UPLOAD_EXISTING_FILE) { |
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3444 } | 3438 } |
3445 | 3439 |
3446 PlatformFileInfoProto entry_file_info; | 3440 PlatformFileInfoProto entry_file_info; |
3447 GDataEntry::ConvertPlatformFileInfoToProto(*file_info, &entry_file_info); | 3441 GDataEntry::ConvertPlatformFileInfoToProto(*file_info, &entry_file_info); |
3448 *entry_proto->mutable_file_info() = entry_file_info; | 3442 *entry_proto->mutable_file_info() = entry_file_info; |
3449 if (!callback.is_null()) | 3443 if (!callback.is_null()) |
3450 callback.Run(GDATA_FILE_OK, entry_proto.Pass()); | 3444 callback.Run(GDATA_FILE_OK, entry_proto.Pass()); |
3451 } | 3445 } |
3452 | 3446 |
3453 } // namespace gdata | 3447 } // namespace gdata |
OLD | NEW |