Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/common/extensions/extension.h" | 5 #include "chrome/common/extensions/extension.h" |
| 6 | 6 |
| 7 #include <ostream> | 7 #include <ostream> |
| 8 | 8 |
| 9 #include "base/base64.h" | 9 #include "base/base64.h" |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| 11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
| 12 #include "base/file_path.h" | 12 #include "base/file_path.h" |
| 13 #include "base/file_util.h" | 13 #include "base/file_util.h" |
| 14 #include "base/i18n/rtl.h" | 14 #include "base/i18n/rtl.h" |
| 15 #include "base/logging.h" | 15 #include "base/logging.h" |
| 16 #include "base/memory/singleton.h" | 16 #include "base/memory/singleton.h" |
| 17 #include "base/stl_util.h" | 17 #include "base/stl_util.h" |
| 18 #include "base/string16.h" | 18 #include "base/string16.h" |
| 19 #include "base/string_number_conversions.h" | 19 #include "base/string_number_conversions.h" |
| 20 #include "base/string_piece.h" | 20 #include "base/string_piece.h" |
| 21 #include "base/string_util.h" | 21 #include "base/string_util.h" |
| 22 #include "base/stringprintf.h" | 22 #include "base/stringprintf.h" |
| 23 #include "base/utf_string_conversions.h" | 23 #include "base/utf_string_conversions.h" |
| 24 #include "base/values.h" | 24 #include "base/values.h" |
| 25 #include "base/version.h" | 25 #include "base/version.h" |
| 26 #include "chrome/common/chrome_constants.h" | 26 #include "chrome/common/chrome_constants.h" |
| 27 #include "chrome/common/chrome_switches.h" | 27 #include "chrome/common/chrome_switches.h" |
| 28 #include "chrome/common/chrome_version_info.h" | 28 #include "chrome/common/chrome_version_info.h" |
| 29 // TODO(rdevlin.cronin): Remove this once PageAction, BrowserAction, and | |
| 30 // SystemIndicator have been moved out of Extension. | |
| 31 #include "chrome/common/extensions/api/extension_action/action_handler_helpers.h " | |
| 32 #include "chrome/common/extensions/api/extension_action/action_info.h" | |
| 29 #include "chrome/common/extensions/csp_validator.h" | 33 #include "chrome/common/extensions/csp_validator.h" |
| 30 #include "chrome/common/extensions/extension_manifest_constants.h" | 34 #include "chrome/common/extensions/extension_manifest_constants.h" |
| 31 #include "chrome/common/extensions/extension_resource.h" | 35 #include "chrome/common/extensions/extension_resource.h" |
| 32 #include "chrome/common/extensions/feature_switch.h" | 36 #include "chrome/common/extensions/feature_switch.h" |
| 33 #include "chrome/common/extensions/features/base_feature_provider.h" | 37 #include "chrome/common/extensions/features/base_feature_provider.h" |
| 34 #include "chrome/common/extensions/features/feature.h" | 38 #include "chrome/common/extensions/features/feature.h" |
| 35 #include "chrome/common/extensions/file_browser_handler.h" | 39 #include "chrome/common/extensions/file_browser_handler.h" |
| 36 #include "chrome/common/extensions/manifest.h" | 40 #include "chrome/common/extensions/manifest.h" |
| 37 #include "chrome/common/extensions/manifest_handler.h" | 41 #include "chrome/common/extensions/manifest_handler.h" |
| 42 #include "chrome/common/extensions/manifest_handler_helpers.h" | |
| 38 #include "chrome/common/extensions/permissions/permission_set.h" | 43 #include "chrome/common/extensions/permissions/permission_set.h" |
| 39 #include "chrome/common/extensions/permissions/permissions_info.h" | 44 #include "chrome/common/extensions/permissions/permissions_info.h" |
| 40 #include "chrome/common/extensions/user_script.h" | 45 #include "chrome/common/extensions/user_script.h" |
| 41 #include "chrome/common/url_constants.h" | 46 #include "chrome/common/url_constants.h" |
| 42 #include "crypto/sha2.h" | 47 #include "crypto/sha2.h" |
| 43 #include "extensions/common/constants.h" | 48 #include "extensions/common/constants.h" |
| 44 #include "extensions/common/error_utils.h" | 49 #include "extensions/common/error_utils.h" |
| 45 #include "extensions/common/url_pattern_set.h" | 50 #include "extensions/common/url_pattern_set.h" |
| 46 #include "googleurl/src/url_util.h" | 51 #include "googleurl/src/url_util.h" |
| 47 #include "grit/chromium_strings.h" | 52 #include "grit/chromium_strings.h" |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 123 if (base::HexStringToInt(base::StringPiece(id->begin() + i, | 128 if (base::HexStringToInt(base::StringPiece(id->begin() + i, |
| 124 id->begin() + i + 1), | 129 id->begin() + i + 1), |
| 125 &val)) { | 130 &val)) { |
| 126 (*id)[i] = val + 'a'; | 131 (*id)[i] = val + 'a'; |
| 127 } else { | 132 } else { |
| 128 (*id)[i] = 'a'; | 133 (*id)[i] = 'a'; |
| 129 } | 134 } |
| 130 } | 135 } |
| 131 } | 136 } |
| 132 | 137 |
| 133 // Strips leading slashes from the file path. Returns true iff the final path is | |
| 134 // non empty. | |
| 135 bool NormalizeAndValidatePath(std::string* path) { | |
| 136 size_t first_non_slash = path->find_first_not_of('/'); | |
| 137 if (first_non_slash == std::string::npos) { | |
| 138 *path = ""; | |
| 139 return false; | |
| 140 } | |
| 141 | |
| 142 *path = path->substr(first_non_slash); | |
| 143 return true; | |
| 144 } | |
| 145 | |
| 146 // Loads icon paths defined in dictionary |icons_value| into ExtensionIconSet | |
| 147 // |icons|. |icons_value| is a dictionary value {icon size -> icon path}. Icons | |
| 148 // in |icons_value| whose size is not in |icon_sizes| will be ignored. | |
| 149 // Returns success. If load fails, |error| will be set. | |
| 150 bool LoadIconsFromDictionary(const DictionaryValue* icons_value, | |
| 151 const int* icon_sizes, | |
| 152 size_t num_icon_sizes, | |
| 153 ExtensionIconSet* icons, | |
| 154 string16* error) { | |
| 155 DCHECK(icons); | |
| 156 for (size_t i = 0; i < num_icon_sizes; ++i) { | |
| 157 std::string key = base::IntToString(icon_sizes[i]); | |
| 158 if (icons_value->HasKey(key)) { | |
| 159 std::string icon_path; | |
| 160 if (!icons_value->GetString(key, &icon_path)) { | |
| 161 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 162 errors::kInvalidIconPath, key); | |
| 163 return false; | |
| 164 } | |
| 165 | |
| 166 if (!NormalizeAndValidatePath(&icon_path)) { | |
| 167 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 168 errors::kInvalidIconPath, key); | |
| 169 return false; | |
| 170 } | |
| 171 | |
| 172 icons->Add(icon_sizes[i], icon_path); | |
| 173 } | |
| 174 } | |
| 175 return true; | |
| 176 } | |
| 177 | |
| 178 // A singleton object containing global data needed by the extension objects. | 138 // A singleton object containing global data needed by the extension objects. |
| 179 class ExtensionConfig { | 139 class ExtensionConfig { |
| 180 public: | 140 public: |
| 181 static ExtensionConfig* GetInstance() { | 141 static ExtensionConfig* GetInstance() { |
| 182 return Singleton<ExtensionConfig>::get(); | 142 return Singleton<ExtensionConfig>::get(); |
| 183 } | 143 } |
| 184 | 144 |
| 185 Extension::ScriptingWhitelist* whitelist() { return &scripting_whitelist_; } | 145 Extension::ScriptingWhitelist* whitelist() { return &scripting_whitelist_; } |
| 186 | 146 |
| 187 private: | 147 private: |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 301 if ((*i)->ManifestEntryForbidden()) { | 261 if ((*i)->ManifestEntryForbidden()) { |
| 302 *error = ErrorUtils::FormatErrorMessageUTF16( | 262 *error = ErrorUtils::FormatErrorMessageUTF16( |
| 303 errors::kPermissionNotAllowedInManifest, | 263 errors::kPermissionNotAllowedInManifest, |
| 304 (*i)->info()->name()); | 264 (*i)->info()->name()); |
| 305 return true; | 265 return true; |
| 306 } | 266 } |
| 307 } | 267 } |
| 308 return false; | 268 return false; |
| 309 } | 269 } |
| 310 | 270 |
| 271 // Helper method to load an ExtensionAction from the page_action or | |
| 272 // browser_action entries in the manifest. | |
|
Yoyo Zhou
2012/12/18 02:01:41
or system_indicator?
Devlin
2012/12/18 20:42:07
Cut-and-pasted comment corrected.
| |
| 273 // TODO(rdevlin.cronin): Remove this once PageAction, BrowserAction, and | |
| 274 // SystemIndicator have been moved out of Extension. | |
| 275 scoped_ptr<ActionInfo> LoadExtensionActionInfoHelper( | |
| 276 const Extension* extension, | |
| 277 const DictionaryValue* extension_action, | |
| 278 string16* error) { | |
| 279 return LoadActionInfo( | |
| 280 extension, extension_action, error); | |
| 281 } | |
| 282 | |
| 311 } // namespace | 283 } // namespace |
| 312 | 284 |
| 313 const FilePath::CharType Extension::kManifestFilename[] = | 285 const FilePath::CharType Extension::kManifestFilename[] = |
| 314 FILE_PATH_LITERAL("manifest.json"); | 286 FILE_PATH_LITERAL("manifest.json"); |
| 315 const FilePath::CharType Extension::kLocaleFolder[] = | 287 const FilePath::CharType Extension::kLocaleFolder[] = |
| 316 FILE_PATH_LITERAL("_locales"); | 288 FILE_PATH_LITERAL("_locales"); |
| 317 const FilePath::CharType Extension::kMessagesFilename[] = | 289 const FilePath::CharType Extension::kMessagesFilename[] = |
| 318 FILE_PATH_LITERAL("messages.json"); | 290 FILE_PATH_LITERAL("messages.json"); |
| 319 | 291 |
| 320 #if defined(OS_WIN) | 292 #if defined(OS_WIN) |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 352 } | 324 } |
| 353 | 325 |
| 354 Extension::InputComponentInfo::~InputComponentInfo() {} | 326 Extension::InputComponentInfo::~InputComponentInfo() {} |
| 355 | 327 |
| 356 Extension::TtsVoice::TtsVoice() {} | 328 Extension::TtsVoice::TtsVoice() {} |
| 357 Extension::TtsVoice::~TtsVoice() {} | 329 Extension::TtsVoice::~TtsVoice() {} |
| 358 | 330 |
| 359 Extension::OAuth2Info::OAuth2Info() {} | 331 Extension::OAuth2Info::OAuth2Info() {} |
| 360 Extension::OAuth2Info::~OAuth2Info() {} | 332 Extension::OAuth2Info::~OAuth2Info() {} |
| 361 | 333 |
| 362 Extension::ActionInfo::ActionInfo() {} | |
| 363 Extension::ActionInfo::~ActionInfo() {} | |
| 364 | |
| 365 Extension::FileHandlerInfo::FileHandlerInfo() {} | 334 Extension::FileHandlerInfo::FileHandlerInfo() {} |
| 366 Extension::FileHandlerInfo::~FileHandlerInfo() {} | 335 Extension::FileHandlerInfo::~FileHandlerInfo() {} |
| 367 | 336 |
| 368 // | 337 // |
| 369 // Extension | 338 // Extension |
| 370 // | 339 // |
| 371 | 340 |
| 372 bool Extension::InstallWarning::operator==(const InstallWarning& other) const { | 341 bool Extension::InstallWarning::operator==(const InstallWarning& other) const { |
| 373 return format == other.format && message == other.message; | 342 return format == other.format && message == other.message; |
| 374 } | 343 } |
| (...skipping 939 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1314 } | 1283 } |
| 1315 | 1284 |
| 1316 const std::string& Extension::id() const { | 1285 const std::string& Extension::id() const { |
| 1317 return manifest_->extension_id(); | 1286 return manifest_->extension_id(); |
| 1318 } | 1287 } |
| 1319 | 1288 |
| 1320 const std::string Extension::VersionString() const { | 1289 const std::string Extension::VersionString() const { |
| 1321 return version()->GetString(); | 1290 return version()->GetString(); |
| 1322 } | 1291 } |
| 1323 | 1292 |
| 1293 void Extension::AddInstallWarning(const InstallWarning& new_warning) { | |
| 1294 install_warnings_.push_back(new_warning); | |
| 1295 } | |
| 1296 | |
| 1324 void Extension::AddInstallWarnings( | 1297 void Extension::AddInstallWarnings( |
| 1325 const InstallWarningVector& new_warnings) { | 1298 const InstallWarningVector& new_warnings) { |
| 1326 install_warnings_.insert(install_warnings_.end(), | 1299 install_warnings_.insert(install_warnings_.end(), |
| 1327 new_warnings.begin(), new_warnings.end()); | 1300 new_warnings.begin(), new_warnings.end()); |
| 1328 } | 1301 } |
| 1329 | 1302 |
| 1330 bool Extension::is_platform_app() const { | 1303 bool Extension::is_platform_app() const { |
| 1331 return manifest_->is_platform_app(); | 1304 return manifest_->is_platform_app(); |
| 1332 } | 1305 } |
| 1333 | 1306 |
| (...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2030 | 2003 |
| 2031 bool Extension::LoadIcons(string16* error) { | 2004 bool Extension::LoadIcons(string16* error) { |
| 2032 if (!manifest_->HasKey(keys::kIcons)) | 2005 if (!manifest_->HasKey(keys::kIcons)) |
| 2033 return true; | 2006 return true; |
| 2034 DictionaryValue* icons_value = NULL; | 2007 DictionaryValue* icons_value = NULL; |
| 2035 if (!manifest_->GetDictionary(keys::kIcons, &icons_value)) { | 2008 if (!manifest_->GetDictionary(keys::kIcons, &icons_value)) { |
| 2036 *error = ASCIIToUTF16(errors::kInvalidIcons); | 2009 *error = ASCIIToUTF16(errors::kInvalidIcons); |
| 2037 return false; | 2010 return false; |
| 2038 } | 2011 } |
| 2039 | 2012 |
| 2040 return LoadIconsFromDictionary(icons_value, | 2013 return manifest_handler_helpers::LoadIconsFromDictionary( |
| 2041 extension_misc::kExtensionIconSizes, | 2014 icons_value, |
| 2042 extension_misc::kNumExtensionIconSizes, | 2015 extension_misc::kExtensionIconSizes, |
| 2043 &icons_, | 2016 extension_misc::kNumExtensionIconSizes, |
| 2044 error); | 2017 &icons_, |
| 2018 error); | |
| 2045 } | 2019 } |
| 2046 | 2020 |
| 2047 bool Extension::LoadCommands(string16* error) { | 2021 bool Extension::LoadCommands(string16* error) { |
| 2048 if (manifest_->HasKey(keys::kCommands)) { | 2022 if (manifest_->HasKey(keys::kCommands)) { |
| 2049 DictionaryValue* commands = NULL; | 2023 DictionaryValue* commands = NULL; |
| 2050 if (!manifest_->GetDictionary(keys::kCommands, &commands)) { | 2024 if (!manifest_->GetDictionary(keys::kCommands, &commands)) { |
| 2051 *error = ASCIIToUTF16(errors::kInvalidCommandsKey); | 2025 *error = ASCIIToUTF16(errors::kInvalidCommandsKey); |
| 2052 return false; | 2026 return false; |
| 2053 } | 2027 } |
| 2054 | 2028 |
| (...skipping 731 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2786 manifest_->GetBoolean(keys::kConvertedFromUserScript, | 2760 manifest_->GetBoolean(keys::kConvertedFromUserScript, |
| 2787 &converted_from_user_script_); | 2761 &converted_from_user_script_); |
| 2788 | 2762 |
| 2789 if (!LoadManifestHandlerFeatures(error) || | 2763 if (!LoadManifestHandlerFeatures(error) || |
| 2790 !LoadDevToolsPage(error) || | 2764 !LoadDevToolsPage(error) || |
| 2791 !LoadInputComponents(*api_permissions, error) || | 2765 !LoadInputComponents(*api_permissions, error) || |
| 2792 !LoadContentScripts(error) || | 2766 !LoadContentScripts(error) || |
| 2793 !LoadPageAction(error) || | 2767 !LoadPageAction(error) || |
| 2794 !LoadBrowserAction(error) || | 2768 !LoadBrowserAction(error) || |
| 2795 !LoadSystemIndicator(api_permissions, error) || | 2769 !LoadSystemIndicator(api_permissions, error) || |
| 2796 !LoadScriptBadge(error) || | |
| 2797 !LoadFileBrowserHandlers(error) || | 2770 !LoadFileBrowserHandlers(error) || |
| 2798 !LoadChromeURLOverrides(error) || | 2771 !LoadChromeURLOverrides(error) || |
| 2799 !LoadTextToSpeechVoices(error) || | 2772 !LoadTextToSpeechVoices(error) || |
| 2800 !LoadIncognitoMode(error) || | 2773 !LoadIncognitoMode(error) || |
| 2801 !LoadFileHandlers(error) || | 2774 !LoadFileHandlers(error) || |
| 2802 !LoadContentSecurityPolicy(error)) | 2775 !LoadContentSecurityPolicy(error)) |
| 2803 return false; | 2776 return false; |
| 2804 | 2777 |
| 2805 return true; | 2778 return true; |
| 2806 } | 2779 } |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3019 } else if (manifest_->HasKey(keys::kPageAction)) { | 2992 } else if (manifest_->HasKey(keys::kPageAction)) { |
| 3020 if (!manifest_->GetDictionary(keys::kPageAction, &page_action_value)) { | 2993 if (!manifest_->GetDictionary(keys::kPageAction, &page_action_value)) { |
| 3021 *error = ASCIIToUTF16(errors::kInvalidPageAction); | 2994 *error = ASCIIToUTF16(errors::kInvalidPageAction); |
| 3022 return false; | 2995 return false; |
| 3023 } | 2996 } |
| 3024 } | 2997 } |
| 3025 | 2998 |
| 3026 // If page_action_value is not NULL, then there was a valid page action. | 2999 // If page_action_value is not NULL, then there was a valid page action. |
| 3027 if (page_action_value) { | 3000 if (page_action_value) { |
| 3028 page_action_info_ = LoadExtensionActionInfoHelper( | 3001 page_action_info_ = LoadExtensionActionInfoHelper( |
| 3029 page_action_value, Extension::ActionInfo::TYPE_PAGE, error); | 3002 this, page_action_value, error); |
| 3030 if (!page_action_info_.get()) | 3003 if (!page_action_info_.get()) |
| 3031 return false; // Failed to parse page action definition. | 3004 return false; // Failed to parse page action definition. |
| 3032 } | 3005 } |
| 3033 | 3006 |
| 3034 return true; | 3007 return true; |
| 3035 } | 3008 } |
| 3036 | 3009 |
| 3037 bool Extension::LoadBrowserAction(string16* error) { | 3010 bool Extension::LoadBrowserAction(string16* error) { |
| 3038 if (!manifest_->HasKey(keys::kBrowserAction)) | 3011 if (!manifest_->HasKey(keys::kBrowserAction)) |
| 3039 return true; | 3012 return true; |
| 3040 DictionaryValue* browser_action_value = NULL; | 3013 DictionaryValue* browser_action_value = NULL; |
| 3041 if (!manifest_->GetDictionary(keys::kBrowserAction, &browser_action_value)) { | 3014 if (!manifest_->GetDictionary(keys::kBrowserAction, &browser_action_value)) { |
| 3042 *error = ASCIIToUTF16(errors::kInvalidBrowserAction); | 3015 *error = ASCIIToUTF16(errors::kInvalidBrowserAction); |
| 3043 return false; | 3016 return false; |
| 3044 } | 3017 } |
| 3045 | 3018 |
| 3046 browser_action_info_ = LoadExtensionActionInfoHelper( | 3019 browser_action_info_ = LoadExtensionActionInfoHelper( |
| 3047 browser_action_value, Extension::ActionInfo::TYPE_BROWSER, error); | 3020 this, browser_action_value, error); |
| 3048 if (!browser_action_info_.get()) | 3021 if (!browser_action_info_.get()) |
| 3049 return false; // Failed to parse browser action definition. | 3022 return false; // Failed to parse browser action definition. |
| 3050 return true; | 3023 return true; |
| 3051 } | 3024 } |
| 3052 | 3025 |
| 3053 bool Extension::LoadScriptBadge(string16* error) { | |
| 3054 if (manifest_->HasKey(keys::kScriptBadge)) { | |
| 3055 if (!FeatureSwitch::script_badges()->IsEnabled()) { | |
| 3056 // So as to not confuse developers if they specify a script badge section | |
| 3057 // in the manifest, show a warning if the script badge declaration isn't | |
| 3058 // going to have any effect. | |
| 3059 install_warnings_.push_back( | |
| 3060 InstallWarning(InstallWarning::FORMAT_TEXT, | |
| 3061 errors::kScriptBadgeRequiresFlag)); | |
| 3062 } | |
| 3063 | |
| 3064 DictionaryValue* script_badge_value = NULL; | |
| 3065 if (!manifest_->GetDictionary(keys::kScriptBadge, &script_badge_value)) { | |
| 3066 *error = ASCIIToUTF16(errors::kInvalidScriptBadge); | |
| 3067 return false; | |
| 3068 } | |
| 3069 | |
| 3070 script_badge_info_ = LoadExtensionActionInfoHelper( | |
| 3071 script_badge_value, Extension::ActionInfo::TYPE_SCRIPT_BADGE, error); | |
| 3072 if (!script_badge_info_.get()) | |
| 3073 return false; // Failed to parse script badge definition. | |
| 3074 } else { | |
|
Devlin
2012/12/17 20:14:53
Do we know yet how we want to handle circumstances
Yoyo Zhou
2012/12/18 02:01:41
This case is currently not yet handled in this CL,
Devlin
2012/12/18 20:42:07
PatchSet 1 did not handle that, correct. HasNoKey
| |
| 3075 script_badge_info_.reset(new ActionInfo()); | |
| 3076 } | |
| 3077 | |
| 3078 // Script badges always use their extension's title and icon so users can rely | |
| 3079 // on the visual appearance to know which extension is running. This isn't | |
| 3080 // bulletproof since an malicious extension could use a different 16x16 icon | |
| 3081 // that matches the icon of a trusted extension, and users wouldn't be warned | |
| 3082 // during installation. | |
| 3083 | |
| 3084 if (!script_badge_info_->default_title.empty()) { | |
| 3085 install_warnings_.push_back( | |
| 3086 InstallWarning(InstallWarning::FORMAT_TEXT, | |
| 3087 errors::kScriptBadgeTitleIgnored)); | |
| 3088 } | |
| 3089 script_badge_info_->default_title = name(); | |
| 3090 | |
| 3091 if (!script_badge_info_->default_icon.empty()) { | |
| 3092 install_warnings_.push_back( | |
| 3093 InstallWarning(InstallWarning::FORMAT_TEXT, | |
| 3094 errors::kScriptBadgeIconIgnored)); | |
| 3095 } | |
| 3096 | |
| 3097 script_badge_info_->default_icon.Clear(); | |
| 3098 for (size_t i = 0; i < extension_misc::kNumScriptBadgeIconSizes; i++) { | |
| 3099 std::string path = icons().Get(extension_misc::kScriptBadgeIconSizes[i], | |
| 3100 ExtensionIconSet::MATCH_BIGGER); | |
| 3101 if (!path.empty()) | |
| 3102 script_badge_info_->default_icon.Add( | |
| 3103 extension_misc::kScriptBadgeIconSizes[i], path); | |
| 3104 } | |
| 3105 | |
| 3106 return true; | |
| 3107 } | |
| 3108 | |
| 3109 bool Extension::LoadSystemIndicator(APIPermissionSet* api_permissions, | 3026 bool Extension::LoadSystemIndicator(APIPermissionSet* api_permissions, |
| 3110 string16* error) { | 3027 string16* error) { |
| 3111 if (!manifest_->HasKey(keys::kSystemIndicator)) { | 3028 if (!manifest_->HasKey(keys::kSystemIndicator)) { |
| 3112 // There was no manifest entry for the system indicator. | 3029 // There was no manifest entry for the system indicator. |
| 3113 return true; | 3030 return true; |
| 3114 } | 3031 } |
| 3115 | 3032 |
| 3116 DictionaryValue* system_indicator_value = NULL; | 3033 DictionaryValue* system_indicator_value = NULL; |
| 3117 if (!manifest_->GetDictionary(keys::kSystemIndicator, | 3034 if (!manifest_->GetDictionary(keys::kSystemIndicator, |
| 3118 &system_indicator_value)) { | 3035 &system_indicator_value)) { |
| 3119 *error = ASCIIToUTF16(errors::kInvalidSystemIndicator); | 3036 *error = ASCIIToUTF16(errors::kInvalidSystemIndicator); |
| 3120 return false; | 3037 return false; |
| 3121 } | 3038 } |
| 3122 | 3039 |
| 3123 system_indicator_info_ = LoadExtensionActionInfoHelper( | 3040 system_indicator_info_ = LoadExtensionActionInfoHelper( |
| 3124 system_indicator_value, | 3041 this, system_indicator_value, error); |
| 3125 Extension::ActionInfo::TYPE_SYSTEM_INDICATOR, | |
| 3126 error); | |
| 3127 | 3042 |
| 3128 if (!system_indicator_info_.get()) { | 3043 if (!system_indicator_info_.get()) { |
| 3129 return false; | 3044 return false; |
| 3130 } | 3045 } |
| 3131 | 3046 |
| 3132 // Because the manifest was successfully parsed, auto-grant the permission. | 3047 // Because the manifest was successfully parsed, auto-grant the permission. |
| 3133 // TODO(dewittj) Add this for all extension action APIs. | 3048 // TODO(dewittj) Add this for all extension action APIs. |
| 3134 api_permissions->insert(APIPermission::kSystemIndicator); | 3049 api_permissions->insert(APIPermission::kSystemIndicator); |
| 3135 | 3050 |
| 3136 return true; | 3051 return true; |
| (...skipping 736 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3873 base::IntToString(i)); | 3788 base::IntToString(i)); |
| 3874 return false; | 3789 return false; |
| 3875 } | 3790 } |
| 3876 | 3791 |
| 3877 (instance->*add_method)(glob); | 3792 (instance->*add_method)(glob); |
| 3878 } | 3793 } |
| 3879 | 3794 |
| 3880 return true; | 3795 return true; |
| 3881 } | 3796 } |
| 3882 | 3797 |
| 3883 scoped_ptr<Extension::ActionInfo> Extension::LoadExtensionActionInfoHelper( | |
| 3884 const DictionaryValue* extension_action, | |
| 3885 ActionInfo::Type action_type, | |
| 3886 string16* error) { | |
| 3887 scoped_ptr<ActionInfo> result(new ActionInfo()); | |
| 3888 | |
| 3889 if (manifest_version_ == 1) { | |
| 3890 // kPageActionIcons is obsolete, and used by very few extensions. Continue | |
| 3891 // loading it, but only take the first icon as the default_icon path. | |
| 3892 const ListValue* icons = NULL; | |
| 3893 if (extension_action->HasKey(keys::kPageActionIcons) && | |
| 3894 extension_action->GetList(keys::kPageActionIcons, &icons)) { | |
| 3895 for (ListValue::const_iterator iter = icons->begin(); | |
| 3896 iter != icons->end(); ++iter) { | |
| 3897 std::string path; | |
| 3898 if (!(*iter)->GetAsString(&path) || !NormalizeAndValidatePath(&path)) { | |
| 3899 *error = ASCIIToUTF16(errors::kInvalidPageActionIconPath); | |
| 3900 return scoped_ptr<ActionInfo>(); | |
| 3901 } | |
| 3902 | |
| 3903 result->default_icon.Add(extension_misc::EXTENSION_ICON_ACTION, path); | |
| 3904 break; | |
| 3905 } | |
| 3906 } | |
| 3907 | |
| 3908 std::string id; | |
| 3909 if (extension_action->HasKey(keys::kPageActionId)) { | |
| 3910 if (!extension_action->GetString(keys::kPageActionId, &id)) { | |
| 3911 *error = ASCIIToUTF16(errors::kInvalidPageActionId); | |
| 3912 return scoped_ptr<ActionInfo>(); | |
| 3913 } | |
| 3914 result->id = id; | |
| 3915 } | |
| 3916 } | |
| 3917 | |
| 3918 // Read the page action |default_icon| (optional). | |
| 3919 // The |default_icon| value can be either dictionary {icon size -> icon path} | |
| 3920 // or non empty string value. | |
| 3921 if (extension_action->HasKey(keys::kPageActionDefaultIcon)) { | |
| 3922 const DictionaryValue* icons_value = NULL; | |
| 3923 std::string default_icon; | |
| 3924 if (extension_action->GetDictionary(keys::kPageActionDefaultIcon, | |
| 3925 &icons_value)) { | |
| 3926 if (!LoadIconsFromDictionary(icons_value, | |
| 3927 extension_misc::kExtensionActionIconSizes, | |
| 3928 extension_misc::kNumExtensionActionIconSizes, | |
| 3929 &result->default_icon, | |
| 3930 error)) { | |
| 3931 return scoped_ptr<ActionInfo>(); | |
| 3932 } | |
| 3933 } else if (extension_action->GetString(keys::kPageActionDefaultIcon, | |
| 3934 &default_icon) && | |
| 3935 NormalizeAndValidatePath(&default_icon)) { | |
| 3936 result->default_icon.Add(extension_misc::EXTENSION_ICON_ACTION, | |
| 3937 default_icon); | |
| 3938 } else { | |
| 3939 *error = ASCIIToUTF16(errors::kInvalidPageActionIconPath); | |
| 3940 return scoped_ptr<ActionInfo>(); | |
| 3941 } | |
| 3942 } | |
| 3943 | |
| 3944 // Read the page action title from |default_title| if present, |name| if not | |
| 3945 // (both optional). | |
| 3946 if (extension_action->HasKey(keys::kPageActionDefaultTitle)) { | |
| 3947 if (!extension_action->GetString(keys::kPageActionDefaultTitle, | |
| 3948 &result->default_title)) { | |
| 3949 *error = ASCIIToUTF16(errors::kInvalidPageActionDefaultTitle); | |
| 3950 return scoped_ptr<ActionInfo>(); | |
| 3951 } | |
| 3952 } else if (manifest_version_ == 1 && extension_action->HasKey(keys::kName)) { | |
| 3953 if (!extension_action->GetString(keys::kName, &result->default_title)) { | |
| 3954 *error = ASCIIToUTF16(errors::kInvalidPageActionName); | |
| 3955 return scoped_ptr<ActionInfo>(); | |
| 3956 } | |
| 3957 } | |
| 3958 | |
| 3959 // Read the action's |popup| (optional). | |
| 3960 const char* popup_key = NULL; | |
| 3961 if (extension_action->HasKey(keys::kPageActionDefaultPopup)) | |
| 3962 popup_key = keys::kPageActionDefaultPopup; | |
| 3963 | |
| 3964 if (manifest_version_ == 1 && | |
| 3965 extension_action->HasKey(keys::kPageActionPopup)) { | |
| 3966 if (popup_key) { | |
| 3967 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 3968 errors::kInvalidPageActionOldAndNewKeys, | |
| 3969 keys::kPageActionDefaultPopup, | |
| 3970 keys::kPageActionPopup); | |
| 3971 return scoped_ptr<ActionInfo>(); | |
| 3972 } | |
| 3973 popup_key = keys::kPageActionPopup; | |
| 3974 } | |
| 3975 | |
| 3976 if (popup_key) { | |
| 3977 const DictionaryValue* popup = NULL; | |
| 3978 std::string url_str; | |
| 3979 | |
| 3980 if (extension_action->GetString(popup_key, &url_str)) { | |
| 3981 // On success, |url_str| is set. Nothing else to do. | |
| 3982 } else if (manifest_version_ == 1 && | |
| 3983 extension_action->GetDictionary(popup_key, &popup)) { | |
| 3984 if (!popup->GetString(keys::kPageActionPopupPath, &url_str)) { | |
| 3985 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 3986 errors::kInvalidPageActionPopupPath, "<missing>"); | |
| 3987 return scoped_ptr<ActionInfo>(); | |
| 3988 } | |
| 3989 } else { | |
| 3990 *error = ASCIIToUTF16(errors::kInvalidPageActionPopup); | |
| 3991 return scoped_ptr<ActionInfo>(); | |
| 3992 } | |
| 3993 | |
| 3994 if (!url_str.empty()) { | |
| 3995 // An empty string is treated as having no popup. | |
| 3996 result->default_popup_url = GetResourceURL(url_str); | |
| 3997 if (!result->default_popup_url.is_valid()) { | |
| 3998 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 3999 errors::kInvalidPageActionPopupPath, url_str); | |
| 4000 return scoped_ptr<ActionInfo>(); | |
| 4001 } | |
| 4002 } else { | |
| 4003 DCHECK(result->default_popup_url.is_empty()) | |
| 4004 << "Shouldn't be possible for the popup to be set."; | |
| 4005 } | |
| 4006 } | |
| 4007 | |
| 4008 return result.Pass(); | |
| 4009 } | |
| 4010 | |
| 4011 bool Extension::LoadOAuth2Info(string16* error) { | 3798 bool Extension::LoadOAuth2Info(string16* error) { |
| 4012 if (!manifest_->HasKey(keys::kOAuth2)) | 3799 if (!manifest_->HasKey(keys::kOAuth2)) |
| 4013 return true; | 3800 return true; |
| 4014 | 3801 |
| 4015 if (!manifest_->GetString(keys::kOAuth2ClientId, &oauth2_info_.client_id) || | 3802 if (!manifest_->GetString(keys::kOAuth2ClientId, &oauth2_info_.client_id) || |
| 4016 oauth2_info_.client_id.empty()) { | 3803 oauth2_info_.client_id.empty()) { |
| 4017 *error = ASCIIToUTF16(errors::kInvalidOAuth2ClientId); | 3804 *error = ASCIIToUTF16(errors::kInvalidOAuth2ClientId); |
| 4018 return false; | 3805 return false; |
| 4019 } | 3806 } |
| 4020 | 3807 |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4220 | 4007 |
| 4221 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo( | 4008 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo( |
| 4222 const Extension* extension, | 4009 const Extension* extension, |
| 4223 const PermissionSet* permissions, | 4010 const PermissionSet* permissions, |
| 4224 Reason reason) | 4011 Reason reason) |
| 4225 : reason(reason), | 4012 : reason(reason), |
| 4226 extension(extension), | 4013 extension(extension), |
| 4227 permissions(permissions) {} | 4014 permissions(permissions) {} |
| 4228 | 4015 |
| 4229 } // namespace extensions | 4016 } // namespace extensions |
| OLD | NEW |