| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <stddef.h> | 5 #include <stddef.h> |
| 6 #include <stdint.h> | 6 #include <stdint.h> |
| 7 | 7 |
| 8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/macros.h" | 10 #include "base/macros.h" |
| 11 #include "base/run_loop.h" | 11 #include "base/run_loop.h" |
| 12 #include "components/mus/common/util.h" | 12 #include "components/mus/common/util.h" |
| 13 #include "components/mus/public/cpp/lib/window_private.h" | 13 #include "components/mus/public/cpp/lib/window_private.h" |
| 14 #include "components/mus/public/cpp/lib/window_tree_client_impl.h" | |
| 15 #include "components/mus/public/cpp/tests/window_server_test_base.h" | 14 #include "components/mus/public/cpp/tests/window_server_test_base.h" |
| 16 #include "components/mus/public/cpp/window_observer.h" | 15 #include "components/mus/public/cpp/window_observer.h" |
| 17 #include "components/mus/public/cpp/window_tree_connection.h" | 16 #include "components/mus/public/cpp/window_tree_client.h" |
| 18 #include "components/mus/public/cpp/window_tree_connection_observer.h" | 17 #include "components/mus/public/cpp/window_tree_client_delegate.h" |
| 19 #include "components/mus/public/cpp/window_tree_delegate.h" | 18 #include "components/mus/public/cpp/window_tree_client_observer.h" |
| 20 #include "ui/gfx/geometry/rect.h" | 19 #include "ui/gfx/geometry/rect.h" |
| 21 | 20 |
| 22 namespace mus { | 21 namespace mus { |
| 23 namespace ws { | 22 namespace ws { |
| 24 | 23 |
| 25 namespace { | 24 namespace { |
| 26 | 25 |
| 27 Id server_id(mus::Window* window) { | 26 Id server_id(mus::Window* window) { |
| 28 return WindowPrivate(window).server_id(); | 27 return WindowPrivate(window).server_id(); |
| 29 } | 28 } |
| 30 | 29 |
| 31 mus::Window* GetChildWindowByServerId(WindowTreeConnection* connection, | 30 mus::Window* GetChildWindowByServerId(WindowTreeClient* client, |
| 32 uint32_t id) { | 31 uint32_t id) { |
| 33 return static_cast<WindowTreeClientImpl*>(connection) | 32 return client->GetWindowByServerId(id); |
| 34 ->GetWindowByServerId(id); | |
| 35 } | 33 } |
| 36 | 34 |
| 37 int ValidIndexOf(const Window::Children& windows, Window* window) { | 35 int ValidIndexOf(const Window::Children& windows, Window* window) { |
| 38 Window::Children::const_iterator it = | 36 Window::Children::const_iterator it = |
| 39 std::find(windows.begin(), windows.end(), window); | 37 std::find(windows.begin(), windows.end(), window); |
| 40 return (it != windows.end()) ? (it - windows.begin()) : -1; | 38 return (it != windows.end()) ? (it - windows.begin()) : -1; |
| 41 } | 39 } |
| 42 | 40 |
| 43 class TestWindowManagerDelegate : public WindowManagerDelegate { | 41 class TestWindowManagerDelegate : public WindowManagerDelegate { |
| 44 public: | 42 public: |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 183 EXPECT_TRUE(WindowServerTestBase::QuitRunLoop()); | 181 EXPECT_TRUE(WindowServerTestBase::QuitRunLoop()); |
| 184 } | 182 } |
| 185 | 183 |
| 186 Window* window_; | 184 Window* window_; |
| 187 | 185 |
| 188 DISALLOW_COPY_AND_ASSIGN(OrderChangeObserver); | 186 DISALLOW_COPY_AND_ASSIGN(OrderChangeObserver); |
| 189 }; | 187 }; |
| 190 | 188 |
| 191 // Wait until |window|'s tree size matches |tree_size|; returns false on | 189 // Wait until |window|'s tree size matches |tree_size|; returns false on |
| 192 // timeout. | 190 // timeout. |
| 193 bool WaitForOrderChange(WindowTreeConnection* connection, Window* window) { | 191 bool WaitForOrderChange(WindowTreeClient* client, Window* window) { |
| 194 OrderChangeObserver observer(window); | 192 OrderChangeObserver observer(window); |
| 195 return WindowServerTestBase::DoRunLoopWithTimeout(); | 193 return WindowServerTestBase::DoRunLoopWithTimeout(); |
| 196 } | 194 } |
| 197 | 195 |
| 198 // Tracks a window's destruction. Query is_valid() for current state. | 196 // Tracks a window's destruction. Query is_valid() for current state. |
| 199 class WindowTracker : public WindowObserver { | 197 class WindowTracker : public WindowObserver { |
| 200 public: | 198 public: |
| 201 explicit WindowTracker(Window* window) : window_(window) { | 199 explicit WindowTracker(Window* window) : window_(window) { |
| 202 window_->AddObserver(this); | 200 window_->AddObserver(this); |
| 203 } | 201 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 219 | 217 |
| 220 DISALLOW_COPY_AND_ASSIGN(WindowTracker); | 218 DISALLOW_COPY_AND_ASSIGN(WindowTracker); |
| 221 }; | 219 }; |
| 222 | 220 |
| 223 } // namespace | 221 } // namespace |
| 224 | 222 |
| 225 // WindowServer | 223 // WindowServer |
| 226 // ----------------------------------------------------------------- | 224 // ----------------------------------------------------------------- |
| 227 | 225 |
| 228 struct EmbedResult { | 226 struct EmbedResult { |
| 229 EmbedResult(WindowTreeConnection* connection, ClientSpecificId id) | 227 EmbedResult(WindowTreeClient* client, ClientSpecificId id) |
| 230 : connection(connection), client_id(id) {} | 228 : client(client), client_id(id) {} |
| 231 EmbedResult() : connection(nullptr), client_id(0) {} | 229 EmbedResult() : client(nullptr), client_id(0) {} |
| 232 | 230 |
| 233 WindowTreeConnection* connection; | 231 WindowTreeClient* client; |
| 234 | 232 |
| 235 // The id supplied to the callback from OnEmbed(). Depending upon the | 233 // The id supplied to the callback from OnEmbed(). Depending upon the |
| 236 // access policy this may or may not match the client id of | 234 // access policy this may or may not match the client id of |
| 237 // |connection|. | 235 // |client|. |
| 238 ClientSpecificId client_id; | 236 ClientSpecificId client_id; |
| 239 }; | 237 }; |
| 240 | 238 |
| 241 Window* GetFirstRoot(WindowTreeConnection* connection) { | 239 Window* GetFirstRoot(WindowTreeClient* client) { |
| 242 return connection->GetRoots().empty() ? nullptr | 240 return client->GetRoots().empty() ? nullptr : *client->GetRoots().begin(); |
| 243 : *connection->GetRoots().begin(); | |
| 244 } | 241 } |
| 245 | 242 |
| 246 // These tests model synchronization of two peer connections to the window | 243 // These tests model synchronization of two peer clients of the window server, |
| 247 // manager | 244 // that are given access to some root window. |
| 248 // service, that are given access to some root window. | |
| 249 | 245 |
| 250 class WindowServerTest : public WindowServerTestBase { | 246 class WindowServerTest : public WindowServerTestBase { |
| 251 public: | 247 public: |
| 252 WindowServerTest() {} | 248 WindowServerTest() {} |
| 253 | 249 |
| 254 Window* GetFirstWMRoot() { return GetFirstRoot(window_manager()); } | 250 Window* GetFirstWMRoot() { return GetFirstRoot(window_manager()); } |
| 255 | 251 |
| 256 Window* NewVisibleWindow(Window* parent, WindowTreeConnection* connection) { | 252 Window* NewVisibleWindow(Window* parent, WindowTreeClient* client) { |
| 257 Window* window = connection->NewWindow(); | 253 Window* window = client->NewWindow(); |
| 258 window->SetVisible(true); | 254 window->SetVisible(true); |
| 259 parent->AddChild(window); | 255 parent->AddChild(window); |
| 260 return window; | 256 return window; |
| 261 } | 257 } |
| 262 | 258 |
| 263 // Embeds another version of the test app @ window. This runs a run loop until | 259 // Embeds another version of the test app @ window. This runs a run loop until |
| 264 // a response is received, or a timeout. On success the new WindowServer is | 260 // a response is received, or a timeout. On success the new WindowServer is |
| 265 // returned. | 261 // returned. |
| 266 EmbedResult Embed(Window* window) { | 262 EmbedResult Embed(Window* window) { |
| 267 DCHECK(!embed_details_); | 263 DCHECK(!embed_details_); |
| 268 embed_details_.reset(new EmbedDetails); | 264 embed_details_.reset(new EmbedDetails); |
| 269 window->Embed(ConnectAndGetWindowServerClient(), | 265 window->Embed(ConnectAndGetWindowServerClient(), |
| 270 base::Bind(&WindowServerTest::EmbedCallbackImpl, | 266 base::Bind(&WindowServerTest::EmbedCallbackImpl, |
| 271 base::Unretained(this))); | 267 base::Unretained(this))); |
| 272 embed_details_->waiting = true; | 268 embed_details_->waiting = true; |
| 273 if (!WindowServerTestBase::DoRunLoopWithTimeout()) | 269 if (!WindowServerTestBase::DoRunLoopWithTimeout()) |
| 274 return EmbedResult(); | 270 return EmbedResult(); |
| 275 const EmbedResult result(embed_details_->connection, | 271 const EmbedResult result(embed_details_->client, |
| 276 embed_details_->client_id); | 272 embed_details_->client_id); |
| 277 embed_details_.reset(); | 273 embed_details_.reset(); |
| 278 return result; | 274 return result; |
| 279 } | 275 } |
| 280 | 276 |
| 281 // Establishes a connection to this application and asks for a | 277 // Establishes a connection to this application and asks for a |
| 282 // WindowTreeClient. | 278 // WindowTreeClient. |
| 283 mus::mojom::WindowTreeClientPtr ConnectAndGetWindowServerClient() { | 279 mus::mojom::WindowTreeClientPtr ConnectAndGetWindowServerClient() { |
| 284 mus::mojom::WindowTreeClientPtr client; | 280 mus::mojom::WindowTreeClientPtr client; |
| 285 connector()->ConnectToInterface(test_name(), &client); | 281 connector()->ConnectToInterface(test_name(), &client); |
| 286 return client; | 282 return client; |
| 287 } | 283 } |
| 288 | 284 |
| 289 // WindowServerTestBase: | 285 // WindowServerTestBase: |
| 290 void OnEmbed(Window* root) override { | 286 void OnEmbed(Window* root) override { |
| 291 if (!embed_details_) { | 287 if (!embed_details_) { |
| 292 WindowServerTestBase::OnEmbed(root); | 288 WindowServerTestBase::OnEmbed(root); |
| 293 return; | 289 return; |
| 294 } | 290 } |
| 295 | 291 |
| 296 embed_details_->connection = root->connection(); | 292 embed_details_->client = root->window_tree(); |
| 297 if (embed_details_->callback_run) | 293 if (embed_details_->callback_run) |
| 298 EXPECT_TRUE(WindowServerTestBase::QuitRunLoop()); | 294 EXPECT_TRUE(WindowServerTestBase::QuitRunLoop()); |
| 299 } | 295 } |
| 300 | 296 |
| 301 private: | 297 private: |
| 302 // Used to track the state of a call to window->Embed(). | 298 // Used to track the state of a call to window->Embed(). |
| 303 struct EmbedDetails { | 299 struct EmbedDetails { |
| 304 EmbedDetails() | 300 EmbedDetails() |
| 305 : callback_run(false), | 301 : callback_run(false), |
| 306 result(false), | 302 result(false), |
| 307 waiting(false), | 303 waiting(false), |
| 308 connection(nullptr) {} | 304 client(nullptr) {} |
| 309 | 305 |
| 310 // The callback supplied to Embed() was received. | 306 // The callback supplied to Embed() was received. |
| 311 bool callback_run; | 307 bool callback_run; |
| 312 | 308 |
| 313 // The boolean supplied to the Embed() callback. | 309 // The boolean supplied to the Embed() callback. |
| 314 bool result; | 310 bool result; |
| 315 | 311 |
| 316 // Whether a MessageLoop is running. | 312 // Whether a MessageLoop is running. |
| 317 bool waiting; | 313 bool waiting; |
| 318 | 314 |
| 319 // Client id supplied to the Embed() callback. | 315 // Client id supplied to the Embed() callback. |
| 320 ClientSpecificId client_id; | 316 ClientSpecificId client_id; |
| 321 | 317 |
| 322 // The WindowTreeConnection that resulted from the Embed(). null if |result| | 318 // The WindowTreeClient that resulted from the Embed(). null if |result| is |
| 323 // is false. | 319 // false. |
| 324 WindowTreeConnection* connection; | 320 WindowTreeClient* client; |
| 325 }; | 321 }; |
| 326 | 322 |
| 327 void EmbedCallbackImpl(bool result) { | 323 void EmbedCallbackImpl(bool result) { |
| 328 embed_details_->callback_run = true; | 324 embed_details_->callback_run = true; |
| 329 embed_details_->result = result; | 325 embed_details_->result = result; |
| 330 if (embed_details_->waiting && (!result || embed_details_->connection)) | 326 if (embed_details_->waiting && (!result || embed_details_->client)) |
| 331 EXPECT_TRUE(WindowServerTestBase::QuitRunLoop()); | 327 EXPECT_TRUE(WindowServerTestBase::QuitRunLoop()); |
| 332 } | 328 } |
| 333 | 329 |
| 334 std::unique_ptr<EmbedDetails> embed_details_; | 330 std::unique_ptr<EmbedDetails> embed_details_; |
| 335 | 331 |
| 336 DISALLOW_COPY_AND_ASSIGN(WindowServerTest); | 332 DISALLOW_COPY_AND_ASSIGN(WindowServerTest); |
| 337 }; | 333 }; |
| 338 | 334 |
| 339 TEST_F(WindowServerTest, RootWindow) { | 335 TEST_F(WindowServerTest, RootWindow) { |
| 340 ASSERT_NE(nullptr, window_manager()); | 336 ASSERT_NE(nullptr, window_manager()); |
| 341 EXPECT_EQ(1u, window_manager()->GetRoots().size()); | 337 EXPECT_EQ(1u, window_manager()->GetRoots().size()); |
| 342 } | 338 } |
| 343 | 339 |
| 344 TEST_F(WindowServerTest, Embed) { | 340 TEST_F(WindowServerTest, Embed) { |
| 345 Window* window = window_manager()->NewWindow(); | 341 Window* window = window_manager()->NewWindow(); |
| 346 ASSERT_NE(nullptr, window); | 342 ASSERT_NE(nullptr, window); |
| 347 window->SetVisible(true); | 343 window->SetVisible(true); |
| 348 GetFirstWMRoot()->AddChild(window); | 344 GetFirstWMRoot()->AddChild(window); |
| 349 WindowTreeConnection* embedded = Embed(window).connection; | 345 WindowTreeClient* embedded = Embed(window).client; |
| 350 ASSERT_NE(nullptr, embedded); | 346 ASSERT_NE(nullptr, embedded); |
| 351 | 347 |
| 352 Window* window_in_embedded = GetFirstRoot(embedded); | 348 Window* window_in_embedded = GetFirstRoot(embedded); |
| 353 ASSERT_NE(nullptr, window_in_embedded); | 349 ASSERT_NE(nullptr, window_in_embedded); |
| 354 EXPECT_EQ(server_id(window), server_id(window_in_embedded)); | 350 EXPECT_EQ(server_id(window), server_id(window_in_embedded)); |
| 355 EXPECT_EQ(nullptr, window_in_embedded->parent()); | 351 EXPECT_EQ(nullptr, window_in_embedded->parent()); |
| 356 EXPECT_TRUE(window_in_embedded->children().empty()); | 352 EXPECT_TRUE(window_in_embedded->children().empty()); |
| 357 } | 353 } |
| 358 | 354 |
| 359 // Window manager has two windows, N1 and N11. Embeds A at N1. A should not see | 355 // Window manager has two windows, N1 and N11. Embeds A at N1. A should not see |
| 360 // N11. | 356 // N11. |
| 361 TEST_F(WindowServerTest, EmbeddedDoesntSeeChild) { | 357 TEST_F(WindowServerTest, EmbeddedDoesntSeeChild) { |
| 362 Window* window = window_manager()->NewWindow(); | 358 Window* window = window_manager()->NewWindow(); |
| 363 ASSERT_NE(nullptr, window); | 359 ASSERT_NE(nullptr, window); |
| 364 window->SetVisible(true); | 360 window->SetVisible(true); |
| 365 GetFirstWMRoot()->AddChild(window); | 361 GetFirstWMRoot()->AddChild(window); |
| 366 Window* nested = window_manager()->NewWindow(); | 362 Window* nested = window_manager()->NewWindow(); |
| 367 ASSERT_NE(nullptr, nested); | 363 ASSERT_NE(nullptr, nested); |
| 368 nested->SetVisible(true); | 364 nested->SetVisible(true); |
| 369 window->AddChild(nested); | 365 window->AddChild(nested); |
| 370 | 366 |
| 371 WindowTreeConnection* embedded = Embed(window).connection; | 367 WindowTreeClient* embedded = Embed(window).client; |
| 372 ASSERT_NE(nullptr, embedded); | 368 ASSERT_NE(nullptr, embedded); |
| 373 Window* window_in_embedded = GetFirstRoot(embedded); | 369 Window* window_in_embedded = GetFirstRoot(embedded); |
| 374 EXPECT_EQ(server_id(window), server_id(window_in_embedded)); | 370 EXPECT_EQ(server_id(window), server_id(window_in_embedded)); |
| 375 EXPECT_EQ(nullptr, window_in_embedded->parent()); | 371 EXPECT_EQ(nullptr, window_in_embedded->parent()); |
| 376 EXPECT_TRUE(window_in_embedded->children().empty()); | 372 EXPECT_TRUE(window_in_embedded->children().empty()); |
| 377 } | 373 } |
| 378 | 374 |
| 379 // TODO(beng): write a replacement test for the one that once existed here: | 375 // TODO(beng): write a replacement test for the one that once existed here: |
| 380 // This test validates the following scenario: | 376 // This test validates the following scenario: |
| 381 // - a window originating from one connection | 377 // - a window originating from one client |
| 382 // - a window originating from a second connection | 378 // - a window originating from a second client |
| 383 // + the connection originating the window is destroyed | 379 // + the client originating the window is destroyed |
| 384 // -> the window should still exist (since the second connection is live) but | 380 // -> the window should still exist (since the second client is live) but |
| 385 // should be disconnected from any windows. | 381 // should be disconnected from any windows. |
| 386 // http://crbug.com/396300 | 382 // http://crbug.com/396300 |
| 387 // | 383 // |
| 388 // TODO(beng): The new test should validate the scenario as described above | 384 // TODO(beng): The new test should validate the scenario as described above |
| 389 // except that the second connection still has a valid tree. | 385 // except that the second client still has a valid tree. |
| 390 | 386 |
| 391 // Verifies that bounds changes applied to a window hierarchy in one connection | 387 // Verifies that bounds changes applied to a window hierarchy in one client |
| 392 // are reflected to another. | 388 // are reflected to another. |
| 393 TEST_F(WindowServerTest, SetBounds) { | 389 TEST_F(WindowServerTest, SetBounds) { |
| 394 Window* window = window_manager()->NewWindow(); | 390 Window* window = window_manager()->NewWindow(); |
| 395 window->SetVisible(true); | 391 window->SetVisible(true); |
| 396 GetFirstWMRoot()->AddChild(window); | 392 GetFirstWMRoot()->AddChild(window); |
| 397 WindowTreeConnection* embedded = Embed(window).connection; | 393 WindowTreeClient* embedded = Embed(window).client; |
| 398 ASSERT_NE(nullptr, embedded); | 394 ASSERT_NE(nullptr, embedded); |
| 399 | 395 |
| 400 Window* window_in_embedded = | 396 Window* window_in_embedded = |
| 401 GetChildWindowByServerId(embedded, server_id(window)); | 397 GetChildWindowByServerId(embedded, server_id(window)); |
| 402 EXPECT_EQ(window->bounds(), window_in_embedded->bounds()); | 398 EXPECT_EQ(window->bounds(), window_in_embedded->bounds()); |
| 403 | 399 |
| 404 window->SetBounds(gfx::Rect(0, 0, 100, 100)); | 400 window->SetBounds(gfx::Rect(0, 0, 100, 100)); |
| 405 ASSERT_TRUE(WaitForBoundsToChange(window_in_embedded)); | 401 ASSERT_TRUE(WaitForBoundsToChange(window_in_embedded)); |
| 406 EXPECT_TRUE(window->bounds() == window_in_embedded->bounds()); | 402 EXPECT_TRUE(window->bounds() == window_in_embedded->bounds()); |
| 407 } | 403 } |
| 408 | 404 |
| 409 // Verifies that bounds changes applied to a window owned by a different | 405 // Verifies that bounds changes applied to a window owned by a different |
| 410 // connection can be refused. | 406 // client can be refused. |
| 411 TEST_F(WindowServerTest, SetBoundsSecurity) { | 407 TEST_F(WindowServerTest, SetBoundsSecurity) { |
| 412 TestWindowManagerDelegate wm_delegate; | 408 TestWindowManagerDelegate wm_delegate; |
| 413 set_window_manager_delegate(&wm_delegate); | 409 set_window_manager_delegate(&wm_delegate); |
| 414 | 410 |
| 415 Window* window = window_manager()->NewWindow(); | 411 Window* window = window_manager()->NewWindow(); |
| 416 window->SetVisible(true); | 412 window->SetVisible(true); |
| 417 GetFirstWMRoot()->AddChild(window); | 413 GetFirstWMRoot()->AddChild(window); |
| 418 WindowTreeConnection* embedded = Embed(window).connection; | 414 WindowTreeClient* embedded = Embed(window).client; |
| 419 ASSERT_NE(nullptr, embedded); | 415 ASSERT_NE(nullptr, embedded); |
| 420 | 416 |
| 421 Window* window_in_embedded = | 417 Window* window_in_embedded = |
| 422 GetChildWindowByServerId(embedded, server_id(window)); | 418 GetChildWindowByServerId(embedded, server_id(window)); |
| 423 window->SetBounds(gfx::Rect(0, 0, 800, 600)); | 419 window->SetBounds(gfx::Rect(0, 0, 800, 600)); |
| 424 ASSERT_TRUE(WaitForBoundsToChange(window_in_embedded)); | 420 ASSERT_TRUE(WaitForBoundsToChange(window_in_embedded)); |
| 425 | 421 |
| 426 window_in_embedded->SetBounds(gfx::Rect(0, 0, 1024, 768)); | 422 window_in_embedded->SetBounds(gfx::Rect(0, 0, 1024, 768)); |
| 427 // Bounds change is initially accepted, but the server declines the request. | 423 // Bounds change is initially accepted, but the server declines the request. |
| 428 EXPECT_FALSE(window->bounds() == window_in_embedded->bounds()); | 424 EXPECT_FALSE(window->bounds() == window_in_embedded->bounds()); |
| 429 | 425 |
| 430 // The client is notified when the requested is declined, and updates the | 426 // The client is notified when the requested is declined, and updates the |
| 431 // local bounds accordingly. | 427 // local bounds accordingly. |
| 432 ASSERT_TRUE(WaitForBoundsToChange(window_in_embedded)); | 428 ASSERT_TRUE(WaitForBoundsToChange(window_in_embedded)); |
| 433 EXPECT_TRUE(window->bounds() == window_in_embedded->bounds()); | 429 EXPECT_TRUE(window->bounds() == window_in_embedded->bounds()); |
| 434 set_window_manager_delegate(nullptr); | 430 set_window_manager_delegate(nullptr); |
| 435 } | 431 } |
| 436 | 432 |
| 437 // Verifies that a root window can always be destroyed. | 433 // Verifies that a root window can always be destroyed. |
| 438 TEST_F(WindowServerTest, DestroySecurity) { | 434 TEST_F(WindowServerTest, DestroySecurity) { |
| 439 Window* window = window_manager()->NewWindow(); | 435 Window* window = window_manager()->NewWindow(); |
| 440 window->SetVisible(true); | 436 window->SetVisible(true); |
| 441 GetFirstWMRoot()->AddChild(window); | 437 GetFirstWMRoot()->AddChild(window); |
| 442 | 438 |
| 443 WindowTreeConnection* embedded = Embed(window).connection; | 439 WindowTreeClient* embedded = Embed(window).client; |
| 444 ASSERT_NE(nullptr, embedded); | 440 ASSERT_NE(nullptr, embedded); |
| 445 | 441 |
| 446 // The root can be destroyed, even though it was not created by the | 442 // The root can be destroyed, even though it was not created by the client. |
| 447 // connection. | |
| 448 Window* embed_root = GetChildWindowByServerId(embedded, server_id(window)); | 443 Window* embed_root = GetChildWindowByServerId(embedded, server_id(window)); |
| 449 WindowTracker tracker1(window); | 444 WindowTracker tracker1(window); |
| 450 WindowTracker tracker2(embed_root); | 445 WindowTracker tracker2(embed_root); |
| 451 embed_root->Destroy(); | 446 embed_root->Destroy(); |
| 452 EXPECT_FALSE(tracker2.is_valid()); | 447 EXPECT_FALSE(tracker2.is_valid()); |
| 453 EXPECT_TRUE(tracker1.is_valid()); | 448 EXPECT_TRUE(tracker1.is_valid()); |
| 454 | 449 |
| 455 window->Destroy(); | 450 window->Destroy(); |
| 456 EXPECT_FALSE(tracker1.is_valid()); | 451 EXPECT_FALSE(tracker1.is_valid()); |
| 457 } | 452 } |
| 458 | 453 |
| 459 TEST_F(WindowServerTest, MultiRoots) { | 454 TEST_F(WindowServerTest, MultiRoots) { |
| 460 Window* window1 = window_manager()->NewWindow(); | 455 Window* window1 = window_manager()->NewWindow(); |
| 461 window1->SetVisible(true); | 456 window1->SetVisible(true); |
| 462 GetFirstWMRoot()->AddChild(window1); | 457 GetFirstWMRoot()->AddChild(window1); |
| 463 Window* window2 = window_manager()->NewWindow(); | 458 Window* window2 = window_manager()->NewWindow(); |
| 464 window2->SetVisible(true); | 459 window2->SetVisible(true); |
| 465 GetFirstWMRoot()->AddChild(window2); | 460 GetFirstWMRoot()->AddChild(window2); |
| 466 WindowTreeConnection* embedded1 = Embed(window1).connection; | 461 WindowTreeClient* embedded1 = Embed(window1).client; |
| 467 ASSERT_NE(nullptr, embedded1); | 462 ASSERT_NE(nullptr, embedded1); |
| 468 WindowTreeConnection* embedded2 = Embed(window2).connection; | 463 WindowTreeClient* embedded2 = Embed(window2).client; |
| 469 ASSERT_NE(nullptr, embedded2); | 464 ASSERT_NE(nullptr, embedded2); |
| 470 EXPECT_NE(embedded1, embedded2); | 465 EXPECT_NE(embedded1, embedded2); |
| 471 } | 466 } |
| 472 | 467 |
| 473 TEST_F(WindowServerTest, Reorder) { | 468 TEST_F(WindowServerTest, Reorder) { |
| 474 Window* window1 = window_manager()->NewWindow(); | 469 Window* window1 = window_manager()->NewWindow(); |
| 475 window1->SetVisible(true); | 470 window1->SetVisible(true); |
| 476 GetFirstWMRoot()->AddChild(window1); | 471 GetFirstWMRoot()->AddChild(window1); |
| 477 | 472 |
| 478 WindowTreeConnection* embedded = Embed(window1).connection; | 473 WindowTreeClient* embedded = Embed(window1).client; |
| 479 ASSERT_NE(nullptr, embedded); | 474 ASSERT_NE(nullptr, embedded); |
| 480 | 475 |
| 481 Window* window11 = embedded->NewWindow(); | 476 Window* window11 = embedded->NewWindow(); |
| 482 window11->SetVisible(true); | 477 window11->SetVisible(true); |
| 483 GetFirstRoot(embedded)->AddChild(window11); | 478 GetFirstRoot(embedded)->AddChild(window11); |
| 484 Window* window12 = embedded->NewWindow(); | 479 Window* window12 = embedded->NewWindow(); |
| 485 window12->SetVisible(true); | 480 window12->SetVisible(true); |
| 486 GetFirstRoot(embedded)->AddChild(window12); | 481 GetFirstRoot(embedded)->AddChild(window12); |
| 487 ASSERT_TRUE(WaitForTreeSizeToMatch(window1, 3u)); | 482 ASSERT_TRUE(WaitForTreeSizeToMatch(window1, 3u)); |
| 488 | 483 |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 553 }; | 548 }; |
| 554 | 549 |
| 555 } // namespace | 550 } // namespace |
| 556 | 551 |
| 557 TEST_F(WindowServerTest, Visible) { | 552 TEST_F(WindowServerTest, Visible) { |
| 558 Window* window1 = window_manager()->NewWindow(); | 553 Window* window1 = window_manager()->NewWindow(); |
| 559 window1->SetVisible(true); | 554 window1->SetVisible(true); |
| 560 GetFirstWMRoot()->AddChild(window1); | 555 GetFirstWMRoot()->AddChild(window1); |
| 561 | 556 |
| 562 // Embed another app and verify initial state. | 557 // Embed another app and verify initial state. |
| 563 WindowTreeConnection* embedded = Embed(window1).connection; | 558 WindowTreeClient* embedded = Embed(window1).client; |
| 564 ASSERT_NE(nullptr, embedded); | 559 ASSERT_NE(nullptr, embedded); |
| 565 ASSERT_NE(nullptr, GetFirstRoot(embedded)); | 560 ASSERT_NE(nullptr, GetFirstRoot(embedded)); |
| 566 Window* embedded_root = GetFirstRoot(embedded); | 561 Window* embedded_root = GetFirstRoot(embedded); |
| 567 EXPECT_TRUE(embedded_root->visible()); | 562 EXPECT_TRUE(embedded_root->visible()); |
| 568 EXPECT_TRUE(embedded_root->IsDrawn()); | 563 EXPECT_TRUE(embedded_root->IsDrawn()); |
| 569 | 564 |
| 570 // Change the visible state from the first connection and verify its mirrored | 565 // Change the visible state from the first client and verify its mirrored |
| 571 // correctly to the embedded app. | 566 // correctly to the embedded app. |
| 572 { | 567 { |
| 573 VisibilityChangeObserver observer(embedded_root); | 568 VisibilityChangeObserver observer(embedded_root); |
| 574 window1->SetVisible(false); | 569 window1->SetVisible(false); |
| 575 ASSERT_TRUE(WindowServerTestBase::DoRunLoopWithTimeout()); | 570 ASSERT_TRUE(WindowServerTestBase::DoRunLoopWithTimeout()); |
| 576 } | 571 } |
| 577 | 572 |
| 578 EXPECT_FALSE(window1->visible()); | 573 EXPECT_FALSE(window1->visible()); |
| 579 EXPECT_FALSE(window1->IsDrawn()); | 574 EXPECT_FALSE(window1->IsDrawn()); |
| 580 | 575 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 617 }; | 612 }; |
| 618 | 613 |
| 619 } // namespace | 614 } // namespace |
| 620 | 615 |
| 621 TEST_F(WindowServerTest, Drawn) { | 616 TEST_F(WindowServerTest, Drawn) { |
| 622 Window* window1 = window_manager()->NewWindow(); | 617 Window* window1 = window_manager()->NewWindow(); |
| 623 window1->SetVisible(true); | 618 window1->SetVisible(true); |
| 624 GetFirstWMRoot()->AddChild(window1); | 619 GetFirstWMRoot()->AddChild(window1); |
| 625 | 620 |
| 626 // Embed another app and verify initial state. | 621 // Embed another app and verify initial state. |
| 627 WindowTreeConnection* embedded = Embed(window1).connection; | 622 WindowTreeClient* embedded = Embed(window1).client; |
| 628 ASSERT_NE(nullptr, embedded); | 623 ASSERT_NE(nullptr, embedded); |
| 629 ASSERT_NE(nullptr, GetFirstRoot(embedded)); | 624 ASSERT_NE(nullptr, GetFirstRoot(embedded)); |
| 630 Window* embedded_root = GetFirstRoot(embedded); | 625 Window* embedded_root = GetFirstRoot(embedded); |
| 631 EXPECT_TRUE(embedded_root->visible()); | 626 EXPECT_TRUE(embedded_root->visible()); |
| 632 EXPECT_TRUE(embedded_root->IsDrawn()); | 627 EXPECT_TRUE(embedded_root->IsDrawn()); |
| 633 | 628 |
| 634 // Change the visibility of the root, this should propagate a drawn state | 629 // Change the visibility of the root, this should propagate a drawn state |
| 635 // change to |embedded|. | 630 // change to |embedded|. |
| 636 { | 631 { |
| 637 DrawnChangeObserver observer(embedded_root); | 632 DrawnChangeObserver observer(embedded_root); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 680 } | 675 } |
| 681 | 676 |
| 682 Window* window_; | 677 Window* window_; |
| 683 Window* last_gained_focus_; | 678 Window* last_gained_focus_; |
| 684 Window* last_lost_focus_; | 679 Window* last_lost_focus_; |
| 685 bool quit_on_change_; | 680 bool quit_on_change_; |
| 686 | 681 |
| 687 DISALLOW_COPY_AND_ASSIGN(FocusChangeObserver); | 682 DISALLOW_COPY_AND_ASSIGN(FocusChangeObserver); |
| 688 }; | 683 }; |
| 689 | 684 |
| 690 class NullFocusChangeObserver : public WindowTreeConnectionObserver { | 685 class NullFocusChangeObserver : public WindowTreeClientObserver { |
| 691 public: | 686 public: |
| 692 explicit NullFocusChangeObserver(WindowTreeConnection* connection) | 687 explicit NullFocusChangeObserver(WindowTreeClient* client) |
| 693 : connection_(connection) { | 688 : client_(client) { |
| 694 connection_->AddObserver(this); | 689 client_->AddObserver(this); |
| 695 } | 690 } |
| 696 ~NullFocusChangeObserver() override { connection_->RemoveObserver(this); } | 691 ~NullFocusChangeObserver() override { client_->RemoveObserver(this); } |
| 697 | 692 |
| 698 private: | 693 private: |
| 699 // Overridden from WindowTreeConnectionObserver. | 694 // Overridden from WindowTreeClientObserver. |
| 700 void OnWindowTreeFocusChanged(Window* gained_focus, | 695 void OnWindowTreeFocusChanged(Window* gained_focus, |
| 701 Window* lost_focus) override { | 696 Window* lost_focus) override { |
| 702 if (!gained_focus) | 697 if (!gained_focus) |
| 703 EXPECT_TRUE(WindowServerTestBase::QuitRunLoop()); | 698 EXPECT_TRUE(WindowServerTestBase::QuitRunLoop()); |
| 704 } | 699 } |
| 705 | 700 |
| 706 WindowTreeConnection* connection_; | 701 WindowTreeClient* client_; |
| 707 | 702 |
| 708 DISALLOW_COPY_AND_ASSIGN(NullFocusChangeObserver); | 703 DISALLOW_COPY_AND_ASSIGN(NullFocusChangeObserver); |
| 709 }; | 704 }; |
| 710 | 705 |
| 711 bool WaitForWindowToHaveFocus(Window* window) { | 706 bool WaitForWindowToHaveFocus(Window* window) { |
| 712 if (window->HasFocus()) | 707 if (window->HasFocus()) |
| 713 return true; | 708 return true; |
| 714 FocusChangeObserver observer(window); | 709 FocusChangeObserver observer(window); |
| 715 return WindowServerTestBase::DoRunLoopWithTimeout(); | 710 return WindowServerTestBase::DoRunLoopWithTimeout(); |
| 716 } | 711 } |
| 717 | 712 |
| 718 bool WaitForNoWindowToHaveFocus(WindowTreeConnection* connection) { | 713 bool WaitForNoWindowToHaveFocus(WindowTreeClient* client) { |
| 719 if (!connection->GetFocusedWindow()) | 714 if (!client->GetFocusedWindow()) |
| 720 return true; | 715 return true; |
| 721 NullFocusChangeObserver observer(connection); | 716 NullFocusChangeObserver observer(client); |
| 722 return WindowServerTestBase::DoRunLoopWithTimeout(); | 717 return WindowServerTestBase::DoRunLoopWithTimeout(); |
| 723 } | 718 } |
| 724 | 719 |
| 725 } // namespace | 720 } // namespace |
| 726 | 721 |
| 727 TEST_F(WindowServerTest, Focus) { | 722 TEST_F(WindowServerTest, Focus) { |
| 728 Window* window1 = window_manager()->NewWindow(); | 723 Window* window1 = window_manager()->NewWindow(); |
| 729 window1->SetVisible(true); | 724 window1->SetVisible(true); |
| 730 GetFirstWMRoot()->AddChild(window1); | 725 GetFirstWMRoot()->AddChild(window1); |
| 731 | 726 |
| 732 WindowTreeConnection* embedded = Embed(window1).connection; | 727 WindowTreeClient* embedded = Embed(window1).client; |
| 733 ASSERT_NE(nullptr, embedded); | 728 ASSERT_NE(nullptr, embedded); |
| 734 Window* window11 = embedded->NewWindow(); | 729 Window* window11 = embedded->NewWindow(); |
| 735 window11->SetVisible(true); | 730 window11->SetVisible(true); |
| 736 GetFirstRoot(embedded)->AddChild(window11); | 731 GetFirstRoot(embedded)->AddChild(window11); |
| 737 | 732 |
| 738 { | 733 { |
| 739 // Focus the embed root in |embedded|. | 734 // Focus the embed root in |embedded|. |
| 740 Window* embedded_root = GetFirstRoot(embedded); | 735 Window* embedded_root = GetFirstRoot(embedded); |
| 741 FocusChangeObserver observer(embedded_root); | 736 FocusChangeObserver observer(embedded_root); |
| 742 observer.set_quit_on_change(false); | 737 observer.set_quit_on_change(false); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 776 EXPECT_EQ(server_id(GetFirstRoot(embedded)), | 771 EXPECT_EQ(server_id(GetFirstRoot(embedded)), |
| 777 server_id(observer.last_gained_focus())); | 772 server_id(observer.last_gained_focus())); |
| 778 } | 773 } |
| 779 } | 774 } |
| 780 | 775 |
| 781 TEST_F(WindowServerTest, ClearFocus) { | 776 TEST_F(WindowServerTest, ClearFocus) { |
| 782 Window* window1 = window_manager()->NewWindow(); | 777 Window* window1 = window_manager()->NewWindow(); |
| 783 window1->SetVisible(true); | 778 window1->SetVisible(true); |
| 784 GetFirstWMRoot()->AddChild(window1); | 779 GetFirstWMRoot()->AddChild(window1); |
| 785 | 780 |
| 786 WindowTreeConnection* embedded = Embed(window1).connection; | 781 WindowTreeClient* embedded = Embed(window1).client; |
| 787 ASSERT_NE(nullptr, embedded); | 782 ASSERT_NE(nullptr, embedded); |
| 788 Window* window11 = embedded->NewWindow(); | 783 Window* window11 = embedded->NewWindow(); |
| 789 window11->SetVisible(true); | 784 window11->SetVisible(true); |
| 790 GetFirstRoot(embedded)->AddChild(window11); | 785 GetFirstRoot(embedded)->AddChild(window11); |
| 791 | 786 |
| 792 // Focus the embed root in |embedded|. | 787 // Focus the embed root in |embedded|. |
| 793 Window* embedded_root = GetFirstRoot(embedded); | 788 Window* embedded_root = GetFirstRoot(embedded); |
| 794 { | 789 { |
| 795 FocusChangeObserver observer(embedded_root); | 790 FocusChangeObserver observer(embedded_root); |
| 796 observer.set_quit_on_change(false); | 791 observer.set_quit_on_change(false); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 815 EXPECT_FALSE(window1->HasFocus()); | 810 EXPECT_FALSE(window1->HasFocus()); |
| 816 EXPECT_FALSE(window_manager()->GetFocusedWindow()); | 811 EXPECT_FALSE(window_manager()->GetFocusedWindow()); |
| 817 } | 812 } |
| 818 } | 813 } |
| 819 | 814 |
| 820 TEST_F(WindowServerTest, FocusNonFocusableWindow) { | 815 TEST_F(WindowServerTest, FocusNonFocusableWindow) { |
| 821 Window* window = window_manager()->NewWindow(); | 816 Window* window = window_manager()->NewWindow(); |
| 822 window->SetVisible(true); | 817 window->SetVisible(true); |
| 823 GetFirstWMRoot()->AddChild(window); | 818 GetFirstWMRoot()->AddChild(window); |
| 824 | 819 |
| 825 WindowTreeConnection* connection = Embed(window).connection; | 820 WindowTreeClient* client = Embed(window).client; |
| 826 ASSERT_NE(nullptr, connection); | 821 ASSERT_NE(nullptr, client); |
| 827 ASSERT_FALSE(connection->GetRoots().empty()); | 822 ASSERT_FALSE(client->GetRoots().empty()); |
| 828 Window* client_window = *connection->GetRoots().begin(); | 823 Window* client_window = *client->GetRoots().begin(); |
| 829 client_window->SetCanFocus(false); | 824 client_window->SetCanFocus(false); |
| 830 | 825 |
| 831 client_window->SetFocus(); | 826 client_window->SetFocus(); |
| 832 ASSERT_TRUE(client_window->HasFocus()); | 827 ASSERT_TRUE(client_window->HasFocus()); |
| 833 | 828 |
| 834 WaitForNoWindowToHaveFocus(connection); | 829 WaitForNoWindowToHaveFocus(client); |
| 835 ASSERT_FALSE(client_window->HasFocus()); | 830 ASSERT_FALSE(client_window->HasFocus()); |
| 836 } | 831 } |
| 837 | 832 |
| 838 TEST_F(WindowServerTest, Activation) { | 833 TEST_F(WindowServerTest, Activation) { |
| 839 Window* parent = NewVisibleWindow(GetFirstWMRoot(), window_manager()); | 834 Window* parent = NewVisibleWindow(GetFirstWMRoot(), window_manager()); |
| 840 | 835 |
| 841 // Allow the child windows to be activated. Do this before we wait, that way | 836 // Allow the child windows to be activated. Do this before we wait, that way |
| 842 // we're guaranteed that when we request focus from a separate client the | 837 // we're guaranteed that when we request focus from a separate client the |
| 843 // requests are processed in order. | 838 // requests are processed in order. |
| 844 window_manager_client()->AddActivationParent(parent); | 839 window_manager_client()->AddActivationParent(parent); |
| 845 | 840 |
| 846 Window* child1 = NewVisibleWindow(parent, window_manager()); | 841 Window* child1 = NewVisibleWindow(parent, window_manager()); |
| 847 Window* child2 = NewVisibleWindow(parent, window_manager()); | 842 Window* child2 = NewVisibleWindow(parent, window_manager()); |
| 848 Window* child3 = NewVisibleWindow(parent, window_manager()); | 843 Window* child3 = NewVisibleWindow(parent, window_manager()); |
| 849 | 844 |
| 850 child1->AddTransientWindow(child3); | 845 child1->AddTransientWindow(child3); |
| 851 | 846 |
| 852 WindowTreeConnection* embedded1 = Embed(child1).connection; | 847 WindowTreeClient* embedded1 = Embed(child1).client; |
| 853 ASSERT_NE(nullptr, embedded1); | 848 ASSERT_NE(nullptr, embedded1); |
| 854 WindowTreeConnection* embedded2 = Embed(child2).connection; | 849 WindowTreeClient* embedded2 = Embed(child2).client; |
| 855 ASSERT_NE(nullptr, embedded2); | 850 ASSERT_NE(nullptr, embedded2); |
| 856 | 851 |
| 857 Window* child11 = NewVisibleWindow(GetFirstRoot(embedded1), embedded1); | 852 Window* child11 = NewVisibleWindow(GetFirstRoot(embedded1), embedded1); |
| 858 Window* child21 = NewVisibleWindow(GetFirstRoot(embedded2), embedded2); | 853 Window* child21 = NewVisibleWindow(GetFirstRoot(embedded2), embedded2); |
| 859 | 854 |
| 860 WaitForTreeSizeToMatch(parent, 6); | 855 WaitForTreeSizeToMatch(parent, 6); |
| 861 | 856 |
| 862 // |child2| and |child3| are stacked about |child1|. | 857 // |child2| and |child3| are stacked about |child1|. |
| 863 EXPECT_GT(ValidIndexOf(parent->children(), child2), | 858 EXPECT_GT(ValidIndexOf(parent->children(), child2), |
| 864 ValidIndexOf(parent->children(), child1)); | 859 ValidIndexOf(parent->children(), child1)); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 897 EXPECT_GT(ValidIndexOf(parent->children(), child3), | 892 EXPECT_GT(ValidIndexOf(parent->children(), child3), |
| 898 ValidIndexOf(parent->children(), child1)); | 893 ValidIndexOf(parent->children(), child1)); |
| 899 } | 894 } |
| 900 | 895 |
| 901 TEST_F(WindowServerTest, ActivationNext) { | 896 TEST_F(WindowServerTest, ActivationNext) { |
| 902 Window* parent = GetFirstWMRoot(); | 897 Window* parent = GetFirstWMRoot(); |
| 903 Window* child1 = NewVisibleWindow(parent, window_manager()); | 898 Window* child1 = NewVisibleWindow(parent, window_manager()); |
| 904 Window* child2 = NewVisibleWindow(parent, window_manager()); | 899 Window* child2 = NewVisibleWindow(parent, window_manager()); |
| 905 Window* child3 = NewVisibleWindow(parent, window_manager()); | 900 Window* child3 = NewVisibleWindow(parent, window_manager()); |
| 906 | 901 |
| 907 WindowTreeConnection* embedded1 = Embed(child1).connection; | 902 WindowTreeClient* embedded1 = Embed(child1).client; |
| 908 ASSERT_NE(nullptr, embedded1); | 903 ASSERT_NE(nullptr, embedded1); |
| 909 WindowTreeConnection* embedded2 = Embed(child2).connection; | 904 WindowTreeClient* embedded2 = Embed(child2).client; |
| 910 ASSERT_NE(nullptr, embedded2); | 905 ASSERT_NE(nullptr, embedded2); |
| 911 WindowTreeConnection* embedded3 = Embed(child3).connection; | 906 WindowTreeClient* embedded3 = Embed(child3).client; |
| 912 ASSERT_NE(nullptr, embedded3); | 907 ASSERT_NE(nullptr, embedded3); |
| 913 | 908 |
| 914 Window* child11 = NewVisibleWindow(GetFirstRoot(embedded1), embedded1); | 909 Window* child11 = NewVisibleWindow(GetFirstRoot(embedded1), embedded1); |
| 915 Window* child21 = NewVisibleWindow(GetFirstRoot(embedded2), embedded2); | 910 Window* child21 = NewVisibleWindow(GetFirstRoot(embedded2), embedded2); |
| 916 Window* child31 = NewVisibleWindow(GetFirstRoot(embedded3), embedded3); | 911 Window* child31 = NewVisibleWindow(GetFirstRoot(embedded3), embedded3); |
| 917 WaitForTreeSizeToMatch(parent, 7); | 912 WaitForTreeSizeToMatch(parent, 7); |
| 918 | 913 |
| 919 Window* expecteds[] = { child3, child2, child1, child3, nullptr }; | 914 Window* expecteds[] = { child3, child2, child1, child3, nullptr }; |
| 920 Window* focused[] = { child31, child21, child11, child31, nullptr }; | 915 Window* focused[] = { child31, child21, child11, child31, nullptr }; |
| 921 for (size_t index = 0; expecteds[index]; ++index) { | 916 for (size_t index = 0; expecteds[index]; ++index) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 942 } | 937 } |
| 943 | 938 |
| 944 private: | 939 private: |
| 945 // Overridden from WindowObserver: | 940 // Overridden from WindowObserver: |
| 946 void OnWindowDestroyed(Window* window) override { | 941 void OnWindowDestroyed(Window* window) override { |
| 947 EXPECT_EQ(window, window_); | 942 EXPECT_EQ(window, window_); |
| 948 window_->RemoveObserver(this); | 943 window_->RemoveObserver(this); |
| 949 *got_destroy_ = true; | 944 *got_destroy_ = true; |
| 950 window_ = nullptr; | 945 window_ = nullptr; |
| 951 | 946 |
| 952 // We should always get OnWindowDestroyed() before OnConnectionLost(). | 947 // We should always get OnWindowDestroyed() before |
| 953 EXPECT_FALSE(test_->window_tree_connection_destroyed()); | 948 // OnWindowTreeClientDestroyed(). |
| 949 EXPECT_FALSE(test_->window_tree_client_destroyed()); |
| 954 } | 950 } |
| 955 | 951 |
| 956 WindowServerTestBase* test_; | 952 WindowServerTestBase* test_; |
| 957 Window* window_; | 953 Window* window_; |
| 958 bool* got_destroy_; | 954 bool* got_destroy_; |
| 959 | 955 |
| 960 DISALLOW_COPY_AND_ASSIGN(DestroyedChangedObserver); | 956 DISALLOW_COPY_AND_ASSIGN(DestroyedChangedObserver); |
| 961 }; | 957 }; |
| 962 | 958 |
| 963 } // namespace | 959 } // namespace |
| 964 | 960 |
| 965 // Verifies deleting a WindowServer sends the right notifications. | 961 // Verifies deleting a WindowServer sends the right notifications. |
| 966 TEST_F(WindowServerTest, DeleteWindowServer) { | 962 TEST_F(WindowServerTest, DeleteWindowServer) { |
| 967 Window* window = window_manager()->NewWindow(); | 963 Window* window = window_manager()->NewWindow(); |
| 968 ASSERT_NE(nullptr, window); | 964 ASSERT_NE(nullptr, window); |
| 969 window->SetVisible(true); | 965 window->SetVisible(true); |
| 970 GetFirstWMRoot()->AddChild(window); | 966 GetFirstWMRoot()->AddChild(window); |
| 971 WindowTreeConnection* connection = Embed(window).connection; | 967 WindowTreeClient* client = Embed(window).client; |
| 972 ASSERT_TRUE(connection); | 968 ASSERT_TRUE(client); |
| 973 bool got_destroy = false; | 969 bool got_destroy = false; |
| 974 DestroyedChangedObserver observer(this, GetFirstRoot(connection), | 970 DestroyedChangedObserver observer(this, GetFirstRoot(client), |
| 975 &got_destroy); | 971 &got_destroy); |
| 976 delete connection; | 972 delete client; |
| 977 EXPECT_TRUE(window_tree_connection_destroyed()); | 973 EXPECT_TRUE(window_tree_client_destroyed()); |
| 978 EXPECT_TRUE(got_destroy); | 974 EXPECT_TRUE(got_destroy); |
| 979 } | 975 } |
| 980 | 976 |
| 981 // Verifies two Embed()s in the same window trigger deletion of the first | 977 // Verifies two Embed()s in the same window trigger deletion of the first |
| 982 // WindowServer. | 978 // WindowServer. |
| 983 TEST_F(WindowServerTest, DisconnectTriggersDelete) { | 979 TEST_F(WindowServerTest, DisconnectTriggersDelete) { |
| 984 Window* window = window_manager()->NewWindow(); | 980 Window* window = window_manager()->NewWindow(); |
| 985 ASSERT_NE(nullptr, window); | 981 ASSERT_NE(nullptr, window); |
| 986 window->SetVisible(true); | 982 window->SetVisible(true); |
| 987 GetFirstWMRoot()->AddChild(window); | 983 GetFirstWMRoot()->AddChild(window); |
| 988 WindowTreeConnection* connection = Embed(window).connection; | 984 WindowTreeClient* client = Embed(window).client; |
| 989 EXPECT_NE(connection, window_manager()); | 985 EXPECT_NE(client, window_manager()); |
| 990 Window* embedded_window = connection->NewWindow(); | 986 Window* embedded_window = client->NewWindow(); |
| 991 // Embed again, this should trigger disconnect and deletion of connection. | 987 // Embed again, this should trigger disconnect and deletion of client. |
| 992 bool got_destroy; | 988 bool got_destroy; |
| 993 DestroyedChangedObserver observer(this, embedded_window, &got_destroy); | 989 DestroyedChangedObserver observer(this, embedded_window, &got_destroy); |
| 994 EXPECT_FALSE(window_tree_connection_destroyed()); | 990 EXPECT_FALSE(window_tree_client_destroyed()); |
| 995 Embed(window); | 991 Embed(window); |
| 996 EXPECT_TRUE(window_tree_connection_destroyed()); | 992 EXPECT_TRUE(window_tree_client_destroyed()); |
| 997 } | 993 } |
| 998 | 994 |
| 999 class WindowRemovedFromParentObserver : public WindowObserver { | 995 class WindowRemovedFromParentObserver : public WindowObserver { |
| 1000 public: | 996 public: |
| 1001 explicit WindowRemovedFromParentObserver(Window* window) | 997 explicit WindowRemovedFromParentObserver(Window* window) |
| 1002 : window_(window), was_removed_(false) { | 998 : window_(window), was_removed_(false) { |
| 1003 window_->AddObserver(this); | 999 window_->AddObserver(this); |
| 1004 } | 1000 } |
| 1005 ~WindowRemovedFromParentObserver() override { window_->RemoveObserver(this); } | 1001 ~WindowRemovedFromParentObserver() override { window_->RemoveObserver(this); } |
| 1006 | 1002 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1035 // we may end up reconnecting to the test and rerunning the test, which is | 1031 // we may end up reconnecting to the test and rerunning the test, which is |
| 1036 // problematic since the other services don't shut down. | 1032 // problematic since the other services don't shut down. |
| 1037 ASSERT_TRUE(DoRunLoopWithTimeout()); | 1033 ASSERT_TRUE(DoRunLoopWithTimeout()); |
| 1038 } | 1034 } |
| 1039 | 1035 |
| 1040 namespace { | 1036 namespace { |
| 1041 | 1037 |
| 1042 class DestroyObserver : public WindowObserver { | 1038 class DestroyObserver : public WindowObserver { |
| 1043 public: | 1039 public: |
| 1044 DestroyObserver(WindowServerTestBase* test, | 1040 DestroyObserver(WindowServerTestBase* test, |
| 1045 WindowTreeConnection* connection, | 1041 WindowTreeClient* client, |
| 1046 bool* got_destroy) | 1042 bool* got_destroy) |
| 1047 : test_(test), got_destroy_(got_destroy) { | 1043 : test_(test), got_destroy_(got_destroy) { |
| 1048 GetFirstRoot(connection)->AddObserver(this); | 1044 GetFirstRoot(client)->AddObserver(this); |
| 1049 } | 1045 } |
| 1050 ~DestroyObserver() override {} | 1046 ~DestroyObserver() override {} |
| 1051 | 1047 |
| 1052 private: | 1048 private: |
| 1053 // Overridden from WindowObserver: | 1049 // Overridden from WindowObserver: |
| 1054 void OnWindowDestroyed(Window* window) override { | 1050 void OnWindowDestroyed(Window* window) override { |
| 1055 *got_destroy_ = true; | 1051 *got_destroy_ = true; |
| 1056 window->RemoveObserver(this); | 1052 window->RemoveObserver(this); |
| 1057 | 1053 |
| 1058 // We should always get OnWindowDestroyed() before | 1054 // We should always get OnWindowDestroyed() before |
| 1059 // OnWindowManagerDestroyed(). | 1055 // OnWindowManagerDestroyed(). |
| 1060 EXPECT_FALSE(test_->window_tree_connection_destroyed()); | 1056 EXPECT_FALSE(test_->window_tree_client_destroyed()); |
| 1061 | 1057 |
| 1062 EXPECT_TRUE(WindowServerTestBase::QuitRunLoop()); | 1058 EXPECT_TRUE(WindowServerTestBase::QuitRunLoop()); |
| 1063 } | 1059 } |
| 1064 | 1060 |
| 1065 WindowServerTestBase* test_; | 1061 WindowServerTestBase* test_; |
| 1066 bool* got_destroy_; | 1062 bool* got_destroy_; |
| 1067 | 1063 |
| 1068 DISALLOW_COPY_AND_ASSIGN(DestroyObserver); | 1064 DISALLOW_COPY_AND_ASSIGN(DestroyObserver); |
| 1069 }; | 1065 }; |
| 1070 | 1066 |
| 1071 } // namespace | 1067 } // namespace |
| 1072 | 1068 |
| 1073 // Verifies deleting a Window that is the root of another connection notifies | 1069 // Verifies deleting a Window that is the root of another client notifies |
| 1074 // observers in the right order (OnWindowDestroyed() before | 1070 // observers in the right order (OnWindowDestroyed() before |
| 1075 // OnWindowManagerDestroyed()). | 1071 // OnWindowManagerDestroyed()). |
| 1076 TEST_F(WindowServerTest, WindowServerDestroyedAfterRootObserver) { | 1072 TEST_F(WindowServerTest, WindowServerDestroyedAfterRootObserver) { |
| 1077 Window* embed_window = window_manager()->NewWindow(); | 1073 Window* embed_window = window_manager()->NewWindow(); |
| 1078 GetFirstWMRoot()->AddChild(embed_window); | 1074 GetFirstWMRoot()->AddChild(embed_window); |
| 1079 | 1075 |
| 1080 WindowTreeConnection* embedded_connection = Embed(embed_window).connection; | 1076 WindowTreeClient* embedded_client = Embed(embed_window).client; |
| 1081 | 1077 |
| 1082 bool got_destroy = false; | 1078 bool got_destroy = false; |
| 1083 DestroyObserver observer(this, embedded_connection, &got_destroy); | 1079 DestroyObserver observer(this, embedded_client, &got_destroy); |
| 1084 // Delete the window |embedded_connection| is embedded in. This is async, | 1080 // Delete the window |embedded_client| is embedded in. This is async, |
| 1085 // but will eventually trigger deleting |embedded_connection|. | 1081 // but will eventually trigger deleting |embedded_client|. |
| 1086 embed_window->Destroy(); | 1082 embed_window->Destroy(); |
| 1087 EXPECT_TRUE(DoRunLoopWithTimeout()); | 1083 EXPECT_TRUE(DoRunLoopWithTimeout()); |
| 1088 EXPECT_TRUE(got_destroy); | 1084 EXPECT_TRUE(got_destroy); |
| 1089 } | 1085 } |
| 1090 | 1086 |
| 1091 TEST_F(WindowServerTest, ClientAreaChanged) { | 1087 TEST_F(WindowServerTest, ClientAreaChanged) { |
| 1092 Window* embed_window = window_manager()->NewWindow(); | 1088 Window* embed_window = window_manager()->NewWindow(); |
| 1093 GetFirstWMRoot()->AddChild(embed_window); | 1089 GetFirstWMRoot()->AddChild(embed_window); |
| 1094 | 1090 |
| 1095 WindowTreeConnection* embedded_connection = Embed(embed_window).connection; | 1091 WindowTreeClient* embedded_client = Embed(embed_window).client; |
| 1096 | 1092 |
| 1097 // Verify change from embedded makes it to parent. | 1093 // Verify change from embedded makes it to parent. |
| 1098 GetFirstRoot(embedded_connection)->SetClientArea(gfx::Insets(1, 2, 3, 4)); | 1094 GetFirstRoot(embedded_client)->SetClientArea(gfx::Insets(1, 2, 3, 4)); |
| 1099 ASSERT_TRUE(WaitForClientAreaToChange(embed_window)); | 1095 ASSERT_TRUE(WaitForClientAreaToChange(embed_window)); |
| 1100 EXPECT_TRUE(gfx::Insets(1, 2, 3, 4) == embed_window->client_area()); | 1096 EXPECT_TRUE(gfx::Insets(1, 2, 3, 4) == embed_window->client_area()); |
| 1101 | 1097 |
| 1102 // Changing bounds shouldn't effect client area. | 1098 // Changing bounds shouldn't effect client area. |
| 1103 embed_window->SetBounds(gfx::Rect(21, 22, 23, 24)); | 1099 embed_window->SetBounds(gfx::Rect(21, 22, 23, 24)); |
| 1104 WaitForBoundsToChange(GetFirstRoot(embedded_connection)); | 1100 WaitForBoundsToChange(GetFirstRoot(embedded_client)); |
| 1105 EXPECT_TRUE(gfx::Rect(21, 22, 23, 24) == | 1101 EXPECT_TRUE(gfx::Rect(21, 22, 23, 24) == |
| 1106 GetFirstRoot(embedded_connection)->bounds()); | 1102 GetFirstRoot(embedded_client)->bounds()); |
| 1107 EXPECT_TRUE(gfx::Insets(1, 2, 3, 4) == | 1103 EXPECT_TRUE(gfx::Insets(1, 2, 3, 4) == |
| 1108 GetFirstRoot(embedded_connection)->client_area()); | 1104 GetFirstRoot(embedded_client)->client_area()); |
| 1109 } | 1105 } |
| 1110 | 1106 |
| 1111 class EstablishConnectionViaFactoryDelegate : public TestWindowManagerDelegate { | 1107 class EstablishConnectionViaFactoryDelegate : public TestWindowManagerDelegate { |
| 1112 public: | 1108 public: |
| 1113 explicit EstablishConnectionViaFactoryDelegate( | 1109 explicit EstablishConnectionViaFactoryDelegate( |
| 1114 WindowTreeConnection* connection) | 1110 WindowTreeClient* client) |
| 1115 : connection_(connection), run_loop_(nullptr), created_window_(nullptr) {} | 1111 : client_(client), run_loop_(nullptr), created_window_(nullptr) {} |
| 1116 ~EstablishConnectionViaFactoryDelegate() override {} | 1112 ~EstablishConnectionViaFactoryDelegate() override {} |
| 1117 | 1113 |
| 1118 bool QuitOnCreate() { | 1114 bool QuitOnCreate() { |
| 1119 if (run_loop_) | 1115 if (run_loop_) |
| 1120 return false; | 1116 return false; |
| 1121 | 1117 |
| 1122 created_window_ = nullptr; | 1118 created_window_ = nullptr; |
| 1123 run_loop_.reset(new base::RunLoop); | 1119 run_loop_.reset(new base::RunLoop); |
| 1124 run_loop_->Run(); | 1120 run_loop_->Run(); |
| 1125 run_loop_.reset(); | 1121 run_loop_.reset(); |
| 1126 return created_window_ != nullptr; | 1122 return created_window_ != nullptr; |
| 1127 } | 1123 } |
| 1128 | 1124 |
| 1129 Window* created_window() { return created_window_; } | 1125 Window* created_window() { return created_window_; } |
| 1130 | 1126 |
| 1131 // WindowManagerDelegate: | 1127 // WindowManagerDelegate: |
| 1132 Window* OnWmCreateTopLevelWindow( | 1128 Window* OnWmCreateTopLevelWindow( |
| 1133 std::map<std::string, std::vector<uint8_t>>* properties) override { | 1129 std::map<std::string, std::vector<uint8_t>>* properties) override { |
| 1134 created_window_ = connection_->NewWindow(properties); | 1130 created_window_ = client_->NewWindow(properties); |
| 1135 (*connection_->GetRoots().begin())->AddChild(created_window_); | 1131 (*client_->GetRoots().begin())->AddChild(created_window_); |
| 1136 if (run_loop_) | 1132 if (run_loop_) |
| 1137 run_loop_->Quit(); | 1133 run_loop_->Quit(); |
| 1138 return created_window_; | 1134 return created_window_; |
| 1139 } | 1135 } |
| 1140 | 1136 |
| 1141 private: | 1137 private: |
| 1142 WindowTreeConnection* connection_; | 1138 WindowTreeClient* client_; |
| 1143 std::unique_ptr<base::RunLoop> run_loop_; | 1139 std::unique_ptr<base::RunLoop> run_loop_; |
| 1144 Window* created_window_; | 1140 Window* created_window_; |
| 1145 | 1141 |
| 1146 DISALLOW_COPY_AND_ASSIGN(EstablishConnectionViaFactoryDelegate); | 1142 DISALLOW_COPY_AND_ASSIGN(EstablishConnectionViaFactoryDelegate); |
| 1147 }; | 1143 }; |
| 1148 | 1144 |
| 1149 TEST_F(WindowServerTest, EstablishConnectionViaFactory) { | 1145 TEST_F(WindowServerTest, EstablishConnectionViaFactory) { |
| 1150 EstablishConnectionViaFactoryDelegate delegate(window_manager()); | 1146 EstablishConnectionViaFactoryDelegate delegate(window_manager()); |
| 1151 set_window_manager_delegate(&delegate); | 1147 set_window_manager_delegate(&delegate); |
| 1152 std::unique_ptr<WindowTreeConnection> second_connection( | 1148 std::unique_ptr<WindowTreeClient> second_client( |
| 1153 WindowTreeConnection::Create(this, connector())); | 1149 new WindowTreeClient(this, nullptr, nullptr)); |
| 1154 Window* window_in_second_connection = | 1150 second_client->ConnectViaWindowTreeFactory(connector()); |
| 1155 second_connection->NewTopLevelWindow(nullptr); | 1151 Window* window_in_second_client = |
| 1156 ASSERT_TRUE(window_in_second_connection); | 1152 second_client->NewTopLevelWindow(nullptr); |
| 1157 ASSERT_TRUE(second_connection->GetRoots().count(window_in_second_connection) > | 1153 ASSERT_TRUE(window_in_second_client); |
| 1154 ASSERT_TRUE(second_client->GetRoots().count(window_in_second_client) > |
| 1158 0); | 1155 0); |
| 1159 // Wait for the window to appear in the wm. | 1156 // Wait for the window to appear in the wm. |
| 1160 ASSERT_TRUE(delegate.QuitOnCreate()); | 1157 ASSERT_TRUE(delegate.QuitOnCreate()); |
| 1161 | 1158 |
| 1162 Window* window_in_wm = delegate.created_window(); | 1159 Window* window_in_wm = delegate.created_window(); |
| 1163 ASSERT_TRUE(window_in_wm); | 1160 ASSERT_TRUE(window_in_wm); |
| 1164 | 1161 |
| 1165 // Change the bounds in the wm, and make sure the child sees it. | 1162 // Change the bounds in the wm, and make sure the child sees it. |
| 1166 window_in_wm->SetBounds(gfx::Rect(1, 11, 12, 101)); | 1163 window_in_wm->SetBounds(gfx::Rect(1, 11, 12, 101)); |
| 1167 ASSERT_TRUE(WaitForBoundsToChange(window_in_second_connection)); | 1164 ASSERT_TRUE(WaitForBoundsToChange(window_in_second_client)); |
| 1168 EXPECT_EQ(gfx::Rect(1, 11, 12, 101), window_in_second_connection->bounds()); | 1165 EXPECT_EQ(gfx::Rect(1, 11, 12, 101), window_in_second_client->bounds()); |
| 1169 } | 1166 } |
| 1170 | 1167 |
| 1171 } // namespace ws | 1168 } // namespace ws |
| 1172 } // namespace mus | 1169 } // namespace mus |
| OLD | NEW |