// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "bluetooth/dispatcher/impersonation_object_manager_interface.h"

#include <memory>
#include <utility>

#include <base/bind.h>
#include <base/message_loop/message_loop.h>
#include <base/run_loop.h>
#include <dbus/mock_bus.h>
#include <dbus/mock_exported_object.h>
#include <dbus/mock_object_manager.h>
#include <dbus/mock_object_proxy.h>
#include <brillo/dbus/exported_property_set.h>
#include <brillo/dbus/mock_dbus_object.h>
#include <brillo/dbus/mock_exported_object_manager.h>
#include <dbus/property.h>
#include <gtest/gtest.h>

#include "bluetooth/dispatcher/client_manager.h"
#include "bluetooth/dispatcher/mock_dbus_connection_factory.h"
#include "bluetooth/dispatcher/test_helper.h"

using ::testing::_;
using ::testing::AnyNumber;
using ::testing::Mock;
using ::testing::Return;
using ::testing::SaveArg;

namespace bluetooth {

namespace {

constexpr char kTestInterfaceName1[] = "org.example.Interface1";
constexpr char kTestInterfaceName2[] = "org.example.Interface2";
constexpr char kTestObjectPath1[] = "/org/example/Object1";
constexpr char kTestObjectPath2[] = "/org/example/Object2";
constexpr char kTestObjectManagerPath[] = "/";
constexpr char kTestServiceName1[] = "org.example.Service1";
constexpr char kTestServiceName2[] = "org.example.Service2";
constexpr char kTestMethodName1[] = "Method1";
constexpr char kTestMethodName2[] = "Method2";

constexpr char kStringPropertyName[] = "SomeString";
constexpr char kIntPropertyName[] = "SomeInt";
constexpr char kBoolPropertyName[] = "SomeBool";
constexpr char kMergeStringPropertyName[] = "SomeStringForMerging";

constexpr char kTestMethodCallString[] = "The Method Call";
constexpr char kTestResponseString[] = "The Response";

constexpr char kTestSender[] = ":1.1";

constexpr int kTestSerial = 10;

constexpr int kTestIntPropertyValue = 7;
constexpr char kTestStringPropertyValue[] = "some property value";
constexpr bool kTestBoolPropertyValue = true;

}  // namespace

class TestInterfaceHandler : public InterfaceHandler {
 public:
  TestInterfaceHandler() {
    property_factory_map_[kStringPropertyName] =
        std::make_unique<PropertyFactory<std::string>>();
    property_factory_map_[kIntPropertyName] =
        std::make_unique<PropertyFactory<int>>();
    property_factory_map_[kBoolPropertyName] =
        std::make_unique<PropertyFactory<bool>>();
    property_factory_map_[kMergeStringPropertyName] =
        std::make_unique<PropertyFactory<std::string>>(
            MergingRule::CONCATENATION);

    method_forwardings_[kTestMethodName1] = ForwardingRule::FORWARD_DEFAULT;
    method_forwardings_[kTestMethodName2] = ForwardingRule::FORWARD_ALL;
  }

  explicit TestInterfaceHandler(ObjectExportRule object_export_rule)
      : TestInterfaceHandler() {
    object_export_rule_ = object_export_rule;
  }

  const PropertyFactoryMap& GetPropertyFactoryMap() const override {
    return property_factory_map_;
  }

  const std::map<std::string, ForwardingRule>& GetMethodForwardings()
      const override {
    return method_forwardings_;
  }

  ObjectExportRule GetObjectExportRule() const override {
    return object_export_rule_;
  }

 private:
  InterfaceHandler::PropertyFactoryMap property_factory_map_;
  std::map<std::string, ForwardingRule> method_forwardings_;
  ObjectExportRule object_export_rule_ = ObjectExportRule::ANY_SERVICE;
};

class ImpersonationObjectManagerInterfaceTest : public ::testing::Test {
 public:
  void SetUp() override {
    bus_ = new dbus::MockBus(dbus::Bus::Options());
    auto dbus_connection_factory =
        std::make_unique<MockDBusConnectionFactory>();
    dbus_connection_factory_ = dbus_connection_factory.get();
    client_manager_ = std::make_unique<ClientManager>(
        bus_, std::move(dbus_connection_factory));
    EXPECT_CALL(*bus_, GetDBusTaskRunner())
        .WillRepeatedly(Return(message_loop_.task_runner().get()));
    EXPECT_CALL(*bus_, AssertOnOriginThread()).Times(AnyNumber());
    EXPECT_CALL(*bus_, AssertOnDBusThread()).Times(AnyNumber());
    EXPECT_CALL(*bus_, Connect()).WillRepeatedly(Return(false));
    EXPECT_CALL(*bus_, HasDBusThread()).WillRepeatedly(Return(false));

    dbus::ObjectPath object_manager_path(kTestObjectManagerPath);

    object_manager_object_proxy1_ = new dbus::MockObjectProxy(
        bus_.get(), kTestServiceName1, object_manager_path);
    EXPECT_CALL(*bus_, GetObjectProxy(kTestServiceName1, object_manager_path))
        .WillOnce(Return(object_manager_object_proxy1_.get()));
    object_manager_object_proxy2_ = new dbus::MockObjectProxy(
        bus_.get(), kTestServiceName2, object_manager_path);
    EXPECT_CALL(*bus_, GetObjectProxy(kTestServiceName2, object_manager_path))
        .WillOnce(Return(object_manager_object_proxy2_.get()));

    object_manager1_ = new dbus::MockObjectManager(
        bus_.get(), kTestServiceName1, object_manager_path);
    object_manager2_ = new dbus::MockObjectManager(
        bus_.get(), kTestServiceName2, object_manager_path);
    // Force MessageLoop to run pending tasks as effect of instantiating
    // MockObjectManager. Needed to avoid memory leaks because pending tasks
    // are unowned pointers that will only self destruct after being run.
    base::RunLoop().RunUntilIdle();
    auto exported_object_manager =
        std::make_unique<brillo::dbus_utils::MockExportedObjectManager>(
            bus_, object_manager_path);
    exported_object_manager_ = exported_object_manager.get();
    EXPECT_CALL(*exported_object_manager_, RegisterAsync(_)).Times(1);
    exported_object_manager_wrapper_ =
        std::make_unique<ExportedObjectManagerWrapper>(
            bus_, std::move(exported_object_manager));
    object_proxy_ = new dbus::MockObjectProxy(
        bus_.get(), kTestServiceName1, dbus::ObjectPath(kTestObjectPath1));
  }

  void StubHandlePropertiesSet(
      dbus::MethodCall* method_call,
      int timeout_ms,
      dbus::ObjectProxy::ResponseCallback* callback,
      dbus::ObjectProxy::ErrorCallback* error_callback) {
    StubHandleMethod(dbus::kPropertiesInterface, dbus::kPropertiesSet,
                     kTestMethodCallString, kTestResponseString,
                     /* error_name */ "", /* error_message */ "", method_call,
                     timeout_ms, callback, error_callback);
  }

