OLD | NEW |
| (Empty) |
1 // Copyright 2016 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 "components/mus/ws/test_utils.h" | |
6 | |
7 #include "base/memory/ptr_util.h" | |
8 #include "cc/output/copy_output_request.h" | |
9 #include "components/mus/surfaces/surfaces_state.h" | |
10 #include "components/mus/ws/display_binding.h" | |
11 #include "components/mus/ws/display_manager.h" | |
12 #include "components/mus/ws/server_window_surface_manager_test_api.h" | |
13 #include "components/mus/ws/window_manager_access_policy.h" | |
14 #include "components/mus/ws/window_manager_window_tree_factory.h" | |
15 #include "services/shell/public/interfaces/connector.mojom.h" | |
16 #include "testing/gtest/include/gtest/gtest.h" | |
17 | |
18 namespace mus { | |
19 namespace ws { | |
20 namespace test { | |
21 namespace { | |
22 | |
23 // ----------------------------------------------------------------------------- | |
24 // Empty implementation of PlatformDisplay. | |
25 class TestPlatformDisplay : public PlatformDisplay { | |
26 public: | |
27 explicit TestPlatformDisplay(int32_t* cursor_id_storage) | |
28 : cursor_id_storage_(cursor_id_storage) { | |
29 display_metrics_.size_in_pixels = gfx::Size(400, 300); | |
30 display_metrics_.device_scale_factor = 1.f; | |
31 } | |
32 ~TestPlatformDisplay() override {} | |
33 | |
34 // PlatformDisplay: | |
35 void Init(PlatformDisplayDelegate* delegate) override { | |
36 // It is necessary to tell the delegate about the ViewportMetrics to make | |
37 // sure that the DisplayBinding is correctly initialized (and a root-window | |
38 // is created). | |
39 delegate->OnViewportMetricsChanged(ViewportMetrics(), display_metrics_); | |
40 } | |
41 void SchedulePaint(const ServerWindow* window, | |
42 const gfx::Rect& bounds) override {} | |
43 void SetViewportSize(const gfx::Size& size) override {} | |
44 void SetTitle(const base::string16& title) override {} | |
45 void SetCapture() override {} | |
46 void ReleaseCapture() override {} | |
47 void SetCursorById(int32_t cursor) override { *cursor_id_storage_ = cursor; } | |
48 mojom::Rotation GetRotation() override { return mojom::Rotation::VALUE_0; } | |
49 float GetDeviceScaleFactor() override { | |
50 return display_metrics_.device_scale_factor; | |
51 } | |
52 void UpdateTextInputState(const ui::TextInputState& state) override {} | |
53 void SetImeVisibility(bool visible) override {} | |
54 bool IsFramePending() const override { return false; } | |
55 void RequestCopyOfOutput( | |
56 std::unique_ptr<cc::CopyOutputRequest> output_request) override {} | |
57 int64_t GetDisplayId() const override { return 1; } | |
58 | |
59 private: | |
60 ViewportMetrics display_metrics_; | |
61 | |
62 int32_t* cursor_id_storage_; | |
63 | |
64 DISALLOW_COPY_AND_ASSIGN(TestPlatformDisplay); | |
65 }; | |
66 | |
67 ClientWindowId NextUnusedClientWindowId(WindowTree* tree) { | |
68 ClientWindowId client_id; | |
69 for (ClientSpecificId id = 1;; ++id) { | |
70 // Used the id of the client in the upper bits to simplify things. | |
71 const ClientWindowId client_id = | |
72 ClientWindowId(WindowIdToTransportId(WindowId(tree->id(), id))); | |
73 if (!tree->GetWindowByClientId(client_id)) | |
74 return client_id; | |
75 } | |
76 } | |
77 | |
78 } // namespace | |
79 | |
80 // WindowManagerWindowTreeFactorySetTestApi ------------------------------------ | |
81 | |
82 WindowManagerWindowTreeFactorySetTestApi:: | |
83 WindowManagerWindowTreeFactorySetTestApi( | |
84 WindowManagerWindowTreeFactorySet* | |
85 window_manager_window_tree_factory_set) | |
86 : window_manager_window_tree_factory_set_( | |
87 window_manager_window_tree_factory_set) {} | |
88 | |
89 WindowManagerWindowTreeFactorySetTestApi:: | |
90 ~WindowManagerWindowTreeFactorySetTestApi() {} | |
91 | |
92 void WindowManagerWindowTreeFactorySetTestApi::Add(const UserId& user_id) { | |
93 WindowManagerWindowTreeFactory* factory = | |
94 window_manager_window_tree_factory_set_->Add(user_id, nullptr); | |
95 factory->CreateWindowTree(nullptr, nullptr); | |
96 } | |
97 | |
98 // TestPlatformDisplayFactory ------------------------------------------------- | |
99 | |
100 TestPlatformDisplayFactory::TestPlatformDisplayFactory( | |
101 int32_t* cursor_id_storage) | |
102 : cursor_id_storage_(cursor_id_storage) {} | |
103 | |
104 TestPlatformDisplayFactory::~TestPlatformDisplayFactory() {} | |
105 | |
106 PlatformDisplay* TestPlatformDisplayFactory::CreatePlatformDisplay() { | |
107 return new TestPlatformDisplay(cursor_id_storage_); | |
108 } | |
109 | |
110 // WindowTreeTestApi --------------------------------------------------------- | |
111 | |
112 WindowTreeTestApi::WindowTreeTestApi(WindowTree* tree) : tree_(tree) {} | |
113 WindowTreeTestApi::~WindowTreeTestApi() {} | |
114 | |
115 void WindowTreeTestApi::SetEventObserver(mojom::EventMatcherPtr matcher, | |
116 uint32_t event_observer_id) { | |
117 tree_->SetEventObserver(std::move(matcher), event_observer_id); | |
118 } | |
119 | |
120 // DisplayTestApi ------------------------------------------------------------ | |
121 | |
122 DisplayTestApi::DisplayTestApi(Display* display) : display_(display) {} | |
123 DisplayTestApi::~DisplayTestApi() {} | |
124 | |
125 // EventDispatcherTestApi ---------------------------------------------------- | |
126 | |
127 bool EventDispatcherTestApi::IsWindowPointerTarget( | |
128 const ServerWindow* window) const { | |
129 for (const auto& pair : ed_->pointer_targets_) { | |
130 if (pair.second.window == window) | |
131 return true; | |
132 } | |
133 return false; | |
134 } | |
135 | |
136 int EventDispatcherTestApi::NumberPointerTargetsForWindow( | |
137 ServerWindow* window) { | |
138 int count = 0; | |
139 for (const auto& pair : ed_->pointer_targets_) | |
140 if (pair.second.window == window) | |
141 count++; | |
142 return count; | |
143 } | |
144 | |
145 // TestDisplayBinding --------------------------------------------------------- | |
146 | |
147 WindowTree* TestDisplayBinding::CreateWindowTree(ServerWindow* root) { | |
148 const uint32_t embed_flags = 0; | |
149 WindowTree* tree = window_server_->EmbedAtWindow( | |
150 root, shell::mojom::kRootUserID, mus::mojom::WindowTreeClientPtr(), | |
151 embed_flags, base::WrapUnique(new WindowManagerAccessPolicy)); | |
152 tree->ConfigureWindowManager(); | |
153 return tree; | |
154 } | |
155 | |
156 // TestWindowManager ---------------------------------------------------------- | |
157 | |
158 void TestWindowManager::WmCreateTopLevelWindow( | |
159 uint32_t change_id, | |
160 ClientSpecificId requesting_client_id, | |
161 mojo::Map<mojo::String, mojo::Array<uint8_t>> properties) { | |
162 got_create_top_level_window_ = true; | |
163 change_id_ = change_id; | |
164 } | |
165 | |
166 void TestWindowManager::WmClientJankinessChanged(ClientSpecificId client_id, | |
167 bool janky) {} | |
168 | |
169 void TestWindowManager::OnAccelerator(uint32_t id, | |
170 std::unique_ptr<ui::Event> event) { | |
171 on_accelerator_called_ = true; | |
172 on_accelerator_id_ = id; | |
173 } | |
174 | |
175 // TestWindowTreeClient ------------------------------------------------------- | |
176 | |
177 TestWindowTreeClient::TestWindowTreeClient() | |
178 : binding_(this), record_on_change_completed_(false) {} | |
179 TestWindowTreeClient::~TestWindowTreeClient() {} | |
180 | |
181 void TestWindowTreeClient::Bind( | |
182 mojo::InterfaceRequest<mojom::WindowTreeClient> request) { | |
183 binding_.Bind(std::move(request)); | |
184 } | |
185 | |
186 void TestWindowTreeClient::OnEmbed(uint16_t client_id, | |
187 mojom::WindowDataPtr root, | |
188 mus::mojom::WindowTreePtr tree, | |
189 int64_t display_id, | |
190 Id focused_window_id, | |
191 bool drawn) { | |
192 // TODO(sky): add test coverage of |focused_window_id|. | |
193 tracker_.OnEmbed(client_id, std::move(root), drawn); | |
194 } | |
195 | |
196 void TestWindowTreeClient::OnEmbeddedAppDisconnected(uint32_t window) { | |
197 tracker_.OnEmbeddedAppDisconnected(window); | |
198 } | |
199 | |
200 void TestWindowTreeClient::OnUnembed(Id window_id) { | |
201 tracker_.OnUnembed(window_id); | |
202 } | |
203 | |
204 void TestWindowTreeClient::OnLostCapture(Id window_id) {} | |
205 | |
206 void TestWindowTreeClient::OnTopLevelCreated(uint32_t change_id, | |
207 mojom::WindowDataPtr data, | |
208 int64_t display_id, | |
209 bool drawn) { | |
210 tracker_.OnTopLevelCreated(change_id, std::move(data), drawn); | |
211 } | |
212 | |
213 void TestWindowTreeClient::OnWindowBoundsChanged(uint32_t window, | |
214 const gfx::Rect& old_bounds, | |
215 const gfx::Rect& new_bounds) { | |
216 tracker_.OnWindowBoundsChanged(window, std::move(old_bounds), | |
217 std::move(new_bounds)); | |
218 } | |
219 | |
220 void TestWindowTreeClient::OnClientAreaChanged( | |
221 uint32_t window_id, | |
222 const gfx::Insets& new_client_area, | |
223 mojo::Array<gfx::Rect> new_additional_client_areas) {} | |
224 | |
225 void TestWindowTreeClient::OnTransientWindowAdded( | |
226 uint32_t window_id, | |
227 uint32_t transient_window_id) {} | |
228 | |
229 void TestWindowTreeClient::OnTransientWindowRemoved( | |
230 uint32_t window_id, | |
231 uint32_t transient_window_id) {} | |
232 | |
233 void TestWindowTreeClient::OnWindowHierarchyChanged( | |
234 uint32_t window, | |
235 uint32_t old_parent, | |
236 uint32_t new_parent, | |
237 mojo::Array<mojom::WindowDataPtr> windows) { | |
238 tracker_.OnWindowHierarchyChanged(window, old_parent, new_parent, | |
239 std::move(windows)); | |
240 } | |
241 | |
242 void TestWindowTreeClient::OnWindowReordered(uint32_t window_id, | |
243 uint32_t relative_window_id, | |
244 mojom::OrderDirection direction) { | |
245 tracker_.OnWindowReordered(window_id, relative_window_id, direction); | |
246 } | |
247 | |
248 void TestWindowTreeClient::OnWindowDeleted(uint32_t window) { | |
249 tracker_.OnWindowDeleted(window); | |
250 } | |
251 | |
252 void TestWindowTreeClient::OnWindowVisibilityChanged(uint32_t window, | |
253 bool visible) { | |
254 tracker_.OnWindowVisibilityChanged(window, visible); | |
255 } | |
256 | |
257 void TestWindowTreeClient::OnWindowOpacityChanged(uint32_t window, | |
258 float old_opacity, | |
259 float new_opacity) { | |
260 tracker_.OnWindowOpacityChanged(window, new_opacity); | |
261 } | |
262 | |
263 void TestWindowTreeClient::OnWindowParentDrawnStateChanged(uint32_t window, | |
264 bool drawn) { | |
265 tracker_.OnWindowParentDrawnStateChanged(window, drawn); | |
266 } | |
267 | |
268 void TestWindowTreeClient::OnWindowSharedPropertyChanged( | |
269 uint32_t window, | |
270 const mojo::String& name, | |
271 mojo::Array<uint8_t> new_data) { | |
272 tracker_.OnWindowSharedPropertyChanged(window, name, std::move(new_data)); | |
273 } | |
274 | |
275 void TestWindowTreeClient::OnWindowInputEvent(uint32_t event_id, | |
276 uint32_t window, | |
277 std::unique_ptr<ui::Event> event, | |
278 uint32_t event_observer_id) { | |
279 tracker_.OnWindowInputEvent(window, *event.get(), event_observer_id); | |
280 } | |
281 | |
282 void TestWindowTreeClient::OnEventObserved(std::unique_ptr<ui::Event> event, | |
283 uint32_t event_observer_id) { | |
284 tracker_.OnEventObserved(*event.get(), event_observer_id); | |
285 } | |
286 | |
287 void TestWindowTreeClient::OnWindowFocused(uint32_t focused_window_id) { | |
288 tracker_.OnWindowFocused(focused_window_id); | |
289 } | |
290 | |
291 void TestWindowTreeClient::OnWindowPredefinedCursorChanged( | |
292 uint32_t window_id, | |
293 mojom::Cursor cursor_id) { | |
294 tracker_.OnWindowPredefinedCursorChanged(window_id, cursor_id); | |
295 } | |
296 | |
297 void TestWindowTreeClient::OnChangeCompleted(uint32_t change_id, bool success) { | |
298 if (record_on_change_completed_) | |
299 tracker_.OnChangeCompleted(change_id, success); | |
300 } | |
301 | |
302 void TestWindowTreeClient::RequestClose(uint32_t window_id) {} | |
303 | |
304 void TestWindowTreeClient::GetWindowManager( | |
305 mojo::AssociatedInterfaceRequest<mojom::WindowManager> internal) {} | |
306 | |
307 // TestWindowTreeBinding ------------------------------------------------------ | |
308 | |
309 TestWindowTreeBinding::TestWindowTreeBinding(WindowTree* tree) | |
310 : WindowTreeBinding(&client_), tree_(tree) {} | |
311 TestWindowTreeBinding::~TestWindowTreeBinding() {} | |
312 | |
313 mojom::WindowManager* TestWindowTreeBinding::GetWindowManager() { | |
314 if (!window_manager_.get()) | |
315 window_manager_.reset(new TestWindowManager); | |
316 return window_manager_.get(); | |
317 } | |
318 void TestWindowTreeBinding::SetIncomingMethodCallProcessingPaused(bool paused) { | |
319 is_paused_ = paused; | |
320 } | |
321 | |
322 // TestWindowServerDelegate ---------------------------------------------- | |
323 | |
324 TestWindowServerDelegate::TestWindowServerDelegate() {} | |
325 TestWindowServerDelegate::~TestWindowServerDelegate() {} | |
326 | |
327 Display* TestWindowServerDelegate::AddDisplay() { | |
328 // Display manages its own lifetime. | |
329 Display* display = new Display(window_server_, PlatformDisplayInitParams()); | |
330 display->Init(nullptr); | |
331 return display; | |
332 } | |
333 | |
334 void TestWindowServerDelegate::OnNoMoreDisplays() { | |
335 got_on_no_more_displays_ = true; | |
336 } | |
337 | |
338 std::unique_ptr<WindowTreeBinding> | |
339 TestWindowServerDelegate::CreateWindowTreeBinding( | |
340 BindingType type, | |
341 ws::WindowServer* window_server, | |
342 ws::WindowTree* tree, | |
343 mojom::WindowTreeRequest* tree_request, | |
344 mojom::WindowTreeClientPtr* client) { | |
345 std::unique_ptr<TestWindowTreeBinding> binding( | |
346 new TestWindowTreeBinding(tree)); | |
347 bindings_.push_back(binding.get()); | |
348 return std::move(binding); | |
349 } | |
350 | |
351 void TestWindowServerDelegate::CreateDefaultDisplays() { | |
352 DCHECK(num_displays_to_create_); | |
353 DCHECK(window_server_); | |
354 | |
355 for (int i = 0; i < num_displays_to_create_; ++i) | |
356 AddDisplay(); | |
357 } | |
358 | |
359 bool TestWindowServerDelegate::IsTestConfig() const { | |
360 return true; | |
361 } | |
362 | |
363 // WindowEventTargetingHelper ------------------------------------------------ | |
364 | |
365 WindowEventTargetingHelper::WindowEventTargetingHelper() | |
366 : wm_client_(nullptr), | |
367 cursor_id_(0), | |
368 platform_display_factory_(&cursor_id_), | |
369 display_binding_(nullptr), | |
370 display_(nullptr), | |
371 surfaces_state_(new SurfacesState()), | |
372 window_server_(nullptr) { | |
373 PlatformDisplay::set_factory_for_testing(&platform_display_factory_); | |
374 window_server_.reset( | |
375 new WindowServer(&window_server_delegate_, surfaces_state_)); | |
376 PlatformDisplayInitParams display_init_params; | |
377 display_init_params.surfaces_state = surfaces_state_; | |
378 display_ = new Display(window_server_.get(), display_init_params); | |
379 display_binding_ = new TestDisplayBinding(window_server_.get()); | |
380 display_->Init(base::WrapUnique(display_binding_)); | |
381 wm_client_ = window_server_delegate_.last_client(); | |
382 wm_client_->tracker()->changes()->clear(); | |
383 } | |
384 | |
385 WindowEventTargetingHelper::~WindowEventTargetingHelper() {} | |
386 | |
387 ServerWindow* WindowEventTargetingHelper::CreatePrimaryTree( | |
388 const gfx::Rect& root_window_bounds, | |
389 const gfx::Rect& window_bounds) { | |
390 WindowTree* wm_tree = window_server_->GetTreeWithId(1); | |
391 const ClientWindowId embed_window_id( | |
392 WindowIdToTransportId(WindowId(wm_tree->id(), 1))); | |
393 EXPECT_TRUE(wm_tree->NewWindow(embed_window_id, ServerWindow::Properties())); | |
394 EXPECT_TRUE(wm_tree->SetWindowVisibility(embed_window_id, true)); | |
395 EXPECT_TRUE(wm_tree->AddWindow(FirstRootId(wm_tree), embed_window_id)); | |
396 display_->root_window()->SetBounds(root_window_bounds); | |
397 mojom::WindowTreeClientPtr client; | |
398 mojom::WindowTreeClientRequest client_request = GetProxy(&client); | |
399 wm_client_->Bind(std::move(client_request)); | |
400 const uint32_t embed_flags = 0; | |
401 wm_tree->Embed(embed_window_id, std::move(client), embed_flags); | |
402 ServerWindow* embed_window = wm_tree->GetWindowByClientId(embed_window_id); | |
403 WindowTree* tree1 = window_server_->GetTreeWithRoot(embed_window); | |
404 EXPECT_NE(nullptr, tree1); | |
405 EXPECT_NE(tree1, wm_tree); | |
406 WindowTreeTestApi(tree1).set_user_id(wm_tree->user_id()); | |
407 | |
408 embed_window->SetBounds(window_bounds); | |
409 | |
410 return embed_window; | |
411 } | |
412 | |
413 void WindowEventTargetingHelper::CreateSecondaryTree( | |
414 ServerWindow* embed_window, | |
415 const gfx::Rect& window_bounds, | |
416 TestWindowTreeClient** out_client, | |
417 WindowTree** window_tree, | |
418 ServerWindow** window) { | |
419 WindowTree* tree1 = window_server_->GetTreeWithRoot(embed_window); | |
420 ASSERT_TRUE(tree1 != nullptr); | |
421 const ClientWindowId child1_id( | |
422 WindowIdToTransportId(WindowId(tree1->id(), 1))); | |
423 EXPECT_TRUE(tree1->NewWindow(child1_id, ServerWindow::Properties())); | |
424 ServerWindow* child1 = tree1->GetWindowByClientId(child1_id); | |
425 ASSERT_TRUE(child1); | |
426 EXPECT_TRUE(tree1->AddWindow(ClientWindowIdForWindow(tree1, embed_window), | |
427 child1_id)); | |
428 tree1->GetDisplay(embed_window)->AddActivationParent(embed_window); | |
429 | |
430 child1->SetVisible(true); | |
431 child1->SetBounds(window_bounds); | |
432 EnableHitTest(child1); | |
433 | |
434 TestWindowTreeClient* embed_client = | |
435 window_server_delegate_.last_client(); | |
436 embed_client->tracker()->changes()->clear(); | |
437 wm_client_->tracker()->changes()->clear(); | |
438 | |
439 *out_client = embed_client; | |
440 *window_tree = tree1; | |
441 *window = child1; | |
442 } | |
443 | |
444 void WindowEventTargetingHelper::SetTaskRunner( | |
445 scoped_refptr<base::SingleThreadTaskRunner> task_runner) { | |
446 message_loop_.SetTaskRunner(task_runner); | |
447 } | |
448 | |
449 // ---------------------------------------------------------------------------- | |
450 | |
451 ServerWindow* FirstRoot(WindowTree* tree) { | |
452 return tree->roots().size() == 1u | |
453 ? tree->GetWindow((*tree->roots().begin())->id()) | |
454 : nullptr; | |
455 } | |
456 | |
457 ClientWindowId FirstRootId(WindowTree* tree) { | |
458 ServerWindow* first_root = FirstRoot(tree); | |
459 return first_root ? ClientWindowIdForWindow(tree, first_root) | |
460 : ClientWindowId(); | |
461 } | |
462 | |
463 ClientWindowId ClientWindowIdForWindow(WindowTree* tree, | |
464 const ServerWindow* window) { | |
465 ClientWindowId client_window_id; | |
466 // If window isn't known we'll return 0, which should then error out. | |
467 tree->IsWindowKnown(window, &client_window_id); | |
468 return client_window_id; | |
469 } | |
470 | |
471 ServerWindow* NewWindowInTree(WindowTree* tree, ClientWindowId* client_id) { | |
472 return NewWindowInTreeWithParent(tree, FirstRoot(tree), client_id); | |
473 } | |
474 | |
475 ServerWindow* NewWindowInTreeWithParent(WindowTree* tree, | |
476 ServerWindow* parent, | |
477 ClientWindowId* client_id) { | |
478 if (!parent) | |
479 return nullptr; | |
480 ClientWindowId parent_client_id; | |
481 if (!tree->IsWindowKnown(parent, &parent_client_id)) | |
482 return nullptr; | |
483 ClientWindowId client_window_id = NextUnusedClientWindowId(tree); | |
484 if (!tree->NewWindow(client_window_id, ServerWindow::Properties())) | |
485 return nullptr; | |
486 if (!tree->SetWindowVisibility(client_window_id, true)) | |
487 return nullptr; | |
488 if (!tree->AddWindow(parent_client_id, client_window_id)) | |
489 return nullptr; | |
490 *client_id = client_window_id; | |
491 return tree->GetWindowByClientId(client_window_id); | |
492 } | |
493 | |
494 } // namespace test | |
495 } // namespace ws | |
496 } // namespace mus | |
OLD | NEW |