OLD | NEW |
| (Empty) |
1 // Copyright 2015 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 <stdint.h> | |
6 | |
7 #include <utility> | |
8 | |
9 #include "base/at_exit.h" | |
10 #include "base/bind.h" | |
11 #include "base/macros.h" | |
12 #include "base/memory/scoped_vector.h" | |
13 #include "base/message_loop/message_loop.h" | |
14 #include "base/path_service.h" | |
15 #include "base/run_loop.h" | |
16 #include "mojo/public/cpp/bindings/strong_binding.h" | |
17 #include "mojo/shell/application_loader.h" | |
18 #include "mojo/shell/application_manager.h" | |
19 #include "mojo/shell/connect_util.h" | |
20 #include "mojo/shell/fetcher.h" | |
21 #include "mojo/shell/package_manager/package_manager_impl.h" | |
22 #include "mojo/shell/public/cpp/interface_factory.h" | |
23 #include "mojo/shell/public/cpp/shell_client.h" | |
24 #include "mojo/shell/public/cpp/shell_connection.h" | |
25 #include "mojo/shell/public/interfaces/content_handler.mojom.h" | |
26 #include "mojo/shell/public/interfaces/interface_provider.mojom.h" | |
27 #include "mojo/shell/test_package_manager.h" | |
28 #include "testing/gtest/include/gtest/gtest.h" | |
29 | |
30 namespace mojo { | |
31 namespace shell { | |
32 namespace test { | |
33 namespace { | |
34 | |
35 const char kTestMimeType[] = "test/mime-type"; | |
36 | |
37 class TestFetcher : public Fetcher { | |
38 public: | |
39 TestFetcher(const FetchCallback& fetch_callback, | |
40 const GURL& url, | |
41 const std::string& mime_type) | |
42 : Fetcher(fetch_callback), url_(url), mime_type_(mime_type) { | |
43 loader_callback_.Run(make_scoped_ptr(this)); | |
44 } | |
45 ~TestFetcher() override {} | |
46 | |
47 // Fetcher: | |
48 const GURL& GetURL() const override { return url_; } | |
49 GURL GetRedirectURL() const override { return GURL("yyy"); } | |
50 GURL GetRedirectReferer() const override { return GURL(); } | |
51 URLResponsePtr AsURLResponse(base::TaskRunner* task_runner, | |
52 uint32_t skip) override { | |
53 return URLResponse::New(); | |
54 } | |
55 void AsPath( | |
56 base::TaskRunner* task_runner, | |
57 base::Callback<void(const base::FilePath&, bool)> callback) override {} | |
58 std::string MimeType() override { return mime_type_; } | |
59 bool HasMojoMagic() override { return false; } | |
60 bool PeekFirstLine(std::string* line) override { return false; } | |
61 | |
62 private: | |
63 const GURL url_; | |
64 const std::string mime_type_; | |
65 | |
66 DISALLOW_COPY_AND_ASSIGN(TestFetcher); | |
67 }; | |
68 | |
69 void QuitClosure(bool* value) { | |
70 *value = true; | |
71 base::MessageLoop::current()->QuitWhenIdle(); | |
72 } | |
73 | |
74 class TestContentHandler : public mojom::ContentHandler, | |
75 public ShellClient { | |
76 public: | |
77 TestContentHandler(Connection* connection, | |
78 InterfaceRequest<mojom::ContentHandler> request) | |
79 : binding_(this, std::move(request)) {} | |
80 | |
81 // ContentHandler: | |
82 void StartApplication( | |
83 InterfaceRequest<mojom::ShellClient> request, | |
84 URLResponsePtr response, | |
85 const Callback<void()>& destruct_callback) override { | |
86 shell_connections_.push_back(new ShellConnection(this, std::move(request))); | |
87 destruct_callback.Run(); | |
88 } | |
89 | |
90 private: | |
91 StrongBinding<mojom::ContentHandler> binding_; | |
92 ScopedVector<ShellConnection> shell_connections_; | |
93 | |
94 DISALLOW_COPY_AND_ASSIGN(TestContentHandler); | |
95 }; | |
96 | |
97 class TestApplicationLoader : public ApplicationLoader, | |
98 public ShellClient, | |
99 public InterfaceFactory<mojom::ContentHandler> { | |
100 public: | |
101 TestApplicationLoader() : num_loads_(0) {} | |
102 ~TestApplicationLoader() override {} | |
103 | |
104 int num_loads() const { return num_loads_; } | |
105 const GURL& last_requestor_url() const { return last_requestor_url_; } | |
106 | |
107 private: | |
108 // ApplicationLoader implementation. | |
109 void Load(const GURL& url, | |
110 InterfaceRequest<mojom::ShellClient> request) override { | |
111 ++num_loads_; | |
112 shell_connection_.reset(new ShellConnection(this, std::move(request))); | |
113 } | |
114 | |
115 // mojo::ShellClient implementation. | |
116 bool AcceptConnection(Connection* connection) override { | |
117 connection->AddInterface<mojom::ContentHandler>(this); | |
118 last_requestor_url_ = GURL(connection->GetRemoteApplicationURL()); | |
119 return true; | |
120 } | |
121 // InterfaceFactory<mojom::ContentHandler> implementation. | |
122 void Create(Connection* connection, | |
123 InterfaceRequest<mojom::ContentHandler> request) override { | |
124 new TestContentHandler(connection, std::move(request)); | |
125 } | |
126 | |
127 scoped_ptr<ShellConnection> shell_connection_; | |
128 int num_loads_; | |
129 GURL last_requestor_url_; | |
130 | |
131 DISALLOW_COPY_AND_ASSIGN(TestApplicationLoader); | |
132 }; | |
133 | |
134 class TestPackageManagerImpl : public PackageManagerImpl { | |
135 public: | |
136 explicit TestPackageManagerImpl(const base::FilePath& package_path) | |
137 : PackageManagerImpl(package_path, nullptr, nullptr), | |
138 mime_type_(kTestMimeType) {} | |
139 ~TestPackageManagerImpl() override {} | |
140 | |
141 void set_mime_type(const std::string& mime_type) { | |
142 mime_type_ = mime_type; | |
143 } | |
144 | |
145 // PackageManagerImpl: | |
146 void FetchRequest( | |
147 URLRequestPtr request, | |
148 const Fetcher::FetchCallback& loader_callback) override { | |
149 new TestFetcher(loader_callback, GURL(request->url.get()), mime_type_); | |
150 } | |
151 | |
152 private: | |
153 std::string mime_type_; | |
154 | |
155 DISALLOW_COPY_AND_ASSIGN(TestPackageManagerImpl); | |
156 }; | |
157 | |
158 } // namespace | |
159 | |
160 class ContentHandlerTest : public testing::Test { | |
161 public: | |
162 ContentHandlerTest() | |
163 : content_handler_url_("http://test.content.handler"), | |
164 requestor_url_("http://requestor.url") {} | |
165 ~ContentHandlerTest() override {} | |
166 | |
167 void SetUp() override { | |
168 base::FilePath shell_dir; | |
169 PathService::Get(base::DIR_MODULE, &shell_dir); | |
170 test_package_manager_ = new TestPackageManagerImpl(shell_dir); | |
171 test_package_manager_->RegisterContentHandler(kTestMimeType, | |
172 content_handler_url_); | |
173 application_manager_.reset(new ApplicationManager( | |
174 make_scoped_ptr(test_package_manager_), true)); | |
175 } | |
176 | |
177 void TearDown() override { | |
178 test_package_manager_ = nullptr; | |
179 application_manager_.reset(); | |
180 } | |
181 | |
182 protected: | |
183 const GURL content_handler_url_; | |
184 const GURL requestor_url_; | |
185 | |
186 base::MessageLoop loop_; | |
187 scoped_ptr<ApplicationManager> application_manager_; | |
188 // Owned by ApplicationManager. | |
189 TestPackageManagerImpl* test_package_manager_; | |
190 | |
191 DISALLOW_COPY_AND_ASSIGN(ContentHandlerTest); | |
192 }; | |
193 | |
194 TEST_F(ContentHandlerTest, ContentHandlerConnectionGetsRequestorURL) { | |
195 TestApplicationLoader* loader = new TestApplicationLoader; | |
196 application_manager_->SetLoaderForURL( | |
197 scoped_ptr<ApplicationLoader>(loader), | |
198 content_handler_url_); | |
199 | |
200 bool called = false; | |
201 scoped_ptr<ConnectToApplicationParams> params(new ConnectToApplicationParams); | |
202 params->set_source(Identity(requestor_url_)); | |
203 params->SetTargetURL(GURL("test:test")); | |
204 params->set_on_application_end( | |
205 base::Bind(&QuitClosure, base::Unretained(&called))); | |
206 application_manager_->ConnectToApplication(std::move(params)); | |
207 loop_.Run(); | |
208 EXPECT_TRUE(called); | |
209 | |
210 ASSERT_EQ(1, loader->num_loads()); | |
211 EXPECT_EQ(requestor_url_, loader->last_requestor_url()); | |
212 } | |
213 | |
214 TEST_F(ContentHandlerTest, | |
215 MultipleConnectionsToContentHandlerGetSameContentHandlerId) { | |
216 TestApplicationLoader* content_handler_loader = new TestApplicationLoader; | |
217 application_manager_->SetLoaderForURL( | |
218 scoped_ptr<ApplicationLoader>(content_handler_loader), | |
219 content_handler_url_); | |
220 | |
221 uint32_t content_handler_id; | |
222 { | |
223 base::RunLoop run_loop; | |
224 scoped_ptr<ConnectToApplicationParams> params( | |
225 new ConnectToApplicationParams); | |
226 params->set_source(Identity(requestor_url_)); | |
227 params->SetTargetURL(GURL("test:test")); | |
228 params->set_connect_callback( | |
229 [&content_handler_id, &run_loop](uint32_t, uint32_t t) { | |
230 content_handler_id = t; | |
231 run_loop.Quit(); | |
232 }); | |
233 application_manager_->ConnectToApplication(std::move(params)); | |
234 run_loop.Run(); | |
235 EXPECT_NE(mojom::Shell::kInvalidApplicationID, content_handler_id); | |
236 } | |
237 | |
238 uint32_t content_handler_id2; | |
239 { | |
240 base::RunLoop run_loop; | |
241 scoped_ptr<ConnectToApplicationParams> params( | |
242 new ConnectToApplicationParams); | |
243 params->set_source(Identity(requestor_url_)); | |
244 params->SetTargetURL(GURL("test:test")); | |
245 params->set_connect_callback( | |
246 [&content_handler_id2, &run_loop](uint32_t, uint32_t t) { | |
247 content_handler_id2 = t; | |
248 run_loop.Quit(); | |
249 }); | |
250 application_manager_->ConnectToApplication(std::move(params)); | |
251 run_loop.Run(); | |
252 EXPECT_NE(mojom::Shell::kInvalidApplicationID, content_handler_id2); | |
253 } | |
254 EXPECT_EQ(content_handler_id, content_handler_id2); | |
255 } | |
256 | |
257 TEST_F(ContentHandlerTest, DifferedContentHandlersGetDifferentIDs) { | |
258 TestApplicationLoader* content_handler_loader = new TestApplicationLoader; | |
259 application_manager_->SetLoaderForURL( | |
260 scoped_ptr<ApplicationLoader>(content_handler_loader), | |
261 content_handler_url_); | |
262 | |
263 uint32_t content_handler_id; | |
264 { | |
265 base::RunLoop run_loop; | |
266 scoped_ptr<ConnectToApplicationParams> params( | |
267 new ConnectToApplicationParams); | |
268 params->set_source(Identity(requestor_url_)); | |
269 params->SetTargetURL(GURL("test:test")); | |
270 params->set_connect_callback( | |
271 [&content_handler_id, &run_loop](uint32_t, uint32_t t) { | |
272 content_handler_id = t; | |
273 run_loop.Quit(); | |
274 }); | |
275 application_manager_->ConnectToApplication(std::move(params)); | |
276 run_loop.Run(); | |
277 EXPECT_NE(mojom::Shell::kInvalidApplicationID, content_handler_id); | |
278 } | |
279 | |
280 const std::string mime_type2 = "test/mime-type2"; | |
281 const GURL content_handler_url2("http://test.content.handler2"); | |
282 test_package_manager_->set_mime_type(mime_type2); | |
283 test_package_manager_->RegisterContentHandler(mime_type2, | |
284 content_handler_url2); | |
285 | |
286 TestApplicationLoader* content_handler_loader2 = new TestApplicationLoader; | |
287 application_manager_->SetLoaderForURL( | |
288 scoped_ptr<ApplicationLoader>(content_handler_loader2), | |
289 content_handler_url2); | |
290 | |
291 uint32_t content_handler_id2; | |
292 { | |
293 base::RunLoop run_loop; | |
294 scoped_ptr<ConnectToApplicationParams> params( | |
295 new ConnectToApplicationParams); | |
296 params->set_source(Identity(requestor_url_)); | |
297 params->SetTargetURL(GURL("test2:test2")); | |
298 params->set_connect_callback( | |
299 [&content_handler_id2, &run_loop](uint32_t, uint32_t t) { | |
300 content_handler_id2 = t; | |
301 run_loop.Quit(); | |
302 }); | |
303 application_manager_->ConnectToApplication(std::move(params)); | |
304 run_loop.Run(); | |
305 EXPECT_NE(mojom::Shell::kInvalidApplicationID, content_handler_id2); | |
306 } | |
307 EXPECT_NE(content_handler_id, content_handler_id2); | |
308 } | |
309 | |
310 TEST_F(ContentHandlerTest, | |
311 ConnectWithNoContentHandlerGetsInvalidContentHandlerId) { | |
312 application_manager_->SetLoaderForURL( | |
313 scoped_ptr<ApplicationLoader>(new TestApplicationLoader), | |
314 GURL("test:test")); | |
315 | |
316 uint32_t content_handler_id = 1u; | |
317 scoped_ptr<ConnectToApplicationParams> params( | |
318 new ConnectToApplicationParams); | |
319 params->SetTargetURL(GURL("test:test")); | |
320 params->set_connect_callback( | |
321 [&content_handler_id](uint32_t, uint32_t t) { content_handler_id = t; }); | |
322 application_manager_->ConnectToApplication(std::move(params)); | |
323 EXPECT_EQ(0u, content_handler_id); | |
324 } | |
325 | |
326 } // namespace test | |
327 } // namespace package_manager | |
328 } // namespace mojo | |
OLD | NEW |