OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "base/bind.h" | |
6 #include "base/command_line.h" | |
7 #include "base/memory/scoped_vector.h" | |
8 #include "mojo/application_manager/application_manager.h" | |
9 #include "mojo/public/cpp/application/application_delegate.h" | |
10 #include "mojo/public/cpp/application/application_impl.h" | |
11 #include "mojo/public/cpp/application/service_provider_impl.h" | |
12 #include "mojo/public/interfaces/application/service_provider.mojom.h" | |
13 #include "mojo/services/public/cpp/view_manager/types.h" | |
14 #include "mojo/services/public/cpp/view_manager/view.h" | |
15 #include "mojo/services/public/cpp/view_manager/view_manager.h" | |
16 #include "mojo/services/public/cpp/view_manager/view_manager_client_factory.h" | |
17 #include "mojo/services/public/cpp/view_manager/view_manager_delegate.h" | |
18 #include "mojo/services/public/interfaces/view_manager/view_manager.mojom.h" | |
19 #include "mojo/services/public/interfaces/window_manager/window_manager.mojom.h" | |
20 #include "mojo/shell/shell_test_helper.h" | |
21 #include "testing/gtest/include/gtest/gtest.h" | |
22 | |
23 namespace mojo { | |
24 namespace { | |
25 | |
26 const char kTestServiceURL[] = "mojo:test_url"; | |
27 | |
28 void EmptyResultCallback(bool result) {} | |
29 | |
30 class TestWindowManagerClient : public WindowManagerClient { | |
31 public: | |
32 typedef base::Callback<void(Id, Id)> | |
33 TwoNodeCallback; | |
34 | |
35 explicit TestWindowManagerClient(base::RunLoop* run_loop) | |
36 : run_loop_(run_loop) {} | |
37 ~TestWindowManagerClient() override {} | |
38 | |
39 void set_focus_changed_callback(const TwoNodeCallback& callback) { | |
40 focus_changed_callback_ = callback; | |
41 } | |
42 void set_active_window_changed_callback(const TwoNodeCallback& callback) { | |
43 active_window_changed_callback_ = callback; | |
44 } | |
45 | |
46 private: | |
47 // Overridden from WindowManagerClient: | |
48 void OnCaptureChanged(Id old_capture_node_id, | |
49 Id new_capture_node_id) override {} | |
50 void OnFocusChanged(Id old_focused_node_id, Id new_focused_node_id) override { | |
51 if (!focus_changed_callback_.is_null()) | |
52 focus_changed_callback_.Run(old_focused_node_id, new_focused_node_id); | |
53 } | |
54 void OnActiveWindowChanged(Id old_active_window, | |
55 Id new_active_window) override { | |
56 if (!active_window_changed_callback_.is_null()) | |
57 active_window_changed_callback_.Run(old_active_window, new_active_window); | |
58 } | |
59 | |
60 base::RunLoop* run_loop_; | |
61 TwoNodeCallback focus_changed_callback_; | |
62 TwoNodeCallback active_window_changed_callback_; | |
63 | |
64 DISALLOW_COPY_AND_ASSIGN(TestWindowManagerClient); | |
65 }; | |
66 | |
67 class TestApplicationLoader : public ApplicationLoader, | |
68 public ApplicationDelegate, | |
69 public ViewManagerDelegate { | |
70 public: | |
71 typedef base::Callback<void(View*)> RootAddedCallback; | |
72 | |
73 explicit TestApplicationLoader(const RootAddedCallback& root_added_callback) | |
74 : root_added_callback_(root_added_callback) {} | |
75 ~TestApplicationLoader() override {} | |
76 | |
77 private: | |
78 // Overridden from ApplicationLoader: | |
79 void Load(ApplicationManager* application_manager, | |
80 const GURL& url, | |
81 ScopedMessagePipeHandle shell_handle, | |
82 LoadCallback callback) override { | |
83 ASSERT_TRUE(shell_handle.is_valid()); | |
84 scoped_ptr<ApplicationImpl> app( | |
85 new ApplicationImpl(this, shell_handle.Pass())); | |
86 apps_.push_back(app.release()); | |
87 } | |
88 void OnApplicationError(ApplicationManager* application_manager, | |
89 const GURL& url) override {} | |
90 | |
91 // Overridden from ApplicationDelegate: | |
92 void Initialize(ApplicationImpl* app) override { | |
93 view_manager_client_factory_.reset( | |
94 new ViewManagerClientFactory(app->shell(), this)); | |
95 } | |
96 | |
97 bool ConfigureIncomingConnection(ApplicationConnection* connection) override { | |
98 connection->AddService(view_manager_client_factory_.get()); | |
99 return true; | |
100 } | |
101 | |
102 // Overridden from ViewManagerDelegate: | |
103 void OnEmbed(ViewManager* view_manager, | |
104 View* root, | |
105 ServiceProviderImpl* exported_services, | |
106 scoped_ptr<ServiceProvider> imported_services) override { | |
107 root_added_callback_.Run(root); | |
108 } | |
109 void OnViewManagerDisconnected(ViewManager* view_manager) override {} | |
110 | |
111 RootAddedCallback root_added_callback_; | |
112 | |
113 ScopedVector<ApplicationImpl> apps_; | |
114 scoped_ptr<ViewManagerClientFactory> view_manager_client_factory_; | |
115 | |
116 DISALLOW_COPY_AND_ASSIGN(TestApplicationLoader); | |
117 }; | |
118 | |
119 } // namespace | |
120 | |
121 class WindowManagerApiTest : public testing::Test { | |
122 public: | |
123 WindowManagerApiTest() {} | |
124 ~WindowManagerApiTest() override {} | |
125 | |
126 protected: | |
127 typedef std::pair<Id, Id> TwoIds; | |
128 | |
129 Id WaitForEmbed() { | |
130 Id id; | |
131 base::RunLoop run_loop; | |
132 root_added_callback_ = base::Bind(&WindowManagerApiTest::OnEmbed, | |
133 base::Unretained(this), &id, &run_loop); | |
134 run_loop.Run(); | |
135 return id; | |
136 } | |
137 | |
138 TwoIds WaitForFocusChange() { | |
139 TwoIds old_and_new; | |
140 base::RunLoop run_loop; | |
141 window_manager_client()->set_focus_changed_callback( | |
142 base::Bind(&WindowManagerApiTest::OnFocusChanged, | |
143 base::Unretained(this), &old_and_new, &run_loop)); | |
144 run_loop.Run(); | |
145 return old_and_new; | |
146 } | |
147 | |
148 TwoIds WaitForActiveWindowChange() { | |
149 TwoIds old_and_new; | |
150 base::RunLoop run_loop; | |
151 window_manager_client()->set_active_window_changed_callback( | |
152 base::Bind(&WindowManagerApiTest::OnActiveWindowChanged, | |
153 base::Unretained(this), &old_and_new, &run_loop)); | |
154 run_loop.Run(); | |
155 return old_and_new; | |
156 } | |
157 | |
158 Id OpenWindow() { | |
159 return OpenWindowWithURL(kTestServiceURL); | |
160 } | |
161 | |
162 Id OpenWindowWithURL(const std::string& url) { | |
163 base::RunLoop run_loop; | |
164 ServiceProviderPtr sp; | |
165 BindToProxy(new ServiceProviderImpl, &sp); | |
166 window_manager_->Embed( | |
167 url, MakeRequest<ServiceProvider>(sp.PassMessagePipe())); | |
168 run_loop.Run(); | |
169 return WaitForEmbed(); | |
170 } | |
171 | |
172 TestWindowManagerClient* window_manager_client() { | |
173 return window_manager_client_.get(); | |
174 } | |
175 | |
176 WindowManagerPtr window_manager_; | |
177 | |
178 private: | |
179 // Overridden from testing::Test: | |
180 void SetUp() override { | |
181 test_helper_.reset(new shell::ShellTestHelper); | |
182 test_helper_->Init(); | |
183 test_helper_->AddCustomMapping(GURL("mojo:window_manager"), | |
184 GURL("mojo:core_window_manager")); | |
185 test_helper_->SetLoaderForURL( | |
186 scoped_ptr<ApplicationLoader>(new TestApplicationLoader(base::Bind( | |
187 &WindowManagerApiTest::OnRootAdded, base::Unretained(this)))), | |
188 GURL(kTestServiceURL)); | |
189 ConnectToWindowManager2(); | |
190 } | |
191 void TearDown() override {} | |
192 | |
193 void ConnectToWindowManager2() { | |
194 test_helper_->application_manager()->ConnectToService( | |
195 GURL("mojo:window_manager"), &window_manager_); | |
196 base::RunLoop connect_loop; | |
197 window_manager_client_.reset(new TestWindowManagerClient(&connect_loop)); | |
198 window_manager_.set_client(window_manager_client()); | |
199 connect_loop.Run(); | |
200 | |
201 // The RunLoop above ensures the connection to the windowmanager completes. | |
202 // Without this the ApplicationManager would loads the windowmanager twice. | |
203 test_helper_->application_manager()->ConnectToService( | |
204 GURL("mojo:core_window_manager"), &window_manager_); | |
205 } | |
206 | |
207 void OnRootAdded(View* root) { | |
208 if (!root_added_callback_.is_null()) | |
209 root_added_callback_.Run(root); | |
210 } | |
211 | |
212 void OnEmbed(Id* root_id, | |
213 base::RunLoop* loop, | |
214 View* root) { | |
215 *root_id = root->id(); | |
216 loop->Quit(); | |
217 } | |
218 | |
219 void OnFocusChanged(TwoIds* old_and_new, | |
220 base::RunLoop* run_loop, | |
221 Id old_focused_node_id, | |
222 Id new_focused_node_id) { | |
223 DCHECK(old_and_new); | |
224 old_and_new->first = old_focused_node_id; | |
225 old_and_new->second = new_focused_node_id; | |
226 run_loop->Quit(); | |
227 } | |
228 | |
229 void OnActiveWindowChanged(TwoIds* old_and_new, | |
230 base::RunLoop* run_loop, | |
231 Id old_focused_node_id, | |
232 Id new_focused_node_id) { | |
233 DCHECK(old_and_new); | |
234 old_and_new->first = old_focused_node_id; | |
235 old_and_new->second = new_focused_node_id; | |
236 run_loop->Quit(); | |
237 } | |
238 | |
239 scoped_ptr<shell::ShellTestHelper> test_helper_; | |
240 scoped_ptr<TestWindowManagerClient> window_manager_client_; | |
241 TestApplicationLoader::RootAddedCallback root_added_callback_; | |
242 | |
243 DISALLOW_COPY_AND_ASSIGN(WindowManagerApiTest); | |
244 }; | |
245 | |
246 // TODO(sky): resolve this. Temporarily disabled as ApplicationManager ends up | |
247 // loading windowmanager twice because of the mapping of window_manager to | |
248 // core_window_manager. | |
249 TEST_F(WindowManagerApiTest, DISABLED_FocusAndActivateWindow) { | |
250 Id first_window = OpenWindow(); | |
251 window_manager_->FocusWindow(first_window, base::Bind(&EmptyResultCallback)); | |
252 TwoIds ids = WaitForFocusChange(); | |
253 EXPECT_TRUE(ids.first == 0); | |
254 EXPECT_EQ(ids.second, first_window); | |
255 | |
256 Id second_window = OpenWindow(); | |
257 window_manager_->ActivateWindow(second_window, | |
258 base::Bind(&EmptyResultCallback)); | |
259 ids = WaitForActiveWindowChange(); | |
260 EXPECT_EQ(ids.first, first_window); | |
261 EXPECT_EQ(ids.second, second_window); | |
262 } | |
263 | |
264 } // namespace mojo | |
OLD | NEW |