Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(226)

Unified Diff: services/ui/public/cpp/tests/window_tree_client_unittest.cc

Issue 2651593002: mus: Remove the old client lib. (Closed)
Patch Set: restore test Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: services/ui/public/cpp/tests/window_tree_client_unittest.cc
diff --git a/services/ui/public/cpp/tests/window_tree_client_unittest.cc b/services/ui/public/cpp/tests/window_tree_client_unittest.cc
deleted file mode 100644
index 1c4efc24f4526e33c2aa5d5b52d010cd0d4c2e90..0000000000000000000000000000000000000000
--- a/services/ui/public/cpp/tests/window_tree_client_unittest.cc
+++ /dev/null
@@ -1,1090 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "services/ui/public/cpp/window_tree_client.h"
-
-#include <stdint.h>
-
-#include "base/logging.h"
-#include "base/macros.h"
-#include "services/ui/common/util.h"
-#include "services/ui/public/cpp/input_event_handler.h"
-#include "services/ui/public/cpp/property_type_converters.h"
-#include "services/ui/public/cpp/tests/test_window.h"
-#include "services/ui/public/cpp/tests/test_window_tree.h"
-#include "services/ui/public/cpp/tests/window_tree_client_private.h"
-#include "services/ui/public/cpp/window.h"
-#include "services/ui/public/cpp/window_observer.h"
-#include "services/ui/public/cpp/window_private.h"
-#include "services/ui/public/cpp/window_property.h"
-#include "services/ui/public/cpp/window_tracker.h"
-#include "services/ui/public/cpp/window_tree_client_delegate.h"
-#include "services/ui/public/cpp/window_tree_client_observer.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/display/test/test_screen.h"
-#include "ui/events/event.h"
-#include "ui/events/event_utils.h"
-#include "ui/gfx/geometry/rect.h"
-
-namespace ui {
-
-namespace {
-
-void DoNothingWithEventResult(mojom::EventResult result) {}
-
-Id server_id(ui::Window* window) {
- return WindowPrivate(window).server_id();
-}
-
-} // namespace
-
-std::vector<uint8_t> Int32ToPropertyTransportValue(int32_t value) {
- return mojo::ConvertTo<std::vector<uint8_t>>(value);
-}
-
-class TestWindowTreeClientDelegate : public WindowTreeClientDelegate {
- public:
- TestWindowTreeClientDelegate() {}
- ~TestWindowTreeClientDelegate() override {}
-
- ui::PointerEvent* last_event_observed() { return last_event_observed_.get(); }
-
- void Reset() { last_event_observed_.reset(); }
-
- // WindowTreeClientDelegate:
- void OnEmbed(Window* root) override {}
- void OnLostConnection(WindowTreeClient* client) override {}
- void OnEmbedRootDestroyed(Window* root) override {}
- void OnPointerEventObserved(const ui::PointerEvent& event,
- Window* target) override {
- last_event_observed_.reset(new ui::PointerEvent(event));
- }
-
- private:
- std::unique_ptr<ui::PointerEvent> last_event_observed_;
-
- DISALLOW_COPY_AND_ASSIGN(TestWindowTreeClientDelegate);
-};
-
-class WindowTreeSetup {
- public:
- WindowTreeSetup() : tree_client_(&window_tree_delegate_, nullptr, nullptr) {
- display::Screen::SetScreenInstance(&test_screen_);
- WindowTreeClientPrivate(&tree_client_).OnEmbed(&window_tree_);
- window_tree_.GetAndClearChangeId(nullptr);
- }
-
- ~WindowTreeSetup() { display::Screen::SetScreenInstance(nullptr); }
-
- WindowTreeClient* client() {
- return &tree_client_;
- }
-
- mojom::WindowTreeClient* window_tree_client() {
- return static_cast<mojom::WindowTreeClient*>(&tree_client_);
- }
-
- TestWindowTree* window_tree() { return &window_tree_; }
-
- TestWindowTreeClientDelegate* window_tree_delegate() {
- return &window_tree_delegate_;
- }
-
- Window* GetFirstRoot() {
- return client()->GetRoots().empty() ? nullptr
- : *client()->GetRoots().begin();
- }
-
- private:
- TestWindowTree window_tree_;
- TestWindowTreeClientDelegate window_tree_delegate_;
- WindowTreeClient tree_client_;
-
- // Dummy screen required to be the screen instance.
- display::test::TestScreen test_screen_;
-
- DISALLOW_COPY_AND_ASSIGN(WindowTreeSetup);
-};
-
-class TestInputEventHandler : public InputEventHandler {
- public:
- TestInputEventHandler()
- : received_event_(false), should_manually_ack_(false) {}
- ~TestInputEventHandler() override {}
-
- void set_should_manually_ack() { should_manually_ack_ = true; }
-
- void AckEvent() {
- DCHECK(should_manually_ack_);
- DCHECK(!ack_callback_.is_null());
- ack_callback_.Run(mojom::EventResult::HANDLED);
- ack_callback_ = base::Bind(&DoNothingWithEventResult);
- }
-
- void Reset() {
- received_event_ = false;
- ack_callback_ = base::Bind(&DoNothingWithEventResult);
- }
- bool received_event() const { return received_event_; }
-
- private:
- // InputEventHandler:
- void OnWindowInputEvent(
- Window* target,
- const ui::Event& event,
- std::unique_ptr<base::Callback<void(mojom::EventResult)>>* ack_callback)
- override {
- EXPECT_FALSE(received_event_)
- << "Observer was not reset after receiving event.";
- received_event_ = true;
- if (should_manually_ack_) {
- ack_callback_ = *ack_callback->get();
- ack_callback->reset();
- }
- }
-
- bool received_event_;
- bool should_manually_ack_;
- base::Callback<void(mojom::EventResult)> ack_callback_;
-
- DISALLOW_COPY_AND_ASSIGN(TestInputEventHandler);
-};
-
-using WindowTreeClientTest = testing::Test;
-
-// Verifies bounds are reverted if the server replied that the change failed.
-TEST_F(WindowTreeClientTest, SetBoundsFailed) {
- WindowTreeSetup setup;
- Window* root = setup.GetFirstRoot();
- ASSERT_TRUE(root);
- const gfx::Rect original_bounds(root->bounds());
- const gfx::Rect new_bounds(gfx::Rect(0, 0, 100, 100));
- ASSERT_NE(new_bounds, root->bounds());
- root->SetBounds(new_bounds);
- uint32_t change_id;
- ASSERT_TRUE(setup.window_tree()->GetAndClearChangeId(&change_id));
- setup.window_tree_client()->OnChangeCompleted(change_id, false);
- EXPECT_EQ(original_bounds, root->bounds());
-}
-
-// Simulates a bounds change, and while the bounds change is in flight the
-// server replies with a new bounds and the original bounds change fails.
-TEST_F(WindowTreeClientTest, SetBoundsFailedWithPendingChange) {
- WindowTreeSetup setup;
- Window* root = setup.GetFirstRoot();
- ASSERT_TRUE(root);
- const gfx::Rect original_bounds(root->bounds());
- const gfx::Rect new_bounds(gfx::Rect(0, 0, 100, 100));
- ASSERT_NE(new_bounds, root->bounds());
- root->SetBounds(new_bounds);
- EXPECT_EQ(new_bounds, root->bounds());
- uint32_t change_id;
- ASSERT_TRUE(setup.window_tree()->GetAndClearChangeId(&change_id));
-
- // Simulate the server responding with a bounds change.
- const gfx::Rect server_changed_bounds(gfx::Rect(0, 0, 101, 102));
- setup.window_tree_client()->OnWindowBoundsChanged(
- server_id(root), original_bounds, server_changed_bounds);
-
- // This shouldn't trigger the bounds changing yet.
- EXPECT_EQ(new_bounds, root->bounds());
-
- // Tell the client the change failed, which should trigger failing to the
- // most recent bounds from server.
- setup.window_tree_client()->OnChangeCompleted(change_id, false);
- EXPECT_EQ(server_changed_bounds, root->bounds());
-
- // Simulate server changing back to original bounds. Should take immediately.
- setup.window_tree_client()->OnWindowBoundsChanged(
- server_id(root), server_changed_bounds, original_bounds);
- EXPECT_EQ(original_bounds, root->bounds());
-}
-
-TEST_F(WindowTreeClientTest, TwoInFlightBoundsChangesBothCanceled) {
- WindowTreeSetup setup;
- Window* root = setup.GetFirstRoot();
- ASSERT_TRUE(root);
- const gfx::Rect original_bounds(root->bounds());
- const gfx::Rect bounds1(gfx::Rect(0, 0, 100, 100));
- const gfx::Rect bounds2(gfx::Rect(0, 0, 100, 102));
- root->SetBounds(bounds1);
- EXPECT_EQ(bounds1, root->bounds());
- uint32_t change_id1;
- ASSERT_TRUE(setup.window_tree()->GetAndClearChangeId(&change_id1));
-
- root->SetBounds(bounds2);
- EXPECT_EQ(bounds2, root->bounds());
- uint32_t change_id2;
- ASSERT_TRUE(setup.window_tree()->GetAndClearChangeId(&change_id2));
-
- // Tell the client change 1 failed. As there is a still a change in flight
- // nothing should happen.
- setup.window_tree_client()->OnChangeCompleted(change_id1, false);
- EXPECT_EQ(bounds2, root->bounds());
-
- // And tell the client change 2 failed too. Should now fallback to original
- // bounds.
- setup.window_tree_client()->OnChangeCompleted(change_id2, false);
- EXPECT_EQ(original_bounds, root->bounds());
-}
-
-// Verifies properties are reverted if the server replied that the change
-// failed.
-TEST_F(WindowTreeClientTest, SetPropertyFailed) {
- WindowTreeSetup setup;
- Window* root = setup.GetFirstRoot();
- ASSERT_TRUE(root);
- ASSERT_FALSE(root->HasSharedProperty("foo"));
- const int32_t new_value = 11;
- root->SetSharedProperty("foo", new_value);
- ASSERT_TRUE(root->HasSharedProperty("foo"));
- EXPECT_EQ(new_value, root->GetSharedProperty<int32_t>("foo"));
- uint32_t change_id;
- ASSERT_TRUE(setup.window_tree()->GetAndClearChangeId(&change_id));
- setup.window_tree_client()->OnChangeCompleted(change_id, false);
- EXPECT_FALSE(root->HasSharedProperty("foo"));
-}
-
-// Simulates a property change, and while the property change is in flight the
-// server replies with a new property and the original property change fails.
-TEST_F(WindowTreeClientTest, SetPropertyFailedWithPendingChange) {
- WindowTreeSetup setup;
- Window* root = setup.GetFirstRoot();
- ASSERT_TRUE(root);
- const int32_t value1 = 11;
- root->SetSharedProperty("foo", value1);
- ASSERT_TRUE(root->HasSharedProperty("foo"));
- EXPECT_EQ(value1, root->GetSharedProperty<int32_t>("foo"));
- uint32_t change_id;
- ASSERT_TRUE(setup.window_tree()->GetAndClearChangeId(&change_id));
-
- // Simulate the server responding with a different value.
- const int32_t server_value = 12;
- setup.window_tree_client()->OnWindowSharedPropertyChanged(
- server_id(root), "foo", Int32ToPropertyTransportValue(server_value));
-
- // This shouldn't trigger the property changing yet.
- ASSERT_TRUE(root->HasSharedProperty("foo"));
- EXPECT_EQ(value1, root->GetSharedProperty<int32_t>("foo"));
-
- // Tell the client the change failed, which should trigger failing to the
- // most recent value from server.
- setup.window_tree_client()->OnChangeCompleted(change_id, false);
- ASSERT_TRUE(root->HasSharedProperty("foo"));
- EXPECT_EQ(server_value, root->GetSharedProperty<int32_t>("foo"));
-
- // Simulate server changing back to value1. Should take immediately.
- setup.window_tree_client()->OnWindowSharedPropertyChanged(
- server_id(root), "foo", Int32ToPropertyTransportValue(value1));
- ASSERT_TRUE(root->HasSharedProperty("foo"));
- EXPECT_EQ(value1, root->GetSharedProperty<int32_t>("foo"));
-}
-
-// Verifies visible is reverted if the server replied that the change failed.
-TEST_F(WindowTreeClientTest, SetVisibleFailed) {
- WindowTreeSetup setup;
- Window* root = setup.GetFirstRoot();
- ASSERT_TRUE(root);
- const bool original_visible = root->visible();
- const bool new_visible = !original_visible;
- ASSERT_NE(new_visible, root->visible());
- root->SetVisible(new_visible);
- uint32_t change_id;
- ASSERT_TRUE(setup.window_tree()->GetAndClearChangeId(&change_id));
- setup.window_tree_client()->OnChangeCompleted(change_id, false);
- EXPECT_EQ(original_visible, root->visible());
-}
-
-// Simulates a visible change, and while the visible change is in flight the
-// server replies with a new visible and the original visible change fails.
-TEST_F(WindowTreeClientTest, SetVisibleFailedWithPendingChange) {
- WindowTreeSetup setup;
- Window* root = setup.GetFirstRoot();
- ASSERT_TRUE(root);
- const bool original_visible = root->visible();
- const bool new_visible = !original_visible;
- ASSERT_NE(new_visible, root->visible());
- root->SetVisible(new_visible);
- EXPECT_EQ(new_visible, root->visible());
- uint32_t change_id;
- ASSERT_TRUE(setup.window_tree()->GetAndClearChangeId(&change_id));
-
- // Simulate the server responding with a visible change.
- const bool server_changed_visible = !new_visible;
- setup.window_tree_client()->OnWindowVisibilityChanged(server_id(root),
- server_changed_visible);
-
- // This shouldn't trigger visible changing yet.
- EXPECT_EQ(new_visible, root->visible());
-
- // Tell the client the change failed, which should trigger failing to the
- // most recent visible from server.
- setup.window_tree_client()->OnChangeCompleted(change_id, false);
- EXPECT_EQ(server_changed_visible, root->visible());
-
- // Simulate server changing back to original visible. Should take immediately.
- setup.window_tree_client()->OnWindowVisibilityChanged(server_id(root),
- original_visible);
- EXPECT_EQ(original_visible, root->visible());
-}
-
-// Verifies that local opacity is not changed if the server replied that the
-// change succeeded.
-TEST_F(WindowTreeClientTest, SetOpacitySucceeds) {
- WindowTreeSetup setup;
- Window* root = setup.GetFirstRoot();
- ASSERT_TRUE(root);
- const float original_opacity = root->opacity();
- const float new_opacity = 0.5f;
- ASSERT_NE(new_opacity, original_opacity);
- ASSERT_NE(new_opacity, root->opacity());
- root->SetOpacity(new_opacity);
- uint32_t change_id;
- ASSERT_TRUE(setup.window_tree()->GetAndClearChangeId(&change_id));
- setup.window_tree_client()->OnChangeCompleted(change_id, true);
- EXPECT_EQ(new_opacity, root->opacity());
-}
-
-// Verifies that opacity is reverted if the server replied that the change
-// failed.
-TEST_F(WindowTreeClientTest, SetOpacityFailed) {
- WindowTreeSetup setup;
- Window* root = setup.GetFirstRoot();
- ASSERT_TRUE(root);
- const float original_opacity = root->opacity();
- const float new_opacity = 0.5f;
- ASSERT_NE(new_opacity, root->opacity());
- root->SetOpacity(new_opacity);
- uint32_t change_id;
- ASSERT_TRUE(setup.window_tree()->GetAndClearChangeId(&change_id));
- setup.window_tree_client()->OnChangeCompleted(change_id, false);
- EXPECT_EQ(original_opacity, root->opacity());
-}
-
-// Simulates the server changing the opacitry while there is an opacity change
-// in flight, causing the requested change to fail.
-TEST_F(WindowTreeClientTest, SetOpacityFailedWithPendingChange) {
- WindowTreeSetup setup;
- Window* root = setup.GetFirstRoot();
- ASSERT_TRUE(root);
- const float original_opacity = root->opacity();
- const float new_opacity = 0.5f;
- ASSERT_NE(new_opacity, root->opacity());
- root->SetOpacity(new_opacity);
- EXPECT_EQ(new_opacity, root->opacity());
- uint32_t change_id;
- ASSERT_TRUE(setup.window_tree()->GetAndClearChangeId(&change_id));
-
- // Simulate the server responding with an opacity change.
- const float server_changed_opacity = 0.75f;
- setup.window_tree_client()->OnWindowOpacityChanged(
- server_id(root), original_opacity, server_changed_opacity);
-
- // This shouldn't trigger opacity changing yet.
- EXPECT_EQ(new_opacity, root->opacity());
-
- // Tell the client the change failed, which should trigger failing to the
- // most recent opacity from server.
- setup.window_tree_client()->OnChangeCompleted(change_id, false);
- EXPECT_EQ(server_changed_opacity, root->opacity());
-
- // Simulate server changing back to original opacity. Should take immediately.
- setup.window_tree_client()->OnWindowOpacityChanged(
- server_id(root), server_changed_opacity, original_opacity);
- EXPECT_EQ(original_opacity, root->opacity());
-}
-
-// Tests that when there are multiple changes in flight, that failing changes
-// update the revert state of subsequent changes.
-TEST_F(WindowTreeClientTest, SetOpacityFailedWithMultiplePendingChange) {
- WindowTreeSetup setup;
- Window* root = setup.GetFirstRoot();
- ASSERT_TRUE(root);
- const float original_opacity = root->opacity();
- const float new_opacity = 0.5f;
- ASSERT_NE(new_opacity, root->opacity());
- root->SetOpacity(new_opacity);
- uint32_t change_id1;
- ASSERT_TRUE(setup.window_tree()->GetAndClearChangeId(&change_id1));
-
- const float second_new_opacity = 0.75f;
- ASSERT_NE(second_new_opacity, root->opacity());
- root->SetOpacity(second_new_opacity);
- uint32_t change_id2;
- ASSERT_TRUE(setup.window_tree()->GetAndClearChangeId(&change_id2));
-
- // Canceling the first one, while there is another in flight, should not
- // change the local opacity.
- setup.window_tree_client()->OnChangeCompleted(change_id1, false);
- EXPECT_EQ(second_new_opacity, root->opacity());
-
- // The previous cancelation should have updated the revert value of the in
- // flight change.
- setup.window_tree_client()->OnChangeCompleted(change_id2, false);
- EXPECT_EQ(original_opacity, root->opacity());
-}
-
-// Verifies |is_modal| is reverted if the server replied that the change failed.
-TEST_F(WindowTreeClientTest, SetModalFailed) {
- WindowTreeSetup setup;
- Window* root = setup.GetFirstRoot();
- ASSERT_TRUE(root);
- EXPECT_FALSE(root->is_modal());
- root->SetModal();
- uint32_t change_id;
- ASSERT_TRUE(setup.window_tree()->GetAndClearChangeId(&change_id));
- EXPECT_TRUE(root->is_modal());
- setup.window_tree_client()->OnChangeCompleted(change_id, false);
- EXPECT_FALSE(root->is_modal());
-}
-
-TEST_F(WindowTreeClientTest, InputEventBasic) {
- WindowTreeSetup setup;
- Window* root = setup.GetFirstRoot();
- ASSERT_TRUE(root);
-
- TestInputEventHandler event_handler;
- root->set_input_event_handler(&event_handler);
-
- std::unique_ptr<ui::Event> ui_event(
- new ui::MouseEvent(ui::ET_MOUSE_MOVED, gfx::Point(), gfx::Point(),
- ui::EventTimeForNow(), ui::EF_NONE, 0));
- setup.window_tree_client()->OnWindowInputEvent(
- 1, server_id(root), ui::Event::Clone(*ui_event.get()), 0);
- EXPECT_TRUE(event_handler.received_event());
- EXPECT_TRUE(setup.window_tree()->WasEventAcked(1));
- event_handler.Reset();
-
- event_handler.set_should_manually_ack();
- setup.window_tree_client()->OnWindowInputEvent(
- 33, server_id(root), ui::Event::Clone(*ui_event.get()), 0);
- EXPECT_TRUE(event_handler.received_event());
- EXPECT_FALSE(setup.window_tree()->WasEventAcked(33));
-
- event_handler.AckEvent();
- EXPECT_TRUE(setup.window_tree()->WasEventAcked(33));
-}
-
-// Tests pointer watchers triggered by events that did not hit a target in this
-// window tree.
-TEST_F(WindowTreeClientTest, OnPointerEventObserved) {
- WindowTreeSetup setup;
- Window* root = setup.GetFirstRoot();
- ASSERT_TRUE(root);
-
- // Start a pointer watcher for all events excluding move events.
- setup.client()->StartPointerWatcher(false /* want_moves */);
-
- // Simulate the server sending an observed event.
- std::unique_ptr<ui::PointerEvent> pointer_event_down(new ui::PointerEvent(
- ui::ET_POINTER_DOWN, gfx::Point(), gfx::Point(), ui::EF_CONTROL_DOWN, 1,
- 0, ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH),
- base::TimeTicks()));
- setup.window_tree_client()->OnPointerEventObserved(
- std::move(pointer_event_down), 0u);
-
- // Delegate sensed the event.
- ui::Event* last_event = setup.window_tree_delegate()->last_event_observed();
- EXPECT_EQ(ui::ET_POINTER_DOWN, last_event->type());
- EXPECT_EQ(ui::EF_CONTROL_DOWN, last_event->flags());
- setup.window_tree_delegate()->Reset();
-
- // Stop the pointer watcher.
- setup.client()->StopPointerWatcher();
-
- // Simulate another event from the server.
- std::unique_ptr<ui::PointerEvent> pointer_event_up(new ui::PointerEvent(
- ui::ET_POINTER_UP, gfx::Point(), gfx::Point(), ui::EF_CONTROL_DOWN, 1, 0,
- ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH),
- base::TimeTicks()));
- setup.window_tree_client()->OnPointerEventObserved(
- std::move(pointer_event_up), 0u);
-
- // No event was sensed.
- EXPECT_FALSE(setup.window_tree_delegate()->last_event_observed());
-}
-
-// Tests pointer watchers triggered by events that hit this window tree.
-TEST_F(WindowTreeClientTest, OnWindowInputEventWithPointerWatcher) {
- WindowTreeSetup setup;
- Window* root = setup.GetFirstRoot();
- ASSERT_TRUE(root);
-
- // Start a pointer watcher for all events excluding move events.
- setup.client()->StartPointerWatcher(false /* want_moves */);
-
- // Simulate the server dispatching an event that also matched the observer.
- std::unique_ptr<ui::PointerEvent> pointer_event_down(new ui::PointerEvent(
- ui::ET_POINTER_DOWN, gfx::Point(), gfx::Point(), ui::EF_CONTROL_DOWN, 1,
- 0, ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH),
- base::TimeTicks()));
- setup.window_tree_client()->OnWindowInputEvent(
- 1, server_id(root), std::move(pointer_event_down), true);
-
- // Delegate sensed the event.
- ui::Event* last_event = setup.window_tree_delegate()->last_event_observed();
- EXPECT_EQ(ui::ET_POINTER_DOWN, last_event->type());
- EXPECT_EQ(ui::EF_CONTROL_DOWN, last_event->flags());
-}
-
-// Verifies focus is reverted if the server replied that the change failed.
-TEST_F(WindowTreeClientTest, SetFocusFailed) {
- WindowTreeSetup setup;
- Window* root = setup.GetFirstRoot();
- ASSERT_TRUE(root);
- root->SetVisible(true);
- Window* child = setup.client()->NewWindow();
- child->SetVisible(true);
- root->AddChild(child);
- Window* original_focus = setup.client()->GetFocusedWindow();
- Window* new_focus = child;
- ASSERT_NE(new_focus, original_focus);
- new_focus->SetFocus();
- ASSERT_TRUE(new_focus->HasFocus());
- uint32_t change_id;
- ASSERT_TRUE(setup.window_tree()->GetAndClearChangeId(&change_id));
- setup.window_tree_client()->OnChangeCompleted(change_id, false);
- EXPECT_EQ(original_focus, setup.client()->GetFocusedWindow());
-}
-
-// Simulates a focus change, and while the focus change is in flight the server
-// replies with a new focus and the original focus change fails.
-TEST_F(WindowTreeClientTest, SetFocusFailedWithPendingChange) {
- WindowTreeSetup setup;
- Window* root = setup.GetFirstRoot();
- ASSERT_TRUE(root);
- root->SetVisible(true);
- Window* child1 = setup.client()->NewWindow();
- child1->SetVisible(true);
- root->AddChild(child1);
- Window* child2 = setup.client()->NewWindow();
- child2->SetVisible(true);
- root->AddChild(child2);
- Window* original_focus = setup.client()->GetFocusedWindow();
- Window* new_focus = child1;
- ASSERT_NE(new_focus, original_focus);
- new_focus->SetFocus();
- ASSERT_TRUE(new_focus->HasFocus());
- uint32_t change_id;
- ASSERT_TRUE(setup.window_tree()->GetAndClearChangeId(&change_id));
-
- // Simulate the server responding with a focus change.
- setup.window_tree_client()->OnWindowFocused(server_id(child2));
-
- // This shouldn't trigger focus changing yet.
- EXPECT_TRUE(child1->HasFocus());
-
- // Tell the client the change failed, which should trigger failing to the
- // most recent focus from server.
- setup.window_tree_client()->OnChangeCompleted(change_id, false);
- EXPECT_FALSE(child1->HasFocus());
- EXPECT_TRUE(child2->HasFocus());
- EXPECT_EQ(child2, setup.client()->GetFocusedWindow());
-
- // Simulate server changing focus to child1. Should take immediately.
- setup.window_tree_client()->OnWindowFocused(server_id(child1));
- EXPECT_TRUE(child1->HasFocus());
-}
-
-TEST_F(WindowTreeClientTest, FocusOnRemovedWindowWithInFlightFocusChange) {
- WindowTreeSetup setup;
- Window* root = setup.GetFirstRoot();
- ASSERT_TRUE(root);
- root->SetVisible(true);
- Window* child1 = setup.client()->NewWindow();
- child1->SetVisible(true);
- root->AddChild(child1);
- Window* child2 = setup.client()->NewWindow();
- child2->SetVisible(true);
- root->AddChild(child2);
-
- child1->SetFocus();
- uint32_t change_id;
- ASSERT_TRUE(setup.window_tree()->GetAndClearChangeId(&change_id));
-
- // Destroy child1, which should set focus to null.
- child1->Destroy();
- EXPECT_EQ(nullptr, setup.client()->GetFocusedWindow());
-
- // Server changes focus to 2.
- setup.window_tree_client()->OnWindowFocused(server_id(child2));
- // Shouldn't take immediately.
- EXPECT_FALSE(child2->HasFocus());
-
- // Ack the change, focus should still be null.
- setup.window_tree_client()->OnChangeCompleted(change_id, true);
- EXPECT_EQ(nullptr, setup.client()->GetFocusedWindow());
-
- // Change to 2 again, this time it should take.
- setup.window_tree_client()->OnWindowFocused(server_id(child2));
- EXPECT_TRUE(child2->HasFocus());
-}
-
-class ToggleVisibilityFromDestroyedObserver : public WindowObserver {
- public:
- explicit ToggleVisibilityFromDestroyedObserver(Window* window)
- : window_(window) {
- window_->AddObserver(this);
- }
-
- ToggleVisibilityFromDestroyedObserver() { EXPECT_FALSE(window_); }
-
- // WindowObserver:
- void OnWindowDestroyed(Window* window) override {
- window_->SetVisible(!window->visible());
- window_->RemoveObserver(this);
- window_ = nullptr;
- }
-
- private:
- Window* window_;
-
- DISALLOW_COPY_AND_ASSIGN(ToggleVisibilityFromDestroyedObserver);
-};
-
-TEST_F(WindowTreeClientTest, ToggleVisibilityFromWindowDestroyed) {
- WindowTreeSetup setup;
- Window* root = setup.GetFirstRoot();
- ASSERT_TRUE(root);
- Window* child1 = setup.client()->NewWindow();
- root->AddChild(child1);
- ToggleVisibilityFromDestroyedObserver toggler(child1);
- // Destroying the window triggers
- // ToggleVisibilityFromDestroyedObserver::OnWindowDestroyed(), which toggles
- // the visibility of the window. Ack the change, which should not crash or
- // trigger DCHECKs.
- child1->Destroy();
- uint32_t change_id;
- ASSERT_TRUE(setup.window_tree()->GetAndClearChangeId(&change_id));
- setup.window_tree_client()->OnChangeCompleted(change_id, true);
-}
-
-TEST_F(WindowTreeClientTest, NewTopLevelWindow) {
- WindowTreeSetup setup;
- Window* root1 = setup.GetFirstRoot();
- ASSERT_TRUE(root1);
- Window* root2 = setup.client()->NewTopLevelWindow(nullptr);
- ASSERT_TRUE(root2);
- EXPECT_TRUE(WindowPrivate(root2).parent_drawn());
- ASSERT_NE(root2, root1);
- EXPECT_NE(server_id(root2), server_id(root1));
- EXPECT_EQ(2u, setup.client()->GetRoots().size());
- EXPECT_TRUE(setup.client()->GetRoots().count(root1) > 0u);
- EXPECT_TRUE(setup.client()->GetRoots().count(root2) > 0u);
-
- // Ack the request to the windowtree to create the new window.
- uint32_t change_id;
- ASSERT_TRUE(setup.window_tree()->GetAndClearChangeId(&change_id));
- EXPECT_EQ(setup.window_tree()->window_id(), server_id(root2));
-
- mojom::WindowDataPtr data = mojom::WindowData::New();
- data->window_id = server_id(root2);
- const int64_t display_id = 1;
- setup.window_tree_client()->OnTopLevelCreated(change_id, std::move(data),
- display_id, false);
-
- EXPECT_FALSE(WindowPrivate(root2).parent_drawn());
-
- // Should not be able to add a top level as a child of another window.
- root1->AddChild(root2);
- ASSERT_EQ(nullptr, root2->parent());
-
- // Destroy the first root, shouldn't initiate tear down.
- root1->Destroy();
- root1 = nullptr;
- EXPECT_EQ(1u, setup.client()->GetRoots().size());
- EXPECT_TRUE(setup.client()->GetRoots().count(root2) > 0u);
-}
-
-TEST_F(WindowTreeClientTest, NewTopLevelWindowGetsPropertiesFromData) {
- WindowTreeSetup setup;
- Window* root1 = setup.GetFirstRoot();
- ASSERT_TRUE(root1);
- Window* root2 = setup.client()->NewTopLevelWindow(nullptr);
- ASSERT_TRUE(root2);
-
- EXPECT_FALSE(root2->IsDrawn());
- EXPECT_FALSE(root2->visible());
-
- // Ack the request to the windowtree to create the new window.
- uint32_t change_id;
- ASSERT_TRUE(setup.window_tree()->GetAndClearChangeId(&change_id));
- EXPECT_EQ(setup.window_tree()->window_id(), server_id(root2));
-
- mojom::WindowDataPtr data = mojom::WindowData::New();
- data->window_id = server_id(root2);
- data->bounds.SetRect(1, 2, 3, 4);
- data->visible = true;
- const int64_t display_id = 1;
- setup.window_tree_client()->OnTopLevelCreated(change_id, std::move(data),
- display_id, true);
-
- // Make sure all the properties took.
- EXPECT_TRUE(root2->IsDrawn());
- EXPECT_TRUE(root2->visible());
- EXPECT_EQ(1, root2->display_id());
- EXPECT_EQ(gfx::Rect(1, 2, 3, 4), root2->bounds());
-}
-
-TEST_F(WindowTreeClientTest, NewTopLevelWindowGetsAllChangesInFlight) {
- WindowTreeSetup setup;
- Window* root1 = setup.GetFirstRoot();
- ASSERT_TRUE(root1);
- Window* root2 = setup.client()->NewTopLevelWindow(nullptr);
- ASSERT_TRUE(root2);
-
- EXPECT_FALSE(root2->IsDrawn());
- EXPECT_FALSE(root2->visible());
-
- // Get the id of the in flight change for creating the new window.
- uint32_t new_window_in_flight_change_id;
- ASSERT_TRUE(setup.window_tree()->GetAndClearChangeId(
- &new_window_in_flight_change_id));
- EXPECT_EQ(setup.window_tree()->window_id(), server_id(root2));
-
- // Make visibility go from false->true->false. Don't ack immediately.
- root2->SetVisible(true);
- uint32_t vis_in_flight_change_id1;
- ASSERT_TRUE(
- setup.window_tree()->GetAndClearChangeId(&vis_in_flight_change_id1));
- EXPECT_NE(new_window_in_flight_change_id, vis_in_flight_change_id1);
- root2->SetVisible(false);
- uint32_t vis_in_flight_change_id2;
- ASSERT_TRUE(
- setup.window_tree()->GetAndClearChangeId(&vis_in_flight_change_id2));
- EXPECT_NE(vis_in_flight_change_id1, vis_in_flight_change_id2);
-
- // Change bounds to 5, 6, 7, 8.
- root2->SetBounds(gfx::Rect(5, 6, 7, 8));
- uint32_t bounds_in_flight_change_id;
- ASSERT_TRUE(
- setup.window_tree()->GetAndClearChangeId(&bounds_in_flight_change_id));
- EXPECT_NE(vis_in_flight_change_id2, bounds_in_flight_change_id);
-
- root2->SetSharedProperty<std::string>("xx", "client_xx");
- uint32_t property_in_flight_change_id;
- ASSERT_TRUE(
- setup.window_tree()->GetAndClearChangeId(&property_in_flight_change_id));
- EXPECT_NE(bounds_in_flight_change_id, property_in_flight_change_id);
-
- // Ack the new window top level window. Vis and bounds shouldn't change.
- mojom::WindowDataPtr data = mojom::WindowData::New();
- data->window_id = server_id(root2);
- data->bounds.SetRect(1, 2, 3, 4);
- data->visible = true;
- constexpr char kXxName[] = "server_xx";
- data->properties["xx"] =
- std::vector<uint8_t>(kXxName, kXxName + strlen(kXxName));
- constexpr char kYyName[] = "server_yy";
- data->properties["yy"] =
- std::vector<uint8_t>(kYyName, kYyName + strlen(kYyName));
- const int64_t display_id = 1;
- setup.window_tree_client()->OnTopLevelCreated(
- new_window_in_flight_change_id, std::move(data), display_id, true);
-
- // The only value that should take effect is the property for 'yy' as it was
- // not in flight.
- EXPECT_TRUE(WindowPrivate(root2).parent_drawn());
- EXPECT_FALSE(root2->visible());
- EXPECT_EQ(1, root2->display_id());
- EXPECT_EQ(gfx::Rect(5, 6, 7, 8), root2->bounds());
- EXPECT_EQ(2u, root2->shared_properties().size());
- ASSERT_TRUE(root2->HasSharedProperty("yy"));
- EXPECT_EQ("server_yy", root2->GetSharedProperty<std::string>("yy"));
- ASSERT_TRUE(root2->HasSharedProperty("xx"));
- EXPECT_EQ("client_xx", root2->GetSharedProperty<std::string>("xx"));
-
- // Tell the client the changes failed. This should cause the values to change
- // to that of the server.
- setup.window_tree_client()->OnChangeCompleted(vis_in_flight_change_id1,
- false);
- EXPECT_FALSE(root2->visible());
- setup.window_tree_client()->OnChangeCompleted(vis_in_flight_change_id2,
- false);
- EXPECT_TRUE(root2->visible());
- setup.window_tree_client()->OnChangeCompleted(bounds_in_flight_change_id,
- false);
- EXPECT_EQ(gfx::Rect(1, 2, 3, 4), root2->bounds());
- setup.window_tree_client()->OnChangeCompleted(property_in_flight_change_id,
- false);
- EXPECT_EQ(2u, root2->shared_properties().size());
- ASSERT_TRUE(root2->HasSharedProperty("yy"));
- EXPECT_EQ("server_yy", root2->GetSharedProperty<std::string>("yy"));
- ASSERT_TRUE(root2->HasSharedProperty("xx"));
- EXPECT_EQ("server_xx", root2->GetSharedProperty<std::string>("xx"));
-}
-
-// Tests that if the client has multiple unowned windows, and one of them is a
-// transient child to another, the teardown can happen cleanly.
-TEST_F(WindowTreeClientTest, MultipleUnOwnedWindowsDuringDestruction) {
- std::unique_ptr<WindowTreeSetup> setup(new WindowTreeSetup());
- Window* root1 = setup->GetFirstRoot();
- ASSERT_TRUE(root1);
- Window* root2 = setup->client()->NewTopLevelWindow(nullptr);
- ASSERT_TRUE(root2);
- root1->AddTransientWindow(root2);
-
- WindowTracker tracker;
- tracker.Add(root1);
- tracker.Add(root2);
- setup.reset();
- EXPECT_TRUE(tracker.windows().empty());
-}
-
-TEST_F(WindowTreeClientTest, TopLevelWindowDestroyedBeforeCreateComplete) {
- WindowTreeSetup setup;
- Window* root1 = setup.GetFirstRoot();
- ASSERT_TRUE(root1);
- Window* root2 = setup.client()->NewTopLevelWindow(nullptr);
- ASSERT_TRUE(root2);
- ASSERT_EQ(2u, setup.client()->GetRoots().size());
-
- // Get the id of the in flight change for creating the new window.
- uint32_t change_id;
- ASSERT_TRUE(setup.window_tree()->GetAndClearChangeId(&change_id));
- EXPECT_EQ(setup.window_tree()->window_id(), server_id(root2));
-
- mojom::WindowDataPtr data = mojom::WindowData::New();
- data->window_id = server_id(root2);
-
- // Destroy the window before the server has a chance to ack the window
- // creation.
- root2->Destroy();
- EXPECT_EQ(1u, setup.client()->GetRoots().size());
-
- const int64_t display_id = 1;
- setup.window_tree_client()->OnTopLevelCreated(change_id, std::move(data),
- display_id, true);
- EXPECT_EQ(1u, setup.client()->GetRoots().size());
-}
-
-// Tests both SetCapture and ReleaseCapture, to ensure that Window is properly
-// updated on failures.
-TEST_F(WindowTreeClientTest, ExplicitCapture) {
- WindowTreeSetup setup;
- Window* root = setup.GetFirstRoot();
- ASSERT_TRUE(root);
-
- root->SetCapture();
- EXPECT_TRUE(root->HasCapture());
- uint32_t change_id1;
- ASSERT_TRUE(setup.window_tree()->GetAndClearChangeId(&change_id1));
- setup.window_tree_client()->OnChangeCompleted(change_id1, false);
- EXPECT_FALSE(root->HasCapture());
-
- root->SetCapture();
- EXPECT_TRUE(root->HasCapture());
- uint32_t change_id2;
- ASSERT_TRUE(setup.window_tree()->GetAndClearChangeId(&change_id2));
- setup.window_tree_client()->OnChangeCompleted(change_id2, true);
- EXPECT_TRUE(root->HasCapture());
-
- root->ReleaseCapture();
- EXPECT_FALSE(root->HasCapture());
- uint32_t change_id3;
- ASSERT_TRUE(setup.window_tree()->GetAndClearChangeId(&change_id3));
- setup.window_tree_client()->OnChangeCompleted(change_id3, false);
- EXPECT_TRUE(root->HasCapture());
-
- root->ReleaseCapture();
- uint32_t change_id4;
- ASSERT_TRUE(setup.window_tree()->GetAndClearChangeId(&change_id4));
- setup.window_tree_client()->OnChangeCompleted(change_id4, true);
- EXPECT_FALSE(root->HasCapture());
-}
-
-// Tests that when capture is lost, that the window tree updates properly.
-TEST_F(WindowTreeClientTest, LostCapture) {
- WindowTreeSetup setup;
- Window* root = setup.GetFirstRoot();
- ASSERT_TRUE(root);
-
- root->SetCapture();
- EXPECT_TRUE(root->HasCapture());
- uint32_t change_id1;
- ASSERT_TRUE(setup.window_tree()->GetAndClearChangeId(&change_id1));
- setup.window_tree_client()->OnChangeCompleted(change_id1, true);
- EXPECT_TRUE(root->HasCapture());
-
- // The second SetCapture should be ignored.
- root->SetCapture();
- uint32_t change_id2;
- ASSERT_FALSE(setup.window_tree()->GetAndClearChangeId(&change_id2));
-
- setup.window_tree_client()->OnCaptureChanged(0, server_id(root));
- EXPECT_FALSE(root->HasCapture());
-}
-
-// Tests that when capture is lost, while there is a release capture request
-// inflight, that the revert value of that request is updated correctly.
-TEST_F(WindowTreeClientTest, LostCaptureDifferentInFlightChange) {
- WindowTreeSetup setup;
- Window* root = setup.GetFirstRoot();
- ASSERT_TRUE(root);
-
- root->SetCapture();
- EXPECT_TRUE(root->HasCapture());
- uint32_t change_id1;
- ASSERT_TRUE(setup.window_tree()->GetAndClearChangeId(&change_id1));
- setup.window_tree_client()->OnChangeCompleted(change_id1, true);
- EXPECT_TRUE(root->HasCapture());
-
- // The ReleaseCapture should be updated to the revert of the SetCapture.
- root->ReleaseCapture();
- uint32_t change_id2;
- ASSERT_TRUE(setup.window_tree()->GetAndClearChangeId(&change_id2));
-
- setup.window_tree_client()->OnCaptureChanged(0, server_id(root));
- EXPECT_FALSE(root->HasCapture());
-
- setup.window_tree_client()->OnChangeCompleted(change_id2, false);
- EXPECT_FALSE(root->HasCapture());
-}
-
-// Tests that while two windows can inflight capture requests, that the
-// WindowTreeClient only identifies one as having the current capture.
-TEST_F(WindowTreeClientTest, TwoWindowsRequestCapture) {
- WindowTreeSetup setup;
- Window* root = setup.GetFirstRoot();
- Window* child = setup.client()->NewWindow();
- child->SetVisible(true);
- root->AddChild(child);
-
- root->SetCapture();
- EXPECT_TRUE(root->HasCapture());
- uint32_t change_id1;
- ASSERT_TRUE(setup.window_tree()->GetAndClearChangeId(&change_id1));
-
- child->SetCapture();
- EXPECT_TRUE(child->HasCapture());
- EXPECT_FALSE(root->HasCapture());
-
- uint32_t change_id2;
- ASSERT_TRUE(setup.window_tree()->GetAndClearChangeId(&change_id2));
-
- setup.window_tree_client()->OnChangeCompleted(change_id1, true);
- EXPECT_FALSE(root->HasCapture());
- EXPECT_TRUE(child->HasCapture());
-
- setup.window_tree_client()->OnChangeCompleted(change_id2, false);
- EXPECT_FALSE(child->HasCapture());
- EXPECT_TRUE(root->HasCapture());
-
- setup.window_tree_client()->OnCaptureChanged(0, server_id(root));
- EXPECT_FALSE(root->HasCapture());
-}
-
-TEST_F(WindowTreeClientTest, WindowDestroyedWhileTransientChildHasCapture) {
- WindowTreeSetup setup;
- Window* root = setup.GetFirstRoot();
- Window* transient_parent = setup.client()->NewWindow();
- Window* transient_child = setup.client()->NewWindow();
- transient_parent->SetVisible(true);
- transient_child->SetVisible(true);
- root->AddChild(transient_parent);
- root->AddChild(transient_child);
-
- transient_parent->AddTransientWindow(transient_child);
-
- WindowTracker tracker;
- tracker.Add(transient_parent);
- tracker.Add(transient_child);
- // Request a capture on the transient child, then destroy the transient
- // parent. That will destroy both windows, and should reset the capture window
- // correctly.
- transient_child->SetCapture();
- transient_parent->Destroy();
- EXPECT_TRUE(tracker.windows().empty());
-
- // Create a new Window, and attempt to place capture on that.
- Window* child = setup.client()->NewWindow();
- child->SetVisible(true);
- root->AddChild(child);
- child->SetCapture();
- EXPECT_TRUE(child->HasCapture());
-}
-
-namespace {
-
-class CaptureRecorder : public WindowTreeClientObserver {
- public:
- explicit CaptureRecorder(WindowTreeClient* tree_client)
- : tree_client_(tree_client) {
- tree_client_->AddObserver(this);
- }
-
- ~CaptureRecorder() override { tree_client_->RemoveObserver(this); }
-
- void reset_capture_captured_count() { capture_changed_count_ = 0; }
- int capture_changed_count() const { return capture_changed_count_; }
- int last_gained_capture_window_id() const {
- return last_gained_capture_window_id_;
- }
- int last_lost_capture_window_id() const {
- return last_lost_capture_window_id_;
- }
-
- // WindowTreeClientObserver:
- void OnWindowTreeCaptureChanged(Window* gained_capture,
- Window* lost_capture) override {
- capture_changed_count_++;
- last_gained_capture_window_id_ =
- gained_capture ? gained_capture->local_id() : 0;
- last_lost_capture_window_id_ = lost_capture ? lost_capture->local_id() : 0;
- }
-
- private:
- WindowTreeClient* tree_client_;
- int capture_changed_count_ = 0;
- int last_gained_capture_window_id_ = 0;
- int last_lost_capture_window_id_ = 0;
-
- DISALLOW_COPY_AND_ASSIGN(CaptureRecorder);
-};
-
-} // namespace
-
-TEST_F(WindowTreeClientTest, OnWindowTreeCaptureChanged) {
- WindowTreeSetup setup;
- CaptureRecorder capture_recorder(setup.client());
- Window* root = setup.GetFirstRoot();
- Window* child1 = setup.client()->NewWindow();
- const int child1_id = 1;
- child1->set_local_id(child1_id);
- child1->SetVisible(true);
- root->AddChild(child1);
- Window* child2 = setup.client()->NewWindow();
- const int child2_id = 2;
- child2->set_local_id(child2_id);
- child2->SetVisible(true);
- root->AddChild(child2);
-
- EXPECT_EQ(0, capture_recorder.capture_changed_count());
- // Give capture to child1 and ensure everyone is notified correctly.
- child1->SetCapture();
- uint32_t change_id;
- ASSERT_TRUE(setup.window_tree()->GetAndClearChangeId(&change_id));
- setup.window_tree_client()->OnChangeCompleted(change_id, true);
- EXPECT_EQ(1, capture_recorder.capture_changed_count());
- EXPECT_EQ(child1_id, capture_recorder.last_gained_capture_window_id());
- EXPECT_EQ(0, capture_recorder.last_lost_capture_window_id());
- capture_recorder.reset_capture_captured_count();
-
- // Deleting a window with capture should notify observers as well.
- child1->Destroy();
- child1 = nullptr;
- EXPECT_EQ(1, capture_recorder.capture_changed_count());
- EXPECT_EQ(0, capture_recorder.last_gained_capture_window_id());
- EXPECT_EQ(child1_id, capture_recorder.last_lost_capture_window_id());
- capture_recorder.reset_capture_captured_count();
-
- // Changes originating from server should notify observers too.
- WindowTreeClientPrivate(setup.client()).CallOnCaptureChanged(child2, nullptr);
- EXPECT_EQ(1, capture_recorder.capture_changed_count());
- EXPECT_EQ(child2_id, capture_recorder.last_gained_capture_window_id());
- EXPECT_EQ(0, capture_recorder.last_lost_capture_window_id());
- capture_recorder.reset_capture_captured_count();
-}
-
-} // namespace ui
« no previous file with comments | « services/ui/public/cpp/tests/window_tree_client_private.cc ('k') | services/ui/public/cpp/tests/window_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698