OLD | NEW |
| (Empty) |
1 // Copyright 2016 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 <stddef.h> | |
6 #include <stdint.h> | |
7 | |
8 #include <utility> | |
9 | |
10 #include "base/bind.h" | |
11 #include "base/macros.h" | |
12 #include "base/message_loop/message_loop.h" | |
13 #include "base/run_loop.h" | |
14 #include "base/threading/simple_thread.h" | |
15 #include "mojo/public/c/system/main.h" | |
16 #include "mojo/public/cpp/bindings/binding_set.h" | |
17 #include "mojo/shell/public/cpp/application_runner.h" | |
18 #include "mojo/shell/public/cpp/connector.h" | |
19 #include "mojo/shell/public/cpp/interface_factory.h" | |
20 #include "mojo/shell/public/cpp/shell_client.h" | |
21 #include "mojo/shell/public/interfaces/shell_client_factory.mojom.h" | |
22 #include "mojo/shell/tests/connect/connect_test.mojom.h" | |
23 | |
24 // Tests that multiple applications can be packaged in a single Mojo application | |
25 // implementing ShellClientFactory; that these applications can be specified by | |
26 // the package's manifest and are thus registered with the PackageManager. | |
27 | |
28 namespace mojo { | |
29 namespace shell { | |
30 namespace { | |
31 void QuitLoop(base::RunLoop* loop) { | |
32 loop->Quit(); | |
33 } | |
34 } | |
35 | |
36 using GetTitleCallback = test::mojom::ConnectTestService::GetTitleCallback; | |
37 | |
38 class ProvidedShellClient | |
39 : public ShellClient, | |
40 public InterfaceFactory<test::mojom::ConnectTestService>, | |
41 public InterfaceFactory<test::mojom::BlockedInterface>, | |
42 public InterfaceFactory<test::mojom::UserIdTest>, | |
43 public test::mojom::ConnectTestService, | |
44 public test::mojom::BlockedInterface, | |
45 public test::mojom::UserIdTest, | |
46 public base::SimpleThread { | |
47 public: | |
48 ProvidedShellClient(const std::string& title, | |
49 mojom::ShellClientRequest request) | |
50 : base::SimpleThread(title), | |
51 title_(title), | |
52 request_(std::move(request)) { | |
53 Start(); | |
54 } | |
55 ~ProvidedShellClient() override { | |
56 Join(); | |
57 } | |
58 | |
59 private: | |
60 // mojo::ShellClient: | |
61 void Initialize(Connector* connector, const Identity& identity, | |
62 uint32_t id) override { | |
63 connector_ = connector; | |
64 identity_ = identity; | |
65 id_ = id; | |
66 bindings_.set_connection_error_handler( | |
67 base::Bind(&ProvidedShellClient::OnConnectionError, | |
68 base::Unretained(this))); | |
69 } | |
70 bool AcceptConnection(Connection* connection) override { | |
71 connection->AddInterface<test::mojom::ConnectTestService>(this); | |
72 connection->AddInterface<test::mojom::BlockedInterface>(this); | |
73 connection->AddInterface<test::mojom::UserIdTest>(this); | |
74 | |
75 uint32_t remote_id = connection->GetRemoteInstanceID(); | |
76 test::mojom::ConnectionStatePtr state(test::mojom::ConnectionState::New()); | |
77 state->connection_local_name = connection->GetConnectionName(); | |
78 state->connection_remote_name = connection->GetRemoteIdentity().name(); | |
79 state->connection_remote_userid = connection->GetRemoteIdentity().user_id(); | |
80 state->connection_remote_id = remote_id; | |
81 state->initialize_local_name = identity_.name(); | |
82 state->initialize_id = id_; | |
83 state->initialize_userid = identity_.user_id(); | |
84 connection->GetInterface(&caller_); | |
85 caller_->ConnectionAccepted(std::move(state)); | |
86 | |
87 return true; | |
88 } | |
89 | |
90 // InterfaceFactory<test::mojom::ConnectTestService>: | |
91 void Create(Connection* connection, | |
92 test::mojom::ConnectTestServiceRequest request) override { | |
93 bindings_.AddBinding(this, std::move(request)); | |
94 } | |
95 | |
96 // InterfaceFactory<test::mojom::BlockedInterface>: | |
97 void Create(Connection* connection, | |
98 test::mojom::BlockedInterfaceRequest request) override { | |
99 blocked_bindings_.AddBinding(this, std::move(request)); | |
100 } | |
101 | |
102 // InterfaceFactory<test::mojom::UserIdTest>: | |
103 void Create(Connection* connection, | |
104 test::mojom::UserIdTestRequest request) override { | |
105 user_id_test_bindings_.AddBinding(this, std::move(request)); | |
106 } | |
107 | |
108 // test::mojom::ConnectTestService: | |
109 void GetTitle(const GetTitleCallback& callback) override { | |
110 callback.Run(title_); | |
111 } | |
112 void GetInstance(const GetInstanceCallback& callback) override { | |
113 callback.Run(identity_.instance()); | |
114 } | |
115 | |
116 // test::mojom::BlockedInterface: | |
117 void GetTitleBlocked(const GetTitleBlockedCallback& callback) override { | |
118 callback.Run("Called Blocked Interface!"); | |
119 } | |
120 | |
121 // test::mojom::UserIdTest: | |
122 void ConnectToClassAppAsDifferentUser( | |
123 mojom::IdentityPtr target, | |
124 const ConnectToClassAppAsDifferentUserCallback& callback) override { | |
125 Connector::ConnectParams params(target.To<Identity>()); | |
126 scoped_ptr<Connection> connection = connector_->Connect(¶ms); | |
127 { | |
128 base::RunLoop loop; | |
129 connection->AddConnectionCompletedClosure(base::Bind(&QuitLoop, &loop)); | |
130 base::MessageLoop::ScopedNestableTaskAllower allow( | |
131 base::MessageLoop::current()); | |
132 loop.Run(); | |
133 } | |
134 callback.Run(static_cast<int32_t>(connection->GetResult()), | |
135 mojom::Identity::From(connection->GetRemoteIdentity())); | |
136 } | |
137 | |
138 // base::SimpleThread: | |
139 void Run() override { | |
140 ApplicationRunner(this).Run(request_.PassMessagePipe().release().value(), | |
141 false); | |
142 delete this; | |
143 } | |
144 | |
145 void OnConnectionError() { | |
146 if (bindings_.empty()) | |
147 base::MessageLoop::current()->QuitWhenIdle(); | |
148 } | |
149 | |
150 Connector* connector_ = nullptr; | |
151 Identity identity_; | |
152 uint32_t id_ = shell::mojom::kInvalidInstanceID; | |
153 const std::string title_; | |
154 mojom::ShellClientRequest request_; | |
155 test::mojom::ExposedInterfacePtr caller_; | |
156 BindingSet<test::mojom::ConnectTestService> bindings_; | |
157 BindingSet<test::mojom::BlockedInterface> blocked_bindings_; | |
158 BindingSet<test::mojom::UserIdTest> user_id_test_bindings_; | |
159 | |
160 DISALLOW_COPY_AND_ASSIGN(ProvidedShellClient); | |
161 }; | |
162 | |
163 class ConnectTestShellClient | |
164 : public ShellClient, | |
165 public InterfaceFactory<mojom::ShellClientFactory>, | |
166 public InterfaceFactory<test::mojom::ConnectTestService>, | |
167 public mojom::ShellClientFactory, | |
168 public test::mojom::ConnectTestService { | |
169 public: | |
170 ConnectTestShellClient() {} | |
171 ~ConnectTestShellClient() override {} | |
172 | |
173 private: | |
174 // mojo::ShellClient: | |
175 void Initialize(Connector* connector, const Identity& identity, | |
176 uint32_t id) override { | |
177 identity_ = identity; | |
178 bindings_.set_connection_error_handler( | |
179 base::Bind(&ConnectTestShellClient::OnConnectionError, | |
180 base::Unretained(this))); | |
181 } | |
182 bool AcceptConnection(Connection* connection) override { | |
183 connection->AddInterface<ShellClientFactory>(this); | |
184 connection->AddInterface<test::mojom::ConnectTestService>(this); | |
185 return true; | |
186 } | |
187 | |
188 // InterfaceFactory<mojom::ShellClientFactory>: | |
189 void Create(Connection* connection, | |
190 mojom::ShellClientFactoryRequest request) override { | |
191 shell_client_factory_bindings_.AddBinding(this, std::move(request)); | |
192 } | |
193 | |
194 // InterfaceFactory<test::mojom::ConnectTestService>: | |
195 void Create(Connection* connection, | |
196 test::mojom::ConnectTestServiceRequest request) override { | |
197 bindings_.AddBinding(this, std::move(request)); | |
198 } | |
199 | |
200 // mojom::ShellClientFactory: | |
201 void CreateShellClient(mojom::ShellClientRequest request, | |
202 const String& name) override { | |
203 if (name == "mojo:connect_test_a") | |
204 new ProvidedShellClient("A", std::move(request)); | |
205 else if (name == "mojo:connect_test_b") | |
206 new ProvidedShellClient("B", std::move(request)); | |
207 } | |
208 | |
209 // test::mojom::ConnectTestService: | |
210 void GetTitle(const GetTitleCallback& callback) override { | |
211 callback.Run("ROOT"); | |
212 } | |
213 void GetInstance(const GetInstanceCallback& callback) override { | |
214 callback.Run(identity_.instance()); | |
215 } | |
216 | |
217 void OnConnectionError() { | |
218 if (bindings_.empty()) | |
219 base::MessageLoop::current()->QuitWhenIdle(); | |
220 } | |
221 | |
222 Identity identity_; | |
223 std::vector<scoped_ptr<ShellClient>> delegates_; | |
224 BindingSet<mojom::ShellClientFactory> shell_client_factory_bindings_; | |
225 BindingSet<test::mojom::ConnectTestService> bindings_; | |
226 | |
227 DISALLOW_COPY_AND_ASSIGN(ConnectTestShellClient); | |
228 }; | |
229 | |
230 } // namespace shell | |
231 } // namespace mojo | |
232 | |
233 | |
234 MojoResult MojoMain(MojoHandle shell_handle) { | |
235 MojoResult rv = mojo::ApplicationRunner( | |
236 new mojo::shell::ConnectTestShellClient).Run(shell_handle); | |
237 return rv; | |
238 } | |
OLD | NEW |