| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/upgrade_detector.h" |
| |
| #include "base/bind.h" |
| #include "base/command_line.h" |
| #include "chrome/app/vector_icons/vector_icons.h" |
| #include "chrome/browser/lifetime/application_lifetime.h" |
| #include "chrome/browser/ui/browser_otr_state.h" |
| #include "chrome/common/chrome_switches.h" |
| #include "chrome/common/pref_names.h" |
| #include "components/prefs/pref_registry_simple.h" |
| #include "ui/gfx/color_palette.h" |
| #include "ui/gfx/paint_vector_icon.h" |
| |
| // How long to wait between checks for whether the user has been idle. |
| static const int kIdleRepeatingTimerWait = 10; // Minutes (seconds if testing). |
| |
| // How much idle time (since last input even was detected) must have passed |
| // until we notify that a critical update has occurred. |
| static const int kIdleAmount = 2; // Hours (or seconds, if testing). |
| |
| bool UseTestingIntervals() { |
| // If a command line parameter specifying how long the upgrade check should |
| // be, we assume it is for testing and switch to using seconds instead of |
| // hours. |
| const base::CommandLine& cmd_line = *base::CommandLine::ForCurrentProcess(); |
| return !cmd_line.GetSwitchValueASCII( |
| switches::kCheckForUpdateIntervalSec).empty(); |
| } |
| |
| // static |
| void UpgradeDetector::RegisterPrefs(PrefRegistrySimple* registry) { |
| registry->RegisterBooleanPref(prefs::kAttemptedToEnableAutoupdate, false); |
| } |
| |
| gfx::Image UpgradeDetector::GetIcon() { |
| SkColor color = gfx::kPlaceholderColor; |
| switch (upgrade_notification_stage_) { |
| case UPGRADE_ANNOYANCE_NONE: |
| return gfx::Image(); |
| case UPGRADE_ANNOYANCE_LOW: |
| color = gfx::kGoogleGreen700; |
| break; |
| case UPGRADE_ANNOYANCE_ELEVATED: |
| color = gfx::kGoogleYellow700; |
| break; |
| case UPGRADE_ANNOYANCE_HIGH: |
| case UPGRADE_ANNOYANCE_SEVERE: |
| case UPGRADE_ANNOYANCE_CRITICAL: |
| color = gfx::kGoogleRed700; |
| break; |
| } |
| DCHECK_NE(gfx::kPlaceholderColor, color); |
| |
| return gfx::Image(gfx::CreateVectorIcon(kBrowserToolsUpdateIcon, color)); |
| } |
| |
| UpgradeDetector::UpgradeDetector() |
| : upgrade_available_(UPGRADE_AVAILABLE_NONE), |
| best_effort_experiment_updates_available_(false), |
| critical_experiment_updates_available_(false), |
| critical_update_acknowledged_(false), |
| is_factory_reset_required_(false), |
| upgrade_notification_stage_(UPGRADE_ANNOYANCE_NONE), |
| notify_upgrade_(false) { |
| } |
| |
| UpgradeDetector::~UpgradeDetector() { |
| } |
| |
| void UpgradeDetector::NotifyOutdatedInstall() { |
| for (auto& observer : observer_list_) |
| observer.OnOutdatedInstall(); |
| } |
| |
| void UpgradeDetector::NotifyOutdatedInstallNoAutoUpdate() { |
| for (auto& observer : observer_list_) |
| observer.OnOutdatedInstallNoAutoUpdate(); |
| } |
| |
| void UpgradeDetector::NotifyUpgrade() { |
| notify_upgrade_ = true; |
| |
| NotifyUpgradeRecommended(); |
| if (upgrade_available_ == UPGRADE_NEEDED_OUTDATED_INSTALL) { |
| NotifyOutdatedInstall(); |
| } else if (upgrade_available_ == UPGRADE_NEEDED_OUTDATED_INSTALL_NO_AU) { |
| NotifyOutdatedInstallNoAutoUpdate(); |
| } else if (upgrade_available_ == UPGRADE_AVAILABLE_CRITICAL || |
| critical_experiment_updates_available_) { |
| TriggerCriticalUpdate(); |
| } |
| } |
| |
| void UpgradeDetector::NotifyUpgradeRecommended() { |
| for (auto& observer : observer_list_) |
| observer.OnUpgradeRecommended(); |
| } |
| |
| void UpgradeDetector::NotifyCriticalUpgradeInstalled() { |
| for (auto& observer : observer_list_) |
| observer.OnCriticalUpgradeInstalled(); |
| } |
| |
| void UpgradeDetector::NotifyUpdateOverCellularAvailable() { |
| for (auto& observer : observer_list_) |
| observer.OnUpdateOverCellularAvailable(); |
| } |
| |
| void UpgradeDetector::NotifyUpdateOverCellularOneTimePermissionGranted() { |
| for (auto& observer : observer_list_) |
| observer.OnUpdateOverCellularOneTimePermissionGranted(); |
| } |
| |
| void UpgradeDetector::TriggerCriticalUpdate() { |
| const base::TimeDelta idle_timer = UseTestingIntervals() ? |
| base::TimeDelta::FromSeconds(kIdleRepeatingTimerWait) : |
| base::TimeDelta::FromMinutes(kIdleRepeatingTimerWait); |
| idle_check_timer_.Start(FROM_HERE, idle_timer, this, |
| &UpgradeDetector::CheckIdle); |
| } |
| |
| void UpgradeDetector::CheckIdle() { |
| // CalculateIdleState expects an interval in seconds. |
| int idle_time_allowed = UseTestingIntervals() ? kIdleAmount : |
| kIdleAmount * 60 * 60; |
| |
| CalculateIdleState( |
| idle_time_allowed, base::Bind(&UpgradeDetector::IdleCallback, |
| base::Unretained(this))); |
| } |
| |
| void UpgradeDetector::IdleCallback(ui::IdleState state) { |
| // Don't proceed while an incognito window is open. The timer will still |
| // keep firing, so this function will get a chance to re-evaluate this. |
| if (chrome::IsIncognitoSessionActive()) |
| return; |
| |
| switch (state) { |
| case ui::IDLE_STATE_LOCKED: |
| // Computer is locked, auto-restart. |
| idle_check_timer_.Stop(); |
| chrome::AttemptRestart(); |
| break; |
| case ui::IDLE_STATE_IDLE: |
| // Computer has been idle for long enough, show warning. |
| idle_check_timer_.Stop(); |
| NotifyCriticalUpgradeInstalled(); |
| break; |
| case ui::IDLE_STATE_ACTIVE: |
| case ui::IDLE_STATE_UNKNOWN: |
| break; |
| default: |
| NOTREACHED(); // Need to add any new value above (either providing |
| // automatic restart or show notification to user). |
| break; |
| } |
| } |
| |
| void UpgradeDetector::AddObserver(UpgradeObserver* observer) { |
| observer_list_.AddObserver(observer); |
| } |
| |
| void UpgradeDetector::RemoveObserver(UpgradeObserver* observer) { |
| observer_list_.RemoveObserver(observer); |
| } |