OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "webkit/browser/fileapi/sandbox_context.h" | 5 #include "webkit/browser/fileapi/sandbox_context.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
| 9 #include "base/metrics/histogram.h" |
9 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
10 #include "base/task_runner_util.h" | 11 #include "base/task_runner_util.h" |
11 #include "net/base/net_util.h" | 12 #include "net/base/net_util.h" |
12 #include "webkit/browser/fileapi/async_file_util_adapter.h" | 13 #include "webkit/browser/fileapi/async_file_util_adapter.h" |
13 #include "webkit/browser/fileapi/file_system_context.h" | 14 #include "webkit/browser/fileapi/file_system_context.h" |
14 #include "webkit/browser/fileapi/file_system_operation_context.h" | 15 #include "webkit/browser/fileapi/file_system_operation_context.h" |
15 #include "webkit/browser/fileapi/file_system_url.h" | 16 #include "webkit/browser/fileapi/file_system_url.h" |
16 #include "webkit/browser/fileapi/file_system_usage_cache.h" | 17 #include "webkit/browser/fileapi/file_system_usage_cache.h" |
17 #include "webkit/browser/fileapi/obfuscated_file_util.h" | 18 #include "webkit/browser/fileapi/obfuscated_file_util.h" |
| 19 #include "webkit/browser/fileapi/sandbox_file_system_backend.h" |
18 #include "webkit/browser/fileapi/sandbox_quota_observer.h" | 20 #include "webkit/browser/fileapi/sandbox_quota_observer.h" |
19 #include "webkit/browser/quota/quota_manager.h" | 21 #include "webkit/browser/quota/quota_manager.h" |
20 #include "webkit/common/fileapi/file_system_util.h" | 22 #include "webkit/common/fileapi/file_system_util.h" |
21 | 23 |
22 namespace fileapi { | 24 namespace fileapi { |
23 | 25 |
24 namespace { | 26 namespace { |
25 | 27 |
| 28 const char kOpenFileSystemLabel[] = "FileSystem.OpenFileSystem"; |
| 29 const char kOpenFileSystemDetailLabel[] = "FileSystem.OpenFileSystemDetail"; |
| 30 const char kOpenFileSystemDetailNonThrottledLabel[] = |
| 31 "FileSystem.OpenFileSystemDetailNonthrottled"; |
| 32 int64 kMinimumStatsCollectionIntervalHours = 1; |
| 33 |
| 34 enum FileSystemError { |
| 35 kOK = 0, |
| 36 kIncognito, |
| 37 kInvalidSchemeError, |
| 38 kCreateDirectoryError, |
| 39 kNotFound, |
| 40 kUnknownError, |
| 41 kFileSystemErrorMax, |
| 42 }; |
| 43 |
26 // Restricted names. | 44 // Restricted names. |
27 // http://dev.w3.org/2009/dap/file-system/file-dir-sys.html#naming-restrictions | 45 // http://dev.w3.org/2009/dap/file-system/file-dir-sys.html#naming-restrictions |
28 const base::FilePath::CharType* const kRestrictedNames[] = { | 46 const base::FilePath::CharType* const kRestrictedNames[] = { |
29 FILE_PATH_LITERAL("."), FILE_PATH_LITERAL(".."), | 47 FILE_PATH_LITERAL("."), FILE_PATH_LITERAL(".."), |
30 }; | 48 }; |
31 | 49 |
32 // Restricted chars. | 50 // Restricted chars. |
33 const base::FilePath::CharType kRestrictedChars[] = { | 51 const base::FilePath::CharType kRestrictedChars[] = { |
34 FILE_PATH_LITERAL('/'), FILE_PATH_LITERAL('\\'), | 52 FILE_PATH_LITERAL('/'), FILE_PATH_LITERAL('\\'), |
35 }; | 53 }; |
(...skipping 11 matching lines...) Expand all Loading... |
47 } | 65 } |
48 | 66 |
49 virtual bool HasFileSystemType(fileapi::FileSystemType type) const OVERRIDE { | 67 virtual bool HasFileSystemType(fileapi::FileSystemType type) const OVERRIDE { |
50 return enum_->HasFileSystemType(type); | 68 return enum_->HasFileSystemType(type); |
51 } | 69 } |
52 | 70 |
53 private: | 71 private: |
54 scoped_ptr<ObfuscatedFileUtil::AbstractOriginEnumerator> enum_; | 72 scoped_ptr<ObfuscatedFileUtil::AbstractOriginEnumerator> enum_; |
55 }; | 73 }; |
56 | 74 |
| 75 void OpenFileSystemOnFileThread( |
| 76 ObfuscatedFileUtil* file_util, |
| 77 const GURL& origin_url, |
| 78 FileSystemType type, |
| 79 OpenFileSystemMode mode, |
| 80 base::PlatformFileError* error_ptr) { |
| 81 DCHECK(error_ptr); |
| 82 const bool create = (mode == OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT); |
| 83 file_util->GetDirectoryForOriginAndType(origin_url, type, create, error_ptr); |
| 84 if (*error_ptr != base::PLATFORM_FILE_OK) { |
| 85 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystemLabel, |
| 86 kCreateDirectoryError, |
| 87 kFileSystemErrorMax); |
| 88 } else { |
| 89 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystemLabel, kOK, kFileSystemErrorMax); |
| 90 } |
| 91 // The reference of file_util will be derefed on the FILE thread |
| 92 // when the storage of this callback gets deleted regardless of whether |
| 93 // this method is called or not. |
| 94 } |
| 95 |
| 96 void DidOpenFileSystem( |
| 97 base::WeakPtr<SandboxContext> sandbox_context, |
| 98 const base::Callback<void(base::PlatformFileError error)>& callback, |
| 99 base::PlatformFileError* error) { |
| 100 if (sandbox_context.get()) |
| 101 sandbox_context.get()->CollectOpenFileSystemMetrics(*error); |
| 102 callback.Run(*error); |
| 103 } |
| 104 |
57 } // namespace | 105 } // namespace |
58 | 106 |
59 const base::FilePath::CharType | 107 const base::FilePath::CharType |
60 SandboxContext::kFileSystemDirectory[] = FILE_PATH_LITERAL("File System"); | 108 SandboxContext::kFileSystemDirectory[] = FILE_PATH_LITERAL("File System"); |
61 | 109 |
62 SandboxContext::SandboxContext( | 110 SandboxContext::SandboxContext( |
63 quota::QuotaManagerProxy* quota_manager_proxy, | 111 quota::QuotaManagerProxy* quota_manager_proxy, |
64 base::SequencedTaskRunner* file_task_runner, | 112 base::SequencedTaskRunner* file_task_runner, |
65 const base::FilePath& profile_path, | 113 const base::FilePath& profile_path, |
66 quota::SpecialStoragePolicy* special_storage_policy, | 114 quota::SpecialStoragePolicy* special_storage_policy, |
67 const FileSystemOptions& file_system_options) | 115 const FileSystemOptions& file_system_options) |
68 : file_task_runner_(file_task_runner), | 116 : file_task_runner_(file_task_runner), |
69 sandbox_file_util_(new AsyncFileUtilAdapter( | 117 sandbox_file_util_(new AsyncFileUtilAdapter( |
70 new ObfuscatedFileUtil( | 118 new ObfuscatedFileUtil( |
71 special_storage_policy, | 119 special_storage_policy, |
72 profile_path.Append(kFileSystemDirectory), | 120 profile_path.Append(kFileSystemDirectory), |
73 file_task_runner))), | 121 file_task_runner))), |
74 file_system_usage_cache_(new FileSystemUsageCache(file_task_runner)), | 122 file_system_usage_cache_(new FileSystemUsageCache(file_task_runner)), |
75 quota_observer_(new SandboxQuotaObserver( | 123 quota_observer_(new SandboxQuotaObserver( |
76 quota_manager_proxy, | 124 quota_manager_proxy, |
77 file_task_runner, | 125 file_task_runner, |
78 sync_file_util(), | 126 sync_file_util(), |
79 usage_cache())), | 127 usage_cache())), |
80 special_storage_policy_(special_storage_policy), | 128 special_storage_policy_(special_storage_policy), |
81 file_system_options_(file_system_options) { | 129 file_system_options_(file_system_options), |
| 130 weak_factory_(this) { |
82 } | 131 } |
83 | 132 |
84 SandboxContext::~SandboxContext() { | 133 SandboxContext::~SandboxContext() { |
85 if (!file_task_runner_->RunsTasksOnCurrentThread()) { | 134 if (!file_task_runner_->RunsTasksOnCurrentThread()) { |
86 AsyncFileUtilAdapter* sandbox_file_util = sandbox_file_util_.release(); | 135 AsyncFileUtilAdapter* sandbox_file_util = sandbox_file_util_.release(); |
87 SandboxQuotaObserver* quota_observer = quota_observer_.release(); | 136 SandboxQuotaObserver* quota_observer = quota_observer_.release(); |
88 FileSystemUsageCache* file_system_usage_cache = | 137 FileSystemUsageCache* file_system_usage_cache = |
89 file_system_usage_cache_.release(); | 138 file_system_usage_cache_.release(); |
90 if (!file_task_runner_->DeleteSoon(FROM_HERE, sandbox_file_util)) | 139 if (!file_task_runner_->DeleteSoon(FROM_HERE, sandbox_file_util)) |
91 delete sandbox_file_util; | 140 delete sandbox_file_util; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 base::FilePath SandboxContext::GetBaseDirectoryForOriginAndType( | 201 base::FilePath SandboxContext::GetBaseDirectoryForOriginAndType( |
153 const GURL& origin_url, fileapi::FileSystemType type, bool create) { | 202 const GURL& origin_url, fileapi::FileSystemType type, bool create) { |
154 base::PlatformFileError error = base::PLATFORM_FILE_OK; | 203 base::PlatformFileError error = base::PLATFORM_FILE_OK; |
155 base::FilePath path = sync_file_util()->GetDirectoryForOriginAndType( | 204 base::FilePath path = sync_file_util()->GetDirectoryForOriginAndType( |
156 origin_url, type, create, &error); | 205 origin_url, type, create, &error); |
157 if (error != base::PLATFORM_FILE_OK) | 206 if (error != base::PLATFORM_FILE_OK) |
158 return base::FilePath(); | 207 return base::FilePath(); |
159 return path; | 208 return path; |
160 } | 209 } |
161 | 210 |
| 211 void SandboxContext::OpenFileSystem( |
| 212 const GURL& origin_url, |
| 213 fileapi::FileSystemType type, |
| 214 OpenFileSystemMode mode, |
| 215 const OpenFileSystemCallback& callback, |
| 216 const GURL& root_url) { |
| 217 if (!IsAllowedScheme(origin_url)) { |
| 218 callback.Run(GURL(), std::string(), base::PLATFORM_FILE_ERROR_SECURITY); |
| 219 return; |
| 220 } |
| 221 |
| 222 std::string name = GetFileSystemName(origin_url, type); |
| 223 |
| 224 base::PlatformFileError* error_ptr = new base::PlatformFileError; |
| 225 file_task_runner_->PostTaskAndReply( |
| 226 FROM_HERE, |
| 227 base::Bind(&OpenFileSystemOnFileThread, |
| 228 sync_file_util(), origin_url, type, mode, |
| 229 base::Unretained(error_ptr)), |
| 230 base::Bind(&DidOpenFileSystem, |
| 231 weak_factory_.GetWeakPtr(), |
| 232 base::Bind(callback, root_url, name), |
| 233 base::Owned(error_ptr))); |
| 234 } |
| 235 |
162 base::PlatformFileError SandboxContext::DeleteOriginDataOnFileThread( | 236 base::PlatformFileError SandboxContext::DeleteOriginDataOnFileThread( |
163 FileSystemContext* file_system_context, | 237 FileSystemContext* file_system_context, |
164 quota::QuotaManagerProxy* proxy, | 238 quota::QuotaManagerProxy* proxy, |
165 const GURL& origin_url, | 239 const GURL& origin_url, |
166 fileapi::FileSystemType type) { | 240 fileapi::FileSystemType type) { |
167 int64 usage = GetOriginUsageOnFileThread( | 241 int64 usage = GetOriginUsageOnFileThread( |
168 file_system_context, origin_url, type); | 242 file_system_context, origin_url, type); |
169 usage_cache()->CloseCacheFiles(); | 243 usage_cache()->CloseCacheFiles(); |
170 bool result = sync_file_util()->DeleteDirectoryForOriginAndType( | 244 bool result = sync_file_util()->DeleteDirectoryForOriginAndType( |
171 origin_url, type); | 245 origin_url, type); |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
302 int64 usage = 0; | 376 int64 usage = 0; |
303 | 377 |
304 while (!(file_path_each = enumerator->Next()).empty()) { | 378 while (!(file_path_each = enumerator->Next()).empty()) { |
305 usage += enumerator->Size(); | 379 usage += enumerator->Size(); |
306 usage += ObfuscatedFileUtil::ComputeFilePathCost(file_path_each); | 380 usage += ObfuscatedFileUtil::ComputeFilePathCost(file_path_each); |
307 } | 381 } |
308 | 382 |
309 return usage; | 383 return usage; |
310 } | 384 } |
311 | 385 |
| 386 void SandboxContext::CollectOpenFileSystemMetrics( |
| 387 base::PlatformFileError error_code) { |
| 388 base::Time now = base::Time::Now(); |
| 389 bool throttled = now < next_release_time_for_open_filesystem_stat_; |
| 390 if (!throttled) { |
| 391 next_release_time_for_open_filesystem_stat_ = |
| 392 now + base::TimeDelta::FromHours(kMinimumStatsCollectionIntervalHours); |
| 393 } |
| 394 |
| 395 #define REPORT(report_value) \ |
| 396 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystemDetailLabel, \ |
| 397 (report_value), \ |
| 398 kFileSystemErrorMax); \ |
| 399 if (!throttled) { \ |
| 400 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystemDetailNonThrottledLabel, \ |
| 401 (report_value), \ |
| 402 kFileSystemErrorMax); \ |
| 403 } |
| 404 |
| 405 switch (error_code) { |
| 406 case base::PLATFORM_FILE_OK: |
| 407 REPORT(kOK); |
| 408 break; |
| 409 case base::PLATFORM_FILE_ERROR_INVALID_URL: |
| 410 REPORT(kInvalidSchemeError); |
| 411 break; |
| 412 case base::PLATFORM_FILE_ERROR_NOT_FOUND: |
| 413 REPORT(kNotFound); |
| 414 break; |
| 415 case base::PLATFORM_FILE_ERROR_FAILED: |
| 416 default: |
| 417 REPORT(kUnknownError); |
| 418 break; |
| 419 } |
| 420 #undef REPORT |
| 421 } |
| 422 |
312 ObfuscatedFileUtil* SandboxContext::sync_file_util() { | 423 ObfuscatedFileUtil* SandboxContext::sync_file_util() { |
313 return static_cast<ObfuscatedFileUtil*>(file_util()->sync_file_util()); | 424 return static_cast<ObfuscatedFileUtil*>(file_util()->sync_file_util()); |
314 } | 425 } |
315 | 426 |
316 } // namespace fileapi | 427 } // namespace fileapi |
OLD | NEW |