Index: chrome/common/extensions/extension.cc |
diff --git a/chrome/common/extensions/extension.cc b/chrome/common/extensions/extension.cc |
index a692e93a840d2be32adcf424965e17e78dc1dbc5..4da63b029c80c33ba3d2093aa45bae15b5a08531 100644 |
--- a/chrome/common/extensions/extension.cc |
+++ b/chrome/common/extensions/extension.cc |
@@ -26,6 +26,9 @@ |
#include "chrome/common/chrome_constants.h" |
#include "chrome/common/chrome_switches.h" |
#include "chrome/common/chrome_version_info.h" |
+// TODO(rdevlin.cronin): Remove this once PageAction, BrowserAction, and |
+// SystemIndicator have been moved out of Extension. |
+#include "chrome/common/extensions/api/extension_action/action_info.h" |
#include "chrome/common/extensions/csp_validator.h" |
#include "chrome/common/extensions/extension_manifest_constants.h" |
#include "chrome/common/extensions/extension_resource.h" |
@@ -34,6 +37,7 @@ |
#include "chrome/common/extensions/features/feature.h" |
#include "chrome/common/extensions/manifest.h" |
#include "chrome/common/extensions/manifest_handler.h" |
+#include "chrome/common/extensions/manifest_handler_helpers.h" |
#include "chrome/common/extensions/manifest_url_handler.h" |
#include "chrome/common/extensions/permissions/permission_set.h" |
#include "chrome/common/extensions/permissions/permissions_info.h" |
@@ -127,51 +131,6 @@ static void ConvertHexadecimalToIDAlphabet(std::string* id) { |
} |
} |
-// Strips leading slashes from the file path. Returns true iff the final path is |
-// non empty. |
-bool NormalizeAndValidatePath(std::string* path) { |
- size_t first_non_slash = path->find_first_not_of('/'); |
- if (first_non_slash == std::string::npos) { |
- *path = ""; |
- return false; |
- } |
- |
- *path = path->substr(first_non_slash); |
- return true; |
-} |
- |
-// Loads icon paths defined in dictionary |icons_value| into ExtensionIconSet |
-// |icons|. |icons_value| is a dictionary value {icon size -> icon path}. Icons |
-// in |icons_value| whose size is not in |icon_sizes| will be ignored. |
-// Returns success. If load fails, |error| will be set. |
-bool LoadIconsFromDictionary(const DictionaryValue* icons_value, |
- const int* icon_sizes, |
- size_t num_icon_sizes, |
- ExtensionIconSet* icons, |
- string16* error) { |
- DCHECK(icons); |
- for (size_t i = 0; i < num_icon_sizes; ++i) { |
- std::string key = base::IntToString(icon_sizes[i]); |
- if (icons_value->HasKey(key)) { |
- std::string icon_path; |
- if (!icons_value->GetString(key, &icon_path)) { |
- *error = ErrorUtils::FormatErrorMessageUTF16( |
- errors::kInvalidIconPath, key); |
- return false; |
- } |
- |
- if (!NormalizeAndValidatePath(&icon_path)) { |
- *error = ErrorUtils::FormatErrorMessageUTF16( |
- errors::kInvalidIconPath, key); |
- return false; |
- } |
- |
- icons->Add(icon_sizes[i], icon_path); |
- } |
- } |
- return true; |
-} |
- |
// A singleton object containing global data needed by the extension objects. |
class ExtensionConfig { |
public: |
@@ -305,6 +264,18 @@ bool ContainsManifestForbiddenPermission(const APIPermissionSet& apis, |
return false; |
} |
+// Helper method to load an ExtensionAction from the page_action, script_badge, |
+// browser_action, or system_indicator entries in the manifest. |
+// TODO(rdevlin.cronin): Remove this once PageAction, BrowserAction, and |
+// SystemIndicator have been moved out of Extension. |
+scoped_ptr<ActionInfo> LoadExtensionActionInfoHelper( |
+ const Extension* extension, |
+ const DictionaryValue* extension_action, |
+ string16* error) { |
+ return manifest_handler_helpers::LoadActionInfo( |
+ extension, extension_action, error); |
+} |
+ |
} // namespace |
const FilePath::CharType Extension::kManifestFilename[] = |
@@ -344,9 +315,6 @@ Extension::Requirements::~Requirements() {} |
Extension::OAuth2Info::OAuth2Info() {} |
Extension::OAuth2Info::~OAuth2Info() {} |
-Extension::ActionInfo::ActionInfo() {} |
-Extension::ActionInfo::~ActionInfo() {} |
- |
// |
// Extension |
// |
@@ -1295,6 +1263,10 @@ const std::string Extension::VersionString() const { |
return version()->GetString(); |
} |
+void Extension::AddInstallWarning(const InstallWarning& new_warning) { |
+ install_warnings_.push_back(new_warning); |
+} |
+ |
void Extension::AddInstallWarnings( |
const InstallWarningVector& new_warnings) { |
install_warnings_.insert(install_warnings_.end(), |
@@ -2027,11 +1999,12 @@ bool Extension::LoadIcons(string16* error) { |
return false; |
} |
- return LoadIconsFromDictionary(icons_value, |
- extension_misc::kExtensionIconSizes, |
- extension_misc::kNumExtensionIconSizes, |
- &icons_, |
- error); |
+ return manifest_handler_helpers::LoadIconsFromDictionary( |
+ icons_value, |
+ extension_misc::kExtensionIconSizes, |
+ extension_misc::kNumExtensionIconSizes, |
+ &icons_, |
+ error); |
} |
bool Extension::LoadCommands(string16* error) { |
@@ -2518,7 +2491,6 @@ bool Extension::LoadExtensionFeatures(APIPermissionSet* api_permissions, |
!LoadPageAction(error) || |
!LoadBrowserAction(error) || |
!LoadSystemIndicator(api_permissions, error) || |
- !LoadScriptBadge(error) || |
!LoadIncognitoMode(error) || |
!LoadContentSecurityPolicy(error)) |
return false; |
@@ -2604,7 +2576,7 @@ bool Extension::LoadPageAction(string16* error) { |
// If page_action_value is not NULL, then there was a valid page action. |
if (page_action_value) { |
page_action_info_ = LoadExtensionActionInfoHelper( |
- page_action_value, Extension::ActionInfo::TYPE_PAGE, error); |
+ this, page_action_value, error); |
if (!page_action_info_.get()) |
return false; // Failed to parse page action definition. |
} |
@@ -2622,68 +2594,12 @@ bool Extension::LoadBrowserAction(string16* error) { |
} |
browser_action_info_ = LoadExtensionActionInfoHelper( |
- browser_action_value, Extension::ActionInfo::TYPE_BROWSER, error); |
+ this, browser_action_value, error); |
if (!browser_action_info_.get()) |
return false; // Failed to parse browser action definition. |
return true; |
} |
-bool Extension::LoadScriptBadge(string16* error) { |
- if (manifest_->HasKey(keys::kScriptBadge)) { |
- if (!FeatureSwitch::script_badges()->IsEnabled()) { |
- // So as to not confuse developers if they specify a script badge section |
- // in the manifest, show a warning if the script badge declaration isn't |
- // going to have any effect. |
- install_warnings_.push_back( |
- InstallWarning(InstallWarning::FORMAT_TEXT, |
- errors::kScriptBadgeRequiresFlag)); |
- } |
- |
- DictionaryValue* script_badge_value = NULL; |
- if (!manifest_->GetDictionary(keys::kScriptBadge, &script_badge_value)) { |
- *error = ASCIIToUTF16(errors::kInvalidScriptBadge); |
- return false; |
- } |
- |
- script_badge_info_ = LoadExtensionActionInfoHelper( |
- script_badge_value, Extension::ActionInfo::TYPE_SCRIPT_BADGE, error); |
- if (!script_badge_info_.get()) |
- return false; // Failed to parse script badge definition. |
- } else { |
- script_badge_info_.reset(new ActionInfo()); |
- } |
- |
- // Script badges always use their extension's title and icon so users can rely |
- // on the visual appearance to know which extension is running. This isn't |
- // bulletproof since an malicious extension could use a different 16x16 icon |
- // that matches the icon of a trusted extension, and users wouldn't be warned |
- // during installation. |
- |
- if (!script_badge_info_->default_title.empty()) { |
- install_warnings_.push_back( |
- InstallWarning(InstallWarning::FORMAT_TEXT, |
- errors::kScriptBadgeTitleIgnored)); |
- } |
- script_badge_info_->default_title = name(); |
- |
- if (!script_badge_info_->default_icon.empty()) { |
- install_warnings_.push_back( |
- InstallWarning(InstallWarning::FORMAT_TEXT, |
- errors::kScriptBadgeIconIgnored)); |
- } |
- |
- script_badge_info_->default_icon.Clear(); |
- for (size_t i = 0; i < extension_misc::kNumScriptBadgeIconSizes; i++) { |
- std::string path = icons().Get(extension_misc::kScriptBadgeIconSizes[i], |
- ExtensionIconSet::MATCH_BIGGER); |
- if (!path.empty()) |
- script_badge_info_->default_icon.Add( |
- extension_misc::kScriptBadgeIconSizes[i], path); |
- } |
- |
- return true; |
-} |
- |
bool Extension::LoadSystemIndicator(APIPermissionSet* api_permissions, |
string16* error) { |
if (!manifest_->HasKey(keys::kSystemIndicator)) { |
@@ -2699,9 +2615,7 @@ bool Extension::LoadSystemIndicator(APIPermissionSet* api_permissions, |
} |
system_indicator_info_ = LoadExtensionActionInfoHelper( |
- system_indicator_value, |
- Extension::ActionInfo::TYPE_SYSTEM_INDICATOR, |
- error); |
+ this, system_indicator_value, error); |
if (!system_indicator_info_.get()) { |
return false; |
@@ -3140,134 +3054,6 @@ bool Extension::LoadGlobsHelper( |
return true; |
} |
-scoped_ptr<Extension::ActionInfo> Extension::LoadExtensionActionInfoHelper( |
- const DictionaryValue* extension_action, |
- ActionInfo::Type action_type, |
- string16* error) { |
- scoped_ptr<ActionInfo> result(new ActionInfo()); |
- |
- if (manifest_version_ == 1) { |
- // kPageActionIcons is obsolete, and used by very few extensions. Continue |
- // loading it, but only take the first icon as the default_icon path. |
- const ListValue* icons = NULL; |
- if (extension_action->HasKey(keys::kPageActionIcons) && |
- extension_action->GetList(keys::kPageActionIcons, &icons)) { |
- for (ListValue::const_iterator iter = icons->begin(); |
- iter != icons->end(); ++iter) { |
- std::string path; |
- if (!(*iter)->GetAsString(&path) || !NormalizeAndValidatePath(&path)) { |
- *error = ASCIIToUTF16(errors::kInvalidPageActionIconPath); |
- return scoped_ptr<ActionInfo>(); |
- } |
- |
- result->default_icon.Add(extension_misc::EXTENSION_ICON_ACTION, path); |
- break; |
- } |
- } |
- |
- std::string id; |
- if (extension_action->HasKey(keys::kPageActionId)) { |
- if (!extension_action->GetString(keys::kPageActionId, &id)) { |
- *error = ASCIIToUTF16(errors::kInvalidPageActionId); |
- return scoped_ptr<ActionInfo>(); |
- } |
- result->id = id; |
- } |
- } |
- |
- // Read the page action |default_icon| (optional). |
- // The |default_icon| value can be either dictionary {icon size -> icon path} |
- // or non empty string value. |
- if (extension_action->HasKey(keys::kPageActionDefaultIcon)) { |
- const DictionaryValue* icons_value = NULL; |
- std::string default_icon; |
- if (extension_action->GetDictionary(keys::kPageActionDefaultIcon, |
- &icons_value)) { |
- if (!LoadIconsFromDictionary(icons_value, |
- extension_misc::kExtensionActionIconSizes, |
- extension_misc::kNumExtensionActionIconSizes, |
- &result->default_icon, |
- error)) { |
- return scoped_ptr<ActionInfo>(); |
- } |
- } else if (extension_action->GetString(keys::kPageActionDefaultIcon, |
- &default_icon) && |
- NormalizeAndValidatePath(&default_icon)) { |
- result->default_icon.Add(extension_misc::EXTENSION_ICON_ACTION, |
- default_icon); |
- } else { |
- *error = ASCIIToUTF16(errors::kInvalidPageActionIconPath); |
- return scoped_ptr<ActionInfo>(); |
- } |
- } |
- |
- // Read the page action title from |default_title| if present, |name| if not |
- // (both optional). |
- if (extension_action->HasKey(keys::kPageActionDefaultTitle)) { |
- if (!extension_action->GetString(keys::kPageActionDefaultTitle, |
- &result->default_title)) { |
- *error = ASCIIToUTF16(errors::kInvalidPageActionDefaultTitle); |
- return scoped_ptr<ActionInfo>(); |
- } |
- } else if (manifest_version_ == 1 && extension_action->HasKey(keys::kName)) { |
- if (!extension_action->GetString(keys::kName, &result->default_title)) { |
- *error = ASCIIToUTF16(errors::kInvalidPageActionName); |
- return scoped_ptr<ActionInfo>(); |
- } |
- } |
- |
- // Read the action's |popup| (optional). |
- const char* popup_key = NULL; |
- if (extension_action->HasKey(keys::kPageActionDefaultPopup)) |
- popup_key = keys::kPageActionDefaultPopup; |
- |
- if (manifest_version_ == 1 && |
- extension_action->HasKey(keys::kPageActionPopup)) { |
- if (popup_key) { |
- *error = ErrorUtils::FormatErrorMessageUTF16( |
- errors::kInvalidPageActionOldAndNewKeys, |
- keys::kPageActionDefaultPopup, |
- keys::kPageActionPopup); |
- return scoped_ptr<ActionInfo>(); |
- } |
- popup_key = keys::kPageActionPopup; |
- } |
- |
- if (popup_key) { |
- const DictionaryValue* popup = NULL; |
- std::string url_str; |
- |
- if (extension_action->GetString(popup_key, &url_str)) { |
- // On success, |url_str| is set. Nothing else to do. |
- } else if (manifest_version_ == 1 && |
- extension_action->GetDictionary(popup_key, &popup)) { |
- if (!popup->GetString(keys::kPageActionPopupPath, &url_str)) { |
- *error = ErrorUtils::FormatErrorMessageUTF16( |
- errors::kInvalidPageActionPopupPath, "<missing>"); |
- return scoped_ptr<ActionInfo>(); |
- } |
- } else { |
- *error = ASCIIToUTF16(errors::kInvalidPageActionPopup); |
- return scoped_ptr<ActionInfo>(); |
- } |
- |
- if (!url_str.empty()) { |
- // An empty string is treated as having no popup. |
- result->default_popup_url = GetResourceURL(url_str); |
- if (!result->default_popup_url.is_valid()) { |
- *error = ErrorUtils::FormatErrorMessageUTF16( |
- errors::kInvalidPageActionPopupPath, url_str); |
- return scoped_ptr<ActionInfo>(); |
- } |
- } else { |
- DCHECK(result->default_popup_url.is_empty()) |
- << "Shouldn't be possible for the popup to be set."; |
- } |
- } |
- |
- return result.Pass(); |
-} |
- |
bool Extension::LoadOAuth2Info(string16* error) { |
if (!manifest_->HasKey(keys::kOAuth2)) |
return true; |