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 1192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1203 | 1203 |
1204 // Otherwise, the move operation involves three steps: | 1204 // Otherwise, the move operation involves three steps: |
1205 // 1. Renames the file at |src_file_path| to basename(|dest_file_path|) | 1205 // 1. Renames the file at |src_file_path| to basename(|dest_file_path|) |
1206 // within the same directory. The rename operation is a no-op if | 1206 // within the same directory. The rename operation is a no-op if |
1207 // basename(|src_file_path|) equals to basename(|dest_file_path|). | 1207 // basename(|src_file_path|) equals to basename(|dest_file_path|). |
1208 // 2. Removes the file from its parent directory (the file is not deleted), | 1208 // 2. Removes the file from its parent directory (the file is not deleted), |
1209 // which effectively moves the file to the root directory. | 1209 // which effectively moves the file to the root directory. |
1210 // 3. Adds the file to the parent directory of |dest_file_path|, which | 1210 // 3. Adds the file to the parent directory of |dest_file_path|, which |
1211 // effectively moves the file from the root directory to the parent | 1211 // effectively moves the file from the root directory to the parent |
1212 // directory of |dest_file_path|. | 1212 // directory of |dest_file_path|. |
1213 FileMoveCallback add_file_to_directory_callback = | 1213 const FileMoveCallback add_file_to_directory_callback = |
1214 base::Bind(&GDataFileSystem::MoveEntryFromRootDirectory, | 1214 base::Bind(&GDataFileSystem::MoveEntryFromRootDirectory, |
1215 ui_weak_ptr_, | 1215 ui_weak_ptr_, |
1216 dest_file_path.DirName(), | 1216 dest_file_path.DirName(), |
1217 callback); | 1217 callback); |
1218 | 1218 |
1219 FileMoveCallback remove_file_from_directory_callback = | 1219 const FileMoveCallback remove_file_from_directory_callback = |
1220 base::Bind(&GDataFileSystem::RemoveEntryFromDirectory, | 1220 base::Bind(&GDataFileSystem::RemoveEntryFromDirectory, |
1221 ui_weak_ptr_, | 1221 ui_weak_ptr_, |
1222 src_file_path.DirName(), | 1222 src_file_path.DirName(), |
1223 add_file_to_directory_callback); | 1223 add_file_to_directory_callback); |
1224 | 1224 |
1225 Rename(src_file_path, dest_file_path.BaseName().value(), | 1225 Rename(src_file_path, dest_file_path.BaseName().value(), |
1226 remove_file_from_directory_callback); | 1226 remove_file_from_directory_callback); |
1227 } | 1227 } |
1228 | 1228 |
1229 void GDataFileSystem::MoveEntryFromRootDirectory( | 1229 void GDataFileSystem::MoveEntryFromRootDirectory( |
(...skipping 750 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1980 *params->feed_list, | 1980 *params->feed_list, |
1981 &file_map, | 1981 &file_map, |
1982 &unused_delta_feed_changestamp, | 1982 &unused_delta_feed_changestamp, |
1983 &unused_uma_stats); | 1983 &unused_uma_stats); |
1984 if (error != GDATA_FILE_OK) { | 1984 if (error != GDATA_FILE_OK) { |
1985 LOG(ERROR) << "Failed to convert feed: " << directory_path.value() | 1985 LOG(ERROR) << "Failed to convert feed: " << directory_path.value() |
1986 << ": " << error; | 1986 << ": " << error; |
1987 return; | 1987 return; |
1988 } | 1988 } |
1989 | 1989 |
1990 directory_service_->GetEntryByResourceIdAsync(params->directory_resource_id, | 1990 directory_service_->RefreshDirectory( |
1991 base::Bind(&GDataFileSystem::RequestDirectoryRefreshByEntry, | 1991 params->directory_resource_id, |
1992 ui_weak_ptr_, | 1992 file_map, |
1993 directory_path, | 1993 base::Bind(&GDataFileSystem::OnDirectoryChangeFileMoveCallback, |
1994 params->directory_resource_id, | 1994 ui_weak_ptr_)); |
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 } | 1995 } |
2030 | 1996 |
2031 void GDataFileSystem::UpdateFileByResourceId( | 1997 void GDataFileSystem::UpdateFileByResourceId( |
2032 const std::string& resource_id, | 1998 const std::string& resource_id, |
2033 const FileOperationCallback& callback) { | 1999 const FileOperationCallback& callback) { |
2034 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || | 2000 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || |
2035 BrowserThread::CurrentlyOn(BrowserThread::IO)); | 2001 BrowserThread::CurrentlyOn(BrowserThread::IO)); |
2036 RunTaskOnUIThread( | 2002 RunTaskOnUIThread( |
2037 base::Bind(&GDataFileSystem::UpdateFileByResourceIdOnUIThread, | 2003 base::Bind(&GDataFileSystem::UpdateFileByResourceIdOnUIThread, |
2038 ui_weak_ptr_, | 2004 ui_weak_ptr_, |
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2479 | 2445 |
2480 GDataEntry* entry = directory_service_->FromDocumentEntry(doc_entry.get()); | 2446 GDataEntry* entry = directory_service_->FromDocumentEntry(doc_entry.get()); |
2481 if (!entry) { | 2447 if (!entry) { |
2482 callback.Run(GDATA_FILE_ERROR_FAILED); | 2448 callback.Run(GDATA_FILE_ERROR_FAILED); |
2483 return; | 2449 return; |
2484 } | 2450 } |
2485 | 2451 |
2486 // |entry| was added in the root directory on the server, so we should | 2452 // |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 | 2453 // first add it to |root_| to mirror the state and then move it to the |
2488 // destination directory by MoveEntryFromRootDirectory(). | 2454 // destination directory by MoveEntryFromRootDirectory(). |
2489 directory_service_->root()->AddEntry(entry); | 2455 directory_service_->AddEntryToDirectory( |
2490 MoveEntryFromRootDirectory(dir_path, | 2456 directory_service_->root(), |
2491 callback, | 2457 entry, |
2492 GDATA_FILE_OK, | 2458 base::Bind(&GDataFileSystem::MoveEntryFromRootDirectory, |
2493 entry->GetFilePath()); | 2459 ui_weak_ptr_, |
2460 dir_path, | |
2461 callback)); | |
2494 } | 2462 } |
2495 | 2463 |
2496 void GDataFileSystem::OnMoveEntryFromRootDirectoryCompleted( | 2464 void GDataFileSystem::OnMoveEntryFromRootDirectoryCompleted( |
2497 const FileOperationCallback& callback, | 2465 const FileOperationCallback& callback, |
2498 const FilePath& file_path, | 2466 const FilePath& file_path, |
2499 const FilePath& dir_path, | 2467 const FilePath& dir_path, |
2500 GDataErrorCode status, | 2468 GDataErrorCode status, |
2501 const GURL& document_url) { | 2469 const GURL& document_url) { |
2502 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 2470 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
2503 DCHECK(!callback.is_null()); | 2471 DCHECK(!callback.is_null()); |
2504 | 2472 |
2505 GDataFileError error = util::GDataToGDataFileError(status); | 2473 GDataFileError error = util::GDataToGDataFileError(status); |
2506 if (error == GDATA_FILE_OK) { | 2474 if (error == GDATA_FILE_OK) { |
2507 GDataEntry* entry = directory_service_->FindEntryByPathSync(file_path); | 2475 GDataEntry* entry = directory_service_->FindEntryByPathSync(file_path); |
2508 if (entry) { | 2476 if (entry) { |
2509 DCHECK_EQ(directory_service_->root(), entry->parent()); | 2477 DCHECK_EQ(directory_service_->root(), entry->parent()); |
2510 directory_service_->MoveEntryToDirectory(dir_path, entry, | 2478 directory_service_->MoveEntryToDirectory( |
2479 dir_path, | |
2480 entry, | |
2511 base::Bind( | 2481 base::Bind( |
2512 &GDataFileSystem::OnMoveEntryToDirectoryWithFileOperationCallback, | 2482 &GDataFileSystem::OnMoveEntryToDirectoryWithFileOperationCallback, |
2513 ui_weak_ptr_, | 2483 ui_weak_ptr_, |
2514 callback)); | 2484 callback)); |
2515 return; | 2485 return; |
2516 } else { | 2486 } else { |
2517 error = GDATA_FILE_ERROR_NOT_FOUND; | 2487 error = GDATA_FILE_ERROR_NOT_FOUND; |
2518 } | 2488 } |
2519 } | 2489 } |
2520 | 2490 |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2729 GDataFileError error, | 2699 GDataFileError error, |
2730 const FilePath& moved_file_path) { | 2700 const FilePath& moved_file_path) { |
2731 DCHECK(!callback.is_null()); | 2701 DCHECK(!callback.is_null()); |
2732 | 2702 |
2733 if (error == GDATA_FILE_OK) | 2703 if (error == GDATA_FILE_OK) |
2734 OnDirectoryChanged(moved_file_path.DirName()); | 2704 OnDirectoryChanged(moved_file_path.DirName()); |
2735 | 2705 |
2736 callback.Run(error); | 2706 callback.Run(error); |
2737 } | 2707 } |
2738 | 2708 |
2709 void GDataFileSystem::OnDirectoryChangeFileMoveCallback( | |
2710 GDataFileError error, | |
2711 const FilePath& directory_path) { | |
2712 if (error == GDATA_FILE_OK) | |
2713 OnDirectoryChanged(directory_path); | |
2714 } | |
2715 | |
2739 GDataFileError GDataFileSystem::RemoveEntryFromFileSystem( | 2716 GDataFileError GDataFileSystem::RemoveEntryFromFileSystem( |
2740 const FilePath& file_path) { | 2717 const FilePath& file_path) { |
2741 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 2718 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
2742 | 2719 |
2743 std::string resource_id; | 2720 std::string resource_id; |
2744 GDataFileError error = RemoveEntryFromGData(file_path, &resource_id); | 2721 GDataFileError error = RemoveEntryFromGData(file_path, &resource_id); |
2745 if (error != GDATA_FILE_OK) | 2722 if (error != GDATA_FILE_OK) |
2746 return error; | 2723 return error; |
2747 | 2724 |
2748 // If resource_id is not empty, remove its corresponding file from cache. | 2725 // If resource_id is not empty, remove its corresponding file from cache. |
2749 if (!resource_id.empty()) | 2726 if (!resource_id.empty()) |
2750 cache_->RemoveOnUIThread(resource_id, CacheOperationCallback()); | 2727 cache_->RemoveOnUIThread(resource_id, CacheOperationCallback()); |
2751 | 2728 |
2752 return GDATA_FILE_OK; | 2729 return GDATA_FILE_OK; |
2753 } | 2730 } |
2754 | 2731 |
2755 // static | |
2756 void GDataFileSystem::RemoveStaleEntryOnUpload(const std::string& resource_id, | 2732 void GDataFileSystem::RemoveStaleEntryOnUpload(const std::string& resource_id, |
2757 GDataDirectory* parent_dir, | 2733 GDataDirectory* parent_dir, |
2758 GDataEntry* existing_entry) { | 2734 GDataEntry* existing_entry) { |
2759 if (existing_entry && | 2735 if (existing_entry && |
2760 // This should always match, but just in case. | 2736 // This should always match, but just in case. |
2761 existing_entry->parent() == parent_dir) { | 2737 existing_entry->parent() == parent_dir) { |
2762 parent_dir->RemoveEntry(existing_entry); | 2738 directory_service_->RemoveEntryFromParent(existing_entry, |
2739 FileMoveCallback()); | |
2763 } else { | 2740 } else { |
2764 LOG(ERROR) << "Entry for the existing file not found: " << resource_id; | 2741 LOG(ERROR) << "Entry for the existing file not found: " << resource_id; |
2765 } | 2742 } |
2766 } | 2743 } |
2767 | 2744 |
2768 void GDataFileSystem::NotifyFileSystemMounted() { | 2745 void GDataFileSystem::NotifyFileSystemMounted() { |
2769 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 2746 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
2770 | 2747 |
2771 DVLOG(1) << "File System is mounted"; | 2748 DVLOG(1) << "File System is mounted"; |
2772 // Notify the observers that the file system is mounted. | 2749 // 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. | 2798 // file with the exact same name. |
2822 GDataDirectory* parent_dir = entry->AsGDataDirectory(); | 2799 GDataDirectory* parent_dir = entry->AsGDataDirectory(); |
2823 if (!parent_dir) | 2800 if (!parent_dir) |
2824 return GDATA_FILE_ERROR_FAILED; | 2801 return GDATA_FILE_ERROR_FAILED; |
2825 | 2802 |
2826 GDataEntry* new_entry = | 2803 GDataEntry* new_entry = |
2827 directory_service_->FromDocumentEntry(doc_entry.get()); | 2804 directory_service_->FromDocumentEntry(doc_entry.get()); |
2828 if (!new_entry) | 2805 if (!new_entry) |
2829 return GDATA_FILE_ERROR_FAILED; | 2806 return GDATA_FILE_ERROR_FAILED; |
2830 | 2807 |
2831 parent_dir->AddEntry(new_entry); | 2808 directory_service_->AddEntryToDirectory( |
2832 | 2809 parent_dir, |
2833 OnDirectoryChanged(directory_path); | 2810 new_entry, |
2811 base::Bind(&GDataFileSystem::OnMoveEntryToDirectoryWithFileMoveCallback, | |
2812 ui_weak_ptr_, | |
2813 FileMoveCallback())); | |
2834 return GDATA_FILE_OK; | 2814 return GDATA_FILE_OK; |
2835 } | 2815 } |
2836 | 2816 |
2837 GDataFileSystem::FindMissingDirectoryResult | 2817 GDataFileSystem::FindMissingDirectoryResult |
2838 GDataFileSystem::FindFirstMissingParentDirectory( | 2818 GDataFileSystem::FindFirstMissingParentDirectory( |
2839 const FilePath& directory_path, | 2819 const FilePath& directory_path, |
2840 GURL* last_dir_content_url, | 2820 GURL* last_dir_content_url, |
2841 FilePath* first_missing_parent_path) { | 2821 FilePath* first_missing_parent_path) { |
2842 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 2822 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
2843 | 2823 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2881 | 2861 |
2882 // You can't remove root element. | 2862 // You can't remove root element. |
2883 if (!entry->parent()) | 2863 if (!entry->parent()) |
2884 return GDATA_FILE_ERROR_ACCESS_DENIED; | 2864 return GDATA_FILE_ERROR_ACCESS_DENIED; |
2885 | 2865 |
2886 // If it's a file (only files have resource id), get its resource id so that | 2866 // 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. | 2867 // we can remove it after releasing the auto lock. |
2888 if (entry->AsGDataFile()) | 2868 if (entry->AsGDataFile()) |
2889 *resource_id = entry->AsGDataFile()->resource_id(); | 2869 *resource_id = entry->AsGDataFile()->resource_id(); |
2890 | 2870 |
2891 GDataDirectory* parent_dir = entry->parent(); | 2871 directory_service_->RemoveEntryFromParent( |
2892 parent_dir->RemoveEntry(entry); | 2872 entry, |
2893 | 2873 base::Bind(&GDataFileSystem::OnDirectoryChangeFileMoveCallback, |
2894 OnDirectoryChanged(parent_dir->GetFilePath()); | 2874 ui_weak_ptr_)); |
2895 return GDATA_FILE_OK; | 2875 return GDATA_FILE_OK; |
2896 } | 2876 } |
2897 | 2877 |
2898 void GDataFileSystem::AddUploadedFile( | 2878 void GDataFileSystem::AddUploadedFile( |
2899 UploadMode upload_mode, | 2879 UploadMode upload_mode, |
2900 const FilePath& virtual_dir_path, | 2880 const FilePath& virtual_dir_path, |
2901 scoped_ptr<DocumentEntry> entry, | 2881 scoped_ptr<DocumentEntry> entry, |
2902 const FilePath& file_content_path, | 2882 const FilePath& file_content_path, |
2903 GDataCache::FileOperationType cache_operation, | 2883 GDataCache::FileOperationType cache_operation, |
2904 const base::Closure& callback) { | 2884 const base::Closure& callback) { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2946 return; | 2926 return; |
2947 | 2927 |
2948 scoped_ptr<GDataEntry> new_entry( | 2928 scoped_ptr<GDataEntry> new_entry( |
2949 directory_service_->FromDocumentEntry(entry.get())); | 2929 directory_service_->FromDocumentEntry(entry.get())); |
2950 if (!new_entry.get()) | 2930 if (!new_entry.get()) |
2951 return; | 2931 return; |
2952 | 2932 |
2953 if (upload_mode == UPLOAD_EXISTING_FILE) { | 2933 if (upload_mode == UPLOAD_EXISTING_FILE) { |
2954 // Remove an existing entry, which should be present. | 2934 // Remove an existing entry, which should be present. |
2955 const std::string& resource_id = new_entry->resource_id(); | 2935 const std::string& resource_id = new_entry->resource_id(); |
2956 directory_service_->GetEntryByResourceIdAsync(resource_id, | 2936 directory_service_->GetEntryByResourceIdAsync( |
2957 base::Bind(&RemoveStaleEntryOnUpload, resource_id, parent_dir)); | 2937 resource_id, |
2938 base::Bind(&GDataFileSystem::RemoveStaleEntryOnUpload, | |
2939 ui_weak_ptr_, | |
2940 resource_id, | |
2941 parent_dir)); | |
satorux1
2012/08/13 22:35:53
This code path is rather worrisome. I think the or
achuithb
2012/08/14 00:18:44
Done.
| |
2958 } | 2942 } |
2959 | 2943 |
2960 GDataFile* file = new_entry->AsGDataFile(); | 2944 GDataFile* file = new_entry->AsGDataFile(); |
2961 DCHECK(file); | 2945 DCHECK(file); |
2962 const std::string& resource_id = file->resource_id(); | 2946 const std::string& resource_id = file->resource_id(); |
2963 const std::string& md5 = file->file_md5(); | 2947 const std::string& md5 = file->file_md5(); |
2964 parent_dir->AddEntry(new_entry.release()); | 2948 directory_service_->AddEntryToDirectory( |
2965 | 2949 parent_dir, |
2966 OnDirectoryChanged(virtual_dir_path); | 2950 new_entry.release(), |
2951 base::Bind(&GDataFileSystem::OnMoveEntryToDirectoryWithFileMoveCallback, | |
2952 ui_weak_ptr_, | |
2953 FileMoveCallback())); | |
2967 | 2954 |
2968 if (upload_mode == UPLOAD_NEW_FILE) { | 2955 if (upload_mode == UPLOAD_NEW_FILE) { |
2969 // Add the file to the cache if we have uploaded a new file. | 2956 // Add the file to the cache if we have uploaded a new file. |
2970 cache_->StoreOnUIThread(resource_id, | 2957 cache_->StoreOnUIThread(resource_id, |
2971 md5, | 2958 md5, |
2972 file_content_path, | 2959 file_content_path, |
2973 cache_operation, | 2960 cache_operation, |
2974 base::Bind(&OnCacheUpdatedForAddUploadedFile, | 2961 base::Bind(&OnCacheUpdatedForAddUploadedFile, |
2975 callback_runner.Release())); | 2962 callback_runner.Release())); |
2976 } else if (upload_mode == UPLOAD_EXISTING_FILE) { | 2963 } else if (upload_mode == UPLOAD_EXISTING_FILE) { |
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3444 } | 3431 } |
3445 | 3432 |
3446 PlatformFileInfoProto entry_file_info; | 3433 PlatformFileInfoProto entry_file_info; |
3447 GDataEntry::ConvertPlatformFileInfoToProto(*file_info, &entry_file_info); | 3434 GDataEntry::ConvertPlatformFileInfoToProto(*file_info, &entry_file_info); |
3448 *entry_proto->mutable_file_info() = entry_file_info; | 3435 *entry_proto->mutable_file_info() = entry_file_info; |
3449 if (!callback.is_null()) | 3436 if (!callback.is_null()) |
3450 callback.Run(GDATA_FILE_OK, entry_proto.Pass()); | 3437 callback.Run(GDATA_FILE_OK, entry_proto.Pass()); |
3451 } | 3438 } |
3452 | 3439 |
3453 } // namespace gdata | 3440 } // namespace gdata |
OLD | NEW |