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 3 // found in the LICENSE file. 4 5 #include "chrome/browser/extensions/extension_warning_badge_service.h" 6 7 #include "base/stl_util.h" 8 #include "chrome/app/chrome_command_ids.h" 9 #include "chrome/browser/extensions/extension_system.h" 10 #include "chrome/browser/ui/global_error/global_error.h" 11 #include "chrome/browser/ui/global_error/global_error_service.h" 12 #include "chrome/browser/ui/global_error/global_error_service_factory.h" 13 #include "chrome/browser/ui/browser_commands.h" 14 #include "grit/generated_resources.h" 15 #include "ui/base/l10n/l10n_util.h" 16 17 namespace extensions { 18 19 namespace { 20 // Non-modal GlobalError implementation that warns the user if extensions 21 // created warnings or errors. If the user clicks on the wrench menu, the user 22 // is redirected to chrome://extensions to inspect the errors. 23 class ErrorBadge : public GlobalError { 24 public: 25 explicit ErrorBadge(ExtensionWarningBadgeService* badge_service); 26 virtual ~ErrorBadge(); 27 28 // Implementation for GlobalError: 29 virtual bool HasMenuItem() OVERRIDE; 30 virtual int MenuItemCommandID() OVERRIDE; 31 virtual string16 MenuItemLabel() OVERRIDE; 32 virtual void ExecuteMenuItem(Browser* browser) OVERRIDE; 33 34 virtual bool HasBubbleView() OVERRIDE; 35 virtual string16 GetBubbleViewTitle() OVERRIDE; 36 virtual std::vector<string16> GetBubbleViewMessages() OVERRIDE; 37 virtual string16 GetBubbleViewAcceptButtonLabel() OVERRIDE; 38 virtual string16 GetBubbleViewCancelButtonLabel() OVERRIDE; 39 virtual void OnBubbleViewDidClose(Browser* browser) OVERRIDE; 40 virtual void BubbleViewAcceptButtonPressed(Browser* browser) OVERRIDE; 41 virtual void BubbleViewCancelButtonPressed(Browser* browser) OVERRIDE; 42 43 static int GetMenuItemCommandID(); 44 45 private: 46 ExtensionWarningBadgeService* badge_service_; 47 48 DISALLOW_COPY_AND_ASSIGN(ErrorBadge); 49 }; 50 51 ErrorBadge::ErrorBadge(ExtensionWarningBadgeService* badge_service) 52 : badge_service_(badge_service) {} 53 54 ErrorBadge::~ErrorBadge() {} 55 56 bool ErrorBadge::HasMenuItem() { 57 return true; 58 } 59 60 int ErrorBadge::MenuItemCommandID() { 61 return GetMenuItemCommandID(); 62 } 63 64 string16 ErrorBadge::MenuItemLabel() { 65 return l10n_util::GetStringUTF16(IDS_EXTENSION_WARNINGS_WRENCH_MENU_ITEM); 66 } 67 68 void ErrorBadge::ExecuteMenuItem(Browser* browser) { 69 // Suppress all current warnings in the extension service from triggering 70 // a badge on the wrench menu in the future of this session. 71 badge_service_->SuppressCurrentWarnings(); 72 73 chrome::ExecuteCommand(browser, IDC_MANAGE_EXTENSIONS); 74 } 75 76 bool ErrorBadge::HasBubbleView() { 77 return false; 78 } 79 80 string16 ErrorBadge::GetBubbleViewTitle() { 81 return string16(); 82 } 83 84 std::vector<string16> ErrorBadge::GetBubbleViewMessages() { 85 return std::vector<string16>(); 86 } 87 88 string16 ErrorBadge::GetBubbleViewAcceptButtonLabel() { 89 return string16(); 90 } 91 92 string16 ErrorBadge::GetBubbleViewCancelButtonLabel() { 93 return string16(); 94 } 95 96 void ErrorBadge::OnBubbleViewDidClose(Browser* browser) { 97 } 98 99 void ErrorBadge::BubbleViewAcceptButtonPressed(Browser* browser) { 100 NOTREACHED(); 101 } 102 103 void ErrorBadge::BubbleViewCancelButtonPressed(Browser* browser) { 104 NOTREACHED(); 105 } 106 107 // static 108 int ErrorBadge::GetMenuItemCommandID() { 109 return IDC_EXTENSION_ERRORS; 110 } 111 112 } // namespace 113 114 115 ExtensionWarningBadgeService::ExtensionWarningBadgeService(Profile* profile) 116 : profile_(profile) { 117 DCHECK(CalledOnValidThread()); 118 } 119 120 ExtensionWarningBadgeService::~ExtensionWarningBadgeService() {} 121 122 void ExtensionWarningBadgeService::SuppressCurrentWarnings() { 123 DCHECK(CalledOnValidThread()); 124 size_t old_size = suppressed_warnings_.size(); 125 126 const ExtensionWarningSet& warnings = GetCurrentWarnings(); 127 suppressed_warnings_.insert(warnings.begin(), warnings.end()); 128 129 if (old_size != suppressed_warnings_.size()) 130 UpdateBadgeStatus(); 131 } 132 133 const ExtensionWarningSet& 134 ExtensionWarningBadgeService::GetCurrentWarnings() const { 135 return ExtensionSystem::Get(profile_)->warning_service()->warnings(); 136 } 137 138 void ExtensionWarningBadgeService::ExtensionWarningsChanged() { 139 DCHECK(CalledOnValidThread()); 140 UpdateBadgeStatus(); 141 } 142 143 void ExtensionWarningBadgeService::UpdateBadgeStatus() { 144 const std::set<ExtensionWarning>& warnings = GetCurrentWarnings(); 145 bool non_suppressed_warnings_exist = false; 146 for (std::set<ExtensionWarning>::const_iterator i = warnings.begin(); 147 i != warnings.end(); ++i) { 148 if (!ContainsKey(suppressed_warnings_, *i)) { 149 non_suppressed_warnings_exist = true; 150 break; 151 } 152 } 153 ShowBadge(non_suppressed_warnings_exist); 154 } 155 156 void ExtensionWarningBadgeService::ShowBadge(bool show) { 157 GlobalErrorService* service = 158 GlobalErrorServiceFactory::GetForProfile(profile_); 159 GlobalError* error = service->GetGlobalErrorByMenuItemCommandID( 160 ErrorBadge::GetMenuItemCommandID()); 161 162 // Activate or hide the warning badge in case the current state is incorrect. 163 if (error && !show) { 164 service->RemoveGlobalError(error); 165 delete error; 166 } else if (!error && show) { 167 service->AddGlobalError(new ErrorBadge(this)); 168 } 169 } 170 171 } // extensions 172