  void StubHandleTestMethod1(dbus::MethodCall* method_call,
                             int timeout_ms,
                             dbus::ObjectProxy::ResponseCallback* callback,
                             dbus::ObjectProxy::ErrorCallback* error_callback) {
    StubHandleMethod(kTestInterfaceName1, kTestMethodName1,
                     kTestMethodCallString, kTestResponseString,
                     /* error_name */ "", /* error_message */ "", method_call,
                     timeout_ms, callback, error_callback);
  }

  void StubHandleTestMethod2(dbus::MethodCall* method_call,
                             int timeout_ms,
                             dbus::ObjectProxy::ResponseCallback* callback,
                             dbus::ObjectProxy::ErrorCallback* error_callback) {
    StubHandleMethod(kTestInterfaceName1, kTestMethodName2,
                     kTestMethodCallString, kTestResponseString,
                     /* error_name */ "", /* error_message */ "", method_call,
                     timeout_ms, callback, error_callback);
  }

 protected:
  // Expects that |exported_object| exports the standard methods:
  // Get/Set/GetAll/PropertiesChanged.
  // Optionally the Set handler will be assigned if |set_method_handler| is
  // provided.
  void ExpectExportPropertiesMethods(
      dbus::MockExportedObject* exported_object,
      dbus::ExportedObject::MethodCallCallback* set_method_handler = nullptr) {
    EXPECT_CALL(*exported_object,
                ExportMethodAndBlock(dbus::kPropertiesInterface,
                                     dbus::kPropertiesGet, _))
        .WillOnce(Return(true));

    EXPECT_CALL(*exported_object,
                ExportMethodAndBlock(dbus::kPropertiesInterface,
                                     dbus::kPropertiesGetAll, _))
        .WillOnce(Return(true));

    if (set_method_handler == nullptr)
      set_method_handler = &dummy_method_handler_;
    EXPECT_CALL(*exported_object,
                ExportMethodAndBlock(dbus::kPropertiesInterface,
                                     dbus::kPropertiesSet, _))
        .WillOnce(DoAll(SaveArg<2>(set_method_handler), Return(true)));
  }

  void TestMethodForwarding(
      const std::string& interface_name,
      const std::string& method_name,
      const dbus::ObjectPath object_path,
      scoped_refptr<dbus::MockBus> forwarding_bus,
      dbus::ExportedObject::MethodCallCallback* tested_method_handler,
      void (ImpersonationObjectManagerInterfaceTest::*stub_method_handler)(
          dbus::MethodCall*,
          int,
          dbus::ObjectProxy::ResponseCallback*,
          dbus::ObjectProxy::ErrorCallback*)) {
    scoped_refptr<dbus::MockObjectProxy> object_proxy1 =
        new dbus::MockObjectProxy(forwarding_bus.get(), kTestServiceName1,
                                  object_path);
    EXPECT_CALL(*forwarding_bus, GetObjectProxy(kTestServiceName1, object_path))
        .WillOnce(Return(object_proxy1.get()));
    EXPECT_CALL(*forwarding_bus, Connect()).WillRepeatedly(Return(true));
    dbus::MethodCall method_call(interface_name, method_name);
    method_call.SetPath(object_path);
    method_call.SetSender(kTestSender);
    method_call.SetSerial(kTestSerial);
    dbus::MessageWriter writer(&method_call);
    writer.AppendString(kTestMethodCallString);
    EXPECT_CALL(*object_proxy1, DoCallMethodWithErrorCallback(_, _, _, _))
        .WillOnce(Invoke(this, stub_method_handler));
    std::unique_ptr<dbus::Response> saved_response;
    tested_method_handler->Run(
        &method_call, base::Bind(
                          [](std::unique_ptr<dbus::Response>* saved_response,
                             std::unique_ptr<dbus::Response> response) {
                            *saved_response = std::move(response);
                          },
                          &saved_response));
    EXPECT_TRUE(saved_response.get() != nullptr);
    std::string saved_response_string;
    dbus::MessageReader reader(saved_response.get());
    reader.PopString(&saved_response_string);
    // Check that the response is the forwarded response of the stub method
    // handler.
    EXPECT_EQ(kTestSender, saved_response->GetDestination());
    EXPECT_EQ(kTestSerial, saved_response->GetReplySerial());
    EXPECT_EQ(kTestResponseString, saved_response_string);
  }

  void TestMethodForwardingMultiService(
      const std::string& interface_name,
      const std::string& method_name,
      const dbus::ObjectPath object_path,
      scoped_refptr<dbus::MockBus> forwarding_bus,
      dbus::ExportedObject::MethodCallCallback* tested_method_handler,
      void (ImpersonationObjectManagerInterfaceTest::*stub_method_handler)(
          dbus::MethodCall*,
          int,
          dbus::ObjectProxy::ResponseCallback*,
          dbus::ObjectProxy::ErrorCallback*)) {
    scoped_refptr<dbus::MockObjectProxy> object_proxy1 =
        new dbus::MockObjectProxy(forwarding_bus.get(), kTestServiceName1,
                                  object_path);
    scoped_refptr<dbus::MockObjectProxy> object_proxy2 =
        new dbus::MockObjectProxy(forwarding_bus.get(), kTestServiceName2,
                                  object_path);
    EXPECT_CALL(*forwarding_bus, GetObjectProxy(kTestServiceName1, object_path))
        .WillOnce(Return(object_proxy1.get()));
    EXPECT_CALL(*forwarding_bus, GetObjectProxy(kTestServiceName2, object_path))
        .WillOnce(Return(object_proxy2.get()));
    EXPECT_CALL(*forwarding_bus, Connect()).WillRepeatedly(Return(true));
    dbus::MethodCall method_call(interface_name, method_name);
    method_call.SetPath(object_path);
    method_call.SetSender(kTestSender);
    method_call.SetSerial(kTestSerial);
    dbus::MessageWriter writer(&method_call);
    writer.AppendString(kTestMethodCallString);

    // Check that the object proxies of both services receive method forwarding.
    EXPECT_CALL(*object_proxy1, DoCallMethodWithErrorCallback(_, _, _, _))
        .WillOnce(Invoke(this, stub_method_handler));
    EXPECT_CALL(*object_proxy2, DoCallMethodWithErrorCallback(_, _, _, _))
        .WillOnce(Invoke(this, stub_method_handler));

    std::unique_ptr<dbus::Response> saved_response;
    tested_method_handler->Run(
        &method_call, base::Bind(
                          [](std::unique_ptr<dbus::Response>* saved_response,
                             std::unique_ptr<dbus::Response> response) {
                            *saved_response = std::move(response);
                          },
                          &saved_response));
    EXPECT_TRUE(saved_response.get() != nullptr);
    std::string saved_response_string;
    dbus::MessageReader reader(saved_response.get());
    reader.PopString(&saved_response_string);
    // Check that the response is the forwarded response of the stub method
    // handler.
    EXPECT_EQ(kTestSender, saved_response->GetDestination());
    EXPECT_EQ(kTestSerial, saved_response->GetReplySerial());
    EXPECT_EQ(kTestResponseString, saved_response_string);
  }

