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