Use Chrome update UI for Chrome OS updates.

BUG=279 (Chromium OS) (Not Complete)
TEST=none

Review URL: http://codereview.chromium.org/587006

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@38697 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/chromeos/google_update_chromeos.cc b/chrome/browser/chromeos/google_update_chromeos.cc
new file mode 100644
index 0000000..2aab04a
--- /dev/null
+++ b/chrome/browser/chromeos/google_update_chromeos.cc
@@ -0,0 +1,114 @@
+// Copyright (c) 2006-2008 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/google_update.h"
+
+#include "base/message_loop.h"
+#include "base/path_service.h"
+#include "base/string_util.h"
+#include "base/task.h"
+#include "base/thread.h"
+#include "base/utf_string_conversions.h"
+#include "chrome/browser/chrome_thread.h"
+#include "chrome/browser/chromeos/cros/cros_library.h"
+#include "third_party/cros/chromeos_update.h"
+#include "views/window/window.h"
+
+using views::Window;
+
+////////////////////////////////////////////////////////////////////////////////
+// GoogleUpdate, public:
+
+GoogleUpdate::GoogleUpdate()
+    : listener_(NULL) {
+  chromeos::CrosLibrary::EnsureLoaded();
+}
+
+GoogleUpdate::~GoogleUpdate() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// GoogleUpdate, views::DialogDelegate implementation:
+
+void GoogleUpdate::CheckForUpdate(bool install_if_newer, Window* window) {
+  // We need to shunt this request over to InitiateGoogleUpdateCheck and have
+  // it run in the file thread.
+  ChromeThread::PostTask(
+      ChromeThread::FILE, FROM_HERE,
+      NewRunnableMethod(
+          this, &GoogleUpdate::InitiateGoogleUpdateCheck, install_if_newer,
+          window, MessageLoop::current()));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// GoogleUpdate, private:
+
+bool GoogleUpdate::InitiateGoogleUpdateCheck(bool install_if_newer,
+                                             Window* window,
+                                             MessageLoop* main_loop) {
+  chromeos::UpdateInformation result;
+  bool success = false;
+
+  if (install_if_newer) {
+    // Possible Results:
+    //  UPGRADE_SUCCESSFUL
+    //  UPGRADE_ALREADY_UP_TO_DATE
+    //  UPGRADE_ERROR
+    if (chromeos::Update) {
+      success = chromeos::Update(&result);
+    }
+  } else {
+    // Possible Results:
+    //  UPGRADE_ALREADY_UP_TO_DATE
+    //  UPGRADE_IS_AVAILABLE
+    //  UPGRADE_ERROR
+    if (chromeos::CheckForUpdate) {
+      success = chromeos::CheckForUpdate(&result);
+    }
+    if (result.version_) {
+      UTF8ToWide(result.version_, std::strlen(result.version_),
+                 &version_available_);
+    }
+  }
+
+  // Map chromeos::UpdateStatus to GoogleUpdateUpgradeResult
+
+  GoogleUpdateUpgradeResult final = UPGRADE_ERROR;
+
+  switch (result.status_) {
+    case chromeos::UPDATE_ERROR:
+      final = UPGRADE_ERROR;
+      break;
+    case chromeos::UPDATE_IS_AVAILABLE:
+      final = UPGRADE_IS_AVAILABLE;
+      break;
+    case chromeos::UPDATE_SUCCESSFUL:
+      final = UPGRADE_SUCCESSFUL;
+      break;
+    case chromeos::UPDATE_ALREADY_UP_TO_DATE:
+      final = UPGRADE_ALREADY_UP_TO_DATE;
+      break;
+    default:
+      // UPGRADE_ERROR
+      break;
+  }
+
+  // Post the results as a task since this is run on a thread.
+
+  main_loop->PostTask(FROM_HERE, NewRunnableMethod(this,
+      &GoogleUpdate::ReportResults, final, success
+      ?  GOOGLE_UPDATE_NO_ERROR : GOOGLE_UPDATE_ERROR_UPDATING));
+
+  return true;
+}
+
+void GoogleUpdate::ReportResults(GoogleUpdateUpgradeResult results,
+                                 GoogleUpdateErrorCode error_code) {
+  // If we get an error, then error code must not be blank, and vice versa.
+  DCHECK(results == UPGRADE_ERROR ? error_code != GOOGLE_UPDATE_NO_ERROR :
+                                    error_code == GOOGLE_UPDATE_NO_ERROR);
+  if (listener_)
+    listener_->OnReportResults(results, error_code, version_available_);
+}
+
diff --git a/chrome/browser/google_update.cc b/chrome/browser/google_update.cc
index 5cddc0f..dca2e9d 100644
--- a/chrome/browser/google_update.cc
+++ b/chrome/browser/google_update.cc
@@ -219,17 +219,6 @@
           window, MessageLoop::current()));
 }
 
