[Android] Enable input event stream validation
[chromium-blink-merge.git] / mojo / application_manager / application_manager_unittest.cc
blob7dd35e87ff29aea4aa7efb8ccef63de2d22937a7
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.
5 #include "base/at_exit.h"
6 #include "base/bind.h"
7 #include "base/message_loop/message_loop.h"
8 #include "mojo/application_manager/application_loader.h"
9 #include "mojo/application_manager/application_manager.h"
10 #include "mojo/application_manager/background_shell_application_loader.h"
11 #include "mojo/application_manager/test.mojom.h"
12 #include "mojo/public/cpp/application/application_connection.h"
13 #include "mojo/public/cpp/application/application_delegate.h"
14 #include "mojo/public/cpp/application/application_impl.h"
15 #include "mojo/public/cpp/application/interface_factory.h"
16 #include "mojo/public/interfaces/application/service_provider.mojom.h"
17 #include "testing/gtest/include/gtest/gtest.h"
19 namespace mojo {
20 namespace {
22 const char kTestURLString[] = "test:testService";
23 const char kTestAURLString[] = "test:TestA";
24 const char kTestBURLString[] = "test:TestB";
26 struct TestContext {
27 TestContext() : num_impls(0), num_loader_deletes(0) {}
28 std::string last_test_string;
29 int num_impls;
30 int num_loader_deletes;
33 class QuitMessageLoopErrorHandler : public ErrorHandler {
34 public:
35 QuitMessageLoopErrorHandler() {}
36 virtual ~QuitMessageLoopErrorHandler() {}
38 // |ErrorHandler| implementation:
39 virtual void OnConnectionError() OVERRIDE {
40 base::MessageLoop::current()->QuitWhenIdle();
43 private:
44 DISALLOW_COPY_AND_ASSIGN(QuitMessageLoopErrorHandler);
47 class TestServiceImpl : public InterfaceImpl<TestService> {
48 public:
49 explicit TestServiceImpl(TestContext* context) : context_(context) {
50 ++context_->num_impls;
53 virtual ~TestServiceImpl() { --context_->num_impls; }
55 virtual void OnConnectionError() OVERRIDE {
56 if (!base::MessageLoop::current()->is_running())
57 return;
58 base::MessageLoop::current()->Quit();
61 // TestService implementation:
62 virtual void Test(const String& test_string) OVERRIDE {
63 context_->last_test_string = test_string;
64 client()->AckTest();
67 private:
68 TestContext* context_;
71 class TestClientImpl : public TestClient {
72 public:
73 explicit TestClientImpl(TestServicePtr service)
74 : service_(service.Pass()), quit_after_ack_(false) {
75 service_.set_client(this);
78 virtual ~TestClientImpl() { service_.reset(); }
80 virtual void AckTest() OVERRIDE {
81 if (quit_after_ack_)
82 base::MessageLoop::current()->Quit();
85 void Test(std::string test_string) {
86 quit_after_ack_ = true;
87 service_->Test(test_string);
90 private:
91 TestServicePtr service_;
92 bool quit_after_ack_;
93 DISALLOW_COPY_AND_ASSIGN(TestClientImpl);
96 class TestApplicationLoader : public ApplicationLoader,
97 public ApplicationDelegate,
98 public InterfaceFactory<TestService> {
99 public:
100 TestApplicationLoader() : context_(NULL), num_loads_(0) {}
102 virtual ~TestApplicationLoader() {
103 if (context_)
104 ++context_->num_loader_deletes;
105 test_app_.reset(NULL);
108 void set_context(TestContext* context) { context_ = context; }
109 int num_loads() const { return num_loads_; }
111 private:
112 // ApplicationLoader implementation.
113 virtual void Load(ApplicationManager* manager,
114 const GURL& url,
115 scoped_refptr<LoadCallbacks> callbacks) OVERRIDE {
116 ++num_loads_;
117 test_app_.reset(
118 new ApplicationImpl(this, callbacks->RegisterApplication().Pass()));
121 virtual void OnApplicationError(ApplicationManager* manager,
122 const GURL& url) OVERRIDE {}
124 // ApplicationDelegate implementation.
125 virtual bool ConfigureIncomingConnection(
126 ApplicationConnection* connection) OVERRIDE {
127 connection->AddService(this);
128 return true;
131 // InterfaceFactory implementation.
132 virtual void Create(ApplicationConnection* connection,
133 InterfaceRequest<TestService> request) OVERRIDE {
134 BindToRequest(new TestServiceImpl(context_), &request);
137 scoped_ptr<ApplicationImpl> test_app_;
138 TestContext* context_;
139 int num_loads_;
140 DISALLOW_COPY_AND_ASSIGN(TestApplicationLoader);
143 class TesterContext {
144 public:
145 explicit TesterContext(base::MessageLoop* loop)
146 : num_b_calls_(0),
147 num_c_calls_(0),
148 num_a_deletes_(0),
149 num_b_deletes_(0),
150 num_c_deletes_(0),
151 tester_called_quit_(false),
152 a_called_quit_(false),
153 loop_(loop) {}
155 void IncrementNumBCalls() {
156 base::AutoLock lock(lock_);
157 num_b_calls_++;
160 void IncrementNumCCalls() {
161 base::AutoLock lock(lock_);
162 num_c_calls_++;
165 void IncrementNumADeletes() {
166 base::AutoLock lock(lock_);
167 num_a_deletes_++;
170 void IncrementNumBDeletes() {
171 base::AutoLock lock(lock_);
172 num_b_deletes_++;
175 void IncrementNumCDeletes() {
176 base::AutoLock lock(lock_);
177 num_c_deletes_++;
180 void set_tester_called_quit() {
181 base::AutoLock lock(lock_);
182 tester_called_quit_ = true;
185 void set_a_called_quit() {
186 base::AutoLock lock(lock_);
187 a_called_quit_ = true;
190 int num_b_calls() {
191 base::AutoLock lock(lock_);
192 return num_b_calls_;
194 int num_c_calls() {
195 base::AutoLock lock(lock_);
196 return num_c_calls_;
198 int num_a_deletes() {
199 base::AutoLock lock(lock_);
200 return num_a_deletes_;
202 int num_b_deletes() {
203 base::AutoLock lock(lock_);
204 return num_b_deletes_;
206 int num_c_deletes() {
207 base::AutoLock lock(lock_);
208 return num_c_deletes_;
210 bool tester_called_quit() {
211 base::AutoLock lock(lock_);
212 return tester_called_quit_;
214 bool a_called_quit() {
215 base::AutoLock lock(lock_);
216 return a_called_quit_;
219 void QuitSoon() {
220 loop_->PostTask(FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
223 private:
224 // lock_ protects all members except for loop_ which must be unchanged for the
225 // lifetime of this class.
226 base::Lock lock_;
227 int num_b_calls_;
228 int num_c_calls_;
229 int num_a_deletes_;
230 int num_b_deletes_;
231 int num_c_deletes_;
232 bool tester_called_quit_;
233 bool a_called_quit_;
235 base::MessageLoop* loop_;
238 // Used to test that the requestor url will be correctly passed.
239 class TestAImpl : public InterfaceImpl<TestA> {
240 public:
241 TestAImpl(ApplicationConnection* connection, TesterContext* test_context)
242 : test_context_(test_context) {
243 connection->ConnectToApplication(kTestBURLString)->ConnectToService(&b_);
245 virtual ~TestAImpl() {
246 test_context_->IncrementNumADeletes();
247 if (base::MessageLoop::current()->is_running())
248 Quit();
251 private:
252 virtual void CallB() OVERRIDE {
253 b_->B(base::Bind(&TestAImpl::Quit, base::Unretained(this)));
256 virtual void CallCFromB() OVERRIDE {
257 b_->CallC(base::Bind(&TestAImpl::Quit, base::Unretained(this)));
260 void Quit() {
261 base::MessageLoop::current()->Quit();
262 test_context_->set_a_called_quit();
263 test_context_->QuitSoon();
266 TesterContext* test_context_;
267 TestBPtr b_;
270 class TestBImpl : public InterfaceImpl<TestB> {
271 public:
272 TestBImpl(ApplicationConnection* connection, TesterContext* test_context)
273 : test_context_(test_context) {
274 connection->ConnectToService(&c_);
277 virtual ~TestBImpl() {
278 test_context_->IncrementNumBDeletes();
279 if (base::MessageLoop::current()->is_running())
280 base::MessageLoop::current()->Quit();
281 test_context_->QuitSoon();
284 private:
285 virtual void B(const mojo::Callback<void()>& callback) OVERRIDE {
286 test_context_->IncrementNumBCalls();
287 callback.Run();
290 virtual void CallC(const mojo::Callback<void()>& callback) OVERRIDE {
291 test_context_->IncrementNumBCalls();
292 c_->C(callback);
295 TesterContext* test_context_;
296 TestCPtr c_;
299 class TestCImpl : public InterfaceImpl<TestC> {
300 public:
301 TestCImpl(ApplicationConnection* connection, TesterContext* test_context)
302 : test_context_(test_context) {}
304 virtual ~TestCImpl() { test_context_->IncrementNumCDeletes(); }
306 private:
307 virtual void C(const mojo::Callback<void()>& callback) OVERRIDE {
308 test_context_->IncrementNumCCalls();
309 callback.Run();
311 TesterContext* test_context_;
314 class Tester : public ApplicationDelegate,
315 public ApplicationLoader,
316 public InterfaceFactory<TestA>,
317 public InterfaceFactory<TestB>,
318 public InterfaceFactory<TestC> {
319 public:
320 Tester(TesterContext* context, const std::string& requestor_url)
321 : context_(context), requestor_url_(requestor_url) {}
322 virtual ~Tester() {}
324 private:
325 virtual void Load(ApplicationManager* manager,
326 const GURL& url,
327 scoped_refptr<LoadCallbacks> callbacks) OVERRIDE {
328 app_.reset(
329 new ApplicationImpl(this, callbacks->RegisterApplication().Pass()));
332 virtual void OnApplicationError(ApplicationManager* manager,
333 const GURL& url) OVERRIDE {}
335 virtual bool ConfigureIncomingConnection(
336 ApplicationConnection* connection) OVERRIDE {
337 if (!requestor_url_.empty() &&
338 requestor_url_ != connection->GetRemoteApplicationURL()) {
339 context_->set_tester_called_quit();
340 context_->QuitSoon();
341 base::MessageLoop::current()->Quit();
342 return false;
344 // If we're coming from A, then add B, otherwise A.
345 if (connection->GetRemoteApplicationURL() == kTestAURLString)
346 connection->AddService<TestB>(this);
347 else
348 connection->AddService<TestA>(this);
349 return true;
352 virtual bool ConfigureOutgoingConnection(
353 ApplicationConnection* connection) OVERRIDE {
354 // If we're connecting to B, then add C.
355 if (connection->GetRemoteApplicationURL() == kTestBURLString)
356 connection->AddService<TestC>(this);
357 return true;
360 virtual void Create(ApplicationConnection* connection,
361 InterfaceRequest<TestA> request) OVERRIDE {
362 BindToRequest(new TestAImpl(connection, context_), &request);
365 virtual void Create(ApplicationConnection* connection,
366 InterfaceRequest<TestB> request) OVERRIDE {
367 BindToRequest(new TestBImpl(connection, context_), &request);
370 virtual void Create(ApplicationConnection* connection,
371 InterfaceRequest<TestC> request) OVERRIDE {
372 BindToRequest(new TestCImpl(connection, context_), &request);
375 TesterContext* context_;
376 scoped_ptr<ApplicationImpl> app_;
377 std::string requestor_url_;
380 class TestServiceInterceptor : public ApplicationManager::Interceptor {
381 public:
382 TestServiceInterceptor() : call_count_(0) {}
384 virtual ServiceProviderPtr OnConnectToClient(
385 const GURL& url,
386 ServiceProviderPtr service_provider) OVERRIDE {
387 ++call_count_;
388 url_ = url;
389 return service_provider.Pass();
392 std::string url_spec() const {
393 if (!url_.is_valid())
394 return "invalid url";
395 return url_.spec();
398 int call_count() const { return call_count_; }
400 private:
401 int call_count_;
402 GURL url_;
403 DISALLOW_COPY_AND_ASSIGN(TestServiceInterceptor);
406 } // namespace
408 class ApplicationManagerTest : public testing::Test {
409 public:
410 ApplicationManagerTest() : tester_context_(&loop_) {}
412 virtual ~ApplicationManagerTest() {}
414 virtual void SetUp() OVERRIDE {
415 application_manager_.reset(new ApplicationManager);
416 TestApplicationLoader* default_loader = new TestApplicationLoader;
417 default_loader->set_context(&context_);
418 application_manager_->set_default_loader(
419 scoped_ptr<ApplicationLoader>(default_loader));
421 TestServicePtr service_proxy;
422 application_manager_->ConnectToService(GURL(kTestURLString),
423 &service_proxy);
424 test_client_.reset(new TestClientImpl(service_proxy.Pass()));
427 virtual void TearDown() OVERRIDE {
428 test_client_.reset(NULL);
429 application_manager_.reset(NULL);
432 scoped_ptr<BackgroundShellApplicationLoader> MakeLoader(
433 const std::string& requestor_url) {
434 scoped_ptr<ApplicationLoader> real_loader(
435 new Tester(&tester_context_, requestor_url));
436 scoped_ptr<BackgroundShellApplicationLoader> loader(
437 new BackgroundShellApplicationLoader(real_loader.Pass(),
438 std::string(),
439 base::MessageLoop::TYPE_DEFAULT));
440 return loader.Pass();
443 void AddLoaderForURL(const GURL& url, const std::string& requestor_url) {
444 application_manager_->SetLoaderForURL(
445 MakeLoader(requestor_url).PassAs<ApplicationLoader>(), url);
448 bool HasFactoryForTestURL() {
449 ApplicationManager::TestAPI manager_test_api(application_manager_.get());
450 return manager_test_api.HasFactoryForURL(GURL(kTestURLString));
453 protected:
454 base::ShadowingAtExitManager at_exit_;
455 TesterContext tester_context_;
456 TestContext context_;
457 base::MessageLoop loop_;
458 scoped_ptr<TestClientImpl> test_client_;
459 scoped_ptr<ApplicationManager> application_manager_;
460 DISALLOW_COPY_AND_ASSIGN(ApplicationManagerTest);
463 TEST_F(ApplicationManagerTest, Basic) {
464 test_client_->Test("test");
465 loop_.Run();
466 EXPECT_EQ(std::string("test"), context_.last_test_string);
469 TEST_F(ApplicationManagerTest, ClientError) {
470 test_client_->Test("test");
471 EXPECT_TRUE(HasFactoryForTestURL());
472 loop_.Run();
473 EXPECT_EQ(1, context_.num_impls);
474 test_client_.reset(NULL);
475 loop_.Run();
476 EXPECT_EQ(0, context_.num_impls);
477 EXPECT_TRUE(HasFactoryForTestURL());
480 TEST_F(ApplicationManagerTest, Deletes) {
482 ApplicationManager sm;
483 TestApplicationLoader* default_loader = new TestApplicationLoader;
484 default_loader->set_context(&context_);
485 TestApplicationLoader* url_loader1 = new TestApplicationLoader;
486 TestApplicationLoader* url_loader2 = new TestApplicationLoader;
487 url_loader1->set_context(&context_);
488 url_loader2->set_context(&context_);
489 TestApplicationLoader* scheme_loader1 = new TestApplicationLoader;
490 TestApplicationLoader* scheme_loader2 = new TestApplicationLoader;
491 scheme_loader1->set_context(&context_);
492 scheme_loader2->set_context(&context_);
493 sm.set_default_loader(scoped_ptr<ApplicationLoader>(default_loader));
494 sm.SetLoaderForURL(scoped_ptr<ApplicationLoader>(url_loader1),
495 GURL("test:test1"));
496 sm.SetLoaderForURL(scoped_ptr<ApplicationLoader>(url_loader2),
497 GURL("test:test1"));
498 sm.SetLoaderForScheme(scoped_ptr<ApplicationLoader>(scheme_loader1),
499 "test");
500 sm.SetLoaderForScheme(scoped_ptr<ApplicationLoader>(scheme_loader2),
501 "test");
503 EXPECT_EQ(5, context_.num_loader_deletes);
506 // Confirm that both urls and schemes can have their loaders explicitly set.
507 TEST_F(ApplicationManagerTest, SetLoaders) {
508 ApplicationManager sm;
509 TestApplicationLoader* default_loader = new TestApplicationLoader;
510 TestApplicationLoader* url_loader = new TestApplicationLoader;
511 TestApplicationLoader* scheme_loader = new TestApplicationLoader;
512 application_manager_->set_default_loader(
513 scoped_ptr<ApplicationLoader>(default_loader));
514 application_manager_->SetLoaderForURL(
515 scoped_ptr<ApplicationLoader>(url_loader), GURL("test:test1"));
516 application_manager_->SetLoaderForScheme(
517 scoped_ptr<ApplicationLoader>(scheme_loader), "test");
519 // test::test1 should go to url_loader.
520 TestServicePtr test_service;
521 application_manager_->ConnectToService(GURL("test:test1"), &test_service);
522 EXPECT_EQ(1, url_loader->num_loads());
523 EXPECT_EQ(0, scheme_loader->num_loads());
524 EXPECT_EQ(0, default_loader->num_loads());
526 // test::test2 should go to scheme loader.
527 application_manager_->ConnectToService(GURL("test:test2"), &test_service);
528 EXPECT_EQ(1, url_loader->num_loads());
529 EXPECT_EQ(1, scheme_loader->num_loads());
530 EXPECT_EQ(0, default_loader->num_loads());
532 // http::test1 should go to default loader.
533 application_manager_->ConnectToService(GURL("http:test1"), &test_service);
534 EXPECT_EQ(1, url_loader->num_loads());
535 EXPECT_EQ(1, scheme_loader->num_loads());
536 EXPECT_EQ(1, default_loader->num_loads());
539 // Confirm that the url of a service is correctly passed to another service that
540 // it loads.
541 TEST_F(ApplicationManagerTest, ACallB) {
542 // Any url can load a.
543 AddLoaderForURL(GURL(kTestAURLString), std::string());
545 // Only a can load b.
546 AddLoaderForURL(GURL(kTestBURLString), kTestAURLString);
548 TestAPtr a;
549 application_manager_->ConnectToService(GURL(kTestAURLString), &a);
550 a->CallB();
551 loop_.Run();
552 EXPECT_EQ(1, tester_context_.num_b_calls());
553 EXPECT_TRUE(tester_context_.a_called_quit());
556 // A calls B which calls C.
557 TEST_F(ApplicationManagerTest, BCallC) {
558 // Any url can load a.
559 AddLoaderForURL(GURL(kTestAURLString), std::string());
561 // Only a can load b.
562 AddLoaderForURL(GURL(kTestBURLString), kTestAURLString);
564 TestAPtr a;
565 application_manager_->ConnectToService(GURL(kTestAURLString), &a);
566 a->CallCFromB();
567 loop_.Run();
569 EXPECT_EQ(1, tester_context_.num_b_calls());
570 EXPECT_EQ(1, tester_context_.num_c_calls());
571 EXPECT_TRUE(tester_context_.a_called_quit());
574 // Confirm that a service impl will be deleted if the app that connected to
575 // it goes away.
576 TEST_F(ApplicationManagerTest, BDeleted) {
577 AddLoaderForURL(GURL(kTestAURLString), std::string());
578 AddLoaderForURL(GURL(kTestBURLString), std::string());
580 TestAPtr a;
581 application_manager_->ConnectToService(GURL(kTestAURLString), &a);
583 a->CallB();
584 loop_.Run();
586 // Kills the a app.
587 application_manager_->SetLoaderForURL(scoped_ptr<ApplicationLoader>(),
588 GURL(kTestAURLString));
589 loop_.Run();
591 EXPECT_EQ(1, tester_context_.num_b_deletes());
594 // Confirm that the url of a service is correctly passed to another service that
595 // it loads, and that it can be rejected.
596 TEST_F(ApplicationManagerTest, ANoLoadB) {
597 // Any url can load a.
598 AddLoaderForURL(GURL(kTestAURLString), std::string());
600 // Only c can load b, so this will fail.
601 AddLoaderForURL(GURL(kTestBURLString), "test:TestC");
603 TestAPtr a;
604 application_manager_->ConnectToService(GURL(kTestAURLString), &a);
605 a->CallB();
606 loop_.Run();
607 EXPECT_EQ(0, tester_context_.num_b_calls());
609 EXPECT_FALSE(tester_context_.a_called_quit());
610 EXPECT_TRUE(tester_context_.tester_called_quit());
613 TEST_F(ApplicationManagerTest, NoServiceNoLoad) {
614 AddLoaderForURL(GURL(kTestAURLString), std::string());
616 // There is no TestC service implementation registered with
617 // ApplicationManager, so this cannot succeed (but also shouldn't crash).
618 TestCPtr c;
619 application_manager_->ConnectToService(GURL(kTestAURLString), &c);
620 QuitMessageLoopErrorHandler quitter;
621 c.set_error_handler(&quitter);
623 loop_.Run();
624 EXPECT_TRUE(c.encountered_error());
627 TEST_F(ApplicationManagerTest, Interceptor) {
628 TestServiceInterceptor interceptor;
629 TestApplicationLoader* default_loader = new TestApplicationLoader;
630 application_manager_->set_default_loader(
631 scoped_ptr<ApplicationLoader>(default_loader));
632 application_manager_->SetInterceptor(&interceptor);
634 std::string url("test:test3");
635 TestServicePtr test_service;
636 application_manager_->ConnectToService(GURL(url), &test_service);
638 EXPECT_EQ(1, interceptor.call_count());
639 EXPECT_EQ(url, interceptor.url_spec());
640 EXPECT_EQ(1, default_loader->num_loads());
643 } // namespace mojo