1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "content/common/mojo/service_registry_impl.h"
6
7#include "mojo/common/common_type_converters.h"
8
9namespace content {
10
11ServiceRegistryImpl::ServiceRegistryImpl()
12    : bound_(false), weak_factory_(this) {
13}
14
15ServiceRegistryImpl::ServiceRegistryImpl(mojo::ScopedMessagePipeHandle handle)
16    : bound_(false), weak_factory_(this) {
17  BindRemoteServiceProvider(handle.Pass());
18}
19
20ServiceRegistryImpl::~ServiceRegistryImpl() {
21  while (!pending_connects_.empty()) {
22    mojo::CloseRaw(pending_connects_.front().second);
23    pending_connects_.pop();
24  }
25}
26
27void ServiceRegistryImpl::BindRemoteServiceProvider(
28    mojo::ScopedMessagePipeHandle handle) {
29  DCHECK(!bound_);
30  bound_ = true;
31  mojo::WeakBindToPipe(this, handle.Pass());
32  while (!pending_connects_.empty()) {
33    client()->ConnectToService(
34        mojo::String::From(pending_connects_.front().first),
35        mojo::ScopedMessagePipeHandle(pending_connects_.front().second));
36    pending_connects_.pop();
37  }
38}
39
40void ServiceRegistryImpl::OnConnectionError() {
41  // TODO(sammc): Support reporting this to our owner.
42}
43
44void ServiceRegistryImpl::AddService(
45    const std::string& service_name,
46    const base::Callback<void(mojo::ScopedMessagePipeHandle)> service_factory) {
47  bool inserted = service_factories_.insert(
48      std::make_pair(service_name, service_factory)).second;
49  DCHECK(inserted);
50}
51
52void ServiceRegistryImpl::RemoveService(const std::string& service_name) {
53  service_factories_.erase(service_name);
54}
55
56void ServiceRegistryImpl::ConnectToRemoteService(
57    const base::StringPiece& service_name,
58    mojo::ScopedMessagePipeHandle handle) {
59  if (!bound_) {
60    pending_connects_.push(
61        std::make_pair(service_name.as_string(), handle.release()));
62    return;
63  }
64  client()->ConnectToService(mojo::String::From(service_name), handle.Pass());
65}
66
67base::WeakPtr<ServiceRegistry> ServiceRegistryImpl::GetWeakPtr() {
68  return weak_factory_.GetWeakPtr();
69}
70
71void ServiceRegistryImpl::ConnectToService(
72    const mojo::String& name,
73    mojo::ScopedMessagePipeHandle client_handle) {
74  std::map<std::string,
75           base::Callback<void(mojo::ScopedMessagePipeHandle)> >::iterator it =
76      service_factories_.find(name);
77  if (it == service_factories_.end())
78    return;
79
80  it->second.Run(client_handle.Pass());
81}
82
83}  // namespace content
84