-// Adds/removes a listener. Only one listener is maintained at the moment.
-void GoogleUpdate::AddStatusChangeListener(
-    GoogleUpdateStatusListener* listener) {
-  DCHECK(!listener_);
-  listener_ = listener;
-}
-
-void GoogleUpdate::RemoveStatusChangeListener() {
-  listener_ = NULL;
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // GoogleUpdate, private:
 
diff --git a/chrome/browser/google_update.h b/chrome/browser/google_update.h
index b2b0961..b430a08 100644
--- a/chrome/browser/google_update.h
+++ b/chrome/browser/google_update.h
@@ -9,7 +9,9 @@
 
 #include "base/basictypes.h"
 #include "base/ref_counted.h"
+#if defined(OS_WIN)
 #include "google_update_idl.h"
+#endif
 
 class MessageLoop;
 namespace views {
@@ -91,16 +93,28 @@
   // be null.
   void CheckForUpdate(bool install_if_newer, views::Window* window);
 
-  // Adds/removes a listener to report status back to. Only one listener is
-  // maintained at the moment.
-  void AddStatusChangeListener(GoogleUpdateStatusListener* listener);
-  void RemoveStatusChangeListener();
+  // Pass NULL to clear the listener
+  void set_status_listener(GoogleUpdateStatusListener* listener) {
+    listener_ = listener;
+  }
 
  private:
   friend class base::RefCountedThreadSafe<GoogleUpdate>;
 
   virtual ~GoogleUpdate();
 
+// The chromeos implementation is in browser/chromeos/google_update.cpp
+
+#if defined(OS_WIN)
+
+  // This function reports failure from the Google Update operation to the
+  // listener.
+  // Note, after this function completes, this object will have deleted itself.
+  bool ReportFailure(HRESULT hr, GoogleUpdateErrorCode error_code,
+                     MessageLoop* main_loop);
+
+#endif
+
   // We need to run the update check on another thread than the main thread, and
   // therefore CheckForUpdate will delegate to this function. |main_loop| points
   // to the message loop that we want the response to come from.
@@ -116,19 +130,13 @@
   void ReportResults(GoogleUpdateUpgradeResult results,
                      GoogleUpdateErrorCode error_code);
 
-  // This function reports failure from the Google Update operation to the
-  // listener.
-  // Note, after this function completes, this object will have deleted itself.
-  bool ReportFailure(HRESULT hr, GoogleUpdateErrorCode error_code,
-                     MessageLoop* main_loop);
-
-  // The listener who is interested in finding out the result of the operation.
-  GoogleUpdateStatusListener* listener_;
-
   // Which version string Google Update found (if a new one was available).
   // Otherwise, this will be blank.
   std::wstring version_available_;
 
+  // The listener who is interested in finding out the result of the operation.
+  GoogleUpdateStatusListener* listener_;
+
   DISALLOW_EVIL_CONSTRUCTORS(GoogleUpdate);
 };
 
diff --git a/chrome/browser/views/about_chrome_view.cc b/chrome/browser/views/about_chrome_view.cc
index 36971a41..544f0335 100755
--- a/chrome/browser/views/about_chrome_view.cc
+++ b/chrome/browser/views/about_chrome_view.cc
@@ -105,9 +105,9 @@
 #endif
   Init();
 
-#if defined(OS_WIN)
+#if defined(OS_WIN) || defined(OS_CHROMEOS)
   google_updater_ = new GoogleUpdate();
-  google_updater_->AddStatusChangeListener(this);
+  google_updater_->set_status_listener(this);
 #endif
 
   if (kBackgroundBmp == NULL) {
@@ -117,11 +117,11 @@
 }
 
 AboutChromeView::~AboutChromeView() {
-#if defined(OS_WIN)
+#if defined(OS_WIN) || defined(OS_CHROMEOS)
   // The Google Updater will hold a pointer to us until it reports status, so we
   // need to let it know that we will no longer be listening.
   if (google_updater_)
-    google_updater_->RemoveStatusChangeListener();
+    google_updater_->set_status_listener(NULL);
 #endif
 }
 
@@ -648,7 +648,7 @@
       parent->AddChildView(&timeout_indicator_);
       timeout_indicator_.SetVisible(false);
 
-#if defined (OS_WIN)
+#if defined(OS_WIN)
       // On-demand updates for Chrome don't work in Vista RTM when UAC is turned
       // off. So, in this case we just want the About box to not mention
       // on-demand updates. Silent updates (in the background) should still
@@ -665,6 +665,10 @@
         // CheckForUpdate(false, ...) means don't upgrade yet.
         google_updater_->CheckForUpdate(false, window());
       }
