[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 | |
| 5 | #include "webkit/tools/test_shell/simple_file_writer.h" |
| 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] | 073a04f | 2011-03-24 00:49:40 | [diff] [blame] | 12 | #include "webkit/fileapi/file_system_context.h" |
[email protected] | 8e3bc3e | 2012-08-24 13:12:53 | [diff] [blame] | 13 | #include "webkit/fileapi/file_system_operation.h" |
[email protected] | d65c8215e | 2012-06-30 08:36:55 | [diff] [blame] | 14 | #include "webkit/fileapi/file_system_types.h" |
[email protected] | 949f25a | 2012-06-27 01:53:09 | [diff] [blame] | 15 | #include "webkit/fileapi/file_system_url.h" |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 16 | #include "webkit/glue/webkit_glue.h" |
| 17 | #include "webkit/tools/test_shell/simple_resource_loader_bridge.h" |
| 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] | 8e3bc3e | 2012-08-24 13:12:53 | [diff] [blame] | 21 | using fileapi::FileSystemOperation; |
[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] | 073a04f | 2011-03-24 00:49:40 | [diff] [blame] | 38 | operation_(NULL), |
| 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] | 103c8d4 | 2010-11-30 18:58:13 | [diff] [blame] | 55 | DCHECK(!operation_); |
[email protected] | d65c8215e | 2012-06-30 08:36:55 | [diff] [blame] | 56 | operation_ = GetNewOperation(url); |
| 57 | operation_->Truncate(url, offset, |
[email protected] | 81f8a3d | 2012-02-14 08:40:37 | [diff] [blame] | 58 | base::Bind(&IOThreadProxy::DidFinish, this)); |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 59 | } |
| 60 | |
[email protected] | d65c8215e | 2012-06-30 08:36:55 | [diff] [blame] | 61 | void Write(const FileSystemURL& url, const GURL& blob_url, int64 offset) { |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 62 | if (!io_thread_->BelongsToCurrentThread()) { |
[email protected] | 2de5530 | 2011-10-10 22:09:58 | [diff] [blame] | 63 | io_thread_->PostTask( |
| 64 | FROM_HERE, |
[email protected] | d65c8215e | 2012-06-30 08:36:55 | [diff] [blame] | 65 | base::Bind(&IOThreadProxy::Write, this, url, blob_url, offset)); |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 66 | return; |
| 67 | } |
[email protected] | d65c8215e | 2012-06-30 08:36:55 | [diff] [blame] | 68 | if (FailIfNotWritable(url)) |
| 69 | return; |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 70 | DCHECK(request_context_); |
[email protected] | 103c8d4 | 2010-11-30 18:58:13 | [diff] [blame] | 71 | DCHECK(!operation_); |
[email protected] | d65c8215e | 2012-06-30 08:36:55 | [diff] [blame] | 72 | operation_ = GetNewOperation(url); |
| 73 | operation_->Write(request_context_, url, blob_url, offset, |
[email protected] | 81f8a3d | 2012-02-14 08:40:37 | [diff] [blame] | 74 | base::Bind(&IOThreadProxy::DidWrite, this)); |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 75 | } |
| 76 | |
| 77 | void Cancel() { |
| 78 | if (!io_thread_->BelongsToCurrentThread()) { |
[email protected] | 2de5530 | 2011-10-10 22:09:58 | [diff] [blame] | 79 | io_thread_->PostTask( |
| 80 | FROM_HERE, |
| 81 | base::Bind(&IOThreadProxy::Cancel, this)); |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 82 | return; |
| 83 | } |
[email protected] | 103c8d4 | 2010-11-30 18:58:13 | [diff] [blame] | 84 | if (!operation_) { |
[email protected] | 81f8a3d | 2012-02-14 08:40:37 | [diff] [blame] | 85 | DidFailOnMainThread(base::PLATFORM_FILE_ERROR_INVALID_OPERATION); |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 86 | return; |
| 87 | } |
[email protected] | 81f8a3d | 2012-02-14 08:40:37 | [diff] [blame] | 88 | operation_->Cancel(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] | 8e3bc3e | 2012-08-24 13:12:53 | [diff] [blame] | 95 | FileSystemOperation* GetNewOperation( const FileSystemURL& url) { |
[email protected] | baa6e11 | 2012-09-10 06:24:46 | [diff] [blame] | 96 | return file_system_context_->CreateFileSystemOperation(url, NULL); |
[email protected] | d65c8215e | 2012-06-30 08:36:55 | [diff] [blame] | 97 | } |
| 98 | |
| 99 | // Returns true if it is not writable. |
| 100 | bool FailIfNotWritable(const FileSystemURL& url) { |
[email protected] | 5ca8334e | 2012-08-27 17:19:40 | [diff] [blame] | 101 | if (url.type() == fileapi::kFileSystemTypeDragged) { |
[email protected] | d65c8215e | 2012-06-30 08:36:55 | [diff] [blame] | 102 | // Write is not allowed in isolate file system in SimpleFileWriter. |
| 103 | DidFailOnMainThread(base::PLATFORM_FILE_ERROR_SECURITY); |
| 104 | return true; |
| 105 | } |
| 106 | return false; |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 107 | } |
| 108 | |
[email protected] | 81f8a3d | 2012-02-14 08:40:37 | [diff] [blame] | 109 | void DidSucceedOnMainThread() { |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 110 | if (!main_thread_->BelongsToCurrentThread()) { |
[email protected] | 2de5530 | 2011-10-10 22:09:58 | [diff] [blame] | 111 | main_thread_->PostTask( |
| 112 | FROM_HERE, |
[email protected] | 81f8a3d | 2012-02-14 08:40:37 | [diff] [blame] | 113 | base::Bind(&IOThreadProxy::DidSucceedOnMainThread, this)); |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 114 | return; |
| 115 | } |
| 116 | if (simple_writer_) |
| 117 | simple_writer_->DidSucceed(); |
| 118 | } |
| 119 | |
[email protected] | 81f8a3d | 2012-02-14 08:40:37 | [diff] [blame] | 120 | void DidFailOnMainThread(base::PlatformFileError error_code) { |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 121 | if (!main_thread_->BelongsToCurrentThread()) { |
[email protected] | 2de5530 | 2011-10-10 22:09:58 | [diff] [blame] | 122 | main_thread_->PostTask( |
| 123 | FROM_HERE, |
[email protected] | 81f8a3d | 2012-02-14 08:40:37 | [diff] [blame] | 124 | base::Bind(&IOThreadProxy::DidFailOnMainThread, this, error_code)); |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 125 | return; |
| 126 | } |
| 127 | if (simple_writer_) |
| 128 | simple_writer_->DidFail(error_code); |
| 129 | } |
| 130 | |
[email protected] | 81f8a3d | 2012-02-14 08:40:37 | [diff] [blame] | 131 | void DidWriteOnMainThread(int64 bytes, bool complete) { |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 132 | if (!main_thread_->BelongsToCurrentThread()) { |
[email protected] | 2de5530 | 2011-10-10 22:09:58 | [diff] [blame] | 133 | main_thread_->PostTask( |
| 134 | FROM_HERE, |
[email protected] | 81f8a3d | 2012-02-14 08:40:37 | [diff] [blame] | 135 | base::Bind(&IOThreadProxy::DidWriteOnMainThread, |
| 136 | this, bytes, complete)); |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 137 | return; |
| 138 | } |
| 139 | if (simple_writer_) |
| 140 | simple_writer_->DidWrite(bytes, complete); |
| 141 | } |
| 142 | |
[email protected] | 103c8d4 | 2010-11-30 18:58:13 | [diff] [blame] | 143 | void ClearOperation() { |
| 144 | DCHECK(io_thread_->BelongsToCurrentThread()); |
| 145 | operation_ = NULL; |
| 146 | } |
| 147 | |
[email protected] | 81f8a3d | 2012-02-14 08:40:37 | [diff] [blame] | 148 | void DidFinish(base::PlatformFileError result) { |
| 149 | if (result == base::PLATFORM_FILE_OK) |
| 150 | DidSucceedOnMainThread(); |
| 151 | else |
| 152 | DidFailOnMainThread(result); |
| 153 | ClearOperation(); |
| 154 | } |
| 155 | |
| 156 | void DidWrite(base::PlatformFileError result, int64 bytes, bool complete) { |
| 157 | if (result == base::PLATFORM_FILE_OK) { |
| 158 | DidWriteOnMainThread(bytes, complete); |
| 159 | if (complete) |
| 160 | ClearOperation(); |
| 161 | } else { |
| 162 | DidFailOnMainThread(result); |
| 163 | ClearOperation(); |
| 164 | } |
| 165 | } |
| 166 | |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 167 | scoped_refptr<base::MessageLoopProxy> io_thread_; |
| 168 | scoped_refptr<base::MessageLoopProxy> main_thread_; |
| 169 | |
| 170 | // Only used on the main thread. |
| 171 | base::WeakPtr<SimpleFileWriter> simple_writer_; |
| 172 | |
| 173 | // Only used on the io thread. |
[email protected] | 8e3bc3e | 2012-08-24 13:12:53 | [diff] [blame] | 174 | FileSystemOperation* operation_; |
[email protected] | 073a04f | 2011-03-24 00:49:40 | [diff] [blame] | 175 | |
| 176 | scoped_refptr<FileSystemContext> file_system_context_; |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 177 | }; |
| 178 | |
| 179 | |
| 180 | SimpleFileWriter::SimpleFileWriter( |
[email protected] | 41e88943 | 2011-04-13 19:53:30 | [diff] [blame] | 181 | const GURL& path, |
[email protected] | 073a04f | 2011-03-24 00:49:40 | [diff] [blame] | 182 | WebFileWriterClient* client, |
| 183 | FileSystemContext* file_system_context) |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 184 | : WebFileWriterBase(path, client), |
[email protected] | 5b7e42e6 | 2013-01-24 22:01:51 | [diff] [blame^] | 185 | file_system_context_(file_system_context), |
[email protected] | 073a04f | 2011-03-24 00:49:40 | [diff] [blame] | 186 | io_thread_proxy_(new IOThreadProxy(AsWeakPtr(), file_system_context)) { |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 187 | } |
| 188 | |
| 189 | SimpleFileWriter::~SimpleFileWriter() { |
| 190 | } |
| 191 | |
[email protected] | 41e88943 | 2011-04-13 19:53:30 | [diff] [blame] | 192 | void SimpleFileWriter::DoTruncate(const GURL& path, int64 offset) { |
[email protected] | 5b7e42e6 | 2013-01-24 22:01:51 | [diff] [blame^] | 193 | FileSystemURL url = file_system_context_->CrackURL(path); |
[email protected] | d65c8215e | 2012-06-30 08:36:55 | [diff] [blame] | 194 | io_thread_proxy_->Truncate(url, offset); |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 195 | } |
| 196 | |
| 197 | void SimpleFileWriter::DoWrite( |
[email protected] | 41e88943 | 2011-04-13 19:53:30 | [diff] [blame] | 198 | const GURL& path, const GURL& blob_url, int64 offset) { |
[email protected] | 5b7e42e6 | 2013-01-24 22:01:51 | [diff] [blame^] | 199 | FileSystemURL url = file_system_context_->CrackURL(path); |
[email protected] | d65c8215e | 2012-06-30 08:36:55 | [diff] [blame] | 200 | io_thread_proxy_->Write(url, blob_url, offset); |
[email protected] | 2687ad7d | 2010-10-14 00:44:08 | [diff] [blame] | 201 | } |
| 202 | |
| 203 | void SimpleFileWriter::DoCancel() { |
| 204 | io_thread_proxy_->Cancel(); |
| 205 | } |