Index: chrome/browser/extensions/api/developer_private/developer_private_api.cc |
diff --git a/chrome/browser/extensions/api/developer_private/developer_private_api.cc b/chrome/browser/extensions/api/developer_private/developer_private_api.cc |
index 89cf5df13f32bf9dff52cd110ca4453b0e9f4bda..07be486d69ef1d8e4aa18756c06c9bcba34d875d 100644 |
--- a/chrome/browser/extensions/api/developer_private/developer_private_api.cc |
+++ b/chrome/browser/extensions/api/developer_private/developer_private_api.cc |
@@ -48,6 +48,7 @@ |
#include "webkit/blob/shareable_file_reference.h" |
#include "webkit/fileapi/file_system_context.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" |
using content::RenderViewHost; |
@@ -56,6 +57,8 @@ namespace extensions { |
namespace { |
+char kUnpackedAppsFolder[] = "apps_target"; |
+ |
ExtensionUpdater* GetExtensionUpdater(Profile* profile) { |
return profile->GetExtensionService()->updater(); |
} |
@@ -73,6 +76,19 @@ GURL ToDataURL(const base::FilePath& path) { |
return GURL(kDataURLPrefix + contents_base64); |
} |
+std::vector<base::FilePath> FolderLs(const base::FilePath path) { |
miket_OOO
2013/04/18 03:22:28
This isn't a great name for this function. Please
kinuko
2013/04/18 08:15:12
ListFolder maybe?
Gaurav
2013/04/18 23:08:46
Done.
Gaurav
2013/04/18 23:08:46
Done.
|
+ file_util::FileEnumerator files(path, false, |
+ file_util::FileEnumerator::DIRECTORIES |
+ | file_util::FileEnumerator::FILES); |
miket_OOO
2013/04/18 03:22:28
Is this right? You're asking for both directories
Gaurav
2013/04/18 23:08:46
Thought paths represent both files and folders ?
|
+ 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; |
+} |
+ |
} // namespace |
namespace AllowFileAccess = api::developer_private::AllowFileAccess; |
@@ -816,7 +832,7 @@ void DeveloperPrivateExportSyncfsFolderToLocalfsFunction:: |
base::FilePath(file_list[i].name))); |
base::FilePath target_path(profile()->GetPath()); |
target_path = |
- target_path.Append(FILE_PATH_LITERAL("apps_target")); |
+ target_path.Append(FILE_PATH_LITERAL(kUnpackedAppsFolder)); |
target_path = target_path.Append(project_name); |
target_path = target_path.Append(file_list[i].name); |
@@ -877,6 +893,134 @@ DeveloperPrivateExportSyncfsFolderToLocalfsFunction:: |
DeveloperPrivateExportSyncfsFolderToLocalfsFunction:: |
~DeveloperPrivateExportSyncfsFolderToLocalfsFunction() {} |
+bool DeveloperPrivateLoadProjectToSyncfsFunction::RunImpl() { |
+ base::FilePath::StringType project_name; |
+ EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &project_name)); |
+ |
+ 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; |
+} |
+ |
+void DeveloperPrivateLoadProjectToSyncfsFunction::CopyFolder( |
+ const base::FilePath::StringType& project_name) { |
+ base::FilePath path(profile()->GetPath()); |
+ path = path.Append(FILE_PATH_LITERAL(kUnpackedAppsFolder)); |
+ path = path.Append(FILE_PATH_LITERAL(project_name)); |
miket_OOO
2013/04/18 03:22:28
Again, dangerous -- assume this name is maliciousl
Gaurav
2013/04/18 23:08:46
Ensuring that the project_name contains only alpha
|
+ |
+ std::vector<base::FilePath> paths = FolderLs(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())); |
+ |
+ 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().MaybeAsASCII()))); |
+ |
+ op->AsLocalFileSystemOperation()->CopyInForeignFile(paths[i], dest_url, |
+ base::Bind(&DeveloperPrivateLoadProjectToSyncfsFunction:: |
+ CopyFilesCallback, |
+ this)); |
miket_OOO
2013/04/18 03:22:28
It looks like this will immediately queue up N ope
Gaurav
2013/04/18 23:08:46
Discussed with Antony. Looks to be an optimal appr
|
+ } |
+} |
+ |
+void DeveloperPrivateLoadProjectToSyncfsFunction::CopyFilesCallback( |
+ const base::PlatformFileError result) { |
+ if (result != base::PLATFORM_FILE_OK) { |
+ DLOG(ERROR) << "Error in copying files to sync filesystem."; |
+ return; |
kinuko
2013/04/18 08:15:12
If the # of file was 1 and we got error here we se
Gaurav
2013/04/18 23:08:46
Fixed. Send true response if all callbacks are suc
|
+ } |
+ |
+ content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, |
+ base::Bind(&DeveloperPrivateLoadProjectToSyncfsFunction::SendResponse, |
+ this, |
+ true)); |
miket_OOO
2013/04/18 03:22:28
Wait a minute -- won't this send the response afte
kinuko
2013/04/18 08:15:12
Looks like it does, we should count up the number
Gaurav
2013/04/18 23:08:46
Done.
Gaurav
2013/04/18 23:08:46
Done.
|
+} |
+ |
+DeveloperPrivateLoadProjectToSyncfsFunction:: |
+ DeveloperPrivateLoadProjectToSyncfsFunction() {} |
+ |
+DeveloperPrivateLoadProjectToSyncfsFunction:: |
+ ~DeveloperPrivateLoadProjectToSyncfsFunction() {} |
+ |
+bool DeveloperPrivateGetProjectsInfoFunction::RunImpl() { |
+ content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE, |
+ base::Bind(&DeveloperPrivateGetProjectsInfoFunction::ReadFolder, |
+ this)); |
+ |
+ // Released by ReadFolder |
+ AddRef(); |
+ return true; |
+} |
+ |
+void DeveloperPrivateGetProjectsInfoFunction::ReadFolder() { |
+ base::FilePath path(profile()->GetPath()); |
+ path = path.Append(FILE_PATH_LITERAL(kUnpackedAppsFolder)); |
+ |
+ std::vector<base::FilePath> paths = FolderLs(path); |
+ ProjectInfoList info_list; |
+ for (size_t i = 0; i < paths.size(); ++i) { |
+ scoped_ptr<developer::ProjectInfo> info(new developer::ProjectInfo()); |
+ info->name = paths[i].BaseName().MaybeAsASCII(); |
+ info_list.push_back( |
+ make_linked_ptr<developer::ProjectInfo>(info.release())); |
+ } |
+ |
+ results_ = developer::GetProjectsInfo::Results::Create(info_list); |
+ content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, |
+ base::Bind(&DeveloperPrivateGetProjectsInfoFunction::SendResponse, |
+ this, |
+ true)); |
+ Release(); |
+} |
+ |
+DeveloperPrivateGetProjectsInfoFunction:: |
+ DeveloperPrivateGetProjectsInfoFunction() {} |
+ |
+DeveloperPrivateGetProjectsInfoFunction:: |
+ ~DeveloperPrivateGetProjectsInfoFunction() {} |
+ |
+bool DeveloperPrivateLoadProjectFunction::RunImpl() { |
+ std::string project_name; |
+ EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &project_name)); |
+ base::FilePath path(profile()->GetPath()); |
+ path = path.Append(FILE_PATH_LITERAL(kUnpackedAppsFolder)); |
+ path = path.Append(project_name); |
miket_OOO
2013/04/18 03:22:28
Scary
Gaurav
2013/04/18 23:08:46
As above.
|
+ ExtensionService* service = profile()->GetExtensionService(); |
+ UnpackedInstaller::Create(service)->Load(path); |
+ SendResponse(true); |
+ return true; |
+} |
+ |
+DeveloperPrivateLoadProjectFunction::DeveloperPrivateLoadProjectFunction() {} |
+ |
+DeveloperPrivateLoadProjectFunction::~DeveloperPrivateLoadProjectFunction() {} |
+ |
bool DeveloperPrivateChoosePathFunction::RunImpl() { |
scoped_ptr<developer::ChoosePath::Params> params( |