1// Copyright 2014 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/ui/toolbar/wrench_menu_badge_controller.h" 6 7#include "base/logging.h" 8#include "chrome/browser/chrome_notification_types.h" 9#include "chrome/browser/ui/global_error/global_error_service.h" 10#include "chrome/browser/ui/global_error/global_error_service_factory.h" 11#include "chrome/browser/upgrade_detector.h" 12 13#if defined(OS_WIN) 14#include "base/win/windows_version.h" 15#include "chrome/browser/enumerate_modules_model_win.h" 16#endif 17 18namespace { 19 20// Maps an upgrade level to a severity level. 21WrenchIconPainter::Severity SeverityFromUpgradeLevel( 22 UpgradeDetector::UpgradeNotificationAnnoyanceLevel level) { 23 switch (level) { 24 case UpgradeDetector::UPGRADE_ANNOYANCE_NONE: 25 return WrenchIconPainter::SEVERITY_NONE; 26 case UpgradeDetector::UPGRADE_ANNOYANCE_LOW: 27 return WrenchIconPainter::SEVERITY_LOW; 28 case UpgradeDetector::UPGRADE_ANNOYANCE_ELEVATED: 29 return WrenchIconPainter::SEVERITY_MEDIUM; 30 case UpgradeDetector::UPGRADE_ANNOYANCE_HIGH: 31 return WrenchIconPainter::SEVERITY_HIGH; 32 case UpgradeDetector::UPGRADE_ANNOYANCE_SEVERE: 33 return WrenchIconPainter::SEVERITY_HIGH; 34 case UpgradeDetector::UPGRADE_ANNOYANCE_CRITICAL: 35 return WrenchIconPainter::SEVERITY_HIGH; 36 } 37 NOTREACHED(); 38 return WrenchIconPainter::SEVERITY_NONE; 39} 40 41// Checks if the wrench icon should be animated for the given upgrade level. 42bool ShouldAnimateUpgradeLevel( 43 UpgradeDetector::UpgradeNotificationAnnoyanceLevel level) { 44 bool should_animate = true; 45 if (level == UpgradeDetector::UPGRADE_ANNOYANCE_LOW) { 46 // Only animate low severity upgrades once. 47 static bool should_animate_low_severity = true; 48 should_animate = should_animate_low_severity; 49 should_animate_low_severity = false; 50 } 51 return should_animate; 52} 53 54// Returns true if we should show the upgrade recommended badge. 55bool ShouldShowUpgradeRecommended() { 56#if defined(OS_CHROMEOS) 57 // In chromeos, the update recommendation is shown in the system tray. So it 58 // should not be displayed in the wrench menu. 59 return false; 60#else 61 return UpgradeDetector::GetInstance()->notify_upgrade(); 62#endif 63} 64 65// Returns true if we should show the warning for incompatible software. 66bool ShouldShowIncompatibilityWarning() { 67#if defined(OS_WIN) 68 EnumerateModulesModel* loaded_modules = EnumerateModulesModel::GetInstance(); 69 loaded_modules->MaybePostScanningTask(); 70 return loaded_modules->ShouldShowConflictWarning(); 71#else 72 return false; 73#endif 74} 75 76} // namespace 77 78WrenchMenuBadgeController::WrenchMenuBadgeController(Profile* profile, 79 Delegate* delegate) 80 : profile_(profile), delegate_(delegate) { 81 DCHECK(profile_); 82 DCHECK(delegate_); 83 84 registrar_.Add(this, chrome::NOTIFICATION_UPGRADE_RECOMMENDED, 85 content::NotificationService::AllSources()); 86 registrar_.Add(this, chrome::NOTIFICATION_GLOBAL_ERRORS_CHANGED, 87 content::Source<Profile>(profile_)); 88 89#if defined(OS_WIN) 90 if (base::win::GetVersion() == base::win::VERSION_XP) { 91 registrar_.Add(this, chrome::NOTIFICATION_MODULE_LIST_ENUMERATED, 92 content::NotificationService::AllSources()); 93 } 94 registrar_.Add(this, chrome::NOTIFICATION_MODULE_INCOMPATIBILITY_BADGE_CHANGE, 95 content::NotificationService::AllSources()); 96#endif 97} 98 99WrenchMenuBadgeController::~WrenchMenuBadgeController() { 100} 101 102void WrenchMenuBadgeController::UpdateDelegate() { 103 if (ShouldShowUpgradeRecommended()) { 104 UpgradeDetector::UpgradeNotificationAnnoyanceLevel level = 105 UpgradeDetector::GetInstance()->upgrade_notification_stage(); 106 delegate_->UpdateBadgeSeverity(BADGE_TYPE_UPGRADE_NOTIFICATION, 107 SeverityFromUpgradeLevel(level), 108 ShouldAnimateUpgradeLevel(level)); 109 return; 110 } 111 112 if (ShouldShowIncompatibilityWarning()) { 113 delegate_->UpdateBadgeSeverity(BADGE_TYPE_INCOMPATIBILITY_WARNING, 114 WrenchIconPainter::SEVERITY_MEDIUM, true); 115 return; 116 } 117 118 if (GlobalErrorServiceFactory::GetForProfile(profile_)-> 119 GetHighestSeverityGlobalErrorWithWrenchMenuItem()) { 120 // If you change the severity here, make sure to also change the menu icon 121 // and the bubble icon. 122 delegate_->UpdateBadgeSeverity(BADGE_TYPE_GLOBAL_ERROR, 123 WrenchIconPainter::SEVERITY_MEDIUM, true); 124 return; 125 } 126 127 delegate_->UpdateBadgeSeverity(BADGE_TYPE_NONE, 128 WrenchIconPainter::SEVERITY_NONE, true); 129} 130 131void WrenchMenuBadgeController::Observe( 132 int type, 133 const content::NotificationSource& source, 134 const content::NotificationDetails& details) { 135 UpdateDelegate(); 136} 137