blob: 98de70b6cece30be439dc3f9320149828aebb0d9 [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
[email protected]eafe40492013-06-04 18:12:455#include "webkit/support/simple_file_writer.h"
[email protected]2687ad7d2010-10-14 00:44:086
[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]c6f9203a2013-05-28 02:08:0712#include "webkit/browser/fileapi/file_system_context.h"
[email protected]3a7bf222013-06-09 14:14:1213#include "webkit/browser/fileapi/file_system_operation_runner.h"
[email protected]c6f9203a2013-05-28 02:08:0714#include "webkit/browser/fileapi/file_system_url.h"
[email protected]61d271f32013-05-28 04:59:2315#include "webkit/common/fileapi/file_system_types.h"
[email protected]2687ad7d2010-10-14 00:44:0816#include "webkit/glue/webkit_glue.h"
[email protected]eafe40492013-06-04 18:12:4517#include "webkit/support/simple_resource_loader_bridge.h"
[email protected]2687ad7d2010-10-14 00:44:0818
[email protected]949f25a2012-06-27 01:53:0919using fileapi::FileSystemURL;
[email protected]073a04f2011-03-24 00:49:4020using fileapi::FileSystemContext;
[email protected]3a7bf222013-06-09 14:14:1221using fileapi::FileSystemOperationRunner;
[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]3a7bf222013-06-09 14:14:1238 operation_id_(FileSystemOperationRunner::kErrorOperationID),
[email protected]073a04f2011-03-24 00:49:4039 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]3a7bf222013-06-09 14:14:1255 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]2687ad7d2010-10-14 00:44:0858 }
59
[email protected]d65c8215e2012-06-30 08:36:5560 void Write(const FileSystemURL& url, const GURL& blob_url, int64 offset) {
[email protected]2687ad7d2010-10-14 00:44:0861 if (!io_thread_->BelongsToCurrentThread()) {
[email protected]2de55302011-10-10 22:09:5862 io_thread_->PostTask(
63 FROM_HERE,
[email protected]d65c8215e2012-06-30 08:36:5564 base::Bind(&IOThreadProxy::Write, this, url, blob_url, offset));
[email protected]2687ad7d2010-10-14 00:44:0865 return;
66 }
[email protected]d65c8215e2012-06-30 08:36:5567 if (FailIfNotWritable(url))
68 return;
[email protected]2687ad7d2010-10-14 00:44:0869 DCHECK(request_context_);
[email protected]3a7bf222013-06-09 14:14:1270 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]2687ad7d2010-10-14 00:44:0874 }
75
76 void Cancel() {
77 if (!io_thread_->BelongsToCurrentThread()) {
[email protected]2de55302011-10-10 22:09:5878 io_thread_->PostTask(
79 FROM_HERE,
80 base::Bind(&IOThreadProxy::Cancel, this));
[email protected]2687ad7d2010-10-14 00:44:0881 return;
82 }
[email protected]3a7bf222013-06-09 14:14:1283 if (operation_id_ == FileSystemOperationRunner::kErrorOperationID) {
[email protected]81f8a3d2012-02-14 08:40:3784 DidFailOnMainThread(base::PLATFORM_FILE_ERROR_INVALID_OPERATION);
[email protected]2687ad7d2010-10-14 00:44:0885 return;
86 }
[email protected]3a7bf222013-06-09 14:14:1287 file_system_context_->operation_runner()->Cancel(
88 operation_id_, 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]d65c8215e2012-06-30 08:36:5595 // Returns true if it is not writable.
96 bool FailIfNotWritable(const FileSystemURL& url) {
[email protected]5ca8334e2012-08-27 17:19:4097 if (url.type() == fileapi::kFileSystemTypeDragged) {
[email protected]d65c8215e2012-06-30 08:36:5598 // 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]2687ad7d2010-10-14 00:44:08103 }
104
[email protected]81f8a3d2012-02-14 08:40:37105 void DidSucceedOnMainThread() {
[email protected]2687ad7d2010-10-14 00:44:08106 if (!main_thread_->BelongsToCurrentThread()) {
[email protected]2de55302011-10-10 22:09:58107 main_thread_->PostTask(
108 FROM_HERE,
[email protected]81f8a3d2012-02-14 08:40:37109 base::Bind(&IOThreadProxy::DidSucceedOnMainThread, this));
[email protected]2687ad7d2010-10-14 00:44:08110 return;
111 }
[email protected]9b55d802013-06-04 02:39:46112 if (simple_writer_.get())
[email protected]2687ad7d2010-10-14 00:44:08113 simple_writer_->DidSucceed();
114 }
115
[email protected]81f8a3d2012-02-14 08:40:37116 void DidFailOnMainThread(base::PlatformFileError error_code) {
[email protected]2687ad7d2010-10-14 00:44:08117 if (!main_thread_->BelongsToCurrentThread()) {
[email protected]2de55302011-10-10 22:09:58118 main_thread_->PostTask(
119 FROM_HERE,
[email protected]81f8a3d2012-02-14 08:40:37120 base::Bind(&IOThreadProxy::DidFailOnMainThread, this, error_code));
[email protected]2687ad7d2010-10-14 00:44:08121 return;
122 }
[email protected]9b55d802013-06-04 02:39:46123 if (simple_writer_.get())
[email protected]2687ad7d2010-10-14 00:44:08124 simple_writer_->DidFail(error_code);
125 }
126
[email protected]81f8a3d2012-02-14 08:40:37127 void DidWriteOnMainThread(int64 bytes, bool complete) {
[email protected]2687ad7d2010-10-14 00:44:08128 if (!main_thread_->BelongsToCurrentThread()) {
[email protected]2de55302011-10-10 22:09:58129 main_thread_->PostTask(
130 FROM_HERE,
[email protected]81f8a3d2012-02-14 08:40:37131 base::Bind(&IOThreadProxy::DidWriteOnMainThread,
132 this, bytes, complete));
[email protected]2687ad7d2010-10-14 00:44:08133 return;
134 }
[email protected]9b55d802013-06-04 02:39:46135 if (simple_writer_.get())
[email protected]2687ad7d2010-10-14 00:44:08136 simple_writer_->DidWrite(bytes, complete);
137 }
138
[email protected]103c8d42010-11-30 18:58:13139 void ClearOperation() {
140 DCHECK(io_thread_->BelongsToCurrentThread());
[email protected]3a7bf222013-06-09 14:14:12141 operation_id_ = FileSystemOperationRunner::kErrorOperationID;
[email protected]103c8d42010-11-30 18:58:13142 }
143
[email protected]81f8a3d2012-02-14 08:40:37144 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]2687ad7d2010-10-14 00:44:08163 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]3a7bf222013-06-09 14:14:12170 FileSystemOperationRunner::OperationID operation_id_;
[email protected]073a04f2011-03-24 00:49:40171
172 scoped_refptr<FileSystemContext> file_system_context_;
[email protected]2687ad7d2010-10-14 00:44:08173};
174
175
176SimpleFileWriter::SimpleFileWriter(
[email protected]41e889432011-04-13 19:53:30177 const GURL& path,
[email protected]073a04f2011-03-24 00:49:40178 WebFileWriterClient* client,
179 FileSystemContext* file_system_context)
[email protected]2687ad7d2010-10-14 00:44:08180 : WebFileWriterBase(path, client),
[email protected]5b7e42e62013-01-24 22:01:51181 file_system_context_(file_system_context),
[email protected]073a04f2011-03-24 00:49:40182 io_thread_proxy_(new IOThreadProxy(AsWeakPtr(), file_system_context)) {
[email protected]2687ad7d2010-10-14 00:44:08183}
184
185SimpleFileWriter::~SimpleFileWriter() {
186}
187
[email protected]41e889432011-04-13 19:53:30188void SimpleFileWriter::DoTruncate(const GURL& path, int64 offset) {
[email protected]5b7e42e62013-01-24 22:01:51189 FileSystemURL url = file_system_context_->CrackURL(path);
[email protected]d65c8215e2012-06-30 08:36:55190 io_thread_proxy_->Truncate(url, offset);
[email protected]2687ad7d2010-10-14 00:44:08191}
192
193void SimpleFileWriter::DoWrite(
[email protected]41e889432011-04-13 19:53:30194 const GURL& path, const GURL& blob_url, int64 offset) {
[email protected]5b7e42e62013-01-24 22:01:51195 FileSystemURL url = file_system_context_->CrackURL(path);
[email protected]d65c8215e2012-06-30 08:36:55196 io_thread_proxy_->Write(url, blob_url, offset);
[email protected]2687ad7d2010-10-14 00:44:08197}
198
199void SimpleFileWriter::DoCancel() {
200 io_thread_proxy_->Cancel();
201}