| 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 "content/browser/file_system/file_system_dispatcher_host.h" | 5 #include "content/browser/file_system/file_system_dispatcher_host.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/file_path.h" | 10 #include "base/file_path.h" |
| 11 #include "base/memory/scoped_ptr.h" | 11 #include "base/memory/scoped_ptr.h" |
| 12 #include "base/platform_file.h" | 12 #include "base/platform_file.h" |
| 13 #include "base/threading/thread.h" | 13 #include "base/threading/thread.h" |
| 14 #include "base/time.h" | 14 #include "base/time.h" |
| 15 #include "content/common/file_system_messages.h" | 15 #include "content/common/file_system_messages.h" |
| 16 #include "content/public/browser/user_metrics.h" | 16 #include "content/public/browser/user_metrics.h" |
| 17 #include "googleurl/src/gurl.h" | 17 #include "googleurl/src/gurl.h" |
| 18 #include "ipc/ipc_platform_file.h" | 18 #include "ipc/ipc_platform_file.h" |
| 19 #include "net/url_request/url_request_context.h" | 19 #include "net/url_request/url_request_context.h" |
| 20 #include "net/url_request/url_request_context_getter.h" | 20 #include "net/url_request/url_request_context_getter.h" |
| 21 #include "webkit/fileapi/file_system_callback_dispatcher.h" | 21 #include "webkit/fileapi/file_system_callback_dispatcher.h" |
| 22 #include "webkit/fileapi/file_system_context.h" | 22 #include "webkit/fileapi/file_system_context.h" |
| 23 #include "webkit/fileapi/file_system_operation.h" | 23 #include "webkit/fileapi/file_system_operation.h" |
| 24 #include "webkit/fileapi/file_system_operation.h" | |
| 25 #include "webkit/fileapi/file_system_quota_util.h" | 24 #include "webkit/fileapi/file_system_quota_util.h" |
| 26 #include "webkit/fileapi/file_system_util.h" | 25 #include "webkit/fileapi/file_system_util.h" |
| 26 #include "webkit/fileapi/sandbox_mount_point_provider.h" |
| 27 | 27 |
| 28 using content::BrowserMessageFilter; | 28 using content::BrowserMessageFilter; |
| 29 using content::BrowserThread; | 29 using content::BrowserThread; |
| 30 using content::UserMetricsAction; | 30 using content::UserMetricsAction; |
| 31 using fileapi::FileSystemCallbackDispatcher; | 31 using fileapi::FileSystemCallbackDispatcher; |
| 32 using fileapi::FileSystemFileUtil; | 32 using fileapi::FileSystemFileUtil; |
| 33 using fileapi::FileSystemOperation; | 33 using fileapi::FileSystemOperation; |
| 34 using fileapi::FileSystemOperationInterface; |
| 34 | 35 |
| 35 class BrowserFileSystemCallbackDispatcher | 36 class BrowserFileSystemCallbackDispatcher |
| 36 : public FileSystemCallbackDispatcher { | 37 : public FileSystemCallbackDispatcher { |
| 37 public: | 38 public: |
| 38 // An instance of this class must be created by Create() | 39 // An instance of this class must be created by Create() |
| 39 // (so that we do not leak ownerships). | 40 // (so that we do not leak ownerships). |
| 40 static scoped_ptr<FileSystemCallbackDispatcher> Create( | 41 static scoped_ptr<FileSystemCallbackDispatcher> Create( |
| 41 FileSystemDispatcherHost* dispatcher_host, int request_id) { | 42 FileSystemDispatcherHost* dispatcher_host, int request_id) { |
| 42 return scoped_ptr<FileSystemCallbackDispatcher>( | 43 return scoped_ptr<FileSystemCallbackDispatcher>( |
| 43 new BrowserFileSystemCallbackDispatcher(dispatcher_host, request_id)); | 44 new BrowserFileSystemCallbackDispatcher(dispatcher_host, request_id)); |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 179 } else if (type == fileapi::kFileSystemTypePersistent) { | 180 } else if (type == fileapi::kFileSystemTypePersistent) { |
| 180 content::RecordAction(UserMetricsAction("OpenFileSystemPersistent")); | 181 content::RecordAction(UserMetricsAction("OpenFileSystemPersistent")); |
| 181 } | 182 } |
| 182 context_->OpenFileSystem(origin_url, type, create, | 183 context_->OpenFileSystem(origin_url, type, create, |
| 183 BrowserFileSystemCallbackDispatcher::Create( | 184 BrowserFileSystemCallbackDispatcher::Create( |
| 184 this, request_id)); | 185 this, request_id)); |
| 185 } | 186 } |
| 186 | 187 |
| 187 void FileSystemDispatcherHost::OnMove( | 188 void FileSystemDispatcherHost::OnMove( |
| 188 int request_id, const GURL& src_path, const GURL& dest_path) { | 189 int request_id, const GURL& src_path, const GURL& dest_path) { |
| 189 GetNewOperation(request_id)->Move(src_path, dest_path); | 190 GetNewOperation(src_path, request_id)->Move(src_path, dest_path); |
| 190 } | 191 } |
| 191 | 192 |
| 192 void FileSystemDispatcherHost::OnCopy( | 193 void FileSystemDispatcherHost::OnCopy( |
| 193 int request_id, const GURL& src_path, const GURL& dest_path) { | 194 int request_id, const GURL& src_path, const GURL& dest_path) { |
| 194 GetNewOperation(request_id)->Copy(src_path, dest_path); | 195 GetNewOperation(src_path, request_id)->Copy(src_path, dest_path); |
| 195 } | 196 } |
| 196 | 197 |
| 197 void FileSystemDispatcherHost::OnRemove( | 198 void FileSystemDispatcherHost::OnRemove( |
| 198 int request_id, const GURL& path, bool recursive) { | 199 int request_id, const GURL& path, bool recursive) { |
| 199 GetNewOperation(request_id)->Remove(path, recursive); | 200 GetNewOperation(path, request_id)->Remove(path, recursive); |
| 200 } | 201 } |
| 201 | 202 |
| 202 void FileSystemDispatcherHost::OnReadMetadata( | 203 void FileSystemDispatcherHost::OnReadMetadata( |
| 203 int request_id, const GURL& path) { | 204 int request_id, const GURL& path) { |
| 204 GetNewOperation(request_id)->GetMetadata(path); | 205 GetNewOperation(path, request_id)->GetMetadata(path); |
| 205 } | 206 } |
| 206 | 207 |
| 207 void FileSystemDispatcherHost::OnCreate( | 208 void FileSystemDispatcherHost::OnCreate( |
| 208 int request_id, const GURL& path, bool exclusive, | 209 int request_id, const GURL& path, bool exclusive, |
| 209 bool is_directory, bool recursive) { | 210 bool is_directory, bool recursive) { |
| 210 if (is_directory) | 211 if (is_directory) |
| 211 GetNewOperation(request_id)->CreateDirectory(path, exclusive, recursive); | 212 GetNewOperation(path, request_id)->CreateDirectory( |
| 213 path, exclusive, recursive); |
| 212 else | 214 else |
| 213 GetNewOperation(request_id)->CreateFile(path, exclusive); | 215 GetNewOperation(path, request_id)->CreateFile(path, exclusive); |
| 214 } | 216 } |
| 215 | 217 |
| 216 void FileSystemDispatcherHost::OnExists( | 218 void FileSystemDispatcherHost::OnExists( |
| 217 int request_id, const GURL& path, bool is_directory) { | 219 int request_id, const GURL& path, bool is_directory) { |
| 218 if (is_directory) | 220 if (is_directory) |
| 219 GetNewOperation(request_id)->DirectoryExists(path); | 221 GetNewOperation(path, request_id)->DirectoryExists(path); |
| 220 else | 222 else |
| 221 GetNewOperation(request_id)->FileExists(path); | 223 GetNewOperation(path, request_id)->FileExists(path); |
| 222 } | 224 } |
| 223 | 225 |
| 224 void FileSystemDispatcherHost::OnReadDirectory( | 226 void FileSystemDispatcherHost::OnReadDirectory( |
| 225 int request_id, const GURL& path) { | 227 int request_id, const GURL& path) { |
| 226 GetNewOperation(request_id)->ReadDirectory(path); | 228 GetNewOperation(path, request_id)->ReadDirectory(path); |
| 227 } | 229 } |
| 228 | 230 |
| 229 void FileSystemDispatcherHost::OnWrite( | 231 void FileSystemDispatcherHost::OnWrite( |
| 230 int request_id, | 232 int request_id, |
| 231 const GURL& path, | 233 const GURL& path, |
| 232 const GURL& blob_url, | 234 const GURL& blob_url, |
| 233 int64 offset) { | 235 int64 offset) { |
| 234 if (!request_context_) { | 236 if (!request_context_) { |
| 235 // We can't write w/o a request context, trying to do so will crash. | 237 // We can't write w/o a request context, trying to do so will crash. |
| 236 NOTREACHED(); | 238 NOTREACHED(); |
| 237 return; | 239 return; |
| 238 } | 240 } |
| 239 GetNewOperation(request_id)->Write( | 241 GetNewOperation(path, request_id)->Write( |
| 240 request_context_, path, blob_url, offset); | 242 request_context_, path, blob_url, offset); |
| 241 } | 243 } |
| 242 | 244 |
| 243 void FileSystemDispatcherHost::OnTruncate( | 245 void FileSystemDispatcherHost::OnTruncate( |
| 244 int request_id, | 246 int request_id, |
| 245 const GURL& path, | 247 const GURL& path, |
| 246 int64 length) { | 248 int64 length) { |
| 247 GetNewOperation(request_id)->Truncate(path, length); | 249 GetNewOperation(path, request_id)->Truncate(path, length); |
| 248 } | 250 } |
| 249 | 251 |
| 250 void FileSystemDispatcherHost::OnTouchFile( | 252 void FileSystemDispatcherHost::OnTouchFile( |
| 251 int request_id, | 253 int request_id, |
| 252 const GURL& path, | 254 const GURL& path, |
| 253 const base::Time& last_access_time, | 255 const base::Time& last_access_time, |
| 254 const base::Time& last_modified_time) { | 256 const base::Time& last_modified_time) { |
| 255 GetNewOperation(request_id)->TouchFile( | 257 GetNewOperation(path, request_id)->TouchFile( |
| 256 path, last_access_time, last_modified_time); | 258 path, last_access_time, last_modified_time); |
| 257 } | 259 } |
| 258 | 260 |
| 259 void FileSystemDispatcherHost::OnCancel( | 261 void FileSystemDispatcherHost::OnCancel( |
| 260 int request_id, | 262 int request_id, |
| 261 int request_id_to_cancel) { | 263 int request_id_to_cancel) { |
| 262 FileSystemOperation* write = operations_.Lookup( | 264 FileSystemOperationInterface* write = operations_.Lookup( |
| 263 request_id_to_cancel); | 265 request_id_to_cancel); |
| 264 if (write) { | 266 if (write) { |
| 265 // The cancel will eventually send both the write failure and the cancel | 267 // The cancel will eventually send both the write failure and the cancel |
| 266 // success. | 268 // success. |
| 267 write->Cancel( | 269 write->Cancel( |
| 268 BrowserFileSystemCallbackDispatcher::Create(this, request_id)); | 270 BrowserFileSystemCallbackDispatcher::Create(this, request_id)); |
| 269 } else { | 271 } else { |
| 270 // The write already finished; report that we failed to stop it. | 272 // The write already finished; report that we failed to stop it. |
| 271 Send(new FileSystemMsg_DidFail( | 273 Send(new FileSystemMsg_DidFail( |
| 272 request_id, base::PLATFORM_FILE_ERROR_INVALID_OPERATION)); | 274 request_id, base::PLATFORM_FILE_ERROR_INVALID_OPERATION)); |
| 273 } | 275 } |
| 274 } | 276 } |
| 275 | 277 |
| 276 void FileSystemDispatcherHost::OnOpenFile( | 278 void FileSystemDispatcherHost::OnOpenFile( |
| 277 int request_id, const GURL& path, int file_flags) { | 279 int request_id, const GURL& path, int file_flags) { |
| 278 GetNewOperation(request_id)->OpenFile(path, file_flags, peer_handle()); | 280 GetNewOperation(path, request_id)->OpenFile(path, file_flags, peer_handle()); |
| 279 } | 281 } |
| 280 | 282 |
| 281 void FileSystemDispatcherHost::OnWillUpdate(const GURL& path) { | 283 void FileSystemDispatcherHost::OnWillUpdate(const GURL& path) { |
| 282 GURL origin_url; | 284 GURL origin_url; |
| 283 fileapi::FileSystemType type; | 285 fileapi::FileSystemType type; |
| 284 if (!CrackFileSystemURL(path, &origin_url, &type, NULL)) | 286 if (!CrackFileSystemURL(path, &origin_url, &type, NULL)) |
| 285 return; | 287 return; |
| 286 fileapi::FileSystemQuotaUtil* quota_util = context_->GetQuotaUtil(type); | 288 fileapi::FileSystemQuotaUtil* quota_util = context_->GetQuotaUtil(type); |
| 287 if (!quota_util) | 289 if (!quota_util) |
| 288 return; | 290 return; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 301 context_->quota_manager_proxy(), origin_url, type, delta); | 303 context_->quota_manager_proxy(), origin_url, type, delta); |
| 302 quota_util->proxy()->EndUpdateOrigin(origin_url, type); | 304 quota_util->proxy()->EndUpdateOrigin(origin_url, type); |
| 303 } | 305 } |
| 304 | 306 |
| 305 void FileSystemDispatcherHost::OnSyncGetPlatformPath( | 307 void FileSystemDispatcherHost::OnSyncGetPlatformPath( |
| 306 const GURL& path, FilePath* platform_path) { | 308 const GURL& path, FilePath* platform_path) { |
| 307 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 309 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 308 DCHECK(platform_path); | 310 DCHECK(platform_path); |
| 309 *platform_path = FilePath(); | 311 *platform_path = FilePath(); |
| 310 | 312 |
| 311 FileSystemOperation* operation = new FileSystemOperation( | 313 GURL origin_url; |
| 312 scoped_ptr<FileSystemCallbackDispatcher>(NULL), | 314 fileapi::FileSystemType file_system_type = fileapi::kFileSystemTypeUnknown; |
| 313 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE), | 315 FilePath file_path; |
| 314 context_); | 316 if (!fileapi::CrackFileSystemURL( |
| 317 path, &origin_url, &file_system_type, &file_path)) { |
| 318 return; |
| 319 } |
| 315 | 320 |
| 321 // This is called only by pepper plugin as of writing to get the |
| 322 // underlying platform path to upload a file in the sandboxed filesystem |
| 323 // (e.g. TEMPORARY or PERSISTENT). |
| 324 // TODO(kinuko): this hack should go away once appropriate upload-stream |
| 325 // handling based on element types is supported. |
| 326 FileSystemOperation* operation = |
| 327 context_->CreateFileSystemOperation( |
| 328 path, scoped_ptr<FileSystemCallbackDispatcher>(NULL), |
| 329 BrowserThread::GetMessageLoopProxyForThread( |
| 330 BrowserThread::FILE))->AsFileSystemOperation(); |
| 331 DCHECK(operation); |
| 316 operation->SyncGetPlatformPath(path, platform_path); | 332 operation->SyncGetPlatformPath(path, platform_path); |
| 317 } | 333 } |
| 318 | 334 |
| 319 FileSystemOperation* FileSystemDispatcherHost::GetNewOperation( | 335 FileSystemOperationInterface* FileSystemDispatcherHost::GetNewOperation( |
| 336 const GURL& target_path, |
| 320 int request_id) { | 337 int request_id) { |
| 321 FileSystemOperation* operation = new FileSystemOperation( | 338 FileSystemOperationInterface* operation = |
| 322 BrowserFileSystemCallbackDispatcher::Create(this, request_id), | 339 context_->CreateFileSystemOperation( |
| 323 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE), | 340 target_path, |
| 324 context_); | 341 BrowserFileSystemCallbackDispatcher::Create(this, request_id), |
| 342 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)); |
| 343 DCHECK(operation); |
| 325 operations_.AddWithID(operation, request_id); | 344 operations_.AddWithID(operation, request_id); |
| 326 return operation; | 345 return operation; |
| 327 } | 346 } |
| 328 | 347 |
| 329 void FileSystemDispatcherHost::UnregisterOperation(int request_id) { | 348 void FileSystemDispatcherHost::UnregisterOperation(int request_id) { |
| 330 // For Cancel and OpenFileSystem we do not create an operation. | 349 // For Cancel and OpenFileSystem we do not create an operation. |
| 331 if (operations_.Lookup(request_id)) | 350 if (operations_.Lookup(request_id)) |
| 332 operations_.Remove(request_id); | 351 operations_.Remove(request_id); |
| 333 } | 352 } |
| OLD | NEW |