blob: e30e1204c42442ab92a16164d27ce22b9bac87f3 [file] [log] [blame]
[email protected]60f60f82012-01-11 10:26:101// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]2687ad7d2010-10-14 00:44:082// 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]2de55302011-10-10 22:09:587#include "base/bind.h"
[email protected]4aefec142012-04-23 21:23:048#include "base/location.h"
[email protected]2687ad7d2010-10-14 00:44:089#include "base/logging.h"
10#include "base/message_loop_proxy.h"
11#include "net/url_request/url_request_context.h"
[email protected]073a04f2011-03-24 00:49:4012#include "webkit/fileapi/file_system_context.h"
[email protected]8e3bc3e2012-08-24 13:12:5313#include "webkit/fileapi/file_system_operation.h"
[email protected]d65c8215e2012-06-30 08:36:5514#include "webkit/fileapi/file_system_types.h"
[email protected]949f25a2012-06-27 01:53:0915#include "webkit/fileapi/file_system_url.h"
[email protected]2687ad7d2010-10-14 00:44:0816#include "webkit/glue/webkit_glue.h"
17#include "webkit/tools/test_shell/simple_resource_loader_bridge.h"
18
[email protected]949f25a2012-06-27 01:53:0919using fileapi::FileSystemURL;
[email protected]073a04f2011-03-24 00:49:4020using fileapi::FileSystemContext;
[email protected]8e3bc3e2012-08-24 13:12:5321using fileapi::FileSystemOperation;
[email protected]2687ad7d2010-10-14 00:44:0822using fileapi::WebFileWriterBase;
23using WebKit::WebFileWriterClient;
24using WebKit::WebString;
25using WebKit::WebURL;
26
[email protected]aeb53f02011-01-15 00:21:3427net::URLRequestContext* SimpleFileWriter::request_context_ = NULL;
[email protected]2687ad7d2010-10-14 00:44:0828
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.
32class SimpleFileWriter::IOThreadProxy
33 : public base::RefCountedThreadSafe<SimpleFileWriter::IOThreadProxy> {
34 public:
[email protected]e7e38032011-07-26 17:25:2535 IOThreadProxy(const base::WeakPtr<SimpleFileWriter>& simple_writer,
36 FileSystemContext* file_system_context)
[email protected]103c8d42010-11-30 18:58:1337 : simple_writer_(simple_writer),
[email protected]073a04f2011-03-24 00:49:4038 operation_(NULL),
39 file_system_context_(file_system_context) {
[email protected]2687ad7d2010-10-14 00:44:0840 // The IO thread needs to be running for this class to work.
41 SimpleResourceLoaderBridge::EnsureIOThread();
42 io_thread_ = SimpleResourceLoaderBridge::GetIoThread();
[email protected]edd685f2011-08-15 20:33:4643 main_thread_ = base::MessageLoopProxy::current();
[email protected]2687ad7d2010-10-14 00:44:0844 }
45
[email protected]d65c8215e2012-06-30 08:36:5546 void Truncate(const FileSystemURL& url, int64 offset) {
[email protected]2687ad7d2010-10-14 00:44:0847 if (!io_thread_->BelongsToCurrentThread()) {
[email protected]2de55302011-10-10 22:09:5848 io_thread_->PostTask(
49 FROM_HERE,
[email protected]d65c8215e2012-06-30 08:36:5550 base::Bind(&IOThreadProxy::Truncate, this, url, offset));
[email protected]2687ad7d2010-10-14 00:44:0851 return;
52 }
[email protected]d65c8215e2012-06-30 08:36:5553 if (FailIfNotWritable(url))
54 return;
[email protected]103c8d42010-11-30 18:58:1355 DCHECK(!operation_);
[email protected]d65c8215e2012-06-30 08:36:5556 operation_ = GetNewOperation(url);
57 operation_->Truncate(url, offset,
[email protected]81f8a3d2012-02-14 08:40:3758 base::Bind(&IOThreadProxy::DidFinish, this));
[email protected]2687ad7d2010-10-14 00:44:0859 }
60
[email protected]d65c8215e2012-06-30 08:36:5561 void Write(const FileSystemURL& url, const GURL& blob_url, int64 offset) {
[email protected]2687ad7d2010-10-14 00:44:0862 if (!io_thread_->BelongsToCurrentThread()) {
[email protected]2de55302011-10-10 22:09:5863 io_thread_->PostTask(
64 FROM_HERE,
[email protected]d65c8215e2012-06-30 08:36:5565 base::Bind(&IOThreadProxy::Write, this, url, blob_url, offset));
[email protected]2687ad7d2010-10-14 00:44:0866 return;
67 }
[email protected]d65c8215e2012-06-30 08:36:5568 if (FailIfNotWritable(url))
69 return;
[email protected]2687ad7d2010-10-14 00:44:0870 DCHECK(request_context_);
[email protected]103c8d42010-11-30 18:58:1371 DCHECK(!operation_);
[email protected]d65c8215e2012-06-30 08:36:5572 operation_ = GetNewOperation(url);
73 operation_->Write(request_context_, url, blob_url, offset,
[email protected]81f8a3d2012-02-14 08:40:3774 base::Bind(&IOThreadProxy::DidWrite, this));
[email protected]2687ad7d2010-10-14 00:44:0875 }
76
77 void Cancel() {
78 if (!io_thread_->BelongsToCurrentThread()) {
[email protected]2de55302011-10-10 22:09:5879 io_thread_->PostTask(
80 FROM_HERE,
81 base::Bind(&IOThreadProxy::Cancel, this));
[email protected]2687ad7d2010-10-14 00:44:0882 return;
83 }
[email protected]103c8d42010-11-30 18:58:1384 if (!operation_) {
[email protected]81f8a3d2012-02-14 08:40:3785 DidFailOnMainThread(base::PLATFORM_FILE_ERROR_INVALID_OPERATION);
[email protected]2687ad7d2010-10-14 00:44:0886 return;
87 }
[email protected]81f8a3d2012-02-14 08:40:3788 operation_->Cancel(base::Bind(&IOThreadProxy::DidFinish, this));
[email protected]2687ad7d2010-10-14 00:44:0889 }
90
91 private:
[email protected]e0ffc6f2012-04-28 07:04:3692 friend class base::RefCountedThreadSafe<IOThreadProxy>;
93 virtual ~IOThreadProxy() {}
94
[email protected]8e3bc3e2012-08-24 13:12:5395 FileSystemOperation* GetNewOperation( const FileSystemURL& url) {
[email protected]baa6e112012-09-10 06:24:4696 return file_system_context_->CreateFileSystemOperation(url, NULL);
[email protected]d65c8215e2012-06-30 08:36:5597 }
98
99 // Returns true if it is not writable.
100 bool FailIfNotWritable(const FileSystemURL& url) {
[email protected]5ca8334e2012-08-27 17:19:40101 if (url.type() == fileapi::kFileSystemTypeDragged) {
[email protected]d65c8215e2012-06-30 08:36:55102 // 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]2687ad7d2010-10-14 00:44:08107 }
108
[email protected]81f8a3d2012-02-14 08:40:37109 void DidSucceedOnMainThread() {
[email protected]2687ad7d2010-10-14 00:44:08110 if (!main_thread_->BelongsToCurrentThread()) {
[email protected]2de55302011-10-10 22:09:58111 main_thread_->PostTask(
112 FROM_HERE,
[email protected]81f8a3d2012-02-14 08:40:37113 base::Bind(&IOThreadProxy::DidSucceedOnMainThread, this));
[email protected]2687ad7d2010-10-14 00:44:08114 return;
115 }
116 if (simple_writer_)
117 simple_writer_->DidSucceed();
118 }
119
[email protected]81f8a3d2012-02-14 08:40:37120 void DidFailOnMainThread(base::PlatformFileError error_code) {
[email protected]2687ad7d2010-10-14 00:44:08121 if (!main_thread_->BelongsToCurrentThread()) {
[email protected]2de55302011-10-10 22:09:58122 main_thread_->PostTask(
123 FROM_HERE,
[email protected]81f8a3d2012-02-14 08:40:37124 base::Bind(&IOThreadProxy::DidFailOnMainThread, this, error_code));
[email protected]2687ad7d2010-10-14 00:44:08125 return;
126 }
127 if (simple_writer_)
128 simple_writer_->DidFail(error_code);
129 }
130
[email protected]81f8a3d2012-02-14 08:40:37131 void DidWriteOnMainThread(int64 bytes, bool complete) {
[email protected]2687ad7d2010-10-14 00:44:08132 if (!main_thread_->BelongsToCurrentThread()) {
[email protected]2de55302011-10-10 22:09:58133 main_thread_->PostTask(
134 FROM_HERE,
[email protected]81f8a3d2012-02-14 08:40:37135 base::Bind(&IOThreadProxy::DidWriteOnMainThread,
136 this, bytes, complete));
[email protected]2687ad7d2010-10-14 00:44:08137 return;
138 }
139 if (simple_writer_)
140 simple_writer_->DidWrite(bytes, complete);
141 }
142
[email protected]103c8d42010-11-30 18:58:13143 void ClearOperation() {
144 DCHECK(io_thread_->BelongsToCurrentThread());
145 operation_ = NULL;
146 }
147
[email protected]81f8a3d2012-02-14 08:40:37148 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]2687ad7d2010-10-14 00:44:08167 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]8e3bc3e2012-08-24 13:12:53174 FileSystemOperation* operation_;
[email protected]073a04f2011-03-24 00:49:40175
176 scoped_refptr<FileSystemContext> file_system_context_;
[email protected]2687ad7d2010-10-14 00:44:08177};
178
179
180SimpleFileWriter::SimpleFileWriter(
[email protected]41e889432011-04-13 19:53:30181 const GURL& path,
[email protected]073a04f2011-03-24 00:49:40182 WebFileWriterClient* client,
183 FileSystemContext* file_system_context)
[email protected]2687ad7d2010-10-14 00:44:08184 : WebFileWriterBase(path, client),
[email protected]5b7e42e62013-01-24 22:01:51185 file_system_context_(file_system_context),
[email protected]073a04f2011-03-24 00:49:40186 io_thread_proxy_(new IOThreadProxy(AsWeakPtr(), file_system_context)) {
[email protected]2687ad7d2010-10-14 00:44:08187}
188
189SimpleFileWriter::~SimpleFileWriter() {
190}
191
[email protected]41e889432011-04-13 19:53:30192void SimpleFileWriter::DoTruncate(const GURL& path, int64 offset) {
[email protected]5b7e42e62013-01-24 22:01:51193 FileSystemURL url = file_system_context_->CrackURL(path);
[email protected]d65c8215e2012-06-30 08:36:55194 io_thread_proxy_->Truncate(url, offset);
[email protected]2687ad7d2010-10-14 00:44:08195}
196
197void SimpleFileWriter::DoWrite(
[email protected]41e889432011-04-13 19:53:30198 const GURL& path, const GURL& blob_url, int64 offset) {
[email protected]5b7e42e62013-01-24 22:01:51199 FileSystemURL url = file_system_context_->CrackURL(path);
[email protected]d65c8215e2012-06-30 08:36:55200 io_thread_proxy_->Write(url, blob_url, offset);
[email protected]2687ad7d2010-10-14 00:44:08201}
202
203void SimpleFileWriter::DoCancel() {
204 io_thread_proxy_->Cancel();
205}