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
18 namespace {
19
20 // Maps an upgrade level to a severity level.
SeverityFromUpgradeLevel(UpgradeDetector::UpgradeNotificationAnnoyanceLevel level)21 WrenchIconPainter::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.
ShouldAnimateUpgradeLevel(UpgradeDetector::UpgradeNotificationAnnoyanceLevel level)42 bool 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.
ShouldShowUpgradeRecommended()55 bool 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.
ShouldShowIncompatibilityWarning()66 bool 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
WrenchMenuBadgeController(Profile * profile,Delegate * delegate)78 WrenchMenuBadgeController::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
~WrenchMenuBadgeController()99 WrenchMenuBadgeController::~WrenchMenuBadgeController() {
100 }
101
UpdateDelegate()102 void 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
Observe(int type,const content::NotificationSource & source,const content::NotificationDetails & details)131 void WrenchMenuBadgeController::Observe(
132 int type,
133 const content::NotificationSource& source,
134 const content::NotificationDetails& details) {
135 UpdateDelegate();
136 }
137