attestation: Use DBusObject to implement the attestation service
Switch Attestation serivce to use chromeos::dbus_utils::DBusObject
to implement its D-Bus object and use CallMethodAndBlock and
ExtractMethodCallResults from libchromeos to invoke a method
from the client.
BUG=None
TEST=USE=attestation emerge-link platform2
Change-Id: Icbd9f5fdc31ee72f142acdaa17325b6e572ab032
Reviewed-on: https://chromium-review.googlesource.com/215685
Reviewed-by: Nam Nguyen <[email protected]>
Tested-by: Alex Vakulenko <[email protected]>
Commit-Queue: Alex Vakulenko <[email protected]>
diff --git a/client/main.cc b/client/main.cc
index d0411d6..1b0d4fb 100644
--- a/client/main.cc
+++ b/client/main.cc
@@ -2,7 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <memory>
+
#include <base/memory/ref_counted.h>
+#include <chromeos/dbus/dbus_method_invoker.h>
+#include <chromeos/errors/error.h>
#include <dbus/bus.h>
#include <dbus/message.h>
#include <dbus/object_proxy.h>
@@ -17,17 +21,21 @@
dbus::ObjectProxy* object = bus->GetObjectProxy(
attestation::kAttestationServiceName,
dbus::ObjectPath(attestation::kAttestationServicePath));
- dbus::MethodCall method_call(
+
+ auto response = chromeos::dbus_utils::CallMethodAndBlock(
+ object,
attestation::kAttestationInterface,
attestation::kStatsMethod);
- scoped_ptr<dbus::Response> response(
- object->CallMethodAndBlock(&method_call,
- dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
- attestation::StatsResponse stats;
- dbus::MessageReader reader(response.get());
- reader.PopArrayOfBytesAsProto(&stats);
- printf("Attestation has been up for %u seconds.\n", stats.uptime());
+ attestation::StatsResponse stats;
+ chromeos::ErrorPtr error;
+ if (chromeos::dbus_utils::ExtractMethodCallResults(response.get(),
+ &error,
+ &stats)) {
+ printf("Attestation has been up for %u seconds.\n", stats.uptime());
+ } else {
+ printf("Error occurred: %s.\n", error->GetMessage().c_str());
+ }
bus->ShutdownAndBlock();
diff --git a/server/attestation_service.cc b/server/attestation_service.cc
index 5b757ee..54d379e 100644
--- a/server/attestation_service.cc
+++ b/server/attestation_service.cc
@@ -6,77 +6,37 @@
#include <string>
-#include <base/bind.h>
#include <base/time/time.h>
+#include <dbus/bus.h>
+#include <dbus/object_path.h>
#include "attestation/common/dbus_interface.pb.h"
namespace attestation {
-namespace {
-
-// Passes |method_call| to |handler| and passes the response to
-// |response_sender|. If |handler| returns NULL, an empty response is created
-// and sent.
-static void HandleSynchronousDBusMethodCall(
- const DBusMethodCallHandler& handler,
- dbus::MethodCall* method_call,
- dbus::ExportedObject::ResponseSender response_sender) {
- ResponsePtr response = handler.Run(method_call);
- if (!response) {
- response = dbus::Response::FromMethodCall(method_call);
- }
-
- response_sender.Run(response.Pass());
+AttestationService::AttestationService(const scoped_refptr<dbus::Bus>& bus)
+ : start_time_{base::Time()},
+ dbus_object_{nullptr, bus, dbus::ObjectPath{kAttestationServicePath}} {
}
-} // namespace
+void AttestationService::RegisterAsync(const CompletionAction& callback) {
+ chromeos::dbus_utils::DBusInterface* itf =
+ dbus_object_.AddOrGetInterface(kAttestationInterface);
-AttestationService::AttestationService()
- : start_time_(base::Time()),
- bus_(nullptr),
- attestation_dbus_object_(nullptr) {}
+ itf->AddMethodHandler(kStatsMethod,
+ base::Unretained(this),
+ &AttestationService::HandleStatsMethod);
-AttestationService::~AttestationService() {}
-
-void AttestationService::Init() {
- dbus::Bus::Options options;
- options.bus_type = dbus::Bus::SYSTEM;
- bus_ = new dbus::Bus(options);
- CHECK(bus_->Connect());
-
- attestation_dbus_object_ = bus_->GetExportedObject(
- dbus::ObjectPath(kAttestationServicePath));
- CHECK(attestation_dbus_object_);
-
- ExportDBusMethod(kStatsMethod,
- base::Bind(&AttestationService::HandleStatsMethod,
- base::Unretained(this)));
-
- CHECK(bus_->RequestOwnershipAndBlock(kAttestationServiceName,
- dbus::Bus::REQUIRE_PRIMARY))
- << "Unable to take ownership of " << kAttestationServiceName;
+ dbus_object_.RegisterAsync(callback);
start_time_ = base::Time::Now();
}
-void AttestationService::ExportDBusMethod(
- const std::string& method_name,
- const DBusMethodCallHandler& handler) {
- CHECK(attestation_dbus_object_->ExportMethodAndBlock(
- kAttestationInterface, method_name,
- base::Bind(&HandleSynchronousDBusMethodCall, handler)));
-}
-
-ResponsePtr AttestationService::HandleStatsMethod(
- dbus::MethodCall* method_call) {
+StatsResponse AttestationService::HandleStatsMethod(chromeos::ErrorPtr* error) {
LOG(INFO) << "Received call to stats method.";
StatsResponse stats;
stats.set_uptime((base::Time::Now() - start_time_).InSeconds());
- ResponsePtr response = dbus::Response::FromMethodCall(method_call);
- dbus::MessageWriter writer(response.get());
- writer.AppendProtoAsArrayOfBytes(stats);
- return response.Pass();
+ return stats;
}
} // namespace attestation
diff --git a/server/attestation_service.h b/server/attestation_service.h
index bf393db..56eef6d 100644
--- a/server/attestation_service.h
+++ b/server/attestation_service.h
@@ -9,42 +9,33 @@
#include <base/callback.h>
#include <base/memory/scoped_ptr.h>
-#include <dbus/bus.h>
-#include <dbus/exported_object.h>
-#include <dbus/message.h>
+#include <chromeos/dbus/dbus_object.h>
+#include <chromeos/errors/error.h>
#include "attestation/common/dbus_interface.h"
namespace attestation {
class AttestationService;
-
-typedef scoped_ptr<dbus::Response> ResponsePtr;
-// Pointer to a member function for handling D-Bus method calls. If an empty
-// scoped_ptr is returned, an empty (but successful) response will be sent.
-typedef base::Callback<ResponsePtr (dbus::MethodCall*)> DBusMethodCallHandler;
+class StatsResponse;
+using CompletionAction =
+ chromeos::dbus_utils::AsyncEventSequencer::CompletionAction;
// Main class within the attestation daemon that ties other classes together.
class AttestationService {
public:
- AttestationService();
- virtual ~AttestationService();
+ explicit AttestationService(const scoped_refptr<dbus::Bus>& bus);
+ virtual ~AttestationService() = default;
// Connects to D-Bus system bus and exports methods.
- void Init();
+ void RegisterAsync(const CompletionAction& callback);
private:
- // Exports |method_name| and uses |handler| to handle calls.
- void ExportDBusMethod(const std::string& method_name,
- const DBusMethodCallHandler& handler);
-
// Callbacks for handling D-Bus signals and method calls.
- ResponsePtr HandleStatsMethod(dbus::MethodCall* method_call);
+ StatsResponse HandleStatsMethod(chromeos::ErrorPtr* error);
base::Time start_time_;
- scoped_refptr<dbus::Bus> bus_;
- // This is owned by bus_.
- dbus::ExportedObject* attestation_dbus_object_;
+ chromeos::dbus_utils::DBusObject dbus_object_;
DISALLOW_COPY_AND_ASSIGN(AttestationService);
};
diff --git a/server/main.cc b/server/main.cc
index 7291451..66d622c 100644
--- a/server/main.cc
+++ b/server/main.cc
@@ -5,14 +5,23 @@
#include <string>
#include <base/at_exit.h>
+#include <base/bind.h>
#include <base/command_line.h>
#include <base/message_loop/message_loop.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <chromeos/syslog_logging.h>
+#include <dbus/bus.h>
#include "attestation/server/attestation_service.h"
+void TakeServiceOwnership(const scoped_refptr<dbus::Bus>& bus, bool success) {
+ CHECK(success) << "Init of one or more objects has failed.";
+ CHECK(bus->RequestOwnershipAndBlock(attestation::kAttestationServiceName,
+ dbus::Bus::REQUIRE_PRIMARY))
+ << "Unable to take ownership of " << attestation::kAttestationServiceName;
+}
+
int main(int argc, char* argv[]) {
CommandLine::Init(argc, argv);
@@ -20,10 +29,15 @@
base::AtExitManager at_exit_manager; // This is for the message loop.
base::MessageLoopForIO message_loop;
+ dbus::Bus::Options options;
+ options.bus_type = dbus::Bus::SYSTEM;
+ scoped_refptr<dbus::Bus> bus(new dbus::Bus(options));
+ CHECK(bus->Connect());
- attestation::AttestationService service;
- service.Init();
+ attestation::AttestationService service(bus);
+ service.RegisterAsync(base::Bind(&TakeServiceOwnership, bus));
message_loop.Run();
+ bus->ShutdownAndBlock();
return 0;
}