  // Expects that |exported_object| exports the test methods.
  // Optionally the method handlers will be assigned if |method1_handler| or
  // |method2_handler| is not null.
  void ExpectExportTestMethods(
      dbus::MockExportedObject* exported_object,
      const std::string& interface_name,
      dbus::ExportedObject::MethodCallCallback* method1_handler = nullptr,
      dbus::ExportedObject::MethodCallCallback* method2_handler = nullptr) {
    if (method1_handler == nullptr)
      method1_handler = &dummy_method_handler_;
    EXPECT_CALL(*exported_object,
                ExportMethodAndBlock(interface_name, kTestMethodName1, _))
        .WillOnce(DoAll(SaveArg<2>(method1_handler), Return(true)));

    if (method2_handler == nullptr)
      method2_handler = &dummy_method_handler_;
    EXPECT_CALL(*exported_object,
                ExportMethodAndBlock(interface_name, kTestMethodName2, _))
        .WillOnce(DoAll(SaveArg<2>(method2_handler), Return(true)));
  }

  void ExpectUnexportTestMethods(dbus::MockExportedObject* exported_object,
                                 const std::string& interface_name) {
    EXPECT_CALL(*exported_object,
                UnexportMethodAndBlock(interface_name, kTestMethodName1))
        .WillOnce(Return(true));
    EXPECT_CALL(*exported_object,
                UnexportMethodAndBlock(interface_name, kTestMethodName2))
        .WillOnce(Return(true));
  }

  template <typename T>
  void SetPropertyValue(dbus::PropertyBase* property_base, T value) {
    dbus::Property<T>* property =
        static_cast<dbus::Property<T>*>(property_base);
    property->SetAndBlock(value);
    property->ReplaceValueWithSetValue();
    property->set_valid(true);
  }

  template <typename T>
  void ExpectExportedPropertyEquals(
      T value,
      brillo::dbus_utils::ExportedPropertyBase* exported_property_base) {
    ASSERT_TRUE(exported_property_base != nullptr);
    brillo::dbus_utils::ExportedProperty<T>* exported_property =
        static_cast<brillo::dbus_utils::ExportedProperty<T>*>(
            exported_property_base);
    EXPECT_EQ(value, exported_property->value());
  }

