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

Side by Side Diff: chrome/browser/chromeos/drive/fileapi_worker.cc

Issue 148913005: Create fileapi/ subdirectory under c/b/cros/drive. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 10 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
(Empty)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
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 "chrome/browser/chromeos/drive/fileapi_worker.h"
6
7 #include "base/files/file_path.h"
8 #include "base/logging.h"
9 #include "base/task_runner_util.h"
10 #include "base/threading/sequenced_worker_pool.h"
11 #include "chrome/browser/chromeos/drive/drive.pb.h"
12 #include "chrome/browser/chromeos/drive/file_errors.h"
13 #include "chrome/browser/chromeos/drive/file_system_interface.h"
14 #include "chrome/browser/chromeos/drive/file_system_util.h"
15 #include "chrome/browser/chromeos/drive/resource_entry_conversion.h"
16 #include "content/public/browser/browser_thread.h"
17 #include "webkit/common/fileapi/directory_entry.h"
18
19 using content::BrowserThread;
20
21 namespace drive {
22 namespace fileapi_internal {
23 namespace {
24
25 // The summary of opening mode is:
26 // - PLATFORM_FILE_OPEN: Open the existing file. Fail if not exists.
27 // - PLATFORM_FILE_CREATE: Create the file if not exists. Fail if exists.
28 // - PLATFORM_FILE_OPEN_ALWAYS: Open the existing file. Create a new file
29 // if not exists.
30 // - PLATFORM_FILE_CREATE_ALWAYS: Create a new file if not exists. If exists
31 // open it with truncate.
32 // - PLATFORM_FILE_OPEN_TRUNCATE: Open the existing file with truncate.
33 // Fail if not exists.
34 OpenMode GetOpenMode(int file_flag) {
35 if (file_flag & (base::PLATFORM_FILE_OPEN |
36 base::PLATFORM_FILE_OPEN_TRUNCATED))
37 return OPEN_FILE;
38
39 if (file_flag & base::PLATFORM_FILE_CREATE)
40 return CREATE_FILE;
41
42 DCHECK(file_flag & (base::PLATFORM_FILE_OPEN_ALWAYS |
43 base::PLATFORM_FILE_CREATE_ALWAYS));
44 return OPEN_OR_CREATE_FILE;
45 }
46
47 // Runs |callback| with the File::Error converted from |error|.
48 void RunStatusCallbackByFileError(const StatusCallback& callback,
49 FileError error) {
50 callback.Run(FileErrorToBaseFileError(error));
51 }
52
53 // Runs |callback| with arguments converted from |error| and |entry|.
54 void RunGetFileInfoCallback(const GetFileInfoCallback& callback,
55 FileError error,
56 scoped_ptr<ResourceEntry> entry) {
57 if (error != FILE_ERROR_OK) {
58 callback.Run(FileErrorToBaseFileError(error), base::File::Info());
59 return;
60 }
61
62 DCHECK(entry);
63 base::File::Info file_info;
64 ConvertResourceEntryToFileInfo(*entry, &file_info);
65 callback.Run(base::File::FILE_OK, file_info);
66 }
67
68 // Runs |callback| with arguments converted from |error| and |resource_entries|.
69 void RunReadDirectoryCallback(
70 const ReadDirectoryCallback& callback,
71 FileError error,
72 scoped_ptr<ResourceEntryVector> resource_entries) {
73 if (error != FILE_ERROR_OK) {
74 callback.Run(FileErrorToBaseFileError(error),
75 std::vector<fileapi::DirectoryEntry>(), false);
76 return;
77 }
78
79 DCHECK(resource_entries);
80
81 std::vector<fileapi::DirectoryEntry> entries;
82 // Convert drive files to File API's directory entry.
83 entries.reserve(resource_entries->size());
84 for (size_t i = 0; i < resource_entries->size(); ++i) {
85 const ResourceEntry& resource_entry = (*resource_entries)[i];
86 fileapi::DirectoryEntry entry;
87 entry.name = resource_entry.base_name();
88
89 const PlatformFileInfoProto& file_info = resource_entry.file_info();
90 entry.is_directory = file_info.is_directory();
91 entry.size = file_info.size();
92 entry.last_modified_time =
93 base::Time::FromInternalValue(file_info.last_modified());
94 entries.push_back(entry);
95 }
96
97 callback.Run(base::File::FILE_OK, entries, false);
98 }
99
100 // Runs |callback| with arguments based on |error|, |local_path| and |entry|.
101 void RunCreateSnapshotFileCallback(const CreateSnapshotFileCallback& callback,
102 FileError error,
103 const base::FilePath& local_path,
104 scoped_ptr<ResourceEntry> entry) {
105 if (error != FILE_ERROR_OK) {
106 callback.Run(
107 FileErrorToBaseFileError(error),
108 base::File::Info(), base::FilePath(),
109 webkit_blob::ScopedFile::ScopeOutPolicy());
110 return;
111 }
112
113 DCHECK(entry);
114
115 // When reading file, last modified time specified in file info will be
116 // compared to the last modified time of the local version of the drive file.
117 // Since those two values don't generally match (last modification time on the
118 // drive server vs. last modification time of the local, downloaded file), so
119 // we have to opt out from this check. We do this by unsetting last_modified
120 // value in the file info passed to the CreateSnapshot caller.
121 base::File::Info file_info;
122 ConvertResourceEntryToFileInfo(*entry, &file_info);
123 file_info.last_modified = base::Time();
124
125 // If the file is a hosted document, a temporary JSON file is created to
126 // represent the document. The JSON file is not cached and its lifetime
127 // is managed by ShareableFileReference.
128 webkit_blob::ScopedFile::ScopeOutPolicy scope_out_policy =
129 entry->file_specific_info().is_hosted_document() ?
130 webkit_blob::ScopedFile::DELETE_ON_SCOPE_OUT :
131 webkit_blob::ScopedFile::DONT_DELETE_ON_SCOPE_OUT;
132
133 callback.Run(base::File::FILE_OK, file_info, local_path, scope_out_policy);
134 }
135
136 // Runs |callback| with arguments converted from |error| and |local_path|.
137 void RunCreateWritableSnapshotFileCallback(
138 const CreateWritableSnapshotFileCallback& callback,
139 FileError error,
140 const base::FilePath& local_path,
141 const base::Closure& close_callback) {
142 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
143 callback.Run(FileErrorToBaseFileError(error), local_path, close_callback);
144 }
145
146 // Runs |callback| with |error| and |platform_file|.
147 void RunOpenFileCallback(const OpenFileCallback& callback,
148 const base::Closure& close_callback,
149 base::File::Error* error,
150 base::PlatformFile platform_file) {
151 callback.Run(*error, platform_file, close_callback);
152 }
153
154 // Part of OpenFile(). Called after FileSystem::OpenFile().
155 void OpenFileAfterFileSystemOpenFile(int file_flags,
156 const OpenFileCallback& callback,
157 FileError error,
158 const base::FilePath& local_path,
159 const base::Closure& close_callback) {
160 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
161
162 if (error != FILE_ERROR_OK) {
163 callback.Run(FileErrorToBaseFileError(error),
164 base::kInvalidPlatformFileValue,
165 base::Closure());
166 return;
167 }
168
169 // Here, the file should be at |local_path|, but there may be timing issue.
170 // Because the file is managed by Drive file system, so, in order to avoid
171 // unexpected file creation, CREATE, OPEN_ALWAYS and CREATE_ALWAYS are
172 // translated into OPEN or OPEN_TRUNCATED, here. Keep OPEN and OPEN_TRUNCATED
173 // as is.
174 if (file_flags & (base::PLATFORM_FILE_CREATE |
175 base::PLATFORM_FILE_OPEN_ALWAYS)) {
176 file_flags &= ~(base::PLATFORM_FILE_CREATE |
177 base::PLATFORM_FILE_OPEN_ALWAYS);
178 file_flags |= base::PLATFORM_FILE_OPEN;
179 } else if (file_flags & base::PLATFORM_FILE_CREATE_ALWAYS) {
180 file_flags &= ~base::PLATFORM_FILE_CREATE_ALWAYS;
181 file_flags |= base::PLATFORM_FILE_OPEN_TRUNCATED;
182 }
183
184 // Cache file prepared for modification is available. Open it locally.
185 // TODO(rvargas): Convert this to base::File.
186 base::File::Error* result =
187 new base::File::Error(base::File::FILE_ERROR_FAILED);
188 bool posted = base::PostTaskAndReplyWithResult(
189 BrowserThread::GetBlockingPool(), FROM_HERE,
190 base::Bind(&base::CreatePlatformFile,
191 local_path, file_flags, static_cast<bool*>(NULL),
192 reinterpret_cast<base::PlatformFileError*>(result)),
193 base::Bind(&RunOpenFileCallback,
194 callback, close_callback, base::Owned(result)));
195 DCHECK(posted);
196 }
197
198 } // namespace
199
200 void RunFileSystemCallback(
201 const FileSystemGetter& file_system_getter,
202 const base::Callback<void(FileSystemInterface*)>& callback,
203 const base::Closure& on_error_callback) {
204 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
205 FileSystemInterface* file_system = file_system_getter.Run();
206
207 if (!file_system) {
208 if (!on_error_callback.is_null())
209 on_error_callback.Run();
210 return;
211 }
212
213 callback.Run(file_system);
214 }
215
216 void GetFileInfo(const base::FilePath& file_path,
217 const GetFileInfoCallback& callback,
218 FileSystemInterface* file_system) {
219 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
220 file_system->GetResourceEntry(
221 file_path,
222 base::Bind(&RunGetFileInfoCallback, callback));
223 }
224
225 void Copy(const base::FilePath& src_file_path,
226 const base::FilePath& dest_file_path,
227 bool preserve_last_modified,
228 const StatusCallback& callback,
229 FileSystemInterface* file_system) {
230 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
231 file_system->Copy(src_file_path, dest_file_path, preserve_last_modified,
232 base::Bind(&RunStatusCallbackByFileError, callback));
233 }
234
235 void Move(const base::FilePath& src_file_path,
236 const base::FilePath& dest_file_path,
237 bool preserve_last_modified,
238 const StatusCallback& callback,
239 FileSystemInterface* file_system) {
240 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
241 file_system->Move(src_file_path, dest_file_path, preserve_last_modified,
242 base::Bind(&RunStatusCallbackByFileError, callback));
243 }
244
245 void CopyInForeignFile(const base::FilePath& src_foreign_file_path,
246 const base::FilePath& dest_file_path,
247 const StatusCallback& callback,
248 FileSystemInterface* file_system) {
249 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
250 file_system->TransferFileFromLocalToRemote(
251 src_foreign_file_path, dest_file_path,
252 base::Bind(&RunStatusCallbackByFileError, callback));
253 }
254
255 void ReadDirectory(const base::FilePath& file_path,
256 const ReadDirectoryCallback& callback,
257 FileSystemInterface* file_system) {
258 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
259 file_system->ReadDirectory(file_path,
260 base::Bind(&RunReadDirectoryCallback, callback));
261 }
262
263 void Remove(const base::FilePath& file_path,
264 bool is_recursive,
265 const StatusCallback& callback,
266 FileSystemInterface* file_system) {
267 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
268 file_system->Remove(file_path, is_recursive,
269 base::Bind(&RunStatusCallbackByFileError, callback));
270 }
271
272 void CreateDirectory(const base::FilePath& file_path,
273 bool is_exclusive,
274 bool is_recursive,
275 const StatusCallback& callback,
276 FileSystemInterface* file_system) {
277 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
278 file_system->CreateDirectory(
279 file_path, is_exclusive, is_recursive,
280 base::Bind(&RunStatusCallbackByFileError, callback));
281 }
282
283 void CreateFile(const base::FilePath& file_path,
284 bool is_exclusive,
285 const StatusCallback& callback,
286 FileSystemInterface* file_system) {
287 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
288 file_system->CreateFile(file_path, is_exclusive,
289 std::string(), // no mime type; guess from file_path
290 base::Bind(&RunStatusCallbackByFileError, callback));
291 }
292
293 void Truncate(const base::FilePath& file_path,
294 int64 length,
295 const StatusCallback& callback,
296 FileSystemInterface* file_system) {
297 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
298 file_system->TruncateFile(
299 file_path, length,
300 base::Bind(&RunStatusCallbackByFileError, callback));
301 }
302
303 void CreateSnapshotFile(const base::FilePath& file_path,
304 const CreateSnapshotFileCallback& callback,
305 FileSystemInterface* file_system) {
306 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
307 file_system->GetFile(file_path,
308 base::Bind(&RunCreateSnapshotFileCallback, callback));
309 }
310
311 void CreateWritableSnapshotFile(
312 const base::FilePath& file_path,
313 const CreateWritableSnapshotFileCallback& callback,
314 FileSystemInterface* file_system) {
315 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
316 file_system->OpenFile(
317 file_path,
318 OPEN_FILE,
319 std::string(), // no mime type; we never create a new file here.
320 base::Bind(&RunCreateWritableSnapshotFileCallback, callback));
321 }
322
323 void OpenFile(const base::FilePath& file_path,
324 int file_flags,
325 const OpenFileCallback& callback,
326 FileSystemInterface* file_system) {
327 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
328
329 // Returns an error if any unsupported flag is found.
330 if (file_flags & ~(base::PLATFORM_FILE_OPEN |
331 base::PLATFORM_FILE_CREATE |
332 base::PLATFORM_FILE_OPEN_ALWAYS |
333 base::PLATFORM_FILE_CREATE_ALWAYS |
334 base::PLATFORM_FILE_OPEN_TRUNCATED |
335 base::PLATFORM_FILE_READ |
336 base::PLATFORM_FILE_WRITE |
337 base::PLATFORM_FILE_WRITE_ATTRIBUTES |
338 base::PLATFORM_FILE_APPEND)) {
339 base::MessageLoopProxy::current()->PostTask(
340 FROM_HERE,
341 base::Bind(callback,
342 base::File::FILE_ERROR_FAILED,
343 base::kInvalidPlatformFileValue,
344 base::Closure()));
345 return;
346 }
347
348 file_system->OpenFile(
349 file_path, GetOpenMode(file_flags),
350 std::string(), // no mime type; guess from file_path
351 base::Bind(&OpenFileAfterFileSystemOpenFile, file_flags, callback));
352 }
353
354 void TouchFile(const base::FilePath& file_path,
355 const base::Time& last_access_time,
356 const base::Time& last_modified_time,
357 const StatusCallback& callback,
358 FileSystemInterface* file_system) {
359 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
360 file_system->TouchFile(file_path, last_access_time, last_modified_time,
361 base::Bind(&RunStatusCallbackByFileError, callback));
362
363 }
364
365 } // namespace fileapi_internal
366 } // namespace drive
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/drive/fileapi_worker.h ('k') | chrome/browser/chromeos/drive/fileapi_worker_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698