Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1001)

Side by Side Diff: webkit/browser/chromeos/fileapi/remote_file_system_operation.cc

Issue 16413007: Make FileSystemOperation NOT self-destruct (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix browser_tests Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 "webkit/browser/chromeos/fileapi/remote_file_system_operation.h" 5 #include "webkit/browser/chromeos/fileapi/remote_file_system_operation.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/platform_file.h" 8 #include "base/platform_file.h"
9 #include "base/strings/utf_string_conversions.h" 9 #include "base/strings/utf_string_conversions.h"
10 #include "base/values.h" 10 #include "base/values.h"
(...skipping 12 matching lines...) Expand all
23 : remote_proxy_(remote_proxy), 23 : remote_proxy_(remote_proxy),
24 pending_operation_(kOperationNone) { 24 pending_operation_(kOperationNone) {
25 } 25 }
26 26
27 RemoteFileSystemOperation::~RemoteFileSystemOperation() { 27 RemoteFileSystemOperation::~RemoteFileSystemOperation() {
28 } 28 }
29 29
30 void RemoteFileSystemOperation::GetMetadata(const FileSystemURL& url, 30 void RemoteFileSystemOperation::GetMetadata(const FileSystemURL& url,
31 const GetMetadataCallback& callback) { 31 const GetMetadataCallback& callback) {
32 DCHECK(SetPendingOperationType(kOperationGetMetadata)); 32 DCHECK(SetPendingOperationType(kOperationGetMetadata));
33 remote_proxy_->GetFileInfo(url, 33 remote_proxy_->GetFileInfo(url, callback);
34 base::Bind(&RemoteFileSystemOperation::DidGetMetadata,
35 base::Owned(this), callback));
36 } 34 }
37 35
38 void RemoteFileSystemOperation::DirectoryExists(const FileSystemURL& url, 36 void RemoteFileSystemOperation::DirectoryExists(const FileSystemURL& url,
39 const StatusCallback& callback) { 37 const StatusCallback& callback) {
40 DCHECK(SetPendingOperationType(kOperationDirectoryExists)); 38 DCHECK(SetPendingOperationType(kOperationDirectoryExists));
41 remote_proxy_->GetFileInfo(url, 39 remote_proxy_->GetFileInfo(url,
42 base::Bind(&RemoteFileSystemOperation::DidDirectoryExists, 40 base::Bind(&RemoteFileSystemOperation::DidDirectoryExists,
43 base::Owned(this), callback)); 41 AsWeakPtr(), callback));
44 } 42 }
45 43
46 void RemoteFileSystemOperation::FileExists(const FileSystemURL& url, 44 void RemoteFileSystemOperation::FileExists(const FileSystemURL& url,
47 const StatusCallback& callback) { 45 const StatusCallback& callback) {
48 DCHECK(SetPendingOperationType(kOperationFileExists)); 46 DCHECK(SetPendingOperationType(kOperationFileExists));
49 remote_proxy_->GetFileInfo(url, 47 remote_proxy_->GetFileInfo(url,
50 base::Bind(base::Bind(&RemoteFileSystemOperation::DidFileExists, 48 base::Bind(base::Bind(&RemoteFileSystemOperation::DidFileExists,
51 base::Owned(this), callback))); 49 AsWeakPtr(), callback)));
52 } 50 }
53 51
54 void RemoteFileSystemOperation::ReadDirectory(const FileSystemURL& url, 52 void RemoteFileSystemOperation::ReadDirectory(const FileSystemURL& url,
55 const ReadDirectoryCallback& callback) { 53 const ReadDirectoryCallback& callback) {
56 DCHECK(SetPendingOperationType(kOperationReadDirectory)); 54 DCHECK(SetPendingOperationType(kOperationReadDirectory));
57 remote_proxy_->ReadDirectory(url, 55 remote_proxy_->ReadDirectory(url, callback);
58 base::Bind(&RemoteFileSystemOperation::DidReadDirectory,
59 base::Owned(this), callback));
60 } 56 }
61 57
62 void RemoteFileSystemOperation::Remove(const FileSystemURL& url, bool recursive, 58 void RemoteFileSystemOperation::Remove(const FileSystemURL& url, bool recursive,
63 const StatusCallback& callback) { 59 const StatusCallback& callback) {
64 DCHECK(SetPendingOperationType(kOperationRemove)); 60 DCHECK(SetPendingOperationType(kOperationRemove));
65 remote_proxy_->Remove(url, recursive, 61 remote_proxy_->Remove(url, recursive,
66 base::Bind(&RemoteFileSystemOperation::DidFinishFileOperation, 62 base::Bind(&RemoteFileSystemOperation::DidFinishFileOperation,
67 base::Owned(this), callback)); 63 AsWeakPtr(), callback));
68 } 64 }
69 65
70 66
71 void RemoteFileSystemOperation::CreateDirectory( 67 void RemoteFileSystemOperation::CreateDirectory(
72 const FileSystemURL& url, bool exclusive, bool recursive, 68 const FileSystemURL& url, bool exclusive, bool recursive,
73 const StatusCallback& callback) { 69 const StatusCallback& callback) {
74 DCHECK(SetPendingOperationType(kOperationCreateDirectory)); 70 DCHECK(SetPendingOperationType(kOperationCreateDirectory));
75 remote_proxy_->CreateDirectory(url, exclusive, recursive, 71 remote_proxy_->CreateDirectory(url, exclusive, recursive,
76 base::Bind(&RemoteFileSystemOperation::DidFinishFileOperation, 72 base::Bind(&RemoteFileSystemOperation::DidFinishFileOperation,
77 base::Owned(this), callback)); 73 AsWeakPtr(), callback));
78 } 74 }
79 75
80 void RemoteFileSystemOperation::CreateFile(const FileSystemURL& url, 76 void RemoteFileSystemOperation::CreateFile(const FileSystemURL& url,
81 bool exclusive, 77 bool exclusive,
82 const StatusCallback& callback) { 78 const StatusCallback& callback) {
83 DCHECK(SetPendingOperationType(kOperationCreateFile)); 79 DCHECK(SetPendingOperationType(kOperationCreateFile));
84 remote_proxy_->CreateFile(url, exclusive, 80 remote_proxy_->CreateFile(url, exclusive,
85 base::Bind(&RemoteFileSystemOperation::DidFinishFileOperation, 81 base::Bind(&RemoteFileSystemOperation::DidFinishFileOperation,
86 base::Owned(this), callback)); 82 AsWeakPtr(), callback));
87 } 83 }
88 84
89 void RemoteFileSystemOperation::Copy(const FileSystemURL& src_url, 85 void RemoteFileSystemOperation::Copy(const FileSystemURL& src_url,
90 const FileSystemURL& dest_url, 86 const FileSystemURL& dest_url,
91 const StatusCallback& callback) { 87 const StatusCallback& callback) {
92 DCHECK(SetPendingOperationType(kOperationCopy)); 88 DCHECK(SetPendingOperationType(kOperationCopy));
93 89
94 remote_proxy_->Copy(src_url, dest_url, 90 remote_proxy_->Copy(src_url, dest_url,
95 base::Bind(&RemoteFileSystemOperation::DidFinishFileOperation, 91 base::Bind(&RemoteFileSystemOperation::DidFinishFileOperation,
96 base::Owned(this), callback)); 92 AsWeakPtr(), callback));
97 } 93 }
98 94
99 void RemoteFileSystemOperation::Move(const FileSystemURL& src_url, 95 void RemoteFileSystemOperation::Move(const FileSystemURL& src_url,
100 const FileSystemURL& dest_url, 96 const FileSystemURL& dest_url,
101 const StatusCallback& callback) { 97 const StatusCallback& callback) {
102 DCHECK(SetPendingOperationType(kOperationMove)); 98 DCHECK(SetPendingOperationType(kOperationMove));
103 99
104 remote_proxy_->Move(src_url, dest_url, 100 remote_proxy_->Move(src_url, dest_url,
105 base::Bind(&RemoteFileSystemOperation::DidFinishFileOperation, 101 base::Bind(&RemoteFileSystemOperation::DidFinishFileOperation,
106 base::Owned(this), callback)); 102 AsWeakPtr(), callback));
107 } 103 }
108 104
109 void RemoteFileSystemOperation::Write( 105 void RemoteFileSystemOperation::Write(
110 const net::URLRequestContext* url_request_context, 106 const net::URLRequestContext* url_request_context,
111 const FileSystemURL& url, 107 const FileSystemURL& url,
112 const GURL& blob_url, 108 const GURL& blob_url,
113 int64 offset, 109 int64 offset,
114 const WriteCallback& callback) { 110 const WriteCallback& callback) {
115 DCHECK(SetPendingOperationType(kOperationWrite)); 111 DCHECK(SetPendingOperationType(kOperationWrite));
116 DCHECK(write_callback_.is_null());
117
118 write_callback_ = callback;
119 file_writer_delegate_.reset( 112 file_writer_delegate_.reset(
120 new fileapi::FileWriterDelegate( 113 new fileapi::FileWriterDelegate(
121 base::Bind(&RemoteFileSystemOperation::DidWrite, 114 base::Bind(&RemoteFileSystemOperation::DidWrite,
122 // FileWriterDelegate is owned by |this|. So Unretained. 115 AsWeakPtr(), callback),
123 base::Unretained(this)),
124 scoped_ptr<fileapi::FileStreamWriter>( 116 scoped_ptr<fileapi::FileStreamWriter>(
125 new fileapi::RemoteFileStreamWriter(remote_proxy_, 117 new fileapi::RemoteFileStreamWriter(remote_proxy_,
126 url, 118 url,
127 offset)))); 119 offset))));
128 120
129 scoped_ptr<net::URLRequest> blob_request(url_request_context->CreateRequest( 121 scoped_ptr<net::URLRequest> blob_request(url_request_context->CreateRequest(
130 blob_url, file_writer_delegate_.get())); 122 blob_url, file_writer_delegate_.get()));
131 123
132 file_writer_delegate_->Start(blob_request.Pass()); 124 file_writer_delegate_->Start(blob_request.Pass());
133 } 125 }
134 126
135 void RemoteFileSystemOperation::Truncate(const FileSystemURL& url, 127 void RemoteFileSystemOperation::Truncate(const FileSystemURL& url,
136 int64 length, 128 int64 length,
137 const StatusCallback& callback) { 129 const StatusCallback& callback) {
138 DCHECK(SetPendingOperationType(kOperationTruncate)); 130 DCHECK(SetPendingOperationType(kOperationTruncate));
139 131
140 remote_proxy_->Truncate(url, length, 132 remote_proxy_->Truncate(url, length,
141 base::Bind(&RemoteFileSystemOperation::DidFinishFileOperation, 133 base::Bind(&RemoteFileSystemOperation::DidFinishFileOperation,
142 base::Owned(this), callback)); 134 AsWeakPtr(), callback));
143 } 135 }
144 136
145 void RemoteFileSystemOperation::Cancel(const StatusCallback& cancel_callback) { 137 void RemoteFileSystemOperation::Cancel(const StatusCallback& cancel_callback) {
138 DCHECK(cancel_callback_.is_null());
139 cancel_callback_ = cancel_callback;
140
146 if (file_writer_delegate_) { 141 if (file_writer_delegate_) {
147 DCHECK_EQ(kOperationWrite, pending_operation_); 142 DCHECK_EQ(kOperationWrite, pending_operation_);
148 143 // This will call DidWrite() with ABORT status code.
149 // Writes are done without proxying through FileUtilProxy after the initial 144 file_writer_delegate_->Cancel();
150 // opening of the PlatformFile. All state changes are done on this thread,
151 // so we're guaranteed to be able to shut down atomically.
152 const bool delete_now = file_writer_delegate_->Cancel();
153
154 if (!write_callback_.is_null()) {
155 // Notify the failure status to the ongoing operation's callback.
156 write_callback_.Run(base::PLATFORM_FILE_ERROR_ABORT, 0, false);
157 }
158 cancel_callback.Run(base::PLATFORM_FILE_OK);
159 write_callback_.Reset();
160
161 if (delete_now) {
162 delete this;
163 return;
164 }
165 } else { 145 } else {
146 // For truncate we have no way to cancel the inflight operation (for now).
147 // Let it just run and dispatch cancel callback later.
166 DCHECK_EQ(kOperationTruncate, pending_operation_); 148 DCHECK_EQ(kOperationTruncate, pending_operation_);
167 // We're cancelling a truncate operation, but we can't actually stop it
168 // since it's been proxied to another thread. We need to save the
169 // cancel_callback so that when the truncate returns, it can see that it's
170 // been cancelled, report it, and report that the cancel has succeeded.
171 DCHECK(cancel_callback_.is_null());
172 cancel_callback_ = cancel_callback;
173 } 149 }
174 } 150 }
175 151
176 void RemoteFileSystemOperation::TouchFile(const FileSystemURL& url, 152 void RemoteFileSystemOperation::TouchFile(const FileSystemURL& url,
177 const base::Time& last_access_time, 153 const base::Time& last_access_time,
178 const base::Time& last_modified_time, 154 const base::Time& last_modified_time,
179 const StatusCallback& callback) { 155 const StatusCallback& callback) {
180 DCHECK(SetPendingOperationType(kOperationTouchFile)); 156 DCHECK(SetPendingOperationType(kOperationTouchFile));
181 remote_proxy_->TouchFile( 157 remote_proxy_->TouchFile(
182 url, 158 url,
183 last_access_time, 159 last_access_time,
184 last_modified_time, 160 last_modified_time,
185 base::Bind(&RemoteFileSystemOperation::DidFinishFileOperation, 161 base::Bind(&RemoteFileSystemOperation::DidFinishFileOperation,
186 base::Owned(this), callback)); 162 AsWeakPtr(), callback));
187 } 163 }
188 164
189 void RemoteFileSystemOperation::OpenFile(const FileSystemURL& url, 165 void RemoteFileSystemOperation::OpenFile(const FileSystemURL& url,
190 int file_flags, 166 int file_flags,
191 base::ProcessHandle peer_handle, 167 base::ProcessHandle peer_handle,
192 const OpenFileCallback& callback) { 168 const OpenFileCallback& callback) {
193 DCHECK(SetPendingOperationType(kOperationOpenFile)); 169 DCHECK(SetPendingOperationType(kOperationOpenFile));
194 remote_proxy_->OpenFile( 170 remote_proxy_->OpenFile(
195 url, 171 url,
196 file_flags, 172 file_flags,
197 peer_handle, 173 peer_handle,
198 base::Bind(&RemoteFileSystemOperation::DidOpenFile, 174 base::Bind(&RemoteFileSystemOperation::DidOpenFile,
199 base::Owned(this), url, callback)); 175 AsWeakPtr(), url, callback));
200 } 176 }
201 177
202 fileapi::LocalFileSystemOperation* 178 fileapi::LocalFileSystemOperation*
203 RemoteFileSystemOperation::AsLocalFileSystemOperation() { 179 RemoteFileSystemOperation::AsLocalFileSystemOperation() {
204 NOTIMPLEMENTED(); 180 NOTIMPLEMENTED();
205 return NULL; 181 return NULL;
206 } 182 }
207 183
208 void RemoteFileSystemOperation::CreateSnapshotFile( 184 void RemoteFileSystemOperation::CreateSnapshotFile(
209 const FileSystemURL& url, 185 const FileSystemURL& url,
210 const SnapshotFileCallback& callback) { 186 const SnapshotFileCallback& callback) {
211 DCHECK(SetPendingOperationType(kOperationCreateSnapshotFile)); 187 DCHECK(SetPendingOperationType(kOperationCreateSnapshotFile));
212 remote_proxy_->CreateSnapshotFile( 188 remote_proxy_->CreateSnapshotFile(url, callback);
213 url,
214 base::Bind(&RemoteFileSystemOperation::DidCreateSnapshotFile,
215 base::Owned(this), callback));
216 } 189 }
217 190
218 bool RemoteFileSystemOperation::SetPendingOperationType(OperationType type) { 191 bool RemoteFileSystemOperation::SetPendingOperationType(OperationType type) {
219 if (pending_operation_ != kOperationNone) 192 if (pending_operation_ != kOperationNone)
220 return false; 193 return false;
221 pending_operation_ = type; 194 pending_operation_ = type;
222 return true; 195 return true;
223 } 196 }
224 197
225 void RemoteFileSystemOperation::DidDirectoryExists( 198 void RemoteFileSystemOperation::DidDirectoryExists(
226 const StatusCallback& callback, 199 const StatusCallback& callback,
227 base::PlatformFileError rv, 200 base::PlatformFileError rv,
228 const base::PlatformFileInfo& file_info, 201 const base::PlatformFileInfo& file_info,
229 const base::FilePath& unused) { 202 const base::FilePath& unused) {
230 if (rv == base::PLATFORM_FILE_OK && !file_info.is_directory) 203 if (rv == base::PLATFORM_FILE_OK && !file_info.is_directory)
231 rv = base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY; 204 rv = base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY;
232 callback.Run(rv); 205 callback.Run(rv);
233 } 206 }
234 207
235 void RemoteFileSystemOperation::DidFileExists( 208 void RemoteFileSystemOperation::DidFileExists(
236 const StatusCallback& callback, 209 const StatusCallback& callback,
237 base::PlatformFileError rv, 210 base::PlatformFileError rv,
238 const base::PlatformFileInfo& file_info, 211 const base::PlatformFileInfo& file_info,
239 const base::FilePath& unused) { 212 const base::FilePath& unused) {
240 if (rv == base::PLATFORM_FILE_OK && file_info.is_directory) 213 if (rv == base::PLATFORM_FILE_OK && file_info.is_directory)
241 rv = base::PLATFORM_FILE_ERROR_NOT_A_FILE; 214 rv = base::PLATFORM_FILE_ERROR_NOT_A_FILE;
242 callback.Run(rv); 215 callback.Run(rv);
243 } 216 }
244 217
245 void RemoteFileSystemOperation::DidGetMetadata(
246 const GetMetadataCallback& callback,
247 base::PlatformFileError rv,
248 const base::PlatformFileInfo& file_info,
249 const base::FilePath& platform_path) {
250 callback.Run(rv, file_info, platform_path);
251 }
252
253 void RemoteFileSystemOperation::DidReadDirectory(
254 const ReadDirectoryCallback& callback,
255 base::PlatformFileError rv,
256 const std::vector<fileapi::DirectoryEntry>& entries,
257 bool has_more) {
258 callback.Run(rv, entries, has_more /* has_more */);
259 }
260
261 void RemoteFileSystemOperation::DidWrite( 218 void RemoteFileSystemOperation::DidWrite(
219 const WriteCallback& write_callback,
262 base::PlatformFileError rv, 220 base::PlatformFileError rv,
263 int64 bytes, 221 int64 bytes,
264 FileWriterDelegate::WriteProgressStatus write_status) { 222 FileWriterDelegate::WriteProgressStatus write_status) {
265 if (write_callback_.is_null()) {
266 // If cancelled, callback is already invoked and set to null in Cancel().
267 // We must not call it twice. Just shut down this operation object.
268 delete this;
269 return;
270 }
271
272 bool complete = (write_status != FileWriterDelegate::SUCCESS_IO_PENDING); 223 bool complete = (write_status != FileWriterDelegate::SUCCESS_IO_PENDING);
273 write_callback_.Run(rv, bytes, complete); 224 StatusCallback cancel_callback = cancel_callback_;
274 if (rv != base::PLATFORM_FILE_OK || complete) { 225 write_callback.Run(rv, bytes, complete);
275 // Other Did*'s doesn't have "delete this", because it is automatic since 226 if (!cancel_callback.is_null())
276 // they are base::Owned by the caller of the callback. For DidWrite, the 227 cancel_callback.Run(base::PLATFORM_FILE_OK);
277 // owner is file_writer_delegate_ which itself is owned by this Operation
278 // object. Hence we need manual life time management here.
279 // TODO(kinaba): think about refactoring FileWriterDelegate to be self
280 // destructing, for avoiding the manual management.
281 delete this;
282 }
283 } 228 }
284 229
285 void RemoteFileSystemOperation::DidFinishFileOperation( 230 void RemoteFileSystemOperation::DidFinishFileOperation(
286 const StatusCallback& callback, 231 const StatusCallback& callback,
287 base::PlatformFileError rv) { 232 base::PlatformFileError rv) {
288 if (!cancel_callback_.is_null()) { 233 if (!cancel_callback_.is_null()) {
289 DCHECK_EQ(kOperationTruncate, pending_operation_); 234 DCHECK_EQ(kOperationTruncate, pending_operation_);
290 235
236 StatusCallback cancel_callback = cancel_callback_;
291 callback.Run(base::PLATFORM_FILE_ERROR_ABORT); 237 callback.Run(base::PLATFORM_FILE_ERROR_ABORT);
292 cancel_callback_.Run(base::PLATFORM_FILE_OK); 238 cancel_callback.Run(base::PLATFORM_FILE_OK);
293 cancel_callback_.Reset();
294 } else { 239 } else {
295 callback.Run(rv); 240 callback.Run(rv);
296 } 241 }
297 } 242 }
298 243
299 void RemoteFileSystemOperation::DidCreateSnapshotFile(
300 const SnapshotFileCallback& callback,
301 base::PlatformFileError result,
302 const base::PlatformFileInfo& file_info,
303 const base::FilePath& platform_path,
304 const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref) {
305 callback.Run(result, file_info, platform_path, file_ref);
306 }
307
308 void RemoteFileSystemOperation::DidOpenFile( 244 void RemoteFileSystemOperation::DidOpenFile(
309 const fileapi::FileSystemURL& url, 245 const fileapi::FileSystemURL& url,
310 const OpenFileCallback& callback, 246 const OpenFileCallback& callback,
311 base::PlatformFileError result, 247 base::PlatformFileError result,
312 base::PlatformFile file, 248 base::PlatformFile file,
313 base::ProcessHandle peer_handle) { 249 base::ProcessHandle peer_handle) {
314 callback.Run( 250 callback.Run(
315 result, file, 251 result, file,
316 base::Bind(&fileapi::RemoteFileSystemProxyInterface::NotifyCloseFile, 252 base::Bind(&fileapi::RemoteFileSystemProxyInterface::NotifyCloseFile,
317 remote_proxy_, url), 253 remote_proxy_, url),
318 peer_handle); 254 peer_handle);
319 } 255 }
320 256
321 } // namespace chromeos 257 } // namespace chromeos
OLDNEW
« no previous file with comments | « webkit/browser/chromeos/fileapi/remote_file_system_operation.h ('k') | webkit/browser/fileapi/async_file_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698