OLD | NEW |
---|---|
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/common/extensions/extension.h" | 5 #include "chrome/common/extensions/extension.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "app/l10n_util.h" | 9 #include "app/l10n_util.h" |
10 #include "base/base64.h" | 10 #include "base/base64.h" |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
242 Extension::kUnlimitedStoragePermission, | 242 Extension::kUnlimitedStoragePermission, |
243 Extension::kWebstorePrivatePermission, | 243 Extension::kWebstorePrivatePermission, |
244 }; | 244 }; |
245 const size_t Extension::kNumHostedAppPermissions = | 245 const size_t Extension::kNumHostedAppPermissions = |
246 arraysize(Extension::kHostedAppPermissionNames); | 246 arraysize(Extension::kHostedAppPermissionNames); |
247 | 247 |
248 // We purposefully don't put this into kPermissionNames. | 248 // We purposefully don't put this into kPermissionNames. |
249 const char Extension::kOldUnlimitedStoragePermission[] = "unlimited_storage"; | 249 const char Extension::kOldUnlimitedStoragePermission[] = "unlimited_storage"; |
250 | 250 |
251 // | 251 // |
252 // Extension::StaticData | |
253 // | |
254 | |
255 Extension::StaticData::StaticData() | |
256 : incognito_split_mode(false), | |
257 location(INVALID), | |
258 converted_from_user_script(false), | |
259 is_theme(false), | |
260 is_app(false), | |
261 launch_container(extension_misc::LAUNCH_TAB), | |
262 launch_width(0), | |
263 launch_height(0) { | |
264 } | |
265 | |
266 Extension::StaticData::~StaticData() { | |
267 } | |
268 | |
269 // | |
270 // Extension::RuntimeData | 252 // Extension::RuntimeData |
271 // | 253 // |
272 | 254 |
273 Extension::RuntimeData::RuntimeData() | 255 Extension::RuntimeData::RuntimeData() |
274 : background_page_ready(false), | 256 : background_page_ready(false), |
275 being_upgraded(false) { | 257 being_upgraded(false) { |
276 } | 258 } |
277 | 259 |
278 Extension::RuntimeData::~RuntimeData() { | 260 Extension::RuntimeData::~RuntimeData() { |
279 } | 261 } |
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
787 key != source.end_keys(); ++key) { | 769 key != source.end_keys(); ++key) { |
788 if (!IsBaseCrxKey(*key) && *key != keys::kTheme) | 770 if (!IsBaseCrxKey(*key) && *key != keys::kTheme) |
789 return true; | 771 return true; |
790 } | 772 } |
791 return false; | 773 return false; |
792 } | 774 } |
793 | 775 |
794 bool Extension::LoadIsApp(const DictionaryValue* manifest, | 776 bool Extension::LoadIsApp(const DictionaryValue* manifest, |
795 std::string* error) { | 777 std::string* error) { |
796 if (manifest->HasKey(keys::kApp)) | 778 if (manifest->HasKey(keys::kApp)) |
797 mutable_static_data_->is_app = true; | 779 is_app_ = true; |
798 | 780 |
799 return true; | 781 return true; |
800 } | 782 } |
801 | 783 |
802 bool Extension::LoadExtent(const DictionaryValue* manifest, | 784 bool Extension::LoadExtent(const DictionaryValue* manifest, |
803 const char* key, | 785 const char* key, |
804 ExtensionExtent* extent, | 786 ExtensionExtent* extent, |
805 const char* list_error, | 787 const char* list_error, |
806 const char* value_error, | 788 const char* value_error, |
807 std::string* error) { | 789 std::string* error) { |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
875 return false; | 857 return false; |
876 } | 858 } |
877 | 859 |
878 // Ensure the launch path is a valid relative URL. | 860 // Ensure the launch path is a valid relative URL. |
879 GURL resolved = url().Resolve(launch_path); | 861 GURL resolved = url().Resolve(launch_path); |
880 if (!resolved.is_valid() || resolved.GetOrigin() != url()) { | 862 if (!resolved.is_valid() || resolved.GetOrigin() != url()) { |
881 *error = errors::kInvalidLaunchLocalPath; | 863 *error = errors::kInvalidLaunchLocalPath; |
882 return false; | 864 return false; |
883 } | 865 } |
884 | 866 |
885 mutable_static_data_->launch_local_path = launch_path; | 867 launch_local_path_ = launch_path; |
886 } else if (manifest->Get(keys::kLaunchWebURL, &temp)) { | 868 } else if (manifest->Get(keys::kLaunchWebURL, &temp)) { |
887 std::string launch_url; | 869 std::string launch_url; |
888 if (!temp->GetAsString(&launch_url)) { | 870 if (!temp->GetAsString(&launch_url)) { |
889 *error = errors::kInvalidLaunchWebURL; | 871 *error = errors::kInvalidLaunchWebURL; |
890 return false; | 872 return false; |
891 } | 873 } |
892 | 874 |
893 // Ensure the launch URL is a valid absolute URL. | 875 // Ensure the launch URL is a valid absolute URL. |
894 if (!GURL(launch_url).is_valid()) { | 876 if (!GURL(launch_url).is_valid()) { |
895 *error = errors::kInvalidLaunchWebURL; | 877 *error = errors::kInvalidLaunchWebURL; |
896 return false; | 878 return false; |
897 } | 879 } |
898 | 880 |
899 mutable_static_data_->launch_web_url = launch_url; | 881 launch_web_url_ = launch_url; |
900 } else if (is_app()) { | 882 } else if (is_app()) { |
901 *error = errors::kLaunchURLRequired; | 883 *error = errors::kLaunchURLRequired; |
902 return false; | 884 return false; |
903 } | 885 } |
904 | 886 |
905 // If there is no extent, we default the extent based on the launch URL. | 887 // If there is no extent, we default the extent based on the launch URL. |
906 if (web_extent().is_empty() && !launch_web_url().empty()) { | 888 if (web_extent().is_empty() && !launch_web_url().empty()) { |
907 GURL launch_url(launch_web_url()); | 889 GURL launch_url(launch_web_url()); |
908 URLPattern pattern(kValidWebExtentSchemes); | 890 URLPattern pattern(kValidWebExtentSchemes); |
909 if (!pattern.SetScheme("*")) { | 891 if (!pattern.SetScheme("*")) { |
910 *error = errors::kInvalidLaunchWebURL; | 892 *error = errors::kInvalidLaunchWebURL; |
911 return false; | 893 return false; |
912 } | 894 } |
913 pattern.set_host(launch_url.host()); | 895 pattern.set_host(launch_url.host()); |
914 pattern.set_path("/*"); | 896 pattern.set_path("/*"); |
915 mutable_static_data_->extent.AddPattern(pattern); | 897 extent_.AddPattern(pattern); |
916 } | 898 } |
917 | 899 |
918 // In order for the --apps-gallery-url switch to work with the gallery | 900 // In order for the --apps-gallery-url switch to work with the gallery |
919 // process isolation, we must insert any provided value into the component | 901 // process isolation, we must insert any provided value into the component |
920 // app's launch url and web extent. | 902 // app's launch url and web extent. |
921 if (id() == extension_misc::kWebStoreAppId) { | 903 if (id() == extension_misc::kWebStoreAppId) { |
922 GURL gallery_url(CommandLine::ForCurrentProcess()-> | 904 GURL gallery_url(CommandLine::ForCurrentProcess()-> |
923 GetSwitchValueASCII(switches::kAppsGalleryURL)); | 905 GetSwitchValueASCII(switches::kAppsGalleryURL)); |
924 if (gallery_url.is_valid()) { | 906 if (gallery_url.is_valid()) { |
925 mutable_static_data_->launch_web_url = gallery_url.spec(); | 907 launch_web_url_ = gallery_url.spec(); |
926 | 908 |
927 URLPattern pattern(URLPattern::SCHEME_HTTP | URLPattern::SCHEME_HTTPS); | 909 URLPattern pattern(URLPattern::SCHEME_HTTP | URLPattern::SCHEME_HTTPS); |
928 pattern.Parse(gallery_url.spec()); | 910 pattern.Parse(gallery_url.spec()); |
929 pattern.set_path(pattern.path() + '*'); | 911 pattern.set_path(pattern.path() + '*'); |
930 mutable_static_data_->extent.AddPattern(pattern); | 912 extent_.AddPattern(pattern); |
931 } | 913 } |
932 } | 914 } |
933 | 915 |
934 return true; | 916 return true; |
935 } | 917 } |
936 | 918 |
937 bool Extension::LoadLaunchContainer(const DictionaryValue* manifest, | 919 bool Extension::LoadLaunchContainer(const DictionaryValue* manifest, |
938 std::string* error) { | 920 std::string* error) { |
939 Value* temp = NULL; | 921 Value* temp = NULL; |
940 if (!manifest->Get(keys::kLaunchContainer, &temp)) | 922 if (!manifest->Get(keys::kLaunchContainer, &temp)) |
941 return true; | 923 return true; |
942 | 924 |
943 std::string launch_container_string; | 925 std::string launch_container_string; |
944 if (!temp->GetAsString(&launch_container_string)) { | 926 if (!temp->GetAsString(&launch_container_string)) { |
945 *error = errors::kInvalidLaunchContainer; | 927 *error = errors::kInvalidLaunchContainer; |
946 return false; | 928 return false; |
947 } | 929 } |
948 | 930 |
949 if (launch_container_string == values::kLaunchContainerPanel) { | 931 if (launch_container_string == values::kLaunchContainerPanel) { |
950 mutable_static_data_->launch_container = extension_misc::LAUNCH_PANEL; | 932 launch_container_ = extension_misc::LAUNCH_PANEL; |
951 } else if (launch_container_string == values::kLaunchContainerTab) { | 933 } else if (launch_container_string == values::kLaunchContainerTab) { |
952 mutable_static_data_->launch_container = extension_misc::LAUNCH_TAB; | 934 launch_container_ = extension_misc::LAUNCH_TAB; |
953 } else { | 935 } else { |
954 *error = errors::kInvalidLaunchContainer; | 936 *error = errors::kInvalidLaunchContainer; |
955 return false; | 937 return false; |
956 } | 938 } |
957 | 939 |
958 // Validate the container width if present. | 940 // Validate the container width if present. |
959 if (manifest->Get(keys::kLaunchWidth, &temp)) { | 941 if (manifest->Get(keys::kLaunchWidth, &temp)) { |
960 if (launch_container() != extension_misc::LAUNCH_PANEL && | 942 if (launch_container() != extension_misc::LAUNCH_PANEL && |
961 launch_container() != extension_misc::LAUNCH_WINDOW) { | 943 launch_container() != extension_misc::LAUNCH_WINDOW) { |
962 *error = errors::kInvalidLaunchWidthContainer; | 944 *error = errors::kInvalidLaunchWidthContainer; |
963 return false; | 945 return false; |
964 } | 946 } |
965 if (!temp->GetAsInteger(&mutable_static_data_->launch_width) || | 947 if (!temp->GetAsInteger(&launch_width_) || |
966 mutable_static_data_->launch_width < 0) { | 948 launch_width_ < 0) { |
967 mutable_static_data_->launch_width = 0; | 949 launch_width_ = 0; |
968 *error = errors::kInvalidLaunchWidth; | 950 *error = errors::kInvalidLaunchWidth; |
969 return false; | 951 return false; |
970 } | 952 } |
971 } | 953 } |
972 | 954 |
973 // Validate container height if present. | 955 // Validate container height if present. |
974 if (manifest->Get(keys::kLaunchHeight, &temp)) { | 956 if (manifest->Get(keys::kLaunchHeight, &temp)) { |
975 if (launch_container() != extension_misc::LAUNCH_PANEL && | 957 if (launch_container() != extension_misc::LAUNCH_PANEL && |
976 launch_container() != extension_misc::LAUNCH_WINDOW) { | 958 launch_container() != extension_misc::LAUNCH_WINDOW) { |
977 *error = errors::kInvalidLaunchHeightContainer; | 959 *error = errors::kInvalidLaunchHeightContainer; |
978 return false; | 960 return false; |
979 } | 961 } |
980 if (!temp->GetAsInteger(&mutable_static_data_->launch_height) || | 962 if (!temp->GetAsInteger(&launch_height_) || launch_height_ < 0) { |
981 mutable_static_data_->launch_height < 0) { | 963 launch_height_ = 0; |
982 mutable_static_data_->launch_height = 0; | |
983 *error = errors::kInvalidLaunchHeight; | 964 *error = errors::kInvalidLaunchHeight; |
984 return false; | 965 return false; |
985 } | 966 } |
986 } | 967 } |
987 | 968 |
988 return true; | 969 return true; |
989 } | 970 } |
990 | 971 |
991 bool Extension::EnsureNotHybridApp(const DictionaryValue* manifest, | 972 bool Extension::EnsureNotHybridApp(const DictionaryValue* manifest, |
992 std::string* error) { | 973 std::string* error) { |
993 if (web_extent().is_empty()) | 974 if (web_extent().is_empty()) |
994 return true; | 975 return true; |
995 | 976 |
996 for (DictionaryValue::key_iterator key = manifest->begin_keys(); | 977 for (DictionaryValue::key_iterator key = manifest->begin_keys(); |
997 key != manifest->end_keys(); ++key) { | 978 key != manifest->end_keys(); ++key) { |
998 if (!IsBaseCrxKey(*key) && | 979 if (!IsBaseCrxKey(*key) && |
999 *key != keys::kApp && | 980 *key != keys::kApp && |
1000 *key != keys::kPermissions && | 981 *key != keys::kPermissions && |
1001 *key != keys::kOptionsPage) { | 982 *key != keys::kOptionsPage) { |
1002 *error = errors::kHostedAppsCannotIncludeExtensionFeatures; | 983 *error = errors::kHostedAppsCannotIncludeExtensionFeatures; |
1003 return false; | 984 return false; |
1004 } | 985 } |
1005 } | 986 } |
1006 | 987 |
1007 return true; | 988 return true; |
1008 } | 989 } |
1009 | 990 |
1010 Extension::Extension(const FilePath& path, Location location) | 991 Extension::Extension(const FilePath& path, Location location) |
1011 : mutable_static_data_(new StaticData) { | 992 : incognito_split_mode_(false), |
993 location_(location), | |
994 converted_from_user_script_(false), | |
995 is_theme_(false), | |
996 is_app_(false), | |
997 launch_container_(extension_misc::LAUNCH_TAB), | |
998 launch_width_(0), | |
999 launch_height_(0) { | |
1012 DCHECK(path.IsAbsolute()); | 1000 DCHECK(path.IsAbsolute()); |
1013 | 1001 path_ = MaybeNormalizePath(path); |
1014 static_data_ = mutable_static_data_; | |
1015 mutable_static_data_->location = location; | |
1016 mutable_static_data_->path = MaybeNormalizePath(path); | |
1017 } | 1002 } |
1018 | 1003 |
1019 Extension::~Extension() { | 1004 Extension::~Extension() { |
1020 } | 1005 } |
1021 | 1006 |
1022 ExtensionResource Extension::GetResource( | 1007 ExtensionResource Extension::GetResource( |
1023 const std::string& relative_path) const { | 1008 const std::string& relative_path) const { |
1024 #if defined(OS_POSIX) | 1009 #if defined(OS_POSIX) |
1025 FilePath relative_file_path(relative_path); | 1010 FilePath relative_file_path(relative_path); |
1026 #elif defined(OS_WIN) | 1011 #elif defined(OS_WIN) |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1204 result->swap(decoded); | 1189 result->swap(decoded); |
1205 } | 1190 } |
1206 | 1191 |
1207 GURL Extension::GetBaseURLFromExtensionId(const std::string& extension_id) { | 1192 GURL Extension::GetBaseURLFromExtensionId(const std::string& extension_id) { |
1208 return GURL(std::string(chrome::kExtensionScheme) + | 1193 return GURL(std::string(chrome::kExtensionScheme) + |
1209 chrome::kStandardSchemeSeparator + extension_id + "/"); | 1194 chrome::kStandardSchemeSeparator + extension_id + "/"); |
1210 } | 1195 } |
1211 | 1196 |
1212 bool Extension::InitFromValue(const DictionaryValue& source, bool require_key, | 1197 bool Extension::InitFromValue(const DictionaryValue& source, bool require_key, |
1213 std::string* error) { | 1198 std::string* error) { |
1214 // Unit tests reuse Extension objects, so we need to reset mutable_static_data | |
1215 // when we re-initialize. | |
1216 mutable_static_data_ = const_cast<StaticData*>(static_data_.get()); | |
1217 | |
1218 if (source.HasKey(keys::kPublicKey)) { | 1199 if (source.HasKey(keys::kPublicKey)) { |
1219 std::string public_key_bytes; | 1200 std::string public_key_bytes; |
1220 if (!source.GetString(keys::kPublicKey, | 1201 if (!source.GetString(keys::kPublicKey, |
1221 &mutable_static_data_->public_key) || | 1202 &public_key_) || |
1222 !ParsePEMKeyBytes(mutable_static_data_->public_key, | 1203 !ParsePEMKeyBytes(public_key_, |
1223 &public_key_bytes) || | 1204 &public_key_bytes) || |
1224 !GenerateId(public_key_bytes, &mutable_static_data_->id)) { | 1205 !GenerateId(public_key_bytes, &id_)) { |
1225 *error = errors::kInvalidKey; | 1206 *error = errors::kInvalidKey; |
1226 return false; | 1207 return false; |
1227 } | 1208 } |
1228 } else if (require_key) { | 1209 } else if (require_key) { |
1229 *error = errors::kInvalidKey; | 1210 *error = errors::kInvalidKey; |
1230 return false; | 1211 return false; |
1231 } else { | 1212 } else { |
1232 // If there is a path, we generate the ID from it. This is useful for | 1213 // If there is a path, we generate the ID from it. This is useful for |
1233 // development mode, because it keeps the ID stable across restarts and | 1214 // development mode, because it keeps the ID stable across restarts and |
1234 // reloading the extension. | 1215 // reloading the extension. |
1235 mutable_static_data_->id = Extension::GenerateIdForPath(path()); | 1216 id_ = Extension::GenerateIdForPath(path()); |
1236 if (mutable_static_data_->id.empty()) { | 1217 if (id_.empty()) { |
1237 NOTREACHED() << "Could not create ID from path."; | 1218 NOTREACHED() << "Could not create ID from path."; |
1238 return false; | 1219 return false; |
1239 } | 1220 } |
1240 } | 1221 } |
1241 | 1222 |
1242 // Make a copy of the manifest so we can store it in prefs. | 1223 // Make a copy of the manifest so we can store it in prefs. |
1243 mutable_static_data_->manifest_value.reset( | 1224 manifest_value_.reset( |
1244 static_cast<DictionaryValue*>(source.DeepCopy())); | 1225 static_cast<DictionaryValue*>(source.DeepCopy())); |
1245 | 1226 |
1246 // Initialize the URL. | 1227 // Initialize the URL. |
1247 mutable_static_data_->extension_url = | 1228 extension_url_ = |
1248 Extension::GetBaseURLFromExtensionId(id()); | 1229 Extension::GetBaseURLFromExtensionId(id()); |
1249 | 1230 |
1250 // Initialize version. | 1231 // Initialize version. |
1251 std::string version_str; | 1232 std::string version_str; |
1252 if (!source.GetString(keys::kVersion, &version_str)) { | 1233 if (!source.GetString(keys::kVersion, &version_str)) { |
1253 *error = errors::kInvalidVersion; | 1234 *error = errors::kInvalidVersion; |
1254 return false; | 1235 return false; |
1255 } | 1236 } |
1256 mutable_static_data_->version.reset( | 1237 version_.reset( |
1257 Version::GetVersionFromString(version_str)); | 1238 Version::GetVersionFromString(version_str)); |
1258 if (!mutable_static_data_->version.get() || | 1239 if (!version_.get() || |
1259 mutable_static_data_->version->components().size() > 4) { | 1240 version_->components().size() > 4) { |
1260 *error = errors::kInvalidVersion; | 1241 *error = errors::kInvalidVersion; |
1261 return false; | 1242 return false; |
1262 } | 1243 } |
1263 | 1244 |
1264 // Initialize name. | 1245 // Initialize name. |
1265 string16 localized_name; | 1246 string16 localized_name; |
1266 if (!source.GetString(keys::kName, &localized_name)) { | 1247 if (!source.GetString(keys::kName, &localized_name)) { |
1267 *error = errors::kInvalidName; | 1248 *error = errors::kInvalidName; |
1268 return false; | 1249 return false; |
1269 } | 1250 } |
1270 base::i18n::AdjustStringForLocaleDirection(localized_name, &localized_name); | 1251 base::i18n::AdjustStringForLocaleDirection(localized_name, &localized_name); |
1271 mutable_static_data_->name = UTF16ToUTF8(localized_name); | 1252 name_ = UTF16ToUTF8(localized_name); |
1272 | 1253 |
1273 // Initialize description (if present). | 1254 // Initialize description (if present). |
1274 if (source.HasKey(keys::kDescription)) { | 1255 if (source.HasKey(keys::kDescription)) { |
1275 if (!source.GetString(keys::kDescription, | 1256 if (!source.GetString(keys::kDescription, |
1276 &mutable_static_data_->description)) { | 1257 &description_)) { |
1277 *error = errors::kInvalidDescription; | 1258 *error = errors::kInvalidDescription; |
1278 return false; | 1259 return false; |
1279 } | 1260 } |
1280 } | 1261 } |
1281 | 1262 |
1282 // Initialize homepage url (if present). | 1263 // Initialize homepage url (if present). |
1283 if (source.HasKey(keys::kHomepageURL)) { | 1264 if (source.HasKey(keys::kHomepageURL)) { |
1284 std::string tmp; | 1265 std::string tmp; |
1285 if (!source.GetString(keys::kHomepageURL, &tmp)) { | 1266 if (!source.GetString(keys::kHomepageURL, &tmp)) { |
1286 *error = ExtensionErrorUtils::FormatErrorMessage( | 1267 *error = ExtensionErrorUtils::FormatErrorMessage( |
1287 errors::kInvalidHomepageURL, ""); | 1268 errors::kInvalidHomepageURL, ""); |
1288 return false; | 1269 return false; |
1289 } | 1270 } |
1290 mutable_static_data_->homepage_url = GURL(tmp); | 1271 homepage_url_ = GURL(tmp); |
1291 if (!mutable_static_data_->homepage_url.is_valid()) { | 1272 if (!homepage_url_.is_valid()) { |
1292 *error = ExtensionErrorUtils::FormatErrorMessage( | 1273 *error = ExtensionErrorUtils::FormatErrorMessage( |
1293 errors::kInvalidHomepageURL, tmp); | 1274 errors::kInvalidHomepageURL, tmp); |
1294 return false; | 1275 return false; |
1295 } | 1276 } |
1296 } | 1277 } |
1297 | 1278 |
1298 // Initialize update url (if present). | 1279 // Initialize update url (if present). |
1299 if (source.HasKey(keys::kUpdateURL)) { | 1280 if (source.HasKey(keys::kUpdateURL)) { |
1300 std::string tmp; | 1281 std::string tmp; |
1301 if (!source.GetString(keys::kUpdateURL, &tmp)) { | 1282 if (!source.GetString(keys::kUpdateURL, &tmp)) { |
1302 *error = ExtensionErrorUtils::FormatErrorMessage( | 1283 *error = ExtensionErrorUtils::FormatErrorMessage( |
1303 errors::kInvalidUpdateURL, ""); | 1284 errors::kInvalidUpdateURL, ""); |
1304 return false; | 1285 return false; |
1305 } | 1286 } |
1306 mutable_static_data_->update_url = GURL(tmp); | 1287 update_url_ = GURL(tmp); |
1307 if (!mutable_static_data_->update_url.is_valid() || | 1288 if (!update_url_.is_valid() || |
1308 mutable_static_data_->update_url.has_ref()) { | 1289 update_url_.has_ref()) { |
1309 *error = ExtensionErrorUtils::FormatErrorMessage( | 1290 *error = ExtensionErrorUtils::FormatErrorMessage( |
1310 errors::kInvalidUpdateURL, tmp); | 1291 errors::kInvalidUpdateURL, tmp); |
1311 return false; | 1292 return false; |
1312 } | 1293 } |
1313 } | 1294 } |
1314 | 1295 |
1315 // Validate minimum Chrome version (if present). We don't need to store this, | 1296 // Validate minimum Chrome version (if present). We don't need to store this, |
1316 // since the extension is not valid if it is incorrect. | 1297 // since the extension is not valid if it is incorrect. |
1317 if (source.HasKey(keys::kMinimumChromeVersion)) { | 1298 if (source.HasKey(keys::kMinimumChromeVersion)) { |
1318 std::string minimum_version_string; | 1299 std::string minimum_version_string; |
(...skipping 27 matching lines...) Expand all Loading... | |
1346 *error = ExtensionErrorUtils::FormatErrorMessage( | 1327 *error = ExtensionErrorUtils::FormatErrorMessage( |
1347 errors::kChromeVersionTooLow, | 1328 errors::kChromeVersionTooLow, |
1348 l10n_util::GetStringUTF8(IDS_PRODUCT_NAME), | 1329 l10n_util::GetStringUTF8(IDS_PRODUCT_NAME), |
1349 minimum_version_string); | 1330 minimum_version_string); |
1350 return false; | 1331 return false; |
1351 } | 1332 } |
1352 } | 1333 } |
1353 | 1334 |
1354 // Initialize converted_from_user_script (if present) | 1335 // Initialize converted_from_user_script (if present) |
1355 source.GetBoolean(keys::kConvertedFromUserScript, | 1336 source.GetBoolean(keys::kConvertedFromUserScript, |
1356 &mutable_static_data_->converted_from_user_script); | 1337 &converted_from_user_script_); |
1357 | 1338 |
1358 // Initialize icons (if present). | 1339 // Initialize icons (if present). |
1359 if (source.HasKey(keys::kIcons)) { | 1340 if (source.HasKey(keys::kIcons)) { |
1360 DictionaryValue* icons_value = NULL; | 1341 DictionaryValue* icons_value = NULL; |
1361 if (!source.GetDictionary(keys::kIcons, &icons_value)) { | 1342 if (!source.GetDictionary(keys::kIcons, &icons_value)) { |
1362 *error = errors::kInvalidIcons; | 1343 *error = errors::kInvalidIcons; |
1363 return false; | 1344 return false; |
1364 } | 1345 } |
1365 | 1346 |
1366 for (size_t i = 0; i < arraysize(kIconSizes); ++i) { | 1347 for (size_t i = 0; i < arraysize(kIconSizes); ++i) { |
1367 std::string key = base::IntToString(kIconSizes[i]); | 1348 std::string key = base::IntToString(kIconSizes[i]); |
1368 if (icons_value->HasKey(key)) { | 1349 if (icons_value->HasKey(key)) { |
1369 std::string icon_path; | 1350 std::string icon_path; |
1370 if (!icons_value->GetString(key, &icon_path)) { | 1351 if (!icons_value->GetString(key, &icon_path)) { |
1371 *error = ExtensionErrorUtils::FormatErrorMessage( | 1352 *error = ExtensionErrorUtils::FormatErrorMessage( |
1372 errors::kInvalidIconPath, key); | 1353 errors::kInvalidIconPath, key); |
1373 return false; | 1354 return false; |
1374 } | 1355 } |
1375 | 1356 |
1376 if (icon_path.size() > 0 && icon_path[0] == '/') | 1357 if (icon_path.size() > 0 && icon_path[0] == '/') |
1377 icon_path = icon_path.substr(1); | 1358 icon_path = icon_path.substr(1); |
1378 | 1359 |
1379 if (icon_path.empty()) { | 1360 if (icon_path.empty()) { |
1380 *error = ExtensionErrorUtils::FormatErrorMessage( | 1361 *error = ExtensionErrorUtils::FormatErrorMessage( |
1381 errors::kInvalidIconPath, key); | 1362 errors::kInvalidIconPath, key); |
1382 return false; | 1363 return false; |
1383 } | 1364 } |
1384 | 1365 |
1385 mutable_static_data_->icons.Add(kIconSizes[i], icon_path); | 1366 icons_.Add(kIconSizes[i], icon_path); |
1386 } | 1367 } |
1387 } | 1368 } |
1388 } | 1369 } |
1389 | 1370 |
1390 // Initialize themes (if present). | 1371 // Initialize themes (if present). |
1391 mutable_static_data_->is_theme = false; | 1372 is_theme_ = false; |
1392 if (source.HasKey(keys::kTheme)) { | 1373 if (source.HasKey(keys::kTheme)) { |
1393 // Themes cannot contain extension keys. | 1374 // Themes cannot contain extension keys. |
1394 if (ContainsNonThemeKeys(source)) { | 1375 if (ContainsNonThemeKeys(source)) { |
1395 *error = errors::kThemesCannotContainExtensions; | 1376 *error = errors::kThemesCannotContainExtensions; |
1396 return false; | 1377 return false; |
1397 } | 1378 } |
1398 | 1379 |
1399 DictionaryValue* theme_value; | 1380 DictionaryValue* theme_value; |
1400 if (!source.GetDictionary(keys::kTheme, &theme_value)) { | 1381 if (!source.GetDictionary(keys::kTheme, &theme_value)) { |
1401 *error = errors::kInvalidTheme; | 1382 *error = errors::kInvalidTheme; |
1402 return false; | 1383 return false; |
1403 } | 1384 } |
1404 mutable_static_data_->is_theme = true; | 1385 is_theme_ = true; |
1405 | 1386 |
1406 DictionaryValue* images_value; | 1387 DictionaryValue* images_value; |
1407 if (theme_value->GetDictionary(keys::kThemeImages, &images_value)) { | 1388 if (theme_value->GetDictionary(keys::kThemeImages, &images_value)) { |
1408 // Validate that the images are all strings | 1389 // Validate that the images are all strings |
1409 for (DictionaryValue::key_iterator iter = images_value->begin_keys(); | 1390 for (DictionaryValue::key_iterator iter = images_value->begin_keys(); |
1410 iter != images_value->end_keys(); ++iter) { | 1391 iter != images_value->end_keys(); ++iter) { |
1411 std::string val; | 1392 std::string val; |
1412 if (!images_value->GetString(*iter, &val)) { | 1393 if (!images_value->GetString(*iter, &val)) { |
1413 *error = errors::kInvalidThemeImages; | 1394 *error = errors::kInvalidThemeImages; |
1414 return false; | 1395 return false; |
1415 } | 1396 } |
1416 } | 1397 } |
1417 mutable_static_data_->theme_images.reset( | 1398 theme_images_.reset( |
1418 static_cast<DictionaryValue*>(images_value->DeepCopy())); | 1399 static_cast<DictionaryValue*>(images_value->DeepCopy())); |
1419 } | 1400 } |
1420 | 1401 |
1421 DictionaryValue* colors_value; | 1402 DictionaryValue* colors_value; |
1422 if (theme_value->GetDictionary(keys::kThemeColors, &colors_value)) { | 1403 if (theme_value->GetDictionary(keys::kThemeColors, &colors_value)) { |
1423 // Validate that the colors are RGB or RGBA lists | 1404 // Validate that the colors are RGB or RGBA lists |
1424 for (DictionaryValue::key_iterator iter = colors_value->begin_keys(); | 1405 for (DictionaryValue::key_iterator iter = colors_value->begin_keys(); |
1425 iter != colors_value->end_keys(); ++iter) { | 1406 iter != colors_value->end_keys(); ++iter) { |
1426 ListValue* color_list; | 1407 ListValue* color_list; |
1427 double alpha; | 1408 double alpha; |
1428 int alpha_int; | 1409 int alpha_int; |
1429 int color; | 1410 int color; |
1430 // The color must be a list | 1411 // The color must be a list |
1431 if (!colors_value->GetListWithoutPathExpansion(*iter, &color_list) || | 1412 if (!colors_value->GetListWithoutPathExpansion(*iter, &color_list) || |
1432 // And either 3 items (RGB) or 4 (RGBA) | 1413 // And either 3 items (RGB) or 4 (RGBA) |
1433 ((color_list->GetSize() != 3) && | 1414 ((color_list->GetSize() != 3) && |
1434 ((color_list->GetSize() != 4) || | 1415 ((color_list->GetSize() != 4) || |
1435 // For RGBA, the fourth item must be a real or int alpha value | 1416 // For RGBA, the fourth item must be a real or int alpha value |
1436 (!color_list->GetReal(3, &alpha) && | 1417 (!color_list->GetReal(3, &alpha) && |
1437 !color_list->GetInteger(3, &alpha_int)))) || | 1418 !color_list->GetInteger(3, &alpha_int)))) || |
1438 // For both RGB and RGBA, the first three items must be ints (R,G,B) | 1419 // For both RGB and RGBA, the first three items must be ints (R,G,B) |
1439 !color_list->GetInteger(0, &color) || | 1420 !color_list->GetInteger(0, &color) || |
1440 !color_list->GetInteger(1, &color) || | 1421 !color_list->GetInteger(1, &color) || |
1441 !color_list->GetInteger(2, &color)) { | 1422 !color_list->GetInteger(2, &color)) { |
1442 *error = errors::kInvalidThemeColors; | 1423 *error = errors::kInvalidThemeColors; |
1443 return false; | 1424 return false; |
1444 } | 1425 } |
1445 } | 1426 } |
1446 mutable_static_data_->theme_colors.reset( | 1427 theme_colors_.reset( |
1447 static_cast<DictionaryValue*>(colors_value->DeepCopy())); | 1428 static_cast<DictionaryValue*>(colors_value->DeepCopy())); |
1448 } | 1429 } |
1449 | 1430 |
1450 DictionaryValue* tints_value; | 1431 DictionaryValue* tints_value; |
1451 if (theme_value->GetDictionary(keys::kThemeTints, &tints_value)) { | 1432 if (theme_value->GetDictionary(keys::kThemeTints, &tints_value)) { |
1452 // Validate that the tints are all reals. | 1433 // Validate that the tints are all reals. |
1453 for (DictionaryValue::key_iterator iter = tints_value->begin_keys(); | 1434 for (DictionaryValue::key_iterator iter = tints_value->begin_keys(); |
1454 iter != tints_value->end_keys(); ++iter) { | 1435 iter != tints_value->end_keys(); ++iter) { |
1455 ListValue* tint_list; | 1436 ListValue* tint_list; |
1456 double v; | 1437 double v; |
1457 int vi; | 1438 int vi; |
1458 if (!tints_value->GetListWithoutPathExpansion(*iter, &tint_list) || | 1439 if (!tints_value->GetListWithoutPathExpansion(*iter, &tint_list) || |
1459 tint_list->GetSize() != 3 || | 1440 tint_list->GetSize() != 3 || |
1460 !(tint_list->GetReal(0, &v) || tint_list->GetInteger(0, &vi)) || | 1441 !(tint_list->GetReal(0, &v) || tint_list->GetInteger(0, &vi)) || |
1461 !(tint_list->GetReal(1, &v) || tint_list->GetInteger(1, &vi)) || | 1442 !(tint_list->GetReal(1, &v) || tint_list->GetInteger(1, &vi)) || |
1462 !(tint_list->GetReal(2, &v) || tint_list->GetInteger(2, &vi))) { | 1443 !(tint_list->GetReal(2, &v) || tint_list->GetInteger(2, &vi))) { |
1463 *error = errors::kInvalidThemeTints; | 1444 *error = errors::kInvalidThemeTints; |
1464 return false; | 1445 return false; |
1465 } | 1446 } |
1466 } | 1447 } |
1467 mutable_static_data_->theme_tints.reset( | 1448 theme_tints_.reset( |
1468 static_cast<DictionaryValue*>(tints_value->DeepCopy())); | 1449 static_cast<DictionaryValue*>(tints_value->DeepCopy())); |
1469 } | 1450 } |
1470 | 1451 |
1471 DictionaryValue* display_properties_value; | 1452 DictionaryValue* display_properties_value; |
1472 if (theme_value->GetDictionary(keys::kThemeDisplayProperties, | 1453 if (theme_value->GetDictionary(keys::kThemeDisplayProperties, |
1473 &display_properties_value)) { | 1454 &display_properties_value)) { |
1474 mutable_static_data_->theme_display_properties.reset( | 1455 theme_display_properties_.reset( |
1475 static_cast<DictionaryValue*>(display_properties_value->DeepCopy())); | 1456 static_cast<DictionaryValue*>(display_properties_value->DeepCopy())); |
1476 } | 1457 } |
1477 | 1458 |
1478 return true; | 1459 return true; |
1479 } | 1460 } |
1480 | 1461 |
1481 // Initialize plugins (optional). | 1462 // Initialize plugins (optional). |
1482 if (source.HasKey(keys::kPlugins)) { | 1463 if (source.HasKey(keys::kPlugins)) { |
1483 ListValue* list_value; | 1464 ListValue* list_value; |
1484 if (!source.GetList(keys::kPlugins, &list_value)) { | 1465 if (!source.GetList(keys::kPlugins, &list_value)) { |
(...skipping 27 matching lines...) Expand all Loading... | |
1512 | 1493 |
1513 // Get plugins[i].content (optional). | 1494 // Get plugins[i].content (optional). |
1514 if (plugin_value->HasKey(keys::kPluginsPublic)) { | 1495 if (plugin_value->HasKey(keys::kPluginsPublic)) { |
1515 if (!plugin_value->GetBoolean(keys::kPluginsPublic, &is_public)) { | 1496 if (!plugin_value->GetBoolean(keys::kPluginsPublic, &is_public)) { |
1516 *error = ExtensionErrorUtils::FormatErrorMessage( | 1497 *error = ExtensionErrorUtils::FormatErrorMessage( |
1517 errors::kInvalidPluginsPublic, base::IntToString(i)); | 1498 errors::kInvalidPluginsPublic, base::IntToString(i)); |
1518 return false; | 1499 return false; |
1519 } | 1500 } |
1520 } | 1501 } |
1521 | 1502 |
1522 mutable_static_data_->plugins.push_back(PluginInfo()); | 1503 plugins_.push_back(PluginInfo()); |
1523 mutable_static_data_->plugins.back().path = path().AppendASCII(path_str); | 1504 plugins_.back().path = path().AppendASCII(path_str); |
1524 mutable_static_data_->plugins.back().is_public = is_public; | 1505 plugins_.back().is_public = is_public; |
1525 } | 1506 } |
1526 } | 1507 } |
1527 | 1508 |
1528 // Initialize background url (optional). | 1509 // Initialize background url (optional). |
1529 if (source.HasKey(keys::kBackground)) { | 1510 if (source.HasKey(keys::kBackground)) { |
1530 std::string background_str; | 1511 std::string background_str; |
1531 if (!source.GetString(keys::kBackground, &background_str)) { | 1512 if (!source.GetString(keys::kBackground, &background_str)) { |
1532 *error = errors::kInvalidBackground; | 1513 *error = errors::kInvalidBackground; |
1533 return false; | 1514 return false; |
1534 } | 1515 } |
1535 mutable_static_data_->background_url = GetResourceURL(background_str); | 1516 background_url_ = GetResourceURL(background_str); |
1536 } | 1517 } |
1537 | 1518 |
1538 // Initialize toolstrips. This is deprecated for public use. | 1519 // Initialize toolstrips. This is deprecated for public use. |
1539 // NOTE(erikkay) Although deprecated, we intend to preserve this parsing | 1520 // NOTE(erikkay) Although deprecated, we intend to preserve this parsing |
1540 // code indefinitely. Please contact me or Joi for details as to why. | 1521 // code indefinitely. Please contact me or Joi for details as to why. |
1541 if (CommandLine::ForCurrentProcess()->HasSwitch( | 1522 if (CommandLine::ForCurrentProcess()->HasSwitch( |
1542 switches::kEnableExperimentalExtensionApis) && | 1523 switches::kEnableExperimentalExtensionApis) && |
1543 source.HasKey(keys::kToolstrips)) { | 1524 source.HasKey(keys::kToolstrips)) { |
1544 ListValue* list_value; | 1525 ListValue* list_value; |
1545 if (!source.GetList(keys::kToolstrips, &list_value)) { | 1526 if (!source.GetList(keys::kToolstrips, &list_value)) { |
(...skipping 14 matching lines...) Expand all Loading... | |
1560 *error = ExtensionErrorUtils::FormatErrorMessage( | 1541 *error = ExtensionErrorUtils::FormatErrorMessage( |
1561 errors::kInvalidToolstrip, base::IntToString(i)); | 1542 errors::kInvalidToolstrip, base::IntToString(i)); |
1562 return false; | 1543 return false; |
1563 } | 1544 } |
1564 toolstrip = GetResourceURL(toolstrip_path); | 1545 toolstrip = GetResourceURL(toolstrip_path); |
1565 } else { | 1546 } else { |
1566 *error = ExtensionErrorUtils::FormatErrorMessage( | 1547 *error = ExtensionErrorUtils::FormatErrorMessage( |
1567 errors::kInvalidToolstrip, base::IntToString(i)); | 1548 errors::kInvalidToolstrip, base::IntToString(i)); |
1568 return false; | 1549 return false; |
1569 } | 1550 } |
1570 mutable_static_data_->toolstrips.push_back(toolstrip); | 1551 toolstrips_.push_back(toolstrip); |
1571 } | 1552 } |
1572 } | 1553 } |
1573 | 1554 |
1574 // Initialize content scripts (optional). | 1555 // Initialize content scripts (optional). |
1575 if (source.HasKey(keys::kContentScripts)) { | 1556 if (source.HasKey(keys::kContentScripts)) { |
1576 ListValue* list_value; | 1557 ListValue* list_value; |
1577 if (!source.GetList(keys::kContentScripts, &list_value)) { | 1558 if (!source.GetList(keys::kContentScripts, &list_value)) { |
1578 *error = errors::kInvalidContentScriptsList; | 1559 *error = errors::kInvalidContentScriptsList; |
1579 return false; | 1560 return false; |
1580 } | 1561 } |
1581 | 1562 |
1582 for (size_t i = 0; i < list_value->GetSize(); ++i) { | 1563 for (size_t i = 0; i < list_value->GetSize(); ++i) { |
1583 DictionaryValue* content_script; | 1564 DictionaryValue* content_script; |
1584 if (!list_value->GetDictionary(i, &content_script)) { | 1565 if (!list_value->GetDictionary(i, &content_script)) { |
1585 *error = ExtensionErrorUtils::FormatErrorMessage( | 1566 *error = ExtensionErrorUtils::FormatErrorMessage( |
1586 errors::kInvalidContentScript, base::IntToString(i)); | 1567 errors::kInvalidContentScript, base::IntToString(i)); |
1587 return false; | 1568 return false; |
1588 } | 1569 } |
1589 | 1570 |
1590 UserScript script; | 1571 UserScript script; |
1591 if (!LoadUserScriptHelper(content_script, i, error, &script)) | 1572 if (!LoadUserScriptHelper(content_script, i, error, &script)) |
1592 return false; // Failed to parse script context definition. | 1573 return false; // Failed to parse script context definition. |
1593 script.set_extension_id(id()); | 1574 script.set_extension_id(id()); |
1594 if (mutable_static_data_->converted_from_user_script) { | 1575 if (converted_from_user_script_) { |
1595 script.set_emulate_greasemonkey(true); | 1576 script.set_emulate_greasemonkey(true); |
1596 script.set_match_all_frames(true); // Greasemonkey matches all frames. | 1577 script.set_match_all_frames(true); // Greasemonkey matches all frames. |
1597 } | 1578 } |
1598 mutable_static_data_->content_scripts.push_back(script); | 1579 content_scripts_.push_back(script); |
1599 } | 1580 } |
1600 } | 1581 } |
1601 | 1582 |
1602 // Initialize page action (optional). | 1583 // Initialize page action (optional). |
1603 DictionaryValue* page_action_value = NULL; | 1584 DictionaryValue* page_action_value = NULL; |
1604 | 1585 |
1605 if (source.HasKey(keys::kPageActions)) { | 1586 if (source.HasKey(keys::kPageActions)) { |
1606 ListValue* list_value; | 1587 ListValue* list_value; |
1607 if (!source.GetList(keys::kPageActions, &list_value)) { | 1588 if (!source.GetList(keys::kPageActions, &list_value)) { |
1608 *error = errors::kInvalidPageActionsList; | 1589 *error = errors::kInvalidPageActionsList; |
(...skipping 16 matching lines...) Expand all Loading... | |
1625 } | 1606 } |
1626 } else if (source.HasKey(keys::kPageAction)) { | 1607 } else if (source.HasKey(keys::kPageAction)) { |
1627 if (!source.GetDictionary(keys::kPageAction, &page_action_value)) { | 1608 if (!source.GetDictionary(keys::kPageAction, &page_action_value)) { |
1628 *error = errors::kInvalidPageAction; | 1609 *error = errors::kInvalidPageAction; |
1629 return false; | 1610 return false; |
1630 } | 1611 } |
1631 } | 1612 } |
1632 | 1613 |
1633 // If page_action_value is not NULL, then there was a valid page action. | 1614 // If page_action_value is not NULL, then there was a valid page action. |
1634 if (page_action_value) { | 1615 if (page_action_value) { |
1635 mutable_static_data_->page_action.reset( | 1616 page_action_.reset( |
1636 LoadExtensionActionHelper(page_action_value, error)); | 1617 LoadExtensionActionHelper(page_action_value, error)); |
1637 if (!mutable_static_data_->page_action.get()) | 1618 if (!page_action_.get()) |
1638 return false; // Failed to parse page action definition. | 1619 return false; // Failed to parse page action definition. |
1639 } | 1620 } |
1640 | 1621 |
1641 // Initialize browser action (optional). | 1622 // Initialize browser action (optional). |
1642 if (source.HasKey(keys::kBrowserAction)) { | 1623 if (source.HasKey(keys::kBrowserAction)) { |
1643 DictionaryValue* browser_action_value; | 1624 DictionaryValue* browser_action_value; |
1644 if (!source.GetDictionary(keys::kBrowserAction, &browser_action_value)) { | 1625 if (!source.GetDictionary(keys::kBrowserAction, &browser_action_value)) { |
1645 *error = errors::kInvalidBrowserAction; | 1626 *error = errors::kInvalidBrowserAction; |
1646 return false; | 1627 return false; |
1647 } | 1628 } |
1648 | 1629 |
1649 mutable_static_data_->browser_action.reset( | 1630 browser_action_.reset( |
1650 LoadExtensionActionHelper(browser_action_value, error)); | 1631 LoadExtensionActionHelper(browser_action_value, error)); |
1651 if (!mutable_static_data_->browser_action.get()) | 1632 if (!browser_action_.get()) |
1652 return false; // Failed to parse browser action definition. | 1633 return false; // Failed to parse browser action definition. |
1653 } | 1634 } |
1654 | 1635 |
1655 // Load App settings. | 1636 // Load App settings. |
1656 if (!LoadIsApp(mutable_static_data_->manifest_value.get(), error) || | 1637 if (!LoadIsApp(manifest_value_.get(), error) || |
1657 !LoadExtent(mutable_static_data_->manifest_value.get(), keys::kWebURLs, | 1638 !LoadExtent(manifest_value_.get(), keys::kWebURLs, |
1658 &mutable_static_data_->extent, | 1639 &extent_, |
1659 errors::kInvalidWebURLs, errors::kInvalidWebURL, error) || | 1640 errors::kInvalidWebURLs, errors::kInvalidWebURL, error) || |
1660 !EnsureNotHybridApp(mutable_static_data_->manifest_value.get(), error) || | 1641 !EnsureNotHybridApp(manifest_value_.get(), error) || |
1661 !LoadLaunchURL(mutable_static_data_->manifest_value.get(), error) || | 1642 !LoadLaunchURL(manifest_value_.get(), error) || |
1662 !LoadLaunchContainer(mutable_static_data_->manifest_value.get(), error)) { | 1643 !LoadLaunchContainer(manifest_value_.get(), error)) { |
1663 return false; | 1644 return false; |
1664 } | 1645 } |
1665 | 1646 |
1666 // Initialize options page url (optional). | 1647 // Initialize options page url (optional). |
1667 // Funtion LoadIsApp() set mutable_static_data_->is_app above. | 1648 // Funtion LoadIsApp() set is_app_ above. |
1668 if (source.HasKey(keys::kOptionsPage)) { | 1649 if (source.HasKey(keys::kOptionsPage)) { |
1669 std::string options_str; | 1650 std::string options_str; |
1670 if (!source.GetString(keys::kOptionsPage, &options_str)) { | 1651 if (!source.GetString(keys::kOptionsPage, &options_str)) { |
1671 *error = errors::kInvalidOptionsPage; | 1652 *error = errors::kInvalidOptionsPage; |
1672 return false; | 1653 return false; |
1673 } | 1654 } |
1674 | 1655 |
1675 if (is_hosted_app()) { | 1656 if (is_hosted_app()) { |
1676 // hosted apps require an absolute URL. | 1657 // hosted apps require an absolute URL. |
1677 GURL options_url(options_str); | 1658 GURL options_url(options_str); |
1678 if (!options_url.is_valid() || | 1659 if (!options_url.is_valid() || |
1679 !(options_url.SchemeIs("http") || options_url.SchemeIs("https"))) { | 1660 !(options_url.SchemeIs("http") || options_url.SchemeIs("https"))) { |
1680 *error = errors::kInvalidOptionsPageInHostedApp; | 1661 *error = errors::kInvalidOptionsPageInHostedApp; |
1681 return false; | 1662 return false; |
1682 } | 1663 } |
1683 mutable_static_data_->options_url = options_url; | 1664 options_url_ = options_url; |
1684 | 1665 |
1685 } else { | 1666 } else { |
1686 GURL absolute(options_str); | 1667 GURL absolute(options_str); |
1687 if (absolute.is_valid()) { | 1668 if (absolute.is_valid()) { |
1688 *error = errors::kInvalidOptionsPageExpectUrlInPackage; | 1669 *error = errors::kInvalidOptionsPageExpectUrlInPackage; |
1689 return false; | 1670 return false; |
1690 } | 1671 } |
1691 mutable_static_data_->options_url = GetResourceURL(options_str); | 1672 options_url_ = GetResourceURL(options_str); |
1692 if (!mutable_static_data_->options_url.is_valid()) { | 1673 if (!options_url_.is_valid()) { |
1693 *error = errors::kInvalidOptionsPage; | 1674 *error = errors::kInvalidOptionsPage; |
1694 return false; | 1675 return false; |
1695 } | 1676 } |
1696 } | 1677 } |
1697 } | 1678 } |
1698 | 1679 |
1699 // Initialize the permissions (optional). | 1680 // Initialize the permissions (optional). |
1700 if (source.HasKey(keys::kPermissions)) { | 1681 if (source.HasKey(keys::kPermissions)) { |
1701 ListValue* permissions = NULL; | 1682 ListValue* permissions = NULL; |
1702 if (!source.GetList(keys::kPermissions, &permissions)) { | 1683 if (!source.GetList(keys::kPermissions, &permissions)) { |
1703 *error = ExtensionErrorUtils::FormatErrorMessage( | 1684 *error = ExtensionErrorUtils::FormatErrorMessage( |
1704 errors::kInvalidPermissions, ""); | 1685 errors::kInvalidPermissions, ""); |
1705 return false; | 1686 return false; |
1706 } | 1687 } |
1707 | 1688 |
1708 for (size_t i = 0; i < permissions->GetSize(); ++i) { | 1689 for (size_t i = 0; i < permissions->GetSize(); ++i) { |
1709 std::string permission_str; | 1690 std::string permission_str; |
1710 if (!permissions->GetString(i, &permission_str)) { | 1691 if (!permissions->GetString(i, &permission_str)) { |
1711 *error = ExtensionErrorUtils::FormatErrorMessage( | 1692 *error = ExtensionErrorUtils::FormatErrorMessage( |
1712 errors::kInvalidPermission, base::IntToString(i)); | 1693 errors::kInvalidPermission, base::IntToString(i)); |
1713 return false; | 1694 return false; |
1714 } | 1695 } |
1715 | 1696 |
1716 // Only COMPONENT extensions can use the webstorePrivate APIs. | 1697 // Only COMPONENT extensions can use the webstorePrivate APIs. |
1717 // TODO(asargent) - We want a more general purpose mechanism for this, | 1698 // TODO(asargent) - We want a more general purpose mechanism for this, |
1718 // and better error messages. (http://crbug.com/54013) | 1699 // and better error messages. (http://crbug.com/54013) |
1719 if (permission_str == kWebstorePrivatePermission && | 1700 if (permission_str == kWebstorePrivatePermission && |
1720 mutable_static_data_->location != Extension::COMPONENT) { | 1701 location_ != Extension::COMPONENT) { |
1721 continue; | 1702 continue; |
1722 } | 1703 } |
1723 | 1704 |
1724 // Remap the old unlimited storage permission name. | 1705 // Remap the old unlimited storage permission name. |
1725 if (permission_str == kOldUnlimitedStoragePermission) | 1706 if (permission_str == kOldUnlimitedStoragePermission) |
1726 permission_str = kUnlimitedStoragePermission; | 1707 permission_str = kUnlimitedStoragePermission; |
1727 | 1708 |
1728 if (web_extent().is_empty() || location() == Extension::COMPONENT) { | 1709 if (web_extent().is_empty() || location() == Extension::COMPONENT) { |
1729 // Check if it's a module permission. If so, enable that permission. | 1710 // Check if it's a module permission. If so, enable that permission. |
1730 if (IsAPIPermission(permission_str)) { | 1711 if (IsAPIPermission(permission_str)) { |
1731 mutable_static_data_->api_permissions.insert(permission_str); | 1712 api_permissions_.insert(permission_str); |
1732 continue; | 1713 continue; |
1733 } | 1714 } |
1734 } else { | 1715 } else { |
1735 // Hosted apps only get access to a subset of the valid permissions. | 1716 // Hosted apps only get access to a subset of the valid permissions. |
1736 if (IsHostedAppPermission(permission_str)) { | 1717 if (IsHostedAppPermission(permission_str)) { |
1737 mutable_static_data_->api_permissions.insert(permission_str); | 1718 api_permissions_.insert(permission_str); |
1738 continue; | 1719 continue; |
1739 } | 1720 } |
1740 } | 1721 } |
1741 | 1722 |
1742 // Otherwise, it's a host pattern permission. | 1723 // Otherwise, it's a host pattern permission. |
1743 URLPattern pattern = URLPattern(CanExecuteScriptEverywhere() ? | 1724 URLPattern pattern = URLPattern(CanExecuteScriptEverywhere() ? |
1744 URLPattern::SCHEME_ALL : | 1725 URLPattern::SCHEME_ALL : |
1745 (UserScript::kValidUserScriptSchemes | | 1726 (UserScript::kValidUserScriptSchemes | |
1746 URLPattern::SCHEME_CHROMEUI) & ~URLPattern::SCHEME_FILE); | 1727 URLPattern::SCHEME_CHROMEUI) & ~URLPattern::SCHEME_FILE); |
1747 | 1728 |
1748 if (URLPattern::PARSE_SUCCESS != pattern.Parse(permission_str)) { | 1729 if (URLPattern::PARSE_SUCCESS != pattern.Parse(permission_str)) { |
1749 *error = ExtensionErrorUtils::FormatErrorMessage( | 1730 *error = ExtensionErrorUtils::FormatErrorMessage( |
1750 errors::kInvalidPermission, base::IntToString(i)); | 1731 errors::kInvalidPermission, base::IntToString(i)); |
1751 return false; | 1732 return false; |
1752 } | 1733 } |
1753 | 1734 |
1754 if (!CanSpecifyHostPermission(pattern)) { | 1735 if (!CanSpecifyHostPermission(pattern)) { |
1755 *error = ExtensionErrorUtils::FormatErrorMessage( | 1736 *error = ExtensionErrorUtils::FormatErrorMessage( |
1756 errors::kInvalidPermissionScheme, base::IntToString(i)); | 1737 errors::kInvalidPermissionScheme, base::IntToString(i)); |
1757 return false; | 1738 return false; |
1758 } | 1739 } |
1759 | 1740 |
1760 // The path component is not used for host permissions, so we force it to | 1741 // The path component is not used for host permissions, so we force it to |
1761 // match all paths. | 1742 // match all paths. |
1762 pattern.set_path("/*"); | 1743 pattern.set_path("/*"); |
1763 | 1744 |
1764 mutable_static_data_->host_permissions.push_back(pattern); | 1745 host_permissions_.push_back(pattern); |
1765 } | 1746 } |
1766 } | 1747 } |
1767 | 1748 |
1768 if (source.HasKey(keys::kDefaultLocale)) { | 1749 if (source.HasKey(keys::kDefaultLocale)) { |
1769 if (!source.GetString(keys::kDefaultLocale, | 1750 if (!source.GetString(keys::kDefaultLocale, |
1770 &mutable_static_data_->default_locale) || | 1751 &default_locale_) || |
1771 mutable_static_data_->default_locale.empty()) { | 1752 default_locale_.empty()) { |
1772 *error = errors::kInvalidDefaultLocale; | 1753 *error = errors::kInvalidDefaultLocale; |
1773 return false; | 1754 return false; |
1774 } | 1755 } |
1775 } | 1756 } |
1776 | 1757 |
1777 // Chrome URL overrides (optional) | 1758 // Chrome URL overrides (optional) |
1778 if (source.HasKey(keys::kChromeURLOverrides)) { | 1759 if (source.HasKey(keys::kChromeURLOverrides)) { |
1779 DictionaryValue* overrides; | 1760 DictionaryValue* overrides; |
1780 if (!source.GetDictionary(keys::kChromeURLOverrides, &overrides)) { | 1761 if (!source.GetDictionary(keys::kChromeURLOverrides, &overrides)) { |
1781 *error = errors::kInvalidChromeURLOverrides; | 1762 *error = errors::kInvalidChromeURLOverrides; |
(...skipping 10 matching lines...) Expand all Loading... | |
1792 #if defined(TOUCH_UI) | 1773 #if defined(TOUCH_UI) |
1793 page != chrome::kChromeUIKeyboardHost && | 1774 page != chrome::kChromeUIKeyboardHost && |
1794 #endif | 1775 #endif |
1795 page != chrome::kChromeUIBookmarksHost && | 1776 page != chrome::kChromeUIBookmarksHost && |
1796 page != chrome::kChromeUIHistoryHost) || | 1777 page != chrome::kChromeUIHistoryHost) || |
1797 !overrides->GetStringWithoutPathExpansion(*iter, &val)) { | 1778 !overrides->GetStringWithoutPathExpansion(*iter, &val)) { |
1798 *error = errors::kInvalidChromeURLOverrides; | 1779 *error = errors::kInvalidChromeURLOverrides; |
1799 return false; | 1780 return false; |
1800 } | 1781 } |
1801 // Replace the entry with a fully qualified chrome-extension:// URL. | 1782 // Replace the entry with a fully qualified chrome-extension:// URL. |
1802 mutable_static_data_->chrome_url_overrides[page] = GetResourceURL(val); | 1783 chrome_url_overrides_[page] = GetResourceURL(val); |
1803 } | 1784 } |
1804 | 1785 |
1805 // An extension may override at most one page. | 1786 // An extension may override at most one page. |
1806 if (overrides->size() > 1) { | 1787 if (overrides->size() > 1) { |
1807 *error = errors::kMultipleOverrides; | 1788 *error = errors::kMultipleOverrides; |
1808 return false; | 1789 return false; |
1809 } | 1790 } |
1810 } | 1791 } |
1811 | 1792 |
1812 if (source.HasKey(keys::kOmniboxKeyword)) { | 1793 if (source.HasKey(keys::kOmniboxKeyword)) { |
1813 if (!source.GetString(keys::kOmniboxKeyword, | 1794 if (!source.GetString(keys::kOmniboxKeyword, |
1814 &mutable_static_data_->omnibox_keyword) || | 1795 &omnibox_keyword_) || |
1815 mutable_static_data_->omnibox_keyword.empty()) { | 1796 omnibox_keyword_.empty()) { |
1816 *error = errors::kInvalidOmniboxKeyword; | 1797 *error = errors::kInvalidOmniboxKeyword; |
1817 return false; | 1798 return false; |
1818 } | 1799 } |
1819 if (!HasApiPermission(Extension::kExperimentalPermission)) { | 1800 if (!HasApiPermission(Extension::kExperimentalPermission)) { |
1820 *error = errors::kOmniboxExperimental; | 1801 *error = errors::kOmniboxExperimental; |
1821 return false; | 1802 return false; |
1822 } | 1803 } |
1823 } | 1804 } |
1824 | 1805 |
1825 // Initialize devtools page url (optional). | 1806 // Initialize devtools page url (optional). |
1826 if (source.HasKey(keys::kDevToolsPage)) { | 1807 if (source.HasKey(keys::kDevToolsPage)) { |
1827 std::string devtools_str; | 1808 std::string devtools_str; |
1828 if (!source.GetString(keys::kDevToolsPage, &devtools_str)) { | 1809 if (!source.GetString(keys::kDevToolsPage, &devtools_str)) { |
1829 *error = errors::kInvalidDevToolsPage; | 1810 *error = errors::kInvalidDevToolsPage; |
1830 return false; | 1811 return false; |
1831 } | 1812 } |
1832 if (!HasApiPermission(Extension::kExperimentalPermission)) { | 1813 if (!HasApiPermission(Extension::kExperimentalPermission)) { |
1833 *error = errors::kDevToolsExperimental; | 1814 *error = errors::kDevToolsExperimental; |
1834 return false; | 1815 return false; |
1835 } | 1816 } |
1836 mutable_static_data_->devtools_url = GetResourceURL(devtools_str); | 1817 devtools_url_ = GetResourceURL(devtools_str); |
1837 } | 1818 } |
1838 | 1819 |
1839 // Initialize incognito behavior. Apps default to split mode, extensions | 1820 // Initialize incognito behavior. Apps default to split mode, extensions |
1840 // default to spanning. | 1821 // default to spanning. |
1841 mutable_static_data_->incognito_split_mode = is_app(); | 1822 incognito_split_mode_ = is_app(); |
1842 if (source.HasKey(keys::kIncognito)) { | 1823 if (source.HasKey(keys::kIncognito)) { |
1843 std::string value; | 1824 std::string value; |
1844 if (!source.GetString(keys::kIncognito, &value)) { | 1825 if (!source.GetString(keys::kIncognito, &value)) { |
1845 *error = errors::kInvalidIncognitoBehavior; | 1826 *error = errors::kInvalidIncognitoBehavior; |
1846 return false; | 1827 return false; |
1847 } | 1828 } |
1848 if (value == values::kIncognitoSpanning) { | 1829 if (value == values::kIncognitoSpanning) { |
1849 mutable_static_data_->incognito_split_mode = false; | 1830 incognito_split_mode_ = false; |
1850 } else if (value == values::kIncognitoSplit) { | 1831 } else if (value == values::kIncognitoSplit) { |
1851 mutable_static_data_->incognito_split_mode = true; | 1832 incognito_split_mode_ = true; |
1852 } else { | 1833 } else { |
1853 *error = errors::kInvalidIncognitoBehavior; | 1834 *error = errors::kInvalidIncognitoBehavior; |
1854 return false; | 1835 return false; |
1855 } | 1836 } |
1856 } | 1837 } |
1857 | 1838 |
1858 if (HasMultipleUISurfaces()) { | 1839 if (HasMultipleUISurfaces()) { |
1859 *error = errors::kOneUISurfaceOnly; | 1840 *error = errors::kOneUISurfaceOnly; |
1860 return false; | 1841 return false; |
1861 } | 1842 } |
1862 | 1843 |
1863 InitEffectiveHostPermissions(); | 1844 InitEffectiveHostPermissions(); |
1864 | 1845 |
1865 // Although |source| is passed in as a const, it's still possible to modify | 1846 // Although |source| is passed in as a const, it's still possible to modify |
1866 // it. This is dangerous since the utility process re-uses |source| after | 1847 // it. This is dangerous since the utility process re-uses |source| after |
1867 // it calls InitFromValue, passing it up to the browser process which calls | 1848 // it calls InitFromValue, passing it up to the browser process which calls |
1868 // InitFromValue again. As a result, we need to make sure that nobody | 1849 // InitFromValue again. As a result, we need to make sure that nobody |
1869 // accidentally modifies it. | 1850 // accidentally modifies it. |
1870 DCHECK(source.Equals(mutable_static_data_->manifest_value.get())); | 1851 DCHECK(source.Equals(manifest_value_.get())); |
1871 | |
1872 // Ensure we can't modify our static data anymore. | |
1873 mutable_static_data_ = NULL; | |
1874 | 1852 |
1875 return true; | 1853 return true; |
1876 } | 1854 } |
1877 | 1855 |
1878 // static | 1856 // static |
1879 std::string Extension::ChromeStoreLaunchURL() { | 1857 std::string Extension::ChromeStoreLaunchURL() { |
1880 std::string gallery_prefix = extension_urls::kGalleryBrowsePrefix; | 1858 std::string gallery_prefix = extension_urls::kGalleryBrowsePrefix; |
1881 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAppsGalleryURL)) | 1859 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAppsGalleryURL)) |
1882 gallery_prefix = CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 1860 gallery_prefix = CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
1883 switches::kAppsGalleryURL); | 1861 switches::kAppsGalleryURL); |
1884 if (EndsWith(gallery_prefix, "/", true)) | 1862 if (EndsWith(gallery_prefix, "/", true)) |
1885 gallery_prefix = gallery_prefix.substr(0, gallery_prefix.length() - 1); | 1863 gallery_prefix = gallery_prefix.substr(0, gallery_prefix.length() - 1); |
1886 return gallery_prefix; | 1864 return gallery_prefix; |
1887 } | 1865 } |
1888 | 1866 |
1889 GURL Extension::GetHomepageURL() const { | 1867 GURL Extension::GetHomepageURL() const { |
1890 if (static_data_->homepage_url.is_valid()) | 1868 if (homepage_url_.is_valid()) |
1891 return static_data_->homepage_url; | 1869 return homepage_url_; |
1892 | 1870 |
1893 if (update_url()!= GURL(extension_urls::kGalleryUpdateHttpsUrl) && | 1871 if (update_url()!= GURL(extension_urls::kGalleryUpdateHttpsUrl) && |
1894 update_url()!= GURL(extension_urls::kGalleryUpdateHttpUrl)) | 1872 update_url()!= GURL(extension_urls::kGalleryUpdateHttpUrl)) |
1895 return GURL(); | 1873 return GURL(); |
1896 | 1874 |
1897 // TODO(erikkay): This may not be entirely correct with the webstore. | 1875 // TODO(erikkay): This may not be entirely correct with the webstore. |
1898 // I think it will have a mixture of /extensions/detail and /webstore/detail | 1876 // I think it will have a mixture of /extensions/detail and /webstore/detail |
1899 // URLs. Perhaps they'll handle this nicely with redirects? | 1877 // URLs. Perhaps they'll handle this nicely with redirects? |
1900 GURL url(ChromeStoreLaunchURL() + std::string("/detail/") + id()); | 1878 GURL url(ChromeStoreLaunchURL() + std::string("/detail/") + id()); |
1901 return url; | 1879 return url; |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2106 host != host_permissions().end(); ++host) { | 2084 host != host_permissions().end(); ++host) { |
2107 if (host->MatchesUrl(url)) | 2085 if (host->MatchesUrl(url)) |
2108 return true; | 2086 return true; |
2109 } | 2087 } |
2110 return false; | 2088 return false; |
2111 } | 2089 } |
2112 | 2090 |
2113 void Extension::InitEffectiveHostPermissions() { | 2091 void Extension::InitEffectiveHostPermissions() { |
2114 for (URLPatternList::const_iterator host = host_permissions().begin(); | 2092 for (URLPatternList::const_iterator host = host_permissions().begin(); |
2115 host != host_permissions().end(); ++host) | 2093 host != host_permissions().end(); ++host) |
2116 mutable_static_data_->effective_host_permissions.AddPattern(*host); | 2094 effective_host_permissions_.AddPattern(*host); |
2117 | 2095 |
2118 for (UserScriptList::const_iterator content_script = | 2096 for (UserScriptList::const_iterator content_script = |
2119 content_scripts().begin(); | 2097 content_scripts().begin(); |
2120 content_script != content_scripts().end(); ++content_script) { | 2098 content_script != content_scripts().end(); ++content_script) { |
2121 UserScript::PatternList::const_iterator pattern = | 2099 UserScript::PatternList::const_iterator pattern = |
2122 content_script->url_patterns().begin(); | 2100 content_script->url_patterns().begin(); |
2123 for (; pattern != content_script->url_patterns().end(); ++pattern) | 2101 for (; pattern != content_script->url_patterns().end(); ++pattern) |
2124 mutable_static_data_->effective_host_permissions.AddPattern(*pattern); | 2102 effective_host_permissions_.AddPattern(*pattern); |
2125 } | 2103 } |
2126 } | 2104 } |
2127 | 2105 |
2128 bool Extension::HasMultipleUISurfaces() const { | 2106 bool Extension::HasMultipleUISurfaces() const { |
2129 int num_surfaces = 0; | 2107 int num_surfaces = 0; |
2130 | 2108 |
2131 if (page_action()) | 2109 if (page_action()) |
2132 ++num_surfaces; | 2110 ++num_surfaces; |
2133 | 2111 |
2134 if (browser_action()) | 2112 if (browser_action()) |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2241 if (id() == *it) { | 2219 if (id() == *it) { |
2242 return true; | 2220 return true; |
2243 } | 2221 } |
2244 } | 2222 } |
2245 | 2223 |
2246 return false; | 2224 return false; |
2247 } | 2225 } |
2248 | 2226 |
2249 Extension::RuntimeData* Extension::GetRuntimeData() const { | 2227 Extension::RuntimeData* Extension::GetRuntimeData() const { |
2250 // TODO(mpcomplete): it would be nice if I could verify we were on the UI | 2228 // TODO(mpcomplete): it would be nice if I could verify we were on the UI |
2251 // thread, but we're in common and don't have access to BrowserThread. | 2229 // thread, but we're in common and don't have access to BrowserThread. |
Aaron Boodman
2010/10/28 00:15:10
I still think this is kinda wonky and should proba
| |
2252 return const_cast<Extension::RuntimeData*>(&runtime_data_); | 2230 return const_cast<Extension::RuntimeData*>(&runtime_data_); |
2253 } | 2231 } |
2254 | 2232 |
2255 ExtensionInfo::ExtensionInfo(const DictionaryValue* manifest, | 2233 ExtensionInfo::ExtensionInfo(const DictionaryValue* manifest, |
2256 const std::string& id, | 2234 const std::string& id, |
2257 const FilePath& path, | 2235 const FilePath& path, |
2258 Extension::Location location) | 2236 Extension::Location location) |
2259 : extension_id(id), | 2237 : extension_id(id), |
2260 extension_path(path), | 2238 extension_path(path), |
2261 extension_location(location) { | 2239 extension_location(location) { |
2262 if (manifest) | 2240 if (manifest) |
2263 extension_manifest.reset( | 2241 extension_manifest.reset( |
2264 static_cast<DictionaryValue*>(manifest->DeepCopy())); | 2242 static_cast<DictionaryValue*>(manifest->DeepCopy())); |
2265 } | 2243 } |
2266 | 2244 |
2267 ExtensionInfo::~ExtensionInfo() {} | 2245 ExtensionInfo::~ExtensionInfo() {} |
2268 | 2246 |
2269 UninstalledExtensionInfo::UninstalledExtensionInfo( | 2247 UninstalledExtensionInfo::UninstalledExtensionInfo( |
2270 const Extension& extension) | 2248 const Extension& extension) |
2271 : extension_id(extension.id()), | 2249 : extension_id(extension.id()), |
2272 extension_api_permissions(extension.api_permissions()), | 2250 extension_api_permissions(extension.api_permissions()), |
2273 is_theme(extension.is_theme()), | 2251 is_theme(extension.is_theme()), |
2274 is_app(extension.is_app()), | 2252 is_app(extension.is_app()), |
2275 converted_from_user_script(extension.converted_from_user_script()), | 2253 converted_from_user_script(extension.converted_from_user_script()), |
2276 update_url(extension.update_url()) {} | 2254 update_url(extension.update_url()) {} |
2277 | 2255 |
2278 UninstalledExtensionInfo::~UninstalledExtensionInfo() {} | 2256 UninstalledExtensionInfo::~UninstalledExtensionInfo() {} |
OLD | NEW |