12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "dbus/object_manager.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string>
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <vector>
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/basictypes.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h"
129ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/run_loop.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/thread.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/thread_restrictions.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "dbus/bus.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "dbus/object_path.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "dbus/object_proxy.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "dbus/property.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "dbus/test_service.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)namespace dbus {
247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The object manager test exercises the asynchronous APIs in ObjectManager,
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// and by extension PropertySet and Property<>.
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ObjectManagerTest
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : public testing::Test,
297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      public ObjectManager::Interface {
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ObjectManagerTest() : timeout_expired_(false) {
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  struct Properties : public PropertySet {
357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    Property<std::string> name;
367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    Property<int16> version;
377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    Property<std::vector<std::string> > methods;
387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    Property<std::vector<ObjectPath> > objects;
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    Properties(ObjectProxy* object_proxy,
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               const std::string& interface_name,
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               PropertyChangedCallback property_changed_callback)
437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        : PropertySet(object_proxy, interface_name, property_changed_callback) {
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      RegisterProperty("Name", &name);
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      RegisterProperty("Version", &version);
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      RegisterProperty("Methods", &methods);
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      RegisterProperty("Objects", &objects);
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual PropertySet* CreateProperties(
527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      ObjectProxy* object_proxy,
537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      const ObjectPath& object_path,
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& interface_name) OVERRIDE {
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Properties* properties = new Properties(
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        object_proxy, interface_name,
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&ObjectManagerTest::OnPropertyChanged,
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   base::Unretained(this), object_path));
597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return static_cast<PropertySet*>(properties);
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SetUp() {
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Make the main thread not to allow IO.
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::ThreadRestrictions::SetIOAllowed(false);
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Start the D-Bus thread.
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dbus_thread_.reset(new base::Thread("D-Bus Thread"));
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::Thread::Options thread_options;
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    thread_options.message_loop_type = base::MessageLoop::TYPE_IO;
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(dbus_thread_->StartWithOptions(thread_options));
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Start the test service, using the D-Bus thread.
737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    TestService::Options options;
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    options.dbus_task_runner = dbus_thread_->message_loop_proxy();
757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    test_service_.reset(new TestService(options));
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(test_service_->StartService());
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(test_service_->WaitUntilServiceIsStarted());
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(test_service_->HasDBusThread());
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Create the client, using the D-Bus thread.
817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    Bus::Options bus_options;
827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    bus_options.bus_type = Bus::SESSION;
837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    bus_options.connection_type = Bus::PRIVATE;
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bus_options.dbus_task_runner = dbus_thread_->message_loop_proxy();
857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    bus_ = new Bus(bus_options);
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(bus_->HasDBusThread());
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    object_manager_ = bus_->GetObjectManager(
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        "org.chromium.TestService",
907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        ObjectPath("/org/chromium/TestService"));
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    object_manager_->RegisterInterface("org.chromium.TestInterface", this);
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WaitForObject();
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void TearDown() {
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bus_->ShutdownOnDBusThreadAndBlock();
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Shut down the service.
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    test_service_->ShutdownAndBlock();
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Reset to the default.
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::ThreadRestrictions::SetIOAllowed(true);
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Stopping a thread is considered an IO operation, so do this after
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // allowing IO.
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    test_service_->Stop();
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    base::RunLoop().RunUntilIdle();
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void MethodCallback(Response* response) {
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    method_callback_called_ = true;
1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    run_loop_->Quit();
1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Called from the PropertiesChangedAsObjectsReceived test case. The test will
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // not run the message loop if it receives the expected PropertiesChanged
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // signal before the timeout. This method immediately fails the test.
1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void PropertiesChangedTestTimeout() {
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    timeout_expired_ = true;
1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    run_loop_->Quit();
1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    FAIL() << "Never received PropertiesChanged";
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) protected:
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Called when an object is added.
1297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual void ObjectAdded(const ObjectPath& object_path,
1307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           const std::string& interface_name) OVERRIDE {
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    added_objects_.push_back(std::make_pair(object_path, interface_name));
1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    run_loop_->Quit();
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Called when an object is removed.
1367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual void ObjectRemoved(const ObjectPath& object_path,
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             const std::string& interface_name) OVERRIDE {
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    removed_objects_.push_back(std::make_pair(object_path, interface_name));
1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    run_loop_->Quit();
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Called when a property value is updated.
1437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void OnPropertyChanged(const ObjectPath& object_path,
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         const std::string& name) {
1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Store the value of the "Name" property if that's the one that
1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // changed.
1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    Properties* properties = static_cast<Properties*>(
1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        object_manager_->GetProperties(
1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            object_path,
1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            "org.chromium.TestInterface"));
1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (name == properties->name.name())
1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      last_name_value_ = properties->name.value();
1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Store the updated property.
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    updated_properties_.push_back(name);
1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    run_loop_->Quit();
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static const size_t kExpectedObjects = 1;
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static const size_t kExpectedProperties = 4;
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void WaitForObject() {
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    while (added_objects_.size() < kExpectedObjects ||
1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci           updated_properties_.size() < kExpectedProperties) {
1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      run_loop_.reset(new base::RunLoop);
1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      run_loop_->Run();
1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (size_t i = 0; i < kExpectedObjects; ++i)
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      added_objects_.erase(added_objects_.begin());
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (size_t i = 0; i < kExpectedProperties; ++i)
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      updated_properties_.erase(updated_properties_.begin());
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void WaitForRemoveObject() {
1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    while (removed_objects_.size() < kExpectedObjects) {
1761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      run_loop_.reset(new base::RunLoop);
1771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      run_loop_->Run();
1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (size_t i = 0; i < kExpectedObjects; ++i)
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      removed_objects_.erase(removed_objects_.begin());
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void WaitForMethodCallback() {
1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    run_loop_.reset(new base::RunLoop);
1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    run_loop_->Run();
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    method_callback_called_ = false;
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void PerformAction(const std::string& action, const ObjectPath& object_path) {
1907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    ObjectProxy* object_proxy = bus_->GetObjectProxy(
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        "org.chromium.TestService",
1927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        ObjectPath("/org/chromium/TestObject"));
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    MethodCall method_call("org.chromium.TestInterface", "PerformAction");
1957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    MessageWriter writer(&method_call);
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    writer.AppendString(action);
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    writer.AppendObjectPath(object_path);
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    object_proxy->CallMethod(&method_call,
2007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                             ObjectProxy::TIMEOUT_USE_DEFAULT,
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             base::Bind(&ObjectManagerTest::MethodCallback,
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        base::Unretained(this)));
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WaitForMethodCallback();
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop message_loop_;
2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<base::RunLoop> run_loop_;
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<base::Thread> dbus_thread_;
2097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_refptr<Bus> bus_;
2107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ObjectManager* object_manager_;
2117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<TestService> test_service_;
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string last_name_value_;
2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool timeout_expired_;
2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  std::vector<std::pair<ObjectPath, std::string> > added_objects_;
2177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  std::vector<std::pair<ObjectPath, std::string> > removed_objects_;
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<std::string> updated_properties_;
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool method_callback_called_;
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ObjectManagerTest, InitialObject) {
2257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ObjectProxy* object_proxy = object_manager_->GetObjectProxy(
2267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      ObjectPath("/org/chromium/TestObject"));
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(object_proxy != NULL);
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Properties* properties = static_cast<Properties*>(
2307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      object_manager_->GetProperties(ObjectPath("/org/chromium/TestObject"),
2317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                     "org.chromium.TestInterface"));
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(properties != NULL);
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("TestService", properties->name.value());
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(10, properties->version.value());
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<std::string> methods = properties->methods.value();
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(4U, methods.size());
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("Echo", methods[0]);
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("SlowEcho", methods[1]);
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("AsyncEcho", methods[2]);
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("BrokenMethod", methods[3]);
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  std::vector<ObjectPath> objects = properties->objects.value();
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(1U, objects.size());
2467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(ObjectPath("/TestObjectPath"), objects[0]);
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ObjectManagerTest, UnknownObjectProxy) {
2507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ObjectProxy* object_proxy = object_manager_->GetObjectProxy(
2517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      ObjectPath("/org/chromium/UnknownObject"));
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(object_proxy == NULL);
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ObjectManagerTest, UnknownObjectProperties) {
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Properties* properties = static_cast<Properties*>(
2577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      object_manager_->GetProperties(ObjectPath("/org/chromium/UnknownObject"),
2587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                     "org.chromium.TestInterface"));
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(properties == NULL);
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ObjectManagerTest, UnknownInterfaceProperties) {
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Properties* properties = static_cast<Properties*>(
2647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      object_manager_->GetProperties(ObjectPath("/org/chromium/TestObject"),
2657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                     "org.chromium.UnknownService"));
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(properties == NULL);
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ObjectManagerTest, GetObjects) {
2707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  std::vector<ObjectPath> object_paths = object_manager_->GetObjects();
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(1U, object_paths.size());
2727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(ObjectPath("/org/chromium/TestObject"), object_paths[0]);
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ObjectManagerTest, GetObjectsWithInterface) {
2767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  std::vector<ObjectPath> object_paths =
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      object_manager_->GetObjectsWithInterface("org.chromium.TestInterface");
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(1U, object_paths.size());
2797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(ObjectPath("/org/chromium/TestObject"), object_paths[0]);
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ObjectManagerTest, GetObjectsWithUnknownInterface) {
2837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  std::vector<ObjectPath> object_paths =
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      object_manager_->GetObjectsWithInterface("org.chromium.UnknownService");
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0U, object_paths.size());
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ObjectManagerTest, SameObject) {
2897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ObjectManager* object_manager = bus_->GetObjectManager(
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "org.chromium.TestService",
2917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      ObjectPath("/org/chromium/TestService"));
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(object_manager_, object_manager);
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ObjectManagerTest, DifferentObjectForService) {
2967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ObjectManager* object_manager = bus_->GetObjectManager(
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "org.chromium.DifferentService",
2987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      ObjectPath("/org/chromium/TestService"));
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(object_manager_, object_manager);
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ObjectManagerTest, DifferentObjectForPath) {
3037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ObjectManager* object_manager = bus_->GetObjectManager(
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "org.chromium.TestService",
3057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      ObjectPath("/org/chromium/DifferentService"));
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(object_manager_, object_manager);
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ObjectManagerTest, SecondObject) {
3107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  PerformAction("AddObject", ObjectPath("/org/chromium/SecondObject"));
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForObject();
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ObjectProxy* object_proxy = object_manager_->GetObjectProxy(
3147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      ObjectPath("/org/chromium/SecondObject"));
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(object_proxy != NULL);
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Properties* properties = static_cast<Properties*>(
3187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      object_manager_->GetProperties(ObjectPath("/org/chromium/SecondObject"),
3197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                     "org.chromium.TestInterface"));
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(properties != NULL);
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  std::vector<ObjectPath> object_paths = object_manager_->GetObjects();
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(2U, object_paths.size());
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::sort(object_paths.begin(), object_paths.end());
3267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(ObjectPath("/org/chromium/SecondObject"), object_paths[0]);
3277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(ObjectPath("/org/chromium/TestObject"), object_paths[1]);
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  object_paths =
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      object_manager_->GetObjectsWithInterface("org.chromium.TestInterface");
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(2U, object_paths.size());
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::sort(object_paths.begin(), object_paths.end());
3347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(ObjectPath("/org/chromium/SecondObject"), object_paths[0]);
3357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(ObjectPath("/org/chromium/TestObject"), object_paths[1]);
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ObjectManagerTest, RemoveSecondObject) {
3397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  PerformAction("AddObject", ObjectPath("/org/chromium/SecondObject"));
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForObject();
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  std::vector<ObjectPath> object_paths = object_manager_->GetObjects();
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(2U, object_paths.size());
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  PerformAction("RemoveObject", ObjectPath("/org/chromium/SecondObject"));
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForRemoveObject();
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ObjectProxy* object_proxy = object_manager_->GetObjectProxy(
3497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      ObjectPath("/org/chromium/SecondObject"));
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(object_proxy == NULL);
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Properties* properties = static_cast<Properties*>(
3537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      object_manager_->GetProperties(ObjectPath("/org/chromium/SecondObject"),
3547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                     "org.chromium.TestInterface"));
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(properties == NULL);
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  object_paths = object_manager_->GetObjects();
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(1U, object_paths.size());
3597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(ObjectPath("/org/chromium/TestObject"), object_paths[0]);
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  object_paths =
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      object_manager_->GetObjectsWithInterface("org.chromium.TestInterface");
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(1U, object_paths.size());
3647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(ObjectPath("/org/chromium/TestObject"), object_paths[0]);
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
367a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(ObjectManagerTest, OwnershipLost) {
368a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  PerformAction("ReleaseOwnership", ObjectPath("/org/chromium/TestService"));
369a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  WaitForRemoveObject();
370a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
371a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::vector<ObjectPath> object_paths = object_manager_->GetObjects();
372a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(0U, object_paths.size());
373a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
374a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
375a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(ObjectManagerTest, OwnershipLostAndRegained) {
376a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  PerformAction("Ownership", ObjectPath("/org/chromium/TestService"));
377a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  WaitForRemoveObject();
378a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  WaitForObject();
379a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
380a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::vector<ObjectPath> object_paths = object_manager_->GetObjects();
381a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(1U, object_paths.size());
382a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
383a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
3841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(ObjectManagerTest, PropertiesChangedAsObjectsReceived) {
3851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Remove the existing object manager.
3861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  object_manager_->UnregisterInterface("org.chromium.TestInterface");
3871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  run_loop_.reset(new base::RunLoop);
3881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(bus_->RemoveObjectManager(
3891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "org.chromium.TestService",
3901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ObjectPath("/org/chromium/TestService"),
3911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      run_loop_->QuitClosure()));
3921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  run_loop_->Run();
3931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  PerformAction("SetSendImmediatePropertiesChanged",
3951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                ObjectPath("/org/chromium/TestService"));
3961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  object_manager_ = bus_->GetObjectManager(
3981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "org.chromium.TestService",
3991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ObjectPath("/org/chromium/TestService"));
4001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  object_manager_->RegisterInterface("org.chromium.TestInterface", this);
4011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // The newly created object manager should call GetManagedObjects immediately
4031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // after setting up the match rule for PropertiesChanged. We should process
4041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // the PropertiesChanged event right after that. If we don't receive it within
4051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // 2 seconds, then fail the test.
4061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  message_loop_.PostDelayedTask(
4071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      FROM_HERE,
4081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(&ObjectManagerTest::PropertiesChangedTestTimeout,
4091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 base::Unretained(this)),
4101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::TimeDelta::FromSeconds(2));
4111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  while (last_name_value_ != "ChangedTestServiceName" && !timeout_expired_) {
4131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    run_loop_.reset(new base::RunLoop);
4141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    run_loop_->Run();
4151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
4161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
4171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}  // namespace dbus
419