Home | History | Annotate | Download | only in cros
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/chromeos/cros/update_library.h"
      6 
      7 #include "base/message_loop.h"
      8 #include "base/string_util.h"
      9 #include "chrome/browser/chromeos/cros/cros_library.h"
     10 #include "content/browser/browser_thread.h"
     11 #include "content/common/notification_service.h"
     12 #include "content/common/notification_type.h"
     13 
     14 namespace chromeos {
     15 
     16 class UpdateLibraryImpl : public UpdateLibrary {
     17  public:
     18   UpdateLibraryImpl()
     19     : status_connection_(NULL) {
     20     if (CrosLibrary::Get()->EnsureLoaded()) {
     21       Init();
     22     }
     23   }
     24 
     25   ~UpdateLibraryImpl() {
     26     if (status_connection_) {
     27       DisconnectUpdateProgress(status_connection_);
     28     }
     29   }
     30 
     31   void AddObserver(Observer* observer) {
     32     observers_.AddObserver(observer);
     33   }
     34 
     35   void RemoveObserver(Observer* observer) {
     36     observers_.RemoveObserver(observer);
     37   }
     38 
     39   bool HasObserver(Observer* observer) {
     40     return observers_.HasObserver(observer);
     41   }
     42 
     43   void RequestUpdateCheck(chromeos::UpdateCallback callback, void* user_data) {
     44     if (CrosLibrary::Get()->EnsureLoaded())
     45       chromeos::RequestUpdateCheck(callback, user_data);
     46   }
     47 
     48   bool RebootAfterUpdate() {
     49     if (!CrosLibrary::Get()->EnsureLoaded())
     50       return false;
     51 
     52     return RebootIfUpdated();
     53   }
     54 
     55   void SetReleaseTrack(const std::string& track) {
     56     if (CrosLibrary::Get()->EnsureLoaded())
     57       chromeos::SetUpdateTrack(track);
     58   }
     59 
     60   void GetReleaseTrack(chromeos::UpdateTrackCallback callback,
     61                        void* user_data) {
     62     if (CrosLibrary::Get()->EnsureLoaded())
     63       chromeos::RequestUpdateTrack(callback, user_data);
     64   }
     65 
     66   const UpdateLibrary::Status& status() const {
     67     return status_;
     68   }
     69 
     70  private:
     71   static void ChangedHandler(void* object,
     72       const UpdateProgress& status) {
     73     UpdateLibraryImpl* updater = static_cast<UpdateLibraryImpl*>(object);
     74     updater->UpdateStatus(Status(status));
     75   }
     76 
     77   void Init() {
     78     status_connection_ = MonitorUpdateStatus(&ChangedHandler, this);
     79   }
     80 
     81   void UpdateStatus(const Status& status) {
     82     // Make sure we run on UI thread.
     83     if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
     84       BrowserThread::PostTask(
     85           BrowserThread::UI, FROM_HERE,
     86           NewRunnableMethod(this, &UpdateLibraryImpl::UpdateStatus, status));
     87       return;
     88     }
     89 
     90     status_ = status;
     91     FOR_EACH_OBSERVER(Observer, observers_, UpdateStatusChanged(this));
     92 
     93     // If the update is ready to install, send a notification so that Chrome
     94     // can update the UI.
     95     if (status_.status == UPDATE_STATUS_UPDATED_NEED_REBOOT) {
     96       NotificationService::current()->Notify(
     97           NotificationType::UPGRADE_RECOMMENDED,
     98           Source<UpdateLibrary>(this),
     99           NotificationService::NoDetails());
    100     }
    101   }
    102 
    103   ObserverList<Observer> observers_;
    104 
    105   // A reference to the update api, to allow callbacks when the update
    106   // status changes.
    107   UpdateStatusConnection status_connection_;
    108 
    109   // The latest power status.
    110   Status status_;
    111 
    112   DISALLOW_COPY_AND_ASSIGN(UpdateLibraryImpl);
    113 };
    114 
    115 class UpdateLibraryStubImpl : public UpdateLibrary {
    116  public:
    117   UpdateLibraryStubImpl() {}
    118   ~UpdateLibraryStubImpl() {}
    119   void AddObserver(Observer* observer) {}
    120   void RemoveObserver(Observer* observer) {}
    121   bool HasObserver(Observer* observer) { return false; }
    122   void RequestUpdateCheck(chromeos::UpdateCallback callback, void* user_data) {
    123     if (callback)
    124       callback(user_data, UPDATE_RESULT_FAILED, "stub update");
    125   }
    126   bool RebootAfterUpdate() { return false; }
    127   void SetReleaseTrack(const std::string& track) { }
    128   void GetReleaseTrack(chromeos::UpdateTrackCallback callback,
    129                        void* user_data) {
    130     if (callback)
    131       callback(user_data, "beta-channel");
    132   }
    133   const UpdateLibrary::Status& status() const {
    134     return status_;
    135   }
    136 
    137  private:
    138   Status status_;
    139 
    140   DISALLOW_COPY_AND_ASSIGN(UpdateLibraryStubImpl);
    141 };
    142 
    143 // static
    144 UpdateLibrary* UpdateLibrary::GetImpl(bool stub) {
    145   if (stub)
    146     return new UpdateLibraryStubImpl();
    147   else
    148     return new UpdateLibraryImpl();
    149 }
    150 
    151 }  // namespace chromeos
    152 
    153 // Allows InvokeLater without adding refcounting. This class is a Singleton and
    154 // won't be deleted until it's last InvokeLater is run.
    155 DISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::UpdateLibraryImpl);
    156