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

Side by Side Diff: chrome/browser/extensions/api/developer_private/developer_private_api.cc

Issue 14232018: Add API to load project from localfs into syncfs. (Closed) Base URL: http://git.chromium.org/chromium/src.git@load_api
Patch Set: . Created 7 years, 8 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
« no previous file with comments | « chrome/browser/extensions/api/developer_private/developer_private_api.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/api/developer_private/developer_private_api. h" 5 #include "chrome/browser/extensions/api/developer_private/developer_private_api. h"
6 6
7 #include "base/base64.h" 7 #include "base/base64.h"
8 #include "base/file_util.h" 8 #include "base/file_util.h"
9 #include "base/strings/string_number_conversions.h" 9 #include "base/strings/string_number_conversions.h"
10 #include "base/utf_string_conversions.h" 10 #include "base/utf_string_conversions.h"
(...skipping 30 matching lines...) Expand all
41 #include "extensions/browser/view_type_utils.h" 41 #include "extensions/browser/view_type_utils.h"
42 #include "extensions/common/constants.h" 42 #include "extensions/common/constants.h"
43 #include "extensions/common/extension_resource.h" 43 #include "extensions/common/extension_resource.h"
44 #include "grit/chromium_strings.h" 44 #include "grit/chromium_strings.h"
45 #include "grit/generated_resources.h" 45 #include "grit/generated_resources.h"
46 #include "net/base/net_util.h" 46 #include "net/base/net_util.h"
47 #include "ui/base/l10n/l10n_util.h" 47 #include "ui/base/l10n/l10n_util.h"
48 #include "webkit/blob/shareable_file_reference.h" 48 #include "webkit/blob/shareable_file_reference.h"
49 #include "webkit/fileapi/file_system_context.h" 49 #include "webkit/fileapi/file_system_context.h"
50 #include "webkit/fileapi/file_system_operation.h" 50 #include "webkit/fileapi/file_system_operation.h"
51 #include "webkit/fileapi/local_file_system_operation.h"
51 #include "webkit/fileapi/syncable/syncable_file_system_util.h" 52 #include "webkit/fileapi/syncable/syncable_file_system_util.h"
52 53
53 using content::RenderViewHost; 54 using content::RenderViewHost;
54 55
55 namespace extensions { 56 namespace extensions {
56 57
57 namespace { 58 namespace {
58 59
59 const base::FilePath::CharType kUnpackedAppsFolder[] 60 const base::FilePath::CharType kUnpackedAppsFolder[]
60 = FILE_PATH_LITERAL("apps_target"); 61 = FILE_PATH_LITERAL("apps_target");
61 62
62 ExtensionUpdater* GetExtensionUpdater(Profile* profile) { 63 ExtensionUpdater* GetExtensionUpdater(Profile* profile) {
63 return profile->GetExtensionService()->updater(); 64 return profile->GetExtensionService()->updater();
64 } 65 }
65 66
66 GURL ToDataURL(const base::FilePath& path) { 67 GURL ToDataURL(const base::FilePath& path) {
67 std::string contents; 68 std::string contents;
68 if (!file_util::ReadFileToString(path, &contents)) 69 if (!file_util::ReadFileToString(path, &contents))
69 return GURL(); 70 return GURL();
70 71
71 std::string contents_base64; 72 std::string contents_base64;
72 if (!base::Base64Encode(contents, &contents_base64)) 73 if (!base::Base64Encode(contents, &contents_base64))
73 return GURL(); 74 return GURL();
74 75
75 const char kDataURLPrefix[] = "data:image;base64,"; 76 const char kDataURLPrefix[] = "data:image;base64,";
76 return GURL(kDataURLPrefix + contents_base64); 77 return GURL(kDataURLPrefix + contents_base64);
77 } 78 }
78 79
80 std::vector<base::FilePath> ListFolder(const base::FilePath path) {
81 file_util::FileEnumerator files(path, false,
82 file_util::FileEnumerator::DIRECTORIES
83 | file_util::FileEnumerator::FILES);
84 std::vector<base::FilePath> paths;
85
86 for (base::FilePath current_path = files.Next(); !current_path.empty();
87 current_path = files.Next()) {
88 paths.push_back(current_path);
89 }
90 return paths;
91 }
92
93 bool ValidateFolderName(const base::FilePath::StringType& name) {
94 if (!name.length() || name[0] == '.' || name[0] == '-')
95 return false;
96
97 for (size_t i = 0; i < name.length(); ++i) {
98 if (!((name[i] >= 'A' && name[i] <= 'Z') ||
99 (name[i] >= 'a' && name[i] <= 'z') ||
100 (name[i] >= '0' && name[i] <= '9') ||
101 (name[i] == '_' || name[i] == '-' || name[i] == '.'))) {
102 return false;
103 }
104 }
105 return true;
106 }
107
79 } // namespace 108 } // namespace
80 109
81 namespace AllowFileAccess = api::developer_private::AllowFileAccess; 110 namespace AllowFileAccess = api::developer_private::AllowFileAccess;
82 namespace AllowIncognito = api::developer_private::AllowIncognito; 111 namespace AllowIncognito = api::developer_private::AllowIncognito;
83 namespace ChoosePath = api::developer_private::ChoosePath; 112 namespace ChoosePath = api::developer_private::ChoosePath;
84 namespace Enable = api::developer_private::Enable; 113 namespace Enable = api::developer_private::Enable;
85 namespace GetItemsInfo = api::developer_private::GetItemsInfo; 114 namespace GetItemsInfo = api::developer_private::GetItemsInfo;
86 namespace Inspect = api::developer_private::Inspect; 115 namespace Inspect = api::developer_private::Inspect;
87 namespace PackDirectory = api::developer_private::PackDirectory; 116 namespace PackDirectory = api::developer_private::PackDirectory;
88 namespace Reload = api::developer_private::Reload; 117 namespace Reload = api::developer_private::Reload;
(...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after
757 786
758 DeveloperPrivatePackDirectoryFunction::DeveloperPrivatePackDirectoryFunction() 787 DeveloperPrivatePackDirectoryFunction::DeveloperPrivatePackDirectoryFunction()
759 {} 788 {}
760 789
761 DeveloperPrivatePackDirectoryFunction::~DeveloperPrivatePackDirectoryFunction() 790 DeveloperPrivatePackDirectoryFunction::~DeveloperPrivatePackDirectoryFunction()
762 {} 791 {}
763 792
764 DeveloperPrivateLoadUnpackedFunction::~DeveloperPrivateLoadUnpackedFunction() {} 793 DeveloperPrivateLoadUnpackedFunction::~DeveloperPrivateLoadUnpackedFunction() {}
765 794
766 bool DeveloperPrivateExportSyncfsFolderToLocalfsFunction::RunImpl() { 795 bool DeveloperPrivateExportSyncfsFolderToLocalfsFunction::RunImpl() {
796 // TODO(grv) : add unittests.
767 base::FilePath::StringType project_name; 797 base::FilePath::StringType project_name;
768 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &project_name)); 798 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &project_name));
799 if (!ValidateFolderName(project_name)) {
800 DLOG(INFO) << "Invalid project_name : [" << project_name << "]";
801 return false;
802 }
769 803
770 context_ = content::BrowserContext::GetStoragePartition(profile(), 804 context_ = content::BrowserContext::GetStoragePartition(profile(),
771 render_view_host()->GetSiteInstance())->GetFileSystemContext(); 805 render_view_host()->GetSiteInstance())->GetFileSystemContext();
772 content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, 806 content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
773 base::Bind(&DeveloperPrivateExportSyncfsFolderToLocalfsFunction:: 807 base::Bind(&DeveloperPrivateExportSyncfsFolderToLocalfsFunction::
774 ReadSyncFileSystemDirectory, 808 ReadSyncFileSystemDirectory,
775 this, project_name)); 809 this, project_name));
776 810
777 return true; 811 return true;
778 } 812 }
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
867 // Return silently if the directory creation fails. 901 // Return silently if the directory creation fails.
868 if (!file_util::CreateDirectory(target_path.DirName())) { 902 if (!file_util::CreateDirectory(target_path.DirName())) {
869 DLOG(ERROR) << "Error in copying files from sync filesystem."; 903 DLOG(ERROR) << "Error in copying files from sync filesystem.";
870 return; 904 return;
871 } 905 }
872 906
873 file_util::CopyFile(src_path, target_path); 907 file_util::CopyFile(src_path, target_path);
874 } 908 }
875 909
876 DeveloperPrivateExportSyncfsFolderToLocalfsFunction:: 910 DeveloperPrivateExportSyncfsFolderToLocalfsFunction::
877 DeveloperPrivateExportSyncfsFolderToLocalfsFunction() 911 DeveloperPrivateExportSyncfsFolderToLocalfsFunction() {}
878 {}
879 912
880 DeveloperPrivateExportSyncfsFolderToLocalfsFunction:: 913 DeveloperPrivateExportSyncfsFolderToLocalfsFunction::
881 ~DeveloperPrivateExportSyncfsFolderToLocalfsFunction() {} 914 ~DeveloperPrivateExportSyncfsFolderToLocalfsFunction() {}
882 915
883 bool DeveloperPrivateLoadProjectToSyncfsFunction::RunImpl() { 916 bool DeveloperPrivateLoadProjectToSyncfsFunction::RunImpl() {
884 // TODO(grv) : implement 917 // TODO(grv) : add unittests.
918 base::FilePath::StringType project_name;
919 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &project_name));
920 if (!ValidateFolderName(project_name)) {
921 DLOG(INFO) << "Invalid project_name : [" << project_name << "]";
922 return false;
923 }
924
925 context_ = content::BrowserContext::GetStoragePartition(profile(),
926 render_view_host()->GetSiteInstance())->GetFileSystemContext();
927 content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE,
928 base::Bind(&DeveloperPrivateLoadProjectToSyncfsFunction::
929 CopyFolder,
930 this, project_name));
885 return true; 931 return true;
886 } 932 }
887 933
934 void DeveloperPrivateLoadProjectToSyncfsFunction::CopyFolder(
935 const base::FilePath::StringType& project_name) {
936 base::FilePath path(profile()->GetPath());
937 path = path.Append(kUnpackedAppsFolder);
938 path = path.Append(project_name);
939
940 std::vector<base::FilePath> paths = ListFolder(path);
941 content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
942 base::Bind(&DeveloperPrivateLoadProjectToSyncfsFunction::
943 CopyFiles,
944 this, paths));
945 }
946
947 void DeveloperPrivateLoadProjectToSyncfsFunction::CopyFiles(
948 const std::vector<base::FilePath>& paths) {
949 std::string origin_url(
950 Extension::GetBaseURLFromExtensionId(extension_id()).spec());
951 fileapi::FileSystemURL url(sync_file_system::CreateSyncableFileSystemURL(
952 GURL(origin_url),
953 sync_file_system::DriveFileSyncService::kServiceName,
954 base::FilePath()));
955
956 pendingCallbacksCount_ = paths.size();
957
958 for (size_t i = 0; i < paths.size(); ++i) {
959 base::PlatformFileError error_code;
960 fileapi::FileSystemOperation* op
961 = context_->CreateFileSystemOperation(url, &error_code);
962 DCHECK(op);
963
964 std::string origin_url(
965 Extension::GetBaseURLFromExtensionId(extension_id()).spec());
966 fileapi::FileSystemURL
967 dest_url(sync_file_system::CreateSyncableFileSystemURL(
968 GURL(origin_url),
969 sync_file_system::DriveFileSyncService::kServiceName,
970 base::FilePath(paths[i].BaseName())));
971
972 op->AsLocalFileSystemOperation()->CopyInForeignFile(paths[i], dest_url,
973 base::Bind(&DeveloperPrivateLoadProjectToSyncfsFunction::
974 CopyFilesCallback,
975 this));
976 }
977 }
978
979 void DeveloperPrivateLoadProjectToSyncfsFunction::CopyFilesCallback(
980 const base::PlatformFileError result) {
981
982 pendingCallbacksCount_--;
983
984 if (success_ && result != base::PLATFORM_FILE_OK) {
985 SetError("Error in copying files to sync filesystem.");
986 success_ = false;
987 }
988
989 if (!pendingCallbacksCount_) {
990 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
991 base::Bind(&DeveloperPrivateLoadProjectToSyncfsFunction::SendResponse,
992 this,
993 success_));
994 }
995 }
996
888 DeveloperPrivateLoadProjectToSyncfsFunction:: 997 DeveloperPrivateLoadProjectToSyncfsFunction::
889 DeveloperPrivateLoadProjectToSyncfsFunction() {} 998 DeveloperPrivateLoadProjectToSyncfsFunction()
999 : pendingCallbacksCount_(0), success_(true) {}
890 1000
891 DeveloperPrivateLoadProjectToSyncfsFunction:: 1001 DeveloperPrivateLoadProjectToSyncfsFunction::
892 ~DeveloperPrivateLoadProjectToSyncfsFunction() {} 1002 ~DeveloperPrivateLoadProjectToSyncfsFunction() {}
893 1003
894 bool DeveloperPrivateGetProjectsInfoFunction::RunImpl() { 1004 bool DeveloperPrivateGetProjectsInfoFunction::RunImpl() {
1005 // TODO(grv) : add unittests.
895 content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE, 1006 content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE,
896 base::Bind(&DeveloperPrivateGetProjectsInfoFunction::ReadFolder, 1007 base::Bind(&DeveloperPrivateGetProjectsInfoFunction::ReadFolder,
897 this)); 1008 this));
898 1009
899 // Released by ReadFolder 1010 // Released by ReadFolder
900 AddRef(); 1011 AddRef();
901 return true; 1012 return true;
902 } 1013 }
903 1014
904 void DeveloperPrivateGetProjectsInfoFunction::ReadFolder() { 1015 void DeveloperPrivateGetProjectsInfoFunction::ReadFolder() {
905 base::FilePath path(profile()->GetPath()); 1016 base::FilePath path(profile()->GetPath());
906 path = path.Append(kUnpackedAppsFolder); 1017 path = path.Append(kUnpackedAppsFolder);
907 1018
908 file_util::FileEnumerator files( 1019 std::vector<base::FilePath> paths = ListFolder(path);
909 path, false, file_util::FileEnumerator::DIRECTORIES);
910 ProjectInfoList info_list; 1020 ProjectInfoList info_list;
911 for (base::FilePath current_path = files.Next(); !current_path.empty(); 1021 for (size_t i = 0; i < paths.size(); ++i) {
912 current_path = files.Next()) {
913 scoped_ptr<developer::ProjectInfo> info(new developer::ProjectInfo()); 1022 scoped_ptr<developer::ProjectInfo> info(new developer::ProjectInfo());
914 info->name = current_path.BaseName().MaybeAsASCII(); 1023 info->name = paths[i].BaseName().MaybeAsASCII();
915 info_list.push_back( 1024 info_list.push_back(
916 make_linked_ptr<developer::ProjectInfo>(info.release())); 1025 make_linked_ptr<developer::ProjectInfo>(info.release()));
917 } 1026 }
1027
918 results_ = developer::GetProjectsInfo::Results::Create(info_list); 1028 results_ = developer::GetProjectsInfo::Results::Create(info_list);
919 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, 1029 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
920 base::Bind(&DeveloperPrivateGetProjectsInfoFunction::SendResponse, 1030 base::Bind(&DeveloperPrivateGetProjectsInfoFunction::SendResponse,
921 this, 1031 this,
922 true)); 1032 true));
923 Release(); 1033 Release();
924 } 1034 }
925 1035
926 DeveloperPrivateGetProjectsInfoFunction:: 1036 DeveloperPrivateGetProjectsInfoFunction::
927 DeveloperPrivateGetProjectsInfoFunction() {} 1037 DeveloperPrivateGetProjectsInfoFunction() {}
928 1038
929 DeveloperPrivateGetProjectsInfoFunction:: 1039 DeveloperPrivateGetProjectsInfoFunction::
930 ~DeveloperPrivateGetProjectsInfoFunction() {} 1040 ~DeveloperPrivateGetProjectsInfoFunction() {}
931 1041
932 bool DeveloperPrivateLoadProjectFunction::RunImpl() { 1042 bool DeveloperPrivateLoadProjectFunction::RunImpl() {
933 // TODO(grv) : add unit tests. 1043 // TODO(grv) : add unit tests.
934 base::FilePath::StringType project_name; 1044 base::FilePath::StringType project_name;
935 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &project_name)); 1045 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &project_name));
1046 if (!ValidateFolderName(project_name)) {
1047 DLOG(INFO) << "Invalid project_name : [" << project_name << "]";
1048 return false;
1049 }
1050
936 base::FilePath path(profile()->GetPath()); 1051 base::FilePath path(profile()->GetPath());
937 path = path.Append(kUnpackedAppsFolder); 1052 path = path.Append(kUnpackedAppsFolder);
938 // TODO(grv) : Sanitize / check project_name. 1053 // TODO(grv) : Sanitize / check project_name.
939 path = path.Append(project_name); 1054 path = path.Append(project_name);
940 ExtensionService* service = profile()->GetExtensionService(); 1055 ExtensionService* service = profile()->GetExtensionService();
941 UnpackedInstaller::Create(service)->Load(path); 1056 UnpackedInstaller::Create(service)->Load(path);
942 SendResponse(true); 1057 SendResponse(true);
943 return true; 1058 return true;
944 } 1059 }
945 1060
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
1079 1194
1080 #undef SET_STRING 1195 #undef SET_STRING
1081 return true; 1196 return true;
1082 } 1197 }
1083 1198
1084 DeveloperPrivateGetStringsFunction::~DeveloperPrivateGetStringsFunction() {} 1199 DeveloperPrivateGetStringsFunction::~DeveloperPrivateGetStringsFunction() {}
1085 1200
1086 } // namespace api 1201 } // namespace api
1087 1202
1088 } // namespace extensions 1203 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/extensions/api/developer_private/developer_private_api.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698