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/drive_file_system.h" | 5 #include "chrome/browser/chromeos/drive/drive_file_system.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
9 #include "base/json/json_file_value_serializer.h" | 9 #include "base/json/json_file_value_serializer.h" |
10 #include "base/message_loop_proxy.h" | 10 #include "base/message_loop_proxy.h" |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 if (entry_proto->file_specific_info().is_hosted_document()) { | 174 if (entry_proto->file_specific_info().is_hosted_document()) { |
175 get_file_callback.Run( | 175 get_file_callback.Run( |
176 DRIVE_FILE_OK, local_file_path, kMimeTypeJson, HOSTED_DOCUMENT); | 176 DRIVE_FILE_OK, local_file_path, kMimeTypeJson, HOSTED_DOCUMENT); |
177 } else { | 177 } else { |
178 get_file_callback.Run( | 178 get_file_callback.Run( |
179 DRIVE_FILE_OK, local_file_path, | 179 DRIVE_FILE_OK, local_file_path, |
180 entry_proto->file_specific_info().content_mime_type(), REGULAR_FILE); | 180 entry_proto->file_specific_info().content_mime_type(), REGULAR_FILE); |
181 } | 181 } |
182 } | 182 } |
183 | 183 |
184 void OnDownloadFileCompleted(const base::FilePath& downloaded_file_path) { | 184 void OnStoreCompleted(const base::FilePath& local_file_path) { |
185 get_file_callback.Run( | 185 get_file_callback.Run( |
186 DRIVE_FILE_OK, downloaded_file_path, | 186 DRIVE_FILE_OK, local_file_path, |
187 entry_proto->file_specific_info().content_mime_type(), REGULAR_FILE); | 187 entry_proto->file_specific_info().content_mime_type(), REGULAR_FILE); |
188 } | 188 } |
189 | 189 |
190 const base::FilePath drive_file_path; | 190 const base::FilePath drive_file_path; |
191 const DriveClientContext context; | 191 const DriveClientContext context; |
192 scoped_ptr<DriveEntryProto> entry_proto; | 192 scoped_ptr<DriveEntryProto> entry_proto; |
193 const GetFileCallback get_file_callback; | 193 const GetFileCallback get_file_callback; |
194 const google_apis::GetContentCallback get_content_callback; | 194 const google_apis::GetContentCallback get_content_callback; |
195 }; | 195 }; |
196 | 196 |
(...skipping 726 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
923 | 923 |
924 if (error != DRIVE_FILE_OK) { | 924 if (error != DRIVE_FILE_OK) { |
925 params->OnError(error); | 925 params->OnError(error); |
926 return; | 926 return; |
927 } | 927 } |
928 | 928 |
929 int64 file_size = entry_proto->file_info().size(); | 929 int64 file_size = entry_proto->file_info().size(); |
930 params->entry_proto = entry_proto.Pass(); // Update the entry in |params|. | 930 params->entry_proto = entry_proto.Pass(); // Update the entry in |params|. |
931 cache_->FreeDiskSpaceIfNeededFor( | 931 cache_->FreeDiskSpaceIfNeededFor( |
932 file_size, | 932 file_size, |
933 base::Bind( | 933 base::Bind(&DriveFileSystem::GetResolvedFileByPathAfterFreeDiskSpace, |
934 &DriveFileSystem | 934 weak_ptr_factory_.GetWeakPtr(), |
935 ::GetResolvedFileByPathAfterFreeDiskSpacePreliminarily, | 935 base::Passed(¶ms), |
936 weak_ptr_factory_.GetWeakPtr(), | 936 download_url)); |
937 base::Passed(¶ms), | |
938 download_url)); | |
939 } | 937 } |
940 | 938 |
941 void DriveFileSystem::GetResolvedFileByPathAfterFreeDiskSpacePreliminarily( | 939 void DriveFileSystem::GetResolvedFileByPathAfterFreeDiskSpace( |
942 scoped_ptr<GetResolvedFileParams> params, | 940 scoped_ptr<GetResolvedFileParams> params, |
943 const GURL& download_url, | 941 const GURL& download_url, |
944 bool has_enough_space) { | 942 bool has_enough_space) { |
945 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 943 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
946 DCHECK(params); | 944 DCHECK(params); |
947 | 945 |
948 if (!has_enough_space) { | 946 if (!has_enough_space) { |
949 // If no enough space, return DRIVE_FILE_ERROR_NO_SPACE. | 947 // If no enough space, return DRIVE_FILE_ERROR_NO_SPACE. |
950 params->OnError(DRIVE_FILE_ERROR_NO_SPACE); | 948 params->OnError(DRIVE_FILE_ERROR_NO_SPACE); |
951 return; | 949 return; |
952 } | 950 } |
953 | 951 |
954 // We have enough disk space. Start downloading the file. | 952 // We have enough disk space. Create download destination file. |
955 base::FilePath local_tmp_path = cache_->GetCacheFilePath( | 953 const base::FilePath temp_download_directory = |
956 params->entry_proto->resource_id(), | 954 cache_->GetCacheDirectoryPath(DriveCache::CACHE_TYPE_TMP_DOWNLOADS); |
957 params->entry_proto->file_specific_info().file_md5(), | 955 base::FilePath* file_path = new base::FilePath; |
958 DriveCache::CACHE_TYPE_TMP, | 956 base::PostTaskAndReplyWithResult( |
959 DriveCache::CACHED_FILE_FROM_SERVER); | 957 blocking_task_runner_, |
| 958 FROM_HERE, |
| 959 base::Bind(&file_util::CreateTemporaryFileInDir, |
| 960 temp_download_directory, |
| 961 file_path), |
| 962 base::Bind(&DriveFileSystem::GetResolveFileByPathAfterCreateTemporaryFile, |
| 963 weak_ptr_factory_.GetWeakPtr(), |
| 964 base::Passed(¶ms), |
| 965 download_url, |
| 966 base::Owned(file_path))); |
| 967 } |
| 968 |
| 969 void DriveFileSystem::GetResolveFileByPathAfterCreateTemporaryFile( |
| 970 scoped_ptr<GetResolvedFileParams> params, |
| 971 const GURL& download_url, |
| 972 base::FilePath* temp_file, |
| 973 bool success) { |
| 974 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 975 DCHECK(params); |
| 976 |
| 977 if (!success) { |
| 978 params->OnError(DRIVE_FILE_ERROR_FAILED); |
| 979 return; |
| 980 } |
| 981 |
960 GetResolvedFileParams* params_ptr = params.get(); | 982 GetResolvedFileParams* params_ptr = params.get(); |
961 scheduler_->DownloadFile( | 983 scheduler_->DownloadFile( |
962 params_ptr->drive_file_path, | 984 params_ptr->drive_file_path, |
963 local_tmp_path, | 985 *temp_file, |
964 download_url, | 986 download_url, |
965 params_ptr->context, | 987 params_ptr->context, |
966 base::Bind(&DriveFileSystem::GetResolvedFileByPathAfterDownloadFile, | 988 base::Bind(&DriveFileSystem::GetResolvedFileByPathAfterDownloadFile, |
967 weak_ptr_factory_.GetWeakPtr(), | 989 weak_ptr_factory_.GetWeakPtr(), |
968 base::Passed(¶ms)), | 990 base::Passed(¶ms)), |
969 params_ptr->get_content_callback); | 991 params_ptr->get_content_callback); |
970 } | 992 } |
971 | 993 |
972 void DriveFileSystem::GetResolvedFileByPathAfterDownloadFile( | 994 void DriveFileSystem::GetResolvedFileByPathAfterDownloadFile( |
973 scoped_ptr<GetResolvedFileParams> params, | 995 scoped_ptr<GetResolvedFileParams> params, |
(...skipping 14 matching lines...) Expand all Loading... |
988 params->entry_proto->resource_id(), | 1010 params->entry_proto->resource_id(), |
989 params->entry_proto->file_specific_info().file_md5())); | 1011 params->entry_proto->file_specific_info().file_md5())); |
990 } | 1012 } |
991 | 1013 |
992 DriveFileError error = util::GDataToDriveFileError(status); | 1014 DriveFileError error = util::GDataToDriveFileError(status); |
993 if (error != DRIVE_FILE_OK) { | 1015 if (error != DRIVE_FILE_OK) { |
994 params->OnError(error); | 1016 params->OnError(error); |
995 return; | 1017 return; |
996 } | 1018 } |
997 | 1019 |
998 // At this point, the disk can be full or nearly full for several reasons: | 1020 DriveEntryProto* entry = params->entry_proto.get(); |
999 // - The expected file size was incorrect and the file was larger | 1021 cache_->Store(entry->resource_id(), |
1000 // - There was an in-flight download operation and it used up space | 1022 entry->file_specific_info().file_md5(), |
1001 // - The disk became full for some user actions we cannot control | 1023 downloaded_file_path, |
1002 // (ex. the user might have downloaded a large file from a regular web site) | 1024 DriveCache::FILE_OPERATION_MOVE, |
1003 // | 1025 base::Bind(&DriveFileSystem::GetResolvedFileByPathAfterStore, |
1004 // If we don't have enough space, we return PLATFORM_FILE_ERROR_NO_SPACE, | 1026 weak_ptr_factory_.GetWeakPtr(), |
1005 // and try to free up space, even if the file was downloaded successfully. | 1027 base::Passed(¶ms), |
1006 cache_->FreeDiskSpaceIfNeededFor( | 1028 downloaded_file_path)); |
1007 0, | |
1008 base::Bind(&DriveFileSystem::GetResolvedFileByPathAfterFreeDiskSpace, | |
1009 weak_ptr_factory_.GetWeakPtr(), | |
1010 base::Passed(¶ms), | |
1011 downloaded_file_path)); | |
1012 } | 1029 } |
1013 | 1030 |
1014 void DriveFileSystem::GetResolvedFileByPathAfterGetCacheEntryForCancel( | 1031 void DriveFileSystem::GetResolvedFileByPathAfterGetCacheEntryForCancel( |
1015 const std::string& resource_id, | 1032 const std::string& resource_id, |
1016 const std::string& md5, | 1033 const std::string& md5, |
1017 bool success, | 1034 bool success, |
1018 const DriveCacheEntry& cache_entry) { | 1035 const DriveCacheEntry& cache_entry) { |
1019 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1036 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
1020 // TODO(hshi): http://crbug.com/127138 notify when file properties change. | 1037 // TODO(hshi): http://crbug.com/127138 notify when file properties change. |
1021 // This allows file manager to clear the "Available offline" checkbox. | 1038 // This allows file manager to clear the "Available offline" checkbox. |
1022 if (success && cache_entry.is_pinned()) { | 1039 if (success && cache_entry.is_pinned()) { |
1023 cache_->Unpin(resource_id, | 1040 cache_->Unpin(resource_id, |
1024 md5, | 1041 md5, |
1025 base::Bind(&util::EmptyFileOperationCallback)); | 1042 base::Bind(&util::EmptyFileOperationCallback)); |
1026 } | 1043 } |
1027 } | 1044 } |
1028 | 1045 |
1029 void DriveFileSystem::GetResolvedFileByPathAfterFreeDiskSpace( | 1046 void DriveFileSystem::GetResolvedFileByPathAfterStore( |
1030 scoped_ptr<GetResolvedFileParams> params, | 1047 scoped_ptr<GetResolvedFileParams> params, |
1031 const base::FilePath& downloaded_file_path, | 1048 const base::FilePath& downloaded_file_path, |
1032 bool has_enough_space) { | 1049 DriveFileError error) { |
1033 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1050 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
1034 DCHECK(params); | 1051 DCHECK(params); |
1035 | 1052 |
1036 // If we don't have enough space, remove the downloaded file, and | 1053 if (error != DRIVE_FILE_OK) { |
1037 // report "no space" error. | |
1038 if (!has_enough_space) { | |
1039 blocking_task_runner_->PostTask( | 1054 blocking_task_runner_->PostTask( |
1040 FROM_HERE, | 1055 FROM_HERE, |
1041 base::Bind(base::IgnoreResult(&file_util::Delete), | 1056 base::Bind(base::IgnoreResult(&file_util::Delete), |
1042 downloaded_file_path, | 1057 downloaded_file_path, |
1043 false /* recursive*/)); | 1058 false /* recursive*/)); |
1044 params->OnError(DRIVE_FILE_ERROR_NO_SPACE); | 1059 params->OnError(error); |
1045 return; | 1060 return; |
1046 } | 1061 } |
1047 | |
1048 // Make sure that downloaded file is properly stored in cache. We don't have | |
1049 // to wait for this operation to finish since the user can already use the | |
1050 // downloaded file. | |
1051 cache_->Store(params->entry_proto->resource_id(), | |
1052 params->entry_proto->file_specific_info().file_md5(), | |
1053 downloaded_file_path, | |
1054 DriveCache::FILE_OPERATION_MOVE, | |
1055 base::Bind(&util::EmptyFileOperationCallback)); | |
1056 // Storing to cache changes the "offline available" status, hence notify. | 1062 // Storing to cache changes the "offline available" status, hence notify. |
1057 OnDirectoryChanged(params->drive_file_path.DirName()); | 1063 OnDirectoryChanged(params->drive_file_path.DirName()); |
1058 | 1064 |
1059 params->OnDownloadFileCompleted(downloaded_file_path); | 1065 DriveEntryProto* entry = params->entry_proto.get(); |
| 1066 cache_->GetFile( |
| 1067 entry->resource_id(), |
| 1068 entry->file_specific_info().file_md5(), |
| 1069 base::Bind(&DriveFileSystem::GetResolvedFileByPathAfterGetFile, |
| 1070 weak_ptr_factory_.GetWeakPtr(), |
| 1071 base::Passed(¶ms))); |
| 1072 } |
| 1073 |
| 1074 void DriveFileSystem::GetResolvedFileByPathAfterGetFile( |
| 1075 scoped_ptr<GetResolvedFileParams> params, |
| 1076 DriveFileError error, |
| 1077 const base::FilePath& cache_file) { |
| 1078 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1079 DCHECK(params); |
| 1080 |
| 1081 if (error != DRIVE_FILE_OK) { |
| 1082 params->OnError(error); |
| 1083 return; |
| 1084 } |
| 1085 params->OnStoreCompleted(cache_file); |
1060 } | 1086 } |
1061 | 1087 |
1062 void DriveFileSystem::RefreshDirectory( | 1088 void DriveFileSystem::RefreshDirectory( |
1063 const base::FilePath& directory_path, | 1089 const base::FilePath& directory_path, |
1064 const FileOperationCallback& callback) { | 1090 const FileOperationCallback& callback) { |
1065 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1091 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
1066 DCHECK(!callback.is_null()); | 1092 DCHECK(!callback.is_null()); |
1067 | 1093 |
1068 // Make sure the destination directory exists. | 1094 // Make sure the destination directory exists. |
1069 resource_metadata_->GetEntryInfoByPath( | 1095 resource_metadata_->GetEntryInfoByPath( |
(...skipping 620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1690 return; | 1716 return; |
1691 } | 1717 } |
1692 | 1718 |
1693 PlatformFileInfoProto entry_file_info; | 1719 PlatformFileInfoProto entry_file_info; |
1694 util::ConvertPlatformFileInfoToProto(*file_info, &entry_file_info); | 1720 util::ConvertPlatformFileInfoToProto(*file_info, &entry_file_info); |
1695 *entry_proto->mutable_file_info() = entry_file_info; | 1721 *entry_proto->mutable_file_info() = entry_file_info; |
1696 callback.Run(DRIVE_FILE_OK, entry_proto.Pass()); | 1722 callback.Run(DRIVE_FILE_OK, entry_proto.Pass()); |
1697 } | 1723 } |
1698 | 1724 |
1699 } // namespace drive | 1725 } // namespace drive |
OLD | NEW |