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"
7 #include "base/macros.h"
8 #include "base/memory/scoped_vector.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/run_loop.h"
11 #include "mojo/application/public/cpp/application_connection.h"
12 #include "mojo/application/public/cpp/application_delegate.h"
13 #include "mojo/application/public/cpp/application_impl.h"
14 #include "mojo/application/public/cpp/interface_factory.h"
15 #include "mojo/application/public/interfaces/content_handler.mojom.h"
16 #include "mojo/application/public/interfaces/service_provider.mojom.h"
17 #include "mojo/public/cpp/bindings/strong_binding.h"
18 #include "mojo/shell/application_loader.h"
19 #include "mojo/shell/application_manager.h"
20 #include "mojo/shell/fetcher.h"
21 #include "mojo/shell/test.mojom.h"
22 #include "testing/gtest/include/gtest/gtest.h"
28 const char kTestURLString
[] = "test:testService";
29 const char kTestAURLString
[] = "test:TestA";
30 const char kTestBURLString
[] = "test:TestB";
32 const char kTestMimeType
[] = "test/mime-type";
34 class TestMimeTypeFetcher
: public Fetcher
{
36 TestMimeTypeFetcher(const FetchCallback
& fetch_callback
,
38 const std::string
& mime_type
)
39 : Fetcher(fetch_callback
), url_(url
), mime_type_(mime_type
) {
40 loader_callback_
.Run(make_scoped_ptr(this));
42 ~TestMimeTypeFetcher() override
{}
45 const GURL
& GetURL() const override
{ return url_
; }
46 GURL
GetRedirectURL() const override
{ return GURL("yyy"); }
47 GURL
GetRedirectReferer() const override
{ return GURL(); }
48 URLResponsePtr
AsURLResponse(base::TaskRunner
* task_runner
,
49 uint32_t skip
) override
{
50 return URLResponse::New().Pass();
53 base::TaskRunner
* task_runner
,
54 base::Callback
<void(const base::FilePath
&, bool)> callback
) override
{}
55 std::string
MimeType() override
{ return mime_type_
; }
56 bool HasMojoMagic() override
{ return false; }
57 bool PeekFirstLine(std::string
* line
) override
{ return false; }
61 const std::string mime_type_
;
63 DISALLOW_COPY_AND_ASSIGN(TestMimeTypeFetcher
);
67 TestContext() : num_impls(0), num_loader_deletes(0) {}
68 std::string last_test_string
;
70 int num_loader_deletes
;
73 void QuitClosure(bool* value
) {
75 base::MessageLoop::current()->QuitWhenIdle();
78 class TestServiceImpl
: public TestService
{
80 TestServiceImpl(TestContext
* context
, InterfaceRequest
<TestService
> request
)
81 : context_(context
), binding_(this, request
.Pass()) {
82 ++context_
->num_impls
;
85 ~TestServiceImpl() override
{
86 --context_
->num_impls
;
87 if (!base::MessageLoop::current()->is_running())
89 base::MessageLoop::current()->Quit();
92 // TestService implementation:
93 void Test(const String
& test_string
,
94 const Callback
<void()>& callback
) override
{
95 context_
->last_test_string
= test_string
;
100 TestContext
* context_
;
101 StrongBinding
<TestService
> binding_
;
106 explicit TestClient(TestServicePtr service
)
107 : service_(service
.Pass()), quit_after_ack_(false) {}
111 base::MessageLoop::current()->Quit();
114 void Test(const std::string
& test_string
) {
115 quit_after_ack_
= true;
116 service_
->Test(test_string
,
117 base::Bind(&TestClient::AckTest
, base::Unretained(this)));
121 TestServicePtr service_
;
122 bool quit_after_ack_
;
123 DISALLOW_COPY_AND_ASSIGN(TestClient
);
126 class TestContentHandler
: public ContentHandler
, public ApplicationDelegate
{
128 TestContentHandler(ApplicationConnection
* connection
,
129 InterfaceRequest
<ContentHandler
> request
)
130 : binding_(this, request
.Pass()) {}
133 void StartApplication(InterfaceRequest
<Application
> application_request
,
134 URLResponsePtr response
) override
{
135 apps_
.push_back(new ApplicationImpl(this, application_request
.Pass()));
139 StrongBinding
<ContentHandler
> binding_
;
140 ScopedVector
<ApplicationImpl
> apps_
;
142 DISALLOW_COPY_AND_ASSIGN(TestContentHandler
);
145 class TestApplicationLoader
: public ApplicationLoader
,
146 public ApplicationDelegate
,
147 public InterfaceFactory
<TestService
>,
148 public InterfaceFactory
<ContentHandler
> {
150 TestApplicationLoader()
151 : context_(nullptr), num_loads_(0), create_content_handler_(false) {}
153 ~TestApplicationLoader() override
{
155 ++context_
->num_loader_deletes
;
159 void set_create_content_handler(bool value
) {
160 create_content_handler_
= true;
163 void set_context(TestContext
* context
) { context_
= context
; }
164 int num_loads() const { return num_loads_
; }
165 const GURL
& last_requestor_url() const { return last_requestor_url_
; }
168 // ApplicationLoader implementation.
169 void Load(const GURL
& url
,
170 InterfaceRequest
<Application
> application_request
) override
{
172 test_app_
.reset(new ApplicationImpl(this, application_request
.Pass()));
175 // ApplicationDelegate implementation.
176 bool ConfigureIncomingConnection(ApplicationConnection
* connection
) override
{
177 connection
->AddService
<TestService
>(this);
178 if (create_content_handler_
)
179 connection
->AddService
<ContentHandler
>(this);
180 last_requestor_url_
= GURL(connection
->GetRemoteApplicationURL());
184 // InterfaceFactory<TestService> implementation.
185 void Create(ApplicationConnection
* connection
,
186 InterfaceRequest
<TestService
> request
) override
{
187 new TestServiceImpl(context_
, request
.Pass());
190 // InterfaceFactory<ContentHandler> implementation.
191 void Create(ApplicationConnection
* connection
,
192 InterfaceRequest
<ContentHandler
> request
) override
{
193 new TestContentHandler(connection
, request
.Pass());
196 scoped_ptr
<ApplicationImpl
> test_app_
;
197 TestContext
* context_
;
199 GURL last_requestor_url_
;
200 bool create_content_handler_
;
202 DISALLOW_COPY_AND_ASSIGN(TestApplicationLoader
);
205 class ClosingApplicationLoader
: public ApplicationLoader
{
207 // ApplicationLoader implementation.
208 void Load(const GURL
& url
,
209 InterfaceRequest
<Application
> application_request
) override
{}
212 class TesterContext
{
214 explicit TesterContext(base::MessageLoop
* loop
)
220 tester_called_quit_(false),
221 a_called_quit_(false),
224 void IncrementNumBCalls() {
225 base::AutoLock
lock(lock_
);
229 void IncrementNumCCalls() {
230 base::AutoLock
lock(lock_
);
234 void IncrementNumADeletes() {
235 base::AutoLock
lock(lock_
);
239 void IncrementNumBDeletes() {
240 base::AutoLock
lock(lock_
);
244 void IncrementNumCDeletes() {
245 base::AutoLock
lock(lock_
);
249 void set_tester_called_quit() {
250 base::AutoLock
lock(lock_
);
251 tester_called_quit_
= true;
254 void set_a_called_quit() {
255 base::AutoLock
lock(lock_
);
256 a_called_quit_
= true;
260 base::AutoLock
lock(lock_
);
264 base::AutoLock
lock(lock_
);
267 int num_a_deletes() {
268 base::AutoLock
lock(lock_
);
269 return num_a_deletes_
;
271 int num_b_deletes() {
272 base::AutoLock
lock(lock_
);
273 return num_b_deletes_
;
275 int num_c_deletes() {
276 base::AutoLock
lock(lock_
);
277 return num_c_deletes_
;
279 bool tester_called_quit() {
280 base::AutoLock
lock(lock_
);
281 return tester_called_quit_
;
283 bool a_called_quit() {
284 base::AutoLock
lock(lock_
);
285 return a_called_quit_
;
289 loop_
->PostTask(FROM_HERE
, base::MessageLoop::QuitWhenIdleClosure());
293 // lock_ protects all members except for loop_ which must be unchanged for the
294 // lifetime of this class.
301 bool tester_called_quit_
;
304 base::MessageLoop
* loop_
;
307 // Used to test that the requestor url will be correctly passed.
308 class TestAImpl
: public TestA
{
310 TestAImpl(ApplicationImpl
* app_impl
,
311 TesterContext
* test_context
,
312 InterfaceRequest
<TestA
> request
)
313 : test_context_(test_context
), binding_(this, request
.Pass()) {
314 mojo::URLRequestPtr
request2(mojo::URLRequest::New());
315 request2
->url
= mojo::String::From(kTestBURLString
);
316 connection_
= app_impl
->ConnectToApplication(request2
.Pass());
317 connection_
->ConnectToService(&b_
);
320 ~TestAImpl() override
{
321 test_context_
->IncrementNumADeletes();
322 if (base::MessageLoop::current()->is_running())
327 void CallB() override
{
328 b_
->B(base::Bind(&TestAImpl::Quit
, base::Unretained(this)));
331 void CallCFromB() override
{
332 b_
->CallC(base::Bind(&TestAImpl::Quit
, base::Unretained(this)));
336 base::MessageLoop::current()->Quit();
337 test_context_
->set_a_called_quit();
338 test_context_
->QuitSoon();
341 scoped_ptr
<ApplicationConnection
> connection_
;
342 TesterContext
* test_context_
;
344 StrongBinding
<TestA
> binding_
;
347 class TestBImpl
: public TestB
{
349 TestBImpl(ApplicationConnection
* connection
,
350 TesterContext
* test_context
,
351 InterfaceRequest
<TestB
> request
)
352 : test_context_(test_context
), binding_(this, request
.Pass()) {
353 connection
->ConnectToService(&c_
);
356 ~TestBImpl() override
{
357 test_context_
->IncrementNumBDeletes();
358 if (base::MessageLoop::current()->is_running())
359 base::MessageLoop::current()->Quit();
360 test_context_
->QuitSoon();
364 void B(const Callback
<void()>& callback
) override
{
365 test_context_
->IncrementNumBCalls();
369 void CallC(const Callback
<void()>& callback
) override
{
370 test_context_
->IncrementNumBCalls();
374 TesterContext
* test_context_
;
376 StrongBinding
<TestB
> binding_
;
379 class TestCImpl
: public TestC
{
381 TestCImpl(ApplicationConnection
* connection
,
382 TesterContext
* test_context
,
383 InterfaceRequest
<TestC
> request
)
384 : test_context_(test_context
), binding_(this, request
.Pass()) {}
386 ~TestCImpl() override
{ test_context_
->IncrementNumCDeletes(); }
389 void C(const Callback
<void()>& callback
) override
{
390 test_context_
->IncrementNumCCalls();
394 TesterContext
* test_context_
;
395 StrongBinding
<TestC
> binding_
;
398 class Tester
: public ApplicationDelegate
,
399 public ApplicationLoader
,
400 public InterfaceFactory
<TestA
>,
401 public InterfaceFactory
<TestB
>,
402 public InterfaceFactory
<TestC
> {
404 Tester(TesterContext
* context
, const std::string
& requestor_url
)
405 : context_(context
), requestor_url_(requestor_url
) {}
406 ~Tester() override
{}
409 void Load(const GURL
& url
,
410 InterfaceRequest
<Application
> application_request
) override
{
411 app_
.reset(new ApplicationImpl(this, application_request
.Pass()));
414 bool ConfigureIncomingConnection(ApplicationConnection
* connection
) override
{
415 if (!requestor_url_
.empty() &&
416 requestor_url_
!= connection
->GetRemoteApplicationURL()) {
417 context_
->set_tester_called_quit();
418 context_
->QuitSoon();
419 base::MessageLoop::current()->Quit();
422 // If we're coming from A, then add B, otherwise A.
423 if (connection
->GetRemoteApplicationURL() == kTestAURLString
)
424 connection
->AddService
<TestB
>(this);
426 connection
->AddService
<TestA
>(this);
430 bool ConfigureOutgoingConnection(ApplicationConnection
* connection
) override
{
431 // If we're connecting to B, then add C.
432 if (connection
->GetRemoteApplicationURL() == kTestBURLString
)
433 connection
->AddService
<TestC
>(this);
437 void Create(ApplicationConnection
* connection
,
438 InterfaceRequest
<TestA
> request
) override
{
439 a_bindings_
.push_back(new TestAImpl(app_
.get(), context_
, request
.Pass()));
442 void Create(ApplicationConnection
* connection
,
443 InterfaceRequest
<TestB
> request
) override
{
444 new TestBImpl(connection
, context_
, request
.Pass());
447 void Create(ApplicationConnection
* connection
,
448 InterfaceRequest
<TestC
> request
) override
{
449 new TestCImpl(connection
, context_
, request
.Pass());
452 TesterContext
* context_
;
453 scoped_ptr
<ApplicationImpl
> app_
;
454 std::string requestor_url_
;
455 ScopedVector
<TestAImpl
> a_bindings_
;
458 class TestDelegate
: public ApplicationManager::Delegate
{
461 : create_test_fetcher_(false),
463 mime_type_(kTestMimeType
) {}
464 ~TestDelegate() override
{}
466 void AddMapping(const GURL
& from
, const GURL
& to
) { mappings_
[from
] = to
; }
468 void set_create_test_fetcher(bool create_test_fetcher
) {
469 create_test_fetcher_
= create_test_fetcher
;
472 void set_fetcher_url(const GURL
& url
) { fetcher_url_
= url
; }
474 void set_mime_type(const std::string
& mime_type
) { mime_type_
= mime_type
; }
476 // ApplicationManager::Delegate
477 GURL
ResolveMappings(const GURL
& url
) override
{
478 auto it
= mappings_
.find(url
);
479 if (it
!= mappings_
.end())
483 GURL
ResolveMojoURL(const GURL
& url
) override
{
484 GURL mapped_url
= ResolveMappings(url
);
485 // The shell automatically map mojo URLs.
486 if (mapped_url
.scheme() == "mojo") {
487 url::Replacements
<char> replacements
;
488 replacements
.SetScheme("file", url::Component(0, 4));
489 mapped_url
= mapped_url
.ReplaceComponents(replacements
);
493 bool CreateFetcher(const GURL
& url
,
494 const Fetcher::FetchCallback
& loader_callback
) override
{
495 if (!create_test_fetcher_
)
497 new TestMimeTypeFetcher(loader_callback
, fetcher_url_
, mime_type_
);
502 std::map
<GURL
, GURL
> mappings_
;
503 bool create_test_fetcher_
;
505 std::string mime_type_
;
507 DISALLOW_COPY_AND_ASSIGN(TestDelegate
);
510 class ApplicationManagerTest
: public testing::Test
{
512 ApplicationManagerTest() : tester_context_(&loop_
) {}
514 ~ApplicationManagerTest() override
{}
516 void SetUp() override
{
517 application_manager_
.reset(new ApplicationManager(&test_delegate_
));
518 test_loader_
= new TestApplicationLoader
;
519 test_loader_
->set_context(&context_
);
520 application_manager_
->set_default_loader(
521 scoped_ptr
<ApplicationLoader
>(test_loader_
));
523 TestServicePtr service_proxy
;
524 application_manager_
->ConnectToService(GURL(kTestURLString
),
526 test_client_
.reset(new TestClient(service_proxy
.Pass()));
529 void TearDown() override
{
530 test_client_
.reset();
531 application_manager_
.reset();
534 void AddLoaderForURL(const GURL
& url
, const std::string
& requestor_url
) {
535 application_manager_
->SetLoaderForURL(
536 make_scoped_ptr(new Tester(&tester_context_
, requestor_url
)), url
);
539 bool HasRunningInstanceForURL(const GURL
& url
) {
540 ApplicationManager::TestAPI
manager_test_api(application_manager_
.get());
541 return manager_test_api
.HasRunningInstanceForURL(url
);
545 base::ShadowingAtExitManager at_exit_
;
546 TestDelegate test_delegate_
;
547 TestApplicationLoader
* test_loader_
;
548 TesterContext tester_context_
;
549 TestContext context_
;
550 base::MessageLoop loop_
;
551 scoped_ptr
<TestClient
> test_client_
;
552 scoped_ptr
<ApplicationManager
> application_manager_
;
553 DISALLOW_COPY_AND_ASSIGN(ApplicationManagerTest
);
556 TEST_F(ApplicationManagerTest
, Basic
) {
557 test_client_
->Test("test");
559 EXPECT_EQ(std::string("test"), context_
.last_test_string
);
562 // Confirm that url mappings are respected.
563 TEST_F(ApplicationManagerTest
, URLMapping
) {
564 ApplicationManager
am(&test_delegate_
);
565 GURL
test_url("test:test");
566 GURL
test_url2("test:test2");
567 test_delegate_
.AddMapping(test_url
, test_url2
);
568 TestApplicationLoader
* loader
= new TestApplicationLoader
;
569 loader
->set_context(&context_
);
570 am
.SetLoaderForURL(scoped_ptr
<ApplicationLoader
>(loader
), test_url2
);
572 // Connect to the mapped url
573 TestServicePtr test_service
;
574 am
.ConnectToService(test_url
, &test_service
);
575 TestClient
test_client(test_service
.Pass());
576 test_client
.Test("test");
580 // Connect to the target url
581 TestServicePtr test_service
;
582 am
.ConnectToService(test_url2
, &test_service
);
583 TestClient
test_client(test_service
.Pass());
584 test_client
.Test("test");
589 TEST_F(ApplicationManagerTest
, ClientError
) {
590 test_client_
->Test("test");
591 EXPECT_TRUE(HasRunningInstanceForURL(GURL(kTestURLString
)));
593 EXPECT_EQ(1, context_
.num_impls
);
594 test_client_
.reset();
596 EXPECT_EQ(0, context_
.num_impls
);
597 EXPECT_TRUE(HasRunningInstanceForURL(GURL(kTestURLString
)));
600 TEST_F(ApplicationManagerTest
, Deletes
) {
602 ApplicationManager
am(&test_delegate_
);
603 TestApplicationLoader
* default_loader
= new TestApplicationLoader
;
604 default_loader
->set_context(&context_
);
605 TestApplicationLoader
* url_loader1
= new TestApplicationLoader
;
606 TestApplicationLoader
* url_loader2
= new TestApplicationLoader
;
607 url_loader1
->set_context(&context_
);
608 url_loader2
->set_context(&context_
);
609 TestApplicationLoader
* scheme_loader1
= new TestApplicationLoader
;
610 TestApplicationLoader
* scheme_loader2
= new TestApplicationLoader
;
611 scheme_loader1
->set_context(&context_
);
612 scheme_loader2
->set_context(&context_
);
613 am
.set_default_loader(scoped_ptr
<ApplicationLoader
>(default_loader
));
614 am
.SetLoaderForURL(scoped_ptr
<ApplicationLoader
>(url_loader1
),
616 am
.SetLoaderForURL(scoped_ptr
<ApplicationLoader
>(url_loader2
),
618 am
.SetLoaderForScheme(scoped_ptr
<ApplicationLoader
>(scheme_loader1
),
620 am
.SetLoaderForScheme(scoped_ptr
<ApplicationLoader
>(scheme_loader2
),
623 EXPECT_EQ(5, context_
.num_loader_deletes
);
626 // Confirm that both urls and schemes can have their loaders explicitly set.
627 TEST_F(ApplicationManagerTest
, SetLoaders
) {
628 TestApplicationLoader
* default_loader
= new TestApplicationLoader
;
629 TestApplicationLoader
* url_loader
= new TestApplicationLoader
;
630 TestApplicationLoader
* scheme_loader
= new TestApplicationLoader
;
631 application_manager_
->set_default_loader(
632 scoped_ptr
<ApplicationLoader
>(default_loader
));
633 application_manager_
->SetLoaderForURL(
634 scoped_ptr
<ApplicationLoader
>(url_loader
), GURL("test:test1"));
635 application_manager_
->SetLoaderForScheme(
636 scoped_ptr
<ApplicationLoader
>(scheme_loader
), "test");
638 // test::test1 should go to url_loader.
639 TestServicePtr test_service
;
640 application_manager_
->ConnectToService(GURL("test:test1"), &test_service
);
641 EXPECT_EQ(1, url_loader
->num_loads());
642 EXPECT_EQ(0, scheme_loader
->num_loads());
643 EXPECT_EQ(0, default_loader
->num_loads());
645 // test::test2 should go to scheme loader.
646 application_manager_
->ConnectToService(GURL("test:test2"), &test_service
);
647 EXPECT_EQ(1, url_loader
->num_loads());
648 EXPECT_EQ(1, scheme_loader
->num_loads());
649 EXPECT_EQ(0, default_loader
->num_loads());
651 // http::test1 should go to default loader.
652 application_manager_
->ConnectToService(GURL("http:test1"), &test_service
);
653 EXPECT_EQ(1, url_loader
->num_loads());
654 EXPECT_EQ(1, scheme_loader
->num_loads());
655 EXPECT_EQ(1, default_loader
->num_loads());
658 // Confirm that the url of a service is correctly passed to another service that
660 TEST_F(ApplicationManagerTest
, ACallB
) {
661 // Any url can load a.
662 AddLoaderForURL(GURL(kTestAURLString
), std::string());
664 // Only a can load b.
665 AddLoaderForURL(GURL(kTestBURLString
), kTestAURLString
);
668 application_manager_
->ConnectToService(GURL(kTestAURLString
), &a
);
671 EXPECT_EQ(1, tester_context_
.num_b_calls());
672 EXPECT_TRUE(tester_context_
.a_called_quit());
675 // A calls B which calls C.
676 TEST_F(ApplicationManagerTest
, BCallC
) {
677 // Any url can load a.
678 AddLoaderForURL(GURL(kTestAURLString
), std::string());
680 // Only a can load b.
681 AddLoaderForURL(GURL(kTestBURLString
), kTestAURLString
);
684 application_manager_
->ConnectToService(GURL(kTestAURLString
), &a
);
688 EXPECT_EQ(1, tester_context_
.num_b_calls());
689 EXPECT_EQ(1, tester_context_
.num_c_calls());
690 EXPECT_TRUE(tester_context_
.a_called_quit());
693 // Confirm that a service impl will be deleted if the app that connected to
695 TEST_F(ApplicationManagerTest
, BDeleted
) {
696 AddLoaderForURL(GURL(kTestAURLString
), std::string());
697 AddLoaderForURL(GURL(kTestBURLString
), std::string());
700 application_manager_
->ConnectToService(GURL(kTestAURLString
), &a
);
706 application_manager_
->SetLoaderForURL(scoped_ptr
<ApplicationLoader
>(),
707 GURL(kTestAURLString
));
710 EXPECT_EQ(1, tester_context_
.num_b_deletes());
713 // Confirm that the url of a service is correctly passed to another service that
714 // it loads, and that it can be rejected.
715 TEST_F(ApplicationManagerTest
, ANoLoadB
) {
716 // Any url can load a.
717 AddLoaderForURL(GURL(kTestAURLString
), std::string());
719 // Only c can load b, so this will fail.
720 AddLoaderForURL(GURL(kTestBURLString
), "test:TestC");
723 application_manager_
->ConnectToService(GURL(kTestAURLString
), &a
);
726 EXPECT_EQ(0, tester_context_
.num_b_calls());
728 EXPECT_FALSE(tester_context_
.a_called_quit());
729 EXPECT_TRUE(tester_context_
.tester_called_quit());
732 TEST_F(ApplicationManagerTest
, NoServiceNoLoad
) {
733 AddLoaderForURL(GURL(kTestAURLString
), std::string());
735 // There is no TestC service implementation registered with
736 // ApplicationManager, so this cannot succeed (but also shouldn't crash).
738 application_manager_
->ConnectToService(GURL(kTestAURLString
), &c
);
739 c
.set_connection_error_handler(
740 []() { base::MessageLoop::current()->QuitWhenIdle(); });
743 EXPECT_TRUE(c
.encountered_error());
746 TEST_F(ApplicationManagerTest
, MappedURLsShouldNotCauseDuplicateLoad
) {
747 test_delegate_
.AddMapping(GURL("foo:foo2"), GURL("foo:foo"));
748 // 1 because ApplicationManagerTest connects once at startup.
749 EXPECT_EQ(1, test_loader_
->num_loads());
751 TestServicePtr test_service
;
752 application_manager_
->ConnectToService(GURL("foo:foo"), &test_service
);
753 EXPECT_EQ(2, test_loader_
->num_loads());
755 TestServicePtr test_service2
;
756 application_manager_
->ConnectToService(GURL("foo:foo2"), &test_service2
);
757 EXPECT_EQ(2, test_loader_
->num_loads());
759 TestServicePtr test_service3
;
760 application_manager_
->ConnectToService(GURL("bar:bar"), &test_service2
);
761 EXPECT_EQ(3, test_loader_
->num_loads());
764 TEST_F(ApplicationManagerTest
, MappedURLsShouldWorkWithLoaders
) {
765 TestApplicationLoader
* custom_loader
= new TestApplicationLoader
;
767 custom_loader
->set_context(&context
);
768 application_manager_
->SetLoaderForURL(make_scoped_ptr(custom_loader
),
770 test_delegate_
.AddMapping(GURL("mojo:foo2"), GURL("mojo:foo"));
772 TestServicePtr test_service
;
773 application_manager_
->ConnectToService(GURL("mojo:foo2"), &test_service
);
774 EXPECT_EQ(1, custom_loader
->num_loads());
775 custom_loader
->set_context(nullptr);
777 EXPECT_TRUE(HasRunningInstanceForURL(GURL("mojo:foo2")));
778 EXPECT_FALSE(HasRunningInstanceForURL(GURL("mojo:foo")));
781 TEST_F(ApplicationManagerTest
, TestQueryWithLoaders
) {
782 TestApplicationLoader
* url_loader
= new TestApplicationLoader
;
783 TestApplicationLoader
* scheme_loader
= new TestApplicationLoader
;
784 application_manager_
->SetLoaderForURL(
785 scoped_ptr
<ApplicationLoader
>(url_loader
), GURL("test:test1"));
786 application_manager_
->SetLoaderForScheme(
787 scoped_ptr
<ApplicationLoader
>(scheme_loader
), "test");
789 // test::test1 should go to url_loader.
790 TestServicePtr test_service
;
791 application_manager_
->ConnectToService(GURL("test:test1?foo=bar"),
793 EXPECT_EQ(1, url_loader
->num_loads());
794 EXPECT_EQ(0, scheme_loader
->num_loads());
796 // test::test2 should go to scheme loader.
797 application_manager_
->ConnectToService(GURL("test:test2?foo=bar"),
799 EXPECT_EQ(1, url_loader
->num_loads());
800 EXPECT_EQ(1, scheme_loader
->num_loads());
803 TEST_F(ApplicationManagerTest
, TestEndApplicationClosure
) {
804 ClosingApplicationLoader
* loader
= new ClosingApplicationLoader();
805 application_manager_
->SetLoaderForScheme(
806 scoped_ptr
<ApplicationLoader
>(loader
), "test");
809 scoped_ptr
<ConnectToApplicationParams
> params(new ConnectToApplicationParams
);
810 params
->SetURLInfo(GURL("test:test"));
811 params
->set_filter(GetPermissiveCapabilityFilter());
812 params
->set_on_application_end(
813 base::Bind(&QuitClosure
, base::Unretained(&called
)));
814 application_manager_
->ConnectToApplication(params
.Pass());
819 TEST(ApplicationManagerTest2
, ContentHandlerConnectionGetsRequestorURL
) {
820 const GURL
content_handler_url("http://test.content.handler");
821 const GURL
requestor_url("http://requestor.url");
822 TestContext test_context
;
823 base::MessageLoop loop
;
824 TestDelegate test_delegate
;
825 test_delegate
.set_create_test_fetcher(true);
826 ApplicationManager
application_manager(&test_delegate
);
827 application_manager
.set_default_loader(nullptr);
828 application_manager
.RegisterContentHandler(kTestMimeType
,
829 content_handler_url
);
831 TestApplicationLoader
* loader
= new TestApplicationLoader
;
832 loader
->set_context(&test_context
);
833 application_manager
.SetLoaderForURL(scoped_ptr
<ApplicationLoader
>(loader
),
834 content_handler_url
);
837 scoped_ptr
<ConnectToApplicationParams
> params(new ConnectToApplicationParams
);
838 params
->set_originator_identity(Identity(requestor_url
));
839 params
->set_originator_filter(GetPermissiveCapabilityFilter());
840 params
->SetURLInfo(GURL("test:test"));
841 params
->set_filter(GetPermissiveCapabilityFilter());
842 params
->set_on_application_end(
843 base::Bind(&QuitClosure
, base::Unretained(&called
)));
844 application_manager
.ConnectToApplication(params
.Pass());
848 ASSERT_EQ(1, loader
->num_loads());
849 EXPECT_EQ(requestor_url
, loader
->last_requestor_url());
852 TEST_F(ApplicationManagerTest
, SameIdentityShouldNotCauseDuplicateLoad
) {
853 // 1 because ApplicationManagerTest connects once at startup.
854 EXPECT_EQ(1, test_loader_
->num_loads());
856 TestServicePtr test_service
;
857 application_manager_
->ConnectToService(GURL("http://www.example.org/abc?def"),
859 EXPECT_EQ(2, test_loader_
->num_loads());
861 // Exactly the same URL as above.
862 application_manager_
->ConnectToService(GURL("http://www.example.org/abc?def"),
864 EXPECT_EQ(2, test_loader_
->num_loads());
866 // The same identity as the one above because only the query string is
868 application_manager_
->ConnectToService(GURL("http://www.example.org/abc"),
870 EXPECT_EQ(2, test_loader_
->num_loads());
872 // A different identity because the path is different.
873 application_manager_
->ConnectToService(
874 GURL("http://www.example.org/another_path"), &test_service
);
875 EXPECT_EQ(3, test_loader_
->num_loads());
877 // A different identity because the domain is different.
878 application_manager_
->ConnectToService(
879 GURL("http://www.another_domain.org/abc"), &test_service
);
880 EXPECT_EQ(4, test_loader_
->num_loads());
883 TEST(ApplicationManagerTest2
,
884 MultipleConnectionsToContentHandlerGetSameContentHandlerId
) {
885 base::MessageLoop loop
;
886 const GURL
content_handler_url("http://test.content.handler");
887 const GURL
requestor_url("http://requestor.url");
888 TestContext test_context
;
889 TestDelegate test_delegate
;
890 test_delegate
.set_fetcher_url(GURL("test:test"));
891 test_delegate
.set_create_test_fetcher(true);
892 ApplicationManager
application_manager(&test_delegate
);
893 application_manager
.set_default_loader(nullptr);
894 application_manager
.RegisterContentHandler(kTestMimeType
,
895 content_handler_url
);
897 TestApplicationLoader
* content_handler_loader
= new TestApplicationLoader
;
898 content_handler_loader
->set_create_content_handler(true);
899 content_handler_loader
->set_context(&test_context
);
900 application_manager
.SetLoaderForURL(
901 scoped_ptr
<ApplicationLoader
>(content_handler_loader
),
902 content_handler_url
);
904 uint32_t content_handler_id
;
906 base::RunLoop run_loop
;
907 scoped_ptr
<ConnectToApplicationParams
> params(
908 new ConnectToApplicationParams
);
909 params
->set_originator_identity(Identity(requestor_url
));
910 params
->set_originator_filter(GetPermissiveCapabilityFilter());
911 params
->SetURLInfo(GURL("test:test"));
912 params
->set_filter(GetPermissiveCapabilityFilter());
913 params
->set_connect_callback([&content_handler_id
, &run_loop
](uint32_t t
) {
914 content_handler_id
= t
;
917 application_manager
.ConnectToApplication(params
.Pass());
919 EXPECT_NE(Shell::kInvalidContentHandlerID
, content_handler_id
);
922 uint32_t content_handler_id2
;
924 base::RunLoop run_loop
;
925 scoped_ptr
<ConnectToApplicationParams
> params(
926 new ConnectToApplicationParams
);
927 params
->set_originator_identity(Identity(requestor_url
));
928 params
->set_originator_filter(GetPermissiveCapabilityFilter());
929 params
->SetURLInfo(GURL("test:test"));
930 params
->set_filter(GetPermissiveCapabilityFilter());
931 params
->set_connect_callback([&content_handler_id2
, &run_loop
](uint32_t t
) {
932 content_handler_id2
= t
;
935 application_manager
.ConnectToApplication(params
.Pass());
937 EXPECT_NE(Shell::kInvalidContentHandlerID
, content_handler_id2
);
939 EXPECT_EQ(content_handler_id
, content_handler_id2
);
942 TEST(ApplicationManagerTest2
, DifferedContentHandlersGetDifferentIDs
) {
943 base::MessageLoop loop
;
944 const GURL
content_handler_url("http://test.content.handler");
945 const GURL
requestor_url("http://requestor.url");
946 TestContext test_context
;
947 TestDelegate test_delegate
;
948 test_delegate
.set_fetcher_url(GURL("test:test"));
949 test_delegate
.set_create_test_fetcher(true);
950 ApplicationManager
application_manager(&test_delegate
);
951 application_manager
.set_default_loader(nullptr);
952 application_manager
.RegisterContentHandler(kTestMimeType
,
953 content_handler_url
);
955 TestApplicationLoader
* content_handler_loader
= new TestApplicationLoader
;
956 content_handler_loader
->set_create_content_handler(true);
957 content_handler_loader
->set_context(&test_context
);
958 application_manager
.SetLoaderForURL(
959 scoped_ptr
<ApplicationLoader
>(content_handler_loader
),
960 content_handler_url
);
962 uint32_t content_handler_id
;
964 base::RunLoop run_loop
;
965 scoped_ptr
<ConnectToApplicationParams
> params(
966 new ConnectToApplicationParams
);
967 params
->set_originator_identity(Identity(requestor_url
));
968 params
->set_originator_filter(GetPermissiveCapabilityFilter());
969 params
->SetURLInfo(GURL("test:test"));
970 params
->set_filter(GetPermissiveCapabilityFilter());
971 params
->set_connect_callback([&content_handler_id
, &run_loop
](uint32_t t
) {
972 content_handler_id
= t
;
975 application_manager
.ConnectToApplication(params
.Pass());
977 EXPECT_NE(Shell::kInvalidContentHandlerID
, content_handler_id
);
980 const std::string
mime_type2("test/mime-type2");
981 const GURL
content_handler_url2("http://test.content2.handler");
982 test_delegate
.set_fetcher_url(GURL("test2:test2"));
983 test_delegate
.set_mime_type(mime_type2
);
984 application_manager
.RegisterContentHandler(mime_type2
, content_handler_url2
);
986 TestApplicationLoader
* content_handler_loader2
= new TestApplicationLoader
;
987 content_handler_loader
->set_create_content_handler(true);
988 content_handler_loader
->set_context(&test_context
);
989 application_manager
.SetLoaderForURL(
990 scoped_ptr
<ApplicationLoader
>(content_handler_loader2
),
991 content_handler_url2
);
993 uint32_t content_handler_id2
;
995 base::RunLoop run_loop
;
996 scoped_ptr
<ConnectToApplicationParams
> params(
997 new ConnectToApplicationParams
);
998 params
->set_originator_identity(Identity(requestor_url
));
999 params
->set_originator_filter(GetPermissiveCapabilityFilter());
1000 params
->SetURLInfo(GURL("test2:test2"));
1001 params
->set_filter(GetPermissiveCapabilityFilter());
1002 params
->set_connect_callback([&content_handler_id2
, &run_loop
](uint32_t t
) {
1003 content_handler_id2
= t
;
1006 application_manager
.ConnectToApplication(params
.Pass());
1008 EXPECT_NE(Shell::kInvalidContentHandlerID
, content_handler_id2
);
1010 EXPECT_NE(content_handler_id
, content_handler_id2
);
1013 TEST_F(ApplicationManagerTest
,
1014 ConnectWithNoContentHandlerGetsInvalidContentHandlerId
) {
1015 application_manager_
->SetLoaderForScheme(
1016 scoped_ptr
<ApplicationLoader
>(new TestApplicationLoader
), "test");
1018 uint32_t content_handler_id
= 1u;
1019 scoped_ptr
<ConnectToApplicationParams
> params(new ConnectToApplicationParams
);
1020 params
->SetURLInfo(GURL("test:test"));
1021 params
->set_filter(GetPermissiveCapabilityFilter());
1022 params
->set_connect_callback(
1023 [&content_handler_id
](uint32_t t
) { content_handler_id
= t
; });
1024 application_manager_
->ConnectToApplication(params
.Pass());
1025 EXPECT_EQ(0u, content_handler_id
);
1029 } // namespace shell