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

Side by Side Diff: chrome/browser/extensions/api/extfs/extfs_api.cc

Issue 16439016: extfs (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 7 years, 5 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/extensions/api/extfs/extfs_api.h"
6
7 #include "base/compiler_specific.h"
8 #include "base/file_util.h"
9 #include "chrome/browser/extensions/event_names.h"
10 #include "chrome/browser/extensions/event_router.h"
11 #include "chrome/browser/extensions/extension_system.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/common/extensions/api/extfs.h"
14 #include "components/browser_context_keyed_service/browser_context_dependency_ma nager.h"
15 #include "components/browser_context_keyed_service/browser_context_keyed_service .h"
16 #include "components/browser_context_keyed_service/browser_context_keyed_service _factory.h"
17 #include "content/public/browser/browser_context.h"
18 #include "webkit/browser/blob/file_stream_reader.h"
19 #include "webkit/browser/fileapi/external_mount_points.h"
20 #include "webkit/browser/fileapi/file_system_url.h"
21 #include "webkit/browser/fileapi/remote_file_system_proxy.h"
22 #include "webkit/common/blob/shareable_file_reference.h"
23 #include "webkit/common/fileapi/directory_entry.h"
24
25 using content::BrowserThread;
26
27 namespace extensions {
28
29 namespace {
30
31 // Converts api::extfs::FileError to base::PlatformFileError.
32 base::PlatformFileError ToPlatformFileError(api::extfs::FileError error) {
33 switch (error) {
34 case api::extfs::FILE_ERROR_NONE:
35 break;
36 case api::extfs::FILE_ERROR_OK:
37 return base::PLATFORM_FILE_OK;
38 case api::extfs::FILE_ERROR_ERROR_FAILED:
39 return base::PLATFORM_FILE_ERROR_FAILED;
40 case api::extfs::FILE_ERROR_ERROR_IN_USE:
41 return base::PLATFORM_FILE_ERROR_IN_USE;
42 case api::extfs::FILE_ERROR_ERROR_EXISTS:
43 return base::PLATFORM_FILE_ERROR_EXISTS;
44 case api::extfs::FILE_ERROR_ERROR_NOT_FOUND:
45 return base::PLATFORM_FILE_ERROR_NOT_FOUND;
46 case api::extfs::FILE_ERROR_ERROR_ACCESS_DENIED:
47 return base::PLATFORM_FILE_ERROR_ACCESS_DENIED;
48 case api::extfs::FILE_ERROR_ERROR_TOO_MANY_OPENED:
49 return base::PLATFORM_FILE_ERROR_TOO_MANY_OPENED;
50 case api::extfs::FILE_ERROR_ERROR_NO_MEMORY:
51 return base::PLATFORM_FILE_ERROR_NO_MEMORY;
52 case api::extfs::FILE_ERROR_ERROR_NO_SPACE:
53 return base::PLATFORM_FILE_ERROR_NO_SPACE;
54 case api::extfs::FILE_ERROR_ERROR_NOT_A_DIRECTORY:
55 return base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY;
56 case api::extfs::FILE_ERROR_ERROR_INVALID_OPERATION:
57 return base::PLATFORM_FILE_ERROR_INVALID_OPERATION;
58 case api::extfs::FILE_ERROR_ERROR_SECURITY:
59 return base::PLATFORM_FILE_ERROR_SECURITY;
60 case api::extfs::FILE_ERROR_ERROR_ABORT:
61 return base::PLATFORM_FILE_ERROR_ABORT;
62 case api::extfs::FILE_ERROR_ERROR_NOT_A_FILE:
63 return base::PLATFORM_FILE_ERROR_NOT_A_FILE;
64 case api::extfs::FILE_ERROR_ERROR_NOT_EMPTY:
65 return base::PLATFORM_FILE_ERROR_NOT_EMPTY;
66 case api::extfs::FILE_ERROR_ERROR_INVALID_URL:
67 return base::PLATFORM_FILE_ERROR_INVALID_URL;
68 case api::extfs::FILE_ERROR_ERROR_IO:
69 return base::PLATFORM_FILE_ERROR_IO;
70 case api::extfs::FILE_ERROR_ERROR_MAX:
71 return base::PLATFORM_FILE_ERROR_MAX;
72 }
73 NOTREACHED();
74 return base::PLATFORM_FILE_ERROR_FAILED;
75 }
76
77 void CreateTemporaryFile(
78 scoped_ptr<std::string> content,
79 base::PlatformFileError* error,
80 base::PlatformFileInfo* file_info,
81 base::FilePath* file_path) {
82 DCHECK(content);
83 DCHECK(error);
84 DCHECK(file_info);
85 DCHECK(file_path);
86
87 *error = base::PLATFORM_FILE_ERROR_FAILED;
88
89
90 if (!file_util::CreateTemporaryFile(file_path))
91 return;
92
93 if (file_util::WriteFile(*file_path, content->data(), content->size()) !=
94 static_cast<int>(content->size()))
95 return;
96
97 if (!file_util::GetFileInfo(*file_path, file_info))
98 return;
99
100 *error = base::PLATFORM_FILE_OK;
101 }
102
103 } // namespace
104
105 class ExtfsProxy : public fileapi::RemoteFileSystemProxyInterface {
106 public:
107 ExtfsProxy(Profile* profile)
108 : profile_(profile),
109 request_id_(0) {
110 }
111
112 bool AddMountPoint(const std::string& mount_point,
113 const std::string& extension_id) {
114 if (mount_point_to_extension_id_map_.count(mount_point) > 0)
115 return false;
116 mount_point_to_extension_id_map_[mount_point] = extension_id;
117 return true;
118 }
119
120 std::string GetExtensionIdFromPath(const base::FilePath& path) {
121 std::vector<base::FilePath::StringType> components;
122 path.GetComponents(&components);
123 DCHECK_LE(2U, components.size());
124 DCHECK_EQ(FILE_PATH_LITERAL("/"), components[0]);
125 const std::string mount_point =
126 base::FilePath(components[1]).AsUTF8Unsafe();
127
128 LOG(ERROR) << "@@ mount_point: " << mount_point;
129 DCHECK_EQ(1U, mount_point_to_extension_id_map_.count(mount_point));
130 return mount_point_to_extension_id_map_[mount_point];
131 }
132
133 // fileapi::RemoteFileSystemProxyInterface overrides.
134 virtual void GetFileInfo(
135 const fileapi::FileSystemURL& url,
136 const fileapi::FileSystemOperation::GetMetadataCallback& callback)
137 OVERRIDE {
138 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
139 LOG(ERROR) << "@@ " << __FUNCTION__ << ": " << url.path().value();
140 const std::string extension_id = GetExtensionIdFromPath(url.path());
141 DCHECK(!extension_id.empty());
142
143 get_metadata_callback_map_[request_id_] = callback;
144 scoped_ptr<base::ListValue> values(new ListValue());
145 values->AppendInteger(request_id_);
146 values->AppendString(url.path().value());
147 scoped_ptr<Event> event(new Event(event_names::kOnEntryRequested,
148 values.Pass()));
149
150 GetEventRouter()->DispatchEventToExtension(extension_id, event.Pass());
151 ++request_id_;
152 }
153
154 virtual void Copy(
155 const fileapi::FileSystemURL& src_url,
156 const fileapi::FileSystemURL& dest_url,
157 const fileapi::FileSystemOperation::StatusCallback& callback)
158 OVERRIDE {
159 NOTREACHED() << "@@ not implemented";
160 }
161
162 virtual void Move(
163 const fileapi::FileSystemURL& src_url,
164 const fileapi::FileSystemURL& dest_url,
165 const fileapi::FileSystemOperation::StatusCallback& callback)
166 OVERRIDE {
167 NOTREACHED() << "@@ not implemented";
168 }
169
170 virtual void ReadDirectory(
171 const fileapi::FileSystemURL& url,
172 const fileapi::FileSystemOperation::ReadDirectoryCallback& callback)
173 OVERRIDE {
174 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
175 LOG(ERROR) << "@@ " << __FUNCTION__ << ": " << url.path().value();
176 const std::string extension_id = GetExtensionIdFromPath(url.path());
177 DCHECK(!extension_id.empty());
178
179 read_directory_callback_map_[request_id_] = callback;
180 scoped_ptr<base::ListValue> values(new ListValue());
181 values->AppendInteger(request_id_);
182 values->AppendString(url.path().value());
183 scoped_ptr<Event> event(
184 new Event(event_names::kOnDirectoryEntriesRequested,
185 values.Pass()));
186
187 GetEventRouter()->DispatchEventToExtension(extension_id, event.Pass());
188 ++request_id_;
189 }
190
191 virtual void Remove(
192 const fileapi::FileSystemURL& url, bool recursive,
193 const fileapi::FileSystemOperation::StatusCallback& callback)
194 OVERRIDE {
195 NOTREACHED() << "@@ not implemented";
196 }
197
198 virtual void CreateDirectory(
199 const fileapi::FileSystemURL& file_url,
200 bool exclusive,
201 bool recursive,
202 const fileapi::FileSystemOperation::StatusCallback& callback)
203 OVERRIDE {
204 NOTREACHED() << "@@ not implemented";
205 }
206
207 virtual void CreateFile(
208 const fileapi::FileSystemURL& file_url,
209 bool exclusive,
210 const fileapi::FileSystemOperation::StatusCallback& callback)
211 OVERRIDE {
212 NOTREACHED() << "@@ not implemented";
213 }
214
215 virtual void Truncate(
216 const fileapi::FileSystemURL& file_url, int64 length,
217 const fileapi::FileSystemOperation::StatusCallback& callback)
218 OVERRIDE {
219 NOTREACHED() << "@@ not implemented";
220 }
221
222 virtual void CreateSnapshotFile(
223 const fileapi::FileSystemURL& url,
224 const fileapi::FileSystemOperation::SnapshotFileCallback& callback)
225 OVERRIDE {
226 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
227 LOG(ERROR) << "@@ " << __FUNCTION__ << ": " << url.path().value();
228 const std::string extension_id = GetExtensionIdFromPath(url.path());
229 DCHECK(!extension_id.empty());
230
231 snapshot_file_callback_map_[request_id_] = callback;
232 scoped_ptr<base::ListValue> values(new ListValue());
233 values->AppendInteger(request_id_);
234 values->AppendString(url.path().value());
235 scoped_ptr<Event> event(
236 new Event(event_names::kOnSnapshotRequested, values.Pass()));
237
238 GetEventRouter()->DispatchEventToExtension(extension_id, event.Pass());
239 LOG(ERROR) << "@@ " << __PRETTY_FUNCTION__ << ": " << request_id_;
240 ++request_id_;
241 }
242
243 virtual void CreateWritableSnapshotFile(
244 const fileapi::FileSystemURL& url,
245 const fileapi::WritableSnapshotFile& callback) OVERRIDE {
246 NOTREACHED() << "@@ not implemented";
247 }
248
249 virtual void OpenFile(
250 const fileapi::FileSystemURL& url,
251 int file_flags,
252 base::ProcessHandle peer_handle,
253 const OpenFileCallback& callback) OVERRIDE {
254 NOTREACHED() << "@@ not implemented";
255 }
256
257 virtual void NotifyCloseFile(const fileapi::FileSystemURL& url) OVERRIDE {
258 NOTREACHED() << "@@ not implemented";
259 }
260
261 virtual void TouchFile(
262 const fileapi::FileSystemURL& url,
263 const base::Time& last_access_time,
264 const base::Time& last_modified_time,
265 const fileapi::FileSystemOperation::StatusCallback& callback)
266 OVERRIDE {
267 NOTREACHED() << "@@ not implemented";
268 }
269
270 virtual scoped_ptr<webkit_blob::FileStreamReader> CreateFileStreamReader(
271 base::SequencedTaskRunner* file_task_runner,
272 const fileapi::FileSystemURL& url,
273 int64 offset,
274 const base::Time& expected_modification_time) OVERRIDE {
275 NOTREACHED() << "@@ not implemented";
276 return scoped_ptr<webkit_blob::FileStreamReader>();
277 }
278
279 void DidGetFileInfo(int request_id,
280 const base::PlatformFileError file_error,
281 const base::PlatformFileInfo& file_info) {
282 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
283 LOG(ERROR) << "@@ " << __PRETTY_FUNCTION__;
284
285 GetMetadataCallbackMap::iterator iter =
286 get_metadata_callback_map_.find(request_id);
287 DCHECK(iter != get_metadata_callback_map_.end());
288 iter->second.Run(file_error, file_info);
289 get_metadata_callback_map_.erase(iter);
290 }
291
292 void DidReadDirectory(int request_id,
293 const base::PlatformFileError file_error,
294 const std::vector<fileapi::DirectoryEntry>& entries) {
295 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
296 LOG(ERROR) << "@@ " << __PRETTY_FUNCTION__;
297
298 ReadDirectoryCallbackMap::iterator iter =
299 read_directory_callback_map_.find(request_id);
300 DCHECK(iter != read_directory_callback_map_.end());
301 iter->second.Run(file_error, entries, false /* has more */);
302 read_directory_callback_map_.erase(iter);
303 }
304
305 void DidCreateSnapshotFile(int request_id,
306 base::PlatformFileError file_error,
307 const base::PlatformFileInfo& file_info,
308 const base::FilePath& file_path) {
309 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
310 LOG(ERROR) << "@@ " << __PRETTY_FUNCTION__ << ": " << request_id;
311
312 SnapshotFileCallbackMap::iterator iter =
313 snapshot_file_callback_map_.find(request_id);
314 DCHECK(iter != snapshot_file_callback_map_.end());
315
316 // Create a reference so that the local file is removed later.
317 scoped_refptr<webkit_blob::ShareableFileReference> reference =
318 webkit_blob::ShareableFileReference::GetOrCreate(
319 file_path,
320 webkit_blob::ShareableFileReference::DELETE_ON_FINAL_RELEASE,
321 BrowserThread::GetMessageLoopProxyForThread(
322 BrowserThread::FILE).get());
323
324 iter->second.Run(file_error, file_info, file_path, reference);
325 snapshot_file_callback_map_.erase(iter);
326 }
327
328 protected:
329 virtual ~ExtfsProxy() {
330 }
331
332 private:
333 EventRouter* GetEventRouter() {
334 return ExtensionSystem::Get(profile_)->event_router();
335 }
336
337 typedef std::map<int, fileapi::FileSystemOperation::GetMetadataCallback>
338 GetMetadataCallbackMap;
339 typedef std::map<int, fileapi::FileSystemOperation::ReadDirectoryCallback>
340 ReadDirectoryCallbackMap;
341 typedef std::map<int, fileapi::FileSystemOperation::SnapshotFileCallback>
342 SnapshotFileCallbackMap;
343
344 Profile* profile_;
345 int request_id_;
346 std::map<std::string, std::string> mount_point_to_extension_id_map_;
347 GetMetadataCallbackMap get_metadata_callback_map_;
348 ReadDirectoryCallbackMap read_directory_callback_map_;
349 SnapshotFileCallbackMap snapshot_file_callback_map_;
350 };
351
352 class ExtfsService : public BrowserContextKeyedService {
353 public:
354 ExtfsService(Profile* profile)
355 : extfs_proxy_(new ExtfsProxy(profile)) {
356 }
357
358 virtual ~ExtfsService() {
359 }
360
361 scoped_refptr<ExtfsProxy> extfs_proxy() {
362 return extfs_proxy_;
363 }
364
365 private:
366 friend class ExtfsServiceFactory;
367 scoped_refptr<ExtfsProxy> extfs_proxy_;
368 };
369
370 class ExtfsServiceFactory : public BrowserContextKeyedServiceFactory {
371 public:
372 static ExtfsService* GetForProfile(Profile* profile) {
373 return static_cast<ExtfsService*>(
374 GetInstance()->GetServiceForBrowserContext(profile, true));
375 }
376
377 static ExtfsServiceFactory* GetInstance() {
378 return Singleton<ExtfsServiceFactory>::get();
379 }
380
381 private:
382 friend struct DefaultSingletonTraits<ExtfsServiceFactory>;
383
384 ExtfsServiceFactory()
385 : BrowserContextKeyedServiceFactory(
386 "ExtfsService",
387 BrowserContextDependencyManager::GetInstance()) {
388 }
389
390 virtual ~ExtfsServiceFactory() {}
391
392 // BrowserContextKeyedServiceFactory overrides:
393 virtual BrowserContextKeyedService*
394 BuildServiceInstanceFor(content::BrowserContext* context) const OVERRIDE {
395 Profile* profile = static_cast<Profile*>(context);
396 return new ExtfsService(profile);
397 }
398 };
399
400 scoped_refptr<ExtfsProxy> GetExtfsProxy(Profile* profile) {
401 return ExtfsServiceFactory::GetForProfile(profile)->extfs_proxy();
402 }
403
404 bool ExtfsAddMountPointFunction::RunImpl() {
405 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
406
407 scoped_ptr<api::extfs::AddMountPoint::Params> params(
408 api::extfs::AddMountPoint::Params::Create(*args_));
409 EXTENSION_FUNCTION_VALIDATE(params.get());
410 LOG(ERROR) << "@@ " << __PRETTY_FUNCTION__
411 << " mount point: " << params->mount_point;
412
413 scoped_refptr<ExtfsProxy> extfs_proxy = GetExtfsProxy(profile());
414
415 if (!extfs_proxy->AddMountPoint(params->mount_point, extension_id())) {
416 NOTREACHED();
417 }
418
419 fileapi::ExternalMountPoints* mount_points =
420 content::BrowserContext::GetMountPoints(profile_);
421 DCHECK(mount_points);
422
423 bool success = mount_points->RegisterRemoteFileSystem(
424 params->mount_point,
425 // TODO(satorux): This file system type is wrong.
426 fileapi::kFileSystemTypeDrive,
427 extfs_proxy,
428 base::FilePath::FromUTF8Unsafe("/" + params->mount_point));
429 DCHECK(success);
430
431 SetResult(base::Value::CreateStringValue(
432 api::extfs::ToString(api::extfs::FILE_ERROR_OK)));
433 SendResponse(true);
434 return true;
435 }
436
437 bool ExtfsReturnEntryFunction::RunImpl() {
438 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
439 LOG(ERROR) << "@@ " << __PRETTY_FUNCTION__;
440
441 scoped_ptr<api::extfs::ReturnEntry::Params> params(
442 api::extfs::ReturnEntry::Params::Create(*args_));
443
444 EXTENSION_FUNCTION_VALIDATE(params.get());
445 base::PlatformFileInfo file_info;
446 file_info.is_directory = params->entry.is_directory;
447
448 scoped_refptr<ExtfsProxy> extfs_proxy = GetExtfsProxy(profile());
449 BrowserThread::PostTask(
450 BrowserThread::IO,
451 FROM_HERE,
452 base::Bind(&ExtfsProxy::DidGetFileInfo,
453 extfs_proxy,
454 params->request_id,
455 ToPlatformFileError(params->error_code),
456 file_info));
457 return true;
458 }
459
460 bool ExtfsReturnEntriesFunction::RunImpl() {
461 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
462 LOG(ERROR) << "@@ " << __PRETTY_FUNCTION__;
463
464 scoped_ptr<api::extfs::ReturnEntries::Params> params(
465 api::extfs::ReturnEntries::Params::Create(*args_));
466
467 EXTENSION_FUNCTION_VALIDATE(params.get());
468 std::vector<fileapi::DirectoryEntry> entries;
469 for (size_t i = 0; i < params->entries.size(); ++i) {
470 fileapi::DirectoryEntry entry;
471 entry.name = params->entries[i]->name;
472 entry.is_directory = params->entries[i]->is_directory;
473 entry.size = params->entries[i]->size;
474 entries.push_back(entry);
475 }
476
477 scoped_refptr<ExtfsProxy> extfs_proxy = GetExtfsProxy(profile());
478 BrowserThread::PostTask(
479 BrowserThread::IO,
480 FROM_HERE,
481 base::Bind(&ExtfsProxy::DidReadDirectory,
482 extfs_proxy,
483 params->request_id,
484 ToPlatformFileError(params->error_code),
485 entries));
486 return true;
487 }
488
489 ExtfsReturnSnapshotFunction::ExtfsReturnSnapshotFunction()
490 : url_fetcher_(NULL),
491 request_id_(0) {
492 }
493
494 bool ExtfsReturnSnapshotFunction::RunImpl() {
495 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
496 LOG(ERROR) << "@@ " << __PRETTY_FUNCTION__;
497
498 // Don't use ReturnSnapshot::Params::Create() as we'll take a blob URL
499 // instead of a blob object. The conversion is done in the custom binding.
500 std::string error_code_as_string;
501 // TODO(satorux): Revoke this URL later.
502 // blob_storage_context->controller()->RemoveBlob(url);
503 std::string blob_url;
504 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &request_id_));
505 EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &error_code_as_string));
506 EXTENSION_FUNCTION_VALIDATE(args_->GetString(2, &blob_url));
507
508 const base::PlatformFileError error_code =
509 ToPlatformFileError(api::extfs::ParseFileError(error_code_as_string));
510
511 if (error_code != base::PLATFORM_FILE_OK) {
512 scoped_refptr<ExtfsProxy> extfs_proxy = GetExtfsProxy(profile());
513 BrowserThread::PostTask(
514 BrowserThread::IO,
515 FROM_HERE,
516 base::Bind(&ExtfsProxy::DidCreateSnapshotFile,
517 extfs_proxy,
518 request_id_,
519 error_code,
520 base::PlatformFileInfo(),
521 base::FilePath()));
522 return true;
523 }
524
525 // TODO(satorux): We should bypass this if the blob contains just a
526 // single file. It's a waste to copy a file here.
527 url_fetcher_ = net::URLFetcher::Create(
528 GURL(blob_url),
529 net::URLFetcher::GET,
530 this);
531 // Add the reference count so this object outlives |url_fetcher_|.
532 // This will be released in OnURLFetchComplete().
533 AddRef();
534
535 url_fetcher_->SetRequestContext(profile_->GetRequestContext());
536 url_fetcher_->Start();
537 return true;
538 }
539
540 void ExtfsReturnSnapshotFunction::OnURLFetchComplete(
541 const net::URLFetcher* source) {
542 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
543 LOG(ERROR) << "@@ " << __PRETTY_FUNCTION__;
544
545 if (source->GetResponseCode() != 200) {
546 scoped_refptr<ExtfsProxy> extfs_proxy = GetExtfsProxy(profile());
547 BrowserThread::PostTask(
548 BrowserThread::IO,
549 FROM_HERE,
550 base::Bind(&ExtfsProxy::DidCreateSnapshotFile,
551 extfs_proxy,
552 request_id_,
553 base::PLATFORM_FILE_ERROR_FAILED,
554 base::PlatformFileInfo(),
555 base::FilePath()));
556 return;
557 }
558
559 scoped_ptr<std::string> content(new std::string);
560 source->GetResponseAsString(content.get());
561 delete url_fetcher_;
562
563 // PostTaskAndReplyWithResult() is not used, in favor of not exposing a
564 // struct name in .h file. Not a big deal though.
565 base::PlatformFileError* file_error = new base::PlatformFileError;
566 base::PlatformFileInfo* file_info = new base::PlatformFileInfo;
567 base::FilePath* file_path = new base::FilePath;
568 BrowserThread::PostTaskAndReply(
569 BrowserThread::FILE,
570 FROM_HERE,
571 base::Bind(&CreateTemporaryFile,
572 base::Passed(&content),
573 file_error,
574 file_info,
575 file_path),
576 base::Bind(&ExtfsReturnSnapshotFunction::DidCreateTemporaryFile,
577 this,
578 base::Owned(file_error),
579 base::Owned(file_info),
580 base::Owned(file_path)));
581
582 // This matches AddRef() in RunImpl().
583 Release();
584 }
585
586 void ExtfsReturnSnapshotFunction::DidCreateTemporaryFile(
587 base::PlatformFileError* file_error,
588 base::PlatformFileInfo* file_info,
589 base::FilePath* file_path) {
590 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
591 LOG(ERROR) << "@@ " << __PRETTY_FUNCTION__;
592
593 scoped_refptr<ExtfsProxy> extfs_proxy = GetExtfsProxy(profile());
594 BrowserThread::PostTask(
595 BrowserThread::IO,
596 FROM_HERE,
597 base::Bind(&ExtfsProxy::DidCreateSnapshotFile,
598 extfs_proxy,
599 request_id_,
600 *file_error,
601 *file_info,
602 *file_path));
603 }
604
605 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/extensions/api/extfs/extfs_api.h ('k') | chrome/browser/extensions/api/extfs/extfs_apitest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698