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

Unified 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, 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/extensions/api/extfs/extfs_api.cc
diff --git a/chrome/browser/extensions/api/extfs/extfs_api.cc b/chrome/browser/extensions/api/extfs/extfs_api.cc
new file mode 100644
index 0000000000000000000000000000000000000000..865818e29f9b870a305bb1ddc032af538a6ed170
--- /dev/null
+++ b/chrome/browser/extensions/api/extfs/extfs_api.cc
@@ -0,0 +1,605 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/extensions/api/extfs/extfs_api.h"
+
+#include "base/compiler_specific.h"
+#include "base/file_util.h"
+#include "chrome/browser/extensions/event_names.h"
+#include "chrome/browser/extensions/event_router.h"
+#include "chrome/browser/extensions/extension_system.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/common/extensions/api/extfs.h"
+#include "components/browser_context_keyed_service/browser_context_dependency_manager.h"
+#include "components/browser_context_keyed_service/browser_context_keyed_service.h"
+#include "components/browser_context_keyed_service/browser_context_keyed_service_factory.h"
+#include "content/public/browser/browser_context.h"
+#include "webkit/browser/blob/file_stream_reader.h"
+#include "webkit/browser/fileapi/external_mount_points.h"
+#include "webkit/browser/fileapi/file_system_url.h"
+#include "webkit/browser/fileapi/remote_file_system_proxy.h"
+#include "webkit/common/blob/shareable_file_reference.h"
+#include "webkit/common/fileapi/directory_entry.h"
+
+using content::BrowserThread;
+
+namespace extensions {
+
+namespace {
+
+// Converts api::extfs::FileError to base::PlatformFileError.
+base::PlatformFileError ToPlatformFileError(api::extfs::FileError error) {
+ switch (error) {
+ case api::extfs::FILE_ERROR_NONE:
+ break;
+ case api::extfs::FILE_ERROR_OK:
+ return base::PLATFORM_FILE_OK;
+ case api::extfs::FILE_ERROR_ERROR_FAILED:
+ return base::PLATFORM_FILE_ERROR_FAILED;
+ case api::extfs::FILE_ERROR_ERROR_IN_USE:
+ return base::PLATFORM_FILE_ERROR_IN_USE;
+ case api::extfs::FILE_ERROR_ERROR_EXISTS:
+ return base::PLATFORM_FILE_ERROR_EXISTS;
+ case api::extfs::FILE_ERROR_ERROR_NOT_FOUND:
+ return base::PLATFORM_FILE_ERROR_NOT_FOUND;
+ case api::extfs::FILE_ERROR_ERROR_ACCESS_DENIED:
+ return base::PLATFORM_FILE_ERROR_ACCESS_DENIED;
+ case api::extfs::FILE_ERROR_ERROR_TOO_MANY_OPENED:
+ return base::PLATFORM_FILE_ERROR_TOO_MANY_OPENED;
+ case api::extfs::FILE_ERROR_ERROR_NO_MEMORY:
+ return base::PLATFORM_FILE_ERROR_NO_MEMORY;
+ case api::extfs::FILE_ERROR_ERROR_NO_SPACE:
+ return base::PLATFORM_FILE_ERROR_NO_SPACE;
+ case api::extfs::FILE_ERROR_ERROR_NOT_A_DIRECTORY:
+ return base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY;
+ case api::extfs::FILE_ERROR_ERROR_INVALID_OPERATION:
+ return base::PLATFORM_FILE_ERROR_INVALID_OPERATION;
+ case api::extfs::FILE_ERROR_ERROR_SECURITY:
+ return base::PLATFORM_FILE_ERROR_SECURITY;
+ case api::extfs::FILE_ERROR_ERROR_ABORT:
+ return base::PLATFORM_FILE_ERROR_ABORT;
+ case api::extfs::FILE_ERROR_ERROR_NOT_A_FILE:
+ return base::PLATFORM_FILE_ERROR_NOT_A_FILE;
+ case api::extfs::FILE_ERROR_ERROR_NOT_EMPTY:
+ return base::PLATFORM_FILE_ERROR_NOT_EMPTY;
+ case api::extfs::FILE_ERROR_ERROR_INVALID_URL:
+ return base::PLATFORM_FILE_ERROR_INVALID_URL;
+ case api::extfs::FILE_ERROR_ERROR_IO:
+ return base::PLATFORM_FILE_ERROR_IO;
+ case api::extfs::FILE_ERROR_ERROR_MAX:
+ return base::PLATFORM_FILE_ERROR_MAX;
+ }
+ NOTREACHED();
+ return base::PLATFORM_FILE_ERROR_FAILED;
+}
+
+void CreateTemporaryFile(
+ scoped_ptr<std::string> content,
+ base::PlatformFileError* error,
+ base::PlatformFileInfo* file_info,
+ base::FilePath* file_path) {
+ DCHECK(content);
+ DCHECK(error);
+ DCHECK(file_info);
+ DCHECK(file_path);
+
+ *error = base::PLATFORM_FILE_ERROR_FAILED;
+
+
+ if (!file_util::CreateTemporaryFile(file_path))
+ return;
+
+ if (file_util::WriteFile(*file_path, content->data(), content->size()) !=
+ static_cast<int>(content->size()))
+ return;
+
+ if (!file_util::GetFileInfo(*file_path, file_info))
+ return;
+
+ *error = base::PLATFORM_FILE_OK;
+}
+
+} // namespace
+
+class ExtfsProxy : public fileapi::RemoteFileSystemProxyInterface {
+ public:
+ ExtfsProxy(Profile* profile)
+ : profile_(profile),
+ request_id_(0) {
+ }
+
+ bool AddMountPoint(const std::string& mount_point,
+ const std::string& extension_id) {
+ if (mount_point_to_extension_id_map_.count(mount_point) > 0)
+ return false;
+ mount_point_to_extension_id_map_[mount_point] = extension_id;
+ return true;
+ }
+
+ std::string GetExtensionIdFromPath(const base::FilePath& path) {
+ std::vector<base::FilePath::StringType> components;
+ path.GetComponents(&components);
+ DCHECK_LE(2U, components.size());
+ DCHECK_EQ(FILE_PATH_LITERAL("/"), components[0]);
+ const std::string mount_point =
+ base::FilePath(components[1]).AsUTF8Unsafe();
+
+ LOG(ERROR) << "@@ mount_point: " << mount_point;
+ DCHECK_EQ(1U, mount_point_to_extension_id_map_.count(mount_point));
+ return mount_point_to_extension_id_map_[mount_point];
+ }
+
+ // fileapi::RemoteFileSystemProxyInterface overrides.
+ virtual void GetFileInfo(
+ const fileapi::FileSystemURL& url,
+ const fileapi::FileSystemOperation::GetMetadataCallback& callback)
+ OVERRIDE {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ LOG(ERROR) << "@@ " << __FUNCTION__ << ": " << url.path().value();
+ const std::string extension_id = GetExtensionIdFromPath(url.path());
+ DCHECK(!extension_id.empty());
+
+ get_metadata_callback_map_[request_id_] = callback;
+ scoped_ptr<base::ListValue> values(new ListValue());
+ values->AppendInteger(request_id_);
+ values->AppendString(url.path().value());
+ scoped_ptr<Event> event(new Event(event_names::kOnEntryRequested,
+ values.Pass()));
+
+ GetEventRouter()->DispatchEventToExtension(extension_id, event.Pass());
+ ++request_id_;
+ }
+
+ virtual void Copy(
+ const fileapi::FileSystemURL& src_url,
+ const fileapi::FileSystemURL& dest_url,
+ const fileapi::FileSystemOperation::StatusCallback& callback)
+ OVERRIDE {
+ NOTREACHED() << "@@ not implemented";
+ }
+
+ virtual void Move(
+ const fileapi::FileSystemURL& src_url,
+ const fileapi::FileSystemURL& dest_url,
+ const fileapi::FileSystemOperation::StatusCallback& callback)
+ OVERRIDE {
+ NOTREACHED() << "@@ not implemented";
+ }
+
+ virtual void ReadDirectory(
+ const fileapi::FileSystemURL& url,
+ const fileapi::FileSystemOperation::ReadDirectoryCallback& callback)
+ OVERRIDE {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ LOG(ERROR) << "@@ " << __FUNCTION__ << ": " << url.path().value();
+ const std::string extension_id = GetExtensionIdFromPath(url.path());
+ DCHECK(!extension_id.empty());
+
+ read_directory_callback_map_[request_id_] = callback;
+ scoped_ptr<base::ListValue> values(new ListValue());
+ values->AppendInteger(request_id_);
+ values->AppendString(url.path().value());
+ scoped_ptr<Event> event(
+ new Event(event_names::kOnDirectoryEntriesRequested,
+ values.Pass()));
+
+ GetEventRouter()->DispatchEventToExtension(extension_id, event.Pass());
+ ++request_id_;
+ }
+
+ virtual void Remove(
+ const fileapi::FileSystemURL& url, bool recursive,
+ const fileapi::FileSystemOperation::StatusCallback& callback)
+ OVERRIDE {
+ NOTREACHED() << "@@ not implemented";
+ }
+
+ virtual void CreateDirectory(
+ const fileapi::FileSystemURL& file_url,
+ bool exclusive,
+ bool recursive,
+ const fileapi::FileSystemOperation::StatusCallback& callback)
+ OVERRIDE {
+ NOTREACHED() << "@@ not implemented";
+ }
+
+ virtual void CreateFile(
+ const fileapi::FileSystemURL& file_url,
+ bool exclusive,
+ const fileapi::FileSystemOperation::StatusCallback& callback)
+ OVERRIDE {
+ NOTREACHED() << "@@ not implemented";
+ }
+
+ virtual void Truncate(
+ const fileapi::FileSystemURL& file_url, int64 length,
+ const fileapi::FileSystemOperation::StatusCallback& callback)
+ OVERRIDE {
+ NOTREACHED() << "@@ not implemented";
+ }
+
+ virtual void CreateSnapshotFile(
+ const fileapi::FileSystemURL& url,
+ const fileapi::FileSystemOperation::SnapshotFileCallback& callback)
+ OVERRIDE {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ LOG(ERROR) << "@@ " << __FUNCTION__ << ": " << url.path().value();
+ const std::string extension_id = GetExtensionIdFromPath(url.path());
+ DCHECK(!extension_id.empty());
+
+ snapshot_file_callback_map_[request_id_] = callback;
+ scoped_ptr<base::ListValue> values(new ListValue());
+ values->AppendInteger(request_id_);
+ values->AppendString(url.path().value());
+ scoped_ptr<Event> event(
+ new Event(event_names::kOnSnapshotRequested, values.Pass()));
+
+ GetEventRouter()->DispatchEventToExtension(extension_id, event.Pass());
+ LOG(ERROR) << "@@ " << __PRETTY_FUNCTION__ << ": " << request_id_;
+ ++request_id_;
+ }
+
+ virtual void CreateWritableSnapshotFile(
+ const fileapi::FileSystemURL& url,
+ const fileapi::WritableSnapshotFile& callback) OVERRIDE {
+ NOTREACHED() << "@@ not implemented";
+ }
+
+ virtual void OpenFile(
+ const fileapi::FileSystemURL& url,
+ int file_flags,
+ base::ProcessHandle peer_handle,
+ const OpenFileCallback& callback) OVERRIDE {
+ NOTREACHED() << "@@ not implemented";
+ }
+
+ virtual void NotifyCloseFile(const fileapi::FileSystemURL& url) OVERRIDE {
+ NOTREACHED() << "@@ not implemented";
+ }
+
+ virtual void TouchFile(
+ const fileapi::FileSystemURL& url,
+ const base::Time& last_access_time,
+ const base::Time& last_modified_time,
+ const fileapi::FileSystemOperation::StatusCallback& callback)
+ OVERRIDE {
+ NOTREACHED() << "@@ not implemented";
+ }
+
+ virtual scoped_ptr<webkit_blob::FileStreamReader> CreateFileStreamReader(
+ base::SequencedTaskRunner* file_task_runner,
+ const fileapi::FileSystemURL& url,
+ int64 offset,
+ const base::Time& expected_modification_time) OVERRIDE {
+ NOTREACHED() << "@@ not implemented";
+ return scoped_ptr<webkit_blob::FileStreamReader>();
+ }
+
+ void DidGetFileInfo(int request_id,
+ const base::PlatformFileError file_error,
+ const base::PlatformFileInfo& file_info) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ LOG(ERROR) << "@@ " << __PRETTY_FUNCTION__;
+
+ GetMetadataCallbackMap::iterator iter =
+ get_metadata_callback_map_.find(request_id);
+ DCHECK(iter != get_metadata_callback_map_.end());
+ iter->second.Run(file_error, file_info);
+ get_metadata_callback_map_.erase(iter);
+ }
+
+ void DidReadDirectory(int request_id,
+ const base::PlatformFileError file_error,
+ const std::vector<fileapi::DirectoryEntry>& entries) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ LOG(ERROR) << "@@ " << __PRETTY_FUNCTION__;
+
+ ReadDirectoryCallbackMap::iterator iter =
+ read_directory_callback_map_.find(request_id);
+ DCHECK(iter != read_directory_callback_map_.end());
+ iter->second.Run(file_error, entries, false /* has more */);
+ read_directory_callback_map_.erase(iter);
+ }
+
+ void DidCreateSnapshotFile(int request_id,
+ base::PlatformFileError file_error,
+ const base::PlatformFileInfo& file_info,
+ const base::FilePath& file_path) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ LOG(ERROR) << "@@ " << __PRETTY_FUNCTION__ << ": " << request_id;
+
+ SnapshotFileCallbackMap::iterator iter =
+ snapshot_file_callback_map_.find(request_id);
+ DCHECK(iter != snapshot_file_callback_map_.end());
+
+ // Create a reference so that the local file is removed later.
+ scoped_refptr<webkit_blob::ShareableFileReference> reference =
+ webkit_blob::ShareableFileReference::GetOrCreate(
+ file_path,
+ webkit_blob::ShareableFileReference::DELETE_ON_FINAL_RELEASE,
+ BrowserThread::GetMessageLoopProxyForThread(
+ BrowserThread::FILE).get());
+
+ iter->second.Run(file_error, file_info, file_path, reference);
+ snapshot_file_callback_map_.erase(iter);
+ }
+
+ protected:
+ virtual ~ExtfsProxy() {
+ }
+
+ private:
+ EventRouter* GetEventRouter() {
+ return ExtensionSystem::Get(profile_)->event_router();
+ }
+
+ typedef std::map<int, fileapi::FileSystemOperation::GetMetadataCallback>
+ GetMetadataCallbackMap;
+ typedef std::map<int, fileapi::FileSystemOperation::ReadDirectoryCallback>
+ ReadDirectoryCallbackMap;
+ typedef std::map<int, fileapi::FileSystemOperation::SnapshotFileCallback>
+ SnapshotFileCallbackMap;
+
+ Profile* profile_;
+ int request_id_;
+ std::map<std::string, std::string> mount_point_to_extension_id_map_;
+ GetMetadataCallbackMap get_metadata_callback_map_;
+ ReadDirectoryCallbackMap read_directory_callback_map_;
+ SnapshotFileCallbackMap snapshot_file_callback_map_;
+};
+
+class ExtfsService : public BrowserContextKeyedService {
+ public:
+ ExtfsService(Profile* profile)
+ : extfs_proxy_(new ExtfsProxy(profile)) {
+ }
+
+ virtual ~ExtfsService() {
+ }
+
+ scoped_refptr<ExtfsProxy> extfs_proxy() {
+ return extfs_proxy_;
+ }
+
+ private:
+ friend class ExtfsServiceFactory;
+ scoped_refptr<ExtfsProxy> extfs_proxy_;
+};
+
+class ExtfsServiceFactory : public BrowserContextKeyedServiceFactory {
+ public:
+ static ExtfsService* GetForProfile(Profile* profile) {
+ return static_cast<ExtfsService*>(
+ GetInstance()->GetServiceForBrowserContext(profile, true));
+ }
+
+ static ExtfsServiceFactory* GetInstance() {
+ return Singleton<ExtfsServiceFactory>::get();
+ }
+
+ private:
+ friend struct DefaultSingletonTraits<ExtfsServiceFactory>;
+
+ ExtfsServiceFactory()
+ : BrowserContextKeyedServiceFactory(
+ "ExtfsService",
+ BrowserContextDependencyManager::GetInstance()) {
+ }
+
+ virtual ~ExtfsServiceFactory() {}
+
+ // BrowserContextKeyedServiceFactory overrides:
+ virtual BrowserContextKeyedService*
+ BuildServiceInstanceFor(content::BrowserContext* context) const OVERRIDE {
+ Profile* profile = static_cast<Profile*>(context);
+ return new ExtfsService(profile);
+ }
+};
+
+scoped_refptr<ExtfsProxy> GetExtfsProxy(Profile* profile) {
+ return ExtfsServiceFactory::GetForProfile(profile)->extfs_proxy();
+}
+
+bool ExtfsAddMountPointFunction::RunImpl() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ scoped_ptr<api::extfs::AddMountPoint::Params> params(
+ api::extfs::AddMountPoint::Params::Create(*args_));
+ EXTENSION_FUNCTION_VALIDATE(params.get());
+ LOG(ERROR) << "@@ " << __PRETTY_FUNCTION__
+ << " mount point: " << params->mount_point;
+
+ scoped_refptr<ExtfsProxy> extfs_proxy = GetExtfsProxy(profile());
+
+ if (!extfs_proxy->AddMountPoint(params->mount_point, extension_id())) {
+ NOTREACHED();
+ }
+
+ fileapi::ExternalMountPoints* mount_points =
+ content::BrowserContext::GetMountPoints(profile_);
+ DCHECK(mount_points);
+
+ bool success = mount_points->RegisterRemoteFileSystem(
+ params->mount_point,
+ // TODO(satorux): This file system type is wrong.
+ fileapi::kFileSystemTypeDrive,
+ extfs_proxy,
+ base::FilePath::FromUTF8Unsafe("/" + params->mount_point));
+ DCHECK(success);
+
+ SetResult(base::Value::CreateStringValue(
+ api::extfs::ToString(api::extfs::FILE_ERROR_OK)));
+ SendResponse(true);
+ return true;
+}
+
+bool ExtfsReturnEntryFunction::RunImpl() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ LOG(ERROR) << "@@ " << __PRETTY_FUNCTION__;
+
+ scoped_ptr<api::extfs::ReturnEntry::Params> params(
+ api::extfs::ReturnEntry::Params::Create(*args_));
+
+ EXTENSION_FUNCTION_VALIDATE(params.get());
+ base::PlatformFileInfo file_info;
+ file_info.is_directory = params->entry.is_directory;
+
+ scoped_refptr<ExtfsProxy> extfs_proxy = GetExtfsProxy(profile());
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&ExtfsProxy::DidGetFileInfo,
+ extfs_proxy,
+ params->request_id,
+ ToPlatformFileError(params->error_code),
+ file_info));
+ return true;
+}
+
+bool ExtfsReturnEntriesFunction::RunImpl() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ LOG(ERROR) << "@@ " << __PRETTY_FUNCTION__;
+
+ scoped_ptr<api::extfs::ReturnEntries::Params> params(
+ api::extfs::ReturnEntries::Params::Create(*args_));
+
+ EXTENSION_FUNCTION_VALIDATE(params.get());
+ std::vector<fileapi::DirectoryEntry> entries;
+ for (size_t i = 0; i < params->entries.size(); ++i) {
+ fileapi::DirectoryEntry entry;
+ entry.name = params->entries[i]->name;
+ entry.is_directory = params->entries[i]->is_directory;
+ entry.size = params->entries[i]->size;
+ entries.push_back(entry);
+ }
+
+ scoped_refptr<ExtfsProxy> extfs_proxy = GetExtfsProxy(profile());
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&ExtfsProxy::DidReadDirectory,
+ extfs_proxy,
+ params->request_id,
+ ToPlatformFileError(params->error_code),
+ entries));
+ return true;
+}
+
+ExtfsReturnSnapshotFunction::ExtfsReturnSnapshotFunction()
+ : url_fetcher_(NULL),
+ request_id_(0) {
+}
+
+bool ExtfsReturnSnapshotFunction::RunImpl() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ LOG(ERROR) << "@@ " << __PRETTY_FUNCTION__;
+
+ // Don't use ReturnSnapshot::Params::Create() as we'll take a blob URL
+ // instead of a blob object. The conversion is done in the custom binding.
+ std::string error_code_as_string;
+ // TODO(satorux): Revoke this URL later.
+ // blob_storage_context->controller()->RemoveBlob(url);
+ std::string blob_url;
+ EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &request_id_));
+ EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &error_code_as_string));
+ EXTENSION_FUNCTION_VALIDATE(args_->GetString(2, &blob_url));
+
+ const base::PlatformFileError error_code =
+ ToPlatformFileError(api::extfs::ParseFileError(error_code_as_string));
+
+ if (error_code != base::PLATFORM_FILE_OK) {
+ scoped_refptr<ExtfsProxy> extfs_proxy = GetExtfsProxy(profile());
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&ExtfsProxy::DidCreateSnapshotFile,
+ extfs_proxy,
+ request_id_,
+ error_code,
+ base::PlatformFileInfo(),
+ base::FilePath()));
+ return true;
+ }
+
+ // TODO(satorux): We should bypass this if the blob contains just a
+ // single file. It's a waste to copy a file here.
+ url_fetcher_ = net::URLFetcher::Create(
+ GURL(blob_url),
+ net::URLFetcher::GET,
+ this);
+ // Add the reference count so this object outlives |url_fetcher_|.
+ // This will be released in OnURLFetchComplete().
+ AddRef();
+
+ url_fetcher_->SetRequestContext(profile_->GetRequestContext());
+ url_fetcher_->Start();
+ return true;
+}
+
+void ExtfsReturnSnapshotFunction::OnURLFetchComplete(
+ const net::URLFetcher* source) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ LOG(ERROR) << "@@ " << __PRETTY_FUNCTION__;
+
+ if (source->GetResponseCode() != 200) {
+ scoped_refptr<ExtfsProxy> extfs_proxy = GetExtfsProxy(profile());
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&ExtfsProxy::DidCreateSnapshotFile,
+ extfs_proxy,
+ request_id_,
+ base::PLATFORM_FILE_ERROR_FAILED,
+ base::PlatformFileInfo(),
+ base::FilePath()));
+ return;
+ }
+
+ scoped_ptr<std::string> content(new std::string);
+ source->GetResponseAsString(content.get());
+ delete url_fetcher_;
+
+ // PostTaskAndReplyWithResult() is not used, in favor of not exposing a
+ // struct name in .h file. Not a big deal though.
+ base::PlatformFileError* file_error = new base::PlatformFileError;
+ base::PlatformFileInfo* file_info = new base::PlatformFileInfo;
+ base::FilePath* file_path = new base::FilePath;
+ BrowserThread::PostTaskAndReply(
+ BrowserThread::FILE,
+ FROM_HERE,
+ base::Bind(&CreateTemporaryFile,
+ base::Passed(&content),
+ file_error,
+ file_info,
+ file_path),
+ base::Bind(&ExtfsReturnSnapshotFunction::DidCreateTemporaryFile,
+ this,
+ base::Owned(file_error),
+ base::Owned(file_info),
+ base::Owned(file_path)));
+
+ // This matches AddRef() in RunImpl().
+ Release();
+}
+
+void ExtfsReturnSnapshotFunction::DidCreateTemporaryFile(
+ base::PlatformFileError* file_error,
+ base::PlatformFileInfo* file_info,
+ base::FilePath* file_path) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ LOG(ERROR) << "@@ " << __PRETTY_FUNCTION__;
+
+ scoped_refptr<ExtfsProxy> extfs_proxy = GetExtfsProxy(profile());
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&ExtfsProxy::DidCreateSnapshotFile,
+ extfs_proxy,
+ request_id_,
+ *file_error,
+ *file_info,
+ *file_path));
+}
+
+} // namespace extensions
« 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