  base::MessageLoop message_loop_;
  scoped_refptr<dbus::MockBus> bus_;
  scoped_refptr<dbus::MockObjectProxy> object_manager_object_proxy1_;
  scoped_refptr<dbus::MockObjectProxy> object_manager_object_proxy2_;
  scoped_refptr<dbus::MockObjectProxy> object_proxy_;
  scoped_refptr<dbus::MockObjectManager> object_manager1_;
  scoped_refptr<dbus::MockObjectManager> object_manager2_;
  std::unique_ptr<ExportedObjectManagerWrapper>
      exported_object_manager_wrapper_;
  brillo::dbus_utils::MockExportedObjectManager* exported_object_manager_;
  std::unique_ptr<ClientManager> client_manager_;
  MockDBusConnectionFactory* dbus_connection_factory_;
  dbus::ExportedObject::MethodCallCallback dummy_method_handler_;
};

TEST_F(ImpersonationObjectManagerInterfaceTest, SingleInterface) {
  dbus::ObjectPath object_path1(kTestObjectPath1);
  dbus::ObjectPath object_path2(kTestObjectPath2);

  std::map<std::string, std::unique_ptr<ExportedObject>> exported_objects;
  auto impersonation_om_interface =
      std::make_unique<ImpersonationObjectManagerInterface>(
          bus_, exported_object_manager_wrapper_.get(),
          std::make_unique<TestInterfaceHandler>(), kTestInterfaceName1,
          client_manager_.get());

  EXPECT_CALL(*object_manager1_, RegisterInterface(kTestInterfaceName1, _));
  impersonation_om_interface->RegisterToObjectManager(object_manager1_.get(),
                                                      kTestServiceName1);

  scoped_refptr<dbus::MockExportedObject> exported_object1 =
      new dbus::MockExportedObject(bus_.get(), object_path1);
  EXPECT_CALL(*bus_, GetExportedObject(object_path1))
      .WillOnce(Return(exported_object1.get()));
  scoped_refptr<dbus::MockExportedObject> exported_object2 =
      new dbus::MockExportedObject(bus_.get(), object_path2);
  EXPECT_CALL(*bus_, GetExportedObject(object_path2))
      .WillOnce(Return(exported_object2.get()));

  // D-Bus properties methods should be exported.
  ExpectExportPropertiesMethods(exported_object1.get());
  // CreateProperties called for an object.
  EXPECT_CALL(*exported_object_manager_,
              ClaimInterface(object_path1, dbus::kPropertiesInterface, _))
      .Times(1);
  std::unique_ptr<dbus::PropertySet> dbus_property_set1(
      impersonation_om_interface->CreateProperties(
          kTestServiceName1, object_proxy_.get(), object_path1,
          kTestInterfaceName1));
  PropertySet* property_set1 =
      static_cast<PropertySet*>(dbus_property_set1.get());
  // The properties should all be registered.
  ASSERT_NE(nullptr, property_set1->GetProperty(kStringPropertyName));
  ASSERT_NE(nullptr, property_set1->GetProperty(kIntPropertyName));
  ASSERT_NE(nullptr, property_set1->GetProperty(kBoolPropertyName));

  // D-Bus properties methods should be exported.
  ExpectExportPropertiesMethods(exported_object2.get());
  // CreateProperties called for another object.
  EXPECT_CALL(*exported_object_manager_,
              ClaimInterface(object_path2, dbus::kPropertiesInterface, _))
      .Times(1);
  std::unique_ptr<dbus::PropertySet> dbus_property_set2(
      impersonation_om_interface->CreateProperties(
          kTestServiceName1, object_proxy_.get(), object_path2,
          kTestInterfaceName1));
  PropertySet* property_set2 =
      static_cast<PropertySet*>(dbus_property_set2.get());

  // The properties should all be registered.
  ASSERT_NE(nullptr, property_set2->GetProperty(kStringPropertyName));
  ASSERT_NE(nullptr, property_set2->GetProperty(kIntPropertyName));
  ASSERT_NE(nullptr, property_set2->GetProperty(kBoolPropertyName));

  // ObjectAdded events
  ExpectExportTestMethods(exported_object1.get(), kTestInterfaceName1);
  ExpectExportTestMethods(exported_object2.get(), kTestInterfaceName1);
  EXPECT_CALL(*exported_object_manager_,
              ClaimInterface(object_path1, kTestInterfaceName1, _))
      .Times(1);
  impersonation_om_interface->ObjectAdded(kTestServiceName1, object_path1,
                                          kTestInterfaceName1);
  EXPECT_CALL(*exported_object_manager_,
              ClaimInterface(object_path2, kTestInterfaceName1, _))
      .Times(1);
  impersonation_om_interface->ObjectAdded(kTestServiceName1, object_path2,
                                          kTestInterfaceName1);

  // ObjectRemoved events
  EXPECT_CALL(*exported_object_manager_,
              ReleaseInterface(object_path1, dbus::kPropertiesInterface))
      .Times(1);
  EXPECT_CALL(*exported_object_manager_,
              ReleaseInterface(object_path1, kTestInterfaceName1))
      .Times(1);
  ExpectUnexportTestMethods(exported_object1.get(), kTestInterfaceName1);
  EXPECT_CALL(*exported_object1, Unregister()).Times(1);
  impersonation_om_interface->ObjectRemoved(kTestServiceName1, object_path1,
                                            kTestInterfaceName1);
  EXPECT_CALL(*exported_object_manager_,
              ReleaseInterface(object_path2, dbus::kPropertiesInterface))
      .Times(1);
  EXPECT_CALL(*exported_object_manager_,
              ReleaseInterface(object_path2, kTestInterfaceName1))
      .Times(1);
  ExpectUnexportTestMethods(exported_object2.get(), kTestInterfaceName1);
  EXPECT_CALL(*exported_object2, Unregister()).Times(1);
  impersonation_om_interface->ObjectRemoved(kTestServiceName1, object_path2,
                                            kTestInterfaceName1);
}

TEST_F(ImpersonationObjectManagerInterfaceTest, MultipleInterfaces) {
  dbus::ObjectPath object_path(kTestObjectPath1);

  scoped_refptr<dbus::MockExportedObject> exported_object =
      new dbus::MockExportedObject(bus_.get(), object_path);
  EXPECT_CALL(*bus_, GetExportedObject(object_path))
      .WillOnce(Return(exported_object.get()));

  std::map<std::string, std::unique_ptr<ExportedObject>> exported_objects;
  auto impersonation_om_interface1 =
      std::make_unique<ImpersonationObjectManagerInterface>(
          bus_, exported_object_manager_wrapper_.get(),
          std::make_unique<TestInterfaceHandler>(), kTestInterfaceName1,
          client_manager_.get());
  auto impersonation_om_interface2 =
      std::make_unique<ImpersonationObjectManagerInterface>(
          bus_, exported_object_manager_wrapper_.get(),
          std::make_unique<TestInterfaceHandler>(), kTestInterfaceName2,
          client_manager_.get());

  EXPECT_CALL(*object_manager1_, RegisterInterface(kTestInterfaceName1, _));
  EXPECT_CALL(*object_manager1_, RegisterInterface(kTestInterfaceName2, _));
  impersonation_om_interface1->RegisterToObjectManager(object_manager1_.get(),
                                                       kTestServiceName1);
  impersonation_om_interface2->RegisterToObjectManager(object_manager1_.get(),
                                                       kTestServiceName1);

  // D-Bus properties methods should be exported.
  ExpectExportPropertiesMethods(exported_object.get());
  // CreateProperties called for an object.
  EXPECT_CALL(*exported_object_manager_,
              ClaimInterface(object_path, dbus::kPropertiesInterface, _))
      .Times(1);
  std::unique_ptr<dbus::PropertySet> dbus_property_set1(
      impersonation_om_interface1->CreateProperties(
          kTestServiceName1, object_proxy_.get(), object_path,
          kTestInterfaceName1));
  PropertySet* property_set1 =
      static_cast<PropertySet*>(dbus_property_set1.get());

  std::unique_ptr<dbus::PropertySet> dbus_property_set2(
      impersonation_om_interface2->CreateProperties(
          kTestServiceName1, object_proxy_.get(), object_path,
          kTestInterfaceName2));
  PropertySet* property_set2 =
      static_cast<PropertySet*>(dbus_property_set2.get());

  // The properties should all be registered.
  ASSERT_NE(nullptr, property_set1->GetProperty(kStringPropertyName));
  ASSERT_NE(nullptr, property_set1->GetProperty(kIntPropertyName));
  ASSERT_NE(nullptr, property_set1->GetProperty(kBoolPropertyName));
  ASSERT_NE(nullptr, property_set2->GetProperty(kStringPropertyName));
  ASSERT_NE(nullptr, property_set2->GetProperty(kIntPropertyName));
  ASSERT_NE(nullptr, property_set2->GetProperty(kBoolPropertyName));

  // ObjectAdded events
  ExpectExportTestMethods(exported_object.get(), kTestInterfaceName1);
  ExpectExportTestMethods(exported_object.get(), kTestInterfaceName2);
  EXPECT_CALL(*exported_object_manager_,
              ClaimInterface(object_path, kTestInterfaceName1, _))
      .Times(1);
  impersonation_om_interface1->ObjectAdded(kTestServiceName1, object_path,
                                           kTestInterfaceName1);
  EXPECT_CALL(*exported_object_manager_,
              ClaimInterface(object_path, kTestInterfaceName2, _))
      .Times(1);
  impersonation_om_interface2->ObjectAdded(kTestServiceName1, object_path,
                                           kTestInterfaceName2);

  // ObjectRemoved events
  EXPECT_CALL(*exported_object_manager_,
              ReleaseInterface(object_path, kTestInterfaceName1))
      .Times(1);
  // Exported object shouldn't be unregistered until the last interface is
  // removed.
  ExpectUnexportTestMethods(exported_object.get(), kTestInterfaceName1);
  EXPECT_CALL(*exported_object, Unregister()).Times(0);
  impersonation_om_interface1->ObjectRemoved(kTestServiceName1, object_path,
                                             kTestInterfaceName1);

  EXPECT_CALL(*exported_object_manager_,
              ReleaseInterface(object_path, dbus::kPropertiesInterface))
      .Times(1);
  EXPECT_CALL(*exported_object_manager_,
              ReleaseInterface(object_path, kTestInterfaceName2))
      .Times(1);
  // Now that the last interface has been removed, exported object should be
  // unregistered.
  ExpectUnexportTestMethods(exported_object.get(), kTestInterfaceName2);
  EXPECT_CALL(*exported_object, Unregister()).Times(1);
  impersonation_om_interface2->ObjectRemoved(kTestServiceName1, object_path,
                                             kTestInterfaceName2);

  // Make sure that the Unregister actually happens on ObjectRemoved above and
  // not due to its automatic deletion when this test case finishes.
  Mock::VerifyAndClearExpectations(exported_object.get());
}

TEST_F(ImpersonationObjectManagerInterfaceTest, UnexpectedEvents) {
  dbus::ObjectPath object_path(kTestObjectPath1);

  scoped_refptr<dbus::MockExportedObject> exported_object =
      new dbus::MockExportedObject(bus_.get(), object_path);
  EXPECT_CALL(*bus_, GetExportedObject(object_path))
      .WillOnce(Return(exported_object.get()));

  std::map<std::string, std::unique_ptr<ExportedObject>> exported_objects;
  auto impersonation_om_interface =
      std::make_unique<ImpersonationObjectManagerInterface>(
          bus_, exported_object_manager_wrapper_.get(),
          std::make_unique<TestInterfaceHandler>(), kTestInterfaceName1,
          client_manager_.get());

  impersonation_om_interface->RegisterToObjectManager(object_manager1_.get(),
                                                      kTestServiceName1);

  // ObjectAdded event happens before CreateProperties. This shouldn't happen.
  // Make sure we only ignore the event and don't crash if this happens.
  EXPECT_CALL(*exported_object_manager_,
              ClaimInterface(object_path, dbus::kPropertiesInterface, _))
      .Times(1);
  EXPECT_CALL(*exported_object_manager_,
              ClaimInterface(object_path, kTestInterfaceName1, _))
      .Times(0);
  impersonation_om_interface->ObjectAdded(kTestServiceName1, object_path,
                                          kTestInterfaceName1);

  // ObjectRemoved event happens before CreateProperties. This shouldn't happen.
  // Make sure we only ignore the event and don't crash if this happens.
  EXPECT_CALL(*exported_object_manager_,
              ReleaseInterface(object_path, dbus::kPropertiesInterface))
      .Times(0);
  EXPECT_CALL(*exported_object_manager_,
              ReleaseInterface(object_path, kTestInterfaceName1))
      .Times(0);
  EXPECT_CALL(*exported_object, Unregister()).Times(0);
  impersonation_om_interface->ObjectRemoved(kTestServiceName1, object_path,
                                            kTestInterfaceName1);

  // D-Bus properties methods should be exported.
  ExpectExportPropertiesMethods(exported_object.get());
  // CreateProperties called for an object.
  std::unique_ptr<dbus::PropertySet> dbus_property_set(
      impersonation_om_interface->CreateProperties(
          kTestServiceName1, object_proxy_.get(), object_path,
          kTestInterfaceName1));
  PropertySet* property_set =
      static_cast<PropertySet*>(dbus_property_set.get());

  // The properties should all be registered.
  ASSERT_NE(nullptr, property_set->GetProperty(kStringPropertyName));
  ASSERT_NE(nullptr, property_set->GetProperty(kIntPropertyName));
  ASSERT_NE(nullptr, property_set->GetProperty(kBoolPropertyName));

  // ObjectRemoved event happens before ObjectAdded. This shouldn't happen.
  // Make sure we still handle this gracefully.
  EXPECT_CALL(*exported_object_manager_,
              ReleaseInterface(object_path, dbus::kPropertiesInterface))
      .Times(1);
  EXPECT_CALL(*exported_object_manager_,
              ReleaseInterface(object_path, kTestInterfaceName1))
      .Times(0);
  EXPECT_CALL(*exported_object, Unregister()).Times(1);
  impersonation_om_interface->ObjectRemoved(kTestServiceName1, object_path,
                                            kTestInterfaceName1);

  // Make sure that the Unregister actually happens on ObjectRemoved above and
  // not due to its automatic deletion when this test case finishes.
  Mock::VerifyAndClearExpectations(exported_object.get());
}

TEST_F(ImpersonationObjectManagerInterfaceTest, PropertiesHandler) {
  dbus::ObjectPath object_path1(kTestObjectPath1);

  scoped_refptr<dbus::MockExportedObject> exported_object1 =
      new dbus::MockExportedObject(bus_.get(), object_path1);
  EXPECT_CALL(*bus_, GetExportedObject(object_path1))
      .WillOnce(Return(exported_object1.get()));

  auto impersonation_om_interface =
      std::make_unique<ImpersonationObjectManagerInterface>(
          bus_, exported_object_manager_wrapper_.get(),
          std::make_unique<TestInterfaceHandler>(), kTestInterfaceName1,
          client_manager_.get());

  EXPECT_CALL(*object_manager1_, RegisterInterface(kTestInterfaceName1, _));
  impersonation_om_interface->RegisterToObjectManager(object_manager1_.get(),
                                                      kTestServiceName1);

  dbus::ExportedObject::MethodCallCallback set_method_handler;

  // D-Bus properties methods should be exported.
  ExpectExportPropertiesMethods(exported_object1.get(), &set_method_handler);
  // CreateProperties called for another object.
  EXPECT_CALL(*exported_object_manager_,
              ClaimInterface(object_path1, dbus::kPropertiesInterface, _))
      .Times(1);
  std::unique_ptr<dbus::PropertySet> dbus_property_set1(
      impersonation_om_interface->CreateProperties(
          kTestServiceName1, object_proxy_.get(), object_path1,
          kTestInterfaceName1));
  PropertySet* property_set1 =
      static_cast<PropertySet*>(dbus_property_set1.get());
  ASSERT_FALSE(set_method_handler.is_null());

  // The properties should all be registered.
  ASSERT_TRUE(property_set1->GetProperty(kStringPropertyName) != nullptr);
  ASSERT_TRUE(property_set1->GetProperty(kIntPropertyName) != nullptr);
  ASSERT_TRUE(property_set1->GetProperty(kBoolPropertyName) != nullptr);

  // Test that Properties.Set handler should forward the message to the source
  // service and forward the response back to the caller.
  TestMethodForwarding(
      dbus::kPropertiesInterface, dbus::kPropertiesSet, object_path1, bus_,
      &set_method_handler,
      &ImpersonationObjectManagerInterfaceTest::StubHandlePropertiesSet);

  // ObjectRemoved events
  EXPECT_CALL(*exported_object_manager_,
              ReleaseInterface(object_path1, dbus::kPropertiesInterface))
      .Times(1);
  EXPECT_CALL(*exported_object1, Unregister()).Times(1);
  impersonation_om_interface->ObjectRemoved(kTestServiceName1, object_path1,
                                            kTestInterfaceName1);
}

TEST_F(ImpersonationObjectManagerInterfaceTest, MethodHandler) {
  dbus::ObjectPath object_path1(kTestObjectPath1);

  scoped_refptr<dbus::MockExportedObject> exported_object1 =
      new dbus::MockExportedObject(bus_.get(), object_path1);
  EXPECT_CALL(*bus_, GetExportedObject(object_path1))
      .WillOnce(Return(exported_object1.get()));

  auto impersonation_om_interface =
      std::make_unique<ImpersonationObjectManagerInterface>(
          bus_, exported_object_manager_wrapper_.get(),
          std::make_unique<TestInterfaceHandler>(), kTestInterfaceName1,
          client_manager_.get());

  EXPECT_CALL(*object_manager1_, RegisterInterface(kTestInterfaceName1, _));
  impersonation_om_interface->RegisterToObjectManager(object_manager1_.get(),
                                                      kTestServiceName1);

  // D-Bus properties methods should be exported.
  ExpectExportPropertiesMethods(exported_object1.get());
  // CreateProperties called for another object.
  EXPECT_CALL(*exported_object_manager_,
              ClaimInterface(object_path1, dbus::kPropertiesInterface, _))
      .Times(1);
  std::unique_ptr<dbus::PropertySet> dbus_property_set1(
      impersonation_om_interface->CreateProperties(
          kTestServiceName1, object_proxy_.get(), object_path1,
          kTestInterfaceName1));

  // Method forwarding
  dbus::ExportedObject::MethodCallCallback method1_handler;
  dbus::ExportedObject::MethodCallCallback method2_handler;
  ExpectExportTestMethods(exported_object1.get(), kTestInterfaceName1,
                          &method1_handler, &method2_handler);
  EXPECT_CALL(*exported_object_manager_,
              ClaimInterface(object_path1, kTestInterfaceName1, _))
      .Times(1);
  impersonation_om_interface->ObjectAdded(kTestServiceName1, object_path1,
                                          kTestInterfaceName1);
  scoped_refptr<dbus::MockBus> client_bus =
      new dbus::MockBus(dbus::Bus::Options());
  EXPECT_CALL(*dbus_connection_factory_, GetNewBus())
      .WillOnce(Return(client_bus));
  // Test that method call should be forwarding to the source service via
  // |client_bus|.
  TestMethodForwarding(
      kTestInterfaceName1, kTestMethodName1, object_path1, client_bus,
      &method1_handler,
      &ImpersonationObjectManagerInterfaceTest::StubHandleTestMethod1);
  TestMethodForwarding(
      kTestInterfaceName1, kTestMethodName2, object_path1, client_bus,
      &method2_handler,
      &ImpersonationObjectManagerInterfaceTest::StubHandleTestMethod2);

  // ObjectRemoved events
  EXPECT_CALL(*exported_object_manager_,
              ReleaseInterface(object_path1, dbus::kPropertiesInterface))
      .Times(1);
  EXPECT_CALL(*exported_object_manager_,
              ReleaseInterface(object_path1, kTestInterfaceName1))
      .Times(1);
  ExpectUnexportTestMethods(exported_object1.get(), kTestInterfaceName1);
  EXPECT_CALL(*exported_object1, Unregister()).Times(1);
  impersonation_om_interface->ObjectRemoved(kTestServiceName1, object_path1,
                                            kTestInterfaceName1);
}

TEST_F(ImpersonationObjectManagerInterfaceTest, MultiService) {
  dbus::ObjectPath object_path1(kTestObjectPath1);

  std::map<std::string, std::unique_ptr<ExportedObject>> exported_objects;
  auto impersonation_om_interface =
      std::make_unique<ImpersonationObjectManagerInterface>(
          bus_, exported_object_manager_wrapper_.get(),
          std::make_unique<TestInterfaceHandler>(), kTestInterfaceName1,
          client_manager_.get());

  impersonation_om_interface->RegisterToObjectManager(object_manager1_.get(),
                                                      kTestServiceName1);
  impersonation_om_interface->RegisterToObjectManager(object_manager2_.get(),
                                                      kTestServiceName2);

  scoped_refptr<dbus::MockExportedObject> exported_object1 =
      new dbus::MockExportedObject(bus_.get(), object_path1);
  EXPECT_CALL(*bus_, GetExportedObject(object_path1))
      .WillOnce(Return(exported_object1.get()));

  // D-Bus properties methods should be exported.
  ExpectExportPropertiesMethods(exported_object1.get());
  // CreateProperties called for an object.
  EXPECT_CALL(*exported_object_manager_,
              ClaimInterface(object_path1, dbus::kPropertiesInterface, _))
      .Times(1);
  std::unique_ptr<dbus::PropertySet> dbus_property_set1(
      impersonation_om_interface->CreateProperties(
          kTestServiceName1, object_proxy_.get(), object_path1,
          kTestInterfaceName1));
  PropertySet* property_set1 =
      static_cast<PropertySet*>(dbus_property_set1.get());
  // The properties should all be registered.
  ASSERT_NE(nullptr, property_set1->GetProperty(kStringPropertyName));
  ASSERT_NE(nullptr, property_set1->GetProperty(kIntPropertyName));
  ASSERT_NE(nullptr, property_set1->GetProperty(kBoolPropertyName));
  EXPECT_CALL(*object_manager1_,
              GetProperties(object_path1, kTestInterfaceName1))
      .WillRepeatedly(Return(property_set1));
  SetPropertyValue<std::string>(property_set1->GetProperty(kStringPropertyName),
                                kTestStringPropertyValue);
  SetPropertyValue<int>(property_set1->GetProperty(kIntPropertyName),
                        kTestIntPropertyValue);
  // Trigger property changed event and check that the exported properties are
  // updated.
  property_set1->NotifyPropertyChanged(kStringPropertyName);
  property_set1->NotifyPropertyChanged(kIntPropertyName);
  property_set1->NotifyPropertyChanged(kBoolPropertyName);
  ExportedInterface* interface =
      exported_object_manager_wrapper_->GetExportedInterface(
          object_path1, kTestInterfaceName1);
  ExpectExportedPropertyEquals<std::string>(
      kTestStringPropertyValue,
      interface->GetRegisteredExportedProperty(kStringPropertyName));
  ExpectExportedPropertyEquals<int>(
      kTestIntPropertyValue,
      interface->GetRegisteredExportedProperty(kIntPropertyName));
  EXPECT_EQ(nullptr,
            interface->GetRegisteredExportedProperty(kBoolPropertyName));

  // Another service also triggers CreateProperties for the same object.
  // This shouldn't trigger another object export since it's already exported
  // when the first service triggered CreateProperties.
  EXPECT_CALL(*exported_object_manager_,
              ClaimInterface(object_path1, dbus::kPropertiesInterface, _))
      .Times(0);
  std::unique_ptr<dbus::PropertySet> dbus_property_set2(
      impersonation_om_interface->CreateProperties(
          kTestServiceName2, object_proxy_.get(), object_path1,
          kTestInterfaceName1));
  PropertySet* property_set2 =
      static_cast<PropertySet*>(dbus_property_set2.get());
  // The properties should all be registered.
  ASSERT_NE(nullptr, property_set2->GetProperty(kStringPropertyName));
  ASSERT_NE(nullptr, property_set2->GetProperty(kIntPropertyName));
  ASSERT_NE(nullptr, property_set2->GetProperty(kBoolPropertyName));
  EXPECT_CALL(*object_manager2_,
              GetProperties(object_path1, kTestInterfaceName1))
      .WillRepeatedly(Return(property_set2));
  SetPropertyValue<int>(property_set2->GetProperty(kIntPropertyName),
                        kTestIntPropertyValue + 1);
  SetPropertyValue<bool>(property_set2->GetProperty(kBoolPropertyName),
                         kTestBoolPropertyValue);

  // ObjectAdded events
  dbus::ExportedObject::MethodCallCallback method1_handler;
  dbus::ExportedObject::MethodCallCallback method2_handler;
  ExpectExportTestMethods(exported_object1.get(), kTestInterfaceName1,
                          &method1_handler, &method2_handler);
  EXPECT_CALL(*exported_object_manager_,
              ClaimInterface(object_path1, kTestInterfaceName1, _))
      .Times(1);
  impersonation_om_interface->ObjectAdded(kTestServiceName1, object_path1,
                                          kTestInterfaceName1);
  EXPECT_CALL(*exported_object_manager_,
              ClaimInterface(object_path1, kTestInterfaceName1, _))
      .Times(0);
  impersonation_om_interface->ObjectAdded(kTestServiceName2, object_path1,
                                          kTestInterfaceName1);

  // Method forwarding
  scoped_refptr<dbus::MockBus> client_bus =
      new dbus::MockBus(dbus::Bus::Options());
  EXPECT_CALL(*client_bus, AssertOnDBusThread()).Times(AnyNumber());
  EXPECT_CALL(*dbus_connection_factory_, GetNewBus())
      .WillOnce(Return(client_bus));

  // Method1's rule is FORWARD_DEFAULT, so test that only Service1 receives
  // method forwarding.
  TestMethodForwarding(
      kTestInterfaceName1, kTestMethodName1, object_path1, client_bus,
      &method1_handler,
      &ImpersonationObjectManagerInterfaceTest::StubHandleTestMethod1);
  // Method2's rule is FORWARD_ALL, so test that all services receive method
  // forwarding.
  TestMethodForwardingMultiService(
      kTestInterfaceName1, kTestMethodName2, object_path1, client_bus,
      &method2_handler,
      &ImpersonationObjectManagerInterfaceTest::StubHandleTestMethod2);

  // ObjectRemoved events
  EXPECT_CALL(*exported_object_manager_,
              ReleaseInterface(object_path1, dbus::kPropertiesInterface))
      .Times(1);
  EXPECT_CALL(*exported_object_manager_,
              ReleaseInterface(object_path1, kTestInterfaceName1))
      .Times(1);
  impersonation_om_interface->ObjectRemoved(kTestServiceName1, object_path1,
                                            kTestInterfaceName1);
  // Service1 removed the object, so now the properties of this object should
  // be updated based on the properties of Service2.
  EXPECT_EQ(nullptr,
            interface->GetRegisteredExportedProperty(kStringPropertyName));
  ExpectExportedPropertyEquals<int>(
      kTestIntPropertyValue + 1,
      interface->GetRegisteredExportedProperty(kIntPropertyName));
  ExpectExportedPropertyEquals<bool>(
      kTestBoolPropertyValue,
      interface->GetRegisteredExportedProperty(kBoolPropertyName));

  // The last service removes the object, the corrseponding exported object
  // should be unregistered.
  ExpectUnexportTestMethods(exported_object1.get(), kTestInterfaceName1);
  EXPECT_CALL(*exported_object1, Unregister()).Times(1);
  impersonation_om_interface->ObjectRemoved(kTestServiceName2, object_path1,
                                            kTestInterfaceName1);
}

TEST_F(ImpersonationObjectManagerInterfaceTest, MultiServiceMerging) {
  dbus::ObjectPath object_path1(kTestObjectPath1);

  std::map<std::string, std::unique_ptr<ExportedObject>> exported_objects;
  auto impersonation_om_interface =
      std::make_unique<ImpersonationObjectManagerInterface>(
          bus_, exported_object_manager_wrapper_.get(),
          std::make_unique<TestInterfaceHandler>(), kTestInterfaceName1,
          client_manager_.get());

  impersonation_om_interface->RegisterToObjectManager(object_manager1_.get(),
                                                      kTestServiceName1);
  impersonation_om_interface->RegisterToObjectManager(object_manager2_.get(),
                                                      kTestServiceName2);

  scoped_refptr<dbus::MockExportedObject> exported_object1 =
      new dbus::MockExportedObject(bus_.get(), object_path1);
  EXPECT_CALL(*bus_, GetExportedObject(object_path1))
      .WillOnce(Return(exported_object1.get()));

  // D-Bus properties methods should be exported.
  ExpectExportPropertiesMethods(exported_object1.get());
  // CreateProperties called for an object.
  std::unique_ptr<dbus::PropertySet> dbus_property_set1(
      impersonation_om_interface->CreateProperties(
          kTestServiceName1, object_proxy_.get(), object_path1,
          kTestInterfaceName1));

  PropertySet* property_set1 =
      static_cast<PropertySet*>(dbus_property_set1.get());
  // The properties should all be registered.
  ASSERT_NE(nullptr, property_set1->GetProperty(kMergeStringPropertyName));
  EXPECT_CALL(*object_manager1_,
              GetProperties(object_path1, kTestInterfaceName1))
      .WillRepeatedly(Return(property_set1));
  SetPropertyValue<std::string>(
      property_set1->GetProperty(kMergeStringPropertyName), "string1");
  // Trigger property changed event and check that the exported properties are
  // updated.
  property_set1->NotifyPropertyChanged(kMergeStringPropertyName);
  ExportedInterface* interface =
      exported_object_manager_wrapper_->GetExportedInterface(
          object_path1, kTestInterfaceName1);
  ExpectExportedPropertyEquals<std::string>(
      "string1",
      interface->GetRegisteredExportedProperty(kMergeStringPropertyName));

  // Now the second service creates the same property.
  std::unique_ptr<dbus::PropertySet> dbus_property_set2(
      impersonation_om_interface->CreateProperties(
          kTestServiceName2, object_proxy_.get(), object_path1,
          kTestInterfaceName1));
  PropertySet* property_set2 =
      static_cast<PropertySet*>(dbus_property_set2.get());
  // The properties should all be registered.
  ASSERT_NE(nullptr, property_set2->GetProperty(kMergeStringPropertyName));
  EXPECT_CALL(*object_manager2_,
              GetProperties(object_path1, kTestInterfaceName1))
      .WillRepeatedly(Return(property_set2));
  SetPropertyValue<std::string>(
      property_set2->GetProperty(kMergeStringPropertyName), "string2");

  // Trigger property changed event and check that the exported properties are
  // updated.
  property_set2->NotifyPropertyChanged(kMergeStringPropertyName);
  ExpectExportedPropertyEquals<std::string>(
      "string1 string2",
      interface->GetRegisteredExportedProperty(kMergeStringPropertyName));

  // ObjectAdded events
  dbus::ExportedObject::MethodCallCallback method1_handler;
  dbus::ExportedObject::MethodCallCallback method2_handler;
  ExpectExportTestMethods(exported_object1.get(), kTestInterfaceName1,
                          &method1_handler, &method2_handler);
  impersonation_om_interface->ObjectAdded(kTestServiceName1, object_path1,
                                          kTestInterfaceName1);
  impersonation_om_interface->ObjectAdded(kTestServiceName2, object_path1,
                                          kTestInterfaceName1);
  // ObjectRemoved events
  impersonation_om_interface->ObjectRemoved(kTestServiceName1, object_path1,
                                            kTestInterfaceName1);
  // Service1 removed the object, so now the property of this object should
  // be updated based on the property of Service2.
  ExpectExportedPropertyEquals<std::string>(
      "string2",
      interface->GetRegisteredExportedProperty(kMergeStringPropertyName));

  // The last service removes the object, the corrseponding exported object
  // should be unregistered and the exported property removed.
  ExpectUnexportTestMethods(exported_object1.get(), kTestInterfaceName1);
  impersonation_om_interface->ObjectRemoved(kTestServiceName2, object_path1,
                                            kTestInterfaceName1);
  EXPECT_EQ(nullptr,
            interface->GetRegisteredExportedProperty(kMergeStringPropertyName));
}

TEST_F(ImpersonationObjectManagerInterfaceTest,
       MultiServiceWithObjectExportRuleAllServices) {
  dbus::ObjectPath object_path1(kTestObjectPath1);

  std::map<std::string, std::unique_ptr<ExportedObject>> exported_objects;
  auto impersonation_om_interface =
      std::make_unique<ImpersonationObjectManagerInterface>(
          bus_, exported_object_manager_wrapper_.get(),
          std::make_unique<TestInterfaceHandler>(
              ObjectExportRule::ALL_SERVICES),
          kTestInterfaceName1, client_manager_.get());

  impersonation_om_interface->RegisterToObjectManager(object_manager1_.get(),
                                                      kTestServiceName1);
  impersonation_om_interface->RegisterToObjectManager(object_manager2_.get(),
                                                      kTestServiceName2);

  scoped_refptr<dbus::MockExportedObject> exported_object1 =
      new dbus::MockExportedObject(bus_.get(), object_path1);
  EXPECT_CALL(*bus_, GetExportedObject(object_path1))
      .WillOnce(Return(exported_object1.get()));

  // D-Bus properties methods should be exported.
  ExpectExportPropertiesMethods(exported_object1.get());
  // CreateProperties called for an object.
  // This shouldn't trigger object export until the second service also exports
  // the same object.
  EXPECT_CALL(*exported_object_manager_,
              ClaimInterface(object_path1, dbus::kPropertiesInterface, _))
      .Times(0);
  std::unique_ptr<dbus::PropertySet> dbus_property_set1(
      impersonation_om_interface->CreateProperties(
          kTestServiceName1, object_proxy_.get(), object_path1,
          kTestInterfaceName1));
  PropertySet* property_set1 =
      static_cast<PropertySet*>(dbus_property_set1.get());
  // The properties should all be registered.
  ASSERT_NE(nullptr, property_set1->GetProperty(kStringPropertyName));
  ASSERT_NE(nullptr, property_set1->GetProperty(kIntPropertyName));
  ASSERT_NE(nullptr, property_set1->GetProperty(kBoolPropertyName));
  EXPECT_CALL(*object_manager1_,
              GetProperties(object_path1, kTestInterfaceName1))
      .WillRepeatedly(Return(property_set1));
  SetPropertyValue<std::string>(property_set1->GetProperty(kStringPropertyName),
                                kTestStringPropertyValue);
  SetPropertyValue<int>(property_set1->GetProperty(kIntPropertyName),
                        kTestIntPropertyValue);
  // Trigger property changed events, they should be ignored.
  property_set1->NotifyPropertyChanged(kStringPropertyName);
  property_set1->NotifyPropertyChanged(kIntPropertyName);
  property_set1->NotifyPropertyChanged(kBoolPropertyName);
  // ObjectAdded event before the other service exports the object. This should
  // be ignored.
  EXPECT_CALL(*exported_object_manager_,
              ClaimInterface(object_path1, kTestInterfaceName1, _))
      .Times(0);
  impersonation_om_interface->ObjectAdded(kTestServiceName2, object_path1,
                                          kTestInterfaceName1);

  // Another service also triggers CreateProperties for the same object.
  // This should trigger an object export.
  EXPECT_CALL(*exported_object_manager_,
              ClaimInterface(object_path1, dbus::kPropertiesInterface, _))
      .Times(1);
  std::unique_ptr<dbus::PropertySet> dbus_property_set2(
      impersonation_om_interface->CreateProperties(
          kTestServiceName2, object_proxy_.get(), object_path1,
          kTestInterfaceName1));
  // The value of the properties should reflect those of Service1.
  ExportedInterface* interface =
      exported_object_manager_wrapper_->GetExportedInterface(
          object_path1, kTestInterfaceName1);
  ExpectExportedPropertyEquals<std::string>(
      kTestStringPropertyValue,
      interface->GetRegisteredExportedProperty(kStringPropertyName));
  ExpectExportedPropertyEquals<int>(
      kTestIntPropertyValue,
      interface->GetRegisteredExportedProperty(kIntPropertyName));
  EXPECT_EQ(nullptr,
            interface->GetRegisteredExportedProperty(kBoolPropertyName));

  PropertySet* property_set2 =
      static_cast<PropertySet*>(dbus_property_set2.get());
  // The properties should all be registered.
  ASSERT_NE(nullptr, property_set2->GetProperty(kStringPropertyName));
  ASSERT_NE(nullptr, property_set2->GetProperty(kIntPropertyName));
  ASSERT_NE(nullptr, property_set2->GetProperty(kBoolPropertyName));
  EXPECT_CALL(*object_manager2_,
              GetProperties(object_path1, kTestInterfaceName1))
      .WillRepeatedly(Return(property_set2));
  SetPropertyValue<int>(property_set2->GetProperty(kIntPropertyName),
                        kTestIntPropertyValue + 1);
  SetPropertyValue<bool>(property_set2->GetProperty(kBoolPropertyName),
                         kTestBoolPropertyValue);

  // ObjectAdded event for Service2.
  dbus::ExportedObject::MethodCallCallback method1_handler;
  dbus::ExportedObject::MethodCallCallback method2_handler;
  ExpectExportTestMethods(exported_object1.get(), kTestInterfaceName1,
                          &method1_handler, &method2_handler);
  EXPECT_CALL(*exported_object_manager_,
              ClaimInterface(object_path1, kTestInterfaceName1, _))
      .Times(1);
  impersonation_om_interface->ObjectAdded(kTestServiceName2, object_path1,
                                          kTestInterfaceName1);

  // ObjectRemoved events
  EXPECT_CALL(*exported_object_manager_,
              ReleaseInterface(object_path1, dbus::kPropertiesInterface))
      .Times(1);
  EXPECT_CALL(*exported_object_manager_,
              ReleaseInterface(object_path1, kTestInterfaceName1))
      .Times(1);
  // Service1 removed the object, the corresponding exported object should be
  // unregistered.
  ExpectUnexportTestMethods(exported_object1.get(), kTestInterfaceName1);
  EXPECT_CALL(*exported_object1, Unregister()).Times(1);
  impersonation_om_interface->ObjectRemoved(kTestServiceName1, object_path1,
                                            kTestInterfaceName1);
  EXPECT_EQ(nullptr, exported_object_manager_wrapper_->GetExportedInterface(
                         object_path1, kTestInterfaceName1));

  // The last service removes the object, there should be no other object
  // unregistration.
  EXPECT_CALL(*exported_object1, Unregister()).Times(0);
  impersonation_om_interface->ObjectRemoved(kTestServiceName2, object_path1,
                                            kTestInterfaceName1);
}

}  // namespace bluetooth
