1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
// 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/chromeos/upgrade_detector_chromeos.h"
#include "base/memory/singleton.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/update_engine_client.h"
using chromeos::DBusThreadManager;
using chromeos::UpdateEngineClient;
namespace {
// How long to wait (each cycle) before checking which severity level we should
// be at. Once we reach the highest severity, the timer will stop.
const int kNotifyCycleTimeMs = 20 * 60 * 1000; // 20 minutes.
} // namespace
class UpgradeDetectorChromeos::ChannelsRequester {
public:
typedef base::Callback<void(const std::string&, const std::string&)>
OnChannelsReceivedCallback;
ChannelsRequester() : weak_factory_(this) {}
void RequestChannels(const OnChannelsReceivedCallback& callback) {
UpdateEngineClient* client =
DBusThreadManager::Get()->GetUpdateEngineClient();
callback_ = callback;
client->GetChannel(true /* get_current_channel */,
base::Bind(&ChannelsRequester::SetCurrentChannel,
weak_factory_.GetWeakPtr()));
client->GetChannel(false /* get_current_channel */,
base::Bind(&ChannelsRequester::SetTargetChannel,
weak_factory_.GetWeakPtr()));
}
private:
void SetCurrentChannel(const std::string& current_channel) {
DCHECK(!current_channel.empty());
current_channel_ = current_channel;
TriggerCallbackIfReady();
}
void SetTargetChannel(const std::string& target_channel) {
DCHECK(!target_channel.empty());
target_channel_ = target_channel;
TriggerCallbackIfReady();
}
void TriggerCallbackIfReady() {
if (current_channel_.empty() || target_channel_.empty())
return;
if (!callback_.is_null())
callback_.Run(current_channel_, target_channel_);
}
std::string current_channel_;
std::string target_channel_;
OnChannelsReceivedCallback callback_;
base::WeakPtrFactory<ChannelsRequester> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(ChannelsRequester);
};
UpgradeDetectorChromeos::UpgradeDetectorChromeos()
: initialized_(false), weak_factory_(this) {
}
UpgradeDetectorChromeos::~UpgradeDetectorChromeos() {
}
void UpgradeDetectorChromeos::Init() {
DBusThreadManager::Get()->GetUpdateEngineClient()->AddObserver(this);
initialized_ = true;
}
void UpgradeDetectorChromeos::Shutdown() {
// Init() may not be called from tests.
if (!initialized_)
return;
DBusThreadManager::Get()->GetUpdateEngineClient()->RemoveObserver(this);
}
void UpgradeDetectorChromeos::UpdateStatusChanged(
const UpdateEngineClient::Status& status) {
if (status.status != UpdateEngineClient::UPDATE_STATUS_UPDATED_NEED_REBOOT)
return;
upgrade_detected_time_ = base::Time::Now();
channels_requester_.reset(new UpgradeDetectorChromeos::ChannelsRequester());
channels_requester_->RequestChannels(
base::Bind(&UpgradeDetectorChromeos::OnChannelsReceived,
weak_factory_.GetWeakPtr()));
}
void UpgradeDetectorChromeos::NotifyOnUpgrade() {
base::TimeDelta delta = base::Time::Now() - upgrade_detected_time_;
int64 time_passed = delta.InDays();
const int kSevereThreshold = 7;
const int kHighThreshold = 4;
const int kElevatedThreshold = 2;
const int kLowThreshold = 0;
// These if statements must be sorted (highest interval first).
if (time_passed >= kSevereThreshold) {
set_upgrade_notification_stage(UPGRADE_ANNOYANCE_SEVERE);
// We can't get any higher, baby.
upgrade_notification_timer_.Stop();
} else if (time_passed >= kHighThreshold) {
set_upgrade_notification_stage(UPGRADE_ANNOYANCE_HIGH);
} else if (time_passed >= kElevatedThreshold) {
set_upgrade_notification_stage(UPGRADE_ANNOYANCE_ELEVATED);
} else if (time_passed >= kLowThreshold) {
set_upgrade_notification_stage(UPGRADE_ANNOYANCE_LOW);
} else {
return; // Not ready to recommend upgrade.
}
NotifyUpgradeRecommended();
}
void UpgradeDetectorChromeos::OnChannelsReceived(
const std::string& current_channel,
const std::string& target_channel) {
// As current update engine status is UPDATE_STATUS_UPDATED_NEED_REBOOT
// and target channel is more stable than current channel, powerwash
// will be performed after reboot.
set_is_factory_reset_required(UpdateEngineClient::IsTargetChannelMoreStable(
current_channel, target_channel));
// ChromeOS shows upgrade arrow once the upgrade becomes available.
NotifyOnUpgrade();
// Setup timer to to move along the upgrade advisory system.
upgrade_notification_timer_.Start(
FROM_HERE,
base::TimeDelta::FromMilliseconds(kNotifyCycleTimeMs),
this,
&UpgradeDetectorChromeos::NotifyOnUpgrade);
}
// static
UpgradeDetectorChromeos* UpgradeDetectorChromeos::GetInstance() {
return Singleton<UpgradeDetectorChromeos>::get();
}
// static
UpgradeDetector* UpgradeDetector::GetInstance() {
return UpgradeDetectorChromeos::GetInstance();
}
|