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/fileapi/fileapi_message_filter.h" | 5 #include "content/browser/fileapi/fileapi_message_filter.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
11 #include "base/file_path.h" | 11 #include "base/file_path.h" |
12 #include "base/memory/scoped_ptr.h" | 12 #include "base/memory/scoped_ptr.h" |
13 #include "base/platform_file.h" | 13 #include "base/platform_file.h" |
14 #include "base/threading/thread.h" | 14 #include "base/threading/thread.h" |
15 #include "base/time.h" | 15 #include "base/time.h" |
16 #include "content/browser/child_process_security_policy_impl.h" | 16 #include "content/browser/child_process_security_policy_impl.h" |
17 #include "content/browser/fileapi/chrome_blob_storage_context.h" | 17 #include "content/browser/fileapi/chrome_blob_storage_context.h" |
18 #include "content/common/fileapi/file_system_messages.h" | 18 #include "content/common/fileapi/file_system_messages.h" |
19 #include "content/common/fileapi/webblob_messages.h" | 19 #include "content/common/fileapi/webblob_messages.h" |
20 #include "content/public/browser/user_metrics.h" | 20 #include "content/public/browser/user_metrics.h" |
21 #include "googleurl/src/gurl.h" | 21 #include "googleurl/src/gurl.h" |
22 #include "ipc/ipc_platform_file.h" | 22 #include "ipc/ipc_platform_file.h" |
23 #include "net/base/mime_util.h" | 23 #include "net/base/mime_util.h" |
24 #include "net/url_request/url_request_context.h" | 24 #include "net/url_request/url_request_context.h" |
25 #include "net/url_request/url_request_context_getter.h" | 25 #include "net/url_request/url_request_context_getter.h" |
26 #include "webkit/blob/blob_data.h" | 26 #include "webkit/blob/blob_data.h" |
27 #include "webkit/blob/blob_storage_controller.h" | 27 #include "webkit/blob/blob_storage_context.h" |
28 #include "webkit/blob/shareable_file_reference.h" | 28 #include "webkit/blob/shareable_file_reference.h" |
29 #include "webkit/fileapi/file_observers.h" | 29 #include "webkit/fileapi/file_observers.h" |
30 #include "webkit/fileapi/file_system_context.h" | 30 #include "webkit/fileapi/file_system_context.h" |
31 #include "webkit/fileapi/file_system_types.h" | 31 #include "webkit/fileapi/file_system_types.h" |
32 #include "webkit/fileapi/file_system_util.h" | 32 #include "webkit/fileapi/file_system_util.h" |
33 #include "webkit/fileapi/isolated_context.h" | 33 #include "webkit/fileapi/isolated_context.h" |
34 #include "webkit/fileapi/local_file_system_operation.h" | 34 #include "webkit/fileapi/local_file_system_operation.h" |
35 #include "webkit/fileapi/sandbox_mount_point_provider.h" | 35 #include "webkit/fileapi/sandbox_mount_point_provider.h" |
36 | 36 |
37 using fileapi::FileSystemFileUtil; | 37 using fileapi::FileSystemFileUtil; |
38 using fileapi::FileSystemMountPointProvider; | 38 using fileapi::FileSystemMountPointProvider; |
39 using fileapi::FileSystemOperation; | 39 using fileapi::FileSystemOperation; |
40 using fileapi::FileSystemURL; | 40 using fileapi::FileSystemURL; |
41 using fileapi::FileUpdateObserver; | 41 using fileapi::FileUpdateObserver; |
42 using fileapi::LocalFileSystemOperation; | 42 using fileapi::LocalFileSystemOperation; |
43 using fileapi::UpdateObserverList; | 43 using fileapi::UpdateObserverList; |
44 using webkit_blob::BlobData; | 44 using webkit_blob::BlobData; |
45 using webkit_blob::BlobStorageController; | 45 using webkit_blob::BlobStorageContext; |
46 using webkit_blob::BlobStorageConsumer; | |
46 | 47 |
47 namespace content { | 48 namespace content { |
48 namespace { | 49 namespace { |
49 | 50 |
50 const int kReadFilePermissions = base::PLATFORM_FILE_OPEN | | 51 const int kReadFilePermissions = base::PLATFORM_FILE_OPEN | |
51 base::PLATFORM_FILE_READ | | 52 base::PLATFORM_FILE_READ | |
52 base::PLATFORM_FILE_EXCLUSIVE_READ | | 53 base::PLATFORM_FILE_EXCLUSIVE_READ | |
53 base::PLATFORM_FILE_ASYNC; | 54 base::PLATFORM_FILE_ASYNC; |
54 | 55 |
55 const int kWriteFilePermissions = base::PLATFORM_FILE_OPEN | | 56 const int kWriteFilePermissions = base::PLATFORM_FILE_OPEN | |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
107 | 108 |
108 void FileAPIMessageFilter::OnChannelConnected(int32 peer_pid) { | 109 void FileAPIMessageFilter::OnChannelConnected(int32 peer_pid) { |
109 BrowserMessageFilter::OnChannelConnected(peer_pid); | 110 BrowserMessageFilter::OnChannelConnected(peer_pid); |
110 | 111 |
111 if (request_context_getter_.get()) { | 112 if (request_context_getter_.get()) { |
112 DCHECK(!request_context_); | 113 DCHECK(!request_context_); |
113 request_context_ = request_context_getter_->GetURLRequestContext(); | 114 request_context_ = request_context_getter_->GetURLRequestContext(); |
114 request_context_getter_ = NULL; | 115 request_context_getter_ = NULL; |
115 DCHECK(request_context_); | 116 DCHECK(request_context_); |
116 } | 117 } |
118 | |
119 blob_storage_consumer_.reset( | |
120 new webkit_blob::BlobStorageConsumer(blob_storage_context_->context())); | |
117 } | 121 } |
118 | 122 |
119 void FileAPIMessageFilter::OnChannelClosing() { | 123 void FileAPIMessageFilter::OnChannelClosing() { |
120 BrowserMessageFilter::OnChannelClosing(); | 124 BrowserMessageFilter::OnChannelClosing(); |
121 | 125 |
122 // Unregister all the blob URLs that are previously registered in this | 126 blob_storage_consumer_.reset(); |
123 // process. | 127 in_transit_snapshot_files_.clear(); |
124 for (base::hash_set<std::string>::const_iterator iter = blob_urls_.begin(); | |
125 iter != blob_urls_.end(); ++iter) { | |
126 blob_storage_context_->controller()->RemoveBlob(GURL(*iter)); | |
127 } | |
128 | 128 |
129 // Close all files that are previously OpenFile()'ed in this process. | 129 // Close all files that are previously OpenFile()'ed in this process. |
130 if (!open_filesystem_urls_.empty()) { | 130 if (!open_filesystem_urls_.empty()) { |
131 DLOG(INFO) | 131 DLOG(INFO) |
132 << "File API: Renderer process shut down before NotifyCloseFile" | 132 << "File API: Renderer process shut down before NotifyCloseFile" |
133 << " for " << open_filesystem_urls_.size() << " files opened in PPAPI"; | 133 << " for " << open_filesystem_urls_.size() << " files opened in PPAPI"; |
134 } | 134 } |
135 for (std::multiset<GURL>::const_iterator iter = | 135 for (std::multiset<GURL>::const_iterator iter = |
136 open_filesystem_urls_.begin(); | 136 open_filesystem_urls_.begin(); |
137 iter != open_filesystem_urls_.end(); ++iter) { | 137 iter != open_filesystem_urls_.end(); ++iter) { |
(...skipping 27 matching lines...) Expand all Loading... | |
165 IPC_MESSAGE_HANDLER(FileSystemHostMsg_Exists, OnExists) | 165 IPC_MESSAGE_HANDLER(FileSystemHostMsg_Exists, OnExists) |
166 IPC_MESSAGE_HANDLER(FileSystemHostMsg_ReadDirectory, OnReadDirectory) | 166 IPC_MESSAGE_HANDLER(FileSystemHostMsg_ReadDirectory, OnReadDirectory) |
167 IPC_MESSAGE_HANDLER(FileSystemHostMsg_Write, OnWrite) | 167 IPC_MESSAGE_HANDLER(FileSystemHostMsg_Write, OnWrite) |
168 IPC_MESSAGE_HANDLER(FileSystemHostMsg_Truncate, OnTruncate) | 168 IPC_MESSAGE_HANDLER(FileSystemHostMsg_Truncate, OnTruncate) |
169 IPC_MESSAGE_HANDLER(FileSystemHostMsg_TouchFile, OnTouchFile) | 169 IPC_MESSAGE_HANDLER(FileSystemHostMsg_TouchFile, OnTouchFile) |
170 IPC_MESSAGE_HANDLER(FileSystemHostMsg_CancelWrite, OnCancel) | 170 IPC_MESSAGE_HANDLER(FileSystemHostMsg_CancelWrite, OnCancel) |
171 IPC_MESSAGE_HANDLER(FileSystemHostMsg_OpenFile, OnOpenFile) | 171 IPC_MESSAGE_HANDLER(FileSystemHostMsg_OpenFile, OnOpenFile) |
172 IPC_MESSAGE_HANDLER(FileSystemHostMsg_NotifyCloseFile, OnNotifyCloseFile) | 172 IPC_MESSAGE_HANDLER(FileSystemHostMsg_NotifyCloseFile, OnNotifyCloseFile) |
173 IPC_MESSAGE_HANDLER(FileSystemHostMsg_CreateSnapshotFile, | 173 IPC_MESSAGE_HANDLER(FileSystemHostMsg_CreateSnapshotFile, |
174 OnCreateSnapshotFile) | 174 OnCreateSnapshotFile) |
175 IPC_MESSAGE_HANDLER(FileSystemHostMsg_DidReceiveSnapshotFile, | |
176 OnDidReceiveSnapshotFile) | |
175 IPC_MESSAGE_HANDLER(FileSystemHostMsg_WillUpdate, OnWillUpdate) | 177 IPC_MESSAGE_HANDLER(FileSystemHostMsg_WillUpdate, OnWillUpdate) |
176 IPC_MESSAGE_HANDLER(FileSystemHostMsg_DidUpdate, OnDidUpdate) | 178 IPC_MESSAGE_HANDLER(FileSystemHostMsg_DidUpdate, OnDidUpdate) |
177 IPC_MESSAGE_HANDLER(FileSystemHostMsg_SyncGetPlatformPath, | 179 IPC_MESSAGE_HANDLER(FileSystemHostMsg_SyncGetPlatformPath, |
178 OnSyncGetPlatformPath) | 180 OnSyncGetPlatformPath) |
179 IPC_MESSAGE_HANDLER(BlobHostMsg_StartBuildingBlob, OnStartBuildingBlob) | 181 IPC_MESSAGE_HANDLER(BlobHostMsg_StartBuildingBlob2, OnStartBuildingBlob2) |
180 IPC_MESSAGE_HANDLER(BlobHostMsg_AppendBlobDataItem, OnAppendBlobDataItem) | 182 IPC_MESSAGE_HANDLER(BlobHostMsg_AppendBlobDataItem2, OnAppendBlobDataItem2) |
181 IPC_MESSAGE_HANDLER(BlobHostMsg_SyncAppendSharedMemory, | 183 IPC_MESSAGE_HANDLER(BlobHostMsg_AppendSharedMemory2, |
182 OnAppendSharedMemory) | 184 OnAppendSharedMemory2) |
183 IPC_MESSAGE_HANDLER(BlobHostMsg_FinishBuildingBlob, OnFinishBuildingBlob) | 185 IPC_MESSAGE_HANDLER(BlobHostMsg_FinishBuildingBlob2, OnFinishBuildingBlob2) |
184 IPC_MESSAGE_HANDLER(BlobHostMsg_CloneBlob, OnCloneBlob) | 186 IPC_MESSAGE_HANDLER(BlobHostMsg_IncrementBlobRefCount, |
185 IPC_MESSAGE_HANDLER(BlobHostMsg_RemoveBlob, OnRemoveBlob) | 187 OnIncrementBlobRefCount) |
188 IPC_MESSAGE_HANDLER(BlobHostMsg_DecrementBlobRefCount, | |
189 OnDecrementBlobRefCount) | |
190 IPC_MESSAGE_HANDLER(BlobHostMsg_RegisterPublicBlobURL, | |
191 OnRegisterPublicBlobURL) | |
192 IPC_MESSAGE_HANDLER(BlobHostMsg_RevokePublicBlobURL, OnRevokePublicBlobURL) | |
186 IPC_MESSAGE_UNHANDLED(handled = false) | 193 IPC_MESSAGE_UNHANDLED(handled = false) |
187 IPC_END_MESSAGE_MAP_EX() | 194 IPC_END_MESSAGE_MAP_EX() |
188 return handled; | 195 return handled; |
189 } | 196 } |
190 | 197 |
191 void FileAPIMessageFilter::UnregisterOperation(int request_id) { | 198 void FileAPIMessageFilter::UnregisterOperation(int request_id) { |
192 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 199 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
193 DCHECK(operations_.Lookup(request_id)); | 200 DCHECK(operations_.Lookup(request_id)); |
194 operations_.Remove(request_id); | 201 operations_.Remove(request_id); |
195 } | 202 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
229 base::PlatformFileError error; | 236 base::PlatformFileError error; |
230 FileSystemURL src_url(src_path); | 237 FileSystemURL src_url(src_path); |
231 FileSystemURL dest_url(dest_path); | 238 FileSystemURL dest_url(dest_path); |
232 const int src_permissions = kReadFilePermissions | kWriteFilePermissions; | 239 const int src_permissions = kReadFilePermissions | kWriteFilePermissions; |
233 if (!HasPermissionsForFile(src_url, src_permissions, &error) || | 240 if (!HasPermissionsForFile(src_url, src_permissions, &error) || |
234 !HasPermissionsForFile(dest_url, kCreateFilePermissions, &error)) { | 241 !HasPermissionsForFile(dest_url, kCreateFilePermissions, &error)) { |
235 Send(new FileSystemMsg_DidFail(request_id, error)); | 242 Send(new FileSystemMsg_DidFail(request_id, error)); |
236 return; | 243 return; |
237 } | 244 } |
238 | 245 |
239 FileSystemOperation* operation = GetNewOperation(dest_url, request_id); | 246 FileSystemOperation* operation = GetNewOperation(src_url, request_id); |
kinuko
2013/01/07 08:52:01
note: in the current code this needs to take dest_
michaeln
2013/01/25 21:19:44
Done.
| |
240 if (!operation) | 247 if (!operation) |
241 return; | 248 return; |
242 operation->Move( | 249 operation->Move( |
243 src_url, dest_url, | 250 src_url, dest_url, |
244 base::Bind(&FileAPIMessageFilter::DidFinish, this, request_id)); | 251 base::Bind(&FileAPIMessageFilter::DidFinish, this, request_id)); |
245 } | 252 } |
246 | 253 |
247 void FileAPIMessageFilter::OnCopy( | 254 void FileAPIMessageFilter::OnCopy( |
248 int request_id, const GURL& src_path, const GURL& dest_path) { | 255 int request_id, const GURL& src_path, const GURL& dest_path) { |
249 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 256 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
250 base::PlatformFileError error; | 257 base::PlatformFileError error; |
251 FileSystemURL src_url(src_path); | 258 FileSystemURL src_url(src_path); |
252 FileSystemURL dest_url(dest_path); | 259 FileSystemURL dest_url(dest_path); |
253 if (!HasPermissionsForFile(src_url, kReadFilePermissions, &error) || | 260 if (!HasPermissionsForFile(src_url, kReadFilePermissions, &error) || |
254 !HasPermissionsForFile(dest_url, kCreateFilePermissions, &error)) { | 261 !HasPermissionsForFile(dest_url, kCreateFilePermissions, &error)) { |
255 Send(new FileSystemMsg_DidFail(request_id, error)); | 262 Send(new FileSystemMsg_DidFail(request_id, error)); |
256 return; | 263 return; |
257 } | 264 } |
258 | 265 |
259 FileSystemOperation* operation = GetNewOperation(dest_url, request_id); | 266 FileSystemOperation* operation = GetNewOperation(src_url, request_id); |
kinuko
2013/01/07 08:52:01
ditto
michaeln
2013/01/25 21:19:44
Done.
| |
260 if (!operation) | 267 if (!operation) |
261 return; | 268 return; |
262 operation->Copy( | 269 operation->Copy( |
263 src_url, dest_url, | 270 src_url, dest_url, |
264 base::Bind(&FileAPIMessageFilter::DidFinish, this, request_id)); | 271 base::Bind(&FileAPIMessageFilter::DidFinish, this, request_id)); |
265 } | 272 } |
266 | 273 |
267 void FileAPIMessageFilter::OnRemove( | 274 void FileAPIMessageFilter::OnRemove( |
268 int request_id, const GURL& path, bool recursive) { | 275 int request_id, const GURL& path, bool recursive) { |
269 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 276 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
363 if (!operation) | 370 if (!operation) |
364 return; | 371 return; |
365 operation->ReadDirectory( | 372 operation->ReadDirectory( |
366 url, base::Bind(&FileAPIMessageFilter::DidReadDirectory, | 373 url, base::Bind(&FileAPIMessageFilter::DidReadDirectory, |
367 this, request_id)); | 374 this, request_id)); |
368 } | 375 } |
369 | 376 |
370 void FileAPIMessageFilter::OnWrite( | 377 void FileAPIMessageFilter::OnWrite( |
371 int request_id, | 378 int request_id, |
372 const GURL& path, | 379 const GURL& path, |
373 const GURL& blob_url, | 380 const std::string& blob_uuid, |
374 int64 offset) { | 381 int64 offset) { |
375 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 382 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
376 if (!request_context_) { | 383 if (!request_context_) { |
377 // We can't write w/o a request context, trying to do so will crash. | 384 // We can't write w/o a request context, trying to do so will crash. |
378 NOTREACHED(); | 385 NOTREACHED(); |
379 return; | 386 return; |
380 } | 387 } |
381 | 388 |
382 FileSystemURL url(path); | 389 FileSystemURL url(path); |
383 base::PlatformFileError error; | 390 base::PlatformFileError error; |
384 if (!HasPermissionsForFile(url, kWriteFilePermissions, &error)) { | 391 if (!HasPermissionsForFile(url, kWriteFilePermissions, &error)) { |
385 Send(new FileSystemMsg_DidFail(request_id, error)); | 392 Send(new FileSystemMsg_DidFail(request_id, error)); |
386 return; | 393 return; |
387 } | 394 } |
388 | 395 |
389 FileSystemOperation* operation = GetNewOperation(url, request_id); | 396 FileSystemOperation* operation = GetNewOperation(url, request_id); |
390 if (!operation) | 397 if (!operation) |
391 return; | 398 return; |
399 scoped_ptr<webkit_blob::BlobDataHandle> blob = | |
400 blob_storage_context_->context()->GetBlobDataFromUUID(blob_uuid); | |
392 operation->Write( | 401 operation->Write( |
393 request_context_, url, blob_url, offset, | 402 request_context_, url, blob.Pass(), offset, |
394 base::Bind(&FileAPIMessageFilter::DidWrite, this, request_id)); | 403 base::Bind(&FileAPIMessageFilter::DidWrite, this, request_id)); |
395 } | 404 } |
396 | 405 |
397 void FileAPIMessageFilter::OnTruncate( | 406 void FileAPIMessageFilter::OnTruncate( |
398 int request_id, | 407 int request_id, |
399 const GURL& path, | 408 const GURL& path, |
400 int64 length) { | 409 int64 length) { |
401 base::PlatformFileError error; | 410 base::PlatformFileError error; |
402 FileSystemURL url(path); | 411 FileSystemURL url(path); |
403 if (!HasPermissionsForFile(url, kWriteFilePermissions, &error)) { | 412 if (!HasPermissionsForFile(url, kWriteFilePermissions, &error)) { |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
536 // (e.g. TEMPORARY or PERSISTENT). | 545 // (e.g. TEMPORARY or PERSISTENT). |
537 // TODO(kinuko): this hack should go away once appropriate upload-stream | 546 // TODO(kinuko): this hack should go away once appropriate upload-stream |
538 // handling based on element types is supported. | 547 // handling based on element types is supported. |
539 LocalFileSystemOperation* operation = | 548 LocalFileSystemOperation* operation = |
540 context_->CreateFileSystemOperation( | 549 context_->CreateFileSystemOperation( |
541 url, NULL)->AsLocalFileSystemOperation(); | 550 url, NULL)->AsLocalFileSystemOperation(); |
542 DCHECK(operation); | 551 DCHECK(operation); |
543 if (!operation) | 552 if (!operation) |
544 return; | 553 return; |
545 | 554 |
546 operation->SyncGetPlatformPath(url, platform_path); | 555 operation->SyncGetPlatformPath(url, platform_path); |
kinuko
2013/01/07 08:52:01
nit: indent is off
michaeln
2013/01/25 21:19:44
Done.
| |
547 | 556 |
548 // The path is to be attached to URLLoader so we grant read permission | 557 // The path is to be attached to URLLoader so we grant read permission |
549 // for the file. (We first need to check if it can already be read not to | 558 // for the file. (We first need to check if it can already be read not to |
550 // overwrite existing permissions) | 559 // overwrite existing permissions) |
551 if (!ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile( | 560 if (!ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile( |
552 process_id_, *platform_path)) { | 561 process_id_, *platform_path)) { |
553 ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile( | 562 ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile( |
554 process_id_, *platform_path); | 563 process_id_, *platform_path); |
555 } | 564 } |
556 } | 565 } |
557 | 566 |
558 void FileAPIMessageFilter::OnCreateSnapshotFile( | 567 void FileAPIMessageFilter::OnCreateSnapshotFile( |
559 int request_id, const GURL& blob_url, const GURL& path) { | 568 int request_id, const GURL& path) { |
560 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 569 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
561 FileSystemURL url(path); | 570 FileSystemURL url(path); |
562 base::Callback<void(const FilePath&)> register_file_callback = | |
563 base::Bind(&FileAPIMessageFilter::RegisterFileAsBlob, | |
564 this, blob_url, url); | |
565 | 571 |
566 // Make sure if this file can be read by the renderer as this is | 572 // Make sure if this file can be read by the renderer as this is |
567 // called when the renderer is about to create a new File object | 573 // called when the renderer is about to create a new File object |
568 // (for reading the file). | 574 // (for reading the file). |
569 base::PlatformFileError error; | 575 base::PlatformFileError error; |
570 if (!HasPermissionsForFile(url, kReadFilePermissions, &error)) { | 576 if (!HasPermissionsForFile(url, kReadFilePermissions, &error)) { |
571 Send(new FileSystemMsg_DidFail(request_id, error)); | 577 Send(new FileSystemMsg_DidFail(request_id, error)); |
572 return; | 578 return; |
573 } | 579 } |
574 | 580 |
575 FileSystemOperation* operation = GetNewOperation(url, request_id); | 581 FileSystemOperation* operation = GetNewOperation(url, request_id); |
576 if (!operation) | 582 if (!operation) |
577 return; | 583 return; |
578 operation->CreateSnapshotFile( | 584 operation->CreateSnapshotFile( |
579 url, | 585 url, |
580 base::Bind(&FileAPIMessageFilter::DidCreateSnapshot, | 586 base::Bind(&FileAPIMessageFilter::DidCreateSnapshot, |
581 this, request_id, register_file_callback)); | 587 this, url, request_id)); |
582 } | 588 } |
583 | 589 |
584 void FileAPIMessageFilter::OnStartBuildingBlob(const GURL& url) { | 590 void FileAPIMessageFilter::OnDidReceiveSnapshotFile(int request_id) { |
585 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 591 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
586 blob_storage_context_->controller()->StartBuildingBlob(url); | 592 in_transit_snapshot_files_.erase(request_id); |
587 blob_urls_.insert(url.spec()); | |
588 } | 593 } |
589 | 594 |
590 void FileAPIMessageFilter::OnAppendBlobDataItem( | 595 void FileAPIMessageFilter::OnStartBuildingBlob2(const std::string& uuid) { |
591 const GURL& url, const BlobData::Item& item) { | 596 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
597 blob_storage_consumer_->StartBuildingBlob(uuid); | |
598 } | |
599 | |
600 void FileAPIMessageFilter::OnAppendBlobDataItem2( | |
601 const std::string& uuid, const webkit_blob::BlobData::Item& item) { | |
592 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 602 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
593 // TODO(kinuko): We must check permission in TYPE_FILE_FILESYSTEM cases too. | 603 // TODO(kinuko): We must check permission in TYPE_FILE_FILESYSTEM cases too. |
594 // http://crbug.com/141827 | 604 // http://crbug.com/141827 |
595 if (item.type() == BlobData::Item::TYPE_FILE && | 605 if (item.type() == BlobData::Item::TYPE_FILE && |
596 !ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile( | 606 !ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile( |
597 process_id_, item.path())) { | 607 process_id_, item.path())) { |
598 OnRemoveBlob(url); | 608 blob_storage_consumer_->CancelBuildingBlob(uuid); |
599 return; | 609 return; |
600 } | 610 } |
601 if (item.length() == 0) { | 611 if (item.length() == 0) { |
602 BadMessageReceived(); | 612 BadMessageReceived(); |
603 return; | 613 return; |
604 } | 614 } |
605 blob_storage_context_->controller()->AppendBlobDataItem(url, item); | 615 blob_storage_consumer_->AppendBlobDataItem(uuid, item); |
606 } | 616 } |
607 | 617 |
608 void FileAPIMessageFilter::OnAppendSharedMemory( | 618 void FileAPIMessageFilter::OnAppendSharedMemory2( |
609 const GURL& url, base::SharedMemoryHandle handle, size_t buffer_size) { | 619 const std::string& uuid, |
620 base::SharedMemoryHandle handle, | |
621 size_t buffer_size) { | |
610 DCHECK(base::SharedMemory::IsHandleValid(handle)); | 622 DCHECK(base::SharedMemory::IsHandleValid(handle)); |
611 if (!buffer_size) { | 623 if (!buffer_size) { |
612 BadMessageReceived(); | 624 BadMessageReceived(); |
613 return; | 625 return; |
614 } | 626 } |
615 #if defined(OS_WIN) | 627 #if defined(OS_WIN) |
616 base::SharedMemory shared_memory(handle, true, peer_handle()); | 628 base::SharedMemory shared_memory(handle, true, peer_handle()); |
617 #else | 629 #else |
618 base::SharedMemory shared_memory(handle, true); | 630 base::SharedMemory shared_memory(handle, true); |
619 #endif | 631 #endif |
620 if (!shared_memory.Map(buffer_size)) { | 632 if (!shared_memory.Map(buffer_size)) { |
621 OnRemoveBlob(url); | 633 blob_storage_consumer_->CancelBuildingBlob(uuid); |
622 return; | 634 return; |
623 } | 635 } |
624 | 636 |
625 BlobData::Item item; | 637 BlobData::Item item; |
626 item.SetToSharedBytes(static_cast<char*>(shared_memory.memory()), | 638 item.SetToSharedBytes(static_cast<char*>(shared_memory.memory()), |
627 buffer_size); | 639 buffer_size); |
628 blob_storage_context_->controller()->AppendBlobDataItem(url, item); | 640 blob_storage_consumer_->AppendBlobDataItem(uuid, item); |
629 } | 641 } |
630 | 642 |
631 void FileAPIMessageFilter::OnFinishBuildingBlob( | 643 void FileAPIMessageFilter::OnFinishBuildingBlob2(const std::string& uuid, |
632 const GURL& url, const std::string& content_type) { | 644 const std::string& content_type) { |
633 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 645 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
634 blob_storage_context_->controller()->FinishBuildingBlob(url, content_type); | 646 blob_storage_consumer_->FinishBuildingBlob(uuid, content_type); |
635 } | 647 } |
636 | 648 |
637 void FileAPIMessageFilter::OnCloneBlob( | 649 void FileAPIMessageFilter::OnIncrementBlobRefCount(const std::string& uuid) { |
638 const GURL& url, const GURL& src_url) { | |
639 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 650 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
640 blob_storage_context_->controller()->CloneBlob(url, src_url); | 651 blob_storage_consumer_->IncrementBlobRefCount(uuid); |
641 blob_urls_.insert(url.spec()); | |
642 } | 652 } |
643 | 653 |
644 void FileAPIMessageFilter::OnRemoveBlob(const GURL& url) { | 654 void FileAPIMessageFilter::OnDecrementBlobRefCount(const std::string& uuid) { |
645 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 655 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
646 blob_storage_context_->controller()->RemoveBlob(url); | 656 blob_storage_consumer_->DecrementBlobRefCount(uuid); |
647 blob_urls_.erase(url.spec()); | 657 } |
658 | |
659 void FileAPIMessageFilter::OnRegisterPublicBlobURL( | |
660 const GURL& public_url, const std::string& uuid) { | |
661 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
662 blob_storage_consumer_->RegisterPublicBlobURL(public_url, uuid); | |
663 } | |
664 | |
665 void FileAPIMessageFilter::OnRevokePublicBlobURL(const GURL& public_url) { | |
666 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
667 blob_storage_consumer_->RevokePublicBlobURL(public_url); | |
648 } | 668 } |
649 | 669 |
650 void FileAPIMessageFilter::DidFinish(int request_id, | 670 void FileAPIMessageFilter::DidFinish(int request_id, |
651 base::PlatformFileError result) { | 671 base::PlatformFileError result) { |
652 if (result == base::PLATFORM_FILE_OK) | 672 if (result == base::PLATFORM_FILE_OK) |
653 Send(new FileSystemMsg_DidSucceed(request_id)); | 673 Send(new FileSystemMsg_DidSucceed(request_id)); |
654 else | 674 else |
655 Send(new FileSystemMsg_DidFail(request_id, result)); | 675 Send(new FileSystemMsg_DidFail(request_id, result)); |
656 UnregisterOperation(request_id); | 676 UnregisterOperation(request_id); |
657 } | 677 } |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
741 base::PlatformFileError result) { | 761 base::PlatformFileError result) { |
742 if (result == base::PLATFORM_FILE_OK) | 762 if (result == base::PLATFORM_FILE_OK) |
743 Send(new FileSystemMsg_DidSucceed(request_id)); | 763 Send(new FileSystemMsg_DidSucceed(request_id)); |
744 else | 764 else |
745 Send(new FileSystemMsg_DidFail(request_id, result)); | 765 Send(new FileSystemMsg_DidFail(request_id, result)); |
746 // For DeleteFileSystem we do not create a new operation, | 766 // For DeleteFileSystem we do not create a new operation, |
747 // so no unregister here. | 767 // so no unregister here. |
748 } | 768 } |
749 | 769 |
750 void FileAPIMessageFilter::DidCreateSnapshot( | 770 void FileAPIMessageFilter::DidCreateSnapshot( |
771 const FileSystemURL& url, | |
751 int request_id, | 772 int request_id, |
752 const base::Callback<void(const FilePath&)>& register_file_callback, | |
753 base::PlatformFileError result, | 773 base::PlatformFileError result, |
754 const base::PlatformFileInfo& info, | 774 const base::PlatformFileInfo& info, |
755 const FilePath& platform_path, | 775 const FilePath& platform_path, |
756 const scoped_refptr<webkit_blob::ShareableFileReference>& unused) { | 776 const scoped_refptr<webkit_blob::ShareableFileReference>& snaphot_file) { |
757 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 777 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
758 if (result != base::PLATFORM_FILE_OK) { | 778 if (result != base::PLATFORM_FILE_OK) { |
759 Send(new FileSystemMsg_DidFail(request_id, result)); | 779 Send(new FileSystemMsg_DidFail(request_id, result)); |
760 return; | 780 return; |
761 } | 781 } |
762 | 782 |
763 // Register the created file to the blob registry by calling | |
764 // RegisterFileAsBlob. | |
765 // Blob storage automatically finds and refs the file_ref, so we don't | |
766 // need to do anything for the returned file reference (|unused|) here. | |
767 register_file_callback.Run(platform_path); | |
768 | |
769 // Return the file info and platform_path. | |
770 Send(new FileSystemMsg_DidReadMetadata(request_id, info, platform_path)); | |
771 } | |
772 | |
773 void FileAPIMessageFilter::RegisterFileAsBlob(const GURL& blob_url, | |
774 const FileSystemURL& url, | |
775 const FilePath& platform_path) { | |
776 // Use the virtual path's extension to determine MIME type. | |
777 FilePath::StringType extension = url.path().Extension(); | |
778 if (!extension.empty()) | |
779 extension = extension.substr(1); // Strip leading ".". | |
780 | |
781 scoped_refptr<webkit_blob::ShareableFileReference> shareable_file = | |
782 webkit_blob::ShareableFileReference::Get(platform_path); | |
783 if (!ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile( | 783 if (!ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile( |
784 process_id_, platform_path)) { | 784 process_id_, platform_path)) { |
785 // If the underlying file system implementation is returning a new | 785 // If the underlying file system implementation is returning a new |
786 // (likely temporary) snapshot file or the file is for sandboxed | 786 // (likely temporary) snapshot file or the file is for sandboxed |
787 // filesystems it's ok to grant permission here. | 787 // filesystems it's ok to grant permission here. |
788 // (Note that we have also already checked if the renderer has the | 788 // (Note that we have also already checked if the renderer has the |
789 // read permission for this file in OnCreateSnapshotFile.) | 789 // read permission for this file in OnCreateSnapshotFile.) |
790 DCHECK(shareable_file || | 790 DCHECK(snaphot_file || |
791 fileapi::SandboxMountPointProvider::CanHandleType(url.type())); | 791 fileapi::SandboxMountPointProvider::CanHandleType(url.type())); |
792 ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile( | 792 ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile( |
793 process_id_, platform_path); | 793 process_id_, platform_path); |
794 if (shareable_file) { | 794 if (snaphot_file) { |
795 // This will revoke all permissions for the file when the last ref | 795 // This will revoke all permissions for the file when the last ref |
796 // of the file is dropped (assuming it's ok). | 796 // of the file is dropped (assuming it's ok). |
797 shareable_file->AddFinalReleaseCallback( | 797 snaphot_file->AddFinalReleaseCallback( |
798 base::Bind(&RevokeFilePermission, process_id_)); | 798 base::Bind(&RevokeFilePermission, process_id_)); |
799 } | 799 } |
800 } | 800 } |
801 | 801 |
802 // This may fail, but then we'll be just setting the empty mime type. | 802 if (snaphot_file) { |
803 std::string mime_type; | 803 // This ref is held until OnDidReceiveSnapshotFile is called. By holding |
804 net::GetWellKnownMimeTypeFromExtension(extension, &mime_type); | 804 // this ref we ensure that the file is not deleted prior to the renderer |
805 BlobData::Item item; | 805 // having created a webcore blob data handle that refers to this file |
806 item.SetToFilePathRange(platform_path, 0, -1, base::Time()); | 806 // and takes a ref of its own. |
kinuko
2013/01/07 08:52:01
nit: extra space before 'a ref'
michaeln
2013/01/25 21:19:44
Done.
| |
807 BlobStorageController* controller = blob_storage_context_->controller(); | 807 in_transit_snapshot_files_[request_id] = snaphot_file; |
808 controller->StartBuildingBlob(blob_url); | 808 } |
809 controller->AppendBlobDataItem(blob_url, item); | 809 |
810 controller->FinishBuildingBlob(blob_url, mime_type); | 810 // Return the file info and platform_path. |
811 blob_urls_.insert(blob_url.spec()); | 811 Send(new FileSystemMsg_DidCreateSnapshotFile( |
812 request_id, info, platform_path)); | |
812 } | 813 } |
813 | 814 |
814 bool FileAPIMessageFilter::HasPermissionsForFile( | 815 bool FileAPIMessageFilter::HasPermissionsForFile( |
815 const FileSystemURL& url, int permissions, base::PlatformFileError* error) { | 816 const FileSystemURL& url, int permissions, base::PlatformFileError* error) { |
816 DCHECK(error); | 817 DCHECK(error); |
817 *error = base::PLATFORM_FILE_OK; | 818 *error = base::PLATFORM_FILE_OK; |
818 | 819 |
819 if (!url.is_valid()) { | 820 if (!url.is_valid()) { |
820 *error = base::PLATFORM_FILE_ERROR_INVALID_URL; | 821 *error = base::PLATFORM_FILE_ERROR_INVALID_URL; |
821 return false; | 822 return false; |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
885 Send(new FileSystemMsg_DidFail(request_id, error_code)); | 886 Send(new FileSystemMsg_DidFail(request_id, error_code)); |
886 return NULL; | 887 return NULL; |
887 } | 888 } |
888 | 889 |
889 DCHECK(operation); | 890 DCHECK(operation); |
890 operations_.AddWithID(operation, request_id); | 891 operations_.AddWithID(operation, request_id); |
891 return operation; | 892 return operation; |
892 } | 893 } |
893 | 894 |
894 } // namespace content | 895 } // namespace content |
OLD | NEW |