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

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

Issue 10565017: Parse the script_badge manifest section. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix aa's and kalman's comments. Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/common/extensions/extension.h ('k') | chrome/common/extensions/extension_action.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 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>
8
7 #include "base/base64.h" 9 #include "base/base64.h"
8 #include "base/basictypes.h" 10 #include "base/basictypes.h"
9 #include "base/command_line.h" 11 #include "base/command_line.h"
10 #include "base/file_path.h" 12 #include "base/file_path.h"
11 #include "base/file_util.h" 13 #include "base/file_util.h"
12 #include "base/i18n/rtl.h" 14 #include "base/i18n/rtl.h"
13 #include "base/logging.h" 15 #include "base/logging.h"
14 #include "base/memory/singleton.h" 16 #include "base/memory/singleton.h"
15 #include "base/stl_util.h" 17 #include "base/stl_util.h"
16 #include "base/string16.h" 18 #include "base/string16.h"
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after
408 const std::string Extension::VersionString() const { 410 const std::string Extension::VersionString() const {
409 return version()->GetString(); 411 return version()->GetString();
410 } 412 }
411 413
412 void Extension::AddInstallWarnings( 414 void Extension::AddInstallWarnings(
413 const InstallWarningVector& new_warnings) { 415 const InstallWarningVector& new_warnings) {
414 install_warnings_.insert(install_warnings_.end(), 416 install_warnings_.insert(install_warnings_.end(),
415 new_warnings.begin(), new_warnings.end()); 417 new_warnings.begin(), new_warnings.end());
416 } 418 }
417 419
420 void Extension::AddDeveloperInstallWarning(
421 InstallWarning::Format format,
422 const std::string& message) {
423 if (location() == LOAD)
not at google - send to devlin 2012/06/18 22:59:41 Install warnings only show up when developer mode
Jeffrey Yasskin 2012/06/18 23:58:42 My idea here was that it would show up for extensi
not at google - send to devlin 2012/06/19 00:27:32 Yeah, makes sense. I'm just saying that this happe
424 install_warnings_.push_back(InstallWarning(format, message));
425 }
426
418 // static 427 // static
419 bool Extension::IsExtension(const FilePath& file_name) { 428 bool Extension::IsExtension(const FilePath& file_name) {
420 return file_name.MatchesExtension(chrome::kExtensionFileExtension); 429 return file_name.MatchesExtension(chrome::kExtensionFileExtension);
421 } 430 }
422 431
423 // static 432 // static
424 bool Extension::IdIsValid(const std::string& id) { 433 bool Extension::IdIsValid(const std::string& id) {
425 // Verify that the id is legal. 434 // Verify that the id is legal.
426 if (id.size() != (kIdSize * 2)) 435 if (id.size() != (kIdSize * 2))
427 return false; 436 return false;
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after
794 return false; 803 return false;
795 } 804 }
796 805
797 (instance->*add_method)(glob); 806 (instance->*add_method)(glob);
798 } 807 }
799 808
800 return true; 809 return true;
801 } 810 }
802 811
803 scoped_ptr<ExtensionAction> Extension::LoadExtensionActionHelper( 812 scoped_ptr<ExtensionAction> Extension::LoadExtensionActionHelper(
804 const DictionaryValue* extension_action, string16* error) { 813 const DictionaryValue* extension_action,
814 ExtensionAction::Type action_type,
815 string16* error) {
805 scoped_ptr<ExtensionAction> result(new ExtensionAction(id())); 816 scoped_ptr<ExtensionAction> result(new ExtensionAction(id()));
806 817
807 // Page actions are hidden by default, and browser actions ignore 818 // Page actions are hidden by default, and browser actions ignore
808 // visibility. 819 // visibility.
809 result->SetIsVisible(ExtensionAction::kDefaultTabId, false); 820 result->SetIsVisible(ExtensionAction::kDefaultTabId, false);
810 821
811 if (manifest_version_ == 1) { 822 if (manifest_version_ == 1) {
812 ListValue* icons = NULL; 823 ListValue* icons = NULL;
813 if (extension_action->HasKey(keys::kPageActionIcons) && 824 if (extension_action->HasKey(keys::kPageActionIcons) &&
814 extension_action->GetList(keys::kPageActionIcons, &icons)) { 825 extension_action->GetList(keys::kPageActionIcons, &icons)) {
(...skipping 15 matching lines...) Expand all
830 *error = ASCIIToUTF16(errors::kInvalidPageActionId); 841 *error = ASCIIToUTF16(errors::kInvalidPageActionId);
831 return scoped_ptr<ExtensionAction>(); 842 return scoped_ptr<ExtensionAction>();
832 } 843 }
833 result->set_id(id); 844 result->set_id(id);
834 } 845 }
835 } 846 }
836 847
837 std::string default_icon; 848 std::string default_icon;
838 // Read the page action |default_icon| (optional). 849 // Read the page action |default_icon| (optional).
839 if (extension_action->HasKey(keys::kPageActionDefaultIcon)) { 850 if (extension_action->HasKey(keys::kPageActionDefaultIcon)) {
840 if (!extension_action->GetString(keys::kPageActionDefaultIcon, 851 if (action_type == ExtensionAction::TYPE_SCRIPT_BADGE) {
841 &default_icon) || 852 AddDeveloperInstallWarning(InstallWarning::FORMAT_TEXT,
842 default_icon.empty()) { 853 errors::kScriptBadgeIconIgnored);
843 *error = ASCIIToUTF16(errors::kInvalidPageActionIconPath); 854 } else {
844 return scoped_ptr<ExtensionAction>(); 855 if (!extension_action->GetString(keys::kPageActionDefaultIcon,
856 &default_icon) ||
857 default_icon.empty()) {
858 *error = ASCIIToUTF16(errors::kInvalidPageActionIconPath);
859 return scoped_ptr<ExtensionAction>();
860 }
861 result->set_default_icon_path(default_icon);
845 } 862 }
846 result->set_default_icon_path(default_icon);
847 } 863 }
848 864
849 // Read the page action title from |default_title| if present, |name| if not 865 // Read the page action title from |default_title| if present, |name| if not
850 // (both optional). 866 // (both optional).
851 std::string title; 867 std::string title;
852 if (extension_action->HasKey(keys::kPageActionDefaultTitle)) { 868 if (extension_action->HasKey(keys::kPageActionDefaultTitle)) {
853 if (!extension_action->GetString(keys::kPageActionDefaultTitle, &title)) { 869 if (!extension_action->GetString(keys::kPageActionDefaultTitle, &title)) {
854 *error = ASCIIToUTF16(errors::kInvalidPageActionDefaultTitle); 870 *error = ASCIIToUTF16(errors::kInvalidPageActionDefaultTitle);
855 return scoped_ptr<ExtensionAction>(); 871 return scoped_ptr<ExtensionAction>();
856 } 872 }
(...skipping 1162 matching lines...) Expand 10 before | Expand all | Expand 10 after
2019 string16* error) { 2035 string16* error) {
2020 if (manifest_->HasKey(keys::kConvertedFromUserScript)) 2036 if (manifest_->HasKey(keys::kConvertedFromUserScript))
2021 manifest_->GetBoolean(keys::kConvertedFromUserScript, 2037 manifest_->GetBoolean(keys::kConvertedFromUserScript,
2022 &converted_from_user_script_); 2038 &converted_from_user_script_);
2023 2039
2024 if (!LoadDevToolsPage(error) || 2040 if (!LoadDevToolsPage(error) ||
2025 !LoadInputComponents(api_permissions, error) || 2041 !LoadInputComponents(api_permissions, error) ||
2026 !LoadContentScripts(error) || 2042 !LoadContentScripts(error) ||
2027 !LoadPageAction(error) || 2043 !LoadPageAction(error) ||
2028 !LoadBrowserAction(error) || 2044 !LoadBrowserAction(error) ||
2045 !LoadScriptBadge(error) ||
2029 !LoadFileBrowserHandlers(error) || 2046 !LoadFileBrowserHandlers(error) ||
2030 !LoadChromeURLOverrides(error) || 2047 !LoadChromeURLOverrides(error) ||
2031 !LoadOmnibox(error) || 2048 !LoadOmnibox(error) ||
2032 !LoadTextToSpeechVoices(error) || 2049 !LoadTextToSpeechVoices(error) ||
2033 !LoadIncognitoMode(error) || 2050 !LoadIncognitoMode(error) ||
2034 !LoadContentSecurityPolicy(error)) 2051 !LoadContentSecurityPolicy(error))
2035 return false; 2052 return false;
2036 2053
2037 return true; 2054 return true;
2038 } 2055 }
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
2239 } 2256 }
2240 } else if (manifest_->HasKey(keys::kPageAction)) { 2257 } else if (manifest_->HasKey(keys::kPageAction)) {
2241 if (!manifest_->GetDictionary(keys::kPageAction, &page_action_value)) { 2258 if (!manifest_->GetDictionary(keys::kPageAction, &page_action_value)) {
2242 *error = ASCIIToUTF16(errors::kInvalidPageAction); 2259 *error = ASCIIToUTF16(errors::kInvalidPageAction);
2243 return false; 2260 return false;
2244 } 2261 }
2245 } 2262 }
2246 2263
2247 // If page_action_value is not NULL, then there was a valid page action. 2264 // If page_action_value is not NULL, then there was a valid page action.
2248 if (page_action_value) { 2265 if (page_action_value) {
2249 page_action_ = LoadExtensionActionHelper(page_action_value, error); 2266 page_action_ = LoadExtensionActionHelper(
2267 page_action_value, ExtensionAction::TYPE_PAGE, error);
2250 if (!page_action_.get()) 2268 if (!page_action_.get())
2251 return false; // Failed to parse page action definition. 2269 return false; // Failed to parse page action definition.
2252 declared_action_type_ = ExtensionAction::TYPE_PAGE; 2270 declared_action_type_ = ExtensionAction::TYPE_PAGE;
2253 2271
2254 // The action box changes the meaning of the page action area, so we need 2272 // The action box changes the meaning of the page action area, so we need
2255 // to convert page actions into browser actions. 2273 // to convert page actions into browser actions.
2256 if (switch_utils::IsActionBoxEnabled()) { 2274 if (switch_utils::IsActionBoxEnabled()) {
2257 browser_action_ = page_action_.Pass(); 2275 browser_action_ = page_action_.Pass();
2258 // declared_action_type_ stays the same; that's the point. 2276 // declared_action_type_ stays the same; that's the point.
2259 } 2277 }
2260 } 2278 }
2261 2279
2262 return true; 2280 return true;
2263 } 2281 }
2264 2282
2265 bool Extension::LoadBrowserAction(string16* error) { 2283 bool Extension::LoadBrowserAction(string16* error) {
2266 if (!manifest_->HasKey(keys::kBrowserAction)) 2284 if (!manifest_->HasKey(keys::kBrowserAction))
2267 return true; 2285 return true;
2268 DictionaryValue* browser_action_value = NULL; 2286 DictionaryValue* browser_action_value = NULL;
2269 if (!manifest_->GetDictionary(keys::kBrowserAction, &browser_action_value)) { 2287 if (!manifest_->GetDictionary(keys::kBrowserAction, &browser_action_value)) {
2270 *error = ASCIIToUTF16(errors::kInvalidBrowserAction); 2288 *error = ASCIIToUTF16(errors::kInvalidBrowserAction);
2271 return false; 2289 return false;
2272 } 2290 }
2273 2291
2274 browser_action_ = LoadExtensionActionHelper(browser_action_value, error); 2292 browser_action_ = LoadExtensionActionHelper(
2293 browser_action_value, ExtensionAction::TYPE_BROWSER, error);
2275 if (!browser_action_.get()) 2294 if (!browser_action_.get())
2276 return false; // Failed to parse browser action definition. 2295 return false; // Failed to parse browser action definition.
2277 declared_action_type_ = ExtensionAction::TYPE_BROWSER; 2296 declared_action_type_ = ExtensionAction::TYPE_BROWSER;
2278 return true; 2297 return true;
2279 } 2298 }
2280 2299
2300 bool Extension::LoadScriptBadge(string16* error) {
2301 DictionaryValue* script_badge_value = NULL;
2302
2303 if (!switch_utils::IsActionBoxEnabled()) {
not at google - send to devlin 2012/06/18 22:59:41 (has been submitted now btw)
Jeffrey Yasskin 2012/06/18 23:58:42 And I've now synced past it.
2304 if (manifest_->HasKey(keys::kScriptBadge)) {
2305 AddDeveloperInstallWarning(InstallWarning::FORMAT_TEXT,
2306 errors::kScriptBadgeRequiresActionBox);
2307 }
2308 return true;
not at google - send to devlin 2012/06/18 22:59:41 Could we just generate a warning here and not earl
Jeffrey Yasskin 2012/06/18 23:58:42 Sure. Then script_badge_ should never be null.
2309 }
2310
2311 if (manifest_->HasKey(keys::kScriptBadge)) {
2312 if (!manifest_->GetDictionary(keys::kScriptBadge, &script_badge_value)) {
2313 *error = ASCIIToUTF16(errors::kInvalidScriptBadge);
2314 return false;
2315 }
2316 script_badge_ = LoadExtensionActionHelper(
2317 script_badge_value, ExtensionAction::TYPE_SCRIPT_BADGE, error);
2318 if (!script_badge_.get())
2319 return false; // Failed to parse script badge definition.
2320 declared_action_type_ = ExtensionAction::TYPE_SCRIPT_BADGE;
2321 } else {
2322 script_badge_.reset(new ExtensionAction(id()));
2323
2324 // Make sure there is always a title.
2325 script_badge_->SetTitle(ExtensionAction::kDefaultTabId, name());
2326 }
2327
2328 // Script badges always use their extension's icon so users can rely on the
2329 // visual appearance to know which extension is running. This isn't
2330 // bulletproof since an malicious extension could use a different 16x16 icon
2331 // that matches the icon of a trusted extension, and users wouldn't be warned
2332 // during installation.
2333
2334 script_badge_->set_default_icon_path(
2335 icons().Get(ExtensionIconSet::EXTENSION_ICON_BITTY,
2336 ExtensionIconSet::MATCH_BIGGER));
2337
2338 script_badge_->SetIsVisible(ExtensionAction::kDefaultTabId, true);
2339
2340 return true;
2341 }
2342
2281 bool Extension::LoadFileBrowserHandlers(string16* error) { 2343 bool Extension::LoadFileBrowserHandlers(string16* error) {
2282 if (!manifest_->HasKey(keys::kFileBrowserHandlers)) 2344 if (!manifest_->HasKey(keys::kFileBrowserHandlers))
2283 return true; 2345 return true;
2284 ListValue* file_browser_handlers_value = NULL; 2346 ListValue* file_browser_handlers_value = NULL;
2285 if (!manifest_->GetList(keys::kFileBrowserHandlers, 2347 if (!manifest_->GetList(keys::kFileBrowserHandlers,
2286 &file_browser_handlers_value)) { 2348 &file_browser_handlers_value)) {
2287 *error = ASCIIToUTF16(errors::kInvalidFileBrowserHandler); 2349 *error = ASCIIToUTF16(errors::kInvalidFileBrowserHandler);
2288 return false; 2350 return false;
2289 } 2351 }
2290 file_browser_handlers_.reset( 2352 file_browser_handlers_.reset(
(...skipping 1319 matching lines...) Expand 10 before | Expand all | Expand 10 after
3610 // We want to sync any extensions that are internal and the chrome web store. 3672 // We want to sync any extensions that are internal and the chrome web store.
3611 return location() == Extension::INTERNAL || 3673 return location() == Extension::INTERNAL ||
3612 id() == extension_misc::kWebStoreAppId; 3674 id() == extension_misc::kWebStoreAppId;
3613 } 3675 }
3614 3676
3615 bool Extension::ShouldDisplayInLauncher() const { 3677 bool Extension::ShouldDisplayInLauncher() const {
3616 // All apps should be displayed on the NTP except for the Cloud Print App. 3678 // All apps should be displayed on the NTP except for the Cloud Print App.
3617 return is_app() && id() != extension_misc::kCloudPrintAppId; 3679 return is_app() && id() != extension_misc::kCloudPrintAppId;
3618 } 3680 }
3619 3681
3682 bool Extension::InstallWarning::operator==(const InstallWarning& other) const {
3683 return format == other.format && message == other.message;
3684 }
3685
3686 void PrintTo(const Extension::InstallWarning& warning, ::std::ostream* os){
3687 *os << "InstallWarning(";
3688 switch (warning.format) {
3689 case Extension::InstallWarning::FORMAT_TEXT:
3690 *os << "FORMAT_TEXT, \"";
3691 break;
3692 case Extension::InstallWarning::FORMAT_HTML:
3693 *os << "FORMAT_HTML, \"";
3694 break;
3695 }
3696 // This is just for test error messages, so no need to escape '"'
3697 // characters inside the message.
3698 *os << warning.message << "\")";
3699 }
3700
3620 ExtensionInfo::ExtensionInfo(const DictionaryValue* manifest, 3701 ExtensionInfo::ExtensionInfo(const DictionaryValue* manifest,
3621 const std::string& id, 3702 const std::string& id,
3622 const FilePath& path, 3703 const FilePath& path,
3623 Extension::Location location) 3704 Extension::Location location)
3624 : extension_id(id), 3705 : extension_id(id),
3625 extension_path(path), 3706 extension_path(path),
3626 extension_location(location) { 3707 extension_location(location) {
3627 if (manifest) 3708 if (manifest)
3628 extension_manifest.reset(manifest->DeepCopy()); 3709 extension_manifest.reset(manifest->DeepCopy());
3629 } 3710 }
(...skipping 27 matching lines...) Expand all
3657 3738
3658 bool Extension::HasContentScriptAtURL(const GURL& url) const { 3739 bool Extension::HasContentScriptAtURL(const GURL& url) const {
3659 for (UserScriptList::const_iterator it = content_scripts_.begin(); 3740 for (UserScriptList::const_iterator it = content_scripts_.begin();
3660 it != content_scripts_.end(); ++it) { 3741 it != content_scripts_.end(); ++it) {
3661 if (it->MatchesURL(url)) 3742 if (it->MatchesURL(url))
3662 return true; 3743 return true;
3663 } 3744 }
3664 return false; 3745 return false;
3665 } 3746 }
3666 3747
3667 ExtensionAction* Extension::GetScriptBadge() const {
3668 if (!script_badge_.get()) {
3669 script_badge_.reset(new ExtensionAction(id()));
3670
3671 // On initialization, copy the default icon path from the browser action,
3672 // or generate a puzzle piece if there isn't one. Extensions may later
3673 // overwrite this icon using the browserAction API.
3674 if (browser_action() && !browser_action()->default_icon_path().empty()) {
3675 script_badge_->set_default_icon_path(
3676 browser_action()->default_icon_path());
3677 } else {
3678 script_badge_->SetIcon(
3679 ExtensionAction::kDefaultTabId,
3680 *ui::ResourceBundle::GetSharedInstance().GetImageNamed(
3681 IDR_EXTENSIONS_FAVICON).ToSkBitmap());
3682 }
3683
3684 // Likewise, make sure there is always a title.
3685 script_badge_->SetTitle(ExtensionAction::kDefaultTabId, name());
3686 }
3687
3688 // Every time, re-initialize the script badge based on the current state of
3689 // the browser action.
3690 int kDefaultTabId = ExtensionAction::kDefaultTabId;
3691
3692 script_badge_->SetIsVisible(kDefaultTabId, true);
3693
3694 if (browser_action()) {
3695 SkBitmap icon = browser_action()->GetIcon(kDefaultTabId);
3696 if (!icon.isNull())
3697 script_badge_->SetIcon(kDefaultTabId, icon);
3698
3699 std::string title = browser_action()->GetTitle(kDefaultTabId);
3700 if (!title.empty())
3701 script_badge_->SetTitle(kDefaultTabId, title);
3702 }
3703
3704 return script_badge_.get();
3705 }
3706
3707 const URLPatternSet* Extension::GetTabSpecificHostPermissions( 3748 const URLPatternSet* Extension::GetTabSpecificHostPermissions(
3708 int tab_id) const { 3749 int tab_id) const {
3709 base::AutoLock auto_lock(runtime_data_lock_); 3750 base::AutoLock auto_lock(runtime_data_lock_);
3710 return runtime_data_.GetTabSpecificHostPermissions(tab_id); 3751 return runtime_data_.GetTabSpecificHostPermissions(tab_id);
3711 } 3752 }
3712 3753
3713 void Extension::SetTabSpecificHostPermissions( 3754 void Extension::SetTabSpecificHostPermissions(
3714 int tab_id, 3755 int tab_id,
3715 const URLPatternSet& permissions) const { 3756 const URLPatternSet& permissions) const {
3716 base::AutoLock auto_lock(runtime_data_lock_); 3757 base::AutoLock auto_lock(runtime_data_lock_);
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
3797 3838
3798 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo( 3839 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo(
3799 const Extension* extension, 3840 const Extension* extension,
3800 const ExtensionPermissionSet* permissions, 3841 const ExtensionPermissionSet* permissions,
3801 Reason reason) 3842 Reason reason)
3802 : reason(reason), 3843 : reason(reason),
3803 extension(extension), 3844 extension(extension),
3804 permissions(permissions) {} 3845 permissions(permissions) {}
3805 3846
3806 } // namespace extensions 3847 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/common/extensions/extension.h ('k') | chrome/common/extensions/extension_action.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698