OLD | NEW |
(Empty) | |
| 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/dbus/update_engine_client.h" |
| 6 |
| 7 #include "base/bind.h" |
| 8 #include "base/callback.h" |
| 9 #include "base/string_util.h" |
| 10 #include "chrome/browser/chromeos/system/runtime_environment.h" |
| 11 #include "dbus/bus.h" |
| 12 #include "dbus/message.h" |
| 13 #include "dbus/object_proxy.h" |
| 14 #include "third_party/cros_system_api/dbus/service_constants.h" |
| 15 |
| 16 namespace chromeos { |
| 17 namespace { |
| 18 |
| 19 // Returns UPDATE_STATUS_ERROR on error. |
| 20 UpdateEngineClient::UpdateStatusOperation UpdateStatusFromString( |
| 21 const std::string& str) { |
| 22 if (str == "UPDATE_STATUS_IDLE") |
| 23 return UpdateEngineClient::UPDATE_STATUS_IDLE; |
| 24 if (str == "UPDATE_STATUS_CHECKING_FOR_UPDATE") |
| 25 return UpdateEngineClient::UPDATE_STATUS_CHECKING_FOR_UPDATE; |
| 26 if (str == "UPDATE_STATUS_UPDATE_AVAILABLE") |
| 27 return UpdateEngineClient::UPDATE_STATUS_UPDATE_AVAILABLE; |
| 28 if (str == "UPDATE_STATUS_DOWNLOADING") |
| 29 return UpdateEngineClient::UPDATE_STATUS_DOWNLOADING; |
| 30 if (str == "UPDATE_STATUS_VERIFYING") |
| 31 return UpdateEngineClient::UPDATE_STATUS_VERIFYING; |
| 32 if (str == "UPDATE_STATUS_FINALIZING") |
| 33 return UpdateEngineClient::UPDATE_STATUS_FINALIZING; |
| 34 if (str == "UPDATE_STATUS_UPDATED_NEED_REBOOT") |
| 35 return UpdateEngineClient::UPDATE_STATUS_UPDATED_NEED_REBOOT; |
| 36 if (str == "UPDATE_STATUS_REPORTING_ERROR_EVENT") |
| 37 return UpdateEngineClient::UPDATE_STATUS_REPORTING_ERROR_EVENT; |
| 38 return UpdateEngineClient::UPDATE_STATUS_ERROR; |
| 39 } |
| 40 |
| 41 // Used in UpdateEngineClient::EmptyUpdateCheckCallback(). |
| 42 void EmptyUpdateCheckCallbackBody( |
| 43 UpdateEngineClient::UpdateCheckResult unused_result) { |
| 44 } |
| 45 |
| 46 } // namespace |
| 47 |
| 48 // The UpdateEngineClient implementation used in production. |
| 49 class UpdateEngineClientImpl : public UpdateEngineClient { |
| 50 public: |
| 51 explicit UpdateEngineClientImpl(dbus::Bus* bus) |
| 52 : update_engine_proxy_(NULL), |
| 53 weak_ptr_factory_(this), |
| 54 last_status_() { |
| 55 update_engine_proxy_ = bus->GetObjectProxy( |
| 56 update_engine::kUpdateEngineServiceName, |
| 57 update_engine::kUpdateEngineServicePath); |
| 58 |
| 59 // Monitor the D-Bus signal for brightness changes. Only the power |
| 60 // manager knows the actual brightness level. We don't cache the |
| 61 // brightness level in Chrome as it will make things less reliable. |
| 62 update_engine_proxy_->ConnectToSignal( |
| 63 update_engine::kUpdateEngineInterface, |
| 64 update_engine::kStatusUpdate, |
| 65 base::Bind(&UpdateEngineClientImpl::StatusUpdateReceived, |
| 66 weak_ptr_factory_.GetWeakPtr()), |
| 67 base::Bind(&UpdateEngineClientImpl::StatusUpdateConnected, |
| 68 weak_ptr_factory_.GetWeakPtr())); |
| 69 } |
| 70 |
| 71 virtual ~UpdateEngineClientImpl() { |
| 72 } |
| 73 |
| 74 // UpdateEngineClient override. |
| 75 virtual void AddObserver(Observer* observer) OVERRIDE { |
| 76 observers_.AddObserver(observer); |
| 77 } |
| 78 |
| 79 // UpdateEngineClient override. |
| 80 virtual void RemoveObserver(Observer* observer) OVERRIDE { |
| 81 observers_.RemoveObserver(observer); |
| 82 } |
| 83 |
| 84 // UpdateEngineClient override. |
| 85 virtual bool HasObserver(Observer* observer) OVERRIDE { |
| 86 return observers_.HasObserver(observer); |
| 87 } |
| 88 |
| 89 // UpdateEngineClient override. |
| 90 virtual void RequestUpdateCheck(UpdateCheckCallback callback) OVERRIDE { |
| 91 dbus::MethodCall method_call( |
| 92 update_engine::kUpdateEngineInterface, |
| 93 update_engine::kAttemptUpdate); |
| 94 dbus::MessageWriter writer(&method_call); |
| 95 writer.AppendString(""); // Unused. |
| 96 writer.AppendString(""); // Unused. |
| 97 |
| 98 VLOG(1) << "Requesting an update check"; |
| 99 update_engine_proxy_->CallMethod( |
| 100 &method_call, |
| 101 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, |
| 102 base::Bind(&UpdateEngineClientImpl::OnRequestUpdateCheck, |
| 103 weak_ptr_factory_.GetWeakPtr(), |
| 104 callback)); |
| 105 } |
| 106 |
| 107 // UpdateEngineClient override. |
| 108 virtual void RebootAfterUpdate() OVERRIDE { |
| 109 dbus::MethodCall method_call( |
| 110 update_engine::kUpdateEngineInterface, |
| 111 update_engine::kRebootIfNeeded); |
| 112 |
| 113 VLOG(1) << "Requesting a reboot"; |
| 114 update_engine_proxy_->CallMethod( |
| 115 &method_call, |
| 116 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, |
| 117 base::Bind(&UpdateEngineClientImpl::OnRebootAfterUpdate, |
| 118 weak_ptr_factory_.GetWeakPtr())); |
| 119 } |
| 120 |
| 121 // UpdateEngineClient override. |
| 122 virtual void SetReleaseTrack(const std::string& track) OVERRIDE { |
| 123 dbus::MethodCall method_call( |
| 124 update_engine::kUpdateEngineInterface, |
| 125 update_engine::kSetTrack); |
| 126 dbus::MessageWriter writer(&method_call); |
| 127 writer.AppendString(track); |
| 128 |
| 129 VLOG(1) << "Requesting to set the release track to " << track; |
| 130 update_engine_proxy_->CallMethod( |
| 131 &method_call, |
| 132 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, |
| 133 base::Bind(&UpdateEngineClientImpl::OnSetReleaseTrack, |
| 134 weak_ptr_factory_.GetWeakPtr())); |
| 135 } |
| 136 |
| 137 // UpdateEngineClient override. |
| 138 virtual void GetReleaseTrack(GetReleaseTrackCallback callback) OVERRIDE { |
| 139 dbus::MethodCall method_call( |
| 140 update_engine::kUpdateEngineInterface, |
| 141 update_engine::kGetTrack); |
| 142 |
| 143 VLOG(1) << "Requesting to get the current release track"; |
| 144 update_engine_proxy_->CallMethod( |
| 145 &method_call, |
| 146 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, |
| 147 base::Bind(&UpdateEngineClientImpl::OnGetReleaseTrack, |
| 148 weak_ptr_factory_.GetWeakPtr(), |
| 149 callback)); |
| 150 } |
| 151 |
| 152 // UpdateEngineClient override. |
| 153 virtual Status GetLastStatus() OVERRIDE { |
| 154 return last_status_; |
| 155 } |
| 156 |
| 157 private: |
| 158 // Called when a response for RequestUpdateCheck() is received. |
| 159 void OnRequestUpdateCheck(UpdateCheckCallback callback, |
| 160 dbus::Response* response) { |
| 161 if (!response) { |
| 162 LOG(ERROR) << "Failed to request update check"; |
| 163 callback.Run(UPDATE_RESULT_FAILED); |
| 164 return; |
| 165 } |
| 166 callback.Run(UPDATE_RESULT_SUCCESS); |
| 167 } |
| 168 |
| 169 // Called when a response for RebootAfterUpdate() is received. |
| 170 void OnRebootAfterUpdate(dbus::Response* response) { |
| 171 if (!response) { |
| 172 LOG(ERROR) << "Failed to request rebooting after update"; |
| 173 return; |
| 174 } |
| 175 } |
| 176 |
| 177 // Called when a response for SetReleaseTrack() is received. |
| 178 void OnSetReleaseTrack(dbus::Response* response) { |
| 179 if (!response) { |
| 180 LOG(ERROR) << "Failed to request setting release track"; |
| 181 return; |
| 182 } |
| 183 } |
| 184 |
| 185 // Called when a response for GetReleaseTrack() is received. |
| 186 void OnGetReleaseTrack(GetReleaseTrackCallback callback, |
| 187 dbus::Response* response) { |
| 188 if (!response) { |
| 189 LOG(ERROR) << "Failed to request getting release track"; |
| 190 callback.Run(""); |
| 191 return; |
| 192 } |
| 193 dbus::MessageReader reader(response); |
| 194 std::string release_track; |
| 195 if (!reader.PopString(&release_track)) { |
| 196 LOG(ERROR) << "Incorrect response: " << response->ToString(); |
| 197 callback.Run(""); |
| 198 return; |
| 199 } |
| 200 VLOG(1) << "The current release track received: " << release_track; |
| 201 callback.Run(release_track); |
| 202 } |
| 203 |
| 204 // Called when a status update signal is received. |
| 205 void StatusUpdateReceived(dbus::Signal* signal) { |
| 206 VLOG(1) << "Status update signal received: " << signal->ToString(); |
| 207 dbus::MessageReader reader(signal); |
| 208 int64 last_checked_time = 0; |
| 209 double progress = 0.0; |
| 210 std::string current_operation; |
| 211 std::string new_version; |
| 212 int64_t new_size = 0; |
| 213 if (!(reader.PopInt64(&last_checked_time) && |
| 214 reader.PopDouble(&progress) && |
| 215 reader.PopString(¤t_operation) && |
| 216 reader.PopString(&new_version) && |
| 217 reader.PopInt64(&new_size))) { |
| 218 LOG(ERROR) << "Status changed signal had incorrect parameters: " |
| 219 << signal->ToString(); |
| 220 return; |
| 221 } |
| 222 Status status; |
| 223 status.last_checked_time = last_checked_time; |
| 224 status.download_progress = progress; |
| 225 status.status = UpdateStatusFromString(current_operation); |
| 226 status.new_version = new_version; |
| 227 status.new_size = new_size; |
| 228 |
| 229 last_status_ = status; |
| 230 FOR_EACH_OBSERVER(Observer, observers_, UpdateStatusChanged(status)); |
| 231 } |
| 232 |
| 233 // Called when the status update signal is initially connected. |
| 234 void StatusUpdateConnected(const std::string& interface_name, |
| 235 const std::string& signal_name, |
| 236 bool success) { |
| 237 LOG_IF(WARNING, !success) |
| 238 << "Failed to connect to status updated signal."; |
| 239 } |
| 240 |
| 241 dbus::ObjectProxy* update_engine_proxy_; |
| 242 ObserverList<Observer> observers_; |
| 243 base::WeakPtrFactory<UpdateEngineClientImpl> weak_ptr_factory_; |
| 244 Status last_status_; |
| 245 |
| 246 DISALLOW_COPY_AND_ASSIGN(UpdateEngineClientImpl); |
| 247 }; |
| 248 |
| 249 // The UpdateEngineClient implementation used on Linux desktop, |
| 250 // which does nothing. |
| 251 class UpdateEngineClientStubImpl : public UpdateEngineClient { |
| 252 // UpdateEngineClient overrides. |
| 253 virtual void AddObserver(Observer* observer) OVERRIDE {} |
| 254 virtual void RemoveObserver(Observer* observer) OVERRIDE {} |
| 255 virtual bool HasObserver(Observer* observer) OVERRIDE { return false; } |
| 256 |
| 257 virtual void RequestUpdateCheck(UpdateCheckCallback callback) OVERRIDE { |
| 258 callback.Run(UPDATE_RESULT_FAILED); |
| 259 } |
| 260 virtual void RebootAfterUpdate() OVERRIDE {} |
| 261 virtual void SetReleaseTrack(const std::string& track) OVERRIDE {} |
| 262 virtual void GetReleaseTrack(GetReleaseTrackCallback callback) OVERRIDE { |
| 263 callback.Run("beta-channel"); |
| 264 } |
| 265 virtual Status GetLastStatus() OVERRIDE { return Status(); } |
| 266 }; |
| 267 |
| 268 UpdateEngineClient::UpdateEngineClient() { |
| 269 } |
| 270 |
| 271 UpdateEngineClient::~UpdateEngineClient() { |
| 272 } |
| 273 |
| 274 // static |
| 275 UpdateEngineClient::UpdateCheckCallback |
| 276 UpdateEngineClient::EmptyUpdateCheckCallback() { |
| 277 return base::Bind(&EmptyUpdateCheckCallbackBody); |
| 278 } |
| 279 |
| 280 // static |
| 281 UpdateEngineClient* UpdateEngineClient::Create(dbus::Bus* bus) { |
| 282 if (system::runtime_environment::IsRunningOnChromeOS()) { |
| 283 return new UpdateEngineClientImpl(bus); |
| 284 } else { |
| 285 return new UpdateEngineClientStubImpl(); |
| 286 } |
| 287 } |
| 288 |
| 289 } // namespace chromeos |
OLD | NEW |