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 |