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 "base/bind.h" 6 #include "base/file_util.h" 7 #include "base/files/scoped_temp_dir.h" 8 #include "base/run_loop.h" 9 #include "testing/gtest/include/gtest/gtest.h" 10 #include "webkit/browser/fileapi/async_file_test_helper.h" 11 #include "webkit/browser/fileapi/file_system_backend.h" 12 #include "webkit/browser/fileapi/file_system_context.h" 13 #include "webkit/browser/fileapi/file_system_operation_runner.h" 14 #include "webkit/browser/fileapi/file_system_url.h" 15 #include "webkit/browser/quota/quota_manager.h" 16 #include "webkit/common/fileapi/file_system_util.h" 17 18 namespace fileapi { 19 20 namespace { 21 22 typedef FileSystemOperation::FileEntryList FileEntryList; 23 24 void AssignAndQuit(base::RunLoop* run_loop, 25 base::PlatformFileError* result_out, 26 base::PlatformFileError result) { 27 *result_out = result; 28 run_loop->Quit(); 29 } 30 31 base::Callback<void(base::PlatformFileError)> 32 AssignAndQuitCallback(base::RunLoop* run_loop, 33 base::PlatformFileError* result) { 34 return base::Bind(&AssignAndQuit, run_loop, base::Unretained(result)); 35 } 36 37 void GetMetadataCallback(base::RunLoop* run_loop, 38 base::PlatformFileError* result_out, 39 base::PlatformFileInfo* file_info_out, 40 base::PlatformFileError result, 41 const base::PlatformFileInfo& file_info) { 42 *result_out = result; 43 if (file_info_out) 44 *file_info_out = file_info; 45 run_loop->Quit(); 46 } 47 48 void CreateSnapshotFileCallback( 49 base::RunLoop* run_loop, 50 base::PlatformFileError* result_out, 51 base::FilePath* platform_path_out, 52 base::PlatformFileError result, 53 const base::PlatformFileInfo& file_info, 54 const base::FilePath& platform_path, 55 const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref) { 56 DCHECK(!file_ref.get()); 57 *result_out = result; 58 if (platform_path_out) 59 *platform_path_out = platform_path; 60 run_loop->Quit(); 61 } 62 63 void ReadDirectoryCallback(base::RunLoop* run_loop, 64 base::PlatformFileError* result_out, 65 FileEntryList* entries_out, 66 base::PlatformFileError result, 67 const FileEntryList& entries, 68 bool has_more) { 69 *result_out = result; 70 *entries_out = entries; 71 if (result != base::PLATFORM_FILE_OK || !has_more) 72 run_loop->Quit(); 73 } 74 75 void DidGetUsageAndQuota(quota::QuotaStatusCode* status_out, 76 int64* usage_out, 77 int64* quota_out, 78 quota::QuotaStatusCode status, 79 int64 usage, 80 int64 quota) { 81 if (status_out) 82 *status_out = status; 83 if (usage_out) 84 *usage_out = usage; 85 if (quota_out) 86 *quota_out = quota; 87 } 88 89 } // namespace 90 91 const int64 AsyncFileTestHelper::kDontCheckSize = -1; 92 93 base::PlatformFileError AsyncFileTestHelper::Copy( 94 FileSystemContext* context, 95 const FileSystemURL& src, 96 const FileSystemURL& dest) { 97 return CopyWithProgress(context, src, dest, CopyProgressCallback()); 98 } 99 100 base::PlatformFileError AsyncFileTestHelper::CopyWithProgress( 101 FileSystemContext* context, 102 const FileSystemURL& src, 103 const FileSystemURL& dest, 104 const CopyProgressCallback& progress_callback) { 105 base::PlatformFileError result = base::PLATFORM_FILE_ERROR_FAILED; 106 base::RunLoop run_loop; 107 context->operation_runner()->Copy( 108 src, dest, FileSystemOperation::OPTION_NONE, progress_callback, 109 AssignAndQuitCallback(&run_loop, &result)); 110 run_loop.Run(); 111 return result; 112 } 113 114 base::PlatformFileError AsyncFileTestHelper::Move( 115 FileSystemContext* context, 116 const FileSystemURL& src, 117 const FileSystemURL& dest) { 118 base::PlatformFileError result = base::PLATFORM_FILE_ERROR_FAILED; 119 base::RunLoop run_loop; 120 context->operation_runner()->Move( 121 src, dest, FileSystemOperation::OPTION_NONE, 122 AssignAndQuitCallback(&run_loop, &result)); 123 run_loop.Run(); 124 return result; 125 } 126 127 base::PlatformFileError AsyncFileTestHelper::Remove( 128 FileSystemContext* context, 129 const FileSystemURL& url, 130 bool recursive) { 131 base::PlatformFileError result = base::PLATFORM_FILE_ERROR_FAILED; 132 base::RunLoop run_loop; 133 context->operation_runner()->Remove( 134 url, recursive, AssignAndQuitCallback(&run_loop, &result)); 135 run_loop.Run(); 136 return result; 137 } 138 139 base::PlatformFileError AsyncFileTestHelper::ReadDirectory( 140 FileSystemContext* context, 141 const FileSystemURL& url, 142 FileEntryList* entries) { 143 base::PlatformFileError result = base::PLATFORM_FILE_ERROR_FAILED; 144 DCHECK(entries); 145 entries->clear(); 146 base::RunLoop run_loop; 147 context->operation_runner()->ReadDirectory( 148 url, base::Bind(&ReadDirectoryCallback, &run_loop, &result, entries)); 149 run_loop.Run(); 150 return result; 151 } 152 153 base::PlatformFileError AsyncFileTestHelper::CreateDirectory( 154 FileSystemContext* context, 155 const FileSystemURL& url) { 156 base::PlatformFileError result = base::PLATFORM_FILE_ERROR_FAILED; 157 base::RunLoop run_loop; 158 context->operation_runner()->CreateDirectory( 159 url, 160 false /* exclusive */, 161 false /* recursive */, 162 AssignAndQuitCallback(&run_loop, &result)); 163 run_loop.Run(); 164 return result; 165 } 166 167 base::PlatformFileError AsyncFileTestHelper::CreateFile( 168 FileSystemContext* context, 169 const FileSystemURL& url) { 170 base::PlatformFileError result = base::PLATFORM_FILE_ERROR_FAILED; 171 base::RunLoop run_loop; 172 context->operation_runner()->CreateFile( 173 url, false /* exclusive */, 174 AssignAndQuitCallback(&run_loop, &result)); 175 run_loop.Run(); 176 return result; 177 } 178 179 base::PlatformFileError AsyncFileTestHelper::CreateFileWithData( 180 FileSystemContext* context, 181 const FileSystemURL& url, 182 const char* buf, 183 int buf_size) { 184 base::ScopedTempDir dir; 185 if (!dir.CreateUniqueTempDir()) 186 return base::PLATFORM_FILE_ERROR_FAILED; 187 base::FilePath local_path = dir.path().AppendASCII("tmp"); 188 if (buf_size != file_util::WriteFile(local_path, buf, buf_size)) 189 return base::PLATFORM_FILE_ERROR_FAILED; 190 base::PlatformFileError result = base::PLATFORM_FILE_ERROR_FAILED; 191 base::RunLoop run_loop; 192 context->operation_runner()->CopyInForeignFile( 193 local_path, url, AssignAndQuitCallback(&run_loop, &result)); 194 run_loop.Run(); 195 return result; 196 } 197 198 base::PlatformFileError AsyncFileTestHelper::TruncateFile( 199 FileSystemContext* context, 200 const FileSystemURL& url, 201 size_t size) { 202 base::RunLoop run_loop; 203 base::PlatformFileError result = base::PLATFORM_FILE_ERROR_FAILED; 204 context->operation_runner()->Truncate( 205 url, size, AssignAndQuitCallback(&run_loop, &result)); 206 run_loop.Run(); 207 return result; 208 } 209 210 base::PlatformFileError AsyncFileTestHelper::GetMetadata( 211 FileSystemContext* context, 212 const FileSystemURL& url, 213 base::PlatformFileInfo* file_info) { 214 base::PlatformFileError result = base::PLATFORM_FILE_ERROR_FAILED; 215 base::RunLoop run_loop; 216 context->operation_runner()->GetMetadata( 217 url, base::Bind(&GetMetadataCallback, &run_loop, &result, 218 file_info)); 219 run_loop.Run(); 220 return result; 221 } 222 223 base::PlatformFileError AsyncFileTestHelper::GetPlatformPath( 224 FileSystemContext* context, 225 const FileSystemURL& url, 226 base::FilePath* platform_path) { 227 base::PlatformFileError result = base::PLATFORM_FILE_ERROR_FAILED; 228 base::RunLoop run_loop; 229 context->operation_runner()->CreateSnapshotFile( 230 url, base::Bind(&CreateSnapshotFileCallback, &run_loop, &result, 231 platform_path)); 232 run_loop.Run(); 233 return result; 234 } 235 236 bool AsyncFileTestHelper::FileExists( 237 FileSystemContext* context, 238 const FileSystemURL& url, 239 int64 expected_size) { 240 base::PlatformFileInfo file_info; 241 base::PlatformFileError result = GetMetadata(context, url, &file_info); 242 if (result != base::PLATFORM_FILE_OK || file_info.is_directory) 243 return false; 244 return expected_size == kDontCheckSize || file_info.size == expected_size; 245 } 246 247 bool AsyncFileTestHelper::DirectoryExists( 248 FileSystemContext* context, 249 const FileSystemURL& url) { 250 base::PlatformFileInfo file_info; 251 base::PlatformFileError result = GetMetadata(context, url, &file_info); 252 return (result == base::PLATFORM_FILE_OK) && file_info.is_directory; 253 } 254 255 quota::QuotaStatusCode AsyncFileTestHelper::GetUsageAndQuota( 256 quota::QuotaManager* quota_manager, 257 const GURL& origin, 258 FileSystemType type, 259 int64* usage, 260 int64* quota) { 261 quota::QuotaStatusCode status = quota::kQuotaStatusUnknown; 262 quota_manager->GetUsageAndQuota( 263 origin, 264 FileSystemTypeToQuotaStorageType(type), 265 base::Bind(&DidGetUsageAndQuota, &status, usage, quota)); 266 base::RunLoop().RunUntilIdle(); 267 return status; 268 } 269 270 } // namespace fileapi 271