Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1086)

Side by Side Diff: mojo/shell/external_application_listener.cc

Issue 522443003: Accept inbound connections on unix domain socket (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@bug407782
Patch Set: Fix clang style complaints Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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/shell/external_application_listener.h"
6
7 #include "base/callback.h"
8 #include "base/files/file_path.h"
9 #include "base/files/file_util.h"
10 #include "base/logging.h"
11 #include "base/memory/ref_counted.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/sequenced_task_runner.h"
15 #include "base/tracked_objects.h"
16 #include "mojo/embedder/channel_init.h"
17 #include "mojo/public/cpp/bindings/error_handler.h"
18 #include "mojo/shell/external_application_registrar.mojom.h"
19 #include "net/base/net_errors.h"
20 #include "net/socket/socket_descriptor.h"
21
22 namespace mojo {
23 namespace shell {
24
25 const char ExternalApplicationListener::kDefaultListenSocketPath[] =
26 "/var/run/mojo/system_socket";
27
28 class ExternalApplicationListener::RegistrarImpl
29 : public InterfaceImpl<ExternalApplicationRegistrar> {
30 public:
31 explicit RegistrarImpl(const RegisterCallback& callback);
32 virtual ~RegistrarImpl() MOJO_OVERRIDE;
33
34 virtual void OnConnectionError() MOJO_OVERRIDE;
35
36 embedder::ChannelInit channel_init;
37
38 private:
39 virtual void Register(const String& app_url,
40 InterfaceRequest<Shell> shell,
41 const mojo::Closure& callback) MOJO_OVERRIDE;
42
43 const RegisterCallback register_callback_;
44 };
45
46 ExternalApplicationListener::ExternalApplicationListener(
47 const scoped_refptr<base::SequencedTaskRunner>& shell_runner,
48 const scoped_refptr<base::SequencedTaskRunner>& io_runner)
49 : shell_runner_(shell_runner),
50 io_runner_(io_runner),
51 signal_on_listening_(true, false),
52 weak_ptr_factory_(this) {
53 DCHECK(shell_runner_.get() && shell_runner_->RunsTasksOnCurrentThread());
54 DCHECK(io_runner_.get());
55 listener_thread_checker_.DetachFromThread(); // Will attach in StartListener.
56 }
57
58 ExternalApplicationListener::~ExternalApplicationListener() {
59 DCHECK(register_thread_checker_.CalledOnValidThread());
60 weak_ptr_factory_.InvalidateWeakPtrs();
61
62 // listener_ needs to be destroyed on io_runner_, and it has to die before
63 // this object does, as it holds a pointer back to this instance.
64 base::WaitableEvent stop_listening_event(true, false);
65 io_runner_->PostTask(FROM_HERE,
66 base::Bind(&ExternalApplicationListener::StopListening,
67 base::Unretained(this),
68 &stop_listening_event));
69 stop_listening_event.Wait();
70 }
71
72 void ExternalApplicationListener::ListenInBackground(
73 const base::FilePath& listen_socket_path,
74 const RegisterCallback& register_callback) {
75 DCHECK(register_thread_checker_.CalledOnValidThread());
76 ListenInBackgroundWithErrorCallback(
77 listen_socket_path, register_callback, ErrorCallback());
78 }
79
80 void ExternalApplicationListener::ListenInBackgroundWithErrorCallback(
81 const base::FilePath& listen_socket_path,
82 const RegisterCallback& register_callback,
83 const ErrorCallback& error_callback) {
84 DCHECK(register_thread_checker_.CalledOnValidThread());
85 register_callback_ = register_callback;
86 error_callback_ = error_callback;
87
88 io_runner_->PostTask(FROM_HERE,
89 base::Bind(&ExternalApplicationListener::StartListening,
90 base::Unretained(this),
91 listen_socket_path));
92 }
93
94 void ExternalApplicationListener::WaitForListening() {
95 DCHECK(register_thread_checker_.CalledOnValidThread());
96 signal_on_listening_.Wait();
97 }
98
99 void ExternalApplicationListener::StartListening(
100 const base::FilePath& listen_socket_path) {
101 CHECK_EQ(base::MessageLoop::current()->type(), base::MessageLoop::TYPE_IO);
102 DCHECK(listener_thread_checker_.CalledOnValidThread());
103 listener_.reset(new IncomingConnectionListener(listen_socket_path, this));
104 listener_->StartListening();
105 }
106
107 void ExternalApplicationListener::StopListening(base::WaitableEvent* event) {
108 DCHECK(listener_thread_checker_.CalledOnValidThread());
109 listener_.reset();
110 event->Signal();
111 }
112
113 void ExternalApplicationListener::OnListening(int rv) {
114 DCHECK(listener_thread_checker_.CalledOnValidThread());
115 signal_on_listening_.Signal();
116 shell_runner_->PostTask(
117 FROM_HERE,
118 base::Bind(
119 &ExternalApplicationListener::RunErrorCallbackIfListeningFailed,
120 weak_ptr_factory_.GetWeakPtr(),
121 rv));
122 }
123
124 void ExternalApplicationListener::OnConnection(net::SocketDescriptor incoming) {
125 DCHECK(listener_thread_checker_.CalledOnValidThread());
126 shell_runner_->PostTask(
127 FROM_HERE,
128 base::Bind(&ExternalApplicationListener::CreatePipeAndBindToRegistrarImpl,
129 weak_ptr_factory_.GetWeakPtr(),
130 incoming));
131 }
132
133 void ExternalApplicationListener::RunErrorCallbackIfListeningFailed(int rv) {
134 DCHECK(register_thread_checker_.CalledOnValidThread());
135 if (rv != net::OK && !error_callback_.is_null()) {
136 error_callback_.Run(rv);
137 }
138 }
139
140 void ExternalApplicationListener::CreatePipeAndBindToRegistrarImpl(
141 net::SocketDescriptor incoming_socket) {
142 DCHECK(register_thread_checker_.CalledOnValidThread());
143
144 DVLOG(1) << "Accepted incoming connection";
145 scoped_ptr<RegistrarImpl> registrar(new RegistrarImpl(register_callback_));
146 // Passes ownership of incoming_socket to registrar->channel_init.
147 mojo::ScopedMessagePipeHandle message_pipe =
148 registrar->channel_init.Init(incoming_socket, io_runner_);
149 CHECK(message_pipe.is_valid());
150
151 BindToPipe(registrar.release(), message_pipe.Pass());
152 }
153
154 ExternalApplicationListener::RegistrarImpl::RegistrarImpl(
155 const RegisterCallback& callback)
156 : register_callback_(callback) {
157 }
158
159 ExternalApplicationListener::RegistrarImpl::~RegistrarImpl() {
160 }
161
162 void ExternalApplicationListener::RegistrarImpl::OnConnectionError() {
163 channel_init.WillDestroySoon();
164 }
165
166 void ExternalApplicationListener::RegistrarImpl::Register(
167 const String& app_url,
168 InterfaceRequest<Shell> shell,
169 const mojo::Closure& callback) {
170 register_callback_.Run(app_url.To<GURL>(), shell.PassMessagePipe());
171 callback.Run();
172 }
173
174 } // namespace shell
175 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698