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

Side by Side Diff: chrome/common/extensions/extension.cc

Issue 4200005: Part 4/4 of immutable Extension refactor: Kill Extension::StaticData and put (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 10 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « chrome/common/extensions/extension.h ('k') | chrome/common/extensions/extension_unittest.cc » ('j') | 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) 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
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
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
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
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
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
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
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
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
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
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
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() {}
OLDNEW
« no previous file with comments | « chrome/common/extensions/extension.h ('k') | chrome/common/extensions/extension_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698