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.
5 #include "mandoline/ui/browser/browser.h"
7 #include "base/run_loop.h"
8 #include "components/view_manager/public/cpp/view.h"
9 #include "mandoline/ui/browser/browser_delegate.h"
10 #include "mojo/application/public/cpp/application_connection.h"
11 #include "mojo/application/public/cpp/application_delegate.h"
12 #include "mojo/application/public/cpp/application_impl.h"
13 #include "mojo/application/public/cpp/application_test_base.h"
17 class TestBrowser
: public Browser
{
19 TestBrowser(mojo::ApplicationImpl
* app
, BrowserDelegate
* delegate
)
20 : Browser(app
, delegate
, GURL()) {}
21 ~TestBrowser() override
{}
23 void WaitForOnEmbed() {
26 embed_run_loop_
.reset(new base::RunLoop
);
27 embed_run_loop_
->Run();
28 embed_run_loop_
.reset();
31 mojo::View
* root() { return root_
; }
34 // Overridden from Browser:
35 void OnEmbed(mojo::View
* root
) override
{
36 // Don't call the base class because we don't want to navigate.
40 embed_run_loop_
->Quit();
43 // If non-null we're waiting for OnEmbed() using this RunLoop.
44 scoped_ptr
<base::RunLoop
> embed_run_loop_
;
46 MOJO_DISALLOW_COPY_AND_ASSIGN(TestBrowser
);
49 class BrowserTest
: public mojo::test::ApplicationTestBase
,
50 public mojo::ApplicationDelegate
,
51 public BrowserDelegate
{
55 last_closed_connection_(nullptr),
56 last_browser_closed_(nullptr) {}
58 // Creates a new Browser object.
59 TestBrowser
* CreateBrowser() {
62 TestBrowser
* browser
= new TestBrowser(app_
, this);
63 browsers_
.insert(browser
);
67 TestBrowser
* WaitForBrowserClosed() {
68 if (!last_browser_closed_
) {
69 browser_closed_run_loop_
.reset(new base::RunLoop
);
70 browser_closed_run_loop_
->Run();
71 browser_closed_run_loop_
.reset();
73 TestBrowser
* last_browser
= last_browser_closed_
;
74 last_browser_closed_
= nullptr;
78 // Returns the last ApplicationConnection closed.
79 void* last_closed_connection() {
80 return last_closed_connection_
;
83 // Overridden from ApplicationDelegate:
84 void Initialize(mojo::ApplicationImpl
* app
) override
{
88 void OnWillCloseConnection(mojo::ApplicationConnection
* connection
) override
{
89 // WARNING: DO NOT FOLLOW THIS POINTER. IT WILL BE DESTROYED.
90 last_closed_connection_
= connection
;
93 // ApplicationTestBase:
94 ApplicationDelegate
* GetApplicationDelegate() override
{ return this; }
96 // Overridden from BrowserDelegate:
97 void BrowserClosed(Browser
* browser
) override
{
98 scoped_ptr
<Browser
> browser_owner(browser
);
99 TestBrowser
* test_browser
= static_cast<TestBrowser
*>(browser
);
100 DCHECK_GT(browsers_
.count(test_browser
), 0u);
101 browsers_
.erase(test_browser
);
102 last_browser_closed_
= test_browser
;
103 if (browser_closed_run_loop_
) {
104 browser_owner
.reset();
105 browser_closed_run_loop_
->Quit();
109 void InitUIIfNecessary(Browser
* browser
, mojo::View
* root_view
) override
{}
112 mojo::ApplicationImpl
* app_
;
113 void* last_closed_connection_
;
114 std::set
<TestBrowser
*> browsers_
;
115 TestBrowser
* last_browser_closed_
;
116 scoped_ptr
<base::RunLoop
> browser_closed_run_loop_
;
118 MOJO_DISALLOW_COPY_AND_ASSIGN(BrowserTest
);
121 // This test verifies that closing a Browser closes the associated application
122 // connection with the view manager.
123 TEST_F(BrowserTest
, ClosingBrowserClosesAppConnection
) {
124 Browser
* browser
= CreateBrowser();
125 ASSERT_NE(nullptr, browser
);
126 mojo::ApplicationConnection
* view_manager_connection
=
127 browser
->view_manager_init_
.connection();
128 ASSERT_NE(nullptr, view_manager_connection
);
129 BrowserClosed(browser
);
130 EXPECT_EQ(last_closed_connection(), view_manager_connection
);
133 // This test verifies that we can create two Browsers and each Browser has a
134 // different AppliationConnection and different root view.
135 TEST_F(BrowserTest
, TwoBrowsers
) {
136 TestBrowser
* browser1
= CreateBrowser();
137 mojo::ApplicationConnection
* browser1_connection
=
138 browser1
->view_manager_init_
.connection();
139 ASSERT_NE(nullptr, browser1
);
140 browser1
->WaitForOnEmbed();
142 TestBrowser
* browser2
= CreateBrowser();
143 mojo::ApplicationConnection
* browser2_connection
=
144 browser2
->view_manager_init_
.connection();
145 ASSERT_NE(nullptr, browser2
);
146 browser2
->WaitForOnEmbed();
148 // Verify that we have two different connections to the ViewManager.
149 ASSERT_NE(browser1_connection
, browser2_connection
);
151 // Verify that we have two different root nodes.
152 ASSERT_NE(browser1
->root(), browser2
->root());
154 // Deleting the view manager closes the connection.
155 delete browser1
->root()->view_manager();
156 EXPECT_EQ(browser1
, WaitForBrowserClosed());
158 delete browser2
->root()->view_manager();
159 EXPECT_EQ(browser2
, WaitForBrowserClosed());
162 } // namespace mandoline