summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsatorux@chromium.org <satorux@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-17 07:39:53 +0000
committersatorux@chromium.org <satorux@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-17 07:39:53 +0000
commitb107dc07c516017e1ed67c92d3f7afb0fa9b07e0 (patch)
treeacdff13bfe5af69876b931a950f32701988215cc
parentc8de167746aa49238fb5d6fe3192fc8a770af827 (diff)
downloadchromium_src-b107dc07c516017e1ed67c92d3f7afb0fa9b07e0.zip
chromium_src-b107dc07c516017e1ed67c92d3f7afb0fa9b07e0.tar.gz
chromium_src-b107dc07c516017e1ed67c92d3f7afb0fa9b07e0.tar.bz2
chromeos: Implement the new D-Bus client for update engine.
This is part 1 of the UpdateLibrary to UpdateEngineClient migration. The new files are added but not used from Chrome yet. The new code is based on update_library.cc and chromeos_update_engine.cc, and the new code will replace the them. For code review, please refer to the files below: http://src.chromium.org/viewvc/chrome/trunk/src/chrome/browser/chromeos/cros/update_library.h?view=markup http://src.chromium.org/viewvc/chrome/trunk/src/chrome/browser/chromeos/cros/update_library.cc?view=markup http://git.chromium.org/gitweb/?p=chromiumos/platform/cros.git;a=blob;f=chromeos_update_engine.h;hb=HEAD http://git.chromium.org/gitweb/?p=chromiumos/platform/cros.git;a=blob;f=chromeos_update_engine.cc;hb=HEAD BUG=chromium-os:16564 TEST=chrome and tests build. Review URL: http://codereview.chromium.org/8572020 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@110467 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/chromeos/dbus/mock_update_engine_client.cc13
-rw-r--r--chrome/browser/chromeos/dbus/mock_update_engine_client.h32
-rw-r--r--chrome/browser/chromeos/dbus/update_engine_client.cc289
-rw-r--r--chrome/browser/chromeos/dbus/update_engine_client.h122
-rw-r--r--chrome/chrome_browser.gypi2
-rw-r--r--chrome/chrome_tests.gypi2
6 files changed, 460 insertions, 0 deletions
diff --git a/chrome/browser/chromeos/dbus/mock_update_engine_client.cc b/chrome/browser/chromeos/dbus/mock_update_engine_client.cc
new file mode 100644
index 0000000..93379d4
--- /dev/null
+++ b/chrome/browser/chromeos/dbus/mock_update_engine_client.cc
@@ -0,0 +1,13 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/dbus/mock_update_engine_client.h"
+
+namespace chromeos {
+
+MockUpdateEngineClient::MockUpdateEngineClient() {}
+
+MockUpdateEngineClient::~MockUpdateEngineClient() {}
+
+} // namespace chromeos
diff --git a/chrome/browser/chromeos/dbus/mock_update_engine_client.h b/chrome/browser/chromeos/dbus/mock_update_engine_client.h
new file mode 100644
index 0000000..21d6f4e
--- /dev/null
+++ b/chrome/browser/chromeos/dbus/mock_update_engine_client.h
@@ -0,0 +1,32 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_DBUS_MOCK_UPDATE_ENGINE_CLIENT_H_
+#define CHROME_BROWSER_CHROMEOS_DBUS_MOCK_UPDATE_ENGINE_CLIENT_H_
+
+#include <string>
+
+#include "chrome/browser/chromeos/dbus/update_engine_client.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace chromeos {
+
+class MockUpdateEngineClient : public UpdateEngineClient {
+ public:
+ MockUpdateEngineClient();
+ virtual ~MockUpdateEngineClient();
+
+ MOCK_METHOD1(AddObserver, void(Observer*));
+ MOCK_METHOD1(RemoveObserver, void(Observer*));
+ MOCK_METHOD1(HasObserver, bool(Observer*));
+ MOCK_METHOD1(RequestUpdateCheck, void(UpdateCheckCallback));
+ MOCK_METHOD0(RebootAfterUpdate, void());
+ MOCK_METHOD1(SetReleaseTrack, void(const std::string&));
+ MOCK_METHOD1(GetReleaseTrack, void(GetReleaseTrackCallback));
+ MOCK_METHOD0(GetLastStatus, Status());
+};
+
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_CHROMEOS_DBUS_MOCK_UPDATE_ENGINE_CLIENT_H_
diff --git a/chrome/browser/chromeos/dbus/update_engine_client.cc b/chrome/browser/chromeos/dbus/update_engine_client.cc
new file mode 100644
index 0000000..ed5cecb
--- /dev/null
+++ b/chrome/browser/chromeos/dbus/update_engine_client.cc
@@ -0,0 +1,289 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/dbus/update_engine_client.h"
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/string_util.h"
+#include "chrome/browser/chromeos/system/runtime_environment.h"
+#include "dbus/bus.h"
+#include "dbus/message.h"
+#include "dbus/object_proxy.h"
+#include "third_party/cros_system_api/dbus/service_constants.h"
+
+namespace chromeos {
+namespace {
+
+// Returns UPDATE_STATUS_ERROR on error.
+UpdateEngineClient::UpdateStatusOperation UpdateStatusFromString(
+ const std::string& str) {
+ if (str == "UPDATE_STATUS_IDLE")
+ return UpdateEngineClient::UPDATE_STATUS_IDLE;
+ if (str == "UPDATE_STATUS_CHECKING_FOR_UPDATE")
+ return UpdateEngineClient::UPDATE_STATUS_CHECKING_FOR_UPDATE;
+ if (str == "UPDATE_STATUS_UPDATE_AVAILABLE")
+ return UpdateEngineClient::UPDATE_STATUS_UPDATE_AVAILABLE;
+ if (str == "UPDATE_STATUS_DOWNLOADING")
+ return UpdateEngineClient::UPDATE_STATUS_DOWNLOADING;
+ if (str == "UPDATE_STATUS_VERIFYING")
+ return UpdateEngineClient::UPDATE_STATUS_VERIFYING;
+ if (str == "UPDATE_STATUS_FINALIZING")
+ return UpdateEngineClient::UPDATE_STATUS_FINALIZING;
+ if (str == "UPDATE_STATUS_UPDATED_NEED_REBOOT")
+ return UpdateEngineClient::UPDATE_STATUS_UPDATED_NEED_REBOOT;
+ if (str == "UPDATE_STATUS_REPORTING_ERROR_EVENT")
+ return UpdateEngineClient::UPDATE_STATUS_REPORTING_ERROR_EVENT;
+ return UpdateEngineClient::UPDATE_STATUS_ERROR;
+}
+
+// Used in UpdateEngineClient::EmptyUpdateCheckCallback().
+void EmptyUpdateCheckCallbackBody(
+ UpdateEngineClient::UpdateCheckResult unused_result) {
+}
+
+} // namespace
+
+// The UpdateEngineClient implementation used in production.
+class UpdateEngineClientImpl : public UpdateEngineClient {
+ public:
+ explicit UpdateEngineClientImpl(dbus::Bus* bus)
+ : update_engine_proxy_(NULL),
+ weak_ptr_factory_(this),
+ last_status_() {
+ update_engine_proxy_ = bus->GetObjectProxy(
+ update_engine::kUpdateEngineServiceName,
+ update_engine::kUpdateEngineServicePath);
+
+ // Monitor the D-Bus signal for brightness changes. Only the power
+ // manager knows the actual brightness level. We don't cache the
+ // brightness level in Chrome as it will make things less reliable.
+ update_engine_proxy_->ConnectToSignal(
+ update_engine::kUpdateEngineInterface,
+ update_engine::kStatusUpdate,
+ base::Bind(&UpdateEngineClientImpl::StatusUpdateReceived,
+ weak_ptr_factory_.GetWeakPtr()),
+ base::Bind(&UpdateEngineClientImpl::StatusUpdateConnected,
+ weak_ptr_factory_.GetWeakPtr()));
+ }
+
+ virtual ~UpdateEngineClientImpl() {
+ }
+
+ // UpdateEngineClient override.
+ virtual void AddObserver(Observer* observer) OVERRIDE {
+ observers_.AddObserver(observer);
+ }
+
+ // UpdateEngineClient override.
+ virtual void RemoveObserver(Observer* observer) OVERRIDE {
+ observers_.RemoveObserver(observer);
+ }
+
+ // UpdateEngineClient override.
+ virtual bool HasObserver(Observer* observer) OVERRIDE {
+ return observers_.HasObserver(observer);
+ }
+
+ // UpdateEngineClient override.
+ virtual void RequestUpdateCheck(UpdateCheckCallback callback) OVERRIDE {
+ dbus::MethodCall method_call(
+ update_engine::kUpdateEngineInterface,
+ update_engine::kAttemptUpdate);
+ dbus::MessageWriter writer(&method_call);
+ writer.AppendString(""); // Unused.
+ writer.AppendString(""); // Unused.
+
+ VLOG(1) << "Requesting an update check";
+ update_engine_proxy_->CallMethod(
+ &method_call,
+ dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
+ base::Bind(&UpdateEngineClientImpl::OnRequestUpdateCheck,
+ weak_ptr_factory_.GetWeakPtr(),
+ callback));
+ }
+
+ // UpdateEngineClient override.
+ virtual void RebootAfterUpdate() OVERRIDE {
+ dbus::MethodCall method_call(
+ update_engine::kUpdateEngineInterface,
+ update_engine::kRebootIfNeeded);
+
+ VLOG(1) << "Requesting a reboot";
+ update_engine_proxy_->CallMethod(
+ &method_call,
+ dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
+ base::Bind(&UpdateEngineClientImpl::OnRebootAfterUpdate,
+ weak_ptr_factory_.GetWeakPtr()));
+ }
+
+ // UpdateEngineClient override.
+ virtual void SetReleaseTrack(const std::string& track) OVERRIDE {
+ dbus::MethodCall method_call(
+ update_engine::kUpdateEngineInterface,
+ update_engine::kSetTrack);
+ dbus::MessageWriter writer(&method_call);
+ writer.AppendString(track);
+
+ VLOG(1) << "Requesting to set the release track to " << track;
+ update_engine_proxy_->CallMethod(
+ &method_call,
+ dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
+ base::Bind(&UpdateEngineClientImpl::OnSetReleaseTrack,
+ weak_ptr_factory_.GetWeakPtr()));
+ }
+
+ // UpdateEngineClient override.
+ virtual void GetReleaseTrack(GetReleaseTrackCallback callback) OVERRIDE {
+ dbus::MethodCall method_call(
+ update_engine::kUpdateEngineInterface,
+ update_engine::kGetTrack);
+
+ VLOG(1) << "Requesting to get the current release track";
+ update_engine_proxy_->CallMethod(
+ &method_call,
+ dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
+ base::Bind(&UpdateEngineClientImpl::OnGetReleaseTrack,
+ weak_ptr_factory_.GetWeakPtr(),
+ callback));
+ }
+
+ // UpdateEngineClient override.
+ virtual Status GetLastStatus() OVERRIDE {
+ return last_status_;
+ }
+
+ private:
+ // Called when a response for RequestUpdateCheck() is received.
+ void OnRequestUpdateCheck(UpdateCheckCallback callback,
+ dbus::Response* response) {
+ if (!response) {
+ LOG(ERROR) << "Failed to request update check";
+ callback.Run(UPDATE_RESULT_FAILED);
+ return;
+ }
+ callback.Run(UPDATE_RESULT_SUCCESS);
+ }
+
+ // Called when a response for RebootAfterUpdate() is received.
+ void OnRebootAfterUpdate(dbus::Response* response) {
+ if (!response) {
+ LOG(ERROR) << "Failed to request rebooting after update";
+ return;
+ }
+ }
+
+ // Called when a response for SetReleaseTrack() is received.
+ void OnSetReleaseTrack(dbus::Response* response) {
+ if (!response) {
+ LOG(ERROR) << "Failed to request setting release track";
+ return;
+ }
+ }
+
+ // Called when a response for GetReleaseTrack() is received.
+ void OnGetReleaseTrack(GetReleaseTrackCallback callback,
+ dbus::Response* response) {
+ if (!response) {
+ LOG(ERROR) << "Failed to request getting release track";
+ callback.Run("");
+ return;
+ }
+ dbus::MessageReader reader(response);
+ std::string release_track;
+ if (!reader.PopString(&release_track)) {
+ LOG(ERROR) << "Incorrect response: " << response->ToString();
+ callback.Run("");
+ return;
+ }
+ VLOG(1) << "The current release track received: " << release_track;
+ callback.Run(release_track);
+ }
+
+ // Called when a status update signal is received.
+ void StatusUpdateReceived(dbus::Signal* signal) {
+ VLOG(1) << "Status update signal received: " << signal->ToString();
+ dbus::MessageReader reader(signal);
+ int64 last_checked_time = 0;
+ double progress = 0.0;
+ std::string current_operation;
+ std::string new_version;
+ int64_t new_size = 0;
+ if (!(reader.PopInt64(&last_checked_time) &&
+ reader.PopDouble(&progress) &&
+ reader.PopString(&current_operation) &&
+ reader.PopString(&new_version) &&
+ reader.PopInt64(&new_size))) {
+ LOG(ERROR) << "Status changed signal had incorrect parameters: "
+ << signal->ToString();
+ return;
+ }
+ Status status;
+ status.last_checked_time = last_checked_time;
+ status.download_progress = progress;
+ status.status = UpdateStatusFromString(current_operation);
+ status.new_version = new_version;
+ status.new_size = new_size;
+
+ last_status_ = status;
+ FOR_EACH_OBSERVER(Observer, observers_, UpdateStatusChanged(status));
+ }
+
+ // Called when the status update signal is initially connected.
+ void StatusUpdateConnected(const std::string& interface_name,
+ const std::string& signal_name,
+ bool success) {
+ LOG_IF(WARNING, !success)
+ << "Failed to connect to status updated signal.";
+ }
+
+ dbus::ObjectProxy* update_engine_proxy_;
+ ObserverList<Observer> observers_;
+ base::WeakPtrFactory<UpdateEngineClientImpl> weak_ptr_factory_;
+ Status last_status_;
+
+ DISALLOW_COPY_AND_ASSIGN(UpdateEngineClientImpl);
+};
+
+// The UpdateEngineClient implementation used on Linux desktop,
+// which does nothing.
+class UpdateEngineClientStubImpl : public UpdateEngineClient {
+ // UpdateEngineClient overrides.
+ virtual void AddObserver(Observer* observer) OVERRIDE {}
+ virtual void RemoveObserver(Observer* observer) OVERRIDE {}
+ virtual bool HasObserver(Observer* observer) OVERRIDE { return false; }
+
+ virtual void RequestUpdateCheck(UpdateCheckCallback callback) OVERRIDE {
+ callback.Run(UPDATE_RESULT_FAILED);
+ }
+ virtual void RebootAfterUpdate() OVERRIDE {}
+ virtual void SetReleaseTrack(const std::string& track) OVERRIDE {}
+ virtual void GetReleaseTrack(GetReleaseTrackCallback callback) OVERRIDE {
+ callback.Run("beta-channel");
+ }
+ virtual Status GetLastStatus() OVERRIDE { return Status(); }
+};
+
+UpdateEngineClient::UpdateEngineClient() {
+}
+
+UpdateEngineClient::~UpdateEngineClient() {
+}
+
+// static
+UpdateEngineClient::UpdateCheckCallback
+UpdateEngineClient::EmptyUpdateCheckCallback() {
+ return base::Bind(&EmptyUpdateCheckCallbackBody);
+}
+
+// static
+UpdateEngineClient* UpdateEngineClient::Create(dbus::Bus* bus) {
+ if (system::runtime_environment::IsRunningOnChromeOS()) {
+ return new UpdateEngineClientImpl(bus);
+ } else {
+ return new UpdateEngineClientStubImpl();
+ }
+}
+
+} // namespace chromeos
diff --git a/chrome/browser/chromeos/dbus/update_engine_client.h b/chrome/browser/chromeos/dbus/update_engine_client.h
new file mode 100644
index 0000000..52d5d20
--- /dev/null
+++ b/chrome/browser/chromeos/dbus/update_engine_client.h
@@ -0,0 +1,122 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_DBUS_UPDATE_ENGINE_CLIENT_H_
+#define CHROME_BROWSER_CHROMEOS_DBUS_UPDATE_ENGINE_CLIENT_H_
+
+#include "base/callback.h"
+#include "base/observer_list.h"
+
+#include <string>
+
+namespace dbus {
+class Bus;
+} // namespace
+
+namespace chromeos {
+
+// UpdateEngineClient is used to communicate with the update engine.
+class UpdateEngineClient {
+ public:
+ // Edges for state machine
+ // IDLE->CHECKING_FOR_UPDATE
+ // CHECKING_FOR_UPDATE->IDLE
+ // CHECKING_FOR_UPDATE->UPDATE_AVAILABLE
+ // ...
+ // FINALIZING->UPDATE_NEED_REBOOT
+ // Any state can transition to REPORTING_ERROR_EVENT and then on to IDLE.
+ enum UpdateStatusOperation {
+ UPDATE_STATUS_ERROR = -1,
+ UPDATE_STATUS_IDLE = 0,
+ UPDATE_STATUS_CHECKING_FOR_UPDATE,
+ UPDATE_STATUS_UPDATE_AVAILABLE,
+ UPDATE_STATUS_DOWNLOADING,
+ UPDATE_STATUS_VERIFYING,
+ UPDATE_STATUS_FINALIZING,
+ UPDATE_STATUS_UPDATED_NEED_REBOOT,
+ UPDATE_STATUS_REPORTING_ERROR_EVENT
+ };
+
+ // The status of the ongoing update attempt.
+ struct Status {
+ Status() : status(UPDATE_STATUS_IDLE),
+ download_progress(0.0),
+ last_checked_time(0),
+ new_size(0) {
+ }
+
+ UpdateStatusOperation status;
+ double download_progress; // 0.0 - 1.0
+ int64_t last_checked_time; // As reported by std::time().
+ std::string new_version;
+ int64_t new_size; // Valid during DOWNLOADING, in bytes.
+ };
+
+ // The result code used for RequestUpdateCheck().
+ enum UpdateCheckResult {
+ UPDATE_RESULT_SUCCESS,
+ UPDATE_RESULT_FAILED,
+ };
+
+ // Interface for observing changes from the update engine.
+ class Observer {
+ public:
+ // Called when the status is updated.
+ virtual void UpdateStatusChanged(const Status& status) {}
+ };
+
+ virtual ~UpdateEngineClient();
+
+ // Adds and removes the observer.
+ virtual void AddObserver(Observer* observer) = 0;
+ virtual void RemoveObserver(Observer* observer) = 0;
+ // Returns true if this object has the given observer.
+ virtual bool HasObserver(Observer* observer) = 0;
+
+ // Called once RequestUpdateCheck() is complete. Takes one parameter:
+ // - UpdateCheckResult: the result of the update check.
+ typedef base::Callback<void(UpdateCheckResult)> UpdateCheckCallback;
+
+ // Requests an update check and calls |callback| when completed.
+ virtual void RequestUpdateCheck(UpdateCheckCallback callback) = 0;
+
+ // Reboots if update has been performed.
+ virtual void RebootAfterUpdate() = 0;
+
+ // Requests to set the release track (channel). |track| should look like
+ // "beta-channel" or "dev-channel".
+ virtual void SetReleaseTrack(const std::string& track) = 0;
+
+ // Called once GetReleaseTrack() is complete. Takes one parameter;
+ // - string: the release track name like "beta-channel".
+ typedef base::Callback<void(const std::string&)> GetReleaseTrackCallback;
+
+ // Requests to get the release track and calls |callback| with the
+ // release track (channel). On error, calls |callback| with an empty
+ // string.
+ virtual void GetReleaseTrack(GetReleaseTrackCallback callback) = 0;
+
+ // Returns the last status the object received from the update engine.
+ //
+ // Ideally, the D-Bus client should be state-less, but there are clients
+ // that need this information.
+ virtual Status GetLastStatus() = 0;
+
+ // Returns an empty UpdateCheckCallback that does nothing.
+ static UpdateCheckCallback EmptyUpdateCheckCallback();
+
+ // Creates the instance.
+ static UpdateEngineClient* Create(dbus::Bus* bus);
+
+ protected:
+ // Create() should be used instead.
+ UpdateEngineClient();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(UpdateEngineClient);
+};
+
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_CHROMEOS_DBUS_UPDATE_ENGINE_CLIENT_H_
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index a2be100..481689d 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -450,6 +450,8 @@
'browser/chromeos/dbus/session_manager_client.h',
'browser/chromeos/dbus/speech_synthesizer_client.cc',
'browser/chromeos/dbus/speech_synthesizer_client.h',
+ 'browser/chromeos/dbus/update_engine_client.cc',
+ 'browser/chromeos/dbus/update_engine_client.h',
'browser/chromeos/disks/disk_mount_manager.cc',
'browser/chromeos/disks/disk_mount_manager.h',
'browser/chromeos/drop_shadow_label.cc',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index a9b1b8fb..004d649 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -110,6 +110,8 @@
'browser/chromeos/dbus/mock_session_manager_client.h',
'browser/chromeos/dbus/mock_speech_synthesizer_client.cc',
'browser/chromeos/dbus/mock_speech_synthesizer_client.h',
+ 'browser/chromeos/dbus/mock_update_engine_client.cc',
+ 'browser/chromeos/dbus/mock_update_engine_client.h',
'browser/chromeos/login/mock_signed_settings_helper.cc',
'browser/chromeos/login/mock_signed_settings_helper.h',
# The only thing used from browser is Browser::Type.