Commit c6d93487 authored by grv@chromium.org's avatar grv@chromium.org

Add API to load project from localfs into syncfs.


This CL is on top of 13885007.

Review URL: https://chromiumcodereview.appspot.com/14232018

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@195287 0039d316-1c4b-4281-b951-d872f2087c98
parent 0cb2e086
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
#include "webkit/blob/shareable_file_reference.h" #include "webkit/blob/shareable_file_reference.h"
#include "webkit/fileapi/file_system_context.h" #include "webkit/fileapi/file_system_context.h"
#include "webkit/fileapi/file_system_operation.h" #include "webkit/fileapi/file_system_operation.h"
#include "webkit/fileapi/local_file_system_operation.h"
#include "webkit/fileapi/syncable/syncable_file_system_util.h" #include "webkit/fileapi/syncable/syncable_file_system_util.h"
using content::RenderViewHost; using content::RenderViewHost;
...@@ -76,6 +77,34 @@ GURL ToDataURL(const base::FilePath& path) { ...@@ -76,6 +77,34 @@ GURL ToDataURL(const base::FilePath& path) {
return GURL(kDataURLPrefix + contents_base64); return GURL(kDataURLPrefix + contents_base64);
} }
std::vector<base::FilePath> ListFolder(const base::FilePath path) {
file_util::FileEnumerator files(path, false,
file_util::FileEnumerator::DIRECTORIES
| file_util::FileEnumerator::FILES);
std::vector<base::FilePath> paths;
for (base::FilePath current_path = files.Next(); !current_path.empty();
current_path = files.Next()) {
paths.push_back(current_path);
}
return paths;
}
bool ValidateFolderName(const base::FilePath::StringType& name) {
if (!name.length() || name[0] == '.' || name[0] == '-')
return false;
for (size_t i = 0; i < name.length(); ++i) {
if (!((name[i] >= 'A' && name[i] <= 'Z') ||
(name[i] >= 'a' && name[i] <= 'z') ||
(name[i] >= '0' && name[i] <= '9') ||
(name[i] == '_' || name[i] == '-' || name[i] == '.'))) {
return false;
}
}
return true;
}
} // namespace } // namespace
namespace AllowFileAccess = api::developer_private::AllowFileAccess; namespace AllowFileAccess = api::developer_private::AllowFileAccess;
...@@ -764,8 +793,13 @@ DeveloperPrivatePackDirectoryFunction::~DeveloperPrivatePackDirectoryFunction() ...@@ -764,8 +793,13 @@ DeveloperPrivatePackDirectoryFunction::~DeveloperPrivatePackDirectoryFunction()
DeveloperPrivateLoadUnpackedFunction::~DeveloperPrivateLoadUnpackedFunction() {} DeveloperPrivateLoadUnpackedFunction::~DeveloperPrivateLoadUnpackedFunction() {}
bool DeveloperPrivateExportSyncfsFolderToLocalfsFunction::RunImpl() { bool DeveloperPrivateExportSyncfsFolderToLocalfsFunction::RunImpl() {
// TODO(grv) : add unittests.
base::FilePath::StringType project_name; base::FilePath::StringType project_name;
EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &project_name)); EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &project_name));
if (!ValidateFolderName(project_name)) {
DLOG(INFO) << "Invalid project_name : [" << project_name << "]";
return false;
}
context_ = content::BrowserContext::GetStoragePartition(profile(), context_ = content::BrowserContext::GetStoragePartition(profile(),
render_view_host()->GetSiteInstance())->GetFileSystemContext(); render_view_host()->GetSiteInstance())->GetFileSystemContext();
...@@ -874,24 +908,101 @@ void DeveloperPrivateExportSyncfsFolderToLocalfsFunction::CopyFile( ...@@ -874,24 +908,101 @@ void DeveloperPrivateExportSyncfsFolderToLocalfsFunction::CopyFile(
} }
DeveloperPrivateExportSyncfsFolderToLocalfsFunction:: DeveloperPrivateExportSyncfsFolderToLocalfsFunction::
DeveloperPrivateExportSyncfsFolderToLocalfsFunction() DeveloperPrivateExportSyncfsFolderToLocalfsFunction() {}
{}
DeveloperPrivateExportSyncfsFolderToLocalfsFunction:: DeveloperPrivateExportSyncfsFolderToLocalfsFunction::
~DeveloperPrivateExportSyncfsFolderToLocalfsFunction() {} ~DeveloperPrivateExportSyncfsFolderToLocalfsFunction() {}
bool DeveloperPrivateLoadProjectToSyncfsFunction::RunImpl() { bool DeveloperPrivateLoadProjectToSyncfsFunction::RunImpl() {
// TODO(grv) : implement // TODO(grv) : add unittests.
base::FilePath::StringType project_name;
EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &project_name));
if (!ValidateFolderName(project_name)) {
DLOG(INFO) << "Invalid project_name : [" << project_name << "]";
return false;
}
context_ = content::BrowserContext::GetStoragePartition(profile(),
render_view_host()->GetSiteInstance())->GetFileSystemContext();
content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE,
base::Bind(&DeveloperPrivateLoadProjectToSyncfsFunction::
CopyFolder,
this, project_name));
return true; return true;
} }
void DeveloperPrivateLoadProjectToSyncfsFunction::CopyFolder(
const base::FilePath::StringType& project_name) {
base::FilePath path(profile()->GetPath());
path = path.Append(kUnpackedAppsFolder);
path = path.Append(project_name);
std::vector<base::FilePath> paths = ListFolder(path);
content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
base::Bind(&DeveloperPrivateLoadProjectToSyncfsFunction::
CopyFiles,
this, paths));
}
void DeveloperPrivateLoadProjectToSyncfsFunction::CopyFiles(
const std::vector<base::FilePath>& paths) {
std::string origin_url(
Extension::GetBaseURLFromExtensionId(extension_id()).spec());
fileapi::FileSystemURL url(sync_file_system::CreateSyncableFileSystemURL(
GURL(origin_url),
sync_file_system::DriveFileSyncService::kServiceName,
base::FilePath()));
pendingCallbacksCount_ = paths.size();
for (size_t i = 0; i < paths.size(); ++i) {
base::PlatformFileError error_code;
fileapi::FileSystemOperation* op
= context_->CreateFileSystemOperation(url, &error_code);
DCHECK(op);
std::string origin_url(
Extension::GetBaseURLFromExtensionId(extension_id()).spec());
fileapi::FileSystemURL
dest_url(sync_file_system::CreateSyncableFileSystemURL(
GURL(origin_url),
sync_file_system::DriveFileSyncService::kServiceName,
base::FilePath(paths[i].BaseName())));
op->AsLocalFileSystemOperation()->CopyInForeignFile(paths[i], dest_url,
base::Bind(&DeveloperPrivateLoadProjectToSyncfsFunction::
CopyFilesCallback,
this));
}
}
void DeveloperPrivateLoadProjectToSyncfsFunction::CopyFilesCallback(
const base::PlatformFileError result) {
pendingCallbacksCount_--;
if (success_ && result != base::PLATFORM_FILE_OK) {
SetError("Error in copying files to sync filesystem.");
success_ = false;
}
if (!pendingCallbacksCount_) {
content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
base::Bind(&DeveloperPrivateLoadProjectToSyncfsFunction::SendResponse,
this,
success_));
}
}
DeveloperPrivateLoadProjectToSyncfsFunction:: DeveloperPrivateLoadProjectToSyncfsFunction::
DeveloperPrivateLoadProjectToSyncfsFunction() {} DeveloperPrivateLoadProjectToSyncfsFunction()
: pendingCallbacksCount_(0), success_(true) {}
DeveloperPrivateLoadProjectToSyncfsFunction:: DeveloperPrivateLoadProjectToSyncfsFunction::
~DeveloperPrivateLoadProjectToSyncfsFunction() {} ~DeveloperPrivateLoadProjectToSyncfsFunction() {}
bool DeveloperPrivateGetProjectsInfoFunction::RunImpl() { bool DeveloperPrivateGetProjectsInfoFunction::RunImpl() {
// TODO(grv) : add unittests.
content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE, content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE,
base::Bind(&DeveloperPrivateGetProjectsInfoFunction::ReadFolder, base::Bind(&DeveloperPrivateGetProjectsInfoFunction::ReadFolder,
this)); this));
...@@ -905,16 +1016,15 @@ void DeveloperPrivateGetProjectsInfoFunction::ReadFolder() { ...@@ -905,16 +1016,15 @@ void DeveloperPrivateGetProjectsInfoFunction::ReadFolder() {
base::FilePath path(profile()->GetPath()); base::FilePath path(profile()->GetPath());
path = path.Append(kUnpackedAppsFolder); path = path.Append(kUnpackedAppsFolder);
file_util::FileEnumerator files( std::vector<base::FilePath> paths = ListFolder(path);
path, false, file_util::FileEnumerator::DIRECTORIES);
ProjectInfoList info_list; ProjectInfoList info_list;
for (base::FilePath current_path = files.Next(); !current_path.empty(); for (size_t i = 0; i < paths.size(); ++i) {
current_path = files.Next()) {
scoped_ptr<developer::ProjectInfo> info(new developer::ProjectInfo()); scoped_ptr<developer::ProjectInfo> info(new developer::ProjectInfo());
info->name = current_path.BaseName().MaybeAsASCII(); info->name = paths[i].BaseName().MaybeAsASCII();
info_list.push_back( info_list.push_back(
make_linked_ptr<developer::ProjectInfo>(info.release())); make_linked_ptr<developer::ProjectInfo>(info.release()));
} }
results_ = developer::GetProjectsInfo::Results::Create(info_list); results_ = developer::GetProjectsInfo::Results::Create(info_list);
content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
base::Bind(&DeveloperPrivateGetProjectsInfoFunction::SendResponse, base::Bind(&DeveloperPrivateGetProjectsInfoFunction::SendResponse,
...@@ -933,6 +1043,11 @@ bool DeveloperPrivateLoadProjectFunction::RunImpl() { ...@@ -933,6 +1043,11 @@ bool DeveloperPrivateLoadProjectFunction::RunImpl() {
// TODO(grv) : add unit tests. // TODO(grv) : add unit tests.
base::FilePath::StringType project_name; base::FilePath::StringType project_name;
EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &project_name)); EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &project_name));
if (!ValidateFolderName(project_name)) {
DLOG(INFO) << "Invalid project_name : [" << project_name << "]";
return false;
}
base::FilePath path(profile()->GetPath()); base::FilePath path(profile()->GetPath());
path = path.Append(kUnpackedAppsFolder); path = path.Append(kUnpackedAppsFolder);
// TODO(grv) : Sanitize / check project_name. // TODO(grv) : Sanitize / check project_name.
......
...@@ -383,6 +383,23 @@ class DeveloperPrivateLoadProjectToSyncfsFunction ...@@ -383,6 +383,23 @@ class DeveloperPrivateLoadProjectToSyncfsFunction
// ExtensionFunction // ExtensionFunction
virtual bool RunImpl() OVERRIDE; virtual bool RunImpl() OVERRIDE;
void CopyFolder(const base::FilePath::StringType& project_name);
void CopyFiles(const std::vector<base::FilePath>& paths);
void CopyFilesCallback(const base::PlatformFileError result);
private:
// Number of pending copy files callbacks.
// It should only be modified on the IO Thread.
int pendingCallbacksCount_;
// True only when all the copyFiles job are successful.
// It should only be modified on the IO thread.
bool success_;
scoped_refptr<fileapi::FileSystemContext> context_;
}; };
class DeveloperPrivateGetProjectsInfoFunction : public AsyncExtensionFunction { class DeveloperPrivateGetProjectsInfoFunction : public AsyncExtensionFunction {
...@@ -415,8 +432,6 @@ class DeveloperPrivateLoadProjectFunction : public SyncExtensionFunction { ...@@ -415,8 +432,6 @@ class DeveloperPrivateLoadProjectFunction : public SyncExtensionFunction {
virtual bool RunImpl() OVERRIDE; virtual bool RunImpl() OVERRIDE;
}; };
} // namespace api } // namespace api
} // namespace extensions } // namespace extensions
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment