[email protected] | 60f60f8 | 2012-01-11 10:26:10 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
[email protected] | eafe4049 | 2013-06-04 18:12:45 | [diff] [blame] | 5 | #include "webkit/support/simple_file_writer.h" |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 6 | |
[email protected] | 2de5530 | 2011-10-10 22:09:58 | [diff] [blame] | 7 | #include "base/bind.h" |
[email protected] | 4aefec14 | 2012-04-23 21:23:04 | [diff] [blame] | 8 | #include "base/location.h" |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 9 | #include "base/logging.h" |
| 10 | #include "base/message_loop_proxy.h" |
| 11 | #include "net/url_request/url_request_context.h" |
[email protected] | c6f9203a | 2013-05-28 02:08:07 | [diff] [blame] | 12 | #include "webkit/browser/fileapi/file_system_context.h" |
[email protected] | 3a7bf22 | 2013-06-09 14:14:12 | [diff] [blame^] | 13 | #include "webkit/browser/fileapi/file_system_operation_runner.h" |
[email protected] | c6f9203a | 2013-05-28 02:08:07 | [diff] [blame] | 14 | #include "webkit/browser/fileapi/file_system_url.h" |
[email protected] | 61d271f3 | 2013-05-28 04:59:23 | [diff] [blame] | 15 | #include "webkit/common/fileapi/file_system_types.h" |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 16 | #include "webkit/glue/webkit_glue.h" |
[email protected] | eafe4049 | 2013-06-04 18:12:45 | [diff] [blame] | 17 | #include "webkit/support/simple_resource_loader_bridge.h" |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 18 | |
[email protected] | 949f25a | 2012-06-27 01:53:09 | [diff] [blame] | 19 | using fileapi::FileSystemURL; |
[email protected] | 073a04f | 2011-03-24 00:49:40 | [diff] [blame] | 20 | using fileapi::FileSystemContext; |
[email protected] | 3a7bf22 | 2013-06-09 14:14:12 | [diff] [blame^] | 21 | using fileapi::FileSystemOperationRunner; |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 22 | using fileapi::WebFileWriterBase; |
| 23 | using WebKit::WebFileWriterClient; |
| 24 | using WebKit::WebString; |
| 25 | using WebKit::WebURL; |
| 26 | |
[email protected] | aeb53f0 | 2011-01-15 00:21:34 | [diff] [blame] | 27 | net::URLRequestContext* SimpleFileWriter::request_context_ = NULL; |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 28 | |
| 29 | // Helper class to proxy to write and truncate calls to the IO thread, |
| 30 | // and to proxy the results back to the main thead. There is a one-to-one |
| 31 | // relationship between SimpleFileWriters and IOThreadBackends. |
| 32 | class SimpleFileWriter::IOThreadProxy |
| 33 | : public base::RefCountedThreadSafe<SimpleFileWriter::IOThreadProxy> { |
| 34 | public: |
[email protected] | e7e3803 | 2011-07-26 17:25:25 | [diff] [blame] | 35 | IOThreadProxy(const base::WeakPtr<SimpleFileWriter>& simple_writer, |
| 36 | FileSystemContext* file_system_context) |
[email protected] | 103c8d4 | 2010-11-30 18:58:13 | [diff] [blame] | 37 | : simple_writer_(simple_writer), |
[email protected] | 3a7bf22 | 2013-06-09 14:14:12 | [diff] [blame^] | 38 | operation_id_(FileSystemOperationRunner::kErrorOperationID), |
[email protected] | 073a04f | 2011-03-24 00:49:40 | [diff] [blame] | 39 | file_system_context_(file_system_context) { |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 40 | // The IO thread needs to be running for this class to work. |
| 41 | SimpleResourceLoaderBridge::EnsureIOThread(); |
| 42 | io_thread_ = SimpleResourceLoaderBridge::GetIoThread(); |
[email protected] | edd685f | 2011-08-15 20:33:46 | [diff] [blame] | 43 | main_thread_ = base::MessageLoopProxy::current(); |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 44 | } |
| 45 | |
[email protected] | d65c8215e | 2012-06-30 08:36:55 | [diff] [blame] | 46 | void Truncate(const FileSystemURL& url, int64 offset) { |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 47 | if (!io_thread_->BelongsToCurrentThread()) { |
[email protected] | 2de5530 | 2011-10-10 22:09:58 | [diff] [blame] | 48 | io_thread_->PostTask( |
| 49 | FROM_HERE, |
[email protected] | d65c8215e | 2012-06-30 08:36:55 | [diff] [blame] | 50 | base::Bind(&IOThreadProxy::Truncate, this, url, offset)); |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 51 | return; |
| 52 | } |
[email protected] | d65c8215e | 2012-06-30 08:36:55 | [diff] [blame] | 53 | if (FailIfNotWritable(url)) |
| 54 | return; |
[email protected] | 3a7bf22 | 2013-06-09 14:14:12 | [diff] [blame^] | 55 | DCHECK_EQ(FileSystemOperationRunner::kErrorOperationID, operation_id_); |
| 56 | operation_id_ = file_system_context_->operation_runner()->Truncate( |
| 57 | url, offset, base::Bind(&IOThreadProxy::DidFinish, this)); |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 58 | } |
| 59 | |
[email protected] | d65c8215e | 2012-06-30 08:36:55 | [diff] [blame] | 60 | void Write(const FileSystemURL& url, const GURL& blob_url, int64 offset) { |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 61 | if (!io_thread_->BelongsToCurrentThread()) { |
[email protected] | 2de5530 | 2011-10-10 22:09:58 | [diff] [blame] | 62 | io_thread_->PostTask( |
| 63 | FROM_HERE, |
[email protected] | d65c8215e | 2012-06-30 08:36:55 | [diff] [blame] | 64 | base::Bind(&IOThreadProxy::Write, this, url, blob_url, offset)); |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 65 | return; |
| 66 | } |
[email protected] | d65c8215e | 2012-06-30 08:36:55 | [diff] [blame] | 67 | if (FailIfNotWritable(url)) |
| 68 | return; |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 69 | DCHECK(request_context_); |
[email protected] | 3a7bf22 | 2013-06-09 14:14:12 | [diff] [blame^] | 70 | DCHECK_EQ(FileSystemOperationRunner::kErrorOperationID, operation_id_); |
| 71 | operation_id_ = file_system_context_->operation_runner()->Write( |
| 72 | request_context_, url, blob_url, offset, |
| 73 | base::Bind(&IOThreadProxy::DidWrite, this)); |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 74 | } |
| 75 | |
| 76 | void Cancel() { |
| 77 | if (!io_thread_->BelongsToCurrentThread()) { |
[email protected] | 2de5530 | 2011-10-10 22:09:58 | [diff] [blame] | 78 | io_thread_->PostTask( |
| 79 | FROM_HERE, |
| 80 | base::Bind(&IOThreadProxy::Cancel, this)); |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 81 | return; |
| 82 | } |
[email protected] | 3a7bf22 | 2013-06-09 14:14:12 | [diff] [blame^] | 83 | if (operation_id_ == FileSystemOperationRunner::kErrorOperationID) { |
[email protected] | 81f8a3d | 2012-02-14 08:40:37 | [diff] [blame] | 84 | DidFailOnMainThread(base::PLATFORM_FILE_ERROR_INVALID_OPERATION); |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 85 | return; |
| 86 | } |
[email protected] | 3a7bf22 | 2013-06-09 14:14:12 | [diff] [blame^] | 87 | file_system_context_->operation_runner()->Cancel( |
| 88 | operation_id_, base::Bind(&IOThreadProxy::DidFinish, this)); |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 89 | } |
| 90 | |
| 91 | private: |
[email protected] | e0ffc6f | 2012-04-28 07:04:36 | [diff] [blame] | 92 | friend class base::RefCountedThreadSafe<IOThreadProxy>; |
| 93 | virtual ~IOThreadProxy() {} |
| 94 | |
[email protected] | d65c8215e | 2012-06-30 08:36:55 | [diff] [blame] | 95 | // Returns true if it is not writable. |
| 96 | bool FailIfNotWritable(const FileSystemURL& url) { |
[email protected] | 5ca8334e | 2012-08-27 17:19:40 | [diff] [blame] | 97 | if (url.type() == fileapi::kFileSystemTypeDragged) { |
[email protected] | d65c8215e | 2012-06-30 08:36:55 | [diff] [blame] | 98 | // Write is not allowed in isolate file system in SimpleFileWriter. |
| 99 | DidFailOnMainThread(base::PLATFORM_FILE_ERROR_SECURITY); |
| 100 | return true; |
| 101 | } |
| 102 | return false; |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 103 | } |
| 104 | |
[email protected] | 81f8a3d | 2012-02-14 08:40:37 | [diff] [blame] | 105 | void DidSucceedOnMainThread() { |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 106 | if (!main_thread_->BelongsToCurrentThread()) { |
[email protected] | 2de5530 | 2011-10-10 22:09:58 | [diff] [blame] | 107 | main_thread_->PostTask( |
| 108 | FROM_HERE, |
[email protected] | 81f8a3d | 2012-02-14 08:40:37 | [diff] [blame] | 109 | base::Bind(&IOThreadProxy::DidSucceedOnMainThread, this)); |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 110 | return; |
| 111 | } |
[email protected] | 9b55d80 | 2013-06-04 02:39:46 | [diff] [blame] | 112 | if (simple_writer_.get()) |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 113 | simple_writer_->DidSucceed(); |
| 114 | } |
| 115 | |
[email protected] | 81f8a3d | 2012-02-14 08:40:37 | [diff] [blame] | 116 | void DidFailOnMainThread(base::PlatformFileError error_code) { |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 117 | if (!main_thread_->BelongsToCurrentThread()) { |
[email protected] | 2de5530 | 2011-10-10 22:09:58 | [diff] [blame] | 118 | main_thread_->PostTask( |
| 119 | FROM_HERE, |
[email protected] | 81f8a3d | 2012-02-14 08:40:37 | [diff] [blame] | 120 | base::Bind(&IOThreadProxy::DidFailOnMainThread, this, error_code)); |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 121 | return; |
| 122 | } |
[email protected] | 9b55d80 | 2013-06-04 02:39:46 | [diff] [blame] | 123 | if (simple_writer_.get()) |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 124 | simple_writer_->DidFail(error_code); |
| 125 | } |
| 126 | |
[email protected] | 81f8a3d | 2012-02-14 08:40:37 | [diff] [blame] | 127 | void DidWriteOnMainThread(int64 bytes, bool complete) { |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 128 | if (!main_thread_->BelongsToCurrentThread()) { |
[email protected] | 2de5530 | 2011-10-10 22:09:58 | [diff] [blame] | 129 | main_thread_->PostTask( |
| 130 | FROM_HERE, |
[email protected] | 81f8a3d | 2012-02-14 08:40:37 | [diff] [blame] | 131 | base::Bind(&IOThreadProxy::DidWriteOnMainThread, |
| 132 | this, bytes, complete)); |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 133 | return; |
| 134 | } |
[email protected] | 9b55d80 | 2013-06-04 02:39:46 | [diff] [blame] | 135 | if (simple_writer_.get()) |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 136 | simple_writer_->DidWrite(bytes, complete); |
| 137 | } |
| 138 | |
[email protected] | 103c8d4 | 2010-11-30 18:58:13 | [diff] [blame] | 139 | void ClearOperation() { |
| 140 | DCHECK(io_thread_->BelongsToCurrentThread()); |
[email protected] | 3a7bf22 | 2013-06-09 14:14:12 | [diff] [blame^] | 141 | operation_id_ = FileSystemOperationRunner::kErrorOperationID; |
[email protected] | 103c8d4 | 2010-11-30 18:58:13 | [diff] [blame] | 142 | } |
| 143 | |
[email protected] | 81f8a3d | 2012-02-14 08:40:37 | [diff] [blame] | 144 | void DidFinish(base::PlatformFileError result) { |
| 145 | if (result == base::PLATFORM_FILE_OK) |
| 146 | DidSucceedOnMainThread(); |
| 147 | else |
| 148 | DidFailOnMainThread(result); |
| 149 | ClearOperation(); |
| 150 | } |
| 151 | |
| 152 | void DidWrite(base::PlatformFileError result, int64 bytes, bool complete) { |
| 153 | if (result == base::PLATFORM_FILE_OK) { |
| 154 | DidWriteOnMainThread(bytes, complete); |
| 155 | if (complete) |
| 156 | ClearOperation(); |
| 157 | } else { |
| 158 | DidFailOnMainThread(result); |
| 159 | ClearOperation(); |
| 160 | } |
| 161 | } |
| 162 | |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 163 | scoped_refptr<base::MessageLoopProxy> io_thread_; |
| 164 | scoped_refptr<base::MessageLoopProxy> main_thread_; |
| 165 | |
| 166 | // Only used on the main thread. |
| 167 | base::WeakPtr<SimpleFileWriter> simple_writer_; |
| 168 | |
| 169 | // Only used on the io thread. |
[email protected] | 3a7bf22 | 2013-06-09 14:14:12 | [diff] [blame^] | 170 | FileSystemOperationRunner::OperationID operation_id_; |
[email protected] | 073a04f | 2011-03-24 00:49:40 | [diff] [blame] | 171 | |
| 172 | scoped_refptr<FileSystemContext> file_system_context_; |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 173 | }; |
| 174 | |
| 175 | |
| 176 | SimpleFileWriter::SimpleFileWriter( |
[email protected] | 41e88943 | 2011-04-13 19:53:30 | [diff] [blame] | 177 | const GURL& path, |
[email protected] | 073a04f | 2011-03-24 00:49:40 | [diff] [blame] | 178 | WebFileWriterClient* client, |
| 179 | FileSystemContext* file_system_context) |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 180 | : WebFileWriterBase(path, client), |
[email protected] | 5b7e42e6 | 2013-01-24 22:01:51 | [diff] [blame] | 181 | file_system_context_(file_system_context), |
[email protected] | 073a04f | 2011-03-24 00:49:40 | [diff] [blame] | 182 | io_thread_proxy_(new IOThreadProxy(AsWeakPtr(), file_system_context)) { |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 183 | } |
| 184 | |
| 185 | SimpleFileWriter::~SimpleFileWriter() { |
| 186 | } |
| 187 | |
[email protected] | 41e88943 | 2011-04-13 19:53:30 | [diff] [blame] | 188 | void SimpleFileWriter::DoTruncate(const GURL& path, int64 offset) { |
[email protected] | 5b7e42e6 | 2013-01-24 22:01:51 | [diff] [blame] | 189 | FileSystemURL url = file_system_context_->CrackURL(path); |
[email protected] | d65c8215e | 2012-06-30 08:36:55 | [diff] [blame] | 190 | io_thread_proxy_->Truncate(url, offset); |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 191 | } |
| 192 | |
| 193 | void SimpleFileWriter::DoWrite( |
[email protected] | 41e88943 | 2011-04-13 19:53:30 | [diff] [blame] | 194 | const GURL& path, const GURL& blob_url, int64 offset) { |
[email protected] | 5b7e42e6 | 2013-01-24 22:01:51 | [diff] [blame] | 195 | FileSystemURL url = file_system_context_->CrackURL(path); |
[email protected] | d65c8215e | 2012-06-30 08:36:55 | [diff] [blame] | 196 | io_thread_proxy_->Write(url, blob_url, offset); |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 197 | } |
| 198 | |
| 199 | void SimpleFileWriter::DoCancel() { |
| 200 | io_thread_proxy_->Cancel(); |
| 201 | } |