+#elif defined(OS_CHROMEOS)
+      UpdateStatus(UPGRADE_CHECK_STARTED, GOOGLE_UPDATE_NO_ERROR);
+      // CheckForUpdate(false, ...) means don't upgrade yet.
+      google_updater_->CheckForUpdate(false, window());
 #endif
     } else {
       parent->RemoveChildView(&update_label_);
@@ -739,7 +743,7 @@
 }
 
 bool AboutChromeView::Accept() {
-#if defined(OS_WIN)
+#if defined(OS_WIN) || defined(OS_CHROMEOS)
   UpdateStatus(UPGRADE_STARTED, GOOGLE_UPDATE_NO_ERROR);
 
   // The Upgrade button isn't available until we have received notification
@@ -747,7 +751,7 @@
   // null-ed out.
   DCHECK(!google_updater_);
   google_updater_ = new GoogleUpdate();
-  google_updater_->AddStatusChangeListener(this);
+  google_updater_->set_status_listener(this);
   // CheckForUpdate(true,...) means perform the upgrade if new version found.
   google_updater_->CheckForUpdate(true, window());
 #endif
@@ -790,7 +794,7 @@
 }
 #endif
 
-#if defined(OS_WIN)
+#if defined(OS_WIN) || defined(OS_CHROMEOS)
 ////////////////////////////////////////////////////////////////////////////////
 // AboutChromeView, GoogleUpdateStatusListener implementation:
 
@@ -805,13 +809,12 @@
   new_version_available_ = version;
   UpdateStatus(result, error_code);
 }
-
 ////////////////////////////////////////////////////////////////////////////////
 // AboutChromeView, private:
 
 void AboutChromeView::UpdateStatus(GoogleUpdateUpgradeResult result,
                                    GoogleUpdateErrorCode error_code) {
-#if !defined(GOOGLE_CHROME_BUILD)
+#if !defined(GOOGLE_CHROME_BUILD) && !defined(OS_CHROMEOS)
   // For Chromium builds it would show an error message.
   // But it looks weird because in fact there is no error,
   // just the update server is not available for non-official builds.
@@ -845,6 +848,12 @@
       show_update_available_indicator = true;
       break;
     case UPGRADE_ALREADY_UP_TO_DATE: {
+      // The extra version check is necessary on Windows because the application
+      // may be already up to date on disk though the running app is still
+      // out of date. Chrome OS doesn't quite have this issue since the
+      // OS/App are updated together. If a newer version of the OS has been
+      // staged then UPGRADE_SUCESSFUL will be returned.
+#if defined(OS_WIN)
       // Google Update reported that Chrome is up-to-date. Now make sure that we
       // are running the latest version and if not, notify the user by falling
       // into the next case of UPGRADE_SUCCESSFUL.
@@ -854,6 +863,7 @@
           installer::Version::GetVersionFromString(current_version_));
       if (!installed_version.get() ||
           !installed_version->IsHigherThan(running_version.get())) {
+#endif
         UserMetrics::RecordAction("UpgradeCheck_AlreadyUpToDate", profile_);
         check_button_status_ = CHECKBUTTON_HIDDEN;
         std::wstring update_label_text =
@@ -867,7 +877,9 @@
         update_label_.SetText(update_label_text);
         show_success_indicator = true;
         break;
+#if defined(OS_WIN)
       }
+#endif
       // No break here as we want to notify user about upgrade if there is one.
     }
     case UPGRADE_SUCCESSFUL: {
@@ -884,7 +896,11 @@
                                   new_version_available_);
       update_label_.SetText(update_string);
       show_success_indicator = true;
