This source file includes following definitions.
- remove_count_
- add_count
- remove_count
- OnTransientChildAdded
- OnTransientChildRemoved
- SetUp
- TearDown
- CreateTransientChild
- TEST_F
- TEST_F
- TEST_F
- results_
- OnWindowDestroyed
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- OnWindowResized
- OnWindowAddedToLayout
- OnWillRemoveWindowFromLayout
- OnWindowRemovedFromLayout
- OnChildWindowVisibilityChanged
- SetChildBounds
- set_ignored_window
- UpdateLayerVisibility
- TEST_F
- TEST_F
- TEST_F
#include "ui/wm/core/transient_window_manager.h"
#include "ui/aura/client/visibility_client.h"
#include "ui/aura/client/window_tree_client.h"
#include "ui/aura/layout_manager.h"
#include "ui/aura/test/aura_test_base.h"
#include "ui/aura/test/test_windows.h"
#include "ui/aura/window.h"
#include "ui/wm/core/transient_window_observer.h"
#include "ui/wm/core/window_util.h"
#include "ui/wm/core/wm_state.h"
using aura::Window;
using aura::test::ChildWindowIDsAsString;
using aura::test::CreateTestWindowWithId;
namespace wm {
class TestTransientWindowObserver : public TransientWindowObserver {
public:
TestTransientWindowObserver() : add_count_(0), remove_count_(0) {
}
virtual ~TestTransientWindowObserver() {
}
int add_count() const { return add_count_; }
int remove_count() const { return remove_count_; }
virtual void OnTransientChildAdded(Window* window,
Window* transient) OVERRIDE {
add_count_++;
}
virtual void OnTransientChildRemoved(Window* window,
Window* transient) OVERRIDE {
remove_count_++;
}
private:
int add_count_;
int remove_count_;
DISALLOW_COPY_AND_ASSIGN(TestTransientWindowObserver);
};
class TransientWindowManagerTest : public aura::test::AuraTestBase {
public:
TransientWindowManagerTest() {}
virtual ~TransientWindowManagerTest() {}
virtual void SetUp() OVERRIDE {
AuraTestBase::SetUp();
wm_state_.reset(new wm::WMState);
}
virtual void TearDown() OVERRIDE {
wm_state_.reset();
AuraTestBase::TearDown();
}
protected:
Window* CreateTransientChild(int id, Window* parent) {
Window* window = new Window(NULL);
window->set_id(id);
window->SetType(ui::wm::WINDOW_TYPE_NORMAL);
window->Init(aura::WINDOW_LAYER_TEXTURED);
aura::client::ParentWindowWithContext(window, root_window(), gfx::Rect());
AddTransientChild(parent, window);
return window;
}
private:
scoped_ptr<wm::WMState> wm_state_;
DISALLOW_COPY_AND_ASSIGN(TransientWindowManagerTest);
};
TEST_F(TransientWindowManagerTest, TransientChildren) {
scoped_ptr<Window> parent(CreateTestWindowWithId(0, root_window()));
scoped_ptr<Window> w1(CreateTestWindowWithId(1, parent.get()));
scoped_ptr<Window> w3(CreateTestWindowWithId(3, parent.get()));
Window* w2 = CreateTestWindowWithId(2, parent.get());
AddTransientChild(w1.get(), w2);
parent->StackChildAtTop(w1.get());
ASSERT_EQ(3u, parent->children().size());
EXPECT_EQ(w2, parent->children().back());
w1.reset();
w2 = NULL;
ASSERT_EQ(1u, parent->children().size());
EXPECT_EQ(w3.get(), parent->children()[0]);
w1.reset(CreateTestWindowWithId(4, parent.get()));
w2 = CreateTestWindowWithId(5, w3.get());
AddTransientChild(w1.get(), w2);
parent->StackChildAtTop(w3.get());
parent->StackChildAtTop(w1.get());
ASSERT_EQ(2u, parent->children().size());
EXPECT_EQ(w3.get(), parent->children()[0]);
EXPECT_EQ(w1.get(), parent->children()[1]);
EXPECT_TRUE(w2->IsVisible());
w1->Hide();
EXPECT_FALSE(w2->IsVisible());
}
TEST_F(TransientWindowManagerTest, TransientChildrenGroupAbove) {
scoped_ptr<Window> parent(CreateTestWindowWithId(0, root_window()));
scoped_ptr<Window> w1(CreateTestWindowWithId(1, parent.get()));
Window* w11 = CreateTestWindowWithId(11, parent.get());
scoped_ptr<Window> w2(CreateTestWindowWithId(2, parent.get()));
Window* w21 = CreateTestWindowWithId(21, parent.get());
Window* w211 = CreateTestWindowWithId(211, parent.get());
Window* w212 = CreateTestWindowWithId(212, parent.get());
Window* w213 = CreateTestWindowWithId(213, parent.get());
Window* w22 = CreateTestWindowWithId(22, parent.get());
ASSERT_EQ(8u, parent->children().size());
AddTransientChild(w1.get(), w11);
AddTransientChild(w2.get(), w21);
AddTransientChild(w2.get(), w22);
AddTransientChild(w21, w211);
AddTransientChild(w21, w212);
AddTransientChild(w21, w213);
EXPECT_EQ("1 11 2 21 211 212 213 22", ChildWindowIDsAsString(parent.get()));
parent->StackChildAtTop(w1.get());
EXPECT_EQ(w11, parent->children().back());
EXPECT_EQ("2 21 211 212 213 22 1 11", ChildWindowIDsAsString(parent.get()));
parent->StackChildAtTop(w2.get());
EXPECT_EQ(w22, parent->children().back());
EXPECT_EQ("1 11 2 21 211 212 213 22", ChildWindowIDsAsString(parent.get()));
parent->StackChildAbove(w11, w2.get());
EXPECT_EQ(w11, parent->children().back());
EXPECT_EQ("2 21 211 212 213 22 1 11", ChildWindowIDsAsString(parent.get()));
parent->StackChildAbove(w21, w1.get());
EXPECT_EQ(w22, parent->children().back());
EXPECT_EQ("1 11 2 21 211 212 213 22", ChildWindowIDsAsString(parent.get()));
parent->StackChildAbove(w21, w22);
EXPECT_EQ(w213, parent->children().back());
EXPECT_EQ("1 11 2 22 21 211 212 213", ChildWindowIDsAsString(parent.get()));
parent->StackChildAbove(w11, w21);
EXPECT_EQ(w11, parent->children().back());
EXPECT_EQ("2 22 21 211 212 213 1 11", ChildWindowIDsAsString(parent.get()));
parent->StackChildAbove(w213, w21);
EXPECT_EQ(w11, parent->children().back());
EXPECT_EQ("2 22 21 213 211 212 1 11", ChildWindowIDsAsString(parent.get()));
parent->StackChildAbove(w21, w211);
EXPECT_EQ(w11, parent->children().back());
EXPECT_EQ("2 22 21 213 211 212 1 11", ChildWindowIDsAsString(parent.get()));
parent->StackChildAbove(w2.get(), w1.get());
EXPECT_EQ(w212, parent->children().back());
EXPECT_EQ("1 11 2 22 21 213 211 212", ChildWindowIDsAsString(parent.get()));
parent->StackChildAbove(w11, w213);
EXPECT_EQ(w11, parent->children().back());
EXPECT_EQ("2 22 21 213 211 212 1 11", ChildWindowIDsAsString(parent.get()));
}
TEST_F(TransientWindowManagerTest, TransientChildrenGroupBelow) {
scoped_ptr<Window> parent(CreateTestWindowWithId(0, root_window()));
scoped_ptr<Window> w1(CreateTestWindowWithId(1, parent.get()));
Window* w11 = CreateTestWindowWithId(11, parent.get());
scoped_ptr<Window> w2(CreateTestWindowWithId(2, parent.get()));
Window* w21 = CreateTestWindowWithId(21, parent.get());
Window* w211 = CreateTestWindowWithId(211, parent.get());
Window* w212 = CreateTestWindowWithId(212, parent.get());
Window* w213 = CreateTestWindowWithId(213, parent.get());
Window* w22 = CreateTestWindowWithId(22, parent.get());
ASSERT_EQ(8u, parent->children().size());
AddTransientChild(w1.get(), w11);
AddTransientChild(w2.get(), w21);
AddTransientChild(w2.get(), w22);
AddTransientChild(w21, w211);
AddTransientChild(w21, w212);
AddTransientChild(w21, w213);
EXPECT_EQ("1 11 2 21 211 212 213 22", ChildWindowIDsAsString(parent.get()));
parent->StackChildAtBottom(w2.get());
EXPECT_EQ(w11, parent->children().back());
EXPECT_EQ("2 21 211 212 213 22 1 11", ChildWindowIDsAsString(parent.get()));
parent->StackChildAtBottom(w1.get());
EXPECT_EQ(w22, parent->children().back());
EXPECT_EQ("1 11 2 21 211 212 213 22", ChildWindowIDsAsString(parent.get()));
parent->StackChildBelow(w21, w1.get());
EXPECT_EQ(w11, parent->children().back());
EXPECT_EQ("2 21 211 212 213 22 1 11", ChildWindowIDsAsString(parent.get()));
parent->StackChildBelow(w11, w2.get());
EXPECT_EQ(w22, parent->children().back());
EXPECT_EQ("1 11 2 21 211 212 213 22", ChildWindowIDsAsString(parent.get()));
parent->StackChildBelow(w22, w21);
EXPECT_EQ(w213, parent->children().back());
EXPECT_EQ("1 11 2 22 21 211 212 213", ChildWindowIDsAsString(parent.get()));
parent->StackChildBelow(w21, w11);
EXPECT_EQ(w11, parent->children().back());
EXPECT_EQ("2 22 21 211 212 213 1 11", ChildWindowIDsAsString(parent.get()));
parent->StackChildBelow(w213, w211);
EXPECT_EQ(w11, parent->children().back());
EXPECT_EQ("2 22 21 213 211 212 1 11", ChildWindowIDsAsString(parent.get()));
parent->StackChildBelow(w21, w211);
EXPECT_EQ(w11, parent->children().back());
EXPECT_EQ("2 22 21 213 211 212 1 11", ChildWindowIDsAsString(parent.get()));
parent->StackChildBelow(w1.get(), w2.get());
EXPECT_EQ(w212, parent->children().back());
EXPECT_EQ("1 11 2 22 21 213 211 212", ChildWindowIDsAsString(parent.get()));
parent->StackChildBelow(w213, w11);
EXPECT_EQ(w11, parent->children().back());
EXPECT_EQ("2 22 21 213 211 212 1 11", ChildWindowIDsAsString(parent.get()));
}
namespace {
class DestroyedTrackingDelegate : public aura::test::TestWindowDelegate {
public:
explicit DestroyedTrackingDelegate(const std::string& name,
std::vector<std::string>* results)
: name_(name),
results_(results) {}
virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE {
results_->push_back(name_);
}
private:
const std::string name_;
std::vector<std::string>* results_;
DISALLOW_COPY_AND_ASSIGN(DestroyedTrackingDelegate);
};
}
TEST_F(TransientWindowManagerTest, NotifyDelegateAfterDeletingTransients) {
std::vector<std::string> destruction_order;
DestroyedTrackingDelegate parent_delegate("parent", &destruction_order);
scoped_ptr<Window> parent(new Window(&parent_delegate));
parent->Init(aura::WINDOW_LAYER_NOT_DRAWN);
DestroyedTrackingDelegate transient_delegate("transient", &destruction_order);
Window* transient = new Window(&transient_delegate);
transient->Init(aura::WINDOW_LAYER_NOT_DRAWN);
AddTransientChild(parent.get(), transient);
parent.reset();
ASSERT_EQ(2u, destruction_order.size());
EXPECT_EQ("transient", destruction_order[0]);
EXPECT_EQ("parent", destruction_order[1]);
}
TEST_F(TransientWindowManagerTest, StackTransientsWhoseLayersHaveNoDelegate) {
scoped_ptr<Window> window1(CreateTestWindowWithId(1, root_window()));
scoped_ptr<Window> window11(CreateTransientChild(11, window1.get()));
scoped_ptr<Window> window12(CreateTransientChild(12, window1.get()));
scoped_ptr<Window> window13(CreateTransientChild(13, window1.get()));
scoped_ptr<Window> window2(CreateTestWindowWithId(2, root_window()));
scoped_ptr<Window> window3(CreateTestWindowWithId(3, root_window()));
EXPECT_EQ("1 11 12 13 2 3", ChildWindowIDsAsString(root_window()));
window11->layer()->set_delegate(NULL);
window13->layer()->set_delegate(NULL);
root_window()->StackChildAtTop(window1.get());
EXPECT_EQ("2 3 1 11 12 13", ChildWindowIDsAsString(root_window()));
}
TEST_F(TransientWindowManagerTest,
StackTransientsLayersRelativeToOtherTransients) {
scoped_ptr<Window> window1(CreateTestWindowWithId(1, root_window()));
scoped_ptr<Window> window11(CreateTransientChild(11, window1.get()));
scoped_ptr<Window> window12(CreateTransientChild(12, window1.get()));
scoped_ptr<Window> window13(CreateTransientChild(13, window1.get()));
EXPECT_EQ("1 11 12 13", ChildWindowIDsAsString(root_window()));
root_window()->StackChildAbove(window11.get(), window12.get());
EXPECT_EQ("1 12 11 13", ChildWindowIDsAsString(root_window()));
root_window()->StackChildBelow(window13.get(), window12.get());
EXPECT_EQ("1 13 12 11", ChildWindowIDsAsString(root_window()));
root_window()->StackChildAbove(window11.get(), window1.get());
EXPECT_EQ("1 11 13 12", ChildWindowIDsAsString(root_window()));
root_window()->StackChildBelow(window12.get(), window13.get());
EXPECT_EQ("1 11 12 13", ChildWindowIDsAsString(root_window()));
}
TEST_F(TransientWindowManagerTest,
StackTransientsLayersRelativeToOtherTransientsNoLayerDelegate) {
scoped_ptr<Window> window1(CreateTestWindowWithId(1, root_window()));
scoped_ptr<Window> window11(CreateTransientChild(11, window1.get()));
scoped_ptr<Window> window12(CreateTransientChild(12, window1.get()));
scoped_ptr<Window> window13(CreateTransientChild(13, window1.get()));
scoped_ptr<Window> window2(CreateTestWindowWithId(2, root_window()));
scoped_ptr<Window> window3(CreateTestWindowWithId(3, root_window()));
EXPECT_EQ("1 11 12 13 2 3", ChildWindowIDsAsString(root_window()));
window1->layer()->set_delegate(NULL);
root_window()->StackChildAtTop(window1.get());
EXPECT_EQ("2 3 1 11 12 13", ChildWindowIDsAsString(root_window()));
}
class StackingMadrigalLayoutManager : public aura::LayoutManager {
public:
explicit StackingMadrigalLayoutManager(Window* root_window)
: root_window_(root_window) {
root_window_->SetLayoutManager(this);
}
virtual ~StackingMadrigalLayoutManager() {
}
private:
virtual void OnWindowResized() OVERRIDE {}
virtual void OnWindowAddedToLayout(Window* child) OVERRIDE {}
virtual void OnWillRemoveWindowFromLayout(Window* child) OVERRIDE {}
virtual void OnWindowRemovedFromLayout(Window* child) OVERRIDE {}
virtual void OnChildWindowVisibilityChanged(Window* child,
bool visible) OVERRIDE {
Window::Windows::const_iterator it = root_window_->children().begin();
Window* last_window = NULL;
for (; it != root_window_->children().end(); ++it) {
if (*it == child && last_window) {
if (!visible)
root_window_->StackChildAbove(last_window, *it);
else
root_window_->StackChildAbove(*it, last_window);
break;
}
last_window = *it;
}
}
virtual void SetChildBounds(Window* child,
const gfx::Rect& requested_bounds) OVERRIDE {
SetChildBoundsDirect(child, requested_bounds);
}
Window* root_window_;
DISALLOW_COPY_AND_ASSIGN(StackingMadrigalLayoutManager);
};
class StackingMadrigalVisibilityClient : public aura::client::VisibilityClient {
public:
explicit StackingMadrigalVisibilityClient(Window* root_window)
: ignored_window_(NULL) {
aura::client::SetVisibilityClient(root_window, this);
}
virtual ~StackingMadrigalVisibilityClient() {
}
void set_ignored_window(Window* ignored_window) {
ignored_window_ = ignored_window;
}
private:
virtual void UpdateLayerVisibility(Window* window, bool visible) OVERRIDE {
if (!visible) {
if (window == ignored_window_)
window->layer()->set_delegate(NULL);
else
window->layer()->SetVisible(visible);
} else {
window->layer()->SetVisible(visible);
}
}
Window* ignored_window_;
DISALLOW_COPY_AND_ASSIGN(StackingMadrigalVisibilityClient);
};
TEST_F(TransientWindowManagerTest, StackingMadrigal) {
new StackingMadrigalLayoutManager(root_window());
StackingMadrigalVisibilityClient visibility_client(root_window());
scoped_ptr<Window> window1(CreateTestWindowWithId(1, root_window()));
scoped_ptr<Window> window11(CreateTransientChild(11, window1.get()));
visibility_client.set_ignored_window(window11.get());
window11->Show();
window11->Hide();
EXPECT_TRUE(aura::test::WindowIsAbove(window11.get(), window1.get()));
EXPECT_TRUE(aura::test::LayerIsAbove(window11.get(), window1.get()));
scoped_ptr<Window> window12(CreateTransientChild(12, window1.get()));
window12->Show();
EXPECT_TRUE(aura::test::WindowIsAbove(window12.get(), window1.get()));
EXPECT_TRUE(aura::test::LayerIsAbove(window12.get(), window1.get()));
root_window()->StackChildAbove(window1.get(), window12.get());
EXPECT_TRUE(aura::test::WindowIsAbove(window12.get(), window1.get()));
EXPECT_TRUE(aura::test::LayerIsAbove(window12.get(), window1.get()));
}
TEST_F(TransientWindowManagerTest, StackOverClosingTransient) {
scoped_ptr<Window> window1(CreateTestWindowWithId(1, root_window()));
scoped_ptr<Window> transient1(CreateTransientChild(11, window1.get()));
scoped_ptr<Window> window2(CreateTestWindowWithId(2, root_window()));
scoped_ptr<Window> transient2(CreateTransientChild(21, window2.get()));
Window* root = root_window();
ASSERT_EQ(4u, root->children().size());
EXPECT_EQ(root->children()[0], window1.get());
EXPECT_EQ(root->children()[1], transient1.get());
EXPECT_EQ(root->children()[2], window2.get());
EXPECT_EQ(root->children()[3], transient2.get());
ASSERT_EQ(4u, root->layer()->children().size());
EXPECT_EQ(root->layer()->children()[0], window1->layer());
EXPECT_EQ(root->layer()->children()[1], transient1->layer());
EXPECT_EQ(root->layer()->children()[2], window2->layer());
EXPECT_EQ(root->layer()->children()[3], transient2->layer());
EXPECT_EQ("1 11 2 21", ChildWindowIDsAsString(root_window()));
root->StackChildAtTop(window1.get());
EXPECT_EQ("2 21 1 11", ChildWindowIDsAsString(root_window()));
EXPECT_EQ(root->children()[0], window2.get());
EXPECT_EQ(root->children()[1], transient2.get());
EXPECT_EQ(root->children()[2], window1.get());
EXPECT_EQ(root->children()[3], transient1.get());
EXPECT_EQ(root->layer()->children()[0], window2->layer());
EXPECT_EQ(root->layer()->children()[1], transient2->layer());
EXPECT_EQ(root->layer()->children()[2], window1->layer());
EXPECT_EQ(root->layer()->children()[3], transient1->layer());
transient1->layer()->set_delegate(NULL);
root->StackChildAtTop(window2.get());
EXPECT_EQ(root->children()[0], window1.get());
EXPECT_EQ(root->children()[1], window2.get());
EXPECT_EQ(root->children()[2], transient2.get());
EXPECT_EQ(root->children()[3], transient1.get());
EXPECT_EQ(root->layer()->children()[0], window1->layer());
EXPECT_EQ(root->layer()->children()[1], window2->layer());
EXPECT_EQ(root->layer()->children()[2], transient2->layer());
EXPECT_EQ(root->layer()->children()[3], transient1->layer());
transient1.reset();
ASSERT_EQ(3u, root->children().size());
EXPECT_EQ(root->children()[0], window1.get());
EXPECT_EQ(root->children()[1], window2.get());
EXPECT_EQ(root->children()[2], transient2.get());
ASSERT_EQ(3u, root->layer()->children().size());
EXPECT_EQ(root->layer()->children()[0], window1->layer());
EXPECT_EQ(root->layer()->children()[1], window2->layer());
EXPECT_EQ(root->layer()->children()[2], transient2->layer());
scoped_ptr<Window> window3(CreateTestWindowWithId(3, root_window()));
ASSERT_EQ(4u, root->children().size());
EXPECT_EQ(root->children()[0], window1.get());
EXPECT_EQ(root->children()[1], window2.get());
EXPECT_EQ(root->children()[2], transient2.get());
EXPECT_EQ(root->children()[3], window3.get());
ASSERT_EQ(4u, root->layer()->children().size());
EXPECT_EQ(root->layer()->children()[0], window1->layer());
EXPECT_EQ(root->layer()->children()[1], window2->layer());
EXPECT_EQ(root->layer()->children()[2], transient2->layer());
EXPECT_EQ(root->layer()->children()[3], window3->layer());
window3->layer()->set_delegate(NULL);
root->StackChildAtTop(window2.get());
ASSERT_EQ(4u, root->children().size());
EXPECT_EQ(root->children()[0], window1.get());
EXPECT_EQ(root->children()[1], window2.get());
EXPECT_EQ(root->children()[2], transient2.get());
EXPECT_EQ(root->children()[3], window3.get());
ASSERT_EQ(4u, root->layer()->children().size());
EXPECT_EQ(root->layer()->children()[0], window1->layer());
EXPECT_EQ(root->layer()->children()[1], window2->layer());
EXPECT_EQ(root->layer()->children()[2], transient2->layer());
EXPECT_EQ(root->layer()->children()[3], window3->layer());
root->StackChildAtTop(window1.get());
ASSERT_EQ(4u, root->children().size());
EXPECT_EQ(root->children()[0], window2.get());
EXPECT_EQ(root->children()[1], transient2.get());
EXPECT_EQ(root->children()[2], window1.get());
EXPECT_EQ(root->children()[3], window3.get());
ASSERT_EQ(4u, root->layer()->children().size());
EXPECT_EQ(root->layer()->children()[0], window2->layer());
EXPECT_EQ(root->layer()->children()[1], transient2->layer());
EXPECT_EQ(root->layer()->children()[2], window1->layer());
EXPECT_EQ(root->layer()->children()[3], window3->layer());
}
TEST_F(TransientWindowManagerTest, TransientWindowObserverNotified) {
scoped_ptr<Window> parent(CreateTestWindowWithId(0, root_window()));
scoped_ptr<Window> w1(CreateTestWindowWithId(1, parent.get()));
TestTransientWindowObserver test_observer;
TransientWindowManager::Get(parent.get())->AddObserver(&test_observer);
AddTransientChild(parent.get(), w1.get());
EXPECT_EQ(1, test_observer.add_count());
EXPECT_EQ(0, test_observer.remove_count());
RemoveTransientChild(parent.get(), w1.get());
EXPECT_EQ(1, test_observer.add_count());
EXPECT_EQ(1, test_observer.remove_count());
TransientWindowManager::Get(parent.get())->RemoveObserver(&test_observer);
}
}