15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/test_service.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/test/test_timeouts.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/platform_thread.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/bus.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/exported_object.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/message.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "dbus/object_manager.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/object_path.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/property.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void EmptyCallback(bool /* success */) {
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace dbus {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Echo, SlowEcho, AsyncEcho, BrokenMethod, GetAll, Get, Set, PerformAction,
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// GetManagedObjects.
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int TestService::kNumMethodsToExport = 9;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TestService::Options::Options()
31a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    : request_ownership_options(Bus::REQUIRE_PRIMARY) {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TestService::Options::~Options() {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TestService::TestService(const Options& options)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : base::Thread("TestService"),
39a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      request_ownership_options_(options.request_ownership_options),
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      dbus_task_runner_(options.dbus_task_runner),
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      on_all_methods_exported_(false, false),
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      num_exported_methods_(0) {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TestService::~TestService() {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Stop();
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TestService::StartService() {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Thread::Options thread_options;
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  thread_options.message_loop_type = base::MessageLoop::TYPE_IO;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return StartWithOptions(thread_options);
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TestService::WaitUntilServiceIsStarted() {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::TimeDelta timeout(TestTimeouts::action_max_timeout());
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wait until all methods are exported.
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return on_all_methods_exported_.TimedWait(timeout);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestService::ShutdownAndBlock() {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message_loop()->PostTask(
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&TestService::ShutdownAndBlockInternal,
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this)));
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TestService::HasDBusThread() {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return bus_->HasDBusThread();
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestService::ShutdownAndBlockInternal() {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (HasDBusThread())
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bus_->ShutdownOnDBusThreadAndBlock();
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bus_->ShutdownAndBlock();
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestService::SendTestSignal(const std::string& message) {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message_loop()->PostTask(
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&TestService::SendTestSignalInternal,
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this),
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 message));
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestService::SendTestSignalFromRoot(const std::string& message) {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message_loop()->PostTask(
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&TestService::SendTestSignalFromRootInternal,
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this),
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 message));
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestService::SendTestSignalInternal(const std::string& message) {
967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  Signal signal("org.chromium.TestInterface", "Test");
977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  MessageWriter writer(&signal);
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  writer.AppendString(message);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exported_object_->SendSignal(&signal);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestService::SendTestSignalFromRootInternal(const std::string& message) {
1037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  Signal signal("org.chromium.TestInterface", "Test");
1047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  MessageWriter writer(&signal);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  writer.AppendString(message);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bus_->RequestOwnership("org.chromium.TestService",
108a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                         request_ownership_options_,
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         base::Bind(&TestService::OnOwnership,
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    base::Unretained(this),
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    base::Bind(&EmptyCallback)));
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use "/" just like dbus-send does.
1147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ExportedObject* root_object = bus_->GetExportedObject(ObjectPath("/"));
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  root_object->SendSignal(&signal);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TestService::RequestOwnership(base::Callback<void(bool)> callback) {
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message_loop()->PostTask(
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&TestService::RequestOwnershipInternal,
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::Unretained(this),
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 callback));
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TestService::RequestOwnershipInternal(
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::Callback<void(bool)> callback) {
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bus_->RequestOwnership("org.chromium.TestService",
129a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                         request_ownership_options_,
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         base::Bind(&TestService::OnOwnership,
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    base::Unretained(this),
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    callback));
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TestService::OnOwnership(base::Callback<void(bool)> callback,
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              const std::string& service_name,
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              bool success) {
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  has_ownership_ = success;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG_IF(ERROR, !success) << "Failed to own: " << service_name;
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback.Run(success);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestService::OnExported(const std::string& interface_name,
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const std::string& method_name,
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             bool success) {
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!success) {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Failed to export: " << interface_name << "."
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               << method_name;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Returning here will make WaitUntilServiceIsStarted() to time out
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // and return false.
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ++num_exported_methods_;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (num_exported_methods_ == kNumMethodsToExport)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    on_all_methods_exported_.Signal();
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void TestService::Run(base::MessageLoop* message_loop) {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Bus::Options bus_options;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bus_options.bus_type = Bus::SESSION;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bus_options.connection_type = Bus::PRIVATE;
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bus_options.dbus_task_runner = dbus_task_runner_;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bus_ = new Bus(bus_options);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bus_->RequestOwnership("org.chromium.TestService",
167a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                         request_ownership_options_,
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         base::Bind(&TestService::OnOwnership,
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    base::Unretained(this),
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    base::Bind(&EmptyCallback)));
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exported_object_ = bus_->GetExportedObject(
1737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      ObjectPath("/org/chromium/TestObject"));
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int num_methods = 0;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exported_object_->ExportMethod(
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "org.chromium.TestInterface",
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Echo",
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&TestService::Echo,
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this)),
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&TestService::OnExported,
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this)));
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ++num_methods;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exported_object_->ExportMethod(
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "org.chromium.TestInterface",
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "SlowEcho",
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&TestService::SlowEcho,
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this)),
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&TestService::OnExported,
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this)));
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ++num_methods;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exported_object_->ExportMethod(
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "org.chromium.TestInterface",
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "AsyncEcho",
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&TestService::AsyncEcho,
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this)),
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&TestService::OnExported,
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this)));
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ++num_methods;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exported_object_->ExportMethod(
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "org.chromium.TestInterface",
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "BrokenMethod",
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&TestService::BrokenMethod,
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this)),
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&TestService::OnExported,
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this)));
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ++num_methods;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exported_object_->ExportMethod(
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "org.chromium.TestInterface",
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "PerformAction",
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&TestService::PerformAction,
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::Unretained(this)),
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&TestService::OnExported,
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::Unretained(this)));
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ++num_methods;
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  exported_object_->ExportMethod(
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       kPropertiesInterface,
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       kPropertiesGetAll,
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       base::Bind(&TestService::GetAllProperties,
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  base::Unretained(this)),
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       base::Bind(&TestService::OnExported,
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  base::Unretained(this)));
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ++num_methods;
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exported_object_->ExportMethod(
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       kPropertiesInterface,
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       kPropertiesGet,
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       base::Bind(&TestService::GetProperty,
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  base::Unretained(this)),
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       base::Bind(&TestService::OnExported,
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  base::Unretained(this)));
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ++num_methods;
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exported_object_->ExportMethod(
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       kPropertiesInterface,
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       kPropertiesSet,
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       base::Bind(&TestService::SetProperty,
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  base::Unretained(this)),
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       base::Bind(&TestService::OnExported,
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  base::Unretained(this)));
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ++num_methods;
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  exported_object_manager_ = bus_->GetExportedObject(
2497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      ObjectPath("/org/chromium/TestService"));
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  exported_object_manager_->ExportMethod(
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       kObjectManagerInterface,
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       kObjectManagerGetManagedObjects,
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       base::Bind(&TestService::GetManagedObjects,
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  base::Unretained(this)),
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       base::Bind(&TestService::OnExported,
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  base::Unretained(this)));
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ++num_methods;
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Just print an error message as we don't want to crash tests.
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Tests will fail at a call to WaitUntilServiceIsStarted().
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (num_methods != kNumMethodsToExport) {
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "The number of methods does not match";
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message_loop->Run();
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestService::Echo(MethodCall* method_call,
2697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                       ExportedObject::ResponseSender response_sender) {
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MessageReader reader(method_call);
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string text_message;
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!reader.PopString(&text_message)) {
2737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    response_sender.Run(scoped_ptr<Response>());
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<Response> response = Response::FromMethodCall(method_call);
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MessageWriter writer(response.get());
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  writer.AppendString(text_message);
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  response_sender.Run(response.Pass());
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void TestService::SlowEcho(MethodCall* method_call,
2847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           ExportedObject::ResponseSender response_sender) {
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::PlatformThread::Sleep(TestTimeouts::tiny_timeout());
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Echo(method_call, response_sender);
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void TestService::AsyncEcho(MethodCall* method_call,
2907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                            ExportedObject::ResponseSender response_sender) {
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Schedule a call to Echo() to send an asynchronous response after we return.
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message_loop()->PostDelayedTask(FROM_HERE,
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  base::Bind(&TestService::Echo,
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             base::Unretained(this),
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             method_call,
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             response_sender),
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  TestTimeouts::tiny_timeout());
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void TestService::BrokenMethod(MethodCall* method_call,
3017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               ExportedObject::ResponseSender response_sender) {
3027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  response_sender.Run(scoped_ptr<Response>());
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestService::GetAllProperties(
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MethodCall* method_call,
3087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    ExportedObject::ResponseSender response_sender) {
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MessageReader reader(method_call);
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string interface;
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!reader.PopString(&interface)) {
3127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    response_sender.Run(scoped_ptr<Response>());
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<Response> response = Response::FromMethodCall(method_call);
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MessageWriter writer(response.get());
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AddPropertiesToWriter(&writer);
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  response_sender.Run(response.Pass());
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void TestService::GetProperty(MethodCall* method_call,
3257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                              ExportedObject::ResponseSender response_sender) {
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MessageReader reader(method_call);
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string interface;
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!reader.PopString(&interface)) {
3297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    response_sender.Run(scoped_ptr<Response>());
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string name;
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!reader.PopString(&name)) {
3357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    response_sender.Run(scoped_ptr<Response>());
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (name == "Name") {
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Return the previous value for the "Name" property:
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Variant<"TestService">
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<Response> response = Response::FromMethodCall(method_call);
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MessageWriter writer(response.get());
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.AppendVariantOfString("TestService");
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    response_sender.Run(response.Pass());
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (name == "Version") {
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Return a new value for the "Version" property:
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Variant<20>
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<Response> response = Response::FromMethodCall(method_call);
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MessageWriter writer(response.get());
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.AppendVariantOfInt16(20);
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    response_sender.Run(response.Pass());
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (name == "Methods") {
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Return the previous value for the "Methods" property:
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Variant<["Echo", "SlowEcho", "AsyncEcho", "BrokenMethod"]>
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<Response> response = Response::FromMethodCall(method_call);
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MessageWriter writer(response.get());
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MessageWriter variant_writer(NULL);
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MessageWriter variant_array_writer(NULL);
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.OpenVariant("as", &variant_writer);
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    variant_writer.OpenArray("s", &variant_array_writer);
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    variant_array_writer.AppendString("Echo");
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    variant_array_writer.AppendString("SlowEcho");
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    variant_array_writer.AppendString("AsyncEcho");
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    variant_array_writer.AppendString("BrokenMethod");
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    variant_writer.CloseContainer(&variant_array_writer);
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.CloseContainer(&variant_writer);
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    response_sender.Run(response.Pass());
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (name == "Objects") {
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Return the previous value for the "Objects" property:
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Variant<[objectpath:"/TestObjectPath"]>
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<Response> response = Response::FromMethodCall(method_call);
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MessageWriter writer(response.get());
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MessageWriter variant_writer(NULL);
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MessageWriter variant_array_writer(NULL);
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.OpenVariant("ao", &variant_writer);
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    variant_writer.OpenArray("o", &variant_array_writer);
3857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    variant_array_writer.AppendObjectPath(ObjectPath("/TestObjectPath"));
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    variant_writer.CloseContainer(&variant_array_writer);
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.CloseContainer(&variant_writer);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    response_sender.Run(response.Pass());
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Return error.
3927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    response_sender.Run(scoped_ptr<Response>());
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void TestService::SetProperty(MethodCall* method_call,
3987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                              ExportedObject::ResponseSender response_sender) {
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MessageReader reader(method_call);
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string interface;
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!reader.PopString(&interface)) {
4027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    response_sender.Run(scoped_ptr<Response>());
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string name;
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!reader.PopString(&name)) {
4087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    response_sender.Run(scoped_ptr<Response>());
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (name != "Name") {
4137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    response_sender.Run(scoped_ptr<Response>());
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string value;
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!reader.PopVariantOfString(&value)) {
4197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    response_sender.Run(scoped_ptr<Response>());
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SendPropertyChangedSignal(value);
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  response_sender.Run(Response::FromMethodCall(method_call));
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TestService::PerformAction(
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      MethodCall* method_call,
4307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      ExportedObject::ResponseSender response_sender) {
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MessageReader reader(method_call);
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string action;
4337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ObjectPath object_path;
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!reader.PopString(&action) || !reader.PopObjectPath(&object_path)) {
4357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    response_sender.Run(scoped_ptr<Response>());
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (action == "AddObject")
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AddObject(object_path);
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else if (action == "RemoveObject")
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RemoveObject(object_path);
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<Response> response = Response::FromMethodCall(method_call);
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  response_sender.Run(response.Pass());
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TestService::GetManagedObjects(
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MethodCall* method_call,
4507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    ExportedObject::ResponseSender response_sender) {
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<Response> response = Response::FromMethodCall(method_call);
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MessageWriter writer(response.get());
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The managed objects response is a dictionary of object paths identifying
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the object(s) with a dictionary of strings identifying the interface(s)
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // they implement and then a dictionary of property values.
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Thus this looks something like:
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // {
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //   "/org/chromium/TestObject": {
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //     "org.chromium.TestInterface": { /* Properties */ }
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //   }
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // }
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MessageWriter array_writer(NULL);
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MessageWriter dict_entry_writer(NULL);
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MessageWriter object_array_writer(NULL);
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MessageWriter object_dict_entry_writer(NULL);
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  writer.OpenArray("{oa{sa{sv}}}", &array_writer);
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  array_writer.OpenDictEntry(&dict_entry_writer);
4757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  dict_entry_writer.AppendObjectPath(ObjectPath("/org/chromium/TestObject"));
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict_entry_writer.OpenArray("{sa{sv}}", &object_array_writer);
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  object_array_writer.OpenDictEntry(&object_dict_entry_writer);
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  object_dict_entry_writer.AppendString("org.chromium.TestInterface");
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AddPropertiesToWriter(&object_dict_entry_writer);
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  object_array_writer.CloseContainer(&object_dict_entry_writer);
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict_entry_writer.CloseContainer(&object_array_writer);
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  array_writer.CloseContainer(&dict_entry_writer);
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  writer.CloseContainer(&array_writer);
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  response_sender.Run(response.Pass());
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void TestService::AddPropertiesToWriter(MessageWriter* writer) {
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The properties response is a dictionary of strings identifying the
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // property and a variant containing the property value. We return all
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // of the properties, thus the response is:
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // {
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //   "Name": Variant<"TestService">,
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //   "Version": Variant<10>,
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //   "Methods": Variant<["Echo", "SlowEcho", "AsyncEcho", "BrokenMethod"]>,
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //   "Objects": Variant<[objectpath:"/TestObjectPath"]>
5017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // }
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MessageWriter array_writer(NULL);
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MessageWriter dict_entry_writer(NULL);
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MessageWriter variant_writer(NULL);
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MessageWriter variant_array_writer(NULL);
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  writer->OpenArray("{sv}", &array_writer);
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  array_writer.OpenDictEntry(&dict_entry_writer);
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict_entry_writer.AppendString("Name");
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict_entry_writer.AppendVariantOfString("TestService");
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  array_writer.CloseContainer(&dict_entry_writer);
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  array_writer.OpenDictEntry(&dict_entry_writer);
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict_entry_writer.AppendString("Version");
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict_entry_writer.AppendVariantOfInt16(10);
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  array_writer.CloseContainer(&dict_entry_writer);
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  array_writer.OpenDictEntry(&dict_entry_writer);
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict_entry_writer.AppendString("Methods");
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict_entry_writer.OpenVariant("as", &variant_writer);
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  variant_writer.OpenArray("s", &variant_array_writer);
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  variant_array_writer.AppendString("Echo");
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  variant_array_writer.AppendString("SlowEcho");
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  variant_array_writer.AppendString("AsyncEcho");
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  variant_array_writer.AppendString("BrokenMethod");
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  variant_writer.CloseContainer(&variant_array_writer);
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict_entry_writer.CloseContainer(&variant_writer);
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  array_writer.CloseContainer(&dict_entry_writer);
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  array_writer.OpenDictEntry(&dict_entry_writer);
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict_entry_writer.AppendString("Objects");
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict_entry_writer.OpenVariant("ao", &variant_writer);
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  variant_writer.OpenArray("o", &variant_array_writer);
5367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  variant_array_writer.AppendObjectPath(ObjectPath("/TestObjectPath"));
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  variant_writer.CloseContainer(&variant_array_writer);
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict_entry_writer.CloseContainer(&variant_writer);
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  array_writer.CloseContainer(&dict_entry_writer);
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  writer->CloseContainer(&array_writer);
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void TestService::AddObject(const ObjectPath& object_path) {
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  message_loop()->PostTask(
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&TestService::AddObjectInternal,
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::Unretained(this),
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 object_path));
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void TestService::AddObjectInternal(const ObjectPath& object_path) {
5537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  Signal signal(kObjectManagerInterface, kObjectManagerInterfacesAdded);
5547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  MessageWriter writer(&signal);
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  writer.AppendObjectPath(object_path);
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MessageWriter array_writer(NULL);
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MessageWriter dict_entry_writer(NULL);
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  writer.OpenArray("{sa{sv}}", &array_writer);
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  array_writer.OpenDictEntry(&dict_entry_writer);
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict_entry_writer.AppendString("org.chromium.TestInterface");
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AddPropertiesToWriter(&dict_entry_writer);
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  array_writer.CloseContainer(&dict_entry_writer);
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  writer.CloseContainer(&array_writer);
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  exported_object_manager_->SendSignal(&signal);
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void TestService::RemoveObject(const ObjectPath& object_path) {
5717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  message_loop()->PostTask(FROM_HERE,
5727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           base::Bind(&TestService::RemoveObjectInternal,
5737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                      base::Unretained(this),
5747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                      object_path));
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void TestService::RemoveObjectInternal(const ObjectPath& object_path) {
5787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  Signal signal(kObjectManagerInterface, kObjectManagerInterfacesRemoved);
5797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  MessageWriter writer(&signal);
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  writer.AppendObjectPath(object_path);
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<std::string> interfaces;
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  interfaces.push_back("org.chromium.TestInterface");
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  writer.AppendArrayOfStrings(interfaces);
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  exported_object_manager_->SendSignal(&signal);
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestService::SendPropertyChangedSignal(const std::string& name) {
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message_loop()->PostTask(
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&TestService::SendPropertyChangedSignalInternal,
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this),
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 name));
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestService::SendPropertyChangedSignalInternal(const std::string& name) {
5997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  Signal signal(kPropertiesInterface, kPropertiesChanged);
6007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  MessageWriter writer(&signal);
6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  writer.AppendString("org.chromium.TestInterface");
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MessageWriter array_writer(NULL);
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MessageWriter dict_entry_writer(NULL);
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  writer.OpenArray("{sv}", &array_writer);
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  array_writer.OpenDictEntry(&dict_entry_writer);
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dict_entry_writer.AppendString("Name");
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dict_entry_writer.AppendVariantOfString(name);
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  array_writer.CloseContainer(&dict_entry_writer);
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  writer.CloseContainer(&array_writer);
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exported_object_->SendSignal(&signal);
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace dbus
617