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

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: Back out support for setting switches in unittests. 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 777 matching lines...) Expand 10 before | Expand all | Expand 10 after
794 return false; 796 return false;
795 } 797 }
796 798
797 (instance->*add_method)(glob); 799 (instance->*add_method)(glob);
798 } 800 }
799 801
800 return true; 802 return true;
801 } 803 }
802 804
803 scoped_ptr<ExtensionAction> Extension::LoadExtensionActionHelper( 805 scoped_ptr<ExtensionAction> Extension::LoadExtensionActionHelper(
804 const DictionaryValue* extension_action, string16* error) { 806 const DictionaryValue* extension_action,
807 ExtensionAction::Type action_type,
808 string16* error) {
805 scoped_ptr<ExtensionAction> result(new ExtensionAction(id())); 809 scoped_ptr<ExtensionAction> result(new ExtensionAction(id()));
806 810
807 // Page actions are hidden by default, and browser actions ignore 811 // Page actions are hidden by default, and browser actions ignore
808 // visibility. 812 // visibility.
809 result->SetIsVisible(ExtensionAction::kDefaultTabId, false); 813 result->SetIsVisible(ExtensionAction::kDefaultTabId, false);
810 814
811 if (manifest_version_ == 1) { 815 if (manifest_version_ == 1) {
812 ListValue* icons = NULL; 816 ListValue* icons = NULL;
813 if (extension_action->HasKey(keys::kPageActionIcons) && 817 if (extension_action->HasKey(keys::kPageActionIcons) &&
814 extension_action->GetList(keys::kPageActionIcons, &icons)) { 818 extension_action->GetList(keys::kPageActionIcons, &icons)) {
(...skipping 15 matching lines...) Expand all
830 *error = ASCIIToUTF16(errors::kInvalidPageActionId); 834 *error = ASCIIToUTF16(errors::kInvalidPageActionId);
831 return scoped_ptr<ExtensionAction>(); 835 return scoped_ptr<ExtensionAction>();
832 } 836 }
833 result->set_id(id); 837 result->set_id(id);
834 } 838 }
835 } 839 }
836 840
837 std::string default_icon; 841 std::string default_icon;
838 // Read the page action |default_icon| (optional). 842 // Read the page action |default_icon| (optional).
839 if (extension_action->HasKey(keys::kPageActionDefaultIcon)) { 843 if (extension_action->HasKey(keys::kPageActionDefaultIcon)) {
840 if (!extension_action->GetString(keys::kPageActionDefaultIcon, 844 if (action_type == ExtensionAction::TYPE_SCRIPT_BADGE) {
841 &default_icon) || 845 install_warnings_.push_back(
842 default_icon.empty()) { 846 InstallWarning(InstallWarning::FORMAT_TEXT,
843 *error = ASCIIToUTF16(errors::kInvalidPageActionIconPath); 847 errors::kScriptBadgeIconIgnored));
844 return scoped_ptr<ExtensionAction>(); 848 } else {
849 if (!extension_action->GetString(keys::kPageActionDefaultIcon,
850 &default_icon) ||
851 default_icon.empty()) {
852 *error = ASCIIToUTF16(errors::kInvalidPageActionIconPath);
853 return scoped_ptr<ExtensionAction>();
854 }
855 result->set_default_icon_path(default_icon);
845 } 856 }
846 result->set_default_icon_path(default_icon);
847 } 857 }
848 858
849 // Read the page action title from |default_title| if present, |name| if not 859 // Read the page action title from |default_title| if present, |name| if not
850 // (both optional). 860 // (both optional).
851 std::string title; 861 std::string title;
852 if (extension_action->HasKey(keys::kPageActionDefaultTitle)) { 862 if (extension_action->HasKey(keys::kPageActionDefaultTitle)) {
853 if (!extension_action->GetString(keys::kPageActionDefaultTitle, &title)) { 863 if (!extension_action->GetString(keys::kPageActionDefaultTitle, &title)) {
854 *error = ASCIIToUTF16(errors::kInvalidPageActionDefaultTitle); 864 *error = ASCIIToUTF16(errors::kInvalidPageActionDefaultTitle);
855 return scoped_ptr<ExtensionAction>(); 865 return scoped_ptr<ExtensionAction>();
856 } 866 }
(...skipping 1162 matching lines...) Expand 10 before | Expand all | Expand 10 after
2019 string16* error) { 2029 string16* error) {
2020 if (manifest_->HasKey(keys::kConvertedFromUserScript)) 2030 if (manifest_->HasKey(keys::kConvertedFromUserScript))
2021 manifest_->GetBoolean(keys::kConvertedFromUserScript, 2031 manifest_->GetBoolean(keys::kConvertedFromUserScript,
2022 &converted_from_user_script_); 2032 &converted_from_user_script_);
2023 2033
2024 if (!LoadDevToolsPage(error) || 2034 if (!LoadDevToolsPage(error) ||
2025 !LoadInputComponents(api_permissions, error) || 2035 !LoadInputComponents(api_permissions, error) ||
2026 !LoadContentScripts(error) || 2036 !LoadContentScripts(error) ||
2027 !LoadPageAction(error) || 2037 !LoadPageAction(error) ||
2028 !LoadBrowserAction(error) || 2038 !LoadBrowserAction(error) ||
2039 !LoadScriptBadge(error) ||
2029 !LoadFileBrowserHandlers(error) || 2040 !LoadFileBrowserHandlers(error) ||
2030 !LoadChromeURLOverrides(error) || 2041 !LoadChromeURLOverrides(error) ||
2031 !LoadOmnibox(error) || 2042 !LoadOmnibox(error) ||
2032 !LoadTextToSpeechVoices(error) || 2043 !LoadTextToSpeechVoices(error) ||
2033 !LoadIncognitoMode(error) || 2044 !LoadIncognitoMode(error) ||
2034 !LoadContentSecurityPolicy(error)) 2045 !LoadContentSecurityPolicy(error))
2035 return false; 2046 return false;
2036 2047
2037 return true; 2048 return true;
2038 } 2049 }
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
2239 } 2250 }
2240 } else if (manifest_->HasKey(keys::kPageAction)) { 2251 } else if (manifest_->HasKey(keys::kPageAction)) {
2241 if (!manifest_->GetDictionary(keys::kPageAction, &page_action_value)) { 2252 if (!manifest_->GetDictionary(keys::kPageAction, &page_action_value)) {
2242 *error = ASCIIToUTF16(errors::kInvalidPageAction); 2253 *error = ASCIIToUTF16(errors::kInvalidPageAction);
2243 return false; 2254 return false;
2244 } 2255 }
2245 } 2256 }
2246 2257
2247 // If page_action_value is not NULL, then there was a valid page action. 2258 // If page_action_value is not NULL, then there was a valid page action.
2248 if (page_action_value) { 2259 if (page_action_value) {
2249 page_action_ = LoadExtensionActionHelper(page_action_value, error); 2260 page_action_ = LoadExtensionActionHelper(
2261 page_action_value, ExtensionAction::TYPE_PAGE, error);
2250 if (!page_action_.get()) 2262 if (!page_action_.get())
2251 return false; // Failed to parse page action definition. 2263 return false; // Failed to parse page action definition.
2252 declared_action_type_ = ExtensionAction::TYPE_PAGE; 2264 declared_action_type_ = ExtensionAction::TYPE_PAGE;
2253 2265
2254 // The action box changes the meaning of the page action area, so we need 2266 // The action box changes the meaning of the page action area, so we need
2255 // to convert page actions into browser actions. 2267 // to convert page actions into browser actions.
2256 if (switch_utils::AreScriptBadgesEnabled()) { 2268 if (switch_utils::AreScriptBadgesEnabled()) {
2257 browser_action_ = page_action_.Pass(); 2269 browser_action_ = page_action_.Pass();
2258 // declared_action_type_ stays the same; that's the point. 2270 // declared_action_type_ stays the same; that's the point.
2259 } 2271 }
2260 } 2272 }
2261 2273
2262 return true; 2274 return true;
2263 } 2275 }
2264 2276
2265 bool Extension::LoadBrowserAction(string16* error) { 2277 bool Extension::LoadBrowserAction(string16* error) {
2266 if (!manifest_->HasKey(keys::kBrowserAction)) 2278 if (!manifest_->HasKey(keys::kBrowserAction))
2267 return true; 2279 return true;
2268 DictionaryValue* browser_action_value = NULL; 2280 DictionaryValue* browser_action_value = NULL;
2269 if (!manifest_->GetDictionary(keys::kBrowserAction, &browser_action_value)) { 2281 if (!manifest_->GetDictionary(keys::kBrowserAction, &browser_action_value)) {
2270 *error = ASCIIToUTF16(errors::kInvalidBrowserAction); 2282 *error = ASCIIToUTF16(errors::kInvalidBrowserAction);
2271 return false; 2283 return false;
2272 } 2284 }
2273 2285
2274 browser_action_ = LoadExtensionActionHelper(browser_action_value, error); 2286 browser_action_ = LoadExtensionActionHelper(
2287 browser_action_value, ExtensionAction::TYPE_BROWSER, error);
2275 if (!browser_action_.get()) 2288 if (!browser_action_.get())
2276 return false; // Failed to parse browser action definition. 2289 return false; // Failed to parse browser action definition.
2277 declared_action_type_ = ExtensionAction::TYPE_BROWSER; 2290 declared_action_type_ = ExtensionAction::TYPE_BROWSER;
2278 return true; 2291 return true;
2279 } 2292 }
2280 2293
2294 bool Extension::LoadScriptBadge(string16* error) {
2295 if (manifest_->HasKey(keys::kScriptBadge)) {
2296 if (!switch_utils::AreScriptBadgesEnabled()) {
2297 // So as to not confuse developers if they specify a script badge section
2298 // in the manifest, show a warning if the script badge declaration isn't
2299 // going to have any effect.
2300 install_warnings_.push_back(
2301 InstallWarning(InstallWarning::FORMAT_TEXT,
2302 errors::kScriptBadgeRequiresFlag));
2303 }
2304
2305 DictionaryValue* script_badge_value = NULL;
2306 if (!manifest_->GetDictionary(keys::kScriptBadge, &script_badge_value)) {
2307 *error = ASCIIToUTF16(errors::kInvalidScriptBadge);
2308 return false;
2309 }
2310
2311 script_badge_ = LoadExtensionActionHelper(
2312 script_badge_value, ExtensionAction::TYPE_SCRIPT_BADGE, error);
2313 if (!script_badge_.get())
2314 return false; // Failed to parse script badge definition.
2315
2316 declared_action_type_ = ExtensionAction::TYPE_SCRIPT_BADGE;
2317 } else {
2318 script_badge_.reset(new ExtensionAction(id()));
2319
2320 // Make sure there is always a title.
2321 script_badge_->SetTitle(ExtensionAction::kDefaultTabId, name());
2322 }
2323
2324 // Script badges always use their extension's icon so users can rely on the
2325 // visual appearance to know which extension is running. This isn't
2326 // bulletproof since an malicious extension could use a different 16x16 icon
2327 // that matches the icon of a trusted extension, and users wouldn't be warned
2328 // during installation.
2329
2330 std::string icon16_path = icons().Get(ExtensionIconSet::EXTENSION_ICON_BITTY,
2331 ExtensionIconSet::MATCH_EXACTLY);
2332 if (!icon16_path.empty()) {
2333 script_badge_->set_default_icon_path(icon16_path);
2334 } else {
2335 script_badge_->SetIcon(
2336 ExtensionAction::kDefaultTabId,
2337 *ui::ResourceBundle::GetSharedInstance().GetImageNamed(
2338 IDR_EXTENSIONS_FAVICON).ToSkBitmap());
2339 }
2340
2341 script_badge_->SetIsVisible(ExtensionAction::kDefaultTabId, true);
2342
2343 return true;
2344 }
2345
2281 bool Extension::LoadFileBrowserHandlers(string16* error) { 2346 bool Extension::LoadFileBrowserHandlers(string16* error) {
2282 if (!manifest_->HasKey(keys::kFileBrowserHandlers)) 2347 if (!manifest_->HasKey(keys::kFileBrowserHandlers))
2283 return true; 2348 return true;
2284 ListValue* file_browser_handlers_value = NULL; 2349 ListValue* file_browser_handlers_value = NULL;
2285 if (!manifest_->GetList(keys::kFileBrowserHandlers, 2350 if (!manifest_->GetList(keys::kFileBrowserHandlers,
2286 &file_browser_handlers_value)) { 2351 &file_browser_handlers_value)) {
2287 *error = ASCIIToUTF16(errors::kInvalidFileBrowserHandler); 2352 *error = ASCIIToUTF16(errors::kInvalidFileBrowserHandler);
2288 return false; 2353 return false;
2289 } 2354 }
2290 file_browser_handlers_.reset( 2355 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. 3675 // We want to sync any extensions that are internal and the chrome web store.
3611 return location() == Extension::INTERNAL || 3676 return location() == Extension::INTERNAL ||
3612 id() == extension_misc::kWebStoreAppId; 3677 id() == extension_misc::kWebStoreAppId;
3613 } 3678 }
3614 3679
3615 bool Extension::ShouldDisplayInLauncher() const { 3680 bool Extension::ShouldDisplayInLauncher() const {
3616 // All apps should be displayed on the NTP except for the Cloud Print App. 3681 // All apps should be displayed on the NTP except for the Cloud Print App.
3617 return is_app() && id() != extension_misc::kCloudPrintAppId; 3682 return is_app() && id() != extension_misc::kCloudPrintAppId;
3618 } 3683 }
3619 3684
3685 bool Extension::InstallWarning::operator==(const InstallWarning& other) const {
3686 return format == other.format && message == other.message;
3687 }
3688
3689 void PrintTo(const Extension::InstallWarning& warning, ::std::ostream* os){
3690 *os << "InstallWarning(";
3691 switch (warning.format) {
3692 case Extension::InstallWarning::FORMAT_TEXT:
3693 *os << "FORMAT_TEXT, \"";
3694 break;
3695 case Extension::InstallWarning::FORMAT_HTML:
3696 *os << "FORMAT_HTML, \"";
3697 break;
3698 }
3699 // This is just for test error messages, so no need to escape '"'
3700 // characters inside the message.
3701 *os << warning.message << "\")";
3702 }
3703
3620 ExtensionInfo::ExtensionInfo(const DictionaryValue* manifest, 3704 ExtensionInfo::ExtensionInfo(const DictionaryValue* manifest,
3621 const std::string& id, 3705 const std::string& id,
3622 const FilePath& path, 3706 const FilePath& path,
3623 Extension::Location location) 3707 Extension::Location location)
3624 : extension_id(id), 3708 : extension_id(id),
3625 extension_path(path), 3709 extension_path(path),
3626 extension_location(location) { 3710 extension_location(location) {
3627 if (manifest) 3711 if (manifest)
3628 extension_manifest.reset(manifest->DeepCopy()); 3712 extension_manifest.reset(manifest->DeepCopy());
3629 } 3713 }
(...skipping 27 matching lines...) Expand all
3657 3741
3658 bool Extension::HasContentScriptAtURL(const GURL& url) const { 3742 bool Extension::HasContentScriptAtURL(const GURL& url) const {
3659 for (UserScriptList::const_iterator it = content_scripts_.begin(); 3743 for (UserScriptList::const_iterator it = content_scripts_.begin();
3660 it != content_scripts_.end(); ++it) { 3744 it != content_scripts_.end(); ++it) {
3661 if (it->MatchesURL(url)) 3745 if (it->MatchesURL(url))
3662 return true; 3746 return true;
3663 } 3747 }
3664 return false; 3748 return false;
3665 } 3749 }
3666 3750
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( 3751 const URLPatternSet* Extension::GetTabSpecificHostPermissions(
3708 int tab_id) const { 3752 int tab_id) const {
3709 base::AutoLock auto_lock(runtime_data_lock_); 3753 base::AutoLock auto_lock(runtime_data_lock_);
3710 return runtime_data_.GetTabSpecificHostPermissions(tab_id); 3754 return runtime_data_.GetTabSpecificHostPermissions(tab_id);
3711 } 3755 }
3712 3756
3713 void Extension::SetTabSpecificHostPermissions( 3757 void Extension::SetTabSpecificHostPermissions(
3714 int tab_id, 3758 int tab_id,
3715 const URLPatternSet& permissions) const { 3759 const URLPatternSet& permissions) const {
3716 base::AutoLock auto_lock(runtime_data_lock_); 3760 base::AutoLock auto_lock(runtime_data_lock_);
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
3797 3841
3798 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo( 3842 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo(
3799 const Extension* extension, 3843 const Extension* extension,
3800 const ExtensionPermissionSet* permissions, 3844 const ExtensionPermissionSet* permissions,
3801 Reason reason) 3845 Reason reason)
3802 : reason(reason), 3846 : reason(reason),
3803 extension(extension), 3847 extension(extension),
3804 permissions(permissions) {} 3848 permissions(permissions) {}
3805 3849
3806 } // namespace extensions 3850 } // 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