OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |