summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/chromeos/login/update_screen.cc74
-rw-r--r--chrome/browser/chromeos/login/update_screen.h14
-rw-r--r--chrome/browser/chromeos/login/update_screen_browsertest.cc1
3 files changed, 80 insertions, 9 deletions
diff --git a/chrome/browser/chromeos/login/update_screen.cc b/chrome/browser/chromeos/login/update_screen.cc
index 6f58ac1..d33c706 100644
--- a/chrome/browser/chromeos/login/update_screen.cc
+++ b/chrome/browser/chromeos/login/update_screen.cc
@@ -4,6 +4,7 @@
#include "chrome/browser/chromeos/login/update_screen.h"
+#include "base/file_util.h"
#include "base/logging.h"
#include "chrome/browser/chromeos/cros/cros_library.h"
#include "chrome/browser/chromeos/login/screen_observer.h"
@@ -29,6 +30,8 @@ const int kDownloadProgressIncrement = 60;
const int kUpdateScreenWidth = 580;
const int kUpdateScreenHeight = 305;
+const char kUpdateDeadlineFile[] = "/tmp/update-check-response-deadline";
+
} // anonymous namespace
namespace chromeos {
@@ -39,7 +42,9 @@ UpdateScreen::UpdateScreen(WizardScreenDelegate* delegate)
kUpdateScreenHeight),
checking_for_update_(true),
maximal_curtain_time_(0),
- reboot_check_delay_(0) {
+ reboot_check_delay_(0),
+ is_downloading_update_(false),
+ is_all_updates_critical_(false) {
}
UpdateScreen::~UpdateScreen() {
@@ -62,10 +67,30 @@ void UpdateScreen::UpdateStatusChanged(UpdateLibrary* library) {
break;
case UPDATE_STATUS_UPDATE_AVAILABLE:
view()->SetProgress(kBeforeDownloadProgress);
- VLOG(1) << "Update available: " << library->status().new_version;
+ if (!HasCriticalUpdate()) {
+ VLOG(1) << "Noncritical update available: "
+ << library->status().new_version;
+ ExitUpdate();
+ } else {
+ VLOG(1) << "Critical update available: "
+ << library->status().new_version;
+ }
break;
case UPDATE_STATUS_DOWNLOADING:
{
+ if (!is_downloading_update_) {
+ // Because update engine doesn't send UPDATE_STATUS_UPDATE_AVAILABLE
+ // we need to is update critical on first downloading notification.
+ is_downloading_update_ = true;
+ if (!HasCriticalUpdate()) {
+ VLOG(1) << "Non-critical update available: "
+ << library->status().new_version;
+ ExitUpdate();
+ } else {
+ VLOG(1) << "Critical update available: "
+ << library->status().new_version;
+ }
+ }
view()->ShowCurtain(false);
int download_progress = static_cast<int>(
library->status().download_progress * kDownloadProgressIncrement);
@@ -82,12 +107,16 @@ void UpdateScreen::UpdateStatusChanged(UpdateLibrary* library) {
// Make sure that first OOBE stage won't be shown after reboot.
WizardController::MarkOobeCompleted();
view()->SetProgress(kProgressComplete);
- view()->ShowCurtain(false);
- CrosLibrary::Get()->GetUpdateLibrary()->RebootAfterUpdate();
- VLOG(1) << "Reboot API was called. Waiting for reboot.";
- reboot_timer_.Start(base::TimeDelta::FromSeconds(reboot_check_delay_),
- this,
- &UpdateScreen::OnWaitForRebootTimeElapsed);
+ if (HasCriticalUpdate()) {
+ view()->ShowCurtain(false);
+ VLOG(1) << "Initiate reboot after update";
+ CrosLibrary::Get()->GetUpdateLibrary()->RebootAfterUpdate();
+ reboot_timer_.Start(base::TimeDelta::FromSeconds(reboot_check_delay_),
+ this,
+ &UpdateScreen::OnWaitForRebootTimeElapsed);
+ } else {
+ ExitUpdate();
+ }
break;
case UPDATE_STATUS_IDLE:
case UPDATE_STATUS_ERROR:
@@ -104,6 +133,7 @@ void UpdateScreen::StartUpdate() {
// Reset view.
view()->Reset();
view()->set_controller(this);
+ is_downloading_update_ = false;
// Start the maximal curtain time timer.
if (maximal_curtain_time_ > 0) {
@@ -121,7 +151,7 @@ void UpdateScreen::StartUpdate() {
LOG(ERROR) << "Error loading CrosLibrary";
} else {
CrosLibrary::Get()->GetUpdateLibrary()->AddObserver(this);
- VLOG(1) << "Checking for update";
+ VLOG(1) << "Initiate update check";
if (!CrosLibrary::Get()->GetUpdateLibrary()->CheckForUpdate()) {
ExitUpdate();
}
@@ -145,6 +175,12 @@ void UpdateScreen::ExitUpdate() {
UpdateLibrary* update_library = CrosLibrary::Get()->GetUpdateLibrary();
update_library->RemoveObserver(this);
switch (update_library->status().status) {
+ case UPDATE_STATUS_UPDATE_AVAILABLE:
+ case UPDATE_STATUS_UPDATED_NEED_REBOOT:
+ case UPDATE_STATUS_DOWNLOADING:
+ DCHECK(!HasCriticalUpdate());
+ // Noncritical update, just exit screen as if there is no update.
+ // no break
case UPDATE_STATUS_IDLE:
observer->OnExit(ScreenObserver::UPDATE_NOUPDATE);
break;
@@ -182,4 +218,24 @@ void UpdateScreen::SetRebootCheckDelay(int seconds) {
reboot_check_delay_ = seconds;
}
+bool UpdateScreen::HasCriticalUpdate() {
+ if (is_all_updates_critical_)
+ return true;
+
+ std::string deadline;
+ FilePath update_deadline_file_path(kUpdateDeadlineFile);
+ if (!file_util::ReadFileToString(update_deadline_file_path, &deadline) ||
+ deadline.empty()) {
+ return false;
+ }
+
+ // TODO(dpolukhin): Analyze file content. Now we can just assume that
+ // if the file exists and not empty, there is critical update.
+ return true;
+}
+
+void UpdateScreen::SetAllUpdatesCritical(bool is_critical) {
+ is_all_updates_critical_ = is_critical;
+}
+
} // namespace chromeos
diff --git a/chrome/browser/chromeos/login/update_screen.h b/chrome/browser/chromeos/login/update_screen.h
index 2253c2e..5741c5e 100644
--- a/chrome/browser/chromeos/login/update_screen.h
+++ b/chrome/browser/chromeos/login/update_screen.h
@@ -46,6 +46,14 @@ class UpdateScreen: public DefaultViewScreen<chromeos::UpdateView>,
int reboot_check_delay() const { return reboot_check_delay_; }
void SetRebootCheckDelay(int seconds);
+ // Returns true if there is critical system update that requires installation
+ // and immediate reboot.
+ bool HasCriticalUpdate();
+
+ // Set flag to treat all updates as critical (for test purpose mainly).
+ // Default value is false.
+ void SetAllUpdatesCritical(bool is_critical);
+
private:
// Timer notification handlers.
void OnMaximalCurtainTimeElapsed();
@@ -70,6 +78,12 @@ class UpdateScreen: public DefaultViewScreen<chromeos::UpdateView>,
// reboot device manually.
int reboot_check_delay_;
+ // Flag that is used to detect when update download has just started.
+ bool is_downloading_update_;
+
+ // Is all updates critical? If true, update deadlines are ignored.
+ bool is_all_updates_critical_;
+
DISALLOW_COPY_AND_ASSIGN(UpdateScreen);
};
diff --git a/chrome/browser/chromeos/login/update_screen_browsertest.cc b/chrome/browser/chromeos/login/update_screen_browsertest.cc
index ebf09dd..02f4eb9 100644
--- a/chrome/browser/chromeos/login/update_screen_browsertest.cc
+++ b/chrome/browser/chromeos/login/update_screen_browsertest.cc
@@ -112,6 +112,7 @@ IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestUpdateAvailable) {
UpdateScreen* update_screen = controller()->GetUpdateScreen();
ASSERT_TRUE(update_screen != NULL);
ASSERT_EQ(controller()->current_screen(), update_screen);
+ update_screen->SetAllUpdatesCritical(true);
UpdateLibrary::Status status;