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