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 "mojo/public/cpp/application/application_impl.h"
6
7#include "mojo/public/cpp/application/application_delegate.h"
8#include "mojo/public/cpp/application/lib/service_registry.h"
9#include "mojo/public/cpp/bindings/interface_ptr.h"
10#include "mojo/public/cpp/environment/logging.h"
11
12namespace mojo {
13
14class ApplicationImpl::ShellPtrWatcher : public ErrorHandler {
15 public:
16  ShellPtrWatcher(ApplicationImpl* impl)
17    : impl_(impl) {}
18
19  virtual ~ShellPtrWatcher() {}
20
21  virtual void OnConnectionError() MOJO_OVERRIDE {
22    impl_->OnShellError();
23  }
24
25 private:
26  ApplicationImpl* impl_;
27  MOJO_DISALLOW_COPY_AND_ASSIGN(ShellPtrWatcher);
28};
29
30ApplicationImpl::ApplicationImpl(ApplicationDelegate* delegate,
31                                 ScopedMessagePipeHandle shell_handle)
32    : initialized_(false), delegate_(delegate), shell_watch_(NULL) {
33  BindShell(shell_handle.Pass());
34}
35
36ApplicationImpl::ApplicationImpl(ApplicationDelegate* delegate,
37                                 MojoHandle shell_handle)
38    : initialized_(false), delegate_(delegate), shell_watch_(NULL) {
39  BindShell(MakeScopedHandle(MessagePipeHandle(shell_handle)));
40}
41
42void ApplicationImpl::ClearConnections() {
43  for (ServiceRegistryList::iterator i(incoming_service_registries_.begin());
44      i != incoming_service_registries_.end(); ++i)
45    delete *i;
46  for (ServiceRegistryList::iterator i(outgoing_service_registries_.begin());
47      i != outgoing_service_registries_.end(); ++i)
48    delete *i;
49  incoming_service_registries_.clear();
50  outgoing_service_registries_.clear();
51}
52
53ApplicationImpl::~ApplicationImpl() {
54  ClearConnections();
55  delete shell_watch_;
56}
57
58void ApplicationImpl::Initialize(Array<String> args) {
59  MOJO_CHECK(!initialized_);
60  initialized_ = true;
61  args_ = args.Pass();
62  delegate_->Initialize(this);
63}
64
65ApplicationConnection* ApplicationImpl::ConnectToApplication(
66    const String& application_url) {
67  MOJO_CHECK(initialized_);
68  ServiceProviderPtr out_service_provider;
69  shell_->ConnectToApplication(application_url, Get(&out_service_provider));
70  internal::ServiceRegistry* registry = new internal::ServiceRegistry(
71      this,
72      application_url,
73      out_service_provider.Pass());
74  if (!delegate_->ConfigureOutgoingConnection(registry)) {
75    delete registry;
76    return NULL;
77  }
78  outgoing_service_registries_.push_back(registry);
79  return registry;
80}
81
82void ApplicationImpl::BindShell(ScopedMessagePipeHandle shell_handle) {
83  shell_watch_ = new ShellPtrWatcher(this);
84  shell_.Bind(shell_handle.Pass());
85  shell_.set_client(this);
86  shell_.set_error_handler(shell_watch_);
87}
88
89void ApplicationImpl::AcceptConnection(const String& requestor_url,
90                                       ServiceProviderPtr service_provider) {
91  internal::ServiceRegistry* registry = new internal::ServiceRegistry(
92      this, requestor_url, service_provider.Pass());
93  if (!delegate_->ConfigureIncomingConnection(registry)) {
94    delete registry;
95    return;
96  }
97  incoming_service_registries_.push_back(registry);
98}
99
100}  // namespace mojo
101