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