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/string_util.h" | |
10 #include "dbus/bus.h" | |
11 #include "dbus/message.h" | |
12 #include "dbus/object_path.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 dbus::ObjectPath(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_NOTIMPLEMENTED); | |
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( | |
282 DBusClientImplementationType type, | |
283 dbus::Bus* bus) { | |
284 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION) | |
285 return new UpdateEngineClientImpl(bus); | |
286 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type); | |
287 return new UpdateEngineClientStubImpl(); | |
288 } | |
289 | |
290 } // namespace chromeos | |
OLD | NEW |