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,
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// 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),
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      on_name_obtained_(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());
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Wait until the ownership of the service name is obtained.
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return on_name_obtained_.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);
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  on_name_obtained_.Signal();
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void TestService::ReleaseOwnership(base::Closure callback) {
146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bus_->GetDBusTaskRunner()->PostTask(
147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FROM_HERE,
148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&TestService::ReleaseOwnershipInternal,
149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this),
150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 callback));
151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void TestService::ReleaseOwnershipInternal(
154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::Closure callback) {
155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bus_->ReleaseOwnership("org.chromium.TestService");
156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  has_ownership_ = false;
157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bus_->GetOriginTaskRunner()->PostTask(
159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FROM_HERE,
160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      callback);
161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid TestService::SetSendImmediatePropertiesChanged() {
1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  send_immediate_properties_changed_ = true;
1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestService::OnExported(const std::string& interface_name,
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const std::string& method_name,
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             bool success) {
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!success) {
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Failed to export: " << interface_name << "."
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               << method_name;
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Returning here will make WaitUntilServiceIsStarted() to time out
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // and return false.
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ++num_exported_methods_;
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (num_exported_methods_ == kNumMethodsToExport) {
1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // As documented in exported_object.h, the service name should be
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // requested after all methods are exposed.
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bus_->RequestOwnership("org.chromium.TestService",
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           request_ownership_options_,
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           base::Bind(&TestService::OnOwnership,
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      base::Unretained(this),
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      base::Bind(&EmptyCallback)));
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void TestService::Run(base::MessageLoop* message_loop) {
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Bus::Options bus_options;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bus_options.bus_type = Bus::SESSION;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bus_options.connection_type = Bus::PRIVATE;
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bus_options.dbus_task_runner = dbus_task_runner_;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bus_ = new Bus(bus_options);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exported_object_ = bus_->GetExportedObject(
1987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      ObjectPath("/org/chromium/TestObject"));
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int num_methods = 0;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exported_object_->ExportMethod(
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "org.chromium.TestInterface",
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Echo",
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&TestService::Echo,
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this)),
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&TestService::OnExported,
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this)));
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ++num_methods;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exported_object_->ExportMethod(
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "org.chromium.TestInterface",
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "SlowEcho",
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&TestService::SlowEcho,
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this)),
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&TestService::OnExported,
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this)));
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ++num_methods;
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exported_object_->ExportMethod(
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "org.chromium.TestInterface",
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "AsyncEcho",
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&TestService::AsyncEcho,
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this)),
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&TestService::OnExported,
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this)));
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ++num_methods;
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exported_object_->ExportMethod(
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "org.chromium.TestInterface",
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "BrokenMethod",
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&TestService::BrokenMethod,
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this)),
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&TestService::OnExported,
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this)));
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ++num_methods;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exported_object_->ExportMethod(
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "org.chromium.TestInterface",
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "PerformAction",
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&TestService::PerformAction,
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::Unretained(this)),
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&TestService::OnExported,
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::Unretained(this)));
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ++num_methods;
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  exported_object_->ExportMethod(
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       kPropertiesInterface,
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       kPropertiesGetAll,
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       base::Bind(&TestService::GetAllProperties,
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  base::Unretained(this)),
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       base::Bind(&TestService::OnExported,
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  base::Unretained(this)));
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ++num_methods;
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exported_object_->ExportMethod(
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       kPropertiesInterface,
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       kPropertiesGet,
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       base::Bind(&TestService::GetProperty,
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  base::Unretained(this)),
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       base::Bind(&TestService::OnExported,
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  base::Unretained(this)));
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ++num_methods;
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exported_object_->ExportMethod(
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       kPropertiesInterface,
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       kPropertiesSet,
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       base::Bind(&TestService::SetProperty,
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  base::Unretained(this)),
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       base::Bind(&TestService::OnExported,
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  base::Unretained(this)));
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ++num_methods;
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  exported_object_manager_ = bus_->GetExportedObject(
2747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      ObjectPath("/org/chromium/TestService"));
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  exported_object_manager_->ExportMethod(
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       kObjectManagerInterface,
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       kObjectManagerGetManagedObjects,
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       base::Bind(&TestService::GetManagedObjects,
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  base::Unretained(this)),
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       base::Bind(&TestService::OnExported,
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  base::Unretained(this)));
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ++num_methods;
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Just print an error message as we don't want to crash tests.
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Tests will fail at a call to WaitUntilServiceIsStarted().
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (num_methods != kNumMethodsToExport) {
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "The number of methods does not match";
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message_loop->Run();
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestService::Echo(MethodCall* method_call,
2947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                       ExportedObject::ResponseSender response_sender) {
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MessageReader reader(method_call);
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string text_message;
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!reader.PopString(&text_message)) {
2987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    response_sender.Run(scoped_ptr<Response>());
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<Response> response = Response::FromMethodCall(method_call);
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MessageWriter writer(response.get());
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  writer.AppendString(text_message);
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  response_sender.Run(response.Pass());
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void TestService::SlowEcho(MethodCall* method_call,
3097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           ExportedObject::ResponseSender response_sender) {
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::PlatformThread::Sleep(TestTimeouts::tiny_timeout());
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Echo(method_call, response_sender);
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void TestService::AsyncEcho(MethodCall* method_call,
3157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                            ExportedObject::ResponseSender response_sender) {
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Schedule a call to Echo() to send an asynchronous response after we return.
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message_loop()->PostDelayedTask(FROM_HERE,
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  base::Bind(&TestService::Echo,
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             base::Unretained(this),
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             method_call,
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             response_sender),
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  TestTimeouts::tiny_timeout());
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void TestService::BrokenMethod(MethodCall* method_call,
3267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               ExportedObject::ResponseSender response_sender) {
3277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  response_sender.Run(scoped_ptr<Response>());
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestService::GetAllProperties(
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MethodCall* method_call,
3337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    ExportedObject::ResponseSender response_sender) {
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MessageReader reader(method_call);
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string interface;
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!reader.PopString(&interface)) {
3377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    response_sender.Run(scoped_ptr<Response>());
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<Response> response = Response::FromMethodCall(method_call);
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MessageWriter writer(response.get());
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AddPropertiesToWriter(&writer);
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  response_sender.Run(response.Pass());
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void TestService::GetProperty(MethodCall* method_call,
3507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                              ExportedObject::ResponseSender response_sender) {
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MessageReader reader(method_call);
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string interface;
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!reader.PopString(&interface)) {
3547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    response_sender.Run(scoped_ptr<Response>());
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string name;
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!reader.PopString(&name)) {
3607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    response_sender.Run(scoped_ptr<Response>());
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (name == "Name") {
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Return the previous value for the "Name" property:
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Variant<"TestService">
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<Response> response = Response::FromMethodCall(method_call);
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MessageWriter writer(response.get());
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.AppendVariantOfString("TestService");
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    response_sender.Run(response.Pass());
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (name == "Version") {
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Return a new value for the "Version" property:
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Variant<20>
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<Response> response = Response::FromMethodCall(method_call);
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MessageWriter writer(response.get());
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.AppendVariantOfInt16(20);
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    response_sender.Run(response.Pass());
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (name == "Methods") {
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Return the previous value for the "Methods" property:
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Variant<["Echo", "SlowEcho", "AsyncEcho", "BrokenMethod"]>
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<Response> response = Response::FromMethodCall(method_call);
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MessageWriter writer(response.get());
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MessageWriter variant_writer(NULL);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MessageWriter variant_array_writer(NULL);
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.OpenVariant("as", &variant_writer);
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    variant_writer.OpenArray("s", &variant_array_writer);
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    variant_array_writer.AppendString("Echo");
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    variant_array_writer.AppendString("SlowEcho");
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    variant_array_writer.AppendString("AsyncEcho");
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    variant_array_writer.AppendString("BrokenMethod");
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    variant_writer.CloseContainer(&variant_array_writer);
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.CloseContainer(&variant_writer);
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    response_sender.Run(response.Pass());
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (name == "Objects") {
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Return the previous value for the "Objects" property:
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Variant<[objectpath:"/TestObjectPath"]>
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<Response> response = Response::FromMethodCall(method_call);
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MessageWriter writer(response.get());
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MessageWriter variant_writer(NULL);
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MessageWriter variant_array_writer(NULL);
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.OpenVariant("ao", &variant_writer);
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    variant_writer.OpenArray("o", &variant_array_writer);
4107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    variant_array_writer.AppendObjectPath(ObjectPath("/TestObjectPath"));
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    variant_writer.CloseContainer(&variant_array_writer);
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.CloseContainer(&variant_writer);
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    response_sender.Run(response.Pass());
415a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  } else if (name == "Bytes") {
416a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Return the previous value for the "Bytes" property:
417a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Variant<[0x54, 0x65, 0x73, 0x74]>
418a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    scoped_ptr<Response> response = Response::FromMethodCall(method_call);
419a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    MessageWriter writer(response.get());
420a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    MessageWriter variant_writer(NULL);
421a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    MessageWriter variant_array_writer(NULL);
422a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
423a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    writer.OpenVariant("ay", &variant_writer);
424a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const uint8 bytes[] = { 0x54, 0x65, 0x73, 0x74 };
425a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    variant_writer.AppendArrayOfBytes(bytes, sizeof(bytes));
426a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    writer.CloseContainer(&variant_writer);
427a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
428a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    response_sender.Run(response.Pass());
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Return error.
4317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    response_sender.Run(scoped_ptr<Response>());
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void TestService::SetProperty(MethodCall* method_call,
4377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                              ExportedObject::ResponseSender response_sender) {
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MessageReader reader(method_call);
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string interface;
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!reader.PopString(&interface)) {
4417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    response_sender.Run(scoped_ptr<Response>());
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string name;
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!reader.PopString(&name)) {
4477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    response_sender.Run(scoped_ptr<Response>());
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (name != "Name") {
4527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    response_sender.Run(scoped_ptr<Response>());
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string value;
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!reader.PopVariantOfString(&value)) {
4587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    response_sender.Run(scoped_ptr<Response>());
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SendPropertyChangedSignal(value);
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  response_sender.Run(Response::FromMethodCall(method_call));
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TestService::PerformAction(
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      MethodCall* method_call,
4697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      ExportedObject::ResponseSender response_sender) {
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MessageReader reader(method_call);
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string action;
4727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ObjectPath object_path;
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!reader.PopString(&action) || !reader.PopObjectPath(&object_path)) {
4747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    response_sender.Run(scoped_ptr<Response>());
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (action == "AddObject") {
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AddObject(object_path);
4801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } else if (action == "RemoveObject") {
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RemoveObject(object_path);
4821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } else if (action == "SetSendImmediatePropertiesChanged") {
4831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SetSendImmediatePropertiesChanged();
4841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } if (action == "ReleaseOwnership") {
485a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ReleaseOwnership(base::Bind(&TestService::PerformActionResponse,
486a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                base::Unretained(this),
487a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                method_call, response_sender));
488a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
489a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  } else if (action == "Ownership") {
490a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ReleaseOwnership(base::Bind(&TestService::OwnershipReleased,
491a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                base::Unretained(this),
492a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                method_call, response_sender));
493a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
494a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<Response> response = Response::FromMethodCall(method_call);
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  response_sender.Run(response.Pass());
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
500a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void TestService::PerformActionResponse(
501a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    MethodCall* method_call,
502a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ExportedObject::ResponseSender response_sender) {
503a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<Response> response = Response::FromMethodCall(method_call);
504a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  response_sender.Run(response.Pass());
505a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
506a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
507a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void TestService::OwnershipReleased(
508a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    MethodCall* method_call,
509a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ExportedObject::ResponseSender response_sender) {
510a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  RequestOwnership(base::Bind(&TestService::OwnershipRegained,
511a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                              base::Unretained(this),
512a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                              method_call, response_sender));
513a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
514a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
515a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
516a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void TestService::OwnershipRegained(
517a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    MethodCall* method_call,
518a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ExportedObject::ResponseSender response_sender,
519a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    bool success) {
520a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  PerformActionResponse(method_call, response_sender);
521a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
522a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
523a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TestService::GetManagedObjects(
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MethodCall* method_call,
5267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    ExportedObject::ResponseSender response_sender) {
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<Response> response = Response::FromMethodCall(method_call);
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MessageWriter writer(response.get());
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The managed objects response is a dictionary of object paths identifying
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the object(s) with a dictionary of strings identifying the interface(s)
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // they implement and then a dictionary of property values.
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Thus this looks something like:
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // {
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //   "/org/chromium/TestObject": {
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //     "org.chromium.TestInterface": { /* Properties */ }
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //   }
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // }
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MessageWriter array_writer(NULL);
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MessageWriter dict_entry_writer(NULL);
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MessageWriter object_array_writer(NULL);
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MessageWriter object_dict_entry_writer(NULL);
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  writer.OpenArray("{oa{sa{sv}}}", &array_writer);
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  array_writer.OpenDictEntry(&dict_entry_writer);
5517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  dict_entry_writer.AppendObjectPath(ObjectPath("/org/chromium/TestObject"));
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict_entry_writer.OpenArray("{sa{sv}}", &object_array_writer);
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  object_array_writer.OpenDictEntry(&object_dict_entry_writer);
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  object_dict_entry_writer.AppendString("org.chromium.TestInterface");
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AddPropertiesToWriter(&object_dict_entry_writer);
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  object_array_writer.CloseContainer(&object_dict_entry_writer);
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict_entry_writer.CloseContainer(&object_array_writer);
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  array_writer.CloseContainer(&dict_entry_writer);
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  writer.CloseContainer(&array_writer);
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  response_sender.Run(response.Pass());
5651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (send_immediate_properties_changed_)
5671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SendPropertyChangedSignal("ChangedTestServiceName");
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void TestService::AddPropertiesToWriter(MessageWriter* writer) {
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The properties response is a dictionary of strings identifying the
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // property and a variant containing the property value. We return all
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // of the properties, thus the response is:
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // {
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //   "Name": Variant<"TestService">,
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //   "Version": Variant<10>,
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //   "Methods": Variant<["Echo", "SlowEcho", "AsyncEcho", "BrokenMethod"]>,
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //   "Objects": Variant<[objectpath:"/TestObjectPath"]>
580a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  //   "Bytes": Variant<[0x54, 0x65, 0x73, 0x74]>
5817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // }
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MessageWriter array_writer(NULL);
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MessageWriter dict_entry_writer(NULL);
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MessageWriter variant_writer(NULL);
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MessageWriter variant_array_writer(NULL);
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  writer->OpenArray("{sv}", &array_writer);
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  array_writer.OpenDictEntry(&dict_entry_writer);
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict_entry_writer.AppendString("Name");
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict_entry_writer.AppendVariantOfString("TestService");
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  array_writer.CloseContainer(&dict_entry_writer);
5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  array_writer.OpenDictEntry(&dict_entry_writer);
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict_entry_writer.AppendString("Version");
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict_entry_writer.AppendVariantOfInt16(10);
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  array_writer.CloseContainer(&dict_entry_writer);
5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  array_writer.OpenDictEntry(&dict_entry_writer);
6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict_entry_writer.AppendString("Methods");
6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict_entry_writer.OpenVariant("as", &variant_writer);
6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  variant_writer.OpenArray("s", &variant_array_writer);
6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  variant_array_writer.AppendString("Echo");
6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  variant_array_writer.AppendString("SlowEcho");
6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  variant_array_writer.AppendString("AsyncEcho");
6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  variant_array_writer.AppendString("BrokenMethod");
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  variant_writer.CloseContainer(&variant_array_writer);
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict_entry_writer.CloseContainer(&variant_writer);
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  array_writer.CloseContainer(&dict_entry_writer);
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  array_writer.OpenDictEntry(&dict_entry_writer);
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict_entry_writer.AppendString("Objects");
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict_entry_writer.OpenVariant("ao", &variant_writer);
6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  variant_writer.OpenArray("o", &variant_array_writer);
6167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  variant_array_writer.AppendObjectPath(ObjectPath("/TestObjectPath"));
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  variant_writer.CloseContainer(&variant_array_writer);
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict_entry_writer.CloseContainer(&variant_writer);
6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  array_writer.CloseContainer(&dict_entry_writer);
6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
621a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  array_writer.OpenDictEntry(&dict_entry_writer);
622a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  dict_entry_writer.AppendString("Bytes");
623a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  dict_entry_writer.OpenVariant("ay", &variant_writer);
624a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const uint8 bytes[] = { 0x54, 0x65, 0x73, 0x74 };
625a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  variant_writer.AppendArrayOfBytes(bytes, sizeof(bytes));
626a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  dict_entry_writer.CloseContainer(&variant_writer);
627a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  array_writer.CloseContainer(&dict_entry_writer);
628a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  writer->CloseContainer(&array_writer);
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void TestService::AddObject(const ObjectPath& object_path) {
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  message_loop()->PostTask(
6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&TestService::AddObjectInternal,
6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::Unretained(this),
6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 object_path));
6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void TestService::AddObjectInternal(const ObjectPath& object_path) {
6417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  Signal signal(kObjectManagerInterface, kObjectManagerInterfacesAdded);
6427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  MessageWriter writer(&signal);
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  writer.AppendObjectPath(object_path);
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MessageWriter array_writer(NULL);
6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MessageWriter dict_entry_writer(NULL);
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  writer.OpenArray("{sa{sv}}", &array_writer);
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  array_writer.OpenDictEntry(&dict_entry_writer);
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict_entry_writer.AppendString("org.chromium.TestInterface");
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AddPropertiesToWriter(&dict_entry_writer);
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  array_writer.CloseContainer(&dict_entry_writer);
6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  writer.CloseContainer(&array_writer);
6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  exported_object_manager_->SendSignal(&signal);
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void TestService::RemoveObject(const ObjectPath& object_path) {
6597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  message_loop()->PostTask(FROM_HERE,
6607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           base::Bind(&TestService::RemoveObjectInternal,
6617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                      base::Unretained(this),
6627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                      object_path));
6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void TestService::RemoveObjectInternal(const ObjectPath& object_path) {
6667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  Signal signal(kObjectManagerInterface, kObjectManagerInterfacesRemoved);
6677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  MessageWriter writer(&signal);
6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  writer.AppendObjectPath(object_path);
6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<std::string> interfaces;
6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  interfaces.push_back("org.chromium.TestInterface");
6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  writer.AppendArrayOfStrings(interfaces);
6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  exported_object_manager_->SendSignal(&signal);
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestService::SendPropertyChangedSignal(const std::string& name) {
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message_loop()->PostTask(
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&TestService::SendPropertyChangedSignalInternal,
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this),
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 name));
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestService::SendPropertyChangedSignalInternal(const std::string& name) {
6877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  Signal signal(kPropertiesInterface, kPropertiesChanged);
6887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  MessageWriter writer(&signal);
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  writer.AppendString("org.chromium.TestInterface");
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MessageWriter array_writer(NULL);
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MessageWriter dict_entry_writer(NULL);
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  writer.OpenArray("{sv}", &array_writer);
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  array_writer.OpenDictEntry(&dict_entry_writer);
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dict_entry_writer.AppendString("Name");
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dict_entry_writer.AppendVariantOfString(name);
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  array_writer.CloseContainer(&dict_entry_writer);
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  writer.CloseContainer(&array_writer);
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exported_object_->SendSignal(&signal);
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace dbus
705