15f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// found in the LICENSE file.
45f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
55f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/ui/toolbar/wrench_menu_badge_controller.h"
65f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/logging.h"
85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/chrome_notification_types.h"
95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/ui/global_error/global_error_service.h"
105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/ui/global_error/global_error_service_factory.h"
115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/upgrade_detector.h"
125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(OS_WIN)
145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/win/windows_version.h"
155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/enumerate_modules_model_win.h"
165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif
175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace {
195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Maps an upgrade level to a severity level.
215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)WrenchIconPainter::Severity SeverityFromUpgradeLevel(
225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    UpgradeDetector::UpgradeNotificationAnnoyanceLevel level) {
235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  switch (level) {
245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case UpgradeDetector::UPGRADE_ANNOYANCE_NONE:
255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return WrenchIconPainter::SEVERITY_NONE;
265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case UpgradeDetector::UPGRADE_ANNOYANCE_LOW:
275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return WrenchIconPainter::SEVERITY_LOW;
285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case UpgradeDetector::UPGRADE_ANNOYANCE_ELEVATED:
295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return WrenchIconPainter::SEVERITY_MEDIUM;
305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case UpgradeDetector::UPGRADE_ANNOYANCE_HIGH:
315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return WrenchIconPainter::SEVERITY_HIGH;
325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case UpgradeDetector::UPGRADE_ANNOYANCE_SEVERE:
335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return WrenchIconPainter::SEVERITY_HIGH;
345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case UpgradeDetector::UPGRADE_ANNOYANCE_CRITICAL:
355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return WrenchIconPainter::SEVERITY_HIGH;
365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  NOTREACHED();
385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return WrenchIconPainter::SEVERITY_NONE;
395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Checks if the wrench icon should be animated for the given upgrade level.
425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool ShouldAnimateUpgradeLevel(
435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    UpgradeDetector::UpgradeNotificationAnnoyanceLevel level) {
445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool should_animate = true;
455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (level == UpgradeDetector::UPGRADE_ANNOYANCE_LOW) {
465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Only animate low severity upgrades once.
475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    static bool should_animate_low_severity = true;
485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    should_animate = should_animate_low_severity;
495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    should_animate_low_severity = false;
505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return should_animate;
525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Returns true if we should show the upgrade recommended badge.
555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool ShouldShowUpgradeRecommended() {
565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(OS_CHROMEOS)
575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // In chromeos, the update recommendation is shown in the system tray. So it
585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // should not be displayed in the wrench menu.
595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return false;
605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#else
615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return UpgradeDetector::GetInstance()->notify_upgrade();
625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif
635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Returns true if we should show the warning for incompatible software.
665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool ShouldShowIncompatibilityWarning() {
675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(OS_WIN)
685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EnumerateModulesModel* loaded_modules = EnumerateModulesModel::GetInstance();
695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  loaded_modules->MaybePostScanningTask();
705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return loaded_modules->ShouldShowConflictWarning();
715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#else
725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return false;
735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif
745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}  // namespace
775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)WrenchMenuBadgeController::WrenchMenuBadgeController(Profile* profile,
795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                     Delegate* delegate)
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    : profile_(profile), delegate_(delegate) {
815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(profile_);
825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(delegate_);
835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  registrar_.Add(this, chrome::NOTIFICATION_UPGRADE_RECOMMENDED,
855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 content::NotificationService::AllSources());
865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  registrar_.Add(this, chrome::NOTIFICATION_GLOBAL_ERRORS_CHANGED,
875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 content::Source<Profile>(profile_));
885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(OS_WIN)
905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (base::win::GetVersion() == base::win::VERSION_XP) {
915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    registrar_.Add(this, chrome::NOTIFICATION_MODULE_LIST_ENUMERATED,
925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   content::NotificationService::AllSources());
935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  registrar_.Add(this, chrome::NOTIFICATION_MODULE_INCOMPATIBILITY_BADGE_CHANGE,
955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 content::NotificationService::AllSources());
965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif
975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)WrenchMenuBadgeController::~WrenchMenuBadgeController() {
1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void WrenchMenuBadgeController::UpdateDelegate() {
1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (ShouldShowUpgradeRecommended()) {
1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    UpgradeDetector::UpgradeNotificationAnnoyanceLevel level =
1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        UpgradeDetector::GetInstance()->upgrade_notification_stage();
1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    delegate_->UpdateBadgeSeverity(BADGE_TYPE_UPGRADE_NOTIFICATION,
1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                   SeverityFromUpgradeLevel(level),
1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                   ShouldAnimateUpgradeLevel(level));
1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (ShouldShowIncompatibilityWarning()) {
1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    delegate_->UpdateBadgeSeverity(BADGE_TYPE_INCOMPATIBILITY_WARNING,
1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                   WrenchIconPainter::SEVERITY_MEDIUM, true);
1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (GlobalErrorServiceFactory::GetForProfile(profile_)->
1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          GetHighestSeverityGlobalErrorWithWrenchMenuItem()) {
1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // If you change the severity here, make sure to also change the menu icon
1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // and the bubble icon.
1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    delegate_->UpdateBadgeSeverity(BADGE_TYPE_GLOBAL_ERROR,
1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                   WrenchIconPainter::SEVERITY_MEDIUM, true);
1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  delegate_->UpdateBadgeSeverity(BADGE_TYPE_NONE,
1285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                 WrenchIconPainter::SEVERITY_NONE, true);
1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void WrenchMenuBadgeController::Observe(
1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    int type,
1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const content::NotificationSource& source,
1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const content::NotificationDetails& details) {
1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  UpdateDelegate();
1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
137