+      // TODO (seanparent) : Need to see if this code needs to change to
+      // force a machine restart.
+#if defined(OS_WIN)
       RestartMessageBox::ShowMessageBox(window()->GetNativeWindow());
+#endif
       break;
     }
     case UPGRADE_ERROR:
diff --git a/chrome/browser/views/about_chrome_view.h b/chrome/browser/views/about_chrome_view.h
index 757209c..62b9da6 100644
--- a/chrome/browser/views/about_chrome_view.h
+++ b/chrome/browser/views/about_chrome_view.h
@@ -11,9 +11,10 @@
 #include "views/view.h"
 #include "views/window/dialog_delegate.h"
 
-#if defined(OS_WIN)
+#if defined(OS_WIN) || defined(OS_CHROMEOS)
 #include "chrome/browser/google_update.h"
-#elif defined(OS_CHROMEOS)
+#endif
+#if defined(OS_CHROMEOS)
 #include "chrome/browser/chromeos/version_loader.h"
 #endif
 
@@ -35,7 +36,7 @@
 class AboutChromeView : public views::View,
                         public views::DialogDelegate,
                         public views::LinkController
-#if defined (OS_WIN)
+#if defined(OS_WIN) || defined(OS_CHROMEOS)
                         , public GoogleUpdateStatusListener
 #endif
                         {
@@ -72,8 +73,7 @@
 
   // Overridden from views::LinkController:
   virtual void LinkActivated(views::Link* source, int event_flags);
-
-#if defined(OS_WIN)
+#if defined(OS_WIN) || defined(OS_CHROMEOS)
   // Overridden from GoogleUpdateStatusListener:
   virtual void OnReportResults(GoogleUpdateUpgradeResult result,
                                GoogleUpdateErrorCode error_code,
@@ -88,7 +88,7 @@
     CHECKBUTTON_ENABLED,
   };
 
-#if defined(OS_WIN)
+#if defined(OS_WIN) || defined(OS_CHROMEOS)
   // Update the UI to show the status of the upgrade.
   void UpdateStatus(GoogleUpdateUpgradeResult result,
                     GoogleUpdateErrorCode error_code);
@@ -181,7 +181,7 @@
   // Determines the order of the two links we draw in the main label.
   bool chromium_url_appears_first_;
 
-#if defined(OS_WIN)
+#if defined(OS_WIN) || defined(OS_CHROMEOS)
   // The class that communicates with Google Update to find out if an update is
   // available and asks it to start an upgrade.
   scoped_refptr<GoogleUpdate> google_updater_;
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index ec1405b..01499810 100755
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -296,6 +296,7 @@
         'browser/chromeos/external_metrics.h',
         'browser/chromeos/external_protocol_dialog.cc',
         'browser/chromeos/external_protocol_dialog.h',
+        'browser/chromeos/google_update_chromeos.cc',
         'browser/chromeos/gview_request_interceptor.cc',
         'browser/chromeos/gview_request_interceptor.h',
         'browser/chromeos/login/account_creation_view.cc',