OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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_info.h" |
29 #include "chrome/common/extensions/csp_validator.h" | 32 #include "chrome/common/extensions/csp_validator.h" |
30 #include "chrome/common/extensions/extension_manifest_constants.h" | 33 #include "chrome/common/extensions/extension_manifest_constants.h" |
31 #include "chrome/common/extensions/extension_resource.h" | 34 #include "chrome/common/extensions/extension_resource.h" |
32 #include "chrome/common/extensions/feature_switch.h" | 35 #include "chrome/common/extensions/feature_switch.h" |
33 #include "chrome/common/extensions/features/base_feature_provider.h" | 36 #include "chrome/common/extensions/features/base_feature_provider.h" |
34 #include "chrome/common/extensions/features/feature.h" | 37 #include "chrome/common/extensions/features/feature.h" |
35 #include "chrome/common/extensions/manifest.h" | 38 #include "chrome/common/extensions/manifest.h" |
36 #include "chrome/common/extensions/manifest_handler.h" | 39 #include "chrome/common/extensions/manifest_handler.h" |
| 40 #include "chrome/common/extensions/manifest_handler_helpers.h" |
37 #include "chrome/common/extensions/manifest_url_handler.h" | 41 #include "chrome/common/extensions/manifest_url_handler.h" |
38 #include "chrome/common/extensions/permissions/permission_set.h" | 42 #include "chrome/common/extensions/permissions/permission_set.h" |
39 #include "chrome/common/extensions/permissions/permissions_info.h" | 43 #include "chrome/common/extensions/permissions/permissions_info.h" |
40 #include "chrome/common/extensions/user_script.h" | 44 #include "chrome/common/extensions/user_script.h" |
41 #include "chrome/common/url_constants.h" | 45 #include "chrome/common/url_constants.h" |
42 #include "crypto/sha2.h" | 46 #include "crypto/sha2.h" |
43 #include "extensions/common/constants.h" | 47 #include "extensions/common/constants.h" |
44 #include "extensions/common/error_utils.h" | 48 #include "extensions/common/error_utils.h" |
45 #include "extensions/common/url_pattern_set.h" | 49 #include "extensions/common/url_pattern_set.h" |
46 #include "googleurl/src/url_util.h" | 50 #include "googleurl/src/url_util.h" |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 if (base::HexStringToInt(base::StringPiece(id->begin() + i, | 124 if (base::HexStringToInt(base::StringPiece(id->begin() + i, |
121 id->begin() + i + 1), | 125 id->begin() + i + 1), |
122 &val)) { | 126 &val)) { |
123 (*id)[i] = val + 'a'; | 127 (*id)[i] = val + 'a'; |
124 } else { | 128 } else { |
125 (*id)[i] = 'a'; | 129 (*id)[i] = 'a'; |
126 } | 130 } |
127 } | 131 } |
128 } | 132 } |
129 | 133 |
130 // Strips leading slashes from the file path. Returns true iff the final path is | |
131 // non empty. | |
132 bool NormalizeAndValidatePath(std::string* path) { | |
133 size_t first_non_slash = path->find_first_not_of('/'); | |
134 if (first_non_slash == std::string::npos) { | |
135 *path = ""; | |
136 return false; | |
137 } | |
138 | |
139 *path = path->substr(first_non_slash); | |
140 return true; | |
141 } | |
142 | |
143 // Loads icon paths defined in dictionary |icons_value| into ExtensionIconSet | |
144 // |icons|. |icons_value| is a dictionary value {icon size -> icon path}. Icons | |
145 // in |icons_value| whose size is not in |icon_sizes| will be ignored. | |
146 // Returns success. If load fails, |error| will be set. | |
147 bool LoadIconsFromDictionary(const DictionaryValue* icons_value, | |
148 const int* icon_sizes, | |
149 size_t num_icon_sizes, | |
150 ExtensionIconSet* icons, | |
151 string16* error) { | |
152 DCHECK(icons); | |
153 for (size_t i = 0; i < num_icon_sizes; ++i) { | |
154 std::string key = base::IntToString(icon_sizes[i]); | |
155 if (icons_value->HasKey(key)) { | |
156 std::string icon_path; | |
157 if (!icons_value->GetString(key, &icon_path)) { | |
158 *error = ErrorUtils::FormatErrorMessageUTF16( | |
159 errors::kInvalidIconPath, key); | |
160 return false; | |
161 } | |
162 | |
163 if (!NormalizeAndValidatePath(&icon_path)) { | |
164 *error = ErrorUtils::FormatErrorMessageUTF16( | |
165 errors::kInvalidIconPath, key); | |
166 return false; | |
167 } | |
168 | |
169 icons->Add(icon_sizes[i], icon_path); | |
170 } | |
171 } | |
172 return true; | |
173 } | |
174 | |
175 // A singleton object containing global data needed by the extension objects. | 134 // A singleton object containing global data needed by the extension objects. |
176 class ExtensionConfig { | 135 class ExtensionConfig { |
177 public: | 136 public: |
178 static ExtensionConfig* GetInstance() { | 137 static ExtensionConfig* GetInstance() { |
179 return Singleton<ExtensionConfig>::get(); | 138 return Singleton<ExtensionConfig>::get(); |
180 } | 139 } |
181 | 140 |
182 Extension::ScriptingWhitelist* whitelist() { return &scripting_whitelist_; } | 141 Extension::ScriptingWhitelist* whitelist() { return &scripting_whitelist_; } |
183 | 142 |
184 private: | 143 private: |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
298 if ((*i)->ManifestEntryForbidden()) { | 257 if ((*i)->ManifestEntryForbidden()) { |
299 *error = ErrorUtils::FormatErrorMessageUTF16( | 258 *error = ErrorUtils::FormatErrorMessageUTF16( |
300 errors::kPermissionNotAllowedInManifest, | 259 errors::kPermissionNotAllowedInManifest, |
301 (*i)->info()->name()); | 260 (*i)->info()->name()); |
302 return true; | 261 return true; |
303 } | 262 } |
304 } | 263 } |
305 return false; | 264 return false; |
306 } | 265 } |
307 | 266 |
| 267 // Helper method to load an ExtensionAction from the page_action, script_badge, |
| 268 // browser_action, or system_indicator entries in the manifest. |
| 269 // TODO(rdevlin.cronin): Remove this once PageAction, BrowserAction, and |
| 270 // SystemIndicator have been moved out of Extension. |
| 271 scoped_ptr<ActionInfo> LoadExtensionActionInfoHelper( |
| 272 const Extension* extension, |
| 273 const DictionaryValue* extension_action, |
| 274 string16* error) { |
| 275 return manifest_handler_helpers::LoadActionInfo( |
| 276 extension, extension_action, error); |
| 277 } |
| 278 |
308 } // namespace | 279 } // namespace |
309 | 280 |
310 const FilePath::CharType Extension::kManifestFilename[] = | 281 const FilePath::CharType Extension::kManifestFilename[] = |
311 FILE_PATH_LITERAL("manifest.json"); | 282 FILE_PATH_LITERAL("manifest.json"); |
312 const FilePath::CharType Extension::kLocaleFolder[] = | 283 const FilePath::CharType Extension::kLocaleFolder[] = |
313 FILE_PATH_LITERAL("_locales"); | 284 FILE_PATH_LITERAL("_locales"); |
314 const FilePath::CharType Extension::kMessagesFilename[] = | 285 const FilePath::CharType Extension::kMessagesFilename[] = |
315 FILE_PATH_LITERAL("messages.json"); | 286 FILE_PATH_LITERAL("messages.json"); |
316 | 287 |
317 #if defined(OS_WIN) | 288 #if defined(OS_WIN) |
(...skipping 19 matching lines...) Expand all Loading... |
337 : webgl(false), | 308 : webgl(false), |
338 css3d(false), | 309 css3d(false), |
339 npapi(false) { | 310 npapi(false) { |
340 } | 311 } |
341 | 312 |
342 Extension::Requirements::~Requirements() {} | 313 Extension::Requirements::~Requirements() {} |
343 | 314 |
344 Extension::OAuth2Info::OAuth2Info() {} | 315 Extension::OAuth2Info::OAuth2Info() {} |
345 Extension::OAuth2Info::~OAuth2Info() {} | 316 Extension::OAuth2Info::~OAuth2Info() {} |
346 | 317 |
347 Extension::ActionInfo::ActionInfo() {} | |
348 Extension::ActionInfo::~ActionInfo() {} | |
349 | |
350 // | 318 // |
351 // Extension | 319 // Extension |
352 // | 320 // |
353 | 321 |
354 bool Extension::InstallWarning::operator==(const InstallWarning& other) const { | 322 bool Extension::InstallWarning::operator==(const InstallWarning& other) const { |
355 return format == other.format && message == other.message; | 323 return format == other.format && message == other.message; |
356 } | 324 } |
357 | 325 |
358 // static | 326 // static |
359 scoped_refptr<Extension> Extension::Create(const FilePath& path, | 327 scoped_refptr<Extension> Extension::Create(const FilePath& path, |
(...skipping 928 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1288 } | 1256 } |
1289 | 1257 |
1290 const std::string& Extension::id() const { | 1258 const std::string& Extension::id() const { |
1291 return manifest_->extension_id(); | 1259 return manifest_->extension_id(); |
1292 } | 1260 } |
1293 | 1261 |
1294 const std::string Extension::VersionString() const { | 1262 const std::string Extension::VersionString() const { |
1295 return version()->GetString(); | 1263 return version()->GetString(); |
1296 } | 1264 } |
1297 | 1265 |
| 1266 void Extension::AddInstallWarning(const InstallWarning& new_warning) { |
| 1267 install_warnings_.push_back(new_warning); |
| 1268 } |
| 1269 |
1298 void Extension::AddInstallWarnings( | 1270 void Extension::AddInstallWarnings( |
1299 const InstallWarningVector& new_warnings) { | 1271 const InstallWarningVector& new_warnings) { |
1300 install_warnings_.insert(install_warnings_.end(), | 1272 install_warnings_.insert(install_warnings_.end(), |
1301 new_warnings.begin(), new_warnings.end()); | 1273 new_warnings.begin(), new_warnings.end()); |
1302 } | 1274 } |
1303 | 1275 |
1304 bool Extension::is_platform_app() const { | 1276 bool Extension::is_platform_app() const { |
1305 return manifest_->is_platform_app(); | 1277 return manifest_->is_platform_app(); |
1306 } | 1278 } |
1307 | 1279 |
(...skipping 712 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2020 | 1992 |
2021 bool Extension::LoadIcons(string16* error) { | 1993 bool Extension::LoadIcons(string16* error) { |
2022 if (!manifest_->HasKey(keys::kIcons)) | 1994 if (!manifest_->HasKey(keys::kIcons)) |
2023 return true; | 1995 return true; |
2024 DictionaryValue* icons_value = NULL; | 1996 DictionaryValue* icons_value = NULL; |
2025 if (!manifest_->GetDictionary(keys::kIcons, &icons_value)) { | 1997 if (!manifest_->GetDictionary(keys::kIcons, &icons_value)) { |
2026 *error = ASCIIToUTF16(errors::kInvalidIcons); | 1998 *error = ASCIIToUTF16(errors::kInvalidIcons); |
2027 return false; | 1999 return false; |
2028 } | 2000 } |
2029 | 2001 |
2030 return LoadIconsFromDictionary(icons_value, | 2002 return manifest_handler_helpers::LoadIconsFromDictionary( |
2031 extension_misc::kExtensionIconSizes, | 2003 icons_value, |
2032 extension_misc::kNumExtensionIconSizes, | 2004 extension_misc::kExtensionIconSizes, |
2033 &icons_, | 2005 extension_misc::kNumExtensionIconSizes, |
2034 error); | 2006 &icons_, |
| 2007 error); |
2035 } | 2008 } |
2036 | 2009 |
2037 bool Extension::LoadCommands(string16* error) { | 2010 bool Extension::LoadCommands(string16* error) { |
2038 if (manifest_->HasKey(keys::kCommands)) { | 2011 if (manifest_->HasKey(keys::kCommands)) { |
2039 DictionaryValue* commands = NULL; | 2012 DictionaryValue* commands = NULL; |
2040 if (!manifest_->GetDictionary(keys::kCommands, &commands)) { | 2013 if (!manifest_->GetDictionary(keys::kCommands, &commands)) { |
2041 *error = ASCIIToUTF16(errors::kInvalidCommandsKey); | 2014 *error = ASCIIToUTF16(errors::kInvalidCommandsKey); |
2042 return false; | 2015 return false; |
2043 } | 2016 } |
2044 | 2017 |
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2511 string16* error) { | 2484 string16* error) { |
2512 if (manifest_->HasKey(keys::kConvertedFromUserScript)) | 2485 if (manifest_->HasKey(keys::kConvertedFromUserScript)) |
2513 manifest_->GetBoolean(keys::kConvertedFromUserScript, | 2486 manifest_->GetBoolean(keys::kConvertedFromUserScript, |
2514 &converted_from_user_script_); | 2487 &converted_from_user_script_); |
2515 | 2488 |
2516 if (!LoadManifestHandlerFeatures(error) || | 2489 if (!LoadManifestHandlerFeatures(error) || |
2517 !LoadContentScripts(error) || | 2490 !LoadContentScripts(error) || |
2518 !LoadPageAction(error) || | 2491 !LoadPageAction(error) || |
2519 !LoadBrowserAction(error) || | 2492 !LoadBrowserAction(error) || |
2520 !LoadSystemIndicator(api_permissions, error) || | 2493 !LoadSystemIndicator(api_permissions, error) || |
2521 !LoadScriptBadge(error) || | |
2522 !LoadIncognitoMode(error) || | 2494 !LoadIncognitoMode(error) || |
2523 !LoadContentSecurityPolicy(error)) | 2495 !LoadContentSecurityPolicy(error)) |
2524 return false; | 2496 return false; |
2525 | 2497 |
2526 return true; | 2498 return true; |
2527 } | 2499 } |
2528 | 2500 |
2529 bool Extension::LoadManifestHandlerFeatures(string16* error) { | 2501 bool Extension::LoadManifestHandlerFeatures(string16* error) { |
2530 std::vector<std::string> keys = ManifestHandler::GetKeys(); | 2502 std::vector<std::string> keys = ManifestHandler::GetKeys(); |
2531 for (size_t i = 0; i < keys.size(); ++i) { | 2503 for (size_t i = 0; i < keys.size(); ++i) { |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2597 } else if (manifest_->HasKey(keys::kPageAction)) { | 2569 } else if (manifest_->HasKey(keys::kPageAction)) { |
2598 if (!manifest_->GetDictionary(keys::kPageAction, &page_action_value)) { | 2570 if (!manifest_->GetDictionary(keys::kPageAction, &page_action_value)) { |
2599 *error = ASCIIToUTF16(errors::kInvalidPageAction); | 2571 *error = ASCIIToUTF16(errors::kInvalidPageAction); |
2600 return false; | 2572 return false; |
2601 } | 2573 } |
2602 } | 2574 } |
2603 | 2575 |
2604 // If page_action_value is not NULL, then there was a valid page action. | 2576 // If page_action_value is not NULL, then there was a valid page action. |
2605 if (page_action_value) { | 2577 if (page_action_value) { |
2606 page_action_info_ = LoadExtensionActionInfoHelper( | 2578 page_action_info_ = LoadExtensionActionInfoHelper( |
2607 page_action_value, Extension::ActionInfo::TYPE_PAGE, error); | 2579 this, page_action_value, error); |
2608 if (!page_action_info_.get()) | 2580 if (!page_action_info_.get()) |
2609 return false; // Failed to parse page action definition. | 2581 return false; // Failed to parse page action definition. |
2610 } | 2582 } |
2611 | 2583 |
2612 return true; | 2584 return true; |
2613 } | 2585 } |
2614 | 2586 |
2615 bool Extension::LoadBrowserAction(string16* error) { | 2587 bool Extension::LoadBrowserAction(string16* error) { |
2616 if (!manifest_->HasKey(keys::kBrowserAction)) | 2588 if (!manifest_->HasKey(keys::kBrowserAction)) |
2617 return true; | 2589 return true; |
2618 DictionaryValue* browser_action_value = NULL; | 2590 DictionaryValue* browser_action_value = NULL; |
2619 if (!manifest_->GetDictionary(keys::kBrowserAction, &browser_action_value)) { | 2591 if (!manifest_->GetDictionary(keys::kBrowserAction, &browser_action_value)) { |
2620 *error = ASCIIToUTF16(errors::kInvalidBrowserAction); | 2592 *error = ASCIIToUTF16(errors::kInvalidBrowserAction); |
2621 return false; | 2593 return false; |
2622 } | 2594 } |
2623 | 2595 |
2624 browser_action_info_ = LoadExtensionActionInfoHelper( | 2596 browser_action_info_ = LoadExtensionActionInfoHelper( |
2625 browser_action_value, Extension::ActionInfo::TYPE_BROWSER, error); | 2597 this, browser_action_value, error); |
2626 if (!browser_action_info_.get()) | 2598 if (!browser_action_info_.get()) |
2627 return false; // Failed to parse browser action definition. | 2599 return false; // Failed to parse browser action definition. |
2628 return true; | 2600 return true; |
2629 } | 2601 } |
2630 | 2602 |
2631 bool Extension::LoadScriptBadge(string16* error) { | |
2632 if (manifest_->HasKey(keys::kScriptBadge)) { | |
2633 if (!FeatureSwitch::script_badges()->IsEnabled()) { | |
2634 // So as to not confuse developers if they specify a script badge section | |
2635 // in the manifest, show a warning if the script badge declaration isn't | |
2636 // going to have any effect. | |
2637 install_warnings_.push_back( | |
2638 InstallWarning(InstallWarning::FORMAT_TEXT, | |
2639 errors::kScriptBadgeRequiresFlag)); | |
2640 } | |
2641 | |
2642 DictionaryValue* script_badge_value = NULL; | |
2643 if (!manifest_->GetDictionary(keys::kScriptBadge, &script_badge_value)) { | |
2644 *error = ASCIIToUTF16(errors::kInvalidScriptBadge); | |
2645 return false; | |
2646 } | |
2647 | |
2648 script_badge_info_ = LoadExtensionActionInfoHelper( | |
2649 script_badge_value, Extension::ActionInfo::TYPE_SCRIPT_BADGE, error); | |
2650 if (!script_badge_info_.get()) | |
2651 return false; // Failed to parse script badge definition. | |
2652 } else { | |
2653 script_badge_info_.reset(new ActionInfo()); | |
2654 } | |
2655 | |
2656 // Script badges always use their extension's title and icon so users can rely | |
2657 // on the visual appearance to know which extension is running. This isn't | |
2658 // bulletproof since an malicious extension could use a different 16x16 icon | |
2659 // that matches the icon of a trusted extension, and users wouldn't be warned | |
2660 // during installation. | |
2661 | |
2662 if (!script_badge_info_->default_title.empty()) { | |
2663 install_warnings_.push_back( | |
2664 InstallWarning(InstallWarning::FORMAT_TEXT, | |
2665 errors::kScriptBadgeTitleIgnored)); | |
2666 } | |
2667 script_badge_info_->default_title = name(); | |
2668 | |
2669 if (!script_badge_info_->default_icon.empty()) { | |
2670 install_warnings_.push_back( | |
2671 InstallWarning(InstallWarning::FORMAT_TEXT, | |
2672 errors::kScriptBadgeIconIgnored)); | |
2673 } | |
2674 | |
2675 script_badge_info_->default_icon.Clear(); | |
2676 for (size_t i = 0; i < extension_misc::kNumScriptBadgeIconSizes; i++) { | |
2677 std::string path = icons().Get(extension_misc::kScriptBadgeIconSizes[i], | |
2678 ExtensionIconSet::MATCH_BIGGER); | |
2679 if (!path.empty()) | |
2680 script_badge_info_->default_icon.Add( | |
2681 extension_misc::kScriptBadgeIconSizes[i], path); | |
2682 } | |
2683 | |
2684 return true; | |
2685 } | |
2686 | |
2687 bool Extension::LoadSystemIndicator(APIPermissionSet* api_permissions, | 2603 bool Extension::LoadSystemIndicator(APIPermissionSet* api_permissions, |
2688 string16* error) { | 2604 string16* error) { |
2689 if (!manifest_->HasKey(keys::kSystemIndicator)) { | 2605 if (!manifest_->HasKey(keys::kSystemIndicator)) { |
2690 // There was no manifest entry for the system indicator. | 2606 // There was no manifest entry for the system indicator. |
2691 return true; | 2607 return true; |
2692 } | 2608 } |
2693 | 2609 |
2694 DictionaryValue* system_indicator_value = NULL; | 2610 DictionaryValue* system_indicator_value = NULL; |
2695 if (!manifest_->GetDictionary(keys::kSystemIndicator, | 2611 if (!manifest_->GetDictionary(keys::kSystemIndicator, |
2696 &system_indicator_value)) { | 2612 &system_indicator_value)) { |
2697 *error = ASCIIToUTF16(errors::kInvalidSystemIndicator); | 2613 *error = ASCIIToUTF16(errors::kInvalidSystemIndicator); |
2698 return false; | 2614 return false; |
2699 } | 2615 } |
2700 | 2616 |
2701 system_indicator_info_ = LoadExtensionActionInfoHelper( | 2617 system_indicator_info_ = LoadExtensionActionInfoHelper( |
2702 system_indicator_value, | 2618 this, system_indicator_value, error); |
2703 Extension::ActionInfo::TYPE_SYSTEM_INDICATOR, | |
2704 error); | |
2705 | 2619 |
2706 if (!system_indicator_info_.get()) { | 2620 if (!system_indicator_info_.get()) { |
2707 return false; | 2621 return false; |
2708 } | 2622 } |
2709 | 2623 |
2710 // Because the manifest was successfully parsed, auto-grant the permission. | 2624 // Because the manifest was successfully parsed, auto-grant the permission. |
2711 // TODO(dewittj) Add this for all extension action APIs. | 2625 // TODO(dewittj) Add this for all extension action APIs. |
2712 api_permissions->insert(APIPermission::kSystemIndicator); | 2626 api_permissions->insert(APIPermission::kSystemIndicator); |
2713 | 2627 |
2714 return true; | 2628 return true; |
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3133 base::IntToString(i)); | 3047 base::IntToString(i)); |
3134 return false; | 3048 return false; |
3135 } | 3049 } |
3136 | 3050 |
3137 (instance->*add_method)(glob); | 3051 (instance->*add_method)(glob); |
3138 } | 3052 } |
3139 | 3053 |
3140 return true; | 3054 return true; |
3141 } | 3055 } |
3142 | 3056 |
3143 scoped_ptr<Extension::ActionInfo> Extension::LoadExtensionActionInfoHelper( | |
3144 const DictionaryValue* extension_action, | |
3145 ActionInfo::Type action_type, | |
3146 string16* error) { | |
3147 scoped_ptr<ActionInfo> result(new ActionInfo()); | |
3148 | |
3149 if (manifest_version_ == 1) { | |
3150 // kPageActionIcons is obsolete, and used by very few extensions. Continue | |
3151 // loading it, but only take the first icon as the default_icon path. | |
3152 const ListValue* icons = NULL; | |
3153 if (extension_action->HasKey(keys::kPageActionIcons) && | |
3154 extension_action->GetList(keys::kPageActionIcons, &icons)) { | |
3155 for (ListValue::const_iterator iter = icons->begin(); | |
3156 iter != icons->end(); ++iter) { | |
3157 std::string path; | |
3158 if (!(*iter)->GetAsString(&path) || !NormalizeAndValidatePath(&path)) { | |
3159 *error = ASCIIToUTF16(errors::kInvalidPageActionIconPath); | |
3160 return scoped_ptr<ActionInfo>(); | |
3161 } | |
3162 | |
3163 result->default_icon.Add(extension_misc::EXTENSION_ICON_ACTION, path); | |
3164 break; | |
3165 } | |
3166 } | |
3167 | |
3168 std::string id; | |
3169 if (extension_action->HasKey(keys::kPageActionId)) { | |
3170 if (!extension_action->GetString(keys::kPageActionId, &id)) { | |
3171 *error = ASCIIToUTF16(errors::kInvalidPageActionId); | |
3172 return scoped_ptr<ActionInfo>(); | |
3173 } | |
3174 result->id = id; | |
3175 } | |
3176 } | |
3177 | |
3178 // Read the page action |default_icon| (optional). | |
3179 // The |default_icon| value can be either dictionary {icon size -> icon path} | |
3180 // or non empty string value. | |
3181 if (extension_action->HasKey(keys::kPageActionDefaultIcon)) { | |
3182 const DictionaryValue* icons_value = NULL; | |
3183 std::string default_icon; | |
3184 if (extension_action->GetDictionary(keys::kPageActionDefaultIcon, | |
3185 &icons_value)) { | |
3186 if (!LoadIconsFromDictionary(icons_value, | |
3187 extension_misc::kExtensionActionIconSizes, | |
3188 extension_misc::kNumExtensionActionIconSizes, | |
3189 &result->default_icon, | |
3190 error)) { | |
3191 return scoped_ptr<ActionInfo>(); | |
3192 } | |
3193 } else if (extension_action->GetString(keys::kPageActionDefaultIcon, | |
3194 &default_icon) && | |
3195 NormalizeAndValidatePath(&default_icon)) { | |
3196 result->default_icon.Add(extension_misc::EXTENSION_ICON_ACTION, | |
3197 default_icon); | |
3198 } else { | |
3199 *error = ASCIIToUTF16(errors::kInvalidPageActionIconPath); | |
3200 return scoped_ptr<ActionInfo>(); | |
3201 } | |
3202 } | |
3203 | |
3204 // Read the page action title from |default_title| if present, |name| if not | |
3205 // (both optional). | |
3206 if (extension_action->HasKey(keys::kPageActionDefaultTitle)) { | |
3207 if (!extension_action->GetString(keys::kPageActionDefaultTitle, | |
3208 &result->default_title)) { | |
3209 *error = ASCIIToUTF16(errors::kInvalidPageActionDefaultTitle); | |
3210 return scoped_ptr<ActionInfo>(); | |
3211 } | |
3212 } else if (manifest_version_ == 1 && extension_action->HasKey(keys::kName)) { | |
3213 if (!extension_action->GetString(keys::kName, &result->default_title)) { | |
3214 *error = ASCIIToUTF16(errors::kInvalidPageActionName); | |
3215 return scoped_ptr<ActionInfo>(); | |
3216 } | |
3217 } | |
3218 | |
3219 // Read the action's |popup| (optional). | |
3220 const char* popup_key = NULL; | |
3221 if (extension_action->HasKey(keys::kPageActionDefaultPopup)) | |
3222 popup_key = keys::kPageActionDefaultPopup; | |
3223 | |
3224 if (manifest_version_ == 1 && | |
3225 extension_action->HasKey(keys::kPageActionPopup)) { | |
3226 if (popup_key) { | |
3227 *error = ErrorUtils::FormatErrorMessageUTF16( | |
3228 errors::kInvalidPageActionOldAndNewKeys, | |
3229 keys::kPageActionDefaultPopup, | |
3230 keys::kPageActionPopup); | |
3231 return scoped_ptr<ActionInfo>(); | |
3232 } | |
3233 popup_key = keys::kPageActionPopup; | |
3234 } | |
3235 | |
3236 if (popup_key) { | |
3237 const DictionaryValue* popup = NULL; | |
3238 std::string url_str; | |
3239 | |
3240 if (extension_action->GetString(popup_key, &url_str)) { | |
3241 // On success, |url_str| is set. Nothing else to do. | |
3242 } else if (manifest_version_ == 1 && | |
3243 extension_action->GetDictionary(popup_key, &popup)) { | |
3244 if (!popup->GetString(keys::kPageActionPopupPath, &url_str)) { | |
3245 *error = ErrorUtils::FormatErrorMessageUTF16( | |
3246 errors::kInvalidPageActionPopupPath, "<missing>"); | |
3247 return scoped_ptr<ActionInfo>(); | |
3248 } | |
3249 } else { | |
3250 *error = ASCIIToUTF16(errors::kInvalidPageActionPopup); | |
3251 return scoped_ptr<ActionInfo>(); | |
3252 } | |
3253 | |
3254 if (!url_str.empty()) { | |
3255 // An empty string is treated as having no popup. | |
3256 result->default_popup_url = GetResourceURL(url_str); | |
3257 if (!result->default_popup_url.is_valid()) { | |
3258 *error = ErrorUtils::FormatErrorMessageUTF16( | |
3259 errors::kInvalidPageActionPopupPath, url_str); | |
3260 return scoped_ptr<ActionInfo>(); | |
3261 } | |
3262 } else { | |
3263 DCHECK(result->default_popup_url.is_empty()) | |
3264 << "Shouldn't be possible for the popup to be set."; | |
3265 } | |
3266 } | |
3267 | |
3268 return result.Pass(); | |
3269 } | |
3270 | |
3271 bool Extension::LoadOAuth2Info(string16* error) { | 3057 bool Extension::LoadOAuth2Info(string16* error) { |
3272 if (!manifest_->HasKey(keys::kOAuth2)) | 3058 if (!manifest_->HasKey(keys::kOAuth2)) |
3273 return true; | 3059 return true; |
3274 | 3060 |
3275 if (!manifest_->GetString(keys::kOAuth2ClientId, &oauth2_info_.client_id) || | 3061 if (!manifest_->GetString(keys::kOAuth2ClientId, &oauth2_info_.client_id) || |
3276 oauth2_info_.client_id.empty()) { | 3062 oauth2_info_.client_id.empty()) { |
3277 *error = ASCIIToUTF16(errors::kInvalidOAuth2ClientId); | 3063 *error = ASCIIToUTF16(errors::kInvalidOAuth2ClientId); |
3278 return false; | 3064 return false; |
3279 } | 3065 } |
3280 | 3066 |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3480 | 3266 |
3481 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo( | 3267 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo( |
3482 const Extension* extension, | 3268 const Extension* extension, |
3483 const PermissionSet* permissions, | 3269 const PermissionSet* permissions, |
3484 Reason reason) | 3270 Reason reason) |
3485 : reason(reason), | 3271 : reason(reason), |
3486 extension(extension), | 3272 extension(extension), |
3487 permissions(permissions) {} | 3273 permissions(permissions) {} |
3488 | 3274 |
3489 } // namespace extensions | 3275 } // namespace extensions |
OLD | NEW |